diff options
Diffstat (limited to 'drivers/media/video/gspca/gspca.c')
-rw-r--r-- | drivers/media/video/gspca/gspca.c | 340 |
1 files changed, 119 insertions, 221 deletions
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index 678675bb3652..d951b0f0e053 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c | |||
@@ -201,7 +201,7 @@ static int alloc_and_submit_int_urb(struct gspca_dev *gspca_dev, | |||
201 | 201 | ||
202 | buffer_len = le16_to_cpu(ep->wMaxPacketSize); | 202 | buffer_len = le16_to_cpu(ep->wMaxPacketSize); |
203 | interval = ep->bInterval; | 203 | interval = ep->bInterval; |
204 | PDEBUG(D_PROBE, "found int in endpoint: 0x%x, " | 204 | PDEBUG(D_CONF, "found int in endpoint: 0x%x, " |
205 | "buffer_len=%u, interval=%u", | 205 | "buffer_len=%u, interval=%u", |
206 | ep->bEndpointAddress, buffer_len, interval); | 206 | ep->bEndpointAddress, buffer_len, interval); |
207 | 207 | ||
@@ -226,7 +226,7 @@ static int alloc_and_submit_int_urb(struct gspca_dev *gspca_dev, | |||
226 | gspca_dev->int_urb = urb; | 226 | gspca_dev->int_urb = urb; |
227 | ret = usb_submit_urb(urb, GFP_KERNEL); | 227 | ret = usb_submit_urb(urb, GFP_KERNEL); |
228 | if (ret < 0) { | 228 | if (ret < 0) { |
229 | PDEBUG(D_ERR, "submit URB failed with error %i", ret); | 229 | PDEBUG(D_ERR, "submit int URB failed with error %i", ret); |
230 | goto error_submit; | 230 | goto error_submit; |
231 | } | 231 | } |
232 | return ret; | 232 | return ret; |
@@ -294,19 +294,6 @@ static inline int gspca_input_connect(struct gspca_dev *dev) | |||
294 | } | 294 | } |
295 | #endif | 295 | #endif |
296 | 296 | ||
297 | /* get the current input frame buffer */ | ||
298 | struct gspca_frame *gspca_get_i_frame(struct gspca_dev *gspca_dev) | ||
299 | { | ||
300 | struct gspca_frame *frame; | ||
301 | |||
302 | frame = gspca_dev->cur_frame; | ||
303 | if ((frame->v4l2_buf.flags & BUF_ALL_FLAGS) | ||
304 | != V4L2_BUF_FLAG_QUEUED) | ||
305 | return NULL; | ||
306 | return frame; | ||
307 | } | ||
308 | EXPORT_SYMBOL(gspca_get_i_frame); | ||
309 | |||
310 | /* | 297 | /* |
311 | * fill a video frame from an URB and resubmit | 298 | * fill a video frame from an URB and resubmit |
312 | */ | 299 | */ |
@@ -439,20 +426,20 @@ void gspca_frame_add(struct gspca_dev *gspca_dev, | |||
439 | 426 | ||
440 | PDEBUG(D_PACK, "add t:%d l:%d", packet_type, len); | 427 | PDEBUG(D_PACK, "add t:%d l:%d", packet_type, len); |
441 | 428 | ||
442 | /* check the availability of the frame buffer */ | ||
443 | frame = gspca_dev->cur_frame; | ||
444 | if ((frame->v4l2_buf.flags & BUF_ALL_FLAGS) | ||
445 | != V4L2_BUF_FLAG_QUEUED) { | ||
446 | gspca_dev->last_packet_type = DISCARD_PACKET; | ||
447 | return; | ||
448 | } | ||
449 | |||
450 | /* when start of a new frame, if the current frame buffer | ||
451 | * is not queued, discard the whole frame */ | ||
452 | if (packet_type == FIRST_PACKET) { | 429 | if (packet_type == FIRST_PACKET) { |
453 | frame->data_end = frame->data; | 430 | i = atomic_read(&gspca_dev->fr_i); |
431 | |||
432 | /* if there are no queued buffer, discard the whole frame */ | ||
433 | if (i == atomic_read(&gspca_dev->fr_q)) { | ||
434 | gspca_dev->last_packet_type = DISCARD_PACKET; | ||
435 | return; | ||
436 | } | ||
437 | j = gspca_dev->fr_queue[i]; | ||
438 | frame = &gspca_dev->frame[j]; | ||
454 | frame->v4l2_buf.timestamp = ktime_to_timeval(ktime_get()); | 439 | frame->v4l2_buf.timestamp = ktime_to_timeval(ktime_get()); |
455 | frame->v4l2_buf.sequence = ++gspca_dev->sequence; | 440 | frame->v4l2_buf.sequence = ++gspca_dev->sequence; |
441 | gspca_dev->image = frame->data; | ||
442 | gspca_dev->image_len = 0; | ||
456 | } else if (gspca_dev->last_packet_type == DISCARD_PACKET) { | 443 | } else if (gspca_dev->last_packet_type == DISCARD_PACKET) { |
457 | if (packet_type == LAST_PACKET) | 444 | if (packet_type == LAST_PACKET) |
458 | gspca_dev->last_packet_type = packet_type; | 445 | gspca_dev->last_packet_type = packet_type; |
@@ -461,34 +448,37 @@ void gspca_frame_add(struct gspca_dev *gspca_dev, | |||
461 | 448 | ||
462 | /* append the packet to the frame buffer */ | 449 | /* append the packet to the frame buffer */ |
463 | if (len > 0) { | 450 | if (len > 0) { |
464 | if (frame->data_end - frame->data + len | 451 | if (gspca_dev->image_len + len > gspca_dev->frsz) { |
465 | > frame->v4l2_buf.length) { | 452 | PDEBUG(D_ERR|D_PACK, "frame overflow %d > %d", |
466 | PDEBUG(D_ERR|D_PACK, "frame overflow %zd > %d", | 453 | gspca_dev->image_len + len, |
467 | frame->data_end - frame->data + len, | 454 | gspca_dev->frsz); |
468 | frame->v4l2_buf.length); | ||
469 | packet_type = DISCARD_PACKET; | 455 | packet_type = DISCARD_PACKET; |
470 | } else { | 456 | } else { |
471 | memcpy(frame->data_end, data, len); | 457 | memcpy(gspca_dev->image + gspca_dev->image_len, |
472 | frame->data_end += len; | 458 | data, len); |
459 | gspca_dev->image_len += len; | ||
473 | } | 460 | } |
474 | } | 461 | } |
475 | gspca_dev->last_packet_type = packet_type; | 462 | gspca_dev->last_packet_type = packet_type; |
476 | 463 | ||
477 | /* if last packet, wake up the application and advance in the queue */ | 464 | /* if last packet, invalidate packet concatenation until |
465 | * next first packet, wake up the application and advance | ||
466 | * in the queue */ | ||
478 | if (packet_type == LAST_PACKET) { | 467 | if (packet_type == LAST_PACKET) { |
479 | frame->v4l2_buf.bytesused = frame->data_end - frame->data; | 468 | i = atomic_read(&gspca_dev->fr_i); |
480 | frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_QUEUED; | ||
481 | frame->v4l2_buf.flags |= V4L2_BUF_FLAG_DONE; | ||
482 | wake_up_interruptible(&gspca_dev->wq); /* event = new frame */ | ||
483 | i = (gspca_dev->fr_i + 1) % gspca_dev->nframes; | ||
484 | gspca_dev->fr_i = i; | ||
485 | PDEBUG(D_FRAM, "frame complete len:%d q:%d i:%d o:%d", | ||
486 | frame->v4l2_buf.bytesused, | ||
487 | gspca_dev->fr_q, | ||
488 | i, | ||
489 | gspca_dev->fr_o); | ||
490 | j = gspca_dev->fr_queue[i]; | 469 | j = gspca_dev->fr_queue[i]; |
491 | gspca_dev->cur_frame = &gspca_dev->frame[j]; | 470 | frame = &gspca_dev->frame[j]; |
471 | frame->v4l2_buf.bytesused = gspca_dev->image_len; | ||
472 | frame->v4l2_buf.flags = (frame->v4l2_buf.flags | ||
473 | | V4L2_BUF_FLAG_DONE) | ||
474 | & ~V4L2_BUF_FLAG_QUEUED; | ||
475 | i = (i + 1) % GSPCA_MAX_FRAMES; | ||
476 | atomic_set(&gspca_dev->fr_i, i); | ||
477 | wake_up_interruptible(&gspca_dev->wq); /* event = new frame */ | ||
478 | PDEBUG(D_FRAM, "frame complete len:%d", | ||
479 | frame->v4l2_buf.bytesused); | ||
480 | gspca_dev->image = NULL; | ||
481 | gspca_dev->image_len = 0; | ||
492 | } | 482 | } |
493 | } | 483 | } |
494 | EXPORT_SYMBOL(gspca_frame_add); | 484 | EXPORT_SYMBOL(gspca_frame_add); |
@@ -506,36 +496,6 @@ static int gspca_is_compressed(__u32 format) | |||
506 | return 0; | 496 | return 0; |
507 | } | 497 | } |
508 | 498 | ||
509 | static void *rvmalloc(long size) | ||
510 | { | ||
511 | void *mem; | ||
512 | unsigned long adr; | ||
513 | |||
514 | mem = vmalloc_32(size); | ||
515 | if (mem != NULL) { | ||
516 | adr = (unsigned long) mem; | ||
517 | while (size > 0) { | ||
518 | SetPageReserved(vmalloc_to_page((void *) adr)); | ||
519 | adr += PAGE_SIZE; | ||
520 | size -= PAGE_SIZE; | ||
521 | } | ||
522 | } | ||
523 | return mem; | ||
524 | } | ||
525 | |||
526 | static void rvfree(void *mem, long size) | ||
527 | { | ||
528 | unsigned long adr; | ||
529 | |||
530 | adr = (unsigned long) mem; | ||
531 | while (size > 0) { | ||
532 | ClearPageReserved(vmalloc_to_page((void *) adr)); | ||
533 | adr += PAGE_SIZE; | ||
534 | size -= PAGE_SIZE; | ||
535 | } | ||
536 | vfree(mem); | ||
537 | } | ||
538 | |||
539 | static int frame_alloc(struct gspca_dev *gspca_dev, | 499 | static int frame_alloc(struct gspca_dev *gspca_dev, |
540 | unsigned int count) | 500 | unsigned int count) |
541 | { | 501 | { |
@@ -548,9 +508,9 @@ static int frame_alloc(struct gspca_dev *gspca_dev, | |||
548 | PDEBUG(D_STREAM, "frame alloc frsz: %d", frsz); | 508 | PDEBUG(D_STREAM, "frame alloc frsz: %d", frsz); |
549 | frsz = PAGE_ALIGN(frsz); | 509 | frsz = PAGE_ALIGN(frsz); |
550 | gspca_dev->frsz = frsz; | 510 | gspca_dev->frsz = frsz; |
551 | if (count > GSPCA_MAX_FRAMES) | 511 | if (count >= GSPCA_MAX_FRAMES) |
552 | count = GSPCA_MAX_FRAMES; | 512 | count = GSPCA_MAX_FRAMES - 1; |
553 | gspca_dev->frbuf = rvmalloc(frsz * count); | 513 | gspca_dev->frbuf = vmalloc_32(frsz * count); |
554 | if (!gspca_dev->frbuf) { | 514 | if (!gspca_dev->frbuf) { |
555 | err("frame alloc failed"); | 515 | err("frame alloc failed"); |
556 | return -ENOMEM; | 516 | return -ENOMEM; |
@@ -565,14 +525,12 @@ static int frame_alloc(struct gspca_dev *gspca_dev, | |||
565 | frame->v4l2_buf.length = frsz; | 525 | frame->v4l2_buf.length = frsz; |
566 | frame->v4l2_buf.memory = gspca_dev->memory; | 526 | frame->v4l2_buf.memory = gspca_dev->memory; |
567 | frame->v4l2_buf.sequence = 0; | 527 | frame->v4l2_buf.sequence = 0; |
568 | frame->data = frame->data_end = | 528 | frame->data = gspca_dev->frbuf + i * frsz; |
569 | gspca_dev->frbuf + i * frsz; | ||
570 | frame->v4l2_buf.m.offset = i * frsz; | 529 | frame->v4l2_buf.m.offset = i * frsz; |
571 | } | 530 | } |
572 | gspca_dev->fr_i = gspca_dev->fr_o = gspca_dev->fr_q = 0; | 531 | atomic_set(&gspca_dev->fr_q, 0); |
573 | gspca_dev->cur_frame = &gspca_dev->frame[0]; | 532 | atomic_set(&gspca_dev->fr_i, 0); |
574 | gspca_dev->last_packet_type = DISCARD_PACKET; | 533 | gspca_dev->fr_o = 0; |
575 | gspca_dev->sequence = 0; | ||
576 | return 0; | 534 | return 0; |
577 | } | 535 | } |
578 | 536 | ||
@@ -582,8 +540,7 @@ static void frame_free(struct gspca_dev *gspca_dev) | |||
582 | 540 | ||
583 | PDEBUG(D_STREAM, "frame free"); | 541 | PDEBUG(D_STREAM, "frame free"); |
584 | if (gspca_dev->frbuf != NULL) { | 542 | if (gspca_dev->frbuf != NULL) { |
585 | rvfree(gspca_dev->frbuf, | 543 | vfree(gspca_dev->frbuf); |
586 | gspca_dev->nframes * gspca_dev->frsz); | ||
587 | gspca_dev->frbuf = NULL; | 544 | gspca_dev->frbuf = NULL; |
588 | for (i = 0; i < gspca_dev->nframes; i++) | 545 | for (i = 0; i < gspca_dev->nframes; i++) |
589 | gspca_dev->frame[i].data = NULL; | 546 | gspca_dev->frame[i].data = NULL; |
@@ -683,12 +640,16 @@ static struct usb_host_endpoint *get_ep(struct gspca_dev *gspca_dev) | |||
683 | : USB_ENDPOINT_XFER_ISOC; | 640 | : USB_ENDPOINT_XFER_ISOC; |
684 | i = gspca_dev->alt; /* previous alt setting */ | 641 | i = gspca_dev->alt; /* previous alt setting */ |
685 | if (gspca_dev->cam.reverse_alts) { | 642 | if (gspca_dev->cam.reverse_alts) { |
643 | if (gspca_dev->audio) | ||
644 | i++; | ||
686 | while (++i < gspca_dev->nbalt) { | 645 | while (++i < gspca_dev->nbalt) { |
687 | ep = alt_xfer(&intf->altsetting[i], xfer); | 646 | ep = alt_xfer(&intf->altsetting[i], xfer); |
688 | if (ep) | 647 | if (ep) |
689 | break; | 648 | break; |
690 | } | 649 | } |
691 | } else { | 650 | } else { |
651 | if (gspca_dev->audio) | ||
652 | i--; | ||
692 | while (--i >= 0) { | 653 | while (--i >= 0) { |
693 | ep = alt_xfer(&intf->altsetting[i], xfer); | 654 | ep = alt_xfer(&intf->altsetting[i], xfer); |
694 | if (ep) | 655 | if (ep) |
@@ -811,6 +772,12 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev) | |||
811 | goto out; | 772 | goto out; |
812 | } | 773 | } |
813 | 774 | ||
775 | /* reset the streaming variables */ | ||
776 | gspca_dev->image = NULL; | ||
777 | gspca_dev->image_len = 0; | ||
778 | gspca_dev->last_packet_type = DISCARD_PACKET; | ||
779 | gspca_dev->sequence = 0; | ||
780 | |||
814 | gspca_dev->usb_err = 0; | 781 | gspca_dev->usb_err = 0; |
815 | 782 | ||
816 | /* set the higher alternate setting and | 783 | /* set the higher alternate setting and |
@@ -1433,34 +1400,6 @@ static int vidioc_g_ctrl(struct file *file, void *priv, | |||
1433 | return ret; | 1400 | return ret; |
1434 | } | 1401 | } |
1435 | 1402 | ||
1436 | /*fixme: have an audio flag in gspca_dev?*/ | ||
1437 | static int vidioc_s_audio(struct file *file, void *priv, | ||
1438 | struct v4l2_audio *audio) | ||
1439 | { | ||
1440 | if (audio->index != 0) | ||
1441 | return -EINVAL; | ||
1442 | return 0; | ||
1443 | } | ||
1444 | |||
1445 | static int vidioc_g_audio(struct file *file, void *priv, | ||
1446 | struct v4l2_audio *audio) | ||
1447 | { | ||
1448 | strcpy(audio->name, "Microphone"); | ||
1449 | return 0; | ||
1450 | } | ||
1451 | |||
1452 | static int vidioc_enumaudio(struct file *file, void *priv, | ||
1453 | struct v4l2_audio *audio) | ||
1454 | { | ||
1455 | if (audio->index != 0) | ||
1456 | return -EINVAL; | ||
1457 | |||
1458 | strcpy(audio->name, "Microphone"); | ||
1459 | audio->capability = 0; | ||
1460 | audio->mode = 0; | ||
1461 | return 0; | ||
1462 | } | ||
1463 | |||
1464 | static int vidioc_querymenu(struct file *file, void *priv, | 1403 | static int vidioc_querymenu(struct file *file, void *priv, |
1465 | struct v4l2_querymenu *qmenu) | 1404 | struct v4l2_querymenu *qmenu) |
1466 | { | 1405 | { |
@@ -1504,7 +1443,8 @@ static int vidioc_reqbufs(struct file *file, void *priv, | |||
1504 | struct gspca_dev *gspca_dev = priv; | 1443 | struct gspca_dev *gspca_dev = priv; |
1505 | int i, ret = 0, streaming; | 1444 | int i, ret = 0, streaming; |
1506 | 1445 | ||
1507 | switch (rb->memory) { | 1446 | i = rb->memory; /* (avoid compilation warning) */ |
1447 | switch (i) { | ||
1508 | case GSPCA_MEMORY_READ: /* (internal call) */ | 1448 | case GSPCA_MEMORY_READ: /* (internal call) */ |
1509 | case V4L2_MEMORY_MMAP: | 1449 | case V4L2_MEMORY_MMAP: |
1510 | case V4L2_MEMORY_USERPTR: | 1450 | case V4L2_MEMORY_USERPTR: |
@@ -1626,7 +1566,7 @@ static int vidioc_streamoff(struct file *file, void *priv, | |||
1626 | enum v4l2_buf_type buf_type) | 1566 | enum v4l2_buf_type buf_type) |
1627 | { | 1567 | { |
1628 | struct gspca_dev *gspca_dev = priv; | 1568 | struct gspca_dev *gspca_dev = priv; |
1629 | int i, ret; | 1569 | int ret; |
1630 | 1570 | ||
1631 | if (buf_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 1571 | if (buf_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
1632 | return -EINVAL; | 1572 | return -EINVAL; |
@@ -1650,12 +1590,10 @@ static int vidioc_streamoff(struct file *file, void *priv, | |||
1650 | gspca_stream_off(gspca_dev); | 1590 | gspca_stream_off(gspca_dev); |
1651 | mutex_unlock(&gspca_dev->usb_lock); | 1591 | mutex_unlock(&gspca_dev->usb_lock); |
1652 | 1592 | ||
1653 | /* empty the application queues */ | 1593 | /* empty the transfer queues */ |
1654 | for (i = 0; i < gspca_dev->nframes; i++) | 1594 | atomic_set(&gspca_dev->fr_q, 0); |
1655 | gspca_dev->frame[i].v4l2_buf.flags &= ~BUF_ALL_FLAGS; | 1595 | atomic_set(&gspca_dev->fr_i, 0); |
1656 | gspca_dev->fr_i = gspca_dev->fr_o = gspca_dev->fr_q = 0; | 1596 | gspca_dev->fr_o = 0; |
1657 | gspca_dev->last_packet_type = DISCARD_PACKET; | ||
1658 | gspca_dev->sequence = 0; | ||
1659 | ret = 0; | 1597 | ret = 0; |
1660 | out: | 1598 | out: |
1661 | mutex_unlock(&gspca_dev->queue_lock); | 1599 | mutex_unlock(&gspca_dev->queue_lock); |
@@ -1732,7 +1670,7 @@ static int vidioc_s_parm(struct file *filp, void *priv, | |||
1732 | int n; | 1670 | int n; |
1733 | 1671 | ||
1734 | n = parm->parm.capture.readbuffers; | 1672 | n = parm->parm.capture.readbuffers; |
1735 | if (n == 0 || n > GSPCA_MAX_FRAMES) | 1673 | if (n == 0 || n >= GSPCA_MAX_FRAMES) |
1736 | parm->parm.capture.readbuffers = gspca_dev->nbufread; | 1674 | parm->parm.capture.readbuffers = gspca_dev->nbufread; |
1737 | else | 1675 | else |
1738 | gspca_dev->nbufread = n; | 1676 | gspca_dev->nbufread = n; |
@@ -1755,49 +1693,6 @@ static int vidioc_s_parm(struct file *filp, void *priv, | |||
1755 | return 0; | 1693 | return 0; |
1756 | } | 1694 | } |
1757 | 1695 | ||
1758 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | ||
1759 | static int vidiocgmbuf(struct file *file, void *priv, | ||
1760 | struct video_mbuf *mbuf) | ||
1761 | { | ||
1762 | struct gspca_dev *gspca_dev = file->private_data; | ||
1763 | int i; | ||
1764 | |||
1765 | PDEBUG(D_STREAM, "cgmbuf"); | ||
1766 | if (gspca_dev->nframes == 0) { | ||
1767 | int ret; | ||
1768 | |||
1769 | { | ||
1770 | struct v4l2_format fmt; | ||
1771 | |||
1772 | fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
1773 | i = gspca_dev->cam.nmodes - 1; /* highest mode */ | ||
1774 | fmt.fmt.pix.width = gspca_dev->cam.cam_mode[i].width; | ||
1775 | fmt.fmt.pix.height = gspca_dev->cam.cam_mode[i].height; | ||
1776 | fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_BGR24; | ||
1777 | ret = vidioc_s_fmt_vid_cap(file, priv, &fmt); | ||
1778 | if (ret != 0) | ||
1779 | return ret; | ||
1780 | } | ||
1781 | { | ||
1782 | struct v4l2_requestbuffers rb; | ||
1783 | |||
1784 | memset(&rb, 0, sizeof rb); | ||
1785 | rb.count = 4; | ||
1786 | rb.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
1787 | rb.memory = V4L2_MEMORY_MMAP; | ||
1788 | ret = vidioc_reqbufs(file, priv, &rb); | ||
1789 | if (ret != 0) | ||
1790 | return ret; | ||
1791 | } | ||
1792 | } | ||
1793 | mbuf->frames = gspca_dev->nframes; | ||
1794 | mbuf->size = gspca_dev->frsz * gspca_dev->nframes; | ||
1795 | for (i = 0; i < mbuf->frames; i++) | ||
1796 | mbuf->offsets[i] = gspca_dev->frame[i].v4l2_buf.m.offset; | ||
1797 | return 0; | ||
1798 | } | ||
1799 | #endif | ||
1800 | |||
1801 | static int dev_mmap(struct file *file, struct vm_area_struct *vma) | 1696 | static int dev_mmap(struct file *file, struct vm_area_struct *vma) |
1802 | { | 1697 | { |
1803 | struct gspca_dev *gspca_dev = file->private_data; | 1698 | struct gspca_dev *gspca_dev = file->private_data; |
@@ -1838,12 +1733,7 @@ static int dev_mmap(struct file *file, struct vm_area_struct *vma) | |||
1838 | ret = -EINVAL; | 1733 | ret = -EINVAL; |
1839 | goto out; | 1734 | goto out; |
1840 | } | 1735 | } |
1841 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | 1736 | if (size != frame->v4l2_buf.length) { |
1842 | /* v4l1 maps all the buffers */ | ||
1843 | if (i != 0 | ||
1844 | || size != frame->v4l2_buf.length * gspca_dev->nframes) | ||
1845 | #endif | ||
1846 | if (size != frame->v4l2_buf.length) { | ||
1847 | PDEBUG(D_STREAM, "mmap bad size"); | 1737 | PDEBUG(D_STREAM, "mmap bad size"); |
1848 | ret = -EINVAL; | 1738 | ret = -EINVAL; |
1849 | goto out; | 1739 | goto out; |
@@ -1883,21 +1773,17 @@ out: | |||
1883 | static int frame_wait(struct gspca_dev *gspca_dev, | 1773 | static int frame_wait(struct gspca_dev *gspca_dev, |
1884 | int nonblock_ing) | 1774 | int nonblock_ing) |
1885 | { | 1775 | { |
1886 | struct gspca_frame *frame; | 1776 | int i, ret; |
1887 | int i, j, ret; | ||
1888 | 1777 | ||
1889 | /* check if a frame is ready */ | 1778 | /* check if a frame is ready */ |
1890 | i = gspca_dev->fr_o; | 1779 | i = gspca_dev->fr_o; |
1891 | j = gspca_dev->fr_queue[i]; | 1780 | if (i == atomic_read(&gspca_dev->fr_i)) { |
1892 | frame = &gspca_dev->frame[j]; | ||
1893 | |||
1894 | if (!(frame->v4l2_buf.flags & V4L2_BUF_FLAG_DONE)) { | ||
1895 | if (nonblock_ing) | 1781 | if (nonblock_ing) |
1896 | return -EAGAIN; | 1782 | return -EAGAIN; |
1897 | 1783 | ||
1898 | /* wait till a frame is ready */ | 1784 | /* wait till a frame is ready */ |
1899 | ret = wait_event_interruptible_timeout(gspca_dev->wq, | 1785 | ret = wait_event_interruptible_timeout(gspca_dev->wq, |
1900 | (frame->v4l2_buf.flags & V4L2_BUF_FLAG_DONE) || | 1786 | i != atomic_read(&gspca_dev->fr_i) || |
1901 | !gspca_dev->streaming || !gspca_dev->present, | 1787 | !gspca_dev->streaming || !gspca_dev->present, |
1902 | msecs_to_jiffies(3000)); | 1788 | msecs_to_jiffies(3000)); |
1903 | if (ret < 0) | 1789 | if (ret < 0) |
@@ -1906,11 +1792,7 @@ static int frame_wait(struct gspca_dev *gspca_dev, | |||
1906 | return -EIO; | 1792 | return -EIO; |
1907 | } | 1793 | } |
1908 | 1794 | ||
1909 | gspca_dev->fr_o = (i + 1) % gspca_dev->nframes; | 1795 | gspca_dev->fr_o = (i + 1) % GSPCA_MAX_FRAMES; |
1910 | PDEBUG(D_FRAM, "frame wait q:%d i:%d o:%d", | ||
1911 | gspca_dev->fr_q, | ||
1912 | gspca_dev->fr_i, | ||
1913 | gspca_dev->fr_o); | ||
1914 | 1796 | ||
1915 | if (gspca_dev->sd_desc->dq_callback) { | 1797 | if (gspca_dev->sd_desc->dq_callback) { |
1916 | mutex_lock(&gspca_dev->usb_lock); | 1798 | mutex_lock(&gspca_dev->usb_lock); |
@@ -1919,7 +1801,7 @@ static int frame_wait(struct gspca_dev *gspca_dev, | |||
1919 | gspca_dev->sd_desc->dq_callback(gspca_dev); | 1801 | gspca_dev->sd_desc->dq_callback(gspca_dev); |
1920 | mutex_unlock(&gspca_dev->usb_lock); | 1802 | mutex_unlock(&gspca_dev->usb_lock); |
1921 | } | 1803 | } |
1922 | return j; | 1804 | return gspca_dev->fr_queue[i]; |
1923 | } | 1805 | } |
1924 | 1806 | ||
1925 | /* | 1807 | /* |
@@ -2024,15 +1906,9 @@ static int vidioc_qbuf(struct file *file, void *priv, | |||
2024 | } | 1906 | } |
2025 | 1907 | ||
2026 | /* put the buffer in the 'queued' queue */ | 1908 | /* put the buffer in the 'queued' queue */ |
2027 | i = gspca_dev->fr_q; | 1909 | i = atomic_read(&gspca_dev->fr_q); |
2028 | gspca_dev->fr_queue[i] = index; | 1910 | gspca_dev->fr_queue[i] = index; |
2029 | if (gspca_dev->fr_i == i) | 1911 | atomic_set(&gspca_dev->fr_q, (i + 1) % GSPCA_MAX_FRAMES); |
2030 | gspca_dev->cur_frame = frame; | ||
2031 | gspca_dev->fr_q = (i + 1) % gspca_dev->nframes; | ||
2032 | PDEBUG(D_FRAM, "qbuf q:%d i:%d o:%d", | ||
2033 | gspca_dev->fr_q, | ||
2034 | gspca_dev->fr_i, | ||
2035 | gspca_dev->fr_o); | ||
2036 | 1912 | ||
2037 | v4l2_buf->flags |= V4L2_BUF_FLAG_QUEUED; | 1913 | v4l2_buf->flags |= V4L2_BUF_FLAG_QUEUED; |
2038 | v4l2_buf->flags &= ~V4L2_BUF_FLAG_DONE; | 1914 | v4l2_buf->flags &= ~V4L2_BUF_FLAG_DONE; |
@@ -2088,7 +1964,7 @@ static int read_alloc(struct gspca_dev *gspca_dev, | |||
2088 | static unsigned int dev_poll(struct file *file, poll_table *wait) | 1964 | static unsigned int dev_poll(struct file *file, poll_table *wait) |
2089 | { | 1965 | { |
2090 | struct gspca_dev *gspca_dev = file->private_data; | 1966 | struct gspca_dev *gspca_dev = file->private_data; |
2091 | int i, ret; | 1967 | int ret; |
2092 | 1968 | ||
2093 | PDEBUG(D_FRAM, "poll"); | 1969 | PDEBUG(D_FRAM, "poll"); |
2094 | 1970 | ||
@@ -2106,11 +1982,9 @@ static unsigned int dev_poll(struct file *file, poll_table *wait) | |||
2106 | if (mutex_lock_interruptible(&gspca_dev->queue_lock) != 0) | 1982 | if (mutex_lock_interruptible(&gspca_dev->queue_lock) != 0) |
2107 | return POLLERR; | 1983 | return POLLERR; |
2108 | 1984 | ||
2109 | /* check the next incoming buffer */ | 1985 | /* check if an image has been received */ |
2110 | i = gspca_dev->fr_o; | 1986 | if (gspca_dev->fr_o != atomic_read(&gspca_dev->fr_i)) |
2111 | i = gspca_dev->fr_queue[i]; | 1987 | ret = POLLIN | POLLRDNORM; /* yes */ |
2112 | if (gspca_dev->frame[i].v4l2_buf.flags & V4L2_BUF_FLAG_DONE) | ||
2113 | ret = POLLIN | POLLRDNORM; /* something to read */ | ||
2114 | else | 1988 | else |
2115 | ret = 0; | 1989 | ret = 0; |
2116 | mutex_unlock(&gspca_dev->queue_lock); | 1990 | mutex_unlock(&gspca_dev->queue_lock); |
@@ -2214,9 +2088,6 @@ static const struct v4l2_ioctl_ops dev_ioctl_ops = { | |||
2214 | .vidioc_queryctrl = vidioc_queryctrl, | 2088 | .vidioc_queryctrl = vidioc_queryctrl, |
2215 | .vidioc_g_ctrl = vidioc_g_ctrl, | 2089 | .vidioc_g_ctrl = vidioc_g_ctrl, |
2216 | .vidioc_s_ctrl = vidioc_s_ctrl, | 2090 | .vidioc_s_ctrl = vidioc_s_ctrl, |
2217 | .vidioc_g_audio = vidioc_g_audio, | ||
2218 | .vidioc_s_audio = vidioc_s_audio, | ||
2219 | .vidioc_enumaudio = vidioc_enumaudio, | ||
2220 | .vidioc_querymenu = vidioc_querymenu, | 2091 | .vidioc_querymenu = vidioc_querymenu, |
2221 | .vidioc_enum_input = vidioc_enum_input, | 2092 | .vidioc_enum_input = vidioc_enum_input, |
2222 | .vidioc_g_input = vidioc_g_input, | 2093 | .vidioc_g_input = vidioc_g_input, |
@@ -2235,9 +2106,6 @@ static const struct v4l2_ioctl_ops dev_ioctl_ops = { | |||
2235 | .vidioc_s_register = vidioc_s_register, | 2106 | .vidioc_s_register = vidioc_s_register, |
2236 | #endif | 2107 | #endif |
2237 | .vidioc_g_chip_ident = vidioc_g_chip_ident, | 2108 | .vidioc_g_chip_ident = vidioc_g_chip_ident, |
2238 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | ||
2239 | .vidiocgmbuf = vidiocgmbuf, | ||
2240 | #endif | ||
2241 | }; | 2109 | }; |
2242 | 2110 | ||
2243 | static struct video_device gspca_template = { | 2111 | static struct video_device gspca_template = { |
@@ -2253,31 +2121,18 @@ static struct video_device gspca_template = { | |||
2253 | * This function must be called by the sub-driver when it is | 2121 | * This function must be called by the sub-driver when it is |
2254 | * called for probing a new device. | 2122 | * called for probing a new device. |
2255 | */ | 2123 | */ |
2256 | int gspca_dev_probe(struct usb_interface *intf, | 2124 | int gspca_dev_probe2(struct usb_interface *intf, |
2257 | const struct usb_device_id *id, | 2125 | const struct usb_device_id *id, |
2258 | const struct sd_desc *sd_desc, | 2126 | const struct sd_desc *sd_desc, |
2259 | int dev_size, | 2127 | int dev_size, |
2260 | struct module *module) | 2128 | struct module *module) |
2261 | { | 2129 | { |
2262 | struct usb_interface_descriptor *interface; | ||
2263 | struct gspca_dev *gspca_dev; | 2130 | struct gspca_dev *gspca_dev; |
2264 | struct usb_device *dev = interface_to_usbdev(intf); | 2131 | struct usb_device *dev = interface_to_usbdev(intf); |
2265 | int ret; | 2132 | int ret; |
2266 | 2133 | ||
2267 | PDEBUG(D_PROBE, "probing %04x:%04x", id->idVendor, id->idProduct); | 2134 | PDEBUG(D_PROBE, "probing %04x:%04x", id->idVendor, id->idProduct); |
2268 | 2135 | ||
2269 | /* we don't handle multi-config cameras */ | ||
2270 | if (dev->descriptor.bNumConfigurations != 1) { | ||
2271 | PDEBUG(D_ERR, "Too many config"); | ||
2272 | return -ENODEV; | ||
2273 | } | ||
2274 | |||
2275 | /* the USB video interface must be the first one */ | ||
2276 | interface = &intf->cur_altsetting->desc; | ||
2277 | if (dev->config->desc.bNumInterfaces != 1 && | ||
2278 | interface->bInterfaceNumber != 0) | ||
2279 | return -ENODEV; | ||
2280 | |||
2281 | /* create the device */ | 2136 | /* create the device */ |
2282 | if (dev_size < sizeof *gspca_dev) | 2137 | if (dev_size < sizeof *gspca_dev) |
2283 | dev_size = sizeof *gspca_dev; | 2138 | dev_size = sizeof *gspca_dev; |
@@ -2293,8 +2148,26 @@ int gspca_dev_probe(struct usb_interface *intf, | |||
2293 | goto out; | 2148 | goto out; |
2294 | } | 2149 | } |
2295 | gspca_dev->dev = dev; | 2150 | gspca_dev->dev = dev; |
2296 | gspca_dev->iface = interface->bInterfaceNumber; | 2151 | gspca_dev->iface = intf->cur_altsetting->desc.bInterfaceNumber; |
2297 | gspca_dev->nbalt = intf->num_altsetting; | 2152 | gspca_dev->nbalt = intf->num_altsetting; |
2153 | |||
2154 | /* check if any audio device */ | ||
2155 | if (dev->config->desc.bNumInterfaces != 1) { | ||
2156 | int i; | ||
2157 | struct usb_interface *intf2; | ||
2158 | |||
2159 | for (i = 0; i < dev->config->desc.bNumInterfaces; i++) { | ||
2160 | intf2 = dev->config->interface[i]; | ||
2161 | if (intf2 != NULL | ||
2162 | && intf2->altsetting != NULL | ||
2163 | && intf2->altsetting->desc.bInterfaceClass == | ||
2164 | USB_CLASS_AUDIO) { | ||
2165 | gspca_dev->audio = 1; | ||
2166 | break; | ||
2167 | } | ||
2168 | } | ||
2169 | } | ||
2170 | |||
2298 | gspca_dev->sd_desc = sd_desc; | 2171 | gspca_dev->sd_desc = sd_desc; |
2299 | gspca_dev->nbufread = 2; | 2172 | gspca_dev->nbufread = 2; |
2300 | gspca_dev->empty_packet = -1; /* don't check the empty packets */ | 2173 | gspca_dev->empty_packet = -1; /* don't check the empty packets */ |
@@ -2345,6 +2218,31 @@ out: | |||
2345 | kfree(gspca_dev); | 2218 | kfree(gspca_dev); |
2346 | return ret; | 2219 | return ret; |
2347 | } | 2220 | } |
2221 | EXPORT_SYMBOL(gspca_dev_probe2); | ||
2222 | |||
2223 | /* same function as the previous one, but check the interface */ | ||
2224 | int gspca_dev_probe(struct usb_interface *intf, | ||
2225 | const struct usb_device_id *id, | ||
2226 | const struct sd_desc *sd_desc, | ||
2227 | int dev_size, | ||
2228 | struct module *module) | ||
2229 | { | ||
2230 | struct usb_device *dev = interface_to_usbdev(intf); | ||
2231 | |||
2232 | /* we don't handle multi-config cameras */ | ||
2233 | if (dev->descriptor.bNumConfigurations != 1) { | ||
2234 | PDEBUG(D_ERR, "%04x:%04x too many config", | ||
2235 | id->idVendor, id->idProduct); | ||
2236 | return -ENODEV; | ||
2237 | } | ||
2238 | |||
2239 | /* the USB video interface must be the first one */ | ||
2240 | if (dev->config->desc.bNumInterfaces != 1 | ||
2241 | && intf->cur_altsetting->desc.bInterfaceNumber != 0) | ||
2242 | return -ENODEV; | ||
2243 | |||
2244 | return gspca_dev_probe2(intf, id, sd_desc, dev_size, module); | ||
2245 | } | ||
2348 | EXPORT_SYMBOL(gspca_dev_probe); | 2246 | EXPORT_SYMBOL(gspca_dev_probe); |
2349 | 2247 | ||
2350 | /* | 2248 | /* |