Hi all,

I have a USB bridge that's implementing SAT passthru cdbs.  We ran into an
issue with the usb-storage driver in that when it does auto-sense (because
the CK_COND bit is set in the passthru cdb), the driver does a sense with
only 18 bytes for the sense buffer.  The problem is that SAT passthru wants
to return 22 bytes of sense data. The last 4 bytes that don't get returned
are fairly important ATA task files registers: lba high hob, lba high,
device, and status.

For testing purposes I use the patch below, but what's the correct way to
deal with this issue?  Is there something in the USB spec mandating 18 bytes
of sense data, or is the usb-storage simply making a hard-coded assumption?

Thanks,
Tim Thelin


---
diff --git a/drivers/usb/storage/transport.c
b/drivers/usb/storage/transport.c
index 7ca896a..7a77008 100644
--- a/drivers/usb/storage/transport.c
+++ b/drivers/usb/storage/transport.c
@@ -625,9 +625,12 @@ void usb_stor_invoke_transport(struct sc
                srb->cmnd[4] = 18;
 
                /* FIXME: we must do the protocol translation here */
-               if (us->subclass == US_SC_RBC || us->subclass == US_SC_SCSI)
+               if (us->subclass == US_SC_RBC || us->subclass == US_SC_SCSI)
{
                        srb->cmd_len = 6;
-               else
+                       // SAT passthru commands give back 22 bytes of sense
data
+                       if (old_cmnd[0] == 0xA1 || old_cmnd[0] == 0x85)
+                               srb->cmnd[4] = 22;
+               } else
                        srb->cmd_len = 12;
 
                /* set the transfer direction */
@@ -640,7 +643,7 @@ void usb_stor_invoke_transport(struct sc
 
                /* set the buffer length for transfer */
                old_request_bufflen = srb->request_bufflen;
-               srb->request_bufflen = US_SENSE_SIZE;
+               srb->request_bufflen = srb->cmnd[4];
 
                /* set up for no scatter-gather use */
                old_sg = srb->use_sg;
diff --git a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h
index 98b0971..80e3a22 100644
--- a/drivers/usb/storage/usb.h
+++ b/drivers/usb/storage/usb.h
@@ -117,7 +117,7 @@ enum { US_DO_ALL_FLAGS };
  */
 
 #define US_IOBUF_SIZE          64      /* Size of the DMA-mapped I/O buffer
*/
-#define US_SENSE_SIZE          18      /* Size of the autosense data buffer
*/
+#define US_SENSE_SIZE          22      /* Size of the autosense data buffer
*/
 
 typedef int (*trans_cmnd)(struct scsi_cmnd *, struct us_data*);
 typedef int (*trans_reset)(struct us_data*);

Reply via email to