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 6.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. #ifndef _USBHUB_H
  2. #define _USBHUB_H
  3. /** @file
  4. *
  5. * USB hubs
  6. *
  7. */
  8. FILE_LICENCE ( GPL2_OR_LATER );
  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. /**
  105. * Get hub descriptor
  106. *
  107. * @v usb USB device
  108. * @v enhanced Hub is an enhanced hub
  109. * @v data Hub descriptor to fill in
  110. * @ret rc Return status code
  111. */
  112. static inline __attribute__ (( always_inline )) int
  113. usb_hub_get_descriptor ( struct usb_device *usb, int enhanced,
  114. union usb_hub_descriptor *data ) {
  115. unsigned int desc;
  116. size_t len;
  117. /* Determine descriptor type and length */
  118. desc = ( enhanced ? USB_HUB_DESCRIPTOR_ENHANCED : USB_HUB_DESCRIPTOR );
  119. len = ( enhanced ? sizeof ( data->enhanced ) : sizeof ( data->basic ) );
  120. return usb_get_descriptor ( usb, USB_TYPE_CLASS, desc, 0, 0,
  121. &data->header, len );
  122. }
  123. /**
  124. * Get port status
  125. *
  126. * @v usb USB device
  127. * @v port Port address
  128. * @v status Port status descriptor to fill in
  129. * @ret rc Return status code
  130. */
  131. static inline __attribute__ (( always_inline )) int
  132. usb_hub_get_port_status ( struct usb_device *usb, unsigned int port,
  133. struct usb_hub_port_status *status ) {
  134. return usb_get_status ( usb, ( USB_TYPE_CLASS | USB_HUB_RECIP_PORT ),
  135. port, status, sizeof ( *status ) );
  136. }
  137. /**
  138. * Clear port feature
  139. *
  140. * @v usb USB device
  141. * @v port Port address
  142. * @v feature Feature to clear
  143. * @v index Index (when clearing a port indicator)
  144. * @ret rc Return status code
  145. */
  146. static inline __attribute__ (( always_inline )) int
  147. usb_hub_clear_port_feature ( struct usb_device *usb, unsigned int port,
  148. unsigned int feature, unsigned int index ) {
  149. return usb_clear_feature ( usb, ( USB_TYPE_CLASS | USB_HUB_RECIP_PORT ),
  150. feature, ( ( index << 8 ) | port ) );
  151. }
  152. /**
  153. * Set port feature
  154. *
  155. * @v usb USB device
  156. * @v port Port address
  157. * @v feature Feature to clear
  158. * @v index Index (when clearing a port indicator)
  159. * @ret rc Return status code
  160. */
  161. static inline __attribute__ (( always_inline )) int
  162. usb_hub_set_port_feature ( struct usb_device *usb, unsigned int port,
  163. unsigned int feature, unsigned int index ) {
  164. return usb_set_feature ( usb, ( USB_TYPE_CLASS | USB_HUB_RECIP_PORT ),
  165. feature, ( ( index << 8 ) | port ) );
  166. }
  167. /**
  168. * Set hub depth
  169. *
  170. * @v usb USB device
  171. * @v depth Hub depth
  172. * @ret rc Return status code
  173. */
  174. static inline __attribute__ (( always_inline )) int
  175. usb_hub_set_hub_depth ( struct usb_device *usb, unsigned int depth ) {
  176. return usb_control ( usb, USB_HUB_SET_HUB_DEPTH, depth, 0, NULL, 0 );
  177. }
  178. /** A USB hub device */
  179. struct usb_hub_device {
  180. /** Name */
  181. const char *name;
  182. /** USB device */
  183. struct usb_device *usb;
  184. /** USB hub */
  185. struct usb_hub *hub;
  186. /** Features */
  187. unsigned int features;
  188. /** Interrupt endpoint */
  189. struct usb_endpoint intr;
  190. /** Interrupt endpoint refill process */
  191. struct process refill;
  192. };
  193. /** Interrupt ring fill level
  194. *
  195. * This is a policy decision.
  196. */
  197. #define USB_HUB_INTR_FILL 4
  198. /** Maximum time to wait for port to become enabled
  199. *
  200. * This is a policy decision.
  201. */
  202. #define USB_HUB_ENABLE_MAX_WAIT_MS 100
  203. #endif /* _USBHUB_H */