diff options
Diffstat (limited to 'drivers/scsi/qla4xxx/ql4_init.c')
| -rw-r--r-- | drivers/scsi/qla4xxx/ql4_init.c | 374 |
1 files changed, 285 insertions, 89 deletions
diff --git a/drivers/scsi/qla4xxx/ql4_init.c b/drivers/scsi/qla4xxx/ql4_init.c index 92329a461c68..5510df8a7fa6 100644 --- a/drivers/scsi/qla4xxx/ql4_init.c +++ b/drivers/scsi/qla4xxx/ql4_init.c | |||
| @@ -189,6 +189,78 @@ static int qla4xxx_init_local_data(struct scsi_qla_host *ha) | |||
| 189 | return qla4xxx_get_firmware_status(ha); | 189 | return qla4xxx_get_firmware_status(ha); |
| 190 | } | 190 | } |
| 191 | 191 | ||
| 192 | static uint8_t | ||
| 193 | qla4xxx_wait_for_ip_config(struct scsi_qla_host *ha) | ||
| 194 | { | ||
| 195 | uint8_t ipv4_wait = 0; | ||
| 196 | uint8_t ipv6_wait = 0; | ||
| 197 | int8_t ip_address[IPv6_ADDR_LEN] = {0} ; | ||
| 198 | |||
| 199 | /* If both IPv4 & IPv6 are enabled, possibly only one | ||
| 200 | * IP address may be acquired, so check to see if we | ||
| 201 | * need to wait for another */ | ||
| 202 | if (is_ipv4_enabled(ha) && is_ipv6_enabled(ha)) { | ||
| 203 | if (((ha->addl_fw_state & FW_ADDSTATE_DHCPv4_ENABLED) != 0) && | ||
| 204 | ((ha->addl_fw_state & | ||
| 205 | FW_ADDSTATE_DHCPv4_LEASE_ACQUIRED) == 0)) { | ||
| 206 | ipv4_wait = 1; | ||
| 207 | } | ||
| 208 | if (((ha->ipv6_addl_options & | ||
| 209 | IPV6_ADDOPT_NEIGHBOR_DISCOVERY_ADDR_ENABLE) != 0) && | ||
| 210 | ((ha->ipv6_link_local_state == IP_ADDRSTATE_ACQUIRING) || | ||
| 211 | (ha->ipv6_addr0_state == IP_ADDRSTATE_ACQUIRING) || | ||
| 212 | (ha->ipv6_addr1_state == IP_ADDRSTATE_ACQUIRING))) { | ||
| 213 | |||
| 214 | ipv6_wait = 1; | ||
| 215 | |||
| 216 | if ((ha->ipv6_link_local_state == | ||
| 217 | IP_ADDRSTATE_PREFERRED) || | ||
| 218 | (ha->ipv6_addr0_state == IP_ADDRSTATE_PREFERRED) || | ||
| 219 | (ha->ipv6_addr1_state == IP_ADDRSTATE_PREFERRED)) { | ||
| 220 | DEBUG2(printk(KERN_INFO "scsi%ld: %s: " | ||
| 221 | "Preferred IP configured." | ||
| 222 | " Don't wait!\n", ha->host_no, | ||
| 223 | __func__)); | ||
| 224 | ipv6_wait = 0; | ||
| 225 | } | ||
| 226 | if (memcmp(&ha->ipv6_default_router_addr, ip_address, | ||
| 227 | IPv6_ADDR_LEN) == 0) { | ||
| 228 | DEBUG2(printk(KERN_INFO "scsi%ld: %s: " | ||
| 229 | "No Router configured. " | ||
| 230 | "Don't wait!\n", ha->host_no, | ||
| 231 | __func__)); | ||
| 232 | ipv6_wait = 0; | ||
| 233 | } | ||
| 234 | if ((ha->ipv6_default_router_state == | ||
| 235 | IPV6_RTRSTATE_MANUAL) && | ||
| 236 | (ha->ipv6_link_local_state == | ||
| 237 | IP_ADDRSTATE_TENTATIVE) && | ||
| 238 | (memcmp(&ha->ipv6_link_local_addr, | ||
| 239 | &ha->ipv6_default_router_addr, 4) == 0)) { | ||
| 240 | DEBUG2(printk("scsi%ld: %s: LinkLocal Router & " | ||
| 241 | "IP configured. Don't wait!\n", | ||
| 242 | ha->host_no, __func__)); | ||
| 243 | ipv6_wait = 0; | ||
| 244 | } | ||
| 245 | } | ||
| 246 | if (ipv4_wait || ipv6_wait) { | ||
| 247 | DEBUG2(printk("scsi%ld: %s: Wait for additional " | ||
| 248 | "IP(s) \"", ha->host_no, __func__)); | ||
| 249 | if (ipv4_wait) | ||
| 250 | DEBUG2(printk("IPv4 ")); | ||
| 251 | if (ha->ipv6_link_local_state == IP_ADDRSTATE_ACQUIRING) | ||
| 252 | DEBUG2(printk("IPv6LinkLocal ")); | ||
| 253 | if (ha->ipv6_addr0_state == IP_ADDRSTATE_ACQUIRING) | ||
| 254 | DEBUG2(printk("IPv6Addr0 ")); | ||
| 255 | if (ha->ipv6_addr1_state == IP_ADDRSTATE_ACQUIRING) | ||
| 256 | DEBUG2(printk("IPv6Addr1 ")); | ||
| 257 | DEBUG2(printk("\"\n")); | ||
| 258 | } | ||
| 259 | } | ||
| 260 | |||
| 261 | return ipv4_wait|ipv6_wait; | ||
| 262 | } | ||
| 263 | |||
| 192 | static int qla4xxx_fw_ready(struct scsi_qla_host *ha) | 264 | static int qla4xxx_fw_ready(struct scsi_qla_host *ha) |
| 193 | { | 265 | { |
| 194 | uint32_t timeout_count; | 266 | uint32_t timeout_count; |
| @@ -226,38 +298,80 @@ static int qla4xxx_fw_ready(struct scsi_qla_host *ha) | |||
| 226 | continue; | 298 | continue; |
| 227 | } | 299 | } |
| 228 | 300 | ||
| 301 | if (ha->firmware_state & FW_STATE_WAIT_AUTOCONNECT) { | ||
| 302 | DEBUG2(printk(KERN_INFO "scsi%ld: %s: fwstate:" | ||
| 303 | "AUTOCONNECT in progress\n", | ||
| 304 | ha->host_no, __func__)); | ||
| 305 | } | ||
| 306 | |||
| 307 | if (ha->firmware_state & FW_STATE_CONFIGURING_IP) { | ||
| 308 | DEBUG2(printk(KERN_INFO "scsi%ld: %s: fwstate:" | ||
| 309 | " CONFIGURING IP\n", | ||
| 310 | ha->host_no, __func__)); | ||
| 311 | /* | ||
| 312 | * Check for link state after 15 secs and if link is | ||
| 313 | * still DOWN then, cable is unplugged. Ignore "DHCP | ||
| 314 | * in Progress/CONFIGURING IP" bit to check if firmware | ||
| 315 | * is in ready state or not after 15 secs. | ||
| 316 | * This is applicable for both 2.x & 3.x firmware | ||
| 317 | */ | ||
| 318 | if (timeout_count <= (ADAPTER_INIT_TOV - 15)) { | ||
| 319 | if (ha->addl_fw_state & FW_ADDSTATE_LINK_UP) { | ||
| 320 | DEBUG2(printk(KERN_INFO "scsi%ld: %s:" | ||
| 321 | " LINK UP (Cable plugged)\n", | ||
| 322 | ha->host_no, __func__)); | ||
| 323 | } else if (ha->firmware_state & | ||
| 324 | (FW_STATE_CONFIGURING_IP | | ||
| 325 | FW_STATE_READY)) { | ||
| 326 | DEBUG2(printk(KERN_INFO "scsi%ld: %s: " | ||
| 327 | "LINK DOWN (Cable unplugged)\n", | ||
| 328 | ha->host_no, __func__)); | ||
| 329 | ha->firmware_state = FW_STATE_READY; | ||
| 330 | } | ||
| 331 | } | ||
| 332 | } | ||
| 333 | |||
| 229 | if (ha->firmware_state == FW_STATE_READY) { | 334 | if (ha->firmware_state == FW_STATE_READY) { |
| 230 | DEBUG2(dev_info(&ha->pdev->dev, "Firmware Ready..\n")); | 335 | /* If DHCP IP Addr is available, retrieve it now. */ |
| 231 | /* The firmware is ready to process SCSI commands. */ | 336 | if (test_and_clear_bit(DPC_GET_DHCP_IP_ADDR, |
| 232 | DEBUG2(dev_info(&ha->pdev->dev, | 337 | &ha->dpc_flags)) |
| 233 | "scsi%ld: %s: MEDIA TYPE - %s\n", | 338 | qla4xxx_get_dhcp_ip_address(ha); |
| 234 | ha->host_no, | 339 | |
| 235 | __func__, (ha->addl_fw_state & | 340 | if (!qla4xxx_wait_for_ip_config(ha) || |
| 236 | FW_ADDSTATE_OPTICAL_MEDIA) | 341 | timeout_count == 1) { |
| 237 | != 0 ? "OPTICAL" : "COPPER")); | 342 | DEBUG2(dev_info(&ha->pdev->dev, |
| 238 | DEBUG2(dev_info(&ha->pdev->dev, | 343 | "Firmware Ready..\n")); |
| 239 | "scsi%ld: %s: DHCP STATE Enabled " | 344 | /* The firmware is ready to process SCSI |
| 240 | "%s\n", | 345 | commands. */ |
| 241 | ha->host_no, __func__, | 346 | DEBUG2(dev_info(&ha->pdev->dev, |
| 242 | (ha->addl_fw_state & | 347 | "scsi%ld: %s: MEDIA TYPE" |
| 243 | FW_ADDSTATE_DHCP_ENABLED) != 0 ? | 348 | " - %s\n", ha->host_no, |
| 244 | "YES" : "NO")); | 349 | __func__, (ha->addl_fw_state & |
| 245 | DEBUG2(dev_info(&ha->pdev->dev, | 350 | FW_ADDSTATE_OPTICAL_MEDIA) |
| 246 | "scsi%ld: %s: LINK %s\n", | 351 | != 0 ? "OPTICAL" : "COPPER")); |
| 247 | ha->host_no, __func__, | 352 | DEBUG2(dev_info(&ha->pdev->dev, |
| 248 | (ha->addl_fw_state & | 353 | "scsi%ld: %s: DHCPv4 STATE" |
| 249 | FW_ADDSTATE_LINK_UP) != 0 ? | 354 | " Enabled %s\n", ha->host_no, |
| 250 | "UP" : "DOWN")); | 355 | __func__, (ha->addl_fw_state & |
| 251 | DEBUG2(dev_info(&ha->pdev->dev, | 356 | FW_ADDSTATE_DHCPv4_ENABLED) != 0 ? |
| 252 | "scsi%ld: %s: iSNS Service " | 357 | "YES" : "NO")); |
| 253 | "Started %s\n", | 358 | DEBUG2(dev_info(&ha->pdev->dev, |
| 254 | ha->host_no, __func__, | 359 | "scsi%ld: %s: LINK %s\n", |
| 255 | (ha->addl_fw_state & | 360 | ha->host_no, __func__, |
| 256 | FW_ADDSTATE_ISNS_SVC_ENABLED) != 0 ? | 361 | (ha->addl_fw_state & |
| 257 | "YES" : "NO")); | 362 | FW_ADDSTATE_LINK_UP) != 0 ? |
| 258 | 363 | "UP" : "DOWN")); | |
| 259 | ready = 1; | 364 | DEBUG2(dev_info(&ha->pdev->dev, |
| 260 | break; | 365 | "scsi%ld: %s: iSNS Service " |
| 366 | "Started %s\n", | ||
| 367 | ha->host_no, __func__, | ||
| 368 | (ha->addl_fw_state & | ||
| 369 | FW_ADDSTATE_ISNS_SVC_ENABLED) != 0 ? | ||
| 370 | "YES" : "NO")); | ||
| 371 | |||
| 372 | ready = 1; | ||
| 373 | break; | ||
| 374 | } | ||
| 261 | } | 375 | } |
| 262 | DEBUG2(printk("scsi%ld: %s: waiting on fw, state=%x:%x - " | 376 | DEBUG2(printk("scsi%ld: %s: waiting on fw, state=%x:%x - " |
| 263 | "seconds expired= %d\n", ha->host_no, __func__, | 377 | "seconds expired= %d\n", ha->host_no, __func__, |
| @@ -272,15 +386,19 @@ static int qla4xxx_fw_ready(struct scsi_qla_host *ha) | |||
| 272 | msleep(1000); | 386 | msleep(1000); |
| 273 | } /* end of for */ | 387 | } /* end of for */ |
| 274 | 388 | ||
| 275 | if (timeout_count == 0) | 389 | if (timeout_count <= 0) |
| 276 | DEBUG2(printk("scsi%ld: %s: FW Initialization timed out!\n", | 390 | DEBUG2(printk("scsi%ld: %s: FW Initialization timed out!\n", |
| 277 | ha->host_no, __func__)); | 391 | ha->host_no, __func__)); |
| 278 | 392 | ||
| 279 | if (ha->firmware_state & FW_STATE_DHCP_IN_PROGRESS) { | 393 | if (ha->firmware_state & FW_STATE_CONFIGURING_IP) { |
| 280 | DEBUG2(printk("scsi%ld: %s: FW is reporting its waiting to" | 394 | DEBUG2(printk("scsi%ld: %s: FW initialized, but is reporting " |
| 281 | " grab an IP address from DHCP server\n", | 395 | "it's waiting to configure an IP address\n", |
| 282 | ha->host_no, __func__)); | 396 | ha->host_no, __func__)); |
| 283 | ready = 1; | 397 | ready = 1; |
| 398 | } else if (ha->firmware_state & FW_STATE_WAIT_AUTOCONNECT) { | ||
| 399 | DEBUG2(printk("scsi%ld: %s: FW initialized, but " | ||
| 400 | "auto-discovery still in process\n", | ||
| 401 | ha->host_no, __func__)); | ||
| 284 | } | 402 | } |
| 285 | 403 | ||
| 286 | return ready; | 404 | return ready; |
| @@ -387,6 +505,7 @@ static int qla4xxx_update_ddb_entry(struct scsi_qla_host *ha, | |||
| 387 | struct dev_db_entry *fw_ddb_entry = NULL; | 505 | struct dev_db_entry *fw_ddb_entry = NULL; |
| 388 | dma_addr_t fw_ddb_entry_dma; | 506 | dma_addr_t fw_ddb_entry_dma; |
| 389 | int status = QLA_ERROR; | 507 | int status = QLA_ERROR; |
| 508 | uint32_t conn_err; | ||
| 390 | 509 | ||
| 391 | if (ddb_entry == NULL) { | 510 | if (ddb_entry == NULL) { |
| 392 | DEBUG2(printk("scsi%ld: %s: ddb_entry is NULL\n", ha->host_no, | 511 | DEBUG2(printk("scsi%ld: %s: ddb_entry is NULL\n", ha->host_no, |
| @@ -407,7 +526,7 @@ static int qla4xxx_update_ddb_entry(struct scsi_qla_host *ha, | |||
| 407 | 526 | ||
| 408 | if (qla4xxx_get_fwddb_entry(ha, fw_ddb_index, fw_ddb_entry, | 527 | if (qla4xxx_get_fwddb_entry(ha, fw_ddb_index, fw_ddb_entry, |
| 409 | fw_ddb_entry_dma, NULL, NULL, | 528 | fw_ddb_entry_dma, NULL, NULL, |
| 410 | &ddb_entry->fw_ddb_device_state, NULL, | 529 | &ddb_entry->fw_ddb_device_state, &conn_err, |
| 411 | &ddb_entry->tcp_source_port_num, | 530 | &ddb_entry->tcp_source_port_num, |
| 412 | &ddb_entry->connection_id) == | 531 | &ddb_entry->connection_id) == |
| 413 | QLA_ERROR) { | 532 | QLA_ERROR) { |
| @@ -419,6 +538,7 @@ static int qla4xxx_update_ddb_entry(struct scsi_qla_host *ha, | |||
| 419 | } | 538 | } |
| 420 | 539 | ||
| 421 | status = QLA_SUCCESS; | 540 | status = QLA_SUCCESS; |
| 541 | ddb_entry->options = le16_to_cpu(fw_ddb_entry->options); | ||
| 422 | ddb_entry->target_session_id = le16_to_cpu(fw_ddb_entry->tsid); | 542 | ddb_entry->target_session_id = le16_to_cpu(fw_ddb_entry->tsid); |
| 423 | ddb_entry->task_mgmt_timeout = | 543 | ddb_entry->task_mgmt_timeout = |
| 424 | le16_to_cpu(fw_ddb_entry->def_timeout); | 544 | le16_to_cpu(fw_ddb_entry->def_timeout); |
| @@ -442,11 +562,44 @@ static int qla4xxx_update_ddb_entry(struct scsi_qla_host *ha, | |||
| 442 | memcpy(&ddb_entry->ip_addr[0], &fw_ddb_entry->ip_addr[0], | 562 | memcpy(&ddb_entry->ip_addr[0], &fw_ddb_entry->ip_addr[0], |
| 443 | min(sizeof(ddb_entry->ip_addr), sizeof(fw_ddb_entry->ip_addr))); | 563 | min(sizeof(ddb_entry->ip_addr), sizeof(fw_ddb_entry->ip_addr))); |
| 444 | 564 | ||
| 445 | DEBUG2(printk("scsi%ld: %s: ddb[%d] - State= %x status= %d.\n", | 565 | ddb_entry->iscsi_max_burst_len = fw_ddb_entry->iscsi_max_burst_len; |
| 446 | ha->host_no, __func__, fw_ddb_index, | 566 | ddb_entry->iscsi_max_outsnd_r2t = fw_ddb_entry->iscsi_max_outsnd_r2t; |
| 447 | ddb_entry->fw_ddb_device_state, status)); | 567 | ddb_entry->iscsi_first_burst_len = fw_ddb_entry->iscsi_first_burst_len; |
| 448 | 568 | ddb_entry->iscsi_max_rcv_data_seg_len = | |
| 449 | exit_update_ddb: | 569 | fw_ddb_entry->iscsi_max_rcv_data_seg_len; |
| 570 | ddb_entry->iscsi_max_snd_data_seg_len = | ||
| 571 | fw_ddb_entry->iscsi_max_snd_data_seg_len; | ||
| 572 | |||
| 573 | if (ddb_entry->options & DDB_OPT_IPV6_DEVICE) { | ||
| 574 | memcpy(&ddb_entry->remote_ipv6_addr, | ||
| 575 | fw_ddb_entry->ip_addr, | ||
| 576 | min(sizeof(ddb_entry->remote_ipv6_addr), | ||
| 577 | sizeof(fw_ddb_entry->ip_addr))); | ||
| 578 | memcpy(&ddb_entry->link_local_ipv6_addr, | ||
| 579 | fw_ddb_entry->link_local_ipv6_addr, | ||
| 580 | min(sizeof(ddb_entry->link_local_ipv6_addr), | ||
| 581 | sizeof(fw_ddb_entry->link_local_ipv6_addr))); | ||
| 582 | |||
| 583 | DEBUG2(dev_info(&ha->pdev->dev, "%s: DDB[%d] osIdx = %d " | ||
| 584 | "State %04x ConnErr %08x IP %pI6 " | ||
| 585 | ":%04d \"%s\"\n", | ||
| 586 | __func__, fw_ddb_index, | ||
| 587 | ddb_entry->os_target_id, | ||
| 588 | ddb_entry->fw_ddb_device_state, | ||
| 589 | conn_err, fw_ddb_entry->ip_addr, | ||
| 590 | le16_to_cpu(fw_ddb_entry->port), | ||
| 591 | fw_ddb_entry->iscsi_name)); | ||
| 592 | } else | ||
| 593 | DEBUG2(dev_info(&ha->pdev->dev, "%s: DDB[%d] osIdx = %d " | ||
| 594 | "State %04x ConnErr %08x IP %pI4 " | ||
| 595 | ":%04d \"%s\"\n", | ||
| 596 | __func__, fw_ddb_index, | ||
| 597 | ddb_entry->os_target_id, | ||
| 598 | ddb_entry->fw_ddb_device_state, | ||
| 599 | conn_err, fw_ddb_entry->ip_addr, | ||
| 600 | le16_to_cpu(fw_ddb_entry->port), | ||
| 601 | fw_ddb_entry->iscsi_name)); | ||
| 602 | exit_update_ddb: | ||
| 450 | if (fw_ddb_entry) | 603 | if (fw_ddb_entry) |
| 451 | dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry), | 604 | dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry), |
| 452 | fw_ddb_entry, fw_ddb_entry_dma); | 605 | fw_ddb_entry, fw_ddb_entry_dma); |
| @@ -492,6 +645,40 @@ static struct ddb_entry * qla4xxx_alloc_ddb(struct scsi_qla_host *ha, | |||
| 492 | } | 645 | } |
| 493 | 646 | ||
| 494 | /** | 647 | /** |
| 648 | * qla4_is_relogin_allowed - Are we allowed to login? | ||
| 649 | * @ha: Pointer to host adapter structure. | ||
| 650 | * @conn_err: Last connection error associated with the ddb | ||
| 651 | * | ||
| 652 | * This routine tests the given connection error to determine if | ||
| 653 | * we are allowed to login. | ||
| 654 | **/ | ||
| 655 | int qla4_is_relogin_allowed(struct scsi_qla_host *ha, uint32_t conn_err) | ||
| 656 | { | ||
| 657 | uint32_t err_code, login_rsp_sts_class; | ||
| 658 | int relogin = 1; | ||
| 659 | |||
| 660 | err_code = ((conn_err & 0x00ff0000) >> 16); | ||
| 661 | login_rsp_sts_class = ((conn_err & 0x0000ff00) >> 8); | ||
| 662 | if (err_code == 0x1c || err_code == 0x06) { | ||
| 663 | DEBUG2(dev_info(&ha->pdev->dev, | ||
| 664 | ": conn_err=0x%08x, send target completed" | ||
| 665 | " or access denied failure\n", conn_err)); | ||
| 666 | relogin = 0; | ||
| 667 | } | ||
| 668 | if ((err_code == 0x08) && (login_rsp_sts_class == 0x02)) { | ||
| 669 | /* Login Response PDU returned an error. | ||
| 670 | Login Response Status in Error Code Detail | ||
| 671 | indicates login should not be retried.*/ | ||
| 672 | DEBUG2(dev_info(&ha->pdev->dev, | ||
| 673 | ": conn_err=0x%08x, do not retry relogin\n", | ||
| 674 | conn_err)); | ||
| 675 | relogin = 0; | ||
| 676 | } | ||
| 677 | |||
| 678 | return relogin; | ||
| 679 | } | ||
| 680 | |||
| 681 | /** | ||
| 495 | * qla4xxx_configure_ddbs - builds driver ddb list | 682 | * qla4xxx_configure_ddbs - builds driver ddb list |
| 496 | * @ha: Pointer to host adapter structure. | 683 | * @ha: Pointer to host adapter structure. |
| 497 | * | 684 | * |
| @@ -505,18 +692,30 @@ static int qla4xxx_build_ddb_list(struct scsi_qla_host *ha) | |||
| 505 | uint32_t fw_ddb_index = 0; | 692 | uint32_t fw_ddb_index = 0; |
| 506 | uint32_t next_fw_ddb_index = 0; | 693 | uint32_t next_fw_ddb_index = 0; |
| 507 | uint32_t ddb_state; | 694 | uint32_t ddb_state; |
| 508 | uint32_t conn_err, err_code; | 695 | uint32_t conn_err; |
| 509 | struct ddb_entry *ddb_entry; | 696 | struct ddb_entry *ddb_entry; |
| 697 | struct dev_db_entry *fw_ddb_entry = NULL; | ||
| 698 | dma_addr_t fw_ddb_entry_dma; | ||
| 699 | uint32_t ipv6_device; | ||
| 510 | uint32_t new_tgt; | 700 | uint32_t new_tgt; |
| 511 | 701 | ||
| 702 | fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry), | ||
| 703 | &fw_ddb_entry_dma, GFP_KERNEL); | ||
| 704 | if (fw_ddb_entry == NULL) { | ||
| 705 | DEBUG2(dev_info(&ha->pdev->dev, "%s: DMA alloc failed\n", | ||
| 706 | __func__)); | ||
| 707 | return QLA_ERROR; | ||
| 708 | } | ||
| 709 | |||
| 512 | dev_info(&ha->pdev->dev, "Initializing DDBs ...\n"); | 710 | dev_info(&ha->pdev->dev, "Initializing DDBs ...\n"); |
| 513 | for (fw_ddb_index = 0; fw_ddb_index < MAX_DDB_ENTRIES; | 711 | for (fw_ddb_index = 0; fw_ddb_index < MAX_DDB_ENTRIES; |
| 514 | fw_ddb_index = next_fw_ddb_index) { | 712 | fw_ddb_index = next_fw_ddb_index) { |
| 515 | /* First, let's see if a device exists here */ | 713 | /* First, let's see if a device exists here */ |
| 516 | if (qla4xxx_get_fwddb_entry(ha, fw_ddb_index, NULL, 0, NULL, | 714 | if (qla4xxx_get_fwddb_entry(ha, fw_ddb_index, fw_ddb_entry, |
| 517 | &next_fw_ddb_index, &ddb_state, | 715 | 0, NULL, &next_fw_ddb_index, |
| 518 | &conn_err, NULL, NULL) == | 716 | &ddb_state, &conn_err, |
| 519 | QLA_ERROR) { | 717 | NULL, NULL) == |
| 718 | QLA_ERROR) { | ||
| 520 | DEBUG2(printk("scsi%ld: %s: get_ddb_entry, " | 719 | DEBUG2(printk("scsi%ld: %s: get_ddb_entry, " |
| 521 | "fw_ddb_index %d failed", ha->host_no, | 720 | "fw_ddb_index %d failed", ha->host_no, |
| 522 | __func__, fw_ddb_index)); | 721 | __func__, fw_ddb_index)); |
| @@ -533,18 +732,19 @@ static int qla4xxx_build_ddb_list(struct scsi_qla_host *ha) | |||
| 533 | /* Try and login to device */ | 732 | /* Try and login to device */ |
| 534 | DEBUG2(printk("scsi%ld: %s: Login to DDB[%d]\n", | 733 | DEBUG2(printk("scsi%ld: %s: Login to DDB[%d]\n", |
| 535 | ha->host_no, __func__, fw_ddb_index)); | 734 | ha->host_no, __func__, fw_ddb_index)); |
| 536 | err_code = ((conn_err & 0x00ff0000) >> 16); | 735 | ipv6_device = le16_to_cpu(fw_ddb_entry->options) & |
| 537 | if (err_code == 0x1c || err_code == 0x06) { | 736 | DDB_OPT_IPV6_DEVICE; |
| 538 | DEBUG2(printk("scsi%ld: %s send target " | 737 | if (qla4_is_relogin_allowed(ha, conn_err) && |
| 539 | "completed " | 738 | ((!ipv6_device && |
| 540 | "or access denied failure\n", | 739 | *((uint32_t *)fw_ddb_entry->ip_addr)) |
| 541 | ha->host_no, __func__)); | 740 | || ipv6_device)) { |
| 542 | } else { | ||
| 543 | qla4xxx_set_ddb_entry(ha, fw_ddb_index, 0); | 741 | qla4xxx_set_ddb_entry(ha, fw_ddb_index, 0); |
| 544 | if (qla4xxx_get_fwddb_entry(ha, fw_ddb_index, | 742 | if (qla4xxx_get_fwddb_entry(ha, fw_ddb_index, |
| 545 | NULL, 0, NULL, &next_fw_ddb_index, | 743 | NULL, 0, NULL, |
| 546 | &ddb_state, &conn_err, NULL, NULL) | 744 | &next_fw_ddb_index, |
| 547 | == QLA_ERROR) { | 745 | &ddb_state, &conn_err, |
| 746 | NULL, NULL) | ||
| 747 | == QLA_ERROR) { | ||
| 548 | DEBUG2(printk("scsi%ld: %s:" | 748 | DEBUG2(printk("scsi%ld: %s:" |
| 549 | "get_ddb_entry %d failed\n", | 749 | "get_ddb_entry %d failed\n", |
| 550 | ha->host_no, | 750 | ha->host_no, |
| @@ -599,7 +799,6 @@ next_one: | |||
| 599 | struct qla4_relog_scan { | 799 | struct qla4_relog_scan { |
| 600 | int halt_wait; | 800 | int halt_wait; |
| 601 | uint32_t conn_err; | 801 | uint32_t conn_err; |
| 602 | uint32_t err_code; | ||
| 603 | uint32_t fw_ddb_index; | 802 | uint32_t fw_ddb_index; |
| 604 | uint32_t next_fw_ddb_index; | 803 | uint32_t next_fw_ddb_index; |
| 605 | uint32_t fw_ddb_device_state; | 804 | uint32_t fw_ddb_device_state; |
| @@ -609,18 +808,7 @@ static int qla4_test_rdy(struct scsi_qla_host *ha, struct qla4_relog_scan *rs) | |||
| 609 | { | 808 | { |
| 610 | struct ddb_entry *ddb_entry; | 809 | struct ddb_entry *ddb_entry; |
| 611 | 810 | ||
| 612 | /* | 811 | if (qla4_is_relogin_allowed(ha, rs->conn_err)) { |
| 613 | * Don't want to do a relogin if connection | ||
| 614 | * error is 0x1c. | ||
| 615 | */ | ||
| 616 | rs->err_code = ((rs->conn_err & 0x00ff0000) >> 16); | ||
| 617 | if (rs->err_code == 0x1c || rs->err_code == 0x06) { | ||
| 618 | DEBUG2(printk( | ||
| 619 | "scsi%ld: %s send target" | ||
| 620 | " completed or " | ||
| 621 | "access denied failure\n", | ||
| 622 | ha->host_no, __func__)); | ||
| 623 | } else { | ||
| 624 | /* We either have a device that is in | 812 | /* We either have a device that is in |
| 625 | * the process of relogging in or a | 813 | * the process of relogging in or a |
| 626 | * device that is waiting to be | 814 | * device that is waiting to be |
| @@ -908,7 +1096,7 @@ static void qla4x00_pci_config(struct scsi_qla_host *ha) | |||
| 908 | static int qla4xxx_start_firmware_from_flash(struct scsi_qla_host *ha) | 1096 | static int qla4xxx_start_firmware_from_flash(struct scsi_qla_host *ha) |
| 909 | { | 1097 | { |
| 910 | int status = QLA_ERROR; | 1098 | int status = QLA_ERROR; |
| 911 | uint32_t max_wait_time; | 1099 | unsigned long max_wait_time; |
| 912 | unsigned long flags; | 1100 | unsigned long flags; |
| 913 | uint32_t mbox_status; | 1101 | uint32_t mbox_status; |
| 914 | 1102 | ||
| @@ -940,7 +1128,10 @@ static int qla4xxx_start_firmware_from_flash(struct scsi_qla_host *ha) | |||
| 940 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 1128 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
| 941 | 1129 | ||
| 942 | /* Wait for firmware to come UP. */ | 1130 | /* Wait for firmware to come UP. */ |
| 943 | max_wait_time = FIRMWARE_UP_TOV * 4; | 1131 | DEBUG2(printk(KERN_INFO "scsi%ld: %s: Wait up to %d seconds for " |
| 1132 | "boot firmware to complete...\n", | ||
| 1133 | ha->host_no, __func__, FIRMWARE_UP_TOV)); | ||
| 1134 | max_wait_time = jiffies + (FIRMWARE_UP_TOV * HZ); | ||
| 944 | do { | 1135 | do { |
| 945 | uint32_t ctrl_status; | 1136 | uint32_t ctrl_status; |
| 946 | 1137 | ||
| @@ -954,16 +1145,15 @@ static int qla4xxx_start_firmware_from_flash(struct scsi_qla_host *ha) | |||
| 954 | if (mbox_status == MBOX_STS_COMMAND_COMPLETE) | 1145 | if (mbox_status == MBOX_STS_COMMAND_COMPLETE) |
| 955 | break; | 1146 | break; |
| 956 | 1147 | ||
| 957 | DEBUG2(printk("scsi%ld: %s: Waiting for boot firmware to " | 1148 | DEBUG2(printk(KERN_INFO "scsi%ld: %s: Waiting for boot " |
| 958 | "complete... ctrl_sts=0x%x, remaining=%d\n", | 1149 | "firmware to complete... ctrl_sts=0x%x\n", |
| 959 | ha->host_no, __func__, ctrl_status, | 1150 | ha->host_no, __func__, ctrl_status)); |
| 960 | max_wait_time)); | ||
| 961 | 1151 | ||
| 962 | msleep(250); | 1152 | msleep_interruptible(250); |
| 963 | } while ((max_wait_time--)); | 1153 | } while (!time_after_eq(jiffies, max_wait_time)); |
| 964 | 1154 | ||
| 965 | if (mbox_status == MBOX_STS_COMMAND_COMPLETE) { | 1155 | if (mbox_status == MBOX_STS_COMMAND_COMPLETE) { |
| 966 | DEBUG(printk("scsi%ld: %s: Firmware has started\n", | 1156 | DEBUG(printk(KERN_INFO "scsi%ld: %s: Firmware has started\n", |
| 967 | ha->host_no, __func__)); | 1157 | ha->host_no, __func__)); |
| 968 | 1158 | ||
| 969 | spin_lock_irqsave(&ha->hardware_lock, flags); | 1159 | spin_lock_irqsave(&ha->hardware_lock, flags); |
| @@ -1141,6 +1331,7 @@ int qla4xxx_initialize_adapter(struct scsi_qla_host *ha, | |||
| 1141 | int status = QLA_ERROR; | 1331 | int status = QLA_ERROR; |
| 1142 | int8_t ip_address[IP_ADDR_LEN] = {0} ; | 1332 | int8_t ip_address[IP_ADDR_LEN] = {0} ; |
| 1143 | 1333 | ||
| 1334 | clear_bit(AF_ONLINE, &ha->flags); | ||
| 1144 | ha->eeprom_cmd_data = 0; | 1335 | ha->eeprom_cmd_data = 0; |
| 1145 | 1336 | ||
| 1146 | qla4x00_pci_config(ha); | 1337 | qla4x00_pci_config(ha); |
| @@ -1166,7 +1357,7 @@ int qla4xxx_initialize_adapter(struct scsi_qla_host *ha, | |||
| 1166 | * the ddb_list and wait for DHCP lease acquired aen to come in | 1357 | * the ddb_list and wait for DHCP lease acquired aen to come in |
| 1167 | * followed by 0x8014 aen" to trigger the tgt discovery process. | 1358 | * followed by 0x8014 aen" to trigger the tgt discovery process. |
| 1168 | */ | 1359 | */ |
| 1169 | if (ha->firmware_state & FW_STATE_DHCP_IN_PROGRESS) | 1360 | if (ha->firmware_state & FW_STATE_CONFIGURING_IP) |
| 1170 | goto exit_init_online; | 1361 | goto exit_init_online; |
| 1171 | 1362 | ||
| 1172 | /* Skip device discovery if ip and subnet is zero */ | 1363 | /* Skip device discovery if ip and subnet is zero */ |
| @@ -1270,8 +1461,8 @@ static void qla4xxx_add_device_dynamically(struct scsi_qla_host *ha, | |||
| 1270 | * | 1461 | * |
| 1271 | * This routine processes a Decive Database Changed AEN Event. | 1462 | * This routine processes a Decive Database Changed AEN Event. |
| 1272 | **/ | 1463 | **/ |
| 1273 | int qla4xxx_process_ddb_changed(struct scsi_qla_host *ha, | 1464 | int qla4xxx_process_ddb_changed(struct scsi_qla_host *ha, uint32_t fw_ddb_index, |
| 1274 | uint32_t fw_ddb_index, uint32_t state) | 1465 | uint32_t state, uint32_t conn_err) |
| 1275 | { | 1466 | { |
| 1276 | struct ddb_entry * ddb_entry; | 1467 | struct ddb_entry * ddb_entry; |
| 1277 | uint32_t old_fw_ddb_device_state; | 1468 | uint32_t old_fw_ddb_device_state; |
| @@ -1318,19 +1509,24 @@ int qla4xxx_process_ddb_changed(struct scsi_qla_host *ha, | |||
| 1318 | * the device came back. | 1509 | * the device came back. |
| 1319 | */ | 1510 | */ |
| 1320 | } else { | 1511 | } else { |
| 1321 | /* Device went away, try to relogin. */ | 1512 | /* Device went away, mark device missing */ |
| 1322 | /* Mark device missing */ | 1513 | if (atomic_read(&ddb_entry->state) == DDB_STATE_ONLINE) { |
| 1323 | if (atomic_read(&ddb_entry->state) == DDB_STATE_ONLINE) | 1514 | DEBUG2(dev_info(&ha->pdev->dev, "%s mark missing " |
| 1515 | "ddb_entry 0x%p sess 0x%p conn 0x%p\n", | ||
| 1516 | __func__, ddb_entry, | ||
| 1517 | ddb_entry->sess, ddb_entry->conn)); | ||
| 1324 | qla4xxx_mark_device_missing(ha, ddb_entry); | 1518 | qla4xxx_mark_device_missing(ha, ddb_entry); |
| 1519 | } | ||
| 1520 | |||
| 1325 | /* | 1521 | /* |
| 1326 | * Relogin if device state changed to a not active state. | 1522 | * Relogin if device state changed to a not active state. |
| 1327 | * However, do not relogin if this aen is a result of an IOCTL | 1523 | * However, do not relogin if a RELOGIN is in process, or |
| 1328 | * logout (DF_NO_RELOGIN) or if this is a discovered device. | 1524 | * we are not allowed to relogin to this DDB. |
| 1329 | */ | 1525 | */ |
| 1330 | if (ddb_entry->fw_ddb_device_state == DDB_DS_SESSION_FAILED && | 1526 | if (ddb_entry->fw_ddb_device_state == DDB_DS_SESSION_FAILED && |
| 1331 | !test_bit(DF_RELOGIN, &ddb_entry->flags) && | 1527 | !test_bit(DF_RELOGIN, &ddb_entry->flags) && |
| 1332 | !test_bit(DF_NO_RELOGIN, &ddb_entry->flags) && | 1528 | !test_bit(DF_NO_RELOGIN, &ddb_entry->flags) && |
| 1333 | !test_bit(DF_ISNS_DISCOVERED, &ddb_entry->flags)) { | 1529 | qla4_is_relogin_allowed(ha, conn_err)) { |
| 1334 | /* | 1530 | /* |
| 1335 | * This triggers a relogin. After the relogin_timer | 1531 | * This triggers a relogin. After the relogin_timer |
| 1336 | * expires, the relogin gets scheduled. We must wait a | 1532 | * expires, the relogin gets scheduled. We must wait a |
| @@ -1338,7 +1534,7 @@ int qla4xxx_process_ddb_changed(struct scsi_qla_host *ha, | |||
| 1338 | * with failed device_state or a logout response before | 1534 | * with failed device_state or a logout response before |
| 1339 | * we can issue another relogin. | 1535 | * we can issue another relogin. |
| 1340 | */ | 1536 | */ |
| 1341 | /* Firmware padds this timeout: (time2wait +1). | 1537 | /* Firmware pads this timeout: (time2wait +1). |
| 1342 | * Driver retry to login should be longer than F/W. | 1538 | * Driver retry to login should be longer than F/W. |
| 1343 | * Otherwise F/W will fail | 1539 | * Otherwise F/W will fail |
| 1344 | * set_ddb() mbx cmd with 0x4005 since it still | 1540 | * set_ddb() mbx cmd with 0x4005 since it still |
