gadget驱动框架(二)

快来打我* 2022-10-23 00:50 77阅读 0赞

gadget驱动框架(二)

usb_composite_driver的创建于注册

源码:drivers/usb/legacy/serial.c

  1. //创建usb_composite_driver
  2. static struct usb_composite_driver gserial_driver = {
  3. .name = "g_serial",
  4. .dev = &device_desc,
  5. .strings = dev_strings,
  6. .max_speed = USB_SPEED_SUPER,
  7. .bind = gs_bind,
  8. .unbind = gs_unbind,
  9. };
  10. static int __init init(void)
  11. {
  12. /* We *could* export two configs; that'd be much cleaner...
  13. * but neither of these product IDs was defined that way.
  14. */bConfigurationValueclasspid
  15. //初始化
  16. if (use_acm) {
  17. serial_config_driver.label = "CDC ACM config";
  18. serial_config_driver.bConfigurationValue = 2;
  19. device_desc.bDeviceClass = USB_CLASS_COMM;
  20. device_desc.idProduct =
  21. cpu_to_le16(GS_CDC_PRODUCT_ID);
  22. } else if (use_obex) {
  23. serial_config_driver.label = "CDC OBEX config";
  24. serial_config_driver.bConfigurationValue = 3;
  25. device_desc.bDeviceClass = USB_CLASS_COMM;
  26. device_desc.idProduct =
  27. cpu_to_le16(GS_CDC_OBEX_PRODUCT_ID);
  28. } else {
  29. serial_config_driver.label = "Generic Serial config";
  30. serial_config_driver.bConfigurationValue = 1;
  31. device_desc.bDeviceClass = USB_CLASS_VENDOR_SPEC;
  32. device_desc.idProduct =
  33. cpu_to_le16(GS_PRODUCT_ID);
  34. }
  35. strings_dev[STRING_DESCRIPTION_IDX].s = serial_config_driver.label;
  36. //注册usb_composite_driver与usb_composite_dev
  37. return usb_composite_probe(&gserial_driver);
  38. }
  39. module_init(init);
  40. static void __exit cleanup(void)
  41. {
  42. usb_composite_unregister(&gserial_driver);
  43. }
  44. module_exit(cleanup);

usb_gadget_driver的创建与注册

  1. //创建usb_gadget_driver
  2. static const struct usb_gadget_driver composite_driver_template = {
  3. .bind = composite_bind,
  4. .unbind = composite_unbind,
  5. .setup = composite_setup,
  6. .reset = composite_disconnect,
  7. .disconnect = composite_disconnect,
  8. .suspend = composite_suspend,
  9. .resume = composite_resume,
  10. .driver = {
  11. .owner = THIS_MODULE,
  12. },
  13. };
  14. int usb_composite_probe(struct usb_composite_driver *driver)
  15. {
  16. struct usb_gadget_driver *gadget_driver;
  17. if (!driver || !driver->dev || !driver->bind)
  18. return -EINVAL;
  19. if (!driver->name)
  20. driver->name = "composite";
  21. driver->gadget_driver = composite_driver_template;
  22. gadget_driver = &driver->gadget_driver;
  23. gadget_driver->function = (char *) driver->name;
  24. gadget_driver->driver.name = driver->name;
  25. gadget_driver->max_speed = driver->max_speed;
  26. //注册usb_gadget_driver
  27. return usb_gadget_probe_driver(gadget_driver);
  28. }
  29. EXPORT_SYMBOL_GPL(usb_composite_probe);
  30. //注册usb_gadget_driver
  31. int usb_gadget_probe_driver(struct usb_gadget_driver *driver)
  32. {
  33. struct usb_udc *udc = NULL;
  34. int ret = -ENODEV;
  35. if (!driver || !driver->bind || !driver->setup)
  36. return -EINVAL;
  37. mutex_lock(&udc_lock);
  38. if (driver->udc_name) {
  39. list_for_each_entry(udc, &udc_list, list) {
  40. ret = strcmp(driver->udc_name, dev_name(&udc->dev));
  41. if (!ret)
  42. break;
  43. }
  44. if (ret)
  45. ret = -ENODEV;
  46. else if (udc->driver)
  47. ret = -EBUSY;
  48. else
  49. goto found;
  50. } else {
  51. list_for_each_entry(udc, &udc_list, list) {
  52. /* For now we take the first one */
  53. if (!udc->driver)
  54. goto found;
  55. }
  56. }
  57. //无udc设备,则将usb_gadget_driver添加到gadget_driver_pending_list链表
  58. if (!driver->match_existing_only) {
  59. list_add_tail(&driver->pending, &gadget_driver_pending_list);
  60. pr_info("udc-core: couldn't find an available UDC - added [%s] to list of pending drivers\n",
  61. driver->function);
  62. ret = 0;
  63. }
  64. mutex_unlock(&udc_lock);
  65. return ret;
  66. found:
  67. //udc设备与usb_gadget_driver绑定
  68. ret = udc_bind_to_driver(udc, driver);
  69. mutex_unlock(&udc_lock);
  70. return ret;
  71. }

usb_gadget的创建及注册

源码:linux4.19.123-drivers/usb/gadget/udc/s3c2410_udc.c

  1. static const struct usb_ep_ops s3c2410_ep_ops = {
  2. .enable = s3c2410_udc_ep_enable,
  3. .disable = s3c2410_udc_ep_disable,
  4. .alloc_request = s3c2410_udc_alloc_request,
  5. .free_request = s3c2410_udc_free_request,
  6. .queue = s3c2410_udc_queue,
  7. .dequeue = s3c2410_udc_dequeue,
  8. .set_halt = s3c2410_udc_set_halt,
  9. };
  10. static const struct usb_gadget_ops s3c2410_ops = {
  11. .get_frame = s3c2410_udc_get_frame,
  12. .wakeup = s3c2410_udc_wakeup,
  13. .set_selfpowered = s3c2410_udc_set_selfpowered,
  14. .pullup = s3c2410_udc_pullup,
  15. .vbus_session = s3c2410_udc_vbus_session,
  16. .vbus_draw = s3c2410_vbus_draw,
  17. .udc_start = s3c2410_udc_start,
  18. .udc_stop = s3c2410_udc_stop,
  19. };
  20. /*---------------------------------------------------------------------------*/
  21. static struct s3c2410_udc memory = {
  22. //usb_gadget初始化
  23. .gadget = {
  24. .ops = &s3c2410_ops,
  25. .ep0 = &memory.ep[0].ep,
  26. .name = gadget_name,
  27. .dev = {
  28. .init_name = "gadget",
  29. },
  30. },
  31. /* control endpoint */
  32. .ep[0] = {
  33. .num = 0,
  34. .ep = {
  35. .name = ep0name,
  36. .ops = &s3c2410_ep_ops,
  37. .maxpacket = EP0_FIFO_SIZE,
  38. .caps = USB_EP_CAPS(USB_EP_CAPS_TYPE_CONTROL,
  39. USB_EP_CAPS_DIR_ALL),
  40. },
  41. .dev = &memory,
  42. },
  43. /* first group of endpoints */
  44. .ep[1] = {
  45. .num = 1,
  46. .ep = {
  47. .name = "ep1-bulk",
  48. .ops = &s3c2410_ep_ops,
  49. .maxpacket = EP_FIFO_SIZE,
  50. .caps = USB_EP_CAPS(USB_EP_CAPS_TYPE_BULK,
  51. USB_EP_CAPS_DIR_ALL),
  52. },
  53. .dev = &memory,
  54. .fifo_size = EP_FIFO_SIZE,
  55. .bEndpointAddress = 1,
  56. .bmAttributes = USB_ENDPOINT_XFER_BULK,
  57. },
  58. .ep[2] = {
  59. .num = 2,
  60. .ep = {
  61. .name = "ep2-bulk",
  62. .ops = &s3c2410_ep_ops,
  63. .maxpacket = EP_FIFO_SIZE,
  64. .caps = USB_EP_CAPS(USB_EP_CAPS_TYPE_BULK,
  65. USB_EP_CAPS_DIR_ALL),
  66. },
  67. .dev = &memory,
  68. .fifo_size = EP_FIFO_SIZE,
  69. .bEndpointAddress = 2,
  70. .bmAttributes = USB_ENDPOINT_XFER_BULK,
  71. },
  72. .ep[3] = {
  73. .num = 3,
  74. .ep = {
  75. .name = "ep3-bulk",
  76. .ops = &s3c2410_ep_ops,
  77. .maxpacket = EP_FIFO_SIZE,
  78. .caps = USB_EP_CAPS(USB_EP_CAPS_TYPE_BULK,
  79. USB_EP_CAPS_DIR_ALL),
  80. },
  81. .dev = &memory,
  82. .fifo_size = EP_FIFO_SIZE,
  83. .bEndpointAddress = 3,
  84. .bmAttributes = USB_ENDPOINT_XFER_BULK,
  85. },
  86. .ep[4] = {
  87. .num = 4,
  88. .ep = {
  89. .name = "ep4-bulk",
  90. .ops = &s3c2410_ep_ops,
  91. .maxpacket = EP_FIFO_SIZE,
  92. .caps = USB_EP_CAPS(USB_EP_CAPS_TYPE_BULK,
  93. USB_EP_CAPS_DIR_ALL),
  94. },
  95. .dev = &memory,
  96. .fifo_size = EP_FIFO_SIZE,
  97. .bEndpointAddress = 4,
  98. .bmAttributes = USB_ENDPOINT_XFER_BULK,
  99. }
  100. };
  101. /*
  102. * probe - binds to the platform device
  103. */
  104. static int s3c2410_udc_probe(struct platform_device *pdev)
  105. {
  106. struct s3c2410_udc *udc = &memory;
  107. struct device *dev = &pdev->dev;
  108. int retval;
  109. int irq;
  110. dev_dbg(dev, "%s()\n", __func__);
  111. ......
  112. //创建/注册udc,注册usb_gadget
  113. retval = usb_add_gadget_udc(&pdev->dev, &udc->gadget);
  114. if (retval)
  115. goto err_add_udc;
  116. ......
  117. return 0;
  118. err_add_udc:
  119. if (udc_info && !udc_info->udc_command &&
  120. gpio_is_valid(udc_info->pullup_pin))
  121. gpio_free(udc_info->pullup_pin);
  122. err_vbus_irq:
  123. if (udc_info && udc_info->vbus_pin > 0)
  124. free_irq(gpio_to_irq(udc_info->vbus_pin), udc);
  125. err_gpio_claim:
  126. if (udc_info && udc_info->vbus_pin > 0)
  127. gpio_free(udc_info->vbus_pin);
  128. err_int:
  129. free_irq(IRQ_USBD, udc);
  130. err_map:
  131. iounmap(base_addr);
  132. err_mem:
  133. release_mem_region(rsrc_start, rsrc_len);
  134. return retval;
  135. }

usb_udc的创建及注册

源码:linux-4.19.123-drivers/usb/gadget/udc/core.c

  1. int usb_add_gadget_udc(struct device *parent, struct usb_gadget *gadget)
  2. {
  3. return usb_add_gadget_udc_release(parent, gadget, NULL);
  4. }
  5. EXPORT_SYMBOL_GPL(usb_add_gadget_udc);
  6. /**
  7. * usb_add_gadget_udc_release - adds a new gadget to the udc class driver list
  8. * @parent: the parent device to this udc. Usually the controller driver's
  9. * device.
  10. * @gadget: the gadget to be added to the list.
  11. * @release: a gadget release function.
  12. *
  13. * Returns zero on success, negative errno otherwise.
  14. * Calls the gadget release function in the latter case.
  15. */
  16. int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget,
  17. void (*release)(struct device *dev))
  18. {
  19. struct usb_udc *udc;
  20. int ret = -ENOMEM;
  21. dev_set_name(&gadget->dev, "gadget");
  22. INIT_WORK(&gadget->work, usb_gadget_state_work);
  23. gadget->dev.parent = parent;
  24. if (release)
  25. gadget->dev.release = release;
  26. else
  27. gadget->dev.release = usb_udc_nop_release;
  28. device_initialize(&gadget->dev);
  29. //创建usb_udc
  30. udc = kzalloc(sizeof(*udc), GFP_KERNEL);
  31. if (!udc)
  32. goto err_put_gadget;
  33. device_initialize(&udc->dev);
  34. udc->dev.release = usb_udc_release;
  35. udc->dev.class = udc_class;
  36. udc->dev.groups = usb_udc_attr_groups;
  37. udc->dev.parent = parent;
  38. ret = dev_set_name(&udc->dev, "%s", kobject_name(&parent->kobj));
  39. if (ret)
  40. goto err_put_udc;
  41. ret = device_add(&gadget->dev);
  42. if (ret)
  43. goto err_put_udc;
  44. udc->gadget = gadget;
  45. gadget->udc = udc;
  46. mutex_lock(&udc_lock);
  47. //将新创建的usb_udc添加到udc_list链表中
  48. list_add_tail(&udc->list, &udc_list);
  49. ret = device_add(&udc->dev);
  50. if (ret)
  51. goto err_unlist_udc;
  52. usb_gadget_set_state(gadget, USB_STATE_NOTATTACHED);
  53. udc->vbus = true;
  54. /* pick up one of pending gadget drivers */
  55. ret = check_pending_gadget_drivers(udc);
  56. if (ret)
  57. goto err_del_udc;
  58. mutex_unlock(&udc_lock);
  59. return 0;
  60. err_del_udc:
  61. device_del(&udc->dev);
  62. err_unlist_udc:
  63. list_del(&udc->list);
  64. mutex_unlock(&udc_lock);
  65. device_del(&gadget->dev);
  66. err_put_udc:
  67. put_device(&udc->dev);
  68. err_put_gadget:
  69. put_device(&gadget->dev);
  70. return ret;
  71. }

小结

至此,已完成usb_gadget_driver、usb_composite_driver、usb_gadget、usb_udc等几个核心结构体的创建及注册。后面将介绍usb_composite_dev等的创建及注册,以及usb_gadget_driver与usb_udc的绑定过程。

发表评论

表情:
评论列表 (有 0 条评论,77人围观)

还没有评论,来说两句吧...

相关阅读