aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefani Seibold <stefani@seibold.net>2010-08-10 21:03:39 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-08-11 11:59:23 -0400
commit5bf2b19320ec31d094d7370fdf536f7fd91fd799 (patch)
tree47052fd9bdb0969d4a4a7d430695388094409964
parent2e956fb320568cc70861761483e2f0e2db75fd66 (diff)
kfifo: add example files to the kernel sample directory
Add four examples to the kernel sample directory. It shows how to handle: - a byte stream fifo - a integer type fifo - a dynamic record sized fifo - the fifo DMA functions [akpm@linux-foundation.org: coding-style fixes] Signed-off-by: Stefani Seibold <stefani@seibold.net> Cc: Greg KH <greg@kroah.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--samples/Kconfig10
-rw-r--r--samples/Makefile2
-rw-r--r--samples/kfifo/Makefile1
-rw-r--r--samples/kfifo/bytestream-example.c163
-rw-r--r--samples/kfifo/dma-example.c115
-rw-r--r--samples/kfifo/inttype-example.c157
-rw-r--r--samples/kfifo/record-example.c167
7 files changed, 614 insertions, 1 deletions
diff --git a/samples/Kconfig b/samples/Kconfig
index 8924f72f0629..954a1d550c5f 100644
--- a/samples/Kconfig
+++ b/samples/Kconfig
@@ -44,4 +44,14 @@ config SAMPLE_HW_BREAKPOINT
44 help 44 help
45 This builds kernel hardware breakpoint example modules. 45 This builds kernel hardware breakpoint example modules.
46 46
47config SAMPLE_KFIFO
48 tristate "Build kfifo examples -- loadable modules only"
49 depends on m
50 help
51 This config option will allow you to build a number of
52 different kfifo sample modules showing how to use the
53 generic kfifo API.
54
55 If in doubt, say "N" here.
56
47endif # SAMPLES 57endif # SAMPLES
diff --git a/samples/Makefile b/samples/Makefile
index 0f15e6d77fd6..76b3c3455c29 100644
--- a/samples/Makefile
+++ b/samples/Makefile
@@ -1,4 +1,4 @@
1# Makefile for Linux samples code 1# Makefile for Linux samples code
2 2
3obj-$(CONFIG_SAMPLES) += kobject/ kprobes/ tracepoints/ trace_events/ \ 3obj-$(CONFIG_SAMPLES) += kobject/ kprobes/ tracepoints/ trace_events/ \
4 hw_breakpoint/ 4 hw_breakpoint/ kfifo/
diff --git a/samples/kfifo/Makefile b/samples/kfifo/Makefile
new file mode 100644
index 000000000000..bcc9484a15b2
--- /dev/null
+++ b/samples/kfifo/Makefile
@@ -0,0 +1 @@
obj-$(CONFIG_SAMPLE_KFIFO) += bytestream-example.o dma-example.o inttype-example.o record-example.o
diff --git a/samples/kfifo/bytestream-example.c b/samples/kfifo/bytestream-example.c
new file mode 100644
index 000000000000..642eef3f6336
--- /dev/null
+++ b/samples/kfifo/bytestream-example.c
@@ -0,0 +1,163 @@
1/*
2 * Sample kfifo byte stream implementation
3 *
4 * Copyright (C) 2010 Stefani Seibold <stefani@seibold.net>
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/proc_fs.h>
13#include <linux/mutex.h>
14#include <linux/kfifo.h>
15
16/*
17 * This module shows how to create a byte stream fifo.
18 */
19
20/* fifo size in elements (bytes) */
21#define FIFO_SIZE 32
22
23/* name of the proc entry */
24#define PROC_FIFO "bytestream-fifo"
25
26/* lock for procfs read access */
27static DEFINE_MUTEX(read_lock);
28
29/* lock for procfs write access */
30static DEFINE_MUTEX(write_lock);
31
32/*
33 * define DYNAMIC in this example for a dynamically allocated fifo.
34 *
35 * Otherwise the fifo storage will be a part of the fifo structure.
36 */
37#if 0
38#define DYNAMIC
39#endif
40
41#ifdef DYNAMIC
42static struct kfifo test;
43#else
44static DECLARE_KFIFO(test, unsigned char, FIFO_SIZE);
45#endif
46
47static int __init testfunc(void)
48{
49 unsigned char buf[6];
50 unsigned char i;
51 unsigned int ret;
52
53 printk(KERN_INFO "byte stream fifo test start\n");
54
55 /* put string into the fifo */
56 kfifo_in(&test, "hello", 5);
57
58 /* put values into the fifo */
59 for (i = 0; i != 10; i++)
60 kfifo_put(&test, &i);
61
62 /* show the number of used elements */
63 printk(KERN_INFO "fifo len: %u\n", kfifo_len(&test));
64
65 /* get max of 5 bytes from the fifo */
66 i = kfifo_out(&test, buf, 5);
67 printk(KERN_INFO "buf: %.*s\n", i, buf);
68
69 /* get max of 2 elements from the fifo */
70 ret = kfifo_out(&test, buf, 2);
71 printk(KERN_INFO "ret: %d\n", ret);
72 /* and put it back to the end of the fifo */
73 ret = kfifo_in(&test, buf, ret);
74 printk(KERN_INFO "ret: %d\n", ret);
75
76 /* put values into the fifo until is full */
77 for (i = 20; kfifo_put(&test, &i); i++)
78 ;
79
80 printk(KERN_INFO "queue len: %u\n", kfifo_len(&test));
81
82 /* print out all values in the fifo */
83 while (kfifo_get(&test, &i))
84 printk("%d ", i);
85 printk("\n");
86
87 return 0;
88}
89
90static ssize_t fifo_write(struct file *file, const char __user *buf,
91 size_t count, loff_t *ppos)
92{
93 int ret;
94 unsigned int copied;
95
96 if (mutex_lock_interruptible(&write_lock))
97 return -ERESTARTSYS;
98
99 ret = kfifo_from_user(&test, buf, count, &copied);
100
101 mutex_unlock(&write_lock);
102
103 return ret ? ret : copied;
104}
105
106static ssize_t fifo_read(struct file *file, char __user *buf,
107 size_t count, loff_t *ppos)
108{
109 int ret;
110 unsigned int copied;
111
112 if (mutex_lock_interruptible(&read_lock))
113 return -ERESTARTSYS;
114
115 ret = kfifo_to_user(&test, buf, count, &copied);
116
117 mutex_unlock(&read_lock);
118
119 return ret ? ret : copied;
120}
121
122static const struct file_operations fifo_fops = {
123 .owner = THIS_MODULE,
124 .read = fifo_read,
125 .write = fifo_write,
126};
127
128static int __init example_init(void)
129{
130#ifdef DYNAMIC
131 int ret;
132
133 ret = kfifo_alloc(&test, FIFO_SIZE, GFP_KERNEL);
134 if (ret) {
135 printk(KERN_ERR "error kfifo_alloc\n");
136 return ret;
137 }
138#else
139 INIT_KFIFO(test);
140#endif
141 testfunc();
142
143 if (proc_create(PROC_FIFO, 0, NULL, &fifo_fops) == NULL) {
144#ifdef DYNAMIC
145 kfifo_free(&test);
146#endif
147 return -ENOMEM;
148 }
149 return 0;
150}
151
152static void __exit example_exit(void)
153{
154 remove_proc_entry(PROC_FIFO, NULL);
155#ifdef DYNAMIC
156 kfifo_free(&test);
157#endif
158}
159
160module_init(example_init);
161module_exit(example_exit);
162MODULE_LICENSE("GPL");
163MODULE_AUTHOR("Stefani Seibold <stefani@seibold.net>");
diff --git a/samples/kfifo/dma-example.c b/samples/kfifo/dma-example.c
new file mode 100644
index 000000000000..b9482c28b41a
--- /dev/null
+++ b/samples/kfifo/dma-example.c
@@ -0,0 +1,115 @@
1/*
2 * Sample fifo dma implementation
3 *
4 * Copyright (C) 2010 Stefani Seibold <stefani@seibold.net>
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
21static struct kfifo fifo;
22
23static int __init example_init(void)
24{
25 int i;
26 unsigned int ret;
27 struct scatterlist sg[10];
28
29 printk(KERN_INFO "DMA fifo test start\n");
30
31 if (kfifo_alloc(&fifo, FIFO_SIZE, GFP_KERNEL)) {
32 printk(KERN_ERR "error kfifo_alloc\n");
33 return 1;
34 }
35
36 printk(KERN_INFO "queue size: %u\n", kfifo_size(&fifo));
37
38 kfifo_in(&fifo, "test", 4);
39
40 for (i = 0; i != 9; i++)
41 kfifo_put(&fifo, &i);
42
43 /* kick away first byte */
44 ret = kfifo_get(&fifo, &i);
45
46 printk(KERN_INFO "queue len: %u\n", kfifo_len(&fifo));
47
48 ret = kfifo_dma_in_prepare(&fifo, sg, ARRAY_SIZE(sg), FIFO_SIZE);
49 printk(KERN_INFO "DMA sgl entries: %d\n", ret);
50
51 /* if 0 was returned, fifo is full and no sgl was created */
52 if (ret) {
53 printk(KERN_INFO "scatterlist for receive:\n");
54 for (i = 0; i < ARRAY_SIZE(sg); i++) {
55 printk(KERN_INFO
56 "sg[%d] -> "
57 "page_link 0x%.8lx offset 0x%.8x length 0x%.8x\n",
58 i, sg[i].page_link, sg[i].offset, sg[i].length);
59
60 if (sg_is_last(&sg[i]))
61 break;
62 }
63
64 /* but here your code to setup and exectute the dma operation */
65 /* ... */
66
67 /* example: zero bytes received */
68 ret = 0;
69
70 /* finish the dma operation and update the received data */
71 kfifo_dma_in_finish(&fifo, ret);
72 }
73
74 ret = kfifo_dma_out_prepare(&fifo, sg, ARRAY_SIZE(sg), 8);
75 printk(KERN_INFO "DMA sgl entries: %d\n", ret);
76
77 /* if 0 was returned, no data was available and no sgl was created */
78 if (ret) {
79 printk(KERN_INFO "scatterlist for transmit:\n");
80 for (i = 0; i < ARRAY_SIZE(sg); i++) {
81 printk(KERN_INFO
82 "sg[%d] -> "
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
86 if (sg_is_last(&sg[i]))
87 break;
88 }
89
90 /* but here your code to setup and exectute the dma operation */
91 /* ... */
92
93 /* example: 5 bytes transmitted */
94 ret = 5;
95
96 /* finish the dma operation and update the transmitted data */
97 kfifo_dma_out_finish(&fifo, ret);
98 }
99
100 printk(KERN_INFO "queue len: %u\n", kfifo_len(&fifo));
101
102 return 0;
103}
104
105static void __exit example_exit(void)
106{
107#ifdef DYNAMIC
108 kfifo_free(&test);
109#endif
110}
111
112module_init(example_init);
113module_exit(example_exit);
114MODULE_LICENSE("GPL");
115MODULE_AUTHOR("Stefani Seibold <stefani@seibold.net>");
diff --git a/samples/kfifo/inttype-example.c b/samples/kfifo/inttype-example.c
new file mode 100644
index 000000000000..d6c5b7d9df64
--- /dev/null
+++ b/samples/kfifo/inttype-example.c
@@ -0,0 +1,157 @@
1/*
2 * Sample kfifo int type implementation
3 *
4 * Copyright (C) 2010 Stefani Seibold <stefani@seibold.net>
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/proc_fs.h>
13#include <linux/mutex.h>
14#include <linux/kfifo.h>
15
16/*
17 * This module shows how to create a int type fifo.
18 */
19
20/* fifo size in elements (ints) */
21#define FIFO_SIZE 32
22
23/* name of the proc entry */
24#define PROC_FIFO "int-fifo"
25
26/* lock for procfs read access */
27static DEFINE_MUTEX(read_lock);
28
29/* lock for procfs write access */
30static DEFINE_MUTEX(write_lock);
31
32/*
33 * define DYNAMIC in this example for a dynamically allocated fifo.
34 *
35 * Otherwise the fifo storage will be a part of the fifo structure.
36 */
37#if 0
38#define DYNAMIC
39#endif
40
41#ifdef DYNAMIC
42static DECLARE_KFIFO_PTR(test, int);
43#else
44static DEFINE_KFIFO(test, int, FIFO_SIZE);
45#endif
46
47static int __init testfunc(void)
48{
49 int buf[6];
50 int i;
51 unsigned int ret;
52
53 printk(KERN_INFO "int fifo test start\n");
54
55 /* put values into the fifo */
56 for (i = 0; i != 10; i++)
57 kfifo_put(&test, &i);
58
59 /* show the number of used elements */
60 printk(KERN_INFO "fifo len: %u\n", kfifo_len(&test));
61
62 /* get max of 2 elements from the fifo */
63 ret = kfifo_out(&test, buf, 2);
64 printk(KERN_INFO "ret: %d\n", ret);
65 /* and put it back to the end of the fifo */
66 ret = kfifo_in(&test, buf, ret);
67 printk(KERN_INFO "ret: %d\n", ret);
68
69 for (i = 20; i != 30; i++)
70 kfifo_put(&test, &i);
71
72 printk(KERN_INFO "queue len: %u\n", kfifo_len(&test));
73
74 /* show the first value without removing from the fifo */
75 if (kfifo_peek(&test, &i))
76 printk(KERN_INFO "%d\n", i);
77
78 /* print out all values in the fifo */
79 while (kfifo_get(&test, &i))
80 printk("%d ", i);
81 printk("\n");
82
83 return 0;
84}
85
86static ssize_t fifo_write(struct file *file, const char __user *buf,
87 size_t count, loff_t *ppos)
88{
89 int ret;
90 unsigned int copied;
91
92 if (mutex_lock_interruptible(&write_lock))
93 return -ERESTARTSYS;
94
95 ret = kfifo_from_user(&test, buf, count, &copied);
96
97 mutex_unlock(&write_lock);
98
99 return ret ? ret : copied;
100}
101
102static ssize_t fifo_read(struct file *file, char __user *buf,
103 size_t count, loff_t *ppos)
104{
105 int ret;
106 unsigned int copied;
107
108 if (mutex_lock_interruptible(&read_lock))
109 return -ERESTARTSYS;
110
111 ret = kfifo_to_user(&test, buf, count, &copied);
112
113 mutex_unlock(&read_lock);
114
115 return ret ? ret : copied;
116}
117
118static const struct file_operations fifo_fops = {
119 .owner = THIS_MODULE,
120 .read = fifo_read,
121 .write = fifo_write,
122};
123
124static int __init example_init(void)
125{
126#ifdef DYNAMIC
127 int ret;
128
129 ret = kfifo_alloc(&test, FIFO_SIZE, GFP_KERNEL);
130 if (ret) {
131 printk(KERN_ERR "error kfifo_alloc\n");
132 return ret;
133 }
134#endif
135 testfunc();
136
137 if (proc_create(PROC_FIFO, 0, NULL, &fifo_fops) == NULL) {
138#ifdef DYNAMIC
139 kfifo_free(&test);
140#endif
141 return -ENOMEM;
142 }
143 return 0;
144}
145
146static void __exit example_exit(void)
147{
148 remove_proc_entry(PROC_FIFO, NULL);
149#ifdef DYNAMIC
150 kfifo_free(&test);
151#endif
152}
153
154module_init(example_init);
155module_exit(example_exit);
156MODULE_LICENSE("GPL");
157MODULE_AUTHOR("Stefani Seibold <stefani@seibold.net>");
diff --git a/samples/kfifo/record-example.c b/samples/kfifo/record-example.c
new file mode 100644
index 000000000000..32c6e0bda744
--- /dev/null
+++ b/samples/kfifo/record-example.c
@@ -0,0 +1,167 @@
1/*
2 * Sample dynamic sized record fifo implementation
3 *
4 * Copyright (C) 2010 Stefani Seibold <stefani@seibold.net>
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/proc_fs.h>
13#include <linux/mutex.h>
14#include <linux/kfifo.h>
15
16/*
17 * This module shows how to create a variable sized record fifo.
18 */
19
20/* fifo size in elements (bytes) */
21#define FIFO_SIZE 128
22
23/* name of the proc entry */
24#define PROC_FIFO "record-fifo"
25
26/* lock for procfs read access */
27static DEFINE_MUTEX(read_lock);
28
29/* lock for procfs write access */
30static DEFINE_MUTEX(write_lock);
31
32/*
33 * define DYNAMIC in this example for a dynamically allocated fifo.
34 *
35 * Otherwise the fifo storage will be a part of the fifo structure.
36 */
37#if 0
38#define DYNAMIC
39#endif
40
41/*
42 * struct kfifo_rec_ptr_1 and STRUCT_KFIFO_REC_1 can handle records of a
43 * length between 0 and 255 bytes.
44 *
45 * struct kfifo_rec_ptr_2 and STRUCT_KFIFO_REC_2 can handle records of a
46 * length between 0 and 65535 bytes.
47 */
48
49#ifdef DYNAMIC
50struct kfifo_rec_ptr_1 test;
51
52#else
53typedef STRUCT_KFIFO_REC_1(FIFO_SIZE) mytest;
54
55static mytest test;
56#endif
57
58static int __init testfunc(void)
59{
60 char buf[100];
61 unsigned int i;
62 unsigned int ret;
63 struct { unsigned char buf[6]; } hello = { "hello" };
64
65 printk(KERN_INFO "record fifo test start\n");
66
67 kfifo_in(&test, &hello, sizeof(hello));
68
69 /* show the size of the next record in the fifo */
70 printk(KERN_INFO "fifo peek len: %u\n", kfifo_peek_len(&test));
71
72 /* put in variable length data */
73 for (i = 0; i < 10; i++) {
74 memset(buf, 'a' + i, i + 1);
75 kfifo_in(&test, buf, i + 1);
76 }
77
78 printk(KERN_INFO "fifo len: %u\n", kfifo_len(&test));
79
80 /* show the first record without removing from the fifo */
81 ret = kfifo_out_peek(&test, buf, sizeof(buf));
82 if (ret)
83 printk(KERN_INFO "%.*s\n", ret, buf);
84
85 /* print out all records in the fifo */
86 while (!kfifo_is_empty(&test)) {
87 ret = kfifo_out(&test, buf, sizeof(buf));
88 printk(KERN_INFO "%.*s\n", ret, buf);
89 }
90
91 return 0;
92}
93
94static ssize_t fifo_write(struct file *file, const char __user *buf,
95 size_t count, loff_t *ppos)
96{
97 int ret;
98 unsigned int copied;
99
100 if (mutex_lock_interruptible(&write_lock))
101 return -ERESTARTSYS;
102
103 ret = kfifo_from_user(&test, buf, count, &copied);
104
105 mutex_unlock(&write_lock);
106
107 return ret ? ret : copied;
108}
109
110static ssize_t fifo_read(struct file *file, char __user *buf,
111 size_t count, loff_t *ppos)
112{
113 int ret;
114 unsigned int copied;
115
116 if (mutex_lock_interruptible(&read_lock))
117 return -ERESTARTSYS;
118
119 ret = kfifo_to_user(&test, buf, count, &copied);
120
121 mutex_unlock(&read_lock);
122
123 return ret ? ret : copied;
124}
125
126static const struct file_operations fifo_fops = {
127 .owner = THIS_MODULE,
128 .read = fifo_read,
129 .write = fifo_write,
130};
131
132static int __init example_init(void)
133{
134#ifdef DYNAMIC
135 int ret;
136
137 ret = kfifo_alloc(&test, FIFO_SIZE, GFP_KERNEL);
138 if (ret) {
139 printk(KERN_ERR "error kfifo_alloc\n");
140 return ret;
141 }
142#else
143 INIT_KFIFO(test);
144#endif
145 testfunc();
146
147 if (proc_create(PROC_FIFO, 0, NULL, &fifo_fops) == NULL) {
148#ifdef DYNAMIC
149 kfifo_free(&test);
150#endif
151 return -ENOMEM;
152 }
153 return 0;
154}
155
156static void __exit example_exit(void)
157{
158 remove_proc_entry(PROC_FIFO, NULL);
159#ifdef DYNAMIC
160 kfifo_free(&test);
161#endif
162}
163
164module_init(example_init);
165module_exit(example_exit);
166MODULE_LICENSE("GPL");
167MODULE_AUTHOR("Stefani Seibold <stefani@seibold.net>");