M4521_BSP V3.02.000
The Board Support Package for M4521
usbh_core.c
Go to the documentation of this file.
1/*
2 * drivers/usb/usb.c
3 *
4 * (C) Copyright Linus Torvalds 1999
5 * (C) Copyright Johannes Erdfelt 1999
6 * (C) Copyright Andreas Gal 1999
7 * (C) Copyright Gregory P. Smith 1999
8 * (C) Copyright Deti Fliegl 1999 (new USB architecture)
9 * (C) Copyright Randy Dunlap 2000
10 * (C) Copyright David Brownell 2000 (kernel hotplug, usb_device_id)
11 * (C) Copyright Yggdrasil Computing, Inc. 2000
12 * (usb_device_id matching changes by Adam J. Richter)
13 *
14 * NOTE! This is not actually a driver at all, rather this is
15 * just a collection of helper routines that implement the
16 * generic USB things that the real drivers can use..
17 *
18 * Think of this as a "USB library" rather than anything else.
19 * It should be considered a slave, with no callbacks. Callbacks
20 * are evil.
21 *
22 * $Id: usb.c,v 1.53 2000/01/14 16:19:09 acher Exp $
23 */
24
25/**************************************************************************/
35#include <stdio.h>
36#include <string.h>
37
38#include "M4521.h"
39#include "usbh_core.h"
40#include "usbh_ohci.h"
41
56
57extern USB_DEV_T g_dev_pool[DEV_MAX_NUM];
58extern uint8_t dev_alloc_mark[DEV_MAX_NUM];
59
60static volatile uint32_t g_devmap;
61
62/*
63 * We have a per-interface "registered driver" list.
64 */
65LIST_HEAD(_UsbDriverList);
66LIST_HEAD(_UsbBusList);
67
69
70
78int32_t USBH_RegisterDriver(USB_DRIVER_T *new_driver)
79{
80 /* Add it to the list of known drivers */
81 list_add_tail(&new_driver->driver_list, &_UsbDriverList);
82 return 0;
83}
84
86
87const USB_DEV_ID_T *usb_match_id(USB_DEV_T *dev, USB_IF_DESC_T *intf,
88 const USB_DEV_ID_T *id)
89{
90 /* proc_connectinfo in devio.c may call us with id == NULL. */
91 if(id == NULL)
92 return NULL;
93
94 /*
95 * It is important to check that id->driver_info is nonzero,
96 * since an entry that is all zeroes except for a nonzero
97 * id->driver_info is the way to create an entry that indicates
98 * that the driver want to examine every device and interface.
99 */
100 for(; id->idVendor || id->bDeviceClass || id->bInterfaceClass || id->driver_info; id++)
101 {
102 if((id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) &&
103 (id->idVendor != dev->descriptor.idVendor))
104 continue;
105
106 if((id->match_flags & USB_DEVICE_ID_MATCH_PRODUCT) &&
107 (id->idProduct != dev->descriptor.idProduct))
108 continue;
109
110 /* No need to test id->bcdDevice_lo != 0, since 0 is never
111 greater than any unsigned number. */
112 if((id->match_flags & USB_DEVICE_ID_MATCH_DEV_LO) &&
113 (id->bcdDevice_lo > dev->descriptor.bcdDevice))
114 continue;
115
116 if((id->match_flags & USB_DEVICE_ID_MATCH_DEV_HI) &&
117 (id->bcdDevice_hi < dev->descriptor.bcdDevice))
118 continue;
119
120 if((id->match_flags & USB_DEVICE_ID_MATCH_DEV_CLASS) &&
121 (id->bDeviceClass != dev->descriptor.bDeviceClass))
122 continue;
123
124 if((id->match_flags & USB_DEVICE_ID_MATCH_DEV_SUBCLASS) &&
125 (id->bDeviceSubClass != dev->descriptor.bDeviceSubClass))
126 continue;
127
128 if((id->match_flags & USB_DEVICE_ID_MATCH_DEV_PROTOCOL) &&
129 (id->bDeviceProtocol != dev->descriptor.bDeviceProtocol))
130 continue;
131
132 if((id->match_flags & USB_DEVICE_ID_MATCH_INT_CLASS) &&
133 (id->bInterfaceClass != intf->bInterfaceClass))
134 continue;
135
136 if((id->match_flags & USB_DEVICE_ID_MATCH_INT_SUBCLASS) &&
137 (id->bInterfaceSubClass != intf->bInterfaceSubClass))
138 continue;
139
140 if((id->match_flags & USB_DEVICE_ID_MATCH_INT_PROTOCOL) &&
141 (id->bInterfaceProtocol != intf->bInterfaceProtocol))
142 continue;
143 return id;
144 }
145 return NULL;
146}
147
148
149/*
150 * This entrypoint gets called for each new device.
151 *
152 * We now walk the list of registered USB drivers,
153 * looking for one that will accept this interface.
154 *
155 * "New Style" drivers use a table describing the devices and interfaces
156 * they handle. Those tables are available to user mode tools deciding
157 * whether to load driver modules for a new device.
158 *
159 * The probe return value is changed to be a private pointer. This way
160 * the drivers don't have to dig around in our structures to set the
161 * private pointer if they only need one interface.
162 *
163 * Returns: 0 if a driver accepted the interface, -1 otherwise
164 */
165static int usb_find_interface_driver(USB_DEV_T *dev, USB_IF_DESC_T *intf)
166{
167 USB_LIST_T *tmp;
168 const USB_DEV_ID_T *id;
169 USB_DRIVER_T *driver;
170 int i, found;
171
172 for(tmp = _UsbDriverList.next; tmp != &_UsbDriverList;) /* search through the driver list */
173 {
174 driver = list_entry(tmp, USB_DRIVER_T, driver_list);
175 tmp = tmp->next;
176
177 id = driver->id_table;
178 id = usb_match_id(dev, intf, id);
179 if(id)
180 {
181 if(driver->probe(dev, intf, id) == 0)
182 {
183 /*
184 * Add driver to driver list of this device.
185 */
186 for(found = 0, i = 0; i < dev->driver_cnt; i++)
187 if(dev->driver[i] == driver) found = 1;
188
189 if(!found)
190 {
191 if(dev->driver_cnt >= MAX_DRIVER_PER_DEV)
192 {
193 USB_error("Driver overrun for one device!\n");
194 return USB_ERR_NOMEM;
195 }
196 dev->driver[dev->driver_cnt] = driver;
197 dev->driver_cnt++;
198 USB_debug("Deivce bind driver count %d\n", dev->driver_cnt);
199 return 0;
200 }
201 }
202 }
203 }
204 if(dev->driver_cnt == 0)
205 USB_warning("No matching driver!!\n");
206 return -1;
207}
208
210
211
220{
221 if(urb && urb->dev)
222 return urb->dev->bus->op->submit_urb(urb);
223 else
224 {
225 return USB_ERR_NODEV;
226 }
227}
228
229
238{
239 if(urb && urb->dev)
240 return urb->dev->bus->op->unlink_urb(urb);
241 else
242 return USB_ERR_NODEV;
243}
244
245
246/*-------------------------------------------------------------------*
247 * COMPLETION HANDLERS *
248 *-------------------------------------------------------------------*/
249
250static volatile int _Event_UrbCompleted;
251
252/*-------------------------------------------------------------------*
253 * completion handler for compatibility wrappers (sync control/bulk) *
254 *-------------------------------------------------------------------*/
255static void ctrl_msg_complete(URB_T *urb)
256{
258}
259
261{
262 return _Event_UrbCompleted;
263}
265{
267}
268
269
270
271/*-------------------------------------------------------------------*
272 * COMPATIBILITY STUFF *
273 *-------------------------------------------------------------------*/
274/* Starts urb and waits for completion or timeout */
275static int usb_start_wait_urb(URB_T *urb, int timeout, int* actual_length)
276{
277 volatile int t0;
278 int status;
279
280 timeout /= 10000;
281 if(timeout == 0) timeout = 100;
282
284
285 status = USBH_SubmitUrb(urb);
286 if(status)
287 return status;
288
289#if 1
290 for(t0 = 0; t0 < 0x100000; t0++)
291 {
293 break;
294 }
295
296 if(t0 >= 0x100000)
298 else
299 urb->status = 0;
300#else
301 t0 = sysGetTicks(TIMER0);
302 while(sysGetTicks(TIMER0) - t0 < timeout)
303 {
305 break;
306 }
307
308 if(sysGetTicks(TIMER0) - t0 >= timeout)
310 else
311 urb->status = 0;
312#endif
313
314 if(urb->status == USB_ERR_INPROGRESS)
315 {
316 /* timeout */
317 USB_warning("usb_control/bulk_msg: timeout\n");
318 USBH_UnlinkUrb(urb); /* remove urb safely */
319 status = USB_ERR_TIMEOUT;
320 }
321 else
322 status = urb->status;
323
324 if(actual_length)
325 *actual_length = urb->actual_length;
326
327 return status;
328}
329
330
331/*-------------------------------------------------------------------*/
332// returns status (negative) or length (positive)
333static int usb_internal_control_msg(USB_DEV_T *usb_dev, uint32_t pipe,
334 DEV_REQ_T *cmd, void *data, int len, int timeout)
335{
336 URB_T urb;
337 int retv;
338 int length;
339
340 FILL_CONTROL_URB(&urb, usb_dev, pipe, (uint8_t*)cmd, data, len, /* build urb */
342
343 retv = usb_start_wait_urb(&urb, timeout, &length);
344 if(retv < 0)
345 return retv;
346 else
347 return length;
348}
349
350
375int32_t USBH_SendCtrlMsg(USB_DEV_T *dev, uint32_t pipe, uint8_t request,
376 uint8_t requesttype, uint16_t value, uint16_t index, void *data,
377 uint16_t size, int timeout)
378{
379 DEV_REQ_T dr;
380
381 dr.requesttype = requesttype;
382 dr.request = request;
383 dr.value = value;
384 dr.index = index;
385 dr.length = size;
386 return usb_internal_control_msg(dev, pipe, &dr, (uint8_t *)data, size, timeout);
387}
388
389
413int32_t USBH_SendBulkMsg(USB_DEV_T *usb_dev, uint32_t pipe,
414 void *data, int len, int *actual_length, int timeout)
415{
416 URB_T urb;
417
418 FILL_BULK_URB(&urb, usb_dev, pipe, (uint8_t *)data, len, /* build urb */
420
421 return usb_start_wait_urb(&urb, timeout, actual_length);
422}
423
425
426int usb_maxpacket(USB_DEV_T *dev, uint32_t pipe, int out)
427{
428 int i;
429 int ep_addr;
430
431 ep_addr = (((pipe) >> 15) & 0xf) | (pipe & 0x80);
432
433 if((ep_addr == 0) || (ep_addr == 0x80))
434 return dev->ep_list[0].wMaxPacketSize;
435
436 for(i = 0; i < dev->ep_list_cnt; i++)
437 {
438 if((dev->ep_list[i].cfgno == dev->act_config) &&
439 (dev->ep_list[i].bEndpointAddress == ep_addr))
440 {
441 return dev->ep_list[i].wMaxPacketSize;
442 }
443 }
444 USB_error("usb_maxpacket - endpoint %x not found!!\n", ep_addr);
445 return 64;
446}
447
448
449static int usb_parse_endpoint(USB_DEV_T *dev, int cfg_value, USB_IF_DESC_T *ifp, uint8_t *buffer, int size)
450{
451 USB_EP_DESC_T endpoint;
452 USB_DESC_HDR_T *header;
453 EP_INFO_T *ep_info;
454 int parsed = 0, numskipped;
455
456 header = (USB_DESC_HDR_T *)buffer;
457 memcpy((uint8_t *)&endpoint, buffer, sizeof(USB_EP_DESC_T));
458
459 /* Everything should be fine being passed into here, but we sanity */
460 if(header->bLength > size)
461 {
462 USB_error("Error! - ran out of descriptors parsing");
463 return -1;
464 }
465
466 if(header->bDescriptorType != USB_DT_ENDPOINT)
467 {
468 USB_warning("Warning! - unexpected descriptor 0x%X, expecting endpoint descriptor, type 0x%X",
469 endpoint.bDescriptorType, USB_DT_ENDPOINT);
470 return parsed;
471 }
472
473 if(dev->ep_list_cnt < MAX_ENDPOINTS)
474 {
475 ep_info = &dev->ep_list[dev->ep_list_cnt];
476 ep_info->cfgno = cfg_value;
477 ep_info->ifnum = ifp->bInterfaceNumber;
478 ep_info->altno = ifp->bAlternateSetting;
479 ep_info->bEndpointAddress = endpoint.bEndpointAddress;
480 ep_info->bmAttributes = endpoint.bmAttributes;
481 ep_info->bInterval = endpoint.bInterval;
482 ep_info->wMaxPacketSize = endpoint.wMaxPacketSize;
483 if ((ep_info->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK)
484 {
485 if (ep_info->wMaxPacketSize > 64)
486 {
487 USB_debug("Endpoint %x wMaxPacketSize is %d bytes, force to change as 64 bytes!\n",
488 endpoint.bEndpointAddress, endpoint.wMaxPacketSize);
489 ep_info->wMaxPacketSize = 64;
490 }
491 }
492 dev->ep_list_cnt++;
493 //USB_debug("Add endpoint 0x%x - %d %d %d, max_pkt = %d\n", ep_info->bEndpointAddress, ep_info->cfgno,
494 // ep_info->ifnum, ep_info->altno, ep_info->wMaxPacketSize);
495 }
496 else
497 {
498 USB_error("Too many endpoints!\n");
499 }
500
501 buffer += header->bLength;
502 size -= header->bLength;
503 parsed += header->bLength;
504
505 /* Skip over the rest of the Class Specific or Vendor Specific descriptors */
506 numskipped = 0;
507 while(size >= sizeof(USB_DESC_HDR_T))
508 {
509 header = (USB_DESC_HDR_T *)buffer;
510
511 if(header->bLength < 2)
512 {
513 USB_error("Error! - invalid descriptor length of %d\n", header->bLength);
514 return -1;
515 }
516
517 /* If we find another descriptor which is at or below us */
518 /* in the descriptor heirarchy then we're done */
519 if((header->bDescriptorType == USB_DT_ENDPOINT) ||
520 (header->bDescriptorType == USB_DT_INTERFACE) ||
521 (header->bDescriptorType == USB_DT_CONFIG) ||
522 (header->bDescriptorType == USB_DT_DEVICE))
523 break;
524 USB_info("skipping descriptor 0x%X\n", header->bDescriptorType);
525 numskipped++;
526
527 buffer += header->bLength;
528 size -= header->bLength;
529 parsed += header->bLength;
530 }
531
532 if(numskipped)
533 USB_warning("Skipped %d class/vendor specific endpoint descriptors\n", numskipped);
534
535 return parsed;
536}
537
538
539static int usb_parse_interface(USB_DEV_T *dev, int cfg_value, uint8_t *buffer, int size)
540{
541 int i, numskipped, retval, parsed = 0;
542 USB_DESC_HDR_T *header;
543 USB_IF_DESC_T ifp;
544
545#ifdef USB_VERBOSE_DEBUG
546 //HexDumpBuffer("usb_parse_interface", (uint8_t *)buffer, size);
547#endif
548
549 while(size > 0)
550 {
551 memcpy((char *)&ifp, buffer, USB_DT_INTERFACE_SIZE);
552
553 /* Skip over the interface */
554 buffer += ifp.bLength;
555 parsed += ifp.bLength;
556 size -= ifp.bLength;
557
558 numskipped = 0;
559
560 /*
561 * Skip over any interface, class or vendor descriptors
562 * ¦b parsing interface descriptors ªº¹Lµ{¤¤, ­Yµo²{ class descriptors
563 * ©?vendor descriptors, ´Nª½±µ skip ¤§, ¤£°µ parsing
564 */
565 while(size >= sizeof(USB_DESC_HDR_T))
566 {
567 header = (USB_DESC_HDR_T *)buffer;
568
569 if(header->bLength < 2)
570 {
571 USB_error("Invalid descriptor length of %d\n", header->bLength);
572 return -1;
573 }
574
575 /* If we find another descriptor which is at or below */
576 /* us in the descriptor heirarchy then return */
577 if((header->bDescriptorType == USB_DT_INTERFACE) ||
578 (header->bDescriptorType == USB_DT_ENDPOINT) ||
579 (header->bDescriptorType == USB_DT_CONFIG) ||
580 (header->bDescriptorType == USB_DT_DEVICE))
581 break;
582
583 USB_info("skipping descriptor 0x%X\n", header->bDescriptorType);
584 numskipped++;
585 buffer += header->bLength;
586 parsed += header->bLength;
587 size -= header->bLength;
588 }
589
590 if(numskipped)
591 {
592 USB_warning("skipped %d class/vendor specific interface descriptors\n", numskipped);
593 }
594
595 /* Did we hit an unexpected descriptor? */
596 header = (USB_DESC_HDR_T *)buffer;
597 if((size >= sizeof(USB_DESC_HDR_T)) &&
598 ((header->bDescriptorType == USB_DT_CONFIG) ||
599 (header->bDescriptorType == USB_DT_DEVICE)))
600 {
601 USB_warning("parsing interface - hit an unexpected descriptor!\n");
602 return parsed;
603 }
604
605 if(ifp.bNumEndpoints > USB_MAXENDPOINTS)
606 {
607 USB_warning("Warning - illegal endpoint number %d\n", ifp.bNumEndpoints);
608 return -1;
609 }
610
611 /* fixed by YCHuang, 2002.03.13, ifp.bNumEndpoints number may be zero */
612 if(ifp.bNumEndpoints > 0)
613 {
614 for(i = 0; i < ifp.bNumEndpoints; i++)
615 {
616 header = (USB_DESC_HDR_T *)buffer;
617 if(header->bLength > size)
618 {
619 USB_error("Error - ran out of descriptors parsing");
620 return -1;
621 }
622
623#ifdef DUMP_DEV_DESCRIPTORS
624 usbh_dump_ep_descriptor((USB_EP_DESC_T *)buffer);
625#endif
626 retval = usb_parse_endpoint(dev, cfg_value, &ifp, buffer, size);
627 if(retval < 0)
628 return retval;
629
630 buffer += retval;
631 parsed += retval;
632 size -= retval;
633 }
634 }
635
636 /* We check to see if it's an alternate to this one */
637 memcpy((char *)&ifp, buffer, USB_DT_INTERFACE_SIZE);
638 if((size < USB_DT_INTERFACE_SIZE) ||
639 (ifp.bDescriptorType != USB_DT_INTERFACE) || !ifp.bAlternateSetting)
640 return parsed;
641 } /* end of while */
642 return parsed;
643}
644
645
646static int usb_parse_configuration(USB_DEV_T *dev, USB_CONFIG_DESC_T *config, uint8_t *buffer)
647{
648 int i, retval, size;
649 USB_DESC_HDR_T *header;
650
651 memcpy(config, buffer, USB_DT_CONFIG_SIZE);
652 size = config->wTotalLength;
653
654 if(config->bNumInterfaces > USB_MAXINTERFACES)
655 {
656 USB_warning("Warning - too many interfaces\n");
657 return -1;
658 }
659
660 buffer += config->bLength;
661 size -= config->bLength;
662
663 for(i = 0; i < config->bNumInterfaces; i++)
664 {
665 int numskipped;
666
667 /* Skip over the rest of the Class Specific or Vendor */
668 /* Specific descriptors */
669 numskipped = 0;
670 while(size >= sizeof(USB_DESC_HDR_T))
671 {
672 header = (USB_DESC_HDR_T *)buffer;
673
674 if((header->bLength > size) || (header->bLength < 2))
675 {
676 USB_error("Error - invalid descriptor length of %d\n", header->bLength);
677 return -1;
678 }
679
680 /* If we find another descriptor which is at or below */
681 /* us in the descriptor heirarchy then we're done */
682 if((header->bDescriptorType == USB_DT_ENDPOINT) ||
683 (header->bDescriptorType == USB_DT_INTERFACE) ||
684 (header->bDescriptorType == USB_DT_CONFIG) ||
685 (header->bDescriptorType == USB_DT_DEVICE))
686 break;
687
688 USB_info("skipping descriptor 0x%X\n", header->bDescriptorType);
689 numskipped++;
690
691 buffer += header->bLength;
692 size -= header->bLength;
693 } /* end of while */
694
695 if(numskipped)
696 {
697 USB_warning("skipped %d class/vendor specific endpoint descriptors\n", numskipped);
698 }
699
700#ifdef DUMP_DEV_DESCRIPTORS
701 usbh_dump_iface_descriptor((USB_IF_DESC_T *)buffer);
702#endif
703
704 retval = usb_parse_interface(dev, config->bConfigurationValue, buffer, size);
705 if(retval < 0)
706 return retval;
707
708 /* probe drivers... */
709 usb_find_interface_driver(dev, (USB_IF_DESC_T *)buffer);
710
711 buffer += retval;
712 size -= retval;
713 }
714 return size;
715}
716
717
718/*
719 * Something got disconnected. Get rid of it, and all of its children.
720 */
721void usbh_disconnect_device(USB_DEV_T **pdev)
722{
723 USB_DEV_T *dev = *pdev;
724 USB_DRIVER_T *driver;
725 int i;
726
727 if(!dev)
728 return;
729
730 *pdev = NULL;
731
732 USB_info("usbh_disconnect_device - USB disconnect on device %d\n", dev->devnum);
733
735
736 for(i = 0; i < dev->driver_cnt; i++)
737 {
738 driver = dev->driver[i];
739 driver->disconnect(dev);
740 }
741
742 /* Free up all the children.. */
743 for(i = 0; i < USB_MAXCHILDREN; i++)
744 {
745 USB_DEV_T **child = dev->children + i;
746 if(*child)
747 usbh_disconnect_device(child);
748 }
749
750 /* Free the device number and remove the /proc/bus/usb entry */
751 if(dev->devnum > 0)
752 {
753 g_devmap &= ~(1 << dev->devnum);
754 }
755
756 /* Free up the device itself */
757 usbh_free_device(dev);
758
759 usbh_mdelay(5); // let Host Controller got some time to free all
760}
761
762
763/*
764 * Connect a new USB device. This basically just initializes
765 * the USB device information and sets up the topology - it's
766 * up to the low-level driver to reset the port and actually
767 * do the setup (the upper levels don't know how to do that).
768 */
769void usbh_connect_device(USB_DEV_T *dev)
770{
771 int devnum;
772
773 dev->descriptor.bMaxPacketSize0 = 8; /* Start off at 8 bytes */
774
775 for(devnum = 1; devnum < 31; devnum++)
776 {
777 if((g_devmap & (1 << devnum)) == 0)
778 break;
779 }
780 if(devnum > 31)
781 {
782 USB_error("Serious devnum error!\n");
783 devnum = 31;
784 }
785
786 g_devmap |= (1 << devnum);
787 dev->devnum = devnum;
788}
789
791
792
793/*
794 * These are the actual routines to send
795 * and receive control messages.
796 */
797
798#define GET_TIMEOUT 1000
799#define SET_TIMEOUT 100
802
803int usbh_set_address(USB_DEV_T *dev)
804{
805 return USBH_SendCtrlMsg(dev, usb_snddefctrl(dev), USB_REQ_SET_ADDRESS,
806 0, dev->devnum, 0, NULL, 0, HZ * GET_TIMEOUT);
807}
808
810
822int32_t USBH_GetDescriptor(USB_DEV_T *dev, uint8_t type, uint8_t index,
823 void *buf, int size)
824{
825 int i = 5;
826 int result = 0;
827
828 memset(buf, 0, size); /* Make sure we parse really received data */
829
830 while(i--)
831 {
832 if((result = USBH_SendCtrlMsg(dev, usb_rcvctrlpipe(dev, 0),
833 USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
834 (type << 8) + index, 0, buf, size, HZ * GET_TIMEOUT)) > 0 || result == USB_ERR_PIPE)
835 break; /* retry if the returned length was 0; flaky device */
836 }
837 return result;
838}
839
841
842static int usbh_get_string_descriptor(USB_DEV_T *dev, uint16_t langid, uint8_t index,
843 void *buf, int size)
844{
845 return USBH_SendCtrlMsg(dev, usb_rcvctrlpipe(dev, 0),
846 USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
847 (USB_DT_STRING << 8) + index, langid, buf, size, HZ * GET_TIMEOUT);
848}
849
850
851static int usbh_get_device_descriptor(USB_DEV_T *dev)
852{
853 int ret;
854
855 ret = USBH_GetDescriptor(dev, USB_DT_DEVICE, 0, &dev->descriptor, sizeof(dev->descriptor));
856 return ret;
857}
858
859
860int usbh_get_protocol(USB_DEV_T *dev, int ifnum)
861{
862 uint8_t type;
863 int ret;
864
865 if((ret = USBH_SendCtrlMsg(dev, usb_rcvctrlpipe(dev, 0),
866 USB_REQ_GET_PROTOCOL, USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
867 0, ifnum, &type, 1, HZ * GET_TIMEOUT)) < 0)
868 return ret;
869
870 return type;
871}
872
873
874int usbh_set_protocol(USB_DEV_T *dev, int ifnum, int protocol)
875{
876 return USBH_SendCtrlMsg(dev, usb_sndctrlpipe(dev, 0),
877 USB_REQ_SET_PROTOCOL, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
878 protocol, ifnum, NULL, 0, HZ * SET_TIMEOUT);
879}
880
881
882int usbh_set_idle(USB_DEV_T *dev, int ifnum, int duration, int report_id)
883{
884 return USBH_SendCtrlMsg(dev, usb_sndctrlpipe(dev, 0),
885 USB_REQ_SET_IDLE, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
886 (duration << 8) | report_id, ifnum, NULL, 0, HZ * SET_TIMEOUT);
887}
888
890
891
900int32_t USBH_ClearHalt(USB_DEV_T *dev, int pipe)
901{
902 int result;
903 uint16_t status;
904 int endp;
905
906 endp = usb_pipeendpoint(pipe) | (usb_pipein(pipe) << 7);
907
908 /*
909 if (!usb_endpoint_halted(dev, endp & 0x0f, usb_endpoint_out(endp)))
910 return 0;
911 */
912
913 result = USBH_SendCtrlMsg(dev, usb_sndctrlpipe(dev, 0),
914 USB_REQ_CLEAR_FEATURE, USB_RECIP_ENDPOINT, 0, endp, NULL, 0, HZ * SET_TIMEOUT);
915
916 /* don't clear if failed */
917 if(result < 0)
918 return result;
919
920 result = USBH_SendCtrlMsg(dev, usb_rcvctrlpipe(dev, 0),
921 USB_REQ_GET_STATUS, USB_DIR_IN | USB_RECIP_ENDPOINT, 0, endp,
922 &status, sizeof(status), HZ * SET_TIMEOUT);
923 if(result < 0)
924 return result;
925
926 if(USB_SWAP16(status) & 1)
927 return USB_ERR_PIPE; /* still halted */
928
929 usb_endpoint_running(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe));
930
931 /* toggle is reset on clear */
932
933 usb_settoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe), 0);
934
935 return 0;
936}
937
938
948int32_t USBH_SetInterface(USB_DEV_T *dev, char interface, char alternate)
949{
950 int ret;
951
952 if((ret = USBH_SendCtrlMsg(dev, usb_sndctrlpipe(dev, 0),
953 USB_REQ_SET_INTERFACE, USB_RECIP_INTERFACE, alternate,
954 interface, NULL, 0, HZ * 5)) < 0)
955 return ret;
956
957 dev->act_iface = interface;
958 dev->iface_alternate = alternate;
959 dev->toggle[0] = 0; /* 9.1.1.5 says to do this */
960 dev->toggle[1] = 0;
961 return 0;
962}
963
964
973int32_t USBH_SetConfiguration(USB_DEV_T *dev, int configuration)
974{
975 int ret;
976
977 if((ret = USBH_SendCtrlMsg(dev, usb_sndctrlpipe(dev, 0),
978 USB_REQ_SET_CONFIGURATION, 0, configuration, 0, NULL, 0, HZ * SET_TIMEOUT)) < 0)
979 return ret;
980 dev->act_config = configuration;
981 dev->toggle[0] = 0;
982 dev->toggle[1] = 0;
983 return 0;
984}
985
986
987/*
988 * usbh_settle_configuration
989 *
990 * 1. get configuration descriptor
991 * 2. set default configuration
992 * 3. parse configuration
993 * 4. probe USB device drivers by interface
994 */
996{
997 int result;
998 uint32_t cfgno, length;
999 uint8_t *buffer;
1000 USB_CONFIG_DESC_T *desc;
1001 uint32_t stack_buff[256];
1002
1003 if(dev->descriptor.bNumConfigurations > USB_MAXCONFIG)
1004 {
1005 USB_warning("Too many configurations\n");
1006 return USB_ERR_INVAL;
1007 }
1008
1009 if(dev->descriptor.bNumConfigurations != 1)
1010 {
1011 USB_warning("This driver does not support multi-configuration devices!\n");
1012 return USB_ERR_INVAL;
1013 }
1014
1015 buffer = (uint8_t *)&stack_buff[0];
1016 desc = (USB_CONFIG_DESC_T *)buffer;
1017
1018 for(cfgno = 0; cfgno < dev->descriptor.bNumConfigurations; cfgno++)
1019 {
1020 /* We grab the first 8 bytes so we know how long the whole */
1021 /* configuration is */
1022 result = USBH_GetDescriptor(dev, USB_DT_CONFIG, cfgno, buffer, 8);
1023 if(result < 8)
1024 {
1025 if(result < 0)
1026 USB_error("Unable to get descriptor\n");
1027 else
1028 {
1029 USB_error("Config descriptor too short (expected %i, got %i)\n", 8, result);
1030 result = USB_ERR_INVAL;
1031 }
1032 goto err;
1033 }
1034
1035 /* Get the full buffer */
1036 length = desc->wTotalLength;
1037
1038 if(length > 256)
1039 {
1040 length = 256;
1041 USB_error("Config descriptor is too large. Read 256 bytes only. This may cause lost of information!\n");
1042 }
1043
1044 /* Now that we know the length, get the whole thing */
1045 result = USBH_GetDescriptor(dev, USB_DT_CONFIG, cfgno, buffer, length);
1046 if(result < 0)
1047 {
1048 USB_error("Couldn't get all of config descriptors\n");
1049 goto err;
1050 }
1051
1052 if(result < length)
1053 {
1054 USB_error("Config descriptor too short (expected %d, got %d)\n", length, result);
1055 result = USB_ERR_INVAL;
1056 goto err;
1057 }
1058
1059 /*
1060 * Set first configuration as the default configuration
1061 */
1062 if(cfgno == 0)
1063 {
1064 result = USBH_SetConfiguration(dev, desc->bConfigurationValue);
1065 if(result)
1066 {
1067 USB_error("Failed to set device %d default configuration (error=%d)\n", dev->devnum, result);
1068 goto err;
1069 }
1070 }
1071
1072#ifdef DUMP_DEV_DESCRIPTORS
1073 usbh_dump_config_descriptor(desc);
1074#endif
1075
1076 result = usb_parse_configuration(dev, desc, buffer);
1077 if(result > 0)
1078 {
1079 USB_warning("Descriptor data left\n");
1080 }
1081 else if(result < 0)
1082 {
1083 USB_warning("usb_parse_configuration error\n");
1084 result = USB_ERR_INVAL;
1085 goto err;
1086 }
1087 }
1088
1089 return 0;
1090
1091err:
1092 dev->descriptor.bNumConfigurations = cfgno;
1093 return result;
1094}
1095
1097
1098/*
1099 * usbh_translate_string:
1100 * returns string length (> 0) or error (< 0)
1101 */
1102int usbh_translate_string(USB_DEV_T *dev, int index, char *buf, int size)
1103{
1104 int err = 0;
1105 uint32_t u, idx;
1106 uint8_t tbuf[256];
1107
1108 if(size == 0 || !buf || !index)
1109 return USB_ERR_INVAL;
1110 buf[0] = 0;
1111
1112 /* get langid for strings if it's not yet known */
1113 if(!dev->have_langid)
1114 {
1115 err = usbh_get_string_descriptor(dev, 0, 0, tbuf, 4);
1116 if(err < 0)
1117 {
1118 USB_error("usbh_translate_string - error getting string descriptor 0 (error=%d)\n", err);
1119 goto errout;
1120 }
1121 else if(tbuf[0] < 4)
1122 {
1123 USB_error("usbh_translate_string - string descriptor 0 too short\n");
1124 err = USB_ERR_INVAL;
1125 goto errout;
1126 }
1127 else
1128 {
1129 dev->have_langid = -1;
1130 dev->string_langid = tbuf[2] | (tbuf[3] << 8);
1131 /* always use the first langid listed */
1132 USB_info("USB device number %d default language ID 0x%x\n",
1133 dev->devnum, dev->string_langid);
1134 }
1135 }
1136
1137 /* YCHuang, added for W99683, prevent halt */
1138 if((dev->descriptor.idVendor == 0x416) && (dev->descriptor.idProduct == 0x9683))
1139 {
1140 USB_warning("??? Skip usbh_get_string_descriptor, 255\n");
1141 goto errout;
1142 }
1143
1144
1145 /*
1146 * Just ask for a maximum length string and then take the length
1147 * that was returned.
1148 */
1149 err = usbh_get_string_descriptor(dev, dev->string_langid, index, tbuf, 255);
1150 if(err < 0)
1151 goto errout;
1152
1153 size--; /* leave room for trailing NULL char in output buffer */
1154 for(idx = 0, u = 2; u < err; u += 2)
1155 {
1156 if(idx >= size)
1157 break;
1158 if(tbuf[u + 1]) /* high byte */
1159 buf[idx++] = '?'; /* non-ASCII character */
1160 else
1161 buf[idx++] = tbuf[u];
1162 }
1163 buf[idx] = 0;
1164 err = idx;
1165
1166errout:
1167 return err;
1168}
1169
1170
1171
1172/*
1173 * By the time we get here, the device has gotten a new device ID
1174 * and is in the default state. We need to identify the thing and
1175 * get the ball rolling..
1176 *
1177 * Returns 0 for success, != 0 for error.
1178 */
1179int usbh_settle_new_device(USB_DEV_T *dev)
1180{
1181 int err;
1182
1183 USB_info("[USBH] Enter usbh_settle_new_device() ...\n");
1184 /*
1185 * USB v1.1 5.5.3
1186 * We read the first 8 bytes from the device descriptor to get to
1187 * the bMaxPacketSize0 field. Then we set the maximum packet size
1188 * for the control pipe, and retrieve the rest
1189 */
1190 dev->ep_list[0].bEndpointAddress = 0;;
1191 dev->ep_list[0].wMaxPacketSize = 8;
1192 dev->ep_list_cnt = 1;
1193
1194 err = usbh_set_address(dev);
1195 if(err < 0)
1196 {
1197 USB_error("USB device not accepting new address=%d (error=%d)\n", dev->devnum, err);
1198 g_devmap &= ~(1 << dev->devnum);
1199 dev->devnum = -1;
1200 return 1;
1201 }
1202
1203 usbh_mdelay(10); /* Let the SET_ADDRESS settle */
1204
1205 memset((char *)&dev->descriptor, 0, 8);
1206
1207 err = USBH_GetDescriptor(dev, USB_DT_DEVICE, 0, &dev->descriptor, 8);
1208 if(err < 8)
1209 {
1210 USB_debug("USBH_GetDescriptor failed!!\n");
1211 if(err < 0)
1212 USB_error("USB device not responding, giving up (error=%d)\n", err);
1213 else
1214 USB_error("USB device descriptor short read (expected %i, got %i)\n", 8, err);
1215 g_devmap &= ~(1 << dev->devnum);
1216 dev->devnum = -1;
1217 return 1;
1218 }
1219
1220 dev->ep_list[0].wMaxPacketSize = dev->descriptor.bMaxPacketSize0;
1221
1222 err = usbh_get_device_descriptor(dev);
1223 if(err < sizeof(dev->descriptor))
1224 {
1225 if(err < 0)
1226 USB_error("unable to get device descriptor (error=%d)\n", err);
1227 else
1228 USB_error("USB device descriptor short read (expected %i, got %i)\n",
1229 sizeof(dev->descriptor), err);
1230
1231 g_devmap &= ~(1 << dev->devnum);
1232 dev->devnum = -1;
1233 return USB_ERR_INVAL;
1234 }
1235
1236#ifdef DUMP_DEV_DESCRIPTORS
1237 usbh_dump_device_descriptor(&dev->descriptor);
1238#endif
1239
1240 err = usbh_settle_configuration(dev);
1241 if(err < 0)
1242 {
1243 USB_error("Unable to get device %d configuration (error=%d)\n", dev->devnum, err);
1244 g_devmap &= ~(1 << dev->devnum);
1245 dev->devnum = -1;
1246 usbh_free_device(dev);
1247 return 1;
1248 }
1249
1250#ifdef USB_VERBOSE_DEBUG
1251 if(dev->descriptor.iManufacturer)
1252 usbh_print_usb_string(dev, "Manufacturer", dev->descriptor.iManufacturer);
1253 if(dev->descriptor.iProduct)
1254 usbh_print_usb_string(dev, "Product", dev->descriptor.iProduct);
1255 if(dev->descriptor.iSerialNumber)
1256 usbh_print_usb_string(dev, "SerialNumber", dev->descriptor.iSerialNumber);
1257#endif
1258 return 0;
1259}
1260
1262
1269int32_t USBH_Open(void)
1270{
1271 volatile int loop;
1272
1273 USBH->HcMiscControl |= 0x8; /* overcurrent setting */
1274 //USBH->HcMiscControl &= ~0x8; /* overcurrent setting */
1275
1277
1278 /*
1279 * Init global variables
1280 */
1281 g_devmap = 0;
1282
1283 ENABLE_USB_INT();
1284
1285 usbh_init_hub_driver();
1286
1287#ifdef SUPPORT_HID_CLASS
1288#endif
1289
1290#ifdef SUPPORT_UMAS_CLASS
1291#endif
1292
1293#ifdef SUPPORT_UVC_CLASS
1294#endif
1295
1296#ifdef SUPPORT_UAC_CLASS
1297#endif
1298
1299#ifdef SUPPORT_CDC_CLASS
1300#endif
1301
1302 if(usbh_init_ohci() < 0)
1303 {
1304 USB_debug("OHCI init failed!\n");
1305 return -1;
1306 }
1307
1308 return 0;
1309}
1310
1311
1318int32_t USBH_Close(void)
1319{
1320 DISABLE_USB_INT();
1321
1322 USBH->HcRhStatus = USBH_HcRhStatus_LPS_Msk;
1323
1325
1326 return 0;
1327}
1328
1329
1336int32_t USBH_Suspend(void)
1337{
1338 int i;
1339 USB_DEV_T *dev;
1340
1341 /* Set feature Device Remote Wakeup to all devices */
1342 for(i = 0; i < DEV_MAX_NUM; i++)
1343 {
1344 if(dev_alloc_mark[i])
1345 {
1346 dev = &g_dev_pool[i];
1347 USBH_SendCtrlMsg(dev, usb_sndctrlpipe(dev, 0),
1348 USB_REQ_SET_FEATURE, 0x00, 0x0001, 0x0000, NULL, 0x0000, HZ * SET_TIMEOUT);
1349 }
1350 }
1351
1352 /* set port suspend if connected */
1353 if(USBH->HcRhPortStatus[0] & 0x1)
1354 USBH->HcRhPortStatus[0] = 0x4;
1355
1356 if(USBH->HcRhPortStatus[1] & 0x1)
1357 USBH->HcRhPortStatus[1] = 0x4;
1358
1359 /* enable Device Remote Wakeup */
1360 USBH->HcRhStatus |= USBH_HcRhStatus_DRWE_Msk;
1361
1362 /* enable USBH RHSC interrupt for system wakeup */
1364
1365 /* set Host Controller enter suspend state */
1366 USBH->HcControl = (USBH->HcControl & ~USBH_HcControl_HCFS_Msk) | (3 << USBH_HcControl_HCFS_Pos);
1367
1368 return 0;
1369}
1370
1377int32_t USBH_Resume(void)
1378{
1379 USBH->HcControl = (USBH->HcControl & ~USBH_HcControl_HCFS_Msk) | (1 << USBH_HcControl_HCFS_Pos);
1380 USBH->HcControl = (USBH->HcControl & ~USBH_HcControl_HCFS_Msk) | (2 << USBH_HcControl_HCFS_Pos);
1381
1382 if(USBH->HcRhPortStatus[0] & 0x4)
1383 USBH->HcRhPortStatus[0] = 0x8;
1384 if(USBH->HcRhPortStatus[1] & 0x4)
1385 USBH->HcRhPortStatus[1] = 0x8;
1386
1387 return 0;
1388}
1389
1390 /* end of group USBH_EXPORTED_FUNCTIONS */
1392 /* end of group USBH_Driver */
1394 /* end of group USB_Host_Driver */
1396
1397
1398
#define USBH_HcRhStatus_DRWE_Msk
Definition: M4521.h:13412
#define USBH_HcInterruptEnable_RD_Msk
Definition: M4521.h:13313
#define USBH_HcRhStatus_LPS_Msk
Definition: M4521.h:13406
#define USBH_HcInterruptEnable_RHSC_Msk
Definition: M4521.h:13319
#define USBH_HcControl_HCFS_Pos
Definition: M4521.h:13270
#define NULL
Definition: M4521.h:13912
#define USBH
Definition: M4521.h:13831
#define TIMER0
Definition: M4521.h:13842
static void ctrl_msg_complete(URB_T *urb)
Definition: usbh_core.c:255
int status
Definition: usbh_core.h:521
static int usb_internal_control_msg(USB_DEV_T *usb_dev, uint32_t pipe, DEV_REQ_T *cmd, void *data, int len, int timeout)
Definition: usbh_core.c:333
int32_t USBH_RegisterDriver(USB_DRIVER_T *new_driver)
Register a device driver to USB Host Core driver.
Definition: usbh_core.c:78
int32_t USBH_SubmitUrb(URB_T *urb)
Submit an URB to USB core for transfer data.
Definition: usbh_core.c:219
int32_t USBH_SendBulkMsg(USB_DEV_T *usb_dev, uint32_t pipe, void *data, int len, int *actual_length, int timeout)
Execute a bulk transfer.
Definition: usbh_core.c:413
int32_t USBH_Resume(void)
Resume USB Host controller and devices.
Definition: usbh_core.c:1377
int32_t USBH_Close(void)
Disable USB Host controller function.
Definition: usbh_core.c:1318
int actual_length
Definition: usbh_core.h:525
int32_t USBH_Suspend(void)
Suspend USB Host Controller and devices.
Definition: usbh_core.c:1336
struct usb_device * dev
Definition: usbh_core.h:519
static void clr_ctrl_msg_signal()
Definition: usbh_core.c:264
int32_t USBH_UnlinkUrb(URB_T *urb)
Cancel an URB which has been submit to USB core.
Definition: usbh_core.c:237
int32_t USBH_Open(void)
Open USB Host controller function.
Definition: usbh_core.c:1269
static int usbh_settle_configuration(USB_DEV_T *dev)
Definition: usbh_core.c:995
int32_t USBH_SetInterface(USB_DEV_T *dev, char interface, char alternate)
Set USB device interface.
Definition: usbh_core.c:948
int32_t USBH_GetDescriptor(USB_DEV_T *dev, uint8_t type, uint8_t index, void *buf, int size)
Get a descriptor from device.
Definition: usbh_core.c:822
static int usb_start_wait_urb(URB_T *urb, int timeout, int *actual_length)
Definition: usbh_core.c:275
USB_BUS_T * bus
Definition: usbh_core.h:657
int32_t USBH_ClearHalt(USB_DEV_T *dev, int pipe)
Clear the halt state of an endpoint.
Definition: usbh_core.c:900
static int get_ctrl_msg_signal()
Definition: usbh_core.c:260
#define SET_TIMEOUT
Definition: usbh_core.c:799
#define GET_TIMEOUT
Definition: usbh_core.c:798
int32_t USBH_SetConfiguration(USB_DEV_T *dev, int configuration)
Select USB device configuration.
Definition: usbh_core.c:973
static volatile int _Event_UrbCompleted
Definition: usbh_core.c:250
int32_t USBH_SendCtrlMsg(USB_DEV_T *dev, uint32_t pipe, uint8_t request, uint8_t requesttype, uint16_t value, uint16_t index, void *data, uint16_t size, int timeout)
Execute a control transfer.
Definition: usbh_core.c:375
return value
Definition: semihosting.h:98
#define DEV_MAX_NUM
Definition: usbh_config.h:32
#define MAX_ENDPOINTS
Definition: usbh_config.h:37
#define MAX_DRIVER_PER_DEV
Definition: usbh_config.h:38
USB Host core driver header file.
USB_IF_DESC_T
Definition: usbh_core.h:315
DEV_REQ_T
Definition: usbh_core.h:173
USB_CONFIG_DESC_T
Definition: usbh_core.h:344
HIDDEN_SYMBOLS struct usb_device USB_DEV_T
USB_EP_DESC_T
Definition: usbh_core.h:282
#define USB_ERR_TIMEOUT
Definition: usbh_err_code.h:18
#define USB_ERR_NODEV
Definition: usbh_err_code.h:11
#define USB_ERR_INPROGRESS
Definition: usbh_err_code.h:19
#define USB_ERR_INVAL
Definition: usbh_err_code.h:12
#define USB_ERR_PIPE
Definition: usbh_err_code.h:13
#define USB_ERR_NOMEM
Definition: usbh_err_code.h:8
void usbh_free_device(USB_DEV_T *dev)
Definition: usbh_support.c:252
HIDDEN_SYMBOLS void usbh_init_memory()
Definition: usbh_support.c:48
void usbh_mdelay(uint32_t msec)
Definition: usbh_support.c:330
void usbh_free_dev_urbs(USB_DEV_T *dev)
Definition: usbh_support.c:115