summaryrefslogtreecommitdiff
path: root/include/scsi
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2014-09-02 19:35:50 +0400
committerChristoph Hellwig <hch@lst.de>2014-09-16 03:01:58 +0400
commit50c4e96411a6cd728f04cf70d8d6def57828b320 (patch)
treefd47f80ec189ac23a75ddfcc82c24a428e8da3aa /include/scsi
parent64bdcbc449105377dd60c8da97cfc1663b39562c (diff)
downloadlinux-50c4e96411a6cd728f04cf70d8d6def57828b320.tar.xz
scsi: don't store LUN bits in CDB[1] for USB mass-storage devices
The SCSI specification requires that the second Command Data Byte should contain the LUN value in its high-order bits if the recipient device reports SCSI level 2 or below. Nevertheless, some USB mass-storage devices use those bits for other purposes in vendor-specific commands. Currently Linux has no way to send such commands, because the SCSI stack always overwrites the LUN bits. Testing shows that Windows 7 and XP do not store the LUN bits in the CDB when sending commands to a USB device. This doesn't matter if the device uses the Bulk-Only or UAS transports (which virtually all modern USB mass-storage devices do), as these have a separate mechanism for sending the LUN value. Therefore this patch introduces a flag in the Scsi_Host structure to inform the SCSI midlayer that a transport does not require the LUN bits to be stored in the CDB, and it makes usb-storage set this flag for all devices using the Bulk-Only transport. (UAS is handled by a separate driver, but it doesn't really matter because no SCSI-2 or lower device is at all likely to use UAS.) The patch also cleans up the code responsible for storing the LUN value by adding a bitflag to the scsi_device structure. The test for whether to stick the LUN value in the CDB can be made when the device is probed, and stored for future use rather than being made over and over in the fast path. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Reported-by: Tiziano Bacocco <tiziano.bacocco@gmail.com> Acked-by: Martin K. Petersen <martin.petersen@oracle.com> Acked-by: James Bottomley <James.Bottomley@HansenPartnership.com> Signed-off-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'include/scsi')
-rw-r--r--include/scsi/scsi_device.h1
-rw-r--r--include/scsi/scsi_host.h3
2 files changed, 4 insertions, 0 deletions
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
index 1a0d1842962e..27ecee73bd72 100644
--- a/include/scsi/scsi_device.h
+++ b/include/scsi/scsi_device.h
@@ -174,6 +174,7 @@ struct scsi_device {
unsigned wce_default_on:1; /* Cache is ON by default */
unsigned no_dif:1; /* T10 PI (DIF) should be disabled */
unsigned broken_fua:1; /* Don't set FUA bit */
+ unsigned lun_in_cdb:1; /* Store LUN bits in CDB[1] */
atomic_t disk_events_disable_depth; /* disable depth for disk events */
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
index cafb260ef2d3..d0f69a3210df 100644
--- a/include/scsi/scsi_host.h
+++ b/include/scsi/scsi_host.h
@@ -693,6 +693,9 @@ struct Scsi_Host {
*/
struct workqueue_struct *tmf_work_q;
+ /* The transport requires the LUN bits NOT to be stored in CDB[1] */
+ unsigned no_scsi2_lun_in_cdb:1;
+
/*
* Value host_blocked counts down from
*/