上一节介绍到了 setup函数。setup函数执行具体的枚举的过程。我们先不看这个函数,先看看setup函数是如何与udc的驱动相关联的。这个主要和class driver、usb device framework 如何与 udc 的驱动结合相关。我们以zero gadget为例。
上层的驱动composite_driver等通过函数usb_gadget_register_driver进行注册。
int usb_gadget_register_driver(struct usb_gadget_driver *driver)
{
struct s3c2410_udc *udc = the_controller;
int retval;
/* Hook the driver */
udc->driver = driver;
udc->gadget.dev.driver = &driver->driver;
/* Bind the driver */
if ((retval = device_add(&udc->gadget.dev)) != 0) {
printk(KERN_ERR "Error in device_add() : %d\n",retval);
goto register_error;
}
dprintk(DEBUG_NORMAL, "binding gadget driver '%s'\n",
driver->driver.name);
if ((retval = driver->bind (&udc->gadget)) != 0) {
device_del(&udc->gadget.dev);
goto register_error;
}
/* Enable udc */
s3c2410_udc_enable(udc); 使能udc。这里也非常关键。也就是说在没有class driver时,udc没有使能,因为udc单独工作没有意义。
return 0;
register_error:
udc->driver = NULL;
udc->gadget.dev.driver = NULL;
return retval;
}
上面进行了关联,并且调用了driver的bind函数。对于composite_dirver,这个composite_driver是一个中间层,在它的bind函数中,还会调用zero gadget的bind函数。bind函数的作用就是将driver与udc 相关联。这样,setup函数就可以调到了。
下面看具体的setup的过程。
static int
composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
{
struct usb_composite_dev *cdev = get_gadget_data(gadget);
struct usb_request *req = cdev->req;
int value = -EOPNOTSUPP;
u16 w_index = le16_to_cpu(ctrl->wIndex);
u8 intf = w_index & 0xFF;
u16 w_value = le16_to_cpu(ctrl->wValue);
u16 w_length