Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5a433f7a authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
parents f24fe98d 15e3d5a2
Loading
Loading
Loading
Loading
+21 −7
Original line number Original line Diff line number Diff line
@@ -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) {
+11 −6
Original line number Original line Diff line number Diff line
@@ -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;
+1 −1
Original line number Original line Diff line number Diff line
@@ -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);
	}
	}