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.c111
1 files changed, 69 insertions, 42 deletions
diff --git a/samples/kfifo/dma-example.c b/samples/kfifo/dma-example.c
index b9482c28b41..ee03a4f0b64 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,72 +41,99 @@ 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 */
63 sg_init_table(sg, ARRAY_SIZE(sg));
48 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);
49 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 }
50 71
51 /* if 0 was returned, fifo is full and no sgl was created */ 72 /* receive data */
52 if (ret) { 73 printk(KERN_INFO "scatterlist for receive:\n");
53 printk(KERN_INFO "scatterlist for receive:\n"); 74 for (i = 0; i < ARRAY_SIZE(sg); i++) {
54 for (i = 0; i < ARRAY_SIZE(sg); i++) { 75 printk(KERN_INFO
55 printk(KERN_INFO 76 "sg[%d] -> "
56 "sg[%d] -> " 77 "page_link 0x%.8lx offset 0x%.8x length 0x%.8x\n",
57 "page_link 0x%.8lx offset 0x%.8x length 0x%.8x\n", 78 i, sg[i].page_link, sg[i].offset, sg[i].length);
58 i, sg[i].page_link, sg[i].offset, sg[i].length);
59 79
60 if (sg_is_last(&sg[i])) 80 if (sg_is_last(&sg[i]))
61 break; 81 break;
62 } 82 }
63 83
64 /* but here your code to setup and exectute the dma operation */ 84 /* put here your code to setup and exectute the dma operation */
65 /* ... */ 85 /* ... */
66 86
67 /* example: zero bytes received */ 87 /* example: zero bytes received */
68 ret = 0; 88 ret = 0;
69 89
70 /* finish the dma operation and update the received data */ 90 /* finish the dma operation and update the received data */
71 kfifo_dma_in_finish(&fifo, ret); 91 kfifo_dma_in_finish(&fifo, ret);
72 }
73 92
93 /* Prepare to transmit data, example: 8 bytes */
74 ret = kfifo_dma_out_prepare(&fifo, sg, ARRAY_SIZE(sg), 8); 94 ret = kfifo_dma_out_prepare(&fifo, sg, ARRAY_SIZE(sg), 8);
75 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 }
76 101
77 /* if 0 was returned, no data was available and no sgl was created */ 102 printk(KERN_INFO "scatterlist for transmit:\n");
78 if (ret) { 103 for (i = 0; i < ARRAY_SIZE(sg); i++) {
79 printk(KERN_INFO "scatterlist for transmit:\n"); 104 printk(KERN_INFO
80 for (i = 0; i < ARRAY_SIZE(sg); i++) { 105 "sg[%d] -> "
81 printk(KERN_INFO 106 "page_link 0x%.8lx offset 0x%.8x length 0x%.8x\n",
82 "sg[%d] -> " 107 i, sg[i].page_link, sg[i].offset, sg[i].length);
83 "page_link 0x%.8lx offset 0x%.8x length 0x%.8x\n",
84 i, sg[i].page_link, sg[i].offset, sg[i].length);
85 108
86 if (sg_is_last(&sg[i])) 109 if (sg_is_last(&sg[i]))
87 break; 110 break;
88 } 111 }
89 112
90 /* but here your code to setup and exectute the dma operation */ 113 /* put here your code to setup and exectute the dma operation */
91 /* ... */ 114 /* ... */
92 115
93 /* example: 5 bytes transmitted */ 116 /* example: 5 bytes transmitted */
94 ret = 5; 117 ret = 5;
95 118
96 /* finish the dma operation and update the transmitted data */ 119 /* finish the dma operation and update the transmitted data */
97 kfifo_dma_out_finish(&fifo, ret); 120 kfifo_dma_out_finish(&fifo, ret);
98 }
99 121
122 ret = kfifo_len(&fifo);
100 printk(KERN_INFO "queue len: %u\n", kfifo_len(&fifo)); 123 printk(KERN_INFO "queue len: %u\n", kfifo_len(&fifo));
101 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
102 return 0; 131 return 0;
103} 132}
104 133
105static void __exit example_exit(void) 134static void __exit example_exit(void)
106{ 135{
107#ifdef DYNAMIC 136 kfifo_free(&fifo);
108 kfifo_free(&test);
109#endif
110} 137}
111 138
112module_init(example_init); 139module_init(example_init);