* PATCH [9/15] qla2xxx: Tape command handling fixes
@ 2004-05-07 5:55 Andrew Vasquez
0 siblings, 0 replies; only message in thread
From: Andrew Vasquez @ 2004-05-07 5:55 UTC (permalink / raw)
To: SCSI Mailing List, James Bottomley
ChangeSet
1.1930 04/04/30 14:01:16 andrew.vasquez@apc.qlogic.com +4 -0
Fix several problems when handling commands issued to tape devices:
1) insure commands are not prematurely returned to the mid-layer
with a failed status during loop/fabric transitions.
2) tape commands tend to have rather 'long' timeout values,
unfortunately, as the these values increase into the 17 to
20 minute range (and larger), the cumulative skew of the
RISC's own timer result in commands being held for seconds
beyond their defined timeout values. Compensate for this
in the driver's command timeout function.
drivers/scsi/qla2xxx/qla_def.h | 3 +
drivers/scsi/qla2xxx/qla_init.c | 4 ++
drivers/scsi/qla2xxx/qla_isr.c | 10 ++---
drivers/scsi/qla2xxx/qla_os.c | 74 ++++++++++++++++++++++++++++++++++++----
4 files changed, 79 insertions(+), 12 deletions(-)
diff -Nru a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
--- a/drivers/scsi/qla2xxx/qla_def.h Mon May 3 15:15:19 2004
+++ b/drivers/scsi/qla2xxx/qla_def.h Mon May 3 15:15:19 2004
@@ -285,7 +285,8 @@
#define SRB_BUSY BIT_8 /* Command is in busy retry state */
#define SRB_FO_CANCEL BIT_9 /* Command don't need to do failover */
-#define SRB_IOCTL BIT_10 /* IOCTL command. */
+#define SRB_IOCTL BIT_10 /* IOCTL command. */
+#define SRB_TAPE BIT_11 /* FCP2 (Tape) command. */
/*
* SRB state definitions
diff -Nru a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
--- a/drivers/scsi/qla2xxx/qla_init.c Mon May 3 15:15:19 2004
+++ b/drivers/scsi/qla2xxx/qla_init.c Mon May 3 15:15:19 2004
@@ -3140,6 +3140,10 @@
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
*/
diff -Nru a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
--- a/drivers/scsi/qla2xxx/qla_isr.c Mon May 3 15:15:19 2004
+++ b/drivers/scsi/qla2xxx/qla_isr.c Mon May 3 15:15:19 2004
@@ -907,7 +907,7 @@
* If loop is in transient state Report DID_BUS_BUSY
*/
if ((comp_status != CS_COMPLETE || scsi_status != 0)) {
- if (!(sp->flags & SRB_IOCTL) &&
+ if (!(sp->flags & (SRB_IOCTL | SRB_TAPE)) &&
(atomic_read(&ha->loop_down_timer) ||
atomic_read(&ha->loop_state) != LOOP_READY)) {
@@ -986,7 +986,7 @@
if (sp->request_sense_length != 0)
ha->status_srb = sp;
- if (!(sp->flags & SRB_IOCTL) &&
+ if (!(sp->flags & (SRB_IOCTL | SRB_TAPE)) &&
qla2x00_check_sense(cp, lq) == QLA_SUCCESS) {
/* Throw away status_cont if any */
ha->status_srb = NULL;
@@ -1053,7 +1053,7 @@
if (sp->request_sense_length != 0)
ha->status_srb = sp;
- if (!(sp->flags & SRB_IOCTL) &&
+ 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);
@@ -1137,7 +1137,7 @@
ha->host_no, t, l, cp->serial_number, comp_status,
atomic_read(&fcport->state)));
- if ((sp->flags & SRB_IOCTL) ||
+ 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)
@@ -1162,7 +1162,7 @@
"scsi(%ld): RESET status detected 0x%x-0x%x.\n",
ha->host_no, comp_status, scsi_status));
- if (sp->flags & SRB_IOCTL) {
+ if (sp->flags & (SRB_IOCTL | SRB_TAPE)) {
cp->result = DID_RESET << 16;
} else {
qla2x00_extend_timeout(cp, EXTEND_CMD_TIMEOUT);
diff -Nru a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
--- a/drivers/scsi/qla2xxx/qla_os.c Mon May 3 15:15:19 2004
+++ b/drivers/scsi/qla2xxx/qla_os.c Mon May 3 15:15:19 2004
@@ -775,10 +775,13 @@
/* Only modify the allowed count if the target is a *non* tape device */
if ((fcport->flags & FCF_TAPE_PRESENT) == 0) {
+ sp->flags &= ~SRB_TAPE;
if (cmd->allowed < ql2xretrycount) {
cmd->allowed = ql2xretrycount;
}
- }
+ } else
+ sp->flags |= SRB_TAPE;
+
DEBUG5(printk("scsi(%ld:%2d:%2d): (queuecmd) queue sp = %p, "
"flags=0x%x fo retry=%d, pid=%ld\n",
@@ -821,7 +824,8 @@
spin_lock_irq(ha->host->host_lock);
return (0);
}
- if (tq && test_bit(TQF_SUSPENDED, &tq->flags)) {
+ if (tq && test_bit(TQF_SUSPENDED, &tq->flags) &&
+ (sp->flags & SRB_TAPE) == 0) {
/* If target suspended put incoming I/O in retry_q. */
qla2x00_extend_timeout(sp->cmd, 10);
add_to_scsi_retry_queue(ha, sp);
@@ -3943,8 +3947,8 @@
int processed;
scsi_qla_host_t *vis_ha, *dest_ha;
struct scsi_cmnd *cmd;
- ulong flags;
- fc_port_t *fcport;
+ unsigned long flags, cpu_flags;
+ fc_port_t *fcport;
cmd = sp->cmd;
vis_ha = (scsi_qla_host_t *)cmd->device->host->hostdata;
@@ -4039,6 +4043,64 @@
return;
}
+ spin_lock_irqsave(&dest_ha->list_lock, cpu_flags);
+ if (sp->state == SRB_DONE_STATE) {
+ /* IO in done_q -- leave it */
+ DEBUG(printk("scsi(%ld): Found in Done queue pid %ld sp=%p.\n",
+ dest_ha->host_no, cmd->serial_number, sp));
+ } else if (sp->state == SRB_SUSPENDED_STATE) {
+ DEBUG(printk("scsi(%ld): Found SP %p in suspended state "
+ "- pid %ld:\n",
+ dest_ha->host_no, sp, cmd->serial_number));
+ DEBUG(qla2x00_dump_buffer((uint8_t *)sp, sizeof(srb_t));)
+ } else if (sp->state == SRB_ACTIVE_STATE) {
+ /*
+ * IO is with ISP find the command in our active list.
+ */
+ spin_unlock_irqrestore(&dest_ha->list_lock, cpu_flags);
+ spin_lock_irqsave(&dest_ha->hardware_lock, flags);
+ if (sp == dest_ha->outstanding_cmds[
+ (unsigned long)sp->cmd->host_scribble]) {
+
+ DEBUG(printk("cmd_timeout: Found in ISP \n"));
+
+ if (sp->flags & SRB_TAPE) {
+ /*
+ * We cannot allow the midlayer error handler
+ * to wakeup and begin the abort process.
+ * Extend the timer so that the firmware can
+ * properly return the IOCB.
+ */
+ DEBUG(printk("cmd_timeout: Extending timeout "
+ "of FCP2 tape command!\n"));
+ qla2x00_extend_timeout(sp->cmd,
+ EXTEND_CMD_TIMEOUT);
+ }
+ sp->state = SRB_ACTIVE_TIMEOUT_STATE;
+ spin_unlock_irqrestore(&dest_ha->hardware_lock, flags);
+ } else {
+ spin_unlock_irqrestore(&dest_ha->hardware_lock, flags);
+ printk(KERN_INFO
+ "qla_cmd_timeout: State indicates it is with "
+ "ISP, But not in active array\n");
+ }
+ spin_lock_irqsave(&dest_ha->list_lock, cpu_flags);
+ } else if (sp->state == SRB_ACTIVE_TIMEOUT_STATE) {
+ DEBUG(printk("qla2100%ld: Found in Active timeout state"
+ "pid %ld, State = %x., \n",
+ dest_ha->host_no,
+ sp->cmd->serial_number, sp->state);)
+ } else {
+ /* EMPTY */
+ DEBUG2(printk("cmd_timeout%ld: LOST command state = "
+ "0x%x, sp=%p\n",
+ vis_ha->host_no, sp->state,sp);)
+
+ qla_printk(KERN_INFO, vis_ha,
+ "cmd_timeout: LOST command state = 0x%x\n", sp->state);
+ }
+ spin_unlock_irqrestore(&dest_ha->list_lock, cpu_flags);
+
DEBUG3(printk("cmd_timeout: Leaving\n");)
}
@@ -4268,7 +4330,7 @@
* continues until the LOOP DOWN time expires or the condition
* goes away.
*/
- if (!(sp->flags & SRB_IOCTL) &&
+ if (!(sp->flags & (SRB_IOCTL | SRB_TAPE)) &&
(atomic_read(&fcport->state) != FCS_ONLINE ||
test_bit(ABORT_ISP_ACTIVE, &dest_ha->dpc_flags) ||
atomic_read(&dest_ha->loop_state) != LOOP_READY)) {
@@ -4293,7 +4355,7 @@
* If this request's lun is suspended then put the request on
* the scsi_retry queue.
*/
- if (!(sp->flags & SRB_IOCTL) &&
+ if (!(sp->flags & (SRB_IOCTL | SRB_TAPE)) &&
sp->lun_queue->q_state == LUN_STATE_WAIT) {
DEBUG3(printk("scsi(%ld): lun wait state - pid=%ld, "
"opcode=%d, allowed=%d, retries=%d\n",
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2004-05-07 5:53 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-05-07 5:55 PATCH [9/15] qla2xxx: Tape command handling fixes Andrew Vasquez
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox