summaryrefslogtreecommitdiff
path: root/drivers/usb/storage
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-12-11 23:22:55 (GMT)
committerLinus Torvalds <torvalds@linux-foundation.org>2009-12-11 23:22:55 (GMT)
commit748e566b7e24541e05e3e70be311887a1262f2a1 (patch)
tree41cc3a9aa04918cc17efa575baf6dbf87f40ddba /drivers/usb/storage
parent5f1141eb352ea79d849920039503e40dd623fffa (diff)
parentacf509ae28301d78b022c534c26b1e4765c18f2b (diff)
downloadlinux-748e566b7e24541e05e3e70be311887a1262f2a1.tar.xz
Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6: (122 commits) USB: mos7840: add device IDs for B&B electronics devices USB: ftdi_sio: add USB device ID's for B&B Electronics line USB: musb: musb_host: fix sparse warning USB: musb: musb_gadget: fix sparse warning USB: musb: omap2430: fix sparse warning USB: core: message: fix sparse warning USB: core: hub: fix sparse warning USB: core: fix sparse warning for static function USB: Added USB_ETH_RNDIS to use instead of CONFIG_USB_ETH_RNDIS USB: Check bandwidth when switching alt settings. USB: Refactor code to find alternate interface settings. USB: xhci: Fix command completion after a drop endpoint. USB: xhci: Make reverting an alt setting "unfailable". USB: usbtmc: Use usb_clear_halt() instead of custom code. USB: xhci: Add correct email and files to MAINTAINERS entry. USB: ehci-omap.c: introduce missing kfree USB: xhci-mem.c: introduce missing kfree USB: add remove_id sysfs attr for usb drivers USB: g_multi kconfig: fix depends and help text USB: option: add pid for ZTE ...
Diffstat (limited to 'drivers/usb/storage')
-rw-r--r--drivers/usb/storage/scsiglue.c3
-rw-r--r--drivers/usb/storage/transport.c17
-rw-r--r--drivers/usb/storage/unusual_devs.h7
-rw-r--r--drivers/usb/storage/usb.c43
-rw-r--r--drivers/usb/storage/usb.h1
5 files changed, 54 insertions, 17 deletions
diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c
index cfa26d5..e5e6df3 100644
--- a/drivers/usb/storage/scsiglue.c
+++ b/drivers/usb/storage/scsiglue.c
@@ -73,7 +73,8 @@
static const char* host_info(struct Scsi_Host *host)
{
- return "SCSI emulation for USB Mass Storage devices";
+ struct us_data *us = host_to_us(host);
+ return us->scsi_name;
}
static int slave_alloc (struct scsi_device *sdev)
diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c
index 589f6b4..cc313d1 100644
--- a/drivers/usb/storage/transport.c
+++ b/drivers/usb/storage/transport.c
@@ -666,10 +666,11 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us)
* to wait for at least one CHECK_CONDITION to determine
* SANE_SENSE support
*/
- if ((srb->cmnd[0] == ATA_16 || srb->cmnd[0] == ATA_12) &&
+ if (unlikely((srb->cmnd[0] == ATA_16 || srb->cmnd[0] == ATA_12) &&
result == USB_STOR_TRANSPORT_GOOD &&
!(us->fflags & US_FL_SANE_SENSE) &&
- !(srb->cmnd[2] & 0x20)) {
+ !(us->fflags & US_FL_BAD_SENSE) &&
+ !(srb->cmnd[2] & 0x20))) {
US_DEBUGP("-- SAT supported, increasing auto-sense\n");
us->fflags |= US_FL_SANE_SENSE;
}
@@ -718,6 +719,12 @@ Retry_Sense:
if (test_bit(US_FLIDX_TIMED_OUT, &us->dflags)) {
US_DEBUGP("-- auto-sense aborted\n");
srb->result = DID_ABORT << 16;
+
+ /* If SANE_SENSE caused this problem, disable it */
+ if (sense_size != US_SENSE_SIZE) {
+ us->fflags &= ~US_FL_SANE_SENSE;
+ us->fflags |= US_FL_BAD_SENSE;
+ }
goto Handle_Errors;
}
@@ -727,10 +734,11 @@ Retry_Sense:
* (small) sense request. This fixes some USB GSM modems
*/
if (temp_result == USB_STOR_TRANSPORT_FAILED &&
- (us->fflags & US_FL_SANE_SENSE) &&
- sense_size != US_SENSE_SIZE) {
+ sense_size != US_SENSE_SIZE) {
US_DEBUGP("-- auto-sense failure, retry small sense\n");
sense_size = US_SENSE_SIZE;
+ us->fflags &= ~US_FL_SANE_SENSE;
+ us->fflags |= US_FL_BAD_SENSE;
goto Retry_Sense;
}
@@ -754,6 +762,7 @@ Retry_Sense:
*/
if (srb->sense_buffer[7] > (US_SENSE_SIZE - 8) &&
!(us->fflags & US_FL_SANE_SENSE) &&
+ !(us->fflags & US_FL_BAD_SENSE) &&
(srb->sense_buffer[0] & 0x7C) == 0x70) {
US_DEBUGP("-- SANE_SENSE support enabled\n");
us->fflags |= US_FL_SANE_SENSE;
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
index d4f034e..64a0a2c 100644
--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -818,6 +818,13 @@ UNUSUAL_DEV( 0x066f, 0x8000, 0x0001, 0x0001,
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_FIX_CAPACITY ),
+/* Reported by Daniel Kukula <daniel.kuku@gmail.com> */
+UNUSUAL_DEV( 0x067b, 0x1063, 0x0100, 0x0100,
+ "Prolific Technology, Inc.",
+ "Prolific Storage Gadget",
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ US_FL_BAD_SENSE ),
+
/* Reported by Rogerio Brito <rbrito@ime.usp.br> */
UNUSUAL_DEV( 0x067b, 0x2317, 0x0001, 0x001,
"Prolific Technology, Inc.",
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
index 8060b85..5a53d4f 100644
--- a/drivers/usb/storage/usb.c
+++ b/drivers/usb/storage/usb.c
@@ -45,6 +45,10 @@
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#ifdef CONFIG_USB_STORAGE_DEBUG
+#define DEBUG
+#endif
+
#include <linux/sched.h>
#include <linux/errno.h>
#include <linux/freezer.h>
@@ -228,6 +232,7 @@ void fill_inquiry_response(struct us_data *us, unsigned char *data,
if (data_len<36) // You lose.
return;
+ memset(data+8, ' ', 28);
if(data[0]&0x20) { /* USB device currently not connected. Return
peripheral qualifier 001b ("...however, the
physical device is not currently connected
@@ -237,15 +242,15 @@ void fill_inquiry_response(struct us_data *us, unsigned char *data,
device, it may return zeros or ASCII spaces
(20h) in those fields until the data is
available from the device."). */
- memset(data+8,0,28);
} else {
u16 bcdDevice = le16_to_cpu(us->pusb_dev->descriptor.bcdDevice);
- memcpy(data+8, us->unusual_dev->vendorName,
- strlen(us->unusual_dev->vendorName) > 8 ? 8 :
- strlen(us->unusual_dev->vendorName));
- memcpy(data+16, us->unusual_dev->productName,
- strlen(us->unusual_dev->productName) > 16 ? 16 :
- strlen(us->unusual_dev->productName));
+ int n;
+
+ n = strlen(us->unusual_dev->vendorName);
+ memcpy(data+8, us->unusual_dev->vendorName, min(8, n));
+ n = strlen(us->unusual_dev->productName);
+ memcpy(data+16, us->unusual_dev->productName, min(16, n));
+
data[32] = 0x30 + ((bcdDevice>>12) & 0x0F);
data[33] = 0x30 + ((bcdDevice>>8) & 0x0F);
data[34] = 0x30 + ((bcdDevice>>4) & 0x0F);
@@ -459,6 +464,9 @@ static void adjust_quirks(struct us_data *us)
case 'a':
f |= US_FL_SANE_SENSE;
break;
+ case 'b':
+ f |= US_FL_BAD_SENSE;
+ break;
case 'c':
f |= US_FL_FIX_CAPACITY;
break;
@@ -808,14 +816,13 @@ static int usb_stor_scan_thread(void * __us)
{
struct us_data *us = (struct us_data *)__us;
- printk(KERN_DEBUG
- "usb-storage: device found at %d\n", us->pusb_dev->devnum);
+ dev_dbg(&us->pusb_intf->dev, "device found\n");
set_freezable();
/* Wait for the timeout to expire or for a disconnect */
if (delay_use > 0) {
- printk(KERN_DEBUG "usb-storage: waiting for device "
- "to settle before scanning\n");
+ dev_dbg(&us->pusb_intf->dev, "waiting for device to settle "
+ "before scanning\n");
wait_event_freezable_timeout(us->delay_wait,
test_bit(US_FLIDX_DONT_SCAN, &us->dflags),
delay_use * HZ);
@@ -832,7 +839,7 @@ static int usb_stor_scan_thread(void * __us)
mutex_unlock(&us->dev_mutex);
}
scsi_scan_host(us_to_host(us));
- printk(KERN_DEBUG "usb-storage: device scan complete\n");
+ dev_dbg(&us->pusb_intf->dev, "scan complete\n");
/* Should we unbind if no devices were detected? */
}
@@ -840,6 +847,15 @@ static int usb_stor_scan_thread(void * __us)
complete_and_exit(&us->scanning_done, 0);
}
+static unsigned int usb_stor_sg_tablesize(struct usb_interface *intf)
+{
+ struct usb_device *usb_dev = interface_to_usbdev(intf);
+
+ if (usb_dev->bus->sg_tablesize) {
+ return usb_dev->bus->sg_tablesize;
+ }
+ return SG_ALL;
+}
/* First part of general USB mass-storage probing */
int usb_stor_probe1(struct us_data **pus,
@@ -868,6 +884,7 @@ int usb_stor_probe1(struct us_data **pus,
* Allow 16-byte CDBs and thus > 2TB
*/
host->max_cmd_len = 16;
+ host->sg_tablesize = usb_stor_sg_tablesize(intf);
*pus = us = host_to_us(host);
memset(us, 0, sizeof(struct us_data));
mutex_init(&(us->dev_mutex));
@@ -929,6 +946,8 @@ int usb_stor_probe2(struct us_data *us)
result = usb_stor_acquire_resources(us);
if (result)
goto BadDevice;
+ snprintf(us->scsi_name, sizeof(us->scsi_name), "usb-storage %s",
+ dev_name(&us->pusb_intf->dev));
result = scsi_add_host(us_to_host(us), &us->pusb_intf->dev);
if (result) {
printk(KERN_WARNING USB_STORAGE
diff --git a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h
index 2609efb..6971713 100644
--- a/drivers/usb/storage/usb.h
+++ b/drivers/usb/storage/usb.h
@@ -132,6 +132,7 @@ struct us_data {
/* SCSI interfaces */
struct scsi_cmnd *srb; /* current srb */
unsigned int tag; /* current dCBWTag */
+ char scsi_name[32]; /* scsi_host name */
/* control and bulk communications data */
struct urb *current_urb; /* USB requests */