USB: storage: Never reset devices that will morph to an old mode
authorOliver Neukum <oliver@neukum.org>
Fri, 18 Dec 2009 11:14:21 +0000 (12:14 +0100)
committerGreg Kroah-Hartman <gregkh@suse.de>
Tue, 2 Mar 2010 22:53:23 +0000 (14:53 -0800)
Some devices must be switched to a new mode to fully use them.
A reset would make them revert to the old mode. Therefore a reset
must not be used for error handling with such devices.

Signed-off-by: Oliver Neukum <oliver@neukum.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/usb/core/quirks.c
drivers/usb/storage/transport.c
include/linux/usb/quirks.h

index ab93918d92076dedec3575b49e5eaacfb2c32e71..0b689224394b8ccb01da265313fdb21297ae2592 100644 (file)
@@ -120,6 +120,7 @@ void usb_detect_quirks(struct usb_device *udev)
         * for all devices.  It will affect things like hub resets
         * and EMF-related port disables.
         */
-       udev->persist_enabled = 1;
+       if (!(udev->quirks & USB_QUIRK_RESET_MORPHS))
+               udev->persist_enabled = 1;
 #endif /* CONFIG_PM */
 }
index cc313d16d727d0dc827627835d380249f638ab9c..468038126e5eb00ba5180585a8923575103be9d0 100644 (file)
@@ -47,6 +47,8 @@
 #include <linux/errno.h>
 #include <linux/slab.h>
 
+#include <linux/usb/quirks.h>
+
 #include <scsi/scsi.h>
 #include <scsi/scsi_eh.h>
 #include <scsi/scsi_device.h>
@@ -1297,6 +1299,10 @@ int usb_stor_port_reset(struct us_data *us)
 {
        int result;
 
+       /*for these devices we must use the class specific method */
+       if (us->pusb_dev->quirks & USB_QUIRK_RESET_MORPHS)
+               return -EPERM;
+
        result = usb_lock_device_for_reset(us->pusb_dev, us->pusb_intf);
        if (result < 0)
                US_DEBUGP("unable to lock device for reset: %d\n", result);
index 2526f3bbd273e522e1ff77b2ba404c87d9a5a56a..0a555dd131fcdc24db1b8debe89f641fcc5b20bb 100644 (file)
@@ -19,4 +19,7 @@
 /* device can't handle its Configuration or Interface strings */
 #define USB_QUIRK_CONFIG_INTF_STRINGS  0x00000008
 
+/*device will morph if reset, don't use reset for handling errors */
+#define USB_QUIRK_RESET_MORPHS         0x00000010
+
 #endif /* __LINUX_USB_QUIRKS_H */