diff options
Diffstat (limited to 'drivers/scsi/mpt2sas/mpt2sas_base.c')
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_base.c | 172 |
1 files changed, 122 insertions, 50 deletions
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c index 0ec1ed389c20..57bcd5c9dcff 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_base.c +++ b/drivers/scsi/mpt2sas/mpt2sas_base.c | |||
@@ -95,6 +95,10 @@ int mpt2sas_fwfault_debug; | |||
95 | MODULE_PARM_DESC(mpt2sas_fwfault_debug, " enable detection of firmware fault " | 95 | MODULE_PARM_DESC(mpt2sas_fwfault_debug, " enable detection of firmware fault " |
96 | "and halt firmware - (default=0)"); | 96 | "and halt firmware - (default=0)"); |
97 | 97 | ||
98 | static int disable_discovery = -1; | ||
99 | module_param(disable_discovery, int, 0); | ||
100 | MODULE_PARM_DESC(disable_discovery, " disable discovery "); | ||
101 | |||
98 | /** | 102 | /** |
99 | * _scsih_set_fwfault_debug - global setting of ioc->fwfault_debug. | 103 | * _scsih_set_fwfault_debug - global setting of ioc->fwfault_debug. |
100 | * | 104 | * |
@@ -1238,7 +1242,7 @@ mpt2sas_base_map_resources(struct MPT2SAS_ADAPTER *ioc) | |||
1238 | u64 pio_chip = 0; | 1242 | u64 pio_chip = 0; |
1239 | u64 chip_phys = 0; | 1243 | u64 chip_phys = 0; |
1240 | 1244 | ||
1241 | dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", | 1245 | dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", |
1242 | ioc->name, __func__)); | 1246 | ioc->name, __func__)); |
1243 | 1247 | ||
1244 | ioc->bars = pci_select_bars(pdev, IORESOURCE_MEM); | 1248 | ioc->bars = pci_select_bars(pdev, IORESOURCE_MEM); |
@@ -1307,6 +1311,9 @@ mpt2sas_base_map_resources(struct MPT2SAS_ADAPTER *ioc) | |||
1307 | printk(MPT2SAS_INFO_FMT "ioport(0x%016llx), size(%d)\n", | 1311 | printk(MPT2SAS_INFO_FMT "ioport(0x%016llx), size(%d)\n", |
1308 | ioc->name, (unsigned long long)pio_chip, pio_sz); | 1312 | ioc->name, (unsigned long long)pio_chip, pio_sz); |
1309 | 1313 | ||
1314 | /* Save PCI configuration state for recovery from PCI AER/EEH errors */ | ||
1315 | pci_save_state(pdev); | ||
1316 | |||
1310 | return 0; | 1317 | return 0; |
1311 | 1318 | ||
1312 | out_fail: | 1319 | out_fail: |
@@ -1861,7 +1868,7 @@ _base_static_config_pages(struct MPT2SAS_ADAPTER *ioc) | |||
1861 | static void | 1868 | static void |
1862 | _base_release_memory_pools(struct MPT2SAS_ADAPTER *ioc) | 1869 | _base_release_memory_pools(struct MPT2SAS_ADAPTER *ioc) |
1863 | { | 1870 | { |
1864 | dexitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name, | 1871 | dexitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, |
1865 | __func__)); | 1872 | __func__)); |
1866 | 1873 | ||
1867 | if (ioc->request) { | 1874 | if (ioc->request) { |
@@ -1947,7 +1954,7 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) | |||
1947 | u32 retry_sz; | 1954 | u32 retry_sz; |
1948 | u16 max_request_credit; | 1955 | u16 max_request_credit; |
1949 | 1956 | ||
1950 | dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name, | 1957 | dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, |
1951 | __func__)); | 1958 | __func__)); |
1952 | 1959 | ||
1953 | retry_sz = 0; | 1960 | retry_sz = 0; |
@@ -2374,7 +2381,7 @@ _base_wait_for_doorbell_int(struct MPT2SAS_ADAPTER *ioc, int timeout, | |||
2374 | do { | 2381 | do { |
2375 | int_status = readl(&ioc->chip->HostInterruptStatus); | 2382 | int_status = readl(&ioc->chip->HostInterruptStatus); |
2376 | if (int_status & MPI2_HIS_IOC2SYS_DB_STATUS) { | 2383 | if (int_status & MPI2_HIS_IOC2SYS_DB_STATUS) { |
2377 | dhsprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: " | 2384 | dhsprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: " |
2378 | "successfull count(%d), timeout(%d)\n", ioc->name, | 2385 | "successfull count(%d), timeout(%d)\n", ioc->name, |
2379 | __func__, count, timeout)); | 2386 | __func__, count, timeout)); |
2380 | return 0; | 2387 | return 0; |
@@ -2415,7 +2422,7 @@ _base_wait_for_doorbell_ack(struct MPT2SAS_ADAPTER *ioc, int timeout, | |||
2415 | do { | 2422 | do { |
2416 | int_status = readl(&ioc->chip->HostInterruptStatus); | 2423 | int_status = readl(&ioc->chip->HostInterruptStatus); |
2417 | if (!(int_status & MPI2_HIS_SYS2IOC_DB_STATUS)) { | 2424 | if (!(int_status & MPI2_HIS_SYS2IOC_DB_STATUS)) { |
2418 | dhsprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: " | 2425 | dhsprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: " |
2419 | "successfull count(%d), timeout(%d)\n", ioc->name, | 2426 | "successfull count(%d), timeout(%d)\n", ioc->name, |
2420 | __func__, count, timeout)); | 2427 | __func__, count, timeout)); |
2421 | return 0; | 2428 | return 0; |
@@ -2463,7 +2470,7 @@ _base_wait_for_doorbell_not_used(struct MPT2SAS_ADAPTER *ioc, int timeout, | |||
2463 | do { | 2470 | do { |
2464 | doorbell_reg = readl(&ioc->chip->Doorbell); | 2471 | doorbell_reg = readl(&ioc->chip->Doorbell); |
2465 | if (!(doorbell_reg & MPI2_DOORBELL_USED)) { | 2472 | if (!(doorbell_reg & MPI2_DOORBELL_USED)) { |
2466 | dhsprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: " | 2473 | dhsprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: " |
2467 | "successfull count(%d), timeout(%d)\n", ioc->name, | 2474 | "successfull count(%d), timeout(%d)\n", ioc->name, |
2468 | __func__, count, timeout)); | 2475 | __func__, count, timeout)); |
2469 | return 0; | 2476 | return 0; |
@@ -2637,9 +2644,9 @@ _base_handshake_req_reply_wait(struct MPT2SAS_ADAPTER *ioc, int request_bytes, | |||
2637 | 2644 | ||
2638 | if (ioc->logging_level & MPT_DEBUG_INIT) { | 2645 | if (ioc->logging_level & MPT_DEBUG_INIT) { |
2639 | mfp = (u32 *)reply; | 2646 | mfp = (u32 *)reply; |
2640 | printk(KERN_DEBUG "\toffset:data\n"); | 2647 | printk(KERN_INFO "\toffset:data\n"); |
2641 | for (i = 0; i < reply_bytes/4; i++) | 2648 | for (i = 0; i < reply_bytes/4; i++) |
2642 | printk(KERN_DEBUG "\t[0x%02x]:%08x\n", i*4, | 2649 | printk(KERN_INFO "\t[0x%02x]:%08x\n", i*4, |
2643 | le32_to_cpu(mfp[i])); | 2650 | le32_to_cpu(mfp[i])); |
2644 | } | 2651 | } |
2645 | return 0; | 2652 | return 0; |
@@ -2672,7 +2679,7 @@ mpt2sas_base_sas_iounit_control(struct MPT2SAS_ADAPTER *ioc, | |||
2672 | void *request; | 2679 | void *request; |
2673 | u16 wait_state_count; | 2680 | u16 wait_state_count; |
2674 | 2681 | ||
2675 | dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name, | 2682 | dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, |
2676 | __func__)); | 2683 | __func__)); |
2677 | 2684 | ||
2678 | mutex_lock(&ioc->base_cmds.mutex); | 2685 | mutex_lock(&ioc->base_cmds.mutex); |
@@ -2777,7 +2784,7 @@ mpt2sas_base_scsi_enclosure_processor(struct MPT2SAS_ADAPTER *ioc, | |||
2777 | void *request; | 2784 | void *request; |
2778 | u16 wait_state_count; | 2785 | u16 wait_state_count; |
2779 | 2786 | ||
2780 | dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name, | 2787 | dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, |
2781 | __func__)); | 2788 | __func__)); |
2782 | 2789 | ||
2783 | mutex_lock(&ioc->base_cmds.mutex); | 2790 | mutex_lock(&ioc->base_cmds.mutex); |
@@ -2865,7 +2872,7 @@ _base_get_port_facts(struct MPT2SAS_ADAPTER *ioc, int port, int sleep_flag) | |||
2865 | Mpi2PortFactsReply_t mpi_reply, *pfacts; | 2872 | Mpi2PortFactsReply_t mpi_reply, *pfacts; |
2866 | int mpi_reply_sz, mpi_request_sz, r; | 2873 | int mpi_reply_sz, mpi_request_sz, r; |
2867 | 2874 | ||
2868 | dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name, | 2875 | dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, |
2869 | __func__)); | 2876 | __func__)); |
2870 | 2877 | ||
2871 | mpi_reply_sz = sizeof(Mpi2PortFactsReply_t); | 2878 | mpi_reply_sz = sizeof(Mpi2PortFactsReply_t); |
@@ -2907,7 +2914,7 @@ _base_get_ioc_facts(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) | |||
2907 | Mpi2IOCFactsReply_t mpi_reply, *facts; | 2914 | Mpi2IOCFactsReply_t mpi_reply, *facts; |
2908 | int mpi_reply_sz, mpi_request_sz, r; | 2915 | int mpi_reply_sz, mpi_request_sz, r; |
2909 | 2916 | ||
2910 | dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name, | 2917 | dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, |
2911 | __func__)); | 2918 | __func__)); |
2912 | 2919 | ||
2913 | mpi_reply_sz = sizeof(Mpi2IOCFactsReply_t); | 2920 | mpi_reply_sz = sizeof(Mpi2IOCFactsReply_t); |
@@ -2979,7 +2986,7 @@ _base_send_ioc_init(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) | |||
2979 | struct timeval current_time; | 2986 | struct timeval current_time; |
2980 | u16 ioc_status; | 2987 | u16 ioc_status; |
2981 | 2988 | ||
2982 | dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name, | 2989 | dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, |
2983 | __func__)); | 2990 | __func__)); |
2984 | 2991 | ||
2985 | memset(&mpi_request, 0, sizeof(Mpi2IOCInitRequest_t)); | 2992 | memset(&mpi_request, 0, sizeof(Mpi2IOCInitRequest_t)); |
@@ -3040,9 +3047,9 @@ _base_send_ioc_init(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) | |||
3040 | int i; | 3047 | int i; |
3041 | 3048 | ||
3042 | mfp = (u32 *)&mpi_request; | 3049 | mfp = (u32 *)&mpi_request; |
3043 | printk(KERN_DEBUG "\toffset:data\n"); | 3050 | printk(KERN_INFO "\toffset:data\n"); |
3044 | for (i = 0; i < sizeof(Mpi2IOCInitRequest_t)/4; i++) | 3051 | for (i = 0; i < sizeof(Mpi2IOCInitRequest_t)/4; i++) |
3045 | printk(KERN_DEBUG "\t[0x%02x]:%08x\n", i*4, | 3052 | printk(KERN_INFO "\t[0x%02x]:%08x\n", i*4, |
3046 | le32_to_cpu(mfp[i])); | 3053 | le32_to_cpu(mfp[i])); |
3047 | } | 3054 | } |
3048 | 3055 | ||
@@ -3121,7 +3128,7 @@ _base_send_port_enable(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) | |||
3121 | r = -ETIME; | 3128 | r = -ETIME; |
3122 | goto out; | 3129 | goto out; |
3123 | } else | 3130 | } else |
3124 | dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: complete\n", | 3131 | dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: complete\n", |
3125 | ioc->name, __func__)); | 3132 | ioc->name, __func__)); |
3126 | 3133 | ||
3127 | ioc_state = _base_wait_on_iocstate(ioc, MPI2_IOC_STATE_OPERATIONAL, | 3134 | ioc_state = _base_wait_on_iocstate(ioc, MPI2_IOC_STATE_OPERATIONAL, |
@@ -3181,7 +3188,7 @@ _base_event_notification(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) | |||
3181 | int r = 0; | 3188 | int r = 0; |
3182 | int i; | 3189 | int i; |
3183 | 3190 | ||
3184 | dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name, | 3191 | dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, |
3185 | __func__)); | 3192 | __func__)); |
3186 | 3193 | ||
3187 | if (ioc->base_cmds.status & MPT2_CMD_PENDING) { | 3194 | if (ioc->base_cmds.status & MPT2_CMD_PENDING) { |
@@ -3219,7 +3226,7 @@ _base_event_notification(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) | |||
3219 | else | 3226 | else |
3220 | r = -ETIME; | 3227 | r = -ETIME; |
3221 | } else | 3228 | } else |
3222 | dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: complete\n", | 3229 | dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: complete\n", |
3223 | ioc->name, __func__)); | 3230 | ioc->name, __func__)); |
3224 | ioc->base_cmds.status = MPT2_CMD_NOT_USED; | 3231 | ioc->base_cmds.status = MPT2_CMD_NOT_USED; |
3225 | return r; | 3232 | return r; |
@@ -3281,7 +3288,7 @@ _base_diag_reset(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) | |||
3281 | 3288 | ||
3282 | _base_save_msix_table(ioc); | 3289 | _base_save_msix_table(ioc); |
3283 | 3290 | ||
3284 | drsprintk(ioc, printk(MPT2SAS_DEBUG_FMT "clear interrupts\n", | 3291 | drsprintk(ioc, printk(MPT2SAS_INFO_FMT "clear interrupts\n", |
3285 | ioc->name)); | 3292 | ioc->name)); |
3286 | 3293 | ||
3287 | count = 0; | 3294 | count = 0; |
@@ -3289,7 +3296,7 @@ _base_diag_reset(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) | |||
3289 | /* Write magic sequence to WriteSequence register | 3296 | /* Write magic sequence to WriteSequence register |
3290 | * Loop until in diagnostic mode | 3297 | * Loop until in diagnostic mode |
3291 | */ | 3298 | */ |
3292 | drsprintk(ioc, printk(MPT2SAS_DEBUG_FMT "write magic " | 3299 | drsprintk(ioc, printk(MPT2SAS_INFO_FMT "write magic " |
3293 | "sequence\n", ioc->name)); | 3300 | "sequence\n", ioc->name)); |
3294 | writel(MPI2_WRSEQ_FLUSH_KEY_VALUE, &ioc->chip->WriteSequence); | 3301 | writel(MPI2_WRSEQ_FLUSH_KEY_VALUE, &ioc->chip->WriteSequence); |
3295 | writel(MPI2_WRSEQ_1ST_KEY_VALUE, &ioc->chip->WriteSequence); | 3302 | writel(MPI2_WRSEQ_1ST_KEY_VALUE, &ioc->chip->WriteSequence); |
@@ -3309,7 +3316,7 @@ _base_diag_reset(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) | |||
3309 | goto out; | 3316 | goto out; |
3310 | 3317 | ||
3311 | host_diagnostic = readl(&ioc->chip->HostDiagnostic); | 3318 | host_diagnostic = readl(&ioc->chip->HostDiagnostic); |
3312 | drsprintk(ioc, printk(MPT2SAS_DEBUG_FMT "wrote magic " | 3319 | drsprintk(ioc, printk(MPT2SAS_INFO_FMT "wrote magic " |
3313 | "sequence: count(%d), host_diagnostic(0x%08x)\n", | 3320 | "sequence: count(%d), host_diagnostic(0x%08x)\n", |
3314 | ioc->name, count, host_diagnostic)); | 3321 | ioc->name, count, host_diagnostic)); |
3315 | 3322 | ||
@@ -3317,7 +3324,7 @@ _base_diag_reset(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) | |||
3317 | 3324 | ||
3318 | hcb_size = readl(&ioc->chip->HCBSize); | 3325 | hcb_size = readl(&ioc->chip->HCBSize); |
3319 | 3326 | ||
3320 | drsprintk(ioc, printk(MPT2SAS_DEBUG_FMT "diag reset: issued\n", | 3327 | drsprintk(ioc, printk(MPT2SAS_INFO_FMT "diag reset: issued\n", |
3321 | ioc->name)); | 3328 | ioc->name)); |
3322 | writel(host_diagnostic | MPI2_DIAG_RESET_ADAPTER, | 3329 | writel(host_diagnostic | MPI2_DIAG_RESET_ADAPTER, |
3323 | &ioc->chip->HostDiagnostic); | 3330 | &ioc->chip->HostDiagnostic); |
@@ -3344,29 +3351,29 @@ _base_diag_reset(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) | |||
3344 | 3351 | ||
3345 | if (host_diagnostic & MPI2_DIAG_HCB_MODE) { | 3352 | if (host_diagnostic & MPI2_DIAG_HCB_MODE) { |
3346 | 3353 | ||
3347 | drsprintk(ioc, printk(MPT2SAS_DEBUG_FMT "restart the adapter " | 3354 | drsprintk(ioc, printk(MPT2SAS_INFO_FMT "restart the adapter " |
3348 | "assuming the HCB Address points to good F/W\n", | 3355 | "assuming the HCB Address points to good F/W\n", |
3349 | ioc->name)); | 3356 | ioc->name)); |
3350 | host_diagnostic &= ~MPI2_DIAG_BOOT_DEVICE_SELECT_MASK; | 3357 | host_diagnostic &= ~MPI2_DIAG_BOOT_DEVICE_SELECT_MASK; |
3351 | host_diagnostic |= MPI2_DIAG_BOOT_DEVICE_SELECT_HCDW; | 3358 | host_diagnostic |= MPI2_DIAG_BOOT_DEVICE_SELECT_HCDW; |
3352 | writel(host_diagnostic, &ioc->chip->HostDiagnostic); | 3359 | writel(host_diagnostic, &ioc->chip->HostDiagnostic); |
3353 | 3360 | ||
3354 | drsprintk(ioc, printk(MPT2SAS_DEBUG_FMT | 3361 | drsprintk(ioc, printk(MPT2SAS_INFO_FMT |
3355 | "re-enable the HCDW\n", ioc->name)); | 3362 | "re-enable the HCDW\n", ioc->name)); |
3356 | writel(hcb_size | MPI2_HCB_SIZE_HCB_ENABLE, | 3363 | writel(hcb_size | MPI2_HCB_SIZE_HCB_ENABLE, |
3357 | &ioc->chip->HCBSize); | 3364 | &ioc->chip->HCBSize); |
3358 | } | 3365 | } |
3359 | 3366 | ||
3360 | drsprintk(ioc, printk(MPT2SAS_DEBUG_FMT "restart the adapter\n", | 3367 | drsprintk(ioc, printk(MPT2SAS_INFO_FMT "restart the adapter\n", |
3361 | ioc->name)); | 3368 | ioc->name)); |
3362 | writel(host_diagnostic & ~MPI2_DIAG_HOLD_IOC_RESET, | 3369 | writel(host_diagnostic & ~MPI2_DIAG_HOLD_IOC_RESET, |
3363 | &ioc->chip->HostDiagnostic); | 3370 | &ioc->chip->HostDiagnostic); |
3364 | 3371 | ||
3365 | drsprintk(ioc, printk(MPT2SAS_DEBUG_FMT "disable writes to the " | 3372 | drsprintk(ioc, printk(MPT2SAS_INFO_FMT "disable writes to the " |
3366 | "diagnostic register\n", ioc->name)); | 3373 | "diagnostic register\n", ioc->name)); |
3367 | writel(MPI2_WRSEQ_FLUSH_KEY_VALUE, &ioc->chip->WriteSequence); | 3374 | writel(MPI2_WRSEQ_FLUSH_KEY_VALUE, &ioc->chip->WriteSequence); |
3368 | 3375 | ||
3369 | drsprintk(ioc, printk(MPT2SAS_DEBUG_FMT "Wait for FW to go to the " | 3376 | drsprintk(ioc, printk(MPT2SAS_INFO_FMT "Wait for FW to go to the " |
3370 | "READY state\n", ioc->name)); | 3377 | "READY state\n", ioc->name)); |
3371 | ioc_state = _base_wait_on_iocstate(ioc, MPI2_IOC_STATE_READY, 20, | 3378 | ioc_state = _base_wait_on_iocstate(ioc, MPI2_IOC_STATE_READY, 20, |
3372 | sleep_flag); | 3379 | sleep_flag); |
@@ -3398,19 +3405,23 @@ _base_make_ioc_ready(struct MPT2SAS_ADAPTER *ioc, int sleep_flag, | |||
3398 | enum reset_type type) | 3405 | enum reset_type type) |
3399 | { | 3406 | { |
3400 | u32 ioc_state; | 3407 | u32 ioc_state; |
3408 | int rc; | ||
3401 | 3409 | ||
3402 | dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name, | 3410 | dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, |
3403 | __func__)); | 3411 | __func__)); |
3404 | 3412 | ||
3413 | if (ioc->pci_error_recovery) | ||
3414 | return 0; | ||
3415 | |||
3405 | ioc_state = mpt2sas_base_get_iocstate(ioc, 0); | 3416 | ioc_state = mpt2sas_base_get_iocstate(ioc, 0); |
3406 | dhsprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: ioc_state(0x%08x)\n", | 3417 | dhsprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: ioc_state(0x%08x)\n", |
3407 | ioc->name, __func__, ioc_state)); | 3418 | ioc->name, __func__, ioc_state)); |
3408 | 3419 | ||
3409 | if ((ioc_state & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_READY) | 3420 | if ((ioc_state & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_READY) |
3410 | return 0; | 3421 | return 0; |
3411 | 3422 | ||
3412 | if (ioc_state & MPI2_DOORBELL_USED) { | 3423 | if (ioc_state & MPI2_DOORBELL_USED) { |
3413 | dhsprintk(ioc, printk(MPT2SAS_DEBUG_FMT "unexpected doorbell " | 3424 | dhsprintk(ioc, printk(MPT2SAS_INFO_FMT "unexpected doorbell " |
3414 | "active!\n", ioc->name)); | 3425 | "active!\n", ioc->name)); |
3415 | goto issue_diag_reset; | 3426 | goto issue_diag_reset; |
3416 | } | 3427 | } |
@@ -3426,11 +3437,15 @@ _base_make_ioc_ready(struct MPT2SAS_ADAPTER *ioc, int sleep_flag, | |||
3426 | 3437 | ||
3427 | if ((ioc_state & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_OPERATIONAL) | 3438 | if ((ioc_state & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_OPERATIONAL) |
3428 | if (!(_base_send_ioc_reset(ioc, | 3439 | if (!(_base_send_ioc_reset(ioc, |
3429 | MPI2_FUNCTION_IOC_MESSAGE_UNIT_RESET, 15, CAN_SLEEP))) | 3440 | MPI2_FUNCTION_IOC_MESSAGE_UNIT_RESET, 15, CAN_SLEEP))) { |
3441 | ioc->ioc_reset_count++; | ||
3430 | return 0; | 3442 | return 0; |
3443 | } | ||
3431 | 3444 | ||
3432 | issue_diag_reset: | 3445 | issue_diag_reset: |
3433 | return _base_diag_reset(ioc, CAN_SLEEP); | 3446 | rc = _base_diag_reset(ioc, CAN_SLEEP); |
3447 | ioc->ioc_reset_count++; | ||
3448 | return rc; | ||
3434 | } | 3449 | } |
3435 | 3450 | ||
3436 | /** | 3451 | /** |
@@ -3449,7 +3464,7 @@ _base_make_ioc_operational(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) | |||
3449 | u16 smid; | 3464 | u16 smid; |
3450 | struct _tr_list *delayed_tr, *delayed_tr_next; | 3465 | struct _tr_list *delayed_tr, *delayed_tr_next; |
3451 | 3466 | ||
3452 | dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name, | 3467 | dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, |
3453 | __func__)); | 3468 | __func__)); |
3454 | 3469 | ||
3455 | /* clean the delayed target reset list */ | 3470 | /* clean the delayed target reset list */ |
@@ -3459,6 +3474,12 @@ _base_make_ioc_operational(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) | |||
3459 | kfree(delayed_tr); | 3474 | kfree(delayed_tr); |
3460 | } | 3475 | } |
3461 | 3476 | ||
3477 | list_for_each_entry_safe(delayed_tr, delayed_tr_next, | ||
3478 | &ioc->delayed_tr_volume_list, list) { | ||
3479 | list_del(&delayed_tr->list); | ||
3480 | kfree(delayed_tr); | ||
3481 | } | ||
3482 | |||
3462 | /* initialize the scsi lookup free list */ | 3483 | /* initialize the scsi lookup free list */ |
3463 | spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); | 3484 | spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); |
3464 | INIT_LIST_HEAD(&ioc->free_list); | 3485 | INIT_LIST_HEAD(&ioc->free_list); |
@@ -3520,6 +3541,13 @@ _base_make_ioc_operational(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) | |||
3520 | if (sleep_flag == CAN_SLEEP) | 3541 | if (sleep_flag == CAN_SLEEP) |
3521 | _base_static_config_pages(ioc); | 3542 | _base_static_config_pages(ioc); |
3522 | 3543 | ||
3544 | if (ioc->wait_for_port_enable_to_complete) { | ||
3545 | if (diag_buffer_enable != 0) | ||
3546 | mpt2sas_enable_diag_buffer(ioc, diag_buffer_enable); | ||
3547 | if (disable_discovery > 0) | ||
3548 | return r; | ||
3549 | } | ||
3550 | |||
3523 | r = _base_send_port_enable(ioc, sleep_flag); | 3551 | r = _base_send_port_enable(ioc, sleep_flag); |
3524 | if (r) | 3552 | if (r) |
3525 | return r; | 3553 | return r; |
@@ -3538,7 +3566,7 @@ mpt2sas_base_free_resources(struct MPT2SAS_ADAPTER *ioc) | |||
3538 | { | 3566 | { |
3539 | struct pci_dev *pdev = ioc->pdev; | 3567 | struct pci_dev *pdev = ioc->pdev; |
3540 | 3568 | ||
3541 | dexitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name, | 3569 | dexitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, |
3542 | __func__)); | 3570 | __func__)); |
3543 | 3571 | ||
3544 | _base_mask_interrupts(ioc); | 3572 | _base_mask_interrupts(ioc); |
@@ -3571,7 +3599,7 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc) | |||
3571 | { | 3599 | { |
3572 | int r, i; | 3600 | int r, i; |
3573 | 3601 | ||
3574 | dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name, | 3602 | dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, |
3575 | __func__)); | 3603 | __func__)); |
3576 | 3604 | ||
3577 | r = mpt2sas_base_map_resources(ioc); | 3605 | r = mpt2sas_base_map_resources(ioc); |
@@ -3606,6 +3634,17 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc) | |||
3606 | 3634 | ||
3607 | init_waitqueue_head(&ioc->reset_wq); | 3635 | init_waitqueue_head(&ioc->reset_wq); |
3608 | 3636 | ||
3637 | /* allocate memory pd handle bitmask list */ | ||
3638 | ioc->pd_handles_sz = (ioc->facts.MaxDevHandle / 8); | ||
3639 | if (ioc->facts.MaxDevHandle % 8) | ||
3640 | ioc->pd_handles_sz++; | ||
3641 | ioc->pd_handles = kzalloc(ioc->pd_handles_sz, | ||
3642 | GFP_KERNEL); | ||
3643 | if (!ioc->pd_handles) { | ||
3644 | r = -ENOMEM; | ||
3645 | goto out_free_resources; | ||
3646 | } | ||
3647 | |||
3609 | ioc->fwfault_debug = mpt2sas_fwfault_debug; | 3648 | ioc->fwfault_debug = mpt2sas_fwfault_debug; |
3610 | 3649 | ||
3611 | /* base internal command bits */ | 3650 | /* base internal command bits */ |
@@ -3635,11 +3674,20 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc) | |||
3635 | 3674 | ||
3636 | /* ctl module internal command bits */ | 3675 | /* ctl module internal command bits */ |
3637 | ioc->ctl_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL); | 3676 | ioc->ctl_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL); |
3677 | ioc->ctl_cmds.sense = kzalloc(SCSI_SENSE_BUFFERSIZE, GFP_KERNEL); | ||
3638 | ioc->ctl_cmds.status = MPT2_CMD_NOT_USED; | 3678 | ioc->ctl_cmds.status = MPT2_CMD_NOT_USED; |
3639 | mutex_init(&ioc->ctl_cmds.mutex); | 3679 | mutex_init(&ioc->ctl_cmds.mutex); |
3640 | 3680 | ||
3641 | if (!ioc->base_cmds.reply || !ioc->transport_cmds.reply || | 3681 | if (!ioc->base_cmds.reply || !ioc->transport_cmds.reply || |
3642 | !ioc->scsih_cmds.reply || !ioc->tm_cmds.reply || | 3682 | !ioc->scsih_cmds.reply || !ioc->tm_cmds.reply || |
3683 | !ioc->config_cmds.reply || !ioc->ctl_cmds.reply || | ||
3684 | !ioc->ctl_cmds.sense) { | ||
3685 | r = -ENOMEM; | ||
3686 | goto out_free_resources; | ||
3687 | } | ||
3688 | |||
3689 | if (!ioc->base_cmds.reply || !ioc->transport_cmds.reply || | ||
3690 | !ioc->scsih_cmds.reply || !ioc->tm_cmds.reply || | ||
3643 | !ioc->config_cmds.reply || !ioc->ctl_cmds.reply) { | 3691 | !ioc->config_cmds.reply || !ioc->ctl_cmds.reply) { |
3644 | r = -ENOMEM; | 3692 | r = -ENOMEM; |
3645 | goto out_free_resources; | 3693 | goto out_free_resources; |
@@ -3667,8 +3715,6 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc) | |||
3667 | goto out_free_resources; | 3715 | goto out_free_resources; |
3668 | 3716 | ||
3669 | mpt2sas_base_start_watchdog(ioc); | 3717 | mpt2sas_base_start_watchdog(ioc); |
3670 | if (diag_buffer_enable != 0) | ||
3671 | mpt2sas_enable_diag_buffer(ioc, diag_buffer_enable); | ||
3672 | return 0; | 3718 | return 0; |
3673 | 3719 | ||
3674 | out_free_resources: | 3720 | out_free_resources: |
@@ -3677,12 +3723,14 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc) | |||
3677 | mpt2sas_base_free_resources(ioc); | 3723 | mpt2sas_base_free_resources(ioc); |
3678 | _base_release_memory_pools(ioc); | 3724 | _base_release_memory_pools(ioc); |
3679 | pci_set_drvdata(ioc->pdev, NULL); | 3725 | pci_set_drvdata(ioc->pdev, NULL); |
3726 | kfree(ioc->pd_handles); | ||
3680 | kfree(ioc->tm_cmds.reply); | 3727 | kfree(ioc->tm_cmds.reply); |
3681 | kfree(ioc->transport_cmds.reply); | 3728 | kfree(ioc->transport_cmds.reply); |
3682 | kfree(ioc->scsih_cmds.reply); | 3729 | kfree(ioc->scsih_cmds.reply); |
3683 | kfree(ioc->config_cmds.reply); | 3730 | kfree(ioc->config_cmds.reply); |
3684 | kfree(ioc->base_cmds.reply); | 3731 | kfree(ioc->base_cmds.reply); |
3685 | kfree(ioc->ctl_cmds.reply); | 3732 | kfree(ioc->ctl_cmds.reply); |
3733 | kfree(ioc->ctl_cmds.sense); | ||
3686 | kfree(ioc->pfacts); | 3734 | kfree(ioc->pfacts); |
3687 | ioc->ctl_cmds.reply = NULL; | 3735 | ioc->ctl_cmds.reply = NULL; |
3688 | ioc->base_cmds.reply = NULL; | 3736 | ioc->base_cmds.reply = NULL; |
@@ -3705,15 +3753,17 @@ void | |||
3705 | mpt2sas_base_detach(struct MPT2SAS_ADAPTER *ioc) | 3753 | mpt2sas_base_detach(struct MPT2SAS_ADAPTER *ioc) |
3706 | { | 3754 | { |
3707 | 3755 | ||
3708 | dexitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name, | 3756 | dexitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, |
3709 | __func__)); | 3757 | __func__)); |
3710 | 3758 | ||
3711 | mpt2sas_base_stop_watchdog(ioc); | 3759 | mpt2sas_base_stop_watchdog(ioc); |
3712 | mpt2sas_base_free_resources(ioc); | 3760 | mpt2sas_base_free_resources(ioc); |
3713 | _base_release_memory_pools(ioc); | 3761 | _base_release_memory_pools(ioc); |
3714 | pci_set_drvdata(ioc->pdev, NULL); | 3762 | pci_set_drvdata(ioc->pdev, NULL); |
3763 | kfree(ioc->pd_handles); | ||
3715 | kfree(ioc->pfacts); | 3764 | kfree(ioc->pfacts); |
3716 | kfree(ioc->ctl_cmds.reply); | 3765 | kfree(ioc->ctl_cmds.reply); |
3766 | kfree(ioc->ctl_cmds.sense); | ||
3717 | kfree(ioc->base_cmds.reply); | 3767 | kfree(ioc->base_cmds.reply); |
3718 | kfree(ioc->tm_cmds.reply); | 3768 | kfree(ioc->tm_cmds.reply); |
3719 | kfree(ioc->transport_cmds.reply); | 3769 | kfree(ioc->transport_cmds.reply); |
@@ -3738,11 +3788,11 @@ _base_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase) | |||
3738 | { | 3788 | { |
3739 | switch (reset_phase) { | 3789 | switch (reset_phase) { |
3740 | case MPT2_IOC_PRE_RESET: | 3790 | case MPT2_IOC_PRE_RESET: |
3741 | dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: " | 3791 | dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: " |
3742 | "MPT2_IOC_PRE_RESET\n", ioc->name, __func__)); | 3792 | "MPT2_IOC_PRE_RESET\n", ioc->name, __func__)); |
3743 | break; | 3793 | break; |
3744 | case MPT2_IOC_AFTER_RESET: | 3794 | case MPT2_IOC_AFTER_RESET: |
3745 | dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: " | 3795 | dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: " |
3746 | "MPT2_IOC_AFTER_RESET\n", ioc->name, __func__)); | 3796 | "MPT2_IOC_AFTER_RESET\n", ioc->name, __func__)); |
3747 | if (ioc->transport_cmds.status & MPT2_CMD_PENDING) { | 3797 | if (ioc->transport_cmds.status & MPT2_CMD_PENDING) { |
3748 | ioc->transport_cmds.status |= MPT2_CMD_RESET; | 3798 | ioc->transport_cmds.status |= MPT2_CMD_RESET; |
@@ -3762,7 +3812,7 @@ _base_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase) | |||
3762 | } | 3812 | } |
3763 | break; | 3813 | break; |
3764 | case MPT2_IOC_DONE_RESET: | 3814 | case MPT2_IOC_DONE_RESET: |
3765 | dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: " | 3815 | dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: " |
3766 | "MPT2_IOC_DONE_RESET\n", ioc->name, __func__)); | 3816 | "MPT2_IOC_DONE_RESET\n", ioc->name, __func__)); |
3767 | break; | 3817 | break; |
3768 | } | 3818 | } |
@@ -3804,7 +3854,7 @@ _wait_for_commands_to_complete(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) | |||
3804 | return; | 3854 | return; |
3805 | 3855 | ||
3806 | /* wait for pending commands to complete */ | 3856 | /* wait for pending commands to complete */ |
3807 | wait_event_timeout(ioc->reset_wq, ioc->pending_io_count == 0, 3 * HZ); | 3857 | wait_event_timeout(ioc->reset_wq, ioc->pending_io_count == 0, 10 * HZ); |
3808 | } | 3858 | } |
3809 | 3859 | ||
3810 | /** | 3860 | /** |
@@ -3822,19 +3872,37 @@ mpt2sas_base_hard_reset_handler(struct MPT2SAS_ADAPTER *ioc, int sleep_flag, | |||
3822 | int r; | 3872 | int r; |
3823 | unsigned long flags; | 3873 | unsigned long flags; |
3824 | 3874 | ||
3825 | dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: enter\n", ioc->name, | 3875 | dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter\n", ioc->name, |
3826 | __func__)); | 3876 | __func__)); |
3827 | 3877 | ||
3878 | if (ioc->pci_error_recovery) { | ||
3879 | printk(MPT2SAS_ERR_FMT "%s: pci error recovery reset\n", | ||
3880 | ioc->name, __func__); | ||
3881 | r = 0; | ||
3882 | goto out; | ||
3883 | } | ||
3884 | |||
3828 | if (mpt2sas_fwfault_debug) | 3885 | if (mpt2sas_fwfault_debug) |
3829 | mpt2sas_halt_firmware(ioc); | 3886 | mpt2sas_halt_firmware(ioc); |
3830 | 3887 | ||
3831 | spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags); | 3888 | /* TODO - What we really should be doing is pulling |
3832 | if (ioc->shost_recovery) { | 3889 | * out all the code associated with NO_SLEEP; its never used. |
3833 | spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags); | 3890 | * That is legacy code from mpt fusion driver, ported over. |
3834 | printk(MPT2SAS_ERR_FMT "%s: busy\n", | 3891 | * I will leave this BUG_ON here for now till its been resolved. |
3835 | ioc->name, __func__); | 3892 | */ |
3836 | return -EBUSY; | 3893 | BUG_ON(sleep_flag == NO_SLEEP); |
3894 | |||
3895 | /* wait for an active reset in progress to complete */ | ||
3896 | if (!mutex_trylock(&ioc->reset_in_progress_mutex)) { | ||
3897 | do { | ||
3898 | ssleep(1); | ||
3899 | } while (ioc->shost_recovery == 1); | ||
3900 | dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: exit\n", ioc->name, | ||
3901 | __func__)); | ||
3902 | return ioc->ioc_reset_in_progress_status; | ||
3837 | } | 3903 | } |
3904 | |||
3905 | spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags); | ||
3838 | ioc->shost_recovery = 1; | 3906 | ioc->shost_recovery = 1; |
3839 | spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags); | 3907 | spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags); |
3840 | 3908 | ||
@@ -3849,13 +3917,17 @@ mpt2sas_base_hard_reset_handler(struct MPT2SAS_ADAPTER *ioc, int sleep_flag, | |||
3849 | if (!r) | 3917 | if (!r) |
3850 | _base_reset_handler(ioc, MPT2_IOC_DONE_RESET); | 3918 | _base_reset_handler(ioc, MPT2_IOC_DONE_RESET); |
3851 | out: | 3919 | out: |
3852 | dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: %s\n", | 3920 | dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: %s\n", |
3853 | ioc->name, __func__, ((r == 0) ? "SUCCESS" : "FAILED"))); | 3921 | ioc->name, __func__, ((r == 0) ? "SUCCESS" : "FAILED"))); |
3854 | 3922 | ||
3855 | spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags); | 3923 | spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags); |
3924 | ioc->ioc_reset_in_progress_status = r; | ||
3856 | ioc->shost_recovery = 0; | 3925 | ioc->shost_recovery = 0; |
3857 | complete(&ioc->shost_recovery_done); | 3926 | complete(&ioc->shost_recovery_done); |
3858 | spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags); | 3927 | spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags); |
3928 | mutex_unlock(&ioc->reset_in_progress_mutex); | ||
3859 | 3929 | ||
3930 | dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: exit\n", ioc->name, | ||
3931 | __func__)); | ||
3860 | return r; | 3932 | return r; |
3861 | } | 3933 | } |