@@ -91,10 +91,12 @@ struct pci_endpoint_test {
9191 struct mutex mutex ;
9292 struct miscdevice miscdev ;
9393 enum pci_barno test_reg_bar ;
94+ size_t alignment ;
9495};
9596
9697struct pci_endpoint_test_data {
9798 enum pci_barno test_reg_bar ;
99+ size_t alignment ;
98100};
99101
100102static int bar_size [] = { 512 , 512 , 1024 , 16384 , 131072 , 1048576 };
@@ -210,16 +212,32 @@ static bool pci_endpoint_test_copy(struct pci_endpoint_test *test, size_t size)
210212 dma_addr_t dst_phys_addr ;
211213 struct pci_dev * pdev = test -> pdev ;
212214 struct device * dev = & pdev -> dev ;
215+ void * orig_src_addr ;
216+ dma_addr_t orig_src_phys_addr ;
217+ void * orig_dst_addr ;
218+ dma_addr_t orig_dst_phys_addr ;
219+ size_t offset ;
220+ size_t alignment = test -> alignment ;
213221 u32 src_crc32 ;
214222 u32 dst_crc32 ;
215223
216- src_addr = dma_alloc_coherent (dev , size , & src_phys_addr , GFP_KERNEL );
217- if (!src_addr ) {
224+ orig_src_addr = dma_alloc_coherent (dev , size + alignment ,
225+ & orig_src_phys_addr , GFP_KERNEL );
226+ if (!orig_src_addr ) {
218227 dev_err (dev , "failed to allocate source buffer\n" );
219228 ret = false;
220229 goto err ;
221230 }
222231
232+ if (alignment && !IS_ALIGNED (orig_src_phys_addr , alignment )) {
233+ src_phys_addr = PTR_ALIGN (orig_src_phys_addr , alignment );
234+ offset = src_phys_addr - orig_src_phys_addr ;
235+ src_addr = orig_src_addr + offset ;
236+ } else {
237+ src_phys_addr = orig_src_phys_addr ;
238+ src_addr = orig_src_addr ;
239+ }
240+
223241 pci_endpoint_test_writel (test , PCI_ENDPOINT_TEST_LOWER_SRC_ADDR ,
224242 lower_32_bits (src_phys_addr ));
225243
@@ -229,11 +247,21 @@ static bool pci_endpoint_test_copy(struct pci_endpoint_test *test, size_t size)
229247 get_random_bytes (src_addr , size );
230248 src_crc32 = crc32_le (~0 , src_addr , size );
231249
232- dst_addr = dma_alloc_coherent (dev , size , & dst_phys_addr , GFP_KERNEL );
233- if (!dst_addr ) {
250+ orig_dst_addr = dma_alloc_coherent (dev , size + alignment ,
251+ & orig_dst_phys_addr , GFP_KERNEL );
252+ if (!orig_dst_addr ) {
234253 dev_err (dev , "failed to allocate destination address\n" );
235254 ret = false;
236- goto err_src_addr ;
255+ goto err_orig_src_addr ;
256+ }
257+
258+ if (alignment && !IS_ALIGNED (orig_dst_phys_addr , alignment )) {
259+ dst_phys_addr = PTR_ALIGN (orig_dst_phys_addr , alignment );
260+ offset = dst_phys_addr - orig_dst_phys_addr ;
261+ dst_addr = orig_dst_addr + offset ;
262+ } else {
263+ dst_phys_addr = orig_dst_phys_addr ;
264+ dst_addr = orig_dst_addr ;
237265 }
238266
239267 pci_endpoint_test_writel (test , PCI_ENDPOINT_TEST_LOWER_DST_ADDR ,
@@ -253,10 +281,12 @@ static bool pci_endpoint_test_copy(struct pci_endpoint_test *test, size_t size)
253281 if (dst_crc32 == src_crc32 )
254282 ret = true;
255283
256- dma_free_coherent (dev , size , dst_addr , dst_phys_addr );
284+ dma_free_coherent (dev , size + alignment , orig_dst_addr ,
285+ orig_dst_phys_addr );
257286
258- err_src_addr :
259- dma_free_coherent (dev , size , src_addr , src_phys_addr );
287+ err_orig_src_addr :
288+ dma_free_coherent (dev , size + alignment , orig_src_addr ,
289+ orig_src_phys_addr );
260290
261291err :
262292 return ret ;
@@ -270,15 +300,29 @@ static bool pci_endpoint_test_write(struct pci_endpoint_test *test, size_t size)
270300 dma_addr_t phys_addr ;
271301 struct pci_dev * pdev = test -> pdev ;
272302 struct device * dev = & pdev -> dev ;
303+ void * orig_addr ;
304+ dma_addr_t orig_phys_addr ;
305+ size_t offset ;
306+ size_t alignment = test -> alignment ;
273307 u32 crc32 ;
274308
275- addr = dma_alloc_coherent (dev , size , & phys_addr , GFP_KERNEL );
276- if (!addr ) {
309+ orig_addr = dma_alloc_coherent (dev , size + alignment , & orig_phys_addr ,
310+ GFP_KERNEL );
311+ if (!orig_addr ) {
277312 dev_err (dev , "failed to allocate address\n" );
278313 ret = false;
279314 goto err ;
280315 }
281316
317+ if (alignment && !IS_ALIGNED (orig_phys_addr , alignment )) {
318+ phys_addr = PTR_ALIGN (orig_phys_addr , alignment );
319+ offset = phys_addr - orig_phys_addr ;
320+ addr = orig_addr + offset ;
321+ } else {
322+ phys_addr = orig_phys_addr ;
323+ addr = orig_addr ;
324+ }
325+
282326 get_random_bytes (addr , size );
283327
284328 crc32 = crc32_le (~0 , addr , size );
@@ -301,7 +345,7 @@ static bool pci_endpoint_test_write(struct pci_endpoint_test *test, size_t size)
301345 if (reg & STATUS_READ_SUCCESS )
302346 ret = true;
303347
304- dma_free_coherent (dev , size , addr , phys_addr );
348+ dma_free_coherent (dev , size + alignment , orig_addr , orig_phys_addr );
305349
306350err :
307351 return ret ;
@@ -314,15 +358,29 @@ static bool pci_endpoint_test_read(struct pci_endpoint_test *test, size_t size)
314358 dma_addr_t phys_addr ;
315359 struct pci_dev * pdev = test -> pdev ;
316360 struct device * dev = & pdev -> dev ;
361+ void * orig_addr ;
362+ dma_addr_t orig_phys_addr ;
363+ size_t offset ;
364+ size_t alignment = test -> alignment ;
317365 u32 crc32 ;
318366
319- addr = dma_alloc_coherent (dev , size , & phys_addr , GFP_KERNEL );
320- if (!addr ) {
367+ orig_addr = dma_alloc_coherent (dev , size + alignment , & orig_phys_addr ,
368+ GFP_KERNEL );
369+ if (!orig_addr ) {
321370 dev_err (dev , "failed to allocate destination address\n" );
322371 ret = false;
323372 goto err ;
324373 }
325374
375+ if (alignment && !IS_ALIGNED (orig_phys_addr , alignment )) {
376+ phys_addr = PTR_ALIGN (orig_phys_addr , alignment );
377+ offset = phys_addr - orig_phys_addr ;
378+ addr = orig_addr + offset ;
379+ } else {
380+ phys_addr = orig_phys_addr ;
381+ addr = orig_addr ;
382+ }
383+
326384 pci_endpoint_test_writel (test , PCI_ENDPOINT_TEST_LOWER_DST_ADDR ,
327385 lower_32_bits (phys_addr ));
328386 pci_endpoint_test_writel (test , PCI_ENDPOINT_TEST_UPPER_DST_ADDR ,
@@ -339,7 +397,7 @@ static bool pci_endpoint_test_read(struct pci_endpoint_test *test, size_t size)
339397 if (crc32 == pci_endpoint_test_readl (test , PCI_ENDPOINT_TEST_CHECKSUM ))
340398 ret = true;
341399
342- dma_free_coherent (dev , size , addr , phys_addr );
400+ dma_free_coherent (dev , size + alignment , orig_addr , orig_phys_addr );
343401err :
344402 return ret ;
345403}
@@ -410,11 +468,14 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev,
410468 return - ENOMEM ;
411469
412470 test -> test_reg_bar = 0 ;
471+ test -> alignment = 0 ;
413472 test -> pdev = pdev ;
414473
415474 data = (struct pci_endpoint_test_data * )ent -> driver_data ;
416- if (data )
475+ if (data ) {
417476 test_reg_bar = data -> test_reg_bar ;
477+ test -> alignment = data -> alignment ;
478+ }
418479
419480 init_completion (& test -> irq_raised );
420481 mutex_init (& test -> mutex );
0 commit comments