Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
samples
kfifo
dma-example.c
Go to the documentation of this file.
1
/*
2
* Sample fifo dma implementation
3
*
4
* Copyright (C) 2010 Stefani Seibold <
[email protected]
>
5
*
6
* Released under the GPL version 2 only.
7
*
8
*/
9
10
#include <
linux/init.h
>
11
#include <linux/module.h>
12
#include <
linux/kfifo.h
>
13
14
/*
15
* This module shows how to handle fifo dma operations.
16
*/
17
18
/* fifo size in elements (bytes) */
19
#define FIFO_SIZE 32
20
21
static
struct
kfifo
fifo
;
22
23
static
int
__init
example_init(
void
)
24
{
25
int
i
;
26
unsigned
int
ret
;
27
unsigned
int
nents;
28
struct
scatterlist
sg
[10];
29
30
printk
(
KERN_INFO
"DMA fifo test start\n"
);
31
32
if
(
kfifo_alloc
(&
fifo
,
FIFO_SIZE
,
GFP_KERNEL
)) {
33
printk
(
KERN_WARNING
"error kfifo_alloc\n"
);
34
return
-
ENOMEM
;
35
}
36
37
printk
(
KERN_INFO
"queue size: %u\n"
,
kfifo_size
(&
fifo
));
38
39
kfifo_in
(&
fifo
,
"test"
, 4);
40
41
for
(i = 0; i != 9; i++)
42
kfifo_put
(&
fifo
, &i);
43
44
/* kick away first byte */
45
kfifo_skip
(&
fifo
);
46
47
printk
(
KERN_INFO
"queue len: %u\n"
,
kfifo_len
(&
fifo
));
48
49
/*
50
* Configure the kfifo buffer to receive data from DMA input.
51
*
52
* .--------------------------------------.
53
* | 0 | 1 | 2 | ... | 12 | 13 | ... | 31 |
54
* |---|------------------|---------------|
55
* \_/ \________________/ \_____________/
56
* \ \ \
57
* \ \_allocated data \
58
* \_*free space* \_*free space*
59
*
60
* We need two different SG entries: one for the free space area at the
61
* end of the kfifo buffer (19 bytes) and another for the first free
62
* byte at the beginning, after the kfifo_skip().
63
*/
64
sg_init_table
(
sg
,
ARRAY_SIZE
(
sg
));
65
nents =
kfifo_dma_in_prepare
(&
fifo
,
sg
,
ARRAY_SIZE
(
sg
),
FIFO_SIZE
);
66
printk
(
KERN_INFO
"DMA sgl entries: %d\n"
, nents);
67
if
(!nents) {
68
/* fifo is full and no sgl was created */
69
printk
(
KERN_WARNING
"error kfifo_dma_in_prepare\n"
);
70
return
-
EIO
;
71
}
72
73
/* receive data */
74
printk
(
KERN_INFO
"scatterlist for receive:\n"
);
75
for
(i = 0; i < nents; i++) {
76
printk
(
KERN_INFO
77
"sg[%d] -> "
78
"page_link 0x%.8lx offset 0x%.8x length 0x%.8x\n"
,
79
i,
sg
[i].
page_link
,
sg
[i].
offset
,
sg
[i].
length
);
80
81
if
(
sg_is_last
(&
sg
[i]))
82
break
;
83
}
84
85
/* put here your code to setup and exectute the dma operation */
86
/* ... */
87
88
/* example: zero bytes received */
89
ret = 0;
90
91
/* finish the dma operation and update the received data */
92
kfifo_dma_in_finish
(&
fifo
, ret);
93
94
/* Prepare to transmit data, example: 8 bytes */
95
nents =
kfifo_dma_out_prepare
(&
fifo
,
sg
,
ARRAY_SIZE
(
sg
), 8);
96
printk
(
KERN_INFO
"DMA sgl entries: %d\n"
, nents);
97
if
(!nents) {
98
/* no data was available and no sgl was created */
99
printk
(
KERN_WARNING
"error kfifo_dma_out_prepare\n"
);
100
return
-
EIO
;
101
}
102
103
printk
(
KERN_INFO
"scatterlist for transmit:\n"
);
104
for
(i = 0; i < nents; i++) {
105
printk
(
KERN_INFO
106
"sg[%d] -> "
107
"page_link 0x%.8lx offset 0x%.8x length 0x%.8x\n"
,
108
i,
sg
[i].
page_link
,
sg
[i].
offset
,
sg
[i].
length
);
109
110
if
(
sg_is_last
(&
sg
[i]))
111
break
;
112
}
113
114
/* put here your code to setup and exectute the dma operation */
115
/* ... */
116
117
/* example: 5 bytes transmitted */
118
ret = 5;
119
120
/* finish the dma operation and update the transmitted data */
121
kfifo_dma_out_finish
(&
fifo
, ret);
122
123
ret =
kfifo_len
(&
fifo
);
124
printk
(
KERN_INFO
"queue len: %u\n"
,
kfifo_len
(&
fifo
));
125
126
if
(ret != 7) {
127
printk
(
KERN_WARNING
"size mismatch: test failed"
);
128
return
-
EIO
;
129
}
130
printk
(
KERN_INFO
"test passed\n"
);
131
132
return
0;
133
}
134
135
static
void
__exit
example_exit(
void
)
136
{
137
kfifo_free
(&
fifo
);
138
}
139
140
module_init
(example_init);
141
module_exit
(example_exit);
142
MODULE_LICENSE
(
"GPL"
);
143
MODULE_AUTHOR
(
"Stefani Seibold <
[email protected]
>"
);
Generated on Thu Jan 10 2013 15:02:47 for Linux Kernel by
1.8.2