aboutsummaryrefslogtreecommitdiffstats
path: root/Documentation/DMA-API-HOWTO.txt
diff options
context:
space:
mode:
authorShuah Khan <shuah.khan@hp.com>2012-10-18 16:00:58 -0400
committerJoerg Roedel <joerg.roedel@amd.com>2012-10-24 11:07:43 -0400
commit8d7f62e6a7aa0bfd7163d3c4a5fb59280f6a6eb5 (patch)
treecafab6820ac262f0c718e498f92fb08ce8033271 /Documentation/DMA-API-HOWTO.txt
parent6c9c6d6301287e369a754d628230fa6e50cdb74b (diff)
Documentation DMA-API-HOWTO.txt Add dma mapping error check usage examples
Enhance the document to discuss the importance of dma mapping error checks after dma_map_single() and dma_map_page() calls. Also added usage examples that include unmap examples in error paths when dma mapping error is returned. Includes correct and incorrect usages to high light some common mistakes in error paths especially when dma mapping fails when more than one dma mapping call is made. Signed-off-by: Shuah Khan <shuah.khan@hp.com> Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
Diffstat (limited to 'Documentation/DMA-API-HOWTO.txt')
-rw-r--r--Documentation/DMA-API-HOWTO.txt126
1 files changed, 126 insertions, 0 deletions
diff --git a/Documentation/DMA-API-HOWTO.txt b/Documentation/DMA-API-HOWTO.txt
index a0b6250add79..4a4fb295ceef 100644
--- a/Documentation/DMA-API-HOWTO.txt
+++ b/Documentation/DMA-API-HOWTO.txt
@@ -468,11 +468,46 @@ To map a single region, you do:
468 size_t size = buffer->len; 468 size_t size = buffer->len;
469 469
470 dma_handle = dma_map_single(dev, addr, size, direction); 470 dma_handle = dma_map_single(dev, addr, size, direction);
471 if (dma_mapping_error(dma_handle)) {
472 /*
473 * reduce current DMA mapping usage,
474 * delay and try again later or
475 * reset driver.
476 */
477 goto map_error_handling;
478 }
471 479
472and to unmap it: 480and to unmap it:
473 481
474 dma_unmap_single(dev, dma_handle, size, direction); 482 dma_unmap_single(dev, dma_handle, size, direction);
475 483
484You should call dma_mapping_error() as dma_map_single() could fail and return
485error. Not all dma implementations support dma_mapping_error() interface.
486However, it is a good practice to call dma_mapping_error() interface, which
487will invoke the generic mapping error check interface. Doing so will ensure
488that the mapping code will work correctly on all dma implementations without
489any dependency on the specifics of the underlying implementation. Using the
490returned address without checking for errors could result in failures ranging
491from panics to silent data corruption. Couple of example of incorrect ways to
492check for errors that make assumptions about the underlying dma implementation
493are as follows and these are applicable to dma_map_page() as well.
494
495Incorrect example 1:
496 dma_addr_t dma_handle;
497
498 dma_handle = dma_map_single(dev, addr, size, direction);
499 if ((dma_handle & 0xffff != 0) || (dma_handle >= 0x1000000)) {
500 goto map_error;
501 }
502
503Incorrect example 2:
504 dma_addr_t dma_handle;
505
506 dma_handle = dma_map_single(dev, addr, size, direction);
507 if (dma_handle == DMA_ERROR_CODE) {
508 goto map_error;
509 }
510
476You should call dma_unmap_single when the DMA activity is finished, e.g. 511You should call dma_unmap_single when the DMA activity is finished, e.g.
477from the interrupt which told you that the DMA transfer is done. 512from the interrupt which told you that the DMA transfer is done.
478 513
@@ -489,6 +524,14 @@ Specifically:
489 size_t size = buffer->len; 524 size_t size = buffer->len;
490 525
491 dma_handle = dma_map_page(dev, page, offset, size, direction); 526 dma_handle = dma_map_page(dev, page, offset, size, direction);
527 if (dma_mapping_error(dma_handle)) {
528 /*
529 * reduce current DMA mapping usage,
530 * delay and try again later or
531 * reset driver.
532 */
533 goto map_error_handling;
534 }
492 535
493 ... 536 ...
494 537
@@ -496,6 +539,12 @@ Specifically:
496 539
497Here, "offset" means byte offset within the given page. 540Here, "offset" means byte offset within the given page.
498 541
542You should call dma_mapping_error() as dma_map_page() could fail and return
543error as outlined under the dma_map_single() discussion.
544
545You should call dma_unmap_page when the DMA activity is finished, e.g.
546from the interrupt which told you that the DMA transfer is done.
547
499With scatterlists, you map a region gathered from several regions by: 548With scatterlists, you map a region gathered from several regions by:
500 549
501 int i, count = dma_map_sg(dev, sglist, nents, direction); 550 int i, count = dma_map_sg(dev, sglist, nents, direction);
@@ -578,6 +627,14 @@ to use the dma_sync_*() interfaces.
578 dma_addr_t mapping; 627 dma_addr_t mapping;
579 628
580 mapping = dma_map_single(cp->dev, buffer, len, DMA_FROM_DEVICE); 629 mapping = dma_map_single(cp->dev, buffer, len, DMA_FROM_DEVICE);
630 if (dma_mapping_error(dma_handle)) {
631 /*
632 * reduce current DMA mapping usage,
633 * delay and try again later or
634 * reset driver.
635 */
636 goto map_error_handling;
637 }
581 638
582 cp->rx_buf = buffer; 639 cp->rx_buf = buffer;
583 cp->rx_len = len; 640 cp->rx_len = len;
@@ -658,6 +715,75 @@ failure can be determined by:
658 * delay and try again later or 715 * delay and try again later or
659 * reset driver. 716 * reset driver.
660 */ 717 */
718 goto map_error_handling;
719 }
720
721- unmap pages that are already mapped, when mapping error occurs in the middle
722 of a multiple page mapping attempt. These example are applicable to
723 dma_map_page() as well.
724
725Example 1:
726 dma_addr_t dma_handle1;
727 dma_addr_t dma_handle2;
728
729 dma_handle1 = dma_map_single(dev, addr, size, direction);
730 if (dma_mapping_error(dev, dma_handle1)) {
731 /*
732 * reduce current DMA mapping usage,
733 * delay and try again later or
734 * reset driver.
735 */
736 goto map_error_handling1;
737 }
738 dma_handle2 = dma_map_single(dev, addr, size, direction);
739 if (dma_mapping_error(dev, dma_handle2)) {
740 /*
741 * reduce current DMA mapping usage,
742 * delay and try again later or
743 * reset driver.
744 */
745 goto map_error_handling2;
746 }
747
748 ...
749
750 map_error_handling2:
751 dma_unmap_single(dma_handle1);
752 map_error_handling1:
753
754Example 2: (if buffers are allocated a loop, unmap all mapped buffers when
755 mapping error is detected in the middle)
756
757 dma_addr_t dma_addr;
758 dma_addr_t array[DMA_BUFFERS];
759 int save_index = 0;
760
761 for (i = 0; i < DMA_BUFFERS; i++) {
762
763 ...
764
765 dma_addr = dma_map_single(dev, addr, size, direction);
766 if (dma_mapping_error(dev, dma_addr)) {
767 /*
768 * reduce current DMA mapping usage,
769 * delay and try again later or
770 * reset driver.
771 */
772 goto map_error_handling;
773 }
774 array[i].dma_addr = dma_addr;
775 save_index++;
776 }
777
778 ...
779
780 map_error_handling:
781
782 for (i = 0; i < save_index; i++) {
783
784 ...
785
786 dma_unmap_single(array[i].dma_addr);
661 } 787 }
662 788
663Networking drivers must call dev_kfree_skb to free the socket buffer 789Networking drivers must call dev_kfree_skb to free the socket buffer