diff options
author | Ian Armstrong <ian@iarmst.demon.co.uk> | 2008-10-04 09:28:24 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2008-10-13 07:08:08 -0400 |
commit | c777549fc9c5c704707394b0235a9a6794247b83 (patch) | |
tree | 3c77e6e1c54a8643b625297e62c184f449dc23c8 | |
parent | a8b864354e060dda1000e62d1fea7c1274581caf (diff) |
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>
-rw-r--r-- | drivers/media/video/ivtv/ivtvfb.c | 76 |
1 files changed, 37 insertions, 39 deletions
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, | |||
275 | int size_in_bytes) | 275 | int size_in_bytes) |
276 | { | 276 | { |
277 | DEFINE_WAIT(wait); | 277 | DEFINE_WAIT(wait); |
278 | int ret = 0; | ||
279 | int got_sig = 0; | 278 | int got_sig = 0; |
280 | 279 | ||
281 | mutex_lock(&itv->udma.lock); | 280 | mutex_lock(&itv->udma.lock); |
@@ -316,7 +315,7 @@ static int ivtvfb_prep_dec_dma_to_device(struct ivtv *itv, | |||
316 | return -EINTR; | 315 | return -EINTR; |
317 | } | 316 | } |
318 | 317 | ||
319 | return ret; | 318 | return 0; |
320 | } | 319 | } |
321 | 320 | ||
322 | static int ivtvfb_prep_frame(struct ivtv *itv, int cmd, void __user *source, | 321 | 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 | unsigned long p = *ppos; | 372 | unsigned long p = *ppos; |
374 | void *dst; | 373 | void *dst; |
375 | int err = 0; | 374 | int err = 0; |
375 | int dma_err; | ||
376 | unsigned long total_size; | 376 | unsigned long total_size; |
377 | struct ivtv *itv = (struct ivtv *) info->par; | 377 | struct ivtv *itv = (struct ivtv *) info->par; |
378 | unsigned long dma_offset = | 378 | unsigned long dma_offset = |
@@ -399,7 +399,6 @@ static ssize_t ivtvfb_write(struct fb_info *info, const char __user *buf, | |||
399 | if (count + p > total_size) { | 399 | if (count + p > total_size) { |
400 | if (!err) | 400 | if (!err) |
401 | err = -ENOSPC; | 401 | err = -ENOSPC; |
402 | |||
403 | count = total_size - p; | 402 | count = total_size - p; |
404 | } | 403 | } |
405 | 404 | ||
@@ -408,39 +407,34 @@ static ssize_t ivtvfb_write(struct fb_info *info, const char __user *buf, | |||
408 | if (info->fbops->fb_sync) | 407 | if (info->fbops->fb_sync) |
409 | info->fbops->fb_sync(info); | 408 | info->fbops->fb_sync(info); |
410 | 409 | ||
411 | if (!access_ok(VERIFY_READ, buf, count)) { | 410 | /* If transfer size > threshold and both src/dst |
412 | IVTVFB_WARN("Invalid userspace pointer 0x%08lx\n", | 411 | addresses are aligned, use DMA */ |
413 | (unsigned long)buf); | 412 | if (count >= 4096 && |
414 | err = -EFAULT; | 413 | ((unsigned long)buf & 3) == ((unsigned long)dst & 3)) { |
415 | } | 414 | /* Odd address = can't DMA. Align */ |
416 | 415 | if ((unsigned long)dst & 3) { | |
417 | if (!err) { | 416 | lead = 4 - ((unsigned long)dst & 3); |
418 | /* If transfer size > threshold and both src/dst | 417 | if (copy_from_user(dst, buf, lead)) |
419 | addresses are aligned, use DMA */ | 418 | return -EFAULT; |
420 | if (count >= 4096 && | 419 | buf += lead; |
421 | ((unsigned long)buf & 3) == ((unsigned long)dst & 3)) { | 420 | dst += lead; |
422 | /* Odd address = can't DMA. Align */ | ||
423 | if ((unsigned long)dst & 3) { | ||
424 | lead = 4 - ((unsigned long)dst & 3); | ||
425 | memcpy(dst, buf, lead); | ||
426 | buf += lead; | ||
427 | dst += lead; | ||
428 | } | ||
429 | /* DMA resolution is 32 bits */ | ||
430 | if ((count - lead) & 3) | ||
431 | tail = (count - lead) & 3; | ||
432 | /* DMA the data */ | ||
433 | dma_size = count - lead - tail; | ||
434 | err = ivtvfb_prep_dec_dma_to_device(itv, | ||
435 | p + lead + dma_offset, (void *)buf, dma_size); | ||
436 | dst += dma_size; | ||
437 | buf += dma_size; | ||
438 | /* Copy any leftover data */ | ||
439 | if (tail) | ||
440 | memcpy(dst, buf, tail); | ||
441 | } else { | ||
442 | memcpy(dst, buf, count); | ||
443 | } | 421 | } |
422 | /* DMA resolution is 32 bits */ | ||
423 | if ((count - lead) & 3) | ||
424 | tail = (count - lead) & 3; | ||
425 | /* DMA the data */ | ||
426 | dma_size = count - lead - tail; | ||
427 | dma_err = ivtvfb_prep_dec_dma_to_device(itv, | ||
428 | p + lead + dma_offset, (void __user *)buf, dma_size); | ||
429 | if (dma_err) | ||
430 | return dma_err; | ||
431 | dst += dma_size; | ||
432 | buf += dma_size; | ||
433 | /* Copy any leftover data */ | ||
434 | if (tail && copy_from_user(dst, buf, tail)) | ||
435 | return -EFAULT; | ||
436 | } else if (copy_from_user(dst, buf, count)) { | ||
437 | return -EFAULT; | ||
444 | } | 438 | } |
445 | 439 | ||
446 | if (!err) | 440 | if (!err) |
@@ -463,9 +457,12 @@ static int ivtvfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long ar | |||
463 | vblank.flags = FB_VBLANK_HAVE_COUNT |FB_VBLANK_HAVE_VCOUNT | | 457 | vblank.flags = FB_VBLANK_HAVE_COUNT |FB_VBLANK_HAVE_VCOUNT | |
464 | FB_VBLANK_HAVE_VSYNC; | 458 | FB_VBLANK_HAVE_VSYNC; |
465 | trace = read_reg(0x028c0) >> 16; | 459 | trace = read_reg(0x028c0) >> 16; |
466 | if (itv->is_50hz && trace > 312) trace -= 312; | 460 | if (itv->is_50hz && trace > 312) |
467 | else if (itv->is_60hz && trace > 262) trace -= 262; | 461 | trace -= 312; |
468 | if (trace == 1) vblank.flags |= FB_VBLANK_VSYNCING; | 462 | else if (itv->is_60hz && trace > 262) |
463 | trace -= 262; | ||
464 | if (trace == 1) | ||
465 | vblank.flags |= FB_VBLANK_VSYNCING; | ||
469 | vblank.count = itv->last_vsync_field; | 466 | vblank.count = itv->last_vsync_field; |
470 | vblank.vcount = trace; | 467 | vblank.vcount = trace; |
471 | vblank.hcount = 0; | 468 | vblank.hcount = 0; |
@@ -476,7 +473,8 @@ static int ivtvfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long ar | |||
476 | 473 | ||
477 | case FBIO_WAITFORVSYNC: | 474 | case FBIO_WAITFORVSYNC: |
478 | prepare_to_wait(&itv->vsync_waitq, &wait, TASK_INTERRUPTIBLE); | 475 | prepare_to_wait(&itv->vsync_waitq, &wait, TASK_INTERRUPTIBLE); |
479 | if (!schedule_timeout(msecs_to_jiffies(50))) rc = -ETIMEDOUT; | 476 | if (!schedule_timeout(msecs_to_jiffies(50))) |
477 | rc = -ETIMEDOUT; | ||
480 | finish_wait(&itv->vsync_waitq, &wait); | 478 | finish_wait(&itv->vsync_waitq, &wait); |
481 | return rc; | 479 | return rc; |
482 | 480 | ||