Skip to content

Commit 065aa1b

Browse files
Vikas ChaudharyJames Bottomley
authored andcommitted
[SCSI] qla4xxx: set device state as per Link UP and LINK DOWN
Link Down -> Mark all devices missing Previously, the driver took no action on a Link Down, and waited for the I/O on a dead connection to timeout in the firmware before marking the DDB missing. Link Up -> Mark all devices online F/W will do auto login to all the devices only once. After that its the responsibility of the driver to relogin to devices whenever there is : * Any sort of connection failure or * KATO expires indicating target has logged out or * I/O times out etc. Signed-off-by: Vikas Chaudhary <vikas.chaudhary@qlogic.com> Signed-off-by: Karen Higgins <karen.higgins@qlogic.com> Signed-off-by: Ravi Anand <ravi.anand@qlogic.com> Reviewed-by: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
1 parent 2a49a78 commit 065aa1b

File tree

4 files changed

+70
-7
lines changed

4 files changed

+70
-7
lines changed

drivers/scsi/qla4xxx/ql4_def.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,7 @@ struct scsi_qla_host {
310310
#define DPC_ISNS_RESTART 7 /* 0x00000080 */
311311
#define DPC_AEN 9 /* 0x00000200 */
312312
#define DPC_GET_DHCP_IP_ADDR 15 /* 0x00008000 */
313+
#define DPC_LINK_CHANGED 18 /* 0x00040000 */
313314

314315
struct Scsi_Host *host; /* pointer to host data */
315316
uint32_t tot_ddbs;

drivers/scsi/qla4xxx/ql4_init.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1279,6 +1279,7 @@ int qla4xxx_initialize_adapter(struct scsi_qla_host *ha,
12791279
int status = QLA_ERROR;
12801280
int8_t ip_address[IP_ADDR_LEN] = {0} ;
12811281

1282+
clear_bit(AF_ONLINE, &ha->flags);
12821283
ha->eeprom_cmd_data = 0;
12831284

12841285
qla4x00_pci_config(ha);
@@ -1456,10 +1457,15 @@ int qla4xxx_process_ddb_changed(struct scsi_qla_host *ha,
14561457
* the device came back.
14571458
*/
14581459
} else {
1459-
/* Device went away, try to relogin. */
1460-
/* Mark device missing */
1461-
if (atomic_read(&ddb_entry->state) == DDB_STATE_ONLINE)
1460+
/* Device went away, mark device missing */
1461+
if (atomic_read(&ddb_entry->state) == DDB_STATE_ONLINE) {
1462+
DEBUG2(dev_info(&ha->pdev->dev, "%s mark missing "
1463+
"ddb_entry 0x%p sess 0x%p conn 0x%p\n",
1464+
__func__, ddb_entry,
1465+
ddb_entry->sess, ddb_entry->conn));
14621466
qla4xxx_mark_device_missing(ha, ddb_entry);
1467+
}
1468+
14631469
/*
14641470
* Relogin if device state changed to a not active state.
14651471
* However, do not relogin if this aen is a result of an IOCTL

drivers/scsi/qla4xxx/ql4_isr.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -498,15 +498,22 @@ static void qla4xxx_isr_decode_mailbox(struct scsi_qla_host * ha,
498498
break;
499499

500500
case MBOX_ASTS_LINK_UP:
501-
DEBUG2(printk("scsi%ld: AEN %04x Adapter LINK UP\n",
502-
ha->host_no, mbox_status));
503501
set_bit(AF_LINK_UP, &ha->flags);
502+
if (test_bit(AF_INIT_DONE, &ha->flags))
503+
set_bit(DPC_LINK_CHANGED, &ha->dpc_flags);
504+
505+
DEBUG2(printk(KERN_INFO "scsi%ld: AEN %04x Adapter"
506+
" LINK UP\n", ha->host_no,
507+
mbox_status));
504508
break;
505509

506510
case MBOX_ASTS_LINK_DOWN:
507-
DEBUG2(printk("scsi%ld: AEN %04x Adapter LINK DOWN\n",
508-
ha->host_no, mbox_status));
509511
clear_bit(AF_LINK_UP, &ha->flags);
512+
set_bit(DPC_LINK_CHANGED, &ha->dpc_flags);
513+
514+
DEBUG2(printk(KERN_INFO "scsi%ld: AEN %04x Adapter"
515+
" LINK DOWN\n", ha->host_no,
516+
mbox_status));
510517
break;
511518

512519
case MBOX_ASTS_HEARTBEAT:

drivers/scsi/qla4xxx/ql4_os.c

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -685,6 +685,7 @@ static void qla4xxx_timer(struct scsi_qla_host *ha)
685685
test_bit(DPC_RESET_HA_DESTROY_DDB_LIST, &ha->dpc_flags) ||
686686
test_bit(DPC_RESET_HA_INTR, &ha->dpc_flags) ||
687687
test_bit(DPC_GET_DHCP_IP_ADDR, &ha->dpc_flags) ||
688+
test_bit(DPC_LINK_CHANGED, &ha->dpc_flags) ||
688689
test_bit(DPC_AEN, &ha->dpc_flags)) &&
689690
ha->dpc_thread) {
690691
DEBUG2(printk("scsi%ld: %s: scheduling dpc routine"
@@ -1069,6 +1070,54 @@ static void qla4xxx_do_dpc(struct work_struct *work)
10691070
if (test_and_clear_bit(DPC_GET_DHCP_IP_ADDR, &ha->dpc_flags))
10701071
qla4xxx_get_dhcp_ip_address(ha);
10711072

1073+
/* ---- link change? --- */
1074+
if (test_and_clear_bit(DPC_LINK_CHANGED, &ha->dpc_flags)) {
1075+
if (!test_bit(AF_LINK_UP, &ha->flags)) {
1076+
/* ---- link down? --- */
1077+
list_for_each_entry_safe(ddb_entry, dtemp,
1078+
&ha->ddb_list, list) {
1079+
if (atomic_read(&ddb_entry->state) ==
1080+
DDB_STATE_ONLINE)
1081+
qla4xxx_mark_device_missing(ha,
1082+
ddb_entry);
1083+
}
1084+
} else {
1085+
/* ---- link up? --- *
1086+
* F/W will auto login to all devices ONLY ONCE after
1087+
* link up during driver initialization and runtime
1088+
* fatal error recovery. Therefore, the driver must
1089+
* manually relogin to devices when recovering from
1090+
* connection failures, logouts, expired KATO, etc. */
1091+
1092+
list_for_each_entry_safe(ddb_entry, dtemp,
1093+
&ha->ddb_list, list) {
1094+
if ((atomic_read(&ddb_entry->state) ==
1095+
DDB_STATE_MISSING) ||
1096+
(atomic_read(&ddb_entry->state) ==
1097+
DDB_STATE_DEAD)) {
1098+
if (ddb_entry->fw_ddb_device_state ==
1099+
DDB_DS_SESSION_ACTIVE) {
1100+
atomic_set(&ddb_entry->state,
1101+
DDB_STATE_ONLINE);
1102+
dev_info(&ha->pdev->dev,
1103+
"scsi%ld: %s: ddb[%d]"
1104+
" os[%d] marked"
1105+
" ONLINE\n",
1106+
ha->host_no, __func__,
1107+
ddb_entry->fw_ddb_index,
1108+
ddb_entry->os_target_id);
1109+
1110+
iscsi_unblock_session(
1111+
ddb_entry->sess);
1112+
} else
1113+
qla4xxx_relogin_device(
1114+
ha, ddb_entry);
1115+
}
1116+
1117+
}
1118+
}
1119+
}
1120+
10721121
/* ---- relogin device? --- */
10731122
if (adapter_up(ha) &&
10741123
test_and_clear_bit(DPC_RELOGIN_DEVICE, &ha->dpc_flags)) {

0 commit comments

Comments
 (0)