diff options
Diffstat (limited to 'drivers/scsi/qla4xxx/ql4_os.c')
-rw-r--r-- | drivers/scsi/qla4xxx/ql4_os.c | 494 |
1 files changed, 331 insertions, 163 deletions
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c index 79243b76d17e..fbc546e893ac 100644 --- a/drivers/scsi/qla4xxx/ql4_os.c +++ b/drivers/scsi/qla4xxx/ql4_os.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic iSCSI HBA Driver | 2 | * QLogic iSCSI HBA Driver |
3 | * Copyright (c) 2003-2010 QLogic Corporation | 3 | * Copyright (c) 2003-2012 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla4xxx for copyright and licensing details. | 5 | * See LICENSE.qla4xxx for copyright and licensing details. |
6 | */ | 6 | */ |
@@ -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 |
@@ -160,7 +161,7 @@ static int qla4xxx_eh_host_reset(struct scsi_cmnd *cmd); | |||
160 | static int qla4xxx_slave_alloc(struct scsi_device *device); | 161 | static int qla4xxx_slave_alloc(struct scsi_device *device); |
161 | static int qla4xxx_slave_configure(struct scsi_device *device); | 162 | static int qla4xxx_slave_configure(struct scsi_device *device); |
162 | static void qla4xxx_slave_destroy(struct scsi_device *sdev); | 163 | static void qla4xxx_slave_destroy(struct scsi_device *sdev); |
163 | static umode_t ql4_attr_is_visible(int param_type, int param); | 164 | static umode_t qla4_attr_is_visible(int param_type, int param); |
164 | static int qla4xxx_host_reset(struct Scsi_Host *shost, int reset_type); | 165 | static int qla4xxx_host_reset(struct Scsi_Host *shost, int reset_type); |
165 | static int qla4xxx_change_queue_depth(struct scsi_device *sdev, int qdepth, | 166 | static int qla4xxx_change_queue_depth(struct scsi_device *sdev, int qdepth, |
166 | int reason); | 167 | int reason); |
@@ -203,7 +204,7 @@ static struct iscsi_transport qla4xxx_iscsi_transport = { | |||
203 | CAP_DATA_PATH_OFFLOAD | CAP_HDRDGST | | 204 | CAP_DATA_PATH_OFFLOAD | CAP_HDRDGST | |
204 | CAP_DATADGST | CAP_LOGIN_OFFLOAD | | 205 | CAP_DATADGST | CAP_LOGIN_OFFLOAD | |
205 | CAP_MULTI_R2T, | 206 | CAP_MULTI_R2T, |
206 | .attr_is_visible = ql4_attr_is_visible, | 207 | .attr_is_visible = qla4_attr_is_visible, |
207 | .create_session = qla4xxx_session_create, | 208 | .create_session = qla4xxx_session_create, |
208 | .destroy_session = qla4xxx_session_destroy, | 209 | .destroy_session = qla4xxx_session_destroy, |
209 | .start_conn = qla4xxx_conn_start, | 210 | .start_conn = qla4xxx_conn_start, |
@@ -315,7 +316,7 @@ exit_send_ping: | |||
315 | return rval; | 316 | return rval; |
316 | } | 317 | } |
317 | 318 | ||
318 | static umode_t ql4_attr_is_visible(int param_type, int param) | 319 | static umode_t qla4_attr_is_visible(int param_type, int param) |
319 | { | 320 | { |
320 | switch (param_type) { | 321 | switch (param_type) { |
321 | case ISCSI_HOST_PARAM: | 322 | case ISCSI_HOST_PARAM: |
@@ -1366,7 +1367,7 @@ static int qla4xxx_conn_get_param(struct iscsi_cls_conn *cls_conn, | |||
1366 | 1367 | ||
1367 | conn = cls_conn->dd_data; | 1368 | conn = cls_conn->dd_data; |
1368 | qla_conn = conn->dd_data; | 1369 | qla_conn = conn->dd_data; |
1369 | dst_addr = &qla_conn->qla_ep->dst_addr; | 1370 | dst_addr = (struct sockaddr *)&qla_conn->qla_ep->dst_addr; |
1370 | 1371 | ||
1371 | switch (param) { | 1372 | switch (param) { |
1372 | case ISCSI_PARAM_CONN_PORT: | 1373 | case ISCSI_PARAM_CONN_PORT: |
@@ -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 | ||
@@ -2420,7 +2430,7 @@ static int qla4_8xxx_check_temp(struct scsi_qla_host *ha) | |||
2420 | uint32_t temp, temp_state, temp_val; | 2430 | uint32_t temp, temp_state, temp_val; |
2421 | int status = QLA_SUCCESS; | 2431 | int status = QLA_SUCCESS; |
2422 | 2432 | ||
2423 | temp = qla4_8xxx_rd_32(ha, CRB_TEMP_STATE); | 2433 | temp = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_TEMP_STATE); |
2424 | 2434 | ||
2425 | temp_state = qla82xx_get_temp_state(temp); | 2435 | temp_state = qla82xx_get_temp_state(temp); |
2426 | temp_val = qla82xx_get_temp_val(temp); | 2436 | temp_val = qla82xx_get_temp_val(temp); |
@@ -2456,7 +2466,8 @@ static int qla4_8xxx_check_fw_alive(struct scsi_qla_host *ha) | |||
2456 | uint32_t fw_heartbeat_counter; | 2466 | uint32_t fw_heartbeat_counter; |
2457 | int status = QLA_SUCCESS; | 2467 | int status = QLA_SUCCESS; |
2458 | 2468 | ||
2459 | fw_heartbeat_counter = qla4_8xxx_rd_32(ha, QLA82XX_PEG_ALIVE_COUNTER); | 2469 | fw_heartbeat_counter = qla4_8xxx_rd_direct(ha, |
2470 | QLA8XXX_PEG_ALIVE_COUNTER); | ||
2460 | /* If PEG_ALIVE_COUNTER is 0xffffffff, AER/EEH is in progress, ignore */ | 2471 | /* If PEG_ALIVE_COUNTER is 0xffffffff, AER/EEH is in progress, ignore */ |
2461 | if (fw_heartbeat_counter == 0xffffffff) { | 2472 | if (fw_heartbeat_counter == 0xffffffff) { |
2462 | DEBUG2(printk(KERN_WARNING "scsi%ld: %s: Device in frozen " | 2473 | DEBUG2(printk(KERN_WARNING "scsi%ld: %s: Device in frozen " |
@@ -2470,28 +2481,7 @@ static int qla4_8xxx_check_fw_alive(struct scsi_qla_host *ha) | |||
2470 | /* FW not alive after 2 seconds */ | 2481 | /* FW not alive after 2 seconds */ |
2471 | if (ha->seconds_since_last_heartbeat == 2) { | 2482 | if (ha->seconds_since_last_heartbeat == 2) { |
2472 | ha->seconds_since_last_heartbeat = 0; | 2483 | ha->seconds_since_last_heartbeat = 0; |
2473 | 2484 | qla4_8xxx_dump_peg_reg(ha); | |
2474 | ql4_printk(KERN_INFO, ha, | ||
2475 | "scsi(%ld): %s, Dumping hw/fw registers:\n " | ||
2476 | " PEG_HALT_STATUS1: 0x%x, PEG_HALT_STATUS2:" | ||
2477 | " 0x%x,\n PEG_NET_0_PC: 0x%x, PEG_NET_1_PC:" | ||
2478 | " 0x%x,\n PEG_NET_2_PC: 0x%x, PEG_NET_3_PC:" | ||
2479 | " 0x%x,\n PEG_NET_4_PC: 0x%x\n", | ||
2480 | ha->host_no, __func__, | ||
2481 | qla4_8xxx_rd_32(ha, | ||
2482 | QLA82XX_PEG_HALT_STATUS1), | ||
2483 | qla4_8xxx_rd_32(ha, | ||
2484 | QLA82XX_PEG_HALT_STATUS2), | ||
2485 | qla4_8xxx_rd_32(ha, QLA82XX_CRB_PEG_NET_0 + | ||
2486 | 0x3c), | ||
2487 | qla4_8xxx_rd_32(ha, QLA82XX_CRB_PEG_NET_1 + | ||
2488 | 0x3c), | ||
2489 | qla4_8xxx_rd_32(ha, QLA82XX_CRB_PEG_NET_2 + | ||
2490 | 0x3c), | ||
2491 | qla4_8xxx_rd_32(ha, QLA82XX_CRB_PEG_NET_3 + | ||
2492 | 0x3c), | ||
2493 | qla4_8xxx_rd_32(ha, QLA82XX_CRB_PEG_NET_4 + | ||
2494 | 0x3c)); | ||
2495 | status = QLA_ERROR; | 2485 | status = QLA_ERROR; |
2496 | } | 2486 | } |
2497 | } else | 2487 | } else |
@@ -2501,6 +2491,48 @@ static int qla4_8xxx_check_fw_alive(struct scsi_qla_host *ha) | |||
2501 | return status; | 2491 | return status; |
2502 | } | 2492 | } |
2503 | 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 | |||
2504 | /** | 2536 | /** |
2505 | * qla4_8xxx_watchdog - Poll dev state | 2537 | * qla4_8xxx_watchdog - Poll dev state |
2506 | * @ha: Pointer to host adapter structure. | 2538 | * @ha: Pointer to host adapter structure. |
@@ -2509,31 +2541,33 @@ static int qla4_8xxx_check_fw_alive(struct scsi_qla_host *ha) | |||
2509 | **/ | 2541 | **/ |
2510 | void qla4_8xxx_watchdog(struct scsi_qla_host *ha) | 2542 | void qla4_8xxx_watchdog(struct scsi_qla_host *ha) |
2511 | { | 2543 | { |
2512 | uint32_t dev_state, halt_status; | 2544 | uint32_t dev_state; |
2513 | 2545 | ||
2514 | /* don't poll if reset is going on */ | 2546 | /* don't poll if reset is going on */ |
2515 | if (!(test_bit(DPC_RESET_ACTIVE, &ha->dpc_flags) || | 2547 | if (!(test_bit(DPC_RESET_ACTIVE, &ha->dpc_flags) || |
2516 | test_bit(DPC_RESET_HA, &ha->dpc_flags) || | 2548 | test_bit(DPC_RESET_HA, &ha->dpc_flags) || |
2517 | test_bit(DPC_RETRY_RESET_HA, &ha->dpc_flags))) { | 2549 | test_bit(DPC_RETRY_RESET_HA, &ha->dpc_flags))) { |
2518 | dev_state = qla4_8xxx_rd_32(ha, QLA82XX_CRB_DEV_STATE); | 2550 | dev_state = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DEV_STATE); |
2519 | 2551 | ||
2520 | if (qla4_8xxx_check_temp(ha)) { | 2552 | if (qla4_8xxx_check_temp(ha)) { |
2521 | ql4_printk(KERN_INFO, ha, "disabling pause" | 2553 | if (is_qla8022(ha)) { |
2522 | " transmit on port 0 & 1.\n"); | 2554 | ql4_printk(KERN_INFO, ha, "disabling pause transmit on port 0 & 1.\n"); |
2523 | qla4_8xxx_wr_32(ha, QLA82XX_CRB_NIU + 0x98, | 2555 | qla4_82xx_wr_32(ha, QLA82XX_CRB_NIU + 0x98, |
2524 | CRB_NIU_XG_PAUSE_CTL_P0 | | 2556 | CRB_NIU_XG_PAUSE_CTL_P0 | |
2525 | CRB_NIU_XG_PAUSE_CTL_P1); | 2557 | CRB_NIU_XG_PAUSE_CTL_P1); |
2558 | } | ||
2526 | set_bit(DPC_HA_UNRECOVERABLE, &ha->dpc_flags); | 2559 | set_bit(DPC_HA_UNRECOVERABLE, &ha->dpc_flags); |
2527 | qla4xxx_wake_dpc(ha); | 2560 | qla4xxx_wake_dpc(ha); |
2528 | } else if (dev_state == QLA82XX_DEV_NEED_RESET && | 2561 | } else if (dev_state == QLA8XXX_DEV_NEED_RESET && |
2529 | !test_bit(DPC_RESET_HA, &ha->dpc_flags)) { | 2562 | !test_bit(DPC_RESET_HA, &ha->dpc_flags)) { |
2530 | if (!ql4xdontresethba) { | 2563 | if (is_qla8032(ha) || |
2564 | (is_qla8022(ha) && !ql4xdontresethba)) { | ||
2531 | ql4_printk(KERN_INFO, ha, "%s: HW State: " | 2565 | ql4_printk(KERN_INFO, ha, "%s: HW State: " |
2532 | "NEED RESET!\n", __func__); | 2566 | "NEED RESET!\n", __func__); |
2533 | set_bit(DPC_RESET_HA, &ha->dpc_flags); | 2567 | set_bit(DPC_RESET_HA, &ha->dpc_flags); |
2534 | qla4xxx_wake_dpc(ha); | 2568 | qla4xxx_wake_dpc(ha); |
2535 | } | 2569 | } |
2536 | } else if (dev_state == QLA82XX_DEV_NEED_QUIESCENT && | 2570 | } else if (dev_state == QLA8XXX_DEV_NEED_QUIESCENT && |
2537 | !test_bit(DPC_HA_NEED_QUIESCENT, &ha->dpc_flags)) { | 2571 | !test_bit(DPC_HA_NEED_QUIESCENT, &ha->dpc_flags)) { |
2538 | ql4_printk(KERN_INFO, ha, "%s: HW State: NEED QUIES!\n", | 2572 | ql4_printk(KERN_INFO, ha, "%s: HW State: NEED QUIES!\n", |
2539 | __func__); | 2573 | __func__); |
@@ -2541,36 +2575,8 @@ void qla4_8xxx_watchdog(struct scsi_qla_host *ha) | |||
2541 | qla4xxx_wake_dpc(ha); | 2575 | qla4xxx_wake_dpc(ha); |
2542 | } else { | 2576 | } else { |
2543 | /* Check firmware health */ | 2577 | /* Check firmware health */ |
2544 | if (qla4_8xxx_check_fw_alive(ha)) { | 2578 | if (qla4_8xxx_check_fw_alive(ha)) |
2545 | ql4_printk(KERN_INFO, ha, "disabling pause" | 2579 | qla4_8xxx_process_fw_error(ha); |
2546 | " transmit on port 0 & 1.\n"); | ||
2547 | qla4_8xxx_wr_32(ha, QLA82XX_CRB_NIU + 0x98, | ||
2548 | CRB_NIU_XG_PAUSE_CTL_P0 | | ||
2549 | CRB_NIU_XG_PAUSE_CTL_P1); | ||
2550 | halt_status = qla4_8xxx_rd_32(ha, | ||
2551 | QLA82XX_PEG_HALT_STATUS1); | ||
2552 | |||
2553 | if (QLA82XX_FWERROR_CODE(halt_status) == 0x67) | ||
2554 | ql4_printk(KERN_ERR, ha, "%s:" | ||
2555 | " Firmware aborted with" | ||
2556 | " error code 0x00006700." | ||
2557 | " Device is being reset\n", | ||
2558 | __func__); | ||
2559 | |||
2560 | /* Since we cannot change dev_state in interrupt | ||
2561 | * context, set appropriate DPC flag then wakeup | ||
2562 | * DPC */ | ||
2563 | if (halt_status & HALT_STATUS_UNRECOVERABLE) | ||
2564 | set_bit(DPC_HA_UNRECOVERABLE, | ||
2565 | &ha->dpc_flags); | ||
2566 | else { | ||
2567 | ql4_printk(KERN_INFO, ha, "%s: detect " | ||
2568 | "abort needed!\n", __func__); | ||
2569 | set_bit(DPC_RESET_HA, &ha->dpc_flags); | ||
2570 | } | ||
2571 | qla4xxx_mailbox_premature_completion(ha); | ||
2572 | qla4xxx_wake_dpc(ha); | ||
2573 | } | ||
2574 | } | 2580 | } |
2575 | } | 2581 | } |
2576 | } | 2582 | } |
@@ -2652,11 +2658,10 @@ static void qla4xxx_timer(struct scsi_qla_host *ha) | |||
2652 | if (!pci_channel_offline(ha->pdev)) | 2658 | if (!pci_channel_offline(ha->pdev)) |
2653 | pci_read_config_word(ha->pdev, PCI_VENDOR_ID, &w); | 2659 | pci_read_config_word(ha->pdev, PCI_VENDOR_ID, &w); |
2654 | 2660 | ||
2655 | if (is_qla8022(ha)) { | 2661 | if (is_qla80XX(ha)) |
2656 | qla4_8xxx_watchdog(ha); | 2662 | qla4_8xxx_watchdog(ha); |
2657 | } | ||
2658 | 2663 | ||
2659 | if (!is_qla8022(ha)) { | 2664 | if (is_qla40XX(ha)) { |
2660 | /* Check for heartbeat interval. */ | 2665 | /* Check for heartbeat interval. */ |
2661 | if (ha->firmware_options & FWOPT_HEARTBEAT_ENABLE && | 2666 | if (ha->firmware_options & FWOPT_HEARTBEAT_ENABLE && |
2662 | ha->heartbeat_interval != 0) { | 2667 | ha->heartbeat_interval != 0) { |
@@ -2941,6 +2946,14 @@ static int qla4xxx_recover_adapter(struct scsi_qla_host *ha) | |||
2941 | 2946 | ||
2942 | set_bit(DPC_RESET_ACTIVE, &ha->dpc_flags); | 2947 | set_bit(DPC_RESET_ACTIVE, &ha->dpc_flags); |
2943 | 2948 | ||
2949 | if (is_qla8032(ha) && | ||
2950 | !test_bit(DPC_RESET_HA_FW_CONTEXT, &ha->dpc_flags)) { | ||
2951 | ql4_printk(KERN_INFO, ha, "%s: disabling pause transmit on port 0 & 1.\n", | ||
2952 | __func__); | ||
2953 | /* disable pause frame for ISP83xx */ | ||
2954 | qla4_83xx_disable_pause(ha); | ||
2955 | } | ||
2956 | |||
2944 | iscsi_host_for_each_session(ha->host, qla4xxx_fail_session); | 2957 | iscsi_host_for_each_session(ha->host, qla4xxx_fail_session); |
2945 | 2958 | ||
2946 | if (test_bit(DPC_RESET_HA, &ha->dpc_flags)) | 2959 | if (test_bit(DPC_RESET_HA, &ha->dpc_flags)) |
@@ -2953,9 +2966,9 @@ static int qla4xxx_recover_adapter(struct scsi_qla_host *ha) | |||
2953 | goto recover_ha_init_adapter; | 2966 | goto recover_ha_init_adapter; |
2954 | } | 2967 | } |
2955 | 2968 | ||
2956 | /* For the ISP-82xx adapter, issue a stop_firmware if invoked | 2969 | /* For the ISP-8xxx adapter, issue a stop_firmware if invoked |
2957 | * from eh_host_reset or ioctl module */ | 2970 | * from eh_host_reset or ioctl module */ |
2958 | if (is_qla8022(ha) && !reset_chip && | 2971 | if (is_qla80XX(ha) && !reset_chip && |
2959 | test_bit(DPC_RESET_HA_FW_CONTEXT, &ha->dpc_flags)) { | 2972 | test_bit(DPC_RESET_HA_FW_CONTEXT, &ha->dpc_flags)) { |
2960 | 2973 | ||
2961 | DEBUG2(ql4_printk(KERN_INFO, ha, | 2974 | DEBUG2(ql4_printk(KERN_INFO, ha, |
@@ -2978,13 +2991,13 @@ static int qla4xxx_recover_adapter(struct scsi_qla_host *ha) | |||
2978 | } | 2991 | } |
2979 | 2992 | ||
2980 | /* Issue full chip reset if recovering from a catastrophic error, | 2993 | /* Issue full chip reset if recovering from a catastrophic error, |
2981 | * or if stop_firmware fails for ISP-82xx. | 2994 | * or if stop_firmware fails for ISP-8xxx. |
2982 | * This is the default case for ISP-4xxx */ | 2995 | * This is the default case for ISP-4xxx */ |
2983 | if (!is_qla8022(ha) || reset_chip) { | 2996 | if (is_qla40XX(ha) || reset_chip) { |
2984 | if (!is_qla8022(ha)) | 2997 | if (is_qla40XX(ha)) |
2985 | goto chip_reset; | 2998 | goto chip_reset; |
2986 | 2999 | ||
2987 | /* Check if 82XX firmware is alive or not | 3000 | /* Check if 8XXX firmware is alive or not |
2988 | * We may have arrived here from NEED_RESET | 3001 | * We may have arrived here from NEED_RESET |
2989 | * detection only */ | 3002 | * detection only */ |
2990 | if (test_bit(AF_FW_RECOVERY, &ha->flags)) | 3003 | if (test_bit(AF_FW_RECOVERY, &ha->flags)) |
@@ -3000,10 +3013,10 @@ static int qla4xxx_recover_adapter(struct scsi_qla_host *ha) | |||
3000 | set_current_state(TASK_UNINTERRUPTIBLE); | 3013 | set_current_state(TASK_UNINTERRUPTIBLE); |
3001 | schedule_timeout(HZ); | 3014 | schedule_timeout(HZ); |
3002 | } | 3015 | } |
3003 | 3016 | chip_reset: | |
3004 | if (!test_bit(AF_FW_RECOVERY, &ha->flags)) | 3017 | if (!test_bit(AF_FW_RECOVERY, &ha->flags)) |
3005 | qla4xxx_cmd_wait(ha); | 3018 | qla4xxx_cmd_wait(ha); |
3006 | chip_reset: | 3019 | |
3007 | qla4xxx_process_aen(ha, FLUSH_DDB_CHANGED_AENS); | 3020 | qla4xxx_process_aen(ha, FLUSH_DDB_CHANGED_AENS); |
3008 | qla4xxx_abort_active_cmds(ha, DID_RESET << 16); | 3021 | qla4xxx_abort_active_cmds(ha, DID_RESET << 16); |
3009 | DEBUG2(ql4_printk(KERN_INFO, ha, | 3022 | DEBUG2(ql4_printk(KERN_INFO, ha, |
@@ -3021,7 +3034,7 @@ recover_ha_init_adapter: | |||
3021 | /* For ISP-4xxx, force function 1 to always initialize | 3034 | /* For ISP-4xxx, force function 1 to always initialize |
3022 | * before function 3 to prevent both funcions from | 3035 | * before function 3 to prevent both funcions from |
3023 | * stepping on top of the other */ | 3036 | * stepping on top of the other */ |
3024 | if (!is_qla8022(ha) && (ha->mac_index == 3)) | 3037 | if (is_qla40XX(ha) && (ha->mac_index == 3)) |
3025 | ssleep(6); | 3038 | ssleep(6); |
3026 | 3039 | ||
3027 | /* NOTE: AF_ONLINE flag set upon successful completion of | 3040 | /* NOTE: AF_ONLINE flag set upon successful completion of |
@@ -3039,11 +3052,12 @@ recover_ha_init_adapter: | |||
3039 | * Since we don't want to block the DPC for too long | 3052 | * Since we don't want to block the DPC for too long |
3040 | * with multiple resets in the same thread, | 3053 | * with multiple resets in the same thread, |
3041 | * utilize DPC to retry */ | 3054 | * utilize DPC to retry */ |
3042 | if (is_qla8022(ha)) { | 3055 | if (is_qla80XX(ha)) { |
3043 | qla4_8xxx_idc_lock(ha); | 3056 | ha->isp_ops->idc_lock(ha); |
3044 | dev_state = qla4_8xxx_rd_32(ha, QLA82XX_CRB_DEV_STATE); | 3057 | dev_state = qla4_8xxx_rd_direct(ha, |
3045 | qla4_8xxx_idc_unlock(ha); | 3058 | QLA8XXX_CRB_DEV_STATE); |
3046 | if (dev_state == QLA82XX_DEV_FAILED) { | 3059 | ha->isp_ops->idc_unlock(ha); |
3060 | if (dev_state == QLA8XXX_DEV_FAILED) { | ||
3047 | ql4_printk(KERN_INFO, ha, "%s: don't retry " | 3061 | ql4_printk(KERN_INFO, ha, "%s: don't retry " |
3048 | "recover adapter. H/W is in Failed " | 3062 | "recover adapter. H/W is in Failed " |
3049 | "state\n", __func__); | 3063 | "state\n", __func__); |
@@ -3168,6 +3182,7 @@ int qla4xxx_unblock_ddb(struct iscsi_cls_session *cls_session) | |||
3168 | struct iscsi_session *sess; | 3182 | struct iscsi_session *sess; |
3169 | struct ddb_entry *ddb_entry; | 3183 | struct ddb_entry *ddb_entry; |
3170 | struct scsi_qla_host *ha; | 3184 | struct scsi_qla_host *ha; |
3185 | int status = QLA_SUCCESS; | ||
3171 | 3186 | ||
3172 | sess = cls_session->dd_data; | 3187 | sess = cls_session->dd_data; |
3173 | ddb_entry = sess->dd_data; | 3188 | ddb_entry = sess->dd_data; |
@@ -3175,11 +3190,20 @@ int qla4xxx_unblock_ddb(struct iscsi_cls_session *cls_session) | |||
3175 | ql4_printk(KERN_INFO, ha, "scsi%ld: %s: ddb[%d]" | 3190 | ql4_printk(KERN_INFO, ha, "scsi%ld: %s: ddb[%d]" |
3176 | " unblock user space session\n", ha->host_no, __func__, | 3191 | " unblock user space session\n", ha->host_no, __func__, |
3177 | ddb_entry->fw_ddb_index); | 3192 | ddb_entry->fw_ddb_index); |
3178 | iscsi_conn_start(ddb_entry->conn); | ||
3179 | iscsi_conn_login_event(ddb_entry->conn, | ||
3180 | ISCSI_CONN_STATE_LOGGED_IN); | ||
3181 | 3193 | ||
3182 | return QLA_SUCCESS; | 3194 | if (!iscsi_is_session_online(cls_session)) { |
3195 | iscsi_conn_start(ddb_entry->conn); | ||
3196 | iscsi_conn_login_event(ddb_entry->conn, | ||
3197 | ISCSI_CONN_STATE_LOGGED_IN); | ||
3198 | } else { | ||
3199 | ql4_printk(KERN_INFO, ha, | ||
3200 | "scsi%ld: %s: ddb[%d] session [%d] already logged in\n", | ||
3201 | ha->host_no, __func__, ddb_entry->fw_ddb_index, | ||
3202 | cls_session->sid); | ||
3203 | status = QLA_ERROR; | ||
3204 | } | ||
3205 | |||
3206 | return status; | ||
3183 | } | 3207 | } |
3184 | 3208 | ||
3185 | static void qla4xxx_relogin_all_devices(struct scsi_qla_host *ha) | 3209 | static void qla4xxx_relogin_all_devices(struct scsi_qla_host *ha) |
@@ -3373,15 +3397,26 @@ static void qla4xxx_do_dpc(struct work_struct *work) | |||
3373 | /* post events to application */ | 3397 | /* post events to application */ |
3374 | qla4xxx_do_work(ha); | 3398 | qla4xxx_do_work(ha); |
3375 | 3399 | ||
3376 | if (is_qla8022(ha)) { | 3400 | if (is_qla80XX(ha)) { |
3377 | if (test_bit(DPC_HA_UNRECOVERABLE, &ha->dpc_flags)) { | 3401 | if (test_bit(DPC_HA_UNRECOVERABLE, &ha->dpc_flags)) { |
3378 | qla4_8xxx_idc_lock(ha); | 3402 | if (is_qla8032(ha)) { |
3379 | qla4_8xxx_wr_32(ha, QLA82XX_CRB_DEV_STATE, | 3403 | ql4_printk(KERN_INFO, ha, "%s: disabling pause transmit on port 0 & 1.\n", |
3380 | QLA82XX_DEV_FAILED); | 3404 | __func__); |
3381 | qla4_8xxx_idc_unlock(ha); | 3405 | /* disable pause frame for ISP83xx */ |
3406 | qla4_83xx_disable_pause(ha); | ||
3407 | } | ||
3408 | |||
3409 | ha->isp_ops->idc_lock(ha); | ||
3410 | qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE, | ||
3411 | QLA8XXX_DEV_FAILED); | ||
3412 | ha->isp_ops->idc_unlock(ha); | ||
3382 | ql4_printk(KERN_INFO, ha, "HW State: FAILED\n"); | 3413 | ql4_printk(KERN_INFO, ha, "HW State: FAILED\n"); |
3383 | qla4_8xxx_device_state_handler(ha); | 3414 | qla4_8xxx_device_state_handler(ha); |
3384 | } | 3415 | } |
3416 | |||
3417 | if (test_and_clear_bit(DPC_POST_IDC_ACK, &ha->dpc_flags)) | ||
3418 | qla4_83xx_post_idc_ack(ha); | ||
3419 | |||
3385 | if (test_and_clear_bit(DPC_HA_NEED_QUIESCENT, &ha->dpc_flags)) { | 3420 | if (test_and_clear_bit(DPC_HA_NEED_QUIESCENT, &ha->dpc_flags)) { |
3386 | qla4_8xxx_need_qsnt_handler(ha); | 3421 | qla4_8xxx_need_qsnt_handler(ha); |
3387 | } | 3422 | } |
@@ -3391,7 +3426,8 @@ static void qla4xxx_do_dpc(struct work_struct *work) | |||
3391 | (test_bit(DPC_RESET_HA, &ha->dpc_flags) || | 3426 | (test_bit(DPC_RESET_HA, &ha->dpc_flags) || |
3392 | test_bit(DPC_RESET_HA_INTR, &ha->dpc_flags) || | 3427 | test_bit(DPC_RESET_HA_INTR, &ha->dpc_flags) || |
3393 | test_bit(DPC_RESET_HA_FW_CONTEXT, &ha->dpc_flags))) { | 3428 | test_bit(DPC_RESET_HA_FW_CONTEXT, &ha->dpc_flags))) { |
3394 | if (ql4xdontresethba) { | 3429 | if ((is_qla8022(ha) && ql4xdontresethba) || |
3430 | (is_qla8032(ha) && qla4_83xx_idc_dontreset(ha))) { | ||
3395 | DEBUG2(printk("scsi%ld: %s: Don't Reset HBA\n", | 3431 | DEBUG2(printk("scsi%ld: %s: Don't Reset HBA\n", |
3396 | ha->host_no, __func__)); | 3432 | ha->host_no, __func__)); |
3397 | clear_bit(DPC_RESET_HA, &ha->dpc_flags); | 3433 | clear_bit(DPC_RESET_HA, &ha->dpc_flags); |
@@ -3477,6 +3513,18 @@ static void qla4xxx_free_adapter(struct scsi_qla_host *ha) | |||
3477 | ha->isp_ops->disable_intrs(ha); | 3513 | ha->isp_ops->disable_intrs(ha); |
3478 | } | 3514 | } |
3479 | 3515 | ||
3516 | if (is_qla40XX(ha)) { | ||
3517 | writel(set_rmask(CSR_SCSI_PROCESSOR_INTR), | ||
3518 | &ha->reg->ctrl_status); | ||
3519 | readl(&ha->reg->ctrl_status); | ||
3520 | } else if (is_qla8022(ha)) { | ||
3521 | writel(0, &ha->qla4_82xx_reg->host_int); | ||
3522 | readl(&ha->qla4_82xx_reg->host_int); | ||
3523 | } else if (is_qla8032(ha)) { | ||
3524 | writel(0, &ha->qla4_83xx_reg->risc_intr); | ||
3525 | readl(&ha->qla4_83xx_reg->risc_intr); | ||
3526 | } | ||
3527 | |||
3480 | /* Remove timer thread, if present */ | 3528 | /* Remove timer thread, if present */ |
3481 | if (ha->timer_active) | 3529 | if (ha->timer_active) |
3482 | qla4xxx_stop_timer(ha); | 3530 | qla4xxx_stop_timer(ha); |
@@ -3492,10 +3540,10 @@ static void qla4xxx_free_adapter(struct scsi_qla_host *ha) | |||
3492 | /* Put firmware in known state */ | 3540 | /* Put firmware in known state */ |
3493 | ha->isp_ops->reset_firmware(ha); | 3541 | ha->isp_ops->reset_firmware(ha); |
3494 | 3542 | ||
3495 | if (is_qla8022(ha)) { | 3543 | if (is_qla80XX(ha)) { |
3496 | qla4_8xxx_idc_lock(ha); | 3544 | ha->isp_ops->idc_lock(ha); |
3497 | qla4_8xxx_clear_drv_active(ha); | 3545 | qla4_8xxx_clear_drv_active(ha); |
3498 | qla4_8xxx_idc_unlock(ha); | 3546 | ha->isp_ops->idc_unlock(ha); |
3499 | } | 3547 | } |
3500 | 3548 | ||
3501 | /* Detach interrupts */ | 3549 | /* Detach interrupts */ |
@@ -3542,16 +3590,20 @@ int qla4_8xxx_iospace_config(struct scsi_qla_host *ha) | |||
3542 | /* Mapping of IO base pointer, door bell read and write pointer */ | 3590 | /* Mapping of IO base pointer, door bell read and write pointer */ |
3543 | 3591 | ||
3544 | /* mapping of IO base pointer */ | 3592 | /* mapping of IO base pointer */ |
3545 | ha->qla4_8xxx_reg = | 3593 | if (is_qla8022(ha)) { |
3546 | (struct device_reg_82xx __iomem *)((uint8_t *)ha->nx_pcibase + | 3594 | ha->qla4_82xx_reg = (struct device_reg_82xx __iomem *) |
3547 | 0xbc000 + (ha->pdev->devfn << 11)); | 3595 | ((uint8_t *)ha->nx_pcibase + 0xbc000 + |
3596 | (ha->pdev->devfn << 11)); | ||
3597 | ha->nx_db_wr_ptr = (ha->pdev->devfn == 4 ? QLA82XX_CAM_RAM_DB1 : | ||
3598 | QLA82XX_CAM_RAM_DB2); | ||
3599 | } else if (is_qla8032(ha)) { | ||
3600 | ha->qla4_83xx_reg = (struct device_reg_83xx __iomem *) | ||
3601 | ((uint8_t *)ha->nx_pcibase); | ||
3602 | } | ||
3548 | 3603 | ||
3549 | db_base = pci_resource_start(pdev, 4); /* doorbell is on bar 4 */ | 3604 | db_base = pci_resource_start(pdev, 4); /* doorbell is on bar 4 */ |
3550 | db_len = pci_resource_len(pdev, 4); | 3605 | db_len = pci_resource_len(pdev, 4); |
3551 | 3606 | ||
3552 | ha->nx_db_wr_ptr = (ha->pdev->devfn == 4 ? QLA82XX_CAM_RAM_DB1 : | ||
3553 | QLA82XX_CAM_RAM_DB2); | ||
3554 | |||
3555 | return 0; | 3607 | return 0; |
3556 | iospace_error_exit: | 3608 | iospace_error_exit: |
3557 | return -ENOMEM; | 3609 | return -ENOMEM; |
@@ -3639,23 +3691,64 @@ static struct isp_operations qla4xxx_isp_ops = { | |||
3639 | .rd_shdw_req_q_out = qla4xxx_rd_shdw_req_q_out, | 3691 | .rd_shdw_req_q_out = qla4xxx_rd_shdw_req_q_out, |
3640 | .rd_shdw_rsp_q_in = qla4xxx_rd_shdw_rsp_q_in, | 3692 | .rd_shdw_rsp_q_in = qla4xxx_rd_shdw_rsp_q_in, |
3641 | .get_sys_info = qla4xxx_get_sys_info, | 3693 | .get_sys_info = qla4xxx_get_sys_info, |
3694 | .queue_mailbox_command = qla4xxx_queue_mbox_cmd, | ||
3695 | .process_mailbox_interrupt = qla4xxx_process_mbox_intr, | ||
3642 | }; | 3696 | }; |
3643 | 3697 | ||
3644 | static struct isp_operations qla4_8xxx_isp_ops = { | 3698 | static struct isp_operations qla4_82xx_isp_ops = { |
3645 | .iospace_config = qla4_8xxx_iospace_config, | 3699 | .iospace_config = qla4_8xxx_iospace_config, |
3646 | .pci_config = qla4_8xxx_pci_config, | 3700 | .pci_config = qla4_8xxx_pci_config, |
3647 | .disable_intrs = qla4_8xxx_disable_intrs, | 3701 | .disable_intrs = qla4_82xx_disable_intrs, |
3648 | .enable_intrs = qla4_8xxx_enable_intrs, | 3702 | .enable_intrs = qla4_82xx_enable_intrs, |
3649 | .start_firmware = qla4_8xxx_load_risc, | 3703 | .start_firmware = qla4_8xxx_load_risc, |
3650 | .intr_handler = qla4_8xxx_intr_handler, | 3704 | .restart_firmware = qla4_82xx_try_start_fw, |
3651 | .interrupt_service_routine = qla4_8xxx_interrupt_service_routine, | 3705 | .intr_handler = qla4_82xx_intr_handler, |
3652 | .reset_chip = qla4_8xxx_isp_reset, | 3706 | .interrupt_service_routine = qla4_82xx_interrupt_service_routine, |
3707 | .need_reset = qla4_8xxx_need_reset, | ||
3708 | .reset_chip = qla4_82xx_isp_reset, | ||
3653 | .reset_firmware = qla4_8xxx_stop_firmware, | 3709 | .reset_firmware = qla4_8xxx_stop_firmware, |
3654 | .queue_iocb = qla4_8xxx_queue_iocb, | 3710 | .queue_iocb = qla4_82xx_queue_iocb, |
3655 | .complete_iocb = qla4_8xxx_complete_iocb, | 3711 | .complete_iocb = qla4_82xx_complete_iocb, |
3656 | .rd_shdw_req_q_out = qla4_8xxx_rd_shdw_req_q_out, | 3712 | .rd_shdw_req_q_out = qla4_82xx_rd_shdw_req_q_out, |
3657 | .rd_shdw_rsp_q_in = qla4_8xxx_rd_shdw_rsp_q_in, | 3713 | .rd_shdw_rsp_q_in = qla4_82xx_rd_shdw_rsp_q_in, |
3658 | .get_sys_info = qla4_8xxx_get_sys_info, | 3714 | .get_sys_info = qla4_8xxx_get_sys_info, |
3715 | .rd_reg_direct = qla4_82xx_rd_32, | ||
3716 | .wr_reg_direct = qla4_82xx_wr_32, | ||
3717 | .rd_reg_indirect = qla4_82xx_md_rd_32, | ||
3718 | .wr_reg_indirect = qla4_82xx_md_wr_32, | ||
3719 | .idc_lock = qla4_82xx_idc_lock, | ||
3720 | .idc_unlock = qla4_82xx_idc_unlock, | ||
3721 | .rom_lock_recovery = qla4_82xx_rom_lock_recovery, | ||
3722 | .queue_mailbox_command = qla4_82xx_queue_mbox_cmd, | ||
3723 | .process_mailbox_interrupt = qla4_82xx_process_mbox_intr, | ||
3724 | }; | ||
3725 | |||
3726 | static struct isp_operations qla4_83xx_isp_ops = { | ||
3727 | .iospace_config = qla4_8xxx_iospace_config, | ||
3728 | .pci_config = qla4_8xxx_pci_config, | ||
3729 | .disable_intrs = qla4_83xx_disable_intrs, | ||
3730 | .enable_intrs = qla4_83xx_enable_intrs, | ||
3731 | .start_firmware = qla4_8xxx_load_risc, | ||
3732 | .restart_firmware = qla4_83xx_start_firmware, | ||
3733 | .intr_handler = qla4_83xx_intr_handler, | ||
3734 | .interrupt_service_routine = qla4_83xx_interrupt_service_routine, | ||
3735 | .need_reset = qla4_8xxx_need_reset, | ||
3736 | .reset_chip = qla4_83xx_isp_reset, | ||
3737 | .reset_firmware = qla4_8xxx_stop_firmware, | ||
3738 | .queue_iocb = qla4_83xx_queue_iocb, | ||
3739 | .complete_iocb = qla4_83xx_complete_iocb, | ||
3740 | .rd_shdw_req_q_out = qla4_83xx_rd_shdw_req_q_out, | ||
3741 | .rd_shdw_rsp_q_in = qla4_83xx_rd_shdw_rsp_q_in, | ||
3742 | .get_sys_info = qla4_8xxx_get_sys_info, | ||
3743 | .rd_reg_direct = qla4_83xx_rd_reg, | ||
3744 | .wr_reg_direct = qla4_83xx_wr_reg, | ||
3745 | .rd_reg_indirect = qla4_83xx_rd_reg_indirect, | ||
3746 | .wr_reg_indirect = qla4_83xx_wr_reg_indirect, | ||
3747 | .idc_lock = qla4_83xx_drv_lock, | ||
3748 | .idc_unlock = qla4_83xx_drv_unlock, | ||
3749 | .rom_lock_recovery = qla4_83xx_rom_lock_recovery, | ||
3750 | .queue_mailbox_command = qla4_83xx_queue_mbox_cmd, | ||
3751 | .process_mailbox_interrupt = qla4_83xx_process_mbox_intr, | ||
3659 | }; | 3752 | }; |
3660 | 3753 | ||
3661 | uint16_t qla4xxx_rd_shdw_req_q_out(struct scsi_qla_host *ha) | 3754 | uint16_t qla4xxx_rd_shdw_req_q_out(struct scsi_qla_host *ha) |
@@ -3663,9 +3756,14 @@ uint16_t qla4xxx_rd_shdw_req_q_out(struct scsi_qla_host *ha) | |||
3663 | return (uint16_t)le32_to_cpu(ha->shadow_regs->req_q_out); | 3756 | return (uint16_t)le32_to_cpu(ha->shadow_regs->req_q_out); |
3664 | } | 3757 | } |
3665 | 3758 | ||
3666 | uint16_t qla4_8xxx_rd_shdw_req_q_out(struct scsi_qla_host *ha) | 3759 | uint16_t qla4_82xx_rd_shdw_req_q_out(struct scsi_qla_host *ha) |
3667 | { | 3760 | { |
3668 | return (uint16_t)le32_to_cpu(readl(&ha->qla4_8xxx_reg->req_q_out)); | 3761 | return (uint16_t)le32_to_cpu(readl(&ha->qla4_82xx_reg->req_q_out)); |
3762 | } | ||
3763 | |||
3764 | uint16_t qla4_83xx_rd_shdw_req_q_out(struct scsi_qla_host *ha) | ||
3765 | { | ||
3766 | return (uint16_t)le32_to_cpu(readl(&ha->qla4_83xx_reg->req_q_out)); | ||
3669 | } | 3767 | } |
3670 | 3768 | ||
3671 | uint16_t qla4xxx_rd_shdw_rsp_q_in(struct scsi_qla_host *ha) | 3769 | uint16_t qla4xxx_rd_shdw_rsp_q_in(struct scsi_qla_host *ha) |
@@ -3673,9 +3771,14 @@ uint16_t qla4xxx_rd_shdw_rsp_q_in(struct scsi_qla_host *ha) | |||
3673 | return (uint16_t)le32_to_cpu(ha->shadow_regs->rsp_q_in); | 3771 | return (uint16_t)le32_to_cpu(ha->shadow_regs->rsp_q_in); |
3674 | } | 3772 | } |
3675 | 3773 | ||
3676 | uint16_t qla4_8xxx_rd_shdw_rsp_q_in(struct scsi_qla_host *ha) | 3774 | uint16_t qla4_82xx_rd_shdw_rsp_q_in(struct scsi_qla_host *ha) |
3677 | { | 3775 | { |
3678 | return (uint16_t)le32_to_cpu(readl(&ha->qla4_8xxx_reg->rsp_q_in)); | 3776 | return (uint16_t)le32_to_cpu(readl(&ha->qla4_82xx_reg->rsp_q_in)); |
3777 | } | ||
3778 | |||
3779 | uint16_t qla4_83xx_rd_shdw_rsp_q_in(struct scsi_qla_host *ha) | ||
3780 | { | ||
3781 | return (uint16_t)le32_to_cpu(readl(&ha->qla4_83xx_reg->rsp_q_in)); | ||
3679 | } | 3782 | } |
3680 | 3783 | ||
3681 | static ssize_t qla4xxx_show_boot_eth_info(void *data, int type, char *buf) | 3784 | static ssize_t qla4xxx_show_boot_eth_info(void *data, int type, char *buf) |
@@ -5050,30 +5153,36 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev, | |||
5050 | ha->pdev = pdev; | 5153 | ha->pdev = pdev; |
5051 | ha->host = host; | 5154 | ha->host = host; |
5052 | ha->host_no = host->host_no; | 5155 | ha->host_no = host->host_no; |
5156 | ha->func_num = PCI_FUNC(ha->pdev->devfn); | ||
5053 | 5157 | ||
5054 | pci_enable_pcie_error_reporting(pdev); | 5158 | pci_enable_pcie_error_reporting(pdev); |
5055 | 5159 | ||
5056 | /* Setup Runtime configurable options */ | 5160 | /* Setup Runtime configurable options */ |
5057 | if (is_qla8022(ha)) { | 5161 | if (is_qla8022(ha)) { |
5058 | ha->isp_ops = &qla4_8xxx_isp_ops; | 5162 | ha->isp_ops = &qla4_82xx_isp_ops; |
5059 | rwlock_init(&ha->hw_lock); | 5163 | ha->reg_tbl = (uint32_t *) qla4_82xx_reg_tbl; |
5060 | ha->qdr_sn_window = -1; | 5164 | ha->qdr_sn_window = -1; |
5061 | ha->ddr_mn_window = -1; | 5165 | ha->ddr_mn_window = -1; |
5062 | ha->curr_window = 255; | 5166 | ha->curr_window = 255; |
5063 | ha->func_num = PCI_FUNC(ha->pdev->devfn); | ||
5064 | nx_legacy_intr = &legacy_intr[ha->func_num]; | 5167 | nx_legacy_intr = &legacy_intr[ha->func_num]; |
5065 | ha->nx_legacy_intr.int_vec_bit = nx_legacy_intr->int_vec_bit; | 5168 | ha->nx_legacy_intr.int_vec_bit = nx_legacy_intr->int_vec_bit; |
5066 | ha->nx_legacy_intr.tgt_status_reg = | 5169 | ha->nx_legacy_intr.tgt_status_reg = |
5067 | nx_legacy_intr->tgt_status_reg; | 5170 | nx_legacy_intr->tgt_status_reg; |
5068 | ha->nx_legacy_intr.tgt_mask_reg = nx_legacy_intr->tgt_mask_reg; | 5171 | ha->nx_legacy_intr.tgt_mask_reg = nx_legacy_intr->tgt_mask_reg; |
5069 | ha->nx_legacy_intr.pci_int_reg = nx_legacy_intr->pci_int_reg; | 5172 | ha->nx_legacy_intr.pci_int_reg = nx_legacy_intr->pci_int_reg; |
5173 | } else if (is_qla8032(ha)) { | ||
5174 | ha->isp_ops = &qla4_83xx_isp_ops; | ||
5175 | ha->reg_tbl = (uint32_t *)qla4_83xx_reg_tbl; | ||
5070 | } else { | 5176 | } else { |
5071 | ha->isp_ops = &qla4xxx_isp_ops; | 5177 | ha->isp_ops = &qla4xxx_isp_ops; |
5072 | } | 5178 | } |
5073 | 5179 | ||
5074 | /* Set EEH reset type to fundamental if required by hba */ | 5180 | if (is_qla80XX(ha)) { |
5075 | if (is_qla8022(ha)) | 5181 | rwlock_init(&ha->hw_lock); |
5182 | ha->pf_bit = ha->func_num << 16; | ||
5183 | /* Set EEH reset type to fundamental if required by hba */ | ||
5076 | pdev->needs_freset = 1; | 5184 | pdev->needs_freset = 1; |
5185 | } | ||
5077 | 5186 | ||
5078 | /* Configure PCI I/O space. */ | 5187 | /* Configure PCI I/O space. */ |
5079 | ret = ha->isp_ops->iospace_config(ha); | 5188 | ret = ha->isp_ops->iospace_config(ha); |
@@ -5094,6 +5203,7 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev, | |||
5094 | init_completion(&ha->disable_acb_comp); | 5203 | init_completion(&ha->disable_acb_comp); |
5095 | 5204 | ||
5096 | spin_lock_init(&ha->hardware_lock); | 5205 | spin_lock_init(&ha->hardware_lock); |
5206 | spin_lock_init(&ha->work_lock); | ||
5097 | 5207 | ||
5098 | /* Initialize work list */ | 5208 | /* Initialize work list */ |
5099 | INIT_LIST_HEAD(&ha->work_list); | 5209 | INIT_LIST_HEAD(&ha->work_list); |
@@ -5128,8 +5238,20 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev, | |||
5128 | if (ret) | 5238 | if (ret) |
5129 | goto probe_failed; | 5239 | goto probe_failed; |
5130 | 5240 | ||
5131 | if (is_qla8022(ha)) | 5241 | if (is_qla80XX(ha)) |
5132 | (void) qla4_8xxx_get_flash_info(ha); | 5242 | qla4_8xxx_get_flash_info(ha); |
5243 | |||
5244 | if (is_qla8032(ha)) { | ||
5245 | qla4_83xx_read_reset_template(ha); | ||
5246 | /* | ||
5247 | * NOTE: If ql4dontresethba==1, set IDC_CTRL DONTRESET_BIT0. | ||
5248 | * If DONRESET_BIT0 is set, drivers should not set dev_state | ||
5249 | * to NEED_RESET. But if NEED_RESET is set, drivers should | ||
5250 | * should honor the reset. | ||
5251 | */ | ||
5252 | if (ql4xdontresethba == 1) | ||
5253 | qla4_83xx_set_idc_dontreset(ha); | ||
5254 | } | ||
5133 | 5255 | ||
5134 | /* | 5256 | /* |
5135 | * Initialize the Host adapter request/response queues and | 5257 | * Initialize the Host adapter request/response queues and |
@@ -5137,14 +5259,20 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev, | |||
5137 | * NOTE: interrupts enabled upon successful completion | 5259 | * NOTE: interrupts enabled upon successful completion |
5138 | */ | 5260 | */ |
5139 | status = qla4xxx_initialize_adapter(ha, INIT_ADAPTER); | 5261 | status = qla4xxx_initialize_adapter(ha, INIT_ADAPTER); |
5262 | |||
5263 | /* Dont retry adapter initialization if IRQ allocation failed */ | ||
5264 | if (!test_bit(AF_IRQ_ATTACHED, &ha->flags)) | ||
5265 | goto skip_retry_init; | ||
5266 | |||
5140 | while ((!test_bit(AF_ONLINE, &ha->flags)) && | 5267 | while ((!test_bit(AF_ONLINE, &ha->flags)) && |
5141 | init_retry_count++ < MAX_INIT_RETRIES) { | 5268 | init_retry_count++ < MAX_INIT_RETRIES) { |
5142 | 5269 | ||
5143 | if (is_qla8022(ha)) { | 5270 | if (is_qla80XX(ha)) { |
5144 | qla4_8xxx_idc_lock(ha); | 5271 | ha->isp_ops->idc_lock(ha); |
5145 | dev_state = qla4_8xxx_rd_32(ha, QLA82XX_CRB_DEV_STATE); | 5272 | dev_state = qla4_8xxx_rd_direct(ha, |
5146 | qla4_8xxx_idc_unlock(ha); | 5273 | QLA82XX_CRB_DEV_STATE); |
5147 | if (dev_state == QLA82XX_DEV_FAILED) { | 5274 | ha->isp_ops->idc_unlock(ha); |
5275 | if (dev_state == QLA8XXX_DEV_FAILED) { | ||
5148 | ql4_printk(KERN_WARNING, ha, "%s: don't retry " | 5276 | ql4_printk(KERN_WARNING, ha, "%s: don't retry " |
5149 | "initialize adapter. H/W is in failed state\n", | 5277 | "initialize adapter. H/W is in failed state\n", |
5150 | __func__); | 5278 | __func__); |
@@ -5160,16 +5288,18 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev, | |||
5160 | status = qla4xxx_initialize_adapter(ha, INIT_ADAPTER); | 5288 | status = qla4xxx_initialize_adapter(ha, INIT_ADAPTER); |
5161 | } | 5289 | } |
5162 | 5290 | ||
5291 | skip_retry_init: | ||
5163 | if (!test_bit(AF_ONLINE, &ha->flags)) { | 5292 | if (!test_bit(AF_ONLINE, &ha->flags)) { |
5164 | ql4_printk(KERN_WARNING, ha, "Failed to initialize adapter\n"); | 5293 | ql4_printk(KERN_WARNING, ha, "Failed to initialize adapter\n"); |
5165 | 5294 | ||
5166 | if (is_qla8022(ha) && ql4xdontresethba) { | 5295 | if ((is_qla8022(ha) && ql4xdontresethba) || |
5296 | (is_qla8032(ha) && qla4_83xx_idc_dontreset(ha))) { | ||
5167 | /* Put the device in failed state. */ | 5297 | /* Put the device in failed state. */ |
5168 | DEBUG2(printk(KERN_ERR "HW STATE: FAILED\n")); | 5298 | DEBUG2(printk(KERN_ERR "HW STATE: FAILED\n")); |
5169 | qla4_8xxx_idc_lock(ha); | 5299 | ha->isp_ops->idc_lock(ha); |
5170 | qla4_8xxx_wr_32(ha, QLA82XX_CRB_DEV_STATE, | 5300 | qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE, |
5171 | QLA82XX_DEV_FAILED); | 5301 | QLA8XXX_DEV_FAILED); |
5172 | qla4_8xxx_idc_unlock(ha); | 5302 | ha->isp_ops->idc_unlock(ha); |
5173 | } | 5303 | } |
5174 | ret = -ENODEV; | 5304 | ret = -ENODEV; |
5175 | goto remove_host; | 5305 | goto remove_host; |
@@ -5195,12 +5325,13 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev, | |||
5195 | goto remove_host; | 5325 | goto remove_host; |
5196 | } | 5326 | } |
5197 | 5327 | ||
5198 | /* For ISP-82XX, request_irqs is called in qla4_8xxx_load_risc | 5328 | /* |
5329 | * For ISP-8XXX, request_irqs is called in qla4_8xxx_load_risc | ||
5199 | * (which is called indirectly by qla4xxx_initialize_adapter), | 5330 | * (which is called indirectly by qla4xxx_initialize_adapter), |
5200 | * so that irqs will be registered after crbinit but before | 5331 | * so that irqs will be registered after crbinit but before |
5201 | * mbx_intr_enable. | 5332 | * mbx_intr_enable. |
5202 | */ | 5333 | */ |
5203 | if (!is_qla8022(ha)) { | 5334 | if (is_qla40XX(ha)) { |
5204 | ret = qla4xxx_request_irqs(ha); | 5335 | ret = qla4xxx_request_irqs(ha); |
5205 | if (ret) { | 5336 | if (ret) { |
5206 | ql4_printk(KERN_WARNING, ha, "Failed to reserve " | 5337 | ql4_printk(KERN_WARNING, ha, "Failed to reserve " |
@@ -5226,6 +5357,10 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev, | |||
5226 | ha->host_no, ha->firmware_version[0], ha->firmware_version[1], | 5357 | ha->host_no, ha->firmware_version[0], ha->firmware_version[1], |
5227 | ha->patch_number, ha->build_number); | 5358 | ha->patch_number, ha->build_number); |
5228 | 5359 | ||
5360 | /* Set the driver version */ | ||
5361 | if (is_qla80XX(ha)) | ||
5362 | qla4_8xxx_set_param(ha, SET_DRVR_VERSION); | ||
5363 | |||
5229 | if (qla4xxx_setup_boot_info(ha)) | 5364 | if (qla4xxx_setup_boot_info(ha)) |
5230 | ql4_printk(KERN_ERR, ha, | 5365 | ql4_printk(KERN_ERR, ha, |
5231 | "%s: No iSCSI boot target configured\n", __func__); | 5366 | "%s: No iSCSI boot target configured\n", __func__); |
@@ -5333,9 +5468,16 @@ static void __devexit qla4xxx_remove_adapter(struct pci_dev *pdev) | |||
5333 | { | 5468 | { |
5334 | struct scsi_qla_host *ha; | 5469 | struct scsi_qla_host *ha; |
5335 | 5470 | ||
5471 | /* | ||
5472 | * If the PCI device is disabled then it means probe_adapter had | ||
5473 | * failed and resources already cleaned up on probe_adapter exit. | ||
5474 | */ | ||
5475 | if (!pci_is_enabled(pdev)) | ||
5476 | return; | ||
5477 | |||
5336 | ha = pci_get_drvdata(pdev); | 5478 | ha = pci_get_drvdata(pdev); |
5337 | 5479 | ||
5338 | if (!is_qla8022(ha)) | 5480 | if (is_qla40XX(ha)) |
5339 | qla4xxx_prevent_other_port_reinit(ha); | 5481 | qla4xxx_prevent_other_port_reinit(ha); |
5340 | 5482 | ||
5341 | /* destroy iface from sysfs */ | 5483 | /* destroy iface from sysfs */ |
@@ -5755,7 +5897,16 @@ static int qla4xxx_eh_host_reset(struct scsi_cmnd *cmd) | |||
5755 | 5897 | ||
5756 | ha = to_qla_host(cmd->device->host); | 5898 | ha = to_qla_host(cmd->device->host); |
5757 | 5899 | ||
5758 | if (ql4xdontresethba) { | 5900 | if (is_qla8032(ha) && ql4xdontresethba) |
5901 | qla4_83xx_set_idc_dontreset(ha); | ||
5902 | |||
5903 | /* | ||
5904 | * For ISP8324, if IDC_CTRL DONTRESET_BIT0 is set by other | ||
5905 | * protocol drivers, we should not set device_state to | ||
5906 | * NEED_RESET | ||
5907 | */ | ||
5908 | if (ql4xdontresethba || | ||
5909 | (is_qla8032(ha) && qla4_83xx_idc_dontreset(ha))) { | ||
5759 | DEBUG2(printk("scsi%ld: %s: Don't Reset HBA\n", | 5910 | DEBUG2(printk("scsi%ld: %s: Don't Reset HBA\n", |
5760 | ha->host_no, __func__)); | 5911 | ha->host_no, __func__)); |
5761 | 5912 | ||
@@ -5779,7 +5930,7 @@ static int qla4xxx_eh_host_reset(struct scsi_cmnd *cmd) | |||
5779 | } | 5930 | } |
5780 | 5931 | ||
5781 | if (!test_bit(DPC_RESET_HA, &ha->dpc_flags)) { | 5932 | if (!test_bit(DPC_RESET_HA, &ha->dpc_flags)) { |
5782 | if (is_qla8022(ha)) | 5933 | if (is_qla80XX(ha)) |
5783 | set_bit(DPC_RESET_HA_FW_CONTEXT, &ha->dpc_flags); | 5934 | set_bit(DPC_RESET_HA_FW_CONTEXT, &ha->dpc_flags); |
5784 | else | 5935 | else |
5785 | set_bit(DPC_RESET_HA, &ha->dpc_flags); | 5936 | set_bit(DPC_RESET_HA, &ha->dpc_flags); |
@@ -5874,7 +6025,7 @@ static int qla4xxx_host_reset(struct Scsi_Host *shost, int reset_type) | |||
5874 | break; | 6025 | break; |
5875 | case SCSI_FIRMWARE_RESET: | 6026 | case SCSI_FIRMWARE_RESET: |
5876 | if (!test_bit(DPC_RESET_HA, &ha->dpc_flags)) { | 6027 | if (!test_bit(DPC_RESET_HA, &ha->dpc_flags)) { |
5877 | if (is_qla8022(ha)) | 6028 | if (is_qla80XX(ha)) |
5878 | /* set firmware context reset */ | 6029 | /* set firmware context reset */ |
5879 | set_bit(DPC_RESET_HA_FW_CONTEXT, | 6030 | set_bit(DPC_RESET_HA_FW_CONTEXT, |
5880 | &ha->dpc_flags); | 6031 | &ha->dpc_flags); |
@@ -6013,32 +6164,43 @@ static uint32_t qla4_8xxx_error_recovery(struct scsi_qla_host *ha) | |||
6013 | "0x%x is the owner\n", ha->host_no, __func__, | 6164 | "0x%x is the owner\n", ha->host_no, __func__, |
6014 | ha->pdev->devfn); | 6165 | ha->pdev->devfn); |
6015 | 6166 | ||
6016 | qla4_8xxx_idc_lock(ha); | 6167 | ha->isp_ops->idc_lock(ha); |
6017 | qla4_8xxx_wr_32(ha, QLA82XX_CRB_DEV_STATE, | 6168 | qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE, |
6018 | QLA82XX_DEV_COLD); | 6169 | QLA8XXX_DEV_COLD); |
6019 | 6170 | ha->isp_ops->idc_unlock(ha); | |
6020 | qla4_8xxx_wr_32(ha, QLA82XX_CRB_DRV_IDC_VERSION, | 6171 | |
6021 | QLA82XX_IDC_VERSION); | 6172 | rval = qla4_8xxx_update_idc_reg(ha); |
6173 | if (rval == QLA_ERROR) { | ||
6174 | ql4_printk(KERN_INFO, ha, "scsi%ld: %s: HW State: FAILED\n", | ||
6175 | ha->host_no, __func__); | ||
6176 | ha->isp_ops->idc_lock(ha); | ||
6177 | qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE, | ||
6178 | QLA8XXX_DEV_FAILED); | ||
6179 | ha->isp_ops->idc_unlock(ha); | ||
6180 | goto exit_error_recovery; | ||
6181 | } | ||
6022 | 6182 | ||
6023 | qla4_8xxx_idc_unlock(ha); | ||
6024 | clear_bit(AF_FW_RECOVERY, &ha->flags); | 6183 | clear_bit(AF_FW_RECOVERY, &ha->flags); |
6025 | rval = qla4xxx_initialize_adapter(ha, RESET_ADAPTER); | 6184 | rval = qla4xxx_initialize_adapter(ha, RESET_ADAPTER); |
6026 | qla4_8xxx_idc_lock(ha); | ||
6027 | 6185 | ||
6028 | if (rval != QLA_SUCCESS) { | 6186 | if (rval != QLA_SUCCESS) { |
6029 | ql4_printk(KERN_INFO, ha, "scsi%ld: %s: HW State: " | 6187 | ql4_printk(KERN_INFO, ha, "scsi%ld: %s: HW State: " |
6030 | "FAILED\n", ha->host_no, __func__); | 6188 | "FAILED\n", ha->host_no, __func__); |
6189 | ha->isp_ops->idc_lock(ha); | ||
6031 | qla4_8xxx_clear_drv_active(ha); | 6190 | qla4_8xxx_clear_drv_active(ha); |
6032 | qla4_8xxx_wr_32(ha, QLA82XX_CRB_DEV_STATE, | 6191 | qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE, |
6033 | QLA82XX_DEV_FAILED); | 6192 | QLA8XXX_DEV_FAILED); |
6193 | ha->isp_ops->idc_unlock(ha); | ||
6034 | } else { | 6194 | } else { |
6035 | ql4_printk(KERN_INFO, ha, "scsi%ld: %s: HW State: " | 6195 | ql4_printk(KERN_INFO, ha, "scsi%ld: %s: HW State: " |
6036 | "READY\n", ha->host_no, __func__); | 6196 | "READY\n", ha->host_no, __func__); |
6037 | qla4_8xxx_wr_32(ha, QLA82XX_CRB_DEV_STATE, | 6197 | ha->isp_ops->idc_lock(ha); |
6038 | QLA82XX_DEV_READY); | 6198 | qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE, |
6199 | QLA8XXX_DEV_READY); | ||
6039 | /* Clear driver state register */ | 6200 | /* Clear driver state register */ |
6040 | qla4_8xxx_wr_32(ha, QLA82XX_CRB_DRV_STATE, 0); | 6201 | qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DRV_STATE, 0); |
6041 | qla4_8xxx_set_drv_active(ha); | 6202 | qla4_8xxx_set_drv_active(ha); |
6203 | ha->isp_ops->idc_unlock(ha); | ||
6042 | ret = qla4xxx_request_irqs(ha); | 6204 | ret = qla4xxx_request_irqs(ha); |
6043 | if (ret) { | 6205 | if (ret) { |
6044 | ql4_printk(KERN_WARNING, ha, "Failed to " | 6206 | ql4_printk(KERN_WARNING, ha, "Failed to " |
@@ -6050,13 +6212,12 @@ static uint32_t qla4_8xxx_error_recovery(struct scsi_qla_host *ha) | |||
6050 | rval = QLA_SUCCESS; | 6212 | rval = QLA_SUCCESS; |
6051 | } | 6213 | } |
6052 | } | 6214 | } |
6053 | qla4_8xxx_idc_unlock(ha); | ||
6054 | } else { | 6215 | } else { |
6055 | ql4_printk(KERN_INFO, ha, "scsi%ld: %s: devfn 0x%x is not " | 6216 | ql4_printk(KERN_INFO, ha, "scsi%ld: %s: devfn 0x%x is not " |
6056 | "the reset owner\n", ha->host_no, __func__, | 6217 | "the reset owner\n", ha->host_no, __func__, |
6057 | ha->pdev->devfn); | 6218 | ha->pdev->devfn); |
6058 | if ((qla4_8xxx_rd_32(ha, QLA82XX_CRB_DEV_STATE) == | 6219 | if ((qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DEV_STATE) == |
6059 | QLA82XX_DEV_READY)) { | 6220 | QLA8XXX_DEV_READY)) { |
6060 | clear_bit(AF_FW_RECOVERY, &ha->flags); | 6221 | clear_bit(AF_FW_RECOVERY, &ha->flags); |
6061 | rval = qla4xxx_initialize_adapter(ha, RESET_ADAPTER); | 6222 | rval = qla4xxx_initialize_adapter(ha, RESET_ADAPTER); |
6062 | if (rval == QLA_SUCCESS) { | 6223 | if (rval == QLA_SUCCESS) { |
@@ -6071,11 +6232,12 @@ static uint32_t qla4_8xxx_error_recovery(struct scsi_qla_host *ha) | |||
6071 | rval = QLA_SUCCESS; | 6232 | rval = QLA_SUCCESS; |
6072 | } | 6233 | } |
6073 | } | 6234 | } |
6074 | qla4_8xxx_idc_lock(ha); | 6235 | ha->isp_ops->idc_lock(ha); |
6075 | qla4_8xxx_set_drv_active(ha); | 6236 | qla4_8xxx_set_drv_active(ha); |
6076 | qla4_8xxx_idc_unlock(ha); | 6237 | ha->isp_ops->idc_unlock(ha); |
6077 | } | 6238 | } |
6078 | } | 6239 | } |
6240 | exit_error_recovery: | ||
6079 | clear_bit(DPC_RESET_ACTIVE, &ha->dpc_flags); | 6241 | clear_bit(DPC_RESET_ACTIVE, &ha->dpc_flags); |
6080 | return rval; | 6242 | return rval; |
6081 | } | 6243 | } |
@@ -6114,7 +6276,7 @@ qla4xxx_pci_slot_reset(struct pci_dev *pdev) | |||
6114 | 6276 | ||
6115 | ha->isp_ops->disable_intrs(ha); | 6277 | ha->isp_ops->disable_intrs(ha); |
6116 | 6278 | ||
6117 | if (is_qla8022(ha)) { | 6279 | if (is_qla80XX(ha)) { |
6118 | if (qla4_8xxx_error_recovery(ha) == QLA_SUCCESS) { | 6280 | if (qla4_8xxx_error_recovery(ha) == QLA_SUCCESS) { |
6119 | ret = PCI_ERS_RESULT_RECOVERED; | 6281 | ret = PCI_ERS_RESULT_RECOVERED; |
6120 | goto exit_slot_reset; | 6282 | goto exit_slot_reset; |
@@ -6180,6 +6342,12 @@ static struct pci_device_id qla4xxx_pci_tbl[] = { | |||
6180 | .subvendor = PCI_ANY_ID, | 6342 | .subvendor = PCI_ANY_ID, |
6181 | .subdevice = PCI_ANY_ID, | 6343 | .subdevice = PCI_ANY_ID, |
6182 | }, | 6344 | }, |
6345 | { | ||
6346 | .vendor = PCI_VENDOR_ID_QLOGIC, | ||
6347 | .device = PCI_DEVICE_ID_QLOGIC_ISP8324, | ||
6348 | .subvendor = PCI_ANY_ID, | ||
6349 | .subdevice = PCI_ANY_ID, | ||
6350 | }, | ||
6183 | {0, 0}, | 6351 | {0, 0}, |
6184 | }; | 6352 | }; |
6185 | MODULE_DEVICE_TABLE(pci, qla4xxx_pci_tbl); | 6353 | MODULE_DEVICE_TABLE(pci, qla4xxx_pci_tbl); |