提交 c777549f 编写于 作者: I Ian Armstrong 提交者: Mauro Carvalho Chehab

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

Signed-off-by: NIan Armstrong <ian@iarmst.demon.co.uk>
Signed-off-by: NHans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: NMauro Carvalho Chehab <mchehab@redhat.com>
上级 a8b86435
...@@ -275,7 +275,6 @@ static int ivtvfb_prep_dec_dma_to_device(struct ivtv *itv, ...@@ -275,7 +275,6 @@ static int ivtvfb_prep_dec_dma_to_device(struct ivtv *itv,
int size_in_bytes) int size_in_bytes)
{ {
DEFINE_WAIT(wait); DEFINE_WAIT(wait);
int ret = 0;
int got_sig = 0; int got_sig = 0;
mutex_lock(&itv->udma.lock); mutex_lock(&itv->udma.lock);
...@@ -316,7 +315,7 @@ static int ivtvfb_prep_dec_dma_to_device(struct ivtv *itv, ...@@ -316,7 +315,7 @@ static int ivtvfb_prep_dec_dma_to_device(struct ivtv *itv,
return -EINTR; return -EINTR;
} }
return ret; return 0;
} }
static int ivtvfb_prep_frame(struct ivtv *itv, int cmd, void __user *source, 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, ...@@ -373,6 +372,7 @@ static ssize_t ivtvfb_write(struct fb_info *info, const char __user *buf,
unsigned long p = *ppos; unsigned long p = *ppos;
void *dst; void *dst;
int err = 0; int err = 0;
int dma_err;
unsigned long total_size; unsigned long total_size;
struct ivtv *itv = (struct ivtv *) info->par; struct ivtv *itv = (struct ivtv *) info->par;
unsigned long dma_offset = unsigned long dma_offset =
...@@ -399,7 +399,6 @@ static ssize_t ivtvfb_write(struct fb_info *info, const char __user *buf, ...@@ -399,7 +399,6 @@ static ssize_t ivtvfb_write(struct fb_info *info, const char __user *buf,
if (count + p > total_size) { if (count + p > total_size) {
if (!err) if (!err)
err = -ENOSPC; err = -ENOSPC;
count = total_size - p; count = total_size - p;
} }
...@@ -408,39 +407,34 @@ static ssize_t ivtvfb_write(struct fb_info *info, const char __user *buf, ...@@ -408,39 +407,34 @@ static ssize_t ivtvfb_write(struct fb_info *info, const char __user *buf,
if (info->fbops->fb_sync) if (info->fbops->fb_sync)
info->fbops->fb_sync(info); info->fbops->fb_sync(info);
if (!access_ok(VERIFY_READ, buf, count)) { /* If transfer size > threshold and both src/dst
IVTVFB_WARN("Invalid userspace pointer 0x%08lx\n", addresses are aligned, use DMA */
(unsigned long)buf); if (count >= 4096 &&
err = -EFAULT; ((unsigned long)buf & 3) == ((unsigned long)dst & 3)) {
} /* Odd address = can't DMA. Align */
if ((unsigned long)dst & 3) {
if (!err) { lead = 4 - ((unsigned long)dst & 3);
/* If transfer size > threshold and both src/dst if (copy_from_user(dst, buf, lead))
addresses are aligned, use DMA */ return -EFAULT;
if (count >= 4096 && buf += lead;
((unsigned long)buf & 3) == ((unsigned long)dst & 3)) { dst += lead;
/* 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);
} }
/* 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) if (!err)
...@@ -463,9 +457,12 @@ static int ivtvfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long ar ...@@ -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 | vblank.flags = FB_VBLANK_HAVE_COUNT |FB_VBLANK_HAVE_VCOUNT |
FB_VBLANK_HAVE_VSYNC; FB_VBLANK_HAVE_VSYNC;
trace = read_reg(0x028c0) >> 16; trace = read_reg(0x028c0) >> 16;
if (itv->is_50hz && trace > 312) trace -= 312; if (itv->is_50hz && trace > 312)
else if (itv->is_60hz && trace > 262) trace -= 262; trace -= 312;
if (trace == 1) vblank.flags |= FB_VBLANK_VSYNCING; else if (itv->is_60hz && trace > 262)
trace -= 262;
if (trace == 1)
vblank.flags |= FB_VBLANK_VSYNCING;
vblank.count = itv->last_vsync_field; vblank.count = itv->last_vsync_field;
vblank.vcount = trace; vblank.vcount = trace;
vblank.hcount = 0; vblank.hcount = 0;
...@@ -476,7 +473,8 @@ static int ivtvfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long ar ...@@ -476,7 +473,8 @@ static int ivtvfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long ar
case FBIO_WAITFORVSYNC: case FBIO_WAITFORVSYNC:
prepare_to_wait(&itv->vsync_waitq, &wait, TASK_INTERRUPTIBLE); 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); finish_wait(&itv->vsync_waitq, &wait);
return rc; return rc;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册