You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

usbhub.h 7.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. #ifndef _USBHUB_H
  2. #define _USBHUB_H
  3. /** @file
  4. *
  5. * USB hubs
  6. *
  7. */
  8. FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  9. #include <ipxe/usb.h>
  10. #include <ipxe/list.h>
  11. #include <ipxe/process.h>
  12. /** Request recipient is a port */
  13. #define USB_HUB_RECIP_PORT ( 3 << 0 )
  14. /** A basic USB hub descriptor */
  15. struct usb_hub_descriptor_basic {
  16. /** Descriptor header */
  17. struct usb_descriptor_header header;
  18. /** Number of ports */
  19. uint8_t ports;
  20. /** Characteristics */
  21. uint16_t characteristics;
  22. /** Power-on delay (in 2ms intervals */
  23. uint8_t delay;
  24. /** Controller current (in mA) */
  25. uint8_t current;
  26. } __attribute__ (( packed ));
  27. /** A basic USB hub descriptor */
  28. #define USB_HUB_DESCRIPTOR 41
  29. /** An enhanced USB hub descriptor */
  30. struct usb_hub_descriptor_enhanced {
  31. /** Basic USB hub descriptor */
  32. struct usb_hub_descriptor_basic basic;
  33. /** Header decode latency */
  34. uint8_t latency;
  35. /** Maximum delay */
  36. uint16_t delay;
  37. /** Removable device bitmask */
  38. uint16_t removable;
  39. } __attribute__ (( packed ));
  40. /** An enhanced USB hub descriptor */
  41. #define USB_HUB_DESCRIPTOR_ENHANCED 42
  42. /** A USB hub descriptor */
  43. union usb_hub_descriptor {
  44. /** Descriptor header */
  45. struct usb_descriptor_header header;
  46. /** Basic hub descriptor */
  47. struct usb_hub_descriptor_basic basic;
  48. /** Enhanced hub descriptor */
  49. struct usb_hub_descriptor_enhanced enhanced;
  50. } __attribute__ (( packed ));
  51. /** Port status */
  52. struct usb_hub_port_status {
  53. /** Current status */
  54. uint16_t current;
  55. /** Changed status */
  56. uint16_t changed;
  57. } __attribute__ (( packed ));
  58. /** Current connect status feature */
  59. #define USB_HUB_PORT_CONNECTION 0
  60. /** Port enabled/disabled feature */
  61. #define USB_HUB_PORT_ENABLE 1
  62. /** Port reset feature */
  63. #define USB_HUB_PORT_RESET 4
  64. /** Port power feature */
  65. #define USB_HUB_PORT_POWER 8
  66. /** Low-speed device attached */
  67. #define USB_HUB_PORT_LOW_SPEED 9
  68. /** High-speed device attached */
  69. #define USB_HUB_PORT_HIGH_SPEED 10
  70. /** Connect status changed */
  71. #define USB_HUB_C_PORT_CONNECTION 16
  72. /** Port enable/disable changed */
  73. #define USB_HUB_C_PORT_ENABLE 17
  74. /** Suspend changed */
  75. #define USB_HUB_C_PORT_SUSPEND 18
  76. /** Over-current indicator changed */
  77. #define USB_HUB_C_PORT_OVER_CURRENT 19
  78. /** Reset changed */
  79. #define USB_HUB_C_PORT_RESET 20
  80. /** Link state changed */
  81. #define USB_HUB_C_PORT_LINK_STATE 25
  82. /** Configuration error */
  83. #define USB_HUB_C_PORT_CONFIG_ERROR 26
  84. /** Calculate feature from change bit number */
  85. #define USB_HUB_C_FEATURE( bit ) ( 16 + (bit) )
  86. /** USB features */
  87. #define USB_HUB_FEATURES \
  88. ( ( 1 << USB_HUB_C_PORT_CONNECTION ) | \
  89. ( 1 << USB_HUB_C_PORT_ENABLE ) | \
  90. ( 1 << USB_HUB_C_PORT_SUSPEND ) | \
  91. ( 1 << USB_HUB_C_PORT_OVER_CURRENT ) | \
  92. ( 1 << USB_HUB_C_PORT_RESET ) )
  93. /** USB features for enhanced hubs */
  94. #define USB_HUB_FEATURES_ENHANCED \
  95. ( ( 1 << USB_HUB_C_PORT_CONNECTION ) | \
  96. ( 1 << USB_HUB_C_PORT_OVER_CURRENT ) | \
  97. ( 1 << USB_HUB_C_PORT_RESET ) | \
  98. ( 1 << USB_HUB_C_PORT_LINK_STATE ) | \
  99. ( 1 << USB_HUB_C_PORT_CONFIG_ERROR ) )
  100. /** Set hub depth */
  101. #define USB_HUB_SET_HUB_DEPTH \
  102. ( USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_DEVICE | \
  103. USB_REQUEST_TYPE ( 12 ) )
  104. /** Clear transaction translator buffer */
  105. #define USB_HUB_CLEAR_TT_BUFFER \
  106. ( USB_DIR_OUT | USB_TYPE_CLASS | USB_HUB_RECIP_PORT | \
  107. USB_REQUEST_TYPE ( 8 ) )
  108. /**
  109. * Get hub descriptor
  110. *
  111. * @v usb USB device
  112. * @v enhanced Hub is an enhanced hub
  113. * @v data Hub descriptor to fill in
  114. * @ret rc Return status code
  115. */
  116. static inline __attribute__ (( always_inline )) int
  117. usb_hub_get_descriptor ( struct usb_device *usb, int enhanced,
  118. union usb_hub_descriptor *data ) {
  119. unsigned int desc;
  120. size_t len;
  121. /* Determine descriptor type and length */
  122. desc = ( enhanced ? USB_HUB_DESCRIPTOR_ENHANCED : USB_HUB_DESCRIPTOR );
  123. len = ( enhanced ? sizeof ( data->enhanced ) : sizeof ( data->basic ) );
  124. return usb_get_descriptor ( usb, USB_TYPE_CLASS, desc, 0, 0,
  125. &data->header, len );
  126. }
  127. /**
  128. * Get port status
  129. *
  130. * @v usb USB device
  131. * @v port Port address
  132. * @v status Port status descriptor to fill in
  133. * @ret rc Return status code
  134. */
  135. static inline __attribute__ (( always_inline )) int
  136. usb_hub_get_port_status ( struct usb_device *usb, unsigned int port,
  137. struct usb_hub_port_status *status ) {
  138. return usb_get_status ( usb, ( USB_TYPE_CLASS | USB_HUB_RECIP_PORT ),
  139. port, status, sizeof ( *status ) );
  140. }
  141. /**
  142. * Clear port feature
  143. *
  144. * @v usb USB device
  145. * @v port Port address
  146. * @v feature Feature to clear
  147. * @v index Index (when clearing a port indicator)
  148. * @ret rc Return status code
  149. */
  150. static inline __attribute__ (( always_inline )) int
  151. usb_hub_clear_port_feature ( struct usb_device *usb, unsigned int port,
  152. unsigned int feature, unsigned int index ) {
  153. return usb_clear_feature ( usb, ( USB_TYPE_CLASS | USB_HUB_RECIP_PORT ),
  154. feature, ( ( index << 8 ) | port ) );
  155. }
  156. /**
  157. * Set port feature
  158. *
  159. * @v usb USB device
  160. * @v port Port address
  161. * @v feature Feature to clear
  162. * @v index Index (when clearing a port indicator)
  163. * @ret rc Return status code
  164. */
  165. static inline __attribute__ (( always_inline )) int
  166. usb_hub_set_port_feature ( struct usb_device *usb, unsigned int port,
  167. unsigned int feature, unsigned int index ) {
  168. return usb_set_feature ( usb, ( USB_TYPE_CLASS | USB_HUB_RECIP_PORT ),
  169. feature, ( ( index << 8 ) | port ) );
  170. }
  171. /**
  172. * Set hub depth
  173. *
  174. * @v usb USB device
  175. * @v depth Hub depth
  176. * @ret rc Return status code
  177. */
  178. static inline __attribute__ (( always_inline )) int
  179. usb_hub_set_hub_depth ( struct usb_device *usb, unsigned int depth ) {
  180. return usb_control ( usb, USB_HUB_SET_HUB_DEPTH, depth, 0, NULL, 0 );
  181. }
  182. /**
  183. * Clear transaction translator buffer
  184. *
  185. * @v usb USB device
  186. * @v device Device address
  187. * @v endpoint Endpoint address
  188. * @v attributes Endpoint attributes
  189. * @v tt_port Transaction translator port (or 1 for single-TT hubs)
  190. * @ret rc Return status code
  191. */
  192. static inline __attribute__ (( always_inline )) int
  193. usb_hub_clear_tt_buffer ( struct usb_device *usb, unsigned int device,
  194. unsigned int endpoint, unsigned int attributes,
  195. unsigned int tt_port ) {
  196. unsigned int value;
  197. /* Calculate value */
  198. value = ( ( ( endpoint & USB_ENDPOINT_MAX ) << 0 ) | ( device << 4 ) |
  199. ( ( attributes & USB_ENDPOINT_ATTR_TYPE_MASK ) << 11 ) |
  200. ( ( endpoint & USB_ENDPOINT_IN ) << 8 ) );
  201. return usb_control ( usb, USB_HUB_CLEAR_TT_BUFFER, value,
  202. tt_port, NULL, 0 );
  203. }
  204. /** Transaction translator port value for single-TT hubs */
  205. #define USB_HUB_TT_SINGLE 1
  206. /** A USB hub device */
  207. struct usb_hub_device {
  208. /** Name */
  209. const char *name;
  210. /** USB device */
  211. struct usb_device *usb;
  212. /** USB hub */
  213. struct usb_hub *hub;
  214. /** Features */
  215. unsigned int features;
  216. /** Flags */
  217. unsigned int flags;
  218. /** Interrupt endpoint */
  219. struct usb_endpoint intr;
  220. /** Interrupt endpoint refill process */
  221. struct process refill;
  222. };
  223. /** Hub requires additional settling delay */
  224. #define USB_HUB_SLOW_START 0x0001
  225. /** Additional setting delay for out-of-spec hubs */
  226. #define USB_HUB_SLOW_START_DELAY_MS 500
  227. /** Interrupt ring fill level
  228. *
  229. * This is a policy decision.
  230. */
  231. #define USB_HUB_INTR_FILL 4
  232. /** Maximum time to wait for port to become enabled
  233. *
  234. * This is a policy decision.
  235. */
  236. #define USB_HUB_ENABLE_MAX_WAIT_MS 100
  237. #endif /* _USBHUB_H */