diff options
author | Laurent Pinchart <laurent.pinchart@skynet.be> | 2009-06-28 07:37:50 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-09-12 11:18:32 -0400 |
commit | 35f02a681b72ece756cf005e17f305a72329c140 (patch) | |
tree | ce566b9875213470d355a50bd8c6f9edeb1dd8dd /drivers/media/video/uvc | |
parent | 6c428b578b15a1dbf40832d3aeed43761940b81f (diff) |
V4L/DVB (12378): uvcvideo: Restructure the driver to support multiple simultaneous streams.
As a first step towards multiple streaming interfaces support, reorganize the
driver's data structures to cleanly separate video control and video streaming
data.
Signed-off-by: Laurent Pinchart <laurent.pinchart@skynet.be>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/uvc')
-rw-r--r-- | drivers/media/video/uvc/uvc_driver.c | 174 | ||||
-rw-r--r-- | drivers/media/video/uvc/uvc_isight.c | 7 | ||||
-rw-r--r-- | drivers/media/video/uvc/uvc_v4l2.c | 195 | ||||
-rw-r--r-- | drivers/media/video/uvc/uvc_video.c | 415 | ||||
-rw-r--r-- | drivers/media/video/uvc/uvcvideo.h | 86 |
5 files changed, 456 insertions, 421 deletions
diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c index e17216c96ac5..81bf67126abf 100644 --- a/drivers/media/video/uvc/uvc_driver.c +++ b/drivers/media/video/uvc/uvc_driver.c | |||
@@ -551,6 +551,7 @@ static int uvc_parse_streaming(struct uvc_device *dev, | |||
551 | } | 551 | } |
552 | 552 | ||
553 | mutex_init(&streaming->mutex); | 553 | mutex_init(&streaming->mutex); |
554 | streaming->dev = dev; | ||
554 | streaming->intf = usb_get_intf(intf); | 555 | streaming->intf = usb_get_intf(intf); |
555 | streaming->intfnum = intf->cur_altsetting->desc.bInterfaceNumber; | 556 | streaming->intfnum = intf->cur_altsetting->desc.bInterfaceNumber; |
556 | 557 | ||
@@ -751,7 +752,7 @@ static int uvc_parse_streaming(struct uvc_device *dev, | |||
751 | streaming->maxpsize = psize; | 752 | streaming->maxpsize = psize; |
752 | } | 753 | } |
753 | 754 | ||
754 | list_add_tail(&streaming->list, &dev->streaming); | 755 | list_add_tail(&streaming->list, &dev->streams); |
755 | return 0; | 756 | return 0; |
756 | 757 | ||
757 | error: | 758 | error: |
@@ -1167,13 +1168,75 @@ next_descriptor: | |||
1167 | */ | 1168 | */ |
1168 | static void uvc_unregister_video(struct uvc_device *dev) | 1169 | static void uvc_unregister_video(struct uvc_device *dev) |
1169 | { | 1170 | { |
1170 | if (dev->video.vdev) { | 1171 | struct uvc_streaming *streaming; |
1171 | if (dev->video.vdev->minor == -1) | 1172 | |
1172 | video_device_release(dev->video.vdev); | 1173 | list_for_each_entry(streaming, &dev->streams, list) { |
1174 | if (streaming->vdev == NULL) | ||
1175 | continue; | ||
1176 | |||
1177 | if (streaming->vdev->minor == -1) | ||
1178 | video_device_release(streaming->vdev); | ||
1173 | else | 1179 | else |
1174 | video_unregister_device(dev->video.vdev); | 1180 | video_unregister_device(streaming->vdev); |
1175 | dev->video.vdev = NULL; | 1181 | streaming->vdev = NULL; |
1182 | } | ||
1183 | } | ||
1184 | |||
1185 | static int uvc_register_video(struct uvc_device *dev, | ||
1186 | struct uvc_streaming *stream) | ||
1187 | { | ||
1188 | struct video_device *vdev; | ||
1189 | struct uvc_entity *term; | ||
1190 | int ret; | ||
1191 | |||
1192 | if (uvc_trace_param & UVC_TRACE_PROBE) { | ||
1193 | uvc_printk(KERN_INFO, "Found a valid video chain ("); | ||
1194 | list_for_each_entry(term, &dev->video.iterms, chain) { | ||
1195 | printk("%d", term->id); | ||
1196 | if (term->chain.next != &dev->video.iterms) | ||
1197 | printk(","); | ||
1198 | } | ||
1199 | printk(" -> %d).\n", dev->video.oterm->id); | ||
1200 | } | ||
1201 | |||
1202 | /* Initialize the streaming interface with default streaming | ||
1203 | * parameters. | ||
1204 | */ | ||
1205 | ret = uvc_video_init(stream); | ||
1206 | if (ret < 0) { | ||
1207 | uvc_printk(KERN_ERR, "Failed to initialize the device " | ||
1208 | "(%d).\n", ret); | ||
1209 | return ret; | ||
1210 | } | ||
1211 | |||
1212 | /* Register the device with V4L. */ | ||
1213 | vdev = video_device_alloc(); | ||
1214 | if (vdev == NULL) | ||
1215 | return -1; | ||
1216 | |||
1217 | /* We already hold a reference to dev->udev. The video device will be | ||
1218 | * unregistered before the reference is released, so we don't need to | ||
1219 | * get another one. | ||
1220 | */ | ||
1221 | vdev->parent = &dev->intf->dev; | ||
1222 | vdev->minor = -1; | ||
1223 | vdev->fops = &uvc_fops; | ||
1224 | vdev->release = video_device_release; | ||
1225 | strlcpy(vdev->name, dev->name, sizeof vdev->name); | ||
1226 | |||
1227 | /* Set the driver data before calling video_register_device, otherwise | ||
1228 | * uvc_v4l2_open might race us. | ||
1229 | */ | ||
1230 | stream->vdev = vdev; | ||
1231 | video_set_drvdata(vdev, stream); | ||
1232 | |||
1233 | if (video_register_device(vdev, VFL_TYPE_GRABBER, -1) < 0) { | ||
1234 | stream->vdev = NULL; | ||
1235 | video_device_release(vdev); | ||
1236 | return -1; | ||
1176 | } | 1237 | } |
1238 | |||
1239 | return 0; | ||
1177 | } | 1240 | } |
1178 | 1241 | ||
1179 | /* | 1242 | /* |
@@ -1419,7 +1482,7 @@ static int uvc_scan_chain(struct uvc_video_device *video) | |||
1419 | } | 1482 | } |
1420 | 1483 | ||
1421 | /* | 1484 | /* |
1422 | * Register the video devices. | 1485 | * Scan the device for video chains and register video devices. |
1423 | * | 1486 | * |
1424 | * The driver currently supports a single video device per control interface | 1487 | * The driver currently supports a single video device per control interface |
1425 | * only. The terminal and units must match the following structure: | 1488 | * only. The terminal and units must match the following structure: |
@@ -1432,15 +1495,14 @@ static int uvc_scan_chain(struct uvc_video_device *video) | |||
1432 | * Extension Units connected to the main chain as single-unit branches are | 1495 | * Extension Units connected to the main chain as single-unit branches are |
1433 | * also supported. | 1496 | * also supported. |
1434 | */ | 1497 | */ |
1435 | static int uvc_register_video(struct uvc_device *dev) | 1498 | static int uvc_scan_device(struct uvc_device *dev) |
1436 | { | 1499 | { |
1437 | struct video_device *vdev; | ||
1438 | struct uvc_entity *term; | 1500 | struct uvc_entity *term; |
1439 | int found = 0, ret; | 1501 | int found = 0; |
1440 | 1502 | ||
1441 | /* Check if the control interface matches the structure we expect. */ | 1503 | /* Check if the control interface matches the structure we expect. */ |
1442 | list_for_each_entry(term, &dev->entities, list) { | 1504 | list_for_each_entry(term, &dev->entities, list) { |
1443 | struct uvc_streaming *streaming; | 1505 | struct uvc_streaming *stream; |
1444 | 1506 | ||
1445 | if (!UVC_ENTITY_IS_TERM(term) || !UVC_ENTITY_IS_OTERM(term)) | 1507 | if (!UVC_ENTITY_IS_TERM(term) || !UVC_ENTITY_IS_OTERM(term)) |
1446 | continue; | 1508 | continue; |
@@ -1454,17 +1516,14 @@ static int uvc_register_video(struct uvc_device *dev) | |||
1454 | if (uvc_scan_chain(&dev->video) < 0) | 1516 | if (uvc_scan_chain(&dev->video) < 0) |
1455 | continue; | 1517 | continue; |
1456 | 1518 | ||
1457 | list_for_each_entry(streaming, &dev->streaming, list) { | 1519 | list_for_each_entry(stream, &dev->streams, list) { |
1458 | if (streaming->header.bTerminalLink == | 1520 | if (stream->header.bTerminalLink == |
1459 | dev->video.sterm->id) { | 1521 | dev->video.sterm->id) { |
1460 | dev->video.streaming = streaming; | 1522 | uvc_register_video(dev, stream); |
1461 | found = 1; | 1523 | found = 1; |
1462 | break; | 1524 | break; |
1463 | } | 1525 | } |
1464 | } | 1526 | } |
1465 | |||
1466 | if (found) | ||
1467 | break; | ||
1468 | } | 1527 | } |
1469 | 1528 | ||
1470 | if (!found) { | 1529 | if (!found) { |
@@ -1472,55 +1531,6 @@ static int uvc_register_video(struct uvc_device *dev) | |||
1472 | return -1; | 1531 | return -1; |
1473 | } | 1532 | } |
1474 | 1533 | ||
1475 | if (uvc_trace_param & UVC_TRACE_PROBE) { | ||
1476 | uvc_printk(KERN_INFO, "Found a valid video chain ("); | ||
1477 | list_for_each_entry(term, &dev->video.iterms, chain) { | ||
1478 | printk("%d", term->id); | ||
1479 | if (term->chain.next != &dev->video.iterms) | ||
1480 | printk(","); | ||
1481 | } | ||
1482 | printk(" -> %d).\n", dev->video.oterm->id); | ||
1483 | } | ||
1484 | |||
1485 | /* Initialize the video buffers queue. */ | ||
1486 | uvc_queue_init(&dev->video.queue, dev->video.streaming->type); | ||
1487 | |||
1488 | /* Initialize the streaming interface with default streaming | ||
1489 | * parameters. | ||
1490 | */ | ||
1491 | if ((ret = uvc_video_init(&dev->video)) < 0) { | ||
1492 | uvc_printk(KERN_ERR, "Failed to initialize the device " | ||
1493 | "(%d).\n", ret); | ||
1494 | return ret; | ||
1495 | } | ||
1496 | |||
1497 | /* Register the device with V4L. */ | ||
1498 | vdev = video_device_alloc(); | ||
1499 | if (vdev == NULL) | ||
1500 | return -1; | ||
1501 | |||
1502 | /* We already hold a reference to dev->udev. The video device will be | ||
1503 | * unregistered before the reference is released, so we don't need to | ||
1504 | * get another one. | ||
1505 | */ | ||
1506 | vdev->parent = &dev->intf->dev; | ||
1507 | vdev->minor = -1; | ||
1508 | vdev->fops = &uvc_fops; | ||
1509 | vdev->release = video_device_release; | ||
1510 | strlcpy(vdev->name, dev->name, sizeof vdev->name); | ||
1511 | |||
1512 | /* Set the driver data before calling video_register_device, otherwise | ||
1513 | * uvc_v4l2_open might race us. | ||
1514 | */ | ||
1515 | dev->video.vdev = vdev; | ||
1516 | video_set_drvdata(vdev, &dev->video); | ||
1517 | |||
1518 | if (video_register_device(vdev, VFL_TYPE_GRABBER, -1) < 0) { | ||
1519 | dev->video.vdev = NULL; | ||
1520 | video_device_release(vdev); | ||
1521 | return -1; | ||
1522 | } | ||
1523 | |||
1524 | return 0; | 1534 | return 0; |
1525 | } | 1535 | } |
1526 | 1536 | ||
@@ -1559,7 +1569,7 @@ void uvc_delete(struct kref *kref) | |||
1559 | kfree(entity); | 1569 | kfree(entity); |
1560 | } | 1570 | } |
1561 | 1571 | ||
1562 | list_for_each_safe(p, n, &dev->streaming) { | 1572 | list_for_each_safe(p, n, &dev->streams) { |
1563 | struct uvc_streaming *streaming; | 1573 | struct uvc_streaming *streaming; |
1564 | streaming = list_entry(p, struct uvc_streaming, list); | 1574 | streaming = list_entry(p, struct uvc_streaming, list); |
1565 | usb_driver_release_interface(&uvc_driver.driver, | 1575 | usb_driver_release_interface(&uvc_driver.driver, |
@@ -1593,7 +1603,7 @@ static int uvc_probe(struct usb_interface *intf, | |||
1593 | return -ENOMEM; | 1603 | return -ENOMEM; |
1594 | 1604 | ||
1595 | INIT_LIST_HEAD(&dev->entities); | 1605 | INIT_LIST_HEAD(&dev->entities); |
1596 | INIT_LIST_HEAD(&dev->streaming); | 1606 | INIT_LIST_HEAD(&dev->streams); |
1597 | kref_init(&dev->kref); | 1607 | kref_init(&dev->kref); |
1598 | atomic_set(&dev->users, 0); | 1608 | atomic_set(&dev->users, 0); |
1599 | 1609 | ||
@@ -1634,8 +1644,8 @@ static int uvc_probe(struct usb_interface *intf, | |||
1634 | if (uvc_ctrl_init_device(dev) < 0) | 1644 | if (uvc_ctrl_init_device(dev) < 0) |
1635 | goto error; | 1645 | goto error; |
1636 | 1646 | ||
1637 | /* Register the video devices. */ | 1647 | /* Scan the device for video chains and register video devices. */ |
1638 | if (uvc_register_video(dev) < 0) | 1648 | if (uvc_scan_device(dev) < 0) |
1639 | goto error; | 1649 | goto error; |
1640 | 1650 | ||
1641 | /* Save our data pointer in the interface data. */ | 1651 | /* Save our data pointer in the interface data. */ |
@@ -1689,6 +1699,7 @@ static void uvc_disconnect(struct usb_interface *intf) | |||
1689 | static int uvc_suspend(struct usb_interface *intf, pm_message_t message) | 1699 | static int uvc_suspend(struct usb_interface *intf, pm_message_t message) |
1690 | { | 1700 | { |
1691 | struct uvc_device *dev = usb_get_intfdata(intf); | 1701 | struct uvc_device *dev = usb_get_intfdata(intf); |
1702 | struct uvc_streaming *stream; | ||
1692 | 1703 | ||
1693 | uvc_trace(UVC_TRACE_SUSPEND, "Suspending interface %u\n", | 1704 | uvc_trace(UVC_TRACE_SUSPEND, "Suspending interface %u\n", |
1694 | intf->cur_altsetting->desc.bInterfaceNumber); | 1705 | intf->cur_altsetting->desc.bInterfaceNumber); |
@@ -1698,18 +1709,20 @@ static int uvc_suspend(struct usb_interface *intf, pm_message_t message) | |||
1698 | UVC_SC_VIDEOCONTROL) | 1709 | UVC_SC_VIDEOCONTROL) |
1699 | return uvc_status_suspend(dev); | 1710 | return uvc_status_suspend(dev); |
1700 | 1711 | ||
1701 | if (dev->video.streaming->intf != intf) { | 1712 | list_for_each_entry(stream, &dev->streams, list) { |
1702 | uvc_trace(UVC_TRACE_SUSPEND, "Suspend: video streaming USB " | 1713 | if (stream->intf == intf) |
1703 | "interface mismatch.\n"); | 1714 | return uvc_video_suspend(stream); |
1704 | return -EINVAL; | ||
1705 | } | 1715 | } |
1706 | 1716 | ||
1707 | return uvc_video_suspend(&dev->video); | 1717 | uvc_trace(UVC_TRACE_SUSPEND, "Suspend: video streaming USB interface " |
1718 | "mismatch.\n"); | ||
1719 | return -EINVAL; | ||
1708 | } | 1720 | } |
1709 | 1721 | ||
1710 | static int __uvc_resume(struct usb_interface *intf, int reset) | 1722 | static int __uvc_resume(struct usb_interface *intf, int reset) |
1711 | { | 1723 | { |
1712 | struct uvc_device *dev = usb_get_intfdata(intf); | 1724 | struct uvc_device *dev = usb_get_intfdata(intf); |
1725 | struct uvc_streaming *stream; | ||
1713 | 1726 | ||
1714 | uvc_trace(UVC_TRACE_SUSPEND, "Resuming interface %u\n", | 1727 | uvc_trace(UVC_TRACE_SUSPEND, "Resuming interface %u\n", |
1715 | intf->cur_altsetting->desc.bInterfaceNumber); | 1728 | intf->cur_altsetting->desc.bInterfaceNumber); |
@@ -1726,13 +1739,14 @@ static int __uvc_resume(struct usb_interface *intf, int reset) | |||
1726 | return uvc_status_resume(dev); | 1739 | return uvc_status_resume(dev); |
1727 | } | 1740 | } |
1728 | 1741 | ||
1729 | if (dev->video.streaming->intf != intf) { | 1742 | list_for_each_entry(stream, &dev->streams, list) { |
1730 | uvc_trace(UVC_TRACE_SUSPEND, "Resume: video streaming USB " | 1743 | if (stream->intf == intf) |
1731 | "interface mismatch.\n"); | 1744 | return uvc_video_resume(stream); |
1732 | return -EINVAL; | ||
1733 | } | 1745 | } |
1734 | 1746 | ||
1735 | return uvc_video_resume(&dev->video); | 1747 | uvc_trace(UVC_TRACE_SUSPEND, "Resume: video streaming USB interface " |
1748 | "mismatch.\n"); | ||
1749 | return -EINVAL; | ||
1736 | } | 1750 | } |
1737 | 1751 | ||
1738 | static int uvc_resume(struct usb_interface *intf) | 1752 | static int uvc_resume(struct usb_interface *intf) |
diff --git a/drivers/media/video/uvc/uvc_isight.c b/drivers/media/video/uvc/uvc_isight.c index 436f462685a0..a9285b570dbe 100644 --- a/drivers/media/video/uvc/uvc_isight.c +++ b/drivers/media/video/uvc/uvc_isight.c | |||
@@ -99,7 +99,7 @@ static int isight_decode(struct uvc_video_queue *queue, struct uvc_buffer *buf, | |||
99 | return 0; | 99 | return 0; |
100 | } | 100 | } |
101 | 101 | ||
102 | void uvc_video_decode_isight(struct urb *urb, struct uvc_video_device *video, | 102 | void uvc_video_decode_isight(struct urb *urb, struct uvc_streaming *stream, |
103 | struct uvc_buffer *buf) | 103 | struct uvc_buffer *buf) |
104 | { | 104 | { |
105 | int ret, i; | 105 | int ret, i; |
@@ -120,7 +120,7 @@ void uvc_video_decode_isight(struct urb *urb, struct uvc_video_device *video, | |||
120 | * processes the data of the first payload of the new frame. | 120 | * processes the data of the first payload of the new frame. |
121 | */ | 121 | */ |
122 | do { | 122 | do { |
123 | ret = isight_decode(&video->queue, buf, | 123 | ret = isight_decode(&stream->queue, buf, |
124 | urb->transfer_buffer + | 124 | urb->transfer_buffer + |
125 | urb->iso_frame_desc[i].offset, | 125 | urb->iso_frame_desc[i].offset, |
126 | urb->iso_frame_desc[i].actual_length); | 126 | urb->iso_frame_desc[i].actual_length); |
@@ -130,7 +130,8 @@ void uvc_video_decode_isight(struct urb *urb, struct uvc_video_device *video, | |||
130 | 130 | ||
131 | if (buf->state == UVC_BUF_STATE_DONE || | 131 | if (buf->state == UVC_BUF_STATE_DONE || |
132 | buf->state == UVC_BUF_STATE_ERROR) | 132 | buf->state == UVC_BUF_STATE_ERROR) |
133 | buf = uvc_queue_next_buffer(&video->queue, buf); | 133 | buf = uvc_queue_next_buffer(&stream->queue, |
134 | buf); | ||
134 | } while (ret == -EAGAIN); | 135 | } while (ret == -EAGAIN); |
135 | } | 136 | } |
136 | } | 137 | } |
diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c index 87cb9cc75af2..7e847bbaf2a4 100644 --- a/drivers/media/video/uvc/uvc_v4l2.c +++ b/drivers/media/video/uvc/uvc_v4l2.c | |||
@@ -103,7 +103,7 @@ static __u32 uvc_try_frame_interval(struct uvc_frame *frame, __u32 interval) | |||
103 | return interval; | 103 | return interval; |
104 | } | 104 | } |
105 | 105 | ||
106 | static int uvc_v4l2_try_format(struct uvc_video_device *video, | 106 | static int uvc_v4l2_try_format(struct uvc_streaming *stream, |
107 | struct v4l2_format *fmt, struct uvc_streaming_control *probe, | 107 | struct v4l2_format *fmt, struct uvc_streaming_control *probe, |
108 | struct uvc_format **uvc_format, struct uvc_frame **uvc_frame) | 108 | struct uvc_format **uvc_format, struct uvc_frame **uvc_frame) |
109 | { | 109 | { |
@@ -116,7 +116,7 @@ static int uvc_v4l2_try_format(struct uvc_video_device *video, | |||
116 | int ret = 0; | 116 | int ret = 0; |
117 | __u8 *fcc; | 117 | __u8 *fcc; |
118 | 118 | ||
119 | if (fmt->type != video->streaming->type) | 119 | if (fmt->type != stream->type) |
120 | return -EINVAL; | 120 | return -EINVAL; |
121 | 121 | ||
122 | fcc = (__u8 *)&fmt->fmt.pix.pixelformat; | 122 | fcc = (__u8 *)&fmt->fmt.pix.pixelformat; |
@@ -126,8 +126,8 @@ static int uvc_v4l2_try_format(struct uvc_video_device *video, | |||
126 | fmt->fmt.pix.width, fmt->fmt.pix.height); | 126 | fmt->fmt.pix.width, fmt->fmt.pix.height); |
127 | 127 | ||
128 | /* Check if the hardware supports the requested format. */ | 128 | /* Check if the hardware supports the requested format. */ |
129 | for (i = 0; i < video->streaming->nformats; ++i) { | 129 | for (i = 0; i < stream->nformats; ++i) { |
130 | format = &video->streaming->format[i]; | 130 | format = &stream->format[i]; |
131 | if (format->fcc == fmt->fmt.pix.pixelformat) | 131 | if (format->fcc == fmt->fmt.pix.pixelformat) |
132 | break; | 132 | break; |
133 | } | 133 | } |
@@ -191,12 +191,13 @@ static int uvc_v4l2_try_format(struct uvc_video_device *video, | |||
191 | * developers test their webcams with the Linux driver as well as with | 191 | * developers test their webcams with the Linux driver as well as with |
192 | * the Windows driver). | 192 | * the Windows driver). |
193 | */ | 193 | */ |
194 | if (video->dev->quirks & UVC_QUIRK_PROBE_EXTRAFIELDS) | 194 | if (stream->dev->quirks & UVC_QUIRK_PROBE_EXTRAFIELDS) |
195 | probe->dwMaxVideoFrameSize = | 195 | probe->dwMaxVideoFrameSize = |
196 | video->streaming->ctrl.dwMaxVideoFrameSize; | 196 | stream->ctrl.dwMaxVideoFrameSize; |
197 | 197 | ||
198 | /* Probe the device. */ | 198 | /* Probe the device. */ |
199 | if ((ret = uvc_probe_video(video, probe)) < 0) | 199 | ret = uvc_probe_video(stream, probe); |
200 | if (ret < 0) | ||
200 | goto done; | 201 | goto done; |
201 | 202 | ||
202 | fmt->fmt.pix.width = frame->wWidth; | 203 | fmt->fmt.pix.width = frame->wWidth; |
@@ -216,13 +217,13 @@ done: | |||
216 | return ret; | 217 | return ret; |
217 | } | 218 | } |
218 | 219 | ||
219 | static int uvc_v4l2_get_format(struct uvc_video_device *video, | 220 | static int uvc_v4l2_get_format(struct uvc_streaming *stream, |
220 | struct v4l2_format *fmt) | 221 | struct v4l2_format *fmt) |
221 | { | 222 | { |
222 | struct uvc_format *format = video->streaming->cur_format; | 223 | struct uvc_format *format = stream->cur_format; |
223 | struct uvc_frame *frame = video->streaming->cur_frame; | 224 | struct uvc_frame *frame = stream->cur_frame; |
224 | 225 | ||
225 | if (fmt->type != video->streaming->type) | 226 | if (fmt->type != stream->type) |
226 | return -EINVAL; | 227 | return -EINVAL; |
227 | 228 | ||
228 | if (format == NULL || frame == NULL) | 229 | if (format == NULL || frame == NULL) |
@@ -233,14 +234,14 @@ static int uvc_v4l2_get_format(struct uvc_video_device *video, | |||
233 | fmt->fmt.pix.height = frame->wHeight; | 234 | fmt->fmt.pix.height = frame->wHeight; |
234 | fmt->fmt.pix.field = V4L2_FIELD_NONE; | 235 | fmt->fmt.pix.field = V4L2_FIELD_NONE; |
235 | fmt->fmt.pix.bytesperline = format->bpp * frame->wWidth / 8; | 236 | fmt->fmt.pix.bytesperline = format->bpp * frame->wWidth / 8; |
236 | fmt->fmt.pix.sizeimage = video->streaming->ctrl.dwMaxVideoFrameSize; | 237 | fmt->fmt.pix.sizeimage = stream->ctrl.dwMaxVideoFrameSize; |
237 | fmt->fmt.pix.colorspace = format->colorspace; | 238 | fmt->fmt.pix.colorspace = format->colorspace; |
238 | fmt->fmt.pix.priv = 0; | 239 | fmt->fmt.pix.priv = 0; |
239 | 240 | ||
240 | return 0; | 241 | return 0; |
241 | } | 242 | } |
242 | 243 | ||
243 | static int uvc_v4l2_set_format(struct uvc_video_device *video, | 244 | static int uvc_v4l2_set_format(struct uvc_streaming *stream, |
244 | struct v4l2_format *fmt) | 245 | struct v4l2_format *fmt) |
245 | { | 246 | { |
246 | struct uvc_streaming_control probe; | 247 | struct uvc_streaming_control probe; |
@@ -248,39 +249,39 @@ static int uvc_v4l2_set_format(struct uvc_video_device *video, | |||
248 | struct uvc_frame *frame; | 249 | struct uvc_frame *frame; |
249 | int ret; | 250 | int ret; |
250 | 251 | ||
251 | if (fmt->type != video->streaming->type) | 252 | if (fmt->type != stream->type) |
252 | return -EINVAL; | 253 | return -EINVAL; |
253 | 254 | ||
254 | if (uvc_queue_allocated(&video->queue)) | 255 | if (uvc_queue_allocated(&stream->queue)) |
255 | return -EBUSY; | 256 | return -EBUSY; |
256 | 257 | ||
257 | ret = uvc_v4l2_try_format(video, fmt, &probe, &format, &frame); | 258 | ret = uvc_v4l2_try_format(stream, fmt, &probe, &format, &frame); |
258 | if (ret < 0) | 259 | if (ret < 0) |
259 | return ret; | 260 | return ret; |
260 | 261 | ||
261 | memcpy(&video->streaming->ctrl, &probe, sizeof probe); | 262 | memcpy(&stream->ctrl, &probe, sizeof probe); |
262 | video->streaming->cur_format = format; | 263 | stream->cur_format = format; |
263 | video->streaming->cur_frame = frame; | 264 | stream->cur_frame = frame; |
264 | 265 | ||
265 | return 0; | 266 | return 0; |
266 | } | 267 | } |
267 | 268 | ||
268 | static int uvc_v4l2_get_streamparm(struct uvc_video_device *video, | 269 | static int uvc_v4l2_get_streamparm(struct uvc_streaming *stream, |
269 | struct v4l2_streamparm *parm) | 270 | struct v4l2_streamparm *parm) |
270 | { | 271 | { |
271 | uint32_t numerator, denominator; | 272 | uint32_t numerator, denominator; |
272 | 273 | ||
273 | if (parm->type != video->streaming->type) | 274 | if (parm->type != stream->type) |
274 | return -EINVAL; | 275 | return -EINVAL; |
275 | 276 | ||
276 | numerator = video->streaming->ctrl.dwFrameInterval; | 277 | numerator = stream->ctrl.dwFrameInterval; |
277 | denominator = 10000000; | 278 | denominator = 10000000; |
278 | uvc_simplify_fraction(&numerator, &denominator, 8, 333); | 279 | uvc_simplify_fraction(&numerator, &denominator, 8, 333); |
279 | 280 | ||
280 | memset(parm, 0, sizeof *parm); | 281 | memset(parm, 0, sizeof *parm); |
281 | parm->type = video->streaming->type; | 282 | parm->type = stream->type; |
282 | 283 | ||
283 | if (video->streaming->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { | 284 | if (stream->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { |
284 | parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME; | 285 | parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME; |
285 | parm->parm.capture.capturemode = 0; | 286 | parm->parm.capture.capturemode = 0; |
286 | parm->parm.capture.timeperframe.numerator = numerator; | 287 | parm->parm.capture.timeperframe.numerator = numerator; |
@@ -297,19 +298,19 @@ static int uvc_v4l2_get_streamparm(struct uvc_video_device *video, | |||
297 | return 0; | 298 | return 0; |
298 | } | 299 | } |
299 | 300 | ||
300 | static int uvc_v4l2_set_streamparm(struct uvc_video_device *video, | 301 | static int uvc_v4l2_set_streamparm(struct uvc_streaming *stream, |
301 | struct v4l2_streamparm *parm) | 302 | struct v4l2_streamparm *parm) |
302 | { | 303 | { |
303 | struct uvc_frame *frame = video->streaming->cur_frame; | 304 | struct uvc_frame *frame = stream->cur_frame; |
304 | struct uvc_streaming_control probe; | 305 | struct uvc_streaming_control probe; |
305 | struct v4l2_fract timeperframe; | 306 | struct v4l2_fract timeperframe; |
306 | uint32_t interval; | 307 | uint32_t interval; |
307 | int ret; | 308 | int ret; |
308 | 309 | ||
309 | if (parm->type != video->streaming->type) | 310 | if (parm->type != stream->type) |
310 | return -EINVAL; | 311 | return -EINVAL; |
311 | 312 | ||
312 | if (uvc_queue_streaming(&video->queue)) | 313 | if (uvc_queue_streaming(&stream->queue)) |
313 | return -EBUSY; | 314 | return -EBUSY; |
314 | 315 | ||
315 | if (parm->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) | 316 | if (parm->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) |
@@ -317,7 +318,7 @@ static int uvc_v4l2_set_streamparm(struct uvc_video_device *video, | |||
317 | else | 318 | else |
318 | timeperframe = parm->parm.output.timeperframe; | 319 | timeperframe = parm->parm.output.timeperframe; |
319 | 320 | ||
320 | memcpy(&probe, &video->streaming->ctrl, sizeof probe); | 321 | memcpy(&probe, &stream->ctrl, sizeof probe); |
321 | interval = uvc_fraction_to_interval(timeperframe.numerator, | 322 | interval = uvc_fraction_to_interval(timeperframe.numerator, |
322 | timeperframe.denominator); | 323 | timeperframe.denominator); |
323 | 324 | ||
@@ -326,10 +327,11 @@ static int uvc_v4l2_set_streamparm(struct uvc_video_device *video, | |||
326 | probe.dwFrameInterval = uvc_try_frame_interval(frame, interval); | 327 | probe.dwFrameInterval = uvc_try_frame_interval(frame, interval); |
327 | 328 | ||
328 | /* Probe the device with the new settings. */ | 329 | /* Probe the device with the new settings. */ |
329 | if ((ret = uvc_probe_video(video, &probe)) < 0) | 330 | ret = uvc_probe_video(stream, &probe); |
331 | if (ret < 0) | ||
330 | return ret; | 332 | return ret; |
331 | 333 | ||
332 | memcpy(&video->streaming->ctrl, &probe, sizeof probe); | 334 | memcpy(&stream->ctrl, &probe, sizeof probe); |
333 | 335 | ||
334 | /* Return the actual frame period. */ | 336 | /* Return the actual frame period. */ |
335 | timeperframe.numerator = probe.dwFrameInterval; | 337 | timeperframe.numerator = probe.dwFrameInterval; |
@@ -382,8 +384,8 @@ static int uvc_acquire_privileges(struct uvc_fh *handle) | |||
382 | 384 | ||
383 | /* Check if the device already has a privileged handle. */ | 385 | /* Check if the device already has a privileged handle. */ |
384 | mutex_lock(&uvc_driver.open_mutex); | 386 | mutex_lock(&uvc_driver.open_mutex); |
385 | if (atomic_inc_return(&handle->device->active) != 1) { | 387 | if (atomic_inc_return(&handle->stream->active) != 1) { |
386 | atomic_dec(&handle->device->active); | 388 | atomic_dec(&handle->stream->active); |
387 | ret = -EBUSY; | 389 | ret = -EBUSY; |
388 | goto done; | 390 | goto done; |
389 | } | 391 | } |
@@ -398,7 +400,7 @@ done: | |||
398 | static void uvc_dismiss_privileges(struct uvc_fh *handle) | 400 | static void uvc_dismiss_privileges(struct uvc_fh *handle) |
399 | { | 401 | { |
400 | if (handle->state == UVC_HANDLE_ACTIVE) | 402 | if (handle->state == UVC_HANDLE_ACTIVE) |
401 | atomic_dec(&handle->device->active); | 403 | atomic_dec(&handle->stream->active); |
402 | 404 | ||
403 | handle->state = UVC_HANDLE_PASSIVE; | 405 | handle->state = UVC_HANDLE_PASSIVE; |
404 | } | 406 | } |
@@ -414,45 +416,47 @@ static int uvc_has_privileges(struct uvc_fh *handle) | |||
414 | 416 | ||
415 | static int uvc_v4l2_open(struct file *file) | 417 | static int uvc_v4l2_open(struct file *file) |
416 | { | 418 | { |
417 | struct uvc_video_device *video; | 419 | struct uvc_streaming *stream; |
418 | struct uvc_fh *handle; | 420 | struct uvc_fh *handle; |
419 | int ret = 0; | 421 | int ret = 0; |
420 | 422 | ||
421 | uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_open\n"); | 423 | uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_open\n"); |
422 | mutex_lock(&uvc_driver.open_mutex); | 424 | mutex_lock(&uvc_driver.open_mutex); |
423 | video = video_drvdata(file); | 425 | stream = video_drvdata(file); |
424 | 426 | ||
425 | if (video->dev->state & UVC_DEV_DISCONNECTED) { | 427 | if (stream->dev->state & UVC_DEV_DISCONNECTED) { |
426 | ret = -ENODEV; | 428 | ret = -ENODEV; |
427 | goto done; | 429 | goto done; |
428 | } | 430 | } |
429 | 431 | ||
430 | ret = usb_autopm_get_interface(video->dev->intf); | 432 | ret = usb_autopm_get_interface(stream->dev->intf); |
431 | if (ret < 0) | 433 | if (ret < 0) |
432 | goto done; | 434 | goto done; |
433 | 435 | ||
434 | /* Create the device handle. */ | 436 | /* Create the device handle. */ |
435 | handle = kzalloc(sizeof *handle, GFP_KERNEL); | 437 | handle = kzalloc(sizeof *handle, GFP_KERNEL); |
436 | if (handle == NULL) { | 438 | if (handle == NULL) { |
437 | usb_autopm_put_interface(video->dev->intf); | 439 | usb_autopm_put_interface(stream->dev->intf); |
438 | ret = -ENOMEM; | 440 | ret = -ENOMEM; |
439 | goto done; | 441 | goto done; |
440 | } | 442 | } |
441 | 443 | ||
442 | if (atomic_inc_return(&video->dev->users) == 1) { | 444 | if (atomic_inc_return(&stream->dev->users) == 1) { |
443 | if ((ret = uvc_status_start(video->dev)) < 0) { | 445 | ret = uvc_status_start(stream->dev); |
444 | usb_autopm_put_interface(video->dev->intf); | 446 | if (ret < 0) { |
445 | atomic_dec(&video->dev->users); | 447 | usb_autopm_put_interface(stream->dev->intf); |
448 | atomic_dec(&stream->dev->users); | ||
446 | kfree(handle); | 449 | kfree(handle); |
447 | goto done; | 450 | goto done; |
448 | } | 451 | } |
449 | } | 452 | } |
450 | 453 | ||
451 | handle->device = video; | 454 | handle->video = &stream->dev->video; |
455 | handle->stream = stream; | ||
452 | handle->state = UVC_HANDLE_PASSIVE; | 456 | handle->state = UVC_HANDLE_PASSIVE; |
453 | file->private_data = handle; | 457 | file->private_data = handle; |
454 | 458 | ||
455 | kref_get(&video->dev->kref); | 459 | kref_get(&stream->dev->kref); |
456 | 460 | ||
457 | done: | 461 | done: |
458 | mutex_unlock(&uvc_driver.open_mutex); | 462 | mutex_unlock(&uvc_driver.open_mutex); |
@@ -461,20 +465,20 @@ done: | |||
461 | 465 | ||
462 | static int uvc_v4l2_release(struct file *file) | 466 | static int uvc_v4l2_release(struct file *file) |
463 | { | 467 | { |
464 | struct uvc_video_device *video = video_drvdata(file); | ||
465 | struct uvc_fh *handle = (struct uvc_fh *)file->private_data; | 468 | struct uvc_fh *handle = (struct uvc_fh *)file->private_data; |
469 | struct uvc_streaming *stream = handle->stream; | ||
466 | 470 | ||
467 | uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_release\n"); | 471 | uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_release\n"); |
468 | 472 | ||
469 | /* Only free resources if this is a privileged handle. */ | 473 | /* Only free resources if this is a privileged handle. */ |
470 | if (uvc_has_privileges(handle)) { | 474 | if (uvc_has_privileges(handle)) { |
471 | uvc_video_enable(video, 0); | 475 | uvc_video_enable(stream, 0); |
472 | 476 | ||
473 | mutex_lock(&video->queue.mutex); | 477 | mutex_lock(&stream->queue.mutex); |
474 | if (uvc_free_buffers(&video->queue) < 0) | 478 | if (uvc_free_buffers(&stream->queue) < 0) |
475 | uvc_printk(KERN_ERR, "uvc_v4l2_release: Unable to " | 479 | uvc_printk(KERN_ERR, "uvc_v4l2_release: Unable to " |
476 | "free buffers.\n"); | 480 | "free buffers.\n"); |
477 | mutex_unlock(&video->queue.mutex); | 481 | mutex_unlock(&stream->queue.mutex); |
478 | } | 482 | } |
479 | 483 | ||
480 | /* Release the file handle. */ | 484 | /* Release the file handle. */ |
@@ -482,19 +486,20 @@ static int uvc_v4l2_release(struct file *file) | |||
482 | kfree(handle); | 486 | kfree(handle); |
483 | file->private_data = NULL; | 487 | file->private_data = NULL; |
484 | 488 | ||
485 | if (atomic_dec_return(&video->dev->users) == 0) | 489 | if (atomic_dec_return(&stream->dev->users) == 0) |
486 | uvc_status_stop(video->dev); | 490 | uvc_status_stop(stream->dev); |
487 | 491 | ||
488 | usb_autopm_put_interface(video->dev->intf); | 492 | usb_autopm_put_interface(stream->dev->intf); |
489 | kref_put(&video->dev->kref, uvc_delete); | 493 | kref_put(&stream->dev->kref, uvc_delete); |
490 | return 0; | 494 | return 0; |
491 | } | 495 | } |
492 | 496 | ||
493 | static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | 497 | static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) |
494 | { | 498 | { |
495 | struct video_device *vdev = video_devdata(file); | 499 | struct video_device *vdev = video_devdata(file); |
496 | struct uvc_video_device *video = video_get_drvdata(vdev); | ||
497 | struct uvc_fh *handle = (struct uvc_fh *)file->private_data; | 500 | struct uvc_fh *handle = (struct uvc_fh *)file->private_data; |
501 | struct uvc_video_device *video = handle->video; | ||
502 | struct uvc_streaming *stream = handle->stream; | ||
498 | long ret = 0; | 503 | long ret = 0; |
499 | 504 | ||
500 | switch (cmd) { | 505 | switch (cmd) { |
@@ -506,10 +511,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
506 | memset(cap, 0, sizeof *cap); | 511 | memset(cap, 0, sizeof *cap); |
507 | strlcpy(cap->driver, "uvcvideo", sizeof cap->driver); | 512 | strlcpy(cap->driver, "uvcvideo", sizeof cap->driver); |
508 | strlcpy(cap->card, vdev->name, sizeof cap->card); | 513 | strlcpy(cap->card, vdev->name, sizeof cap->card); |
509 | usb_make_path(video->dev->udev, | 514 | usb_make_path(stream->dev->udev, |
510 | cap->bus_info, sizeof(cap->bus_info)); | 515 | cap->bus_info, sizeof(cap->bus_info)); |
511 | cap->version = DRIVER_VERSION_NUMBER; | 516 | cap->version = DRIVER_VERSION_NUMBER; |
512 | if (video->streaming->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) | 517 | if (stream->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) |
513 | cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | 518 | cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
514 | | V4L2_CAP_STREAMING; | 519 | | V4L2_CAP_STREAMING; |
515 | else | 520 | else |
@@ -703,15 +708,15 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
703 | enum v4l2_buf_type type = fmt->type; | 708 | enum v4l2_buf_type type = fmt->type; |
704 | __u32 index = fmt->index; | 709 | __u32 index = fmt->index; |
705 | 710 | ||
706 | if (fmt->type != video->streaming->type || | 711 | if (fmt->type != stream->type || |
707 | fmt->index >= video->streaming->nformats) | 712 | fmt->index >= stream->nformats) |
708 | return -EINVAL; | 713 | return -EINVAL; |
709 | 714 | ||
710 | memset(fmt, 0, sizeof(*fmt)); | 715 | memset(fmt, 0, sizeof(*fmt)); |
711 | fmt->index = index; | 716 | fmt->index = index; |
712 | fmt->type = type; | 717 | fmt->type = type; |
713 | 718 | ||
714 | format = &video->streaming->format[fmt->index]; | 719 | format = &stream->format[fmt->index]; |
715 | fmt->flags = 0; | 720 | fmt->flags = 0; |
716 | if (format->flags & UVC_FMT_FLAG_COMPRESSED) | 721 | if (format->flags & UVC_FMT_FLAG_COMPRESSED) |
717 | fmt->flags |= V4L2_FMT_FLAG_COMPRESSED; | 722 | fmt->flags |= V4L2_FMT_FLAG_COMPRESSED; |
@@ -729,17 +734,17 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
729 | if ((ret = uvc_acquire_privileges(handle)) < 0) | 734 | if ((ret = uvc_acquire_privileges(handle)) < 0) |
730 | return ret; | 735 | return ret; |
731 | 736 | ||
732 | return uvc_v4l2_try_format(video, arg, &probe, NULL, NULL); | 737 | return uvc_v4l2_try_format(stream, arg, &probe, NULL, NULL); |
733 | } | 738 | } |
734 | 739 | ||
735 | case VIDIOC_S_FMT: | 740 | case VIDIOC_S_FMT: |
736 | if ((ret = uvc_acquire_privileges(handle)) < 0) | 741 | if ((ret = uvc_acquire_privileges(handle)) < 0) |
737 | return ret; | 742 | return ret; |
738 | 743 | ||
739 | return uvc_v4l2_set_format(video, arg); | 744 | return uvc_v4l2_set_format(stream, arg); |
740 | 745 | ||
741 | case VIDIOC_G_FMT: | 746 | case VIDIOC_G_FMT: |
742 | return uvc_v4l2_get_format(video, arg); | 747 | return uvc_v4l2_get_format(stream, arg); |
743 | 748 | ||
744 | /* Frame size enumeration */ | 749 | /* Frame size enumeration */ |
745 | case VIDIOC_ENUM_FRAMESIZES: | 750 | case VIDIOC_ENUM_FRAMESIZES: |
@@ -750,10 +755,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
750 | int i; | 755 | int i; |
751 | 756 | ||
752 | /* Look for the given pixel format */ | 757 | /* Look for the given pixel format */ |
753 | for (i = 0; i < video->streaming->nformats; i++) { | 758 | for (i = 0; i < stream->nformats; i++) { |
754 | if (video->streaming->format[i].fcc == | 759 | if (stream->format[i].fcc == |
755 | fsize->pixel_format) { | 760 | fsize->pixel_format) { |
756 | format = &video->streaming->format[i]; | 761 | format = &stream->format[i]; |
757 | break; | 762 | break; |
758 | } | 763 | } |
759 | } | 764 | } |
@@ -779,10 +784,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
779 | int i; | 784 | int i; |
780 | 785 | ||
781 | /* Look for the given pixel format and frame size */ | 786 | /* Look for the given pixel format and frame size */ |
782 | for (i = 0; i < video->streaming->nformats; i++) { | 787 | for (i = 0; i < stream->nformats; i++) { |
783 | if (video->streaming->format[i].fcc == | 788 | if (stream->format[i].fcc == |
784 | fival->pixel_format) { | 789 | fival->pixel_format) { |
785 | format = &video->streaming->format[i]; | 790 | format = &stream->format[i]; |
786 | break; | 791 | break; |
787 | } | 792 | } |
788 | } | 793 | } |
@@ -832,21 +837,21 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
832 | 837 | ||
833 | /* Get & Set streaming parameters */ | 838 | /* Get & Set streaming parameters */ |
834 | case VIDIOC_G_PARM: | 839 | case VIDIOC_G_PARM: |
835 | return uvc_v4l2_get_streamparm(video, arg); | 840 | return uvc_v4l2_get_streamparm(stream, arg); |
836 | 841 | ||
837 | case VIDIOC_S_PARM: | 842 | case VIDIOC_S_PARM: |
838 | if ((ret = uvc_acquire_privileges(handle)) < 0) | 843 | if ((ret = uvc_acquire_privileges(handle)) < 0) |
839 | return ret; | 844 | return ret; |
840 | 845 | ||
841 | return uvc_v4l2_set_streamparm(video, arg); | 846 | return uvc_v4l2_set_streamparm(stream, arg); |
842 | 847 | ||
843 | /* Cropping and scaling */ | 848 | /* Cropping and scaling */ |
844 | case VIDIOC_CROPCAP: | 849 | case VIDIOC_CROPCAP: |
845 | { | 850 | { |
846 | struct v4l2_cropcap *ccap = arg; | 851 | struct v4l2_cropcap *ccap = arg; |
847 | struct uvc_frame *frame = video->streaming->cur_frame; | 852 | struct uvc_frame *frame = stream->cur_frame; |
848 | 853 | ||
849 | if (ccap->type != video->streaming->type) | 854 | if (ccap->type != stream->type) |
850 | return -EINVAL; | 855 | return -EINVAL; |
851 | 856 | ||
852 | ccap->bounds.left = 0; | 857 | ccap->bounds.left = 0; |
@@ -870,16 +875,16 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
870 | { | 875 | { |
871 | struct v4l2_requestbuffers *rb = arg; | 876 | struct v4l2_requestbuffers *rb = arg; |
872 | unsigned int bufsize = | 877 | unsigned int bufsize = |
873 | video->streaming->ctrl.dwMaxVideoFrameSize; | 878 | stream->ctrl.dwMaxVideoFrameSize; |
874 | 879 | ||
875 | if (rb->type != video->streaming->type || | 880 | if (rb->type != stream->type || |
876 | rb->memory != V4L2_MEMORY_MMAP) | 881 | rb->memory != V4L2_MEMORY_MMAP) |
877 | return -EINVAL; | 882 | return -EINVAL; |
878 | 883 | ||
879 | if ((ret = uvc_acquire_privileges(handle)) < 0) | 884 | if ((ret = uvc_acquire_privileges(handle)) < 0) |
880 | return ret; | 885 | return ret; |
881 | 886 | ||
882 | ret = uvc_alloc_buffers(&video->queue, rb->count, bufsize); | 887 | ret = uvc_alloc_buffers(&stream->queue, rb->count, bufsize); |
883 | if (ret < 0) | 888 | if (ret < 0) |
884 | return ret; | 889 | return ret; |
885 | 890 | ||
@@ -892,39 +897,40 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
892 | { | 897 | { |
893 | struct v4l2_buffer *buf = arg; | 898 | struct v4l2_buffer *buf = arg; |
894 | 899 | ||
895 | if (buf->type != video->streaming->type) | 900 | if (buf->type != stream->type) |
896 | return -EINVAL; | 901 | return -EINVAL; |
897 | 902 | ||
898 | if (!uvc_has_privileges(handle)) | 903 | if (!uvc_has_privileges(handle)) |
899 | return -EBUSY; | 904 | return -EBUSY; |
900 | 905 | ||
901 | return uvc_query_buffer(&video->queue, buf); | 906 | return uvc_query_buffer(&stream->queue, buf); |
902 | } | 907 | } |
903 | 908 | ||
904 | case VIDIOC_QBUF: | 909 | case VIDIOC_QBUF: |
905 | if (!uvc_has_privileges(handle)) | 910 | if (!uvc_has_privileges(handle)) |
906 | return -EBUSY; | 911 | return -EBUSY; |
907 | 912 | ||
908 | return uvc_queue_buffer(&video->queue, arg); | 913 | return uvc_queue_buffer(&stream->queue, arg); |
909 | 914 | ||
910 | case VIDIOC_DQBUF: | 915 | case VIDIOC_DQBUF: |
911 | if (!uvc_has_privileges(handle)) | 916 | if (!uvc_has_privileges(handle)) |
912 | return -EBUSY; | 917 | return -EBUSY; |
913 | 918 | ||
914 | return uvc_dequeue_buffer(&video->queue, arg, | 919 | return uvc_dequeue_buffer(&stream->queue, arg, |
915 | file->f_flags & O_NONBLOCK); | 920 | file->f_flags & O_NONBLOCK); |
916 | 921 | ||
917 | case VIDIOC_STREAMON: | 922 | case VIDIOC_STREAMON: |
918 | { | 923 | { |
919 | int *type = arg; | 924 | int *type = arg; |
920 | 925 | ||
921 | if (*type != video->streaming->type) | 926 | if (*type != stream->type) |
922 | return -EINVAL; | 927 | return -EINVAL; |
923 | 928 | ||
924 | if (!uvc_has_privileges(handle)) | 929 | if (!uvc_has_privileges(handle)) |
925 | return -EBUSY; | 930 | return -EBUSY; |
926 | 931 | ||
927 | if ((ret = uvc_video_enable(video, 1)) < 0) | 932 | ret = uvc_video_enable(stream, 1); |
933 | if (ret < 0) | ||
928 | return ret; | 934 | return ret; |
929 | break; | 935 | break; |
930 | } | 936 | } |
@@ -933,13 +939,13 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
933 | { | 939 | { |
934 | int *type = arg; | 940 | int *type = arg; |
935 | 941 | ||
936 | if (*type != video->streaming->type) | 942 | if (*type != stream->type) |
937 | return -EINVAL; | 943 | return -EINVAL; |
938 | 944 | ||
939 | if (!uvc_has_privileges(handle)) | 945 | if (!uvc_has_privileges(handle)) |
940 | return -EBUSY; | 946 | return -EBUSY; |
941 | 947 | ||
942 | return uvc_video_enable(video, 0); | 948 | return uvc_video_enable(stream, 0); |
943 | } | 949 | } |
944 | 950 | ||
945 | /* Analog video standards make no sense for digital cameras. */ | 951 | /* Analog video standards make no sense for digital cameras. */ |
@@ -1070,7 +1076,9 @@ static struct vm_operations_struct uvc_vm_ops = { | |||
1070 | 1076 | ||
1071 | static int uvc_v4l2_mmap(struct file *file, struct vm_area_struct *vma) | 1077 | static int uvc_v4l2_mmap(struct file *file, struct vm_area_struct *vma) |
1072 | { | 1078 | { |
1073 | struct uvc_video_device *video = video_drvdata(file); | 1079 | struct uvc_fh *handle = (struct uvc_fh *)file->private_data; |
1080 | struct uvc_streaming *stream = handle->stream; | ||
1081 | struct uvc_video_queue *queue = &stream->queue; | ||
1074 | struct uvc_buffer *uninitialized_var(buffer); | 1082 | struct uvc_buffer *uninitialized_var(buffer); |
1075 | struct page *page; | 1083 | struct page *page; |
1076 | unsigned long addr, start, size; | 1084 | unsigned long addr, start, size; |
@@ -1082,15 +1090,15 @@ static int uvc_v4l2_mmap(struct file *file, struct vm_area_struct *vma) | |||
1082 | start = vma->vm_start; | 1090 | start = vma->vm_start; |
1083 | size = vma->vm_end - vma->vm_start; | 1091 | size = vma->vm_end - vma->vm_start; |
1084 | 1092 | ||
1085 | mutex_lock(&video->queue.mutex); | 1093 | mutex_lock(&queue->mutex); |
1086 | 1094 | ||
1087 | for (i = 0; i < video->queue.count; ++i) { | 1095 | for (i = 0; i < queue->count; ++i) { |
1088 | buffer = &video->queue.buffer[i]; | 1096 | buffer = &queue->buffer[i]; |
1089 | if ((buffer->buf.m.offset >> PAGE_SHIFT) == vma->vm_pgoff) | 1097 | if ((buffer->buf.m.offset >> PAGE_SHIFT) == vma->vm_pgoff) |
1090 | break; | 1098 | break; |
1091 | } | 1099 | } |
1092 | 1100 | ||
1093 | if (i == video->queue.count || size != video->queue.buf_size) { | 1101 | if (i == queue->count || size != queue->buf_size) { |
1094 | ret = -EINVAL; | 1102 | ret = -EINVAL; |
1095 | goto done; | 1103 | goto done; |
1096 | } | 1104 | } |
@@ -1101,7 +1109,7 @@ static int uvc_v4l2_mmap(struct file *file, struct vm_area_struct *vma) | |||
1101 | */ | 1109 | */ |
1102 | vma->vm_flags |= VM_IO; | 1110 | vma->vm_flags |= VM_IO; |
1103 | 1111 | ||
1104 | addr = (unsigned long)video->queue.mem + buffer->buf.m.offset; | 1112 | addr = (unsigned long)queue->mem + buffer->buf.m.offset; |
1105 | while (size > 0) { | 1113 | while (size > 0) { |
1106 | page = vmalloc_to_page((void *)addr); | 1114 | page = vmalloc_to_page((void *)addr); |
1107 | if ((ret = vm_insert_page(vma, start, page)) < 0) | 1115 | if ((ret = vm_insert_page(vma, start, page)) < 0) |
@@ -1117,17 +1125,18 @@ static int uvc_v4l2_mmap(struct file *file, struct vm_area_struct *vma) | |||
1117 | uvc_vm_open(vma); | 1125 | uvc_vm_open(vma); |
1118 | 1126 | ||
1119 | done: | 1127 | done: |
1120 | mutex_unlock(&video->queue.mutex); | 1128 | mutex_unlock(&queue->mutex); |
1121 | return ret; | 1129 | return ret; |
1122 | } | 1130 | } |
1123 | 1131 | ||
1124 | static unsigned int uvc_v4l2_poll(struct file *file, poll_table *wait) | 1132 | static unsigned int uvc_v4l2_poll(struct file *file, poll_table *wait) |
1125 | { | 1133 | { |
1126 | struct uvc_video_device *video = video_drvdata(file); | 1134 | struct uvc_fh *handle = (struct uvc_fh *)file->private_data; |
1135 | struct uvc_streaming *stream = handle->stream; | ||
1127 | 1136 | ||
1128 | uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_poll\n"); | 1137 | uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_poll\n"); |
1129 | 1138 | ||
1130 | return uvc_queue_poll(&video->queue, file, wait); | 1139 | return uvc_queue_poll(&stream->queue, file, wait); |
1131 | } | 1140 | } |
1132 | 1141 | ||
1133 | const struct v4l2_file_operations uvc_fops = { | 1142 | const struct v4l2_file_operations uvc_fops = { |
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c index 68468309932d..acbd73ac6bf4 100644 --- a/drivers/media/video/uvc/uvc_video.c +++ b/drivers/media/video/uvc/uvc_video.c | |||
@@ -61,7 +61,7 @@ int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit, | |||
61 | return 0; | 61 | return 0; |
62 | } | 62 | } |
63 | 63 | ||
64 | static void uvc_fixup_video_ctrl(struct uvc_video_device *video, | 64 | static void uvc_fixup_video_ctrl(struct uvc_streaming *stream, |
65 | struct uvc_streaming_control *ctrl) | 65 | struct uvc_streaming_control *ctrl) |
66 | { | 66 | { |
67 | struct uvc_format *format; | 67 | struct uvc_format *format; |
@@ -69,10 +69,10 @@ static void uvc_fixup_video_ctrl(struct uvc_video_device *video, | |||
69 | unsigned int i; | 69 | unsigned int i; |
70 | 70 | ||
71 | if (ctrl->bFormatIndex <= 0 || | 71 | if (ctrl->bFormatIndex <= 0 || |
72 | ctrl->bFormatIndex > video->streaming->nformats) | 72 | ctrl->bFormatIndex > stream->nformats) |
73 | return; | 73 | return; |
74 | 74 | ||
75 | format = &video->streaming->format[ctrl->bFormatIndex - 1]; | 75 | format = &stream->format[ctrl->bFormatIndex - 1]; |
76 | 76 | ||
77 | for (i = 0; i < format->nframes; ++i) { | 77 | for (i = 0; i < format->nframes; ++i) { |
78 | if (format->frame[i].bFrameIndex == ctrl->bFrameIndex) { | 78 | if (format->frame[i].bFrameIndex == ctrl->bFrameIndex) { |
@@ -86,12 +86,12 @@ static void uvc_fixup_video_ctrl(struct uvc_video_device *video, | |||
86 | 86 | ||
87 | if (!(format->flags & UVC_FMT_FLAG_COMPRESSED) || | 87 | if (!(format->flags & UVC_FMT_FLAG_COMPRESSED) || |
88 | (ctrl->dwMaxVideoFrameSize == 0 && | 88 | (ctrl->dwMaxVideoFrameSize == 0 && |
89 | video->dev->uvc_version < 0x0110)) | 89 | stream->dev->uvc_version < 0x0110)) |
90 | ctrl->dwMaxVideoFrameSize = | 90 | ctrl->dwMaxVideoFrameSize = |
91 | frame->dwMaxVideoFrameBufferSize; | 91 | frame->dwMaxVideoFrameBufferSize; |
92 | 92 | ||
93 | if (video->dev->quirks & UVC_QUIRK_FIX_BANDWIDTH && | 93 | if (stream->dev->quirks & UVC_QUIRK_FIX_BANDWIDTH && |
94 | video->streaming->intf->num_altsetting > 1) { | 94 | stream->intf->num_altsetting > 1) { |
95 | u32 interval; | 95 | u32 interval; |
96 | u32 bandwidth; | 96 | u32 bandwidth; |
97 | 97 | ||
@@ -108,7 +108,7 @@ static void uvc_fixup_video_ctrl(struct uvc_video_device *video, | |||
108 | bandwidth = frame->wWidth * frame->wHeight / 8 * format->bpp; | 108 | bandwidth = frame->wWidth * frame->wHeight / 8 * format->bpp; |
109 | bandwidth *= 10000000 / interval + 1; | 109 | bandwidth *= 10000000 / interval + 1; |
110 | bandwidth /= 1000; | 110 | bandwidth /= 1000; |
111 | if (video->dev->udev->speed == USB_SPEED_HIGH) | 111 | if (stream->dev->udev->speed == USB_SPEED_HIGH) |
112 | bandwidth /= 8; | 112 | bandwidth /= 8; |
113 | bandwidth += 12; | 113 | bandwidth += 12; |
114 | 114 | ||
@@ -116,14 +116,14 @@ static void uvc_fixup_video_ctrl(struct uvc_video_device *video, | |||
116 | } | 116 | } |
117 | } | 117 | } |
118 | 118 | ||
119 | static int uvc_get_video_ctrl(struct uvc_video_device *video, | 119 | static int uvc_get_video_ctrl(struct uvc_streaming *stream, |
120 | struct uvc_streaming_control *ctrl, int probe, __u8 query) | 120 | struct uvc_streaming_control *ctrl, int probe, __u8 query) |
121 | { | 121 | { |
122 | __u8 *data; | 122 | __u8 *data; |
123 | __u16 size; | 123 | __u16 size; |
124 | int ret; | 124 | int ret; |
125 | 125 | ||
126 | size = video->dev->uvc_version >= 0x0110 ? 34 : 26; | 126 | size = stream->dev->uvc_version >= 0x0110 ? 34 : 26; |
127 | data = kmalloc(size, GFP_KERNEL); | 127 | data = kmalloc(size, GFP_KERNEL); |
128 | if (data == NULL) | 128 | if (data == NULL) |
129 | return -ENOMEM; | 129 | return -ENOMEM; |
@@ -131,7 +131,7 @@ static int uvc_get_video_ctrl(struct uvc_video_device *video, | |||
131 | if ((video->dev->quirks & UVC_QUIRK_PROBE_DEF) && query == UVC_GET_DEF) | 131 | if ((video->dev->quirks & UVC_QUIRK_PROBE_DEF) && query == UVC_GET_DEF) |
132 | return -EIO; | 132 | return -EIO; |
133 | 133 | ||
134 | ret = __uvc_query_ctrl(video->dev, query, 0, video->streaming->intfnum, | 134 | ret = __uvc_query_ctrl(stream->dev, query, 0, stream->intfnum, |
135 | probe ? UVC_VS_PROBE_CONTROL : UVC_VS_COMMIT_CONTROL, data, | 135 | probe ? UVC_VS_PROBE_CONTROL : UVC_VS_COMMIT_CONTROL, data, |
136 | size, UVC_CTRL_STREAMING_TIMEOUT); | 136 | size, UVC_CTRL_STREAMING_TIMEOUT); |
137 | 137 | ||
@@ -140,7 +140,7 @@ static int uvc_get_video_ctrl(struct uvc_video_device *video, | |||
140 | * answer a GET_MIN or GET_MAX request with the wCompQuality | 140 | * answer a GET_MIN or GET_MAX request with the wCompQuality |
141 | * field only. | 141 | * field only. |
142 | */ | 142 | */ |
143 | uvc_warn_once(video->dev, UVC_WARN_MINMAX, "UVC non " | 143 | uvc_warn_once(stream->dev, UVC_WARN_MINMAX, "UVC non " |
144 | "compliance - GET_MIN/MAX(PROBE) incorrectly " | 144 | "compliance - GET_MIN/MAX(PROBE) incorrectly " |
145 | "supported. Enabling workaround.\n"); | 145 | "supported. Enabling workaround.\n"); |
146 | memset(ctrl, 0, sizeof ctrl); | 146 | memset(ctrl, 0, sizeof ctrl); |
@@ -152,7 +152,7 @@ static int uvc_get_video_ctrl(struct uvc_video_device *video, | |||
152 | * video probe control. Warn once and return, the caller will | 152 | * video probe control. Warn once and return, the caller will |
153 | * fall back to GET_CUR. | 153 | * fall back to GET_CUR. |
154 | */ | 154 | */ |
155 | uvc_warn_once(video->dev, UVC_WARN_PROBE_DEF, "UVC non " | 155 | uvc_warn_once(stream->dev, UVC_WARN_PROBE_DEF, "UVC non " |
156 | "compliance - GET_DEF(PROBE) not supported. " | 156 | "compliance - GET_DEF(PROBE) not supported. " |
157 | "Enabling workaround.\n"); | 157 | "Enabling workaround.\n"); |
158 | ret = -EIO; | 158 | ret = -EIO; |
@@ -184,7 +184,7 @@ static int uvc_get_video_ctrl(struct uvc_video_device *video, | |||
184 | ctrl->bMinVersion = data[32]; | 184 | ctrl->bMinVersion = data[32]; |
185 | ctrl->bMaxVersion = data[33]; | 185 | ctrl->bMaxVersion = data[33]; |
186 | } else { | 186 | } else { |
187 | ctrl->dwClockFrequency = video->dev->clock_frequency; | 187 | ctrl->dwClockFrequency = stream->dev->clock_frequency; |
188 | ctrl->bmFramingInfo = 0; | 188 | ctrl->bmFramingInfo = 0; |
189 | ctrl->bPreferedVersion = 0; | 189 | ctrl->bPreferedVersion = 0; |
190 | ctrl->bMinVersion = 0; | 190 | ctrl->bMinVersion = 0; |
@@ -195,7 +195,7 @@ static int uvc_get_video_ctrl(struct uvc_video_device *video, | |||
195 | * dwMaxPayloadTransferSize fields. Try to get the value from the | 195 | * dwMaxPayloadTransferSize fields. Try to get the value from the |
196 | * format and frame descriptors. | 196 | * format and frame descriptors. |
197 | */ | 197 | */ |
198 | uvc_fixup_video_ctrl(video, ctrl); | 198 | uvc_fixup_video_ctrl(stream, ctrl); |
199 | ret = 0; | 199 | ret = 0; |
200 | 200 | ||
201 | out: | 201 | out: |
@@ -203,14 +203,14 @@ out: | |||
203 | return ret; | 203 | return ret; |
204 | } | 204 | } |
205 | 205 | ||
206 | static int uvc_set_video_ctrl(struct uvc_video_device *video, | 206 | static int uvc_set_video_ctrl(struct uvc_streaming *stream, |
207 | struct uvc_streaming_control *ctrl, int probe) | 207 | struct uvc_streaming_control *ctrl, int probe) |
208 | { | 208 | { |
209 | __u8 *data; | 209 | __u8 *data; |
210 | __u16 size; | 210 | __u16 size; |
211 | int ret; | 211 | int ret; |
212 | 212 | ||
213 | size = video->dev->uvc_version >= 0x0110 ? 34 : 26; | 213 | size = stream->dev->uvc_version >= 0x0110 ? 34 : 26; |
214 | data = kzalloc(size, GFP_KERNEL); | 214 | data = kzalloc(size, GFP_KERNEL); |
215 | if (data == NULL) | 215 | if (data == NULL) |
216 | return -ENOMEM; | 216 | return -ENOMEM; |
@@ -235,8 +235,7 @@ static int uvc_set_video_ctrl(struct uvc_video_device *video, | |||
235 | data[33] = ctrl->bMaxVersion; | 235 | data[33] = ctrl->bMaxVersion; |
236 | } | 236 | } |
237 | 237 | ||
238 | ret = __uvc_query_ctrl(video->dev, UVC_SET_CUR, 0, | 238 | ret = __uvc_query_ctrl(stream->dev, UVC_SET_CUR, 0, stream->intfnum, |
239 | video->streaming->intfnum, | ||
240 | probe ? UVC_VS_PROBE_CONTROL : UVC_VS_COMMIT_CONTROL, data, | 239 | probe ? UVC_VS_PROBE_CONTROL : UVC_VS_COMMIT_CONTROL, data, |
241 | size, UVC_CTRL_STREAMING_TIMEOUT); | 240 | size, UVC_CTRL_STREAMING_TIMEOUT); |
242 | if (ret != size) { | 241 | if (ret != size) { |
@@ -250,7 +249,7 @@ static int uvc_set_video_ctrl(struct uvc_video_device *video, | |||
250 | return ret; | 249 | return ret; |
251 | } | 250 | } |
252 | 251 | ||
253 | int uvc_probe_video(struct uvc_video_device *video, | 252 | int uvc_probe_video(struct uvc_streaming *stream, |
254 | struct uvc_streaming_control *probe) | 253 | struct uvc_streaming_control *probe) |
255 | { | 254 | { |
256 | struct uvc_streaming_control probe_min, probe_max; | 255 | struct uvc_streaming_control probe_min, probe_max; |
@@ -258,7 +257,7 @@ int uvc_probe_video(struct uvc_video_device *video, | |||
258 | unsigned int i; | 257 | unsigned int i; |
259 | int ret; | 258 | int ret; |
260 | 259 | ||
261 | mutex_lock(&video->streaming->mutex); | 260 | mutex_lock(&stream->mutex); |
262 | 261 | ||
263 | /* Perform probing. The device should adjust the requested values | 262 | /* Perform probing. The device should adjust the requested values |
264 | * according to its capabilities. However, some devices, namely the | 263 | * according to its capabilities. However, some devices, namely the |
@@ -267,15 +266,16 @@ int uvc_probe_video(struct uvc_video_device *video, | |||
267 | * that reason, if the needed bandwidth exceeds the maximum available | 266 | * that reason, if the needed bandwidth exceeds the maximum available |
268 | * bandwidth, try to lower the quality. | 267 | * bandwidth, try to lower the quality. |
269 | */ | 268 | */ |
270 | if ((ret = uvc_set_video_ctrl(video, probe, 1)) < 0) | 269 | ret = uvc_set_video_ctrl(stream, probe, 1); |
270 | if (ret < 0) | ||
271 | goto done; | 271 | goto done; |
272 | 272 | ||
273 | /* Get the minimum and maximum values for compression settings. */ | 273 | /* Get the minimum and maximum values for compression settings. */ |
274 | if (!(video->dev->quirks & UVC_QUIRK_PROBE_MINMAX)) { | 274 | if (!(stream->dev->quirks & UVC_QUIRK_PROBE_MINMAX)) { |
275 | ret = uvc_get_video_ctrl(video, &probe_min, 1, UVC_GET_MIN); | 275 | ret = uvc_get_video_ctrl(stream, &probe_min, 1, UVC_GET_MIN); |
276 | if (ret < 0) | 276 | if (ret < 0) |
277 | goto done; | 277 | goto done; |
278 | ret = uvc_get_video_ctrl(video, &probe_max, 1, UVC_GET_MAX); | 278 | ret = uvc_get_video_ctrl(stream, &probe_max, 1, UVC_GET_MAX); |
279 | if (ret < 0) | 279 | if (ret < 0) |
280 | goto done; | 280 | goto done; |
281 | 281 | ||
@@ -283,21 +283,21 @@ int uvc_probe_video(struct uvc_video_device *video, | |||
283 | } | 283 | } |
284 | 284 | ||
285 | for (i = 0; i < 2; ++i) { | 285 | for (i = 0; i < 2; ++i) { |
286 | ret = uvc_set_video_ctrl(video, probe, 1); | 286 | ret = uvc_set_video_ctrl(stream, probe, 1); |
287 | if (ret < 0) | 287 | if (ret < 0) |
288 | goto done; | 288 | goto done; |
289 | ret = uvc_get_video_ctrl(video, probe, 1, UVC_GET_CUR); | 289 | ret = uvc_get_video_ctrl(stream, probe, 1, UVC_GET_CUR); |
290 | if (ret < 0) | 290 | if (ret < 0) |
291 | goto done; | 291 | goto done; |
292 | 292 | ||
293 | if (video->streaming->intf->num_altsetting == 1) | 293 | if (stream->intf->num_altsetting == 1) |
294 | break; | 294 | break; |
295 | 295 | ||
296 | bandwidth = probe->dwMaxPayloadTransferSize; | 296 | bandwidth = probe->dwMaxPayloadTransferSize; |
297 | if (bandwidth <= video->streaming->maxpsize) | 297 | if (bandwidth <= stream->maxpsize) |
298 | break; | 298 | break; |
299 | 299 | ||
300 | if (video->dev->quirks & UVC_QUIRK_PROBE_MINMAX) { | 300 | if (stream->dev->quirks & UVC_QUIRK_PROBE_MINMAX) { |
301 | ret = -ENOSPC; | 301 | ret = -ENOSPC; |
302 | goto done; | 302 | goto done; |
303 | } | 303 | } |
@@ -310,14 +310,14 @@ int uvc_probe_video(struct uvc_video_device *video, | |||
310 | } | 310 | } |
311 | 311 | ||
312 | done: | 312 | done: |
313 | mutex_unlock(&video->streaming->mutex); | 313 | mutex_unlock(&stream->mutex); |
314 | return ret; | 314 | return ret; |
315 | } | 315 | } |
316 | 316 | ||
317 | int uvc_commit_video(struct uvc_video_device *video, | 317 | int uvc_commit_video(struct uvc_streaming *stream, |
318 | struct uvc_streaming_control *probe) | 318 | struct uvc_streaming_control *probe) |
319 | { | 319 | { |
320 | return uvc_set_video_ctrl(video, probe, 0); | 320 | return uvc_set_video_ctrl(stream, probe, 0); |
321 | } | 321 | } |
322 | 322 | ||
323 | /* ------------------------------------------------------------------------ | 323 | /* ------------------------------------------------------------------------ |
@@ -369,7 +369,7 @@ int uvc_commit_video(struct uvc_video_device *video, | |||
369 | * to be called with a NULL buf parameter. uvc_video_decode_data and | 369 | * to be called with a NULL buf parameter. uvc_video_decode_data and |
370 | * uvc_video_decode_end will never be called with a NULL buffer. | 370 | * uvc_video_decode_end will never be called with a NULL buffer. |
371 | */ | 371 | */ |
372 | static int uvc_video_decode_start(struct uvc_video_device *video, | 372 | static int uvc_video_decode_start(struct uvc_streaming *stream, |
373 | struct uvc_buffer *buf, const __u8 *data, int len) | 373 | struct uvc_buffer *buf, const __u8 *data, int len) |
374 | { | 374 | { |
375 | __u8 fid; | 375 | __u8 fid; |
@@ -395,25 +395,25 @@ static int uvc_video_decode_start(struct uvc_video_device *video, | |||
395 | * NULL. | 395 | * NULL. |
396 | */ | 396 | */ |
397 | if (buf == NULL) { | 397 | if (buf == NULL) { |
398 | video->last_fid = fid; | 398 | stream->last_fid = fid; |
399 | return -ENODATA; | 399 | return -ENODATA; |
400 | } | 400 | } |
401 | 401 | ||
402 | /* Synchronize to the input stream by waiting for the FID bit to be | 402 | /* Synchronize to the input stream by waiting for the FID bit to be |
403 | * toggled when the the buffer state is not UVC_BUF_STATE_ACTIVE. | 403 | * toggled when the the buffer state is not UVC_BUF_STATE_ACTIVE. |
404 | * video->last_fid is initialized to -1, so the first isochronous | 404 | * stream->last_fid is initialized to -1, so the first isochronous |
405 | * frame will always be in sync. | 405 | * frame will always be in sync. |
406 | * | 406 | * |
407 | * If the device doesn't toggle the FID bit, invert video->last_fid | 407 | * If the device doesn't toggle the FID bit, invert stream->last_fid |
408 | * when the EOF bit is set to force synchronisation on the next packet. | 408 | * when the EOF bit is set to force synchronisation on the next packet. |
409 | */ | 409 | */ |
410 | if (buf->state != UVC_BUF_STATE_ACTIVE) { | 410 | if (buf->state != UVC_BUF_STATE_ACTIVE) { |
411 | if (fid == video->last_fid) { | 411 | if (fid == stream->last_fid) { |
412 | uvc_trace(UVC_TRACE_FRAME, "Dropping payload (out of " | 412 | uvc_trace(UVC_TRACE_FRAME, "Dropping payload (out of " |
413 | "sync).\n"); | 413 | "sync).\n"); |
414 | if ((video->dev->quirks & UVC_QUIRK_STREAM_NO_FID) && | 414 | if ((stream->dev->quirks & UVC_QUIRK_STREAM_NO_FID) && |
415 | (data[1] & UVC_STREAM_EOF)) | 415 | (data[1] & UVC_STREAM_EOF)) |
416 | video->last_fid ^= UVC_STREAM_FID; | 416 | stream->last_fid ^= UVC_STREAM_FID; |
417 | return -ENODATA; | 417 | return -ENODATA; |
418 | } | 418 | } |
419 | 419 | ||
@@ -428,7 +428,7 @@ static int uvc_video_decode_start(struct uvc_video_device *video, | |||
428 | * last payload can be lost anyway). We thus must check if the FID has | 428 | * last payload can be lost anyway). We thus must check if the FID has |
429 | * been toggled. | 429 | * been toggled. |
430 | * | 430 | * |
431 | * video->last_fid is initialized to -1, so the first isochronous | 431 | * stream->last_fid is initialized to -1, so the first isochronous |
432 | * frame will never trigger an end of frame detection. | 432 | * frame will never trigger an end of frame detection. |
433 | * | 433 | * |
434 | * Empty buffers (bytesused == 0) don't trigger end of frame detection | 434 | * Empty buffers (bytesused == 0) don't trigger end of frame detection |
@@ -436,22 +436,22 @@ static int uvc_video_decode_start(struct uvc_video_device *video, | |||
436 | * avoids detecting end of frame conditions at FID toggling if the | 436 | * avoids detecting end of frame conditions at FID toggling if the |
437 | * previous payload had the EOF bit set. | 437 | * previous payload had the EOF bit set. |
438 | */ | 438 | */ |
439 | if (fid != video->last_fid && buf->buf.bytesused != 0) { | 439 | if (fid != stream->last_fid && buf->buf.bytesused != 0) { |
440 | uvc_trace(UVC_TRACE_FRAME, "Frame complete (FID bit " | 440 | uvc_trace(UVC_TRACE_FRAME, "Frame complete (FID bit " |
441 | "toggled).\n"); | 441 | "toggled).\n"); |
442 | buf->state = UVC_BUF_STATE_DONE; | 442 | buf->state = UVC_BUF_STATE_DONE; |
443 | return -EAGAIN; | 443 | return -EAGAIN; |
444 | } | 444 | } |
445 | 445 | ||
446 | video->last_fid = fid; | 446 | stream->last_fid = fid; |
447 | 447 | ||
448 | return data[0]; | 448 | return data[0]; |
449 | } | 449 | } |
450 | 450 | ||
451 | static void uvc_video_decode_data(struct uvc_video_device *video, | 451 | static void uvc_video_decode_data(struct uvc_streaming *stream, |
452 | struct uvc_buffer *buf, const __u8 *data, int len) | 452 | struct uvc_buffer *buf, const __u8 *data, int len) |
453 | { | 453 | { |
454 | struct uvc_video_queue *queue = &video->queue; | 454 | struct uvc_video_queue *queue = &stream->queue; |
455 | unsigned int maxlen, nbytes; | 455 | unsigned int maxlen, nbytes; |
456 | void *mem; | 456 | void *mem; |
457 | 457 | ||
@@ -472,7 +472,7 @@ static void uvc_video_decode_data(struct uvc_video_device *video, | |||
472 | } | 472 | } |
473 | } | 473 | } |
474 | 474 | ||
475 | static void uvc_video_decode_end(struct uvc_video_device *video, | 475 | static void uvc_video_decode_end(struct uvc_streaming *stream, |
476 | struct uvc_buffer *buf, const __u8 *data, int len) | 476 | struct uvc_buffer *buf, const __u8 *data, int len) |
477 | { | 477 | { |
478 | /* Mark the buffer as done if the EOF marker is set. */ | 478 | /* Mark the buffer as done if the EOF marker is set. */ |
@@ -481,8 +481,8 @@ static void uvc_video_decode_end(struct uvc_video_device *video, | |||
481 | if (data[0] == len) | 481 | if (data[0] == len) |
482 | uvc_trace(UVC_TRACE_FRAME, "EOF in empty payload.\n"); | 482 | uvc_trace(UVC_TRACE_FRAME, "EOF in empty payload.\n"); |
483 | buf->state = UVC_BUF_STATE_DONE; | 483 | buf->state = UVC_BUF_STATE_DONE; |
484 | if (video->dev->quirks & UVC_QUIRK_STREAM_NO_FID) | 484 | if (stream->dev->quirks & UVC_QUIRK_STREAM_NO_FID) |
485 | video->last_fid ^= UVC_STREAM_FID; | 485 | stream->last_fid ^= UVC_STREAM_FID; |
486 | } | 486 | } |
487 | } | 487 | } |
488 | 488 | ||
@@ -497,26 +497,26 @@ static void uvc_video_decode_end(struct uvc_video_device *video, | |||
497 | * uvc_video_encode_data is called for every URB and copies the data from the | 497 | * uvc_video_encode_data is called for every URB and copies the data from the |
498 | * video buffer to the transfer buffer. | 498 | * video buffer to the transfer buffer. |
499 | */ | 499 | */ |
500 | static int uvc_video_encode_header(struct uvc_video_device *video, | 500 | static int uvc_video_encode_header(struct uvc_streaming *stream, |
501 | struct uvc_buffer *buf, __u8 *data, int len) | 501 | struct uvc_buffer *buf, __u8 *data, int len) |
502 | { | 502 | { |
503 | data[0] = 2; /* Header length */ | 503 | data[0] = 2; /* Header length */ |
504 | data[1] = UVC_STREAM_EOH | UVC_STREAM_EOF | 504 | data[1] = UVC_STREAM_EOH | UVC_STREAM_EOF |
505 | | (video->last_fid & UVC_STREAM_FID); | 505 | | (stream->last_fid & UVC_STREAM_FID); |
506 | return 2; | 506 | return 2; |
507 | } | 507 | } |
508 | 508 | ||
509 | static int uvc_video_encode_data(struct uvc_video_device *video, | 509 | static int uvc_video_encode_data(struct uvc_streaming *stream, |
510 | struct uvc_buffer *buf, __u8 *data, int len) | 510 | struct uvc_buffer *buf, __u8 *data, int len) |
511 | { | 511 | { |
512 | struct uvc_video_queue *queue = &video->queue; | 512 | struct uvc_video_queue *queue = &stream->queue; |
513 | unsigned int nbytes; | 513 | unsigned int nbytes; |
514 | void *mem; | 514 | void *mem; |
515 | 515 | ||
516 | /* Copy video data to the URB buffer. */ | 516 | /* Copy video data to the URB buffer. */ |
517 | mem = queue->mem + buf->buf.m.offset + queue->buf_used; | 517 | mem = queue->mem + buf->buf.m.offset + queue->buf_used; |
518 | nbytes = min((unsigned int)len, buf->buf.bytesused - queue->buf_used); | 518 | nbytes = min((unsigned int)len, buf->buf.bytesused - queue->buf_used); |
519 | nbytes = min(video->bulk.max_payload_size - video->bulk.payload_size, | 519 | nbytes = min(stream->bulk.max_payload_size - stream->bulk.payload_size, |
520 | nbytes); | 520 | nbytes); |
521 | memcpy(data, mem, nbytes); | 521 | memcpy(data, mem, nbytes); |
522 | 522 | ||
@@ -532,8 +532,8 @@ static int uvc_video_encode_data(struct uvc_video_device *video, | |||
532 | /* | 532 | /* |
533 | * Completion handler for video URBs. | 533 | * Completion handler for video URBs. |
534 | */ | 534 | */ |
535 | static void uvc_video_decode_isoc(struct urb *urb, | 535 | static void uvc_video_decode_isoc(struct urb *urb, struct uvc_streaming *stream, |
536 | struct uvc_video_device *video, struct uvc_buffer *buf) | 536 | struct uvc_buffer *buf) |
537 | { | 537 | { |
538 | u8 *mem; | 538 | u8 *mem; |
539 | int ret, i; | 539 | int ret, i; |
@@ -548,31 +548,32 @@ static void uvc_video_decode_isoc(struct urb *urb, | |||
548 | /* Decode the payload header. */ | 548 | /* Decode the payload header. */ |
549 | mem = urb->transfer_buffer + urb->iso_frame_desc[i].offset; | 549 | mem = urb->transfer_buffer + urb->iso_frame_desc[i].offset; |
550 | do { | 550 | do { |
551 | ret = uvc_video_decode_start(video, buf, mem, | 551 | ret = uvc_video_decode_start(stream, buf, mem, |
552 | urb->iso_frame_desc[i].actual_length); | 552 | urb->iso_frame_desc[i].actual_length); |
553 | if (ret == -EAGAIN) | 553 | if (ret == -EAGAIN) |
554 | buf = uvc_queue_next_buffer(&video->queue, buf); | 554 | buf = uvc_queue_next_buffer(&stream->queue, |
555 | buf); | ||
555 | } while (ret == -EAGAIN); | 556 | } while (ret == -EAGAIN); |
556 | 557 | ||
557 | if (ret < 0) | 558 | if (ret < 0) |
558 | continue; | 559 | continue; |
559 | 560 | ||
560 | /* Decode the payload data. */ | 561 | /* Decode the payload data. */ |
561 | uvc_video_decode_data(video, buf, mem + ret, | 562 | uvc_video_decode_data(stream, buf, mem + ret, |
562 | urb->iso_frame_desc[i].actual_length - ret); | 563 | urb->iso_frame_desc[i].actual_length - ret); |
563 | 564 | ||
564 | /* Process the header again. */ | 565 | /* Process the header again. */ |
565 | uvc_video_decode_end(video, buf, mem, | 566 | uvc_video_decode_end(stream, buf, mem, |
566 | urb->iso_frame_desc[i].actual_length); | 567 | urb->iso_frame_desc[i].actual_length); |
567 | 568 | ||
568 | if (buf->state == UVC_BUF_STATE_DONE || | 569 | if (buf->state == UVC_BUF_STATE_DONE || |
569 | buf->state == UVC_BUF_STATE_ERROR) | 570 | buf->state == UVC_BUF_STATE_ERROR) |
570 | buf = uvc_queue_next_buffer(&video->queue, buf); | 571 | buf = uvc_queue_next_buffer(&stream->queue, buf); |
571 | } | 572 | } |
572 | } | 573 | } |
573 | 574 | ||
574 | static void uvc_video_decode_bulk(struct urb *urb, | 575 | static void uvc_video_decode_bulk(struct urb *urb, struct uvc_streaming *stream, |
575 | struct uvc_video_device *video, struct uvc_buffer *buf) | 576 | struct uvc_buffer *buf) |
576 | { | 577 | { |
577 | u8 *mem; | 578 | u8 *mem; |
578 | int len, ret; | 579 | int len, ret; |
@@ -582,24 +583,25 @@ static void uvc_video_decode_bulk(struct urb *urb, | |||
582 | 583 | ||
583 | mem = urb->transfer_buffer; | 584 | mem = urb->transfer_buffer; |
584 | len = urb->actual_length; | 585 | len = urb->actual_length; |
585 | video->bulk.payload_size += len; | 586 | stream->bulk.payload_size += len; |
586 | 587 | ||
587 | /* If the URB is the first of its payload, decode and save the | 588 | /* If the URB is the first of its payload, decode and save the |
588 | * header. | 589 | * header. |
589 | */ | 590 | */ |
590 | if (video->bulk.header_size == 0 && !video->bulk.skip_payload) { | 591 | if (stream->bulk.header_size == 0 && !stream->bulk.skip_payload) { |
591 | do { | 592 | do { |
592 | ret = uvc_video_decode_start(video, buf, mem, len); | 593 | ret = uvc_video_decode_start(stream, buf, mem, len); |
593 | if (ret == -EAGAIN) | 594 | if (ret == -EAGAIN) |
594 | buf = uvc_queue_next_buffer(&video->queue, buf); | 595 | buf = uvc_queue_next_buffer(&stream->queue, |
596 | buf); | ||
595 | } while (ret == -EAGAIN); | 597 | } while (ret == -EAGAIN); |
596 | 598 | ||
597 | /* If an error occured skip the rest of the payload. */ | 599 | /* If an error occured skip the rest of the payload. */ |
598 | if (ret < 0 || buf == NULL) { | 600 | if (ret < 0 || buf == NULL) { |
599 | video->bulk.skip_payload = 1; | 601 | stream->bulk.skip_payload = 1; |
600 | } else { | 602 | } else { |
601 | memcpy(video->bulk.header, mem, ret); | 603 | memcpy(stream->bulk.header, mem, ret); |
602 | video->bulk.header_size = ret; | 604 | stream->bulk.header_size = ret; |
603 | 605 | ||
604 | mem += ret; | 606 | mem += ret; |
605 | len -= ret; | 607 | len -= ret; |
@@ -612,33 +614,34 @@ static void uvc_video_decode_bulk(struct urb *urb, | |||
612 | */ | 614 | */ |
613 | 615 | ||
614 | /* Process video data. */ | 616 | /* Process video data. */ |
615 | if (!video->bulk.skip_payload && buf != NULL) | 617 | if (!stream->bulk.skip_payload && buf != NULL) |
616 | uvc_video_decode_data(video, buf, mem, len); | 618 | uvc_video_decode_data(stream, buf, mem, len); |
617 | 619 | ||
618 | /* Detect the payload end by a URB smaller than the maximum size (or | 620 | /* Detect the payload end by a URB smaller than the maximum size (or |
619 | * a payload size equal to the maximum) and process the header again. | 621 | * a payload size equal to the maximum) and process the header again. |
620 | */ | 622 | */ |
621 | if (urb->actual_length < urb->transfer_buffer_length || | 623 | if (urb->actual_length < urb->transfer_buffer_length || |
622 | video->bulk.payload_size >= video->bulk.max_payload_size) { | 624 | stream->bulk.payload_size >= stream->bulk.max_payload_size) { |
623 | if (!video->bulk.skip_payload && buf != NULL) { | 625 | if (!stream->bulk.skip_payload && buf != NULL) { |
624 | uvc_video_decode_end(video, buf, video->bulk.header, | 626 | uvc_video_decode_end(stream, buf, stream->bulk.header, |
625 | video->bulk.payload_size); | 627 | stream->bulk.payload_size); |
626 | if (buf->state == UVC_BUF_STATE_DONE || | 628 | if (buf->state == UVC_BUF_STATE_DONE || |
627 | buf->state == UVC_BUF_STATE_ERROR) | 629 | buf->state == UVC_BUF_STATE_ERROR) |
628 | buf = uvc_queue_next_buffer(&video->queue, buf); | 630 | buf = uvc_queue_next_buffer(&stream->queue, |
631 | buf); | ||
629 | } | 632 | } |
630 | 633 | ||
631 | video->bulk.header_size = 0; | 634 | stream->bulk.header_size = 0; |
632 | video->bulk.skip_payload = 0; | 635 | stream->bulk.skip_payload = 0; |
633 | video->bulk.payload_size = 0; | 636 | stream->bulk.payload_size = 0; |
634 | } | 637 | } |
635 | } | 638 | } |
636 | 639 | ||
637 | static void uvc_video_encode_bulk(struct urb *urb, | 640 | static void uvc_video_encode_bulk(struct urb *urb, struct uvc_streaming *stream, |
638 | struct uvc_video_device *video, struct uvc_buffer *buf) | 641 | struct uvc_buffer *buf) |
639 | { | 642 | { |
640 | u8 *mem = urb->transfer_buffer; | 643 | u8 *mem = urb->transfer_buffer; |
641 | int len = video->urb_size, ret; | 644 | int len = stream->urb_size, ret; |
642 | 645 | ||
643 | if (buf == NULL) { | 646 | if (buf == NULL) { |
644 | urb->transfer_buffer_length = 0; | 647 | urb->transfer_buffer_length = 0; |
@@ -646,40 +649,40 @@ static void uvc_video_encode_bulk(struct urb *urb, | |||
646 | } | 649 | } |
647 | 650 | ||
648 | /* If the URB is the first of its payload, add the header. */ | 651 | /* If the URB is the first of its payload, add the header. */ |
649 | if (video->bulk.header_size == 0) { | 652 | if (stream->bulk.header_size == 0) { |
650 | ret = uvc_video_encode_header(video, buf, mem, len); | 653 | ret = uvc_video_encode_header(stream, buf, mem, len); |
651 | video->bulk.header_size = ret; | 654 | stream->bulk.header_size = ret; |
652 | video->bulk.payload_size += ret; | 655 | stream->bulk.payload_size += ret; |
653 | mem += ret; | 656 | mem += ret; |
654 | len -= ret; | 657 | len -= ret; |
655 | } | 658 | } |
656 | 659 | ||
657 | /* Process video data. */ | 660 | /* Process video data. */ |
658 | ret = uvc_video_encode_data(video, buf, mem, len); | 661 | ret = uvc_video_encode_data(stream, buf, mem, len); |
659 | 662 | ||
660 | video->bulk.payload_size += ret; | 663 | stream->bulk.payload_size += ret; |
661 | len -= ret; | 664 | len -= ret; |
662 | 665 | ||
663 | if (buf->buf.bytesused == video->queue.buf_used || | 666 | if (buf->buf.bytesused == stream->queue.buf_used || |
664 | video->bulk.payload_size == video->bulk.max_payload_size) { | 667 | stream->bulk.payload_size == stream->bulk.max_payload_size) { |
665 | if (buf->buf.bytesused == video->queue.buf_used) { | 668 | if (buf->buf.bytesused == stream->queue.buf_used) { |
666 | video->queue.buf_used = 0; | 669 | stream->queue.buf_used = 0; |
667 | buf->state = UVC_BUF_STATE_DONE; | 670 | buf->state = UVC_BUF_STATE_DONE; |
668 | uvc_queue_next_buffer(&video->queue, buf); | 671 | uvc_queue_next_buffer(&stream->queue, buf); |
669 | video->last_fid ^= UVC_STREAM_FID; | 672 | stream->last_fid ^= UVC_STREAM_FID; |
670 | } | 673 | } |
671 | 674 | ||
672 | video->bulk.header_size = 0; | 675 | stream->bulk.header_size = 0; |
673 | video->bulk.payload_size = 0; | 676 | stream->bulk.payload_size = 0; |
674 | } | 677 | } |
675 | 678 | ||
676 | urb->transfer_buffer_length = video->urb_size - len; | 679 | urb->transfer_buffer_length = stream->urb_size - len; |
677 | } | 680 | } |
678 | 681 | ||
679 | static void uvc_video_complete(struct urb *urb) | 682 | static void uvc_video_complete(struct urb *urb) |
680 | { | 683 | { |
681 | struct uvc_video_device *video = urb->context; | 684 | struct uvc_streaming *stream = urb->context; |
682 | struct uvc_video_queue *queue = &video->queue; | 685 | struct uvc_video_queue *queue = &stream->queue; |
683 | struct uvc_buffer *buf = NULL; | 686 | struct uvc_buffer *buf = NULL; |
684 | unsigned long flags; | 687 | unsigned long flags; |
685 | int ret; | 688 | int ret; |
@@ -693,7 +696,7 @@ static void uvc_video_complete(struct urb *urb) | |||
693 | "completion handler.\n", urb->status); | 696 | "completion handler.\n", urb->status); |
694 | 697 | ||
695 | case -ENOENT: /* usb_kill_urb() called. */ | 698 | case -ENOENT: /* usb_kill_urb() called. */ |
696 | if (video->frozen) | 699 | if (stream->frozen) |
697 | return; | 700 | return; |
698 | 701 | ||
699 | case -ECONNRESET: /* usb_unlink_urb() called. */ | 702 | case -ECONNRESET: /* usb_unlink_urb() called. */ |
@@ -708,7 +711,7 @@ static void uvc_video_complete(struct urb *urb) | |||
708 | queue); | 711 | queue); |
709 | spin_unlock_irqrestore(&queue->irqlock, flags); | 712 | spin_unlock_irqrestore(&queue->irqlock, flags); |
710 | 713 | ||
711 | video->decode(urb, video, buf); | 714 | stream->decode(urb, stream, buf); |
712 | 715 | ||
713 | if ((ret = usb_submit_urb(urb, GFP_ATOMIC)) < 0) { | 716 | if ((ret = usb_submit_urb(urb, GFP_ATOMIC)) < 0) { |
714 | uvc_printk(KERN_ERR, "Failed to resubmit video URB (%d).\n", | 717 | uvc_printk(KERN_ERR, "Failed to resubmit video URB (%d).\n", |
@@ -719,19 +722,19 @@ static void uvc_video_complete(struct urb *urb) | |||
719 | /* | 722 | /* |
720 | * Free transfer buffers. | 723 | * Free transfer buffers. |
721 | */ | 724 | */ |
722 | static void uvc_free_urb_buffers(struct uvc_video_device *video) | 725 | static void uvc_free_urb_buffers(struct uvc_streaming *stream) |
723 | { | 726 | { |
724 | unsigned int i; | 727 | unsigned int i; |
725 | 728 | ||
726 | for (i = 0; i < UVC_URBS; ++i) { | 729 | for (i = 0; i < UVC_URBS; ++i) { |
727 | if (video->urb_buffer[i]) { | 730 | if (stream->urb_buffer[i]) { |
728 | usb_buffer_free(video->dev->udev, video->urb_size, | 731 | usb_buffer_free(stream->dev->udev, stream->urb_size, |
729 | video->urb_buffer[i], video->urb_dma[i]); | 732 | stream->urb_buffer[i], stream->urb_dma[i]); |
730 | video->urb_buffer[i] = NULL; | 733 | stream->urb_buffer[i] = NULL; |
731 | } | 734 | } |
732 | } | 735 | } |
733 | 736 | ||
734 | video->urb_size = 0; | 737 | stream->urb_size = 0; |
735 | } | 738 | } |
736 | 739 | ||
737 | /* | 740 | /* |
@@ -745,15 +748,15 @@ static void uvc_free_urb_buffers(struct uvc_video_device *video) | |||
745 | * | 748 | * |
746 | * Return the number of allocated packets on success or 0 when out of memory. | 749 | * Return the number of allocated packets on success or 0 when out of memory. |
747 | */ | 750 | */ |
748 | static int uvc_alloc_urb_buffers(struct uvc_video_device *video, | 751 | static int uvc_alloc_urb_buffers(struct uvc_streaming *stream, |
749 | unsigned int size, unsigned int psize, gfp_t gfp_flags) | 752 | unsigned int size, unsigned int psize, gfp_t gfp_flags) |
750 | { | 753 | { |
751 | unsigned int npackets; | 754 | unsigned int npackets; |
752 | unsigned int i; | 755 | unsigned int i; |
753 | 756 | ||
754 | /* Buffers are already allocated, bail out. */ | 757 | /* Buffers are already allocated, bail out. */ |
755 | if (video->urb_size) | 758 | if (stream->urb_size) |
756 | return video->urb_size / psize; | 759 | return stream->urb_size / psize; |
757 | 760 | ||
758 | /* Compute the number of packets. Bulk endpoints might transfer UVC | 761 | /* Compute the number of packets. Bulk endpoints might transfer UVC |
759 | * payloads accross multiple URBs. | 762 | * payloads accross multiple URBs. |
@@ -765,17 +768,17 @@ static int uvc_alloc_urb_buffers(struct uvc_video_device *video, | |||
765 | /* Retry allocations until one succeed. */ | 768 | /* Retry allocations until one succeed. */ |
766 | for (; npackets > 1; npackets /= 2) { | 769 | for (; npackets > 1; npackets /= 2) { |
767 | for (i = 0; i < UVC_URBS; ++i) { | 770 | for (i = 0; i < UVC_URBS; ++i) { |
768 | video->urb_buffer[i] = usb_buffer_alloc( | 771 | stream->urb_buffer[i] = usb_buffer_alloc( |
769 | video->dev->udev, psize * npackets, | 772 | stream->dev->udev, psize * npackets, |
770 | gfp_flags | __GFP_NOWARN, &video->urb_dma[i]); | 773 | gfp_flags | __GFP_NOWARN, &stream->urb_dma[i]); |
771 | if (!video->urb_buffer[i]) { | 774 | if (!stream->urb_buffer[i]) { |
772 | uvc_free_urb_buffers(video); | 775 | uvc_free_urb_buffers(stream); |
773 | break; | 776 | break; |
774 | } | 777 | } |
775 | } | 778 | } |
776 | 779 | ||
777 | if (i == UVC_URBS) { | 780 | if (i == UVC_URBS) { |
778 | video->urb_size = psize * npackets; | 781 | stream->urb_size = psize * npackets; |
779 | return npackets; | 782 | return npackets; |
780 | } | 783 | } |
781 | } | 784 | } |
@@ -786,29 +789,30 @@ static int uvc_alloc_urb_buffers(struct uvc_video_device *video, | |||
786 | /* | 789 | /* |
787 | * Uninitialize isochronous/bulk URBs and free transfer buffers. | 790 | * Uninitialize isochronous/bulk URBs and free transfer buffers. |
788 | */ | 791 | */ |
789 | static void uvc_uninit_video(struct uvc_video_device *video, int free_buffers) | 792 | static void uvc_uninit_video(struct uvc_streaming *stream, int free_buffers) |
790 | { | 793 | { |
791 | struct urb *urb; | 794 | struct urb *urb; |
792 | unsigned int i; | 795 | unsigned int i; |
793 | 796 | ||
794 | for (i = 0; i < UVC_URBS; ++i) { | 797 | for (i = 0; i < UVC_URBS; ++i) { |
795 | if ((urb = video->urb[i]) == NULL) | 798 | urb = stream->urb[i]; |
799 | if (urb == NULL) | ||
796 | continue; | 800 | continue; |
797 | 801 | ||
798 | usb_kill_urb(urb); | 802 | usb_kill_urb(urb); |
799 | usb_free_urb(urb); | 803 | usb_free_urb(urb); |
800 | video->urb[i] = NULL; | 804 | stream->urb[i] = NULL; |
801 | } | 805 | } |
802 | 806 | ||
803 | if (free_buffers) | 807 | if (free_buffers) |
804 | uvc_free_urb_buffers(video); | 808 | uvc_free_urb_buffers(stream); |
805 | } | 809 | } |
806 | 810 | ||
807 | /* | 811 | /* |
808 | * Initialize isochronous URBs and allocate transfer buffers. The packet size | 812 | * Initialize isochronous URBs and allocate transfer buffers. The packet size |
809 | * is given by the endpoint. | 813 | * is given by the endpoint. |
810 | */ | 814 | */ |
811 | static int uvc_init_video_isoc(struct uvc_video_device *video, | 815 | static int uvc_init_video_isoc(struct uvc_streaming *stream, |
812 | struct usb_host_endpoint *ep, gfp_t gfp_flags) | 816 | struct usb_host_endpoint *ep, gfp_t gfp_flags) |
813 | { | 817 | { |
814 | struct urb *urb; | 818 | struct urb *urb; |
@@ -818,9 +822,9 @@ static int uvc_init_video_isoc(struct uvc_video_device *video, | |||
818 | 822 | ||
819 | psize = le16_to_cpu(ep->desc.wMaxPacketSize); | 823 | psize = le16_to_cpu(ep->desc.wMaxPacketSize); |
820 | psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3)); | 824 | psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3)); |
821 | size = video->streaming->ctrl.dwMaxVideoFrameSize; | 825 | size = stream->ctrl.dwMaxVideoFrameSize; |
822 | 826 | ||
823 | npackets = uvc_alloc_urb_buffers(video, size, psize, gfp_flags); | 827 | npackets = uvc_alloc_urb_buffers(stream, size, psize, gfp_flags); |
824 | if (npackets == 0) | 828 | if (npackets == 0) |
825 | return -ENOMEM; | 829 | return -ENOMEM; |
826 | 830 | ||
@@ -829,18 +833,18 @@ static int uvc_init_video_isoc(struct uvc_video_device *video, | |||
829 | for (i = 0; i < UVC_URBS; ++i) { | 833 | for (i = 0; i < UVC_URBS; ++i) { |
830 | urb = usb_alloc_urb(npackets, gfp_flags); | 834 | urb = usb_alloc_urb(npackets, gfp_flags); |
831 | if (urb == NULL) { | 835 | if (urb == NULL) { |
832 | uvc_uninit_video(video, 1); | 836 | uvc_uninit_video(stream, 1); |
833 | return -ENOMEM; | 837 | return -ENOMEM; |
834 | } | 838 | } |
835 | 839 | ||
836 | urb->dev = video->dev->udev; | 840 | urb->dev = stream->dev->udev; |
837 | urb->context = video; | 841 | urb->context = stream; |
838 | urb->pipe = usb_rcvisocpipe(video->dev->udev, | 842 | urb->pipe = usb_rcvisocpipe(stream->dev->udev, |
839 | ep->desc.bEndpointAddress); | 843 | ep->desc.bEndpointAddress); |
840 | urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP; | 844 | urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP; |
841 | urb->interval = ep->desc.bInterval; | 845 | urb->interval = ep->desc.bInterval; |
842 | urb->transfer_buffer = video->urb_buffer[i]; | 846 | urb->transfer_buffer = stream->urb_buffer[i]; |
843 | urb->transfer_dma = video->urb_dma[i]; | 847 | urb->transfer_dma = stream->urb_dma[i]; |
844 | urb->complete = uvc_video_complete; | 848 | urb->complete = uvc_video_complete; |
845 | urb->number_of_packets = npackets; | 849 | urb->number_of_packets = npackets; |
846 | urb->transfer_buffer_length = size; | 850 | urb->transfer_buffer_length = size; |
@@ -850,7 +854,7 @@ static int uvc_init_video_isoc(struct uvc_video_device *video, | |||
850 | urb->iso_frame_desc[j].length = psize; | 854 | urb->iso_frame_desc[j].length = psize; |
851 | } | 855 | } |
852 | 856 | ||
853 | video->urb[i] = urb; | 857 | stream->urb[i] = urb; |
854 | } | 858 | } |
855 | 859 | ||
856 | return 0; | 860 | return 0; |
@@ -860,7 +864,7 @@ static int uvc_init_video_isoc(struct uvc_video_device *video, | |||
860 | * Initialize bulk URBs and allocate transfer buffers. The packet size is | 864 | * Initialize bulk URBs and allocate transfer buffers. The packet size is |
861 | * given by the endpoint. | 865 | * given by the endpoint. |
862 | */ | 866 | */ |
863 | static int uvc_init_video_bulk(struct uvc_video_device *video, | 867 | static int uvc_init_video_bulk(struct uvc_streaming *stream, |
864 | struct usb_host_endpoint *ep, gfp_t gfp_flags) | 868 | struct usb_host_endpoint *ep, gfp_t gfp_flags) |
865 | { | 869 | { |
866 | struct urb *urb; | 870 | struct urb *urb; |
@@ -869,39 +873,39 @@ static int uvc_init_video_bulk(struct uvc_video_device *video, | |||
869 | u32 size; | 873 | u32 size; |
870 | 874 | ||
871 | psize = le16_to_cpu(ep->desc.wMaxPacketSize) & 0x07ff; | 875 | psize = le16_to_cpu(ep->desc.wMaxPacketSize) & 0x07ff; |
872 | size = video->streaming->ctrl.dwMaxPayloadTransferSize; | 876 | size = stream->ctrl.dwMaxPayloadTransferSize; |
873 | video->bulk.max_payload_size = size; | 877 | stream->bulk.max_payload_size = size; |
874 | 878 | ||
875 | npackets = uvc_alloc_urb_buffers(video, size, psize, gfp_flags); | 879 | npackets = uvc_alloc_urb_buffers(stream, size, psize, gfp_flags); |
876 | if (npackets == 0) | 880 | if (npackets == 0) |
877 | return -ENOMEM; | 881 | return -ENOMEM; |
878 | 882 | ||
879 | size = npackets * psize; | 883 | size = npackets * psize; |
880 | 884 | ||
881 | if (usb_endpoint_dir_in(&ep->desc)) | 885 | if (usb_endpoint_dir_in(&ep->desc)) |
882 | pipe = usb_rcvbulkpipe(video->dev->udev, | 886 | pipe = usb_rcvbulkpipe(stream->dev->udev, |
883 | ep->desc.bEndpointAddress); | 887 | ep->desc.bEndpointAddress); |
884 | else | 888 | else |
885 | pipe = usb_sndbulkpipe(video->dev->udev, | 889 | pipe = usb_sndbulkpipe(stream->dev->udev, |
886 | ep->desc.bEndpointAddress); | 890 | ep->desc.bEndpointAddress); |
887 | 891 | ||
888 | if (video->streaming->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) | 892 | if (stream->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) |
889 | size = 0; | 893 | size = 0; |
890 | 894 | ||
891 | for (i = 0; i < UVC_URBS; ++i) { | 895 | for (i = 0; i < UVC_URBS; ++i) { |
892 | urb = usb_alloc_urb(0, gfp_flags); | 896 | urb = usb_alloc_urb(0, gfp_flags); |
893 | if (urb == NULL) { | 897 | if (urb == NULL) { |
894 | uvc_uninit_video(video, 1); | 898 | uvc_uninit_video(stream, 1); |
895 | return -ENOMEM; | 899 | return -ENOMEM; |
896 | } | 900 | } |
897 | 901 | ||
898 | usb_fill_bulk_urb(urb, video->dev->udev, pipe, | 902 | usb_fill_bulk_urb(urb, stream->dev->udev, pipe, |
899 | video->urb_buffer[i], size, uvc_video_complete, | 903 | stream->urb_buffer[i], size, uvc_video_complete, |
900 | video); | 904 | stream); |
901 | urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP; | 905 | urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP; |
902 | urb->transfer_dma = video->urb_dma[i]; | 906 | urb->transfer_dma = stream->urb_dma[i]; |
903 | 907 | ||
904 | video->urb[i] = urb; | 908 | stream->urb[i] = urb; |
905 | } | 909 | } |
906 | 910 | ||
907 | return 0; | 911 | return 0; |
@@ -910,35 +914,35 @@ static int uvc_init_video_bulk(struct uvc_video_device *video, | |||
910 | /* | 914 | /* |
911 | * Initialize isochronous/bulk URBs and allocate transfer buffers. | 915 | * Initialize isochronous/bulk URBs and allocate transfer buffers. |
912 | */ | 916 | */ |
913 | static int uvc_init_video(struct uvc_video_device *video, gfp_t gfp_flags) | 917 | static int uvc_init_video(struct uvc_streaming *stream, gfp_t gfp_flags) |
914 | { | 918 | { |
915 | struct usb_interface *intf = video->streaming->intf; | 919 | struct usb_interface *intf = stream->intf; |
916 | struct usb_host_interface *alts; | 920 | struct usb_host_interface *alts; |
917 | struct usb_host_endpoint *ep = NULL; | 921 | struct usb_host_endpoint *ep = NULL; |
918 | int intfnum = video->streaming->intfnum; | 922 | int intfnum = stream->intfnum; |
919 | unsigned int bandwidth, psize, i; | 923 | unsigned int bandwidth, psize, i; |
920 | int ret; | 924 | int ret; |
921 | 925 | ||
922 | video->last_fid = -1; | 926 | stream->last_fid = -1; |
923 | video->bulk.header_size = 0; | 927 | stream->bulk.header_size = 0; |
924 | video->bulk.skip_payload = 0; | 928 | stream->bulk.skip_payload = 0; |
925 | video->bulk.payload_size = 0; | 929 | stream->bulk.payload_size = 0; |
926 | 930 | ||
927 | if (intf->num_altsetting > 1) { | 931 | if (intf->num_altsetting > 1) { |
928 | /* Isochronous endpoint, select the alternate setting. */ | 932 | /* Isochronous endpoint, select the alternate setting. */ |
929 | bandwidth = video->streaming->ctrl.dwMaxPayloadTransferSize; | 933 | bandwidth = stream->ctrl.dwMaxPayloadTransferSize; |
930 | 934 | ||
931 | if (bandwidth == 0) { | 935 | if (bandwidth == 0) { |
932 | uvc_printk(KERN_WARNING, "device %s requested null " | 936 | uvc_printk(KERN_WARNING, "device %s requested null " |
933 | "bandwidth, defaulting to lowest.\n", | 937 | "bandwidth, defaulting to lowest.\n", |
934 | video->vdev->name); | 938 | stream->dev->name); |
935 | bandwidth = 1; | 939 | bandwidth = 1; |
936 | } | 940 | } |
937 | 941 | ||
938 | for (i = 0; i < intf->num_altsetting; ++i) { | 942 | for (i = 0; i < intf->num_altsetting; ++i) { |
939 | alts = &intf->altsetting[i]; | 943 | alts = &intf->altsetting[i]; |
940 | ep = uvc_find_endpoint(alts, | 944 | ep = uvc_find_endpoint(alts, |
941 | video->streaming->header.bEndpointAddress); | 945 | stream->header.bEndpointAddress); |
942 | if (ep == NULL) | 946 | if (ep == NULL) |
943 | continue; | 947 | continue; |
944 | 948 | ||
@@ -952,18 +956,19 @@ static int uvc_init_video(struct uvc_video_device *video, gfp_t gfp_flags) | |||
952 | if (i >= intf->num_altsetting) | 956 | if (i >= intf->num_altsetting) |
953 | return -EIO; | 957 | return -EIO; |
954 | 958 | ||
955 | if ((ret = usb_set_interface(video->dev->udev, intfnum, i)) < 0) | 959 | ret = usb_set_interface(stream->dev->udev, intfnum, i); |
960 | if (ret < 0) | ||
956 | return ret; | 961 | return ret; |
957 | 962 | ||
958 | ret = uvc_init_video_isoc(video, ep, gfp_flags); | 963 | ret = uvc_init_video_isoc(stream, ep, gfp_flags); |
959 | } else { | 964 | } else { |
960 | /* Bulk endpoint, proceed to URB initialization. */ | 965 | /* Bulk endpoint, proceed to URB initialization. */ |
961 | ep = uvc_find_endpoint(&intf->altsetting[0], | 966 | ep = uvc_find_endpoint(&intf->altsetting[0], |
962 | video->streaming->header.bEndpointAddress); | 967 | stream->header.bEndpointAddress); |
963 | if (ep == NULL) | 968 | if (ep == NULL) |
964 | return -EIO; | 969 | return -EIO; |
965 | 970 | ||
966 | ret = uvc_init_video_bulk(video, ep, gfp_flags); | 971 | ret = uvc_init_video_bulk(stream, ep, gfp_flags); |
967 | } | 972 | } |
968 | 973 | ||
969 | if (ret < 0) | 974 | if (ret < 0) |
@@ -971,10 +976,11 @@ static int uvc_init_video(struct uvc_video_device *video, gfp_t gfp_flags) | |||
971 | 976 | ||
972 | /* Submit the URBs. */ | 977 | /* Submit the URBs. */ |
973 | for (i = 0; i < UVC_URBS; ++i) { | 978 | for (i = 0; i < UVC_URBS; ++i) { |
974 | if ((ret = usb_submit_urb(video->urb[i], gfp_flags)) < 0) { | 979 | ret = usb_submit_urb(stream->urb[i], gfp_flags); |
980 | if (ret < 0) { | ||
975 | uvc_printk(KERN_ERR, "Failed to submit URB %u " | 981 | uvc_printk(KERN_ERR, "Failed to submit URB %u " |
976 | "(%d).\n", i, ret); | 982 | "(%d).\n", i, ret); |
977 | uvc_uninit_video(video, 1); | 983 | uvc_uninit_video(stream, 1); |
978 | return ret; | 984 | return ret; |
979 | } | 985 | } |
980 | } | 986 | } |
@@ -993,14 +999,14 @@ static int uvc_init_video(struct uvc_video_device *video, gfp_t gfp_flags) | |||
993 | * video buffers in any way. We mark the device as frozen to make sure the URB | 999 | * video buffers in any way. We mark the device as frozen to make sure the URB |
994 | * completion handler won't try to cancel the queue when we kill the URBs. | 1000 | * completion handler won't try to cancel the queue when we kill the URBs. |
995 | */ | 1001 | */ |
996 | int uvc_video_suspend(struct uvc_video_device *video) | 1002 | int uvc_video_suspend(struct uvc_streaming *stream) |
997 | { | 1003 | { |
998 | if (!uvc_queue_streaming(&video->queue)) | 1004 | if (!uvc_queue_streaming(&stream->queue)) |
999 | return 0; | 1005 | return 0; |
1000 | 1006 | ||
1001 | video->frozen = 1; | 1007 | stream->frozen = 1; |
1002 | uvc_uninit_video(video, 0); | 1008 | uvc_uninit_video(stream, 0); |
1003 | usb_set_interface(video->dev->udev, video->streaming->intfnum, 0); | 1009 | usb_set_interface(stream->dev->udev, stream->intfnum, 0); |
1004 | return 0; | 1010 | return 0; |
1005 | } | 1011 | } |
1006 | 1012 | ||
@@ -1012,22 +1018,24 @@ int uvc_video_suspend(struct uvc_video_device *video) | |||
1012 | * buffers, making sure userspace applications are notified of the problem | 1018 | * buffers, making sure userspace applications are notified of the problem |
1013 | * instead of waiting forever. | 1019 | * instead of waiting forever. |
1014 | */ | 1020 | */ |
1015 | int uvc_video_resume(struct uvc_video_device *video) | 1021 | int uvc_video_resume(struct uvc_streaming *stream) |
1016 | { | 1022 | { |
1017 | int ret; | 1023 | int ret; |
1018 | 1024 | ||
1019 | video->frozen = 0; | 1025 | stream->frozen = 0; |
1020 | 1026 | ||
1021 | if ((ret = uvc_commit_video(video, &video->streaming->ctrl)) < 0) { | 1027 | ret = uvc_commit_video(stream, &stream->ctrl); |
1022 | uvc_queue_enable(&video->queue, 0); | 1028 | if (ret < 0) { |
1029 | uvc_queue_enable(&stream->queue, 0); | ||
1023 | return ret; | 1030 | return ret; |
1024 | } | 1031 | } |
1025 | 1032 | ||
1026 | if (!uvc_queue_streaming(&video->queue)) | 1033 | if (!uvc_queue_streaming(&stream->queue)) |
1027 | return 0; | 1034 | return 0; |
1028 | 1035 | ||
1029 | if ((ret = uvc_init_video(video, GFP_NOIO)) < 0) | 1036 | ret = uvc_init_video(stream, GFP_NOIO); |
1030 | uvc_queue_enable(&video->queue, 0); | 1037 | if (ret < 0) |
1038 | uvc_queue_enable(&stream->queue, 0); | ||
1031 | 1039 | ||
1032 | return ret; | 1040 | return ret; |
1033 | } | 1041 | } |
@@ -1046,48 +1054,53 @@ int uvc_video_resume(struct uvc_video_device *video) | |||
1046 | * | 1054 | * |
1047 | * This function is called before registering the device with V4L. | 1055 | * This function is called before registering the device with V4L. |
1048 | */ | 1056 | */ |
1049 | int uvc_video_init(struct uvc_video_device *video) | 1057 | int uvc_video_init(struct uvc_streaming *stream) |
1050 | { | 1058 | { |
1051 | struct uvc_streaming_control *probe = &video->streaming->ctrl; | 1059 | struct uvc_streaming_control *probe = &stream->ctrl; |
1052 | struct uvc_format *format = NULL; | 1060 | struct uvc_format *format = NULL; |
1053 | struct uvc_frame *frame = NULL; | 1061 | struct uvc_frame *frame = NULL; |
1054 | unsigned int i; | 1062 | unsigned int i; |
1055 | int ret; | 1063 | int ret; |
1056 | 1064 | ||
1057 | if (video->streaming->nformats == 0) { | 1065 | if (stream->nformats == 0) { |
1058 | uvc_printk(KERN_INFO, "No supported video formats found.\n"); | 1066 | uvc_printk(KERN_INFO, "No supported video formats found.\n"); |
1059 | return -EINVAL; | 1067 | return -EINVAL; |
1060 | } | 1068 | } |
1061 | 1069 | ||
1070 | atomic_set(&stream->active, 0); | ||
1071 | |||
1072 | /* Initialize the video buffers queue. */ | ||
1073 | uvc_queue_init(&stream->queue, stream->type); | ||
1074 | |||
1062 | /* Alternate setting 0 should be the default, yet the XBox Live Vision | 1075 | /* Alternate setting 0 should be the default, yet the XBox Live Vision |
1063 | * Cam (and possibly other devices) crash or otherwise misbehave if | 1076 | * Cam (and possibly other devices) crash or otherwise misbehave if |
1064 | * they don't receive a SET_INTERFACE request before any other video | 1077 | * they don't receive a SET_INTERFACE request before any other video |
1065 | * control request. | 1078 | * control request. |
1066 | */ | 1079 | */ |
1067 | usb_set_interface(video->dev->udev, video->streaming->intfnum, 0); | 1080 | usb_set_interface(stream->dev->udev, stream->intfnum, 0); |
1068 | 1081 | ||
1069 | /* Set the streaming probe control with default streaming parameters | 1082 | /* Set the streaming probe control with default streaming parameters |
1070 | * retrieved from the device. Webcams that don't suport GET_DEF | 1083 | * retrieved from the device. Webcams that don't suport GET_DEF |
1071 | * requests on the probe control will just keep their current streaming | 1084 | * requests on the probe control will just keep their current streaming |
1072 | * parameters. | 1085 | * parameters. |
1073 | */ | 1086 | */ |
1074 | if (uvc_get_video_ctrl(video, probe, 1, UVC_GET_DEF) == 0) | 1087 | if (uvc_get_video_ctrl(stream, probe, 1, UVC_GET_DEF) == 0) |
1075 | uvc_set_video_ctrl(video, probe, 1); | 1088 | uvc_set_video_ctrl(stream, probe, 1); |
1076 | 1089 | ||
1077 | /* Initialize the streaming parameters with the probe control current | 1090 | /* Initialize the streaming parameters with the probe control current |
1078 | * value. This makes sure SET_CUR requests on the streaming commit | 1091 | * value. This makes sure SET_CUR requests on the streaming commit |
1079 | * control will always use values retrieved from a successful GET_CUR | 1092 | * control will always use values retrieved from a successful GET_CUR |
1080 | * request on the probe control, as required by the UVC specification. | 1093 | * request on the probe control, as required by the UVC specification. |
1081 | */ | 1094 | */ |
1082 | ret = uvc_get_video_ctrl(video, probe, 1, UVC_GET_CUR); | 1095 | ret = uvc_get_video_ctrl(stream, probe, 1, UVC_GET_CUR); |
1083 | if (ret < 0) | 1096 | if (ret < 0) |
1084 | return ret; | 1097 | return ret; |
1085 | 1098 | ||
1086 | /* Check if the default format descriptor exists. Use the first | 1099 | /* Check if the default format descriptor exists. Use the first |
1087 | * available format otherwise. | 1100 | * available format otherwise. |
1088 | */ | 1101 | */ |
1089 | for (i = video->streaming->nformats; i > 0; --i) { | 1102 | for (i = stream->nformats; i > 0; --i) { |
1090 | format = &video->streaming->format[i-1]; | 1103 | format = &stream->format[i-1]; |
1091 | if (format->index == probe->bFormatIndex) | 1104 | if (format->index == probe->bFormatIndex) |
1092 | break; | 1105 | break; |
1093 | } | 1106 | } |
@@ -1112,21 +1125,20 @@ int uvc_video_init(struct uvc_video_device *video) | |||
1112 | probe->bFormatIndex = format->index; | 1125 | probe->bFormatIndex = format->index; |
1113 | probe->bFrameIndex = frame->bFrameIndex; | 1126 | probe->bFrameIndex = frame->bFrameIndex; |
1114 | 1127 | ||
1115 | video->streaming->cur_format = format; | 1128 | stream->cur_format = format; |
1116 | video->streaming->cur_frame = frame; | 1129 | stream->cur_frame = frame; |
1117 | atomic_set(&video->active, 0); | ||
1118 | 1130 | ||
1119 | /* Select the video decoding function */ | 1131 | /* Select the video decoding function */ |
1120 | if (video->streaming->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { | 1132 | if (stream->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { |
1121 | if (video->dev->quirks & UVC_QUIRK_BUILTIN_ISIGHT) | 1133 | if (stream->dev->quirks & UVC_QUIRK_BUILTIN_ISIGHT) |
1122 | video->decode = uvc_video_decode_isight; | 1134 | stream->decode = uvc_video_decode_isight; |
1123 | else if (video->streaming->intf->num_altsetting > 1) | 1135 | else if (stream->intf->num_altsetting > 1) |
1124 | video->decode = uvc_video_decode_isoc; | 1136 | stream->decode = uvc_video_decode_isoc; |
1125 | else | 1137 | else |
1126 | video->decode = uvc_video_decode_bulk; | 1138 | stream->decode = uvc_video_decode_bulk; |
1127 | } else { | 1139 | } else { |
1128 | if (video->streaming->intf->num_altsetting == 1) | 1140 | if (stream->intf->num_altsetting == 1) |
1129 | video->decode = uvc_video_encode_bulk; | 1141 | stream->decode = uvc_video_encode_bulk; |
1130 | else { | 1142 | else { |
1131 | uvc_printk(KERN_INFO, "Isochronous endpoints are not " | 1143 | uvc_printk(KERN_INFO, "Isochronous endpoints are not " |
1132 | "supported for video output devices.\n"); | 1144 | "supported for video output devices.\n"); |
@@ -1140,31 +1152,32 @@ int uvc_video_init(struct uvc_video_device *video) | |||
1140 | /* | 1152 | /* |
1141 | * Enable or disable the video stream. | 1153 | * Enable or disable the video stream. |
1142 | */ | 1154 | */ |
1143 | int uvc_video_enable(struct uvc_video_device *video, int enable) | 1155 | int uvc_video_enable(struct uvc_streaming *stream, int enable) |
1144 | { | 1156 | { |
1145 | int ret; | 1157 | int ret; |
1146 | 1158 | ||
1147 | if (!enable) { | 1159 | if (!enable) { |
1148 | uvc_uninit_video(video, 1); | 1160 | uvc_uninit_video(stream, 1); |
1149 | usb_set_interface(video->dev->udev, | 1161 | usb_set_interface(stream->dev->udev, stream->intfnum, 0); |
1150 | video->streaming->intfnum, 0); | 1162 | uvc_queue_enable(&stream->queue, 0); |
1151 | uvc_queue_enable(&video->queue, 0); | ||
1152 | return 0; | 1163 | return 0; |
1153 | } | 1164 | } |
1154 | 1165 | ||
1155 | if ((video->streaming->cur_format->flags & UVC_FMT_FLAG_COMPRESSED) || | 1166 | if ((stream->cur_format->flags & UVC_FMT_FLAG_COMPRESSED) || |
1156 | uvc_no_drop_param) | 1167 | uvc_no_drop_param) |
1157 | video->queue.flags &= ~UVC_QUEUE_DROP_INCOMPLETE; | 1168 | stream->queue.flags &= ~UVC_QUEUE_DROP_INCOMPLETE; |
1158 | else | 1169 | else |
1159 | video->queue.flags |= UVC_QUEUE_DROP_INCOMPLETE; | 1170 | stream->queue.flags |= UVC_QUEUE_DROP_INCOMPLETE; |
1160 | 1171 | ||
1161 | if ((ret = uvc_queue_enable(&video->queue, 1)) < 0) | 1172 | ret = uvc_queue_enable(&stream->queue, 1); |
1173 | if (ret < 0) | ||
1162 | return ret; | 1174 | return ret; |
1163 | 1175 | ||
1164 | /* Commit the streaming parameters. */ | 1176 | /* Commit the streaming parameters. */ |
1165 | if ((ret = uvc_commit_video(video, &video->streaming->ctrl)) < 0) | 1177 | ret = uvc_commit_video(stream, &stream->ctrl); |
1178 | if (ret < 0) | ||
1166 | return ret; | 1179 | return ret; |
1167 | 1180 | ||
1168 | return uvc_init_video(video, GFP_KERNEL); | 1181 | return uvc_init_video(stream, GFP_KERNEL); |
1169 | } | 1182 | } |
1170 | 1183 | ||
diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h index fcccf9c9b7ba..3cd9041e22a1 100644 --- a/drivers/media/video/uvc/uvcvideo.h +++ b/drivers/media/video/uvc/uvcvideo.h | |||
@@ -361,26 +361,6 @@ struct uvc_streaming_header { | |||
361 | __u8 bTriggerUsage; | 361 | __u8 bTriggerUsage; |
362 | }; | 362 | }; |
363 | 363 | ||
364 | struct uvc_streaming { | ||
365 | struct list_head list; | ||
366 | |||
367 | struct usb_interface *intf; | ||
368 | int intfnum; | ||
369 | __u16 maxpsize; | ||
370 | |||
371 | struct uvc_streaming_header header; | ||
372 | enum v4l2_buf_type type; | ||
373 | |||
374 | unsigned int nformats; | ||
375 | struct uvc_format *format; | ||
376 | |||
377 | struct uvc_streaming_control ctrl; | ||
378 | struct uvc_format *cur_format; | ||
379 | struct uvc_frame *cur_frame; | ||
380 | |||
381 | struct mutex mutex; | ||
382 | }; | ||
383 | |||
384 | enum uvc_buffer_state { | 364 | enum uvc_buffer_state { |
385 | UVC_BUF_STATE_IDLE = 0, | 365 | UVC_BUF_STATE_IDLE = 0, |
386 | UVC_BUF_STATE_QUEUED = 1, | 366 | UVC_BUF_STATE_QUEUED = 1, |
@@ -422,26 +402,31 @@ struct uvc_video_queue { | |||
422 | struct list_head irqqueue; | 402 | struct list_head irqqueue; |
423 | }; | 403 | }; |
424 | 404 | ||
425 | struct uvc_video_device { | 405 | struct uvc_streaming { |
406 | struct list_head list; | ||
426 | struct uvc_device *dev; | 407 | struct uvc_device *dev; |
427 | struct video_device *vdev; | 408 | struct video_device *vdev; |
428 | atomic_t active; | 409 | atomic_t active; |
429 | unsigned int frozen : 1; | ||
430 | 410 | ||
431 | struct list_head iterms; /* Input terminals */ | 411 | struct usb_interface *intf; |
432 | struct uvc_entity *oterm; /* Output terminal */ | 412 | int intfnum; |
433 | struct uvc_entity *sterm; /* USB streaming terminal */ | 413 | __u16 maxpsize; |
434 | struct uvc_entity *processing; | ||
435 | struct uvc_entity *selector; | ||
436 | struct list_head extensions; | ||
437 | struct mutex ctrl_mutex; | ||
438 | 414 | ||
439 | struct uvc_video_queue queue; | 415 | struct uvc_streaming_header header; |
416 | enum v4l2_buf_type type; | ||
417 | |||
418 | unsigned int nformats; | ||
419 | struct uvc_format *format; | ||
440 | 420 | ||
441 | /* Video streaming object, must always be non-NULL. */ | 421 | struct uvc_streaming_control ctrl; |
442 | struct uvc_streaming *streaming; | 422 | struct uvc_format *cur_format; |
423 | struct uvc_frame *cur_frame; | ||
424 | |||
425 | struct mutex mutex; | ||
443 | 426 | ||
444 | void (*decode) (struct urb *urb, struct uvc_video_device *video, | 427 | unsigned int frozen : 1; |
428 | struct uvc_video_queue queue; | ||
429 | void (*decode) (struct urb *urb, struct uvc_streaming *video, | ||
445 | struct uvc_buffer *buf); | 430 | struct uvc_buffer *buf); |
446 | 431 | ||
447 | /* Context data used by the bulk completion handler. */ | 432 | /* Context data used by the bulk completion handler. */ |
@@ -461,6 +446,18 @@ struct uvc_video_device { | |||
461 | __u8 last_fid; | 446 | __u8 last_fid; |
462 | }; | 447 | }; |
463 | 448 | ||
449 | struct uvc_video_device { | ||
450 | struct uvc_device *dev; | ||
451 | |||
452 | struct list_head iterms; /* Input terminals */ | ||
453 | struct uvc_entity *oterm; /* Output terminal */ | ||
454 | struct uvc_entity *sterm; /* USB streaming terminal */ | ||
455 | struct uvc_entity *processing; | ||
456 | struct uvc_entity *selector; | ||
457 | struct list_head extensions; | ||
458 | struct mutex ctrl_mutex; | ||
459 | }; | ||
460 | |||
464 | enum uvc_device_state { | 461 | enum uvc_device_state { |
465 | UVC_DEV_DISCONNECTED = 1, | 462 | UVC_DEV_DISCONNECTED = 1, |
466 | }; | 463 | }; |
@@ -486,15 +483,15 @@ struct uvc_device { | |||
486 | 483 | ||
487 | struct uvc_video_device video; | 484 | struct uvc_video_device video; |
488 | 485 | ||
486 | /* Video Streaming interfaces */ | ||
487 | struct list_head streams; | ||
488 | |||
489 | /* Status Interrupt Endpoint */ | 489 | /* Status Interrupt Endpoint */ |
490 | struct usb_host_endpoint *int_ep; | 490 | struct usb_host_endpoint *int_ep; |
491 | struct urb *int_urb; | 491 | struct urb *int_urb; |
492 | __u8 *status; | 492 | __u8 *status; |
493 | struct input_dev *input; | 493 | struct input_dev *input; |
494 | char input_phys[64]; | 494 | char input_phys[64]; |
495 | |||
496 | /* Video Streaming interfaces */ | ||
497 | struct list_head streaming; | ||
498 | }; | 495 | }; |
499 | 496 | ||
500 | enum uvc_handle_state { | 497 | enum uvc_handle_state { |
@@ -503,7 +500,8 @@ enum uvc_handle_state { | |||
503 | }; | 500 | }; |
504 | 501 | ||
505 | struct uvc_fh { | 502 | struct uvc_fh { |
506 | struct uvc_video_device *device; | 503 | struct uvc_video_device *video; |
504 | struct uvc_streaming *stream; | ||
507 | enum uvc_handle_state state; | 505 | enum uvc_handle_state state; |
508 | }; | 506 | }; |
509 | 507 | ||
@@ -600,13 +598,13 @@ static inline int uvc_queue_streaming(struct uvc_video_queue *queue) | |||
600 | extern const struct v4l2_file_operations uvc_fops; | 598 | extern const struct v4l2_file_operations uvc_fops; |
601 | 599 | ||
602 | /* Video */ | 600 | /* Video */ |
603 | extern int uvc_video_init(struct uvc_video_device *video); | 601 | extern int uvc_video_init(struct uvc_streaming *stream); |
604 | extern int uvc_video_suspend(struct uvc_video_device *video); | 602 | extern int uvc_video_suspend(struct uvc_streaming *stream); |
605 | extern int uvc_video_resume(struct uvc_video_device *video); | 603 | extern int uvc_video_resume(struct uvc_streaming *stream); |
606 | extern int uvc_video_enable(struct uvc_video_device *video, int enable); | 604 | extern int uvc_video_enable(struct uvc_streaming *stream, int enable); |
607 | extern int uvc_probe_video(struct uvc_video_device *video, | 605 | extern int uvc_probe_video(struct uvc_streaming *stream, |
608 | struct uvc_streaming_control *probe); | 606 | struct uvc_streaming_control *probe); |
609 | extern int uvc_commit_video(struct uvc_video_device *video, | 607 | extern int uvc_commit_video(struct uvc_streaming *stream, |
610 | struct uvc_streaming_control *ctrl); | 608 | struct uvc_streaming_control *ctrl); |
611 | extern int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit, | 609 | extern int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit, |
612 | __u8 intfnum, __u8 cs, void *data, __u16 size); | 610 | __u8 intfnum, __u8 cs, void *data, __u16 size); |
@@ -660,7 +658,7 @@ extern struct usb_host_endpoint *uvc_find_endpoint( | |||
660 | struct usb_host_interface *alts, __u8 epaddr); | 658 | struct usb_host_interface *alts, __u8 epaddr); |
661 | 659 | ||
662 | /* Quirks support */ | 660 | /* Quirks support */ |
663 | void uvc_video_decode_isight(struct urb *urb, struct uvc_video_device *video, | 661 | void uvc_video_decode_isight(struct urb *urb, struct uvc_streaming *stream, |
664 | struct uvc_buffer *buf); | 662 | struct uvc_buffer *buf); |
665 | 663 | ||
666 | #endif /* __KERNEL__ */ | 664 | #endif /* __KERNEL__ */ |