]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] v4l: video-buf update
authorGerd Knorr <kraxel@bytesex.org>
Mon, 10 Mar 2003 03:09:48 +0000 (19:09 -0800)
committerLinus Torvalds <torvalds@home.transmeta.com>
Mon, 10 Mar 2003 03:09:48 +0000 (19:09 -0800)
This patch is a update for the video-buf mm helper module.  It has
some minor bugfixes and a number of signed/unsigned cleanups to make
gcc 3.3 happy.

drivers/media/video/video-buf.c
drivers/media/video/video-buf.h

index 1083cac45da47b4478798eabbbbd3697a89d54ea..20e2c2e6f6926d9cd4001077582e2518d7b6911d 100644 (file)
@@ -83,6 +83,8 @@ videobuf_pages_to_sg(struct page **pages, int nr_pages, int offset)
                return NULL;
        memset(sglist, 0, sizeof(*sglist) * nr_pages);
 
+       if (NULL == pages[0])
+               goto nopage;
        if (PageHighMem(pages[0]))
                /* DMA to highmem pages might not work */
                goto highmem;
@@ -118,7 +120,7 @@ int videobuf_lock(struct page **pages, int nr_pages)
        for (i = 0; i < nr_pages; i++)
                if (TryLockPage(pages[i]))
                        goto err;
-       dprintk(2,"lock ok\n");
+       dprintk(2,"lock ok [%d pages]\n",nr_pages);
        return 0;
 
  err:
@@ -136,7 +138,7 @@ int videobuf_unlock(struct page **pages, int nr_pages)
        dprintk(2,"unlock start ...\n");
        for (i = 0; i < nr_pages; i++)
                unlock_page(pages[i]);
-       dprintk(2,"unlock ok\n");
+       dprintk(2,"unlock ok [%d pages]\n",nr_pages);
        return 0;
 }
 
@@ -270,7 +272,7 @@ int videobuf_dma_free(struct videobuf_dmabuf *dma)
 
 /* --------------------------------------------------------------------- */
 
-void* videobuf_alloc(int size)
+void* videobuf_alloc(unsigned int size)
 {
        struct videobuf_buffer *vb;
 
@@ -340,7 +342,7 @@ videobuf_queue_init(struct videobuf_queue *q,
                    spinlock_t *irqlock,
                    enum v4l2_buf_type type,
                    enum v4l2_field field,
-                   int msize)
+                   unsigned int msize)
 {
        memset(q,0,sizeof(*q));
 
@@ -417,11 +419,11 @@ videobuf_next_field(struct videobuf_queue *q)
 
        if (V4L2_FIELD_ALTERNATE == field) {
                if (V4L2_FIELD_TOP == q->last) {
-                       field   = V4L2_FIELD_TOP;
-                       q->last = V4L2_FIELD_TOP;
-               } else {
                        field   = V4L2_FIELD_BOTTOM;
                        q->last = V4L2_FIELD_BOTTOM;
+               } else {
+                       field   = V4L2_FIELD_TOP;
+                       q->last = V4L2_FIELD_TOP;
                }
        }
        return field;
@@ -463,7 +465,8 @@ int
 videobuf_reqbufs(struct file *file, struct videobuf_queue *q,
                 struct v4l2_requestbuffers *req)
 {
-       int size,count,retval;
+       unsigned int size,count;
+       int retval;
 
        if (req->type != q->type)
                return -EINVAL;
@@ -477,6 +480,8 @@ videobuf_reqbufs(struct file *file, struct videobuf_queue *q,
        size = 0;
        q->ops->buf_setup(file,&count,&size);
        size = PAGE_ALIGN(size);
+       dprintk(1,"reqbufs: bufs=%d, size=0x%x [%d pages total]\n",
+               count, size, (count*size)>>PAGE_SHIFT);
 
        retval = videobuf_mmap_setup(file,q,count,size);
        if (retval < 0)
@@ -660,7 +665,10 @@ videobuf_read_zerocopy(struct file *file, struct videobuf_queue *q,
         retval = videobuf_waiton(q->read_buf,0,0);
         if (0 == retval) {
                videobuf_dma_pci_sync(q->pci,&q->read_buf->dma);
-                retval = q->read_buf->size;
+               if (STATE_ERROR == q->read_buf->state)
+                       retval = -EIO;
+               else
+                       retval = q->read_buf->size;
        }
 
  done:
@@ -676,7 +684,8 @@ ssize_t videobuf_read_one(struct file *file, struct videobuf_queue *q,
 {
        enum v4l2_field field;
        unsigned long flags;
-       int retval, bytes, size, nbufs;
+       unsigned size, nbufs, bytes;
+       int retval;
 
        down(&q->lock);
 
@@ -686,7 +695,7 @@ ssize_t videobuf_read_one(struct file *file, struct videobuf_queue *q,
            count >= size        &&
            !(file->f_flags & O_NONBLOCK)) {
                retval = videobuf_read_zerocopy(file,q,data,count,ppos);
-               if (retval >= 0)
+               if (retval >= 0  ||  retval == -EIO)
                        /* ok, all done */
                        goto done;
                /* fallback to kernel bounce buffer on failures */
@@ -714,6 +723,15 @@ ssize_t videobuf_read_one(struct file *file, struct videobuf_queue *q,
                goto done;
        videobuf_dma_pci_sync(q->pci,&q->read_buf->dma);
 
+       if (STATE_ERROR == q->read_buf->state) {
+               /* catch I/O errors */
+               q->ops->buf_release(file,q->read_buf);
+               kfree(q->read_buf);
+               q->read_buf = NULL;
+               retval = -EIO;
+               goto done;
+       }
+
        /* copy to userspace */
        bytes = count;
        if (bytes > q->read_buf->size - q->read_off)
@@ -788,8 +806,8 @@ ssize_t videobuf_read_stream(struct file *file, struct videobuf_queue *q,
                             char *data, size_t count, loff_t *ppos,
                             int vbihack)
 {
-       unsigned int *fc;
-       int err, bytes, retval;
+       unsigned int *fc, bytes;
+       int err, retval;
        unsigned long flags;
        
        down(&q->lock);
@@ -968,9 +986,10 @@ static struct vm_operations_struct videobuf_vm_ops =
 };
 
 int videobuf_mmap_setup(struct file *file, struct videobuf_queue *q,
-                       int bcount, int bsize)
+                       unsigned int bcount, unsigned int bsize)
 {
-       int i,err;
+       unsigned int i;
+       int err;
 
        err = videobuf_mmap_free(file,q);
        if (0 != err)
@@ -1008,7 +1027,8 @@ int videobuf_mmap_mapper(struct vm_area_struct *vma,
                         struct videobuf_queue *q)
 {
        struct videobuf_mapping *map;
-       int first,last,size,i,retval;
+       unsigned int first,last,size,i;
+       int retval;
 
        down(&q->lock);
        retval = -EINVAL;
@@ -1025,7 +1045,7 @@ int videobuf_mmap_mapper(struct vm_area_struct *vma,
        for (first = 0; first < VIDEO_MAX_FRAME; first++) {
                if (NULL == q->bufs[first])
                        continue;
-               if (q->bufs[first]->boff  == (vma->vm_pgoff << PAGE_SHIFT))
+               if (q->bufs[first]->boff == (vma->vm_pgoff << PAGE_SHIFT))
                        break;
        }
        if (VIDEO_MAX_FRAME == first) {
index d4b03b3570d820d056e453ee9752a19e17cb49d9..fceea3e24f754fe6960195d0c58571bf27afc4d7 100644 (file)
@@ -110,7 +110,7 @@ struct videobuf_buffer;
 struct videobuf_queue;
 
 struct videobuf_mapping {
-       int count;
+       unsigned int count;
        int highmem_ok;
        unsigned long start;
        unsigned long end;
@@ -128,19 +128,19 @@ enum videobuf_state {
 };
 
 struct videobuf_buffer {
-       int                     i;
+       unsigned int            i;
 
        /* info about the buffer */
-       int                     width;
-       int                     height;
-       long                    size;
+       unsigned int            width;
+       unsigned int            height;
+       unsigned long           size;
        enum v4l2_field         field;
        enum videobuf_state     state;
        struct videobuf_dmabuf  dma;
        struct list_head        stream;  /* QBUF/DQBUF list */
 
        /* for mmap'ed buffers */
-       off_t                   boff;    /* buffer offset (mmap) */
+       size_t                  boff;    /* buffer offset (mmap) */
        size_t                  bsize;   /* buffer size */
        unsigned long           baddr;   /* buffer addr (userland ptr!) */
        struct videobuf_mapping *map;
@@ -148,12 +148,13 @@ struct videobuf_buffer {
        /* touched by irq handler */
        struct list_head        queue;
        wait_queue_head_t       done;
-       int                     field_count;
+       unsigned int            field_count;
        struct timeval          ts;
 };
 
 struct videobuf_queue_ops {
-       int (*buf_setup)(struct file *file, int *count, int *size);
+       int (*buf_setup)(struct file *file,
+                        unsigned int *count, unsigned int *size);
        int (*buf_prepare)(struct file *file,struct videobuf_buffer *vb,
                           enum v4l2_field field);
        void (*buf_queue)(struct file *file,struct videobuf_buffer *vb);
@@ -166,23 +167,23 @@ struct videobuf_queue {
        struct pci_dev             *pci;
 
        enum v4l2_buf_type         type;
-       int                        msize;
+       unsigned int               msize;
        enum v4l2_field            field;
        enum v4l2_field            last; /* for field=V4L2_FIELD_ALTERNATE */
        struct videobuf_buffer     *bufs[VIDEO_MAX_FRAME];
        struct videobuf_queue_ops  *ops;
 
        /* capture via mmap() + ioctl(QBUF/DQBUF) */
-       int                        streaming;
+       unsigned int               streaming;
        struct list_head           stream;
 
        /* capture via read() */
-       int                        reading;
-       int                        read_off;
+       unsigned int               reading;
+       unsigned int               read_off;
        struct videobuf_buffer     *read_buf;
 };
 
-void* videobuf_alloc(int size);
+void* videobuf_alloc(unsigned int size);
 int videobuf_waiton(struct videobuf_buffer *vb, int non_blocking, int intr);
 int videobuf_iolock(struct pci_dev *pci, struct videobuf_buffer *vb);
 
@@ -190,7 +191,8 @@ void videobuf_queue_init(struct videobuf_queue *q,
                         struct videobuf_queue_ops *ops,
                         struct pci_dev *pci, spinlock_t *irqlock,
                         enum v4l2_buf_type type,
-                        enum v4l2_field field, int msize);
+                        enum v4l2_field field,
+                        unsigned int msize);
 int  videobuf_queue_is_busy(struct videobuf_queue *q);
 void videobuf_queue_cancel(struct file *file, struct videobuf_queue *q);
 
@@ -218,7 +220,7 @@ unsigned int videobuf_poll_stream(struct file *file,
                                  poll_table *wait);
 
 int videobuf_mmap_setup(struct file *file, struct videobuf_queue *q,
-                       int bcount, int bsize);
+                       unsigned int bcount, unsigned int bsize);
 int videobuf_mmap_free(struct file *file, struct videobuf_queue *q);
 int videobuf_mmap_mapper(struct vm_area_struct *vma,
                         struct videobuf_queue *q);