V4L/DVB (9163): ivtvfb: fix sparse warnings and improve write function
authorIan Armstrong <ian@iarmst.demon.co.uk>
Sat, 4 Oct 2008 13:28:24 +0000 (10:28 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Mon, 13 Oct 2008 11:08:08 +0000 (09:08 -0200)
Signed-off-by: Ian Armstrong <ian@iarmst.demon.co.uk>
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/media/video/ivtv/ivtvfb.c

index bdfda48e56bf55e0b5ea3af83404348053fd26b8..249758e53f5f6faa7fa238f48780e3213fd277b0 100644 (file)
@@ -275,7 +275,6 @@ static int ivtvfb_prep_dec_dma_to_device(struct ivtv *itv,
                                  int size_in_bytes)
 {
        DEFINE_WAIT(wait);
-       int ret = 0;
        int got_sig = 0;
 
        mutex_lock(&itv->udma.lock);
@@ -316,7 +315,7 @@ static int ivtvfb_prep_dec_dma_to_device(struct ivtv *itv,
                return -EINTR;
        }
 
-       return ret;
+       return 0;
 }
 
 static int ivtvfb_prep_frame(struct ivtv *itv, int cmd, void __user *source,
@@ -373,6 +372,7 @@ static ssize_t ivtvfb_write(struct fb_info *info, const char __user *buf,
        unsigned long p = *ppos;
        void *dst;
        int err = 0;
+       int dma_err;
        unsigned long total_size;
        struct ivtv *itv = (struct ivtv *) info->par;
        unsigned long dma_offset =
@@ -399,7 +399,6 @@ static ssize_t ivtvfb_write(struct fb_info *info, const char __user *buf,
        if (count + p > total_size) {
                if (!err)
                        err = -ENOSPC;
-
                count = total_size - p;
        }
 
@@ -408,39 +407,34 @@ static ssize_t ivtvfb_write(struct fb_info *info, const char __user *buf,
        if (info->fbops->fb_sync)
                info->fbops->fb_sync(info);
 
-       if (!access_ok(VERIFY_READ, buf, count)) {
-               IVTVFB_WARN("Invalid userspace pointer 0x%08lx\n",
-                       (unsigned long)buf);
-               err = -EFAULT;
-       }
-
-       if (!err) {
-               /* If transfer size > threshold and both src/dst
-               addresses are aligned, use DMA */
-               if (count >= 4096 &&
-                   ((unsigned long)buf & 3) == ((unsigned long)dst & 3)) {
-                       /* Odd address = can't DMA. Align */
-                       if ((unsigned long)dst & 3) {
-                               lead = 4 - ((unsigned long)dst & 3);
-                               memcpy(dst, buf, lead);
-                               buf += lead;
-                               dst += lead;
-                       }
-                       /* DMA resolution is 32 bits */
-                       if ((count - lead) & 3)
-                               tail = (count - lead) & 3;
-                       /* DMA the data */
-                       dma_size = count - lead - tail;
-                       err = ivtvfb_prep_dec_dma_to_device(itv,
-                              p + lead + dma_offset, (void *)buf, dma_size);
-                       dst += dma_size;
-                       buf += dma_size;
-                       /* Copy any leftover data */
-                       if (tail)
-                               memcpy(dst, buf, tail);
-               } else {
-                       memcpy(dst, buf, count);
+       /* If transfer size > threshold and both src/dst
+       addresses are aligned, use DMA */
+       if (count >= 4096 &&
+           ((unsigned long)buf & 3) == ((unsigned long)dst & 3)) {
+               /* Odd address = can't DMA. Align */
+               if ((unsigned long)dst & 3) {
+                       lead = 4 - ((unsigned long)dst & 3);
+                       if (copy_from_user(dst, buf, lead))
+                               return -EFAULT;
+                       buf += lead;
+                       dst += lead;
                }
+               /* DMA resolution is 32 bits */
+               if ((count - lead) & 3)
+                       tail = (count - lead) & 3;
+               /* DMA the data */
+               dma_size = count - lead - tail;
+               dma_err = ivtvfb_prep_dec_dma_to_device(itv,
+                      p + lead + dma_offset, (void __user *)buf, dma_size);
+               if (dma_err)
+                       return dma_err;
+               dst += dma_size;
+               buf += dma_size;
+               /* Copy any leftover data */
+               if (tail && copy_from_user(dst, buf, tail))
+                       return -EFAULT;
+       } else if (copy_from_user(dst, buf, count)) {
+               return -EFAULT;
        }
 
        if  (!err)
@@ -463,9 +457,12 @@ static int ivtvfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long ar
                        vblank.flags = FB_VBLANK_HAVE_COUNT |FB_VBLANK_HAVE_VCOUNT |
                                        FB_VBLANK_HAVE_VSYNC;
                        trace = read_reg(0x028c0) >> 16;
-                       if (itv->is_50hz && trace > 312) trace -= 312;
-                       else if (itv->is_60hz && trace > 262) trace -= 262;
-                       if (trace == 1) vblank.flags |= FB_VBLANK_VSYNCING;
+                       if (itv->is_50hz && trace > 312)
+                               trace -= 312;
+                       else if (itv->is_60hz && trace > 262)
+                               trace -= 262;
+                       if (trace == 1)
+                               vblank.flags |= FB_VBLANK_VSYNCING;
                        vblank.count = itv->last_vsync_field;
                        vblank.vcount = trace;
                        vblank.hcount = 0;
@@ -476,7 +473,8 @@ static int ivtvfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long ar
 
                case FBIO_WAITFORVSYNC:
                        prepare_to_wait(&itv->vsync_waitq, &wait, TASK_INTERRUPTIBLE);
-                       if (!schedule_timeout(msecs_to_jiffies(50))) rc = -ETIMEDOUT;
+                       if (!schedule_timeout(msecs_to_jiffies(50)))
+                               rc = -ETIMEDOUT;
                        finish_wait(&itv->vsync_waitq, &wait);
                        return rc;