diff options
Diffstat (limited to 'drivers/usb/storage')
-rw-r--r-- | drivers/usb/storage/dpcm.c | 56 | ||||
-rw-r--r-- | drivers/usb/storage/onetouch.c | 13 | ||||
-rw-r--r-- | drivers/usb/storage/scsiglue.c | 21 | ||||
-rw-r--r-- | drivers/usb/storage/unusual_devs.h | 206 | ||||
-rw-r--r-- | drivers/usb/storage/usb.c | 94 | ||||
-rw-r--r-- | drivers/usb/storage/usb.h | 1 |
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 */ |