Commit f4f051eb authored by 's avatar Committed by James Bottomley
Browse files

[PATCH] qla2xxx: remove internal queuing...



Remove internal command queuing from the driver.  As is, this
driver cannot tolerate cable-pulls as I/Os will begin to fail
by the upper layers.

     o Should be used in conjuction with the
       11-fc_rport_adds_2.diff patch.
     o Removes qla_listops.h file -- no longer needed.

Signed-off-by: default avatarAndrew Vasquez <andrew.vasquez@qlogic.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent c46f2ffb
Loading
Loading
Loading
Loading
+0 −22
Original line number Diff line number Diff line
@@ -2175,27 +2175,6 @@ typedef struct scsi_qla_host {
	uint32_t	current_outstanding_cmd; 
	srb_t		*status_srb;	/* Status continuation entry. */

	/*
	 * Need to hold the list_lock with irq's disabled in order to access
	 * the following list.
	 *
	 * This list_lock is of lower priority than the host_lock.
	 */
	spinlock_t		list_lock ____cacheline_aligned;
						/* lock to guard lists which
						 * hold srb_t's */
        struct list_head        retry_queue;    /* watchdog queue */
        struct list_head        done_queue;     /* job on done queue */
        struct list_head        failover_queue; /* failover list link. */
	struct list_head        scsi_retry_queue;     /* SCSI retry queue */
	struct list_head        pending_queue;	/* SCSI command pending queue */

	unsigned long    done_q_cnt;
	unsigned long    pending_in_q;
        uint32_t	retry_q_cnt; 
        uint32_t	scsi_retry_q_cnt; 
        uint32_t	failover_cnt; 

	unsigned long	last_irq_cpu;	/* cpu where we got our last irq */

	uint16_t           revision;
@@ -2479,7 +2458,6 @@ struct _qla2x00stats {
#include "qla_gbl.h"
#include "qla_dbg.h"
#include "qla_inline.h"
#include "qla_listops.h"

/*
* String arrays
+1 −5
Original line number Diff line number Diff line
@@ -74,6 +74,7 @@ extern int ql2xsuspendcount;
#if defined(MODULE)
extern char *ql2xopts;
#endif
extern void qla2x00_sp_compl(scsi_qla_host_t *, srb_t *);

extern char *qla2x00_get_fw_version_str(struct scsi_qla_host *, char *);

@@ -82,17 +83,12 @@ extern void qla2x00_cmd_timeout(srb_t *);
extern int __qla2x00_suspend_lun(scsi_qla_host_t *, os_lun_t *, int, int, int);

extern void qla2x00_done(scsi_qla_host_t *);
extern void qla2x00_next(scsi_qla_host_t *);
extern void qla2x00_flush_failover_q(scsi_qla_host_t *, os_lun_t *);
extern void qla2x00_reset_lun_fo_counts(scsi_qla_host_t *, os_lun_t *);

extern void qla2x00_extend_timeout(struct scsi_cmnd *, int);

extern void qla2x00_mark_device_lost(scsi_qla_host_t *, fc_port_t *, int);
extern void qla2x00_mark_all_devices_lost(scsi_qla_host_t *);

extern void qla2x00_abort_queues(scsi_qla_host_t *, uint8_t);

extern void qla2x00_blink_led(scsi_qla_host_t *);

extern int qla2x00_down_timeout(struct semaphore *, unsigned long);
+2 −104
Original line number Diff line number Diff line
@@ -3146,7 +3146,6 @@ qla2x00_loop_resync(scsi_qla_host_t *ha)
				wait_time &&
				(test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags)));
		}
		qla2x00_restart_queues(ha, 1);
	}

	if (test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags)) {
@@ -3160,87 +3159,6 @@ qla2x00_loop_resync(scsi_qla_host_t *ha)
	return (rval);
}

/*
 *  qla2x00_restart_queues
 *	Restart device queues.
 *
 * Input:
 *	ha = adapter block pointer.
 *
 * Context:
 *	Kernel/Interrupt context.
 */
void
qla2x00_restart_queues(scsi_qla_host_t *ha, uint8_t flush) 
{
	srb_t  		*sp;
	int		retry_q_cnt = 0;
	int		pending_q_cnt = 0;
	struct list_head *list, *temp;
	unsigned long flags = 0;

	clear_bit(RESTART_QUEUES_NEEDED, &ha->dpc_flags);

	/* start pending queue */
	pending_q_cnt = ha->qthreads;
	if (flush) {
		spin_lock_irqsave(&ha->list_lock,flags);
		list_for_each_safe(list, temp, &ha->pending_queue) {
			sp = list_entry(list, srb_t, list);

			if ((sp->flags & SRB_TAPE))
				continue;
			 
			/* 
			 * When time expire return request back to OS as BUSY 
			 */
			__del_from_pending_queue(ha, sp);
			sp->cmd->result = DID_BUS_BUSY << 16;
			sp->cmd->host_scribble = (unsigned char *)NULL;
			__add_to_done_queue(ha, sp);
		}
		spin_unlock_irqrestore(&ha->list_lock, flags);
	} else {
		if (!list_empty(&ha->pending_queue))
			qla2x00_next(ha);
	}

	/*
	 * Clear out our retry queue
	 */
	if (flush) {
		spin_lock_irqsave(&ha->list_lock, flags);
		retry_q_cnt = ha->retry_q_cnt;
		list_for_each_safe(list, temp, &ha->retry_queue) {
			sp = list_entry(list, srb_t, list);
			/* when time expire return request back to OS as BUSY */
			__del_from_retry_queue(ha, sp);
			sp->cmd->result = DID_BUS_BUSY << 16;
			sp->cmd->host_scribble = (unsigned char *)NULL;
			__add_to_done_queue(ha, sp);
		}
		spin_unlock_irqrestore(&ha->list_lock, flags);

		DEBUG2(printk("%s(%ld): callback %d commands.\n",
				__func__,
				ha->host_no,
				retry_q_cnt);)
	}

	DEBUG2(printk("%s(%ld): active=%ld, retry=%d, pending=%d, "
			"done=%ld, scsi retry=%d commands.\n",
			__func__,
			ha->host_no,
			ha->actthreads,
			ha->retry_q_cnt,
			pending_q_cnt,
			ha->done_q_cnt,
			ha->scsi_retry_q_cnt);)

	if (!list_empty(&ha->done_queue))
		qla2x00_done(ha);
}

void
qla2x00_rescan_fcports(scsi_qla_host_t *ha)
{
@@ -3699,24 +3617,10 @@ qla2x00_abort_isp(scsi_qla_host_t *ha)
					ha->actthreads--;
				sp->lun_queue->out_cnt--;

				/*
				 * Set the cmd host_byte status depending on
				 * whether the scsi_error_handler is
				 * active or not.
 				 */
				if (sp->flags & SRB_TAPE) {
					sp->cmd->result = DID_NO_CONNECT << 16;
				} else {
					if (ha->host->eh_active != EH_ACTIVE)
						sp->cmd->result =
						    DID_BUS_BUSY << 16;
					else
						sp->cmd->result =
						    DID_RESET << 16;
				}
				sp->flags = 0;
				sp->cmd->result = DID_RESET << 16;
				sp->cmd->host_scribble = (unsigned char *)NULL;
				add_to_done_queue(ha, sp);
				qla2x00_sp_compl(ha, sp);
			}
		}
		spin_unlock_irqrestore(&ha->hardware_lock, flags);
@@ -3739,11 +3643,6 @@ qla2x00_abort_isp(scsi_qla_host_t *ha)
			/* Enable ISP interrupts. */
			qla2x00_enable_intrs(ha);

			/* v2.19.5b6 Return all commands */
			qla2x00_abort_queues(ha, 1);

			/* Restart queues that may have been stopped. */
			qla2x00_restart_queues(ha, 1);
			ha->isp_abort_cnt = 0; 
			clear_bit(ISP_ABORT_RETRY, &ha->dpc_flags);
		} else {	/* failed the ISP abort */
@@ -3758,7 +3657,6 @@ qla2x00_abort_isp(scsi_qla_host_t *ha)
					 * completely.
					 */
					qla2x00_reset_adapter(ha);
					qla2x00_abort_queues(ha, 0);
					ha->flags.online = 0;
					clear_bit(ISP_ABORT_RETRY,
					    &ha->dpc_flags);
+0 −13
Original line number Diff line number Diff line
@@ -334,7 +334,6 @@ qla2x00_start_scsi(srb_t *sp)
	uint32_t        index;
	uint32_t	handle;
	cmd_entry_t	*cmd_pkt;
	uint32_t        timeout;
	struct scatterlist *sg;
	uint16_t	cnt;
	uint16_t	req_cnt;
@@ -433,18 +432,6 @@ qla2x00_start_scsi(srb_t *sp)
		}
	}

	/*
	 * Allocate at least 5 (+ QLA_CMD_TIMER_DELTA) seconds for RISC timeout.
	 */
	timeout = (uint32_t)(cmd->timeout_per_command / HZ);
	if (timeout > 65535)
		cmd_pkt->timeout = __constant_cpu_to_le16(0);
	else if (timeout > 25)
		cmd_pkt->timeout = cpu_to_le16((uint16_t)timeout -
		    (5 + QLA_CMD_TIMER_DELTA));
	else
		cmd_pkt->timeout = cpu_to_le16((uint16_t)timeout);

	/* Load SCSI command packet. */
	memcpy(cmd_pkt->scsi_cdb, cmd->cmnd, cmd->cmd_len);
	cmd_pkt->byte_count = cpu_to_le32((uint32_t)cmd->request_bufflen);
+8 −139
Original line number Diff line number Diff line
@@ -27,8 +27,6 @@ static void qla2x00_status_cont_entry(scsi_qla_host_t *, sts_cont_entry_t *);
static void qla2x00_error_entry(scsi_qla_host_t *, sts_entry_t *);
static void qla2x00_ms_entry(scsi_qla_host_t *, ms_iocb_entry_t *);

static int qla2x00_check_sense(struct scsi_cmnd *cp, os_lun_t *);

/**
 * qla2100_intr_handler() - Process interrupts for the ISP2100 and ISP2200.
 * @irq:
@@ -93,7 +91,6 @@ qla2100_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
	}
	spin_unlock_irqrestore(&ha->hardware_lock, flags);

	qla2x00_next(ha);
	ha->last_irq_cpu = _smp_processor_id();
	ha->total_isr_cnt++;

@@ -107,9 +104,6 @@ qla2100_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
		spin_unlock_irqrestore(&ha->mbx_reg_lock, flags);
	}

	if (!list_empty(&ha->done_queue))
		qla2x00_done(ha);

	return (IRQ_HANDLED);
}

@@ -206,7 +200,6 @@ qla2300_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
	}
	spin_unlock_irqrestore(&ha->hardware_lock, flags);

	qla2x00_next(ha);
	ha->last_irq_cpu = _smp_processor_id();
	ha->total_isr_cnt++;

@@ -220,9 +213,6 @@ qla2300_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
		spin_unlock_irqrestore(&ha->mbx_reg_lock, flags);
	}

	if (!list_empty(&ha->done_queue))
		qla2x00_done(ha);

	return (IRQ_HANDLED);
}

@@ -714,7 +704,7 @@ qla2x00_process_completed_request(struct scsi_qla_host *ha, uint32_t index)
		/* Save ISP completion status */
		sp->cmd->result = DID_OK << 16;
		sp->fo_retry_cnt = 0;
		add_to_done_queue(ha, sp);
		qla2x00_sp_compl(ha, sp);
	} else {
		DEBUG2(printk("scsi(%ld): Invalid ISP SCSI completion handle\n",
		    ha->host_no));
@@ -914,24 +904,6 @@ qla2x00_status_entry(scsi_qla_host_t *ha, sts_entry_t *pkt)
	tq = sp->tgt_queue;
	lq = sp->lun_queue;

	/*
	 * If loop is in transient state Report DID_BUS_BUSY
	 */
	if ((comp_status != CS_COMPLETE || scsi_status != 0)) {
		if (!(sp->flags & (SRB_IOCTL | SRB_TAPE)) &&
		    (atomic_read(&ha->loop_down_timer) ||
			atomic_read(&ha->loop_state) != LOOP_READY)) {

			DEBUG2(printk("scsi(%ld:%d:%d:%d): Loop Not Ready - "
			    "pid=%lx.\n",
			    ha->host_no, b, t, l, cp->serial_number));

			qla2x00_extend_timeout(cp, EXTEND_CMD_TIMEOUT);
			add_to_retry_queue(ha, sp);
			return;
		}
	}

	/* Check for any FCP transport errors. */
	if (scsi_status & SS_RESPONSE_INFO_LEN_VALID) {
		rsp_info_len = le16_to_cpu(pkt->rsp_info_len);
@@ -945,7 +917,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha, sts_entry_t *pkt)
			    pkt->rsp_info[6], pkt->rsp_info[7]));

			cp->result = DID_BUS_BUSY << 16;
			add_to_done_queue(ha, sp);
			qla2x00_sp_compl(ha, sp);
			return;
		}
	}
@@ -964,11 +936,6 @@ qla2x00_status_entry(scsi_qla_host_t *ha, sts_entry_t *pkt)
			cp->resid = resid;
			CMD_RESID_LEN(cp) = resid;
		}
		if (lscsi_status == SS_BUSY_CONDITION) {
			cp->result = DID_BUS_BUSY << 16 | lscsi_status;
			break;
		}

		cp->result = DID_OK << 16 | lscsi_status;

		if (lscsi_status != SS_CHECK_CONDITION)
@@ -1002,14 +969,6 @@ qla2x00_status_entry(scsi_qla_host_t *ha, sts_entry_t *pkt)
		if (sp->request_sense_length != 0)
			ha->status_srb = sp;

		if (!(sp->flags & (SRB_IOCTL | SRB_TAPE)) &&
		    qla2x00_check_sense(cp, lq) == QLA_SUCCESS) {
			/* Throw away status_cont if any */
			ha->status_srb = NULL;
			add_to_scsi_retry_queue(ha, sp);
			return;
		}

		DEBUG5(printk("%s(): Check condition Sense data, "
		    "scsi(%ld:%d:%d:%d) cmd=%p pid=%ld\n",
		    __func__, ha->host_no, b, t, l, cp,
@@ -1035,12 +994,6 @@ qla2x00_status_entry(scsi_qla_host_t *ha, sts_entry_t *pkt)
		 * Status.
		 */
		if (lscsi_status != 0) {
			if (lscsi_status == SS_BUSY_CONDITION) {
				cp->result = DID_BUS_BUSY << 16 |
				    lscsi_status;
				break;
			}

			cp->result = DID_OK << 16 | lscsi_status;

			if (lscsi_status != SS_CHECK_CONDITION)
@@ -1072,12 +1025,6 @@ qla2x00_status_entry(scsi_qla_host_t *ha, sts_entry_t *pkt)
			if (sp->request_sense_length != 0)
				ha->status_srb = sp;

			if (!(sp->flags & (SRB_IOCTL | SRB_TAPE)) &&
			    (qla2x00_check_sense(cp, lq) == QLA_SUCCESS)) {
				ha->status_srb = NULL;
				add_to_scsi_retry_queue(ha, sp);
				return;
			}
			DEBUG5(printk("%s(): Check condition Sense data, "
			    "scsi(%ld:%d:%d:%d) cmd=%p pid=%ld\n",
			    __func__, ha->host_no, b, t, l, cp,
@@ -1155,24 +1102,10 @@ qla2x00_status_entry(scsi_qla_host_t *ha, sts_entry_t *pkt)
		    ha->host_no, t, l, cp->serial_number, comp_status,
		    atomic_read(&fcport->state)));

		if ((sp->flags & (SRB_IOCTL | SRB_TAPE)) ||
		    atomic_read(&fcport->state) == FCS_DEVICE_DEAD) {
			cp->result = DID_NO_CONNECT << 16;
			if (atomic_read(&ha->loop_state) == LOOP_DOWN) 
				sp->err_id = SRB_ERR_LOOP;
			else
				sp->err_id = SRB_ERR_PORT;
			add_to_done_queue(ha, sp);
		} else {
			qla2x00_extend_timeout(cp, EXTEND_CMD_TIMEOUT);
			add_to_retry_queue(ha, sp);
		}

		cp->result = DID_BUS_BUSY << 16;
		if (atomic_read(&fcport->state) == FCS_ONLINE) {
			qla2x00_mark_device_lost(ha, fcport, 1);
		}

		return;
		break;

	case CS_RESET:
@@ -1180,13 +1113,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha, sts_entry_t *pkt)
		    "scsi(%ld): RESET status detected 0x%x-0x%x.\n",
		    ha->host_no, comp_status, scsi_status));

		if (sp->flags & (SRB_IOCTL | SRB_TAPE)) {
		cp->result = DID_RESET << 16;
		} else {
			qla2x00_extend_timeout(cp, EXTEND_CMD_TIMEOUT);
			add_to_retry_queue(ha, sp);
			return;
		}
		break;

	case CS_ABORTED:
@@ -1253,7 +1180,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha, sts_entry_t *pkt)

	/* Place command on done queue. */
	if (ha->status_srb == NULL)
		add_to_done_queue(ha, sp);
		qla2x00_sp_compl(ha, sp);
}

/**
@@ -1298,8 +1225,8 @@ qla2x00_status_cont_entry(scsi_qla_host_t *ha, sts_cont_entry_t *pkt)

		/* Place command on done queue. */
		if (sp->request_sense_length == 0) {
			add_to_done_queue(ha, sp);
			ha->status_srb = NULL;
			qla2x00_sp_compl(ha, sp);
		}
	}
}
@@ -1353,8 +1280,7 @@ qla2x00_error_entry(scsi_qla_host_t *ha, sts_entry_t *pkt)
		} else {
			sp->cmd->result = DID_ERROR << 16;
		}
		/* Place command on done queue. */
		add_to_done_queue(ha, sp);
		qla2x00_sp_compl(ha, sp);

	} else if (pkt->entry_type == COMMAND_A64_TYPE ||
	    pkt->entry_type == COMMAND_TYPE) {
@@ -1403,62 +1329,5 @@ qla2x00_ms_entry(scsi_qla_host_t *ha, ms_iocb_entry_t *pkt)
	/* Free outstanding command slot. */
	ha->outstanding_cmds[pkt->handle1] = NULL;

	add_to_done_queue(ha, sp);
}

/**
 * qla2x00_check_sense() - Perform any sense data interrogation.
 * @cp: SCSI Command
 * @lq: Lun queue
 *
 * Returns QLA_SUCCESS if the lun queue is suspended, else
 * QLA_FUNCTION_FAILED  (lun queue not suspended).
 */
static int 
qla2x00_check_sense(struct scsi_cmnd *cp, os_lun_t *lq)
{
	scsi_qla_host_t	*ha;
	srb_t		*sp;
	fc_port_t	*fcport;

	ha = (scsi_qla_host_t *) cp->device->host->hostdata;
	if ((cp->sense_buffer[0] & 0x70) != 0x70) {
		return (QLA_FUNCTION_FAILED);
	}

	sp = (srb_t * )CMD_SP(cp);
	sp->flags |= SRB_GOT_SENSE;

	switch (cp->sense_buffer[2] & 0xf) {
	case RECOVERED_ERROR:
		cp->result = DID_OK << 16;
		cp->sense_buffer[0] = 0;
		break;

	case NOT_READY:
		fcport = lq->fclun->fcport;

		/*
		 * Suspend the lun only for hard disk device type.
		 */
		if ((fcport->flags & FCF_TAPE_PRESENT) == 0 &&
		    lq->q_state != LUN_STATE_TIMEOUT) {
			/*
			 * If target is in process of being ready then suspend
			 * lun for 6 secs and retry all the commands.
			 */
			if (cp->sense_buffer[12] == 0x4 &&
			    cp->sense_buffer[13] == 0x1) {

				/* Suspend the lun for 6 secs */
				qla2x00_suspend_lun(ha, lq, 6,
				    ql2xsuspendcount);

				return (QLA_SUCCESS);
			}
		}
		break;
	}

	return (QLA_FUNCTION_FAILED);
	qla2x00_sp_compl(ha, sp);
}
Loading