[SCSI] qla2xxx: Correct rport/fcport visibility-state handling during loop-resync.
authorSeokmann Ju <seokmann.ju@qlogic.com>
Thu, 10 Jul 2008 23:55:58 +0000 (16:55 -0700)
committerJames Bottomley <James.Bottomley@HansenPartnership.com>
Sat, 26 Jul 2008 19:14:44 +0000 (15:14 -0400)
There were several issues here, one, during RSCN handling if a
follow-on RSCN occurred (within interrupt context) the DPC thread
could inadvertantly leave the fcport in a stale lost state.
Secondly, scheduled rport removal is handled exclusively by the
'parent' DPC thread, so wake up the proper thread.  Finally,
process vport loop-resync's only when the vport has in an
"active" state (ID acquired).

Signed-off-by: Seokmann Ju <seokmann.ju@qlogic.com>
Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
drivers/scsi/qla2xxx/qla_init.c
drivers/scsi/qla2xxx/qla_mid.c
drivers/scsi/qla2xxx/qla_os.c

index 4c83ff81d79b792113091b20c5168dab174b6915..f8cfeb0e91a6b6fa48753d9e4c6819644efb33e7 100644 (file)
@@ -2012,8 +2012,10 @@ qla2x00_configure_loop(scsi_qla_host_t *ha)
        if (test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags)) {
                if (test_bit(LOCAL_LOOP_UPDATE, &save_flags))
                        set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags);
-               if (test_bit(RSCN_UPDATE, &save_flags))
+               if (test_bit(RSCN_UPDATE, &save_flags)) {
+                       ha->flags.rscn_queue_overflow = 1;
                        set_bit(RSCN_UPDATE, &ha->dpc_flags);
+               }
        }
 
        return (rval);
index e7565765fa14dd558064467f83900d5820560864..9a850a24b38a9b2189a5918e5aa33c2bc156cac1 100644 (file)
@@ -277,7 +277,8 @@ qla2x00_do_dpc_vp(scsi_qla_host_t *vha)
                clear_bit(RESET_ACTIVE, &vha->dpc_flags);
        }
 
-       if (test_and_clear_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags)) {
+       if (atomic_read(&vha->vp_state) == VP_ACTIVE &&
+           test_and_clear_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags)) {
                if (!(test_and_set_bit(LOOP_RESYNC_ACTIVE, &vha->dpc_flags))) {
                        qla2x00_loop_resync(vha);
                        clear_bit(LOOP_RESYNC_ACTIVE, &vha->dpc_flags);
index 3f391698e1ce106c220014fd227d3b4d08d7aa97..0f44914b41d7bdf5fa6932015e5b0a92acf8c7bd 100644 (file)
@@ -1849,6 +1849,7 @@ qla2x00_schedule_rport_del(struct scsi_qla_host *ha, fc_port_t *fcport,
     int defer)
 {
        struct fc_rport *rport;
+       scsi_qla_host_t *pha = to_qla_parent(ha);
 
        if (!fcport->rport)
                return;
@@ -1858,8 +1859,8 @@ qla2x00_schedule_rport_del(struct scsi_qla_host *ha, fc_port_t *fcport,
                spin_lock_irq(ha->host->host_lock);
                fcport->drport = rport;
                spin_unlock_irq(ha->host->host_lock);
-               set_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags);
-               qla2xxx_wake_dpc(ha);
+               set_bit(FCPORT_UPDATE_NEEDED, &pha->dpc_flags);
+               qla2xxx_wake_dpc(pha);
        } else
                fc_remote_port_delete(rport);
 }