ChangeSet 1.1122.1.3, 2003/04/21 15:53:49-07:00, stern@rowland.harvard.edu [PATCH] USB: usb-storage fixes The first patch implements an auto-reset following a scsi abort for the bulk-only transport. This behavior is required by the specification, which states that two commands may not be issued without retrieving a status or performing a reset in between. The second patch implements unique CBW/CSW tags for the bulk-only transport. The old code used the scsi serial number, which is not always incremented for each new command. Unique tags allow us to identify mismatches and synchronization errors more quickly. drivers/usb/storage/transport.c | 6 +++++- drivers/usb/storage/usb.h | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff -Nru a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c --- a/drivers/usb/storage/transport.c Wed Apr 23 10:50:26 2003 +++ b/drivers/usb/storage/transport.c Wed Apr 23 10:50:26 2003 @@ -636,6 +636,10 @@ if (result == USB_STOR_TRANSPORT_ABORTED) { US_DEBUGP("-- transport indicates command was aborted\n"); srb->result = DID_ABORT << 16; + + /* Bulk-only aborts require a device reset */ + if (us->protocol == US_PR_BULK) + us->transport_reset(us); return; } @@ -1119,7 +1123,7 @@ bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = cpu_to_le32(usb_stor_transfer_length(srb)); bcb->Flags = srb->sc_data_direction == SCSI_DATA_READ ? 1 << 7 : 0; - bcb->Tag = srb->serial_number; + bcb->Tag = ++(us->tag); bcb->Lun = srb->cmnd[1] >> 5; if (us->flags & US_FL_SCM_MULT_TARG) bcb->Lun |= srb->target << 4; diff -Nru a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h --- a/drivers/usb/storage/usb.h Wed Apr 23 10:50:26 2003 +++ b/drivers/usb/storage/usb.h Wed Apr 23 10:50:26 2003 @@ -171,6 +171,7 @@ struct semaphore current_urb_sem; /* to protect irq_urb */ struct urb *current_urb; /* non-int USB requests */ struct completion current_done; /* the done flag */ + unsigned int tag; /* tag for bulk CBW/CSW */ /* the semaphore for sleeping the control thread */ struct semaphore sema; /* to sleep thread on */