Merge tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
authorLinus Torvalds <torvalds@linux-foundation.org>
Sun, 11 Oct 2015 17:02:30 +0000 (10:02 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sun, 11 Oct 2015 17:02:30 +0000 (10:02 -0700)
Pull SCSI fixes from James Bottomley:
 "This is a set of three bug fixes, two of which are regressions from
  recent updates (the 3ware one from 4.1 and the device handler fixes
  from 4.2)"

* tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi:
  3w-9xxx: don't unmap bounce buffered commands
  scsi_dh: Use the correct module name when loading device handler
  libiscsi: Fix iscsi_check_transport_timeouts possible infinite loop

drivers/scsi/3w-9xxx.c
drivers/scsi/libiscsi.c
drivers/scsi/scsi_dh.c

index add419d..a56a7b2 100644 (file)
@@ -212,6 +212,17 @@ static const struct file_operations twa_fops = {
        .llseek         = noop_llseek,
 };
 
+/*
+ * The controllers use an inline buffer instead of a mapped SGL for small,
+ * single entry buffers.  Note that we treat a zero-length transfer like
+ * a mapped SGL.
+ */
+static bool twa_command_mapped(struct scsi_cmnd *cmd)
+{
+       return scsi_sg_count(cmd) != 1 ||
+               scsi_bufflen(cmd) >= TW_MIN_SGL_LENGTH;
+}
+
 /* This function will complete an aen request from the isr */
 static int twa_aen_complete(TW_Device_Extension *tw_dev, int request_id)
 {
@@ -1339,7 +1350,8 @@ static irqreturn_t twa_interrupt(int irq, void *dev_instance)
                                }
 
                                /* Now complete the io */
-                               scsi_dma_unmap(cmd);
+                               if (twa_command_mapped(cmd))
+                                       scsi_dma_unmap(cmd);
                                cmd->scsi_done(cmd);
                                tw_dev->state[request_id] = TW_S_COMPLETED;
                                twa_free_request_id(tw_dev, request_id);
@@ -1582,7 +1594,8 @@ static int twa_reset_device_extension(TW_Device_Extension *tw_dev)
                                struct scsi_cmnd *cmd = tw_dev->srb[i];
 
                                cmd->result = (DID_RESET << 16);
-                               scsi_dma_unmap(cmd);
+                               if (twa_command_mapped(cmd))
+                                       scsi_dma_unmap(cmd);
                                cmd->scsi_done(cmd);
                        }
                }
@@ -1765,12 +1778,14 @@ static int twa_scsi_queue_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_
        retval = twa_scsiop_execute_scsi(tw_dev, request_id, NULL, 0, NULL);
        switch (retval) {
        case SCSI_MLQUEUE_HOST_BUSY:
-               scsi_dma_unmap(SCpnt);
+               if (twa_command_mapped(SCpnt))
+                       scsi_dma_unmap(SCpnt);
                twa_free_request_id(tw_dev, request_id);
                break;
        case 1:
                SCpnt->result = (DID_ERROR << 16);
-               scsi_dma_unmap(SCpnt);
+               if (twa_command_mapped(SCpnt))
+                       scsi_dma_unmap(SCpnt);
                done(SCpnt);
                tw_dev->state[request_id] = TW_S_COMPLETED;
                twa_free_request_id(tw_dev, request_id);
@@ -1831,8 +1846,7 @@ static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id,
                /* Map sglist from scsi layer to cmd packet */
 
                if (scsi_sg_count(srb)) {
-                       if ((scsi_sg_count(srb) == 1) &&
-                           (scsi_bufflen(srb) < TW_MIN_SGL_LENGTH)) {
+                       if (!twa_command_mapped(srb)) {
                                if (srb->sc_data_direction == DMA_TO_DEVICE ||
                                    srb->sc_data_direction == DMA_BIDIRECTIONAL)
                                        scsi_sg_copy_to_buffer(srb,
@@ -1905,7 +1919,7 @@ static void twa_scsiop_execute_scsi_complete(TW_Device_Extension *tw_dev, int re
 {
        struct scsi_cmnd *cmd = tw_dev->srb[request_id];
 
-       if (scsi_bufflen(cmd) < TW_MIN_SGL_LENGTH &&
+       if (!twa_command_mapped(cmd) &&
            (cmd->sc_data_direction == DMA_FROM_DEVICE ||
             cmd->sc_data_direction == DMA_BIDIRECTIONAL)) {
                if (scsi_sg_count(cmd) == 1) {
index 33c74d3..6bffd91 100644 (file)
@@ -976,13 +976,13 @@ static void iscsi_tmf_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
        wake_up(&conn->ehwait);
 }
 
-static void iscsi_send_nopout(struct iscsi_conn *conn, struct iscsi_nopin *rhdr)
+static int iscsi_send_nopout(struct iscsi_conn *conn, struct iscsi_nopin *rhdr)
 {
         struct iscsi_nopout hdr;
        struct iscsi_task *task;
 
        if (!rhdr && conn->ping_task)
-               return;
+               return -EINVAL;
 
        memset(&hdr, 0, sizeof(struct iscsi_nopout));
        hdr.opcode = ISCSI_OP_NOOP_OUT | ISCSI_OP_IMMEDIATE;
@@ -996,13 +996,16 @@ static void iscsi_send_nopout(struct iscsi_conn *conn, struct iscsi_nopin *rhdr)
                hdr.ttt = RESERVED_ITT;
 
        task = __iscsi_conn_send_pdu(conn, (struct iscsi_hdr *)&hdr, NULL, 0);
-       if (!task)
+       if (!task) {
                iscsi_conn_printk(KERN_ERR, conn, "Could not send nopout\n");
-       else if (!rhdr) {
+               return -EIO;
+       } else if (!rhdr) {
                /* only track our nops */
                conn->ping_task = task;
                conn->last_ping = jiffies;
        }
+
+       return 0;
 }
 
 static int iscsi_nop_out_rsp(struct iscsi_task *task,
@@ -2092,8 +2095,10 @@ static void iscsi_check_transport_timeouts(unsigned long data)
        if (time_before_eq(last_recv + recv_timeout, jiffies)) {
                /* send a ping to try to provoke some traffic */
                ISCSI_DBG_CONN(conn, "Sending nopout as ping\n");
-               iscsi_send_nopout(conn, NULL);
-               next_timeout = conn->last_ping + (conn->ping_timeout * HZ);
+               if (iscsi_send_nopout(conn, NULL))
+                       next_timeout = jiffies + (1 * HZ);
+               else
+                       next_timeout = conn->last_ping + (conn->ping_timeout * HZ);
        } else
                next_timeout = last_recv + recv_timeout;
 
index edb044a..0a2168e 100644 (file)
@@ -111,7 +111,7 @@ static struct scsi_device_handler *scsi_dh_lookup(const char *name)
 
        dh = __scsi_dh_lookup(name);
        if (!dh) {
-               request_module(name);
+               request_module("scsi_dh_%s", name);
                dh = __scsi_dh_lookup(name);
        }