linux dma实例,DMA使用示例!

29 #include 30

31 #define MAX_DMA_ADDRESS     (~0UL)

32

33 static void fsl_dma_test_callback(void *dma_async_param)

34 {

35    struct completion *cmp = dma_async_param;

36    printk( KERN_ERR "dma transfer done, end=%lu\n", jiffies );

37    complete(cmp);

38 }

39

40 static int fsl_dma_self_test(struct dma_chan *chan)

41 {

42    int i;

43    u8 *src;

44    u8 *dest;

45    struct dma_device *dma = chan->device;

46    struct device *dev = dma->dev;

47    struct dma_chan* dma_chan = chan;

48    struct dma_async_tx_descriptor *tx;

49    dma_addr_t dma_dest, dma_src;

50    dma_cookie_t cookie;

51    int err = 0;

52    struct completion cmp;

53    unsigned long tmo;

54    unsigned long flags;

55    u32 test_size = 1024*1024*4u;

56

57    src = kzalloc(sizeof(u8) * test_size, GFP_KERNEL);

58    if (!src)

59        return -ENOMEM;

60    dest = kzalloc(sizeof(u8) * test_size, GFP_KERNEL);

61    if (!dest) {

62        kfree(src);

63        return -ENOMEM;

64    }

65

66    /* Fill in src buffer */

67    for (i = 0; i < test_size; i++)

68        src[i] = (u8)i;

69

70    /* Start copy, using first DMA channel */

71    dma_src = dma_map_single(dev, src, test_size, DMA_TO_DEVICE);

72    dma_dest = dma_map_single(dev, dest, test_size, DMA_FROM_DEVICE);

73    flags = DMA_COMPL_SRC_UNMAP_SINGLE | DMA_COMPL_DEST_UNMAP_SINGLE |

74        DMA_PREP_INTERRUPT;

75

76    printk( KERN_ERR "try to dma copy %d bytes: 0x%08x-->0x%08x\n", test_size, dma_src,     dma_dest );

77    tx = dma->device_prep_dma_memcpy(dma_chan, dma_dest, dma_src,

78                           test_size, flags);

79    if (!tx) {

80        dev_err(dev, "Self-test prep failed, disabling\n");

81        err = -ENODEV;

82        goto free_resources;

83    }

84

85    async_tx_ack(tx);

86    init_completion(&cmp);

87    tx->callback = fsl_dma_test_callback;

88    tx->callback_param = &cmp;

89    cookie = tx->tx_submit(tx);

90    if (cookie < 0) {

91        dev_err(dev, "Self-test setup failed, disabling\n");

92        err = -ENODEV;

93        goto free_resources;

94    }

95

96    printk( KERN_ERR "begin dma transfer: %d bytes, start=%lu\n", test_size, jiffies );

97    dma->device_issue_pending(dma_chan);

98

99    tmo = wait_for_completion_timeout(&cmp, msecs_to_jiffies(3000));

100

101    if (tmo == 0 ||

102        dma->device_tx_status(dma_chan, cookie, NULL)

103                    != DMA_SUCCESS) {

104        dev_err(dev, "Self-test copy timed out, disabling\n");

105        err = -ENODEV;

106        goto free_resources;

107    }

108    if (memcmp(src, dest, test_size)) {

109        dev_err(dev, "Self-test copy failed compare, disabling\n");

110        err = -ENODEV;

111        goto free_resources;

112    }

113

114 free_resources:

115     dma->device_free_chan_resources(dma_chan);

116     kfree(src);

117    kfree(dest);

118    return err;

119 }

120

121

122

123 static int __init test_init(void)

124 {

125     struct dma_chan *dc = dma_find_channel(DMA_MEMCPY);

126     if (dc) {

127         printk(" ------- get channel ----\n");

128         fsl_dma_self_test(dc);

129     }

130     printk(" ------- init time ----\n");

131     return 0;

132 }

133

134 static void __exit test_exit(void)

135 {

136     printk("-------- test exit over ----------\n");

137     return;

138 }

139

140 MODULE_LICENSE("GPL");

141

142 module_init(test_init);

143 module_exit(test_exit);