Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
[cascardo/linux.git] / drivers / usb / storage / transport.c
index 47644b5..5780ed1 100644 (file)
@@ -50,7 +50,7 @@
 #include <linux/slab.h>
 
 #include <scsi/scsi.h>
-#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_eh.h>
 #include <scsi/scsi_device.h>
 
 #include "usb.h"
@@ -427,7 +427,7 @@ static int usb_stor_bulk_transfer_sglist(struct us_data *us, unsigned int pipe,
        US_DEBUGP("%s: xfer %u bytes, %d entries\n", __FUNCTION__,
                        length, num_sg);
        result = usb_sg_init(&us->current_sg, us->pusb_dev, pipe, 0,
-                       sg, num_sg, length, SLAB_NOIO);
+                       sg, num_sg, length, GFP_NOIO);
        if (result) {
                US_DEBUGP("usb_sg_init returned %d\n", result);
                return USB_STOR_XFER_ERROR;
@@ -458,6 +458,22 @@ static int usb_stor_bulk_transfer_sglist(struct us_data *us, unsigned int pipe,
                        us->current_sg.bytes);
 }
 
+/*
+ * Common used function. Transfer a complete command
+ * via usb_stor_bulk_transfer_sglist() above. Set cmnd resid
+ */
+int usb_stor_bulk_srb(struct us_data* us, unsigned int pipe,
+                     struct scsi_cmnd* srb)
+{
+       unsigned int partial;
+       int result = usb_stor_bulk_transfer_sglist(us, pipe, scsi_sglist(srb),
+                                     scsi_sg_count(srb), scsi_bufflen(srb),
+                                     &partial);
+
+       scsi_set_resid(srb, scsi_bufflen(srb) - partial);
+       return result;
+}
+
 /*
  * Transfer an entire SCSI command's worth of data payload over the bulk
  * pipe.
@@ -508,7 +524,7 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us)
        int result;
 
        /* send the command to the transport layer */
-       srb->resid = 0;
+       scsi_set_resid(srb, 0);
        result = us->transport(srb, us);
 
        /* if the command gets aborted by the higher layers, we need to
@@ -568,7 +584,7 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us)
         * A short transfer on a command where we don't expect it
         * is unusual, but it doesn't mean we need to auto-sense.
         */
-       if ((srb->resid > 0) &&
+       if ((scsi_get_resid(srb) > 0) &&
            !((srb->cmnd[0] == REQUEST_SENSE) ||
              (srb->cmnd[0] == INQUIRY) ||
              (srb->cmnd[0] == MODE_SENSE) ||
@@ -580,25 +596,11 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us)
        /* Now, if we need to do the auto-sense, let's do it */
        if (need_auto_sense) {
                int temp_result;
-               void* old_request_buffer;
-               unsigned short old_sg;
-               unsigned old_request_bufflen;
-               unsigned char old_sc_data_direction;
-               unsigned char old_cmd_len;
-               unsigned char old_cmnd[MAX_COMMAND_SIZE];
-               int old_resid;
+               struct scsi_eh_save ses;
 
                US_DEBUGP("Issuing auto-REQUEST_SENSE\n");
 
-               /* save the old command */
-               memcpy(old_cmnd, srb->cmnd, MAX_COMMAND_SIZE);
-               old_cmd_len = srb->cmd_len;
-
-               /* set the command and the LUN */
-               memset(srb->cmnd, 0, MAX_COMMAND_SIZE);
-               srb->cmnd[0] = REQUEST_SENSE;
-               srb->cmnd[1] = old_cmnd[1] & 0xE0;
-               srb->cmnd[4] = 18;
+               scsi_eh_prep_cmnd(srb, &ses, NULL, 0, US_SENSE_SIZE);
 
                /* FIXME: we must do the protocol translation here */
                if (us->subclass == US_SC_RBC || us->subclass == US_SC_SCSI)
@@ -606,36 +608,12 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us)
                else
                        srb->cmd_len = 12;
 
-               /* set the transfer direction */
-               old_sc_data_direction = srb->sc_data_direction;
-               srb->sc_data_direction = DMA_FROM_DEVICE;
-
-               /* use the new buffer we have */
-               old_request_buffer = srb->request_buffer;
-               srb->request_buffer = us->sensebuf;
-
-               /* set the buffer length for transfer */
-               old_request_bufflen = srb->request_bufflen;
-               srb->request_bufflen = US_SENSE_SIZE;
-
-               /* set up for no scatter-gather use */
-               old_sg = srb->use_sg;
-               srb->use_sg = 0;
-
                /* issue the auto-sense command */
-               old_resid = srb->resid;
-               srb->resid = 0;
+               scsi_set_resid(srb, 0);
                temp_result = us->transport(us->srb, us);
 
                /* let's clean up right away */
-               memcpy(srb->sense_buffer, us->sensebuf, US_SENSE_SIZE);
-               srb->resid = old_resid;
-               srb->request_buffer = old_request_buffer;
-               srb->request_bufflen = old_request_bufflen;
-               srb->use_sg = old_sg;
-               srb->sc_data_direction = old_sc_data_direction;
-               srb->cmd_len = old_cmd_len;
-               memcpy(srb->cmnd, old_cmnd, MAX_COMMAND_SIZE);
+               scsi_eh_restore_cmnd(srb, &ses);
 
                if (test_bit(US_FLIDX_TIMED_OUT, &us->flags)) {
                        US_DEBUGP("-- auto-sense aborted\n");
@@ -687,7 +665,7 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us)
 
        /* Did we transfer less than the minimum amount required? */
        if (srb->result == SAM_STAT_GOOD &&
-                       srb->request_bufflen - srb->resid < srb->underflow)
+                       scsi_bufflen(srb) - scsi_get_resid(srb) < srb->underflow)
                srb->result = (DID_ERROR << 16) | (SUGGEST_RETRY << 24);
 
        return;
@@ -746,7 +724,7 @@ void usb_stor_stop_transport(struct us_data *us)
 
 int usb_stor_CBI_transport(struct scsi_cmnd *srb, struct us_data *us)
 {
-       unsigned int transfer_length = srb->request_bufflen;
+       unsigned int transfer_length = scsi_bufflen(srb);
        unsigned int pipe = 0;
        int result;
 
@@ -775,9 +753,7 @@ int usb_stor_CBI_transport(struct scsi_cmnd *srb, struct us_data *us)
        if (transfer_length) {
                pipe = srb->sc_data_direction == DMA_FROM_DEVICE ? 
                                us->recv_bulk_pipe : us->send_bulk_pipe;
-               result = usb_stor_bulk_transfer_sg(us, pipe,
-                                       srb->request_buffer, transfer_length,
-                                       srb->use_sg, &srb->resid);
+               result = usb_stor_bulk_srb(us, pipe, srb);
                US_DEBUGP("CBI data stage result is 0x%x\n", result);
 
                /* if we stalled the data transfer it means command failed */
@@ -846,7 +822,7 @@ int usb_stor_CBI_transport(struct scsi_cmnd *srb, struct us_data *us)
  */
 int usb_stor_CB_transport(struct scsi_cmnd *srb, struct us_data *us)
 {
-       unsigned int transfer_length = srb->request_bufflen;
+       unsigned int transfer_length = scsi_bufflen(srb);
        int result;
 
        /* COMMAND STAGE */
@@ -874,9 +850,7 @@ int usb_stor_CB_transport(struct scsi_cmnd *srb, struct us_data *us)
        if (transfer_length) {
                unsigned int pipe = srb->sc_data_direction == DMA_FROM_DEVICE ? 
                                us->recv_bulk_pipe : us->send_bulk_pipe;
-               result = usb_stor_bulk_transfer_sg(us, pipe,
-                                       srb->request_buffer, transfer_length,
-                                       srb->use_sg, &srb->resid);
+               result = usb_stor_bulk_srb(us, pipe, srb);
                US_DEBUGP("CB data stage result is 0x%x\n", result);
 
                /* if we stalled the data transfer it means command failed */
@@ -917,17 +891,6 @@ int usb_stor_Bulk_max_lun(struct us_data *us)
        if (result > 0)
                return us->iobuf[0];
 
-       /* 
-        * Some devices (i.e. Iomega Zip100) need this -- apparently
-        * the bulk pipes get STALLed when the GetMaxLUN request is
-        * processed.   This is, in theory, harmless to all other devices
-        * (regardless of if they stall or not).
-        */
-       if (result == -EPIPE) {
-               usb_stor_clear_halt(us, us->recv_bulk_pipe);
-               usb_stor_clear_halt(us, us->send_bulk_pipe);
-       }
-
        /*
         * Some devices don't like GetMaxLUN.  They may STALL the control
         * pipe, they may return a zero-length result, they may do nothing at
@@ -942,7 +905,7 @@ int usb_stor_Bulk_transport(struct scsi_cmnd *srb, struct us_data *us)
 {
        struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
        struct bulk_cs_wrap *bcs = (struct bulk_cs_wrap *) us->iobuf;
-       unsigned int transfer_length = srb->request_bufflen;
+       unsigned int transfer_length = scsi_bufflen(srb);
        unsigned int residue;
        int result;
        int fake_sense = 0;
@@ -993,9 +956,7 @@ int usb_stor_Bulk_transport(struct scsi_cmnd *srb, struct us_data *us)
        if (transfer_length) {
                unsigned int pipe = srb->sc_data_direction == DMA_FROM_DEVICE ? 
                                us->recv_bulk_pipe : us->send_bulk_pipe;
-               result = usb_stor_bulk_transfer_sg(us, pipe,
-                                       srb->request_buffer, transfer_length,
-                                       srb->use_sg, &srb->resid);
+               result = usb_stor_bulk_srb(us, pipe, srb);
                US_DEBUGP("Bulk data transfer result 0x%x\n", result);
                if (result == USB_STOR_XFER_ERROR)
                        return USB_STOR_TRANSPORT_ERROR;
@@ -1074,7 +1035,8 @@ int usb_stor_Bulk_transport(struct scsi_cmnd *srb, struct us_data *us)
        if (residue) {
                if (!(us->flags & US_FL_IGNORE_RESIDUE)) {
                        residue = min(residue, transfer_length);
-                       srb->resid = max(srb->resid, (int) residue);
+                       scsi_set_resid(srb, max(scsi_get_resid(srb),
+                                                              (int) residue));
                }
        }