From: Ian Armstrong <ian@iarmst.demon.co.uk>
Date: Sat, 4 Oct 2008 13:28:24 +0000 (-0300)
Subject: V4L/DVB (9163): ivtvfb: fix sparse warnings and improve write function
X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=c777549fc9c5c704707394b0235a9a6794247b83;p=GitHub%2FLineageOS%2FG12%2Fandroid_kernel_amlogic_linux-4.9.git

V4L/DVB (9163): ivtvfb: fix sparse warnings and improve write function

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>
---

diff --git a/drivers/media/video/ivtv/ivtvfb.c b/drivers/media/video/ivtv/ivtvfb.c
index bdfda48e56bf..249758e53f5f 100644
--- a/drivers/media/video/ivtv/ivtvfb.c
+++ b/drivers/media/video/ivtv/ivtvfb.c
@@ -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;