]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
qla2xxx: Handle device mapping changes due to device logout.
authorArun Easi <arun.easi@qlogic.com>
Wed, 11 Apr 2012 06:55:38 +0000 (12:25 +0530)
committerMaxim Uvarov <maxim.uvarov@oracle.com>
Wed, 9 May 2012 00:40:59 +0000 (17:40 -0700)
A device logout sent in the delete path of a fcport would clear the
port handle binding inside the firmware. This could lead to queued
work items for the fcport, if any, getting incorrect results. This
patch fixes the issue by checking for device name changes after a
call to get port database.

JIRA Key: V2632FC-131

Signed-off-by: Saurav Kashyap <saurav.kashyap@qlogic.com>
drivers/scsi/qla2xxx/qla_init.c
drivers/scsi/qla2xxx/qla_mbx.c

index 2d9b5cb4577a929014d6cd3f45028cc1ff33f77b..72d81b52c4df15d51b0a8def80cfc93af1ebdc28 100644 (file)
@@ -349,6 +349,13 @@ qla2x00_async_login_done(struct scsi_qla_host *vha, fc_port_t *fcport,
                 * requests.
                 */
                rval = qla2x00_get_port_database(vha, fcport, 0);
+               if (rval == QLA_NOT_LOGGED_IN) {
+                       fcport->flags &= ~FCF_ASYNC_SENT;
+                       fcport->flags |= FCF_LOGIN_NEEDED;
+                       set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
+                       break;
+               }
+
                if (rval != QLA_SUCCESS) {
                        qla2x00_post_async_logout_work(vha, fcport, NULL);
                        qla2x00_post_async_login_work(vha, fcport, NULL);
@@ -3326,6 +3333,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha,
                        fcport->flags |= FCF_LOGIN_NEEDED;
                        if (fcport->loop_id != FC_NO_LOOP_ID &&
                            (fcport->flags & FCF_FCP2_DEVICE) == 0 &&
+                           (fcport->flags & FCF_ASYNC_SENT) == 0 &&
                            fcport->port_type != FCT_INITIATOR &&
                            fcport->port_type != FCT_BROADCAST) {
                                ha->isp_ops->fabric_logout(vha, fcport->loop_id,
index 7fdd3c1e99104b1db57c151cce9675f3ac625e92..5dba6e6a05efedf0d2806623065e86adefcc1241 100644 (file)
@@ -1285,6 +1285,7 @@ qla2x00_get_port_database(scsi_qla_host_t *vha, fc_port_t *fcport, uint8_t opt)
                goto gpd_error_out;
 
        if (IS_FWI2_CAPABLE(ha)) {
+               uint64_t zero = 0;
                pd24 = (struct port_database_24xx *) pd;
 
                /* Check for logged in state. */
@@ -1298,6 +1299,14 @@ qla2x00_get_port_database(scsi_qla_host_t *vha, fc_port_t *fcport, uint8_t opt)
                        goto gpd_error_out;
                }
 
+               if (fcport->loop_id == FC_NO_LOOP_ID ||
+                   (memcmp(fcport->port_name, (uint8_t *)&zero, 8) &&
+                    memcmp(fcport->port_name, pd24->port_name, 8))) {
+                       /* We lost the device mid way. */
+                       rval = QLA_NOT_LOGGED_IN;
+                       goto gpd_error_out;
+               }
+
                /* Names are little-endian. */
                memcpy(fcport->node_name, pd24->node_name, WWN_SIZE);
                memcpy(fcport->port_name, pd24->port_name, WWN_SIZE);
@@ -1314,6 +1323,8 @@ qla2x00_get_port_database(scsi_qla_host_t *vha, fc_port_t *fcport, uint8_t opt)
                else
                        fcport->port_type = FCT_TARGET;
        } else {
+               uint64_t zero = 0;
+
                /* Check for logged in state. */
                if (pd->master_state != PD_STATE_PORT_LOGGED_IN &&
                    pd->slave_state != PD_STATE_PORT_LOGGED_IN) {
@@ -1326,6 +1337,14 @@ qla2x00_get_port_database(scsi_qla_host_t *vha, fc_port_t *fcport, uint8_t opt)
                        goto gpd_error_out;
                }
 
+               if (fcport->loop_id == FC_NO_LOOP_ID ||
+                   (memcmp(fcport->port_name, (uint8_t *)&zero, 8) &&
+                    memcmp(fcport->port_name, pd->port_name, 8))) {
+                       /* We lost the device mid way. */
+                       rval = QLA_NOT_LOGGED_IN;
+                       goto gpd_error_out;
+               }
+
                /* Names are little-endian. */
                memcpy(fcport->node_name, pd->node_name, WWN_SIZE);
                memcpy(fcport->port_name, pd->port_name, WWN_SIZE);