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