diff options
author | Vikas Chaudhary <vikas.chaudhary@qlogic.com> | 2010-04-28 02:08:11 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2010-05-02 15:39:20 -0400 |
commit | 065aa1b4db63c7fa68a3e889510c4e63404a1ac7 (patch) | |
tree | 11a19a7faf1ef71d0a8f45f385b87c8235155f64 /drivers/scsi | |
parent | 2a49a78ed3c8d7c8319595270110c69f99c61a74 (diff) |
[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>
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/qla4xxx/ql4_def.h | 1 | ||||
-rw-r--r-- | drivers/scsi/qla4xxx/ql4_init.c | 12 | ||||
-rw-r--r-- | drivers/scsi/qla4xxx/ql4_isr.c | 15 | ||||
-rw-r--r-- | drivers/scsi/qla4xxx/ql4_os.c | 49 |
4 files changed, 70 insertions, 7 deletions
diff --git a/drivers/scsi/qla4xxx/ql4_def.h b/drivers/scsi/qla4xxx/ql4_def.h index 3175709d486..347a7c8b53e 100644 --- a/drivers/scsi/qla4xxx/ql4_def.h +++ b/drivers/scsi/qla4xxx/ql4_def.h | |||
@@ -310,6 +310,7 @@ struct scsi_qla_host { | |||
310 | #define DPC_ISNS_RESTART 7 /* 0x00000080 */ | 310 | #define DPC_ISNS_RESTART 7 /* 0x00000080 */ |
311 | #define DPC_AEN 9 /* 0x00000200 */ | 311 | #define DPC_AEN 9 /* 0x00000200 */ |
312 | #define DPC_GET_DHCP_IP_ADDR 15 /* 0x00008000 */ | 312 | #define DPC_GET_DHCP_IP_ADDR 15 /* 0x00008000 */ |
313 | #define DPC_LINK_CHANGED 18 /* 0x00040000 */ | ||
313 | 314 | ||
314 | struct Scsi_Host *host; /* pointer to host data */ | 315 | struct Scsi_Host *host; /* pointer to host data */ |
315 | uint32_t tot_ddbs; | 316 | uint32_t tot_ddbs; |
diff --git a/drivers/scsi/qla4xxx/ql4_init.c b/drivers/scsi/qla4xxx/ql4_init.c index 36ec02c49a1..7f6cc2ebf46 100644 --- a/drivers/scsi/qla4xxx/ql4_init.c +++ b/drivers/scsi/qla4xxx/ql4_init.c | |||
@@ -1279,6 +1279,7 @@ int qla4xxx_initialize_adapter(struct scsi_qla_host *ha, | |||
1279 | int status = QLA_ERROR; | 1279 | int status = QLA_ERROR; |
1280 | int8_t ip_address[IP_ADDR_LEN] = {0} ; | 1280 | int8_t ip_address[IP_ADDR_LEN] = {0} ; |
1281 | 1281 | ||
1282 | clear_bit(AF_ONLINE, &ha->flags); | ||
1282 | ha->eeprom_cmd_data = 0; | 1283 | ha->eeprom_cmd_data = 0; |
1283 | 1284 | ||
1284 | qla4x00_pci_config(ha); | 1285 | qla4x00_pci_config(ha); |
@@ -1456,10 +1457,15 @@ int qla4xxx_process_ddb_changed(struct scsi_qla_host *ha, | |||
1456 | * the device came back. | 1457 | * the device came back. |
1457 | */ | 1458 | */ |
1458 | } else { | 1459 | } else { |
1459 | /* Device went away, try to relogin. */ | 1460 | /* Device went away, mark device missing */ |
1460 | /* Mark device missing */ | 1461 | if (atomic_read(&ddb_entry->state) == DDB_STATE_ONLINE) { |
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)); | ||
1462 | qla4xxx_mark_device_missing(ha, ddb_entry); | 1466 | qla4xxx_mark_device_missing(ha, ddb_entry); |
1467 | } | ||
1468 | |||
1463 | /* | 1469 | /* |
1464 | * Relogin if device state changed to a not active state. | 1470 | * Relogin if device state changed to a not active state. |
1465 | * However, do not relogin if this aen is a result of an IOCTL | 1471 | * However, do not relogin if this aen is a result of an IOCTL |
diff --git a/drivers/scsi/qla4xxx/ql4_isr.c b/drivers/scsi/qla4xxx/ql4_isr.c index c196d55eae3..9db286df7ca 100644 --- a/drivers/scsi/qla4xxx/ql4_isr.c +++ b/drivers/scsi/qla4xxx/ql4_isr.c | |||
@@ -498,15 +498,22 @@ static void qla4xxx_isr_decode_mailbox(struct scsi_qla_host * ha, | |||
498 | break; | 498 | break; |
499 | 499 | ||
500 | case MBOX_ASTS_LINK_UP: | 500 | case MBOX_ASTS_LINK_UP: |
501 | DEBUG2(printk("scsi%ld: AEN %04x Adapter LINK UP\n", | ||
502 | ha->host_no, mbox_status)); | ||
503 | set_bit(AF_LINK_UP, &ha->flags); | 501 | 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)); | ||
504 | break; | 508 | break; |
505 | 509 | ||
506 | case MBOX_ASTS_LINK_DOWN: | 510 | case MBOX_ASTS_LINK_DOWN: |
507 | DEBUG2(printk("scsi%ld: AEN %04x Adapter LINK DOWN\n", | ||
508 | ha->host_no, mbox_status)); | ||
509 | clear_bit(AF_LINK_UP, &ha->flags); | 511 | 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)); | ||
510 | break; | 517 | break; |
511 | 518 | ||
512 | case MBOX_ASTS_HEARTBEAT: | 519 | case MBOX_ASTS_HEARTBEAT: |
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c index 2ccad36bee9..d6c8b429a67 100644 --- a/drivers/scsi/qla4xxx/ql4_os.c +++ b/drivers/scsi/qla4xxx/ql4_os.c | |||
@@ -685,6 +685,7 @@ static void qla4xxx_timer(struct scsi_qla_host *ha) | |||
685 | test_bit(DPC_RESET_HA_DESTROY_DDB_LIST, &ha->dpc_flags) || | 685 | test_bit(DPC_RESET_HA_DESTROY_DDB_LIST, &ha->dpc_flags) || |
686 | test_bit(DPC_RESET_HA_INTR, &ha->dpc_flags) || | 686 | test_bit(DPC_RESET_HA_INTR, &ha->dpc_flags) || |
687 | test_bit(DPC_GET_DHCP_IP_ADDR, &ha->dpc_flags) || | 687 | test_bit(DPC_GET_DHCP_IP_ADDR, &ha->dpc_flags) || |
688 | test_bit(DPC_LINK_CHANGED, &ha->dpc_flags) || | ||
688 | test_bit(DPC_AEN, &ha->dpc_flags)) && | 689 | test_bit(DPC_AEN, &ha->dpc_flags)) && |
689 | ha->dpc_thread) { | 690 | ha->dpc_thread) { |
690 | DEBUG2(printk("scsi%ld: %s: scheduling dpc routine" | 691 | DEBUG2(printk("scsi%ld: %s: scheduling dpc routine" |
@@ -1069,6 +1070,54 @@ static void qla4xxx_do_dpc(struct work_struct *work) | |||
1069 | if (test_and_clear_bit(DPC_GET_DHCP_IP_ADDR, &ha->dpc_flags)) | 1070 | if (test_and_clear_bit(DPC_GET_DHCP_IP_ADDR, &ha->dpc_flags)) |
1070 | qla4xxx_get_dhcp_ip_address(ha); | 1071 | qla4xxx_get_dhcp_ip_address(ha); |
1071 | 1072 | ||
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 | |||
1072 | /* ---- relogin device? --- */ | 1121 | /* ---- relogin device? --- */ |
1073 | if (adapter_up(ha) && | 1122 | if (adapter_up(ha) && |
1074 | test_and_clear_bit(DPC_RELOGIN_DEVICE, &ha->dpc_flags)) { | 1123 | test_and_clear_bit(DPC_RELOGIN_DEVICE, &ha->dpc_flags)) { |