aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSreekanth Reddy <sreekanth.reddy@avagotech.com>2014-09-12 06:05:22 -0400
committerChristoph Hellwig <hch@lst.de>2014-09-16 12:14:16 -0400
commit5fb1bf8aaa832e1e9ca3198de7bbecb8eff7db9c (patch)
tree251f8823dd8a8bbccd84d0844ce582b182d42bcd
parentdaeaa9df92bd742f4e6d4d6039d689277a8e31bd (diff)
mpt2sas: Added Reply Descriptor Post Queue (RDPQ) Array support
Up to now, Driver allocates a single contiguous block of memory pool for all reply queues and passes down a single address in the ReplyDescriptorPostQueueAddress field of the IOC Init Request Message to the firmware. When firmware receives this address, it will program each of the Reply Descriptor Post Queue registers, as each reply queue has its own register. Thus the firmware, starting from a base address it determines the starting address of the subsequent reply queues through some simple arithmetic calculations. The size of this contiguous block of memory pool is directly proportional to number of MSI-X vectors and the HBA queue depth. For example higher MSIX vectors requires larger contiguous block of memory pool. But some of the OS kernels are unable to allocate this larger contiguous block of memory pool. So, the proposal is to allocate memory independently for each Reply Queue and pass down all of the addresses to the firmware. Then the firmware will just take each address and program the value into the correct register. When HBAs with older firmware(i.e. without RDPQ capability) is used with this new driver then the max_msix_vectors value would be set to 8 by default. Change_set in v1: 1. Declared _base_get_ioc_facts() function at the beginning of the mpt2sas_base.c file instead of moving all these functions before mpt2sas_base_map_resources() function a. _base_wait_for_doorbell_int() b. _base_wait_for_doorbell_ack() c. _base_wait_for_doorbell_not_used() d. _base_handshake_req_reply_wait() e. _base_get_ioc_facts() 2. Initially set the consistent DMA mask to 32 bit and then change it to 64 bit mask after allocating RDPQ pools by calling the function _base_change_consistent_dma_mask. This is to ensure that all the upper 32 bits of RDPQ entries's base address to be same. 3. Reduced the redundancy between the RDPQ and non-RDPQ support in these following functions a. _base_release_memory_pools() b. _base_allocate_memory_pools() c. _base_send_ioc_init() d. _base_make_ioc_operational() Signed-off-by: Sreekanth Reddy <Sreekanth.Reddy@avagotech.com> Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com> Signed-off-by: Christoph Hellwig <hch@lst.de>
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_base.c240
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_base.h20
2 files changed, 199 insertions, 61 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;
92module_param(disable_discovery, int, 0); 92module_param(disable_discovery, int, 0);
93MODULE_PARM_DESC(disable_discovery, " disable discovery "); 93MODULE_PARM_DESC(disable_discovery, " disable discovery ");
94 94
95static 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
1222static 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)
2331static void 2365static 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; 3646out:
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);
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.h b/drivers/scsi/mpt2sas/mpt2sas_base.h
index e0e4dd48e9dc..9bc8e0b915b8 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_base.h
+++ b/drivers/scsi/mpt2sas/mpt2sas_base.h
@@ -636,6 +636,11 @@ struct mpt2sas_port_facts {
636 u16 MaxPostedCmdBuffers; 636 u16 MaxPostedCmdBuffers;
637}; 637};
638 638
639struct reply_post_struct {
640 Mpi2ReplyDescriptorsUnion_t *reply_post_free;
641 dma_addr_t reply_post_free_dma;
642};
643
639/** 644/**
640 * enum mutex_type - task management mutex type 645 * enum mutex_type - task management mutex type
641 * @TM_MUTEX_OFF: mutex is not required becuase calling function is acquiring it 646 * @TM_MUTEX_OFF: mutex is not required becuase calling function is acquiring it
@@ -663,6 +668,7 @@ typedef void (*MPT2SAS_FLUSH_RUNNING_CMDS)(struct MPT2SAS_ADAPTER *ioc);
663 * @ir_firmware: IR firmware present 668 * @ir_firmware: IR firmware present
664 * @bars: bitmask of BAR's that must be configured 669 * @bars: bitmask of BAR's that must be configured
665 * @mask_interrupts: ignore interrupt 670 * @mask_interrupts: ignore interrupt
671 * @dma_mask: used to set the consistent dma mask
666 * @fault_reset_work_q_name: fw fault work queue 672 * @fault_reset_work_q_name: fw fault work queue
667 * @fault_reset_work_q: "" 673 * @fault_reset_work_q: ""
668 * @fault_reset_work: "" 674 * @fault_reset_work: ""
@@ -779,8 +785,11 @@ typedef void (*MPT2SAS_FLUSH_RUNNING_CMDS)(struct MPT2SAS_ADAPTER *ioc);
779 * @reply_free_dma_pool: 785 * @reply_free_dma_pool:
780 * @reply_free_host_index: tail index in pool to insert free replys 786 * @reply_free_host_index: tail index in pool to insert free replys
781 * @reply_post_queue_depth: reply post queue depth 787 * @reply_post_queue_depth: reply post queue depth
782 * @reply_post_free: pool for reply post (64bit descriptor) 788 * @reply_post_struct: struct for reply_post_free physical & virt address
783 * @reply_post_free_dma: 789 * @rdpq_array_capable: FW supports multiple reply queue addresses in ioc_init
790 * @rdpq_array_enable: rdpq_array support is enabled in the driver
791 * @rdpq_array_enable_assigned: this ensures that rdpq_array_enable flag
792 * is assigned only ones
784 * @reply_queue_count: number of reply queue's 793 * @reply_queue_count: number of reply queue's
785 * @reply_queue_list: link list contaning the reply queue info 794 * @reply_queue_list: link list contaning the reply queue info
786 * @reply_post_host_index: head index in the pool where FW completes IO 795 * @reply_post_host_index: head index in the pool where FW completes IO
@@ -802,6 +811,7 @@ struct MPT2SAS_ADAPTER {
802 u8 ir_firmware; 811 u8 ir_firmware;
803 int bars; 812 int bars;
804 u8 mask_interrupts; 813 u8 mask_interrupts;
814 int dma_mask;
805 815
806 /* fw fault handler */ 816 /* fw fault handler */
807 char fault_reset_work_q_name[20]; 817 char fault_reset_work_q_name[20];
@@ -972,8 +982,10 @@ struct MPT2SAS_ADAPTER {
972 982
973 /* reply post queue */ 983 /* reply post queue */
974 u16 reply_post_queue_depth; 984 u16 reply_post_queue_depth;
975 Mpi2ReplyDescriptorsUnion_t *reply_post_free; 985 struct reply_post_struct *reply_post;
976 dma_addr_t reply_post_free_dma; 986 u8 rdpq_array_capable;
987 u8 rdpq_array_enable;
988 u8 rdpq_array_enable_assigned;
977 struct dma_pool *reply_post_free_dma_pool; 989 struct dma_pool *reply_post_free_dma_pool;
978 u8 reply_queue_count; 990 u8 reply_queue_count;
979 struct list_head reply_queue_list; 991 struct list_head reply_queue_list;