diff options
Diffstat (limited to 'drivers/scsi/qla4xxx/ql4_os.c')
-rw-r--r-- | drivers/scsi/qla4xxx/ql4_os.c | 262 |
1 files changed, 171 insertions, 91 deletions
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c index 519f6667dc0..3e0e5de2c33 100644 --- a/drivers/scsi/qla4xxx/ql4_os.c +++ b/drivers/scsi/qla4xxx/ql4_os.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include "ql4_glbl.h" | 18 | #include "ql4_glbl.h" |
19 | #include "ql4_dbg.h" | 19 | #include "ql4_dbg.h" |
20 | #include "ql4_inline.h" | 20 | #include "ql4_inline.h" |
21 | #include "ql4_83xx.h" | ||
21 | 22 | ||
22 | /* | 23 | /* |
23 | * Driver version | 24 | * Driver version |
@@ -2315,8 +2316,17 @@ static void qla4xxx_mem_free(struct scsi_qla_host *ha) | |||
2315 | if (ha->nx_pcibase) | 2316 | if (ha->nx_pcibase) |
2316 | iounmap( | 2317 | iounmap( |
2317 | (struct device_reg_82xx __iomem *)ha->nx_pcibase); | 2318 | (struct device_reg_82xx __iomem *)ha->nx_pcibase); |
2318 | } else if (ha->reg) | 2319 | } else if (is_qla8032(ha)) { |
2320 | if (ha->nx_pcibase) | ||
2321 | iounmap( | ||
2322 | (struct device_reg_83xx __iomem *)ha->nx_pcibase); | ||
2323 | } else if (ha->reg) { | ||
2319 | iounmap(ha->reg); | 2324 | iounmap(ha->reg); |
2325 | } | ||
2326 | |||
2327 | if (ha->reset_tmplt.buff) | ||
2328 | vfree(ha->reset_tmplt.buff); | ||
2329 | |||
2320 | pci_release_regions(ha->pdev); | 2330 | pci_release_regions(ha->pdev); |
2321 | } | 2331 | } |
2322 | 2332 | ||
@@ -2454,7 +2464,6 @@ static int qla4_8xxx_check_temp(struct scsi_qla_host *ha) | |||
2454 | static int qla4_8xxx_check_fw_alive(struct scsi_qla_host *ha) | 2464 | static int qla4_8xxx_check_fw_alive(struct scsi_qla_host *ha) |
2455 | { | 2465 | { |
2456 | uint32_t fw_heartbeat_counter; | 2466 | uint32_t fw_heartbeat_counter; |
2457 | uint32_t halt_status1, halt_status2; | ||
2458 | int status = QLA_SUCCESS; | 2467 | int status = QLA_SUCCESS; |
2459 | 2468 | ||
2460 | fw_heartbeat_counter = qla4_8xxx_rd_direct(ha, | 2469 | fw_heartbeat_counter = qla4_8xxx_rd_direct(ha, |
@@ -2472,28 +2481,7 @@ static int qla4_8xxx_check_fw_alive(struct scsi_qla_host *ha) | |||
2472 | /* FW not alive after 2 seconds */ | 2481 | /* FW not alive after 2 seconds */ |
2473 | if (ha->seconds_since_last_heartbeat == 2) { | 2482 | if (ha->seconds_since_last_heartbeat == 2) { |
2474 | ha->seconds_since_last_heartbeat = 0; | 2483 | ha->seconds_since_last_heartbeat = 0; |
2475 | halt_status1 = qla4_8xxx_rd_direct(ha, | 2484 | qla4_8xxx_dump_peg_reg(ha); |
2476 | QLA8XXX_PEG_HALT_STATUS1); | ||
2477 | halt_status2 = qla4_8xxx_rd_direct(ha, | ||
2478 | QLA8XXX_PEG_HALT_STATUS2); | ||
2479 | |||
2480 | ql4_printk(KERN_INFO, ha, | ||
2481 | "scsi(%ld): %s, Dumping hw/fw registers:\n " | ||
2482 | " PEG_HALT_STATUS1: 0x%x, PEG_HALT_STATUS2:" | ||
2483 | " 0x%x,\n PEG_NET_0_PC: 0x%x, PEG_NET_1_PC:" | ||
2484 | " 0x%x,\n PEG_NET_2_PC: 0x%x, PEG_NET_3_PC:" | ||
2485 | " 0x%x,\n PEG_NET_4_PC: 0x%x\n", ha->host_no, | ||
2486 | __func__, halt_status1, halt_status2, | ||
2487 | qla4_82xx_rd_32(ha, QLA82XX_CRB_PEG_NET_0 + | ||
2488 | 0x3c), | ||
2489 | qla4_82xx_rd_32(ha, QLA82XX_CRB_PEG_NET_1 + | ||
2490 | 0x3c), | ||
2491 | qla4_82xx_rd_32(ha, QLA82XX_CRB_PEG_NET_2 + | ||
2492 | 0x3c), | ||
2493 | qla4_82xx_rd_32(ha, QLA82XX_CRB_PEG_NET_3 + | ||
2494 | 0x3c), | ||
2495 | qla4_82xx_rd_32(ha, QLA82XX_CRB_PEG_NET_4 + | ||
2496 | 0x3c)); | ||
2497 | status = QLA_ERROR; | 2485 | status = QLA_ERROR; |
2498 | } | 2486 | } |
2499 | } else | 2487 | } else |
@@ -2503,6 +2491,48 @@ static int qla4_8xxx_check_fw_alive(struct scsi_qla_host *ha) | |||
2503 | return status; | 2491 | return status; |
2504 | } | 2492 | } |
2505 | 2493 | ||
2494 | static void qla4_8xxx_process_fw_error(struct scsi_qla_host *ha) | ||
2495 | { | ||
2496 | uint32_t halt_status; | ||
2497 | int halt_status_unrecoverable = 0; | ||
2498 | |||
2499 | halt_status = qla4_8xxx_rd_direct(ha, QLA8XXX_PEG_HALT_STATUS1); | ||
2500 | |||
2501 | if (is_qla8022(ha)) { | ||
2502 | ql4_printk(KERN_INFO, ha, "%s: disabling pause transmit on port 0 & 1.\n", | ||
2503 | __func__); | ||
2504 | qla4_82xx_wr_32(ha, QLA82XX_CRB_NIU + 0x98, | ||
2505 | CRB_NIU_XG_PAUSE_CTL_P0 | | ||
2506 | CRB_NIU_XG_PAUSE_CTL_P1); | ||
2507 | |||
2508 | if (QLA82XX_FWERROR_CODE(halt_status) == 0x67) | ||
2509 | ql4_printk(KERN_ERR, ha, "%s: Firmware aborted with error code 0x00006700. Device is being reset\n", | ||
2510 | __func__); | ||
2511 | if (halt_status & HALT_STATUS_UNRECOVERABLE) | ||
2512 | halt_status_unrecoverable = 1; | ||
2513 | } else if (is_qla8032(ha)) { | ||
2514 | if (halt_status & QLA83XX_HALT_STATUS_FW_RESET) | ||
2515 | ql4_printk(KERN_ERR, ha, "%s: Firmware error detected device is being reset\n", | ||
2516 | __func__); | ||
2517 | else if (halt_status & QLA83XX_HALT_STATUS_UNRECOVERABLE) | ||
2518 | halt_status_unrecoverable = 1; | ||
2519 | } | ||
2520 | |||
2521 | /* | ||
2522 | * Since we cannot change dev_state in interrupt context, | ||
2523 | * set appropriate DPC flag then wakeup DPC | ||
2524 | */ | ||
2525 | if (halt_status_unrecoverable) { | ||
2526 | set_bit(DPC_HA_UNRECOVERABLE, &ha->dpc_flags); | ||
2527 | } else { | ||
2528 | ql4_printk(KERN_INFO, ha, "%s: detect abort needed!\n", | ||
2529 | __func__); | ||
2530 | set_bit(DPC_RESET_HA, &ha->dpc_flags); | ||
2531 | } | ||
2532 | qla4xxx_mailbox_premature_completion(ha); | ||
2533 | qla4xxx_wake_dpc(ha); | ||
2534 | } | ||
2535 | |||
2506 | /** | 2536 | /** |
2507 | * qla4_8xxx_watchdog - Poll dev state | 2537 | * qla4_8xxx_watchdog - Poll dev state |
2508 | * @ha: Pointer to host adapter structure. | 2538 | * @ha: Pointer to host adapter structure. |
@@ -2511,7 +2541,7 @@ static int qla4_8xxx_check_fw_alive(struct scsi_qla_host *ha) | |||
2511 | **/ | 2541 | **/ |
2512 | void qla4_8xxx_watchdog(struct scsi_qla_host *ha) | 2542 | void qla4_8xxx_watchdog(struct scsi_qla_host *ha) |
2513 | { | 2543 | { |
2514 | uint32_t dev_state, halt_status; | 2544 | uint32_t dev_state; |
2515 | 2545 | ||
2516 | /* don't poll if reset is going on */ | 2546 | /* don't poll if reset is going on */ |
2517 | if (!(test_bit(DPC_RESET_ACTIVE, &ha->dpc_flags) || | 2547 | if (!(test_bit(DPC_RESET_ACTIVE, &ha->dpc_flags) || |
@@ -2520,16 +2550,18 @@ void qla4_8xxx_watchdog(struct scsi_qla_host *ha) | |||
2520 | dev_state = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DEV_STATE); | 2550 | dev_state = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DEV_STATE); |
2521 | 2551 | ||
2522 | if (qla4_8xxx_check_temp(ha)) { | 2552 | if (qla4_8xxx_check_temp(ha)) { |
2523 | ql4_printk(KERN_INFO, ha, "disabling pause" | 2553 | if (is_qla8022(ha)) { |
2524 | " transmit on port 0 & 1.\n"); | 2554 | ql4_printk(KERN_INFO, ha, "disabling pause transmit on port 0 & 1.\n"); |
2525 | qla4_82xx_wr_32(ha, QLA82XX_CRB_NIU + 0x98, | 2555 | qla4_82xx_wr_32(ha, QLA82XX_CRB_NIU + 0x98, |
2526 | CRB_NIU_XG_PAUSE_CTL_P0 | | 2556 | CRB_NIU_XG_PAUSE_CTL_P0 | |
2527 | CRB_NIU_XG_PAUSE_CTL_P1); | 2557 | CRB_NIU_XG_PAUSE_CTL_P1); |
2558 | } | ||
2528 | set_bit(DPC_HA_UNRECOVERABLE, &ha->dpc_flags); | 2559 | set_bit(DPC_HA_UNRECOVERABLE, &ha->dpc_flags); |
2529 | qla4xxx_wake_dpc(ha); | 2560 | qla4xxx_wake_dpc(ha); |
2530 | } else if (dev_state == QLA8XXX_DEV_NEED_RESET && | 2561 | } else if (dev_state == QLA8XXX_DEV_NEED_RESET && |
2531 | !test_bit(DPC_RESET_HA, &ha->dpc_flags)) { | 2562 | !test_bit(DPC_RESET_HA, &ha->dpc_flags)) { |
2532 | if (!ql4xdontresethba) { | 2563 | if (is_qla8032(ha) || |
2564 | (is_qla8022(ha) && !ql4xdontresethba)) { | ||
2533 | ql4_printk(KERN_INFO, ha, "%s: HW State: " | 2565 | ql4_printk(KERN_INFO, ha, "%s: HW State: " |
2534 | "NEED RESET!\n", __func__); | 2566 | "NEED RESET!\n", __func__); |
2535 | set_bit(DPC_RESET_HA, &ha->dpc_flags); | 2567 | set_bit(DPC_RESET_HA, &ha->dpc_flags); |
@@ -2543,36 +2575,8 @@ void qla4_8xxx_watchdog(struct scsi_qla_host *ha) | |||
2543 | qla4xxx_wake_dpc(ha); | 2575 | qla4xxx_wake_dpc(ha); |
2544 | } else { | 2576 | } else { |
2545 | /* Check firmware health */ | 2577 | /* Check firmware health */ |
2546 | if (qla4_8xxx_check_fw_alive(ha)) { | 2578 | if (qla4_8xxx_check_fw_alive(ha)) |
2547 | ql4_printk(KERN_INFO, ha, "disabling pause" | 2579 | qla4_8xxx_process_fw_error(ha); |
2548 | " transmit on port 0 & 1.\n"); | ||
2549 | qla4_82xx_wr_32(ha, QLA82XX_CRB_NIU + 0x98, | ||
2550 | CRB_NIU_XG_PAUSE_CTL_P0 | | ||
2551 | CRB_NIU_XG_PAUSE_CTL_P1); | ||
2552 | halt_status = qla4_8xxx_rd_direct(ha, | ||
2553 | QLA8XXX_PEG_HALT_STATUS1); | ||
2554 | |||
2555 | if (QLA82XX_FWERROR_CODE(halt_status) == 0x67) | ||
2556 | ql4_printk(KERN_ERR, ha, "%s:" | ||
2557 | " Firmware aborted with" | ||
2558 | " error code 0x00006700." | ||
2559 | " Device is being reset\n", | ||
2560 | __func__); | ||
2561 | |||
2562 | /* Since we cannot change dev_state in interrupt | ||
2563 | * context, set appropriate DPC flag then wakeup | ||
2564 | * DPC */ | ||
2565 | if (halt_status & HALT_STATUS_UNRECOVERABLE) | ||
2566 | set_bit(DPC_HA_UNRECOVERABLE, | ||
2567 | &ha->dpc_flags); | ||
2568 | else { | ||
2569 | ql4_printk(KERN_INFO, ha, "%s: detect " | ||
2570 | "abort needed!\n", __func__); | ||
2571 | set_bit(DPC_RESET_HA, &ha->dpc_flags); | ||
2572 | } | ||
2573 | qla4xxx_mailbox_premature_completion(ha); | ||
2574 | qla4xxx_wake_dpc(ha); | ||
2575 | } | ||
2576 | } | 2580 | } |
2577 | } | 2581 | } |
2578 | } | 2582 | } |
@@ -2654,9 +2658,8 @@ static void qla4xxx_timer(struct scsi_qla_host *ha) | |||
2654 | if (!pci_channel_offline(ha->pdev)) | 2658 | if (!pci_channel_offline(ha->pdev)) |
2655 | pci_read_config_word(ha->pdev, PCI_VENDOR_ID, &w); | 2659 | pci_read_config_word(ha->pdev, PCI_VENDOR_ID, &w); |
2656 | 2660 | ||
2657 | if (is_qla8022(ha)) { | 2661 | if (is_qla80XX(ha)) |
2658 | qla4_8xxx_watchdog(ha); | 2662 | qla4_8xxx_watchdog(ha); |
2659 | } | ||
2660 | 2663 | ||
2661 | if (is_qla40XX(ha)) { | 2664 | if (is_qla40XX(ha)) { |
2662 | /* Check for heartbeat interval. */ | 2665 | /* Check for heartbeat interval. */ |
@@ -2955,9 +2958,9 @@ static int qla4xxx_recover_adapter(struct scsi_qla_host *ha) | |||
2955 | goto recover_ha_init_adapter; | 2958 | goto recover_ha_init_adapter; |
2956 | } | 2959 | } |
2957 | 2960 | ||
2958 | /* For the ISP-82xx adapter, issue a stop_firmware if invoked | 2961 | /* For the ISP-8xxx adapter, issue a stop_firmware if invoked |
2959 | * from eh_host_reset or ioctl module */ | 2962 | * from eh_host_reset or ioctl module */ |
2960 | if (is_qla8022(ha) && !reset_chip && | 2963 | if (is_qla80XX(ha) && !reset_chip && |
2961 | test_bit(DPC_RESET_HA_FW_CONTEXT, &ha->dpc_flags)) { | 2964 | test_bit(DPC_RESET_HA_FW_CONTEXT, &ha->dpc_flags)) { |
2962 | 2965 | ||
2963 | DEBUG2(ql4_printk(KERN_INFO, ha, | 2966 | DEBUG2(ql4_printk(KERN_INFO, ha, |
@@ -2980,13 +2983,13 @@ static int qla4xxx_recover_adapter(struct scsi_qla_host *ha) | |||
2980 | } | 2983 | } |
2981 | 2984 | ||
2982 | /* Issue full chip reset if recovering from a catastrophic error, | 2985 | /* Issue full chip reset if recovering from a catastrophic error, |
2983 | * or if stop_firmware fails for ISP-82xx. | 2986 | * or if stop_firmware fails for ISP-8xxx. |
2984 | * This is the default case for ISP-4xxx */ | 2987 | * This is the default case for ISP-4xxx */ |
2985 | if (is_qla40XX(ha) || reset_chip) { | 2988 | if (is_qla40XX(ha) || reset_chip) { |
2986 | if (is_qla40XX(ha)) | 2989 | if (is_qla40XX(ha)) |
2987 | goto chip_reset; | 2990 | goto chip_reset; |
2988 | 2991 | ||
2989 | /* Check if 82XX firmware is alive or not | 2992 | /* Check if 8XXX firmware is alive or not |
2990 | * We may have arrived here from NEED_RESET | 2993 | * We may have arrived here from NEED_RESET |
2991 | * detection only */ | 2994 | * detection only */ |
2992 | if (test_bit(AF_FW_RECOVERY, &ha->flags)) | 2995 | if (test_bit(AF_FW_RECOVERY, &ha->flags)) |
@@ -3041,7 +3044,7 @@ recover_ha_init_adapter: | |||
3041 | * Since we don't want to block the DPC for too long | 3044 | * Since we don't want to block the DPC for too long |
3042 | * with multiple resets in the same thread, | 3045 | * with multiple resets in the same thread, |
3043 | * utilize DPC to retry */ | 3046 | * utilize DPC to retry */ |
3044 | if (is_qla8022(ha)) { | 3047 | if (is_qla80XX(ha)) { |
3045 | ha->isp_ops->idc_lock(ha); | 3048 | ha->isp_ops->idc_lock(ha); |
3046 | dev_state = qla4_8xxx_rd_direct(ha, | 3049 | dev_state = qla4_8xxx_rd_direct(ha, |
3047 | QLA8XXX_CRB_DEV_STATE); | 3050 | QLA8XXX_CRB_DEV_STATE); |
@@ -3386,7 +3389,7 @@ static void qla4xxx_do_dpc(struct work_struct *work) | |||
3386 | /* post events to application */ | 3389 | /* post events to application */ |
3387 | qla4xxx_do_work(ha); | 3390 | qla4xxx_do_work(ha); |
3388 | 3391 | ||
3389 | if (is_qla8022(ha)) { | 3392 | if (is_qla80XX(ha)) { |
3390 | if (test_bit(DPC_HA_UNRECOVERABLE, &ha->dpc_flags)) { | 3393 | if (test_bit(DPC_HA_UNRECOVERABLE, &ha->dpc_flags)) { |
3391 | ha->isp_ops->idc_lock(ha); | 3394 | ha->isp_ops->idc_lock(ha); |
3392 | qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE, | 3395 | qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE, |
@@ -3404,7 +3407,8 @@ static void qla4xxx_do_dpc(struct work_struct *work) | |||
3404 | (test_bit(DPC_RESET_HA, &ha->dpc_flags) || | 3407 | (test_bit(DPC_RESET_HA, &ha->dpc_flags) || |
3405 | test_bit(DPC_RESET_HA_INTR, &ha->dpc_flags) || | 3408 | test_bit(DPC_RESET_HA_INTR, &ha->dpc_flags) || |
3406 | test_bit(DPC_RESET_HA_FW_CONTEXT, &ha->dpc_flags))) { | 3409 | test_bit(DPC_RESET_HA_FW_CONTEXT, &ha->dpc_flags))) { |
3407 | if (ql4xdontresethba) { | 3410 | if ((is_qla8022(ha) && ql4xdontresethba) || |
3411 | (is_qla8032(ha) && qla4_83xx_idc_dontreset(ha))) { | ||
3408 | DEBUG2(printk("scsi%ld: %s: Don't Reset HBA\n", | 3412 | DEBUG2(printk("scsi%ld: %s: Don't Reset HBA\n", |
3409 | ha->host_no, __func__)); | 3413 | ha->host_no, __func__)); |
3410 | clear_bit(DPC_RESET_HA, &ha->dpc_flags); | 3414 | clear_bit(DPC_RESET_HA, &ha->dpc_flags); |
@@ -3514,7 +3518,7 @@ static void qla4xxx_free_adapter(struct scsi_qla_host *ha) | |||
3514 | /* Put firmware in known state */ | 3518 | /* Put firmware in known state */ |
3515 | ha->isp_ops->reset_firmware(ha); | 3519 | ha->isp_ops->reset_firmware(ha); |
3516 | 3520 | ||
3517 | if (is_qla8022(ha)) { | 3521 | if (is_qla80XX(ha)) { |
3518 | ha->isp_ops->idc_lock(ha); | 3522 | ha->isp_ops->idc_lock(ha); |
3519 | qla4_8xxx_clear_drv_active(ha); | 3523 | qla4_8xxx_clear_drv_active(ha); |
3520 | ha->isp_ops->idc_unlock(ha); | 3524 | ha->isp_ops->idc_unlock(ha); |
@@ -3564,16 +3568,20 @@ int qla4_8xxx_iospace_config(struct scsi_qla_host *ha) | |||
3564 | /* Mapping of IO base pointer, door bell read and write pointer */ | 3568 | /* Mapping of IO base pointer, door bell read and write pointer */ |
3565 | 3569 | ||
3566 | /* mapping of IO base pointer */ | 3570 | /* mapping of IO base pointer */ |
3567 | ha->qla4_82xx_reg = | 3571 | if (is_qla8022(ha)) { |
3568 | (struct device_reg_82xx __iomem *)((uint8_t *)ha->nx_pcibase + | 3572 | ha->qla4_82xx_reg = (struct device_reg_82xx __iomem *) |
3569 | 0xbc000 + (ha->pdev->devfn << 11)); | 3573 | ((uint8_t *)ha->nx_pcibase + 0xbc000 + |
3574 | (ha->pdev->devfn << 11)); | ||
3575 | ha->nx_db_wr_ptr = (ha->pdev->devfn == 4 ? QLA82XX_CAM_RAM_DB1 : | ||
3576 | QLA82XX_CAM_RAM_DB2); | ||
3577 | } else if (is_qla8032(ha)) { | ||
3578 | ha->qla4_83xx_reg = (struct device_reg_83xx __iomem *) | ||
3579 | ((uint8_t *)ha->nx_pcibase); | ||
3580 | } | ||
3570 | 3581 | ||
3571 | db_base = pci_resource_start(pdev, 4); /* doorbell is on bar 4 */ | 3582 | db_base = pci_resource_start(pdev, 4); /* doorbell is on bar 4 */ |
3572 | db_len = pci_resource_len(pdev, 4); | 3583 | db_len = pci_resource_len(pdev, 4); |
3573 | 3584 | ||
3574 | ha->nx_db_wr_ptr = (ha->pdev->devfn == 4 ? QLA82XX_CAM_RAM_DB1 : | ||
3575 | QLA82XX_CAM_RAM_DB2); | ||
3576 | |||
3577 | return 0; | 3585 | return 0; |
3578 | iospace_error_exit: | 3586 | iospace_error_exit: |
3579 | return -ENOMEM; | 3587 | return -ENOMEM; |
@@ -3693,6 +3701,34 @@ static struct isp_operations qla4_82xx_isp_ops = { | |||
3693 | .process_mailbox_interrupt = qla4_82xx_process_mbox_intr, | 3701 | .process_mailbox_interrupt = qla4_82xx_process_mbox_intr, |
3694 | }; | 3702 | }; |
3695 | 3703 | ||
3704 | static struct isp_operations qla4_83xx_isp_ops = { | ||
3705 | .iospace_config = qla4_8xxx_iospace_config, | ||
3706 | .pci_config = qla4_8xxx_pci_config, | ||
3707 | .disable_intrs = qla4_83xx_disable_intrs, | ||
3708 | .enable_intrs = qla4_83xx_enable_intrs, | ||
3709 | .start_firmware = qla4_8xxx_load_risc, | ||
3710 | .restart_firmware = qla4_83xx_start_firmware, | ||
3711 | .intr_handler = qla4_83xx_intr_handler, | ||
3712 | .interrupt_service_routine = qla4_83xx_interrupt_service_routine, | ||
3713 | .need_reset = qla4_8xxx_need_reset, | ||
3714 | .reset_chip = qla4_83xx_isp_reset, | ||
3715 | .reset_firmware = qla4_8xxx_stop_firmware, | ||
3716 | .queue_iocb = qla4_83xx_queue_iocb, | ||
3717 | .complete_iocb = qla4_83xx_complete_iocb, | ||
3718 | .rd_shdw_req_q_out = qla4_83xx_rd_shdw_req_q_out, | ||
3719 | .rd_shdw_rsp_q_in = qla4_83xx_rd_shdw_rsp_q_in, | ||
3720 | .get_sys_info = qla4_8xxx_get_sys_info, | ||
3721 | .rd_reg_direct = qla4_83xx_rd_reg, | ||
3722 | .wr_reg_direct = qla4_83xx_wr_reg, | ||
3723 | .rd_reg_indirect = qla4_83xx_rd_reg_indirect, | ||
3724 | .wr_reg_indirect = qla4_83xx_wr_reg_indirect, | ||
3725 | .idc_lock = qla4_83xx_drv_lock, | ||
3726 | .idc_unlock = qla4_83xx_drv_unlock, | ||
3727 | .rom_lock_recovery = qla4_83xx_rom_lock_recovery, | ||
3728 | .queue_mailbox_command = qla4_83xx_queue_mbox_cmd, | ||
3729 | .process_mailbox_interrupt = qla4_83xx_process_mbox_intr, | ||
3730 | }; | ||
3731 | |||
3696 | uint16_t qla4xxx_rd_shdw_req_q_out(struct scsi_qla_host *ha) | 3732 | uint16_t qla4xxx_rd_shdw_req_q_out(struct scsi_qla_host *ha) |
3697 | { | 3733 | { |
3698 | return (uint16_t)le32_to_cpu(ha->shadow_regs->req_q_out); | 3734 | return (uint16_t)le32_to_cpu(ha->shadow_regs->req_q_out); |
@@ -3703,6 +3739,11 @@ uint16_t qla4_82xx_rd_shdw_req_q_out(struct scsi_qla_host *ha) | |||
3703 | return (uint16_t)le32_to_cpu(readl(&ha->qla4_82xx_reg->req_q_out)); | 3739 | return (uint16_t)le32_to_cpu(readl(&ha->qla4_82xx_reg->req_q_out)); |
3704 | } | 3740 | } |
3705 | 3741 | ||
3742 | uint16_t qla4_83xx_rd_shdw_req_q_out(struct scsi_qla_host *ha) | ||
3743 | { | ||
3744 | return (uint16_t)le32_to_cpu(readl(&ha->qla4_83xx_reg->req_q_out)); | ||
3745 | } | ||
3746 | |||
3706 | uint16_t qla4xxx_rd_shdw_rsp_q_in(struct scsi_qla_host *ha) | 3747 | uint16_t qla4xxx_rd_shdw_rsp_q_in(struct scsi_qla_host *ha) |
3707 | { | 3748 | { |
3708 | return (uint16_t)le32_to_cpu(ha->shadow_regs->rsp_q_in); | 3749 | return (uint16_t)le32_to_cpu(ha->shadow_regs->rsp_q_in); |
@@ -3713,6 +3754,11 @@ uint16_t qla4_82xx_rd_shdw_rsp_q_in(struct scsi_qla_host *ha) | |||
3713 | return (uint16_t)le32_to_cpu(readl(&ha->qla4_82xx_reg->rsp_q_in)); | 3754 | return (uint16_t)le32_to_cpu(readl(&ha->qla4_82xx_reg->rsp_q_in)); |
3714 | } | 3755 | } |
3715 | 3756 | ||
3757 | uint16_t qla4_83xx_rd_shdw_rsp_q_in(struct scsi_qla_host *ha) | ||
3758 | { | ||
3759 | return (uint16_t)le32_to_cpu(readl(&ha->qla4_83xx_reg->rsp_q_in)); | ||
3760 | } | ||
3761 | |||
3716 | static ssize_t qla4xxx_show_boot_eth_info(void *data, int type, char *buf) | 3762 | static ssize_t qla4xxx_show_boot_eth_info(void *data, int type, char *buf) |
3717 | { | 3763 | { |
3718 | struct scsi_qla_host *ha = data; | 3764 | struct scsi_qla_host *ha = data; |
@@ -5085,6 +5131,7 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev, | |||
5085 | ha->pdev = pdev; | 5131 | ha->pdev = pdev; |
5086 | ha->host = host; | 5132 | ha->host = host; |
5087 | ha->host_no = host->host_no; | 5133 | ha->host_no = host->host_no; |
5134 | ha->func_num = PCI_FUNC(ha->pdev->devfn); | ||
5088 | 5135 | ||
5089 | pci_enable_pcie_error_reporting(pdev); | 5136 | pci_enable_pcie_error_reporting(pdev); |
5090 | 5137 | ||
@@ -5092,24 +5139,28 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev, | |||
5092 | if (is_qla8022(ha)) { | 5139 | if (is_qla8022(ha)) { |
5093 | ha->isp_ops = &qla4_82xx_isp_ops; | 5140 | ha->isp_ops = &qla4_82xx_isp_ops; |
5094 | ha->reg_tbl = (uint32_t *) qla4_82xx_reg_tbl; | 5141 | ha->reg_tbl = (uint32_t *) qla4_82xx_reg_tbl; |
5095 | rwlock_init(&ha->hw_lock); | ||
5096 | ha->qdr_sn_window = -1; | 5142 | ha->qdr_sn_window = -1; |
5097 | ha->ddr_mn_window = -1; | 5143 | ha->ddr_mn_window = -1; |
5098 | ha->curr_window = 255; | 5144 | ha->curr_window = 255; |
5099 | ha->func_num = PCI_FUNC(ha->pdev->devfn); | ||
5100 | nx_legacy_intr = &legacy_intr[ha->func_num]; | 5145 | nx_legacy_intr = &legacy_intr[ha->func_num]; |
5101 | ha->nx_legacy_intr.int_vec_bit = nx_legacy_intr->int_vec_bit; | 5146 | ha->nx_legacy_intr.int_vec_bit = nx_legacy_intr->int_vec_bit; |
5102 | ha->nx_legacy_intr.tgt_status_reg = | 5147 | ha->nx_legacy_intr.tgt_status_reg = |
5103 | nx_legacy_intr->tgt_status_reg; | 5148 | nx_legacy_intr->tgt_status_reg; |
5104 | ha->nx_legacy_intr.tgt_mask_reg = nx_legacy_intr->tgt_mask_reg; | 5149 | ha->nx_legacy_intr.tgt_mask_reg = nx_legacy_intr->tgt_mask_reg; |
5105 | ha->nx_legacy_intr.pci_int_reg = nx_legacy_intr->pci_int_reg; | 5150 | ha->nx_legacy_intr.pci_int_reg = nx_legacy_intr->pci_int_reg; |
5151 | } else if (is_qla8032(ha)) { | ||
5152 | ha->isp_ops = &qla4_83xx_isp_ops; | ||
5153 | ha->reg_tbl = (uint32_t *)qla4_83xx_reg_tbl; | ||
5106 | } else { | 5154 | } else { |
5107 | ha->isp_ops = &qla4xxx_isp_ops; | 5155 | ha->isp_ops = &qla4xxx_isp_ops; |
5108 | } | 5156 | } |
5109 | 5157 | ||
5110 | /* Set EEH reset type to fundamental if required by hba */ | 5158 | if (is_qla80XX(ha)) { |
5111 | if (is_qla8022(ha)) | 5159 | rwlock_init(&ha->hw_lock); |
5160 | ha->pf_bit = ha->func_num << 16; | ||
5161 | /* Set EEH reset type to fundamental if required by hba */ | ||
5112 | pdev->needs_freset = 1; | 5162 | pdev->needs_freset = 1; |
5163 | } | ||
5113 | 5164 | ||
5114 | /* Configure PCI I/O space. */ | 5165 | /* Configure PCI I/O space. */ |
5115 | ret = ha->isp_ops->iospace_config(ha); | 5166 | ret = ha->isp_ops->iospace_config(ha); |
@@ -5165,8 +5216,20 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev, | |||
5165 | if (ret) | 5216 | if (ret) |
5166 | goto probe_failed; | 5217 | goto probe_failed; |
5167 | 5218 | ||
5168 | if (is_qla8022(ha)) | 5219 | if (is_qla80XX(ha)) |
5169 | (void) qla4_8xxx_get_flash_info(ha); | 5220 | qla4_8xxx_get_flash_info(ha); |
5221 | |||
5222 | if (is_qla8032(ha)) { | ||
5223 | qla4_83xx_read_reset_template(ha); | ||
5224 | /* | ||
5225 | * NOTE: If ql4dontresethba==1, set IDC_CTRL DONTRESET_BIT0. | ||
5226 | * If DONRESET_BIT0 is set, drivers should not set dev_state | ||
5227 | * to NEED_RESET. But if NEED_RESET is set, drivers should | ||
5228 | * should honor the reset. | ||
5229 | */ | ||
5230 | if (ql4xdontresethba == 1) | ||
5231 | qla4_83xx_set_idc_dontreset(ha); | ||
5232 | } | ||
5170 | 5233 | ||
5171 | /* | 5234 | /* |
5172 | * Initialize the Host adapter request/response queues and | 5235 | * Initialize the Host adapter request/response queues and |
@@ -5177,7 +5240,7 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev, | |||
5177 | while ((!test_bit(AF_ONLINE, &ha->flags)) && | 5240 | while ((!test_bit(AF_ONLINE, &ha->flags)) && |
5178 | init_retry_count++ < MAX_INIT_RETRIES) { | 5241 | init_retry_count++ < MAX_INIT_RETRIES) { |
5179 | 5242 | ||
5180 | if (is_qla8022(ha)) { | 5243 | if (is_qla80XX(ha)) { |
5181 | ha->isp_ops->idc_lock(ha); | 5244 | ha->isp_ops->idc_lock(ha); |
5182 | dev_state = qla4_8xxx_rd_direct(ha, | 5245 | dev_state = qla4_8xxx_rd_direct(ha, |
5183 | QLA82XX_CRB_DEV_STATE); | 5246 | QLA82XX_CRB_DEV_STATE); |
@@ -5201,7 +5264,8 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev, | |||
5201 | if (!test_bit(AF_ONLINE, &ha->flags)) { | 5264 | if (!test_bit(AF_ONLINE, &ha->flags)) { |
5202 | ql4_printk(KERN_WARNING, ha, "Failed to initialize adapter\n"); | 5265 | ql4_printk(KERN_WARNING, ha, "Failed to initialize adapter\n"); |
5203 | 5266 | ||
5204 | if (is_qla8022(ha) && ql4xdontresethba) { | 5267 | if ((is_qla8022(ha) && ql4xdontresethba) || |
5268 | (is_qla8032(ha) && qla4_83xx_idc_dontreset(ha))) { | ||
5205 | /* Put the device in failed state. */ | 5269 | /* Put the device in failed state. */ |
5206 | DEBUG2(printk(KERN_ERR "HW STATE: FAILED\n")); | 5270 | DEBUG2(printk(KERN_ERR "HW STATE: FAILED\n")); |
5207 | ha->isp_ops->idc_lock(ha); | 5271 | ha->isp_ops->idc_lock(ha); |
@@ -5233,7 +5297,8 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev, | |||
5233 | goto remove_host; | 5297 | goto remove_host; |
5234 | } | 5298 | } |
5235 | 5299 | ||
5236 | /* For ISP-82XX, request_irqs is called in qla4_8xxx_load_risc | 5300 | /* |
5301 | * For ISP-8XXX, request_irqs is called in qla4_8xxx_load_risc | ||
5237 | * (which is called indirectly by qla4xxx_initialize_adapter), | 5302 | * (which is called indirectly by qla4xxx_initialize_adapter), |
5238 | * so that irqs will be registered after crbinit but before | 5303 | * so that irqs will be registered after crbinit but before |
5239 | * mbx_intr_enable. | 5304 | * mbx_intr_enable. |
@@ -5793,7 +5858,16 @@ static int qla4xxx_eh_host_reset(struct scsi_cmnd *cmd) | |||
5793 | 5858 | ||
5794 | ha = to_qla_host(cmd->device->host); | 5859 | ha = to_qla_host(cmd->device->host); |
5795 | 5860 | ||
5796 | if (ql4xdontresethba) { | 5861 | if (is_qla8032(ha) && ql4xdontresethba) |
5862 | qla4_83xx_set_idc_dontreset(ha); | ||
5863 | |||
5864 | /* | ||
5865 | * For ISP8324, if IDC_CTRL DONTRESET_BIT0 is set by other | ||
5866 | * protocol drivers, we should not set device_state to | ||
5867 | * NEED_RESET | ||
5868 | */ | ||
5869 | if (ql4xdontresethba || | ||
5870 | (is_qla8032(ha) && qla4_83xx_idc_dontreset(ha))) { | ||
5797 | DEBUG2(printk("scsi%ld: %s: Don't Reset HBA\n", | 5871 | DEBUG2(printk("scsi%ld: %s: Don't Reset HBA\n", |
5798 | ha->host_no, __func__)); | 5872 | ha->host_no, __func__)); |
5799 | 5873 | ||
@@ -5817,7 +5891,7 @@ static int qla4xxx_eh_host_reset(struct scsi_cmnd *cmd) | |||
5817 | } | 5891 | } |
5818 | 5892 | ||
5819 | if (!test_bit(DPC_RESET_HA, &ha->dpc_flags)) { | 5893 | if (!test_bit(DPC_RESET_HA, &ha->dpc_flags)) { |
5820 | if (is_qla8022(ha)) | 5894 | if (is_qla80XX(ha)) |
5821 | set_bit(DPC_RESET_HA_FW_CONTEXT, &ha->dpc_flags); | 5895 | set_bit(DPC_RESET_HA_FW_CONTEXT, &ha->dpc_flags); |
5822 | else | 5896 | else |
5823 | set_bit(DPC_RESET_HA, &ha->dpc_flags); | 5897 | set_bit(DPC_RESET_HA, &ha->dpc_flags); |
@@ -5912,7 +5986,7 @@ static int qla4xxx_host_reset(struct Scsi_Host *shost, int reset_type) | |||
5912 | break; | 5986 | break; |
5913 | case SCSI_FIRMWARE_RESET: | 5987 | case SCSI_FIRMWARE_RESET: |
5914 | if (!test_bit(DPC_RESET_HA, &ha->dpc_flags)) { | 5988 | if (!test_bit(DPC_RESET_HA, &ha->dpc_flags)) { |
5915 | if (is_qla8022(ha)) | 5989 | if (is_qla80XX(ha)) |
5916 | /* set firmware context reset */ | 5990 | /* set firmware context reset */ |
5917 | set_bit(DPC_RESET_HA_FW_CONTEXT, | 5991 | set_bit(DPC_RESET_HA_FW_CONTEXT, |
5918 | &ha->dpc_flags); | 5992 | &ha->dpc_flags); |
@@ -6150,7 +6224,7 @@ qla4xxx_pci_slot_reset(struct pci_dev *pdev) | |||
6150 | 6224 | ||
6151 | ha->isp_ops->disable_intrs(ha); | 6225 | ha->isp_ops->disable_intrs(ha); |
6152 | 6226 | ||
6153 | if (is_qla8022(ha)) { | 6227 | if (is_qla80XX(ha)) { |
6154 | if (qla4_8xxx_error_recovery(ha) == QLA_SUCCESS) { | 6228 | if (qla4_8xxx_error_recovery(ha) == QLA_SUCCESS) { |
6155 | ret = PCI_ERS_RESULT_RECOVERED; | 6229 | ret = PCI_ERS_RESULT_RECOVERED; |
6156 | goto exit_slot_reset; | 6230 | goto exit_slot_reset; |
@@ -6216,6 +6290,12 @@ static struct pci_device_id qla4xxx_pci_tbl[] = { | |||
6216 | .subvendor = PCI_ANY_ID, | 6290 | .subvendor = PCI_ANY_ID, |
6217 | .subdevice = PCI_ANY_ID, | 6291 | .subdevice = PCI_ANY_ID, |
6218 | }, | 6292 | }, |
6293 | { | ||
6294 | .vendor = PCI_VENDOR_ID_QLOGIC, | ||
6295 | .device = PCI_DEVICE_ID_QLOGIC_ISP8324, | ||
6296 | .subvendor = PCI_ANY_ID, | ||
6297 | .subdevice = PCI_ANY_ID, | ||
6298 | }, | ||
6219 | {0, 0}, | 6299 | {0, 0}, |
6220 | }; | 6300 | }; |
6221 | MODULE_DEVICE_TABLE(pci, qla4xxx_pci_tbl); | 6301 | MODULE_DEVICE_TABLE(pci, qla4xxx_pci_tbl); |