[SCSI] qla2xxx: Verify login-state has transitioned to PRLI-completed.
authorAndrew Vasquez <andrew.vasquez@qlogic.com>
Wed, 30 Mar 2011 18:46:31 +0000 (11:46 -0700)
committerJames Bottomley <James.Bottomley@suse.de>
Sun, 1 May 2011 15:14:17 +0000 (10:14 -0500)
Before driver's own internal state is marked as PLOGI/PRLI
complete. This additional check closes a window seen with
dual-personality initiator/target devices where a driver's
PLOGI/PRLI request occurs within the window after the target's
PLOGI request has completed, but prior to the target's PRLI
arriving and processed by the firmware. Without this additional
check, the firmware will return port-information stating that the
port neither supports target nor initiator functions, causing the
driver to register the rport prematurely to the FC-transport
without the proper 'roles' being set.

Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com>
Signed-off-by: Giridhar Malavali <giridhar.malavali@qlogic.com>
Signed-off-by: Madhuranath Iyengar <Madhu.Iyengar@qlogic.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
drivers/scsi/qla2xxx/qla_init.c
drivers/scsi/qla2xxx/qla_mbx.c

index 234c1c28bf4430c62d64dbd8ac227345a9c17441..d31ac9bd81d98856f76676dd58dd55270f63854e 100644 (file)
@@ -383,6 +383,17 @@ qla2x00_async_login_done(struct scsi_qla_host *vha, fc_port_t *fcport,
 
        switch (data[0]) {
        case MBS_COMMAND_COMPLETE:
+               /*
+                * Driver must validate login state - If PRLI not complete,
+                * force a relogin attempt via implicit LOGO, PLOGI, and PRLI
+                * requests.
+                */
+               rval = qla2x00_get_port_database(vha, fcport, 0);
+               if (rval != QLA_SUCCESS) {
+                       qla2x00_post_async_logout_work(vha, fcport, NULL);
+                       qla2x00_post_async_login_work(vha, fcport, NULL);
+                       break;
+               }
                if (fcport->flags & FCF_FCP2_DEVICE) {
                        qla2x00_post_async_adisc_work(vha, fcport, data);
                        break;
index 32b689061ea7709225e72d61ffe91a9f98964773..975aeaae297aa10c8d9bb1ca61577f02eb0b10ad 100644 (file)
@@ -1261,11 +1261,12 @@ qla2x00_get_port_database(scsi_qla_host_t *vha, fc_port_t *fcport, uint8_t opt)
                /* Check for logged in state. */
                if (pd24->current_login_state != PDS_PRLI_COMPLETE &&
                    pd24->last_login_state != PDS_PRLI_COMPLETE) {
-                       DEBUG2(printk("%s(%ld): Unable to verify "
-                           "login-state (%x/%x) for loop_id %x\n",
-                           __func__, vha->host_no,
-                           pd24->current_login_state,
-                           pd24->last_login_state, fcport->loop_id));
+                       DEBUG2(qla_printk(KERN_WARNING, ha,
+                          "scsi(%ld): Unable to verify login-state (%x/%x) "
+                          " - portid=%02x%02x%02x.\n", vha->host_no,
+                          pd24->current_login_state, pd24->last_login_state,
+                          fcport->d_id.b.domain, fcport->d_id.b.area,
+                          fcport->d_id.b.al_pa));
                        rval = QLA_FUNCTION_FAILED;
                        goto gpd_error_out;
                }
@@ -1289,6 +1290,12 @@ qla2x00_get_port_database(scsi_qla_host_t *vha, fc_port_t *fcport, uint8_t opt)
                /* Check for logged in state. */
                if (pd->master_state != PD_STATE_PORT_LOGGED_IN &&
                    pd->slave_state != PD_STATE_PORT_LOGGED_IN) {
+                       DEBUG2(qla_printk(KERN_WARNING, ha,
+                          "scsi(%ld): Unable to verify login-state (%x/%x) "
+                          " - portid=%02x%02x%02x.\n", vha->host_no,
+                          pd->master_state, pd->slave_state,
+                          fcport->d_id.b.domain, fcport->d_id.b.area,
+                          fcport->d_id.b.al_pa));
                        rval = QLA_FUNCTION_FAILED;
                        goto gpd_error_out;
                }