aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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}