Commit 5bf2b19320ec31d094d7370fdf536f7fd91fd799

Authored by Stefani Seibold
Committed by Linus Torvalds
1 parent 2e956fb320

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>

Showing 7 changed files with 614 additions and 1 deletions Side-by-side Diff

... ... @@ -44,5 +44,15 @@
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 # Makefile for Linux samples code
2 2  
3 3 obj-$(CONFIG_SAMPLES) += kobject/ kprobes/ tracepoints/ trace_events/ \
4   - hw_breakpoint/
  4 + hw_breakpoint/ kfifo/
samples/kfifo/Makefile
  1 +obj-$(CONFIG_SAMPLE_KFIFO) += bytestream-example.o dma-example.o inttype-example.o record-example.o
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>");
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>");
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>");
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>");