aboutsummaryrefslogtreecommitdiffstats
path: root/samples/kfifo/dma-example.c
diff options
context:
space:
mode:
Diffstat (limited to 'samples/kfifo/dma-example.c')
-rw-r--r--samples/kfifo/dma-example.c106
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