我对回调函数理解和驱动加载为什么要有顺序

                 (1)有什么事件来了,就调用相关的函数处理,非常方便用在库函数编写者提供一个callback作为接口,然后库调用者的做相关的事件处理和状态获取,库的编写者要屏蔽相关的信息,库的使用者需要更多的灵活权限,涉及两个人的使用.

static  xxxxxxxxxxxxx(,,callback)

{

     if(xxx) {

               callback

    }

   if(xxx)  {

             callback

   } 

}

static callback()

{

       // 有什么状态信息  或者自己的事件处理   自己业务逻辑处理

}

                (2)所有层次代码编写  都是使用  注册   也就是填充 xxx结构体    在其他地方调用     这就是为什么要各种底层代码xxx驱动的注册

                    一般在core.c文件里面  .  一个复杂的带有函数指针的结构体变量    然后添加进链表里面    其他层会从这个链表里面取相关操作

                       linux驱动   linux 各种层次    常见    给其他层次代码使用      

   

 

  

      

/* readonly to gadget driver */
 const struct usb_gadget_ops *ops;    // 代码uc硬件操作 udc控制基本操作 不涉及端点的操作
 struct usb_ep   *ep0;    // 端点0及其相关操作
/* the rest of the api to the controller hardware: device operations,
 * which don't involve endpoints (or i/o).
 */
struct usb_gadget_ops {
 int (*get_frame)(struct usb_gadget *);
 int (*wakeup)(struct usb_gadget *);
 int (*set_selfpowered) (struct usb_gadget *, int is_selfpowered);
 int (*vbus_session) (struct usb_gadget *, int is_active);
 int (*vbus_draw) (struct usb_gadget *, unsigned mA);
 int (*pullup) (struct usb_gadget *, int is_on);
 int (*ioctl)(struct usb_gadget *,
    unsigned code, unsigned long param);
 void (*get_config_params)(struct usb_dcd_config_params *);
 int (*udc_start)(struct usb_gadget *,
   struct usb_gadget_driver *);
 int (*udc_stop)(struct usb_gadget *);
 struct usb_ep *(*match_ep)(struct usb_gadget *,
   struct usb_endpoint_descriptor *,
   struct usb_ss_ep_comp_descriptor *);
};
// 硬件底层  gadget.c    定义变量
static const struct usb_gadget_ops dwc2_hsotg_gadget_ops = {
 .get_frame = dwc2_hsotg_gadget_getframe,
 .udc_start  = dwc2_hsotg_udc_start,
 .udc_stop  = dwc2_hsotg_udc_stop,
 .pullup                 = dwc2_hsotg_pullup,
 .vbus_session  = dwc2_hsotg_vbus_session,
 .vbus_draw  = dwc2_hsotg_vbus_draw,
};

/**
 * dwc2_hsotg_udc_start - prepare the udc for work
 * @gadget: The usb gadget state
 * @driver: The usb gadget driver
 *
 * Perform initialization to prepare udc device and driver
 * to work.
 */
static int dwc2_hsotg_udc_start(struct usb_gadget *gadget,
      struct usb_gadget_driver *driver)
{
 struct dwc2_hsotg *hsotg = to_hsotg(gadget);
 unsigned long flags;
 int ret;
 if (!hsotg) {
  pr_err("%s: called with no device\n", __func__);
  return -ENODEV;
 }
 if (!driver) {
  dev_err(hsotg->dev, "%s: no driver\n", __func__);
  return -EINVAL;
 }
 if (driver->max_speed < USB_SPEED_FULL)
  dev_err(hsotg->dev, "%s: bad speed\n", __func__);
 if (!driver->setup) {
  dev_err(hsotg->dev, "%s: missing entry points\n", __func__);
  return -EINVAL;
 }
 WARN_ON(hsotg->driver);
 driver->driver.bus = NULL;
 hsotg->driver = driver;
 hsotg->gadget.dev.of_node = hsotg->dev->of_node;
 hsotg->gadget.speed = USB_SPEED_UNKNOWN;
 if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL) {
  ret = dwc2_lowlevel_hw_enable(hsotg);
  if (ret)
   goto err;
 }
 if (hsotg->dr_mode == USB_DR_MODE_OTG) {
  struct platform_device *pdev = to_platform_device(hsotg->dev);
  if (hsotg->uphy) {
   ret = usb_phy_init(hsotg->uphy);
  } else if (hsotg->plat && hsotg->plat->phy_init) {
   ret = hsotg->plat->phy_init(pdev,
          hsotg->plat->phy_type);
  } else {
   ret = phy_power_on(hsotg->phy);
   if (ret == 0)
    ret = phy_init(hsotg->phy);
  }
  if (ret)
   goto err;
 }
 if (!IS_ERR_OR_NULL(hsotg->uphy))
  otg_set_peripheral(hsotg->uphy->otg, &hsotg->gadget);
 spin_lock_irqsave(&hsotg->lock, flags);
 if (dwc2_hw_is_device(hsotg)) {
  dwc2_hsotg_init(hsotg);
  dwc2_hsotg_core_init_disconnected(hsotg, false);
 }
 hsotg->enabled = 0;
 spin_unlock_irqrestore(&hsotg->lock, flags);
 dev_info(hsotg->dev, "bound driver %s\n", driver->driver.name);
 return 0;
err:
 hsotg->driver = NULL;
 return ret;
}
/**
 * dwc2_hsotg_pullup - connect/disconnect the USB PHY
 * @gadget: The usb gadget state
 * @is_on: Current state of the USB PHY
 *
 * Connect/Disconnect the USB PHY pullup
 */
static int dwc2_hsotg_pullup(struct usb_gadget *gadget, int is_on)
{
 struct dwc2_hsotg *hsotg = to_hsotg(gadget);
 unsigned long flags = 0;
 dev_dbg(hsotg->dev, "%s: is_on: %d op_state: %d\n", __func__, is_on,
   hsotg->op_state);
 /* Don't modify pullup state while in host mode */
 if (hsotg->op_state != OTG_STATE_B_PERIPHERAL) {
  hsotg->enabled = is_on;
  return 0;
 }
 spin_lock_irqsave(&hsotg->lock, flags);
 if (is_on) {
  hsotg->enabled = 1;
  dwc2_hsotg_core_init_disconnected(hsotg, false);
  dwc2_hsotg_core_connect(hsotg);
 } else {
  dwc2_hsotg_core_disconnect(hsotg);
  dwc2_hsotg_disconnect(hsotg);
  hsotg->enabled = 0;
 }
 hsotg->gadget.speed = USB_SPEED_UNKNOWN;
 spin_unlock_irqrestore(&hsotg->lock, flags);
 return 0;
}
static int dwc2_hsotg_vbus_session(struct usb_gadget *gadget, int is_active)
{
 struct dwc2_hsotg *hsotg = to_hsotg(gadget);
 unsigned long flags;
 dev_dbg(hsotg->dev, "%s: is_active: %d\n", __func__, is_active);
 spin_lock_irqsave(&hsotg->lock, flags);
 /*
  * If controller is hibernated, it must exit from hibernation
  * before being initialized / de-initialized
  */
 if (hsotg->lx_state == DWC2_L2)
  dwc2_exit_hibernation(hsotg, false);
 if (is_active) {
  hsotg->op_state = OTG_STATE_B_PERIPHERAL;
  dwc2_hsotg_core_init_disconnected(hsotg, false);
  if (hsotg->enabled)
   dwc2_hsotg_core_connect(hsotg);
 } else {
  dwc2_hsotg_core_disconnect(hsotg);
  dwc2_hsotg_disconnect(hsotg);
 }
 spin_unlock_irqrestore(&hsotg->lock, flags);
 return 0;
}
 
添加到另一个变量里面
/**
 * dwc2_gadget_init - init function for gadget
 * @dwc2: The data structure for the DWC2 driver.
 * @irq: The IRQ number for the controller.
 */
int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq)
//
 hsotg->gadget.max_speed = USB_SPEED_HIGH;
 hsotg->gadget.ops = &dwc2_hsotg_gadget_ops;
 hsotg->gadget.name = dev_name(dev);
 if (hsotg->dr_mode == USB_DR_MODE_OTG)
  hsotg->gadget.is_otg = 1;
 else if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL)
  hsotg->op_state = OTG_STATE_B_PERIPHERAL;
 
  //这里就会跑到上层代码里面
ret = usb_add_gadget_udc(dev, &hsotg->gadget);
if (ret) {
 dwc2_hsotg_ep_free_request(&hsotg->eps_out[0]->ep,
       hsotg->ctrl_req);
 return ret;
}

/**
 * usb_add_gadget_udc_release - adds a new gadget to the udc class driver list
 * @parent: the parent device to this udc. Usually the controller driver's
 * device.
 * @gadget: the gadget to be added to the list.
 * @release: a gadget release function.
 *
 * Returns zero on success, negative errno otherwise.
 */
int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget,
          void (*release)(struct device *dev))
    udc->gadget = gadget;
 gadget->udc = udc;
 mutex_lock(&udc_lock);
 list_add_tail(&udc->list, &udc_list);
 ret = device_add(&udc->dev);
 if (ret)
  goto err4;
 usb_gadget_set_state(gadget, USB_STATE_NOTATTACHED);
 udc->vbus = true;
 mutex_unlock(&udc_lock);
 
 // 最终添加到链表里面去了
static struct class *udc_class;
static LIST_HEAD(udc_list);
  // 每一层 换一个马甲  指针赋值 
 // 上层哪里被调用     中间层
 找到 udc驱动
 方式一:
   gadget/legacy
  
例子:ether.c
static struct usb_composite_driver eth_driver = {
 .name  = "g_ether",
 .dev  = &device_desc,
 .strings = dev_strings,
 .max_speed = USB_SPEED_SUPER,
 .bind  = eth_bind,
 .unbind  = eth_unbind,
};
module_usb_composite_driver(eth_driver);
/**
 * module_usb_composite_driver() - Helper macro for registering a USB gadget
 * composite driver
 * @__usb_composite_driver: usb_composite_driver struct
 *
 * Helper macro for USB gadget composite drivers which do not do anything
 * special in module init/exit. This eliminates a lot of boilerplate. Each
 * module may only use this macro once, and calling it replaces module_init()
 * and module_exit()
 */
#define module_usb_composite_driver(__usb_composite_driver) \
 module_driver(__usb_composite_driver, usb_composite_probe, \
         usb_composite_unregister)
 
int usb_composite_probe(struct usb_composite_driver *driver)
{
 struct usb_gadget_driver *gadget_driver;
 if (!driver || !driver->dev || !driver->bind)
  return -EINVAL;
 if (!driver->name)
  driver->name = "composite";
 driver->gadget_driver = composite_driver_template;
 gadget_driver = &driver->gadget_driver;
 gadget_driver->function =  (char *) driver->name;
 gadget_driver->driver.name = driver->name;
 gadget_driver->max_speed = driver->max_speed;
 return usb_gadget_probe_driver(gadget_driver);
}
EXPORT_SYMBOL_GPL(usb_composite_probe);
int usb_gadget_probe_driver(struct usb_gadget_driver *driver)
{
 struct usb_udc  *udc = NULL;
 int   ret;
 if (!driver || !driver->bind || !driver->setup)
  return -EINVAL;
 mutex_lock(&udc_lock);
 list_for_each_entry(udc, &udc_list, list) {
  /* For now we take the first one */
  if (!udc->driver)
   goto found;
 }
 pr_debug("couldn't find an available UDC\n");
 mutex_unlock(&udc_lock);
 return -ENODEV;
found:
 ret = udc_bind_to_driver(udc, driver);
 mutex_unlock(&udc_lock);
 return ret;
}
EXPORT_SYMBOL_GPL(usb_gadget_probe_driver);
方式二:
使用configfs.c
static ssize_t gadget_dev_desc_UDC_store(struct config_item *item,
  const char *page, size_t len)
{
 struct gadget_info *gi = to_gadget_info(item);
 char *name;
 int ret;
 name = kstrdup(page, GFP_KERNEL);
 if (!name)
  return -ENOMEM;
 if (name[len - 1] == '\n')
  name[len - 1] = '\0';
 mutex_lock(&gi->lock);
 if (!strlen(name) || strcmp(name, "none") == 0) {
  ret = unregister_gadget(gi);
  if (ret)
   goto err;
  kfree(name);
 } else {
  if (gi->udc_name) {
   ret = -EBUSY;
   goto err;
  }
  ret = usb_udc_attach_driver(name, &gi->composite.gadget_driver);
  if (ret)
   goto err;
  gi->udc_name = name;
 }
 mutex_unlock(&gi->lock);
 return len;
err:
 kfree(name);
 mutex_unlock(&gi->lock);
 return ret;
}
 int usb_udc_attach_driver(const char *name, struct usb_gadget_driver *driver)
{
 struct usb_udc *udc = NULL;
 int ret = -ENODEV;
 mutex_lock(&udc_lock);
 list_for_each_entry(udc, &udc_list, list) {
  ret = strcmp(name, dev_name(&udc->dev));
  if (!ret)
   break;
 }
 if (ret) {
  ret = -ENODEV;
  goto out;
 }
 if (udc->driver) {
  ret = -EBUSY;
  goto out;
 }
 ret = udc_bind_to_driver(udc, driver);
out:
 mutex_unlock(&udc_lock);
 return ret;
}
EXPORT_SYMBOL_GPL(usb_udc_attach_driver);

操作UDC:回调函数的调用
 ret = driver->bind(udc->gadget, driver);
 if (ret)
  goto err1;
 ret = usb_gadget_udc_start(udc);
 if (ret) {
  driver->unbind(udc->gadget);
  goto err1;
 }
 usb_udc_connect_control(udc);
 kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE);
 return 0;
 
 // 这个udc变量从驱动里面找到了 
/**
 * usb_gadget_udc_start - tells usb device controller to start up
 * @udc: The UDC to be started
 *
 * This call is issued by the UDC Class driver when it's about
 * to register a gadget driver to the device controller, before
 * calling gadget driver's bind() method.
 *
 * It allows the controller to be powered off until strictly
 * necessary to have it powered on.
 *
 * Returns zero on success, else negative errno.
 */
static inline int usb_gadget_udc_start(struct usb_udc *udc)
{
 return udc->gadget->ops->udc_start(udc->gadget, udc->driver);
}
/**
 * usb_gadget_udc_stop - tells usb device controller we don't need it anymore
 * @gadget: The device we want to stop activity
 * @driver: The driver to unbind from @gadget
 *
 * This call is issued by the UDC Class driver after calling
 * gadget driver's unbind() method.
 *
 * The details are implementation specific, but it can go as
 * far as powering off UDC completely and disable its data
 * line pullups.
 */
static inline void usb_gadget_udc_stop(struct usb_udc *udc)
{
 udc->gadget->ops->udc_stop(udc->gadget);
}
 
 
 
 
一勤天下无难事。
原文地址:https://www.cnblogs.com/nowroot/p/12155178.html