===== scsiglue.c 1.62 vs edited ===== --- 1.62/drivers/usb/storage/scsiglue.c Fri Nov 14 04:15:20 2003 +++ edited/drivers/usb/storage/scsiglue.c Tue Dec 16 10:56:12 2003 @@ -219,6 +219,21 @@ return result < 0 ? FAILED : SUCCESS; } +/* Report a driver-initiated device reset to the SCSI layer. + * Calling this for a SCSI-initiated reset is unnecessary but harmless. */ +void usb_stor_report_device_reset(struct us_data *us) +{ + int i; + + scsi_lock(us->host); + scsi_report_device_reset(us->host, 0, 0); + if (us->flags & US_FL_SCM_MULT_TARG) { + for (i = 1; i < 8; ++i) + scsi_report_device_reset(us->host, 0, i); + } + scsi_unlock(us->host); +} + /*********************************************************************** * /proc/scsi/ functions ***********************************************************************/ ===== scsiglue.h 1.7 vs edited ===== --- 1.7/drivers/usb/storage/scsiglue.h Mon Jul 28 14:29:04 2003 +++ edited/drivers/usb/storage/scsiglue.h Tue Dec 16 10:56:31 2003 @@ -44,6 +44,9 @@ #include #include "scsi.h" #include "hosts.h" +#include "usb.h" + +extern void usb_stor_report_device_reset(struct us_data *us); extern unsigned char usb_stor_sense_notready[18]; extern unsigned char usb_stor_sense_invalidCDB[18]; ===== transport.c 1.113 vs edited ===== --- 1.113/drivers/usb/storage/transport.c Fri Oct 24 11:05:36 2003 +++ edited/drivers/usb/storage/transport.c Tue Dec 16 11:41:27 2003 @@ -929,6 +929,7 @@ unsigned int residue; int result; int fake_sense = 0; + unsigned int cswlen; /* set up the command wrapper */ bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); @@ -985,7 +986,17 @@ /* get CSW for device status */ US_DEBUGP("Attempting to get CSW...\n"); result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, - bcs, US_BULK_CS_WRAP_LEN, NULL); + bcs, US_BULK_CS_WRAP_LEN, &cswlen); + + /* Some broken devices add unnecessary zero-length packets to the + * end of their data transfers. Such packets show up as 0-length + * CSWs. If we encounter such a thing, try to read the CSW again. + */ + if (result == USB_STOR_XFER_SHORT && cswlen == 0) { + US_DEBUGP("Received 0-length CSW; retrying...\n"); + result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, + bcs, US_BULK_CS_WRAP_LEN, &cswlen); + } /* did the attempt to read the CSW fail? */ if (result == USB_STOR_XFER_STALLED) { @@ -1066,6 +1077,9 @@ { int result; int result2; + + /* Let the SCSI layer know we are doing a reset */ + usb_stor_report_device_reset(us); /* A 20-second timeout may seem rather long, but a LaCie * StudioDrive USB2 device takes 16+ seconds to get going