aboutsummaryrefslogtreecommitdiff
path: root/drivers/usb/storage
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/storage')
-rw-r--r--drivers/usb/storage/dpcm.c56
-rw-r--r--drivers/usb/storage/onetouch.c13
-rw-r--r--drivers/usb/storage/scsiglue.c21
-rw-r--r--drivers/usb/storage/unusual_devs.h206
-rw-r--r--drivers/usb/storage/usb.c94
-rw-r--r--drivers/usb/storage/usb.h1
6 files changed, 217 insertions, 174 deletions
diff --git a/drivers/usb/storage/dpcm.c b/drivers/usb/storage/dpcm.c
index 1628cb25856..9a410b5a6e5 100644
--- a/drivers/usb/storage/dpcm.c
+++ b/drivers/usb/storage/dpcm.c
@@ -46,43 +46,43 @@
*/
int dpcm_transport(struct scsi_cmnd *srb, struct us_data *us)
{
- int ret;
+ int ret;
- if(srb == NULL)
- return USB_STOR_TRANSPORT_ERROR;
+ if (srb == NULL)
+ return USB_STOR_TRANSPORT_ERROR;
- US_DEBUGP("dpcm_transport: LUN=%d\n", srb->device->lun);
+ US_DEBUGP("dpcm_transport: LUN=%d\n", srb->device->lun);
- switch(srb->device->lun) {
- case 0:
+ switch (srb->device->lun) {
+ case 0:
- /*
- * LUN 0 corresponds to the CompactFlash card reader.
- */
- ret = usb_stor_CB_transport(srb, us);
- break;
+ /*
+ * LUN 0 corresponds to the CompactFlash card reader.
+ */
+ ret = usb_stor_CB_transport(srb, us);
+ break;
#ifdef CONFIG_USB_STORAGE_SDDR09
- case 1:
+ case 1:
- /*
- * LUN 1 corresponds to the SmartMedia card reader.
- */
+ /*
+ * LUN 1 corresponds to the SmartMedia card reader.
+ */
- /*
- * Set the LUN to 0 (just in case).
- */
- srb->device->lun = 0; us->srb->device->lun = 0;
- ret = sddr09_transport(srb, us);
- srb->device->lun = 1; us->srb->device->lun = 1;
- break;
+ /*
+ * Set the LUN to 0 (just in case).
+ */
+ srb->device->lun = 0; us->srb->device->lun = 0;
+ ret = sddr09_transport(srb, us);
+ srb->device->lun = 1; us->srb->device->lun = 1;
+ break;
#endif
- default:
- US_DEBUGP("dpcm_transport: Invalid LUN %d\n", srb->device->lun);
- ret = USB_STOR_TRANSPORT_ERROR;
- break;
- }
- return ret;
+ default:
+ US_DEBUGP("dpcm_transport: Invalid LUN %d\n", srb->device->lun);
+ ret = USB_STOR_TRANSPORT_ERROR;
+ break;
+ }
+ return ret;
}
diff --git a/drivers/usb/storage/onetouch.c b/drivers/usb/storage/onetouch.c
index d35369392fe..dfd42fe9e5f 100644
--- a/drivers/usb/storage/onetouch.c
+++ b/drivers/usb/storage/onetouch.c
@@ -57,9 +57,10 @@ static void usb_onetouch_irq(struct urb *urb)
struct usb_onetouch *onetouch = urb->context;
signed char *data = onetouch->data;
struct input_dev *dev = onetouch->dev;
- int status;
+ int status = urb->status;
+ int retval;
- switch (urb->status) {
+ switch (status) {
case 0: /* success */
break;
case -ECONNRESET: /* unlink */
@@ -75,11 +76,11 @@ static void usb_onetouch_irq(struct urb *urb)
input_sync(dev);
resubmit:
- status = usb_submit_urb (urb, GFP_ATOMIC);
- if (status)
- err ("can't resubmit intr, %s-%s/input0, status %d",
+ retval = usb_submit_urb (urb, GFP_ATOMIC);
+ if (retval)
+ err ("can't resubmit intr, %s-%s/input0, retval %d",
onetouch->udev->bus->bus_name,
- onetouch->udev->devpath, status);
+ onetouch->udev->devpath, retval);
}
static int usb_onetouch_open(struct input_dev *dev)
diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c
index e227f64d564..47e56079925 100644
--- a/drivers/usb/storage/scsiglue.c
+++ b/drivers/usb/storage/scsiglue.c
@@ -285,10 +285,15 @@ static int device_reset(struct scsi_cmnd *srb)
US_DEBUGP("%s called\n", __FUNCTION__);
- /* lock the device pointers and do the reset */
- mutex_lock(&(us->dev_mutex));
- result = us->transport_reset(us);
- mutex_unlock(&us->dev_mutex);
+ result = usb_autopm_get_interface(us->pusb_intf);
+ if (result == 0) {
+
+ /* lock the device pointers and do the reset */
+ mutex_lock(&(us->dev_mutex));
+ result = us->transport_reset(us);
+ mutex_unlock(&us->dev_mutex);
+ usb_autopm_put_interface(us->pusb_intf);
+ }
return result < 0 ? FAILED : SUCCESS;
}
@@ -321,10 +326,14 @@ void usb_stor_report_device_reset(struct us_data *us)
/* Report a driver-initiated bus reset to the SCSI layer.
* Calling this for a SCSI-initiated reset is unnecessary but harmless.
- * The caller must own the SCSI host lock. */
+ * The caller must not own the SCSI host lock. */
void usb_stor_report_bus_reset(struct us_data *us)
{
- scsi_report_bus_reset(us_to_host(us), 0);
+ struct Scsi_Host *host = us_to_host(us);
+
+ scsi_lock(host);
+ scsi_report_bus_reset(host, 0);
+ scsi_unlock(host);
}
/***********************************************************************
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
index 54979c239c6..a624e72f81d 100644
--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -50,10 +50,10 @@
/* patch submitted by Vivian Bregier <Vivian.Bregier@imag.fr>
*/
UNUSUAL_DEV( 0x03eb, 0x2002, 0x0100, 0x0100,
- "ATMEL",
- "SND1 Storage",
- US_SC_DEVICE, US_PR_DEVICE, NULL,
- US_FL_IGNORE_RESIDUE),
+ "ATMEL",
+ "SND1 Storage",
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ US_FL_IGNORE_RESIDUE),
/* modified by Tobias Lorenz <tobias.lorenz@gmx.net> */
UNUSUAL_DEV( 0x03ee, 0x6901, 0x0000, 0x0200,
@@ -69,18 +69,18 @@ UNUSUAL_DEV( 0x03ee, 0x6906, 0x0003, 0x0003,
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_IGNORE_RESIDUE ),
-UNUSUAL_DEV( 0x03f0, 0x0107, 0x0200, 0x0200,
+UNUSUAL_DEV( 0x03f0, 0x0107, 0x0200, 0x0200,
"HP",
"CD-Writer+",
- US_SC_8070, US_PR_CB, NULL, 0),
+ US_SC_8070, US_PR_CB, NULL, 0),
#ifdef CONFIG_USB_STORAGE_USBAT
-UNUSUAL_DEV( 0x03f0, 0x0207, 0x0001, 0x0001,
+UNUSUAL_DEV( 0x03f0, 0x0207, 0x0001, 0x0001,
"HP",
"CD-Writer+ 8200e",
US_SC_8070, US_PR_USBAT, init_usbat_cd, 0),
-UNUSUAL_DEV( 0x03f0, 0x0307, 0x0001, 0x0001,
+UNUSUAL_DEV( 0x03f0, 0x0307, 0x0001, 0x0001,
"HP",
"CD-Writer+ CD-4e",
US_SC_8070, US_PR_USBAT, init_usbat_cd, 0),
@@ -115,10 +115,10 @@ UNUSUAL_DEV( 0x0411, 0x001c, 0x0113, 0x0113,
/* Submitted by Ernestas Vaiciukevicius <ernisv@gmail.com> */
UNUSUAL_DEV( 0x0419, 0x0100, 0x0100, 0x0100,
- "Samsung Info. Systems America, Inc.",
- "MP3 Player",
- US_SC_DEVICE, US_PR_DEVICE, NULL,
- US_FL_IGNORE_RESIDUE ),
+ "Samsung Info. Systems America, Inc.",
+ "MP3 Player",
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ US_FL_IGNORE_RESIDUE ),
/* Reported by Orgad Shaneh <orgads@gmail.com> */
UNUSUAL_DEV( 0x0419, 0xaace, 0x0100, 0x0100,
@@ -256,10 +256,10 @@ UNUSUAL_DEV( 0x0457, 0x0150, 0x0100, 0x0100,
* the revision to my model only
*/
UNUSUAL_DEV( 0x0457, 0x0151, 0x0100, 0x0100,
- "USB 2.0",
- "Flash Disk",
- US_SC_DEVICE, US_PR_DEVICE, NULL,
- US_FL_NOT_LOCKABLE ),
+ "USB 2.0",
+ "Flash Disk",
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ US_FL_NOT_LOCKABLE ),
#ifdef CONFIG_USB_STORAGE_KARMA
UNUSUAL_DEV( 0x045a, 0x5210, 0x0101, 0x0101,
@@ -313,6 +313,13 @@ UNUSUAL_DEV( 0x04b0, 0x0301, 0x0010, 0x0010,
US_SC_DEVICE, US_PR_DEVICE,NULL,
US_FL_NOT_LOCKABLE ),
+/* Reported by Stefan de Konink <skinkie@xs4all.nl> */
+UNUSUAL_DEV( 0x04b0, 0x0401, 0x0200, 0x0200,
+ "NIKON",
+ "NIKON DSC D100",
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ US_FL_FIX_CAPACITY),
+
/* Reported by Andreas Bockhold <andreas@bockionline.de> */
UNUSUAL_DEV( 0x04b0, 0x0405, 0x0100, 0x0100,
"NIKON",
@@ -408,19 +415,19 @@ UNUSUAL_DEV( 0x04da, 0x2373, 0x0000, 0x9999,
/* Most of the following entries were developed with the help of
* Shuttle/SCM directly.
*/
-UNUSUAL_DEV( 0x04e6, 0x0001, 0x0200, 0x0200,
+UNUSUAL_DEV( 0x04e6, 0x0001, 0x0200, 0x0200,
"Matshita",
"LS-120",
US_SC_8020, US_PR_CB, NULL, 0),
-UNUSUAL_DEV( 0x04e6, 0x0002, 0x0100, 0x0100,
+UNUSUAL_DEV( 0x04e6, 0x0002, 0x0100, 0x0100,
"Shuttle",
"eUSCSI Bridge",
US_SC_DEVICE, US_PR_DEVICE, usb_stor_euscsi_init,
- US_FL_SCM_MULT_TARG ),
+ US_FL_SCM_MULT_TARG ),
#ifdef CONFIG_USB_STORAGE_SDDR09
-UNUSUAL_DEV( 0x04e6, 0x0003, 0x0000, 0x9999,
+UNUSUAL_DEV( 0x04e6, 0x0003, 0x0000, 0x9999,
"Sandisk",
"ImageMate SDDR09",
US_SC_SCSI, US_PR_EUSB_SDDR09, usb_stor_sddr09_init,
@@ -431,52 +438,52 @@ UNUSUAL_DEV( 0x04e6, 0x0005, 0x0100, 0x0208,
"SCM Microsystems",
"eUSB SmartMedia / CompactFlash Adapter",
US_SC_SCSI, US_PR_DPCM_USB, usb_stor_sddr09_dpcm_init,
- 0),
+ 0),
#endif
/* Reported by Markus Demleitner <msdemlei@cl.uni-heidelberg.de> */
-UNUSUAL_DEV( 0x04e6, 0x0006, 0x0100, 0x0100,
+UNUSUAL_DEV( 0x04e6, 0x0006, 0x0100, 0x0100,
"SCM Microsystems Inc.",
"eUSB MMC Adapter",
- US_SC_SCSI, US_PR_CB, NULL,
- US_FL_SINGLE_LUN),
+ US_SC_SCSI, US_PR_CB, NULL,
+ US_FL_SINGLE_LUN),
/* Reported by Daniel Nouri <dpunktnpunkt@web.de> */
-UNUSUAL_DEV( 0x04e6, 0x0006, 0x0205, 0x0205,
+UNUSUAL_DEV( 0x04e6, 0x0006, 0x0205, 0x0205,
"Shuttle",
"eUSB MMC Adapter",
- US_SC_SCSI, US_PR_DEVICE, NULL,
- US_FL_SINGLE_LUN),
+ US_SC_SCSI, US_PR_DEVICE, NULL,
+ US_FL_SINGLE_LUN),
-UNUSUAL_DEV( 0x04e6, 0x0007, 0x0100, 0x0200,
+UNUSUAL_DEV( 0x04e6, 0x0007, 0x0100, 0x0200,
"Sony",
"Hifd",
- US_SC_SCSI, US_PR_CB, NULL,
- US_FL_SINGLE_LUN),
+ US_SC_SCSI, US_PR_CB, NULL,
+ US_FL_SINGLE_LUN),
-UNUSUAL_DEV( 0x04e6, 0x0009, 0x0200, 0x0200,
+UNUSUAL_DEV( 0x04e6, 0x0009, 0x0200, 0x0200,
"Shuttle",
"eUSB ATA/ATAPI Adapter",
US_SC_8020, US_PR_CB, NULL, 0),
-UNUSUAL_DEV( 0x04e6, 0x000a, 0x0200, 0x0200,
+UNUSUAL_DEV( 0x04e6, 0x000a, 0x0200, 0x0200,
"Shuttle",
"eUSB CompactFlash Adapter",
US_SC_8020, US_PR_CB, NULL, 0),
-UNUSUAL_DEV( 0x04e6, 0x000B, 0x0100, 0x0100,
+UNUSUAL_DEV( 0x04e6, 0x000B, 0x0100, 0x0100,
"Shuttle",
"eUSCSI Bridge",
- US_SC_SCSI, US_PR_BULK, usb_stor_euscsi_init,
+ US_SC_SCSI, US_PR_BULK, usb_stor_euscsi_init,
US_FL_SCM_MULT_TARG ),
-UNUSUAL_DEV( 0x04e6, 0x000C, 0x0100, 0x0100,
+UNUSUAL_DEV( 0x04e6, 0x000C, 0x0100, 0x0100,
"Shuttle",
"eUSCSI Bridge",
- US_SC_SCSI, US_PR_BULK, usb_stor_euscsi_init,
- US_FL_SCM_MULT_TARG ),
+ US_SC_SCSI, US_PR_BULK, usb_stor_euscsi_init,
+ US_FL_SCM_MULT_TARG ),
-UNUSUAL_DEV( 0x04e6, 0x0101, 0x0200, 0x0200,
+UNUSUAL_DEV( 0x04e6, 0x0101, 0x0200, 0x0200,
"Shuttle",
"CD-RW Device",
US_SC_8020, US_PR_CB, NULL, 0),
@@ -556,9 +563,9 @@ UNUSUAL_DEV( 0x052b, 0x1911, 0x0100, 0x0100,
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_IGNORE_RESIDUE ),
-UNUSUAL_DEV( 0x054c, 0x0010, 0x0106, 0x0450,
+UNUSUAL_DEV( 0x054c, 0x0010, 0x0106, 0x0450,
"Sony",
- "DSC-S30/S70/S75/505V/F505/F707/F717/P8",
+ "DSC-S30/S70/S75/505V/F505/F707/F717/P8",
US_SC_SCSI, US_PR_DEVICE, NULL,
US_FL_SINGLE_LUN | US_FL_NOT_LOCKABLE | US_FL_NO_WP_DETECT ),
@@ -572,7 +579,7 @@ UNUSUAL_DEV( 0x054c, 0x0010, 0x0500, 0x0610,
/* Reported by wim@geeks.nl */
-UNUSUAL_DEV( 0x054c, 0x0025, 0x0100, 0x0100,
+UNUSUAL_DEV( 0x054c, 0x0025, 0x0100, 0x0100,
"Sony",
"Memorystick NW-MS7",
US_SC_DEVICE, US_PR_DEVICE, NULL,
@@ -593,21 +600,21 @@ UNUSUAL_DEV( 0x054c, 0x002c, 0x0501, 0x2000,
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_SINGLE_LUN ),
-UNUSUAL_DEV( 0x054c, 0x002d, 0x0100, 0x0100,
+UNUSUAL_DEV( 0x054c, 0x002d, 0x0100, 0x0100,
"Sony",
"Memorystick MSAC-US1",
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_SINGLE_LUN ),
/* Submitted by Klaus Mueller <k.mueller@intershop.de> */
-UNUSUAL_DEV( 0x054c, 0x002e, 0x0106, 0x0310,
+UNUSUAL_DEV( 0x054c, 0x002e, 0x0106, 0x0310,
"Sony",
"Handycam",
US_SC_SCSI, US_PR_DEVICE, NULL,
US_FL_SINGLE_LUN ),
/* Submitted by Rajesh Kumble Nayak <nayak@obs-nice.fr> */
-UNUSUAL_DEV( 0x054c, 0x002e, 0x0500, 0x0500,
+UNUSUAL_DEV( 0x054c, 0x002e, 0x0500, 0x0500,
"Sony",
"Handycam HC-85",
US_SC_UFI, US_PR_DEVICE, NULL,
@@ -648,26 +655,26 @@ UNUSUAL_DEV( 0x054c, 0x016a, 0x0000, 0x9999,
/* Submitted by Frank Engel <frankie@cse.unsw.edu.au> */
UNUSUAL_DEV( 0x054c, 0x0099, 0x0000, 0x9999,
- "Sony",
- "PEG Mass Storage",
- US_SC_DEVICE, US_PR_DEVICE, NULL,
- US_FL_FIX_INQUIRY ),
+ "Sony",
+ "PEG Mass Storage",
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ US_FL_FIX_INQUIRY ),
/* floppy reports multiple luns */
UNUSUAL_DEV( 0x055d, 0x2020, 0x0000, 0x0210,
- "SAMSUNG",
- "SFD-321U [FW 0C]",
- US_SC_DEVICE, US_PR_DEVICE, NULL,
- US_FL_SINGLE_LUN ),
+ "SAMSUNG",
+ "SFD-321U [FW 0C]",
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ US_FL_SINGLE_LUN ),
-UNUSUAL_DEV( 0x057b, 0x0000, 0x0000, 0x0299,
+UNUSUAL_DEV( 0x057b, 0x0000, 0x0000, 0x0299,
"Y-E Data",
"Flashbuster-U",
US_SC_DEVICE, US_PR_CB, NULL,
US_FL_SINGLE_LUN),
-UNUSUAL_DEV( 0x057b, 0x0000, 0x0300, 0x9999,
+UNUSUAL_DEV( 0x057b, 0x0000, 0x0300, 0x9999,
"Y-E Data",
"Flashbuster-U",
US_SC_DEVICE, US_PR_DEVICE, NULL,
@@ -677,7 +684,7 @@ UNUSUAL_DEV( 0x057b, 0x0000, 0x0300, 0x9999,
* This entry is needed only because the device reports
* bInterfaceClass = 0xff (vendor-specific)
*/
-UNUSUAL_DEV( 0x057b, 0x0022, 0x0000, 0x9999,
+UNUSUAL_DEV( 0x057b, 0x0022, 0x0000, 0x9999,
"Y-E Data",
"Silicon Media R/W",
US_SC_DEVICE, US_PR_DEVICE, NULL, 0),
@@ -825,13 +832,13 @@ UNUSUAL_DEV( 0x0636, 0x0003, 0x0000, 0x9999,
US_SC_SCSI, US_PR_BULK, NULL,
US_FL_FIX_INQUIRY ),
-UNUSUAL_DEV( 0x0644, 0x0000, 0x0100, 0x0100,
+UNUSUAL_DEV( 0x0644, 0x0000, 0x0100, 0x0100,
"TEAC",
"Floppy Drive",
- US_SC_UFI, US_PR_CB, NULL, 0 ),
+ US_SC_UFI, US_PR_CB, NULL, 0 ),
#ifdef CONFIG_USB_STORAGE_SDDR09
-UNUSUAL_DEV( 0x066b, 0x0105, 0x0100, 0x0100,
+UNUSUAL_DEV( 0x066b, 0x0105, 0x0100, 0x0100,
"Olympus",
"Camedia MAUSB-2",
US_SC_SCSI, US_PR_EUSB_SDDR09, usb_stor_sddr09_init,
@@ -867,14 +874,14 @@ UNUSUAL_DEV( 0x0686, 0x4011, 0x0001, 0x0001,
/* Reported by Miguel A. Fosas <amn3s1a@ono.com> */
UNUSUAL_DEV( 0x0686, 0x4017, 0x0001, 0x0001,
- "Minolta",
- "DIMAGE E223",
- US_SC_SCSI, US_PR_DEVICE, NULL, 0 ),
+ "Minolta",
+ "DIMAGE E223",
+ US_SC_SCSI, US_PR_DEVICE, NULL, 0 ),
UNUSUAL_DEV( 0x0693, 0x0005, 0x0100, 0x0100,
"Hagiwara",
"Flashgate",
- US_SC_SCSI, US_PR_BULK, NULL, 0 ),
+ US_SC_SCSI, US_PR_BULK, NULL, 0 ),
/* Reported by David Hamilton <niftimusmaximus@lycos.com> */
UNUSUAL_DEV( 0x069b, 0x3004, 0x0001, 0x0001,
@@ -918,7 +925,7 @@ UNUSUAL_DEV( 0x0781, 0x0100, 0x0100, 0x0100,
US_FL_SINGLE_LUN ),
#ifdef CONFIG_USB_STORAGE_SDDR09
-UNUSUAL_DEV( 0x0781, 0x0200, 0x0000, 0x9999,
+UNUSUAL_DEV( 0x0781, 0x0200, 0x0000, 0x9999,
"Sandisk",
"ImageMate SDDR-09",
US_SC_SCSI, US_PR_EUSB_SDDR09, usb_stor_sddr09_init,
@@ -939,17 +946,17 @@ UNUSUAL_DEV( 0x07ab, 0xfccd, 0x0000, 0x9999,
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_FIX_CAPACITY),
-UNUSUAL_DEV( 0x07af, 0x0004, 0x0100, 0x0133,
+UNUSUAL_DEV( 0x07af, 0x0004, 0x0100, 0x0133,
"Microtech",
"USB-SCSI-DB25",
US_SC_SCSI, US_PR_BULK, usb_stor_euscsi_init,
US_FL_SCM_MULT_TARG ),
-UNUSUAL_DEV( 0x07af, 0x0005, 0x0100, 0x0100,
+UNUSUAL_DEV( 0x07af, 0x0005, 0x0100, 0x0100,
"Microtech",
"USB-SCSI-HD50",
US_SC_DEVICE, US_PR_DEVICE, usb_stor_euscsi_init,
- US_FL_SCM_MULT_TARG ),
+ US_FL_SCM_MULT_TARG ),
#ifdef CONFIG_USB_STORAGE_DPCM
UNUSUAL_DEV( 0x07af, 0x0006, 0x0100, 0x0100,
@@ -1053,10 +1060,10 @@ UNUSUAL_DEV( 0x07c4, 0xa109, 0x0000, 0xffff,
* as "DualSlot CompactFlash(TM) & MStick Drive USB"
*/
UNUSUAL_DEV( 0x07c4, 0xa10b, 0x0000, 0xffff,
- "DataFab Systems Inc.",
- "USB CF+MS",
- US_SC_SCSI, US_PR_DATAFAB, NULL,
- 0 ),
+ "DataFab Systems Inc.",
+ "USB CF+MS",
+ US_SC_SCSI, US_PR_DATAFAB, NULL,
+ 0 ),
#endif
@@ -1119,10 +1126,10 @@ UNUSUAL_DEV( 0x08bd, 0x1100, 0x0000, 0x0000,
* US_FL_IGNORE_RESIDUE Needed
*/
UNUSUAL_DEV( 0x08ca, 0x3103, 0x0100, 0x0100,
- "AIPTEK",
- "Aiptek USB Keychain MP3 Player",
- US_SC_DEVICE, US_PR_DEVICE, NULL,
- US_FL_IGNORE_RESIDUE),
+ "AIPTEK",
+ "Aiptek USB Keychain MP3 Player",
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ US_FL_IGNORE_RESIDUE),
/* Entry needed for flags. Moreover, all devices with this ID use
* bulk-only transport, but _some_ falsely report Control/Bulk instead.
@@ -1166,26 +1173,26 @@ UNUSUAL_DEV( 0x090c, 0x1132, 0x0000, 0xffff,
* Submitted by James Courtier-Dutton <James@superbug.demon.co.uk>
*/
UNUSUAL_DEV( 0x0a17, 0x0004, 0x1000, 0x1000,
- "Pentax",
- "Optio 2/3/400",
- US_SC_DEVICE, US_PR_DEVICE, NULL,
- US_FL_FIX_INQUIRY ),
+ "Pentax",
+ "Optio 2/3/400",
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ US_FL_FIX_INQUIRY ),
/* Submitted by Per Winkvist <per.winkvist@uk.com> */
UNUSUAL_DEV( 0x0a17, 0x006, 0x0000, 0xffff,
- "Pentax",
- "Optio S/S4",
- US_SC_DEVICE, US_PR_DEVICE, NULL,
- US_FL_FIX_INQUIRY ),
+ "Pentax",
+ "Optio S/S4",
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ US_FL_FIX_INQUIRY ),
/* These are virtual windows driver CDs, which the zd1211rw driver
* automatically converts into WLAN devices. */
UNUSUAL_DEV( 0x0ace, 0x2011, 0x0101, 0x0101,
- "ZyXEL",
- "G-220F USB-WLAN Install",
- US_SC_DEVICE, US_PR_DEVICE, NULL,
- US_FL_IGNORE_DEVICE ),
+ "ZyXEL",
+ "G-220F USB-WLAN Install",
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ US_FL_IGNORE_DEVICE ),
UNUSUAL_DEV( 0x0ace, 0x20ff, 0x0101, 0x0101,
"SiteCom",
@@ -1211,17 +1218,17 @@ UNUSUAL_DEV( 0x0bf6, 0xa001, 0x0100, 0x0110,
#ifdef CONFIG_USB_STORAGE_DATAFAB
UNUSUAL_DEV( 0x0c0b, 0xa109, 0x0000, 0xffff,
- "Acomdata",
- "CF",
- US_SC_SCSI, US_PR_DATAFAB, NULL,
- US_FL_SINGLE_LUN ),
+ "Acomdata",
+ "CF",
+ US_SC_SCSI, US_PR_DATAFAB, NULL,
+ US_FL_SINGLE_LUN ),
#endif
#ifdef CONFIG_USB_STORAGE_SDDR55
UNUSUAL_DEV( 0x0c0b, 0xa109, 0x0000, 0xffff,
- "Acomdata",
- "SM",
- US_SC_SCSI, US_PR_SDDR55, NULL,
- US_FL_SINGLE_LUN ),
+ "Acomdata",
+ "SM",
+ US_SC_SCSI, US_PR_SDDR55, NULL,
+ US_FL_SINGLE_LUN ),
#endif
/* Submitted by: Nick Sillik <n.sillik@temple.edu>
@@ -1384,6 +1391,17 @@ UNUSUAL_DEV( 0x1019, 0x0c55, 0x0000, 0x0110,
US_SC_DEVICE, US_PR_DEVICE, usb_stor_ucr61s2b_init,
0 ),
+/* Reported by Kevin Lloyd <linux@sierrawireless.com>
+ * Entry is needed for the initializer function override,
+ * which instructs the device to load as a modem
+ * device.
+ */
+UNUSUAL_DEV( 0x1199, 0x0fff, 0x0000, 0x9999,
+ "Sierra Wireless",
+ "USB MMC Storage",
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ US_FL_IGNORE_DEVICE),
+
/* Reported by Jaco Kroon <jaco@kroon.co.za>
* The usb-storage module found on the Digitech GNX4 (and supposedly other
* devices) misbehaves and causes a bunch of invalid I/O errors.
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
index 8e898e3d861..28842d208bb 100644
--- a/drivers/usb/storage/usb.c
+++ b/drivers/usb/storage/usb.c
@@ -191,16 +191,13 @@ static int storage_suspend(struct usb_interface *iface, pm_message_t message)
{
struct us_data *us = usb_get_intfdata(iface);
+ US_DEBUGP("%s\n", __FUNCTION__);
+
/* Wait until no command is running */
mutex_lock(&us->dev_mutex);
- US_DEBUGP("%s\n", __FUNCTION__);
if (us->suspend_resume_hook)
(us->suspend_resume_hook)(us, US_SUSPEND);
- iface->dev.power.power_state.event = message.event;
-
- /* When runtime PM is working, we'll set a flag to indicate
- * whether we should autoresume when a SCSI request arrives. */
mutex_unlock(&us->dev_mutex);
return 0;
@@ -210,14 +207,25 @@ static int storage_resume(struct usb_interface *iface)
{
struct us_data *us = usb_get_intfdata(iface);
- mutex_lock(&us->dev_mutex);
-
US_DEBUGP("%s\n", __FUNCTION__);
+
if (us->suspend_resume_hook)
(us->suspend_resume_hook)(us, US_RESUME);
- iface->dev.power.power_state.event = PM_EVENT_ON;
- mutex_unlock(&us->dev_mutex);
+ return 0;
+}
+
+static int storage_reset_resume(struct usb_interface *iface)
+{
+ struct us_data *us = usb_get_intfdata(iface);
+
+ US_DEBUGP("%s\n", __FUNCTION__);
+
+ /* Report the reset to the SCSI core */
+ usb_stor_report_bus_reset(us);
+
+ /* FIXME: Notify the subdrivers that they need to reinitialize
+ * the device */
return 0;
}
@@ -228,7 +236,7 @@ static int storage_resume(struct usb_interface *iface)
* a USB port reset, whether from this driver or a different one.
*/
-static void storage_pre_reset(struct usb_interface *iface)
+static int storage_pre_reset(struct usb_interface *iface)
{
struct us_data *us = usb_get_intfdata(iface);
@@ -236,22 +244,23 @@ static void storage_pre_reset(struct usb_interface *iface)
/* Make sure no command runs during the reset */
mutex_lock(&us->dev_mutex);
+ return 0;
}
-static void storage_post_reset(struct usb_interface *iface)
+static int storage_post_reset(struct usb_interface *iface)
{
struct us_data *us = usb_get_intfdata(iface);
US_DEBUGP("%s\n", __FUNCTION__);
/* Report the reset to the SCSI core */
- scsi_lock(us_to_host(us));
usb_stor_report_bus_reset(us);
- scsi_unlock(us_to_host(us));
/* FIXME: Notify the subdrivers that they need to reinitialize
* the device */
+
mutex_unlock(&us->dev_mutex);
+ return 0;
}
/*
@@ -300,8 +309,7 @@ static int usb_stor_control_thread(void * __us)
{
struct us_data *us = (struct us_data *)__us;
struct Scsi_Host *host = us_to_host(us);
-
- current->flags |= PF_NOFREEZE;
+ int autopm_rc;
for(;;) {
US_DEBUGP("*** thread sleeping.\n");
@@ -310,6 +318,9 @@ static int usb_stor_control_thread(void * __us)
US_DEBUGP("*** thread awakened.\n");
+ /* Autoresume the device */
+ autopm_rc = usb_autopm_get_interface(us->pusb_intf);
+
/* lock the device pointers */
mutex_lock(&(us->dev_mutex));
@@ -368,6 +379,12 @@ static int usb_stor_control_thread(void * __us)
us->srb->result = SAM_STAT_GOOD;
}
+ /* Did the autoresume fail? */
+ else if (autopm_rc < 0) {
+ US_DEBUGP("Could not wake device\n");
+ us->srb->result = DID_ERROR << 16;
+ }
+
/* we've got a command, let's do it! */
else {
US_DEBUG(usb_stor_show_command(us->srb));
@@ -410,25 +427,21 @@ SkipForAbort:
/* unlock the device pointers */
mutex_unlock(&us->dev_mutex);
- } /* for (;;) */
- scsi_host_put(host);
+ /* Start an autosuspend */
+ if (autopm_rc == 0)
+ usb_autopm_put_interface(us->pusb_intf);
+ } /* for (;;) */
- /* notify the exit routine that we're actually exiting now
- *
- * complete()/wait_for_completion() is similar to up()/down(),
- * except that complete() is safe in the case where the structure
- * is getting deleted in a parallel mode of execution (i.e. just
- * after the down() -- that's necessary for the thread-shutdown
- * case.
- *
- * complete_and_exit() goes even further than this -- it is safe in
- * the case that the thread of the caller is going away (not just
- * the structure) -- this is necessary for the module-remove case.
- * This is important in preemption kernels, which transfer the flow
- * of execution immediately upon a complete().
- */
- complete_and_exit(&threads_gone, 0);
+ /* Wait until we are told to stop */
+ for (;;) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ if (kthread_should_stop())
+ break;
+ schedule();
+ }
+ __set_current_state(TASK_RUNNING);
+ return 0;
}
/***********************************************************************
@@ -796,19 +809,13 @@ static int usb_stor_acquire_resources(struct us_data *us)
}
/* Start up our control thread */
- th = kthread_create(usb_stor_control_thread, us, "usb-storage");
+ th = kthread_run(usb_stor_control_thread, us, "usb-storage");
if (IS_ERR(th)) {
printk(KERN_WARNING USB_STORAGE
"Unable to start control thread\n");
return PTR_ERR(th);
}
-
- /* Take a reference to the host for the control thread and
- * count it among all the threads we have launched. Then
- * start it up. */
- scsi_host_get(us_to_host(us));
- atomic_inc(&total_threads);
- wake_up_process(th);
+ us->ctl_thread = th;
return 0;
}
@@ -825,6 +832,8 @@ static void usb_stor_release_resources(struct us_data *us)
US_DEBUGP("-- sending exit command to thread\n");
set_bit(US_FLIDX_DISCONNECTING, &us->flags);
up(&us->sema);
+ if (us->ctl_thread)
+ kthread_stop(us->ctl_thread);
/* Call the destructor routine, if it exists */
if (us->extra_destructor) {
@@ -909,6 +918,7 @@ static int usb_stor_scan_thread(void * __us)
printk(KERN_DEBUG
"usb-storage: device found at %d\n", us->pusb_dev->devnum);
+ set_freezable();
/* Wait for the timeout to expire or for a disconnect */
if (delay_use > 0) {
printk(KERN_DEBUG "usb-storage: waiting for device "
@@ -938,6 +948,7 @@ retry:
}
scsi_host_put(us_to_host(us));
+ usb_autopm_put_interface(us->pusb_intf);
complete_and_exit(&threads_gone, 0);
}
@@ -1027,6 +1038,7 @@ static int storage_probe(struct usb_interface *intf,
* start it up. */
scsi_host_get(us_to_host(us));
atomic_inc(&total_threads);
+ usb_autopm_get_interface(intf); /* dropped in the scanning thread */
wake_up_process(th);
return 0;
@@ -1059,10 +1071,12 @@ static struct usb_driver usb_storage_driver = {
#ifdef CONFIG_PM
.suspend = storage_suspend,
.resume = storage_resume,
+ .reset_resume = storage_reset_resume,
#endif
.pre_reset = storage_pre_reset,
.post_reset = storage_post_reset,
.id_table = storage_usb_ids,
+ .supports_autosuspend = 1,
};
static int __init usb_stor_init(void)
diff --git a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h
index 6dac1ffdde8..6445665b157 100644
--- a/drivers/usb/storage/usb.h
+++ b/drivers/usb/storage/usb.h
@@ -144,6 +144,7 @@ struct us_data {
unsigned char *sensebuf; /* sense data buffer */
dma_addr_t cr_dma; /* buffer DMA addresses */
dma_addr_t iobuf_dma;
+ struct task_struct *ctl_thread; /* the control thread */
/* mutual exclusion and synchronization structures */
struct semaphore sema; /* to sleep thread on */