diff options
Diffstat (limited to 'drivers/media/video/vivi.c')
-rw-r--r-- | drivers/media/video/vivi.c | 350 |
1 files changed, 108 insertions, 242 deletions
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c index 1db067c02815..b1e9592acb90 100644 --- a/drivers/media/video/vivi.c +++ b/drivers/media/video/vivi.c | |||
@@ -146,8 +146,6 @@ struct vivi_buffer { | |||
146 | 146 | ||
147 | struct vivi_dmaqueue { | 147 | struct vivi_dmaqueue { |
148 | struct list_head active; | 148 | struct list_head active; |
149 | struct list_head queued; | ||
150 | struct timer_list timeout; | ||
151 | 149 | ||
152 | /* thread for generating video stream*/ | 150 | /* thread for generating video stream*/ |
153 | struct task_struct *kthread; | 151 | struct task_struct *kthread; |
@@ -162,8 +160,8 @@ static LIST_HEAD(vivi_devlist); | |||
162 | struct vivi_dev { | 160 | struct vivi_dev { |
163 | struct list_head vivi_devlist; | 161 | struct list_head vivi_devlist; |
164 | 162 | ||
165 | struct mutex lock; | ||
166 | spinlock_t slock; | 163 | spinlock_t slock; |
164 | struct mutex mutex; | ||
167 | 165 | ||
168 | int users; | 166 | int users; |
169 | 167 | ||
@@ -322,24 +320,26 @@ static void gen_line(char *basep, int inipos, int wmax, | |||
322 | end: | 320 | end: |
323 | return; | 321 | return; |
324 | } | 322 | } |
323 | |||
325 | static void vivi_fillbuff(struct vivi_dev *dev, struct vivi_buffer *buf) | 324 | static void vivi_fillbuff(struct vivi_dev *dev, struct vivi_buffer *buf) |
326 | { | 325 | { |
327 | int h , pos = 0; | 326 | int h , pos = 0; |
328 | int hmax = buf->vb.height; | 327 | int hmax = buf->vb.height; |
329 | int wmax = buf->vb.width; | 328 | int wmax = buf->vb.width; |
330 | struct timeval ts; | 329 | struct timeval ts; |
331 | char *tmpbuf = kmalloc(wmax * 2, GFP_KERNEL); | 330 | char *tmpbuf = kmalloc(wmax * 2, GFP_ATOMIC); |
332 | void *vbuf = videobuf_to_vmalloc(&buf->vb); | 331 | void *vbuf = videobuf_to_vmalloc(&buf->vb); |
333 | 332 | ||
334 | if (!tmpbuf) | 333 | if (!tmpbuf) |
335 | return; | 334 | return; |
336 | 335 | ||
336 | if (!vbuf) | ||
337 | return; | ||
338 | |||
337 | for (h = 0; h < hmax; h++) { | 339 | for (h = 0; h < hmax; h++) { |
338 | gen_line(tmpbuf, 0, wmax, hmax, h, dev->mv_count, | 340 | gen_line(tmpbuf, 0, wmax, hmax, h, dev->mv_count, |
339 | dev->timestr); | 341 | dev->timestr); |
340 | /* FIXME: replacing to __copy_to_user */ | 342 | memcpy(vbuf + pos, tmpbuf, wmax * 2); |
341 | if (copy_to_user(vbuf + pos, tmpbuf, wmax * 2) != 0) | ||
342 | dprintk(dev, 2, "vivifill copy_to_user failed.\n"); | ||
343 | pos += wmax*2; | 343 | pos += wmax*2; |
344 | } | 344 | } |
345 | 345 | ||
@@ -372,107 +372,71 @@ static void vivi_fillbuff(struct vivi_dev *dev, struct vivi_buffer *buf) | |||
372 | dev->timestr, (unsigned long)tmpbuf, pos); | 372 | dev->timestr, (unsigned long)tmpbuf, pos); |
373 | 373 | ||
374 | /* Advice that buffer was filled */ | 374 | /* Advice that buffer was filled */ |
375 | buf->vb.state = VIDEOBUF_DONE; | ||
376 | buf->vb.field_count++; | 375 | buf->vb.field_count++; |
377 | do_gettimeofday(&ts); | 376 | do_gettimeofday(&ts); |
378 | buf->vb.ts = ts; | 377 | buf->vb.ts = ts; |
379 | 378 | buf->vb.state = VIDEOBUF_DONE; | |
380 | list_del(&buf->vb.queue); | ||
381 | wake_up(&buf->vb.done); | ||
382 | } | 379 | } |
383 | 380 | ||
384 | static int restart_video_queue(struct vivi_dmaqueue *dma_q); | 381 | static void vivi_thread_tick(struct vivi_fh *fh) |
385 | |||
386 | static void vivi_thread_tick(struct vivi_dmaqueue *dma_q) | ||
387 | { | 382 | { |
388 | struct vivi_buffer *buf; | 383 | struct vivi_buffer *buf; |
389 | struct vivi_dev *dev = container_of(dma_q, struct vivi_dev, vidq); | 384 | struct vivi_dev *dev = fh->dev; |
385 | struct vivi_dmaqueue *dma_q = &dev->vidq; | ||
390 | 386 | ||
391 | int bc; | 387 | unsigned long flags = 0; |
392 | 388 | ||
393 | spin_lock(&dev->slock); | 389 | dprintk(dev, 1, "Thread tick\n"); |
394 | /* Announces videobuf that all went ok */ | ||
395 | for (bc = 0;; bc++) { | ||
396 | if (list_empty(&dma_q->active)) { | ||
397 | dprintk(dev, 1, "No active queue to serve\n"); | ||
398 | break; | ||
399 | } | ||
400 | 390 | ||
401 | buf = list_entry(dma_q->active.next, | 391 | spin_lock_irqsave(&dev->slock, flags); |
402 | struct vivi_buffer, vb.queue); | 392 | if (list_empty(&dma_q->active)) { |
393 | dprintk(dev, 1, "No active queue to serve\n"); | ||
394 | goto unlock; | ||
395 | } | ||
403 | 396 | ||
404 | /* Nobody is waiting something to be done, just return */ | 397 | buf = list_entry(dma_q->active.next, |
405 | if (!waitqueue_active(&buf->vb.done)) { | 398 | struct vivi_buffer, vb.queue); |
406 | mod_timer(&dma_q->timeout, jiffies+BUFFER_TIMEOUT); | 399 | |
407 | spin_unlock(&dev->slock); | 400 | /* Nobody is waiting on this buffer, return */ |
408 | return; | 401 | if (!waitqueue_active(&buf->vb.done)) |
409 | } | 402 | goto unlock; |
410 | 403 | ||
411 | do_gettimeofday(&buf->vb.ts); | 404 | list_del(&buf->vb.queue); |
412 | dprintk(dev, 2, "[%p/%d] wakeup\n", buf, buf->vb. i); | ||
413 | 405 | ||
414 | /* Fill buffer */ | 406 | do_gettimeofday(&buf->vb.ts); |
415 | vivi_fillbuff(dev, buf); | ||
416 | 407 | ||
417 | if (list_empty(&dma_q->active)) { | 408 | /* Fill buffer */ |
418 | del_timer(&dma_q->timeout); | 409 | vivi_fillbuff(dev, buf); |
419 | } else { | 410 | dprintk(dev, 1, "filled buffer %p\n", buf); |
420 | mod_timer(&dma_q->timeout, jiffies + BUFFER_TIMEOUT); | 411 | |
421 | } | 412 | wake_up(&buf->vb.done); |
422 | } | 413 | dprintk(dev, 2, "[%p/%d] wakeup\n", buf, buf->vb. i); |
423 | if (bc != 1) | 414 | unlock: |
424 | dprintk(dev, 1, "%s: %d buffers handled (should be 1)\n", | 415 | spin_unlock_irqrestore(&dev->slock, flags); |
425 | __FUNCTION__, bc); | 416 | return; |
426 | spin_unlock(&dev->slock); | ||
427 | } | 417 | } |
428 | 418 | ||
429 | #define frames_to_ms(frames) \ | 419 | #define frames_to_ms(frames) \ |
430 | ((frames * WAKE_NUMERATOR * 1000) / WAKE_DENOMINATOR) | 420 | ((frames * WAKE_NUMERATOR * 1000) / WAKE_DENOMINATOR) |
431 | 421 | ||
432 | static void vivi_sleep(struct vivi_dmaqueue *dma_q) | 422 | static void vivi_sleep(struct vivi_fh *fh) |
433 | { | 423 | { |
434 | struct vivi_dev *dev = container_of(dma_q, struct vivi_dev, vidq); | 424 | struct vivi_dev *dev = fh->dev; |
435 | int timeout, running_time; | 425 | struct vivi_dmaqueue *dma_q = &dev->vidq; |
426 | int timeout; | ||
436 | DECLARE_WAITQUEUE(wait, current); | 427 | DECLARE_WAITQUEUE(wait, current); |
437 | 428 | ||
438 | dprintk(dev, 1, "%s dma_q=0x%08lx\n", __FUNCTION__, | 429 | dprintk(dev, 1, "%s dma_q=0x%08lx\n", __func__, |
439 | (unsigned long)dma_q); | 430 | (unsigned long)dma_q); |
440 | 431 | ||
441 | add_wait_queue(&dma_q->wq, &wait); | 432 | add_wait_queue(&dma_q->wq, &wait); |
442 | if (kthread_should_stop()) | 433 | if (kthread_should_stop()) |
443 | goto stop_task; | 434 | goto stop_task; |
444 | 435 | ||
445 | running_time = jiffies - dma_q->ini_jiffies; | ||
446 | dma_q->frame++; | ||
447 | |||
448 | /* Calculate time to wake up */ | 436 | /* Calculate time to wake up */ |
449 | timeout = msecs_to_jiffies(frames_to_ms(dma_q->frame)) - running_time; | 437 | timeout = msecs_to_jiffies(frames_to_ms(1)); |
450 | |||
451 | if (timeout > msecs_to_jiffies(frames_to_ms(2)) || timeout <= 0) { | ||
452 | int old = dma_q->frame; | ||
453 | int nframes; | ||
454 | |||
455 | dma_q->frame = (jiffies_to_msecs(running_time) / | ||
456 | frames_to_ms(1)) + 1; | ||
457 | |||
458 | timeout = msecs_to_jiffies(frames_to_ms(dma_q->frame)) | ||
459 | - running_time; | ||
460 | |||
461 | if (unlikely (timeout <= 0)) | ||
462 | timeout = 1; | ||
463 | |||
464 | nframes = (dma_q->frame > old)? | ||
465 | dma_q->frame - old : old - dma_q->frame; | ||
466 | |||
467 | dprintk(dev, 1, "%ld: %s %d frames. " | ||
468 | "Current frame is %d. Will sleep for %d jiffies\n", | ||
469 | jiffies, | ||
470 | (dma_q->frame > old)? "Underrun, losed" : "Overrun of", | ||
471 | nframes, dma_q->frame, timeout); | ||
472 | } else | ||
473 | dprintk(dev, 1, "will sleep for %d jiffies\n", timeout); | ||
474 | 438 | ||
475 | vivi_thread_tick(dma_q); | 439 | vivi_thread_tick(fh); |
476 | 440 | ||
477 | schedule_timeout_interruptible(timeout); | 441 | schedule_timeout_interruptible(timeout); |
478 | 442 | ||
@@ -483,16 +447,15 @@ stop_task: | |||
483 | 447 | ||
484 | static int vivi_thread(void *data) | 448 | static int vivi_thread(void *data) |
485 | { | 449 | { |
486 | struct vivi_dmaqueue *dma_q = data; | 450 | struct vivi_fh *fh = data; |
487 | struct vivi_dev *dev = container_of(dma_q, struct vivi_dev, vidq); | 451 | struct vivi_dev *dev = fh->dev; |
488 | 452 | ||
489 | dprintk(dev, 1, "thread started\n"); | 453 | dprintk(dev, 1, "thread started\n"); |
490 | 454 | ||
491 | mod_timer(&dma_q->timeout, jiffies+BUFFER_TIMEOUT); | ||
492 | set_freezable(); | 455 | set_freezable(); |
493 | 456 | ||
494 | for (;;) { | 457 | for (;;) { |
495 | vivi_sleep(dma_q); | 458 | vivi_sleep(fh); |
496 | 459 | ||
497 | if (kthread_should_stop()) | 460 | if (kthread_should_stop()) |
498 | break; | 461 | break; |
@@ -501,16 +464,17 @@ static int vivi_thread(void *data) | |||
501 | return 0; | 464 | return 0; |
502 | } | 465 | } |
503 | 466 | ||
504 | static int vivi_start_thread(struct vivi_dmaqueue *dma_q) | 467 | static int vivi_start_thread(struct vivi_fh *fh) |
505 | { | 468 | { |
506 | struct vivi_dev *dev = container_of(dma_q, struct vivi_dev, vidq); | 469 | struct vivi_dev *dev = fh->dev; |
470 | struct vivi_dmaqueue *dma_q = &dev->vidq; | ||
507 | 471 | ||
508 | dma_q->frame = 0; | 472 | dma_q->frame = 0; |
509 | dma_q->ini_jiffies = jiffies; | 473 | dma_q->ini_jiffies = jiffies; |
510 | 474 | ||
511 | dprintk(dev, 1, "%s\n", __FUNCTION__); | 475 | dprintk(dev, 1, "%s\n", __func__); |
512 | 476 | ||
513 | dma_q->kthread = kthread_run(vivi_thread, dma_q, "vivi"); | 477 | dma_q->kthread = kthread_run(vivi_thread, fh, "vivi"); |
514 | 478 | ||
515 | if (IS_ERR(dma_q->kthread)) { | 479 | if (IS_ERR(dma_q->kthread)) { |
516 | printk(KERN_ERR "vivi: kernel_thread() failed\n"); | 480 | printk(KERN_ERR "vivi: kernel_thread() failed\n"); |
@@ -519,7 +483,7 @@ static int vivi_start_thread(struct vivi_dmaqueue *dma_q) | |||
519 | /* Wakes thread */ | 483 | /* Wakes thread */ |
520 | wake_up_interruptible(&dma_q->wq); | 484 | wake_up_interruptible(&dma_q->wq); |
521 | 485 | ||
522 | dprintk(dev, 1, "returning from %s\n", __FUNCTION__); | 486 | dprintk(dev, 1, "returning from %s\n", __func__); |
523 | return 0; | 487 | return 0; |
524 | } | 488 | } |
525 | 489 | ||
@@ -527,7 +491,7 @@ static void vivi_stop_thread(struct vivi_dmaqueue *dma_q) | |||
527 | { | 491 | { |
528 | struct vivi_dev *dev = container_of(dma_q, struct vivi_dev, vidq); | 492 | struct vivi_dev *dev = container_of(dma_q, struct vivi_dev, vidq); |
529 | 493 | ||
530 | dprintk(dev, 1, "%s\n", __FUNCTION__); | 494 | dprintk(dev, 1, "%s\n", __func__); |
531 | /* shutdown control thread */ | 495 | /* shutdown control thread */ |
532 | if (dma_q->kthread) { | 496 | if (dma_q->kthread) { |
533 | kthread_stop(dma_q->kthread); | 497 | kthread_stop(dma_q->kthread); |
@@ -535,91 +499,6 @@ static void vivi_stop_thread(struct vivi_dmaqueue *dma_q) | |||
535 | } | 499 | } |
536 | } | 500 | } |
537 | 501 | ||
538 | static int restart_video_queue(struct vivi_dmaqueue *dma_q) | ||
539 | { | ||
540 | struct vivi_dev *dev = container_of(dma_q, struct vivi_dev, vidq); | ||
541 | struct vivi_buffer *buf, *prev; | ||
542 | |||
543 | dprintk(dev, 1, "%s dma_q=0x%08lx\n", __FUNCTION__, | ||
544 | (unsigned long)dma_q); | ||
545 | |||
546 | if (!list_empty(&dma_q->active)) { | ||
547 | buf = list_entry(dma_q->active.next, | ||
548 | struct vivi_buffer, vb.queue); | ||
549 | dprintk(dev, 2, "restart_queue [%p/%d]: restart dma\n", | ||
550 | buf, buf->vb.i); | ||
551 | |||
552 | dprintk(dev, 1, "Restarting video dma\n"); | ||
553 | vivi_stop_thread(dma_q); | ||
554 | |||
555 | /* cancel all outstanding capture / vbi requests */ | ||
556 | list_for_each_entry_safe(buf, prev, &dma_q->active, vb.queue) { | ||
557 | list_del(&buf->vb.queue); | ||
558 | buf->vb.state = VIDEOBUF_ERROR; | ||
559 | wake_up(&buf->vb.done); | ||
560 | } | ||
561 | mod_timer(&dma_q->timeout, jiffies+BUFFER_TIMEOUT); | ||
562 | |||
563 | return 0; | ||
564 | } | ||
565 | |||
566 | prev = NULL; | ||
567 | for (;;) { | ||
568 | if (list_empty(&dma_q->queued)) | ||
569 | return 0; | ||
570 | buf = list_entry(dma_q->queued.next, | ||
571 | struct vivi_buffer, vb.queue); | ||
572 | if (NULL == prev) { | ||
573 | list_del(&buf->vb.queue); | ||
574 | list_add_tail(&buf->vb.queue, &dma_q->active); | ||
575 | |||
576 | dprintk(dev, 1, "Restarting video dma\n"); | ||
577 | vivi_stop_thread(dma_q); | ||
578 | vivi_start_thread(dma_q); | ||
579 | |||
580 | buf->vb.state = VIDEOBUF_ACTIVE; | ||
581 | mod_timer(&dma_q->timeout, jiffies+BUFFER_TIMEOUT); | ||
582 | dprintk(dev, 2, | ||
583 | "[%p/%d] restart_queue - first active\n", | ||
584 | buf, buf->vb.i); | ||
585 | |||
586 | } else if (prev->vb.width == buf->vb.width && | ||
587 | prev->vb.height == buf->vb.height && | ||
588 | prev->fmt == buf->fmt) { | ||
589 | list_del(&buf->vb.queue); | ||
590 | list_add_tail(&buf->vb.queue, &dma_q->active); | ||
591 | buf->vb.state = VIDEOBUF_ACTIVE; | ||
592 | dprintk(dev, 2, | ||
593 | "[%p/%d] restart_queue - move to active\n", | ||
594 | buf, buf->vb.i); | ||
595 | } else { | ||
596 | return 0; | ||
597 | } | ||
598 | prev = buf; | ||
599 | } | ||
600 | } | ||
601 | |||
602 | static void vivi_vid_timeout(unsigned long data) | ||
603 | { | ||
604 | struct vivi_dev *dev = (struct vivi_dev *)data; | ||
605 | struct vivi_dmaqueue *vidq = &dev->vidq; | ||
606 | struct vivi_buffer *buf; | ||
607 | |||
608 | spin_lock(&dev->slock); | ||
609 | |||
610 | while (!list_empty(&vidq->active)) { | ||
611 | buf = list_entry(vidq->active.next, | ||
612 | struct vivi_buffer, vb.queue); | ||
613 | list_del(&buf->vb.queue); | ||
614 | buf->vb.state = VIDEOBUF_ERROR; | ||
615 | wake_up(&buf->vb.done); | ||
616 | printk(KERN_INFO "vivi/0: [%p/%d] timeout\n", buf, buf->vb.i); | ||
617 | } | ||
618 | restart_video_queue(vidq); | ||
619 | |||
620 | spin_unlock(&dev->slock); | ||
621 | } | ||
622 | |||
623 | /* ------------------------------------------------------------------ | 502 | /* ------------------------------------------------------------------ |
624 | Videobuf operations | 503 | Videobuf operations |
625 | ------------------------------------------------------------------*/ | 504 | ------------------------------------------------------------------*/ |
@@ -637,7 +516,7 @@ buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size) | |||
637 | while (*size * *count > vid_limit * 1024 * 1024) | 516 | while (*size * *count > vid_limit * 1024 * 1024) |
638 | (*count)--; | 517 | (*count)--; |
639 | 518 | ||
640 | dprintk(dev, 1, "%s, count=%d, size=%d\n", __FUNCTION__, | 519 | dprintk(dev, 1, "%s, count=%d, size=%d\n", __func__, |
641 | *count, *size); | 520 | *count, *size); |
642 | 521 | ||
643 | return 0; | 522 | return 0; |
@@ -648,13 +527,13 @@ static void free_buffer(struct videobuf_queue *vq, struct vivi_buffer *buf) | |||
648 | struct vivi_fh *fh = vq->priv_data; | 527 | struct vivi_fh *fh = vq->priv_data; |
649 | struct vivi_dev *dev = fh->dev; | 528 | struct vivi_dev *dev = fh->dev; |
650 | 529 | ||
651 | dprintk(dev, 1, "%s\n", __FUNCTION__); | 530 | dprintk(dev, 1, "%s, state: %i\n", __func__, buf->vb.state); |
652 | 531 | ||
653 | if (in_interrupt()) | 532 | if (in_interrupt()) |
654 | BUG(); | 533 | BUG(); |
655 | 534 | ||
656 | videobuf_waiton(&buf->vb, 0, 0); | ||
657 | videobuf_vmalloc_free(&buf->vb); | 535 | videobuf_vmalloc_free(&buf->vb); |
536 | dprintk(dev, 1, "free_buffer: freed\n"); | ||
658 | buf->vb.state = VIDEOBUF_NEEDS_INIT; | 537 | buf->vb.state = VIDEOBUF_NEEDS_INIT; |
659 | } | 538 | } |
660 | 539 | ||
@@ -667,28 +546,25 @@ buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, | |||
667 | struct vivi_fh *fh = vq->priv_data; | 546 | struct vivi_fh *fh = vq->priv_data; |
668 | struct vivi_dev *dev = fh->dev; | 547 | struct vivi_dev *dev = fh->dev; |
669 | struct vivi_buffer *buf = container_of(vb, struct vivi_buffer, vb); | 548 | struct vivi_buffer *buf = container_of(vb, struct vivi_buffer, vb); |
670 | int rc, init_buffer = 0; | 549 | int rc; |
671 | 550 | ||
672 | dprintk(dev, 1, "%s, field=%d\n", __FUNCTION__, field); | 551 | dprintk(dev, 1, "%s, field=%d\n", __func__, field); |
673 | 552 | ||
674 | BUG_ON(NULL == fh->fmt); | 553 | BUG_ON(NULL == fh->fmt); |
554 | |||
675 | if (fh->width < 48 || fh->width > norm_maxw() || | 555 | if (fh->width < 48 || fh->width > norm_maxw() || |
676 | fh->height < 32 || fh->height > norm_maxh()) | 556 | fh->height < 32 || fh->height > norm_maxh()) |
677 | return -EINVAL; | 557 | return -EINVAL; |
558 | |||
678 | buf->vb.size = fh->width*fh->height*2; | 559 | buf->vb.size = fh->width*fh->height*2; |
679 | if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) | 560 | if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) |
680 | return -EINVAL; | 561 | return -EINVAL; |
681 | 562 | ||
682 | if (buf->fmt != fh->fmt || | 563 | /* These properties only change when queue is idle, see s_fmt */ |
683 | buf->vb.width != fh->width || | 564 | buf->fmt = fh->fmt; |
684 | buf->vb.height != fh->height || | 565 | buf->vb.width = fh->width; |
685 | buf->vb.field != field) { | 566 | buf->vb.height = fh->height; |
686 | buf->fmt = fh->fmt; | 567 | buf->vb.field = field; |
687 | buf->vb.width = fh->width; | ||
688 | buf->vb.height = fh->height; | ||
689 | buf->vb.field = field; | ||
690 | init_buffer = 1; | ||
691 | } | ||
692 | 568 | ||
693 | if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { | 569 | if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { |
694 | rc = videobuf_iolock(vq, &buf->vb, NULL); | 570 | rc = videobuf_iolock(vq, &buf->vb, NULL); |
@@ -711,45 +587,12 @@ buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) | |||
711 | struct vivi_buffer *buf = container_of(vb, struct vivi_buffer, vb); | 587 | struct vivi_buffer *buf = container_of(vb, struct vivi_buffer, vb); |
712 | struct vivi_fh *fh = vq->priv_data; | 588 | struct vivi_fh *fh = vq->priv_data; |
713 | struct vivi_dev *dev = fh->dev; | 589 | struct vivi_dev *dev = fh->dev; |
714 | struct vivi_dmaqueue *vidq = &dev->vidq; | 590 | struct vivi_dmaqueue *vidq = &dev->vidq; |
715 | struct vivi_buffer *prev; | 591 | |
716 | 592 | dprintk(dev, 1, "%s\n", __func__); | |
717 | if (!list_empty(&vidq->queued)) { | 593 | |
718 | dprintk(dev, 1, "adding vb queue=0x%08lx\n", | 594 | buf->vb.state = VIDEOBUF_QUEUED; |
719 | (unsigned long)&buf->vb.queue); | 595 | list_add_tail(&buf->vb.queue, &vidq->active); |
720 | list_add_tail(&buf->vb.queue, &vidq->queued); | ||
721 | buf->vb.state = VIDEOBUF_QUEUED; | ||
722 | dprintk(dev, 2, "[%p/%d] buffer_queue - append to queued\n", | ||
723 | buf, buf->vb.i); | ||
724 | } else if (list_empty(&vidq->active)) { | ||
725 | list_add_tail(&buf->vb.queue, &vidq->active); | ||
726 | |||
727 | buf->vb.state = VIDEOBUF_ACTIVE; | ||
728 | mod_timer(&vidq->timeout, jiffies+BUFFER_TIMEOUT); | ||
729 | dprintk(dev, 2, "[%p/%d] buffer_queue - first active\n", | ||
730 | buf, buf->vb.i); | ||
731 | |||
732 | vivi_start_thread(vidq); | ||
733 | } else { | ||
734 | prev = list_entry(vidq->active.prev, | ||
735 | struct vivi_buffer, vb.queue); | ||
736 | if (prev->vb.width == buf->vb.width && | ||
737 | prev->vb.height == buf->vb.height && | ||
738 | prev->fmt == buf->fmt) { | ||
739 | list_add_tail(&buf->vb.queue, &vidq->active); | ||
740 | buf->vb.state = VIDEOBUF_ACTIVE; | ||
741 | dprintk(dev, 2, | ||
742 | "[%p/%d] buffer_queue - append to active\n", | ||
743 | buf, buf->vb.i); | ||
744 | |||
745 | } else { | ||
746 | list_add_tail(&buf->vb.queue, &vidq->queued); | ||
747 | buf->vb.state = VIDEOBUF_QUEUED; | ||
748 | dprintk(dev, 2, | ||
749 | "[%p/%d] buffer_queue - first queued\n", | ||
750 | buf, buf->vb.i); | ||
751 | } | ||
752 | } | ||
753 | } | 596 | } |
754 | 597 | ||
755 | static void buffer_release(struct videobuf_queue *vq, | 598 | static void buffer_release(struct videobuf_queue *vq, |
@@ -758,11 +601,8 @@ static void buffer_release(struct videobuf_queue *vq, | |||
758 | struct vivi_buffer *buf = container_of(vb, struct vivi_buffer, vb); | 601 | struct vivi_buffer *buf = container_of(vb, struct vivi_buffer, vb); |
759 | struct vivi_fh *fh = vq->priv_data; | 602 | struct vivi_fh *fh = vq->priv_data; |
760 | struct vivi_dev *dev = (struct vivi_dev *)fh->dev; | 603 | struct vivi_dev *dev = (struct vivi_dev *)fh->dev; |
761 | struct vivi_dmaqueue *vidq = &dev->vidq; | ||
762 | |||
763 | dprintk(dev, 1, "%s\n", __FUNCTION__); | ||
764 | 604 | ||
765 | vivi_stop_thread(vidq); | 605 | dprintk(dev, 1, "%s\n", __func__); |
766 | 606 | ||
767 | free_buffer(vq, buf); | 607 | free_buffer(vq, buf); |
768 | } | 608 | } |
@@ -869,17 +709,31 @@ static int vidioc_s_fmt_cap(struct file *file, void *priv, | |||
869 | struct v4l2_format *f) | 709 | struct v4l2_format *f) |
870 | { | 710 | { |
871 | struct vivi_fh *fh = priv; | 711 | struct vivi_fh *fh = priv; |
712 | struct videobuf_queue *q = &fh->vb_vidq; | ||
713 | |||
872 | int ret = vidioc_try_fmt_cap(file, fh, f); | 714 | int ret = vidioc_try_fmt_cap(file, fh, f); |
873 | if (ret < 0) | 715 | if (ret < 0) |
874 | return (ret); | 716 | return (ret); |
875 | 717 | ||
718 | mutex_lock(&q->vb_lock); | ||
719 | |||
720 | if (videobuf_queue_is_busy(&fh->vb_vidq)) { | ||
721 | dprintk(fh->dev, 1, "%s queue busy\n", __func__); | ||
722 | ret = -EBUSY; | ||
723 | goto out; | ||
724 | } | ||
725 | |||
876 | fh->fmt = &format; | 726 | fh->fmt = &format; |
877 | fh->width = f->fmt.pix.width; | 727 | fh->width = f->fmt.pix.width; |
878 | fh->height = f->fmt.pix.height; | 728 | fh->height = f->fmt.pix.height; |
879 | fh->vb_vidq.field = f->fmt.pix.field; | 729 | fh->vb_vidq.field = f->fmt.pix.field; |
880 | fh->type = f->type; | 730 | fh->type = f->type; |
881 | 731 | ||
882 | return (0); | 732 | ret = 0; |
733 | out: | ||
734 | mutex_unlock(&q->vb_lock); | ||
735 | |||
736 | return (ret); | ||
883 | } | 737 | } |
884 | 738 | ||
885 | static int vidioc_reqbufs(struct file *file, void *priv, | 739 | static int vidioc_reqbufs(struct file *file, void *priv, |
@@ -1036,6 +890,7 @@ static int vivi_open(struct inode *inode, struct file *file) | |||
1036 | struct vivi_dev *dev; | 890 | struct vivi_dev *dev; |
1037 | struct vivi_fh *fh; | 891 | struct vivi_fh *fh; |
1038 | int i; | 892 | int i; |
893 | int retval = 0; | ||
1039 | 894 | ||
1040 | printk(KERN_DEBUG "vivi: open called (minor=%d)\n", minor); | 895 | printk(KERN_DEBUG "vivi: open called (minor=%d)\n", minor); |
1041 | 896 | ||
@@ -1045,9 +900,15 @@ static int vivi_open(struct inode *inode, struct file *file) | |||
1045 | return -ENODEV; | 900 | return -ENODEV; |
1046 | 901 | ||
1047 | found: | 902 | found: |
1048 | /* If more than one user, mutex should be added */ | 903 | mutex_lock(&dev->mutex); |
1049 | dev->users++; | 904 | dev->users++; |
1050 | 905 | ||
906 | if (dev->users > 1) { | ||
907 | dev->users--; | ||
908 | retval = -EBUSY; | ||
909 | goto unlock; | ||
910 | } | ||
911 | |||
1051 | dprintk(dev, 1, "open minor=%d type=%s users=%d\n", minor, | 912 | dprintk(dev, 1, "open minor=%d type=%s users=%d\n", minor, |
1052 | v4l2_type_names[V4L2_BUF_TYPE_VIDEO_CAPTURE], dev->users); | 913 | v4l2_type_names[V4L2_BUF_TYPE_VIDEO_CAPTURE], dev->users); |
1053 | 914 | ||
@@ -1055,8 +916,13 @@ found: | |||
1055 | fh = kzalloc(sizeof(*fh), GFP_KERNEL); | 916 | fh = kzalloc(sizeof(*fh), GFP_KERNEL); |
1056 | if (NULL == fh) { | 917 | if (NULL == fh) { |
1057 | dev->users--; | 918 | dev->users--; |
1058 | return -ENOMEM; | 919 | retval = -ENOMEM; |
920 | goto unlock; | ||
1059 | } | 921 | } |
922 | unlock: | ||
923 | mutex_unlock(&dev->mutex); | ||
924 | if (retval) | ||
925 | return retval; | ||
1060 | 926 | ||
1061 | file->private_data = fh; | 927 | file->private_data = fh; |
1062 | fh->dev = dev; | 928 | fh->dev = dev; |
@@ -1084,6 +950,8 @@ found: | |||
1084 | NULL, &dev->slock, fh->type, V4L2_FIELD_INTERLACED, | 950 | NULL, &dev->slock, fh->type, V4L2_FIELD_INTERLACED, |
1085 | sizeof(struct vivi_buffer), fh); | 951 | sizeof(struct vivi_buffer), fh); |
1086 | 952 | ||
953 | vivi_start_thread(fh); | ||
954 | |||
1087 | return 0; | 955 | return 0; |
1088 | } | 956 | } |
1089 | 957 | ||
@@ -1106,7 +974,7 @@ vivi_poll(struct file *file, struct poll_table_struct *wait) | |||
1106 | struct vivi_dev *dev = fh->dev; | 974 | struct vivi_dev *dev = fh->dev; |
1107 | struct videobuf_queue *q = &fh->vb_vidq; | 975 | struct videobuf_queue *q = &fh->vb_vidq; |
1108 | 976 | ||
1109 | dprintk(dev, 1, "%s\n", __FUNCTION__); | 977 | dprintk(dev, 1, "%s\n", __func__); |
1110 | 978 | ||
1111 | if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type) | 979 | if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type) |
1112 | return POLLERR; | 980 | return POLLERR; |
@@ -1128,7 +996,9 @@ static int vivi_close(struct inode *inode, struct file *file) | |||
1128 | 996 | ||
1129 | kfree(fh); | 997 | kfree(fh); |
1130 | 998 | ||
999 | mutex_lock(&dev->mutex); | ||
1131 | dev->users--; | 1000 | dev->users--; |
1001 | mutex_unlock(&dev->mutex); | ||
1132 | 1002 | ||
1133 | dprintk(dev, 1, "close called (minor=%d, users=%d)\n", | 1003 | dprintk(dev, 1, "close called (minor=%d, users=%d)\n", |
1134 | minor, dev->users); | 1004 | minor, dev->users); |
@@ -1182,6 +1052,7 @@ static const struct file_operations vivi_fops = { | |||
1182 | .read = vivi_read, | 1052 | .read = vivi_read, |
1183 | .poll = vivi_poll, | 1053 | .poll = vivi_poll, |
1184 | .ioctl = video_ioctl2, /* V4L2 ioctl handler */ | 1054 | .ioctl = video_ioctl2, /* V4L2 ioctl handler */ |
1055 | .compat_ioctl = v4l_compat_ioctl32, | ||
1185 | .mmap = vivi_mmap, | 1056 | .mmap = vivi_mmap, |
1186 | .llseek = no_llseek, | 1057 | .llseek = no_llseek, |
1187 | }; | 1058 | }; |
@@ -1236,16 +1107,11 @@ static int __init vivi_init(void) | |||
1236 | 1107 | ||
1237 | /* init video dma queues */ | 1108 | /* init video dma queues */ |
1238 | INIT_LIST_HEAD(&dev->vidq.active); | 1109 | INIT_LIST_HEAD(&dev->vidq.active); |
1239 | INIT_LIST_HEAD(&dev->vidq.queued); | ||
1240 | init_waitqueue_head(&dev->vidq.wq); | 1110 | init_waitqueue_head(&dev->vidq.wq); |
1241 | 1111 | ||
1242 | /* initialize locks */ | 1112 | /* initialize locks */ |
1243 | mutex_init(&dev->lock); | ||
1244 | spin_lock_init(&dev->slock); | 1113 | spin_lock_init(&dev->slock); |
1245 | 1114 | mutex_init(&dev->mutex); | |
1246 | dev->vidq.timeout.function = vivi_vid_timeout; | ||
1247 | dev->vidq.timeout.data = (unsigned long)dev; | ||
1248 | init_timer(&dev->vidq.timeout); | ||
1249 | 1115 | ||
1250 | vfd = video_device_alloc(); | 1116 | vfd = video_device_alloc(); |
1251 | if (NULL == vfd) | 1117 | if (NULL == vfd) |