usbh_core.c 44 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192
  1. /*
  2. * Copyright (c) 2022, sakumisu
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include "usbh_core.h"
  7. #undef USB_DBG_TAG
  8. #define USB_DBG_TAG "usbh_core"
  9. #include "usb_log.h"
  10. struct usbh_class_info *usbh_class_info_table_begin = NULL;
  11. struct usbh_class_info *usbh_class_info_table_end = NULL;
  12. usb_slist_t g_bus_head = USB_SLIST_OBJECT_INIT(g_bus_head);
  13. struct setup_align_buffer {
  14. uint8_t buffer[USB_ALIGN_UP(8, CONFIG_USB_ALIGN_SIZE)];
  15. };
  16. USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t ep0_request_buffer[CONFIG_USBHOST_MAX_BUS][USB_ALIGN_UP(CONFIG_USBHOST_REQUEST_BUFFER_LEN, CONFIG_USB_ALIGN_SIZE)];
  17. USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX struct setup_align_buffer g_setup_buffer[CONFIG_USBHOST_MAX_BUS][CONFIG_USBHOST_MAX_EXTHUBS + 1][CONFIG_USBHOST_MAX_EHPORTS];
  18. struct usbh_bus g_usbhost_bus[CONFIG_USBHOST_MAX_BUS];
  19. /* general descriptor field offsets */
  20. #define DESC_bLength 0 /** Length offset */
  21. #define DESC_bDescriptorType 1 /** Descriptor type offset */
  22. #define USB_DEV_ADDR_MAX 0x7f
  23. #define USB_DEV_ADDR_MARK_OFFSET 5
  24. #define USB_DEV_ADDR_MARK_MASK 0x1f
  25. static int usbh_allocate_devaddr(struct usbh_devaddr_map *devgen)
  26. {
  27. uint8_t lastaddr = devgen->last;
  28. uint8_t devaddr = lastaddr;
  29. int index;
  30. int bitno;
  31. for (;;) {
  32. devaddr++;
  33. if (devaddr > 0x7f) {
  34. devaddr = 2;
  35. }
  36. if (devaddr == lastaddr) {
  37. return -USB_ERR_NOMEM;
  38. }
  39. index = devaddr >> 5;
  40. bitno = devaddr & 0x1f;
  41. if ((devgen->alloctab[index] & (1ul << bitno)) == 0) {
  42. devgen->alloctab[index] |= (1ul << bitno);
  43. devgen->last = devaddr;
  44. return (int)devaddr;
  45. }
  46. }
  47. }
  48. static int __usbh_free_devaddr(struct usbh_devaddr_map *devgen, uint8_t devaddr)
  49. {
  50. int index;
  51. int bitno;
  52. if ((devaddr > 0) && (devaddr < USB_DEV_ADDR_MAX)) {
  53. index = devaddr >> USB_DEV_ADDR_MARK_OFFSET;
  54. bitno = devaddr & USB_DEV_ADDR_MARK_MASK;
  55. /* Free the address */
  56. if ((devgen->alloctab[index] & (1ul << bitno)) != 0) {
  57. devgen->alloctab[index] &= ~(1ul << bitno);
  58. } else {
  59. return -1;
  60. }
  61. }
  62. return 0;
  63. }
  64. static int usbh_free_devaddr(struct usbh_hubport *hport)
  65. {
  66. if (hport->dev_addr > 0) {
  67. __usbh_free_devaddr(&hport->bus->devgen, hport->dev_addr);
  68. }
  69. return 0;
  70. }
  71. static const struct usbh_class_driver *usbh_find_class_driver(uint8_t class, uint8_t subclass, uint8_t protocol, uint8_t intf,
  72. uint16_t vid, uint16_t pid)
  73. {
  74. struct usbh_class_info *index = NULL;
  75. for (index = usbh_class_info_table_begin; index < usbh_class_info_table_end; index++) {
  76. if ((index->match_flags & USB_CLASS_MATCH_INTF_CLASS) && !(index->bInterfaceClass == class)) {
  77. continue;
  78. }
  79. if ((index->match_flags & USB_CLASS_MATCH_INTF_SUBCLASS) && !(index->bInterfaceSubClass == subclass)) {
  80. continue;
  81. }
  82. if ((index->match_flags & USB_CLASS_MATCH_INTF_PROTOCOL) && !(index->bInterfaceProtocol == protocol)) {
  83. continue;
  84. }
  85. if ((index->match_flags & USB_CLASS_MATCH_INTF_NUM) && !(index->bInterfaceNumber == intf)) {
  86. continue;
  87. }
  88. if (index->match_flags & USB_CLASS_MATCH_VID_PID && index->id_table) {
  89. /* scan id table */
  90. uint32_t i;
  91. for (i = 0; index->id_table[i][0]; i++) {
  92. if (index->id_table[i][0] == vid && index->id_table[i][1] == pid) {
  93. break;
  94. }
  95. }
  96. /* do not match, continue next */
  97. if (!index->id_table[i][0]) {
  98. continue;
  99. }
  100. }
  101. return index->class_driver;
  102. }
  103. return NULL;
  104. }
  105. static int parse_device_descriptor(struct usbh_hubport *hport, struct usb_device_descriptor *desc, uint16_t length)
  106. {
  107. if (desc->bLength != USB_SIZEOF_DEVICE_DESC) {
  108. USB_LOG_ERR("invalid device bLength 0x%02x\r\n", desc->bLength);
  109. return -USB_ERR_INVAL;
  110. } else if (desc->bDescriptorType != USB_DESCRIPTOR_TYPE_DEVICE) {
  111. USB_LOG_ERR("unexpected device descriptor 0x%02x\r\n", desc->bDescriptorType);
  112. return -USB_ERR_INVAL;
  113. } else {
  114. if (length <= 8) {
  115. return 0;
  116. }
  117. #if 0
  118. USB_LOG_DBG("Device Descriptor:\r\n");
  119. USB_LOG_DBG("bLength: 0x%02x \r\n", desc->bLength);
  120. USB_LOG_DBG("bDescriptorType: 0x%02x \r\n", desc->bDescriptorType);
  121. USB_LOG_DBG("bcdUSB: 0x%04x \r\n", desc->bcdUSB);
  122. USB_LOG_DBG("bDeviceClass: 0x%02x \r\n", desc->bDeviceClass);
  123. USB_LOG_DBG("bDeviceSubClass: 0x%02x \r\n", desc->bDeviceSubClass);
  124. USB_LOG_DBG("bDeviceProtocol: 0x%02x \r\n", desc->bDeviceProtocol);
  125. USB_LOG_DBG("bMaxPacketSize0: 0x%02x \r\n", desc->bMaxPacketSize0);
  126. USB_LOG_DBG("idVendor: 0x%04x \r\n", desc->idVendor);
  127. USB_LOG_DBG("idProduct: 0x%04x \r\n", desc->idProduct);
  128. USB_LOG_DBG("bcdDevice: 0x%04x \r\n", desc->bcdDevice);
  129. USB_LOG_DBG("iManufacturer: 0x%02x \r\n", desc->iManufacturer);
  130. USB_LOG_DBG("iProduct: 0x%02x \r\n", desc->iProduct);
  131. USB_LOG_DBG("iSerialNumber: 0x%02x \r\n", desc->iSerialNumber);
  132. USB_LOG_DBG("bNumConfigurations: 0x%02x\r\n", desc->bNumConfigurations);
  133. #endif
  134. hport->device_desc.bLength = desc->bLength;
  135. hport->device_desc.bDescriptorType = desc->bDescriptorType;
  136. hport->device_desc.bcdUSB = desc->bcdUSB;
  137. hport->device_desc.bDeviceClass = desc->bDeviceClass;
  138. hport->device_desc.bDeviceSubClass = desc->bDeviceSubClass;
  139. hport->device_desc.bDeviceProtocol = desc->bDeviceProtocol;
  140. hport->device_desc.bMaxPacketSize0 = desc->bMaxPacketSize0;
  141. hport->device_desc.idVendor = desc->idVendor;
  142. hport->device_desc.idProduct = desc->idProduct;
  143. hport->device_desc.bcdDevice = desc->bcdDevice;
  144. hport->device_desc.iManufacturer = desc->iManufacturer;
  145. hport->device_desc.iProduct = desc->iProduct;
  146. hport->device_desc.iSerialNumber = desc->iSerialNumber;
  147. hport->device_desc.bNumConfigurations = desc->bNumConfigurations;
  148. }
  149. return 0;
  150. }
  151. static int parse_config_descriptor(struct usbh_hubport *hport, struct usb_configuration_descriptor *desc, uint16_t length)
  152. {
  153. struct usb_interface_descriptor *intf_desc;
  154. struct usb_endpoint_descriptor *ep_desc;
  155. uint8_t cur_alt_setting = 0xff;
  156. uint8_t cur_iface = 0xff;
  157. uint8_t cur_ep = 0xff;
  158. uint8_t cur_ep_num = 0xff;
  159. uint32_t desc_len = 0;
  160. uint8_t *p;
  161. if (desc->bLength != USB_SIZEOF_CONFIG_DESC) {
  162. USB_LOG_ERR("invalid config bLength 0x%02x\r\n", desc->bLength);
  163. return -USB_ERR_INVAL;
  164. } else if (desc->bDescriptorType != USB_DESCRIPTOR_TYPE_CONFIGURATION) {
  165. USB_LOG_ERR("unexpected config descriptor 0x%02x\r\n", desc->bDescriptorType);
  166. return -USB_ERR_INVAL;
  167. } else {
  168. if (length <= USB_SIZEOF_CONFIG_DESC) {
  169. return 0;
  170. }
  171. #if 0
  172. USB_LOG_DBG("Config Descriptor:\r\n");
  173. USB_LOG_DBG("bLength: 0x%02x \r\n", desc->bLength);
  174. USB_LOG_DBG("bDescriptorType: 0x%02x \r\n", desc->bDescriptorType);
  175. USB_LOG_DBG("wTotalLength: 0x%04x \r\n", desc->wTotalLength);
  176. USB_LOG_DBG("bNumInterfaces: 0x%02x \r\n", desc->bNumInterfaces);
  177. USB_LOG_DBG("bConfigurationValue: 0x%02x \r\n", desc->bConfigurationValue);
  178. USB_LOG_DBG("iConfiguration: 0x%02x \r\n", desc->iConfiguration);
  179. USB_LOG_DBG("bmAttributes: 0x%02x \r\n", desc->bmAttributes);
  180. USB_LOG_DBG("bMaxPower: 0x%02x \r\n", desc->bMaxPower);
  181. #endif
  182. hport->config.config_desc.bLength = desc->bLength;
  183. hport->config.config_desc.bDescriptorType = desc->bDescriptorType;
  184. hport->config.config_desc.wTotalLength = desc->wTotalLength;
  185. hport->config.config_desc.bNumInterfaces = desc->bNumInterfaces;
  186. hport->config.config_desc.bConfigurationValue = desc->bConfigurationValue;
  187. hport->config.config_desc.iConfiguration = desc->iConfiguration;
  188. hport->config.config_desc.iConfiguration = desc->iConfiguration;
  189. hport->config.config_desc.bmAttributes = desc->bmAttributes;
  190. hport->config.config_desc.bMaxPower = desc->bMaxPower;
  191. p = (uint8_t *)desc;
  192. p += USB_SIZEOF_CONFIG_DESC;
  193. desc_len = USB_SIZEOF_CONFIG_DESC;
  194. memset(hport->config.intf, 0, sizeof(struct usbh_interface) * CONFIG_USBHOST_MAX_INTERFACES);
  195. while (p[DESC_bLength] && (desc_len <= length)) {
  196. switch (p[DESC_bDescriptorType]) {
  197. case USB_DESCRIPTOR_TYPE_INTERFACE:
  198. intf_desc = (struct usb_interface_descriptor *)p;
  199. cur_iface = intf_desc->bInterfaceNumber;
  200. cur_alt_setting = intf_desc->bAlternateSetting;
  201. cur_ep_num = intf_desc->bNumEndpoints;
  202. cur_ep = 0;
  203. if (cur_iface >= CONFIG_USBHOST_MAX_INTERFACES) {
  204. USB_LOG_ERR("Interface num %d overflow\r\n", cur_iface);
  205. return -USB_ERR_NOMEM;
  206. }
  207. if (cur_ep_num >= CONFIG_USBHOST_MAX_ENDPOINTS) {
  208. USB_LOG_ERR("Endpoint num %d overflow\r\n", cur_ep_num);
  209. return -USB_ERR_NOMEM;
  210. }
  211. if (cur_alt_setting >= CONFIG_USBHOST_MAX_INTF_ALTSETTINGS) {
  212. USB_LOG_ERR("Interface altsetting num %d overflow\r\n", cur_alt_setting);
  213. return -USB_ERR_NOMEM;
  214. }
  215. #if 0
  216. USB_LOG_DBG("Interface Descriptor:\r\n");
  217. USB_LOG_DBG("bLength: 0x%02x \r\n", intf_desc->bLength);
  218. USB_LOG_DBG("bDescriptorType: 0x%02x \r\n", intf_desc->bDescriptorType);
  219. USB_LOG_DBG("bInterfaceNumber: 0x%02x \r\n", intf_desc->bInterfaceNumber);
  220. USB_LOG_DBG("bAlternateSetting: 0x%02x \r\n", intf_desc->bAlternateSetting);
  221. USB_LOG_DBG("bNumEndpoints: 0x%02x \r\n", intf_desc->bNumEndpoints);
  222. USB_LOG_DBG("bInterfaceClass: 0x%02x \r\n", intf_desc->bInterfaceClass);
  223. USB_LOG_DBG("bInterfaceSubClass: 0x%02x \r\n", intf_desc->bInterfaceSubClass);
  224. USB_LOG_DBG("bInterfaceProtocol: 0x%02x \r\n", intf_desc->bInterfaceProtocol);
  225. USB_LOG_DBG("iInterface: 0x%02x \r\n", intf_desc->iInterface);
  226. #endif
  227. memcpy(&hport->config.intf[cur_iface].altsetting[cur_alt_setting].intf_desc, intf_desc, 9);
  228. hport->config.intf[cur_iface].altsetting_num = cur_alt_setting + 1;
  229. break;
  230. case USB_DESCRIPTOR_TYPE_ENDPOINT:
  231. ep_desc = (struct usb_endpoint_descriptor *)p;
  232. memcpy(&hport->config.intf[cur_iface].altsetting[cur_alt_setting].ep[cur_ep].ep_desc, ep_desc, 7);
  233. cur_ep++;
  234. break;
  235. default:
  236. break;
  237. }
  238. /* skip to next descriptor */
  239. p += p[DESC_bLength];
  240. desc_len += p[DESC_bLength];
  241. }
  242. }
  243. return 0;
  244. }
  245. static void usbh_print_setup(struct usb_setup_packet *setup)
  246. {
  247. (void)setup;
  248. USB_LOG_DBG("Setup: "
  249. "bmRequestType 0x%02x, bRequest 0x%02x, wValue 0x%04x, wIndex 0x%04x, wLength 0x%04x\r\n",
  250. setup->bmRequestType,
  251. setup->bRequest,
  252. setup->wValue,
  253. setup->wIndex,
  254. setup->wLength);
  255. }
  256. static int usbh_get_default_mps(int speed)
  257. {
  258. switch (speed) {
  259. case USB_SPEED_LOW: /* For low speed, we use 8 bytes */
  260. return 8;
  261. case USB_SPEED_FULL: /* For full or high speed, we use 64 bytes */
  262. case USB_SPEED_HIGH:
  263. return 64;
  264. case USB_SPEED_SUPER: /* For super speed , we must use 512 bytes */
  265. case USB_SPEED_SUPER_PLUS:
  266. return 512;
  267. default:
  268. return 64;
  269. }
  270. }
  271. int usbh_enumerate(struct usbh_hubport *hport)
  272. {
  273. struct usb_interface_descriptor *intf_desc;
  274. struct usb_setup_packet *setup;
  275. struct usb_device_descriptor *dev_desc;
  276. struct usb_endpoint_descriptor *ep;
  277. int dev_addr;
  278. uint16_t ep_mps;
  279. uint8_t config_value;
  280. uint8_t config_index;
  281. int ret;
  282. hport->setup = (struct usb_setup_packet *)&g_setup_buffer[hport->bus->busid][hport->parent->index - 1][hport->port - 1];
  283. setup = hport->setup;
  284. ep = &hport->ep0;
  285. /* Config EP0 mps from speed */
  286. ep->bEndpointAddress = 0x00;
  287. ep->bDescriptorType = USB_DESCRIPTOR_TYPE_ENDPOINT;
  288. ep->bmAttributes = USB_ENDPOINT_TYPE_CONTROL;
  289. ep->wMaxPacketSize = usbh_get_default_mps(hport->speed);
  290. ep->bInterval = 0;
  291. ep->bLength = 7;
  292. /* Configure EP0 with zero address */
  293. hport->dev_addr = 0;
  294. /* Read the first 8 bytes of the device descriptor */
  295. setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_DEVICE;
  296. setup->bRequest = USB_REQUEST_GET_DESCRIPTOR;
  297. setup->wValue = (uint16_t)((USB_DESCRIPTOR_TYPE_DEVICE << 8) | 0);
  298. setup->wIndex = 0;
  299. setup->wLength = 8;
  300. ret = usbh_control_transfer(hport, setup, ep0_request_buffer[hport->bus->busid]);
  301. if (ret < 0) {
  302. USB_LOG_ERR("Failed to get device descriptor,errorcode:%d\r\n", ret);
  303. goto errout;
  304. }
  305. ret = parse_device_descriptor(hport, (struct usb_device_descriptor *)ep0_request_buffer[hport->bus->busid], 8);
  306. if (ret < 0) {
  307. USB_LOG_ERR("Parse device descriptor fail\r\n");
  308. goto errout;
  309. }
  310. /* Extract the correct max packetsize from the device descriptor */
  311. dev_desc = (struct usb_device_descriptor *)ep0_request_buffer[hport->bus->busid];
  312. if (dev_desc->bcdUSB >= USB_3_0) {
  313. ep_mps = 1 << dev_desc->bMaxPacketSize0;
  314. } else {
  315. ep_mps = dev_desc->bMaxPacketSize0;
  316. }
  317. USB_LOG_DBG("Device rev=%04x cls=%02x sub=%02x proto=%02x size=%d\r\n",
  318. dev_desc->bcdUSB, dev_desc->bDeviceClass, dev_desc->bDeviceSubClass,
  319. dev_desc->bDeviceProtocol, ep_mps);
  320. /* Reconfigure EP0 with the correct maximum packet size */
  321. ep->wMaxPacketSize = ep_mps;
  322. /* Assign a function address to the device connected to this port */
  323. dev_addr = usbh_allocate_devaddr(&hport->bus->devgen);
  324. if (dev_addr < 0) {
  325. USB_LOG_ERR("Failed to allocate devaddr,errorcode:%d\r\n", ret);
  326. goto errout;
  327. }
  328. /* Set the USB device address */
  329. setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_DEVICE;
  330. setup->bRequest = USB_REQUEST_SET_ADDRESS;
  331. setup->wValue = dev_addr;
  332. setup->wIndex = 0;
  333. setup->wLength = 0;
  334. ret = usbh_control_transfer(hport, setup, NULL);
  335. if (ret < 0) {
  336. USB_LOG_ERR("Failed to set devaddr,errorcode:%d\r\n", ret);
  337. goto errout;
  338. }
  339. /* Wait device set address completely */
  340. usb_osal_msleep(10);
  341. /*Reconfigure EP0 with the correct address */
  342. hport->dev_addr = dev_addr;
  343. /* Read the full device descriptor */
  344. setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_DEVICE;
  345. setup->bRequest = USB_REQUEST_GET_DESCRIPTOR;
  346. setup->wValue = (uint16_t)((USB_DESCRIPTOR_TYPE_DEVICE << 8) | 0);
  347. setup->wIndex = 0;
  348. setup->wLength = USB_SIZEOF_DEVICE_DESC;
  349. ret = usbh_control_transfer(hport, setup, ep0_request_buffer[hport->bus->busid]);
  350. if (ret < 0) {
  351. USB_LOG_ERR("Failed to get full device descriptor,errorcode:%d\r\n", ret);
  352. goto errout;
  353. }
  354. parse_device_descriptor(hport, (struct usb_device_descriptor *)ep0_request_buffer[hport->bus->busid], USB_SIZEOF_DEVICE_DESC);
  355. USB_LOG_INFO("New device found,idVendor:%04x,idProduct:%04x,bcdDevice:%04x\r\n",
  356. ((struct usb_device_descriptor *)ep0_request_buffer[hport->bus->busid])->idVendor,
  357. ((struct usb_device_descriptor *)ep0_request_buffer[hport->bus->busid])->idProduct,
  358. ((struct usb_device_descriptor *)ep0_request_buffer[hport->bus->busid])->bcdDevice);
  359. USB_LOG_INFO("The device has %d bNumConfigurations\r\n", ((struct usb_device_descriptor *)ep0_request_buffer[hport->bus->busid])->bNumConfigurations);
  360. config_index = usbh_get_hport_active_config_index(hport);
  361. USB_LOG_DBG("The device selects config %d\r\n", config_index);
  362. /* Read the first 9 bytes of the config descriptor */
  363. setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_DEVICE;
  364. setup->bRequest = USB_REQUEST_GET_DESCRIPTOR;
  365. setup->wValue = (uint16_t)((USB_DESCRIPTOR_TYPE_CONFIGURATION << 8) | config_index);
  366. setup->wIndex = 0;
  367. setup->wLength = USB_SIZEOF_CONFIG_DESC;
  368. ret = usbh_control_transfer(hport, setup, ep0_request_buffer[hport->bus->busid]);
  369. if (ret < 0) {
  370. USB_LOG_ERR("Failed to get config descriptor,errorcode:%d\r\n", ret);
  371. goto errout;
  372. }
  373. ret = parse_config_descriptor(hport, (struct usb_configuration_descriptor *)ep0_request_buffer[hport->bus->busid], USB_SIZEOF_CONFIG_DESC);
  374. if (ret < 0) {
  375. USB_LOG_ERR("Parse config descriptor fail\r\n");
  376. goto errout;
  377. }
  378. /* Read the full size of the configuration data */
  379. uint16_t wTotalLength = ((struct usb_configuration_descriptor *)ep0_request_buffer[hport->bus->busid])->wTotalLength;
  380. if (wTotalLength > CONFIG_USBHOST_REQUEST_BUFFER_LEN) {
  381. ret = -USB_ERR_NOMEM;
  382. USB_LOG_ERR("wTotalLength %d is overflow, default is %d\r\n", wTotalLength, (unsigned int)CONFIG_USBHOST_REQUEST_BUFFER_LEN);
  383. goto errout;
  384. }
  385. setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_DEVICE;
  386. setup->bRequest = USB_REQUEST_GET_DESCRIPTOR;
  387. setup->wValue = (uint16_t)((USB_DESCRIPTOR_TYPE_CONFIGURATION << 8) | config_index);
  388. setup->wIndex = 0;
  389. setup->wLength = wTotalLength;
  390. ret = usbh_control_transfer(hport, setup, ep0_request_buffer[hport->bus->busid]);
  391. if (ret < 0) {
  392. USB_LOG_ERR("Failed to get full config descriptor,errorcode:%d\r\n", ret);
  393. goto errout;
  394. }
  395. ret = parse_config_descriptor(hport, (struct usb_configuration_descriptor *)ep0_request_buffer[hport->bus->busid], wTotalLength);
  396. if (ret < 0) {
  397. USB_LOG_ERR("Parse config descriptor fail\r\n");
  398. goto errout;
  399. }
  400. USB_LOG_INFO("The device has %d interfaces\r\n", ((struct usb_configuration_descriptor *)ep0_request_buffer[hport->bus->busid])->bNumInterfaces);
  401. hport->raw_config_desc = usb_osal_malloc(wTotalLength + 1);
  402. if (hport->raw_config_desc == NULL) {
  403. ret = -USB_ERR_NOMEM;
  404. USB_LOG_ERR("No memory to alloc for raw_config_desc\r\n");
  405. goto errout;
  406. }
  407. config_value = ((struct usb_configuration_descriptor *)ep0_request_buffer[hport->bus->busid])->bConfigurationValue;
  408. memcpy(hport->raw_config_desc, ep0_request_buffer[hport->bus->busid], wTotalLength);
  409. hport->raw_config_desc[wTotalLength] = '\0';
  410. #ifdef CONFIG_USBHOST_GET_STRING_DESC
  411. uint8_t string_buffer[128];
  412. if (hport->device_desc.iManufacturer > 0) {
  413. /* Get Manufacturer string */
  414. memset(string_buffer, 0, 128);
  415. ret = usbh_get_string_desc(hport, USB_STRING_MFC_INDEX, string_buffer, 128);
  416. if (ret < 0) {
  417. USB_LOG_ERR("Failed to get Manufacturer string,errorcode:%d\r\n", ret);
  418. goto errout;
  419. }
  420. USB_LOG_INFO("Manufacturer: %s\r\n", string_buffer);
  421. } else {
  422. USB_LOG_WRN("Do not support Manufacturer string\r\n");
  423. }
  424. if (hport->device_desc.iProduct > 0) {
  425. /* Get Product string */
  426. memset(string_buffer, 0, 128);
  427. ret = usbh_get_string_desc(hport, USB_STRING_PRODUCT_INDEX, string_buffer, 128);
  428. if (ret < 0) {
  429. USB_LOG_ERR("Failed to get Product string,errorcode:%d\r\n", ret);
  430. goto errout;
  431. }
  432. USB_LOG_INFO("Product: %s\r\n", string_buffer);
  433. } else {
  434. USB_LOG_WRN("Do not support Product string\r\n");
  435. }
  436. if (hport->device_desc.iSerialNumber > 0) {
  437. /* Get SerialNumber string */
  438. memset(string_buffer, 0, 128);
  439. ret = usbh_get_string_desc(hport, USB_STRING_SERIAL_INDEX, string_buffer, 128);
  440. if (ret < 0) {
  441. USB_LOG_ERR("Failed to get SerialNumber string,errorcode:%d\r\n", ret);
  442. goto errout;
  443. }
  444. USB_LOG_INFO("SerialNumber: %s\r\n", string_buffer);
  445. } else {
  446. USB_LOG_WRN("Do not support SerialNumber string\r\n");
  447. }
  448. #endif
  449. /* Select device configuration 1 */
  450. setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_DEVICE;
  451. setup->bRequest = USB_REQUEST_SET_CONFIGURATION;
  452. setup->wValue = config_value;
  453. setup->wIndex = 0;
  454. setup->wLength = 0;
  455. ret = usbh_control_transfer(hport, setup, NULL);
  456. if (ret < 0) {
  457. USB_LOG_ERR("Failed to set configuration,errorcode:%d\r\n", ret);
  458. goto errout;
  459. }
  460. #ifdef CONFIG_USBHOST_MSOS_ENABLE
  461. setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE;
  462. setup->bRequest = CONFIG_USBHOST_MSOS_VENDOR_CODE;
  463. setup->wValue = 0;
  464. setup->wIndex = 0x0004;
  465. setup->wLength = 16;
  466. ret = usbh_control_transfer(hport, setup, ep0_request_buffer[hport->bus->busid]);
  467. if (ret < 0 && (ret != -USB_ERR_STALL)) {
  468. USB_LOG_ERR("Failed to get msosv1 compat id,errorcode:%d\r\n", ret);
  469. goto errout;
  470. }
  471. #endif
  472. USB_LOG_INFO("Enumeration success, start loading class driver\r\n");
  473. /*search supported class driver*/
  474. for (uint8_t i = 0; i < hport->config.config_desc.bNumInterfaces; i++) {
  475. intf_desc = &hport->config.intf[i].altsetting[0].intf_desc;
  476. USB_ASSERT_MSG(intf_desc->bInterfaceNumber == i, "Interface number mismatch, do not support non-standard device\r\n");
  477. struct usbh_class_driver *class_driver = (struct usbh_class_driver *)usbh_find_class_driver(intf_desc->bInterfaceClass,
  478. intf_desc->bInterfaceSubClass,
  479. intf_desc->bInterfaceProtocol,
  480. intf_desc->bInterfaceNumber,
  481. hport->device_desc.idVendor,
  482. hport->device_desc.idProduct);
  483. if (class_driver == NULL) {
  484. USB_LOG_ERR("Do not support Class:0x%02x, Subclass:0x%02x, Protocl:0x%02x on interface %u\r\n",
  485. intf_desc->bInterfaceClass,
  486. intf_desc->bInterfaceSubClass,
  487. intf_desc->bInterfaceProtocol,
  488. i);
  489. continue;
  490. }
  491. hport->config.intf[i].class_driver = class_driver;
  492. USB_LOG_INFO("Loading %s class driver on interface %u\r\n", class_driver->driver_name, i);
  493. ret = CLASS_CONNECT(hport, i);
  494. }
  495. errout:
  496. if (hport->raw_config_desc) {
  497. usb_osal_free(hport->raw_config_desc);
  498. hport->raw_config_desc = NULL;
  499. }
  500. return ret;
  501. }
  502. void usbh_hubport_release(struct usbh_hubport *hport)
  503. {
  504. if (hport->connected) {
  505. hport->connected = false;
  506. usbh_kill_urb(&hport->ep0_urb);
  507. usbh_free_devaddr(hport);
  508. for (uint8_t i = 0; i < hport->config.config_desc.bNumInterfaces; i++) {
  509. if (hport->config.intf[i].class_driver && hport->config.intf[i].class_driver->disconnect) {
  510. CLASS_DISCONNECT(hport, i);
  511. }
  512. }
  513. hport->config.config_desc.bNumInterfaces = 0;
  514. if (hport->mutex) {
  515. usb_osal_mutex_delete(hport->mutex);
  516. }
  517. }
  518. }
  519. static void usbh_bus_init(struct usbh_bus *bus, uint8_t busid, uintptr_t reg_base)
  520. {
  521. memset(bus, 0, sizeof(struct usbh_bus));
  522. bus->busid = busid;
  523. bus->hcd.hcd_id = busid;
  524. bus->hcd.reg_base = reg_base;
  525. /* devaddr 1 is for roothub */
  526. bus->devgen.last = 0x7f;
  527. usb_slist_add_tail(&g_bus_head, &bus->list);
  528. }
  529. int usbh_initialize(uint8_t busid, uintptr_t reg_base)
  530. {
  531. struct usbh_bus *bus;
  532. USB_ASSERT_MSG(busid < CONFIG_USBHOST_MAX_BUS, "bus overflow\r\n");
  533. bus = &g_usbhost_bus[busid];
  534. usbh_bus_init(bus, busid, reg_base);
  535. #ifdef __ARMCC_VERSION /* ARM C Compiler */
  536. extern const int usbh_class_info$$Base;
  537. extern const int usbh_class_info$$Limit;
  538. usbh_class_info_table_begin = (struct usbh_class_info *)&usbh_class_info$$Base;
  539. usbh_class_info_table_end = (struct usbh_class_info *)&usbh_class_info$$Limit;
  540. #elif defined(__GNUC__)
  541. extern uint32_t __usbh_class_info_start__;
  542. extern uint32_t __usbh_class_info_end__;
  543. usbh_class_info_table_begin = (struct usbh_class_info *)&__usbh_class_info_start__;
  544. usbh_class_info_table_end = (struct usbh_class_info *)&__usbh_class_info_end__;
  545. #elif defined(__ICCARM__) || defined(__ICCRX__) || defined(__ICCRISCV__)
  546. usbh_class_info_table_begin = (struct usbh_class_info *)__section_begin(".usbh_class_info");
  547. usbh_class_info_table_end = (struct usbh_class_info *)__section_end(".usbh_class_info");
  548. #endif
  549. usbh_hub_initialize(bus);
  550. return 0;
  551. }
  552. int usbh_deinitialize(uint8_t busid)
  553. {
  554. struct usbh_bus *bus;
  555. USB_ASSERT_MSG(busid < CONFIG_USBHOST_MAX_BUS, "bus overflow\r\n");
  556. bus = &g_usbhost_bus[busid];
  557. usbh_hub_deinitialize(bus);
  558. usb_slist_remove(&g_bus_head, &bus->list);
  559. return 0;
  560. }
  561. int usbh_control_transfer(struct usbh_hubport *hport, struct usb_setup_packet *setup, uint8_t *buffer)
  562. {
  563. struct usbh_urb *urb;
  564. volatile uint8_t retry = 3;
  565. int ret;
  566. if (!hport || !setup) {
  567. return -USB_ERR_INVAL;
  568. }
  569. urb = &hport->ep0_urb;
  570. usb_osal_mutex_take(hport->mutex);
  571. usbh_print_setup(setup);
  572. resubmit:
  573. usbh_control_urb_fill(urb, hport, setup, buffer, setup->wLength, CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT, NULL, NULL);
  574. ret = usbh_submit_urb(urb);
  575. if (ret == 0) {
  576. ret = urb->actual_length;
  577. }
  578. if (ret < 0 && (ret != -USB_ERR_TIMEOUT)) {
  579. retry--;
  580. if (retry > 0) {
  581. USB_LOG_WRN("Control transfer failed, errorcode %d, retrying...\r\n", ret);
  582. goto resubmit;
  583. }
  584. }
  585. usb_osal_mutex_give(hport->mutex);
  586. return ret;
  587. }
  588. int usbh_get_string_desc(struct usbh_hubport *hport, uint8_t index, uint8_t *output, uint16_t output_len)
  589. {
  590. struct usb_setup_packet *setup = hport->setup;
  591. int ret;
  592. uint8_t *src;
  593. uint8_t *dst;
  594. uint16_t len;
  595. uint16_t i = 2;
  596. uint16_t j = 0;
  597. /* Get Manufacturer string */
  598. setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_DEVICE;
  599. setup->bRequest = USB_REQUEST_GET_DESCRIPTOR;
  600. setup->wValue = (uint16_t)((USB_DESCRIPTOR_TYPE_STRING << 8) | index);
  601. setup->wIndex = 0x0409;
  602. setup->wLength = 255;
  603. ret = usbh_control_transfer(hport, setup, ep0_request_buffer[hport->bus->busid]);
  604. if (ret < 0) {
  605. return ret;
  606. }
  607. src = ep0_request_buffer[hport->bus->busid];
  608. dst = output;
  609. len = src[0];
  610. if (((len - 2) / 2) > output_len) {
  611. return -USB_ERR_NOMEM;
  612. }
  613. while (i < len) {
  614. dst[j] = src[i];
  615. i += 2;
  616. j++;
  617. }
  618. return 0;
  619. }
  620. int usbh_set_interface(struct usbh_hubport *hport, uint8_t intf, uint8_t altsetting)
  621. {
  622. struct usb_setup_packet *setup = hport->setup;
  623. setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_INTERFACE;
  624. setup->bRequest = USB_REQUEST_SET_INTERFACE;
  625. setup->wValue = altsetting;
  626. setup->wIndex = intf;
  627. setup->wLength = 0;
  628. return usbh_control_transfer(hport, setup, NULL);
  629. }
  630. static void *usbh_list_all_interface_name(struct usbh_hub *hub, const char *devname)
  631. {
  632. struct usbh_hubport *hport;
  633. struct usbh_hub *hub_next;
  634. void *priv;
  635. for (uint8_t port = 0; port < hub->nports; port++) {
  636. hport = &hub->child[port];
  637. if (hport->connected) {
  638. for (uint8_t itf = 0; itf < hport->config.config_desc.bNumInterfaces; itf++) {
  639. if (hport->config.intf[itf].class_driver && hport->config.intf[itf].class_driver->driver_name) {
  640. if ((strncmp(hport->config.intf[itf].devname, devname, CONFIG_USBHOST_DEV_NAMELEN) == 0) && hport->config.intf[itf].priv)
  641. return hport->config.intf[itf].priv;
  642. if (strcmp(hport->config.intf[itf].class_driver->driver_name, "hub") == 0) {
  643. hub_next = hport->config.intf[itf].priv;
  644. if (hub_next && hub_next->connected) {
  645. priv = usbh_list_all_interface_name(hub_next, devname);
  646. if (priv) {
  647. return priv;
  648. }
  649. }
  650. }
  651. }
  652. }
  653. }
  654. }
  655. return NULL;
  656. }
  657. static struct usbh_hubport *usbh_list_all_hubport(struct usbh_hub *hub, uint8_t hub_index, uint8_t hub_port)
  658. {
  659. struct usbh_hubport *hport;
  660. struct usbh_hub *hub_next;
  661. if (hub->index == hub_index) {
  662. hport = &hub->child[hub_port - 1];
  663. if (hport->connected) {
  664. return hport;
  665. } else {
  666. return NULL;
  667. }
  668. } else {
  669. for (uint8_t port = 0; port < hub->nports; port++) {
  670. hport = &hub->child[port];
  671. if (hport->connected) {
  672. for (uint8_t itf = 0; itf < hport->config.config_desc.bNumInterfaces; itf++) {
  673. if (hport->config.intf[itf].class_driver && hport->config.intf[itf].class_driver->driver_name) {
  674. if (strcmp(hport->config.intf[itf].class_driver->driver_name, "hub") == 0) {
  675. hub_next = hport->config.intf[itf].priv;
  676. if (hub_next && hub_next->connected) {
  677. hport = usbh_list_all_hubport(hub_next, hub_index, hub_port);
  678. if (hport) {
  679. return hport;
  680. }
  681. }
  682. }
  683. }
  684. }
  685. }
  686. }
  687. }
  688. return NULL;
  689. }
  690. void *usbh_find_class_instance(const char *devname)
  691. {
  692. usb_slist_t *bus_list;
  693. struct usbh_hub *hub;
  694. struct usbh_bus *bus;
  695. void *priv;
  696. size_t flags;
  697. flags = usb_osal_enter_critical_section();
  698. usb_slist_for_each(bus_list, &g_bus_head)
  699. {
  700. bus = usb_slist_entry(bus_list, struct usbh_bus, list);
  701. hub = &bus->hcd.roothub;
  702. priv = usbh_list_all_interface_name(hub, devname);
  703. if (priv) {
  704. usb_osal_leave_critical_section(flags);
  705. return priv;
  706. }
  707. }
  708. usb_osal_leave_critical_section(flags);
  709. return NULL;
  710. }
  711. struct usbh_hubport *usbh_find_hubport(uint8_t busid, uint8_t hub_index, uint8_t hub_port)
  712. {
  713. struct usbh_hub *hub;
  714. struct usbh_bus *bus;
  715. struct usbh_hubport *hport;
  716. size_t flags;
  717. flags = usb_osal_enter_critical_section();
  718. bus = &g_usbhost_bus[busid];
  719. hub = &bus->hcd.roothub;
  720. hport = usbh_list_all_hubport(hub, hub_index, hub_port);
  721. usb_osal_leave_critical_section(flags);
  722. return hport;
  723. }
  724. static void usbh_print_hubport_info(struct usbh_hubport *hport)
  725. {
  726. USB_LOG_RAW("Device Descriptor:\r\n");
  727. USB_LOG_RAW("bLength: 0x%02x \r\n", hport->device_desc.bLength);
  728. USB_LOG_RAW("bDescriptorType: 0x%02x \r\n", hport->device_desc.bDescriptorType);
  729. USB_LOG_RAW("bcdUSB: 0x%04x \r\n", hport->device_desc.bcdUSB);
  730. USB_LOG_RAW("bDeviceClass: 0x%02x \r\n", hport->device_desc.bDeviceClass);
  731. USB_LOG_RAW("bDeviceSubClass: 0x%02x \r\n", hport->device_desc.bDeviceSubClass);
  732. USB_LOG_RAW("bDeviceProtocol: 0x%02x \r\n", hport->device_desc.bDeviceProtocol);
  733. USB_LOG_RAW("bMaxPacketSize0: 0x%02x \r\n", hport->device_desc.bMaxPacketSize0);
  734. USB_LOG_RAW("idVendor: 0x%04x \r\n", hport->device_desc.idVendor);
  735. USB_LOG_RAW("idProduct: 0x%04x \r\n", hport->device_desc.idProduct);
  736. USB_LOG_RAW("bcdDevice: 0x%04x \r\n", hport->device_desc.bcdDevice);
  737. USB_LOG_RAW("iManufacturer: 0x%02x \r\n", hport->device_desc.iManufacturer);
  738. USB_LOG_RAW("iProduct: 0x%02x \r\n", hport->device_desc.iProduct);
  739. USB_LOG_RAW("iSerialNumber: 0x%02x \r\n", hport->device_desc.iSerialNumber);
  740. USB_LOG_RAW("bNumConfigurations: 0x%02x\r\n", hport->device_desc.bNumConfigurations);
  741. USB_LOG_RAW("Config Descriptor:\r\n");
  742. USB_LOG_RAW("bLength: 0x%02x \r\n", hport->config.config_desc.bLength);
  743. USB_LOG_RAW("bDescriptorType: 0x%02x \r\n", hport->config.config_desc.bDescriptorType);
  744. USB_LOG_RAW("wTotalLength: 0x%04x \r\n", hport->config.config_desc.wTotalLength);
  745. USB_LOG_RAW("bNumInterfaces: 0x%02x \r\n", hport->config.config_desc.bNumInterfaces);
  746. USB_LOG_RAW("bConfigurationValue: 0x%02x \r\n", hport->config.config_desc.bConfigurationValue);
  747. USB_LOG_RAW("iConfiguration: 0x%02x \r\n", hport->config.config_desc.iConfiguration);
  748. USB_LOG_RAW("bmAttributes: 0x%02x \r\n", hport->config.config_desc.bmAttributes);
  749. USB_LOG_RAW("bMaxPower: 0x%02x \r\n", hport->config.config_desc.bMaxPower);
  750. for (uint8_t i = 0; i < hport->config.config_desc.bNumInterfaces; i++) {
  751. for (uint8_t j = 0; j < hport->config.intf[i].altsetting_num; j++) {
  752. USB_LOG_RAW("\tInterface Descriptor:\r\n");
  753. USB_LOG_RAW("\tbLength: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bLength);
  754. USB_LOG_RAW("\tbDescriptorType: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bDescriptorType);
  755. USB_LOG_RAW("\tbInterfaceNumber: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bInterfaceNumber);
  756. USB_LOG_RAW("\tbAlternateSetting: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bAlternateSetting);
  757. USB_LOG_RAW("\tbNumEndpoints: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bNumEndpoints);
  758. USB_LOG_RAW("\tbInterfaceClass: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bInterfaceClass);
  759. USB_LOG_RAW("\tbInterfaceSubClass: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bInterfaceSubClass);
  760. USB_LOG_RAW("\tbInterfaceProtocol: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bInterfaceProtocol);
  761. USB_LOG_RAW("\tiInterface: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.iInterface);
  762. for (uint8_t k = 0; k < hport->config.intf[i].altsetting[j].intf_desc.bNumEndpoints; k++) {
  763. USB_LOG_RAW("\t\tEndpoint Descriptor:\r\n");
  764. USB_LOG_RAW("\t\tbLength: 0x%02x \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.bLength);
  765. USB_LOG_RAW("\t\tbDescriptorType: 0x%02x \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.bDescriptorType);
  766. USB_LOG_RAW("\t\tbEndpointAddress: 0x%02x \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.bEndpointAddress);
  767. USB_LOG_RAW("\t\tbmAttributes: 0x%02x \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.bmAttributes);
  768. USB_LOG_RAW("\t\twMaxPacketSize: 0x%04x \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.wMaxPacketSize);
  769. USB_LOG_RAW("\t\tbInterval: 0x%02x \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.bInterval);
  770. }
  771. }
  772. }
  773. }
  774. static void usbh_list_device(struct usbh_hub *hub, bool astree, bool verbose, int dev_addr, int vid, int pid)
  775. {
  776. static const char *speed_table[] = {
  777. "UNKNOWN",
  778. "low-speed",
  779. "full-speed",
  780. "high-speed",
  781. "wireless",
  782. "super-speed",
  783. "super-speed-plus",
  784. };
  785. static const char *root_speed_table[] = {
  786. "UNKNOWN",
  787. "1.1",
  788. "1.1",
  789. "2.0",
  790. "2.5",
  791. "3.0",
  792. "3.0",
  793. };
  794. static const uint16_t speed_baud[] = {
  795. 0,
  796. 12,
  797. 12,
  798. 480,
  799. 480,
  800. 5000,
  801. 10000,
  802. };
  803. struct usbh_bus *bus;
  804. struct usbh_hubport *hport;
  805. struct usbh_hub *hub_next;
  806. uint8_t imbuf[64];
  807. uint8_t ipbuf[64];
  808. const char *pimstr;
  809. const char *pipstr;
  810. bool imvalid = false;
  811. bool ipvalid = false;
  812. int ret;
  813. bus = hub->bus;
  814. (void)speed_table;
  815. if (hub->is_roothub) {
  816. if (astree) {
  817. USB_LOG_RAW("/: Bus %02u.Port 1: Dev %u, Class=root_hub, Driver=hcd, %uM\r\n",
  818. bus->busid, hub->hub_addr, speed_baud[hub->speed]);
  819. } else {
  820. if ((dev_addr < 0) || (hub->hub_addr == dev_addr)) {
  821. if (((vid < 0) || (vid == 0xffff)) && ((pid < 0) || (pid == 0xffff))) {
  822. USB_LOG_RAW("Bus %03u Device %03u: ID %04x:%04x %s %s root hub\r\n",
  823. bus->busid, hub->hub_addr, 0xffff, 0xffff,
  824. "Cherry-Embedded", root_speed_table[hub->speed]);
  825. }
  826. }
  827. }
  828. }
  829. for (uint8_t port = 0; port < hub->nports; port++) {
  830. hport = &hub->child[port];
  831. if (hport->connected) {
  832. ret = 0;
  833. if (hport->device_desc.iManufacturer) {
  834. memset(imbuf, 0, sizeof(imbuf));
  835. ret = usbh_get_string_desc(hport, hport->device_desc.iManufacturer, imbuf, sizeof(imbuf));
  836. if (ret == 0) {
  837. imvalid = true;
  838. }
  839. }
  840. if (hport->device_desc.iProduct) {
  841. memset(ipbuf, 0, sizeof(ipbuf));
  842. ret = usbh_get_string_desc(hport, hport->device_desc.iProduct, ipbuf, sizeof(ipbuf));
  843. if (ret == 0) {
  844. ipvalid = true;
  845. }
  846. }
  847. if (imvalid) {
  848. pimstr = (const char *)imbuf;
  849. } else {
  850. pimstr = "Not specified Manufacturer";
  851. }
  852. if (ipvalid) {
  853. pipstr = (const char *)ipbuf;
  854. } else {
  855. pipstr = "Not specified Product";
  856. }
  857. if (!astree) {
  858. if ((dev_addr < 0) || (hport->dev_addr == dev_addr)) {
  859. if (((vid < 0) || (vid == hport->device_desc.idVendor)) && ((pid < 0) || (pid == hport->device_desc.idProduct))) {
  860. USB_LOG_RAW("Bus %03u Device %03u: ID %04x:%04x %s %s\r\n",
  861. bus->busid, hport->dev_addr, hport->device_desc.idVendor, hport->device_desc.idProduct,
  862. pimstr, pipstr);
  863. if (verbose) {
  864. usbh_print_hubport_info(hport);
  865. }
  866. }
  867. }
  868. }
  869. for (uint8_t intf = 0; intf < hport->config.config_desc.bNumInterfaces; intf++) {
  870. if (hport->config.intf[intf].class_driver && hport->config.intf[intf].class_driver->driver_name) {
  871. if (astree) {
  872. for (uint8_t j = 0; j < hub->index; j++) {
  873. USB_LOG_RAW(" ");
  874. }
  875. USB_LOG_RAW("|__ Port %u: Dev %u, If %u, ClassDriver=%s, %uM\r\n",
  876. hport->port, hport->dev_addr, intf, hport->config.intf[intf].class_driver->driver_name, speed_baud[hport->speed]);
  877. }
  878. if (!strcmp(hport->config.intf[intf].class_driver->driver_name, "hub")) {
  879. hub_next = hport->config.intf[intf].priv;
  880. if (hub_next && hub_next->connected) {
  881. usbh_list_device(hub_next, astree, verbose, dev_addr, vid, pid);
  882. }
  883. }
  884. } else if (astree) {
  885. for (uint8_t j = 0; j < hub->index; j++) {
  886. USB_LOG_RAW(" ");
  887. }
  888. USB_LOG_RAW("|__ Port %u: Dev %u, If 0 ClassDriver=none, %uM\r\n",
  889. hport->port, hport->dev_addr, speed_baud[hport->speed]);
  890. }
  891. }
  892. }
  893. }
  894. }
  895. void lsusb_help(void)
  896. {
  897. USB_LOG_RAW("List USB Devices\r\n"
  898. "Usage: lsusb [options]...\r\n"
  899. "\r\n"
  900. "-v, --verbose\r\n"
  901. " - increase verbosity (show descriptors)\r\n"
  902. "-s [[bus]:][dev_addr]\r\n"
  903. " - show only devices with specified device and/or\r\n"
  904. " bus numbers (in decimal)\r\n"
  905. "-d vendor:[product]\r\n"
  906. " - show only devices with the specified vendor and\r\n"
  907. " product ID numbers (in hexadecimal)\r\n"
  908. "-t, --tree\r\n"
  909. " - dump the physical USB device hierarchy as a tree\r\n"
  910. "-V, --version\r\n"
  911. " - show version of the cherryusb\r\n"
  912. "-h, --help\r\n"
  913. " - show usage and help information\r\n");
  914. }
  915. int lsusb(int argc, char **argv)
  916. {
  917. usb_slist_t *bus_list;
  918. struct usbh_bus *bus;
  919. int busid = -1;
  920. int dev_addr = -1;
  921. int vid = -1;
  922. int pid = -1;
  923. bool astree = false;
  924. bool verbose = false;
  925. if (argc < 2) {
  926. lsusb_help();
  927. return 0;
  928. }
  929. while (argc > 1) {
  930. argc--;
  931. argv++;
  932. if (!strcmp(*argv, "-V") || !strcmp(*argv, "--version")) {
  933. USB_LOG_RAW("CherryUSB version %s\r\n", CHERRYUSB_VERSION_STR);
  934. return 0;
  935. } else if (!strcmp(*argv, "-h") || !strcmp(*argv, "--help")) {
  936. lsusb_help();
  937. return 0;
  938. } else if (!strcmp(*argv, "-v") || !strcmp(*argv, "--verbose")) {
  939. verbose = true;
  940. } else if (!strcmp(*argv, "-t") || !strcmp(*argv, "--tree")) {
  941. astree = true;
  942. } else if (!strcmp(*argv, "-s")) {
  943. if (argc > 1) {
  944. argc--;
  945. argv++;
  946. if (*argv[0] == '-') {
  947. continue;
  948. }
  949. char *endptr;
  950. const char *colon = strchr(*argv, ':');
  951. (void)endptr;
  952. if (colon != NULL) {
  953. const char *str;
  954. if (colon > *argv) {
  955. busid = strtol(*argv, &endptr, 10);
  956. }
  957. str = colon + 1;
  958. if (*str != '\0') {
  959. dev_addr = strtol(str, &endptr, 10);
  960. if (dev_addr <= 0 || dev_addr >= 128) {
  961. dev_addr = -1;
  962. }
  963. }
  964. } else {
  965. dev_addr = strtol(*argv, &endptr, 10);
  966. if (dev_addr <= 0 || dev_addr >= 128) {
  967. dev_addr = -1;
  968. }
  969. }
  970. }
  971. } else if (!strcmp(*argv, "-d")) {
  972. if (argc > 1) {
  973. argc--;
  974. argv++;
  975. if (*argv[0] == '-') {
  976. continue;
  977. }
  978. char *endptr;
  979. const char *colon = strchr(*argv, ':');
  980. (void)endptr;
  981. if (colon == NULL) {
  982. continue;
  983. }
  984. const char *str;
  985. vid = strtol(*argv, &endptr, 16);
  986. if (vid < 0 || vid > 0xffff) {
  987. vid = -1;
  988. continue;
  989. }
  990. str = colon + 1;
  991. if (*str != '\0') {
  992. pid = strtol(str, &endptr, 16);
  993. if (pid < 0 || pid > 0xffff) {
  994. pid = -1;
  995. }
  996. }
  997. }
  998. }
  999. }
  1000. if (astree) {
  1001. busid = -1;
  1002. dev_addr = -1;
  1003. vid = -1;
  1004. pid = -1;
  1005. verbose = false;
  1006. }
  1007. usb_slist_for_each(bus_list, &g_bus_head)
  1008. {
  1009. bus = usb_slist_entry(bus_list, struct usbh_bus, list);
  1010. if (busid >= 0) {
  1011. if (bus->busid != busid) {
  1012. continue;
  1013. }
  1014. }
  1015. usbh_list_device(&bus->hcd.roothub, astree, verbose, dev_addr, vid, pid);
  1016. }
  1017. return 0;
  1018. }
  1019. __WEAK uint8_t usbh_get_hport_active_config_index(struct usbh_hubport *hport)
  1020. {
  1021. ARG_UNUSED(hport);
  1022. return 0; // Default to configuration index 0
  1023. }