Hello community, here is the log from the commit of package uvcvideo checked in at Thu Jan 24 00:00:41 CET 2008. -------- --- uvcvideo/uvcvideo.changes 2007-12-22 18:00:26.000000000 +0100 +++ /mounts/work_src_done/STABLE/uvcvideo/uvcvideo.changes 2008-01-23 07:42:30.537007000 +0100 @@ -1,0 +2,6 @@ +Wed Jan 23 07:41:34 CET 2008 - bphilips@suse.de + +- r171 skype now works, usb autosuspend support and bug fixes +- SLES-10-SP2 for FATE 303309 + +------------------------------------------------------------------- Old: ---- uvcvideo-r157.tar.bz2 New: ---- uvcvideo-r171.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ uvcvideo.spec ++++++ --- /var/tmp/diff_new_pack.Bw2081/_old 2008-01-24 00:00:26.000000000 +0100 +++ /var/tmp/diff_new_pack.Bw2081/_new 2008-01-24 00:00:26.000000000 +0100 @@ -1,7 +1,7 @@ # -# spec file for package uvcvideo (Version r157) +# spec file for package uvcvideo (Version r171) # -# Copyright (c) 2007 SUSE LINUX Products GmbH, Nuernberg, Germany. +# Copyright (c) 2008 SUSE LINUX Products GmbH, Nuernberg, Germany. # This file and all modifications and additions to the pristine # package are under the same license as the package itself. # @@ -16,7 +16,7 @@ Group: System/Kernel AutoReqProv: on Summary: USB Video Class (UVC) webcam driver -Version: r157 +Version: r171 Release: 1 Source: %name-%version.tar.bz2 Source1: preamble @@ -92,12 +92,15 @@ rm -rf $RPM_BUILD_ROOT %changelog -* Sat Dec 22 2007 - crrodriguez@suse.de +* Wed Jan 23 2008 bphilips@suse.de +- r171 skype now works, usb autosuspend support and bug fixes +- SLES-10-SP2 for FATE 303309 +* Sat Dec 22 2007 crrodriguez@suse.de - r157, merge uvc_input_header and uvc_output_header into uvc_streaming_header -* Tue Dec 18 2007 - crrodriguez@suse.de +* Tue Dec 18 2007 crrodriguez@suse.de - update to r156, most important change is the merge of isight patch into the official codebase -* Wed Dec 05 2007 - ro@suse.de +* Wed Dec 05 2007 ro@suse.de - updated isight patch from http://www.i-nz.net/files/projects/linux-kernel/isight/isight.patch - update to r148 @@ -111,7 +114,7 @@ 2.6.24-rc1. Remove references. - Fix UVC version checking - added kmp preamble -* Sat Nov 10 2007 - bwalle@suse.de +* Sat Nov 10 2007 bwalle@suse.de - add grep and coreutils as pre-requirements - update to r141 upstream version o The unused video_device structure hardware field has been @@ -150,7 +153,7 @@ o Increase control timeout to 1s for streaming controls. o Removed unused uvc_stream_state enumeration o Support for Acer OrbiCam (unknown vendor) -* Tue Jul 24 2007 - ro@suse.de +* Tue Jul 24 2007 ro@suse.de - update to r117 - Removed unused uvc_stream_state enumeration - update to r116 @@ -167,7 +170,7 @@ - update to r111 - Support for OEM webcam found in some Acer notebooks (unknown vendor) - hacked iSight patch to work with current code -* Fri Jun 15 2007 - ro@suse.de +* Fri Jun 15 2007 ro@suse.de - update to r110 - Input selection support - update to r109 @@ -197,26 +200,26 @@ - update to r98 - update to r97 - update to r96 -* Fri Apr 20 2007 - ro@suse.de +* Fri Apr 20 2007 ro@suse.de - update to r95 and add isight patch -* Thu Apr 19 2007 - ro@suse.de +* Thu Apr 19 2007 ro@suse.de - no debuginfo (no main package) -* Wed Apr 04 2007 - lrupp@suse.de +* Wed Apr 04 2007 lrupp@suse.de - added module-init-tools to BuildRequires -* Mon Mar 26 2007 - bwalle@suse.de +* Mon Mar 26 2007 bwalle@suse.de - include flavours but instead of excluding them to fix build on IA64 -* Sun Mar 25 2007 - ro@suse.de +* Sun Mar 25 2007 ro@suse.de - added KMP subpackage to specfile (transport for PDB data) -* Wed Mar 21 2007 - bwalle@suse.de +* Wed Mar 21 2007 bwalle@suse.de - exclude s390, s390x - build only for default + bigsmp kernel -* Fri Mar 16 2007 - bwalle@suse.de +* Fri Mar 16 2007 bwalle@suse.de - don't clean the buildroot before installing (http://lists.opensuse.org/opensuse-packaging/2007-02/msg00005.html) -* Thu Mar 15 2007 - bwalle@suse.de +* Thu Mar 15 2007 bwalle@suse.de - removed supplements tags - added real author - fixed modaliases -* Wed Feb 07 2007 - wstephenson@suse.de +* Wed Feb 07 2007 wstephenson@suse.de - Initial package ++++++ uvcvideo-r157.tar.bz2 -> uvcvideo-r171.tar.bz2 ++++++ Files old/uvcvideo-r157/dynctrl.txt and new/uvcvideo-r171/dynctrl.txt differ diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/uvcvideo-r157/uvc_compat.h new/uvcvideo-r171/uvc_compat.h --- old/uvcvideo-r157/uvc_compat.h 2007-11-09 10:29:38.000000000 +0100 +++ new/uvcvideo-r171/uvc_compat.h 2008-01-19 01:40:15.000000000 +0100 @@ -243,6 +243,18 @@ { return (usb_endpoint_xfer_int(epd) && usb_endpoint_dir_in(epd)); } + +/* + * USB auto suspend + * + * Included in Linux 2.6.19 + */ +static inline int usb_autopm_get_interface(struct usb_interface *intf) +{ return 0; } + +static inline void usb_autopm_put_interface(struct usb_interface *intf) +{ } + #endif #endif /* __KERNEL__ */ diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/uvcvideo-r157/uvc_ctrl.c new/uvcvideo-r171/uvc_ctrl.c --- old/uvcvideo-r157/uvc_ctrl.c 2007-12-18 01:15:36.000000000 +0100 +++ new/uvcvideo-r171/uvc_ctrl.c 2008-01-19 01:40:15.000000000 +0100 @@ -126,6 +126,14 @@ }, { .entity = UVC_GUID_UVC_CAMERA, + .selector = CT_AE_PRIORITY_CONTROL, + .index = 2, + .size = 1, + .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR + | UVC_CONTROL_RESTORE, + }, + { + .entity = UVC_GUID_UVC_CAMERA, .selector = CT_EXPOSURE_TIME_ABSOLUTE_CONTROL, .index = 3, .size = 4, @@ -172,6 +180,13 @@ { 2, "60 Hz" }, }; +static struct uvc_menu_info exposure_auto_controls[] = { + { 1, "Manual Mode" }, + { 2, "Auto Mode" }, + { 4, "Shutter Priority Mode" }, + { 8, "Aperture Priority Mode" }, +}; + static struct uvc_control_mapping uvc_ctrl_mappings[] = { { .id = V4L2_CID_BRIGHTNESS, @@ -282,8 +297,20 @@ .selector = CT_AE_MODE_CONTROL, .size = 4, .offset = 0, - .v4l2_type = V4L2_CTRL_TYPE_INTEGER, + .v4l2_type = V4L2_CTRL_TYPE_MENU, .data_type = UVC_CTRL_DATA_TYPE_BITMASK, + .menu_info = exposure_auto_controls, + .menu_count = ARRAY_SIZE(exposure_auto_controls), + }, + { + .id = V4L2_CID_EXPOSURE_AUTO_PRIORITY, + .name = "Exposure, Auto Priority", + .entity = UVC_GUID_UVC_CAMERA, + .selector = CT_AE_PRIORITY_CONTROL, + .size = 1, + .offset = 0, + .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN, + .data_type = UVC_CTRL_DATA_TYPE_BOOLEAN, }, { .id = V4L2_CID_EXPOSURE_ABSOLUTE, diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/uvcvideo-r157/uvc_driver.c new/uvcvideo-r171/uvc_driver.c --- old/uvcvideo-r157/uvc_driver.c 2007-12-18 01:15:36.000000000 +0100 +++ new/uvcvideo-r171/uvc_driver.c 2008-01-19 01:40:15.000000000 +0100 @@ -370,7 +370,7 @@ return -EINVAL; } - switch (buffer[8]) { + switch (buffer[8] & 0x7f) { case 0: strncpy(format->name, "SD-DV", sizeof format->name); break; @@ -388,6 +388,9 @@ return -EINVAL; } + strncat(format->name, buffer[8] & (1 << 7) ? " 60Hz" : " 50Hz", + sizeof format->name); + format->fcc = V4L2_PIX_FMT_DV; format->flags = UVC_FMT_FLAG_COMPRESSED | UVC_FMT_FLAG_STREAM; format->bpp = 0; @@ -867,6 +870,8 @@ if (uvc_parse_streaming(dev, streaming) < 0) { usb_put_intf(intf); + kfree(streaming->format); + kfree(streaming->header.bmaControls); kfree(streaming); continue; } @@ -1661,8 +1666,7 @@ .bInterfaceClass = USB_CLASS_VIDEO, .bInterfaceSubClass = 1, .bInterfaceProtocol = 0, - .driver_info = UVC_QUIRK_PROBE_MINMAX - }, + .driver_info = UVC_QUIRK_PROBE_MINMAX }, /* Creative Live! Optia */ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, @@ -1671,15 +1675,7 @@ .bInterfaceClass = USB_CLASS_VIDEO, .bInterfaceSubClass = 1, .bInterfaceProtocol = 0, - .driver_info = UVC_QUIRK_PROBE_MINMAX - }, - /* Apple Built-In iSight */ - { .match_flags = USB_DEVICE_ID_MATCH_DEVICE, - .idVendor = 0x05ac, - .idProduct = 0x8501, - .driver_info = UVC_QUIRK_PROBE_MINMAX - | UVC_QUIRK_BUILTIN_ISIGHT - }, + .driver_info = UVC_QUIRK_PROBE_MINMAX }, /* Microsoft Lifecam NX-6000 */ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, @@ -1737,6 +1733,12 @@ .bInterfaceClass = USB_CLASS_VENDOR_SPEC, .bInterfaceSubClass = 1, .bInterfaceProtocol = 0 }, + /* Apple Built-In iSight */ + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE, + .idVendor = 0x05ac, + .idProduct = 0x8501, + .driver_info = UVC_QUIRK_PROBE_MINMAX + | UVC_QUIRK_BUILTIN_ISIGHT }, /* Silicon Motion SM371 */ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, @@ -1745,8 +1747,25 @@ .bInterfaceClass = USB_CLASS_VIDEO, .bInterfaceSubClass = 1, .bInterfaceProtocol = 0, - .driver_info = UVC_QUIRK_PROBE_MINMAX - }, + .driver_info = UVC_QUIRK_PROBE_MINMAX }, + /* MT6227 */ + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x0e8d, + .idProduct = 0x0004, + .bInterfaceClass = USB_CLASS_VIDEO, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, + .driver_info = UVC_QUIRK_PROBE_MINMAX }, + /* Syntek (HP Spartan) */ + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x174f, + .idProduct = 0x5212, + .bInterfaceClass = USB_CLASS_VIDEO, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, + .driver_info = UVC_QUIRK_STREAM_NO_FID }, /* Ecamm Pico iMage */ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, @@ -1755,8 +1774,7 @@ .bInterfaceClass = USB_CLASS_VIDEO, .bInterfaceSubClass = 1, .bInterfaceProtocol = 0, - .driver_info = UVC_QUIRK_PROBE_EXTRAFIELDS - }, + .driver_info = UVC_QUIRK_PROBE_EXTRAFIELDS }, /* Bodelin ProScopeHR */ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, @@ -1765,8 +1783,7 @@ .bInterfaceClass = USB_CLASS_VIDEO, .bInterfaceSubClass = 1, .bInterfaceProtocol = 0, - .driver_info = UVC_QUIRK_STATUS_INTERVAL - }, + .driver_info = UVC_QUIRK_STATUS_INTERVAL }, /* Acer OEM Webcam - Unknown vendor */ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, @@ -1775,8 +1792,7 @@ .bInterfaceClass = USB_CLASS_VIDEO, .bInterfaceSubClass = 1, .bInterfaceProtocol = 0, - .driver_info = UVC_QUIRK_PROBE_MINMAX - }, + .driver_info = UVC_QUIRK_PROBE_MINMAX }, /* Acer Crystal Eye webcam */ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, @@ -1785,8 +1801,7 @@ .bInterfaceClass = USB_CLASS_VIDEO, .bInterfaceSubClass = 1, .bInterfaceProtocol = 0, - .driver_info = UVC_QUIRK_PROBE_MINMAX - }, + .driver_info = UVC_QUIRK_PROBE_MINMAX }, /* Acer OrbiCam - Unknown vendor */ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, @@ -1795,8 +1810,7 @@ .bInterfaceClass = USB_CLASS_VIDEO, .bInterfaceSubClass = 1, .bInterfaceProtocol = 0, - .driver_info = UVC_QUIRK_PROBE_MINMAX - }, + .driver_info = UVC_QUIRK_PROBE_MINMAX }, /* Generic USB Video Class */ { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, 0) }, {} @@ -1815,6 +1829,9 @@ .suspend = uvc_suspend, .resume = uvc_resume, .id_table = uvc_ids, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19) + .supports_autosuspend = 1, +#endif }, }; diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/uvcvideo-r157/uvc_isight.c new/uvcvideo-r171/uvc_isight.c --- old/uvcvideo-r157/uvc_isight.c 2007-12-15 16:47:25.000000000 +0100 +++ new/uvcvideo-r171/uvc_isight.c 2008-01-19 01:40:15.000000000 +0100 @@ -104,7 +104,7 @@ return 0; } -void uvc_video_decode_isight (struct urb *urb, struct uvc_video_queue *queue, +void uvc_video_decode_isight (struct urb *urb, struct uvc_video_device *video, struct uvc_buffer *buf) { int ret, i; @@ -125,7 +125,7 @@ * processes the data of the first payload of the new frame. */ do { - ret = isight_decode(queue, buf, + ret = isight_decode(&video->queue, buf, urb->transfer_buffer + urb->iso_frame_desc[i].offset, urb->iso_frame_desc[i].actual_length); @@ -134,7 +134,7 @@ if (buf->state == UVC_BUF_STATE_DONE || buf->state == UVC_BUF_STATE_ERROR) - buf = uvc_queue_next_buffer(queue, buf); + buf = uvc_queue_next_buffer(&video->queue, buf); } while (ret == -EAGAIN); } } diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/uvcvideo-r157/uvc_queue.c new/uvcvideo-r171/uvc_queue.c --- old/uvcvideo-r157/uvc_queue.c 2007-12-18 01:15:36.000000000 +0100 +++ new/uvcvideo-r171/uvc_queue.c 2008-01-19 01:40:15.000000000 +0100 @@ -128,7 +128,6 @@ for (i = 0; i < nbuffers; ++i) { memset(&queue->buffer[i], 0, sizeof queue->buffer[i]); - queue->buffer[i].size = bufsize; queue->buffer[i].buf.index = i; queue->buffer[i].buf.m.offset = i * bufsize; queue->buffer[i].buf.length = buflength; @@ -142,6 +141,7 @@ queue->mem = mem; queue->count = nbuffers; + queue->buf_size = bufsize; ret = nbuffers; done: @@ -166,7 +166,7 @@ if (queue->count) { #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15) unsigned long addr = (unsigned long)queue->mem; - size_t size = queue->count * queue->buffer[0].size; + size_t size = queue->count * queue->buf_size; while (size > 0) { ClearPageReserved(vmalloc_to_page((void*)addr)); addr += PAGE_SIZE; @@ -348,12 +348,8 @@ ret = -EBUSY; goto done; } - queue->last_fid = -1; queue->sequence = 0; queue->streaming = 1; - queue->bulk.header_size = -1; - queue->bulk.skip_payload = 0; - queue->bulk.payload_size = 0; } else { uvc_queue_cancel(queue); diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/uvcvideo-r157/uvc_v4l2.c new/uvcvideo-r171/uvc_v4l2.c --- old/uvcvideo-r157/uvc_v4l2.c 2007-11-09 10:29:38.000000000 +0100 +++ new/uvcvideo-r171/uvc_v4l2.c 2008-01-19 01:40:15.000000000 +0100 @@ -249,6 +249,9 @@ if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; + if (video->queue.streaming) + return -EBUSY; + ret = uvc_v4l2_try_format(video, fmt, &probe, &format, &frame); if (ret < 0) return ret; @@ -298,6 +301,9 @@ if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; + if (video->queue.streaming) + return -EBUSY; + memcpy(&probe, &video->streaming->ctrl, sizeof probe); interval = uvc_fraction_to_interval( parm->parm.capture.timeperframe.numerator, @@ -350,11 +356,11 @@ * * Operations which require privileges are: * - * - VIDIO_S_INPUT - * - VIDIO_S_PARM - * - VIDIO_S_FMT - * - VIDIO_TRY_FMT - * - VIDIO_REQBUFS + * - VIDIOC_S_INPUT + * - VIDIOC_S_PARM + * - VIDIOC_S_FMT + * - VIDIOC_TRY_FMT + * - VIDIOC_REQBUFS */ static int uvc_acquire_privileges(struct uvc_fh *handle) { @@ -366,8 +372,8 @@ /* Check if the device already has a privileged handle. */ mutex_lock(&uvc_driver.open_mutex); - if (!atomic_dec_and_test(&handle->device->active)) { - atomic_inc(&handle->device->active); + if (atomic_inc_return(&handle->device->active) != 1) { + atomic_dec(&handle->device->active); ret = -EBUSY; goto done; } @@ -382,7 +388,7 @@ static void uvc_dismiss_privileges(struct uvc_fh *handle) { if (handle->state == UVC_HANDLE_ACTIVE) - atomic_inc(&handle->device->active); + atomic_dec(&handle->device->active); handle->state = UVC_HANDLE_PASSIVE; } @@ -413,9 +419,14 @@ goto done; } + ret = usb_autopm_get_interface(video->dev->intf); + if (ret < 0) + goto done; + /* Create the device handle. */ handle = kzalloc(sizeof *handle, GFP_KERNEL); if (handle == NULL) { + usb_autopm_put_interface(video->dev->intf); ret = -ENOMEM; goto done; } @@ -455,6 +466,7 @@ kfree(handle); file->private_data = NULL; + usb_autopm_put_interface(video->dev->intf); kref_put(&video->dev->kref, uvc_delete); return 0; } @@ -1027,7 +1039,7 @@ } } - if (buffer == NULL || size != buffer->size) { + if (buffer == NULL || size != video->queue.buf_size) { ret = -EINVAL; goto done; } diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/uvcvideo-r157/uvc_video.c new/uvcvideo-r171/uvc_video.c --- old/uvcvideo-r157/uvc_video.c 2007-12-18 01:15:36.000000000 +0100 +++ new/uvcvideo-r171/uvc_video.c 2008-01-21 23:06:19.000000000 +0100 @@ -195,6 +195,9 @@ (ret = uvc_get_video_ctrl(video, probe, 1, GET_CUR)) < 0) goto done; + if (video->streaming->intf->num_altsetting == 1) + break; + bandwidth = probe->dwMaxPayloadTransferSize; if (bandwidth <= video->streaming->maxpsize) break; @@ -265,7 +268,7 @@ * to be called with a NULL buf parameter. uvc_video_decode_data and * uvc_video_decode_end will never be called with a NULL buffer. */ -static int uvc_video_decode_start(struct uvc_video_queue *queue, +static int uvc_video_decode_start(struct uvc_video_device *video, struct uvc_buffer *buf, const __u8 *data, int len) { __u8 fid; @@ -290,7 +293,7 @@ * NULL. */ if (buf == NULL) { - queue->last_fid = fid; + video->last_fid = fid; return -ENODATA; } @@ -298,11 +301,17 @@ * toggled when the the buffer state is not UVC_BUF_STATE_ACTIVE. * queue->last_fid is initialized to -1, so the first isochronous * frame will always be in sync. + * + * If the device doesn't toggle the FID bit, invert video->last_fid + * when the EOF bit is set to force synchronisation on the next packet. */ if (buf->state != UVC_BUF_STATE_ACTIVE) { - if (fid == queue->last_fid) { + if (fid == video->last_fid) { uvc_trace(UVC_TRACE_FRAME, "Dropping payload (out of " "sync).\n"); + if ((video->dev->quirks & UVC_QUIRK_STREAM_NO_FID) && + (data[1] & UVC_STREAM_EOF)) + video->last_fid ^= UVC_STREAM_FID; return -ENODATA; } @@ -325,21 +334,22 @@ * avoids detecting and of frame conditions at FID toggling if the * previous payload had the EOF bit set. */ - if (fid != queue->last_fid && buf->buf.bytesused != 0) { + if (fid != video->last_fid && buf->buf.bytesused != 0) { uvc_trace(UVC_TRACE_FRAME, "Frame complete (FID bit " "toggled).\n"); buf->state = UVC_BUF_STATE_DONE; return -EAGAIN; } - queue->last_fid = fid; + video->last_fid = fid; return data[0]; } -static void uvc_video_decode_data(struct uvc_video_queue *queue, +static void uvc_video_decode_data(struct uvc_video_device *video, struct uvc_buffer *buf, const __u8 *data, int len) { + struct uvc_video_queue *queue = &video->queue; unsigned int maxlen, nbytes; void *mem; @@ -360,7 +370,7 @@ } } -static void uvc_video_decode_end(struct uvc_video_queue *queue, +static void uvc_video_decode_end(struct uvc_video_device *video, struct uvc_buffer *buf, const __u8 *data, int len) { /* Mark the buffer as done if the EOF marker is set. */ @@ -369,6 +379,8 @@ if (data[0] == len) uvc_trace(UVC_TRACE_FRAME, "EOF in empty payload.\n"); buf->state = UVC_BUF_STATE_DONE; + if (video->dev->quirks & UVC_QUIRK_STREAM_NO_FID) + video->last_fid ^= UVC_STREAM_FID; } } @@ -380,7 +392,7 @@ * Completion handler for video URBs. */ static void uvc_video_decode_isoc(struct urb *urb, - struct uvc_video_queue *queue, struct uvc_buffer *buf) + struct uvc_video_device *video, struct uvc_buffer *buf) { u8 *mem; int ret, i; @@ -395,56 +407,56 @@ /* Decode the payload header. */ mem = urb->transfer_buffer + urb->iso_frame_desc[i].offset; do { - ret = uvc_video_decode_start(queue, buf, mem, + ret = uvc_video_decode_start(video, buf, mem, urb->iso_frame_desc[i].actual_length); if (ret == -EAGAIN) - buf = uvc_queue_next_buffer(queue, buf); + buf = uvc_queue_next_buffer(&video->queue, buf); } while (ret == -EAGAIN); if (ret < 0) continue; /* Decode the payload data. */ - uvc_video_decode_data(queue, buf, mem + ret, + uvc_video_decode_data(video, buf, mem + ret, urb->iso_frame_desc[i].actual_length - ret); /* Process the header again. */ - uvc_video_decode_end(queue, buf, mem, ret); + uvc_video_decode_end(video, buf, mem, ret); if (buf->state == UVC_BUF_STATE_DONE || buf->state == UVC_BUF_STATE_ERROR) - buf = uvc_queue_next_buffer(queue, buf); + buf = uvc_queue_next_buffer(&video->queue, buf); } } static void uvc_video_decode_bulk(struct urb *urb, - struct uvc_video_queue *queue, struct uvc_buffer *buf) + struct uvc_video_device *video, struct uvc_buffer *buf) { u8 *mem; int len, ret; mem = urb->transfer_buffer; len = urb->actual_length; - queue->bulk.payload_size += len; + video->bulk.payload_size += len; /* If the URB is the first of its payload, decode and save the * header. */ - if (queue->bulk.header_size == -1) { + if (video->bulk.header_size == 0) { do { - ret = uvc_video_decode_start(queue, buf, mem, len); + ret = uvc_video_decode_start(video, buf, mem, len); if (ret == -EAGAIN) - buf = uvc_queue_next_buffer(queue, buf); + buf = uvc_queue_next_buffer(&video->queue, buf); } while (ret == -EAGAIN); /* If an error occured skip the rest of the payload. */ if (ret < 0 || buf == NULL) { - queue->bulk.skip_payload = 1; + video->bulk.skip_payload = 1; return; } - queue->bulk.header_size = ret; - memcpy(queue->bulk.header, mem, queue->bulk.header_size); + video->bulk.header_size = ret; + memcpy(video->bulk.header, mem, video->bulk.header_size); mem += ret; len -= ret; @@ -456,25 +468,25 @@ */ /* Process video data. */ - if (!queue->bulk.skip_payload && buf != NULL) - uvc_video_decode_data(queue, buf, mem, len); + if (!video->bulk.skip_payload && buf != NULL) + uvc_video_decode_data(video, buf, mem, len); /* Detect the payload end by a URB smaller than the maximum size (or * a payload size equal to the maximum) and process the header again. */ if (urb->actual_length < urb->transfer_buffer_length || - queue->bulk.payload_size >= queue->bulk.max_payload_size) { - if (!queue->bulk.skip_payload && buf != NULL) { - uvc_video_decode_end(queue, buf, queue->bulk.header, - queue->bulk.header_size); + video->bulk.payload_size >= video->bulk.max_payload_size) { + if (!video->bulk.skip_payload && buf != NULL) { + uvc_video_decode_end(video, buf, video->bulk.header, + video->bulk.header_size); if (buf->state == UVC_BUF_STATE_DONE || buf->state == UVC_BUF_STATE_ERROR) - buf = uvc_queue_next_buffer(queue, buf); + buf = uvc_queue_next_buffer(&video->queue, buf); } - queue->bulk.header_size = -1; - queue->bulk.skip_payload = 0; - queue->bulk.payload_size = 0; + video->bulk.header_size = 0; + video->bulk.skip_payload = 0; + video->bulk.payload_size = 0; } } @@ -484,7 +496,8 @@ static void uvc_video_complete(struct urb *urb) #endif { - struct uvc_video_queue *queue = urb->context; + struct uvc_video_device *video = urb->context; + struct uvc_video_queue *queue = &video->queue; struct uvc_buffer *buf = NULL; unsigned long flags; int ret; @@ -512,7 +525,7 @@ buf = list_entry(queue->irqqueue.next, struct uvc_buffer, queue); spin_unlock_irqrestore(&queue->irqlock, flags); - queue->decode(urb, queue, buf); + video->decode(urb, video, buf); if ((ret = usb_submit_urb(urb, GFP_ATOMIC)) < 0) { uvc_printk(KERN_ERR, "Failed to resubmit video URB (%d).\n", @@ -592,7 +605,7 @@ } urb->dev = video->dev->udev; - urb->context = &video->queue; + urb->context = video; urb->pipe = usb_rcvisocpipe(video->dev->udev, ep->desc.bEndpointAddress); urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP; @@ -632,7 +645,7 @@ */ psize = le16_to_cpu(ep->desc.wMaxPacketSize) & 0x07ff; size = video->streaming->ctrl.dwMaxPayloadTransferSize; - video->queue.bulk.max_payload_size = size; + video->bulk.max_payload_size = size; if (size > psize * UVC_MAX_ISO_PACKETS) size = psize * UVC_MAX_ISO_PACKETS; @@ -655,7 +668,7 @@ usb_fill_bulk_urb(urb, video->dev->udev, pipe, video->urb_buffer[i], size, uvc_video_complete, - &video->queue); + video); urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP; video->urb[i] = urb; @@ -676,6 +689,11 @@ unsigned int bandwidth, psize, i; int ret; + video->last_fid = -1; + video->bulk.header_size = 0; + video->bulk.skip_payload = 0; + video->bulk.payload_size = 0; + if (intf->num_altsetting > 1) { /* Isochronous endpoint, select the alternate setting. */ bandwidth = video->streaming->ctrl.dwMaxPayloadTransferSize; @@ -859,15 +877,15 @@ video->streaming->cur_format = format; video->streaming->cur_frame = frame; - atomic_set(&video->active, 1); + atomic_set(&video->active, 0); /* Select the video decoding function */ if (video->dev->quirks & UVC_QUIRK_BUILTIN_ISIGHT) - video->queue.decode = uvc_video_decode_isight; + video->decode = uvc_video_decode_isight; else if (video->streaming->intf->num_altsetting > 1) - video->queue.decode = uvc_video_decode_isoc; + video->decode = uvc_video_decode_isoc; else - video->queue.decode = uvc_video_decode_bulk; + video->decode = uvc_video_decode_bulk; return 0; } diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/uvcvideo-r157/uvcvideo.h new/uvcvideo-r171/uvcvideo.h --- old/uvcvideo-r157/uvcvideo.h 2007-12-18 01:15:36.000000000 +0100 +++ new/uvcvideo-r171/uvcvideo.h 2008-01-19 01:40:15.000000000 +0100 @@ -26,11 +26,12 @@ #define V4L2_CID_EXPOSURE_AUTO (V4L2_CID_PRIVATE_BASE+10) #define V4L2_CID_EXPOSURE_ABSOLUTE (V4L2_CID_PRIVATE_BASE+11) +#define V4L2_CID_EXPOSURE_AUTO_PRIORITY (V4L2_CID_PRIVATE_BASE+14) #define V4L2_CID_WHITE_BALANCE_TEMPERATURE_AUTO (V4L2_CID_PRIVATE_BASE+12) #define V4L2_CID_WHITE_BALANCE_TEMPERATURE (V4L2_CID_PRIVATE_BASE+13) -#define V4L2_CID_PRIVATE_LAST V4L2_CID_WHITE_BALANCE_TEMPERATURE +#define V4L2_CID_PRIVATE_LAST V4L2_CID_EXPOSURE_AUTO_PRIORITY /* * Dynamic controls @@ -312,6 +313,7 @@ #define UVC_QUIRK_PROBE_MINMAX 0x00000002 #define UVC_QUIRK_PROBE_EXTRAFIELDS 0x00000004 #define UVC_QUIRK_BUILTIN_ISIGHT 0x00000008 +#define UVC_QUIRK_STREAM_NO_FID 0x00000010 /* Format flags */ #define UVC_FMT_FLAG_COMPRESSED 0x00000001 @@ -538,7 +540,6 @@ }; struct uvc_buffer { - unsigned int size; unsigned long vma_use_count; struct list_head stream; @@ -554,27 +555,15 @@ unsigned int streaming : 1, frozen : 1; __u32 sequence; - __u8 last_fid; - - /* Context data used by the bulk completion handler. */ - struct { - __u8 header[256]; - int header_size; - int skip_payload; - __u32 payload_size; - __u32 max_payload_size; - } bulk; unsigned int count; + unsigned int buf_size; struct uvc_buffer buffer[UVC_MAX_VIDEO_BUFFERS]; struct mutex mutex; spinlock_t irqlock; struct list_head mainqueue; struct list_head irqqueue; - - void (*decode) (struct urb *urb, struct uvc_video_queue *queue, - struct uvc_buffer *buf); }; struct uvc_video_device { @@ -594,8 +583,22 @@ /* Video streaming object, must always be non-NULL. */ struct uvc_streaming *streaming; + void (*decode) (struct urb *urb, struct uvc_video_device *video, + struct uvc_buffer *buf); + + /* Context data used by the bulk completion handler. */ + struct { + __u8 header[256]; + unsigned int header_size; + int skip_payload; + __u32 payload_size; + __u32 max_payload_size; + } bulk; + struct urb *urb[UVC_URBS]; char *urb_buffer[UVC_URBS]; + + __u8 last_fid; }; enum uvc_device_state { @@ -769,7 +772,7 @@ struct usb_host_interface *alts, __u8 epaddr); /* Quirks support */ -void uvc_video_decode_isight (struct urb *urb, struct uvc_video_queue *queue, +void uvc_video_decode_isight (struct urb *urb, struct uvc_video_device *video, struct uvc_buffer *buf); #endif /* __KERNEL__ */ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Remember to have fun... --------------------------------------------------------------------- To unsubscribe, e-mail: opensuse-commit+unsubscribe@opensuse.org For additional commands, e-mail: opensuse-commit+help@opensuse.org
participants (1)
-
root@Hilbert.suse.de