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

kfifo: add the new generic kfifo API

Add the new version of the kfifo API files kfifo.c and kfifo.h.

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
4201d9a8 4457d984

+1446
+844
include/linux/kfifo-new.h
··· 1 + /* 2 + * A generic kernel FIFO implementation 3 + * 4 + * Copyright (C) 2009/2010 Stefani Seibold <stefani@seibold.net> 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License as published by 8 + * the Free Software Foundation; either version 2 of the License, or 9 + * (at your option) any later version. 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + * 16 + * You should have received a copy of the GNU General Public License 17 + * along with this program; if not, write to the Free Software 18 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 + * 20 + */ 21 + 22 + #ifndef _LINUX_KFIFO_H 23 + #define _LINUX_KFIFO_H 24 + 25 + /* 26 + * How to porting drivers to the new generic FIFO API: 27 + * 28 + * - Modify the declaration of the "struct kfifo *" object into a 29 + * in-place "struct kfifo" object 30 + * - Init the in-place object with kfifo_alloc() or kfifo_init() 31 + * Note: The address of the in-place "struct kfifo" object must be 32 + * passed as the first argument to this functions 33 + * - Replace the use of __kfifo_put into kfifo_in and __kfifo_get 34 + * into kfifo_out 35 + * - Replace the use of kfifo_put into kfifo_in_spinlocked and kfifo_get 36 + * into kfifo_out_spinlocked 37 + * Note: the spinlock pointer formerly passed to kfifo_init/kfifo_alloc 38 + * must be passed now to the kfifo_in_spinlocked and kfifo_out_spinlocked 39 + * as the last parameter 40 + * - The formerly __kfifo_* functions are renamed into kfifo_* 41 + */ 42 + 43 + /* 44 + * Note about locking : There is no locking required until only * one reader 45 + * and one writer is using the fifo and no kfifo_reset() will be * called 46 + * kfifo_reset_out() can be safely used, until it will be only called 47 + * in the reader thread. 48 + * For multiple writer and one reader there is only a need to lock the writer. 49 + * And vice versa for only one writer and multiple reader there is only a need 50 + * to lock the reader. 51 + */ 52 + 53 + #include <linux/kernel.h> 54 + #include <linux/spinlock.h> 55 + #include <linux/stddef.h> 56 + #include <linux/scatterlist.h> 57 + 58 + struct __kfifo { 59 + unsigned int in; 60 + unsigned int out; 61 + unsigned int mask; 62 + unsigned int esize; 63 + void *data; 64 + }; 65 + 66 + #define __STRUCT_KFIFO_COMMON(datatype, recsize, ptrtype) \ 67 + union { \ 68 + struct __kfifo kfifo; \ 69 + datatype *type; \ 70 + char (*rectype)[recsize]; \ 71 + ptrtype *ptr; \ 72 + const ptrtype *ptr_const; \ 73 + } 74 + 75 + #define __STRUCT_KFIFO(type, size, recsize, ptrtype) \ 76 + { \ 77 + __STRUCT_KFIFO_COMMON(type, recsize, ptrtype); \ 78 + type buf[((size < 2) || (size & (size - 1))) ? -1 : size]; \ 79 + } 80 + 81 + #define STRUCT_KFIFO(type, size) \ 82 + struct __STRUCT_KFIFO(type, size, 0, type) 83 + 84 + #define __STRUCT_KFIFO_PTR(type, recsize, ptrtype) \ 85 + { \ 86 + __STRUCT_KFIFO_COMMON(type, recsize, ptrtype); \ 87 + type buf[0]; \ 88 + } 89 + 90 + #define STRUCT_KFIFO_PTR(type) \ 91 + struct __STRUCT_KFIFO_PTR(type, 0, type) 92 + 93 + /* 94 + * define compatibility "struct kfifo" for dynamic allocated fifos 95 + */ 96 + struct kfifo __STRUCT_KFIFO_PTR(unsigned char, 0, void); 97 + 98 + #define STRUCT_KFIFO_REC_1(size) \ 99 + struct __STRUCT_KFIFO(unsigned char, size, 1, void) 100 + 101 + #define STRUCT_KFIFO_REC_2(size) \ 102 + struct __STRUCT_KFIFO(unsigned char, size, 2, void) 103 + 104 + /* 105 + * define kfifo_rec types 106 + */ 107 + struct kfifo_rec_ptr_1 __STRUCT_KFIFO_PTR(unsigned char, 1, void); 108 + struct kfifo_rec_ptr_2 __STRUCT_KFIFO_PTR(unsigned char, 2, void); 109 + 110 + /* 111 + * helper macro to distinguish between real in place fifo where the fifo 112 + * array is a part of the structure and the fifo type where the array is 113 + * outside of the fifo structure. 114 + */ 115 + #define __is_kfifo_ptr(fifo) (sizeof(*fifo) == sizeof(struct __kfifo)) 116 + 117 + /** 118 + * DECLARE_KFIFO_PTR - macro to declare a fifo pointer object 119 + * @fifo: name of the declared fifo 120 + * @type: type of the fifo elements 121 + */ 122 + #define DECLARE_KFIFO_PTR(fifo, type) STRUCT_KFIFO_PTR(type) fifo 123 + 124 + /** 125 + * DECLARE_KFIFO - macro to declare a fifo object 126 + * @fifo: name of the declared fifo 127 + * @type: type of the fifo elements 128 + * @size: the number of elements in the fifo, this must be a power of 2 129 + */ 130 + #define DECLARE_KFIFO(fifo, type, size) STRUCT_KFIFO(type, size) fifo 131 + 132 + /** 133 + * INIT_KFIFO - Initialize a fifo declared by DECLARE_KFIFO 134 + * @fifo: name of the declared fifo datatype 135 + */ 136 + #define INIT_KFIFO(fifo) \ 137 + (void)({ \ 138 + typeof(&(fifo)) __tmp = &(fifo); \ 139 + struct __kfifo *__kfifo = &__tmp->kfifo; \ 140 + __kfifo->in = 0; \ 141 + __kfifo->out = 0; \ 142 + __kfifo->mask = __is_kfifo_ptr(__tmp) ? 0 : ARRAY_SIZE(__tmp->buf) - 1;\ 143 + __kfifo->esize = sizeof(*__tmp->buf); \ 144 + __kfifo->data = __is_kfifo_ptr(__tmp) ? NULL : __tmp->buf; \ 145 + }) 146 + 147 + /** 148 + * DEFINE_KFIFO - macro to define and initialize a fifo 149 + * @fifo: name of the declared fifo datatype 150 + * @type: type of the fifo elements 151 + * @size: the number of elements in the fifo, this must be a power of 2 152 + * 153 + * Note: the macro can be used for global and local fifo data type variables. 154 + */ 155 + #define DEFINE_KFIFO(fifo, type, size) \ 156 + DECLARE_KFIFO(fifo, type, size) = \ 157 + (typeof(fifo)) { \ 158 + { \ 159 + { \ 160 + .in = 0, \ 161 + .out = 0, \ 162 + .mask = __is_kfifo_ptr(&(fifo)) ? \ 163 + 0 : \ 164 + ARRAY_SIZE((fifo).buf) - 1, \ 165 + .esize = sizeof(*(fifo).buf), \ 166 + .data = __is_kfifo_ptr(&(fifo)) ? \ 167 + NULL : \ 168 + (fifo).buf, \ 169 + } \ 170 + } \ 171 + } 172 + 173 + 174 + static inline unsigned int __must_check 175 + __kfifo_must_check_helper(unsigned int val) 176 + { 177 + return val; 178 + } 179 + 180 + /** 181 + * kfifo_initialized - Check if the fifo is initialized 182 + * @fifo: address of the fifo to check 183 + * 184 + * Return %true if fifo is initialized, otherwise %false. 185 + * Assumes the fifo was 0 before. 186 + */ 187 + #define kfifo_initialized(fifo) ((fifo)->kfifo.mask) 188 + 189 + /** 190 + * kfifo_esize - returns the size of the element managed by the fifo 191 + * @fifo: address of the fifo to be used 192 + */ 193 + #define kfifo_esize(fifo) ((fifo)->kfifo.esize) 194 + 195 + /** 196 + * kfifo_recsize - returns the size of the record length field 197 + * @fifo: address of the fifo to be used 198 + */ 199 + #define kfifo_recsize(fifo) (sizeof(*(fifo)->rectype)) 200 + 201 + /** 202 + * kfifo_size - returns the size of the fifo in elements 203 + * @fifo: address of the fifo to be used 204 + */ 205 + #define kfifo_size(fifo) ((fifo)->kfifo.mask + 1) 206 + 207 + /** 208 + * kfifo_reset - removes the entire fifo content 209 + * @fifo: address of the fifo to be used 210 + * 211 + * Note: usage of kfifo_reset() is dangerous. It should be only called when the 212 + * fifo is exclusived locked or when it is secured that no other thread is 213 + * accessing the fifo. 214 + */ 215 + #define kfifo_reset(fifo) \ 216 + (void)({ \ 217 + typeof(fifo + 1) __tmp = (fifo); \ 218 + __tmp->kfifo.in = __tmp->kfifo.out = 0; \ 219 + }) 220 + 221 + /** 222 + * kfifo_reset_out - skip fifo content 223 + * @fifo: address of the fifo to be used 224 + * 225 + * Note: The usage of kfifo_reset_out() is safe until it will be only called 226 + * from the reader thread and there is only one concurrent reader. Otherwise 227 + * it is dangerous and must be handled in the same way as kfifo_reset(). 228 + */ 229 + #define kfifo_reset_out(fifo) \ 230 + (void)({ \ 231 + typeof(fifo + 1) __tmp = (fifo); \ 232 + __tmp->kfifo.out = __tmp->kfifo.in; \ 233 + }) 234 + 235 + /** 236 + * kfifo_len - returns the number of used elements in the fifo 237 + * @fifo: address of the fifo to be used 238 + */ 239 + #define kfifo_len(fifo) \ 240 + ({ \ 241 + typeof(fifo + 1) __tmpl = (fifo); \ 242 + __tmpl->kfifo.in - __tmpl->kfifo.out; \ 243 + }) 244 + 245 + /** 246 + * kfifo_is_empty - returns true if the fifo is empty 247 + * @fifo: address of the fifo to be used 248 + */ 249 + #define kfifo_is_empty(fifo) \ 250 + ({ \ 251 + typeof(fifo + 1) __tmpq = (fifo); \ 252 + __tmpq->kfifo.in == __tmpq->kfifo.out; \ 253 + }) 254 + 255 + /** 256 + * kfifo_is_full - returns true if the fifo is full 257 + * @fifo: address of the fifo to be used 258 + */ 259 + #define kfifo_is_full(fifo) \ 260 + ({ \ 261 + typeof(fifo + 1) __tmpq = (fifo); \ 262 + kfifo_len(__tmpq) > __tmpq->kfifo.mask; \ 263 + }) 264 + 265 + /** 266 + * kfifo_avail - returns the number of unused elements in the fifo 267 + * @fifo: address of the fifo to be used 268 + */ 269 + #define kfifo_avail(fifo) \ 270 + __kfifo_must_check_helper( \ 271 + ({ \ 272 + typeof(fifo + 1) __tmpq = (fifo); \ 273 + const size_t __recsize = sizeof(*__tmpq->rectype); \ 274 + unsigned int __avail = kfifo_size(__tmpq) - kfifo_len(__tmpq); \ 275 + (__recsize) ? ((__avail <= __recsize) ? 0 : \ 276 + __kfifo_max_r(__avail - __recsize, __recsize)) : \ 277 + __avail; \ 278 + }) \ 279 + ) 280 + 281 + /** 282 + * kfifo_skip - skip output data 283 + * @fifo: address of the fifo to be used 284 + */ 285 + #define kfifo_skip(fifo) \ 286 + (void)({ \ 287 + typeof(fifo + 1) __tmp = (fifo); \ 288 + const size_t __recsize = sizeof(*__tmp->rectype); \ 289 + struct __kfifo *__kfifo = &__tmp->kfifo; \ 290 + if (__recsize) \ 291 + __kfifo_skip_r(__kfifo, __recsize); \ 292 + else \ 293 + __kfifo->out++; \ 294 + }) 295 + 296 + /** 297 + * kfifo_peek_len - gets the size of the next fifo record 298 + * @fifo: address of the fifo to be used 299 + * 300 + * This function returns the size of the next fifo record in number of bytes. 301 + */ 302 + #define kfifo_peek_len(fifo) \ 303 + __kfifo_must_check_helper( \ 304 + ({ \ 305 + typeof(fifo + 1) __tmp = (fifo); \ 306 + const size_t __recsize = sizeof(*__tmp->rectype); \ 307 + struct __kfifo *__kfifo = &__tmp->kfifo; \ 308 + (!__recsize) ? kfifo_len(__tmp) * sizeof(*__tmp->type) : \ 309 + __kfifo_len_r(__kfifo, __recsize); \ 310 + }) \ 311 + ) 312 + 313 + /** 314 + * kfifo_alloc - dynamically allocates a new fifo buffer 315 + * @fifo: pointer to the fifo 316 + * @size: the number of elements in the fifo, this must be a power of 2 317 + * @gfp_mask: get_free_pages mask, passed to kmalloc() 318 + * 319 + * This macro dynamically allocates a new fifo buffer. 320 + * 321 + * The numer of elements will be rounded-up to a power of 2. 322 + * The fifo will be release with kfifo_free(). 323 + * Return 0 if no error, otherwise an error code. 324 + */ 325 + #define kfifo_alloc(fifo, size, gfp_mask) \ 326 + __kfifo_must_check_helper( \ 327 + ({ \ 328 + typeof(fifo + 1) __tmp = (fifo); \ 329 + struct __kfifo *__kfifo = &__tmp->kfifo; \ 330 + __is_kfifo_ptr(__tmp) ? \ 331 + __kfifo_alloc(__kfifo, size, sizeof(*__tmp->type), gfp_mask) : \ 332 + -EINVAL; \ 333 + }) \ 334 + ) 335 + 336 + /** 337 + * kfifo_free - frees the fifo 338 + * @fifo: the fifo to be freed 339 + */ 340 + #define kfifo_free(fifo) \ 341 + ({ \ 342 + typeof(fifo + 1) __tmp = (fifo); \ 343 + struct __kfifo *__kfifo = &__tmp->kfifo; \ 344 + if (__is_kfifo_ptr(__tmp)) \ 345 + __kfifo_free(__kfifo); \ 346 + }) 347 + 348 + /** 349 + * kfifo_init - initialize a fifo using a preallocated buffer 350 + * @fifo: the fifo to assign the buffer 351 + * @buffer: the preallocated buffer to be used 352 + * @size: the size of the internal buffer, this have to be a power of 2 353 + * 354 + * This macro initialize a fifo using a preallocated buffer. 355 + * 356 + * The numer of elements will be rounded-up to a power of 2. 357 + * Return 0 if no error, otherwise an error code. 358 + */ 359 + #define kfifo_init(fifo, buffer, size) \ 360 + ({ \ 361 + typeof(fifo + 1) __tmp = (fifo); \ 362 + struct __kfifo *__kfifo = &__tmp->kfifo; \ 363 + __is_kfifo_ptr(__tmp) ? \ 364 + __kfifo_init(__kfifo, buffer, size, sizeof(*__tmp->type)) : \ 365 + -EINVAL; \ 366 + }) 367 + 368 + /** 369 + * kfifo_put - put data into the fifo 370 + * @fifo: address of the fifo to be used 371 + * @val: the data to be added 372 + * 373 + * This macro copies the given value into the fifo. 374 + * It returns 0 if the fifo was full. Otherwise it returns the number 375 + * processed elements. 376 + * 377 + * Note that with only one concurrent reader and one concurrent 378 + * writer, you don't need extra locking to use these macro. 379 + */ 380 + #define kfifo_put(fifo, val) \ 381 + ({ \ 382 + typeof(fifo + 1) __tmp = (fifo); \ 383 + typeof(val + 1) __val = (val); \ 384 + unsigned int __ret; \ 385 + const size_t __recsize = sizeof(*__tmp->rectype); \ 386 + struct __kfifo *__kfifo = &__tmp->kfifo; \ 387 + if (0) { \ 388 + typeof(__tmp->ptr_const) __dummy __attribute__ ((unused)); \ 389 + __dummy = (typeof(__val))NULL; \ 390 + } \ 391 + if (__recsize) \ 392 + __ret = __kfifo_in_r(__kfifo, __val, sizeof(*__val), \ 393 + __recsize); \ 394 + else { \ 395 + __ret = !kfifo_is_full(__tmp); \ 396 + if (__ret) { \ 397 + (__is_kfifo_ptr(__tmp) ? \ 398 + ((typeof(__tmp->type))__kfifo->data) : \ 399 + (__tmp->buf) \ 400 + )[__kfifo->in & __tmp->kfifo.mask] = \ 401 + *(typeof(__tmp->type))__val; \ 402 + smp_wmb(); \ 403 + __kfifo->in++; \ 404 + } \ 405 + } \ 406 + __ret; \ 407 + }) 408 + 409 + /** 410 + * kfifo_get - get data from the fifo 411 + * @fifo: address of the fifo to be used 412 + * @val: the var where to store the data to be added 413 + * 414 + * This macro reads the data from the fifo. 415 + * It returns 0 if the fifo was empty. Otherwise it returns the number 416 + * processed elements. 417 + * 418 + * Note that with only one concurrent reader and one concurrent 419 + * writer, you don't need extra locking to use these macro. 420 + */ 421 + #define kfifo_get(fifo, val) \ 422 + __kfifo_must_check_helper( \ 423 + ({ \ 424 + typeof(fifo + 1) __tmp = (fifo); \ 425 + typeof(val + 1) __val = (val); \ 426 + unsigned int __ret; \ 427 + const size_t __recsize = sizeof(*__tmp->rectype); \ 428 + struct __kfifo *__kfifo = &__tmp->kfifo; \ 429 + if (0) \ 430 + __val = (typeof(__tmp->ptr))0; \ 431 + if (__recsize) \ 432 + __ret = __kfifo_out_r(__kfifo, __val, sizeof(*__val), \ 433 + __recsize); \ 434 + else { \ 435 + __ret = !kfifo_is_empty(__tmp); \ 436 + if (__ret) { \ 437 + *(typeof(__tmp->type))__val = \ 438 + (__is_kfifo_ptr(__tmp) ? \ 439 + ((typeof(__tmp->type))__kfifo->data) : \ 440 + (__tmp->buf) \ 441 + )[__kfifo->out & __tmp->kfifo.mask]; \ 442 + smp_wmb(); \ 443 + __kfifo->out++; \ 444 + } \ 445 + } \ 446 + __ret; \ 447 + }) \ 448 + ) 449 + 450 + /** 451 + * kfifo_peek - get data from the fifo without removing 452 + * @fifo: address of the fifo to be used 453 + * @val: the var where to store the data to be added 454 + * 455 + * This reads the data from the fifo without removing it from the fifo. 456 + * It returns 0 if the fifo was empty. Otherwise it returns the number 457 + * processed elements. 458 + * 459 + * Note that with only one concurrent reader and one concurrent 460 + * writer, you don't need extra locking to use these macro. 461 + */ 462 + #define kfifo_peek(fifo, val) \ 463 + __kfifo_must_check_helper( \ 464 + ({ \ 465 + typeof(fifo + 1) __tmp = (fifo); \ 466 + typeof(val + 1) __val = (val); \ 467 + unsigned int __ret; \ 468 + const size_t __recsize = sizeof(*__tmp->rectype); \ 469 + struct __kfifo *__kfifo = &__tmp->kfifo; \ 470 + if (0) \ 471 + __val = (typeof(__tmp->ptr))NULL; \ 472 + if (__recsize) \ 473 + __ret = __kfifo_out_peek_r(__kfifo, __val, sizeof(*__val), \ 474 + __recsize); \ 475 + else { \ 476 + __ret = !kfifo_is_empty(__tmp); \ 477 + if (__ret) { \ 478 + *(typeof(__tmp->type))__val = \ 479 + (__is_kfifo_ptr(__tmp) ? \ 480 + ((typeof(__tmp->type))__kfifo->data) : \ 481 + (__tmp->buf) \ 482 + )[__kfifo->out & __tmp->kfifo.mask]; \ 483 + smp_wmb(); \ 484 + } \ 485 + } \ 486 + __ret; \ 487 + }) \ 488 + ) 489 + 490 + /** 491 + * kfifo_in - put data into the fifo 492 + * @fifo: address of the fifo to be used 493 + * @buf: the data to be added 494 + * @n: number of elements to be added 495 + * 496 + * This macro copies the given buffer into the fifo and returns the 497 + * number of copied elements. 498 + * 499 + * Note that with only one concurrent reader and one concurrent 500 + * writer, you don't need extra locking to use these macro. 501 + */ 502 + #define kfifo_in(fifo, buf, n) \ 503 + ({ \ 504 + typeof(fifo + 1) __tmp = (fifo); \ 505 + typeof(buf + 1) __buf = (buf); \ 506 + unsigned long __n = (n); \ 507 + const size_t __recsize = sizeof(*__tmp->rectype); \ 508 + struct __kfifo *__kfifo = &__tmp->kfifo; \ 509 + if (0) { \ 510 + typeof(__tmp->ptr_const) __dummy __attribute__ ((unused)); \ 511 + __dummy = (typeof(__buf))NULL; \ 512 + } \ 513 + (__recsize) ?\ 514 + __kfifo_in_r(__kfifo, __buf, __n, __recsize) : \ 515 + __kfifo_in(__kfifo, __buf, __n); \ 516 + }) 517 + 518 + /** 519 + * kfifo_in_spinlocked - put data into the fifo using a spinlock for locking 520 + * @fifo: address of the fifo to be used 521 + * @buf: the data to be added 522 + * @n: number of elements to be added 523 + * @lock: pointer to the spinlock to use for locking 524 + * 525 + * This macro copies the given values buffer into the fifo and returns the 526 + * number of copied elements. 527 + */ 528 + #define kfifo_in_spinlocked(fifo, buf, n, lock) \ 529 + ({ \ 530 + unsigned long __flags; \ 531 + unsigned int __ret; \ 532 + spin_lock_irqsave(lock, __flags); \ 533 + __ret = kfifo_in(fifo, buf, n); \ 534 + spin_unlock_irqrestore(lock, __flags); \ 535 + __ret; \ 536 + }) 537 + 538 + /* alias for kfifo_in_spinlocked, will be removed in a future release */ 539 + #define kfifo_in_locked(fifo, buf, n, lock) \ 540 + kfifo_in_spinlocked(fifo, buf, n, lock) 541 + 542 + /** 543 + * kfifo_out - get data from the fifo 544 + * @fifo: address of the fifo to be used 545 + * @buf: pointer to the storage buffer 546 + * @n: max. number of elements to get 547 + * 548 + * This macro get some data from the fifo and return the numbers of elements 549 + * copied. 550 + * 551 + * Note that with only one concurrent reader and one concurrent 552 + * writer, you don't need extra locking to use these macro. 553 + */ 554 + #define kfifo_out(fifo, buf, n) \ 555 + __kfifo_must_check_helper( \ 556 + ({ \ 557 + typeof(fifo + 1) __tmp = (fifo); \ 558 + typeof(buf + 1) __buf = (buf); \ 559 + unsigned long __n = (n); \ 560 + const size_t __recsize = sizeof(*__tmp->rectype); \ 561 + struct __kfifo *__kfifo = &__tmp->kfifo; \ 562 + if (0) { \ 563 + typeof(__tmp->ptr) __dummy = NULL; \ 564 + __buf = __dummy; \ 565 + } \ 566 + (__recsize) ?\ 567 + __kfifo_out_r(__kfifo, __buf, __n, __recsize) : \ 568 + __kfifo_out(__kfifo, __buf, __n); \ 569 + }) \ 570 + ) 571 + 572 + /** 573 + * kfifo_out_spinlocked - get data from the fifo using a spinlock for locking 574 + * @fifo: address of the fifo to be used 575 + * @buf: pointer to the storage buffer 576 + * @n: max. number of elements to get 577 + * @lock: pointer to the spinlock to use for locking 578 + * 579 + * This macro get the data from the fifo and return the numbers of elements 580 + * copied. 581 + */ 582 + #define kfifo_out_spinlocked(fifo, buf, n, lock) \ 583 + __kfifo_must_check_helper( \ 584 + ({ \ 585 + unsigned long __flags; \ 586 + unsigned int __ret; \ 587 + spin_lock_irqsave(lock, __flags); \ 588 + __ret = kfifo_out(fifo, buf, n); \ 589 + spin_unlock_irqrestore(lock, __flags); \ 590 + __ret; \ 591 + }) \ 592 + ) 593 + 594 + /* alias for kfifo_out_spinlocked, will be removed in a future release */ 595 + #define kfifo_out_locked(fifo, buf, n, lock) \ 596 + kfifo_out_spinlocked(fifo, buf, n, lock) 597 + 598 + /** 599 + * kfifo_from_user - puts some data from user space into the fifo 600 + * @fifo: address of the fifo to be used 601 + * @from: pointer to the data to be added 602 + * @len: the length of the data to be added 603 + * @copied: pointer to output variable to store the number of copied bytes 604 + * 605 + * This macro copies at most @len bytes from the @from into the 606 + * fifo, depending of the available space and returns -EFAULT/0. 607 + * 608 + * Note that with only one concurrent reader and one concurrent 609 + * writer, you don't need extra locking to use these macro. 610 + */ 611 + #define kfifo_from_user(fifo, from, len, copied) \ 612 + __kfifo_must_check_helper( \ 613 + ({ \ 614 + typeof(fifo + 1) __tmp = (fifo); \ 615 + const void __user *__from = (from); \ 616 + unsigned int __len = (len); \ 617 + unsigned int *__copied = (copied); \ 618 + const size_t __recsize = sizeof(*__tmp->rectype); \ 619 + struct __kfifo *__kfifo = &__tmp->kfifo; \ 620 + (__recsize) ? \ 621 + __kfifo_from_user_r(__kfifo, __from, __len, __copied, __recsize) : \ 622 + __kfifo_from_user(__kfifo, __from, __len, __copied); \ 623 + }) \ 624 + ) 625 + 626 + /** 627 + * kfifo_to_user - copies data from the fifo into user space 628 + * @fifo: address of the fifo to be used 629 + * @to: where the data must be copied 630 + * @len: the size of the destination buffer 631 + * @copied: pointer to output variable to store the number of copied bytes 632 + * 633 + * This macro copies at most @len bytes from the fifo into the 634 + * @to buffer and returns -EFAULT/0. 635 + * 636 + * Note that with only one concurrent reader and one concurrent 637 + * writer, you don't need extra locking to use these macro. 638 + */ 639 + #define kfifo_to_user(fifo, to, len, copied) \ 640 + __kfifo_must_check_helper( \ 641 + ({ \ 642 + typeof(fifo + 1) __tmp = (fifo); \ 643 + void __user *__to = (to); \ 644 + unsigned int __len = (len); \ 645 + unsigned int *__copied = (copied); \ 646 + const size_t __recsize = sizeof(*__tmp->rectype); \ 647 + struct __kfifo *__kfifo = &__tmp->kfifo; \ 648 + (__recsize) ? \ 649 + __kfifo_to_user_r(__kfifo, __to, __len, __copied, __recsize) : \ 650 + __kfifo_to_user(__kfifo, __to, __len, __copied); \ 651 + }) \ 652 + ) 653 + 654 + /** 655 + * kfifo_dma_in_prepare - setup a scatterlist for DMA input 656 + * @fifo: address of the fifo to be used 657 + * @sgl: pointer to the scatterlist array 658 + * @nents: number of entries in the scatterlist array 659 + * @len: number of elements to transfer 660 + * 661 + * This macro fills a scatterlist for DMA input. 662 + * It returns the number entries in the scatterlist array. 663 + * 664 + * Note that with only one concurrent reader and one concurrent 665 + * writer, you don't need extra locking to use these macros. 666 + */ 667 + #define kfifo_dma_in_prepare(fifo, sgl, nents, len) \ 668 + ({ \ 669 + typeof(fifo + 1) __tmp = (fifo); \ 670 + struct scatterlist *__sgl = (sgl); \ 671 + int __nents = (nents); \ 672 + unsigned int __len = (len); \ 673 + const size_t __recsize = sizeof(*__tmp->rectype); \ 674 + struct __kfifo *__kfifo = &__tmp->kfifo; \ 675 + (__recsize) ? \ 676 + __kfifo_dma_in_prepare_r(__kfifo, __sgl, __nents, __len, __recsize) : \ 677 + __kfifo_dma_in_prepare(__kfifo, __sgl, __nents, __len); \ 678 + }) 679 + 680 + /** 681 + * kfifo_dma_in_finish - finish a DMA IN operation 682 + * @fifo: address of the fifo to be used 683 + * @len: number of bytes to received 684 + * 685 + * This macro finish a DMA IN operation. The in counter will be updated by 686 + * the len parameter. No error checking will be done. 687 + * 688 + * Note that with only one concurrent reader and one concurrent 689 + * writer, you don't need extra locking to use these macros. 690 + */ 691 + #define kfifo_dma_in_finish(fifo, len) \ 692 + (void)({ \ 693 + typeof(fifo + 1) __tmp = (fifo); \ 694 + unsigned int __len = (len); \ 695 + const size_t __recsize = sizeof(*__tmp->rectype); \ 696 + struct __kfifo *__kfifo = &__tmp->kfifo; \ 697 + if (__recsize) \ 698 + __kfifo_dma_in_finish_r(__kfifo, __len, __recsize); \ 699 + else \ 700 + __kfifo->in += __len / sizeof(*__tmp->type); \ 701 + }) 702 + 703 + /** 704 + * kfifo_dma_out_prepare - setup a scatterlist for DMA output 705 + * @fifo: address of the fifo to be used 706 + * @sgl: pointer to the scatterlist array 707 + * @nents: number of entries in the scatterlist array 708 + * @len: number of elements to transfer 709 + * 710 + * This macro fills a scatterlist for DMA output which at most @len bytes 711 + * to transfer. 712 + * It returns the number entries in the scatterlist array. 713 + * A zero means there is no space available and the scatterlist is not filled. 714 + * 715 + * Note that with only one concurrent reader and one concurrent 716 + * writer, you don't need extra locking to use these macros. 717 + */ 718 + #define kfifo_dma_out_prepare(fifo, sgl, nents, len) \ 719 + ({ \ 720 + typeof(fifo + 1) __tmp = (fifo); \ 721 + struct scatterlist *__sgl = (sgl); \ 722 + int __nents = (nents); \ 723 + unsigned int __len = (len); \ 724 + const size_t __recsize = sizeof(*__tmp->rectype); \ 725 + struct __kfifo *__kfifo = &__tmp->kfifo; \ 726 + (__recsize) ? \ 727 + __kfifo_dma_out_prepare_r(__kfifo, __sgl, __nents, __len, __recsize) : \ 728 + __kfifo_dma_out_prepare(__kfifo, __sgl, __nents, __len); \ 729 + }) 730 + 731 + /** 732 + * kfifo_dma_out_finish - finish a DMA OUT operation 733 + * @fifo: address of the fifo to be used 734 + * @len: number of bytes transferd 735 + * 736 + * This macro finish a DMA OUT operation. The out counter will be updated by 737 + * the len parameter. No error checking will be done. 738 + * 739 + * Note that with only one concurrent reader and one concurrent 740 + * writer, you don't need extra locking to use these macros. 741 + */ 742 + #define kfifo_dma_out_finish(fifo, len) \ 743 + (void)({ \ 744 + typeof(fifo + 1) __tmp = (fifo); \ 745 + unsigned int __len = (len); \ 746 + const size_t __recsize = sizeof(*__tmp->rectype); \ 747 + struct __kfifo *__kfifo = &__tmp->kfifo; \ 748 + if (__recsize) \ 749 + __kfifo_dma_out_finish_r(__kfifo, __recsize); \ 750 + else \ 751 + __kfifo->out += __len / sizeof(*__tmp->type); \ 752 + }) 753 + 754 + /** 755 + * kfifo_out_peek - gets some data from the fifo 756 + * @fifo: address of the fifo to be used 757 + * @buf: pointer to the storage buffer 758 + * @n: max. number of elements to get 759 + * 760 + * This macro get the data from the fifo and return the numbers of elements 761 + * copied. The data is not removed from the fifo. 762 + * 763 + * Note that with only one concurrent reader and one concurrent 764 + * writer, you don't need extra locking to use these macro. 765 + */ 766 + #define kfifo_out_peek(fifo, buf, n) \ 767 + __kfifo_must_check_helper( \ 768 + ({ \ 769 + typeof(fifo + 1) __tmp = (fifo); \ 770 + typeof(buf + 1) __buf = (buf); \ 771 + unsigned long __n = (n); \ 772 + const size_t __recsize = sizeof(*__tmp->rectype); \ 773 + struct __kfifo *__kfifo = &__tmp->kfifo; \ 774 + if (0) { \ 775 + typeof(__tmp->ptr) __dummy __attribute__ ((unused)) = NULL; \ 776 + __buf = __dummy; \ 777 + } \ 778 + (__recsize) ? \ 779 + __kfifo_out_peek_r(__kfifo, __buf, __n, __recsize) : \ 780 + __kfifo_out_peek(__kfifo, __buf, __n); \ 781 + }) \ 782 + ) 783 + 784 + extern int __kfifo_alloc(struct __kfifo *fifo, unsigned int size, 785 + size_t esize, gfp_t gfp_mask); 786 + 787 + extern void __kfifo_free(struct __kfifo *fifo); 788 + 789 + extern int __kfifo_init(struct __kfifo *fifo, void *buffer, 790 + unsigned int size, size_t esize); 791 + 792 + extern unsigned int __kfifo_in(struct __kfifo *fifo, 793 + const void *buf, unsigned int len); 794 + 795 + extern unsigned int __kfifo_out(struct __kfifo *fifo, 796 + void *buf, unsigned int len); 797 + 798 + extern int __kfifo_from_user(struct __kfifo *fifo, 799 + const void __user *from, unsigned long len, unsigned int *copied); 800 + 801 + extern int __kfifo_to_user(struct __kfifo *fifo, 802 + void __user *to, unsigned long len, unsigned int *copied); 803 + 804 + extern unsigned int __kfifo_dma_in_prepare(struct __kfifo *fifo, 805 + struct scatterlist *sgl, int nents, unsigned int len); 806 + 807 + extern unsigned int __kfifo_dma_out_prepare(struct __kfifo *fifo, 808 + struct scatterlist *sgl, int nents, unsigned int len); 809 + 810 + extern unsigned int __kfifo_out_peek(struct __kfifo *fifo, 811 + void *buf, unsigned int len); 812 + 813 + extern unsigned int __kfifo_in_r(struct __kfifo *fifo, 814 + const void *buf, unsigned int len, size_t recsize); 815 + 816 + extern unsigned int __kfifo_out_r(struct __kfifo *fifo, 817 + void *buf, unsigned int len, size_t recsize); 818 + 819 + extern int __kfifo_from_user_r(struct __kfifo *fifo, 820 + const void __user *from, unsigned long len, unsigned int *copied, 821 + size_t recsize); 822 + 823 + extern int __kfifo_to_user_r(struct __kfifo *fifo, void __user *to, 824 + unsigned long len, unsigned int *copied, size_t recsize); 825 + 826 + extern unsigned int __kfifo_dma_in_prepare_r(struct __kfifo *fifo, 827 + struct scatterlist *sgl, int nents, unsigned int len, size_t recsize); 828 + 829 + extern void __kfifo_dma_in_finish_r(struct __kfifo *fifo, 830 + unsigned int len, size_t recsize); 831 + 832 + extern unsigned int __kfifo_dma_out_prepare_r(struct __kfifo *fifo, 833 + struct scatterlist *sgl, int nents, unsigned int len, size_t recsize); 834 + 835 + extern void __kfifo_dma_out_finish_r(struct __kfifo *fifo, size_t recsize); 836 + 837 + extern unsigned int __kfifo_len_r(struct __kfifo *fifo, size_t recsize); 838 + 839 + extern unsigned int __kfifo_out_peek_r(struct __kfifo *fifo, 840 + void *buf, unsigned int len, size_t recsize); 841 + 842 + extern unsigned int __kfifo_max_r(unsigned int len, size_t recsize); 843 + 844 + #endif
+602
kernel/kfifo-new.c
··· 1 + /* 2 + * A generic kernel FIFO implementation 3 + * 4 + * Copyright (C) 2009/2010 Stefani Seibold <stefani@seibold.net> 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License as published by 8 + * the Free Software Foundation; either version 2 of the License, or 9 + * (at your option) any later version. 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + * 16 + * You should have received a copy of the GNU General Public License 17 + * along with this program; if not, write to the Free Software 18 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 + * 20 + */ 21 + 22 + #include <linux/kernel.h> 23 + #include <linux/module.h> 24 + #include <linux/slab.h> 25 + #include <linux/err.h> 26 + #include <linux/log2.h> 27 + #include <linux/uaccess.h> 28 + #include <linux/kfifo.h> 29 + 30 + /* 31 + * internal helper to calculate the unused elements in a fifo 32 + */ 33 + static inline unsigned int kfifo_unused(struct __kfifo *fifo) 34 + { 35 + return (fifo->mask + 1) - (fifo->in - fifo->out); 36 + } 37 + 38 + int __kfifo_alloc(struct __kfifo *fifo, unsigned int size, 39 + size_t esize, gfp_t gfp_mask) 40 + { 41 + /* 42 + * round down to the next power of 2, since our 'let the indices 43 + * wrap' technique works only in this case. 44 + */ 45 + if (!is_power_of_2(size)) 46 + size = rounddown_pow_of_two(size); 47 + 48 + fifo->in = 0; 49 + fifo->out = 0; 50 + fifo->esize = esize; 51 + 52 + if (size < 2) { 53 + fifo->data = NULL; 54 + fifo->mask = 0; 55 + return -EINVAL; 56 + } 57 + 58 + fifo->data = kmalloc(size * esize, gfp_mask); 59 + 60 + if (!fifo->data) { 61 + fifo->mask = 0; 62 + return -ENOMEM; 63 + } 64 + fifo->mask = size - 1; 65 + 66 + return 0; 67 + } 68 + EXPORT_SYMBOL(__kfifo_alloc); 69 + 70 + void __kfifo_free(struct __kfifo *fifo) 71 + { 72 + kfree(fifo->data); 73 + fifo->in = 0; 74 + fifo->out = 0; 75 + fifo->esize = 0; 76 + fifo->data = NULL; 77 + fifo->mask = 0; 78 + } 79 + EXPORT_SYMBOL(__kfifo_free); 80 + 81 + int __kfifo_init(struct __kfifo *fifo, void *buffer, 82 + unsigned int size, size_t esize) 83 + { 84 + size /= esize; 85 + 86 + if (!is_power_of_2(size)) 87 + size = rounddown_pow_of_two(size); 88 + 89 + fifo->in = 0; 90 + fifo->out = 0; 91 + fifo->esize = esize; 92 + fifo->data = buffer; 93 + 94 + if (size < 2) { 95 + fifo->mask = 0; 96 + return -EINVAL; 97 + } 98 + fifo->mask = size - 1; 99 + 100 + return 0; 101 + } 102 + EXPORT_SYMBOL(__kfifo_init); 103 + 104 + static void kfifo_copy_in(struct __kfifo *fifo, const void *src, 105 + unsigned int len, unsigned int off) 106 + { 107 + unsigned int size = fifo->mask + 1; 108 + unsigned int esize = fifo->esize; 109 + unsigned int l; 110 + 111 + off &= fifo->mask; 112 + if (esize != 1) { 113 + off *= esize; 114 + size *= esize; 115 + len *= esize; 116 + } 117 + l = min(len, size - off); 118 + 119 + memcpy(fifo->data + off, src, l); 120 + memcpy(fifo->data, src + l, len - l); 121 + /* 122 + * make sure that the data in the fifo is up to date before 123 + * incrementing the fifo->in index counter 124 + */ 125 + smp_wmb(); 126 + } 127 + 128 + unsigned int __kfifo_in(struct __kfifo *fifo, 129 + const void *buf, unsigned int len) 130 + { 131 + unsigned int l; 132 + 133 + l = kfifo_unused(fifo); 134 + if (len > l) 135 + len = l; 136 + 137 + kfifo_copy_in(fifo, buf, len, fifo->in); 138 + fifo->in += len; 139 + return len; 140 + } 141 + EXPORT_SYMBOL(__kfifo_in); 142 + 143 + static void kfifo_copy_out(struct __kfifo *fifo, void *dst, 144 + unsigned int len, unsigned int off) 145 + { 146 + unsigned int size = fifo->mask + 1; 147 + unsigned int esize = fifo->esize; 148 + unsigned int l; 149 + 150 + off &= fifo->mask; 151 + if (esize != 1) { 152 + off *= esize; 153 + size *= esize; 154 + len *= esize; 155 + } 156 + l = min(len, size - off); 157 + 158 + memcpy(dst, fifo->data + off, l); 159 + memcpy(dst + l, fifo->data, len - l); 160 + /* 161 + * make sure that the data is copied before 162 + * incrementing the fifo->out index counter 163 + */ 164 + smp_wmb(); 165 + } 166 + 167 + unsigned int __kfifo_out_peek(struct __kfifo *fifo, 168 + void *buf, unsigned int len) 169 + { 170 + unsigned int l; 171 + 172 + l = fifo->in - fifo->out; 173 + if (len > l) 174 + len = l; 175 + 176 + kfifo_copy_out(fifo, buf, len, fifo->out); 177 + return len; 178 + } 179 + EXPORT_SYMBOL(__kfifo_out_peek); 180 + 181 + unsigned int __kfifo_out(struct __kfifo *fifo, 182 + void *buf, unsigned int len) 183 + { 184 + len = __kfifo_out_peek(fifo, buf, len); 185 + fifo->out += len; 186 + return len; 187 + } 188 + EXPORT_SYMBOL(__kfifo_out); 189 + 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) 193 + { 194 + unsigned int size = fifo->mask + 1; 195 + unsigned int esize = fifo->esize; 196 + unsigned int l; 197 + unsigned long ret; 198 + 199 + off &= fifo->mask; 200 + if (esize != 1) { 201 + off *= esize; 202 + size *= esize; 203 + len *= esize; 204 + } 205 + l = min(len, size - off); 206 + 207 + ret = copy_from_user(fifo->data + off, from, l); 208 + if (unlikely(ret)) 209 + ret = DIV_ROUND_UP(ret + len - l, esize); 210 + else { 211 + ret = copy_from_user(fifo->data, from + l, len - l); 212 + if (unlikely(ret)) 213 + ret = DIV_ROUND_UP(ret, esize); 214 + } 215 + /* 216 + * make sure that the data in the fifo is up to date before 217 + * incrementing the fifo->in index counter 218 + */ 219 + smp_wmb(); 220 + *copied = len - ret; 221 + /* return the number of elements which are not copied */ 222 + return ret; 223 + } 224 + 225 + int __kfifo_from_user(struct __kfifo *fifo, const void __user *from, 226 + unsigned long len, unsigned int *copied) 227 + { 228 + unsigned int l; 229 + unsigned long ret; 230 + unsigned int esize = fifo->esize; 231 + int err; 232 + 233 + if (esize != 1) 234 + len /= esize; 235 + 236 + l = kfifo_unused(fifo); 237 + if (len > l) 238 + len = l; 239 + 240 + ret = kfifo_copy_from_user(fifo, from, len, fifo->in, copied); 241 + if (unlikely(ret)) { 242 + len -= ret; 243 + err = -EFAULT; 244 + } else 245 + err = 0; 246 + fifo->in += len; 247 + return err; 248 + } 249 + EXPORT_SYMBOL(__kfifo_from_user); 250 + 251 + static unsigned long kfifo_copy_to_user(struct __kfifo *fifo, void __user *to, 252 + unsigned int len, unsigned int off, unsigned int *copied) 253 + { 254 + unsigned int l; 255 + unsigned long ret; 256 + unsigned int size = fifo->mask + 1; 257 + unsigned int esize = fifo->esize; 258 + 259 + off &= fifo->mask; 260 + if (esize != 1) { 261 + off *= esize; 262 + size *= esize; 263 + len *= esize; 264 + } 265 + l = min(len, size - off); 266 + 267 + ret = copy_to_user(to, fifo->data + off, l); 268 + if (unlikely(ret)) 269 + ret = DIV_ROUND_UP(ret + len - l, esize); 270 + else { 271 + ret = copy_to_user(to + l, fifo->data, len - l); 272 + if (unlikely(ret)) 273 + ret = DIV_ROUND_UP(ret, esize); 274 + } 275 + /* 276 + * make sure that the data is copied before 277 + * incrementing the fifo->out index counter 278 + */ 279 + smp_wmb(); 280 + *copied = len - ret; 281 + /* return the number of elements which are not copied */ 282 + return ret; 283 + } 284 + 285 + int __kfifo_to_user(struct __kfifo *fifo, void __user *to, 286 + unsigned long len, unsigned int *copied) 287 + { 288 + unsigned int l; 289 + unsigned long ret; 290 + unsigned int esize = fifo->esize; 291 + int err; 292 + 293 + if (esize != 1) 294 + len /= esize; 295 + 296 + l = fifo->in - fifo->out; 297 + if (len > l) 298 + len = l; 299 + ret = kfifo_copy_to_user(fifo, to, len, fifo->out, copied); 300 + if (unlikely(ret)) { 301 + len -= ret; 302 + err = -EFAULT; 303 + } else 304 + err = 0; 305 + fifo->out += len; 306 + return err; 307 + } 308 + EXPORT_SYMBOL(__kfifo_to_user); 309 + 310 + static int setup_sgl_buf(struct scatterlist *sgl, void *buf, 311 + int nents, unsigned int len) 312 + { 313 + int n; 314 + unsigned int l; 315 + unsigned int off; 316 + struct page *page; 317 + 318 + if (!nents) 319 + return 0; 320 + 321 + if (!len) 322 + return 0; 323 + 324 + n = 0; 325 + page = virt_to_page(buf); 326 + off = offset_in_page(buf); 327 + l = 0; 328 + 329 + while (len >= l + PAGE_SIZE - off) { 330 + struct page *npage; 331 + 332 + l += PAGE_SIZE; 333 + buf += PAGE_SIZE; 334 + npage = virt_to_page(buf); 335 + if (page_to_phys(page) != page_to_phys(npage) - l) { 336 + sgl->page_link = 0; 337 + sg_set_page(sgl++, page, l - off, off); 338 + if (++n == nents) 339 + return n; 340 + page = npage; 341 + len -= l - off; 342 + l = off = 0; 343 + } 344 + } 345 + sgl->page_link = 0; 346 + sg_set_page(sgl++, page, len, off); 347 + return n + 1; 348 + } 349 + 350 + static unsigned int setup_sgl(struct __kfifo *fifo, struct scatterlist *sgl, 351 + int nents, unsigned int len, unsigned int off) 352 + { 353 + unsigned int size = fifo->mask + 1; 354 + unsigned int esize = fifo->esize; 355 + unsigned int l; 356 + unsigned int n; 357 + 358 + off &= fifo->mask; 359 + if (esize != 1) { 360 + off *= esize; 361 + size *= esize; 362 + len *= esize; 363 + } 364 + l = min(len, size - off); 365 + 366 + n = setup_sgl_buf(sgl, fifo->data + off, nents, l); 367 + n += setup_sgl_buf(sgl + n, fifo->data, nents - n, len - l); 368 + 369 + if (n) 370 + sg_mark_end(sgl + n - 1); 371 + return n; 372 + } 373 + 374 + unsigned int __kfifo_dma_in_prepare(struct __kfifo *fifo, 375 + struct scatterlist *sgl, int nents, unsigned int len) 376 + { 377 + unsigned int l; 378 + 379 + l = kfifo_unused(fifo); 380 + if (len > l) 381 + len = l; 382 + 383 + return setup_sgl(fifo, sgl, nents, len, fifo->in); 384 + } 385 + EXPORT_SYMBOL(__kfifo_dma_in_prepare); 386 + 387 + unsigned int __kfifo_dma_out_prepare(struct __kfifo *fifo, 388 + struct scatterlist *sgl, int nents, unsigned int len) 389 + { 390 + unsigned int l; 391 + 392 + l = fifo->in - fifo->out; 393 + if (len > l) 394 + len = l; 395 + 396 + return setup_sgl(fifo, sgl, nents, len, fifo->out); 397 + } 398 + EXPORT_SYMBOL(__kfifo_dma_out_prepare); 399 + 400 + unsigned int __kfifo_max_r(unsigned int len, size_t recsize) 401 + { 402 + unsigned int max = (1 << (recsize << 3)) - 1; 403 + 404 + if (len > max) 405 + return max; 406 + return len; 407 + } 408 + 409 + #define __KFIFO_PEEK(data, out, mask) \ 410 + ((data)[(out) & (mask)]) 411 + /* 412 + * __kfifo_peek_n internal helper function for determinate the length of 413 + * the next record in the fifo 414 + */ 415 + static unsigned int __kfifo_peek_n(struct __kfifo *fifo, size_t recsize) 416 + { 417 + unsigned int l; 418 + unsigned int mask = fifo->mask; 419 + unsigned char *data = fifo->data; 420 + 421 + l = __KFIFO_PEEK(data, fifo->out, mask); 422 + 423 + if (--recsize) 424 + l |= __KFIFO_PEEK(data, fifo->out + 1, mask) << 8; 425 + 426 + return l; 427 + } 428 + 429 + #define __KFIFO_POKE(data, in, mask, val) \ 430 + ( \ 431 + (data)[(in) & (mask)] = (unsigned char)(val) \ 432 + ) 433 + 434 + /* 435 + * __kfifo_poke_n internal helper function for storeing the length of 436 + * the record into the fifo 437 + */ 438 + static void __kfifo_poke_n(struct __kfifo *fifo, unsigned int n, size_t recsize) 439 + { 440 + unsigned int mask = fifo->mask; 441 + unsigned char *data = fifo->data; 442 + 443 + __KFIFO_POKE(data, fifo->in, mask, n); 444 + 445 + if (recsize > 1) 446 + __KFIFO_POKE(data, fifo->in + 1, mask, n >> 8); 447 + } 448 + 449 + unsigned int __kfifo_len_r(struct __kfifo *fifo, size_t recsize) 450 + { 451 + return __kfifo_peek_n(fifo, recsize); 452 + } 453 + EXPORT_SYMBOL(__kfifo_len_r); 454 + 455 + unsigned int __kfifo_in_r(struct __kfifo *fifo, const void *buf, 456 + unsigned int len, size_t recsize) 457 + { 458 + if (len + recsize > kfifo_unused(fifo)) 459 + return 0; 460 + 461 + __kfifo_poke_n(fifo, len, recsize); 462 + 463 + kfifo_copy_in(fifo, buf, len, fifo->in + recsize); 464 + fifo->in += len + recsize; 465 + return len; 466 + } 467 + EXPORT_SYMBOL(__kfifo_in_r); 468 + 469 + static unsigned int kfifo_out_copy_r(struct __kfifo *fifo, 470 + void *buf, unsigned int len, size_t recsize, unsigned int *n) 471 + { 472 + *n = __kfifo_peek_n(fifo, recsize); 473 + 474 + if (len > *n) 475 + len = *n; 476 + 477 + kfifo_copy_out(fifo, buf, len, fifo->out + recsize); 478 + return len; 479 + } 480 + 481 + unsigned int __kfifo_out_peek_r(struct __kfifo *fifo, void *buf, 482 + unsigned int len, size_t recsize) 483 + { 484 + unsigned int n; 485 + 486 + if (fifo->in == fifo->out) 487 + return 0; 488 + 489 + return kfifo_out_copy_r(fifo, buf, len, recsize, &n); 490 + } 491 + EXPORT_SYMBOL(__kfifo_out_peek_r); 492 + 493 + unsigned int __kfifo_out_r(struct __kfifo *fifo, void *buf, 494 + unsigned int len, size_t recsize) 495 + { 496 + unsigned int n; 497 + 498 + if (fifo->in == fifo->out) 499 + return 0; 500 + 501 + len = kfifo_out_copy_r(fifo, buf, len, recsize, &n); 502 + fifo->out += n + recsize; 503 + return len; 504 + } 505 + EXPORT_SYMBOL(__kfifo_out_r); 506 + 507 + int __kfifo_from_user_r(struct __kfifo *fifo, const void __user *from, 508 + unsigned long len, unsigned int *copied, size_t recsize) 509 + { 510 + unsigned long ret; 511 + 512 + len = __kfifo_max_r(len, recsize); 513 + 514 + if (len + recsize > kfifo_unused(fifo)) { 515 + *copied = 0; 516 + return 0; 517 + } 518 + 519 + __kfifo_poke_n(fifo, len, recsize); 520 + 521 + ret = kfifo_copy_from_user(fifo, from, len, fifo->in + recsize, copied); 522 + if (unlikely(ret)) { 523 + *copied = 0; 524 + return -EFAULT; 525 + } 526 + fifo->in += len + recsize; 527 + return 0; 528 + } 529 + EXPORT_SYMBOL(__kfifo_from_user_r); 530 + 531 + int __kfifo_to_user_r(struct __kfifo *fifo, void __user *to, 532 + unsigned long len, unsigned int *copied, size_t recsize) 533 + { 534 + unsigned long ret; 535 + unsigned int n; 536 + 537 + if (fifo->in == fifo->out) { 538 + *copied = 0; 539 + return 0; 540 + } 541 + 542 + n = __kfifo_peek_n(fifo, recsize); 543 + if (len > n) 544 + len = n; 545 + 546 + ret = kfifo_copy_to_user(fifo, to, len, fifo->out + recsize, copied); 547 + if (unlikely(ret)) { 548 + *copied = 0; 549 + return -EFAULT; 550 + } 551 + fifo->out += n + recsize; 552 + return 0; 553 + } 554 + EXPORT_SYMBOL(__kfifo_to_user_r); 555 + 556 + unsigned int __kfifo_dma_in_prepare_r(struct __kfifo *fifo, 557 + struct scatterlist *sgl, int nents, unsigned int len, size_t recsize) 558 + { 559 + if (!nents) 560 + BUG(); 561 + 562 + len = __kfifo_max_r(len, recsize); 563 + 564 + if (len + recsize > kfifo_unused(fifo)) 565 + return 0; 566 + 567 + return setup_sgl(fifo, sgl, nents, len, fifo->in + recsize); 568 + } 569 + EXPORT_SYMBOL(__kfifo_dma_in_prepare_r); 570 + 571 + void __kfifo_dma_in_finish_r(struct __kfifo *fifo, 572 + unsigned int len, size_t recsize) 573 + { 574 + len = __kfifo_max_r(len, recsize); 575 + __kfifo_poke_n(fifo, len, recsize); 576 + fifo->in += len + recsize; 577 + } 578 + EXPORT_SYMBOL(__kfifo_dma_in_finish_r); 579 + 580 + unsigned int __kfifo_dma_out_prepare_r(struct __kfifo *fifo, 581 + struct scatterlist *sgl, int nents, unsigned int len, size_t recsize) 582 + { 583 + if (!nents) 584 + BUG(); 585 + 586 + len = __kfifo_max_r(len, recsize); 587 + 588 + if (len + recsize > fifo->in - fifo->out) 589 + return 0; 590 + 591 + return setup_sgl(fifo, sgl, nents, len, fifo->out + recsize); 592 + } 593 + EXPORT_SYMBOL(__kfifo_dma_out_prepare_r); 594 + 595 + void __kfifo_dma_out_finish_r(struct __kfifo *fifo, size_t recsize) 596 + { 597 + unsigned int len; 598 + 599 + len = __kfifo_peek_n(fifo, recsize); 600 + fifo->out += len + recsize; 601 + } 602 + EXPORT_SYMBOL(__kfifo_dma_out_finish_r);