drm/amdgpu/nv: update VCN 3 max HEVC encoding resolution
[linux-2.6-block.git] / samples / kfifo / bytestream-example.c
CommitLineData
912d0f0b 1// SPDX-License-Identifier: GPL-2.0-only
5bf2b193
SS
2/*
3 * Sample kfifo byte stream implementation
4 *
5 * Copyright (C) 2010 Stefani Seibold <stefani@seibold.net>
5bf2b193
SS
6 */
7
8#include <linux/init.h>
9#include <linux/module.h>
10#include <linux/proc_fs.h>
11#include <linux/mutex.h>
12#include <linux/kfifo.h>
13
14/*
15 * This module shows how to create a byte stream fifo.
16 */
17
18/* fifo size in elements (bytes) */
19#define FIFO_SIZE 32
20
21/* name of the proc entry */
22#define PROC_FIFO "bytestream-fifo"
23
24/* lock for procfs read access */
880732ae 25static DEFINE_MUTEX(read_access);
5bf2b193
SS
26
27/* lock for procfs write access */
880732ae 28static DEFINE_MUTEX(write_access);
5bf2b193
SS
29
30/*
31 * define DYNAMIC in this example for a dynamically allocated fifo.
32 *
33 * Otherwise the fifo storage will be a part of the fifo structure.
34 */
35#if 0
36#define DYNAMIC
37#endif
38
39#ifdef DYNAMIC
40static struct kfifo test;
41#else
42static DECLARE_KFIFO(test, unsigned char, FIFO_SIZE);
43#endif
44
a25effa4 45static const unsigned char expected_result[FIFO_SIZE] = {
2aaf2092
AR
46 3, 4, 5, 6, 7, 8, 9, 0,
47 1, 20, 21, 22, 23, 24, 25, 26,
48 27, 28, 29, 30, 31, 32, 33, 34,
49 35, 36, 37, 38, 39, 40, 41, 42,
50};
51
5bf2b193
SS
52static int __init testfunc(void)
53{
54 unsigned char buf[6];
2aaf2092 55 unsigned char i, j;
5bf2b193
SS
56 unsigned int ret;
57
58 printk(KERN_INFO "byte stream fifo test start\n");
59
60 /* put string into the fifo */
61 kfifo_in(&test, "hello", 5);
62
63 /* put values into the fifo */
64 for (i = 0; i != 10; i++)
498d319b 65 kfifo_put(&test, i);
5bf2b193
SS
66
67 /* show the number of used elements */
68 printk(KERN_INFO "fifo len: %u\n", kfifo_len(&test));
69
70 /* get max of 5 bytes from the fifo */
71 i = kfifo_out(&test, buf, 5);
72 printk(KERN_INFO "buf: %.*s\n", i, buf);
73
74 /* get max of 2 elements from the fifo */
75 ret = kfifo_out(&test, buf, 2);
76 printk(KERN_INFO "ret: %d\n", ret);
77 /* and put it back to the end of the fifo */
78 ret = kfifo_in(&test, buf, ret);
79 printk(KERN_INFO "ret: %d\n", ret);
80
5ddf8391
AR
81 /* skip first element of the fifo */
82 printk(KERN_INFO "skip 1st element\n");
83 kfifo_skip(&test);
84
5bf2b193 85 /* put values into the fifo until is full */
498d319b 86 for (i = 20; kfifo_put(&test, i); i++)
5bf2b193
SS
87 ;
88
89 printk(KERN_INFO "queue len: %u\n", kfifo_len(&test));
90
a25effa4
AR
91 /* show the first value without removing from the fifo */
92 if (kfifo_peek(&test, &i))
93 printk(KERN_INFO "%d\n", i);
94
2aaf2092
AR
95 /* check the correctness of all values in the fifo */
96 j = 0;
97 while (kfifo_get(&test, &i)) {
a25effa4 98 printk(KERN_INFO "item = %d\n", i);
2aaf2092
AR
99 if (i != expected_result[j++]) {
100 printk(KERN_WARNING "value mismatch: test failed\n");
101 return -EIO;
102 }
103 }
104 if (j != ARRAY_SIZE(expected_result)) {
105 printk(KERN_WARNING "size mismatch: test failed\n");
106 return -EIO;
107 }
108 printk(KERN_INFO "test passed\n");
5bf2b193
SS
109
110 return 0;
111}
112
113static ssize_t fifo_write(struct file *file, const char __user *buf,
114 size_t count, loff_t *ppos)
115{
116 int ret;
117 unsigned int copied;
118
880732ae 119 if (mutex_lock_interruptible(&write_access))
5bf2b193
SS
120 return -ERESTARTSYS;
121
122 ret = kfifo_from_user(&test, buf, count, &copied);
123
880732ae 124 mutex_unlock(&write_access);
926ee00e
DC
125 if (ret)
126 return ret;
5bf2b193 127
926ee00e 128 return copied;
5bf2b193
SS
129}
130
131static ssize_t fifo_read(struct file *file, char __user *buf,
132 size_t count, loff_t *ppos)
133{
134 int ret;
135 unsigned int copied;
136
880732ae 137 if (mutex_lock_interruptible(&read_access))
5bf2b193
SS
138 return -ERESTARTSYS;
139
140 ret = kfifo_to_user(&test, buf, count, &copied);
141
880732ae 142 mutex_unlock(&read_access);
926ee00e
DC
143 if (ret)
144 return ret;
5bf2b193 145
926ee00e 146 return copied;
5bf2b193
SS
147}
148
97a32539
AD
149static const struct proc_ops fifo_proc_ops = {
150 .proc_read = fifo_read,
151 .proc_write = fifo_write,
152 .proc_lseek = noop_llseek,
5bf2b193
SS
153};
154
155static int __init example_init(void)
156{
157#ifdef DYNAMIC
158 int ret;
159
160 ret = kfifo_alloc(&test, FIFO_SIZE, GFP_KERNEL);
161 if (ret) {
162 printk(KERN_ERR "error kfifo_alloc\n");
163 return ret;
164 }
165#else
166 INIT_KFIFO(test);
167#endif
2aaf2092
AR
168 if (testfunc() < 0) {
169#ifdef DYNAMIC
170 kfifo_free(&test);
171#endif
172 return -EIO;
173 }
5bf2b193 174
97a32539 175 if (proc_create(PROC_FIFO, 0, NULL, &fifo_proc_ops) == NULL) {
5bf2b193
SS
176#ifdef DYNAMIC
177 kfifo_free(&test);
178#endif
179 return -ENOMEM;
180 }
181 return 0;
182}
183
184static void __exit example_exit(void)
185{
186 remove_proc_entry(PROC_FIFO, NULL);
187#ifdef DYNAMIC
188 kfifo_free(&test);
189#endif
190}
191
192module_init(example_init);
193module_exit(example_exit);
194MODULE_LICENSE("GPL");
195MODULE_AUTHOR("Stefani Seibold <stefani@seibold.net>");