@@ -2810,7 +2810,7 @@ _base_config_dma_addressing(struct MPT3SAS_ADAPTER *ioc, struct pci_dev *pdev)
28102810 int dma_mask ;
28112811
28122812 if (ioc -> is_mcpu_endpoint ||
2813- sizeof (dma_addr_t ) == 4 ||
2813+ sizeof (dma_addr_t ) == 4 || ioc -> use_32bit_dma ||
28142814 dma_get_required_mask (& pdev -> dev ) <= 32 )
28152815 dma_mask = 32 ;
28162816 /* Set 63 bit DMA mask for all SAS3 and SAS35 controllers */
@@ -4807,8 +4807,8 @@ _base_release_memory_pools(struct MPT3SAS_ADAPTER *ioc)
48074807{
48084808 int i = 0 ;
48094809 int j = 0 ;
4810+ int dma_alloc_count = 0 ;
48104811 struct chain_tracker * ct ;
4811- struct reply_post_struct * rps ;
48124812
48134813 dexitprintk (ioc , ioc_info (ioc , "%s\n" , __func__ ));
48144814
@@ -4850,29 +4850,34 @@ _base_release_memory_pools(struct MPT3SAS_ADAPTER *ioc)
48504850 }
48514851
48524852 if (ioc -> reply_post ) {
4853- do {
4854- rps = & ioc -> reply_post [i ];
4855- if (rps -> reply_post_free ) {
4856- dma_pool_free (
4857- ioc -> reply_post_free_dma_pool ,
4858- rps -> reply_post_free ,
4859- rps -> reply_post_free_dma );
4860- dexitprintk (ioc ,
4861- ioc_info (ioc , "reply_post_free_pool(0x%p): free\n" ,
4862- rps -> reply_post_free ));
4863- rps -> reply_post_free = NULL ;
4853+ dma_alloc_count = DIV_ROUND_UP (ioc -> reply_queue_count ,
4854+ RDPQ_MAX_INDEX_IN_ONE_CHUNK );
4855+ for (i = 0 ; i < ioc -> reply_queue_count ; i ++ ) {
4856+ if (i % RDPQ_MAX_INDEX_IN_ONE_CHUNK == 0
4857+ && dma_alloc_count ) {
4858+ if (ioc -> reply_post [i ].reply_post_free ) {
4859+ dma_pool_free (
4860+ ioc -> reply_post_free_dma_pool ,
4861+ ioc -> reply_post [i ].reply_post_free ,
4862+ ioc -> reply_post [i ].reply_post_free_dma );
4863+ dexitprintk (ioc , ioc_info (ioc ,
4864+ "reply_post_free_pool(0x%p): free\n" ,
4865+ ioc -> reply_post [i ].reply_post_free ));
4866+ ioc -> reply_post [i ].reply_post_free =
4867+ NULL ;
4868+ }
4869+ -- dma_alloc_count ;
48644870 }
4865- } while ( ioc -> rdpq_array_enable &&
4866- ( ++ i < ioc -> reply_queue_count ) );
4871+ }
4872+ dma_pool_destroy ( ioc -> reply_post_free_dma_pool );
48674873 if (ioc -> reply_post_free_array &&
48684874 ioc -> rdpq_array_enable ) {
48694875 dma_pool_free (ioc -> reply_post_free_array_dma_pool ,
4870- ioc -> reply_post_free_array ,
4871- ioc -> reply_post_free_array_dma );
4876+ ioc -> reply_post_free_array ,
4877+ ioc -> reply_post_free_array_dma );
48724878 ioc -> reply_post_free_array = NULL ;
48734879 }
48744880 dma_pool_destroy (ioc -> reply_post_free_array_dma_pool );
4875- dma_pool_destroy (ioc -> reply_post_free_dma_pool );
48764881 kfree (ioc -> reply_post );
48774882 }
48784883
@@ -4948,36 +4953,75 @@ mpt3sas_check_same_4gb_region(long reply_pool_start_address, u32 pool_sz)
49484953static int
49494954base_alloc_rdpq_dma_pool (struct MPT3SAS_ADAPTER * ioc , int sz )
49504955{
4951- int i ;
4956+ int i = 0 ;
4957+ u32 dma_alloc_count = 0 ;
4958+ int reply_post_free_sz = ioc -> reply_post_queue_depth *
4959+ sizeof (Mpi2DefaultReplyDescriptor_t );
49524960 int count = ioc -> rdpq_array_enable ? ioc -> reply_queue_count : 1 ;
49534961
49544962 ioc -> reply_post = kcalloc (count , sizeof (struct reply_post_struct ),
49554963 GFP_KERNEL );
49564964 if (!ioc -> reply_post )
49574965 return - ENOMEM ;
4966+ /*
4967+ * For INVADER_SERIES each set of 8 reply queues(0-7, 8-15, ..) and
4968+ * VENTURA_SERIES each set of 16 reply queues(0-15, 16-31, ..) should
4969+ * be within 4GB boundary i.e reply queues in a set must have same
4970+ * upper 32-bits in their memory address. so here driver is allocating
4971+ * the DMA'able memory for reply queues according.
4972+ * Driver uses limitation of
4973+ * VENTURA_SERIES to manage INVADER_SERIES as well.
4974+ */
4975+ dma_alloc_count = DIV_ROUND_UP (ioc -> reply_queue_count ,
4976+ RDPQ_MAX_INDEX_IN_ONE_CHUNK );
49584977 ioc -> reply_post_free_dma_pool =
4959- dma_pool_create ("reply_post_free pool" ,
4960- & ioc -> pdev -> dev , sz , 16 , 0 );
4978+ dma_pool_create ("reply_post_free pool" ,
4979+ & ioc -> pdev -> dev , sz , 16 , 0 );
49614980 if (!ioc -> reply_post_free_dma_pool )
49624981 return - ENOMEM ;
4963- i = 0 ;
4964- do {
4965- ioc -> reply_post [i ].reply_post_free =
4966- dma_pool_zalloc (ioc -> reply_post_free_dma_pool ,
4967- GFP_KERNEL ,
4968- & ioc -> reply_post [i ].reply_post_free_dma );
4969- if (!ioc -> reply_post [i ].reply_post_free )
4970- return - ENOMEM ;
4971- dinitprintk (ioc ,
4972- ioc_info (ioc , "reply post free pool (0x%p): depth(%d),"
4973- "element_size(%d), pool_size(%d kB)\n" ,
4974- ioc -> reply_post [i ].reply_post_free ,
4975- ioc -> reply_post_queue_depth , 8 , sz / 1024 ));
4976- dinitprintk (ioc ,
4977- ioc_info (ioc , "reply_post_free_dma = (0x%llx)\n" ,
4978- (u64 )ioc -> reply_post [i ].reply_post_free_dma ));
4982+ for (i = 0 ; i < ioc -> reply_queue_count ; i ++ ) {
4983+ if ((i % RDPQ_MAX_INDEX_IN_ONE_CHUNK == 0 ) && dma_alloc_count ) {
4984+ ioc -> reply_post [i ].reply_post_free =
4985+ dma_pool_alloc (ioc -> reply_post_free_dma_pool ,
4986+ GFP_KERNEL ,
4987+ & ioc -> reply_post [i ].reply_post_free_dma );
4988+ if (!ioc -> reply_post [i ].reply_post_free )
4989+ return - ENOMEM ;
4990+ /*
4991+ * Each set of RDPQ pool must satisfy 4gb boundary
4992+ * restriction.
4993+ * 1) Check if allocated resources for RDPQ pool are in
4994+ * the same 4GB range.
4995+ * 2) If #1 is true, continue with 64 bit DMA.
4996+ * 3) If #1 is false, return 1. which means free all the
4997+ * resources and set DMA mask to 32 and allocate.
4998+ */
4999+ if (!mpt3sas_check_same_4gb_region (
5000+ (long )ioc -> reply_post [i ].reply_post_free , sz )) {
5001+ dinitprintk (ioc ,
5002+ ioc_err (ioc , "bad Replypost free pool(0x%p)"
5003+ "reply_post_free_dma = (0x%llx)\n" ,
5004+ ioc -> reply_post [i ].reply_post_free ,
5005+ (unsigned long long )
5006+ ioc -> reply_post [i ].reply_post_free_dma ));
5007+ return - EAGAIN ;
5008+ }
5009+ memset (ioc -> reply_post [i ].reply_post_free , 0 ,
5010+ RDPQ_MAX_INDEX_IN_ONE_CHUNK *
5011+ reply_post_free_sz );
5012+ dma_alloc_count -- ;
49795013
4980- } while (ioc -> rdpq_array_enable && ++ i < ioc -> reply_queue_count );
5014+ } else {
5015+ ioc -> reply_post [i ].reply_post_free =
5016+ (Mpi2ReplyDescriptorsUnion_t * )
5017+ ((long )ioc -> reply_post [i - 1 ].reply_post_free
5018+ + reply_post_free_sz );
5019+ ioc -> reply_post [i ].reply_post_free_dma =
5020+ (dma_addr_t )
5021+ (ioc -> reply_post [i - 1 ].reply_post_free_dma +
5022+ reply_post_free_sz );
5023+ }
5024+ }
49815025 return 0 ;
49825026}
49835027
@@ -4995,10 +5039,12 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc)
49955039 u16 chains_needed_per_io ;
49965040 u32 sz , total_sz , reply_post_free_sz , reply_post_free_array_sz ;
49975041 u32 retry_sz ;
5042+ u32 rdpq_sz = 0 ;
49985043 u16 max_request_credit , nvme_blocks_needed ;
49995044 unsigned short sg_tablesize ;
50005045 u16 sge_size ;
50015046 int i , j ;
5047+ int ret = 0 ;
50025048 struct chain_tracker * ct ;
50035049
50045050 dinitprintk (ioc , ioc_info (ioc , "%s\n" , __func__ ));
@@ -5152,14 +5198,28 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc)
51525198 /* reply post queue, 16 byte align */
51535199 reply_post_free_sz = ioc -> reply_post_queue_depth *
51545200 sizeof (Mpi2DefaultReplyDescriptor_t );
5155-
5156- sz = reply_post_free_sz ;
5201+ rdpq_sz = reply_post_free_sz * RDPQ_MAX_INDEX_IN_ONE_CHUNK ;
51575202 if (_base_is_controller_msix_enabled (ioc ) && !ioc -> rdpq_array_enable )
5158- sz *= ioc -> reply_queue_count ;
5159- if (base_alloc_rdpq_dma_pool (ioc , sz ))
5160- goto out ;
5161- total_sz += sz * (!ioc -> rdpq_array_enable ? 1 : ioc -> reply_queue_count );
5162-
5203+ rdpq_sz = reply_post_free_sz * ioc -> reply_queue_count ;
5204+ ret = base_alloc_rdpq_dma_pool (ioc , rdpq_sz );
5205+ if (ret == - EAGAIN ) {
5206+ /*
5207+ * Free allocated bad RDPQ memory pools.
5208+ * Change dma coherent mask to 32 bit and reallocate RDPQ
5209+ */
5210+ _base_release_memory_pools (ioc );
5211+ ioc -> use_32bit_dma = true;
5212+ if (_base_config_dma_addressing (ioc , ioc -> pdev ) != 0 ) {
5213+ ioc_err (ioc ,
5214+ "32 DMA mask failed %s\n" , pci_name (ioc -> pdev ));
5215+ return - ENODEV ;
5216+ }
5217+ if (base_alloc_rdpq_dma_pool (ioc , rdpq_sz ))
5218+ return - ENOMEM ;
5219+ } else if (ret == - ENOMEM )
5220+ return - ENOMEM ;
5221+ total_sz = rdpq_sz * (!ioc -> rdpq_array_enable ? 1 :
5222+ DIV_ROUND_UP (ioc -> reply_queue_count , RDPQ_MAX_INDEX_IN_ONE_CHUNK ));
51635223 ioc -> scsiio_depth = ioc -> hba_queue_depth -
51645224 ioc -> hi_priority_depth - ioc -> internal_depth ;
51655225
@@ -5171,7 +5231,6 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc)
51715231 ioc_info (ioc , "scsi host: can_queue depth (%d)\n" ,
51725232 ioc -> shost -> can_queue ));
51735233
5174-
51755234 /* contiguous pool for request and chains, 16 byte align, one extra "
51765235 * "frame for smid=0
51775236 */
@@ -7141,6 +7200,7 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc)
71417200 ioc -> smp_affinity_enable = smp_affinity_enable ;
71427201
71437202 ioc -> rdpq_array_enable_assigned = 0 ;
7203+ ioc -> use_32bit_dma = 0 ;
71447204 if (ioc -> is_aero_ioc )
71457205 ioc -> base_readl = & _base_readl_aero ;
71467206 else
0 commit comments