diff options
Diffstat (limited to 'drivers/scsi/mpt2sas/mpt2sas_base.c')
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_base.c | 240 |
1 files changed, 183 insertions, 57 deletions
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c index 8a78ab767e86..fc9dfda72699 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_base.c +++ b/drivers/scsi/mpt2sas/mpt2sas_base.c | |||
@@ -92,6 +92,9 @@ static int disable_discovery = -1; | |||
92 | module_param(disable_discovery, int, 0); | 92 | module_param(disable_discovery, int, 0); |
93 | MODULE_PARM_DESC(disable_discovery, " disable discovery "); | 93 | MODULE_PARM_DESC(disable_discovery, " disable discovery "); |
94 | 94 | ||
95 | static int | ||
96 | _base_get_ioc_facts(struct MPT2SAS_ADAPTER *ioc, int sleep_flag); | ||
97 | |||
95 | /** | 98 | /** |
96 | * _scsih_set_fwfault_debug - global setting of ioc->fwfault_debug. | 99 | * _scsih_set_fwfault_debug - global setting of ioc->fwfault_debug. |
97 | * | 100 | * |
@@ -1179,17 +1182,22 @@ static int | |||
1179 | _base_config_dma_addressing(struct MPT2SAS_ADAPTER *ioc, struct pci_dev *pdev) | 1182 | _base_config_dma_addressing(struct MPT2SAS_ADAPTER *ioc, struct pci_dev *pdev) |
1180 | { | 1183 | { |
1181 | struct sysinfo s; | 1184 | struct sysinfo s; |
1182 | char *desc = NULL; | 1185 | u64 consistent_dma_mask; |
1186 | |||
1187 | if (ioc->dma_mask) | ||
1188 | consistent_dma_mask = DMA_BIT_MASK(64); | ||
1189 | else | ||
1190 | consistent_dma_mask = DMA_BIT_MASK(32); | ||
1183 | 1191 | ||
1184 | if (sizeof(dma_addr_t) > 4) { | 1192 | if (sizeof(dma_addr_t) > 4) { |
1185 | const uint64_t required_mask = | 1193 | const uint64_t required_mask = |
1186 | dma_get_required_mask(&pdev->dev); | 1194 | dma_get_required_mask(&pdev->dev); |
1187 | if ((required_mask > DMA_BIT_MASK(32)) && !pci_set_dma_mask(pdev, | 1195 | if ((required_mask > DMA_BIT_MASK(32)) && |
1188 | DMA_BIT_MASK(64)) && !pci_set_consistent_dma_mask(pdev, | 1196 | !pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) && |
1189 | DMA_BIT_MASK(64))) { | 1197 | !pci_set_consistent_dma_mask(pdev, consistent_dma_mask)) { |
1190 | ioc->base_add_sg_single = &_base_add_sg_single_64; | 1198 | ioc->base_add_sg_single = &_base_add_sg_single_64; |
1191 | ioc->sge_size = sizeof(Mpi2SGESimple64_t); | 1199 | ioc->sge_size = sizeof(Mpi2SGESimple64_t); |
1192 | desc = "64"; | 1200 | ioc->dma_mask = 64; |
1193 | goto out; | 1201 | goto out; |
1194 | } | 1202 | } |
1195 | } | 1203 | } |
@@ -1198,18 +1206,29 @@ _base_config_dma_addressing(struct MPT2SAS_ADAPTER *ioc, struct pci_dev *pdev) | |||
1198 | && !pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) { | 1206 | && !pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) { |
1199 | ioc->base_add_sg_single = &_base_add_sg_single_32; | 1207 | ioc->base_add_sg_single = &_base_add_sg_single_32; |
1200 | ioc->sge_size = sizeof(Mpi2SGESimple32_t); | 1208 | ioc->sge_size = sizeof(Mpi2SGESimple32_t); |
1201 | desc = "32"; | 1209 | ioc->dma_mask = 32; |
1202 | } else | 1210 | } else |
1203 | return -ENODEV; | 1211 | return -ENODEV; |
1204 | 1212 | ||
1205 | out: | 1213 | out: |
1206 | si_meminfo(&s); | 1214 | si_meminfo(&s); |
1207 | printk(MPT2SAS_INFO_FMT "%s BIT PCI BUS DMA ADDRESSING SUPPORTED, " | 1215 | printk(MPT2SAS_INFO_FMT |
1208 | "total mem (%ld kB)\n", ioc->name, desc, convert_to_kb(s.totalram)); | 1216 | "%d BIT PCI BUS DMA ADDRESSING SUPPORTED, total mem (%ld kB)\n", |
1217 | ioc->name, ioc->dma_mask, convert_to_kb(s.totalram)); | ||
1209 | 1218 | ||
1210 | return 0; | 1219 | return 0; |
1211 | } | 1220 | } |
1212 | 1221 | ||
1222 | static int | ||
1223 | _base_change_consistent_dma_mask(struct MPT2SAS_ADAPTER *ioc, | ||
1224 | struct pci_dev *pdev) | ||
1225 | { | ||
1226 | if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64))) { | ||
1227 | if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) | ||
1228 | return -ENODEV; | ||
1229 | } | ||
1230 | return 0; | ||
1231 | } | ||
1213 | /** | 1232 | /** |
1214 | * _base_check_enable_msix - checks MSIX capabable. | 1233 | * _base_check_enable_msix - checks MSIX capabable. |
1215 | * @ioc: per adapter object | 1234 | * @ioc: per adapter object |
@@ -1406,11 +1425,15 @@ _base_enable_msix(struct MPT2SAS_ADAPTER *ioc) | |||
1406 | ioc->reply_queue_count = min_t(int, ioc->cpu_count, | 1425 | ioc->reply_queue_count = min_t(int, ioc->cpu_count, |
1407 | ioc->msix_vector_count); | 1426 | ioc->msix_vector_count); |
1408 | 1427 | ||
1428 | if (!ioc->rdpq_array_enable && max_msix_vectors == -1) | ||
1429 | max_msix_vectors = 8; | ||
1430 | |||
1409 | if (max_msix_vectors > 0) { | 1431 | if (max_msix_vectors > 0) { |
1410 | ioc->reply_queue_count = min_t(int, max_msix_vectors, | 1432 | ioc->reply_queue_count = min_t(int, max_msix_vectors, |
1411 | ioc->reply_queue_count); | 1433 | ioc->reply_queue_count); |
1412 | ioc->msix_vector_count = ioc->reply_queue_count; | 1434 | ioc->msix_vector_count = ioc->reply_queue_count; |
1413 | } | 1435 | } else if (max_msix_vectors == 0) |
1436 | goto try_ioapic; | ||
1414 | 1437 | ||
1415 | printk(MPT2SAS_INFO_FMT | 1438 | printk(MPT2SAS_INFO_FMT |
1416 | "MSI-X vectors supported: %d, no of cores: %d, max_msix_vectors: %d\n", | 1439 | "MSI-X vectors supported: %d, no of cores: %d, max_msix_vectors: %d\n", |
@@ -1453,6 +1476,7 @@ _base_enable_msix(struct MPT2SAS_ADAPTER *ioc) | |||
1453 | /* failback to io_apic interrupt routing */ | 1476 | /* failback to io_apic interrupt routing */ |
1454 | try_ioapic: | 1477 | try_ioapic: |
1455 | 1478 | ||
1479 | ioc->reply_queue_count = 1; | ||
1456 | r = _base_request_irq(ioc, 0, ioc->pdev->irq); | 1480 | r = _base_request_irq(ioc, 0, ioc->pdev->irq); |
1457 | 1481 | ||
1458 | return r; | 1482 | return r; |
@@ -1534,6 +1558,16 @@ mpt2sas_base_map_resources(struct MPT2SAS_ADAPTER *ioc) | |||
1534 | } | 1558 | } |
1535 | 1559 | ||
1536 | _base_mask_interrupts(ioc); | 1560 | _base_mask_interrupts(ioc); |
1561 | |||
1562 | r = _base_get_ioc_facts(ioc, CAN_SLEEP); | ||
1563 | if (r) | ||
1564 | goto out_fail; | ||
1565 | |||
1566 | if (!ioc->rdpq_array_enable_assigned) { | ||
1567 | ioc->rdpq_array_enable = ioc->rdpq_array_capable; | ||
1568 | ioc->rdpq_array_enable_assigned = 1; | ||
1569 | } | ||
1570 | |||
1537 | r = _base_enable_msix(ioc); | 1571 | r = _base_enable_msix(ioc); |
1538 | if (r) | 1572 | if (r) |
1539 | goto out_fail; | 1573 | goto out_fail; |
@@ -2331,7 +2365,8 @@ _base_static_config_pages(struct MPT2SAS_ADAPTER *ioc) | |||
2331 | static void | 2365 | static void |
2332 | _base_release_memory_pools(struct MPT2SAS_ADAPTER *ioc) | 2366 | _base_release_memory_pools(struct MPT2SAS_ADAPTER *ioc) |
2333 | { | 2367 | { |
2334 | int i; | 2368 | int i = 0; |
2369 | struct reply_post_struct *rps; | ||
2335 | 2370 | ||
2336 | dexitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, | 2371 | dexitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, |
2337 | __func__)); | 2372 | __func__)); |
@@ -2372,15 +2407,25 @@ _base_release_memory_pools(struct MPT2SAS_ADAPTER *ioc) | |||
2372 | ioc->reply_free = NULL; | 2407 | ioc->reply_free = NULL; |
2373 | } | 2408 | } |
2374 | 2409 | ||
2375 | if (ioc->reply_post_free) { | 2410 | if (ioc->reply_post) { |
2376 | pci_pool_free(ioc->reply_post_free_dma_pool, | 2411 | do { |
2377 | ioc->reply_post_free, ioc->reply_post_free_dma); | 2412 | rps = &ioc->reply_post[i]; |
2413 | if (rps->reply_post_free) { | ||
2414 | pci_pool_free( | ||
2415 | ioc->reply_post_free_dma_pool, | ||
2416 | rps->reply_post_free, | ||
2417 | rps->reply_post_free_dma); | ||
2418 | dexitprintk(ioc, printk(MPT2SAS_INFO_FMT | ||
2419 | "reply_post_free_pool(0x%p): free\n", | ||
2420 | ioc->name, rps->reply_post_free)); | ||
2421 | rps->reply_post_free = NULL; | ||
2422 | } | ||
2423 | } while (ioc->rdpq_array_enable && | ||
2424 | (++i < ioc->reply_queue_count)); | ||
2425 | |||
2378 | if (ioc->reply_post_free_dma_pool) | 2426 | if (ioc->reply_post_free_dma_pool) |
2379 | pci_pool_destroy(ioc->reply_post_free_dma_pool); | 2427 | pci_pool_destroy(ioc->reply_post_free_dma_pool); |
2380 | dexitprintk(ioc, printk(MPT2SAS_INFO_FMT | 2428 | kfree(ioc->reply_post); |
2381 | "reply_post_free_pool(0x%p): free\n", ioc->name, | ||
2382 | ioc->reply_post_free)); | ||
2383 | ioc->reply_post_free = NULL; | ||
2384 | } | 2429 | } |
2385 | 2430 | ||
2386 | if (ioc->config_page) { | 2431 | if (ioc->config_page) { |
@@ -2523,6 +2568,65 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) | |||
2523 | ioc->max_sges_in_chain_message, ioc->shost->sg_tablesize, | 2568 | ioc->max_sges_in_chain_message, ioc->shost->sg_tablesize, |
2524 | ioc->chains_needed_per_io)); | 2569 | ioc->chains_needed_per_io)); |
2525 | 2570 | ||
2571 | /* reply post queue, 16 byte align */ | ||
2572 | reply_post_free_sz = ioc->reply_post_queue_depth * | ||
2573 | sizeof(Mpi2DefaultReplyDescriptor_t); | ||
2574 | |||
2575 | sz = reply_post_free_sz; | ||
2576 | if (_base_is_controller_msix_enabled(ioc) && !ioc->rdpq_array_enable) | ||
2577 | sz *= ioc->reply_queue_count; | ||
2578 | |||
2579 | ioc->reply_post = kcalloc((ioc->rdpq_array_enable) ? | ||
2580 | (ioc->reply_queue_count):1, | ||
2581 | sizeof(struct reply_post_struct), GFP_KERNEL); | ||
2582 | |||
2583 | if (!ioc->reply_post) { | ||
2584 | printk(MPT2SAS_ERR_FMT "reply_post_free pool: kcalloc failed\n", | ||
2585 | ioc->name); | ||
2586 | goto out; | ||
2587 | } | ||
2588 | ioc->reply_post_free_dma_pool = pci_pool_create("reply_post_free pool", | ||
2589 | ioc->pdev, sz, 16, 0); | ||
2590 | if (!ioc->reply_post_free_dma_pool) { | ||
2591 | printk(MPT2SAS_ERR_FMT | ||
2592 | "reply_post_free pool: pci_pool_create failed\n", | ||
2593 | ioc->name); | ||
2594 | goto out; | ||
2595 | } | ||
2596 | i = 0; | ||
2597 | do { | ||
2598 | ioc->reply_post[i].reply_post_free = | ||
2599 | pci_pool_alloc(ioc->reply_post_free_dma_pool, | ||
2600 | GFP_KERNEL, | ||
2601 | &ioc->reply_post[i].reply_post_free_dma); | ||
2602 | if (!ioc->reply_post[i].reply_post_free) { | ||
2603 | printk(MPT2SAS_ERR_FMT | ||
2604 | "reply_post_free pool: pci_pool_alloc failed\n", | ||
2605 | ioc->name); | ||
2606 | goto out; | ||
2607 | } | ||
2608 | memset(ioc->reply_post[i].reply_post_free, 0, sz); | ||
2609 | dinitprintk(ioc, printk(MPT2SAS_INFO_FMT | ||
2610 | "reply post free pool (0x%p): depth(%d)," | ||
2611 | "element_size(%d), pool_size(%d kB)\n", ioc->name, | ||
2612 | ioc->reply_post[i].reply_post_free, | ||
2613 | ioc->reply_post_queue_depth, 8, sz/1024)); | ||
2614 | dinitprintk(ioc, printk(MPT2SAS_INFO_FMT | ||
2615 | "reply_post_free_dma = (0x%llx)\n", ioc->name, | ||
2616 | (unsigned long long) | ||
2617 | ioc->reply_post[i].reply_post_free_dma)); | ||
2618 | total_sz += sz; | ||
2619 | } while (ioc->rdpq_array_enable && (++i < ioc->reply_queue_count)); | ||
2620 | |||
2621 | if (ioc->dma_mask == 64) { | ||
2622 | if (_base_change_consistent_dma_mask(ioc, ioc->pdev) != 0) { | ||
2623 | printk(MPT2SAS_WARN_FMT | ||
2624 | "no suitable consistent DMA mask for %s\n", | ||
2625 | ioc->name, pci_name(ioc->pdev)); | ||
2626 | goto out; | ||
2627 | } | ||
2628 | } | ||
2629 | |||
2526 | ioc->scsiio_depth = ioc->hba_queue_depth - | 2630 | ioc->scsiio_depth = ioc->hba_queue_depth - |
2527 | ioc->hi_priority_depth - ioc->internal_depth; | 2631 | ioc->hi_priority_depth - ioc->internal_depth; |
2528 | 2632 | ||
@@ -2734,37 +2838,6 @@ chain_done: | |||
2734 | "(0x%llx)\n", ioc->name, (unsigned long long)ioc->reply_free_dma)); | 2838 | "(0x%llx)\n", ioc->name, (unsigned long long)ioc->reply_free_dma)); |
2735 | total_sz += sz; | 2839 | total_sz += sz; |
2736 | 2840 | ||
2737 | /* reply post queue, 16 byte align */ | ||
2738 | reply_post_free_sz = ioc->reply_post_queue_depth * | ||
2739 | sizeof(Mpi2DefaultReplyDescriptor_t); | ||
2740 | if (_base_is_controller_msix_enabled(ioc)) | ||
2741 | sz = reply_post_free_sz * ioc->reply_queue_count; | ||
2742 | else | ||
2743 | sz = reply_post_free_sz; | ||
2744 | ioc->reply_post_free_dma_pool = pci_pool_create("reply_post_free pool", | ||
2745 | ioc->pdev, sz, 16, 0); | ||
2746 | if (!ioc->reply_post_free_dma_pool) { | ||
2747 | printk(MPT2SAS_ERR_FMT "reply_post_free pool: pci_pool_create " | ||
2748 | "failed\n", ioc->name); | ||
2749 | goto out; | ||
2750 | } | ||
2751 | ioc->reply_post_free = pci_pool_alloc(ioc->reply_post_free_dma_pool , | ||
2752 | GFP_KERNEL, &ioc->reply_post_free_dma); | ||
2753 | if (!ioc->reply_post_free) { | ||
2754 | printk(MPT2SAS_ERR_FMT "reply_post_free pool: pci_pool_alloc " | ||
2755 | "failed\n", ioc->name); | ||
2756 | goto out; | ||
2757 | } | ||
2758 | memset(ioc->reply_post_free, 0, sz); | ||
2759 | dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "reply post free pool" | ||
2760 | "(0x%p): depth(%d), element_size(%d), pool_size(%d kB)\n", | ||
2761 | ioc->name, ioc->reply_post_free, ioc->reply_post_queue_depth, 8, | ||
2762 | sz/1024)); | ||
2763 | dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "reply_post_free_dma = " | ||
2764 | "(0x%llx)\n", ioc->name, (unsigned long long) | ||
2765 | ioc->reply_post_free_dma)); | ||
2766 | total_sz += sz; | ||
2767 | |||
2768 | ioc->config_page_sz = 512; | 2841 | ioc->config_page_sz = 512; |
2769 | ioc->config_page = pci_alloc_consistent(ioc->pdev, | 2842 | ioc->config_page = pci_alloc_consistent(ioc->pdev, |
2770 | ioc->config_page_sz, &ioc->config_page_dma); | 2843 | ioc->config_page_sz, &ioc->config_page_dma); |
@@ -3436,6 +3509,9 @@ _base_get_ioc_facts(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) | |||
3436 | facts->IOCCapabilities = le32_to_cpu(mpi_reply.IOCCapabilities); | 3509 | facts->IOCCapabilities = le32_to_cpu(mpi_reply.IOCCapabilities); |
3437 | if ((facts->IOCCapabilities & MPI2_IOCFACTS_CAPABILITY_INTEGRATED_RAID)) | 3510 | if ((facts->IOCCapabilities & MPI2_IOCFACTS_CAPABILITY_INTEGRATED_RAID)) |
3438 | ioc->ir_firmware = 1; | 3511 | ioc->ir_firmware = 1; |
3512 | if ((facts->IOCCapabilities & | ||
3513 | MPI2_IOCFACTS_CAPABILITY_RDPQ_ARRAY_CAPABLE)) | ||
3514 | ioc->rdpq_array_capable = 1; | ||
3439 | facts->FWVersion.Word = le32_to_cpu(mpi_reply.FWVersion.Word); | 3515 | facts->FWVersion.Word = le32_to_cpu(mpi_reply.FWVersion.Word); |
3440 | facts->IOCRequestFrameSize = | 3516 | facts->IOCRequestFrameSize = |
3441 | le16_to_cpu(mpi_reply.IOCRequestFrameSize); | 3517 | le16_to_cpu(mpi_reply.IOCRequestFrameSize); |
@@ -3471,9 +3547,12 @@ _base_send_ioc_init(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) | |||
3471 | { | 3547 | { |
3472 | Mpi2IOCInitRequest_t mpi_request; | 3548 | Mpi2IOCInitRequest_t mpi_request; |
3473 | Mpi2IOCInitReply_t mpi_reply; | 3549 | Mpi2IOCInitReply_t mpi_reply; |
3474 | int r; | 3550 | int i, r = 0; |
3475 | struct timeval current_time; | 3551 | struct timeval current_time; |
3476 | u16 ioc_status; | 3552 | u16 ioc_status; |
3553 | u32 reply_post_free_array_sz = 0; | ||
3554 | Mpi2IOCInitRDPQArrayEntry *reply_post_free_array = NULL; | ||
3555 | dma_addr_t reply_post_free_array_dma; | ||
3477 | 3556 | ||
3478 | dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, | 3557 | dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, |
3479 | __func__)); | 3558 | __func__)); |
@@ -3502,9 +3581,31 @@ _base_send_ioc_init(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) | |||
3502 | cpu_to_le64((u64)ioc->request_dma); | 3581 | cpu_to_le64((u64)ioc->request_dma); |
3503 | mpi_request.ReplyFreeQueueAddress = | 3582 | mpi_request.ReplyFreeQueueAddress = |
3504 | cpu_to_le64((u64)ioc->reply_free_dma); | 3583 | cpu_to_le64((u64)ioc->reply_free_dma); |
3505 | mpi_request.ReplyDescriptorPostQueueAddress = | ||
3506 | cpu_to_le64((u64)ioc->reply_post_free_dma); | ||
3507 | 3584 | ||
3585 | if (ioc->rdpq_array_enable) { | ||
3586 | reply_post_free_array_sz = ioc->reply_queue_count * | ||
3587 | sizeof(Mpi2IOCInitRDPQArrayEntry); | ||
3588 | reply_post_free_array = pci_alloc_consistent(ioc->pdev, | ||
3589 | reply_post_free_array_sz, &reply_post_free_array_dma); | ||
3590 | if (!reply_post_free_array) { | ||
3591 | printk(MPT2SAS_ERR_FMT | ||
3592 | "reply_post_free_array: pci_alloc_consistent failed\n", | ||
3593 | ioc->name); | ||
3594 | r = -ENOMEM; | ||
3595 | goto out; | ||
3596 | } | ||
3597 | memset(reply_post_free_array, 0, reply_post_free_array_sz); | ||
3598 | for (i = 0; i < ioc->reply_queue_count; i++) | ||
3599 | reply_post_free_array[i].RDPQBaseAddress = | ||
3600 | cpu_to_le64( | ||
3601 | (u64)ioc->reply_post[i].reply_post_free_dma); | ||
3602 | mpi_request.MsgFlags = MPI2_IOCINIT_MSGFLAG_RDPQ_ARRAY_MODE; | ||
3603 | mpi_request.ReplyDescriptorPostQueueAddress = | ||
3604 | cpu_to_le64((u64)reply_post_free_array_dma); | ||
3605 | } else { | ||
3606 | mpi_request.ReplyDescriptorPostQueueAddress = | ||
3607 | cpu_to_le64((u64)ioc->reply_post[0].reply_post_free_dma); | ||
3608 | } | ||
3508 | 3609 | ||
3509 | /* This time stamp specifies number of milliseconds | 3610 | /* This time stamp specifies number of milliseconds |
3510 | * since epoch ~ midnight January 1, 1970. | 3611 | * since epoch ~ midnight January 1, 1970. |
@@ -3532,7 +3633,7 @@ _base_send_ioc_init(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) | |||
3532 | if (r != 0) { | 3633 | if (r != 0) { |
3533 | printk(MPT2SAS_ERR_FMT "%s: handshake failed (r=%d)\n", | 3634 | printk(MPT2SAS_ERR_FMT "%s: handshake failed (r=%d)\n", |
3534 | ioc->name, __func__, r); | 3635 | ioc->name, __func__, r); |
3535 | return r; | 3636 | goto out; |
3536 | } | 3637 | } |
3537 | 3638 | ||
3538 | ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK; | 3639 | ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK; |
@@ -3542,7 +3643,12 @@ _base_send_ioc_init(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) | |||
3542 | r = -EIO; | 3643 | r = -EIO; |
3543 | } | 3644 | } |
3544 | 3645 | ||
3545 | return 0; | 3646 | out: |
3647 | if (reply_post_free_array) | ||
3648 | pci_free_consistent(ioc->pdev, reply_post_free_array_sz, | ||
3649 | reply_post_free_array, | ||
3650 | reply_post_free_array_dma); | ||
3651 | return r; | ||
3546 | } | 3652 | } |
3547 | 3653 | ||
3548 | /** | 3654 | /** |
@@ -4075,7 +4181,7 @@ _base_make_ioc_operational(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) | |||
4075 | u8 hide_flag; | 4181 | u8 hide_flag; |
4076 | struct adapter_reply_queue *reply_q; | 4182 | struct adapter_reply_queue *reply_q; |
4077 | long reply_post_free; | 4183 | long reply_post_free; |
4078 | u32 reply_post_free_sz; | 4184 | u32 reply_post_free_sz, index = 0; |
4079 | 4185 | ||
4080 | dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, | 4186 | dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, |
4081 | __func__)); | 4187 | __func__)); |
@@ -4146,19 +4252,27 @@ _base_make_ioc_operational(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) | |||
4146 | _base_assign_reply_queues(ioc); | 4252 | _base_assign_reply_queues(ioc); |
4147 | 4253 | ||
4148 | /* initialize Reply Post Free Queue */ | 4254 | /* initialize Reply Post Free Queue */ |
4149 | reply_post_free = (long)ioc->reply_post_free; | ||
4150 | reply_post_free_sz = ioc->reply_post_queue_depth * | 4255 | reply_post_free_sz = ioc->reply_post_queue_depth * |
4151 | sizeof(Mpi2DefaultReplyDescriptor_t); | 4256 | sizeof(Mpi2DefaultReplyDescriptor_t); |
4257 | reply_post_free = (long)ioc->reply_post[index].reply_post_free; | ||
4152 | list_for_each_entry(reply_q, &ioc->reply_queue_list, list) { | 4258 | list_for_each_entry(reply_q, &ioc->reply_queue_list, list) { |
4153 | reply_q->reply_post_host_index = 0; | 4259 | reply_q->reply_post_host_index = 0; |
4154 | reply_q->reply_post_free = (Mpi2ReplyDescriptorsUnion_t *) | 4260 | reply_q->reply_post_free = (Mpi2ReplyDescriptorsUnion_t *) |
4155 | reply_post_free; | 4261 | reply_post_free; |
4156 | for (i = 0; i < ioc->reply_post_queue_depth; i++) | 4262 | for (i = 0; i < ioc->reply_post_queue_depth; i++) |
4157 | reply_q->reply_post_free[i].Words = | 4263 | reply_q->reply_post_free[i].Words = |
4158 | cpu_to_le64(ULLONG_MAX); | 4264 | cpu_to_le64(ULLONG_MAX); |
4159 | if (!_base_is_controller_msix_enabled(ioc)) | 4265 | if (!_base_is_controller_msix_enabled(ioc)) |
4160 | goto skip_init_reply_post_free_queue; | 4266 | goto skip_init_reply_post_free_queue; |
4161 | reply_post_free += reply_post_free_sz; | 4267 | /* |
4268 | * If RDPQ is enabled, switch to the next allocation. | ||
4269 | * Otherwise advance within the contiguous region. | ||
4270 | */ | ||
4271 | if (ioc->rdpq_array_enable) | ||
4272 | reply_post_free = (long) | ||
4273 | ioc->reply_post[++index].reply_post_free; | ||
4274 | else | ||
4275 | reply_post_free += reply_post_free_sz; | ||
4162 | } | 4276 | } |
4163 | skip_init_reply_post_free_queue: | 4277 | skip_init_reply_post_free_queue: |
4164 | 4278 | ||
@@ -4286,6 +4400,8 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc) | |||
4286 | } | 4400 | } |
4287 | } | 4401 | } |
4288 | 4402 | ||
4403 | ioc->rdpq_array_enable_assigned = 0; | ||
4404 | ioc->dma_mask = 0; | ||
4289 | r = mpt2sas_base_map_resources(ioc); | 4405 | r = mpt2sas_base_map_resources(ioc); |
4290 | if (r) | 4406 | if (r) |
4291 | goto out_free_resources; | 4407 | goto out_free_resources; |
@@ -4647,6 +4763,16 @@ mpt2sas_base_hard_reset_handler(struct MPT2SAS_ADAPTER *ioc, int sleep_flag, | |||
4647 | r = -EFAULT; | 4763 | r = -EFAULT; |
4648 | goto out; | 4764 | goto out; |
4649 | } | 4765 | } |
4766 | |||
4767 | r = _base_get_ioc_facts(ioc, CAN_SLEEP); | ||
4768 | if (r) | ||
4769 | goto out; | ||
4770 | |||
4771 | if (ioc->rdpq_array_enable && !ioc->rdpq_array_capable) | ||
4772 | panic("%s: Issue occurred with flashing controller firmware." | ||
4773 | "Please reboot the system and ensure that the correct" | ||
4774 | " firmware version is running\n", ioc->name); | ||
4775 | |||
4650 | r = _base_make_ioc_operational(ioc, sleep_flag); | 4776 | r = _base_make_ioc_operational(ioc, sleep_flag); |
4651 | if (!r) | 4777 | if (!r) |
4652 | _base_reset_handler(ioc, MPT2_IOC_DONE_RESET); | 4778 | _base_reset_handler(ioc, MPT2_IOC_DONE_RESET); |