mirror of https://gitee.com/openkylin/linux.git
[SCSI] qla2xxx: Handle device mapping changes due to device logout.
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>
This commit is contained in:
parent
642ef98386
commit
0eba25df21
|
@ -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);
|
||||
|
@ -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,
|
||||
|
|
|
@ -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. */
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue