diff options
| author | J. Bruce Fields <bfields@citi.umich.edu> | 2008-07-03 16:24:06 -0400 |
|---|---|---|
| committer | J. Bruce Fields <bfields@citi.umich.edu> | 2008-07-03 16:24:06 -0400 |
| commit | e86322f611eef95aafaf726fd3965e5b211f1985 (patch) | |
| tree | 28547e26df4fc6ae671dc8cc6912a53717e4db08 /drivers/usb/core | |
| parent | b001a1b6aa960949a24c2cdc28257dfcc9428d74 (diff) | |
| parent | 8948896c9e098c6fd31a6a698a598a7cbd7fa40e (diff) | |
Merge branch 'for-bfields' of git://linux-nfs.org/~tomtucker/xprt-switch-2.6 into for-2.6.27
Diffstat (limited to 'drivers/usb/core')
| -rw-r--r-- | drivers/usb/core/generic.c | 5 | ||||
| -rw-r--r-- | drivers/usb/core/hcd.c | 6 | ||||
| -rw-r--r-- | drivers/usb/core/hcd.h | 2 | ||||
| -rw-r--r-- | drivers/usb/core/hub.c | 61 | ||||
| -rw-r--r-- | drivers/usb/core/quirks.c | 7 | ||||
| -rw-r--r-- | drivers/usb/core/sysfs.c | 44 |
6 files changed, 91 insertions, 34 deletions
diff --git a/drivers/usb/core/generic.c b/drivers/usb/core/generic.c index c1cb94e9f242..7e912f21fd36 100644 --- a/drivers/usb/core/generic.c +++ b/drivers/usb/core/generic.c | |||
| @@ -155,9 +155,6 @@ static int generic_probe(struct usb_device *udev) | |||
| 155 | { | 155 | { |
| 156 | int err, c; | 156 | int err, c; |
| 157 | 157 | ||
| 158 | /* put device-specific files into sysfs */ | ||
| 159 | usb_create_sysfs_dev_files(udev); | ||
| 160 | |||
| 161 | /* Choose and set the configuration. This registers the interfaces | 158 | /* Choose and set the configuration. This registers the interfaces |
| 162 | * with the driver core and lets interface drivers bind to them. | 159 | * with the driver core and lets interface drivers bind to them. |
| 163 | */ | 160 | */ |
| @@ -189,8 +186,6 @@ static void generic_disconnect(struct usb_device *udev) | |||
| 189 | * unconfigure the device */ | 186 | * unconfigure the device */ |
| 190 | if (udev->actconfig) | 187 | if (udev->actconfig) |
| 191 | usb_set_configuration(udev, -1); | 188 | usb_set_configuration(udev, -1); |
| 192 | |||
| 193 | usb_remove_sysfs_dev_files(udev); | ||
| 194 | } | 189 | } |
| 195 | 190 | ||
| 196 | #ifdef CONFIG_PM | 191 | #ifdef CONFIG_PM |
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index bf10e9c4195e..09a53e7f3327 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c | |||
| @@ -818,12 +818,12 @@ static int usb_register_bus(struct usb_bus *bus) | |||
| 818 | set_bit (busnum, busmap.busmap); | 818 | set_bit (busnum, busmap.busmap); |
| 819 | bus->busnum = busnum; | 819 | bus->busnum = busnum; |
| 820 | 820 | ||
| 821 | bus->dev = device_create(usb_host_class, bus->controller, MKDEV(0, 0), | 821 | bus->dev = device_create_drvdata(usb_host_class, bus->controller, |
| 822 | "usb_host%d", busnum); | 822 | MKDEV(0, 0), bus, |
| 823 | "usb_host%d", busnum); | ||
| 823 | result = PTR_ERR(bus->dev); | 824 | result = PTR_ERR(bus->dev); |
| 824 | if (IS_ERR(bus->dev)) | 825 | if (IS_ERR(bus->dev)) |
| 825 | goto error_create_class_dev; | 826 | goto error_create_class_dev; |
| 826 | dev_set_drvdata(bus->dev, bus); | ||
| 827 | 827 | ||
| 828 | /* Add it to the local list of buses */ | 828 | /* Add it to the local list of buses */ |
| 829 | list_add (&bus->bus_list, &usb_bus_list); | 829 | list_add (&bus->bus_list, &usb_bus_list); |
diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h index 1e4b81e9eb50..a0bf5df6cb6f 100644 --- a/drivers/usb/core/hcd.h +++ b/drivers/usb/core/hcd.h | |||
| @@ -213,6 +213,8 @@ struct hc_driver { | |||
| 213 | 213 | ||
| 214 | /* force handover of high-speed port to full-speed companion */ | 214 | /* force handover of high-speed port to full-speed companion */ |
| 215 | void (*relinquish_port)(struct usb_hcd *, int); | 215 | void (*relinquish_port)(struct usb_hcd *, int); |
| 216 | /* has a port been handed over to a companion? */ | ||
| 217 | int (*port_handed_over)(struct usb_hcd *, int); | ||
| 216 | }; | 218 | }; |
| 217 | 219 | ||
| 218 | extern int usb_hcd_link_urb_to_ep(struct usb_hcd *hcd, struct urb *urb); | 220 | extern int usb_hcd_link_urb_to_ep(struct usb_hcd *hcd, struct urb *urb); |
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index eb57fcc701d7..94789be54ca3 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
| @@ -644,6 +644,48 @@ static void hub_stop(struct usb_hub *hub) | |||
| 644 | 644 | ||
| 645 | #ifdef CONFIG_PM | 645 | #ifdef CONFIG_PM |
| 646 | 646 | ||
| 647 | /* Try to identify which devices need USB-PERSIST handling */ | ||
| 648 | static int persistent_device(struct usb_device *udev) | ||
| 649 | { | ||
| 650 | int i; | ||
| 651 | int retval; | ||
| 652 | struct usb_host_config *actconfig; | ||
| 653 | |||
| 654 | /* Explicitly not marked persistent? */ | ||
| 655 | if (!udev->persist_enabled) | ||
| 656 | return 0; | ||
| 657 | |||
| 658 | /* No active config? */ | ||
| 659 | actconfig = udev->actconfig; | ||
| 660 | if (!actconfig) | ||
| 661 | return 0; | ||
| 662 | |||
| 663 | /* FIXME! We should check whether it's open here or not! */ | ||
| 664 | |||
| 665 | /* | ||
| 666 | * Check that all the interface drivers have a | ||
| 667 | * 'reset_resume' entrypoint | ||
| 668 | */ | ||
| 669 | retval = 0; | ||
| 670 | for (i = 0; i < actconfig->desc.bNumInterfaces; i++) { | ||
| 671 | struct usb_interface *intf; | ||
| 672 | struct usb_driver *driver; | ||
| 673 | |||
| 674 | intf = actconfig->interface[i]; | ||
| 675 | if (!intf->dev.driver) | ||
| 676 | continue; | ||
| 677 | driver = to_usb_driver(intf->dev.driver); | ||
| 678 | if (!driver->reset_resume) | ||
| 679 | return 0; | ||
| 680 | /* | ||
| 681 | * We have at least one driver, and that one | ||
| 682 | * has a reset_resume method. | ||
| 683 | */ | ||
| 684 | retval = 1; | ||
| 685 | } | ||
| 686 | return retval; | ||
| 687 | } | ||
| 688 | |||
| 647 | static void hub_restart(struct usb_hub *hub, int type) | 689 | static void hub_restart(struct usb_hub *hub, int type) |
| 648 | { | 690 | { |
| 649 | struct usb_device *hdev = hub->hdev; | 691 | struct usb_device *hdev = hub->hdev; |
| @@ -689,8 +731,8 @@ static void hub_restart(struct usb_hub *hub, int type) | |||
| 689 | * turn off the various status changes to prevent | 731 | * turn off the various status changes to prevent |
| 690 | * khubd from disconnecting it later. | 732 | * khubd from disconnecting it later. |
| 691 | */ | 733 | */ |
| 692 | if (udev->persist_enabled && status == 0 && | 734 | if (status == 0 && !(portstatus & USB_PORT_STAT_ENABLE) && |
| 693 | !(portstatus & USB_PORT_STAT_ENABLE)) { | 735 | persistent_device(udev)) { |
| 694 | if (portchange & USB_PORT_STAT_C_ENABLE) | 736 | if (portchange & USB_PORT_STAT_C_ENABLE) |
| 695 | clear_port_feature(hub->hdev, port1, | 737 | clear_port_feature(hub->hdev, port1, |
| 696 | USB_PORT_FEAT_C_ENABLE); | 738 | USB_PORT_FEAT_C_ENABLE); |
| @@ -1326,6 +1368,12 @@ void usb_disconnect(struct usb_device **pdev) | |||
| 1326 | 1368 | ||
| 1327 | usb_unlock_device(udev); | 1369 | usb_unlock_device(udev); |
| 1328 | 1370 | ||
| 1371 | /* Remove the device-specific files from sysfs. This must be | ||
| 1372 | * done with udev unlocked, because some of the attribute | ||
| 1373 | * routines try to acquire the device lock. | ||
| 1374 | */ | ||
| 1375 | usb_remove_sysfs_dev_files(udev); | ||
| 1376 | |||
| 1329 | /* Unregister the device. The device driver is responsible | 1377 | /* Unregister the device. The device driver is responsible |
| 1330 | * for removing the device files from usbfs and sysfs and for | 1378 | * for removing the device files from usbfs and sysfs and for |
| 1331 | * de-configuring the device. | 1379 | * de-configuring the device. |
| @@ -1541,6 +1589,9 @@ int usb_new_device(struct usb_device *udev) | |||
| 1541 | goto fail; | 1589 | goto fail; |
| 1542 | } | 1590 | } |
| 1543 | 1591 | ||
| 1592 | /* put device-specific files into sysfs */ | ||
| 1593 | usb_create_sysfs_dev_files(udev); | ||
| 1594 | |||
| 1544 | /* Tell the world! */ | 1595 | /* Tell the world! */ |
| 1545 | announce_device(udev); | 1596 | announce_device(udev); |
| 1546 | return err; | 1597 | return err; |
| @@ -2744,7 +2795,11 @@ loop: | |||
| 2744 | if ((status == -ENOTCONN) || (status == -ENOTSUPP)) | 2795 | if ((status == -ENOTCONN) || (status == -ENOTSUPP)) |
| 2745 | break; | 2796 | break; |
| 2746 | } | 2797 | } |
| 2747 | dev_err(hub_dev, "unable to enumerate USB device on port %d\n", port1); | 2798 | if (hub->hdev->parent || |
| 2799 | !hcd->driver->port_handed_over || | ||
| 2800 | !(hcd->driver->port_handed_over)(hcd, port1)) | ||
| 2801 | dev_err(hub_dev, "unable to enumerate USB device on port %d\n", | ||
| 2802 | port1); | ||
| 2748 | 2803 | ||
| 2749 | done: | 2804 | done: |
| 2750 | hub_port_disable(hub, port1, 1); | 2805 | hub_port_disable(hub, port1, 1); |
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index 2e2019390290..c070b34b669d 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c | |||
| @@ -47,6 +47,13 @@ static const struct usb_device_id usb_quirk_list[] = { | |||
| 47 | /* Edirol SD-20 */ | 47 | /* Edirol SD-20 */ |
| 48 | { USB_DEVICE(0x0582, 0x0027), .driver_info = USB_QUIRK_RESET_RESUME }, | 48 | { USB_DEVICE(0x0582, 0x0027), .driver_info = USB_QUIRK_RESET_RESUME }, |
| 49 | 49 | ||
| 50 | /* appletouch */ | ||
| 51 | { USB_DEVICE(0x05ac, 0x021a), .driver_info = USB_QUIRK_RESET_RESUME }, | ||
| 52 | |||
| 53 | /* Avision AV600U */ | ||
| 54 | { USB_DEVICE(0x0638, 0x0a13), .driver_info = | ||
| 55 | USB_QUIRK_STRING_FETCH_255 }, | ||
| 56 | |||
| 50 | /* M-Systems Flash Disk Pioneers */ | 57 | /* M-Systems Flash Disk Pioneers */ |
| 51 | { USB_DEVICE(0x08ec, 0x1000), .driver_info = USB_QUIRK_RESET_RESUME }, | 58 | { USB_DEVICE(0x08ec, 0x1000), .driver_info = USB_QUIRK_RESET_RESUME }, |
| 52 | 59 | ||
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index c783cb111847..5e1f5d55bf04 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c | |||
| @@ -588,35 +588,33 @@ read_descriptors(struct kobject *kobj, struct bin_attribute *attr, | |||
| 588 | container_of(kobj, struct device, kobj)); | 588 | container_of(kobj, struct device, kobj)); |
| 589 | size_t nleft = count; | 589 | size_t nleft = count; |
| 590 | size_t srclen, n; | 590 | size_t srclen, n; |
| 591 | int cfgno; | ||
| 592 | void *src; | ||
| 591 | 593 | ||
| 592 | usb_lock_device(udev); | 594 | /* The binary attribute begins with the device descriptor. |
| 593 | 595 | * Following that are the raw descriptor entries for all the | |
| 594 | /* The binary attribute begins with the device descriptor */ | 596 | * configurations (config plus subsidiary descriptors). |
| 595 | srclen = sizeof(struct usb_device_descriptor); | ||
| 596 | if (off < srclen) { | ||
| 597 | n = min_t(size_t, nleft, srclen - off); | ||
| 598 | memcpy(buf, off + (char *) &udev->descriptor, n); | ||
| 599 | nleft -= n; | ||
| 600 | buf += n; | ||
| 601 | off = 0; | ||
| 602 | } else { | ||
| 603 | off -= srclen; | ||
| 604 | } | ||
| 605 | |||
| 606 | /* Then follows the raw descriptor entry for the current | ||
| 607 | * configuration (config plus subsidiary descriptors). | ||
| 608 | */ | 597 | */ |
| 609 | if (udev->actconfig) { | 598 | for (cfgno = -1; cfgno < udev->descriptor.bNumConfigurations && |
| 610 | int cfgno = udev->actconfig - udev->config; | 599 | nleft > 0; ++cfgno) { |
| 611 | 600 | if (cfgno < 0) { | |
| 612 | srclen = __le16_to_cpu(udev->actconfig->desc.wTotalLength); | 601 | src = &udev->descriptor; |
| 602 | srclen = sizeof(struct usb_device_descriptor); | ||
| 603 | } else { | ||
| 604 | src = udev->rawdescriptors[cfgno]; | ||
| 605 | srclen = __le16_to_cpu(udev->config[cfgno].desc. | ||
| 606 | wTotalLength); | ||
| 607 | } | ||
| 613 | if (off < srclen) { | 608 | if (off < srclen) { |
| 614 | n = min_t(size_t, nleft, srclen - off); | 609 | n = min(nleft, srclen - (size_t) off); |
| 615 | memcpy(buf, off + udev->rawdescriptors[cfgno], n); | 610 | memcpy(buf, src + off, n); |
| 616 | nleft -= n; | 611 | nleft -= n; |
| 612 | buf += n; | ||
| 613 | off = 0; | ||
| 614 | } else { | ||
| 615 | off -= srclen; | ||
| 617 | } | 616 | } |
| 618 | } | 617 | } |
| 619 | usb_unlock_device(udev); | ||
| 620 | return count - nleft; | 618 | return count - nleft; |
| 621 | } | 619 | } |
| 622 | 620 | ||
