22 #include <linux/kernel.h>
23 #include <linux/export.h>
24 #include <linux/slab.h>
33 static inline unsigned int kfifo_unused(
struct __kfifo *
fifo)
35 return (fifo->
mask + 1) - (fifo->
in - fifo->
out);
64 fifo->
mask = size - 1;
82 unsigned int size,
size_t esize)
98 fifo->
mask = size - 1;
104 static void kfifo_copy_in(
struct __kfifo *fifo,
const void *
src,
105 unsigned int len,
unsigned int off)
108 unsigned int esize = fifo->
esize;
117 l =
min(len, size - off);
129 const void *
buf,
unsigned int len)
133 l = kfifo_unused(fifo);
137 kfifo_copy_in(fifo, buf, len, fifo->
in);
143 static void kfifo_copy_out(
struct __kfifo *fifo,
void *
dst,
144 unsigned int len,
unsigned int off)
146 unsigned int size = fifo->
mask + 1;
147 unsigned int esize = fifo->
esize;
156 l =
min(len, size - off);
168 void *
buf,
unsigned int len)
172 l = fifo->
in - fifo->
out;
176 kfifo_copy_out(fifo, buf, len, fifo->
out);
182 void *
buf,
unsigned int len)
190 static unsigned long kfifo_copy_from_user(
struct __kfifo *fifo,
191 const void __user *
from,
unsigned int len,
unsigned int off,
192 unsigned int *copied)
194 unsigned int size = fifo->
mask + 1;
195 unsigned int esize = fifo->
esize;
205 l =
min(len, size - off);
226 unsigned long len,
unsigned int *copied)
230 unsigned int esize = fifo->
esize;
236 l = kfifo_unused(fifo);
240 ret = kfifo_copy_from_user(fifo, from, len, fifo->
in, copied);
251 static unsigned long kfifo_copy_to_user(
struct __kfifo *fifo,
void __user *to,
252 unsigned int len,
unsigned int off,
unsigned int *copied)
256 unsigned int size = fifo->
mask + 1;
257 unsigned int esize = fifo->
esize;
265 l =
min(len, size - off);
286 unsigned long len,
unsigned int *copied)
290 unsigned int esize = fifo->
esize;
296 l = fifo->
in - fifo->
out;
299 ret = kfifo_copy_to_user(fifo, to, len, fifo->
out, copied);
311 int nents,
unsigned int len)
336 sg_set_page(sgl, page, l - off, off);
338 if (++n == nents || sgl ==
NULL)
345 sg_set_page(sgl, page, len, off);
350 int nents,
unsigned int len,
unsigned int off)
352 unsigned int size = fifo->
mask + 1;
353 unsigned int esize = fifo->
esize;
363 l =
min(len, size - off);
365 n = setup_sgl_buf(sgl, fifo->
data + off, nents, l);
366 n += setup_sgl_buf(sgl + n, fifo->
data, nents - n, len - l);
372 struct scatterlist *sgl,
int nents,
unsigned int len)
376 l = kfifo_unused(fifo);
380 return setup_sgl(fifo, sgl, nents, len, fifo->
in);
385 struct scatterlist *sgl,
int nents,
unsigned int len)
389 l = fifo->
in - fifo->
out;
393 return setup_sgl(fifo, sgl, nents, len, fifo->
out);
399 unsigned int max = (1 << (recsize << 3)) - 1;
407 #define __KFIFO_PEEK(data, out, mask) \
408 ((data)[(out) & (mask)])
413 static unsigned int __kfifo_peek_n(
struct __kfifo *fifo,
size_t recsize)
427 #define __KFIFO_POKE(data, in, mask, val) \
429 (data)[(in) & (mask)] = (unsigned char)(val) \
436 static void __kfifo_poke_n(
struct __kfifo *fifo,
unsigned int n,
size_t recsize)
449 return __kfifo_peek_n(fifo, recsize);
454 unsigned int len,
size_t recsize)
456 if (len + recsize > kfifo_unused(fifo))
459 __kfifo_poke_n(fifo, len, recsize);
461 kfifo_copy_in(fifo, buf, len, fifo->
in + recsize);
462 fifo->
in += len + recsize;
467 static unsigned int kfifo_out_copy_r(
struct __kfifo *fifo,
468 void *buf,
unsigned int len,
size_t recsize,
unsigned int *n)
470 *n = __kfifo_peek_n(fifo, recsize);
475 kfifo_copy_out(fifo, buf, len, fifo->
out + recsize);
480 unsigned int len,
size_t recsize)
484 if (fifo->
in == fifo->
out)
487 return kfifo_out_copy_r(fifo, buf, len, recsize, &n);
492 unsigned int len,
size_t recsize)
496 if (fifo->
in == fifo->
out)
499 len = kfifo_out_copy_r(fifo, buf, len, recsize, &n);
500 fifo->
out += n + recsize;
509 n = __kfifo_peek_n(fifo, recsize);
510 fifo->
out += n + recsize;
515 unsigned long len,
unsigned int *copied,
size_t recsize)
521 if (len + recsize > kfifo_unused(fifo)) {
526 __kfifo_poke_n(fifo, len, recsize);
528 ret = kfifo_copy_from_user(fifo, from, len, fifo->
in + recsize, copied);
533 fifo->
in += len + recsize;
539 unsigned long len,
unsigned int *copied,
size_t recsize)
544 if (fifo->
in == fifo->
out) {
549 n = __kfifo_peek_n(fifo, recsize);
553 ret = kfifo_copy_to_user(fifo, to, len, fifo->
out + recsize, copied);
558 fifo->
out += n + recsize;
564 struct scatterlist *sgl,
int nents,
unsigned int len,
size_t recsize)
571 if (len + recsize > kfifo_unused(fifo))
574 return setup_sgl(fifo, sgl, nents, len, fifo->
in + recsize);
579 unsigned int len,
size_t recsize)
582 __kfifo_poke_n(fifo, len, recsize);
583 fifo->
in += len + recsize;
588 struct scatterlist *sgl,
int nents,
unsigned int len,
size_t recsize)
595 if (len + recsize > fifo->
in - fifo->
out)
598 return setup_sgl(fifo, sgl, nents, len, fifo->
out + recsize);
606 len = __kfifo_peek_n(fifo, recsize);
607 fifo->
out += len + recsize;