diff options
Diffstat (limited to 'drivers/scsi/qla4xxx/ql4_init.c')
-rw-r--r-- | drivers/scsi/qla4xxx/ql4_init.c | 105 |
1 files changed, 69 insertions, 36 deletions
diff --git a/drivers/scsi/qla4xxx/ql4_init.c b/drivers/scsi/qla4xxx/ql4_init.c index 6365df268612..1e29f51d596b 100644 --- a/drivers/scsi/qla4xxx/ql4_init.c +++ b/drivers/scsi/qla4xxx/ql4_init.c | |||
@@ -6,6 +6,9 @@ | |||
6 | */ | 6 | */ |
7 | 7 | ||
8 | #include "ql4_def.h" | 8 | #include "ql4_def.h" |
9 | #include "ql4_glbl.h" | ||
10 | #include "ql4_dbg.h" | ||
11 | #include "ql4_inline.h" | ||
9 | 12 | ||
10 | static struct ddb_entry * qla4xxx_alloc_ddb(struct scsi_qla_host *ha, | 13 | static struct ddb_entry * qla4xxx_alloc_ddb(struct scsi_qla_host *ha, |
11 | uint32_t fw_ddb_index); | 14 | uint32_t fw_ddb_index); |
@@ -300,12 +303,12 @@ static int qla4xxx_init_firmware(struct scsi_qla_host *ha) | |||
300 | if (!qla4xxx_fw_ready(ha)) | 303 | if (!qla4xxx_fw_ready(ha)) |
301 | return status; | 304 | return status; |
302 | 305 | ||
303 | set_bit(AF_ONLINE, &ha->flags); | ||
304 | return qla4xxx_get_firmware_status(ha); | 306 | return qla4xxx_get_firmware_status(ha); |
305 | } | 307 | } |
306 | 308 | ||
307 | static struct ddb_entry* qla4xxx_get_ddb_entry(struct scsi_qla_host *ha, | 309 | static struct ddb_entry* qla4xxx_get_ddb_entry(struct scsi_qla_host *ha, |
308 | uint32_t fw_ddb_index) | 310 | uint32_t fw_ddb_index, |
311 | uint32_t *new_tgt) | ||
309 | { | 312 | { |
310 | struct dev_db_entry *fw_ddb_entry = NULL; | 313 | struct dev_db_entry *fw_ddb_entry = NULL; |
311 | dma_addr_t fw_ddb_entry_dma; | 314 | dma_addr_t fw_ddb_entry_dma; |
@@ -313,6 +316,7 @@ static struct ddb_entry* qla4xxx_get_ddb_entry(struct scsi_qla_host *ha, | |||
313 | int found = 0; | 316 | int found = 0; |
314 | uint32_t device_state; | 317 | uint32_t device_state; |
315 | 318 | ||
319 | *new_tgt = 0; | ||
316 | /* Make sure the dma buffer is valid */ | 320 | /* Make sure the dma buffer is valid */ |
317 | fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev, | 321 | fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev, |
318 | sizeof(*fw_ddb_entry), | 322 | sizeof(*fw_ddb_entry), |
@@ -337,7 +341,7 @@ static struct ddb_entry* qla4xxx_get_ddb_entry(struct scsi_qla_host *ha, | |||
337 | DEBUG2(printk("scsi%ld: %s: Looking for ddb[%d]\n", ha->host_no, | 341 | DEBUG2(printk("scsi%ld: %s: Looking for ddb[%d]\n", ha->host_no, |
338 | __func__, fw_ddb_index)); | 342 | __func__, fw_ddb_index)); |
339 | list_for_each_entry(ddb_entry, &ha->ddb_list, list) { | 343 | list_for_each_entry(ddb_entry, &ha->ddb_list, list) { |
340 | if (memcmp(ddb_entry->iscsi_name, fw_ddb_entry->iscsiName, | 344 | if (memcmp(ddb_entry->iscsi_name, fw_ddb_entry->iscsi_name, |
341 | ISCSI_NAME_SIZE) == 0) { | 345 | ISCSI_NAME_SIZE) == 0) { |
342 | found++; | 346 | found++; |
343 | break; | 347 | break; |
@@ -348,6 +352,7 @@ static struct ddb_entry* qla4xxx_get_ddb_entry(struct scsi_qla_host *ha, | |||
348 | DEBUG2(printk("scsi%ld: %s: ddb[%d] not found - allocating " | 352 | DEBUG2(printk("scsi%ld: %s: ddb[%d] not found - allocating " |
349 | "new ddb\n", ha->host_no, __func__, | 353 | "new ddb\n", ha->host_no, __func__, |
350 | fw_ddb_index)); | 354 | fw_ddb_index)); |
355 | *new_tgt = 1; | ||
351 | ddb_entry = qla4xxx_alloc_ddb(ha, fw_ddb_index); | 356 | ddb_entry = qla4xxx_alloc_ddb(ha, fw_ddb_index); |
352 | } | 357 | } |
353 | 358 | ||
@@ -409,26 +414,26 @@ static int qla4xxx_update_ddb_entry(struct scsi_qla_host *ha, | |||
409 | } | 414 | } |
410 | 415 | ||
411 | status = QLA_SUCCESS; | 416 | status = QLA_SUCCESS; |
412 | ddb_entry->target_session_id = le16_to_cpu(fw_ddb_entry->TSID); | 417 | ddb_entry->target_session_id = le16_to_cpu(fw_ddb_entry->tsid); |
413 | ddb_entry->task_mgmt_timeout = | 418 | ddb_entry->task_mgmt_timeout = |
414 | le16_to_cpu(fw_ddb_entry->taskMngmntTimeout); | 419 | le16_to_cpu(fw_ddb_entry->def_timeout); |
415 | ddb_entry->CmdSn = 0; | 420 | ddb_entry->CmdSn = 0; |
416 | ddb_entry->exe_throttle = le16_to_cpu(fw_ddb_entry->exeThrottle); | 421 | ddb_entry->exe_throttle = le16_to_cpu(fw_ddb_entry->exec_throttle); |
417 | ddb_entry->default_relogin_timeout = | 422 | ddb_entry->default_relogin_timeout = |
418 | le16_to_cpu(fw_ddb_entry->taskMngmntTimeout); | 423 | le16_to_cpu(fw_ddb_entry->def_timeout); |
419 | ddb_entry->default_time2wait = le16_to_cpu(fw_ddb_entry->minTime2Wait); | 424 | ddb_entry->default_time2wait = le16_to_cpu(fw_ddb_entry->iscsi_def_time2wait); |
420 | 425 | ||
421 | /* Update index in case it changed */ | 426 | /* Update index in case it changed */ |
422 | ddb_entry->fw_ddb_index = fw_ddb_index; | 427 | ddb_entry->fw_ddb_index = fw_ddb_index; |
423 | ha->fw_ddb_index_map[fw_ddb_index] = ddb_entry; | 428 | ha->fw_ddb_index_map[fw_ddb_index] = ddb_entry; |
424 | 429 | ||
425 | ddb_entry->port = le16_to_cpu(fw_ddb_entry->portNumber); | 430 | ddb_entry->port = le16_to_cpu(fw_ddb_entry->port); |
426 | ddb_entry->tpgt = le32_to_cpu(fw_ddb_entry->TargetPortalGroup); | 431 | ddb_entry->tpgt = le32_to_cpu(fw_ddb_entry->tgt_portal_grp); |
427 | memcpy(&ddb_entry->iscsi_name[0], &fw_ddb_entry->iscsiName[0], | 432 | memcpy(&ddb_entry->iscsi_name[0], &fw_ddb_entry->iscsi_name[0], |
428 | min(sizeof(ddb_entry->iscsi_name), | 433 | min(sizeof(ddb_entry->iscsi_name), |
429 | sizeof(fw_ddb_entry->iscsiName))); | 434 | sizeof(fw_ddb_entry->iscsi_name))); |
430 | memcpy(&ddb_entry->ip_addr[0], &fw_ddb_entry->ipAddr[0], | 435 | memcpy(&ddb_entry->ip_addr[0], &fw_ddb_entry->ip_addr[0], |
431 | min(sizeof(ddb_entry->ip_addr), sizeof(fw_ddb_entry->ipAddr))); | 436 | min(sizeof(ddb_entry->ip_addr), sizeof(fw_ddb_entry->ip_addr))); |
432 | 437 | ||
433 | DEBUG2(printk("scsi%ld: %s: ddb[%d] - State= %x status= %d.\n", | 438 | DEBUG2(printk("scsi%ld: %s: ddb[%d] - State= %x status= %d.\n", |
434 | ha->host_no, __func__, fw_ddb_index, | 439 | ha->host_no, __func__, fw_ddb_index, |
@@ -495,6 +500,7 @@ static int qla4xxx_build_ddb_list(struct scsi_qla_host *ha) | |||
495 | uint32_t ddb_state; | 500 | uint32_t ddb_state; |
496 | uint32_t conn_err, err_code; | 501 | uint32_t conn_err, err_code; |
497 | struct ddb_entry *ddb_entry; | 502 | struct ddb_entry *ddb_entry; |
503 | uint32_t new_tgt; | ||
498 | 504 | ||
499 | dev_info(&ha->pdev->dev, "Initializing DDBs ...\n"); | 505 | dev_info(&ha->pdev->dev, "Initializing DDBs ...\n"); |
500 | for (fw_ddb_index = 0; fw_ddb_index < MAX_DDB_ENTRIES; | 506 | for (fw_ddb_index = 0; fw_ddb_index < MAX_DDB_ENTRIES; |
@@ -526,8 +532,19 @@ static int qla4xxx_build_ddb_list(struct scsi_qla_host *ha) | |||
526 | "completed " | 532 | "completed " |
527 | "or access denied failure\n", | 533 | "or access denied failure\n", |
528 | ha->host_no, __func__)); | 534 | ha->host_no, __func__)); |
529 | } else | 535 | } else { |
530 | qla4xxx_set_ddb_entry(ha, fw_ddb_index, 0); | 536 | qla4xxx_set_ddb_entry(ha, fw_ddb_index, 0); |
537 | if (qla4xxx_get_fwddb_entry(ha, fw_ddb_index, | ||
538 | NULL, 0, NULL, &next_fw_ddb_index, | ||
539 | &ddb_state, &conn_err, NULL, NULL) | ||
540 | == QLA_ERROR) { | ||
541 | DEBUG2(printk("scsi%ld: %s:" | ||
542 | "get_ddb_entry %d failed\n", | ||
543 | ha->host_no, | ||
544 | __func__, fw_ddb_index)); | ||
545 | return QLA_ERROR; | ||
546 | } | ||
547 | } | ||
531 | } | 548 | } |
532 | 549 | ||
533 | if (ddb_state != DDB_DS_SESSION_ACTIVE) | 550 | if (ddb_state != DDB_DS_SESSION_ACTIVE) |
@@ -540,7 +557,7 @@ static int qla4xxx_build_ddb_list(struct scsi_qla_host *ha) | |||
540 | ha->host_no, __func__, fw_ddb_index)); | 557 | ha->host_no, __func__, fw_ddb_index)); |
541 | 558 | ||
542 | /* Add DDB to internal our ddb list. */ | 559 | /* Add DDB to internal our ddb list. */ |
543 | ddb_entry = qla4xxx_get_ddb_entry(ha, fw_ddb_index); | 560 | ddb_entry = qla4xxx_get_ddb_entry(ha, fw_ddb_index, &new_tgt); |
544 | if (ddb_entry == NULL) { | 561 | if (ddb_entry == NULL) { |
545 | DEBUG2(printk("scsi%ld: %s: Unable to allocate memory " | 562 | DEBUG2(printk("scsi%ld: %s: Unable to allocate memory " |
546 | "for device at fw_ddb_index %d\n", | 563 | "for device at fw_ddb_index %d\n", |
@@ -865,21 +882,20 @@ static int qla4xxx_config_nvram(struct scsi_qla_host *ha) | |||
865 | 882 | ||
866 | static void qla4x00_pci_config(struct scsi_qla_host *ha) | 883 | static void qla4x00_pci_config(struct scsi_qla_host *ha) |
867 | { | 884 | { |
868 | uint16_t w, mwi; | 885 | uint16_t w; |
886 | int status; | ||
869 | 887 | ||
870 | dev_info(&ha->pdev->dev, "Configuring PCI space...\n"); | 888 | dev_info(&ha->pdev->dev, "Configuring PCI space...\n"); |
871 | 889 | ||
872 | pci_set_master(ha->pdev); | 890 | pci_set_master(ha->pdev); |
873 | mwi = 0; | 891 | status = pci_set_mwi(ha->pdev); |
874 | if (pci_set_mwi(ha->pdev)) | ||
875 | mwi = PCI_COMMAND_INVALIDATE; | ||
876 | /* | 892 | /* |
877 | * We want to respect framework's setting of PCI configuration space | 893 | * We want to respect framework's setting of PCI configuration space |
878 | * command register and also want to make sure that all bits of | 894 | * command register and also want to make sure that all bits of |
879 | * interest to us are properly set in command register. | 895 | * interest to us are properly set in command register. |
880 | */ | 896 | */ |
881 | pci_read_config_word(ha->pdev, PCI_COMMAND, &w); | 897 | pci_read_config_word(ha->pdev, PCI_COMMAND, &w); |
882 | w |= mwi | (PCI_COMMAND_PARITY | PCI_COMMAND_SERR); | 898 | w |= PCI_COMMAND_PARITY | PCI_COMMAND_SERR; |
883 | w &= ~PCI_COMMAND_INTX_DISABLE; | 899 | w &= ~PCI_COMMAND_INTX_DISABLE; |
884 | pci_write_config_word(ha->pdev, PCI_COMMAND, w); | 900 | pci_write_config_word(ha->pdev, PCI_COMMAND, w); |
885 | } | 901 | } |
@@ -911,6 +927,9 @@ static int qla4xxx_start_firmware_from_flash(struct scsi_qla_host *ha) | |||
911 | writel(set_rmask(NVR_WRITE_ENABLE), | 927 | writel(set_rmask(NVR_WRITE_ENABLE), |
912 | &ha->reg->u1.isp4022.nvram); | 928 | &ha->reg->u1.isp4022.nvram); |
913 | 929 | ||
930 | writel(2, &ha->reg->mailbox[6]); | ||
931 | readl(&ha->reg->mailbox[6]); | ||
932 | |||
914 | writel(set_rmask(CSR_BOOT_ENABLE), &ha->reg->ctrl_status); | 933 | writel(set_rmask(CSR_BOOT_ENABLE), &ha->reg->ctrl_status); |
915 | readl(&ha->reg->ctrl_status); | 934 | readl(&ha->reg->ctrl_status); |
916 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 935 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
@@ -958,25 +977,25 @@ static int qla4xxx_start_firmware_from_flash(struct scsi_qla_host *ha) | |||
958 | return status; | 977 | return status; |
959 | } | 978 | } |
960 | 979 | ||
961 | int ql4xxx_lock_drvr_wait(struct scsi_qla_host *ha) | 980 | int ql4xxx_lock_drvr_wait(struct scsi_qla_host *a) |
962 | { | 981 | { |
963 | #define QL4_LOCK_DRVR_WAIT 30 | 982 | #define QL4_LOCK_DRVR_WAIT 60 |
964 | #define QL4_LOCK_DRVR_SLEEP 1 | 983 | #define QL4_LOCK_DRVR_SLEEP 1 |
965 | 984 | ||
966 | int drvr_wait = QL4_LOCK_DRVR_WAIT; | 985 | int drvr_wait = QL4_LOCK_DRVR_WAIT; |
967 | while (drvr_wait) { | 986 | while (drvr_wait) { |
968 | if (ql4xxx_lock_drvr(ha) == 0) { | 987 | if (ql4xxx_lock_drvr(a) == 0) { |
969 | ssleep(QL4_LOCK_DRVR_SLEEP); | 988 | ssleep(QL4_LOCK_DRVR_SLEEP); |
970 | if (drvr_wait) { | 989 | if (drvr_wait) { |
971 | DEBUG2(printk("scsi%ld: %s: Waiting for " | 990 | DEBUG2(printk("scsi%ld: %s: Waiting for " |
972 | "Global Init Semaphore(%d)...n", | 991 | "Global Init Semaphore(%d)...\n", |
973 | ha->host_no, | 992 | a->host_no, |
974 | __func__, drvr_wait)); | 993 | __func__, drvr_wait)); |
975 | } | 994 | } |
976 | drvr_wait -= QL4_LOCK_DRVR_SLEEP; | 995 | drvr_wait -= QL4_LOCK_DRVR_SLEEP; |
977 | } else { | 996 | } else { |
978 | DEBUG2(printk("scsi%ld: %s: Global Init Semaphore " | 997 | DEBUG2(printk("scsi%ld: %s: Global Init Semaphore " |
979 | "acquired.n", ha->host_no, __func__)); | 998 | "acquired\n", a->host_no, __func__)); |
980 | return QLA_SUCCESS; | 999 | return QLA_SUCCESS; |
981 | } | 1000 | } |
982 | } | 1001 | } |
@@ -1125,17 +1144,17 @@ int qla4xxx_initialize_adapter(struct scsi_qla_host *ha, | |||
1125 | 1144 | ||
1126 | /* Initialize the Host adapter request/response queues and firmware */ | 1145 | /* Initialize the Host adapter request/response queues and firmware */ |
1127 | if (qla4xxx_start_firmware(ha) == QLA_ERROR) | 1146 | if (qla4xxx_start_firmware(ha) == QLA_ERROR) |
1128 | return status; | 1147 | goto exit_init_hba; |
1129 | 1148 | ||
1130 | if (qla4xxx_validate_mac_address(ha) == QLA_ERROR) | 1149 | if (qla4xxx_validate_mac_address(ha) == QLA_ERROR) |
1131 | return status; | 1150 | goto exit_init_hba; |
1132 | 1151 | ||
1133 | if (qla4xxx_init_local_data(ha) == QLA_ERROR) | 1152 | if (qla4xxx_init_local_data(ha) == QLA_ERROR) |
1134 | return status; | 1153 | goto exit_init_hba; |
1135 | 1154 | ||
1136 | status = qla4xxx_init_firmware(ha); | 1155 | status = qla4xxx_init_firmware(ha); |
1137 | if (status == QLA_ERROR) | 1156 | if (status == QLA_ERROR) |
1138 | return status; | 1157 | goto exit_init_hba; |
1139 | 1158 | ||
1140 | /* | 1159 | /* |
1141 | * FW is waiting to get an IP address from DHCP server: Skip building | 1160 | * FW is waiting to get an IP address from DHCP server: Skip building |
@@ -1143,12 +1162,12 @@ int qla4xxx_initialize_adapter(struct scsi_qla_host *ha, | |||
1143 | * followed by 0x8014 aen" to trigger the tgt discovery process. | 1162 | * followed by 0x8014 aen" to trigger the tgt discovery process. |
1144 | */ | 1163 | */ |
1145 | if (ha->firmware_state & FW_STATE_DHCP_IN_PROGRESS) | 1164 | if (ha->firmware_state & FW_STATE_DHCP_IN_PROGRESS) |
1146 | return status; | 1165 | goto exit_init_online; |
1147 | 1166 | ||
1148 | /* Skip device discovery if ip and subnet is zero */ | 1167 | /* Skip device discovery if ip and subnet is zero */ |
1149 | if (memcmp(ha->ip_address, ip_address, IP_ADDR_LEN) == 0 || | 1168 | if (memcmp(ha->ip_address, ip_address, IP_ADDR_LEN) == 0 || |
1150 | memcmp(ha->subnet_mask, ip_address, IP_ADDR_LEN) == 0) | 1169 | memcmp(ha->subnet_mask, ip_address, IP_ADDR_LEN) == 0) |
1151 | return status; | 1170 | goto exit_init_online; |
1152 | 1171 | ||
1153 | if (renew_ddb_list == PRESERVE_DDB_LIST) { | 1172 | if (renew_ddb_list == PRESERVE_DDB_LIST) { |
1154 | /* | 1173 | /* |
@@ -1177,9 +1196,10 @@ int qla4xxx_initialize_adapter(struct scsi_qla_host *ha, | |||
1177 | ha->host_no)); | 1196 | ha->host_no)); |
1178 | } | 1197 | } |
1179 | 1198 | ||
1180 | exit_init_hba: | 1199 | exit_init_online: |
1200 | set_bit(AF_ONLINE, &ha->flags); | ||
1201 | exit_init_hba: | ||
1181 | return status; | 1202 | return status; |
1182 | |||
1183 | } | 1203 | } |
1184 | 1204 | ||
1185 | /** | 1205 | /** |
@@ -1193,9 +1213,10 @@ static void qla4xxx_add_device_dynamically(struct scsi_qla_host *ha, | |||
1193 | uint32_t fw_ddb_index) | 1213 | uint32_t fw_ddb_index) |
1194 | { | 1214 | { |
1195 | struct ddb_entry * ddb_entry; | 1215 | struct ddb_entry * ddb_entry; |
1216 | uint32_t new_tgt; | ||
1196 | 1217 | ||
1197 | /* First allocate a device structure */ | 1218 | /* First allocate a device structure */ |
1198 | ddb_entry = qla4xxx_get_ddb_entry(ha, fw_ddb_index); | 1219 | ddb_entry = qla4xxx_get_ddb_entry(ha, fw_ddb_index, &new_tgt); |
1199 | if (ddb_entry == NULL) { | 1220 | if (ddb_entry == NULL) { |
1200 | DEBUG2(printk(KERN_WARNING | 1221 | DEBUG2(printk(KERN_WARNING |
1201 | "scsi%ld: Unable to allocate memory to add " | 1222 | "scsi%ld: Unable to allocate memory to add " |
@@ -1203,6 +1224,18 @@ static void qla4xxx_add_device_dynamically(struct scsi_qla_host *ha, | |||
1203 | return; | 1224 | return; |
1204 | } | 1225 | } |
1205 | 1226 | ||
1227 | if (!new_tgt && (ddb_entry->fw_ddb_index != fw_ddb_index)) { | ||
1228 | /* Target has been bound to a new fw_ddb_index */ | ||
1229 | qla4xxx_free_ddb(ha, ddb_entry); | ||
1230 | ddb_entry = qla4xxx_alloc_ddb(ha, fw_ddb_index); | ||
1231 | if (ddb_entry == NULL) { | ||
1232 | DEBUG2(printk(KERN_WARNING | ||
1233 | "scsi%ld: Unable to allocate memory" | ||
1234 | " to add fw_ddb_index %d\n", | ||
1235 | ha->host_no, fw_ddb_index)); | ||
1236 | return; | ||
1237 | } | ||
1238 | } | ||
1206 | if (qla4xxx_update_ddb_entry(ha, ddb_entry, fw_ddb_index) == | 1239 | if (qla4xxx_update_ddb_entry(ha, ddb_entry, fw_ddb_index) == |
1207 | QLA_ERROR) { | 1240 | QLA_ERROR) { |
1208 | ha->fw_ddb_index_map[fw_ddb_index] = | 1241 | ha->fw_ddb_index_map[fw_ddb_index] = |