diff options
Diffstat (limited to 'samples/kfifo/dma-example.c')
-rw-r--r-- | samples/kfifo/dma-example.c | 106 |
1 files changed, 67 insertions, 39 deletions
diff --git a/samples/kfifo/dma-example.c b/samples/kfifo/dma-example.c index 3682278785f7..ee03a4f0b64f 100644 --- a/samples/kfifo/dma-example.c +++ b/samples/kfifo/dma-example.c | |||
@@ -29,8 +29,8 @@ static int __init example_init(void) | |||
29 | printk(KERN_INFO "DMA fifo test start\n"); | 29 | printk(KERN_INFO "DMA fifo test start\n"); |
30 | 30 | ||
31 | if (kfifo_alloc(&fifo, FIFO_SIZE, GFP_KERNEL)) { | 31 | if (kfifo_alloc(&fifo, FIFO_SIZE, GFP_KERNEL)) { |
32 | printk(KERN_ERR "error kfifo_alloc\n"); | 32 | printk(KERN_WARNING "error kfifo_alloc\n"); |
33 | return 1; | 33 | return -ENOMEM; |
34 | } | 34 | } |
35 | 35 | ||
36 | printk(KERN_INFO "queue size: %u\n", kfifo_size(&fifo)); | 36 | printk(KERN_INFO "queue size: %u\n", kfifo_size(&fifo)); |
@@ -41,65 +41,93 @@ static int __init example_init(void) | |||
41 | kfifo_put(&fifo, &i); | 41 | kfifo_put(&fifo, &i); |
42 | 42 | ||
43 | /* kick away first byte */ | 43 | /* kick away first byte */ |
44 | ret = kfifo_get(&fifo, &i); | 44 | kfifo_skip(&fifo); |
45 | 45 | ||
46 | printk(KERN_INFO "queue len: %u\n", kfifo_len(&fifo)); | 46 | printk(KERN_INFO "queue len: %u\n", kfifo_len(&fifo)); |
47 | 47 | ||
48 | /* | ||
49 | * Configure the kfifo buffer to receive data from DMA input. | ||
50 | * | ||
51 | * .--------------------------------------. | ||
52 | * | 0 | 1 | 2 | ... | 12 | 13 | ... | 31 | | ||
53 | * |---|------------------|---------------| | ||
54 | * \_/ \________________/ \_____________/ | ||
55 | * \ \ \ | ||
56 | * \ \_allocated data \ | ||
57 | * \_*free space* \_*free space* | ||
58 | * | ||
59 | * We need two different SG entries: one for the free space area at the | ||
60 | * end of the kfifo buffer (19 bytes) and another for the first free | ||
61 | * byte at the beginning, after the kfifo_skip(). | ||
62 | */ | ||
48 | sg_init_table(sg, ARRAY_SIZE(sg)); | 63 | sg_init_table(sg, ARRAY_SIZE(sg)); |
49 | ret = kfifo_dma_in_prepare(&fifo, sg, ARRAY_SIZE(sg), FIFO_SIZE); | 64 | ret = kfifo_dma_in_prepare(&fifo, sg, ARRAY_SIZE(sg), FIFO_SIZE); |
50 | printk(KERN_INFO "DMA sgl entries: %d\n", ret); | 65 | printk(KERN_INFO "DMA sgl entries: %d\n", ret); |
66 | if (!ret) { | ||
67 | /* fifo is full and no sgl was created */ | ||
68 | printk(KERN_WARNING "error kfifo_dma_in_prepare\n"); | ||
69 | return -EIO; | ||
70 | } | ||
51 | 71 | ||
52 | /* if 0 was returned, fifo is full and no sgl was created */ | 72 | /* receive data */ |
53 | if (ret) { | 73 | printk(KERN_INFO "scatterlist for receive:\n"); |
54 | printk(KERN_INFO "scatterlist for receive:\n"); | 74 | for (i = 0; i < ARRAY_SIZE(sg); i++) { |
55 | for (i = 0; i < ARRAY_SIZE(sg); i++) { | 75 | printk(KERN_INFO |
56 | printk(KERN_INFO | 76 | "sg[%d] -> " |
57 | "sg[%d] -> " | 77 | "page_link 0x%.8lx offset 0x%.8x length 0x%.8x\n", |
58 | "page_link 0x%.8lx offset 0x%.8x length 0x%.8x\n", | 78 | i, sg[i].page_link, sg[i].offset, sg[i].length); |
59 | i, sg[i].page_link, sg[i].offset, sg[i].length); | ||
60 | 79 | ||
61 | if (sg_is_last(&sg[i])) | 80 | if (sg_is_last(&sg[i])) |
62 | break; | 81 | break; |
63 | } | 82 | } |
64 | 83 | ||
65 | /* but here your code to setup and exectute the dma operation */ | 84 | /* put here your code to setup and exectute the dma operation */ |
66 | /* ... */ | 85 | /* ... */ |
67 | 86 | ||
68 | /* example: zero bytes received */ | 87 | /* example: zero bytes received */ |
69 | ret = 0; | 88 | ret = 0; |
70 | 89 | ||
71 | /* finish the dma operation and update the received data */ | 90 | /* finish the dma operation and update the received data */ |
72 | kfifo_dma_in_finish(&fifo, ret); | 91 | kfifo_dma_in_finish(&fifo, ret); |
73 | } | ||
74 | 92 | ||
93 | /* Prepare to transmit data, example: 8 bytes */ | ||
75 | ret = kfifo_dma_out_prepare(&fifo, sg, ARRAY_SIZE(sg), 8); | 94 | ret = kfifo_dma_out_prepare(&fifo, sg, ARRAY_SIZE(sg), 8); |
76 | printk(KERN_INFO "DMA sgl entries: %d\n", ret); | 95 | printk(KERN_INFO "DMA sgl entries: %d\n", ret); |
96 | if (!ret) { | ||
97 | /* no data was available and no sgl was created */ | ||
98 | printk(KERN_WARNING "error kfifo_dma_out_prepare\n"); | ||
99 | return -EIO; | ||
100 | } | ||
77 | 101 | ||
78 | /* if 0 was returned, no data was available and no sgl was created */ | 102 | printk(KERN_INFO "scatterlist for transmit:\n"); |
79 | if (ret) { | 103 | for (i = 0; i < ARRAY_SIZE(sg); i++) { |
80 | printk(KERN_INFO "scatterlist for transmit:\n"); | 104 | printk(KERN_INFO |
81 | for (i = 0; i < ARRAY_SIZE(sg); i++) { | 105 | "sg[%d] -> " |
82 | printk(KERN_INFO | 106 | "page_link 0x%.8lx offset 0x%.8x length 0x%.8x\n", |
83 | "sg[%d] -> " | 107 | i, sg[i].page_link, sg[i].offset, sg[i].length); |
84 | "page_link 0x%.8lx offset 0x%.8x length 0x%.8x\n", | ||
85 | i, sg[i].page_link, sg[i].offset, sg[i].length); | ||
86 | 108 | ||
87 | if (sg_is_last(&sg[i])) | 109 | if (sg_is_last(&sg[i])) |
88 | break; | 110 | break; |
89 | } | 111 | } |
90 | 112 | ||
91 | /* but here your code to setup and exectute the dma operation */ | 113 | /* put here your code to setup and exectute the dma operation */ |
92 | /* ... */ | 114 | /* ... */ |
93 | 115 | ||
94 | /* example: 5 bytes transmitted */ | 116 | /* example: 5 bytes transmitted */ |
95 | ret = 5; | 117 | ret = 5; |
96 | 118 | ||
97 | /* finish the dma operation and update the transmitted data */ | 119 | /* finish the dma operation and update the transmitted data */ |
98 | kfifo_dma_out_finish(&fifo, ret); | 120 | kfifo_dma_out_finish(&fifo, ret); |
99 | } | ||
100 | 121 | ||
122 | ret = kfifo_len(&fifo); | ||
101 | printk(KERN_INFO "queue len: %u\n", kfifo_len(&fifo)); | 123 | printk(KERN_INFO "queue len: %u\n", kfifo_len(&fifo)); |
102 | 124 | ||
125 | if (ret != 7) { | ||
126 | printk(KERN_WARNING "size mismatch: test failed"); | ||
127 | return -EIO; | ||
128 | } | ||
129 | printk(KERN_INFO "test passed\n"); | ||
130 | |||
103 | return 0; | 131 | return 0; |
104 | } | 132 | } |
105 | 133 | ||