usbh_core.c 46 KB

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