diff -ruaN lirc-0.8.6.orig//drivers/lirc_dev/lirc_dev.h lirc-0.8.6/drivers/lirc_dev/lirc_dev.h --- lirc-0.8.6.orig//drivers/lirc_dev/lirc_dev.h 2009-03-15 09:34:00.000000000 +0000 +++ lirc-0.8.6/drivers/lirc_dev/lirc_dev.h 2010-08-04 02:20:07.000000000 +0000 @@ -4,7 +4,7 @@ * (L) by Artur Lipowski * This code is licensed under GNU GPL * - * $Id: lirc_dev.h,v 1.37 2009/03/15 09:34:00 lirc Exp $ + * $Id: lirc_dev.h,v 1.39 2010/01/23 16:28:07 lirc Exp $ * */ @@ -30,14 +30,19 @@ struct lirc_buffer { wait_queue_head_t wait_poll; - spinlock_t lock; + spinlock_t fifo_lock; unsigned int chunk_size; unsigned int size; /* in chunks */ /* Using chunks instead of bytes pretends to simplify boundary checking * And should allow for some performance fine tunning later */ #ifdef LIRC_HAVE_KFIFO +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33) struct kfifo *fifo; #else + struct kfifo fifo; + u8 fifo_initialized; +#endif +#else unsigned int fill; /* in chunks */ int head, tail; /* in chunks */ unsigned char *data; @@ -47,12 +52,12 @@ static inline void lirc_buffer_lock(struct lirc_buffer *buf, unsigned long *flags) { - spin_lock_irqsave(&buf->lock, *flags); + spin_lock_irqsave(&buf->fifo_lock, *flags); } static inline void lirc_buffer_unlock(struct lirc_buffer *buf, unsigned long *flags) { - spin_unlock_irqrestore(&buf->lock, *flags); + spin_unlock_irqrestore(&buf->fifo_lock, *flags); } static inline void _lirc_buffer_clear(struct lirc_buffer *buf) { @@ -64,10 +69,21 @@ static inline void lirc_buffer_clear(struct lirc_buffer *buf) { #ifdef LIRC_HAVE_KFIFO +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33) if (buf->fifo) kfifo_reset(buf->fifo); #else unsigned long flags; + + if (buf->fifo_initialized) { + spin_lock_irqsave(&buf->fifo_lock, flags); + kfifo_reset(&buf->fifo); + spin_unlock_irqrestore(&buf->fifo_lock, flags); + } +#endif +#else + unsigned long flags; + lirc_buffer_lock(buf, &flags); _lirc_buffer_clear(buf); lirc_buffer_unlock(buf, &flags); @@ -77,31 +93,47 @@ unsigned int chunk_size, unsigned int size) { + int ret = 0; + init_waitqueue_head(&buf->wait_poll); - spin_lock_init(&buf->lock); + spin_lock_init(&buf->fifo_lock); #ifndef LIRC_HAVE_KFIFO _lirc_buffer_clear(buf); #endif buf->chunk_size = chunk_size; buf->size = size; #ifdef LIRC_HAVE_KFIFO - buf->fifo = kfifo_alloc(size*chunk_size, GFP_KERNEL, &buf->lock); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33) + buf->fifo = kfifo_alloc(size*chunk_size, GFP_KERNEL, &buf->fifo_lock); if (!buf->fifo) return -ENOMEM; #else + ret = kfifo_alloc(&buf->fifo, size * chunk_size, GFP_KERNEL); + if (ret == 0) + buf->fifo_initialized = 1; +#endif +#else buf->data = kmalloc(size*chunk_size, GFP_KERNEL); if (buf->data == NULL) return -ENOMEM; memset(buf->data, 0, size*chunk_size); #endif - return 0; + + return ret; } static inline void lirc_buffer_free(struct lirc_buffer *buf) { #ifdef LIRC_HAVE_KFIFO +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33) if (buf->fifo) kfifo_free(buf->fifo); #else + if (buf->fifo_initialized) { + kfifo_free(&buf->fifo); + buf->fifo_initialized = 0; + } +#endif +#else kfree(buf->data); buf->data = NULL; buf->head = 0; @@ -111,6 +143,25 @@ buf->size = 0; #endif } + +#ifdef LIRC_HAVE_KFIFO +static inline int lirc_buffer_len(struct lirc_buffer *buf) +{ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33) + return kfifo_len(buf->fifo); +#else + int len; + unsigned long flags; + + spin_lock_irqsave(&buf->fifo_lock, flags); + len = kfifo_len(&buf->fifo); + spin_unlock_irqrestore(&buf->fifo_lock, flags); + + return len; +#endif +} +#endif + #ifndef LIRC_HAVE_KFIFO static inline int _lirc_buffer_full(struct lirc_buffer *buf) { @@ -120,7 +171,7 @@ static inline int lirc_buffer_full(struct lirc_buffer *buf) { #ifdef LIRC_HAVE_KFIFO - return kfifo_len(buf->fifo) == buf->size * buf->chunk_size; + return lirc_buffer_len(buf) == buf->size * buf->chunk_size; #else unsigned long flags; int ret; @@ -139,7 +190,7 @@ static inline int lirc_buffer_empty(struct lirc_buffer *buf) { #ifdef LIRC_HAVE_KFIFO - return !kfifo_len(buf->fifo); + return !lirc_buffer_len(buf); #else unsigned long flags; int ret; @@ -158,7 +209,7 @@ static inline int lirc_buffer_available(struct lirc_buffer *buf) { #ifdef LIRC_HAVE_KFIFO - return buf->size - (kfifo_len(buf->fifo) / buf->chunk_size); + return buf->size - (lirc_buffer_len(buf) / buf->chunk_size); #else unsigned long flags; int ret; @@ -177,21 +228,30 @@ buf->fill -= 1; } #endif -static inline void lirc_buffer_read(struct lirc_buffer *buf, - unsigned char *dest) +static inline unsigned int lirc_buffer_read(struct lirc_buffer *buf, + unsigned char *dest) { + unsigned int ret = 0; + #ifdef LIRC_HAVE_KFIFO - if (kfifo_len(buf->fifo) >= buf->chunk_size) - kfifo_get(buf->fifo, dest, buf->chunk_size); + if (lirc_buffer_len(buf) >= buf->chunk_size) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33) + ret = kfifo_get(buf->fifo, dest, buf->chunk_size); +#else + ret = kfifo_out_locked(&buf->fifo, dest, buf->chunk_size, + &buf->fifo_lock); +#endif #else unsigned long flags; lirc_buffer_lock(buf, &flags); _lirc_buffer_read_1(buf, dest); lirc_buffer_unlock(buf, &flags); #endif + + return ret; } #ifndef LIRC_HAVE_KFIFO -static inline void _lirc_buffer_write_1(struct lirc_buffer *buf, +static inline _lirc_buffer_write_1(struct lirc_buffer *buf, unsigned char *orig) { memcpy(&buf->data[buf->tail*buf->chunk_size], orig, buf->chunk_size); @@ -199,17 +259,26 @@ buf->fill++; } #endif -static inline void lirc_buffer_write(struct lirc_buffer *buf, - unsigned char *orig) +static inline unsigned int lirc_buffer_write(struct lirc_buffer *buf, + unsigned char *orig) { + unsigned int ret = 0; + #ifdef LIRC_HAVE_KFIFO - kfifo_put(buf->fifo, orig, buf->chunk_size); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33) + ret = kfifo_put(buf->fifo, orig, buf->chunk_size); +#else + ret = kfifo_in_locked(&buf->fifo, orig, buf->chunk_size, + &buf->fifo_lock); +#endif #else unsigned long flags; lirc_buffer_lock(buf, &flags); _lirc_buffer_write_1(buf, orig); lirc_buffer_unlock(buf, &flags); #endif + + return ret; } #ifndef LIRC_HAVE_KFIFO static inline void _lirc_buffer_write_n(struct lirc_buffer *buf, @@ -234,17 +303,26 @@ buf->fill += count; } #endif -static inline void lirc_buffer_write_n(struct lirc_buffer *buf, - unsigned char *orig, int count) +static inline unsigned int lirc_buffer_write_n(struct lirc_buffer *buf, + unsigned char *orig, int count) { + unsigned int ret = 0; + #ifdef LIRC_HAVE_KFIFO - kfifo_put(buf->fifo, orig, count * buf->chunk_size); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33) + ret = kfifo_put(buf->fifo, orig, count * buf->chunk_size); +#else + ret = kfifo_in_locked(&buf->fifo, orig, count * buf->chunk_size, + &buf->fifo_lock); +#endif #else unsigned long flags; lirc_buffer_lock(buf, &flags); _lirc_buffer_write_n(buf, orig, count); lirc_buffer_unlock(buf, &flags); #endif + + return ret; } struct lirc_driver {