aboutsummaryrefslogtreecommitdiff
path: root/drivers/usb/core
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/core')
-rw-r--r--drivers/usb/core/driver.c9
-rw-r--r--drivers/usb/core/hub.c3
-rw-r--r--drivers/usb/core/message.c28
-rw-r--r--drivers/usb/core/quirks.c12
4 files changed, 44 insertions, 8 deletions
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index 654857493a8..a1ad11d0c47 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -1224,6 +1224,8 @@ static int usb_autopm_do_device(struct usb_device *udev, int inc_usage_cnt)
udev->auto_pm = 1;
udev->pm_usage_cnt += inc_usage_cnt;
WARN_ON(udev->pm_usage_cnt < 0);
+ if (inc_usage_cnt)
+ udev->last_busy = jiffies;
if (inc_usage_cnt >= 0 && udev->pm_usage_cnt > 0) {
if (udev->state == USB_STATE_SUSPENDED)
status = usb_resume_both(udev);
@@ -1232,8 +1234,6 @@ static int usb_autopm_do_device(struct usb_device *udev, int inc_usage_cnt)
else if (inc_usage_cnt)
udev->last_busy = jiffies;
} else if (inc_usage_cnt <= 0 && udev->pm_usage_cnt <= 0) {
- if (inc_usage_cnt)
- udev->last_busy = jiffies;
status = usb_suspend_both(udev, PMSG_SUSPEND);
}
usb_pm_unlock(udev);
@@ -1342,16 +1342,15 @@ static int usb_autopm_do_interface(struct usb_interface *intf,
else {
udev->auto_pm = 1;
intf->pm_usage_cnt += inc_usage_cnt;
+ udev->last_busy = jiffies;
if (inc_usage_cnt >= 0 && intf->pm_usage_cnt > 0) {
if (udev->state == USB_STATE_SUSPENDED)
status = usb_resume_both(udev);
if (status != 0)
intf->pm_usage_cnt -= inc_usage_cnt;
- else if (inc_usage_cnt)
+ else
udev->last_busy = jiffies;
} else if (inc_usage_cnt <= 0 && intf->pm_usage_cnt <= 0) {
- if (inc_usage_cnt)
- udev->last_busy = jiffies;
status = usb_suspend_both(udev, PMSG_SUSPEND);
}
}
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index e341a1da517..f7b337feb3e 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -1644,9 +1644,10 @@ static int finish_port_resume(struct usb_device *udev)
* and device drivers will know about any resume quirks.
*/
if (status == 0) {
+ devstatus = 0;
status = usb_get_status(udev, USB_RECIP_DEVICE, 0, &devstatus);
if (status >= 0)
- status = (status == 2 ? 0 : -ENODEV);
+ status = (status > 0 ? 0 : -ENODEV);
}
if (status) {
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index b6bd05e3d43..d8f7b089a8f 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -637,12 +637,12 @@ int usb_get_descriptor(struct usb_device *dev, unsigned char type, unsigned char
memset(buf,0,size); // Make sure we parse really received data
for (i = 0; i < 3; ++i) {
- /* retry on length 0 or stall; some devices are flakey */
+ /* retry on length 0 or error; some devices are flakey */
result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
(type << 8) + index, 0, buf, size,
USB_CTRL_GET_TIMEOUT);
- if (result == 0 || result == -EPIPE)
+ if (result <= 0 && result != -ETIMEDOUT)
continue;
if (result > 1 && ((u8 *)buf)[1] != type) {
result = -EPROTO;
@@ -1358,6 +1358,30 @@ static int usb_if_uevent(struct device *dev, char **envp, int num_envp,
usb_dev = interface_to_usbdev(intf);
alt = intf->cur_altsetting;
+#ifdef CONFIG_USB_DEVICEFS
+ if (add_uevent_var(envp, num_envp, &i,
+ buffer, buffer_size, &length,
+ "DEVICE=/proc/bus/usb/%03d/%03d",
+ usb_dev->bus->busnum, usb_dev->devnum))
+ return -ENOMEM;
+#endif
+
+ if (add_uevent_var(envp, num_envp, &i,
+ buffer, buffer_size, &length,
+ "PRODUCT=%x/%x/%x",
+ le16_to_cpu(usb_dev->descriptor.idVendor),
+ le16_to_cpu(usb_dev->descriptor.idProduct),
+ le16_to_cpu(usb_dev->descriptor.bcdDevice)))
+ return -ENOMEM;
+
+ if (add_uevent_var(envp, num_envp, &i,
+ buffer, buffer_size, &length,
+ "TYPE=%d/%d/%d",
+ usb_dev->descriptor.bDeviceClass,
+ usb_dev->descriptor.bDeviceSubClass,
+ usb_dev->descriptor.bDeviceProtocol))
+ return -ENOMEM;
+
if (add_uevent_var(envp, num_envp, &i,
buffer, buffer_size, &length,
"INTERFACE=%d/%d/%d",
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
index b7917c5a3c6..9e467118dc9 100644
--- a/drivers/usb/core/quirks.c
+++ b/drivers/usb/core/quirks.c
@@ -30,6 +30,8 @@
static const struct usb_device_id usb_quirk_list[] = {
/* HP 5300/5370C scanner */
{ USB_DEVICE(0x03f0, 0x0701), .driver_info = USB_QUIRK_STRING_FETCH_255 },
+ /* Hewlett-Packard PhotoSmart 720 / PhotoSmart 935 (storage) */
+ { USB_DEVICE(0x03f0, 0x4002), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
/* Acer Peripherals Inc. (now BenQ Corp.) Prisa 640BU */
{ USB_DEVICE(0x04a5, 0x207e), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
/* Benq S2W 3300U */
@@ -56,6 +58,8 @@ static const struct usb_device_id usb_quirk_list[] = {
{ USB_DEVICE(0x04b8, 0x0121), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
/* Seiko Epson Corp.*/
{ USB_DEVICE(0x04b8, 0x0122), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
+ /* Samsung ML-2010 printer */
+ { USB_DEVICE(0x04e8, 0x326c), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
/* Samsung ML-2510 Series printer */
{ USB_DEVICE(0x04e8, 0x327e), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
/* Elsa MicroLink 56k (V.250) */
@@ -64,12 +68,20 @@ static const struct usb_device_id usb_quirk_list[] = {
{ USB_DEVICE(0x05d8, 0x4005), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
/* Agfa Snapscan1212u */
{ USB_DEVICE(0x06bd, 0x2061), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
+ /* Seagate RSS LLC */
+ { USB_DEVICE(0x0bc2, 0x3000), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
/* Umax [hex] Astra 3400U */
{ USB_DEVICE(0x1606, 0x0060), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
/* Philips PSC805 audio device */
{ USB_DEVICE(0x0471, 0x0155), .driver_info = USB_QUIRK_RESET_RESUME },
+ /* Alcor multi-card reader */
+ { USB_DEVICE(0x058f, 0x6366), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
+
+ /* Canon EOS 5D in PC Connection mode */
+ { USB_DEVICE(0x04a9, 0x3101), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
+
/* RIM Blackberry */
{ USB_DEVICE(0x0fca, 0x0001), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
{ USB_DEVICE(0x0fca, 0x0004), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },