Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Stefani Seibold and committed by
Linus Torvalds
5bf2b193 2e956fb3

+614 -1
+10
samples/Kconfig
··· 44 44 help 45 45 This builds kernel hardware breakpoint example modules. 46 46 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 + 47 57 endif # SAMPLES
+1 -1
samples/Makefile
··· 1 1 # Makefile for Linux samples code 2 2 3 3 obj-$(CONFIG_SAMPLES) += kobject/ kprobes/ tracepoints/ trace_events/ \ 4 - hw_breakpoint/ 4 + hw_breakpoint/ kfifo/
+1
samples/kfifo/Makefile
··· 1 + obj-$(CONFIG_SAMPLE_KFIFO) += bytestream-example.o dma-example.o inttype-example.o record-example.o
+163
samples/kfifo/bytestream-example.c
··· 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>");
+115
samples/kfifo/dma-example.c
··· 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>");
+157
samples/kfifo/inttype-example.c
··· 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>");
+167
samples/kfifo/record-example.c
··· 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>");