aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/mpt3sas/mpt3sas_base.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/mpt3sas/mpt3sas_base.c')
-rw-r--r--drivers/scsi/mpt3sas/mpt3sas_base.c287
1 files changed, 227 insertions, 60 deletions
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 93ce2b2baa41..1560115079c7 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -3,7 +3,7 @@
3 * for access to MPT (Message Passing Technology) firmware. 3 * for access to MPT (Message Passing Technology) firmware.
4 * 4 *
5 * This code is based on drivers/scsi/mpt3sas/mpt3sas_base.c 5 * This code is based on drivers/scsi/mpt3sas/mpt3sas_base.c
6 * Copyright (C) 2012-2013 LSI Corporation 6 * Copyright (C) 2012-2014 LSI Corporation
7 * (mailto:DL-MPTFusionLinux@lsi.com) 7 * (mailto:DL-MPTFusionLinux@lsi.com)
8 * 8 *
9 * This program is free software; you can redistribute it and/or 9 * This program is free software; you can redistribute it and/or
@@ -91,6 +91,8 @@ static int mpt3sas_fwfault_debug;
91MODULE_PARM_DESC(mpt3sas_fwfault_debug, 91MODULE_PARM_DESC(mpt3sas_fwfault_debug,
92 " enable detection of firmware fault and halt firmware - (default=0)"); 92 " enable detection of firmware fault and halt firmware - (default=0)");
93 93
94static int
95_base_get_ioc_facts(struct MPT3SAS_ADAPTER *ioc, int sleep_flag);
94 96
95/** 97/**
96 * _scsih_set_fwfault_debug - global setting of ioc->fwfault_debug. 98 * _scsih_set_fwfault_debug - global setting of ioc->fwfault_debug.
@@ -1482,17 +1484,22 @@ static int
1482_base_config_dma_addressing(struct MPT3SAS_ADAPTER *ioc, struct pci_dev *pdev) 1484_base_config_dma_addressing(struct MPT3SAS_ADAPTER *ioc, struct pci_dev *pdev)
1483{ 1485{
1484 struct sysinfo s; 1486 struct sysinfo s;
1485 char *desc = NULL; 1487 u64 consistent_dma_mask;
1488
1489 if (ioc->dma_mask)
1490 consistent_dma_mask = DMA_BIT_MASK(64);
1491 else
1492 consistent_dma_mask = DMA_BIT_MASK(32);
1486 1493
1487 if (sizeof(dma_addr_t) > 4) { 1494 if (sizeof(dma_addr_t) > 4) {
1488 const uint64_t required_mask = 1495 const uint64_t required_mask =
1489 dma_get_required_mask(&pdev->dev); 1496 dma_get_required_mask(&pdev->dev);
1490 if ((required_mask > DMA_BIT_MASK(32)) && 1497 if ((required_mask > DMA_BIT_MASK(32)) &&
1491 !pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) && 1498 !pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) &&
1492 !pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64))) { 1499 !pci_set_consistent_dma_mask(pdev, consistent_dma_mask)) {
1493 ioc->base_add_sg_single = &_base_add_sg_single_64; 1500 ioc->base_add_sg_single = &_base_add_sg_single_64;
1494 ioc->sge_size = sizeof(Mpi2SGESimple64_t); 1501 ioc->sge_size = sizeof(Mpi2SGESimple64_t);
1495 desc = "64"; 1502 ioc->dma_mask = 64;
1496 goto out; 1503 goto out;
1497 } 1504 }
1498 } 1505 }
@@ -1501,19 +1508,30 @@ _base_config_dma_addressing(struct MPT3SAS_ADAPTER *ioc, struct pci_dev *pdev)
1501 && !pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) { 1508 && !pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) {
1502 ioc->base_add_sg_single = &_base_add_sg_single_32; 1509 ioc->base_add_sg_single = &_base_add_sg_single_32;
1503 ioc->sge_size = sizeof(Mpi2SGESimple32_t); 1510 ioc->sge_size = sizeof(Mpi2SGESimple32_t);
1504 desc = "32"; 1511 ioc->dma_mask = 32;
1505 } else 1512 } else
1506 return -ENODEV; 1513 return -ENODEV;
1507 1514
1508 out: 1515 out:
1509 si_meminfo(&s); 1516 si_meminfo(&s);
1510 pr_info(MPT3SAS_FMT 1517 pr_info(MPT3SAS_FMT
1511 "%s BIT PCI BUS DMA ADDRESSING SUPPORTED, total mem (%ld kB)\n", 1518 "%d BIT PCI BUS DMA ADDRESSING SUPPORTED, total mem (%ld kB)\n",
1512 ioc->name, desc, convert_to_kb(s.totalram)); 1519 ioc->name, ioc->dma_mask, convert_to_kb(s.totalram));
1513 1520
1514 return 0; 1521 return 0;
1515} 1522}
1516 1523
1524static int
1525_base_change_consistent_dma_mask(struct MPT3SAS_ADAPTER *ioc,
1526 struct pci_dev *pdev)
1527{
1528 if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64))) {
1529 if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)))
1530 return -ENODEV;
1531 }
1532 return 0;
1533}
1534
1517/** 1535/**
1518 * _base_check_enable_msix - checks MSIX capabable. 1536 * _base_check_enable_msix - checks MSIX capabable.
1519 * @ioc: per adapter object 1537 * @ioc: per adapter object
@@ -1698,11 +1716,15 @@ _base_enable_msix(struct MPT3SAS_ADAPTER *ioc)
1698 ": %d, max_msix_vectors: %d\n", ioc->name, ioc->msix_vector_count, 1716 ": %d, max_msix_vectors: %d\n", ioc->name, ioc->msix_vector_count,
1699 ioc->cpu_count, max_msix_vectors); 1717 ioc->cpu_count, max_msix_vectors);
1700 1718
1719 if (!ioc->rdpq_array_enable && max_msix_vectors == -1)
1720 max_msix_vectors = 8;
1721
1701 if (max_msix_vectors > 0) { 1722 if (max_msix_vectors > 0) {
1702 ioc->reply_queue_count = min_t(int, max_msix_vectors, 1723 ioc->reply_queue_count = min_t(int, max_msix_vectors,
1703 ioc->reply_queue_count); 1724 ioc->reply_queue_count);
1704 ioc->msix_vector_count = ioc->reply_queue_count; 1725 ioc->msix_vector_count = ioc->reply_queue_count;
1705 } 1726 } else if (max_msix_vectors == 0)
1727 goto try_ioapic;
1706 1728
1707 entries = kcalloc(ioc->reply_queue_count, sizeof(struct msix_entry), 1729 entries = kcalloc(ioc->reply_queue_count, sizeof(struct msix_entry),
1708 GFP_KERNEL); 1730 GFP_KERNEL);
@@ -1716,10 +1738,10 @@ _base_enable_msix(struct MPT3SAS_ADAPTER *ioc)
1716 for (i = 0, a = entries; i < ioc->reply_queue_count; i++, a++) 1738 for (i = 0, a = entries; i < ioc->reply_queue_count; i++, a++)
1717 a->entry = i; 1739 a->entry = i;
1718 1740
1719 r = pci_enable_msix(ioc->pdev, entries, ioc->reply_queue_count); 1741 r = pci_enable_msix_exact(ioc->pdev, entries, ioc->reply_queue_count);
1720 if (r) { 1742 if (r) {
1721 dfailprintk(ioc, pr_info(MPT3SAS_FMT 1743 dfailprintk(ioc, pr_info(MPT3SAS_FMT
1722 "pci_enable_msix failed (r=%d) !!!\n", 1744 "pci_enable_msix_exact failed (r=%d) !!!\n",
1723 ioc->name, r)); 1745 ioc->name, r));
1724 kfree(entries); 1746 kfree(entries);
1725 goto try_ioapic; 1747 goto try_ioapic;
@@ -1742,6 +1764,7 @@ _base_enable_msix(struct MPT3SAS_ADAPTER *ioc)
1742/* failback to io_apic interrupt routing */ 1764/* failback to io_apic interrupt routing */
1743 try_ioapic: 1765 try_ioapic:
1744 1766
1767 ioc->reply_queue_count = 1;
1745 r = _base_request_irq(ioc, 0, ioc->pdev->irq); 1768 r = _base_request_irq(ioc, 0, ioc->pdev->irq);
1746 1769
1747 return r; 1770 return r;
@@ -1821,6 +1844,16 @@ mpt3sas_base_map_resources(struct MPT3SAS_ADAPTER *ioc)
1821 } 1844 }
1822 1845
1823 _base_mask_interrupts(ioc); 1846 _base_mask_interrupts(ioc);
1847
1848 r = _base_get_ioc_facts(ioc, CAN_SLEEP);
1849 if (r)
1850 goto out_fail;
1851
1852 if (!ioc->rdpq_array_enable_assigned) {
1853 ioc->rdpq_array_enable = ioc->rdpq_array_capable;
1854 ioc->rdpq_array_enable_assigned = 1;
1855 }
1856
1824 r = _base_enable_msix(ioc); 1857 r = _base_enable_msix(ioc);
1825 if (r) 1858 if (r)
1826 goto out_fail; 1859 goto out_fail;
@@ -2185,6 +2218,53 @@ mpt3sas_base_put_smid_default(struct MPT3SAS_ADAPTER *ioc, u16 smid)
2185 &ioc->scsi_lookup_lock); 2218 &ioc->scsi_lookup_lock);
2186} 2219}
2187 2220
2221/**
2222 * _base_display_intel_branding - Display branding string
2223 * @ioc: per adapter object
2224 *
2225 * Return nothing.
2226 */
2227static void
2228_base_display_intel_branding(struct MPT3SAS_ADAPTER *ioc)
2229{
2230 if (ioc->pdev->subsystem_vendor != PCI_VENDOR_ID_INTEL)
2231 return;
2232
2233 switch (ioc->pdev->device) {
2234 case MPI25_MFGPAGE_DEVID_SAS3008:
2235 switch (ioc->pdev->subsystem_device) {
2236 case MPT3SAS_INTEL_RMS3JC080_SSDID:
2237 pr_info(MPT3SAS_FMT "%s\n", ioc->name,
2238 MPT3SAS_INTEL_RMS3JC080_BRANDING);
2239 break;
2240
2241 case MPT3SAS_INTEL_RS3GC008_SSDID:
2242 pr_info(MPT3SAS_FMT "%s\n", ioc->name,
2243 MPT3SAS_INTEL_RS3GC008_BRANDING);
2244 break;
2245 case MPT3SAS_INTEL_RS3FC044_SSDID:
2246 pr_info(MPT3SAS_FMT "%s\n", ioc->name,
2247 MPT3SAS_INTEL_RS3FC044_BRANDING);
2248 break;
2249 case MPT3SAS_INTEL_RS3UC080_SSDID:
2250 pr_info(MPT3SAS_FMT "%s\n", ioc->name,
2251 MPT3SAS_INTEL_RS3UC080_BRANDING);
2252 break;
2253 default:
2254 pr_info(MPT3SAS_FMT
2255 "Intel(R) Controller: Subsystem ID: 0x%X\n",
2256 ioc->name, ioc->pdev->subsystem_device);
2257 break;
2258 }
2259 break;
2260 default:
2261 pr_info(MPT3SAS_FMT
2262 "Intel(R) Controller: Subsystem ID: 0x%X\n",
2263 ioc->name, ioc->pdev->subsystem_device);
2264 break;
2265 }
2266}
2267
2188 2268
2189 2269
2190/** 2270/**
@@ -2216,6 +2296,8 @@ _base_display_ioc_capabilities(struct MPT3SAS_ADAPTER *ioc)
2216 (bios_version & 0x0000FF00) >> 8, 2296 (bios_version & 0x0000FF00) >> 8,
2217 bios_version & 0x000000FF); 2297 bios_version & 0x000000FF);
2218 2298
2299 _base_display_intel_branding(ioc);
2300
2219 pr_info(MPT3SAS_FMT "Protocol=(", ioc->name); 2301 pr_info(MPT3SAS_FMT "Protocol=(", ioc->name);
2220 2302
2221 if (ioc->facts.ProtocolFlags & MPI2_IOCFACTS_PROTOCOL_SCSI_INITIATOR) { 2303 if (ioc->facts.ProtocolFlags & MPI2_IOCFACTS_PROTOCOL_SCSI_INITIATOR) {
@@ -2447,7 +2529,8 @@ _base_static_config_pages(struct MPT3SAS_ADAPTER *ioc)
2447static void 2529static void
2448_base_release_memory_pools(struct MPT3SAS_ADAPTER *ioc) 2530_base_release_memory_pools(struct MPT3SAS_ADAPTER *ioc)
2449{ 2531{
2450 int i; 2532 int i = 0;
2533 struct reply_post_struct *rps;
2451 2534
2452 dexitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name, 2535 dexitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name,
2453 __func__)); 2536 __func__));
@@ -2492,15 +2575,25 @@ _base_release_memory_pools(struct MPT3SAS_ADAPTER *ioc)
2492 ioc->reply_free = NULL; 2575 ioc->reply_free = NULL;
2493 } 2576 }
2494 2577
2495 if (ioc->reply_post_free) { 2578 if (ioc->reply_post) {
2496 pci_pool_free(ioc->reply_post_free_dma_pool, 2579 do {
2497 ioc->reply_post_free, ioc->reply_post_free_dma); 2580 rps = &ioc->reply_post[i];
2581 if (rps->reply_post_free) {
2582 pci_pool_free(
2583 ioc->reply_post_free_dma_pool,
2584 rps->reply_post_free,
2585 rps->reply_post_free_dma);
2586 dexitprintk(ioc, pr_info(MPT3SAS_FMT
2587 "reply_post_free_pool(0x%p): free\n",
2588 ioc->name, rps->reply_post_free));
2589 rps->reply_post_free = NULL;
2590 }
2591 } while (ioc->rdpq_array_enable &&
2592 (++i < ioc->reply_queue_count));
2593
2498 if (ioc->reply_post_free_dma_pool) 2594 if (ioc->reply_post_free_dma_pool)
2499 pci_pool_destroy(ioc->reply_post_free_dma_pool); 2595 pci_pool_destroy(ioc->reply_post_free_dma_pool);
2500 dexitprintk(ioc, pr_info(MPT3SAS_FMT 2596 kfree(ioc->reply_post);
2501 "reply_post_free_pool(0x%p): free\n", ioc->name,
2502 ioc->reply_post_free));
2503 ioc->reply_post_free = NULL;
2504 } 2597 }
2505 2598
2506 if (ioc->config_page) { 2599 if (ioc->config_page) {
@@ -2647,6 +2740,65 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc, int sleep_flag)
2647 ioc->max_sges_in_chain_message, ioc->shost->sg_tablesize, 2740 ioc->max_sges_in_chain_message, ioc->shost->sg_tablesize,
2648 ioc->chains_needed_per_io)); 2741 ioc->chains_needed_per_io));
2649 2742
2743 /* reply post queue, 16 byte align */
2744 reply_post_free_sz = ioc->reply_post_queue_depth *
2745 sizeof(Mpi2DefaultReplyDescriptor_t);
2746
2747 sz = reply_post_free_sz;
2748 if (_base_is_controller_msix_enabled(ioc) && !ioc->rdpq_array_enable)
2749 sz *= ioc->reply_queue_count;
2750
2751 ioc->reply_post = kcalloc((ioc->rdpq_array_enable) ?
2752 (ioc->reply_queue_count):1,
2753 sizeof(struct reply_post_struct), GFP_KERNEL);
2754
2755 if (!ioc->reply_post) {
2756 pr_err(MPT3SAS_FMT "reply_post_free pool: kcalloc failed\n",
2757 ioc->name);
2758 goto out;
2759 }
2760 ioc->reply_post_free_dma_pool = pci_pool_create("reply_post_free pool",
2761 ioc->pdev, sz, 16, 0);
2762 if (!ioc->reply_post_free_dma_pool) {
2763 pr_err(MPT3SAS_FMT
2764 "reply_post_free pool: pci_pool_create failed\n",
2765 ioc->name);
2766 goto out;
2767 }
2768 i = 0;
2769 do {
2770 ioc->reply_post[i].reply_post_free =
2771 pci_pool_alloc(ioc->reply_post_free_dma_pool,
2772 GFP_KERNEL,
2773 &ioc->reply_post[i].reply_post_free_dma);
2774 if (!ioc->reply_post[i].reply_post_free) {
2775 pr_err(MPT3SAS_FMT
2776 "reply_post_free pool: pci_pool_alloc failed\n",
2777 ioc->name);
2778 goto out;
2779 }
2780 memset(ioc->reply_post[i].reply_post_free, 0, sz);
2781 dinitprintk(ioc, pr_info(MPT3SAS_FMT
2782 "reply post free pool (0x%p): depth(%d),"
2783 "element_size(%d), pool_size(%d kB)\n", ioc->name,
2784 ioc->reply_post[i].reply_post_free,
2785 ioc->reply_post_queue_depth, 8, sz/1024));
2786 dinitprintk(ioc, pr_info(MPT3SAS_FMT
2787 "reply_post_free_dma = (0x%llx)\n", ioc->name,
2788 (unsigned long long)
2789 ioc->reply_post[i].reply_post_free_dma));
2790 total_sz += sz;
2791 } while (ioc->rdpq_array_enable && (++i < ioc->reply_queue_count));
2792
2793 if (ioc->dma_mask == 64) {
2794 if (_base_change_consistent_dma_mask(ioc, ioc->pdev) != 0) {
2795 pr_warn(MPT3SAS_FMT
2796 "no suitable consistent DMA mask for %s\n",
2797 ioc->name, pci_name(ioc->pdev));
2798 goto out;
2799 }
2800 }
2801
2650 ioc->scsiio_depth = ioc->hba_queue_depth - 2802 ioc->scsiio_depth = ioc->hba_queue_depth -
2651 ioc->hi_priority_depth - ioc->internal_depth; 2803 ioc->hi_priority_depth - ioc->internal_depth;
2652 2804
@@ -2861,40 +3013,6 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc, int sleep_flag)
2861 ioc->name, (unsigned long long)ioc->reply_free_dma)); 3013 ioc->name, (unsigned long long)ioc->reply_free_dma));
2862 total_sz += sz; 3014 total_sz += sz;
2863 3015
2864 /* reply post queue, 16 byte align */
2865 reply_post_free_sz = ioc->reply_post_queue_depth *
2866 sizeof(Mpi2DefaultReplyDescriptor_t);
2867 if (_base_is_controller_msix_enabled(ioc))
2868 sz = reply_post_free_sz * ioc->reply_queue_count;
2869 else
2870 sz = reply_post_free_sz;
2871 ioc->reply_post_free_dma_pool = pci_pool_create("reply_post_free pool",
2872 ioc->pdev, sz, 16, 0);
2873 if (!ioc->reply_post_free_dma_pool) {
2874 pr_err(MPT3SAS_FMT
2875 "reply_post_free pool: pci_pool_create failed\n",
2876 ioc->name);
2877 goto out;
2878 }
2879 ioc->reply_post_free = pci_pool_alloc(ioc->reply_post_free_dma_pool ,
2880 GFP_KERNEL, &ioc->reply_post_free_dma);
2881 if (!ioc->reply_post_free) {
2882 pr_err(MPT3SAS_FMT
2883 "reply_post_free pool: pci_pool_alloc failed\n",
2884 ioc->name);
2885 goto out;
2886 }
2887 memset(ioc->reply_post_free, 0, sz);
2888 dinitprintk(ioc, pr_info(MPT3SAS_FMT "reply post free pool" \
2889 "(0x%p): depth(%d), element_size(%d), pool_size(%d kB)\n",
2890 ioc->name, ioc->reply_post_free, ioc->reply_post_queue_depth, 8,
2891 sz/1024));
2892 dinitprintk(ioc, pr_info(MPT3SAS_FMT
2893 "reply_post_free_dma = (0x%llx)\n",
2894 ioc->name, (unsigned long long)
2895 ioc->reply_post_free_dma));
2896 total_sz += sz;
2897
2898 ioc->config_page_sz = 512; 3016 ioc->config_page_sz = 512;
2899 ioc->config_page = pci_alloc_consistent(ioc->pdev, 3017 ioc->config_page = pci_alloc_consistent(ioc->pdev,
2900 ioc->config_page_sz, &ioc->config_page_dma); 3018 ioc->config_page_sz, &ioc->config_page_dma);
@@ -3577,6 +3695,9 @@ _base_get_ioc_facts(struct MPT3SAS_ADAPTER *ioc, int sleep_flag)
3577 facts->IOCCapabilities = le32_to_cpu(mpi_reply.IOCCapabilities); 3695 facts->IOCCapabilities = le32_to_cpu(mpi_reply.IOCCapabilities);
3578 if ((facts->IOCCapabilities & MPI2_IOCFACTS_CAPABILITY_INTEGRATED_RAID)) 3696 if ((facts->IOCCapabilities & MPI2_IOCFACTS_CAPABILITY_INTEGRATED_RAID))
3579 ioc->ir_firmware = 1; 3697 ioc->ir_firmware = 1;
3698 if ((facts->IOCCapabilities &
3699 MPI2_IOCFACTS_CAPABILITY_RDPQ_ARRAY_CAPABLE))
3700 ioc->rdpq_array_capable = 1;
3580 facts->FWVersion.Word = le32_to_cpu(mpi_reply.FWVersion.Word); 3701 facts->FWVersion.Word = le32_to_cpu(mpi_reply.FWVersion.Word);
3581 facts->IOCRequestFrameSize = 3702 facts->IOCRequestFrameSize =
3582 le16_to_cpu(mpi_reply.IOCRequestFrameSize); 3703 le16_to_cpu(mpi_reply.IOCRequestFrameSize);
@@ -3613,9 +3734,12 @@ _base_send_ioc_init(struct MPT3SAS_ADAPTER *ioc, int sleep_flag)
3613{ 3734{
3614 Mpi2IOCInitRequest_t mpi_request; 3735 Mpi2IOCInitRequest_t mpi_request;
3615 Mpi2IOCInitReply_t mpi_reply; 3736 Mpi2IOCInitReply_t mpi_reply;
3616 int r; 3737 int i, r = 0;
3617 struct timeval current_time; 3738 struct timeval current_time;
3618 u16 ioc_status; 3739 u16 ioc_status;
3740 u32 reply_post_free_array_sz = 0;
3741 Mpi2IOCInitRDPQArrayEntry *reply_post_free_array = NULL;
3742 dma_addr_t reply_post_free_array_dma;
3619 3743
3620 dinitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name, 3744 dinitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name,
3621 __func__)); 3745 __func__));
@@ -3644,9 +3768,31 @@ _base_send_ioc_init(struct MPT3SAS_ADAPTER *ioc, int sleep_flag)
3644 cpu_to_le64((u64)ioc->request_dma); 3768 cpu_to_le64((u64)ioc->request_dma);
3645 mpi_request.ReplyFreeQueueAddress = 3769 mpi_request.ReplyFreeQueueAddress =
3646 cpu_to_le64((u64)ioc->reply_free_dma); 3770 cpu_to_le64((u64)ioc->reply_free_dma);
3647 mpi_request.ReplyDescriptorPostQueueAddress =
3648 cpu_to_le64((u64)ioc->reply_post_free_dma);
3649 3771
3772 if (ioc->rdpq_array_enable) {
3773 reply_post_free_array_sz = ioc->reply_queue_count *
3774 sizeof(Mpi2IOCInitRDPQArrayEntry);
3775 reply_post_free_array = pci_alloc_consistent(ioc->pdev,
3776 reply_post_free_array_sz, &reply_post_free_array_dma);
3777 if (!reply_post_free_array) {
3778 pr_err(MPT3SAS_FMT
3779 "reply_post_free_array: pci_alloc_consistent failed\n",
3780 ioc->name);
3781 r = -ENOMEM;
3782 goto out;
3783 }
3784 memset(reply_post_free_array, 0, reply_post_free_array_sz);
3785 for (i = 0; i < ioc->reply_queue_count; i++)
3786 reply_post_free_array[i].RDPQBaseAddress =
3787 cpu_to_le64(
3788 (u64)ioc->reply_post[i].reply_post_free_dma);
3789 mpi_request.MsgFlags = MPI2_IOCINIT_MSGFLAG_RDPQ_ARRAY_MODE;
3790 mpi_request.ReplyDescriptorPostQueueAddress =
3791 cpu_to_le64((u64)reply_post_free_array_dma);
3792 } else {
3793 mpi_request.ReplyDescriptorPostQueueAddress =
3794 cpu_to_le64((u64)ioc->reply_post[0].reply_post_free_dma);
3795 }
3650 3796
3651 /* This time stamp specifies number of milliseconds 3797 /* This time stamp specifies number of milliseconds
3652 * since epoch ~ midnight January 1, 1970. 3798 * since epoch ~ midnight January 1, 1970.
@@ -3674,7 +3820,7 @@ _base_send_ioc_init(struct MPT3SAS_ADAPTER *ioc, int sleep_flag)
3674 if (r != 0) { 3820 if (r != 0) {
3675 pr_err(MPT3SAS_FMT "%s: handshake failed (r=%d)\n", 3821 pr_err(MPT3SAS_FMT "%s: handshake failed (r=%d)\n",
3676 ioc->name, __func__, r); 3822 ioc->name, __func__, r);
3677 return r; 3823 goto out;
3678 } 3824 }
3679 3825
3680 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK; 3826 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK;
@@ -3684,7 +3830,12 @@ _base_send_ioc_init(struct MPT3SAS_ADAPTER *ioc, int sleep_flag)
3684 r = -EIO; 3830 r = -EIO;
3685 } 3831 }
3686 3832
3687 return 0; 3833out:
3834 if (reply_post_free_array)
3835 pci_free_consistent(ioc->pdev, reply_post_free_array_sz,
3836 reply_post_free_array,
3837 reply_post_free_array_dma);
3838 return r;
3688} 3839}
3689 3840
3690/** 3841/**
@@ -4234,7 +4385,7 @@ _base_make_ioc_operational(struct MPT3SAS_ADAPTER *ioc, int sleep_flag)
4234 struct _tr_list *delayed_tr, *delayed_tr_next; 4385 struct _tr_list *delayed_tr, *delayed_tr_next;
4235 struct adapter_reply_queue *reply_q; 4386 struct adapter_reply_queue *reply_q;
4236 long reply_post_free; 4387 long reply_post_free;
4237 u32 reply_post_free_sz; 4388 u32 reply_post_free_sz, index = 0;
4238 4389
4239 dinitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name, 4390 dinitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name,
4240 __func__)); 4391 __func__));
@@ -4305,9 +4456,9 @@ _base_make_ioc_operational(struct MPT3SAS_ADAPTER *ioc, int sleep_flag)
4305 _base_assign_reply_queues(ioc); 4456 _base_assign_reply_queues(ioc);
4306 4457
4307 /* initialize Reply Post Free Queue */ 4458 /* initialize Reply Post Free Queue */
4308 reply_post_free = (long)ioc->reply_post_free;
4309 reply_post_free_sz = ioc->reply_post_queue_depth * 4459 reply_post_free_sz = ioc->reply_post_queue_depth *
4310 sizeof(Mpi2DefaultReplyDescriptor_t); 4460 sizeof(Mpi2DefaultReplyDescriptor_t);
4461 reply_post_free = (long)ioc->reply_post[index].reply_post_free;
4311 list_for_each_entry(reply_q, &ioc->reply_queue_list, list) { 4462 list_for_each_entry(reply_q, &ioc->reply_queue_list, list) {
4312 reply_q->reply_post_host_index = 0; 4463 reply_q->reply_post_host_index = 0;
4313 reply_q->reply_post_free = (Mpi2ReplyDescriptorsUnion_t *) 4464 reply_q->reply_post_free = (Mpi2ReplyDescriptorsUnion_t *)
@@ -4317,7 +4468,15 @@ _base_make_ioc_operational(struct MPT3SAS_ADAPTER *ioc, int sleep_flag)
4317 cpu_to_le64(ULLONG_MAX); 4468 cpu_to_le64(ULLONG_MAX);
4318 if (!_base_is_controller_msix_enabled(ioc)) 4469 if (!_base_is_controller_msix_enabled(ioc))
4319 goto skip_init_reply_post_free_queue; 4470 goto skip_init_reply_post_free_queue;
4320 reply_post_free += reply_post_free_sz; 4471 /*
4472 * If RDPQ is enabled, switch to the next allocation.
4473 * Otherwise advance within the contiguous region.
4474 */
4475 if (ioc->rdpq_array_enable)
4476 reply_post_free = (long)
4477 ioc->reply_post[++index].reply_post_free;
4478 else
4479 reply_post_free += reply_post_free_sz;
4321 } 4480 }
4322 skip_init_reply_post_free_queue: 4481 skip_init_reply_post_free_queue:
4323 4482
@@ -4428,6 +4587,8 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc)
4428 goto out_free_resources; 4587 goto out_free_resources;
4429 } 4588 }
4430 4589
4590 ioc->rdpq_array_enable_assigned = 0;
4591 ioc->dma_mask = 0;
4431 r = mpt3sas_base_map_resources(ioc); 4592 r = mpt3sas_base_map_resources(ioc);
4432 if (r) 4593 if (r)
4433 goto out_free_resources; 4594 goto out_free_resources;
@@ -4804,6 +4965,12 @@ mpt3sas_base_hard_reset_handler(struct MPT3SAS_ADAPTER *ioc, int sleep_flag,
4804 r = _base_get_ioc_facts(ioc, CAN_SLEEP); 4965 r = _base_get_ioc_facts(ioc, CAN_SLEEP);
4805 if (r) 4966 if (r)
4806 goto out; 4967 goto out;
4968
4969 if (ioc->rdpq_array_enable && !ioc->rdpq_array_capable)
4970 panic("%s: Issue occurred with flashing controller firmware."
4971 "Please reboot the system and ensure that the correct"
4972 " firmware version is running\n", ioc->name);
4973
4807 r = _base_make_ioc_operational(ioc, sleep_flag); 4974 r = _base_make_ioc_operational(ioc, sleep_flag);
4808 if (!r) 4975 if (!r)
4809 _base_reset_handler(ioc, MPT3_IOC_DONE_RESET); 4976 _base_reset_handler(ioc, MPT3_IOC_DONE_RESET);