ChangeSet 1.1342.8.59, 2003/09/30 15:02:06-07:00, mdharm-usb@one-eyed-alien.net [PATCH] USB: fix freecom.c This patch for 2.6 fixes freecom.c -- an error in return-code interpretation was introduced somewhere during 2.5. This also adds a few more checks to try to catch commands that appear to want to move data, but of length 0. This is likely a bug in some higher layer -- I'll bring it up on linux-scsi. drivers/usb/storage/freecom.c | 16 ++++++++++++---- 1 files changed, 12 insertions(+), 4 deletions(-) diff -Nru a/drivers/usb/storage/freecom.c b/drivers/usb/storage/freecom.c --- a/drivers/usb/storage/freecom.c Fri Oct 3 16:44:52 2003 +++ b/drivers/usb/storage/freecom.c Fri Oct 3 16:44:52 2003 @@ -101,7 +101,8 @@ #define FCM_PACKET_IDE_READ 0xC0 /* All packets (except for status) are 64 bytes long. */ -#define FCM_PACKET_LENGTH 64 +#define FCM_PACKET_LENGTH 64 +#define FCM_STATUS_PACKET_LENGTH 4 static int freecom_readdata (Scsi_Cmnd *srb, struct us_data *us, @@ -216,7 +217,7 @@ /* There are times we can optimize out this status read, but it * doesn't hurt us to always do it now. */ result = usb_stor_bulk_transfer_buf (us, ipipe, fst, - FCM_PACKET_LENGTH, &partial); + FCM_STATUS_PACKET_LENGTH, &partial); US_DEBUGP("foo Status result %d %u\n", result, partial); if (result != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_ERROR; @@ -256,10 +257,10 @@ /* get the data */ result = usb_stor_bulk_transfer_buf (us, ipipe, fst, - FCM_PACKET_LENGTH, &partial); + FCM_STATUS_PACKET_LENGTH, &partial); US_DEBUGP("bar Status result %d %u\n", result, partial); - if (result > USB_STOR_XFER_SHORT) + if (result != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_ERROR; US_DEBUG(pdump ((void *) fst, partial)); @@ -302,6 +303,9 @@ switch (us->srb->sc_data_direction) { case SCSI_DATA_READ: + /* catch bogus "read 0 length" case */ + if (!length) + break; /* Make sure that the status indicates that the device * wants data as well. */ if ((fst->Status & DRQ_STAT) == 0 || (fst->Reason & 3) != 2) { @@ -331,6 +335,9 @@ break; case SCSI_DATA_WRITE: + /* catch bogus "write 0 length" case */ + if (!length) + break; /* Make sure the status indicates that the device wants to * send us data. */ /* !!IMPLEMENT!! */ @@ -362,6 +369,7 @@ break; default: + /* should never hit here -- filtered in usb.c */ US_DEBUGP ("freecom unimplemented direction: %d\n", us->srb->sc_data_direction); // Return fail, SCSI seems to handle this better.