aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorStefani Seibold <stefani@seibold.net>2009-12-21 17:37:26 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-12-22 17:17:55 -0500
commit45465487897a1c6d508b14b904dc5777f7ec7e04 (patch)
tree935c8dae68dc793ff2f795d57cf027531475cd53 /drivers/media
parent2ec91eec47f713e3d158ba5b28a24a85a2cf3650 (diff)
kfifo: move struct kfifo in place
This is a new generic kernel FIFO implementation. The current kernel fifo API is not very widely used, because it has to many constrains. Only 17 files in the current 2.6.31-rc5 used it. FIFO's are like list's a very basic thing and a kfifo API which handles the most use case would save a lot of development time and memory resources. I think this are the reasons why kfifo is not in use: - The API is to simple, important functions are missing - A fifo can be only allocated dynamically - There is a requirement of a spinlock whether you need it or not - There is no support for data records inside a fifo So I decided to extend the kfifo in a more generic way without blowing up the API to much. The new API has the following benefits: - Generic usage: For kernel internal use and/or device driver. - Provide an API for the most use case. - Slim API: The whole API provides 25 functions. - Linux style habit. - DECLARE_KFIFO, DEFINE_KFIFO and INIT_KFIFO Macros - Direct copy_to_user from the fifo and copy_from_user into the fifo. - The kfifo itself is an in place member of the using data structure, this save an indirection access and does not waste the kernel allocator. - Lockless access: if only one reader and one writer is active on the fifo, which is the common use case, no additional locking is necessary. - Remove spinlock - give the user the freedom of choice what kind of locking to use if one is required. - Ability to handle records. Three type of records are supported: - Variable length records between 0-255 bytes, with a record size field of 1 bytes. - Variable length records between 0-65535 bytes, with a record size field of 2 bytes. - Fixed size records, which no record size field. - Preserve memory resource. - Performance! - Easy to use! This patch: Since most users want to have the kfifo as part of another object, reorganize the code to allow including struct kfifo in another data structure. This requires changing the kfifo_alloc and kfifo_init prototypes so that we pass an existing kfifo pointer into them. This patch changes the implementation and all existing users. [akpm@linux-foundation.org: fix warning] Signed-off-by: Stefani Seibold <stefani@seibold.net> Acked-by: Greg Kroah-Hartman <gregkh@suse.de> Acked-by: Mauro Carvalho Chehab <mchehab@redhat.com> Acked-by: Andi Kleen <ak@linux.intel.com> Acked-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/video/meye.c48
-rw-r--r--drivers/media/video/meye.h4
2 files changed, 25 insertions, 27 deletions
diff --git a/drivers/media/video/meye.c b/drivers/media/video/meye.c
index 6ffa64cd1c6d..dacbbb839b9e 100644
--- a/drivers/media/video/meye.c
+++ b/drivers/media/video/meye.c
@@ -800,7 +800,7 @@ again:
800 return IRQ_HANDLED; 800 return IRQ_HANDLED;
801 801
802 if (meye.mchip_mode == MCHIP_HIC_MODE_CONT_OUT) { 802 if (meye.mchip_mode == MCHIP_HIC_MODE_CONT_OUT) {
803 if (kfifo_get(meye.grabq, (unsigned char *)&reqnr, 803 if (kfifo_get(&meye.grabq, (unsigned char *)&reqnr,
804 sizeof(int)) != sizeof(int)) { 804 sizeof(int)) != sizeof(int)) {
805 mchip_free_frame(); 805 mchip_free_frame();
806 return IRQ_HANDLED; 806 return IRQ_HANDLED;
@@ -811,7 +811,7 @@ again:
811 meye.grab_buffer[reqnr].state = MEYE_BUF_DONE; 811 meye.grab_buffer[reqnr].state = MEYE_BUF_DONE;
812 do_gettimeofday(&meye.grab_buffer[reqnr].timestamp); 812 do_gettimeofday(&meye.grab_buffer[reqnr].timestamp);
813 meye.grab_buffer[reqnr].sequence = sequence++; 813 meye.grab_buffer[reqnr].sequence = sequence++;
814 kfifo_put(meye.doneq, (unsigned char *)&reqnr, sizeof(int)); 814 kfifo_put(&meye.doneq, (unsigned char *)&reqnr, sizeof(int));
815 wake_up_interruptible(&meye.proc_list); 815 wake_up_interruptible(&meye.proc_list);
816 } else { 816 } else {
817 int size; 817 int size;
@@ -820,7 +820,7 @@ again:
820 mchip_free_frame(); 820 mchip_free_frame();
821 goto again; 821 goto again;
822 } 822 }
823 if (kfifo_get(meye.grabq, (unsigned char *)&reqnr, 823 if (kfifo_get(&meye.grabq, (unsigned char *)&reqnr,
824 sizeof(int)) != sizeof(int)) { 824 sizeof(int)) != sizeof(int)) {
825 mchip_free_frame(); 825 mchip_free_frame();
826 goto again; 826 goto again;
@@ -831,7 +831,7 @@ again:
831 meye.grab_buffer[reqnr].state = MEYE_BUF_DONE; 831 meye.grab_buffer[reqnr].state = MEYE_BUF_DONE;
832 do_gettimeofday(&meye.grab_buffer[reqnr].timestamp); 832 do_gettimeofday(&meye.grab_buffer[reqnr].timestamp);
833 meye.grab_buffer[reqnr].sequence = sequence++; 833 meye.grab_buffer[reqnr].sequence = sequence++;
834 kfifo_put(meye.doneq, (unsigned char *)&reqnr, sizeof(int)); 834 kfifo_put(&meye.doneq, (unsigned char *)&reqnr, sizeof(int));
835 wake_up_interruptible(&meye.proc_list); 835 wake_up_interruptible(&meye.proc_list);
836 } 836 }
837 mchip_free_frame(); 837 mchip_free_frame();
@@ -859,8 +859,8 @@ static int meye_open(struct file *file)
859 859
860 for (i = 0; i < MEYE_MAX_BUFNBRS; i++) 860 for (i = 0; i < MEYE_MAX_BUFNBRS; i++)
861 meye.grab_buffer[i].state = MEYE_BUF_UNUSED; 861 meye.grab_buffer[i].state = MEYE_BUF_UNUSED;
862 kfifo_reset(meye.grabq); 862 kfifo_reset(&meye.grabq);
863 kfifo_reset(meye.doneq); 863 kfifo_reset(&meye.doneq);
864 return 0; 864 return 0;
865} 865}
866 866
@@ -933,7 +933,7 @@ static int meyeioc_qbuf_capt(int *nb)
933 mchip_cont_compression_start(); 933 mchip_cont_compression_start();
934 934
935 meye.grab_buffer[*nb].state = MEYE_BUF_USING; 935 meye.grab_buffer[*nb].state = MEYE_BUF_USING;
936 kfifo_put(meye.grabq, (unsigned char *)nb, sizeof(int)); 936 kfifo_put(&meye.grabq, (unsigned char *)nb, sizeof(int));
937 mutex_unlock(&meye.lock); 937 mutex_unlock(&meye.lock);
938 938
939 return 0; 939 return 0;
@@ -965,7 +965,7 @@ static int meyeioc_sync(struct file *file, void *fh, int *i)
965 /* fall through */ 965 /* fall through */
966 case MEYE_BUF_DONE: 966 case MEYE_BUF_DONE:
967 meye.grab_buffer[*i].state = MEYE_BUF_UNUSED; 967 meye.grab_buffer[*i].state = MEYE_BUF_UNUSED;
968 kfifo_get(meye.doneq, (unsigned char *)&unused, sizeof(int)); 968 kfifo_get(&meye.doneq, (unsigned char *)&unused, sizeof(int));
969 } 969 }
970 *i = meye.grab_buffer[*i].size; 970 *i = meye.grab_buffer[*i].size;
971 mutex_unlock(&meye.lock); 971 mutex_unlock(&meye.lock);
@@ -1452,7 +1452,7 @@ static int vidioc_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
1452 buf->flags |= V4L2_BUF_FLAG_QUEUED; 1452 buf->flags |= V4L2_BUF_FLAG_QUEUED;
1453 buf->flags &= ~V4L2_BUF_FLAG_DONE; 1453 buf->flags &= ~V4L2_BUF_FLAG_DONE;
1454 meye.grab_buffer[buf->index].state = MEYE_BUF_USING; 1454 meye.grab_buffer[buf->index].state = MEYE_BUF_USING;
1455 kfifo_put(meye.grabq, (unsigned char *)&buf->index, sizeof(int)); 1455 kfifo_put(&meye.grabq, (unsigned char *)&buf->index, sizeof(int));
1456 mutex_unlock(&meye.lock); 1456 mutex_unlock(&meye.lock);
1457 1457
1458 return 0; 1458 return 0;
@@ -1467,18 +1467,18 @@ static int vidioc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
1467 1467
1468 mutex_lock(&meye.lock); 1468 mutex_lock(&meye.lock);
1469 1469
1470 if (kfifo_len(meye.doneq) == 0 && file->f_flags & O_NONBLOCK) { 1470 if (kfifo_len(&meye.doneq) == 0 && file->f_flags & O_NONBLOCK) {
1471 mutex_unlock(&meye.lock); 1471 mutex_unlock(&meye.lock);
1472 return -EAGAIN; 1472 return -EAGAIN;
1473 } 1473 }
1474 1474
1475 if (wait_event_interruptible(meye.proc_list, 1475 if (wait_event_interruptible(meye.proc_list,
1476 kfifo_len(meye.doneq) != 0) < 0) { 1476 kfifo_len(&meye.doneq) != 0) < 0) {
1477 mutex_unlock(&meye.lock); 1477 mutex_unlock(&meye.lock);
1478 return -EINTR; 1478 return -EINTR;
1479 } 1479 }
1480 1480
1481 if (!kfifo_get(meye.doneq, (unsigned char *)&reqnr, 1481 if (!kfifo_get(&meye.doneq, (unsigned char *)&reqnr,
1482 sizeof(int))) { 1482 sizeof(int))) {
1483 mutex_unlock(&meye.lock); 1483 mutex_unlock(&meye.lock);
1484 return -EBUSY; 1484 return -EBUSY;
@@ -1529,8 +1529,8 @@ static int vidioc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i)
1529{ 1529{
1530 mutex_lock(&meye.lock); 1530 mutex_lock(&meye.lock);
1531 mchip_hic_stop(); 1531 mchip_hic_stop();
1532 kfifo_reset(meye.grabq); 1532 kfifo_reset(&meye.grabq);
1533 kfifo_reset(meye.doneq); 1533 kfifo_reset(&meye.doneq);
1534 1534
1535 for (i = 0; i < MEYE_MAX_BUFNBRS; i++) 1535 for (i = 0; i < MEYE_MAX_BUFNBRS; i++)
1536 meye.grab_buffer[i].state = MEYE_BUF_UNUSED; 1536 meye.grab_buffer[i].state = MEYE_BUF_UNUSED;
@@ -1572,7 +1572,7 @@ static unsigned int meye_poll(struct file *file, poll_table *wait)
1572 1572
1573 mutex_lock(&meye.lock); 1573 mutex_lock(&meye.lock);
1574 poll_wait(file, &meye.proc_list, wait); 1574 poll_wait(file, &meye.proc_list, wait);
1575 if (kfifo_len(meye.doneq)) 1575 if (kfifo_len(&meye.doneq))
1576 res = POLLIN | POLLRDNORM; 1576 res = POLLIN | POLLRDNORM;
1577 mutex_unlock(&meye.lock); 1577 mutex_unlock(&meye.lock);
1578 return res; 1578 return res;
@@ -1745,16 +1745,14 @@ static int __devinit meye_probe(struct pci_dev *pcidev,
1745 } 1745 }
1746 1746
1747 spin_lock_init(&meye.grabq_lock); 1747 spin_lock_init(&meye.grabq_lock);
1748 meye.grabq = kfifo_alloc(sizeof(int) * MEYE_MAX_BUFNBRS, GFP_KERNEL, 1748 if (kfifo_alloc(&meye.grabq, sizeof(int) * MEYE_MAX_BUFNBRS, GFP_KERNEL,
1749 &meye.grabq_lock); 1749 &meye.grabq_lock)) {
1750 if (IS_ERR(meye.grabq)) {
1751 printk(KERN_ERR "meye: fifo allocation failed\n"); 1750 printk(KERN_ERR "meye: fifo allocation failed\n");
1752 goto outkfifoalloc1; 1751 goto outkfifoalloc1;
1753 } 1752 }
1754 spin_lock_init(&meye.doneq_lock); 1753 spin_lock_init(&meye.doneq_lock);
1755 meye.doneq = kfifo_alloc(sizeof(int) * MEYE_MAX_BUFNBRS, GFP_KERNEL, 1754 if (kfifo_alloc(&meye.doneq, sizeof(int) * MEYE_MAX_BUFNBRS, GFP_KERNEL,
1756 &meye.doneq_lock); 1755 &meye.doneq_lock)) {
1757 if (IS_ERR(meye.doneq)) {
1758 printk(KERN_ERR "meye: fifo allocation failed\n"); 1756 printk(KERN_ERR "meye: fifo allocation failed\n");
1759 goto outkfifoalloc2; 1757 goto outkfifoalloc2;
1760 } 1758 }
@@ -1868,9 +1866,9 @@ outregions:
1868outenabledev: 1866outenabledev:
1869 sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERA, 0); 1867 sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERA, 0);
1870outsonypienable: 1868outsonypienable:
1871 kfifo_free(meye.doneq); 1869 kfifo_free(&meye.doneq);
1872outkfifoalloc2: 1870outkfifoalloc2:
1873 kfifo_free(meye.grabq); 1871 kfifo_free(&meye.grabq);
1874outkfifoalloc1: 1872outkfifoalloc1:
1875 vfree(meye.grab_temp); 1873 vfree(meye.grab_temp);
1876outvmalloc: 1874outvmalloc:
@@ -1901,8 +1899,8 @@ static void __devexit meye_remove(struct pci_dev *pcidev)
1901 1899
1902 sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERA, 0); 1900 sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERA, 0);
1903 1901
1904 kfifo_free(meye.doneq); 1902 kfifo_free(&meye.doneq);
1905 kfifo_free(meye.grabq); 1903 kfifo_free(&meye.grabq);
1906 1904
1907 vfree(meye.grab_temp); 1905 vfree(meye.grab_temp);
1908 1906
diff --git a/drivers/media/video/meye.h b/drivers/media/video/meye.h
index 5f70a106ba2b..1321ad5d6597 100644
--- a/drivers/media/video/meye.h
+++ b/drivers/media/video/meye.h
@@ -303,9 +303,9 @@ struct meye {
303 struct meye_grab_buffer grab_buffer[MEYE_MAX_BUFNBRS]; 303 struct meye_grab_buffer grab_buffer[MEYE_MAX_BUFNBRS];
304 int vma_use_count[MEYE_MAX_BUFNBRS]; /* mmap count */ 304 int vma_use_count[MEYE_MAX_BUFNBRS]; /* mmap count */
305 struct mutex lock; /* mutex for open/mmap... */ 305 struct mutex lock; /* mutex for open/mmap... */
306 struct kfifo *grabq; /* queue for buffers to be grabbed */ 306 struct kfifo grabq; /* queue for buffers to be grabbed */
307 spinlock_t grabq_lock; /* lock protecting the queue */ 307 spinlock_t grabq_lock; /* lock protecting the queue */
308 struct kfifo *doneq; /* queue for grabbed buffers */ 308 struct kfifo doneq; /* queue for grabbed buffers */
309 spinlock_t doneq_lock; /* lock protecting the queue */ 309 spinlock_t doneq_lock; /* lock protecting the queue */
310 wait_queue_head_t proc_list; /* wait queue */ 310 wait_queue_head_t proc_list; /* wait queue */
311 struct video_device *video_dev; /* video device parameters */ 311 struct video_device *video_dev; /* video device parameters */