diff options
Diffstat (limited to 'drivers/usb/core/hcd.c')
-rw-r--r-- | drivers/usb/core/hcd.c | 220 |
1 files changed, 185 insertions, 35 deletions
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 42b93da1085d..ce3f453f02ef 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c | |||
@@ -128,6 +128,27 @@ static inline int is_root_hub(struct usb_device *udev) | |||
128 | #define KERNEL_REL ((LINUX_VERSION_CODE >> 16) & 0x0ff) | 128 | #define KERNEL_REL ((LINUX_VERSION_CODE >> 16) & 0x0ff) |
129 | #define KERNEL_VER ((LINUX_VERSION_CODE >> 8) & 0x0ff) | 129 | #define KERNEL_VER ((LINUX_VERSION_CODE >> 8) & 0x0ff) |
130 | 130 | ||
131 | /* usb 3.0 root hub device descriptor */ | ||
132 | static const u8 usb3_rh_dev_descriptor[18] = { | ||
133 | 0x12, /* __u8 bLength; */ | ||
134 | 0x01, /* __u8 bDescriptorType; Device */ | ||
135 | 0x00, 0x03, /* __le16 bcdUSB; v3.0 */ | ||
136 | |||
137 | 0x09, /* __u8 bDeviceClass; HUB_CLASSCODE */ | ||
138 | 0x00, /* __u8 bDeviceSubClass; */ | ||
139 | 0x03, /* __u8 bDeviceProtocol; USB 3.0 hub */ | ||
140 | 0x09, /* __u8 bMaxPacketSize0; 2^9 = 512 Bytes */ | ||
141 | |||
142 | 0x6b, 0x1d, /* __le16 idVendor; Linux Foundation */ | ||
143 | 0x02, 0x00, /* __le16 idProduct; device 0x0002 */ | ||
144 | KERNEL_VER, KERNEL_REL, /* __le16 bcdDevice */ | ||
145 | |||
146 | 0x03, /* __u8 iManufacturer; */ | ||
147 | 0x02, /* __u8 iProduct; */ | ||
148 | 0x01, /* __u8 iSerialNumber; */ | ||
149 | 0x01 /* __u8 bNumConfigurations; */ | ||
150 | }; | ||
151 | |||
131 | /* usb 2.0 root hub device descriptor */ | 152 | /* usb 2.0 root hub device descriptor */ |
132 | static const u8 usb2_rh_dev_descriptor [18] = { | 153 | static const u8 usb2_rh_dev_descriptor [18] = { |
133 | 0x12, /* __u8 bLength; */ | 154 | 0x12, /* __u8 bLength; */ |
@@ -273,6 +294,47 @@ static const u8 hs_rh_config_descriptor [] = { | |||
273 | 0x0c /* __u8 ep_bInterval; (256ms -- usb 2.0 spec) */ | 294 | 0x0c /* __u8 ep_bInterval; (256ms -- usb 2.0 spec) */ |
274 | }; | 295 | }; |
275 | 296 | ||
297 | static const u8 ss_rh_config_descriptor[] = { | ||
298 | /* one configuration */ | ||
299 | 0x09, /* __u8 bLength; */ | ||
300 | 0x02, /* __u8 bDescriptorType; Configuration */ | ||
301 | 0x19, 0x00, /* __le16 wTotalLength; FIXME */ | ||
302 | 0x01, /* __u8 bNumInterfaces; (1) */ | ||
303 | 0x01, /* __u8 bConfigurationValue; */ | ||
304 | 0x00, /* __u8 iConfiguration; */ | ||
305 | 0xc0, /* __u8 bmAttributes; | ||
306 | Bit 7: must be set, | ||
307 | 6: Self-powered, | ||
308 | 5: Remote wakeup, | ||
309 | 4..0: resvd */ | ||
310 | 0x00, /* __u8 MaxPower; */ | ||
311 | |||
312 | /* one interface */ | ||
313 | 0x09, /* __u8 if_bLength; */ | ||
314 | 0x04, /* __u8 if_bDescriptorType; Interface */ | ||
315 | 0x00, /* __u8 if_bInterfaceNumber; */ | ||
316 | 0x00, /* __u8 if_bAlternateSetting; */ | ||
317 | 0x01, /* __u8 if_bNumEndpoints; */ | ||
318 | 0x09, /* __u8 if_bInterfaceClass; HUB_CLASSCODE */ | ||
319 | 0x00, /* __u8 if_bInterfaceSubClass; */ | ||
320 | 0x00, /* __u8 if_bInterfaceProtocol; */ | ||
321 | 0x00, /* __u8 if_iInterface; */ | ||
322 | |||
323 | /* one endpoint (status change endpoint) */ | ||
324 | 0x07, /* __u8 ep_bLength; */ | ||
325 | 0x05, /* __u8 ep_bDescriptorType; Endpoint */ | ||
326 | 0x81, /* __u8 ep_bEndpointAddress; IN Endpoint 1 */ | ||
327 | 0x03, /* __u8 ep_bmAttributes; Interrupt */ | ||
328 | /* __le16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8) | ||
329 | * see hub.c:hub_configure() for details. */ | ||
330 | (USB_MAXCHILDREN + 1 + 7) / 8, 0x00, | ||
331 | 0x0c /* __u8 ep_bInterval; (256ms -- usb 2.0 spec) */ | ||
332 | /* | ||
333 | * All 3.0 hubs should have an endpoint companion descriptor, | ||
334 | * but we're ignoring that for now. FIXME? | ||
335 | */ | ||
336 | }; | ||
337 | |||
276 | /*-------------------------------------------------------------------------*/ | 338 | /*-------------------------------------------------------------------------*/ |
277 | 339 | ||
278 | /* | 340 | /* |
@@ -426,23 +488,39 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb) | |||
426 | case DeviceRequest | USB_REQ_GET_DESCRIPTOR: | 488 | case DeviceRequest | USB_REQ_GET_DESCRIPTOR: |
427 | switch (wValue & 0xff00) { | 489 | switch (wValue & 0xff00) { |
428 | case USB_DT_DEVICE << 8: | 490 | case USB_DT_DEVICE << 8: |
429 | if (hcd->driver->flags & HCD_USB2) | 491 | switch (hcd->driver->flags & HCD_MASK) { |
492 | case HCD_USB3: | ||
493 | bufp = usb3_rh_dev_descriptor; | ||
494 | break; | ||
495 | case HCD_USB2: | ||
430 | bufp = usb2_rh_dev_descriptor; | 496 | bufp = usb2_rh_dev_descriptor; |
431 | else if (hcd->driver->flags & HCD_USB11) | 497 | break; |
498 | case HCD_USB11: | ||
432 | bufp = usb11_rh_dev_descriptor; | 499 | bufp = usb11_rh_dev_descriptor; |
433 | else | 500 | break; |
501 | default: | ||
434 | goto error; | 502 | goto error; |
503 | } | ||
435 | len = 18; | 504 | len = 18; |
436 | if (hcd->has_tt) | 505 | if (hcd->has_tt) |
437 | patch_protocol = 1; | 506 | patch_protocol = 1; |
438 | break; | 507 | break; |
439 | case USB_DT_CONFIG << 8: | 508 | case USB_DT_CONFIG << 8: |
440 | if (hcd->driver->flags & HCD_USB2) { | 509 | switch (hcd->driver->flags & HCD_MASK) { |
510 | case HCD_USB3: | ||
511 | bufp = ss_rh_config_descriptor; | ||
512 | len = sizeof ss_rh_config_descriptor; | ||
513 | break; | ||
514 | case HCD_USB2: | ||
441 | bufp = hs_rh_config_descriptor; | 515 | bufp = hs_rh_config_descriptor; |
442 | len = sizeof hs_rh_config_descriptor; | 516 | len = sizeof hs_rh_config_descriptor; |
443 | } else { | 517 | break; |
518 | case HCD_USB11: | ||
444 | bufp = fs_rh_config_descriptor; | 519 | bufp = fs_rh_config_descriptor; |
445 | len = sizeof fs_rh_config_descriptor; | 520 | len = sizeof fs_rh_config_descriptor; |
521 | break; | ||
522 | default: | ||
523 | goto error; | ||
446 | } | 524 | } |
447 | if (device_can_wakeup(&hcd->self.root_hub->dev)) | 525 | if (device_can_wakeup(&hcd->self.root_hub->dev)) |
448 | patch_wakeup = 1; | 526 | patch_wakeup = 1; |
@@ -755,23 +833,6 @@ static struct attribute_group usb_bus_attr_group = { | |||
755 | 833 | ||
756 | /*-------------------------------------------------------------------------*/ | 834 | /*-------------------------------------------------------------------------*/ |
757 | 835 | ||
758 | static struct class *usb_host_class; | ||
759 | |||
760 | int usb_host_init(void) | ||
761 | { | ||
762 | int retval = 0; | ||
763 | |||
764 | usb_host_class = class_create(THIS_MODULE, "usb_host"); | ||
765 | if (IS_ERR(usb_host_class)) | ||
766 | retval = PTR_ERR(usb_host_class); | ||
767 | return retval; | ||
768 | } | ||
769 | |||
770 | void usb_host_cleanup(void) | ||
771 | { | ||
772 | class_destroy(usb_host_class); | ||
773 | } | ||
774 | |||
775 | /** | 836 | /** |
776 | * usb_bus_init - shared initialization code | 837 | * usb_bus_init - shared initialization code |
777 | * @bus: the bus structure being initialized | 838 | * @bus: the bus structure being initialized |
@@ -818,12 +879,6 @@ static int usb_register_bus(struct usb_bus *bus) | |||
818 | set_bit (busnum, busmap.busmap); | 879 | set_bit (busnum, busmap.busmap); |
819 | bus->busnum = busnum; | 880 | bus->busnum = busnum; |
820 | 881 | ||
821 | bus->dev = device_create(usb_host_class, bus->controller, MKDEV(0, 0), | ||
822 | bus, "usb_host%d", busnum); | ||
823 | result = PTR_ERR(bus->dev); | ||
824 | if (IS_ERR(bus->dev)) | ||
825 | goto error_create_class_dev; | ||
826 | |||
827 | /* Add it to the local list of buses */ | 882 | /* Add it to the local list of buses */ |
828 | list_add (&bus->bus_list, &usb_bus_list); | 883 | list_add (&bus->bus_list, &usb_bus_list); |
829 | mutex_unlock(&usb_bus_list_lock); | 884 | mutex_unlock(&usb_bus_list_lock); |
@@ -834,8 +889,6 @@ static int usb_register_bus(struct usb_bus *bus) | |||
834 | "number %d\n", bus->busnum); | 889 | "number %d\n", bus->busnum); |
835 | return 0; | 890 | return 0; |
836 | 891 | ||
837 | error_create_class_dev: | ||
838 | clear_bit(busnum, busmap.busmap); | ||
839 | error_find_busnum: | 892 | error_find_busnum: |
840 | mutex_unlock(&usb_bus_list_lock); | 893 | mutex_unlock(&usb_bus_list_lock); |
841 | return result; | 894 | return result; |
@@ -865,8 +918,6 @@ static void usb_deregister_bus (struct usb_bus *bus) | |||
865 | usb_notify_remove_bus(bus); | 918 | usb_notify_remove_bus(bus); |
866 | 919 | ||
867 | clear_bit (bus->busnum, busmap.busmap); | 920 | clear_bit (bus->busnum, busmap.busmap); |
868 | |||
869 | device_unregister(bus->dev); | ||
870 | } | 921 | } |
871 | 922 | ||
872 | /** | 923 | /** |
@@ -1199,7 +1250,8 @@ static int map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb, | |||
1199 | 1250 | ||
1200 | /* Map the URB's buffers for DMA access. | 1251 | /* Map the URB's buffers for DMA access. |
1201 | * Lower level HCD code should use *_dma exclusively, | 1252 | * Lower level HCD code should use *_dma exclusively, |
1202 | * unless it uses pio or talks to another transport. | 1253 | * unless it uses pio or talks to another transport, |
1254 | * or uses the provided scatter gather list for bulk. | ||
1203 | */ | 1255 | */ |
1204 | if (is_root_hub(urb->dev)) | 1256 | if (is_root_hub(urb->dev)) |
1205 | return 0; | 1257 | return 0; |
@@ -1520,6 +1572,92 @@ rescan: | |||
1520 | } | 1572 | } |
1521 | } | 1573 | } |
1522 | 1574 | ||
1575 | /* Check whether a new configuration or alt setting for an interface | ||
1576 | * will exceed the bandwidth for the bus (or the host controller resources). | ||
1577 | * Only pass in a non-NULL config or interface, not both! | ||
1578 | * Passing NULL for both new_config and new_intf means the device will be | ||
1579 | * de-configured by issuing a set configuration 0 command. | ||
1580 | */ | ||
1581 | int usb_hcd_check_bandwidth(struct usb_device *udev, | ||
1582 | struct usb_host_config *new_config, | ||
1583 | struct usb_interface *new_intf) | ||
1584 | { | ||
1585 | int num_intfs, i, j; | ||
1586 | struct usb_interface_cache *intf_cache; | ||
1587 | struct usb_host_interface *alt = 0; | ||
1588 | int ret = 0; | ||
1589 | struct usb_hcd *hcd; | ||
1590 | struct usb_host_endpoint *ep; | ||
1591 | |||
1592 | hcd = bus_to_hcd(udev->bus); | ||
1593 | if (!hcd->driver->check_bandwidth) | ||
1594 | return 0; | ||
1595 | |||
1596 | /* Configuration is being removed - set configuration 0 */ | ||
1597 | if (!new_config && !new_intf) { | ||
1598 | for (i = 1; i < 16; ++i) { | ||
1599 | ep = udev->ep_out[i]; | ||
1600 | if (ep) | ||
1601 | hcd->driver->drop_endpoint(hcd, udev, ep); | ||
1602 | ep = udev->ep_in[i]; | ||
1603 | if (ep) | ||
1604 | hcd->driver->drop_endpoint(hcd, udev, ep); | ||
1605 | } | ||
1606 | hcd->driver->check_bandwidth(hcd, udev); | ||
1607 | return 0; | ||
1608 | } | ||
1609 | /* Check if the HCD says there's enough bandwidth. Enable all endpoints | ||
1610 | * each interface's alt setting 0 and ask the HCD to check the bandwidth | ||
1611 | * of the bus. There will always be bandwidth for endpoint 0, so it's | ||
1612 | * ok to exclude it. | ||
1613 | */ | ||
1614 | if (new_config) { | ||
1615 | num_intfs = new_config->desc.bNumInterfaces; | ||
1616 | /* Remove endpoints (except endpoint 0, which is always on the | ||
1617 | * schedule) from the old config from the schedule | ||
1618 | */ | ||
1619 | for (i = 1; i < 16; ++i) { | ||
1620 | ep = udev->ep_out[i]; | ||
1621 | if (ep) { | ||
1622 | ret = hcd->driver->drop_endpoint(hcd, udev, ep); | ||
1623 | if (ret < 0) | ||
1624 | goto reset; | ||
1625 | } | ||
1626 | ep = udev->ep_in[i]; | ||
1627 | if (ep) { | ||
1628 | ret = hcd->driver->drop_endpoint(hcd, udev, ep); | ||
1629 | if (ret < 0) | ||
1630 | goto reset; | ||
1631 | } | ||
1632 | } | ||
1633 | for (i = 0; i < num_intfs; ++i) { | ||
1634 | |||
1635 | /* Dig the endpoints for alt setting 0 out of the | ||
1636 | * interface cache for this interface | ||
1637 | */ | ||
1638 | intf_cache = new_config->intf_cache[i]; | ||
1639 | for (j = 0; j < intf_cache->num_altsetting; j++) { | ||
1640 | if (intf_cache->altsetting[j].desc.bAlternateSetting == 0) | ||
1641 | alt = &intf_cache->altsetting[j]; | ||
1642 | } | ||
1643 | if (!alt) { | ||
1644 | printk(KERN_DEBUG "Did not find alt setting 0 for intf %d\n", i); | ||
1645 | continue; | ||
1646 | } | ||
1647 | for (j = 0; j < alt->desc.bNumEndpoints; j++) { | ||
1648 | ret = hcd->driver->add_endpoint(hcd, udev, &alt->endpoint[j]); | ||
1649 | if (ret < 0) | ||
1650 | goto reset; | ||
1651 | } | ||
1652 | } | ||
1653 | } | ||
1654 | ret = hcd->driver->check_bandwidth(hcd, udev); | ||
1655 | reset: | ||
1656 | if (ret < 0) | ||
1657 | hcd->driver->reset_bandwidth(hcd, udev); | ||
1658 | return ret; | ||
1659 | } | ||
1660 | |||
1523 | /* Disables the endpoint: synchronizes with the hcd to make sure all | 1661 | /* Disables the endpoint: synchronizes with the hcd to make sure all |
1524 | * endpoint state is gone from hardware. usb_hcd_flush_endpoint() must | 1662 | * endpoint state is gone from hardware. usb_hcd_flush_endpoint() must |
1525 | * have been called previously. Use for set_configuration, set_interface, | 1663 | * have been called previously. Use for set_configuration, set_interface, |
@@ -1897,8 +2035,20 @@ int usb_add_hcd(struct usb_hcd *hcd, | |||
1897 | retval = -ENOMEM; | 2035 | retval = -ENOMEM; |
1898 | goto err_allocate_root_hub; | 2036 | goto err_allocate_root_hub; |
1899 | } | 2037 | } |
1900 | rhdev->speed = (hcd->driver->flags & HCD_USB2) ? USB_SPEED_HIGH : | 2038 | |
1901 | USB_SPEED_FULL; | 2039 | switch (hcd->driver->flags & HCD_MASK) { |
2040 | case HCD_USB11: | ||
2041 | rhdev->speed = USB_SPEED_FULL; | ||
2042 | break; | ||
2043 | case HCD_USB2: | ||
2044 | rhdev->speed = USB_SPEED_HIGH; | ||
2045 | break; | ||
2046 | case HCD_USB3: | ||
2047 | rhdev->speed = USB_SPEED_SUPER; | ||
2048 | break; | ||
2049 | default: | ||
2050 | goto err_allocate_root_hub; | ||
2051 | } | ||
1902 | hcd->self.root_hub = rhdev; | 2052 | hcd->self.root_hub = rhdev; |
1903 | 2053 | ||
1904 | /* wakeup flag init defaults to "everything works" for root hubs, | 2054 | /* wakeup flag init defaults to "everything works" for root hubs, |