aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx
diff options
context:
space:
mode:
authorArun Easi <arun.easi@qlogic.com>2012-02-09 14:15:58 -0500
committerJames Bottomley <JBottomley@Parallels.com>2012-02-19 09:33:48 -0500
commit0eba25df2190f191cb92879b225a0e484c3e5b51 (patch)
tree72260202ee80e498b939e61dd7bdbb8c9f4b9f24 /drivers/scsi/qla2xxx
parent642ef983861a6a7ba41e9d7c0aa4da8f6d5af5bf (diff)
[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>
Diffstat (limited to 'drivers/scsi/qla2xxx')
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c8
-rw-r--r--drivers/scsi/qla2xxx/qla_mbx.c19
2 files changed, 27 insertions, 0 deletions
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 2627c87a4a34..b9465643396b 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -350,6 +350,13 @@ qla2x00_async_login_done(struct scsi_qla_host *vha, fc_port_t *fcport,
350 * requests. 350 * requests.
351 */ 351 */
352 rval = qla2x00_get_port_database(vha, fcport, 0); 352 rval = qla2x00_get_port_database(vha, fcport, 0);
353 if (rval == QLA_NOT_LOGGED_IN) {
354 fcport->flags &= ~FCF_ASYNC_SENT;
355 fcport->flags |= FCF_LOGIN_NEEDED;
356 set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
357 break;
358 }
359
353 if (rval != QLA_SUCCESS) { 360 if (rval != QLA_SUCCESS) {
354 qla2x00_post_async_logout_work(vha, fcport, NULL); 361 qla2x00_post_async_logout_work(vha, fcport, NULL);
355 qla2x00_post_async_login_work(vha, fcport, NULL); 362 qla2x00_post_async_login_work(vha, fcport, NULL);
@@ -3318,6 +3325,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha,
3318 fcport->flags |= FCF_LOGIN_NEEDED; 3325 fcport->flags |= FCF_LOGIN_NEEDED;
3319 if (fcport->loop_id != FC_NO_LOOP_ID && 3326 if (fcport->loop_id != FC_NO_LOOP_ID &&
3320 (fcport->flags & FCF_FCP2_DEVICE) == 0 && 3327 (fcport->flags & FCF_FCP2_DEVICE) == 0 &&
3328 (fcport->flags & FCF_ASYNC_SENT) == 0 &&
3321 fcport->port_type != FCT_INITIATOR && 3329 fcport->port_type != FCT_INITIATOR &&
3322 fcport->port_type != FCT_BROADCAST) { 3330 fcport->port_type != FCT_BROADCAST) {
3323 ha->isp_ops->fabric_logout(vha, fcport->loop_id, 3331 ha->isp_ops->fabric_logout(vha, fcport->loop_id,
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index adc2b14b03f5..b4a23394a7bd 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -1289,6 +1289,7 @@ qla2x00_get_port_database(scsi_qla_host_t *vha, fc_port_t *fcport, uint8_t opt)
1289 goto gpd_error_out; 1289 goto gpd_error_out;
1290 1290
1291 if (IS_FWI2_CAPABLE(ha)) { 1291 if (IS_FWI2_CAPABLE(ha)) {
1292 uint64_t zero = 0;
1292 pd24 = (struct port_database_24xx *) pd; 1293 pd24 = (struct port_database_24xx *) pd;
1293 1294
1294 /* Check for logged in state. */ 1295 /* 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)
1302 goto gpd_error_out; 1303 goto gpd_error_out;
1303 } 1304 }
1304 1305
1306 if (fcport->loop_id == FC_NO_LOOP_ID ||
1307 (memcmp(fcport->port_name, (uint8_t *)&zero, 8) &&
1308 memcmp(fcport->port_name, pd24->port_name, 8))) {
1309 /* We lost the device mid way. */
1310 rval = QLA_NOT_LOGGED_IN;
1311 goto gpd_error_out;
1312 }
1313
1305 /* Names are little-endian. */ 1314 /* Names are little-endian. */
1306 memcpy(fcport->node_name, pd24->node_name, WWN_SIZE); 1315 memcpy(fcport->node_name, pd24->node_name, WWN_SIZE);
1307 memcpy(fcport->port_name, pd24->port_name, WWN_SIZE); 1316 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)
1318 else 1327 else
1319 fcport->port_type = FCT_TARGET; 1328 fcport->port_type = FCT_TARGET;
1320 } else { 1329 } else {
1330 uint64_t zero = 0;
1331
1321 /* Check for logged in state. */ 1332 /* Check for logged in state. */
1322 if (pd->master_state != PD_STATE_PORT_LOGGED_IN && 1333 if (pd->master_state != PD_STATE_PORT_LOGGED_IN &&
1323 pd->slave_state != PD_STATE_PORT_LOGGED_IN) { 1334 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)
1330 goto gpd_error_out; 1341 goto gpd_error_out;
1331 } 1342 }
1332 1343
1344 if (fcport->loop_id == FC_NO_LOOP_ID ||
1345 (memcmp(fcport->port_name, (uint8_t *)&zero, 8) &&
1346 memcmp(fcport->port_name, pd->port_name, 8))) {
1347 /* We lost the device mid way. */
1348 rval = QLA_NOT_LOGGED_IN;
1349 goto gpd_error_out;
1350 }
1351
1333 /* Names are little-endian. */ 1352 /* Names are little-endian. */
1334 memcpy(fcport->node_name, pd->node_name, WWN_SIZE); 1353 memcpy(fcport->node_name, pd->node_name, WWN_SIZE);
1335 memcpy(fcport->port_name, pd->port_name, WWN_SIZE); 1354 memcpy(fcport->port_name, pd->port_name, WWN_SIZE);