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.

Greg, please apply.

Matt

# This is a BitKeeper generated patch for the following project:
# Project Name: greg k-h's linux 2.5 USB kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
#                  ChangeSet    1.2131  -> 1.2132 
#       drivers/usb/storage/freecom.c   1.35    -> 1.36   
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 03/09/28      [EMAIL PROTECTED]       1.2132
# Fix reads of status packet.  This error was introduced somewhere in 2.5.
# 
# Also add length-checking to make sure we don't have a bogus command.
# --------------------------------------------
#
diff -Nru a/drivers/usb/storage/freecom.c b/drivers/usb/storage/freecom.c
--- a/drivers/usb/storage/freecom.c     Sun Sep 28 15:50:21 2003
+++ b/drivers/usb/storage/freecom.c     Sun Sep 28 15:50:21 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.
-- 
Matthew Dharm                              Home: [EMAIL PROTECTED] 
Maintainer, Linux USB Mass Storage Driver

What the hell are you?
                                        -- Pitr to Dust Puppy 
User Friendly, 12/3/1997

Attachment: pgp00000.pgp
Description: PGP signature

Reply via email to