@@ -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
@@ -4950,36 +4955,75 @@ mpt3sas_check_same_4gb_region(long reply_pool_start_address, u32 pool_sz)
49504955static int
49514956base_alloc_rdpq_dma_pool (struct MPT3SAS_ADAPTER * ioc , int sz )
49524957{
4953- int i ;
4958+ int i = 0 ;
4959+ u32 dma_alloc_count = 0 ;
4960+ int reply_post_free_sz = ioc -> reply_post_queue_depth *
4961+ sizeof (Mpi2DefaultReplyDescriptor_t );
49544962 int count = ioc -> rdpq_array_enable ? ioc -> reply_queue_count : 1 ;
49554963
49564964 ioc -> reply_post = kcalloc (count , sizeof (struct reply_post_struct ),
49574965 GFP_KERNEL );
49584966 if (!ioc -> reply_post )
49594967 return - ENOMEM ;
4968+ /*
4969+ * For INVADER_SERIES each set of 8 reply queues(0-7, 8-15, ..) and
4970+ * VENTURA_SERIES each set of 16 reply queues(0-15, 16-31, ..) should
4971+ * be within 4GB boundary i.e reply queues in a set must have same
4972+ * upper 32-bits in their memory address. so here driver is allocating
4973+ * the DMA'able memory for reply queues according.
4974+ * Driver uses limitation of
4975+ * VENTURA_SERIES to manage INVADER_SERIES as well.
4976+ */
4977+ dma_alloc_count = DIV_ROUND_UP (ioc -> reply_queue_count ,
4978+ RDPQ_MAX_INDEX_IN_ONE_CHUNK );
49604979 ioc -> reply_post_free_dma_pool =
4961- dma_pool_create ("reply_post_free pool" ,
4962- & ioc -> pdev -> dev , sz , 16 , 0 );
4980+ dma_pool_create ("reply_post_free pool" ,
4981+ & ioc -> pdev -> dev , sz , 16 , 0 );
49634982 if (!ioc -> reply_post_free_dma_pool )
49644983 return - ENOMEM ;
4965- i = 0 ;
4966- do {
4967- ioc -> reply_post [i ].reply_post_free =
4968- dma_pool_zalloc (ioc -> reply_post_free_dma_pool ,
4969- GFP_KERNEL ,
4970- & ioc -> reply_post [i ].reply_post_free_dma );
4971- if (!ioc -> reply_post [i ].reply_post_free )
4972- return - ENOMEM ;
4973- dinitprintk (ioc ,
4974- ioc_info (ioc , "reply post free pool (0x%p): depth(%d),"
4975- "element_size(%d), pool_size(%d kB)\n" ,
4976- ioc -> reply_post [i ].reply_post_free ,
4977- ioc -> reply_post_queue_depth , 8 , sz / 1024 ));
4978- dinitprintk (ioc ,
4979- ioc_info (ioc , "reply_post_free_dma = (0x%llx)\n" ,
4980- (u64 )ioc -> reply_post [i ].reply_post_free_dma ));
4984+ for (i = 0 ; i < ioc -> reply_queue_count ; i ++ ) {
4985+ if ((i % RDPQ_MAX_INDEX_IN_ONE_CHUNK == 0 ) && dma_alloc_count ) {
4986+ ioc -> reply_post [i ].reply_post_free =
4987+ dma_pool_alloc (ioc -> reply_post_free_dma_pool ,
4988+ GFP_KERNEL ,
4989+ & ioc -> reply_post [i ].reply_post_free_dma );
4990+ if (!ioc -> reply_post [i ].reply_post_free )
4991+ return - ENOMEM ;
4992+ /*
4993+ * Each set of RDPQ pool must satisfy 4gb boundary
4994+ * restriction.
4995+ * 1) Check if allocated resources for RDPQ pool are in
4996+ * the same 4GB range.
4997+ * 2) If #1 is true, continue with 64 bit DMA.
4998+ * 3) If #1 is false, return 1. which means free all the
4999+ * resources and set DMA mask to 32 and allocate.
5000+ */
5001+ if (!mpt3sas_check_same_4gb_region (
5002+ (long )ioc -> reply_post [i ].reply_post_free , sz )) {
5003+ dinitprintk (ioc ,
5004+ ioc_err (ioc , "bad Replypost free pool(0x%p)"
5005+ "reply_post_free_dma = (0x%llx)\n" ,
5006+ ioc -> reply_post [i ].reply_post_free ,
5007+ (unsigned long long )
5008+ ioc -> reply_post [i ].reply_post_free_dma ));
5009+ return - EAGAIN ;
5010+ }
5011+ memset (ioc -> reply_post [i ].reply_post_free , 0 ,
5012+ RDPQ_MAX_INDEX_IN_ONE_CHUNK *
5013+ reply_post_free_sz );
5014+ dma_alloc_count -- ;
49815015
4982- } while (ioc -> rdpq_array_enable && ++ i < ioc -> reply_queue_count );
5016+ } else {
5017+ ioc -> reply_post [i ].reply_post_free =
5018+ (Mpi2ReplyDescriptorsUnion_t * )
5019+ ((long )ioc -> reply_post [i - 1 ].reply_post_free
5020+ + reply_post_free_sz );
5021+ ioc -> reply_post [i ].reply_post_free_dma =
5022+ (dma_addr_t )
5023+ (ioc -> reply_post [i - 1 ].reply_post_free_dma +
5024+ reply_post_free_sz );
5025+ }
5026+ }
49835027 return 0 ;
49845028}
49855029
@@ -4997,10 +5041,12 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc)
49975041 u16 chains_needed_per_io ;
49985042 u32 sz , total_sz , reply_post_free_sz , reply_post_free_array_sz ;
49995043 u32 retry_sz ;
5044+ u32 rdpq_sz = 0 ;
50005045 u16 max_request_credit , nvme_blocks_needed ;
50015046 unsigned short sg_tablesize ;
50025047 u16 sge_size ;
50035048 int i , j ;
5049+ int ret = 0 ;
50045050 struct chain_tracker * ct ;
50055051
50065052 dinitprintk (ioc , ioc_info (ioc , "%s\n" , __func__ ));
@@ -5154,14 +5200,28 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc)
51545200 /* reply post queue, 16 byte align */
51555201 reply_post_free_sz = ioc -> reply_post_queue_depth *
51565202 sizeof (Mpi2DefaultReplyDescriptor_t );
5157-
5158- sz = reply_post_free_sz ;
5203+ rdpq_sz = reply_post_free_sz * RDPQ_MAX_INDEX_IN_ONE_CHUNK ;
51595204 if (_base_is_controller_msix_enabled (ioc ) && !ioc -> rdpq_array_enable )
5160- sz *= ioc -> reply_queue_count ;
5161- if (base_alloc_rdpq_dma_pool (ioc , sz ))
5162- goto out ;
5163- total_sz += sz * (!ioc -> rdpq_array_enable ? 1 : ioc -> reply_queue_count );
5164-
5205+ rdpq_sz = reply_post_free_sz * ioc -> reply_queue_count ;
5206+ ret = base_alloc_rdpq_dma_pool (ioc , rdpq_sz );
5207+ if (ret == - EAGAIN ) {
5208+ /*
5209+ * Free allocated bad RDPQ memory pools.
5210+ * Change dma coherent mask to 32 bit and reallocate RDPQ
5211+ */
5212+ _base_release_memory_pools (ioc );
5213+ ioc -> use_32bit_dma = true;
5214+ if (_base_config_dma_addressing (ioc , ioc -> pdev ) != 0 ) {
5215+ ioc_err (ioc ,
5216+ "32 DMA mask failed %s\n" , pci_name (ioc -> pdev ));
5217+ return - ENODEV ;
5218+ }
5219+ if (base_alloc_rdpq_dma_pool (ioc , rdpq_sz ))
5220+ return - ENOMEM ;
5221+ } else if (ret == - ENOMEM )
5222+ return - ENOMEM ;
5223+ total_sz = rdpq_sz * (!ioc -> rdpq_array_enable ? 1 :
5224+ DIV_ROUND_UP (ioc -> reply_queue_count , RDPQ_MAX_INDEX_IN_ONE_CHUNK ));
51655225 ioc -> scsiio_depth = ioc -> hba_queue_depth -
51665226 ioc -> hi_priority_depth - ioc -> internal_depth ;
51675227
@@ -5173,7 +5233,6 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc)
51735233 ioc_info (ioc , "scsi host: can_queue depth (%d)\n" ,
51745234 ioc -> shost -> can_queue ));
51755235
5176-
51775236 /* contiguous pool for request and chains, 16 byte align, one extra "
51785237 * "frame for smid=0
51795238 */
@@ -7143,6 +7202,7 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc)
71437202 ioc -> smp_affinity_enable = smp_affinity_enable ;
71447203
71457204 ioc -> rdpq_array_enable_assigned = 0 ;
7205+ ioc -> use_32bit_dma = 0 ;
71467206 if (ioc -> is_aero_ioc )
71477207 ioc -> base_readl = & _base_readl_aero ;
71487208 else
0 commit comments