SCSI fixes on 20151010
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). Signed-off-by: James Bottomley <JBottomley@Odin.com> -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQEbBAABAgAGBQJWGgjcAAoJEDeqqVYsXL0MDjIH+N1poa/RB6jU163q1bMnJlp6 6ygEqLtrJH7FNjadiRuYjsZaSWfuabbEyj0zV8t6S7Z2wWQmXG7Qfkic3W0CZa9u qCa3aPmRB06Al9nwmEDlgilBfFP5hWkWldiPF7uEBqcCsBtzT3cxxUnyoCS1fy28 USMHSQ4fnQDFdaTafXqDCRrMjXIJLeRY1Gg7YuiG7l6h4YK5qPC+0cCpiIeDyDyI WjTr/SbFzIyDg0r/SNwjZqbhY2+s4a2/4GcAmjpBMWvg2GnXDGt6vxibRvrwZfHf PtUvsVS7eJhAOAKs67KOJavP6kvheXkj/QTZWq5Y/DqDrd/14qIgjOPpIHYyig== =20ji -----END PGP SIGNATURE----- Merge tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi 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
This commit is contained in:
commit
5a433f7a6b
|
@ -212,6 +212,17 @@ static const struct file_operations twa_fops = {
|
||||||
.llseek = noop_llseek,
|
.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 */
|
/* This function will complete an aen request from the isr */
|
||||||
static int twa_aen_complete(TW_Device_Extension *tw_dev, int request_id)
|
static int twa_aen_complete(TW_Device_Extension *tw_dev, int request_id)
|
||||||
{
|
{
|
||||||
|
@ -1339,6 +1350,7 @@ static irqreturn_t twa_interrupt(int irq, void *dev_instance)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now complete the io */
|
/* Now complete the io */
|
||||||
|
if (twa_command_mapped(cmd))
|
||||||
scsi_dma_unmap(cmd);
|
scsi_dma_unmap(cmd);
|
||||||
cmd->scsi_done(cmd);
|
cmd->scsi_done(cmd);
|
||||||
tw_dev->state[request_id] = TW_S_COMPLETED;
|
tw_dev->state[request_id] = TW_S_COMPLETED;
|
||||||
|
@ -1582,6 +1594,7 @@ static int twa_reset_device_extension(TW_Device_Extension *tw_dev)
|
||||||
struct scsi_cmnd *cmd = tw_dev->srb[i];
|
struct scsi_cmnd *cmd = tw_dev->srb[i];
|
||||||
|
|
||||||
cmd->result = (DID_RESET << 16);
|
cmd->result = (DID_RESET << 16);
|
||||||
|
if (twa_command_mapped(cmd))
|
||||||
scsi_dma_unmap(cmd);
|
scsi_dma_unmap(cmd);
|
||||||
cmd->scsi_done(cmd);
|
cmd->scsi_done(cmd);
|
||||||
}
|
}
|
||||||
|
@ -1765,11 +1778,13 @@ 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);
|
retval = twa_scsiop_execute_scsi(tw_dev, request_id, NULL, 0, NULL);
|
||||||
switch (retval) {
|
switch (retval) {
|
||||||
case SCSI_MLQUEUE_HOST_BUSY:
|
case SCSI_MLQUEUE_HOST_BUSY:
|
||||||
|
if (twa_command_mapped(SCpnt))
|
||||||
scsi_dma_unmap(SCpnt);
|
scsi_dma_unmap(SCpnt);
|
||||||
twa_free_request_id(tw_dev, request_id);
|
twa_free_request_id(tw_dev, request_id);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
SCpnt->result = (DID_ERROR << 16);
|
SCpnt->result = (DID_ERROR << 16);
|
||||||
|
if (twa_command_mapped(SCpnt))
|
||||||
scsi_dma_unmap(SCpnt);
|
scsi_dma_unmap(SCpnt);
|
||||||
done(SCpnt);
|
done(SCpnt);
|
||||||
tw_dev->state[request_id] = TW_S_COMPLETED;
|
tw_dev->state[request_id] = TW_S_COMPLETED;
|
||||||
|
@ -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 */
|
/* Map sglist from scsi layer to cmd packet */
|
||||||
|
|
||||||
if (scsi_sg_count(srb)) {
|
if (scsi_sg_count(srb)) {
|
||||||
if ((scsi_sg_count(srb) == 1) &&
|
if (!twa_command_mapped(srb)) {
|
||||||
(scsi_bufflen(srb) < TW_MIN_SGL_LENGTH)) {
|
|
||||||
if (srb->sc_data_direction == DMA_TO_DEVICE ||
|
if (srb->sc_data_direction == DMA_TO_DEVICE ||
|
||||||
srb->sc_data_direction == DMA_BIDIRECTIONAL)
|
srb->sc_data_direction == DMA_BIDIRECTIONAL)
|
||||||
scsi_sg_copy_to_buffer(srb,
|
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];
|
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_FROM_DEVICE ||
|
||||||
cmd->sc_data_direction == DMA_BIDIRECTIONAL)) {
|
cmd->sc_data_direction == DMA_BIDIRECTIONAL)) {
|
||||||
if (scsi_sg_count(cmd) == 1) {
|
if (scsi_sg_count(cmd) == 1) {
|
||||||
|
|
|
@ -976,13 +976,13 @@ static void iscsi_tmf_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
|
||||||
wake_up(&conn->ehwait);
|
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_nopout hdr;
|
||||||
struct iscsi_task *task;
|
struct iscsi_task *task;
|
||||||
|
|
||||||
if (!rhdr && conn->ping_task)
|
if (!rhdr && conn->ping_task)
|
||||||
return;
|
return -EINVAL;
|
||||||
|
|
||||||
memset(&hdr, 0, sizeof(struct iscsi_nopout));
|
memset(&hdr, 0, sizeof(struct iscsi_nopout));
|
||||||
hdr.opcode = ISCSI_OP_NOOP_OUT | ISCSI_OP_IMMEDIATE;
|
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;
|
hdr.ttt = RESERVED_ITT;
|
||||||
|
|
||||||
task = __iscsi_conn_send_pdu(conn, (struct iscsi_hdr *)&hdr, NULL, 0);
|
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");
|
iscsi_conn_printk(KERN_ERR, conn, "Could not send nopout\n");
|
||||||
else if (!rhdr) {
|
return -EIO;
|
||||||
|
} else if (!rhdr) {
|
||||||
/* only track our nops */
|
/* only track our nops */
|
||||||
conn->ping_task = task;
|
conn->ping_task = task;
|
||||||
conn->last_ping = jiffies;
|
conn->last_ping = jiffies;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int iscsi_nop_out_rsp(struct iscsi_task *task,
|
static int iscsi_nop_out_rsp(struct iscsi_task *task,
|
||||||
|
@ -2092,7 +2095,9 @@ static void iscsi_check_transport_timeouts(unsigned long data)
|
||||||
if (time_before_eq(last_recv + recv_timeout, jiffies)) {
|
if (time_before_eq(last_recv + recv_timeout, jiffies)) {
|
||||||
/* send a ping to try to provoke some traffic */
|
/* send a ping to try to provoke some traffic */
|
||||||
ISCSI_DBG_CONN(conn, "Sending nopout as ping\n");
|
ISCSI_DBG_CONN(conn, "Sending nopout as ping\n");
|
||||||
iscsi_send_nopout(conn, NULL);
|
if (iscsi_send_nopout(conn, NULL))
|
||||||
|
next_timeout = jiffies + (1 * HZ);
|
||||||
|
else
|
||||||
next_timeout = conn->last_ping + (conn->ping_timeout * HZ);
|
next_timeout = conn->last_ping + (conn->ping_timeout * HZ);
|
||||||
} else
|
} else
|
||||||
next_timeout = last_recv + recv_timeout;
|
next_timeout = last_recv + recv_timeout;
|
||||||
|
|
|
@ -111,7 +111,7 @@ static struct scsi_device_handler *scsi_dh_lookup(const char *name)
|
||||||
|
|
||||||
dh = __scsi_dh_lookup(name);
|
dh = __scsi_dh_lookup(name);
|
||||||
if (!dh) {
|
if (!dh) {
|
||||||
request_module(name);
|
request_module("scsi_dh_%s", name);
|
||||||
dh = __scsi_dh_lookup(name);
|
dh = __scsi_dh_lookup(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue