• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022, sakumisu
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 #include "usbh_core.h"
7 #include "usbh_hub.h"
8 
9 struct usbh_class_info *usbh_class_info_table_begin = NULL;
10 struct usbh_class_info *usbh_class_info_table_end = NULL;
11 
12 USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t ep0_request_buffer[CONFIG_USBHOST_REQUEST_BUFFER_LEN];
13 USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX struct usb_setup_packet g_setup[CONFIG_USBHOST_MAX_EXTHUBS + 1][CONFIG_USBHOST_MAX_EHPORTS];
14 
15 /* general descriptor field offsets */
16 #define DESC_bLength             0 /** Length offset */
17 #define DESC_bDescriptorType     1 /** Descriptor type offset */
18 
19 #define USB_DEV_ADDR_MAX         0x7f
20 #define USB_DEV_ADDR_MARK_OFFSET 5
21 #define USB_DEV_ADDR_MARK_MASK   0x1f
22 
23 struct usbh_devaddr_map {
24     /**
25      * alloctab[0]:addr from 0~31
26      * alloctab[1]:addr from 32~63
27      * alloctab[2]:addr from 64~95
28      * alloctab[3]:addr from 96~127
29      *
30      */
31     uint8_t next;         /* Next device address */
32     uint32_t alloctab[4]; /* Bit allocation table */
33 };
34 
35 struct usbh_bus {
36     struct usbh_devaddr_map devgen;
37 } g_usbh_bus;
38 
usbh_allocate_devaddr(struct usbh_devaddr_map * devgen)39 static int usbh_allocate_devaddr(struct usbh_devaddr_map *devgen)
40 {
41     uint8_t startaddr = devgen->next;
42     uint8_t devaddr;
43     int index;
44     int bitno;
45 
46     for (;;) {
47         devaddr = devgen->next;
48         if (devgen->next >= 0x7f) {
49             devgen->next = 2;
50         } else {
51             devgen->next++;
52         }
53 
54         index = devaddr >> 5;
55         bitno = devaddr & 0x1f;
56         if ((devgen->alloctab[index] & (1 << bitno)) == 0) {
57             devgen->alloctab[index] |= (1 << bitno);
58             return (int)devaddr;
59         }
60 
61         if (startaddr == devaddr) {
62             return -ENOMEM;
63         }
64     }
65 }
66 
usbh_free_devaddr(struct usbh_devaddr_map * devgen,uint8_t devaddr)67 static int usbh_free_devaddr(struct usbh_devaddr_map *devgen, uint8_t devaddr)
68 {
69     int index;
70     int bitno;
71 
72     if ((devaddr > 0) && (devaddr < USB_DEV_ADDR_MAX)) {
73         index = devaddr >> USB_DEV_ADDR_MARK_OFFSET;
74         bitno = devaddr & USB_DEV_ADDR_MARK_MASK;
75 
76         /* Free the address  */
77         if ((devgen->alloctab[index] |= (1 << bitno)) != 0) {
78             devgen->alloctab[index] &= ~(1 << bitno);
79         } else {
80             return -1;
81         }
82 
83         if (devaddr < devgen->next) {
84             devgen->next = devaddr;
85         }
86     }
87 
88     return 0;
89 }
90 
usbh_find_class_driver(uint8_t class,uint8_t subclass,uint8_t protocol,uint16_t vid,uint16_t pid)91 static const struct usbh_class_driver *usbh_find_class_driver(uint8_t class, uint8_t subclass, uint8_t protocol,
92                                                               uint16_t vid, uint16_t pid)
93 {
94     struct usbh_class_info *index = NULL;
95 
96     for (index = usbh_class_info_table_begin; index < usbh_class_info_table_end; index++) {
97         if ((index->match_flags & (USB_CLASS_MATCH_VENDOR | USB_CLASS_MATCH_PRODUCT | USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL)) ==
98             (USB_CLASS_MATCH_VENDOR | USB_CLASS_MATCH_PRODUCT | USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL)) {
99             if (index->vid == vid && index->pid == pid &&
100                 index->class == class && index->subclass == subclass && index->protocol == protocol) {
101                 return index->class_driver;
102             }
103         } else if ((index->match_flags & (USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL)) ==
104                    (USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL)) {
105             if (index->class == class && index->subclass == subclass && index->protocol == protocol) {
106                 return index->class_driver;
107             }
108         } else if ((index->match_flags & (USB_CLASS_MATCH_VENDOR | USB_CLASS_MATCH_PRODUCT | USB_CLASS_MATCH_INTF_CLASS)) ==
109                    (USB_CLASS_MATCH_VENDOR | USB_CLASS_MATCH_PRODUCT | USB_CLASS_MATCH_INTF_CLASS)) {
110             if (index->vid == vid && index->pid == pid && index->class == class) {
111                 return index->class_driver;
112             }
113         } else if ((index->match_flags & (USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS)) == (USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS)) {
114             if (index->class == class && index->subclass == subclass) {
115                 return index->class_driver;
116             }
117         } else if ((index->match_flags & (USB_CLASS_MATCH_INTF_CLASS)) == USB_CLASS_MATCH_INTF_CLASS) {
118             if (index->class == class) {
119                 return index->class_driver;
120             }
121         }
122     }
123     return NULL;
124 }
125 
parse_device_descriptor(struct usbh_hubport * hport,struct usb_device_descriptor * desc,uint16_t length)126 static int parse_device_descriptor(struct usbh_hubport *hport, struct usb_device_descriptor *desc, uint16_t length)
127 {
128     if (desc->bLength != USB_SIZEOF_DEVICE_DESC) {
129         USB_LOG_ERR("invalid device bLength 0x%02x\r\n", desc->bLength);
130         return -EINVAL;
131     } else if (desc->bDescriptorType != USB_DESCRIPTOR_TYPE_DEVICE) {
132         USB_LOG_ERR("unexpected device descriptor 0x%02x\r\n", desc->bDescriptorType);
133         return -EINVAL;
134     } else {
135         if (length <= 8) {
136             return 0;
137         }
138 #if 0
139         USB_LOG_DBG("Device Descriptor:\r\n");
140         USB_LOG_DBG("bLength: 0x%02x           \r\n", desc->bLength);
141         USB_LOG_DBG("bDescriptorType: 0x%02x   \r\n", desc->bDescriptorType);
142         USB_LOG_DBG("bcdUSB: 0x%04x            \r\n", desc->bcdUSB);
143         USB_LOG_DBG("bDeviceClass: 0x%02x      \r\n", desc->bDeviceClass);
144         USB_LOG_DBG("bDeviceSubClass: 0x%02x   \r\n", desc->bDeviceSubClass);
145         USB_LOG_DBG("bDeviceProtocol: 0x%02x   \r\n", desc->bDeviceProtocol);
146         USB_LOG_DBG("bMaxPacketSize0: 0x%02x   \r\n", desc->bMaxPacketSize0);
147         USB_LOG_DBG("idVendor: 0x%04x          \r\n", desc->idVendor);
148         USB_LOG_DBG("idProduct: 0x%04x         \r\n", desc->idProduct);
149         USB_LOG_DBG("bcdDevice: 0x%04x         \r\n", desc->bcdDevice);
150         USB_LOG_DBG("iManufacturer: 0x%02x     \r\n", desc->iManufacturer);
151         USB_LOG_DBG("iProduct: 0x%02x          \r\n", desc->iProduct);
152         USB_LOG_DBG("iSerialNumber: 0x%02x     \r\n", desc->iSerialNumber);
153         USB_LOG_DBG("bNumConfigurations: 0x%02x\r\n", desc->bNumConfigurations);
154 #endif
155         hport->device_desc.bLength = desc->bLength;
156         hport->device_desc.bDescriptorType = desc->bDescriptorType;
157         hport->device_desc.bcdUSB = desc->bcdUSB;
158         hport->device_desc.bDeviceClass = desc->bDeviceClass;
159         hport->device_desc.bDeviceSubClass = desc->bDeviceSubClass;
160         hport->device_desc.bDeviceProtocol = desc->bDeviceProtocol;
161         hport->device_desc.bMaxPacketSize0 = desc->bMaxPacketSize0;
162         hport->device_desc.idVendor = desc->idVendor;
163         hport->device_desc.idProduct = desc->idProduct;
164         hport->device_desc.bcdDevice = desc->bcdDevice;
165         hport->device_desc.iManufacturer = desc->iManufacturer;
166         hport->device_desc.iProduct = desc->iProduct;
167         hport->device_desc.iSerialNumber = desc->iSerialNumber;
168         hport->device_desc.bNumConfigurations = desc->bNumConfigurations;
169     }
170     return 0;
171 }
172 
parse_config_descriptor(struct usbh_hubport * hport,struct usb_configuration_descriptor * desc,uint16_t length)173 static int parse_config_descriptor(struct usbh_hubport *hport, struct usb_configuration_descriptor *desc, uint16_t length)
174 {
175     struct usb_interface_descriptor *intf_desc;
176     struct usb_endpoint_descriptor *ep_desc;
177     uint8_t cur_alt_setting = 0xff;
178     uint8_t cur_iface = 0xff;
179     uint8_t cur_ep = 0xff;
180     uint8_t cur_ep_num = 0xff;
181     uint32_t desc_len = 0;
182     uint8_t *p;
183 
184     if (desc->bLength != USB_SIZEOF_CONFIG_DESC) {
185         USB_LOG_ERR("invalid config bLength 0x%02x\r\n", desc->bLength);
186         return -EINVAL;
187     } else if (desc->bDescriptorType != USB_DESCRIPTOR_TYPE_CONFIGURATION) {
188         USB_LOG_ERR("unexpected config descriptor 0x%02x\r\n", desc->bDescriptorType);
189         return -EINVAL;
190     } else {
191         if (length <= USB_SIZEOF_CONFIG_DESC) {
192             return 0;
193         }
194 #if 0
195         USB_LOG_DBG("Config Descriptor:\r\n");
196         USB_LOG_DBG("bLength: 0x%02x             \r\n", desc->bLength);
197         USB_LOG_DBG("bDescriptorType: 0x%02x     \r\n", desc->bDescriptorType);
198         USB_LOG_DBG("wTotalLength: 0x%04x        \r\n", desc->wTotalLength);
199         USB_LOG_DBG("bNumInterfaces: 0x%02x      \r\n", desc->bNumInterfaces);
200         USB_LOG_DBG("bConfigurationValue: 0x%02x \r\n", desc->bConfigurationValue);
201         USB_LOG_DBG("iConfiguration: 0x%02x      \r\n", desc->iConfiguration);
202         USB_LOG_DBG("bmAttributes: 0x%02x        \r\n", desc->bmAttributes);
203         USB_LOG_DBG("bMaxPower: 0x%02x           \r\n", desc->bMaxPower);
204 #endif
205         hport->config.config_desc.bLength = desc->bLength;
206         hport->config.config_desc.bDescriptorType = desc->bDescriptorType;
207         hport->config.config_desc.wTotalLength = desc->wTotalLength;
208         hport->config.config_desc.bNumInterfaces = desc->bNumInterfaces;
209         hport->config.config_desc.bConfigurationValue = desc->bConfigurationValue;
210         hport->config.config_desc.iConfiguration = desc->iConfiguration;
211         hport->config.config_desc.iConfiguration = desc->iConfiguration;
212         hport->config.config_desc.bmAttributes = desc->bmAttributes;
213         hport->config.config_desc.bMaxPower = desc->bMaxPower;
214 
215         p = (uint8_t *)desc;
216         p += USB_SIZEOF_CONFIG_DESC;
217         desc_len = USB_SIZEOF_CONFIG_DESC;
218 
219         memset(hport->config.intf, 0, sizeof(struct usbh_interface) * CONFIG_USBHOST_MAX_INTERFACES);
220 
221         while (p[DESC_bLength] && (desc_len <= length)) {
222             switch (p[DESC_bDescriptorType]) {
223                 case USB_DESCRIPTOR_TYPE_INTERFACE:
224                     intf_desc = (struct usb_interface_descriptor *)p;
225                     cur_iface = intf_desc->bInterfaceNumber;
226                     cur_alt_setting = intf_desc->bAlternateSetting;
227                     cur_ep_num = intf_desc->bNumEndpoints;
228                     cur_ep = 0;
229                     if (cur_iface > (CONFIG_USBHOST_MAX_INTERFACES - 1)) {
230                         USB_LOG_ERR("Interface num overflow\r\n");
231                         return -ENOMEM;
232                     }
233                     if (cur_alt_setting > (CONFIG_USBHOST_MAX_INTF_ALTSETTINGS - 1)) {
234                         USB_LOG_ERR("Interface altsetting num overflow\r\n");
235                         return -ENOMEM;
236                     }
237                     if (cur_ep_num > CONFIG_USBHOST_MAX_ENDPOINTS) {
238                         USB_LOG_ERR("Endpoint num overflow\r\n");
239                         return -ENOMEM;
240                     }
241 #if 0
242                     USB_LOG_DBG("Interface Descriptor:\r\n");
243                     USB_LOG_DBG("bLength: 0x%02x            \r\n", intf_desc->bLength);
244                     USB_LOG_DBG("bDescriptorType: 0x%02x    \r\n", intf_desc->bDescriptorType);
245                     USB_LOG_DBG("bInterfaceNumber: 0x%02x   \r\n", intf_desc->bInterfaceNumber);
246                     USB_LOG_DBG("bAlternateSetting: 0x%02x  \r\n", intf_desc->bAlternateSetting);
247                     USB_LOG_DBG("bNumEndpoints: 0x%02x      \r\n", intf_desc->bNumEndpoints);
248                     USB_LOG_DBG("bInterfaceClass: 0x%02x    \r\n", intf_desc->bInterfaceClass);
249                     USB_LOG_DBG("bInterfaceSubClass: 0x%02x \r\n", intf_desc->bInterfaceSubClass);
250                     USB_LOG_DBG("bInterfaceProtocol: 0x%02x \r\n", intf_desc->bInterfaceProtocol);
251                     USB_LOG_DBG("iInterface: 0x%02x         \r\n", intf_desc->iInterface);
252 #endif
253                     memcpy(&hport->config.intf[cur_iface].altsetting[cur_alt_setting].intf_desc, intf_desc, 9);
254                     hport->config.intf[cur_iface].altsetting_num = cur_alt_setting + 1;
255                     break;
256                 case USB_DESCRIPTOR_TYPE_ENDPOINT:
257                     ep_desc = (struct usb_endpoint_descriptor *)p;
258                     memcpy(&hport->config.intf[cur_iface].altsetting[cur_alt_setting].ep[cur_ep].ep_desc, ep_desc, 7);
259                     cur_ep++;
260                     break;
261 
262                 default:
263                     break;
264             }
265             /* skip to next descriptor */
266             p += p[DESC_bLength];
267             desc_len += p[DESC_bLength];
268         }
269     }
270     return 0;
271 }
272 
usbh_print_hubport_info(struct usbh_hubport * hport)273 static void usbh_print_hubport_info(struct usbh_hubport *hport)
274 {
275     USB_LOG_RAW("Device Descriptor:\r\n");
276     USB_LOG_RAW("bLength: 0x%02x           \r\n", hport->device_desc.bLength);
277     USB_LOG_RAW("bDescriptorType: 0x%02x   \r\n", hport->device_desc.bDescriptorType);
278     USB_LOG_RAW("bcdUSB: 0x%04x            \r\n", hport->device_desc.bcdUSB);
279     USB_LOG_RAW("bDeviceClass: 0x%02x      \r\n", hport->device_desc.bDeviceClass);
280     USB_LOG_RAW("bDeviceSubClass: 0x%02x   \r\n", hport->device_desc.bDeviceSubClass);
281     USB_LOG_RAW("bDeviceProtocol: 0x%02x   \r\n", hport->device_desc.bDeviceProtocol);
282     USB_LOG_RAW("bMaxPacketSize0: 0x%02x   \r\n", hport->device_desc.bMaxPacketSize0);
283     USB_LOG_RAW("idVendor: 0x%04x          \r\n", hport->device_desc.idVendor);
284     USB_LOG_RAW("idProduct: 0x%04x         \r\n", hport->device_desc.idProduct);
285     USB_LOG_RAW("bcdDevice: 0x%04x         \r\n", hport->device_desc.bcdDevice);
286     USB_LOG_RAW("iManufacturer: 0x%02x     \r\n", hport->device_desc.iManufacturer);
287     USB_LOG_RAW("iProduct: 0x%02x          \r\n", hport->device_desc.iProduct);
288     USB_LOG_RAW("iSerialNumber: 0x%02x     \r\n", hport->device_desc.iSerialNumber);
289     USB_LOG_RAW("bNumConfigurations: 0x%02x\r\n", hport->device_desc.bNumConfigurations);
290 
291     USB_LOG_RAW("Config Descriptor:\r\n");
292     USB_LOG_RAW("bLength: 0x%02x             \r\n", hport->config.config_desc.bLength);
293     USB_LOG_RAW("bDescriptorType: 0x%02x     \r\n", hport->config.config_desc.bDescriptorType);
294     USB_LOG_RAW("wTotalLength: 0x%04x        \r\n", hport->config.config_desc.wTotalLength);
295     USB_LOG_RAW("bNumInterfaces: 0x%02x      \r\n", hport->config.config_desc.bNumInterfaces);
296     USB_LOG_RAW("bConfigurationValue: 0x%02x \r\n", hport->config.config_desc.bConfigurationValue);
297     USB_LOG_RAW("iConfiguration: 0x%02x      \r\n", hport->config.config_desc.iConfiguration);
298     USB_LOG_RAW("bmAttributes: 0x%02x        \r\n", hport->config.config_desc.bmAttributes);
299     USB_LOG_RAW("bMaxPower: 0x%02x           \r\n", hport->config.config_desc.bMaxPower);
300 
301     for (uint8_t i = 0; i < hport->config.config_desc.bNumInterfaces; i++) {
302         for (uint8_t j = 0; j < hport->config.intf[i].altsetting_num; j++) {
303             USB_LOG_RAW("Interface Descriptor:\r\n");
304             USB_LOG_RAW("bLength: 0x%02x            \r\n", hport->config.intf[i].altsetting[j].intf_desc.bLength);
305             USB_LOG_RAW("bDescriptorType: 0x%02x    \r\n", hport->config.intf[i].altsetting[j].intf_desc.bDescriptorType);
306             USB_LOG_RAW("bInterfaceNumber: 0x%02x   \r\n", hport->config.intf[i].altsetting[j].intf_desc.bInterfaceNumber);
307             USB_LOG_RAW("bAlternateSetting: 0x%02x  \r\n", hport->config.intf[i].altsetting[j].intf_desc.bAlternateSetting);
308             USB_LOG_RAW("bNumEndpoints: 0x%02x      \r\n", hport->config.intf[i].altsetting[j].intf_desc.bNumEndpoints);
309             USB_LOG_RAW("bInterfaceClass: 0x%02x    \r\n", hport->config.intf[i].altsetting[j].intf_desc.bInterfaceClass);
310             USB_LOG_RAW("bInterfaceSubClass: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bInterfaceSubClass);
311             USB_LOG_RAW("bInterfaceProtocol: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bInterfaceProtocol);
312             USB_LOG_RAW("iInterface: 0x%02x         \r\n", hport->config.intf[i].altsetting[j].intf_desc.iInterface);
313 
314             for (uint8_t k = 0; k < hport->config.intf[i].altsetting[j].intf_desc.bNumEndpoints; k++) {
315                 USB_LOG_RAW("Endpoint Descriptor:\r\n");
316                 USB_LOG_RAW("bLength: 0x%02x          \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.bLength);
317                 USB_LOG_RAW("bDescriptorType: 0x%02x  \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.bDescriptorType);
318                 USB_LOG_RAW("bEndpointAddress: 0x%02x \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.bEndpointAddress);
319                 USB_LOG_RAW("bmAttributes: 0x%02x     \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.bmAttributes);
320                 USB_LOG_RAW("wMaxPacketSize: 0x%04x   \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.wMaxPacketSize);
321                 USB_LOG_RAW("bInterval: 0x%02x        \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.bInterval);
322             }
323         }
324     }
325 }
326 
usbh_get_default_mps(int speed)327 static int usbh_get_default_mps(int speed)
328 {
329     switch (speed) {
330         case USB_SPEED_LOW: /* For low speed, we use 8 bytes */
331             return 8;
332         case USB_SPEED_FULL: /* For full or high speed, we use 64 bytes */
333         case USB_SPEED_HIGH:
334             return 64;
335         case USB_SPEED_SUPER: /* For super speed , we must use 512 bytes */
336         case USB_SPEED_SUPER_PLUS:
337             return 512;
338         default:
339             return 64;
340     }
341 }
342 
usbh_hport_activate_ep0(struct usbh_hubport * hport)343 int usbh_hport_activate_ep0(struct usbh_hubport *hport)
344 {
345     struct usbh_endpoint_cfg ep0_cfg = { 0 };
346 
347     ep0_cfg.ep_addr = 0x00;
348     ep0_cfg.ep_interval = 0x00;
349     ep0_cfg.ep_mps = usbh_get_default_mps(hport->speed);
350     ep0_cfg.ep_type = USB_ENDPOINT_TYPE_CONTROL;
351     ep0_cfg.hport = hport;
352 
353     usbh_pipe_alloc(&hport->ep0, &ep0_cfg);
354     return 0;
355 }
356 
usbh_hport_deactivate_ep0(struct usbh_hubport * hport)357 int usbh_hport_deactivate_ep0(struct usbh_hubport *hport)
358 {
359 #ifndef CONFIG_USBHOST_XHCI
360     if (hport->dev_addr > 0) {
361         usbh_free_devaddr(&g_usbh_bus.devgen, hport->dev_addr);
362     }
363 #endif
364     if (hport->ep0) {
365         usbh_pipe_free(hport->ep0);
366     }
367 
368     hport->ep0 = NULL;
369     hport->dev_addr = 0;
370     return 0;
371 }
372 
usbh_hport_activate_epx(usbh_pipe_t * pipe,struct usbh_hubport * hport,struct usb_endpoint_descriptor * ep_desc)373 int usbh_hport_activate_epx(usbh_pipe_t *pipe, struct usbh_hubport *hport, struct usb_endpoint_descriptor *ep_desc)
374 {
375     struct usbh_endpoint_cfg ep_cfg = { 0 };
376 
377     ep_cfg.ep_addr = ep_desc->bEndpointAddress;
378     ep_cfg.ep_type = ep_desc->bmAttributes & USB_ENDPOINT_TYPE_MASK;
379     ep_cfg.ep_mps = ep_desc->wMaxPacketSize & USB_MAXPACKETSIZE_MASK;
380     ep_cfg.ep_interval = ep_desc->bInterval;
381     ep_cfg.mult = (ep_desc->wMaxPacketSize & USB_MAXPACKETSIZE_ADDITIONAL_TRANSCATION_MASK) >> USB_MAXPACKETSIZE_ADDITIONAL_TRANSCATION_SHIFT;
382     ep_cfg.hport = hport;
383 
384     USB_LOG_INFO("Ep=%02x Attr=%02u Mps=%d Interval=%02u Mult=%02u\r\n",
385                  ep_cfg.ep_addr,
386                  ep_desc->bmAttributes,
387                  ep_cfg.ep_mps,
388                  ep_cfg.ep_interval,
389                  ep_cfg.mult);
390 
391     return usbh_pipe_alloc(pipe, &ep_cfg);
392 }
393 
usbh_get_string_desc(struct usbh_hubport * hport,uint8_t index,uint8_t * output)394 int usbh_get_string_desc(struct usbh_hubport *hport, uint8_t index, uint8_t *output)
395 {
396     struct usb_setup_packet *setup = hport->setup;
397     int ret;
398     uint8_t *src;
399     uint8_t *dst;
400     uint16_t len;
401     uint16_t i = 2;
402     uint16_t j = 0;
403 
404     /* Get Manufacturer string */
405     setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_DEVICE;
406     setup->bRequest = USB_REQUEST_GET_DESCRIPTOR;
407     setup->wValue = (uint16_t)((USB_DESCRIPTOR_TYPE_STRING << 8) | index);
408     setup->wIndex = 0x0409;
409     setup->wLength = 255;
410 
411     ret = usbh_control_transfer(hport->ep0, setup, ep0_request_buffer);
412     if (ret < 0) {
413         return ret;
414     }
415 
416     src = ep0_request_buffer;
417     dst = output;
418     len = src[0];
419 
420     while (i < len) {
421         dst[j] = src[i];
422         i += 2;
423         j++;
424     }
425 
426     return 0;
427 }
428 
usbh_set_interface(struct usbh_hubport * hport,uint8_t intf,uint8_t altsetting)429 int usbh_set_interface(struct usbh_hubport *hport, uint8_t intf, uint8_t altsetting)
430 {
431     struct usb_setup_packet *setup = hport->setup;
432 
433     setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_INTERFACE;
434     setup->bRequest = USB_REQUEST_SET_INTERFACE;
435     setup->wValue = altsetting;
436     setup->wIndex = intf;
437     setup->wLength = 0;
438 
439     return usbh_control_transfer(hport->ep0, setup, NULL);
440 }
441 
usbh_enumerate(struct usbh_hubport * hport)442 int usbh_enumerate(struct usbh_hubport *hport)
443 {
444     struct usb_interface_descriptor *intf_desc;
445     struct usb_setup_packet *setup;
446     struct usb_device_descriptor *dev_desc;
447     int dev_addr;
448     uint16_t ep_mps;
449     int ret;
450 
451     hport->setup = &g_setup[hport->parent->index - 1][hport->port - 1];
452     setup = hport->setup;
453 
454     /* Read the first 8 bytes of the device descriptor */
455     setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_DEVICE;
456     setup->bRequest = USB_REQUEST_GET_DESCRIPTOR;
457     setup->wValue = (uint16_t)((USB_DESCRIPTOR_TYPE_DEVICE << 8) | 0);
458     setup->wIndex = 0;
459     setup->wLength = 8;
460 
461     ret = usbh_control_transfer(hport->ep0, setup, ep0_request_buffer);
462     if (ret < 0) {
463         USB_LOG_ERR("Failed to get device descriptor,errorcode:%d\r\n", ret);
464         goto errout;
465     }
466 
467     parse_device_descriptor(hport, (struct usb_device_descriptor *)ep0_request_buffer, 8);
468 
469     /* Extract the correct max packetsize from the device descriptor */
470     dev_desc = (struct usb_device_descriptor *)ep0_request_buffer;
471     if (dev_desc->bcdUSB >= USB_3_0) {
472         ep_mps = 1 << dev_desc->bMaxPacketSize0;
473     } else {
474         ep_mps = dev_desc->bMaxPacketSize0;
475     }
476 
477     USB_LOG_DBG("Device rev=%04x cls=%02x sub=%02x proto=%02x size=%d\r\n",
478                 dev_desc->bcdUSB, dev_desc->bDeviceClass, dev_desc->bDeviceSubClass,
479                 dev_desc->bDeviceProtocol, ep_mps);
480 
481     /* Reconfigure EP0 with the correct maximum packet size */
482     usbh_ep_pipe_reconfigure(hport->ep0, 0, ep_mps, 0);
483 
484 #ifdef CONFIG_USBHOST_XHCI
485     extern int usbh_get_xhci_devaddr(usbh_pipe_t * pipe);
486 
487     /* Assign a function address to the device connected to this port */
488     dev_addr = usbh_get_xhci_devaddr(hport->ep0);
489     if (dev_addr < 0) {
490         USB_LOG_ERR("Failed to allocate devaddr,errorcode:%d\r\n", ret);
491         goto errout;
492     }
493 #else
494     /* Assign a function address to the device connected to this port */
495     dev_addr = usbh_allocate_devaddr(&g_usbh_bus.devgen);
496     if (dev_addr < 0) {
497         USB_LOG_ERR("Failed to allocate devaddr,errorcode:%d\r\n", ret);
498         goto errout;
499     }
500 #endif
501 
502     /* Set the USB device address */
503     setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_DEVICE;
504     setup->bRequest = USB_REQUEST_SET_ADDRESS;
505     setup->wValue = dev_addr;
506     setup->wIndex = 0;
507     setup->wLength = 0;
508 
509     ret = usbh_control_transfer(hport->ep0, setup, NULL);
510     if (ret < 0) {
511         USB_LOG_ERR("Failed to set devaddr,errorcode:%d\r\n", ret);
512         goto errout;
513     }
514 
515     /* Wait device set address completely */
516     usb_osal_msleep(2);
517 
518     /* Assign the function address to the port */
519     hport->dev_addr = dev_addr;
520 
521     /* And reconfigure EP0 with the correct address */
522     usbh_ep_pipe_reconfigure(hport->ep0, dev_addr, ep_mps, 0);
523 
524     /* Read the full device descriptor */
525     setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_DEVICE;
526     setup->bRequest = USB_REQUEST_GET_DESCRIPTOR;
527     setup->wValue = (uint16_t)((USB_DESCRIPTOR_TYPE_DEVICE << 8) | 0);
528     setup->wIndex = 0;
529     setup->wLength = USB_SIZEOF_DEVICE_DESC;
530 
531     ret = usbh_control_transfer(hport->ep0, setup, ep0_request_buffer);
532     if (ret < 0) {
533         USB_LOG_ERR("Failed to get full device descriptor,errorcode:%d\r\n", ret);
534         goto errout;
535     }
536 
537     parse_device_descriptor(hport, (struct usb_device_descriptor *)ep0_request_buffer, USB_SIZEOF_DEVICE_DESC);
538     USB_LOG_INFO("New device found,idVendor:%04x,idProduct:%04x,bcdDevice:%04x\r\n",
539                  ((struct usb_device_descriptor *)ep0_request_buffer)->idVendor,
540                  ((struct usb_device_descriptor *)ep0_request_buffer)->idProduct,
541                  ((struct usb_device_descriptor *)ep0_request_buffer)->bcdDevice);
542 
543     /* Read the first 9 bytes of the config descriptor */
544     setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_DEVICE;
545     setup->bRequest = USB_REQUEST_GET_DESCRIPTOR;
546     setup->wValue = (uint16_t)((USB_DESCRIPTOR_TYPE_CONFIGURATION << 8) | 0);
547     setup->wIndex = 0;
548     setup->wLength = USB_SIZEOF_CONFIG_DESC;
549 
550     ret = usbh_control_transfer(hport->ep0, setup, ep0_request_buffer);
551     if (ret < 0) {
552         USB_LOG_ERR("Failed to get config descriptor,errorcode:%d\r\n", ret);
553         goto errout;
554     }
555 
556     parse_config_descriptor(hport, (struct usb_configuration_descriptor *)ep0_request_buffer, USB_SIZEOF_CONFIG_DESC);
557 
558     /* Read the full size of the configuration data */
559     uint16_t wTotalLength = ((struct usb_configuration_descriptor *)ep0_request_buffer)->wTotalLength;
560 
561     setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_DEVICE;
562     setup->bRequest = USB_REQUEST_GET_DESCRIPTOR;
563     setup->wValue = (uint16_t)((USB_DESCRIPTOR_TYPE_CONFIGURATION << 8) | 0);
564     setup->wIndex = 0;
565     setup->wLength = wTotalLength;
566 
567     ret = usbh_control_transfer(hport->ep0, setup, ep0_request_buffer);
568     if (ret < 0) {
569         USB_LOG_ERR("Failed to get full config descriptor,errorcode:%d\r\n", ret);
570         goto errout;
571     }
572 
573     ret = parse_config_descriptor(hport, (struct usb_configuration_descriptor *)ep0_request_buffer, wTotalLength);
574     if (ret < 0) {
575         USB_LOG_ERR("Parse config fail\r\n");
576         goto errout;
577     }
578     USB_LOG_INFO("The device has %d interfaces\r\n", ((struct usb_configuration_descriptor *)ep0_request_buffer)->bNumInterfaces);
579     hport->raw_config_desc = usb_malloc(wTotalLength);
580     if (hport->raw_config_desc == NULL) {
581         ret = -ENOMEM;
582         USB_LOG_ERR("No memory to alloc for raw_config_desc\r\n");
583         goto errout;
584     }
585     memcpy(hport->raw_config_desc, ep0_request_buffer, wTotalLength);
586 #ifdef CONFIG_USBHOST_GET_STRING_DESC
587     uint8_t string_buffer[128];
588 
589     /* Get Manufacturer string */
590     memset(string_buffer, 0, 128);
591     ret = usbh_get_string_desc(hport, USB_STRING_MFC_INDEX, string_buffer);
592     if (ret < 0) {
593         USB_LOG_ERR("Failed to get Manufacturer string,errorcode:%d\r\n", ret);
594         goto errout;
595     }
596 
597     USB_LOG_INFO("Manufacturer: %s\r\n", string_buffer);
598 
599     /* Get Product string */
600     memset(string_buffer, 0, 128);
601     ret = usbh_get_string_desc(hport, USB_STRING_PRODUCT_INDEX, string_buffer);
602     if (ret < 0) {
603         USB_LOG_ERR("Failed to get get Product string,errorcode:%d\r\n", ret);
604         goto errout;
605     }
606 
607     USB_LOG_INFO("Product: %s\r\n", string_buffer);
608 
609     /* Get SerialNumber string */
610     memset(string_buffer, 0, 128);
611     ret = usbh_get_string_desc(hport, USB_STRING_SERIAL_INDEX, string_buffer);
612     if (ret < 0) {
613         USB_LOG_ERR("Failed to get get SerialNumber string,errorcode:%d\r\n", ret);
614         goto errout;
615     }
616 
617     USB_LOG_INFO("SerialNumber: %s\r\n", string_buffer);
618 #endif
619     /* Select device configuration 1 */
620     setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_DEVICE;
621     setup->bRequest = USB_REQUEST_SET_CONFIGURATION;
622     setup->wValue = 1;
623     setup->wIndex = 0;
624     setup->wLength = 0;
625 
626     ret = usbh_control_transfer(hport->ep0, setup, NULL);
627     if (ret < 0) {
628         USB_LOG_ERR("Failed to set configuration,errorcode:%d\r\n", ret);
629         goto errout;
630     }
631 
632 #ifdef CONFIG_USBHOST_MSOS_ENABLE
633     setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE;
634     setup->bRequest = CONFIG_USBHOST_MSOS_VENDOR_CODE;
635     setup->wValue = 0;
636     setup->wIndex = 0x0004;
637     setup->wLength = 16;
638 
639     ret = usbh_control_transfer(hport, setup, ep0_request_buffer);
640     if (ret < 0 && (ret != -EPERM)) {
641         USB_LOG_ERR("Failed to get msosv1 compat id,errorcode:%d\r\n", ret);
642         goto errout;
643     }
644 #endif
645     USB_LOG_INFO("Enumeration success, start loading class driver\r\n");
646     /*search supported class driver*/
647     for (uint8_t i = 0; i < hport->config.config_desc.bNumInterfaces; i++) {
648         intf_desc = &hport->config.intf[i].altsetting[0].intf_desc;
649 
650         struct usbh_class_driver *class_driver = (struct usbh_class_driver *)usbh_find_class_driver(intf_desc->bInterfaceClass, intf_desc->bInterfaceSubClass, intf_desc->bInterfaceProtocol, hport->device_desc.idVendor, hport->device_desc.idProduct);
651 
652         if (class_driver == NULL) {
653             USB_LOG_ERR("do not support Class:0x%02x,Subclass:0x%02x,Protocl:0x%02x\r\n",
654                         intf_desc->bInterfaceClass,
655                         intf_desc->bInterfaceSubClass,
656                         intf_desc->bInterfaceProtocol);
657 
658             continue;
659         }
660         hport->config.intf[i].class_driver = class_driver;
661         USB_LOG_INFO("Loading %s class driver\r\n", class_driver->driver_name);
662         ret = CLASS_CONNECT(hport, i);
663     }
664 
665 errout:
666     if (hport->raw_config_desc) {
667         usb_free(hport->raw_config_desc);
668         hport->raw_config_desc = NULL;
669     }
670     return ret;
671 }
672 
usbh_find_class_instance(const char * devname)673 void *usbh_find_class_instance(const char *devname)
674 {
675     struct usbh_hubport *hport;
676     usb_slist_t *hub_list;
677 
678     usb_slist_for_each(hub_list, &hub_class_head)
679     {
680         struct usbh_hub *hub = usb_slist_entry(hub_list, struct usbh_hub, list);
681         for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) {
682             hport = &hub->child[port];
683             if (hport->connected) {
684                 for (uint8_t itf = 0; itf < hport->config.config_desc.bNumInterfaces; itf++) {
685                     if ((strncmp(hport->config.intf[itf].devname, devname, CONFIG_USBHOST_DEV_NAMELEN) == 0) && hport->config.intf[itf].priv)
686                         return hport->config.intf[itf].priv;
687                 }
688             }
689         }
690     }
691     return NULL;
692 }
693 
usbh_initialize(void)694 int usbh_initialize(void)
695 {
696     memset(&g_usbh_bus, 0, sizeof(struct usbh_bus));
697 
698 #ifdef __ARMCC_VERSION /* ARM C Compiler */
699     extern const int usbh_class_info$$Base;
700     extern const int usbh_class_info$$Limit;
701     usbh_class_info_table_begin = (struct usbh_class_info *)&usbh_class_info$$Base;
702     usbh_class_info_table_end = (struct usbh_class_info *)&usbh_class_info$$Limit;
703 #elif defined(__GNUC__)
704     extern uint32_t __usbh_class_info_start__;
705     extern uint32_t __usbh_class_info_end__;
706     usbh_class_info_table_begin = (struct usbh_class_info *)&__usbh_class_info_start__;
707     usbh_class_info_table_end = (struct usbh_class_info *)&__usbh_class_info_end__;
708 #elif defined(__ICCARM__) || defined(__ICCRX__)
709     usbh_class_info_table_begin = (struct usbh_class_info *)__section_begin("usbh_class_info");
710     usbh_class_info_table_end = (struct usbh_class_info *)__section_end("usbh_class_info");
711 #endif
712 
713     /* devaddr 1 is for roothub */
714     g_usbh_bus.devgen.next = 2;
715 
716     usbh_hub_initialize();
717     return 0;
718 }
719 
usbh_control_transfer(usbh_pipe_t pipe,struct usb_setup_packet * setup,uint8_t * buffer)720 int usbh_control_transfer(usbh_pipe_t pipe, struct usb_setup_packet *setup, uint8_t *buffer)
721 {
722     struct usbh_urb *urb;
723     int ret;
724 
725     urb = usb_malloc(sizeof(struct usbh_urb));
726     memset(urb, 0, sizeof(struct usbh_urb));
727 
728     usbh_control_urb_fill(urb, pipe, setup, buffer, setup->wLength, CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT, NULL, NULL);
729 
730     ret = usbh_submit_urb(urb);
731     if (ret == 0) {
732         ret = urb->actual_length;
733     }
734     usb_free(urb);
735     return ret;
736 }
737 
lsusb(int argc,char ** argv)738 int lsusb(int argc, char **argv)
739 {
740     usb_slist_t *i;
741     struct usbh_hubport *hport;
742 
743     if (argc < 2) {
744         USB_LOG_RAW("Usage: lsusb [options]...\r\n");
745         USB_LOG_RAW("List USB devices\r\n");
746         USB_LOG_RAW("  -v, --verbose\r\n");
747         USB_LOG_RAW("      Increase verbosity (show descriptors)\r\n");
748         // USB_LOG_RAW("  -s [[bus]:[devnum]]\r\n");
749         // USB_LOG_RAW("      Show only devices with specified device and/or bus numbers (in decimal)\r\n");
750         // USB_LOG_RAW("  -d vendor:[product]\r\n");
751         // USB_LOG_RAW("      Show only devices with the specified vendor and product ID numbers (in hexadecimal)\r\n");
752         USB_LOG_RAW("  -t, --tree\r\n");
753         USB_LOG_RAW("      Dump the physical USB device hierachy as a tree\r\n");
754         USB_LOG_RAW("  -V, --version\r\n");
755         USB_LOG_RAW("      Show version of program\r\n");
756         USB_LOG_RAW("  -h, --help\r\n");
757         USB_LOG_RAW("      Show usage and help\r\n");
758         return 0;
759     }
760     if (argc > 3) {
761         return 0;
762     }
763 
764     if (strcmp(argv[1], "-t") == 0) {
765         usb_slist_for_each(i, &hub_class_head)
766         {
767             struct usbh_hub *hub = usb_slist_entry(i, struct usbh_hub, list);
768 
769             if (hub->is_roothub) {
770                 USB_LOG_RAW("/: Hub %02u, ports=%u, is roothub\r\n", hub->index, hub->hub_desc.bNbrPorts);
771             } else {
772                 USB_LOG_RAW("/: Hub %02u, ports=%u, mounted on Hub %02u:Port %u\r\n",
773                             hub->index,
774                             hub->hub_desc.bNbrPorts,
775                             hub->parent->parent->index,
776                             hub->parent->port);
777             }
778 
779             for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) {
780                 hport = &hub->child[port];
781                 if (hport->connected) {
782                     for (uint8_t i = 0; i < hport->config.config_desc.bNumInterfaces; i++) {
783                         if (hport->config.intf[i].class_driver->driver_name) {
784                             USB_LOG_RAW("    |__Port %u,Port addr:0x%02x,If %u,ClassDriver=%s\r\n",
785                                         hport->port,
786                                         hport->dev_addr,
787                                         i,
788                                         hport->config.intf[i].class_driver->driver_name);
789                         }
790                     }
791                 }
792             }
793         }
794     }
795 
796     if (strcmp(argv[1], "-v") == 0) {
797         usb_slist_for_each(i, &hub_class_head)
798         {
799             struct usbh_hub *hub = usb_slist_entry(i, struct usbh_hub, list);
800             for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) {
801                 hport = &hub->child[port];
802                 if (hport->connected) {
803                     USB_LOG_RAW("Hub %02u,Port %u,Port addr:0x%02x,VID:PID 0x%04x:0x%04x\r\n",
804                                 hub->index,
805                                 hport->port,
806                                 hport->dev_addr,
807                                 hport->device_desc.idVendor,
808                                 hport->device_desc.idProduct);
809                     usbh_print_hubport_info(hport);
810                 }
811             }
812         }
813     }
814 
815     return 0;
816 }
817