Received: by 2002:a05:6a10:c7c6:0:0:0:0 with SMTP id h6csp2555077pxy; Tue, 3 Aug 2021 09:06:03 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxXuSMO2TTccxc+w+2ZR4Kdvwmycq5ibW9EFw3Y7E2wwOQsIlsgnq0wAdX90ooS/NOSo1nC X-Received: by 2002:a05:6602:2f09:: with SMTP id q9mr2145353iow.196.1628006763522; Tue, 03 Aug 2021 09:06:03 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1628006763; cv=none; d=google.com; s=arc-20160816; b=G7qR6HO1zo8mt/519s8VfBc/MrfBXjddmFlSqIIfYN1Xl0gC9uN/X9Q72mylC6BnaZ Y8m406aPvGO+sXLXQGEvXDQEYYs0kqm5sHDpAdSyP1jbrYr93YJjWbjF5l8CBHaJMoT8 vNYKsbK8LAVylO6s+hif2d0/umHSD2H443ED0nDs/hCe4N3DFjLIroxFa42luG2Aed4S j0XaxXs0rvQraHVsoIKmVg9wRI6qAhgPOza3cZr0oGvkyASIY+c5TTb5z6+9fR7860xQ KoC1I1HNCfoOyBM6ivmScvK0ZYP8VQ0aWq9ZdjOQzyML/+OOX2iuVW3EId9nDl38yG52 tATg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:mime-version:user-agent:references:message-id :in-reply-to:subject:cc:to:from:date; bh=4rXaK1UwtYYkNBcGmc3iSh8/AcLyum8cAsX3gWBcYY0=; b=iQVDIy44hyoZ0euQdF2vD4sWKyFVmsc8twuFf5gO6Wq5br+S5AKQQtVEZPZXDckKRO IMWDAZEjhFAEoGPbkSMQviQC7fkBDRoc37FVPGag3wI5VLZ6ZNYZfZVHvQI00dtaTKzj z6AjO+bA3QEySuL5IJGQcprI43axYJTcy8VNL5PD1mYOOAfc8z0dLGN05ADvkLgbVKbq GaQ8Qk4fr1QdVyldfKWcO7f9W8HGbRDVVGLhJT2x9VRLyXs6btrYeUXXvillHbq7uQ4Z z2yODfNELeebk9g5eF04dwpITnpcP7dxygb7gA49eVFShrgY9cl99oqY9pDiJ90UIOQ/ vL8w== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=fields.utoronto.ca Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id y11si16950053ilc.54.2021.08.03.09.05.38; Tue, 03 Aug 2021 09:06:03 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=fields.utoronto.ca Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231825AbhHCQEy (ORCPT + 99 others); Tue, 3 Aug 2021 12:04:54 -0400 Received: from gfs2.fields.utoronto.ca ([128.100.216.21]:43722 "EHLO gfs2.fields.utoronto.ca" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231688AbhHCQEt (ORCPT ); Tue, 3 Aug 2021 12:04:49 -0400 Received: from fields.fields.utoronto.ca (fields.fields.utoronto.ca [128.100.216.11]) by gfs2.fields.utoronto.ca (8.15.2/8.15.2/Fields_9.1_server_1625693608) with ESMTPS id 173G4TBJ018403 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Tue, 3 Aug 2021 12:04:29 -0400 Received: from fields.fields.utoronto.ca (localhost [127.0.0.1]) by fields.fields.utoronto.ca (8.15.2/8.15.2/Fields_9.1_workstation_1) with ESMTPS id 173G4TsO004962 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Tue, 3 Aug 2021 12:04:29 -0400 Received: from localhost (pspencer@localhost) by fields.fields.utoronto.ca (8.15.2/8.15.2/Submit) with ESMTP id 173G4T4H004959; Tue, 3 Aug 2021 12:04:29 -0400 Date: Tue, 3 Aug 2021 12:04:29 -0400 (EDT) From: Philip Spencer To: Laurent Pinchart cc: Mauro Carvalho Chehab , linux-media@vger.kernel.org, linux-kernel@vger.kernel.org Subject: Re: [PATCH] uvcvideo: Support devices that require SET_INTERFACE(0) before/after streaming In-Reply-To: Message-ID: References: User-Agent: Alpine 2.21 (LFD 202 2017-01-01) MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII X-Spam-Assessment: NotSpam -3.898/5 BAYES_00,SPF_HELO_NONE,SPF_NONE,FROM_LOCAL_MACHINE X-Scanned-By: MIMEDefang 2.79 X-Greylist: No major spam indications; not delayed by milter-greylist-4.6.1 (gfs2.fields.utoronto.ca [128.100.216.26]); Tue, 03 Aug 2021 12:04:31 -0400 (EDT) Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Mon, 2 Aug 2021, Philip Spencer wrote: > (This is my first kernel-related mailing list posting; my apologies if I have > targeted wrong maintainers and/or lists. This is posted on the Ubuntu > launchpad bug tracker at > https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1938669 and it was > suggested there that I post directly to the maintainers/mailing lists). My apologies; I thought I had set my mailer not to mangle the patches but I hadn't. Resending properly formatted patch (I hope): --- a/drivers/media/usb/uvc/uvc_video.c 2021-08-01 10:19:19.343564026 -0400 +++ b/drivers/media/usb/uvc/uvc_video.c 2021-08-01 10:38:54.234311440 -0400 @@ -2108,6 +2081,15 @@ int uvc_video_start_streaming(struct uvc { int ret; + /* On a bulk-based device where there is only one alternate + * setting possibility, set it explicitly to 0. This should be + * the default value, but some devices (e.g. Epiphan Systems + * framegrabbers) freeze and won't restart streaming until they + * receive a SET_INTERFACE(0) request. + */ + if (stream->intf->num_altsetting == 1) + usb_set_interface(stream->dev->udev, stream->intfnum, 0); + ret = uvc_video_clock_init(stream); if (ret < 0) return ret; @@ -2135,9 +2117,17 @@ void uvc_video_stop_streaming(struct uvc { uvc_video_stop_transfer(stream, 1); - if (stream->intf->num_altsetting > 1) { - usb_set_interface(stream->dev->udev, stream->intfnum, 0); - } else { + /* On isochronous devices, switch back to interface 0 to move + * the device out of the "streaming" state. + * + * On bulk-based devices, this interface will already be selected + * but we re-select it explicitly because some devices seem to need + * a SET_INTERFACE(0) request to prepare them for receiving other + * control requests and/or to tell them to stop streaming. + */ + usb_set_interface(stream->dev->udev, stream->intfnum, 0); + + if (stream->intf->num_altsetting == 1) { /* UVC doesn't specify how to inform a bulk-based device * when the video stream is stopped. Windows sends a * CLEAR_FEATURE(HALT) request to the video streaming > > Video capture devices made by Epiphan Systems (vendor id 0x2b77) work once, > but as soon as the video device is closed (or even if it is kept open but the > application issues a VIDIOC_STREAMOFF ioctl) it won't work again - subsequent > calls to VIDOC_DQBUF simply hang - until the device is unbound from and > rebound to the uvcvideo module. (modprobe -r uvcvideo; modprobe uvcvideo also > works). > > For example: > > ffplay /dev/video0 -- works fine and shows the captured stream. > > ffplay /dev/video0 -- when run a second time: hangs and does not capture > anything > > modprobe -r uvcvideo ; modprobe uvcvideo; ffplay /dev/video0 -- works fine > again. > > Experimenting with the device and the uvcvideo module source code reveals that > problem is the device is expecting SET_INTERFACE(0) to be sent to return it to > a state where it can accept control requests and start streaming again. > > The code in uvc_video.c has several comments stating that some bulk-transfer > devices require a SET_INTERFACE(0) call to be made before any control > commands, even though 0 is already the default and only valid interface value. > And, the function uvc_video_init makes such a call (which is why the device > starts working again after rebinding to the uvcvideo module). But no such call > is made when streaming is stopped then restarted. > > Furthermore, SET_INTERFACE(0) is the mechanism by which isochronous devices > are told to stop streaming, and the comments in uvc_video_stop_streaming state > that the UVC specification is unclear on how a bulk-based device should be > told to stop streaming, so it is reasonable to imagine this particular > bulk-based device might be expecting the same SET_INTERFACE(0) call that an > isochronous device would get as means of being told to stop streaming. > > The attached patch fixes the problem for these Epiphan devices by adding a > SET_INTERFACE(0) call in two places. Either one by itself is sufficient to > resolve the symptoms but I think it is probably safest to include both. > > The first hunk adds a SET_INTERFACE(0) call in uvc_video_start_streaming, but > only in the bulk-based case where 0 is the only possible interface value (it > won't mess with an isochronous device that might be set to a different > interface). > > The second hunk modifies the behaviour of uvc_video_stop_streaming to call > SET_INTERFACE(0) unconditionally instead of only calling it for isochronous > devices. Since interface 0 should already be set on non-isochronous devices, > it should be safe to set it again, and this way devices that are expecting it > as a signal to stop streaming will get it. > > The patch is against 5.4.137 but also applies cleanly to 5.14-rc3. > > --- a/drivers/media/usb/uvc/uvc_video.c 2021-08-01 10:19:19.343564026 -0400 > +++ b/drivers/media/usb/uvc/uvc_video.c 2021-08-01 10:38:54.234311440 -0400 > @@ -2108,6 +2081,15 @@ int uvc_video_start_streaming(struct uvc > { > int ret; > > + /* On a bulk-based device where there is only one alternate > + * setting possibility, set it explicitly to 0. This should be > + * the default value, but some devices (e.g. Epiphan Systems > + * framegrabbers) freeze and won't restart streaming until they > + * receive a SET_INTERFACE(0) request. > + */ > + if (stream->intf->num_altsetting == 1) + > usb_set_interface(stream->dev->udev, stream->intfnum, 0); > + > ret = uvc_video_clock_init(stream); > if (ret < 0) > return ret; > @@ -2135,9 +2117,17 @@ void uvc_video_stop_streaming(struct uvc > { > uvc_video_stop_transfer(stream, 1); > > - if (stream->intf->num_altsetting > 1) { > - usb_set_interface(stream->dev->udev, stream->intfnum, 0); > - } else { > + /* On isochronous devices, switch back to interface 0 to move > + * the device out of the "streaming" state. > + * > + * On bulk-based devices, this interface will already be selected > + * but we re-select it explicitly because some devices seem to need > + * a SET_INTERFACE(0) request to prepare them for receiving other > + * control requests and/or to tell them to stop streaming. > + */ > + usb_set_interface(stream->dev->udev, stream->intfnum, 0); > + > + if (stream->intf->num_altsetting == 1) { > /* UVC doesn't specify how to inform a bulk-based device > * when the video stream is stopped. Windows sends a > * CLEAR_FEATURE(HALT) request to the video streaming > > Philip > > --------------------------------------------+------------------------------- > Philip Spencer pspencer@fields.utoronto.ca | Director of Computing Services > Room 348 (416)-348-9710 ext3048 | The Fields Institute for > 222 College St, Toronto ON M5T 3J1 Canada | Research in Mathematical > Sciences > --------------------------------------------+------------------------------- Philip Spencer pspencer@fields.utoronto.ca | Director of Computing Services Room 348 (416)-348-9710 ext3048 | The Fields Institute for 222 College St, Toronto ON M5T 3J1 Canada | Research in Mathematical Sciences