Skip to content

Commit

Permalink
[SCSI] qla2xxx: Handle device mapping changes due to device logout.
Browse files Browse the repository at this point in the history
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.

Signed-off-by: Arun Easi <arun.easi@qlogic.com>
Signed-off-by: Chad Dupuis <chad.dupuis@qlogic.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
  • Loading branch information
Arun Easi authored and James Bottomley committed Feb 19, 2012
1 parent 642ef98 commit 0eba25d
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 0 deletions.
8 changes: 8 additions & 0 deletions drivers/scsi/qla2xxx/qla_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,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);
Expand Down Expand Up @@ -3318,6 +3325,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,
Expand Down
19 changes: 19 additions & 0 deletions drivers/scsi/qla2xxx/qla_mbx.c
Original file line number Diff line number Diff line change
Expand Up @@ -1289,6 +1289,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. */
Expand All @@ -1302,6 +1303,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);
Expand All @@ -1318,6 +1327,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) {
Expand All @@ -1330,6 +1341,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);
Expand Down

0 comments on commit 0eba25d

Please sign in to comment.