History

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>

Stefani Seibold committed 16 years ago

Commit 5bf2b191 parent 2e956fb7 files · +614 −1Browse files

Unified · Split

7 files
  1. samples/Kconfig +10 −0
  2. samples/Makefile +1 −1
  3. samples/kfifo/Makefile +1 −0
  4. samples/kfifo/bytestream-example.c +163 −0
  5. samples/kfifo/dma-example.c +115 −0
  6. samples/kfifo/inttype-example.c +157 −0
  7. samples/kfifo/record-example.c +167 −0
samples/Kconfig+10−0
@@ -44,4 +44,14 @@ config SAMPLE_HW_BREAKPOINT · 43 unmodified lines
4444 help
4545 This builds kernel hardware breakpoint example modules.
4646
47+config 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+
4757 endif # SAMPLES
samples/Makefile+1−1
@@ -1,4 +1,4 @@
11 # Makefile for Linux samples code
22
33 obj-$(CONFIG_SAMPLES) += kobject/ kprobes/ tracepoints/ trace_events/ \
4− hw_breakpoint/
4+ hw_breakpoint/ kfifo/
samples/kfifo/Makefile+1−0
@@ -0,0 +1 @@
1+obj-$(CONFIG_SAMPLE_KFIFO) += bytestream-example.o dma-example.o inttype-example.o record-example.o
samples/kfifo/bytestream-example.c+163−0
@@ -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 */
27+static DEFINE_MUTEX(read_lock);
28+
29+/* lock for procfs write access */
30+static 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
42+static struct kfifo test;
43+#else
44+static DECLARE_KFIFO(test, unsigned char, FIFO_SIZE);
45+#endif
46+
47+static 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+
90+static 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+
106+static 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+
122+static const struct file_operations fifo_fops = {
123+ .owner = THIS_MODULE,
124+ .read = fifo_read,
125+ .write = fifo_write,
126+};
127+
128+static 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+
152+static void __exit example_exit(void)
153+{
154+ remove_proc_entry(PROC_FIFO, NULL);
155+#ifdef DYNAMIC
156+ kfifo_free(&test);
157+#endif
158+}
159+
160+module_init(example_init);
161+module_exit(example_exit);
162+MODULE_LICENSE("GPL");
163+MODULE_AUTHOR("Stefani Seibold <stefani@seibold.net>");
samples/kfifo/dma-example.c+115−0
@@ -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+
21+static struct kfifo fifo;
22+
23+static 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+
105+static void __exit example_exit(void)
106+{
107+#ifdef DYNAMIC
108+ kfifo_free(&test);
109+#endif
110+}
111+
112+module_init(example_init);
113+module_exit(example_exit);
114+MODULE_LICENSE("GPL");
115+MODULE_AUTHOR("Stefani Seibold <stefani@seibold.net>");
samples/kfifo/inttype-example.c+157−0
@@ -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 */
27+static DEFINE_MUTEX(read_lock);
28+
29+/* lock for procfs write access */
30+static 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
42+static DECLARE_KFIFO_PTR(test, int);
43+#else
44+static DEFINE_KFIFO(test, int, FIFO_SIZE);
45+#endif
46+
47+static 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+
86+static 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+
102+static 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+
118+static const struct file_operations fifo_fops = {
119+ .owner = THIS_MODULE,
120+ .read = fifo_read,
121+ .write = fifo_write,
122+};
123+
124+static 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+
146+static void __exit example_exit(void)
147+{
148+ remove_proc_entry(PROC_FIFO, NULL);
149+#ifdef DYNAMIC
150+ kfifo_free(&test);
151+#endif
152+}
153+
154+module_init(example_init);
155+module_exit(example_exit);
156+MODULE_LICENSE("GPL");
157+MODULE_AUTHOR("Stefani Seibold <stefani@seibold.net>");
samples/kfifo/record-example.c+167−0
@@ -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 */
27+static DEFINE_MUTEX(read_lock);
28+
29+/* lock for procfs write access */
30+static 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
50+struct kfifo_rec_ptr_1 test;
51+
52+#else
53+typedef STRUCT_KFIFO_REC_1(FIFO_SIZE) mytest;
54+
55+static mytest test;
56+#endif
57+
58+static 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+
94+static 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+
110+static 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+
126+static const struct file_operations fifo_fops = {
127+ .owner = THIS_MODULE,
128+ .read = fifo_read,
129+ .write = fifo_write,
130+};
131+
132+static 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+
156+static void __exit example_exit(void)
157+{
158+ remove_proc_entry(PROC_FIFO, NULL);
159+#ifdef DYNAMIC
160+ kfifo_free(&test);
161+#endif
162+}
163+
164+module_init(example_init);
165+module_exit(example_exit);
166+MODULE_LICENSE("GPL");
167+MODULE_AUTHOR("Stefani Seibold <stefani@seibold.net>");

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t