diff options
Diffstat (limited to 'drivers/scsi/qla4xxx/ql4_nx.c')
-rw-r--r-- | drivers/scsi/qla4xxx/ql4_nx.c | 89 |
1 files changed, 46 insertions, 43 deletions
diff --git a/drivers/scsi/qla4xxx/ql4_nx.c b/drivers/scsi/qla4xxx/ql4_nx.c index d001202d3565..63328c812b70 100644 --- a/drivers/scsi/qla4xxx/ql4_nx.c +++ b/drivers/scsi/qla4xxx/ql4_nx.c | |||
@@ -2383,6 +2383,11 @@ static void qla4_8xxx_mark_entry_skipped(struct scsi_qla_host *ha, | |||
2383 | "scsi(%ld): Skipping entry[%d]: ETYPE[0x%x]-ELEVEL[0x%x]\n", | 2383 | "scsi(%ld): Skipping entry[%d]: ETYPE[0x%x]-ELEVEL[0x%x]\n", |
2384 | ha->host_no, index, entry_hdr->entry_type, | 2384 | ha->host_no, index, entry_hdr->entry_type, |
2385 | entry_hdr->d_ctrl.entry_capture_mask)); | 2385 | entry_hdr->d_ctrl.entry_capture_mask)); |
2386 | /* If driver encounters a new entry type that it cannot process, | ||
2387 | * it should just skip the entry and adjust the total buffer size by | ||
2388 | * from subtracting the skipped bytes from it | ||
2389 | */ | ||
2390 | ha->fw_dump_skip_size += entry_hdr->entry_capture_size; | ||
2386 | } | 2391 | } |
2387 | 2392 | ||
2388 | /* ISP83xx functions to process new minidump entries... */ | 2393 | /* ISP83xx functions to process new minidump entries... */ |
@@ -2590,6 +2595,7 @@ static int qla4_8xxx_collect_md_data(struct scsi_qla_host *ha) | |||
2590 | uint64_t now; | 2595 | uint64_t now; |
2591 | uint32_t timestamp; | 2596 | uint32_t timestamp; |
2592 | 2597 | ||
2598 | ha->fw_dump_skip_size = 0; | ||
2593 | if (!ha->fw_dump) { | 2599 | if (!ha->fw_dump) { |
2594 | ql4_printk(KERN_INFO, ha, "%s(%ld) No buffer to dump\n", | 2600 | ql4_printk(KERN_INFO, ha, "%s(%ld) No buffer to dump\n", |
2595 | __func__, ha->host_no); | 2601 | __func__, ha->host_no); |
@@ -2761,7 +2767,7 @@ skip_nxt_entry: | |||
2761 | entry_hdr->entry_size); | 2767 | entry_hdr->entry_size); |
2762 | } | 2768 | } |
2763 | 2769 | ||
2764 | if (data_collected != ha->fw_dump_size) { | 2770 | if ((data_collected + ha->fw_dump_skip_size) != ha->fw_dump_size) { |
2765 | ql4_printk(KERN_INFO, ha, | 2771 | ql4_printk(KERN_INFO, ha, |
2766 | "Dump data mismatch: Data collected: [0x%x], total_data_size:[0x%x]\n", | 2772 | "Dump data mismatch: Data collected: [0x%x], total_data_size:[0x%x]\n", |
2767 | data_collected, ha->fw_dump_size); | 2773 | data_collected, ha->fw_dump_size); |
@@ -2820,63 +2826,35 @@ void qla4_8xxx_get_minidump(struct scsi_qla_host *ha) | |||
2820 | int qla4_8xxx_device_bootstrap(struct scsi_qla_host *ha) | 2826 | int qla4_8xxx_device_bootstrap(struct scsi_qla_host *ha) |
2821 | { | 2827 | { |
2822 | int rval = QLA_ERROR; | 2828 | int rval = QLA_ERROR; |
2823 | int i, timeout; | 2829 | int i; |
2824 | uint32_t old_count, count, idc_ctrl; | 2830 | uint32_t old_count, count; |
2825 | int need_reset = 0, peg_stuck = 1; | 2831 | int need_reset = 0; |
2826 | 2832 | ||
2827 | need_reset = ha->isp_ops->need_reset(ha); | 2833 | need_reset = ha->isp_ops->need_reset(ha); |
2828 | old_count = qla4_8xxx_rd_direct(ha, QLA8XXX_PEG_ALIVE_COUNTER); | ||
2829 | |||
2830 | for (i = 0; i < 10; i++) { | ||
2831 | timeout = msleep_interruptible(200); | ||
2832 | if (timeout) { | ||
2833 | qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE, | ||
2834 | QLA8XXX_DEV_FAILED); | ||
2835 | return rval; | ||
2836 | } | ||
2837 | |||
2838 | count = qla4_8xxx_rd_direct(ha, QLA8XXX_PEG_ALIVE_COUNTER); | ||
2839 | if (count != old_count) | ||
2840 | peg_stuck = 0; | ||
2841 | } | ||
2842 | 2834 | ||
2843 | if (need_reset) { | 2835 | if (need_reset) { |
2844 | /* We are trying to perform a recovery here. */ | 2836 | /* We are trying to perform a recovery here. */ |
2845 | if (peg_stuck) | 2837 | if (test_bit(AF_FW_RECOVERY, &ha->flags)) |
2846 | ha->isp_ops->rom_lock_recovery(ha); | 2838 | ha->isp_ops->rom_lock_recovery(ha); |
2847 | goto dev_initialize; | ||
2848 | } else { | 2839 | } else { |
2849 | /* Start of day for this ha context. */ | 2840 | old_count = qla4_8xxx_rd_direct(ha, QLA8XXX_PEG_ALIVE_COUNTER); |
2850 | if (peg_stuck) { | 2841 | for (i = 0; i < 10; i++) { |
2851 | /* Either we are the first or recovery in progress. */ | 2842 | msleep(200); |
2852 | ha->isp_ops->rom_lock_recovery(ha); | 2843 | count = qla4_8xxx_rd_direct(ha, |
2853 | goto dev_initialize; | 2844 | QLA8XXX_PEG_ALIVE_COUNTER); |
2854 | } else { | 2845 | if (count != old_count) { |
2855 | /* Firmware already running. */ | 2846 | rval = QLA_SUCCESS; |
2856 | rval = QLA_SUCCESS; | 2847 | goto dev_ready; |
2857 | goto dev_ready; | 2848 | } |
2858 | } | 2849 | } |
2850 | ha->isp_ops->rom_lock_recovery(ha); | ||
2859 | } | 2851 | } |
2860 | 2852 | ||
2861 | dev_initialize: | ||
2862 | /* set to DEV_INITIALIZING */ | 2853 | /* set to DEV_INITIALIZING */ |
2863 | ql4_printk(KERN_INFO, ha, "HW State: INITIALIZING\n"); | 2854 | ql4_printk(KERN_INFO, ha, "HW State: INITIALIZING\n"); |
2864 | qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE, | 2855 | qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE, |
2865 | QLA8XXX_DEV_INITIALIZING); | 2856 | QLA8XXX_DEV_INITIALIZING); |
2866 | 2857 | ||
2867 | /* | ||
2868 | * For ISP8324 and ISP8042, if IDC_CTRL GRACEFUL_RESET_BIT1 is set, | ||
2869 | * reset it after device goes to INIT state. | ||
2870 | */ | ||
2871 | if (is_qla8032(ha) || is_qla8042(ha)) { | ||
2872 | idc_ctrl = qla4_83xx_rd_reg(ha, QLA83XX_IDC_DRV_CTRL); | ||
2873 | if (idc_ctrl & GRACEFUL_RESET_BIT1) { | ||
2874 | qla4_83xx_wr_reg(ha, QLA83XX_IDC_DRV_CTRL, | ||
2875 | (idc_ctrl & ~GRACEFUL_RESET_BIT1)); | ||
2876 | set_bit(AF_83XX_NO_FW_DUMP, &ha->flags); | ||
2877 | } | ||
2878 | } | ||
2879 | |||
2880 | ha->isp_ops->idc_unlock(ha); | 2858 | ha->isp_ops->idc_unlock(ha); |
2881 | 2859 | ||
2882 | if (is_qla8022(ha)) | 2860 | if (is_qla8022(ha)) |
@@ -3209,6 +3187,10 @@ int qla4_8xxx_load_risc(struct scsi_qla_host *ha) | |||
3209 | 3187 | ||
3210 | retval = qla4_8xxx_device_state_handler(ha); | 3188 | retval = qla4_8xxx_device_state_handler(ha); |
3211 | 3189 | ||
3190 | /* Initialize request and response queues. */ | ||
3191 | if (retval == QLA_SUCCESS) | ||
3192 | qla4xxx_init_rings(ha); | ||
3193 | |||
3212 | if (retval == QLA_SUCCESS && !test_bit(AF_IRQ_ATTACHED, &ha->flags)) | 3194 | if (retval == QLA_SUCCESS && !test_bit(AF_IRQ_ATTACHED, &ha->flags)) |
3213 | retval = qla4xxx_request_irqs(ha); | 3195 | retval = qla4xxx_request_irqs(ha); |
3214 | 3196 | ||
@@ -3836,3 +3818,24 @@ qla4_8xxx_enable_msix(struct scsi_qla_host *ha) | |||
3836 | msix_out: | 3818 | msix_out: |
3837 | return ret; | 3819 | return ret; |
3838 | } | 3820 | } |
3821 | |||
3822 | int qla4_8xxx_check_init_adapter_retry(struct scsi_qla_host *ha) | ||
3823 | { | ||
3824 | int status = QLA_SUCCESS; | ||
3825 | |||
3826 | /* Dont retry adapter initialization if IRQ allocation failed */ | ||
3827 | if (!test_bit(AF_IRQ_ATTACHED, &ha->flags)) { | ||
3828 | ql4_printk(KERN_WARNING, ha, "%s: Skipping retry of adapter initialization as IRQs are not attached\n", | ||
3829 | __func__); | ||
3830 | status = QLA_ERROR; | ||
3831 | goto exit_init_adapter_failure; | ||
3832 | } | ||
3833 | |||
3834 | /* Since interrupts are registered in start_firmware for | ||
3835 | * 8xxx, release them here if initialize_adapter fails | ||
3836 | * and retry adapter initialization */ | ||
3837 | qla4xxx_free_irqs(ha); | ||
3838 | |||
3839 | exit_init_adapter_failure: | ||
3840 | return status; | ||
3841 | } | ||