gadget之usb_function

雨点打透心脏的1/2处 2022-10-23 00:52 255阅读 0赞

gadget之usb_function

usb_function

  1. /**
  2. * struct usb_function - describes one function of a configuration
  3. * @name: For diagnostics, identifies the function.
  4. * @strings: tables of strings, keyed by identifiers assigned during bind()
  5. * and by language IDs provided in control requests
  6. * @fs_descriptors: Table of full (or low) speed descriptors, using interface and
  7. * string identifiers assigned during @bind(). If this pointer is null,
  8. * the function will not be available at full speed (or at low speed).
  9. * @hs_descriptors: Table of high speed descriptors, using interface and
  10. * string identifiers assigned during @bind(). If this pointer is null,
  11. * the function will not be available at high speed.
  12. * @ss_descriptors: Table of super speed descriptors, using interface and
  13. * string identifiers assigned during @bind(). If this
  14. * pointer is null after initiation, the function will not
  15. * be available at super speed.
  16. * @ssp_descriptors: Table of super speed plus descriptors, using
  17. * interface and string identifiers assigned during @bind(). If
  18. * this pointer is null after initiation, the function will not
  19. * be available at super speed plus.
  20. * @config: assigned when @usb_add_function() is called; this is the
  21. * configuration with which this function is associated.
  22. * @os_desc_table: Table of (interface id, os descriptors) pairs. The function
  23. * can expose more than one interface. If an interface is a member of
  24. * an IAD, only the first interface of IAD has its entry in the table.
  25. * @os_desc_n: Number of entries in os_desc_table
  26. * @bind: Before the gadget can register, all of its functions bind() to the
  27. * available resources including string and interface identifiers used
  28. * in interface or class descriptors; endpoints; I/O buffers; and so on.
  29. * @unbind: Reverses @bind; called as a side effect of unregistering the
  30. * driver which added this function.
  31. * @free_func: free the struct usb_function.
  32. * @mod: (internal) points to the module that created this structure.
  33. * @set_alt: (REQUIRED) Reconfigures altsettings; function drivers may
  34. * initialize usb_ep.driver data at this time (when it is used).
  35. * Note that setting an interface to its current altsetting resets
  36. * interface state, and that all interfaces have a disabled state.
  37. * @get_alt: Returns the active altsetting. If this is not provided,
  38. * then only altsetting zero is supported.
  39. * @disable: (REQUIRED) Indicates the function should be disabled. Reasons
  40. * include host resetting or reconfiguring the gadget, and disconnection.
  41. * @setup: Used for interface-specific control requests.
  42. * @req_match: Tests if a given class request can be handled by this function.
  43. * @suspend: Notifies functions when the host stops sending USB traffic.
  44. * @resume: Notifies functions when the host restarts USB traffic.
  45. * @get_status: Returns function status as a reply to
  46. * GetStatus() request when the recipient is Interface.
  47. * @func_suspend: callback to be called when
  48. * SetFeature(FUNCTION_SUSPEND) is reseived
  49. *
  50. * A single USB function uses one or more interfaces, and should in most
  51. * cases support operation at both full and high speeds. Each function is
  52. * associated by @usb_add_function() with a one configuration; that function
  53. * causes @bind() to be called so resources can be allocated as part of
  54. * setting up a gadget driver. Those resources include endpoints, which
  55. * should be allocated using @usb_ep_autoconfig().
  56. *
  57. * To support dual speed operation, a function driver provides descriptors
  58. * for both high and full speed operation. Except in rare cases that don't
  59. * involve bulk endpoints, each speed needs different endpoint descriptors.
  60. *
  61. * Function drivers choose their own strategies for managing instance data.
  62. * The simplest strategy just declares it "static', which means the function
  63. * can only be activated once. If the function needs to be exposed in more
  64. * than one configuration at a given speed, it needs to support multiple
  65. * usb_function structures (one for each configuration).
  66. *
  67. * A more complex strategy might encapsulate a @usb_function structure inside
  68. * a driver-specific instance structure to allows multiple activations. An
  69. * example of multiple activations might be a CDC ACM function that supports
  70. * two or more distinct instances within the same configuration, providing
  71. * several independent logical data links to a USB host.
  72. */
  73. //描述一个配置的一个功能
  74. struct usb_function {
  75. const char *name;//功能名称,匹配时需要用到
  76. struct usb_gadget_strings **strings;//string数组,通过bind中分配的id访问
  77. struct usb_descriptor_header **fs_descriptors;//全速和低速的描述符表,用于bind中分配的接口描述符和string描述符
  78. struct usb_descriptor_header **hs_descriptors;//高速描述符表
  79. struct usb_descriptor_header **ss_descriptors;
  80. struct usb_descriptor_header **ssp_descriptors;
  81. struct usb_configuration *config;//调用usb_add_function()函数赋值,是这个功能关联的配置描述符
  82. struct usb_os_desc_table *os_desc_table;
  83. unsigned os_desc_n;
  84. /* REVISIT: bind() functions can be marked __init, which
  85. * makes trouble for section mismatch analysis. See if
  86. * we can't restructure things to avoid mismatching.
  87. * Related: unbind() may kfree() but bind() won't...
  88. */
  89. /* configuration management: bind/unbind */
  90. int (*bind)(struct usb_configuration *,
  91. struct usb_function *);/*unbind的逆操作*/
  92. void (*unbind)(struct usb_configuration *,
  93. struct usb_function *);
  94. void (*free_func)(struct usb_function *f);
  95. struct module *mod;
  96. /* runtime state management */
  97. int (*set_alt)(struct usb_function *,
  98. unsigned interface, unsigned alt);
  99. int (*get_alt)(struct usb_function *,
  100. unsigned interface);
  101. void (*disable)(struct usb_function *);
  102. int (*setup)(struct usb_function *,
  103. const struct usb_ctrlrequest *);
  104. bool (*req_match)(struct usb_function *,
  105. const struct usb_ctrlrequest *,
  106. bool config0);
  107. void (*suspend)(struct usb_function *);
  108. void (*resume)(struct usb_function *);
  109. /* USB 3.0 additions */
  110. int (*get_status)(struct usb_function *);
  111. int (*func_suspend)(struct usb_function *,
  112. u8 suspend_opt);
  113. /* private: */
  114. /* internals */
  115. struct list_head list;
  116. DECLARE_BITMAP(endpoints, 32);
  117. const struct usb_function_instance *fi;
  118. unsigned int bind_deactivated:1;
  119. };

usb_function_driver

  1. struct usb_function_driver {
  2. const char *name;//usb_function_driver的name,如:"acm"
  3. struct module *mod;
  4. struct list_head list;
  5. struct usb_function_instance *(*alloc_inst)(void);//alloc usb_function_instance
  6. struct usb_function *(*alloc_func)(struct usb_function_instance *inst);//alloc usb_function
  7. };

创建usb_function_driver
源码:include/linux/usb/composite.h

  1. #define DECLARE_USB_FUNCTION(_name, _inst_alloc, _func_alloc) \
  2. static struct usb_function_driver _name ## usb_func = { \
  3. .name = __stringify(_name), \
  4. .mod = THIS_MODULE, \
  5. .alloc_inst = _inst_alloc, \
  6. .alloc_func = _func_alloc, \
  7. }; \
  8. MODULE_ALIAS("usbfunc:"__stringify(_name));

注册usb_function_driver
源码:include/linux/usb/composite.h

  1. #define DECLARE_USB_FUNCTION_INIT(_name, _inst_alloc, _func_alloc) \
  2. DECLARE_USB_FUNCTION(_name, _inst_alloc, _func_alloc) \
  3. static int __init _name ## mod_init(void) \
  4. { \
  5. return usb_function_register(&_name ## usb_func); \
  6. } \
  7. static void __exit _name ## mod_exit(void) \
  8. { \
  9. usb_function_unregister(&_name ## usb_func); \
  10. } \
  11. module_init(_name ## mod_init); \
  12. module_exit(_name ## mod_exit)

源码:drivers/usb/gadget/functions.c

  1. int usb_function_register(struct usb_function_driver *newf)
  2. {
  3. struct usb_function_driver *fd;
  4. int ret;
  5. ret = -EEXIST;
  6. mutex_lock(&func_lock);
  7. //遍历func_list链表,根据func_name判断该func是否注册
  8. list_for_each_entry(fd, &func_list, list) {
  9. if (!strcmp(fd->name, newf->name))
  10. goto out;
  11. }
  12. ret = 0;
  13. //将new_func添加到func_list中
  14. list_add_tail(&newf->list, &func_list);
  15. out:
  16. mutex_unlock(&func_lock);
  17. return ret;
  18. }
  19. EXPORT_SYMBOL_GPL(usb_function_register);
  20. void usb_function_unregister(struct usb_function_driver *fd)
  21. {
  22. mutex_lock(&func_lock);
  23. list_del(&fd->list);
  24. mutex_unlock(&func_lock);
  25. }
  26. EXPORT_SYMBOL_GPL(usb_function_unregister);

示例:以acm function为例说明,如下:

源码:drivers/usb/gadget/function/f_acm.c

  1. DECLARE_USB_FUNCTION_INIT(acm, acm_alloc_instance, acm_alloc_func);

usb_function_instance

源码:include/linux/usb/composite.h

  1. struct usb_function_instance {
  2. struct config_group group;
  3. struct list_head cfs_list;
  4. struct usb_function_driver *fd;
  5. int (*set_inst_name)(struct usb_function_instance *inst,
  6. const char *name);
  7. void (*free_func_inst)(struct usb_function_instance *inst);
  8. };

发表评论

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

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

相关阅读