aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2013-03-18 07:41:13 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2013-03-25 07:45:10 -0400
commita7eb931d635cce7b831f745c903204fb79a4aba0 (patch)
treeb1957f825b3e3cd8e1fffcd70c9bed81de7a90eb
parent6a2e65d54ebb1284c4d234ec606e4eccab7eb812 (diff)
[media] solo6x10: move global fields in solo_enc_fh to solo_enc_dev
All fields in solo_enc_fh do not belong there since they refer to global properties. After moving all these fields to solo_enc_dev the solo_dev_fh struct can be removed completely. Note that this also kills the 'listener' feature of this driver. This feature (where multiple filehandles can read the video) is illegal in the V4L2 API. Do this in userspace: it's much more efficient to copy memory than it is to DMA to every listener. Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/staging/media/solo6x10/solo6x10.h17
-rw-r--r--drivers/staging/media/solo6x10/v4l2-enc.c379
2 files changed, 175 insertions, 221 deletions
diff --git a/drivers/staging/media/solo6x10/solo6x10.h b/drivers/staging/media/solo6x10/solo6x10.h
index 830359f3bb16..413ee10e691e 100644
--- a/drivers/staging/media/solo6x10/solo6x10.h
+++ b/drivers/staging/media/solo6x10/solo6x10.h
@@ -135,6 +135,11 @@ struct solo_p2m_dev {
135 135
136#define OSD_TEXT_MAX 44 136#define OSD_TEXT_MAX 44
137 137
138enum solo_enc_types {
139 SOLO_ENC_TYPE_STD,
140 SOLO_ENC_TYPE_EXT,
141};
142
138struct solo_enc_dev { 143struct solo_enc_dev {
139 struct solo_dev *solo_dev; 144 struct solo_dev *solo_dev;
140 /* V4L2 Items */ 145 /* V4L2 Items */
@@ -163,8 +168,16 @@ struct solo_enc_dev {
163 unsigned char jpeg_header[1024]; 168 unsigned char jpeg_header[1024];
164 int jpeg_len; 169 int jpeg_len;
165 170
166 /* File handles that are listening for buffers */ 171 u32 fmt;
167 struct list_head listeners; 172 u8 enc_on;
173 enum solo_enc_types type;
174 struct videobuf_queue vidq;
175 struct list_head vidq_active;
176 int desc_count;
177 int desc_nelts;
178 struct solo_p2m_desc *desc_items;
179 dma_addr_t desc_dma;
180 spinlock_t av_lock;
168}; 181};
169 182
170/* The SOLO6x10 PCI Device */ 183/* The SOLO6x10 PCI Device */
diff --git a/drivers/staging/media/solo6x10/v4l2-enc.c b/drivers/staging/media/solo6x10/v4l2-enc.c
index 7cf3e7b8725f..546a18b31328 100644
--- a/drivers/staging/media/solo6x10/v4l2-enc.c
+++ b/drivers/staging/media/solo6x10/v4l2-enc.c
@@ -41,27 +41,6 @@
41#define MP4_QS 16 41#define MP4_QS 16
42#define DMA_ALIGN 4096 42#define DMA_ALIGN 4096
43 43
44enum solo_enc_types {
45 SOLO_ENC_TYPE_STD,
46 SOLO_ENC_TYPE_EXT,
47};
48
49struct solo_enc_fh {
50 struct v4l2_fh fh;
51 struct solo_enc_dev *enc;
52 u32 fmt;
53 u8 enc_on;
54 enum solo_enc_types type;
55 struct videobuf_queue vidq;
56 struct list_head vidq_active;
57 int desc_count;
58 int desc_nelts;
59 struct solo_p2m_desc *desc_items;
60 dma_addr_t desc_dma;
61 spinlock_t av_lock;
62 struct list_head list;
63};
64
65struct solo_videobuf { 44struct solo_videobuf {
66 struct videobuf_buffer vb; 45 struct videobuf_buffer vb;
67 unsigned int flags; 46 unsigned int flags;
@@ -286,16 +265,15 @@ static void solo_update_mode(struct solo_enc_dev *solo_enc)
286} 265}
287 266
288/* MUST be called with solo_enc->enable_lock held */ 267/* MUST be called with solo_enc->enable_lock held */
289static int __solo_enc_on(struct solo_enc_fh *fh) 268static int __solo_enc_on(struct solo_enc_dev *solo_enc)
290{ 269{
291 struct solo_enc_dev *solo_enc = fh->enc;
292 u8 ch = solo_enc->ch; 270 u8 ch = solo_enc->ch;
293 struct solo_dev *solo_dev = solo_enc->solo_dev; 271 struct solo_dev *solo_dev = solo_enc->solo_dev;
294 u8 interval; 272 u8 interval;
295 273
296 BUG_ON(!mutex_is_locked(&solo_enc->enable_lock)); 274 BUG_ON(!mutex_is_locked(&solo_enc->enable_lock));
297 275
298 if (fh->enc_on) 276 if (solo_enc->enc_on)
299 return 0; 277 return 0;
300 278
301 solo_update_mode(solo_enc); 279 solo_update_mode(solo_enc);
@@ -308,15 +286,14 @@ static int __solo_enc_on(struct solo_enc_fh *fh)
308 solo_dev->enc_bw_remain -= solo_enc->bw_weight; 286 solo_dev->enc_bw_remain -= solo_enc->bw_weight;
309 } 287 }
310 288
311 fh->enc_on = 1; 289 solo_enc->enc_on = 1;
312 list_add(&fh->list, &solo_enc->listeners);
313 290
314 if (fh->type == SOLO_ENC_TYPE_EXT) 291 if (solo_enc->type == SOLO_ENC_TYPE_EXT)
315 solo_reg_write(solo_dev, SOLO_CAP_CH_COMP_ENA_E(ch), 1); 292 solo_reg_write(solo_dev, SOLO_CAP_CH_COMP_ENA_E(ch), 1);
316 293
317 /* Reset the encoder if we are the first mpeg reader, else only reset 294 /* Reset the encoder if we are the first mpeg reader, else only reset
318 * on the first mjpeg reader. */ 295 * on the first mjpeg reader. */
319 if (fh->fmt == V4L2_PIX_FMT_MPEG) { 296 if (solo_enc->fmt == V4L2_PIX_FMT_MPEG) {
320 atomic_inc(&solo_enc->readers); 297 atomic_inc(&solo_enc->readers);
321 if (atomic_inc_return(&solo_enc->mpeg_readers) > 1) 298 if (atomic_inc_return(&solo_enc->mpeg_readers) > 1)
322 return 0; 299 return 0;
@@ -352,32 +329,29 @@ static int __solo_enc_on(struct solo_enc_fh *fh)
352 return 0; 329 return 0;
353} 330}
354 331
355static int solo_enc_on(struct solo_enc_fh *fh) 332static int solo_enc_on(struct solo_enc_dev *solo_enc)
356{ 333{
357 struct solo_enc_dev *solo_enc = fh->enc;
358 int ret; 334 int ret;
359 335
360 mutex_lock(&solo_enc->enable_lock); 336 mutex_lock(&solo_enc->enable_lock);
361 ret = __solo_enc_on(fh); 337 ret = __solo_enc_on(solo_enc);
362 mutex_unlock(&solo_enc->enable_lock); 338 mutex_unlock(&solo_enc->enable_lock);
363 339
364 return ret; 340 return ret;
365} 341}
366 342
367static void __solo_enc_off(struct solo_enc_fh *fh) 343static void __solo_enc_off(struct solo_enc_dev *solo_enc)
368{ 344{
369 struct solo_enc_dev *solo_enc = fh->enc;
370 struct solo_dev *solo_dev = solo_enc->solo_dev; 345 struct solo_dev *solo_dev = solo_enc->solo_dev;
371 346
372 BUG_ON(!mutex_is_locked(&solo_enc->enable_lock)); 347 BUG_ON(!mutex_is_locked(&solo_enc->enable_lock));
373 348
374 if (!fh->enc_on) 349 if (!solo_enc->enc_on)
375 return; 350 return;
376 351
377 list_del(&fh->list); 352 solo_enc->enc_on = 0;
378 fh->enc_on = 0;
379 353
380 if (fh->fmt == V4L2_PIX_FMT_MPEG) 354 if (solo_enc->fmt == V4L2_PIX_FMT_MPEG)
381 atomic_dec(&solo_enc->mpeg_readers); 355 atomic_dec(&solo_enc->mpeg_readers);
382 356
383 if (atomic_dec_return(&solo_enc->readers) > 0) 357 if (atomic_dec_return(&solo_enc->readers) > 0)
@@ -389,12 +363,10 @@ static void __solo_enc_off(struct solo_enc_fh *fh)
389 solo_reg_write(solo_dev, SOLO_CAP_CH_COMP_ENA_E(solo_enc->ch), 0); 363 solo_reg_write(solo_dev, SOLO_CAP_CH_COMP_ENA_E(solo_enc->ch), 0);
390} 364}
391 365
392static void solo_enc_off(struct solo_enc_fh *fh) 366static void solo_enc_off(struct solo_enc_dev *solo_enc)
393{ 367{
394 struct solo_enc_dev *solo_enc = fh->enc;
395
396 mutex_lock(&solo_enc->enable_lock); 368 mutex_lock(&solo_enc->enable_lock);
397 __solo_enc_off(fh); 369 __solo_enc_off(solo_enc);
398 mutex_unlock(&solo_enc->enable_lock); 370 mutex_unlock(&solo_enc->enable_lock);
399} 371}
400 372
@@ -430,11 +402,11 @@ static int enc_get_mpeg_dma(struct solo_dev *solo_dev, dma_addr_t dma,
430 402
431/* Build a descriptor queue out of an SG list and send it to the P2M for 403/* Build a descriptor queue out of an SG list and send it to the P2M for
432 * processing. */ 404 * processing. */
433static int solo_send_desc(struct solo_enc_fh *fh, int skip, 405static int solo_send_desc(struct solo_enc_dev *solo_enc, int skip,
434 struct videobuf_dmabuf *vbuf, int off, int size, 406 struct videobuf_dmabuf *vbuf, int off, int size,
435 unsigned int base, unsigned int base_size) 407 unsigned int base, unsigned int base_size)
436{ 408{
437 struct solo_dev *solo_dev = fh->enc->solo_dev; 409 struct solo_dev *solo_dev = solo_enc->solo_dev;
438 struct scatterlist *sg; 410 struct scatterlist *sg;
439 int i; 411 int i;
440 int ret; 412 int ret;
@@ -442,7 +414,7 @@ static int solo_send_desc(struct solo_enc_fh *fh, int skip,
442 if (WARN_ON_ONCE(size > FRAME_BUF_SIZE)) 414 if (WARN_ON_ONCE(size > FRAME_BUF_SIZE))
443 return -EINVAL; 415 return -EINVAL;
444 416
445 fh->desc_count = 1; 417 solo_enc->desc_count = 1;
446 418
447 for_each_sg(vbuf->sglist, sg, vbuf->sglen, i) { 419 for_each_sg(vbuf->sglist, sg, vbuf->sglen, i) {
448 struct solo_p2m_desc *desc; 420 struct solo_p2m_desc *desc;
@@ -450,7 +422,7 @@ static int solo_send_desc(struct solo_enc_fh *fh, int skip,
450 int len; 422 int len;
451 int left = base_size - off; 423 int left = base_size - off;
452 424
453 desc = &fh->desc_items[fh->desc_count++]; 425 desc = &solo_enc->desc_items[solo_enc->desc_count++];
454 dma = sg_dma_address(sg); 426 dma = sg_dma_address(sg);
455 len = sg_dma_len(sg); 427 len = sg_dma_len(sg);
456 428
@@ -486,7 +458,7 @@ static int solo_send_desc(struct solo_enc_fh *fh, int skip,
486 if (ret) 458 if (ret)
487 return ret; 459 return ret;
488 460
489 fh->desc_count--; 461 solo_enc->desc_count--;
490 } 462 }
491 463
492 size -= len; 464 size -= len;
@@ -498,27 +470,26 @@ static int solo_send_desc(struct solo_enc_fh *fh, int skip,
498 off -= base_size; 470 off -= base_size;
499 471
500 /* Because we may use two descriptors per loop */ 472 /* Because we may use two descriptors per loop */
501 if (fh->desc_count >= (fh->desc_nelts - 1)) { 473 if (solo_enc->desc_count >= (solo_enc->desc_nelts - 1)) {
502 ret = solo_p2m_dma_desc(solo_dev, fh->desc_items, 474 ret = solo_p2m_dma_desc(solo_dev, solo_enc->desc_items,
503 fh->desc_dma, 475 solo_enc->desc_dma,
504 fh->desc_count - 1); 476 solo_enc->desc_count - 1);
505 if (ret) 477 if (ret)
506 return ret; 478 return ret;
507 fh->desc_count = 1; 479 solo_enc->desc_count = 1;
508 } 480 }
509 } 481 }
510 482
511 if (fh->desc_count <= 1) 483 if (solo_enc->desc_count <= 1)
512 return 0; 484 return 0;
513 485
514 return solo_p2m_dma_desc(solo_dev, fh->desc_items, fh->desc_dma, 486 return solo_p2m_dma_desc(solo_dev, solo_enc->desc_items, solo_enc->desc_dma,
515 fh->desc_count - 1); 487 solo_enc->desc_count - 1);
516} 488}
517 489
518static int solo_fill_jpeg(struct solo_enc_fh *fh, struct videobuf_buffer *vb, 490static int solo_fill_jpeg(struct solo_enc_dev *solo_enc, struct videobuf_buffer *vb,
519 struct videobuf_dmabuf *vbuf, struct vop_header *vh) 491 struct videobuf_dmabuf *vbuf, struct vop_header *vh)
520{ 492{
521 struct solo_enc_dev *solo_enc = fh->enc;
522 struct solo_dev *solo_dev = solo_enc->solo_dev; 493 struct solo_dev *solo_dev = solo_enc->solo_dev;
523 struct solo_videobuf *svb = (struct solo_videobuf *)vb; 494 struct solo_videobuf *svb = (struct solo_videobuf *)vb;
524 int frame_size; 495 int frame_size;
@@ -539,15 +510,14 @@ static int solo_fill_jpeg(struct solo_enc_fh *fh, struct videobuf_buffer *vb,
539 frame_size = (vh->jpeg_size + solo_enc->jpeg_len + (DMA_ALIGN - 1)) 510 frame_size = (vh->jpeg_size + solo_enc->jpeg_len + (DMA_ALIGN - 1))
540 & ~(DMA_ALIGN - 1); 511 & ~(DMA_ALIGN - 1);
541 512
542 return solo_send_desc(fh, solo_enc->jpeg_len, vbuf, vh->jpeg_off, 513 return solo_send_desc(solo_enc, solo_enc->jpeg_len, vbuf, vh->jpeg_off,
543 frame_size, SOLO_JPEG_EXT_ADDR(solo_dev), 514 frame_size, SOLO_JPEG_EXT_ADDR(solo_dev),
544 SOLO_JPEG_EXT_SIZE(solo_dev)); 515 SOLO_JPEG_EXT_SIZE(solo_dev));
545} 516}
546 517
547static int solo_fill_mpeg(struct solo_enc_fh *fh, struct videobuf_buffer *vb, 518static int solo_fill_mpeg(struct solo_enc_dev *solo_enc, struct videobuf_buffer *vb,
548 struct videobuf_dmabuf *vbuf, struct vop_header *vh) 519 struct videobuf_dmabuf *vbuf, struct vop_header *vh)
549{ 520{
550 struct solo_enc_dev *solo_enc = fh->enc;
551 struct solo_dev *solo_dev = solo_enc->solo_dev; 521 struct solo_dev *solo_dev = solo_enc->solo_dev;
552 struct solo_videobuf *svb = (struct solo_videobuf *)vb; 522 struct solo_videobuf *svb = (struct solo_videobuf *)vb;
553 int frame_off, frame_size; 523 int frame_off, frame_size;
@@ -580,16 +550,15 @@ static int solo_fill_mpeg(struct solo_enc_fh *fh, struct videobuf_buffer *vb,
580 frame_size = (vh->mpeg_size + skip + (DMA_ALIGN - 1)) 550 frame_size = (vh->mpeg_size + skip + (DMA_ALIGN - 1))
581 & ~(DMA_ALIGN - 1); 551 & ~(DMA_ALIGN - 1);
582 552
583 return solo_send_desc(fh, skip, vbuf, frame_off, frame_size, 553 return solo_send_desc(solo_enc, skip, vbuf, frame_off, frame_size,
584 SOLO_MP4E_EXT_ADDR(solo_dev), 554 SOLO_MP4E_EXT_ADDR(solo_dev),
585 SOLO_MP4E_EXT_SIZE(solo_dev)); 555 SOLO_MP4E_EXT_SIZE(solo_dev));
586} 556}
587 557
588static int solo_enc_fillbuf(struct solo_enc_fh *fh, 558static int solo_enc_fillbuf(struct solo_enc_dev *solo_enc,
589 struct videobuf_buffer *vb, 559 struct videobuf_buffer *vb,
590 struct solo_enc_buf *enc_buf) 560 struct solo_enc_buf *enc_buf)
591{ 561{
592 struct solo_enc_dev *solo_enc = fh->enc;
593 struct solo_videobuf *svb = (struct solo_videobuf *)vb; 562 struct solo_videobuf *svb = (struct solo_videobuf *)vb;
594 struct videobuf_dmabuf *vbuf = NULL; 563 struct videobuf_dmabuf *vbuf = NULL;
595 struct vop_header *vh = enc_buf->vh; 564 struct vop_header *vh = enc_buf->vh;
@@ -613,10 +582,10 @@ static int solo_enc_fillbuf(struct solo_enc_fh *fh,
613 svb->flags |= V4L2_BUF_FLAG_MOTION_DETECTED; 582 svb->flags |= V4L2_BUF_FLAG_MOTION_DETECTED;
614 } 583 }
615 584
616 if (fh->fmt == V4L2_PIX_FMT_MPEG) 585 if (solo_enc->fmt == V4L2_PIX_FMT_MPEG)
617 ret = solo_fill_mpeg(fh, vb, vbuf, vh); 586 ret = solo_fill_mpeg(solo_enc, vb, vbuf, vh);
618 else 587 else
619 ret = solo_fill_jpeg(fh, vb, vbuf, vh); 588 ret = solo_fill_jpeg(solo_enc, vb, vbuf, vh);
620 589
621vbuf_error: 590vbuf_error:
622 /* On error, we push this buffer back into the queue. The 591 /* On error, we push this buffer back into the queue. The
@@ -625,10 +594,10 @@ vbuf_error:
625 if (ret) { 594 if (ret) {
626 unsigned long flags; 595 unsigned long flags;
627 596
628 spin_lock_irqsave(&fh->av_lock, flags); 597 spin_lock_irqsave(&solo_enc->av_lock, flags);
629 list_add(&vb->queue, &fh->vidq_active); 598 list_add(&vb->queue, &solo_enc->vidq_active);
630 vb->state = VIDEOBUF_QUEUED; 599 vb->state = VIDEOBUF_QUEUED;
631 spin_unlock_irqrestore(&fh->av_lock, flags); 600 spin_unlock_irqrestore(&solo_enc->av_lock, flags);
632 } else { 601 } else {
633 vb->state = VIDEOBUF_DONE; 602 vb->state = VIDEOBUF_DONE;
634 vb->field_count++; 603 vb->field_count++;
@@ -644,34 +613,29 @@ vbuf_error:
644static void solo_enc_handle_one(struct solo_enc_dev *solo_enc, 613static void solo_enc_handle_one(struct solo_enc_dev *solo_enc,
645 struct solo_enc_buf *enc_buf) 614 struct solo_enc_buf *enc_buf)
646{ 615{
647 struct solo_enc_fh *fh; 616 struct videobuf_buffer *vb;
617 unsigned long flags;
648 618
649 mutex_lock(&solo_enc->enable_lock); 619 mutex_lock(&solo_enc->enable_lock);
650 620
651 list_for_each_entry(fh, &solo_enc->listeners, list) { 621 if (solo_enc->type != enc_buf->type)
652 struct videobuf_buffer *vb; 622 goto unlock;
653 unsigned long flags;
654
655 if (fh->type != enc_buf->type)
656 continue;
657
658
659 if (list_empty(&fh->vidq_active))
660 continue;
661 623
662 spin_lock_irqsave(&fh->av_lock, flags); 624 if (list_empty(&solo_enc->vidq_active))
625 goto unlock;
663 626
664 vb = list_first_entry(&fh->vidq_active, 627 spin_lock_irqsave(&solo_enc->av_lock, flags);
665 struct videobuf_buffer, queue);
666 628
667 list_del(&vb->queue); 629 vb = list_first_entry(&solo_enc->vidq_active,
668 vb->state = VIDEOBUF_ACTIVE; 630 struct videobuf_buffer, queue);
669 631
670 spin_unlock_irqrestore(&fh->av_lock, flags); 632 list_del(&vb->queue);
633 vb->state = VIDEOBUF_ACTIVE;
671 634
672 solo_enc_fillbuf(fh, vb, enc_buf); 635 spin_unlock_irqrestore(&solo_enc->av_lock, flags);
673 }
674 636
637 solo_enc_fillbuf(solo_enc, vb, enc_buf);
638unlock:
675 mutex_unlock(&solo_enc->enable_lock); 639 mutex_unlock(&solo_enc->enable_lock);
676} 640}
677 641
@@ -799,10 +763,10 @@ static int solo_enc_buf_prepare(struct videobuf_queue *vq,
799static void solo_enc_buf_queue(struct videobuf_queue *vq, 763static void solo_enc_buf_queue(struct videobuf_queue *vq,
800 struct videobuf_buffer *vb) 764 struct videobuf_buffer *vb)
801{ 765{
802 struct solo_enc_fh *fh = vq->priv_data; 766 struct solo_enc_dev *solo_enc = vq->priv_data;
803 767
804 vb->state = VIDEOBUF_QUEUED; 768 vb->state = VIDEOBUF_QUEUED;
805 list_add_tail(&vb->queue, &fh->vidq_active); 769 list_add_tail(&vb->queue, &solo_enc->vidq_active);
806} 770}
807 771
808static void solo_enc_buf_release(struct videobuf_queue *vq, 772static void solo_enc_buf_release(struct videobuf_queue *vq,
@@ -824,20 +788,20 @@ static const struct videobuf_queue_ops solo_enc_video_qops = {
824static unsigned int solo_enc_poll(struct file *file, 788static unsigned int solo_enc_poll(struct file *file,
825 struct poll_table_struct *wait) 789 struct poll_table_struct *wait)
826{ 790{
827 struct solo_enc_fh *fh = file->private_data; 791 struct solo_enc_dev *solo_enc = video_drvdata(file);
828 unsigned long req_events = poll_requested_events(wait); 792 unsigned long req_events = poll_requested_events(wait);
829 unsigned res = v4l2_ctrl_poll(file, wait); 793 unsigned res = v4l2_ctrl_poll(file, wait);
830 794
831 if (!(req_events & (POLLIN | POLLRDNORM))) 795 if (!(req_events & (POLLIN | POLLRDNORM)))
832 return res; 796 return res;
833 return videobuf_poll_stream(file, &fh->vidq, wait); 797 return videobuf_poll_stream(file, &solo_enc->vidq, wait);
834} 798}
835 799
836static int solo_enc_mmap(struct file *file, struct vm_area_struct *vma) 800static int solo_enc_mmap(struct file *file, struct vm_area_struct *vma)
837{ 801{
838 struct solo_enc_fh *fh = file->private_data; 802 struct solo_enc_dev *solo_enc = video_drvdata(file);
839 803
840 return videobuf_mmap_mapper(&fh->vidq, vma); 804 return videobuf_mmap_mapper(&solo_enc->vidq, vma);
841} 805}
842 806
843static int solo_ring_start(struct solo_dev *solo_dev) 807static int solo_ring_start(struct solo_dev *solo_dev)
@@ -875,91 +839,50 @@ static int solo_enc_open(struct file *file)
875{ 839{
876 struct solo_enc_dev *solo_enc = video_drvdata(file); 840 struct solo_enc_dev *solo_enc = video_drvdata(file);
877 struct solo_dev *solo_dev = solo_enc->solo_dev; 841 struct solo_dev *solo_dev = solo_enc->solo_dev;
878 struct solo_enc_fh *fh; 842 int ret = v4l2_fh_open(file);
879 int ret;
880 843
881 ret = solo_ring_start(solo_dev);
882 if (ret) 844 if (ret)
883 return ret; 845 return ret;
884 846 ret = solo_ring_start(solo_dev);
885 fh = kzalloc(sizeof(*fh), GFP_KERNEL); 847 if (ret) {
886 if (fh == NULL) { 848 v4l2_fh_release(file);
887 solo_ring_stop(solo_dev); 849 return ret;
888 return -ENOMEM;
889 }
890
891 fh->desc_nelts = 32;
892 fh->desc_items = pci_alloc_consistent(solo_dev->pdev,
893 sizeof(struct solo_p2m_desc) *
894 fh->desc_nelts, &fh->desc_dma);
895 if (fh->desc_items == NULL) {
896 kfree(fh);
897 solo_ring_stop(solo_dev);
898 return -ENOMEM;
899 } 850 }
900
901 v4l2_fh_init(&fh->fh, video_devdata(file));
902 fh->enc = solo_enc;
903 spin_lock_init(&fh->av_lock);
904 file->private_data = fh;
905 INIT_LIST_HEAD(&fh->vidq_active);
906 fh->fmt = V4L2_PIX_FMT_MPEG;
907 fh->type = SOLO_ENC_TYPE_STD;
908
909 videobuf_queue_sg_init(&fh->vidq, &solo_enc_video_qops,
910 &solo_dev->pdev->dev,
911 &fh->av_lock,
912 V4L2_BUF_TYPE_VIDEO_CAPTURE,
913 V4L2_FIELD_INTERLACED,
914 sizeof(struct solo_videobuf),
915 fh, NULL);
916 v4l2_fh_add(&fh->fh);
917 return 0; 851 return 0;
918} 852}
919 853
920static ssize_t solo_enc_read(struct file *file, char __user *data, 854static ssize_t solo_enc_read(struct file *file, char __user *data,
921 size_t count, loff_t *ppos) 855 size_t count, loff_t *ppos)
922{ 856{
923 struct solo_enc_fh *fh = file->private_data; 857 struct solo_enc_dev *solo_enc = video_drvdata(file);
924 int ret; 858 int ret;
925 859
926 /* Make sure the encoder is on */ 860 /* Make sure the encoder is on */
927 ret = solo_enc_on(fh); 861 ret = solo_enc_on(solo_enc);
928 if (ret) 862 if (ret)
929 return ret; 863 return ret;
930 864
931 return videobuf_read_stream(&fh->vidq, data, count, ppos, 0, 865 return videobuf_read_stream(&solo_enc->vidq, data, count, ppos, 0,
932 file->f_flags & O_NONBLOCK); 866 file->f_flags & O_NONBLOCK);
933} 867}
934 868
935static int solo_enc_release(struct file *file) 869static int solo_enc_release(struct file *file)
936{ 870{
937 struct solo_enc_fh *fh = file->private_data; 871 struct solo_enc_dev *solo_enc = video_drvdata(file);
938 struct solo_dev *solo_dev = fh->enc->solo_dev; 872 struct solo_dev *solo_dev = solo_enc->solo_dev;
939
940 solo_enc_off(fh);
941 v4l2_fh_del(&fh->fh);
942 v4l2_fh_exit(&fh->fh);
943
944 videobuf_stop(&fh->vidq);
945 videobuf_mmap_free(&fh->vidq);
946
947 pci_free_consistent(fh->enc->solo_dev->pdev,
948 sizeof(struct solo_p2m_desc) *
949 fh->desc_nelts, fh->desc_items, fh->desc_dma);
950
951 kfree(fh);
952 873
874 solo_enc_off(solo_enc);
875 videobuf_stop(&solo_enc->vidq);
876 videobuf_mmap_free(&solo_enc->vidq);
953 solo_ring_stop(solo_dev); 877 solo_ring_stop(solo_dev);
954 878
955 return 0; 879 return v4l2_fh_release(file);
956} 880}
957 881
958static int solo_enc_querycap(struct file *file, void *priv, 882static int solo_enc_querycap(struct file *file, void *priv,
959 struct v4l2_capability *cap) 883 struct v4l2_capability *cap)
960{ 884{
961 struct solo_enc_fh *fh = priv; 885 struct solo_enc_dev *solo_enc = video_drvdata(file);
962 struct solo_enc_dev *solo_enc = fh->enc;
963 struct solo_dev *solo_dev = solo_enc->solo_dev; 886 struct solo_dev *solo_dev = solo_enc->solo_dev;
964 887
965 strcpy(cap->driver, SOLO6X10_NAME); 888 strcpy(cap->driver, SOLO6X10_NAME);
@@ -976,8 +899,7 @@ static int solo_enc_querycap(struct file *file, void *priv,
976static int solo_enc_enum_input(struct file *file, void *priv, 899static int solo_enc_enum_input(struct file *file, void *priv,
977 struct v4l2_input *input) 900 struct v4l2_input *input)
978{ 901{
979 struct solo_enc_fh *fh = priv; 902 struct solo_enc_dev *solo_enc = video_drvdata(file);
980 struct solo_enc_dev *solo_enc = fh->enc;
981 struct solo_dev *solo_dev = solo_enc->solo_dev; 903 struct solo_dev *solo_dev = solo_enc->solo_dev;
982 904
983 if (input->index) 905 if (input->index)
@@ -1039,8 +961,7 @@ static int solo_enc_enum_fmt_cap(struct file *file, void *priv,
1039static int solo_enc_try_fmt_cap(struct file *file, void *priv, 961static int solo_enc_try_fmt_cap(struct file *file, void *priv,
1040 struct v4l2_format *f) 962 struct v4l2_format *f)
1041{ 963{
1042 struct solo_enc_fh *fh = priv; 964 struct solo_enc_dev *solo_enc = video_drvdata(file);
1043 struct solo_enc_dev *solo_enc = fh->enc;
1044 struct solo_dev *solo_dev = solo_enc->solo_dev; 965 struct solo_dev *solo_dev = solo_enc->solo_dev;
1045 struct v4l2_pix_format *pix = &f->fmt.pix; 966 struct v4l2_pix_format *pix = &f->fmt.pix;
1046 967
@@ -1081,8 +1002,7 @@ static int solo_enc_try_fmt_cap(struct file *file, void *priv,
1081static int solo_enc_set_fmt_cap(struct file *file, void *priv, 1002static int solo_enc_set_fmt_cap(struct file *file, void *priv,
1082 struct v4l2_format *f) 1003 struct v4l2_format *f)
1083{ 1004{
1084 struct solo_enc_fh *fh = priv; 1005 struct solo_enc_dev *solo_enc = video_drvdata(file);
1085 struct solo_enc_dev *solo_enc = fh->enc;
1086 struct solo_dev *solo_dev = solo_enc->solo_dev; 1006 struct solo_dev *solo_dev = solo_enc->solo_dev;
1087 struct v4l2_pix_format *pix = &f->fmt.pix; 1007 struct v4l2_pix_format *pix = &f->fmt.pix;
1088 int ret; 1008 int ret;
@@ -1110,10 +1030,10 @@ static int solo_enc_set_fmt_cap(struct file *file, void *priv,
1110 solo_enc->mode = SOLO_ENC_MODE_CIF; 1030 solo_enc->mode = SOLO_ENC_MODE_CIF;
1111 1031
1112 /* This does not change the encoder at all */ 1032 /* This does not change the encoder at all */
1113 fh->fmt = pix->pixelformat; 1033 solo_enc->fmt = pix->pixelformat;
1114 1034
1115 if (pix->priv) 1035 if (pix->priv)
1116 fh->type = SOLO_ENC_TYPE_EXT; 1036 solo_enc->type = SOLO_ENC_TYPE_EXT;
1117 1037
1118 mutex_unlock(&solo_enc->enable_lock); 1038 mutex_unlock(&solo_enc->enable_lock);
1119 1039
@@ -1123,13 +1043,12 @@ static int solo_enc_set_fmt_cap(struct file *file, void *priv,
1123static int solo_enc_get_fmt_cap(struct file *file, void *priv, 1043static int solo_enc_get_fmt_cap(struct file *file, void *priv,
1124 struct v4l2_format *f) 1044 struct v4l2_format *f)
1125{ 1045{
1126 struct solo_enc_fh *fh = priv; 1046 struct solo_enc_dev *solo_enc = video_drvdata(file);
1127 struct solo_enc_dev *solo_enc = fh->enc;
1128 struct v4l2_pix_format *pix = &f->fmt.pix; 1047 struct v4l2_pix_format *pix = &f->fmt.pix;
1129 1048
1130 pix->width = solo_enc->width; 1049 pix->width = solo_enc->width;
1131 pix->height = solo_enc->height; 1050 pix->height = solo_enc->height;
1132 pix->pixelformat = fh->fmt; 1051 pix->pixelformat = solo_enc->fmt;
1133 pix->field = solo_enc->interlaced ? V4L2_FIELD_INTERLACED : 1052 pix->field = solo_enc->interlaced ? V4L2_FIELD_INTERLACED :
1134 V4L2_FIELD_NONE; 1053 V4L2_FIELD_NONE;
1135 pix->sizeimage = FRAME_BUF_SIZE; 1054 pix->sizeimage = FRAME_BUF_SIZE;
@@ -1142,45 +1061,45 @@ static int solo_enc_get_fmt_cap(struct file *file, void *priv,
1142static int solo_enc_reqbufs(struct file *file, void *priv, 1061static int solo_enc_reqbufs(struct file *file, void *priv,
1143 struct v4l2_requestbuffers *req) 1062 struct v4l2_requestbuffers *req)
1144{ 1063{
1145 struct solo_enc_fh *fh = priv; 1064 struct solo_enc_dev *solo_enc = video_drvdata(file);
1146 1065
1147 return videobuf_reqbufs(&fh->vidq, req); 1066 return videobuf_reqbufs(&solo_enc->vidq, req);
1148} 1067}
1149 1068
1150static int solo_enc_querybuf(struct file *file, void *priv, 1069static int solo_enc_querybuf(struct file *file, void *priv,
1151 struct v4l2_buffer *buf) 1070 struct v4l2_buffer *buf)
1152{ 1071{
1153 struct solo_enc_fh *fh = priv; 1072 struct solo_enc_dev *solo_enc = video_drvdata(file);
1154 1073
1155 return videobuf_querybuf(&fh->vidq, buf); 1074 return videobuf_querybuf(&solo_enc->vidq, buf);
1156} 1075}
1157 1076
1158static int solo_enc_qbuf(struct file *file, void *priv, 1077static int solo_enc_qbuf(struct file *file, void *priv,
1159 struct v4l2_buffer *buf) 1078 struct v4l2_buffer *buf)
1160{ 1079{
1161 struct solo_enc_fh *fh = priv; 1080 struct solo_enc_dev *solo_enc = video_drvdata(file);
1162 1081
1163 return videobuf_qbuf(&fh->vidq, buf); 1082 return videobuf_qbuf(&solo_enc->vidq, buf);
1164} 1083}
1165 1084
1166static int solo_enc_dqbuf(struct file *file, void *priv, 1085static int solo_enc_dqbuf(struct file *file, void *priv,
1167 struct v4l2_buffer *buf) 1086 struct v4l2_buffer *buf)
1168{ 1087{
1169 struct solo_enc_fh *fh = priv; 1088 struct solo_enc_dev *solo_enc = video_drvdata(file);
1170 struct solo_videobuf *svb; 1089 struct solo_videobuf *svb;
1171 int ret; 1090 int ret;
1172 1091
1173 /* Make sure the encoder is on */ 1092 /* Make sure the encoder is on */
1174 ret = solo_enc_on(fh); 1093 ret = solo_enc_on(solo_enc);
1175 if (ret) 1094 if (ret)
1176 return ret; 1095 return ret;
1177 1096
1178 ret = videobuf_dqbuf(&fh->vidq, buf, file->f_flags & O_NONBLOCK); 1097 ret = videobuf_dqbuf(&solo_enc->vidq, buf, file->f_flags & O_NONBLOCK);
1179 if (ret) 1098 if (ret)
1180 return ret; 1099 return ret;
1181 1100
1182 /* Copy over the flags */ 1101 /* Copy over the flags */
1183 svb = (struct solo_videobuf *)fh->vidq.bufs[buf->index]; 1102 svb = (struct solo_videobuf *)solo_enc->vidq.bufs[buf->index];
1184 buf->flags |= svb->flags; 1103 buf->flags |= svb->flags;
1185 1104
1186 return 0; 1105 return 0;
@@ -1189,26 +1108,26 @@ static int solo_enc_dqbuf(struct file *file, void *priv,
1189static int solo_enc_streamon(struct file *file, void *priv, 1108static int solo_enc_streamon(struct file *file, void *priv,
1190 enum v4l2_buf_type i) 1109 enum v4l2_buf_type i)
1191{ 1110{
1192 struct solo_enc_fh *fh = priv; 1111 struct solo_enc_dev *solo_enc = video_drvdata(file);
1193 1112
1194 if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1113 if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1195 return -EINVAL; 1114 return -EINVAL;
1196 1115
1197 return videobuf_streamon(&fh->vidq); 1116 return videobuf_streamon(&solo_enc->vidq);
1198} 1117}
1199 1118
1200static int solo_enc_streamoff(struct file *file, void *priv, 1119static int solo_enc_streamoff(struct file *file, void *priv,
1201 enum v4l2_buf_type i) 1120 enum v4l2_buf_type i)
1202{ 1121{
1203 struct solo_enc_fh *fh = priv; 1122 struct solo_enc_dev *solo_enc = video_drvdata(file);
1204 int ret; 1123 int ret;
1205 1124
1206 if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1125 if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1207 return -EINVAL; 1126 return -EINVAL;
1208 1127
1209 ret = videobuf_streamoff(&fh->vidq); 1128 ret = videobuf_streamoff(&solo_enc->vidq);
1210 if (!ret) 1129 if (!ret)
1211 solo_enc_off(fh); 1130 solo_enc_off(solo_enc);
1212 1131
1213 return ret; 1132 return ret;
1214} 1133}
@@ -1221,8 +1140,8 @@ static int solo_enc_s_std(struct file *file, void *priv, v4l2_std_id i)
1221static int solo_enum_framesizes(struct file *file, void *priv, 1140static int solo_enum_framesizes(struct file *file, void *priv,
1222 struct v4l2_frmsizeenum *fsize) 1141 struct v4l2_frmsizeenum *fsize)
1223{ 1142{
1224 struct solo_enc_fh *fh = priv; 1143 struct solo_enc_dev *solo_enc = video_drvdata(file);
1225 struct solo_dev *solo_dev = fh->enc->solo_dev; 1144 struct solo_dev *solo_dev = solo_enc->solo_dev;
1226 1145
1227 if (fsize->pixel_format != V4L2_PIX_FMT_MPEG && 1146 if (fsize->pixel_format != V4L2_PIX_FMT_MPEG &&
1228 fsize->pixel_format != V4L2_PIX_FMT_MJPEG) 1147 fsize->pixel_format != V4L2_PIX_FMT_MJPEG)
@@ -1249,8 +1168,8 @@ static int solo_enum_framesizes(struct file *file, void *priv,
1249static int solo_enum_frameintervals(struct file *file, void *priv, 1168static int solo_enum_frameintervals(struct file *file, void *priv,
1250 struct v4l2_frmivalenum *fintv) 1169 struct v4l2_frmivalenum *fintv)
1251{ 1170{
1252 struct solo_enc_fh *fh = priv; 1171 struct solo_enc_dev *solo_enc = video_drvdata(file);
1253 struct solo_dev *solo_dev = fh->enc->solo_dev; 1172 struct solo_dev *solo_dev = solo_enc->solo_dev;
1254 1173
1255 if (fintv->pixel_format != V4L2_PIX_FMT_MPEG && 1174 if (fintv->pixel_format != V4L2_PIX_FMT_MPEG &&
1256 fintv->pixel_format != V4L2_PIX_FMT_MJPEG) 1175 fintv->pixel_format != V4L2_PIX_FMT_MJPEG)
@@ -1280,8 +1199,7 @@ static int solo_enum_frameintervals(struct file *file, void *priv,
1280static int solo_g_parm(struct file *file, void *priv, 1199static int solo_g_parm(struct file *file, void *priv,
1281 struct v4l2_streamparm *sp) 1200 struct v4l2_streamparm *sp)
1282{ 1201{
1283 struct solo_enc_fh *fh = priv; 1202 struct solo_enc_dev *solo_enc = video_drvdata(file);
1284 struct solo_enc_dev *solo_enc = fh->enc;
1285 struct solo_dev *solo_dev = solo_enc->solo_dev; 1203 struct solo_dev *solo_dev = solo_enc->solo_dev;
1286 struct v4l2_captureparm *cp = &sp->parm.capture; 1204 struct v4l2_captureparm *cp = &sp->parm.capture;
1287 1205
@@ -1298,8 +1216,7 @@ static int solo_g_parm(struct file *file, void *priv,
1298static int solo_s_parm(struct file *file, void *priv, 1216static int solo_s_parm(struct file *file, void *priv,
1299 struct v4l2_streamparm *sp) 1217 struct v4l2_streamparm *sp)
1300{ 1218{
1301 struct solo_enc_fh *fh = priv; 1219 struct solo_enc_dev *solo_enc = video_drvdata(file);
1302 struct solo_enc_dev *solo_enc = fh->enc;
1303 struct solo_dev *solo_dev = solo_enc->solo_dev; 1220 struct solo_dev *solo_dev = solo_enc->solo_dev;
1304 struct v4l2_captureparm *cp = &sp->parm.capture; 1221 struct v4l2_captureparm *cp = &sp->parm.capture;
1305 1222
@@ -1512,45 +1429,17 @@ static struct solo_enc_dev *solo_enc_alloc(struct solo_dev *solo_dev,
1512 v4l2_ctrl_new_custom(hdl, &solo_osd_text_ctrl, NULL); 1429 v4l2_ctrl_new_custom(hdl, &solo_osd_text_ctrl, NULL);
1513 if (hdl->error) { 1430 if (hdl->error) {
1514 ret = hdl->error; 1431 ret = hdl->error;
1515 v4l2_ctrl_handler_free(hdl); 1432 goto hdl_free;
1516 kfree(solo_enc);
1517 return ERR_PTR(ret);
1518 }
1519
1520 solo_enc->vfd = video_device_alloc();
1521 if (!solo_enc->vfd) {
1522 v4l2_ctrl_handler_free(hdl);
1523 kfree(solo_enc);
1524 return ERR_PTR(-ENOMEM);
1525 } 1433 }
1526 1434
1527 solo_enc->solo_dev = solo_dev; 1435 solo_enc->solo_dev = solo_dev;
1528 solo_enc->ch = ch; 1436 solo_enc->ch = ch;
1529 1437 spin_lock_init(&solo_enc->av_lock);
1530 *solo_enc->vfd = solo_enc_template; 1438 INIT_LIST_HEAD(&solo_enc->vidq_active);
1531 solo_enc->vfd->v4l2_dev = &solo_dev->v4l2_dev; 1439 solo_enc->fmt = V4L2_PIX_FMT_MPEG;
1532 solo_enc->vfd->ctrl_handler = hdl; 1440 solo_enc->type = SOLO_ENC_TYPE_STD;
1533 set_bit(V4L2_FL_USE_FH_PRIO, &solo_enc->vfd->flags);
1534 ret = video_register_device(solo_enc->vfd, VFL_TYPE_GRABBER, nr);
1535 if (ret < 0) {
1536 video_device_release(solo_enc->vfd);
1537 v4l2_ctrl_handler_free(hdl);
1538 kfree(solo_enc);
1539 return ERR_PTR(ret);
1540 }
1541
1542 video_set_drvdata(solo_enc->vfd, solo_enc);
1543
1544 snprintf(solo_enc->vfd->name, sizeof(solo_enc->vfd->name),
1545 "%s-enc (%i/%i)", SOLO6X10_NAME, solo_dev->vfd->num,
1546 solo_enc->vfd->num);
1547
1548 INIT_LIST_HEAD(&solo_enc->listeners);
1549 mutex_init(&solo_enc->enable_lock);
1550 spin_lock_init(&solo_enc->motion_lock);
1551 1441
1552 atomic_set(&solo_enc->readers, 0); 1442 atomic_set(&solo_enc->readers, 0);
1553 atomic_set(&solo_enc->mpeg_readers, 0);
1554 1443
1555 solo_enc->qp = SOLO_DEFAULT_QP; 1444 solo_enc->qp = SOLO_DEFAULT_QP;
1556 solo_enc->gop = solo_dev->fps; 1445 solo_enc->gop = solo_dev->fps;
@@ -1558,15 +1447,65 @@ static struct solo_enc_dev *solo_enc_alloc(struct solo_dev *solo_dev,
1558 solo_enc->mode = SOLO_ENC_MODE_CIF; 1447 solo_enc->mode = SOLO_ENC_MODE_CIF;
1559 solo_enc->motion_thresh = SOLO_DEF_MOT_THRESH; 1448 solo_enc->motion_thresh = SOLO_DEF_MOT_THRESH;
1560 1449
1561 mutex_lock(&solo_enc->enable_lock); 1450 spin_lock(&solo_enc->av_lock);
1562 solo_update_mode(solo_enc); 1451 solo_update_mode(solo_enc);
1563 mutex_unlock(&solo_enc->enable_lock); 1452 spin_unlock(&solo_enc->av_lock);
1453
1454 mutex_init(&solo_enc->enable_lock);
1455 spin_lock_init(&solo_enc->motion_lock);
1456
1457 atomic_set(&solo_enc->readers, 0);
1458 atomic_set(&solo_enc->mpeg_readers, 0);
1564 1459
1565 /* Initialize this per encoder */ 1460 /* Initialize this per encoder */
1566 solo_enc->jpeg_len = sizeof(jpeg_header); 1461 solo_enc->jpeg_len = sizeof(jpeg_header);
1567 memcpy(solo_enc->jpeg_header, jpeg_header, solo_enc->jpeg_len); 1462 memcpy(solo_enc->jpeg_header, jpeg_header, solo_enc->jpeg_len);
1568 1463
1464 solo_enc->desc_nelts = 32;
1465 solo_enc->desc_items = pci_alloc_consistent(solo_dev->pdev,
1466 sizeof(struct solo_p2m_desc) *
1467 solo_enc->desc_nelts, &solo_enc->desc_dma);
1468 ret = -ENOMEM;
1469 if (solo_enc->desc_items == NULL)
1470 goto hdl_free;
1471
1472 videobuf_queue_sg_init(&solo_enc->vidq, &solo_enc_video_qops,
1473 &solo_dev->pdev->dev,
1474 &solo_enc->av_lock,
1475 V4L2_BUF_TYPE_VIDEO_CAPTURE,
1476 V4L2_FIELD_INTERLACED,
1477 sizeof(struct solo_videobuf),
1478 solo_enc, NULL);
1479
1480 solo_enc->vfd = video_device_alloc();
1481 if (!solo_enc->vfd)
1482 goto pci_free;
1483
1484 *solo_enc->vfd = solo_enc_template;
1485 solo_enc->vfd->v4l2_dev = &solo_dev->v4l2_dev;
1486 solo_enc->vfd->ctrl_handler = hdl;
1487 set_bit(V4L2_FL_USE_FH_PRIO, &solo_enc->vfd->flags);
1488 video_set_drvdata(solo_enc->vfd, solo_enc);
1489 ret = video_register_device(solo_enc->vfd, VFL_TYPE_GRABBER, nr);
1490 if (ret < 0)
1491 goto vdev_release;
1492
1493 snprintf(solo_enc->vfd->name, sizeof(solo_enc->vfd->name),
1494 "%s-enc (%i/%i)", SOLO6X10_NAME, solo_dev->vfd->num,
1495 solo_enc->vfd->num);
1496
1569 return solo_enc; 1497 return solo_enc;
1498
1499vdev_release:
1500 video_device_release(solo_enc->vfd);
1501pci_free:
1502 pci_free_consistent(solo_enc->solo_dev->pdev,
1503 sizeof(struct solo_p2m_desc) * solo_enc->desc_nelts,
1504 solo_enc->desc_items, solo_enc->desc_dma);
1505hdl_free:
1506 v4l2_ctrl_handler_free(hdl);
1507 kfree(solo_enc);
1508 return ERR_PTR(ret);
1570} 1509}
1571 1510
1572static void solo_enc_free(struct solo_enc_dev *solo_enc) 1511static void solo_enc_free(struct solo_enc_dev *solo_enc)
@@ -1605,6 +1544,7 @@ int solo_enc_v4l2_init(struct solo_dev *solo_dev, unsigned nr)
1605 solo_enc_free(solo_dev->v4l2_enc[i]); 1544 solo_enc_free(solo_dev->v4l2_enc[i]);
1606 pci_free_consistent(solo_dev->pdev, solo_dev->vh_size, 1545 pci_free_consistent(solo_dev->pdev, solo_dev->vh_size,
1607 solo_dev->vh_buf, solo_dev->vh_dma); 1546 solo_dev->vh_buf, solo_dev->vh_dma);
1547 solo_dev->vh_buf = NULL;
1608 return ret; 1548 return ret;
1609 } 1549 }
1610 1550
@@ -1627,6 +1567,7 @@ void solo_enc_v4l2_exit(struct solo_dev *solo_dev)
1627 for (i = 0; i < solo_dev->nr_chans; i++) 1567 for (i = 0; i < solo_dev->nr_chans; i++)
1628 solo_enc_free(solo_dev->v4l2_enc[i]); 1568 solo_enc_free(solo_dev->v4l2_enc[i]);
1629 1569
1630 pci_free_consistent(solo_dev->pdev, solo_dev->vh_size, 1570 if (solo_dev->vh_buf)
1571 pci_free_consistent(solo_dev->pdev, solo_dev->vh_size,
1631 solo_dev->vh_buf, solo_dev->vh_dma); 1572 solo_dev->vh_buf, solo_dev->vh_dma);
1632} 1573}