aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorandrew.vasquez@qlogic.com <andrew.vasquez@qlogic.com>2006-02-07 11:45:45 -0500
committer <jejb@mulgrave.il.steeleye.com>2006-02-07 11:53:56 -0500
commit387f96b4d9391bf3ce6928fb9cd90c9c7df37291 (patch)
treeb2c1af3552d6cd98d67913be741f50a5d76cd9a2 /drivers/scsi
parent62288f105b3cad0b8643526d2a41b5503d0a1476 (diff)
[PATCH] qla2xxx: Close window on race between rport removal and fcport transition.
Fcport visibility is recognized during interrupt time, but, rport removal can only occur during a process (sleeping)-context. Return a DID_IMM_RETRY status for commands submitted within this window to insure I/Os do not prematurely run-out of retries. Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 495ccbc7f8cb..9b5a10ac3e25 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -366,6 +366,12 @@ qla2x00_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
366 goto qc_fail_command; 366 goto qc_fail_command;
367 } 367 }
368 368
369 /* Close window on fcport/rport state-transitioning. */
370 if (!*(fc_port_t **)rport->dd_data) {
371 cmd->result = DID_IMM_RETRY << 16;
372 goto qc_fail_command;
373 }
374
369 if (atomic_read(&fcport->state) != FCS_ONLINE) { 375 if (atomic_read(&fcport->state) != FCS_ONLINE) {
370 if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD || 376 if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD ||
371 atomic_read(&ha->loop_state) == LOOP_DEAD) { 377 atomic_read(&ha->loop_state) == LOOP_DEAD) {
@@ -421,6 +427,12 @@ qla24xx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
421 goto qc24_fail_command; 427 goto qc24_fail_command;
422 } 428 }
423 429
430 /* Close window on fcport/rport state-transitioning. */
431 if (!*(fc_port_t **)rport->dd_data) {
432 cmd->result = DID_IMM_RETRY << 16;
433 goto qc24_fail_command;
434 }
435
424 if (atomic_read(&fcport->state) != FCS_ONLINE) { 436 if (atomic_read(&fcport->state) != FCS_ONLINE) {
425 if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD || 437 if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD ||
426 atomic_read(&ha->loop_state) == LOOP_DEAD) { 438 atomic_read(&ha->loop_state) == LOOP_DEAD) {
@@ -1675,11 +1687,13 @@ qla2x00_schedule_rport_del(struct scsi_qla_host *ha, fc_port_t *fcport,
1675 spin_lock_irqsave(&fcport->rport_lock, flags); 1687 spin_lock_irqsave(&fcport->rport_lock, flags);
1676 fcport->drport = rport; 1688 fcport->drport = rport;
1677 fcport->rport = NULL; 1689 fcport->rport = NULL;
1690 *(fc_port_t **)rport->dd_data = NULL;
1678 spin_unlock_irqrestore(&fcport->rport_lock, flags); 1691 spin_unlock_irqrestore(&fcport->rport_lock, flags);
1679 set_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags); 1692 set_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags);
1680 } else { 1693 } else {
1681 spin_lock_irqsave(&fcport->rport_lock, flags); 1694 spin_lock_irqsave(&fcport->rport_lock, flags);
1682 fcport->rport = NULL; 1695 fcport->rport = NULL;
1696 *(fc_port_t **)rport->dd_data = NULL;
1683 spin_unlock_irqrestore(&fcport->rport_lock, flags); 1697 spin_unlock_irqrestore(&fcport->rport_lock, flags);
1684 fc_remote_port_delete(rport); 1698 fc_remote_port_delete(rport);
1685 } 1699 }