This patch switches from using usb_stor_bulk_msg() to
usb_stor_bulk_transfer_buf(), which includes a great deal more logic.  This
allows for elimination of all sorts of duplicate code (clearing STALLs,
etc.).

This also eliminates the (now) redundant functions from the ISD-200 driver.

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.642   -> 1.643  
#       drivers/usb/storage/isd200.c    1.22    -> 1.23   
#       drivers/usb/storage/transport.c 1.61    -> 1.62   
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/11/03      [EMAIL PROTECTED]       1.643
# Use the new transfer_buf() and friends to consolidate code.
# --------------------------------------------
#
diff -Nru a/drivers/usb/storage/isd200.c b/drivers/usb/storage/isd200.c
--- a/drivers/usb/storage/isd200.c      Sun Nov  3 14:52:20 2002
+++ b/drivers/usb/storage/isd200.c      Sun Nov  3 14:52:20 2002
@@ -31,6 +31,8 @@
  *
  * History:
  *
+ *  2002-10-19: Removed the specialized transfer routines.
+ *             (Alan Stern <[EMAIL PROTECTED]>)
  *  2001-02-24: Removed lots of duplicate code and simplified the structure.
  *              ([EMAIL PROTECTED])
  *  2002-01-16: Fixed endianness bug so it works on the ppc arch.
@@ -386,147 +388,6 @@
         }
 }
 
-/***********************************************************************
- * Data transfer routines
- ***********************************************************************/
-
-
-/**************************************************************************
- * Transfer one SCSI scatter-gather buffer via bulk transfer
- *
- * Note that this function is necessary because we want the ability to
- * use scatter-gather memory.  Good performance is achieved by a combination
- * of scatter-gather and clustering (which makes each chunk bigger).
- *
- * Note that the lower layer will always retry when a NAK occurs, up to the
- * timeout limit.  Thus we don't have to worry about it for individual
- * packets.
- */
-static int isd200_transfer_partial( struct us_data *us, 
-                                   unsigned char dataDirection,
-                                   char *buf, int length )
-{
-        int result;
-        int partial;
-        unsigned int pipe;
-
-        /* calculate the appropriate pipe information */
-       if (dataDirection == SCSI_DATA_READ)
-                pipe = us->recv_bulk_pipe;
-        else
-                pipe = us->send_bulk_pipe;
-
-        /* transfer the data */
-        US_DEBUGP("isd200_transfer_partial(): xfer %d bytes\n", length);
-        result = usb_stor_bulk_msg(us, buf, pipe, length, &partial);
-        US_DEBUGP("usb_stor_bulk_msg() returned %d xferred %d/%d\n",
-                  result, partial, length);
-
-        /* if we stall, we need to clear it before we go on */
-        if (result == -EPIPE) {
-                US_DEBUGP("clearing endpoint halt for pipe 0x%x\n", pipe);
-                if (usb_stor_clear_halt(us, pipe) < 0)
-                       return ISD200_TRANSPORT_FAILED;
-        }
-    
-        /* did we send all the data? */
-        if (partial == length) {
-                US_DEBUGP("isd200_transfer_partial(): transfer complete\n");
-                return ISD200_TRANSPORT_GOOD;
-        }
-
-       /* did we abort this command? */
-       if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
-                US_DEBUGP("isd200_transfer_partial(): transfer aborted\n");
-               return ISD200_TRANSPORT_ABORTED;
-       }
-
-        /* uh oh... we have an error code, so something went wrong. */
-        if (result) {
-                /* NAK - that means we've retried a few times already */
-                if (result == -ETIMEDOUT) {
-                        US_DEBUGP("isd200_transfer_partial(): device NAKed\n");
-                        return ISD200_TRANSPORT_FAILED;
-                }
-
-                /* the catch-all case */
-                US_DEBUGP("isd200_transfer_partial(): unknown error\n");
-                return ISD200_TRANSPORT_FAILED;
-        }
-
-        /* no error code, so we must have transferred some data, 
-         * just not all of it */
-        return ISD200_TRANSPORT_SHORT;
-}
-
-
-/**************************************************************************
- * Transfer an entire SCSI command's worth of data payload over the bulk
- * pipe.
- *
- * Note that this uses us_transfer_partial to achieve it's goals -- this
- * function simply determines if we're going to use scatter-gather or not,
- * and acts appropriately.  For now, it also re-interprets the error codes.
- */
-static void isd200_transfer( struct us_data *us, Scsi_Cmnd *srb )
-{
-        int i;
-        int result = -1;
-        struct scatterlist *sg;
-        unsigned int total_transferred = 0;
-        unsigned int transfer_amount;
-
-        /* calculate how much we want to transfer */
-       int dir = srb->sc_data_direction;
-       srb->sc_data_direction = SCSI_DATA_WRITE;
-        transfer_amount = usb_stor_transfer_length(srb);
-       srb->sc_data_direction = dir;
-
-        /* was someone foolish enough to request more data than available
-         * buffer space? */
-        if (transfer_amount > srb->request_bufflen)
-                transfer_amount = srb->request_bufflen;
-
-        /* are we scatter-gathering? */
-        if (srb->use_sg) {
-
-                /* loop over all the scatter gather structures and 
-                 * make the appropriate requests for each, until done
-                 */
-                sg = (struct scatterlist *) srb->request_buffer;
-                for (i = 0; i < srb->use_sg; i++) {
-
-                        /* transfer the lesser of the next buffer or the
-                         * remaining data */
-                        if (transfer_amount - total_transferred >= 
-                            sg[i].length) {
-                                result = isd200_transfer_partial(us, 
-                                                                 
srb->sc_data_direction,
-                                                                 sg_address(sg[i]), 
-                                                                 sg[i].length);
-                                total_transferred += sg[i].length;
-                        } else
-                                result = isd200_transfer_partial(us, 
-                                                                 
srb->sc_data_direction,                            
-                                                                 sg_address(sg[i]), 
-                                                                 transfer_amount - 
total_transferred);
-
-                        /* if we get an error, end the loop here */
-                        if (result)
-                                break;
-                }
-        }
-        else
-                /* no scatter-gather, just make the request */
-                result = isd200_transfer_partial(us, 
-                                                 srb->sc_data_direction,
-                                                 srb->request_buffer, 
-                                                 transfer_amount);
-
-        /* return the result in the data structure itself */
-        srb->result = result;
-}
-
 
 /***********************************************************************
  * Transport routines
@@ -546,23 +407,21 @@
         struct bulk_cb_wrap bcb;
         struct bulk_cs_wrap bcs;
         int result;
-        int partial;
-        unsigned int transfer_amount;
+        unsigned int transfer_length;
 
        int dir = srb->sc_data_direction;
        srb->sc_data_direction = SCSI_DATA_WRITE;
-        transfer_amount = usb_stor_transfer_length(srb);
+        transfer_length = usb_stor_transfer_length(srb);
        srb->sc_data_direction = dir;
     
         /* set up the command wrapper */
         bcb.Signature = cpu_to_le32(US_BULK_CB_SIGN);
-        bcb.DataTransferLength = cpu_to_le32(transfer_amount);
+        bcb.DataTransferLength = cpu_to_le32(transfer_length);
         bcb.Flags = srb->sc_data_direction == SCSI_DATA_READ ? 1 << 7 : 0;
         bcb.Tag = srb->serial_number;
         bcb.Lun = srb->cmnd[1] >> 5;
         if (us->flags & US_FL_SCM_MULT_TARG)
                 bcb.Lun |= srb->target << 4;
-
         bcb.Length = AtaCdbLength;
     
         /* copy the command payload */
@@ -572,33 +431,32 @@
         /* send it to out endpoint */
         US_DEBUGP("Bulk command S 0x%x T 0x%x Trg %d LUN %d L %d F %d CL %d\n",
                   le32_to_cpu(bcb.Signature), bcb.Tag,
-                  (bcb.Lun >> 4), (bcb.Lun & 0xFF), 
+                  (bcb.Lun >> 4), (bcb.Lun & 0x0F), 
                   le32_to_cpu(bcb.DataTransferLength), bcb.Flags, bcb.Length);
-        result = usb_stor_bulk_msg(us, &bcb, us->send_bulk_pipe,
-                               US_BULK_CB_WRAP_LEN, &partial);
+       result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe,
+                               (char *) &bcb, US_BULK_CB_WRAP_LEN, NULL);
         US_DEBUGP("Bulk command transfer result=%d\n", result);
     
        /* did we abort this command? */
        if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
                return ISD200_TRANSPORT_ABORTED;
        }
-
-       else if (result == -EPIPE) {
-               /* if we stall, we need to clear it before we go on */
-                US_DEBUGP("clearing endpoint halt for pipe 0x%x\n",
-                               us->send_bulk_pipe);
-                if (usb_stor_clear_halt(us, us->send_bulk_pipe) < 0)
-                       return ISD200_TRANSPORT_ERROR;
-       } else if (result)  
+       if (result != USB_STOR_XFER_GOOD)  
                 return ISD200_TRANSPORT_ERROR;
     
         /* if the command transfered well, then we go to the data stage */
-        if (!result && bcb.DataTransferLength) {
-               isd200_transfer(us, srb);
-               US_DEBUGP("Bulk data transfer result 0x%x\n", srb->result);
-               
-               if (srb->result == ISD200_TRANSPORT_ABORTED)
+       if (transfer_length) {
+               unsigned int pipe = srb->sc_data_direction == SCSI_DATA_READ ? 
+                               us->recv_bulk_pipe : us->send_bulk_pipe;
+               result = usb_stor_bulk_transfer_srb(us, pipe, srb,
+                                       transfer_length);
+               US_DEBUGP("Bulk data transfer result 0x%x\n", result);
+
+               /* if it was aborted, we need to indicate that */
+               if (result == USB_STOR_XFER_ABORTED)
                        return ISD200_TRANSPORT_ABORTED;
+               if (result == USB_STOR_XFER_ERROR)
+                       return ISD200_TRANSPORT_ERROR;
         }
     
         /* See flow chart on pg 15 of the Bulk Only Transport spec for
@@ -607,42 +465,31 @@
     
         /* get CSW for device status */
         US_DEBUGP("Attempting to get CSW...\n");
-        result = usb_stor_bulk_msg(us, &bcs, us->recv_bulk_pipe,
-                               US_BULK_CS_WRAP_LEN, &partial);
+       result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
+                               (char *) &bcs, US_BULK_CS_WRAP_LEN, NULL);
+
        /* did we abort this command? */
        if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
                return ISD200_TRANSPORT_ABORTED;
        }
 
         /* did the attempt to read the CSW fail? */
-        if (result == -EPIPE) {
-                US_DEBUGP("clearing endpoint halt for pipe 0x%x\n",
-                               us->recv_bulk_pipe);
-                if (usb_stor_clear_halt(us, us->recv_bulk_pipe) < 0)
-                       return ISD200_TRANSPORT_ERROR;
+       if (result == USB_STOR_XFER_STALLED) {
            
                 /* get the status again */
                 US_DEBUGP("Attempting to get CSW (2nd try)...\n");
-                result = usb_stor_bulk_msg(us, &bcs, us->recv_bulk_pipe,
-                                           US_BULK_CS_WRAP_LEN, &partial);
+               result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
+                               (char *) &bcs, US_BULK_CS_WRAP_LEN, NULL);
 
                 /* if the command was aborted, indicate that */
                if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
                        return ISD200_TRANSPORT_ABORTED;
                }
-        
-                /* if it fails again, we need a reset and return an error*/
-                if (result == -EPIPE) {
-                        US_DEBUGP("clearing halt for pipe 0x%x\n",
-                                       us->recv_bulk_pipe);
-                        usb_stor_clear_halt(us, us->recv_bulk_pipe);
-                        return ISD200_TRANSPORT_ERROR;
-                }
         }
     
         /* if we still have a failure at this point, we're in trouble */
         US_DEBUGP("Bulk status result = %d\n", result);
-        if (result)
+        if (result != USB_STOR_XFER_GOOD)
                 return ISD200_TRANSPORT_ERROR;
     
         /* check bulk status */
@@ -651,7 +498,7 @@
                   bcs.Residue, bcs.Status);
         if (bcs.Signature != cpu_to_le32(US_BULK_CS_SIGN) || 
             bcs.Tag != bcb.Tag || 
-            bcs.Status > US_BULK_STAT_PHASE || partial != 13) {
+            bcs.Status > US_BULK_STAT_PHASE) {
                 US_DEBUGP("Bulk logical error\n");
                 return ISD200_TRANSPORT_ERROR;
         }
diff -Nru a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c
--- a/drivers/usb/storage/transport.c   Sun Nov  3 14:52:20 2002
+++ b/drivers/usb/storage/transport.c   Sun Nov  3 14:52:20 2002
@@ -1296,7 +1296,6 @@
        struct bulk_cs_wrap bcs;
        unsigned int transfer_length = usb_stor_transfer_length(srb);
        int result;
-       int partial;
 
        /* set up the command wrapper */
        bcb.Signature = cpu_to_le32(US_BULK_CB_SIGN);
@@ -1316,9 +1315,9 @@
        US_DEBUGP("Bulk command S 0x%x T 0x%x Trg %d LUN %d L %d F %d CL %d\n",
                  le32_to_cpu(bcb.Signature), bcb.Tag,
                  (bcb.Lun >> 4), (bcb.Lun & 0x0F), 
-                 bcb.DataTransferLength, bcb.Flags, bcb.Length);
-       result = usb_stor_bulk_msg(us, &bcb, us->send_bulk_pipe,
-                               US_BULK_CB_WRAP_LEN, &partial);
+                 le32_to_cpu(bcb.DataTransferLength), bcb.Flags, bcb.Length);
+       result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe,
+                               (char *) &bcb, US_BULK_CB_WRAP_LEN, NULL);
        US_DEBUGP("Bulk command transfer result=%d\n", result);
 
        /* did we abort this command? */
@@ -1326,23 +1325,8 @@
                US_DEBUGP("usb_stor_Bulk_transport(): transfer aborted\n");
                return USB_STOR_TRANSPORT_ABORTED;
        }
-
-       /* if we stall, we need to clear it before we go on */
-       if (result == -EPIPE) {
-               US_DEBUGP("clearing endpoint halt for pipe 0x%x\n",
-                               us->send_bulk_pipe);
-               result = usb_stor_clear_halt(us, us->send_bulk_pipe);
-
-               /* did we abort this command? */
-               if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
-                       US_DEBUGP("usb_stor_Bulk_transport(): transfer aborted\n");
-                       return USB_STOR_TRANSPORT_ABORTED;
-               }
-               return USB_STOR_TRANSPORT_ERROR;
-       } else if (result) {
-               /* unknown error -- we've got a problem */
+       if (result != USB_STOR_XFER_GOOD)
                return USB_STOR_TRANSPORT_ERROR;
-       }
 
        /* DATA STAGE */
        /* send/receive data payload, if there is any */
@@ -1366,8 +1350,8 @@
 
        /* get CSW for device status */
        US_DEBUGP("Attempting to get CSW...\n");
-       result = usb_stor_bulk_msg(us, &bcs, us->recv_bulk_pipe,
-                               US_BULK_CS_WRAP_LEN, &partial);
+       result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
+                               (char *) &bcs, US_BULK_CS_WRAP_LEN, NULL);
 
        /* did we abort this command? */
        if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
@@ -1376,50 +1360,24 @@
        }
 
        /* did the attempt to read the CSW fail? */
-       if (result == -EPIPE) {
-               US_DEBUGP("clearing endpoint halt for pipe 0x%x\n",
-                               us->recv_bulk_pipe);
-               result = usb_stor_clear_halt(us, us->recv_bulk_pipe);
-
-               /* did we abort this command? */
-               if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
-                       US_DEBUGP("usb_stor_Bulk_transport(): transfer aborted\n");
-                       return USB_STOR_TRANSPORT_ABORTED;
-               }
-               if (result < 0)
-                       return USB_STOR_TRANSPORT_ERROR;
+       if (result == USB_STOR_XFER_STALLED) {
 
                /* get the status again */
                US_DEBUGP("Attempting to get CSW (2nd try)...\n");
-               result = usb_stor_bulk_msg(us, &bcs, us->recv_bulk_pipe,
-                                          US_BULK_CS_WRAP_LEN, &partial);
+               result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
+                               (char *) &bcs, US_BULK_CS_WRAP_LEN, NULL);
 
                /* did we abort this command? */
                if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
                        US_DEBUGP("usb_stor_Bulk_transport(): transfer aborted\n");
                        return USB_STOR_TRANSPORT_ABORTED;
                }
-
-               /* if it fails again, we need a reset and return an error*/
-               if (result == -EPIPE) {
-                       US_DEBUGP("clearing halt for pipe 0x%x\n",
-                                       us->recv_bulk_pipe);
-                       result = usb_stor_clear_halt(us, us->recv_bulk_pipe);
-
-                       /* did we abort this command? */
-                       if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
-                               US_DEBUGP("usb_stor_Bulk_transport(): transfer 
aborted\n");
-                               return USB_STOR_TRANSPORT_ABORTED;
-                       }
-                       return USB_STOR_TRANSPORT_ERROR;
-               }
        }
 
        /* if we still have a failure at this point, we're in trouble */
        US_DEBUGP("Bulk status result = %d\n", result);
-       if (result) {
+       if (result != USB_STOR_XFER_GOOD)
                return USB_STOR_TRANSPORT_ERROR;
-       }
 
        /* check bulk status */
        US_DEBUGP("Bulk status Sig 0x%x T 0x%x R %d Stat 0x%x\n",
@@ -1427,7 +1385,7 @@
                  bcs.Residue, bcs.Status);
        if (bcs.Signature != cpu_to_le32(US_BULK_CS_SIGN) || 
            bcs.Tag != bcb.Tag || 
-           bcs.Status > US_BULK_STAT_PHASE || partial != 13) {
+           bcs.Status > US_BULK_STAT_PHASE) {
                US_DEBUGP("Bulk logical error\n");
                return USB_STOR_TRANSPORT_ERROR;
        }

-- 
Matthew Dharm                              Home: [EMAIL PROTECTED] 
Maintainer, Linux USB Mass Storage Driver

C:  They kicked your ass, didn't they?
S:  They were cheating!
                                        -- The Chief and Stef
User Friendly, 11/19/1997

Attachment: msg09196/pgp00000.pgp
Description: PGP signature

Reply via email to