From patchwork Mon Nov 6 19:17:00 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Alan Stern X-Patchwork-Id: 10044301 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id CE6B8602BF for ; Mon, 6 Nov 2017 19:17:32 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id BC52629FA3 for ; Mon, 6 Nov 2017 19:17:32 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B0E2129FA8; Mon, 6 Nov 2017 19:17:32 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 2904229FA7 for ; Mon, 6 Nov 2017 19:17:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:Message-ID:In-Reply-To: Subject:To:From:Date:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:References: List-Owner; bh=5I8DSFJk86vN/ycZ42CCsrseuh6rqDNKJjvVgHQ4pM0=; b=K6U63nvSnoqfvC OER6hwNTu4sej1jpNcWXKlApruJcezSyocnrjhdPwOline4gAosY18RyWgtZtQ4XcBqota7/FKiUI Q9lrjwN4MOOMnBtP/g9zAk33HKu4rwdCLrV8IV5qJ/YDoD9/ndHoEDQR1n5hR/u/f6GIfzV6vU1db TygOZ+bS0TILJKndbpCraC+j6nE9UIApQkakfS3HgQBEnyN+Mr21AwJ1hGE+wtIJ9ULrfkstQwdsz sI7giSBZg+HHbCb4TRDk/7ZvJH4ij+uVdijhMf/Y+/qjiO2HMWjEhfX7dHZpA6RwRtAu8JQKJFDs9 QPIXj/SHrUDE/pXqHeQg==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1eBmtm-0001OG-0u; Mon, 06 Nov 2017 19:17:30 +0000 Received: from iolanthe.rowland.org ([192.131.102.54]) by bombadil.infradead.org with smtp (Exim 4.87 #1 (Red Hat Linux)) id 1eBmti-0001Mh-K2 for linux-rockchip@lists.infradead.org; Mon, 06 Nov 2017 19:17:28 +0000 Received: (qmail 3056 invoked by uid 2102); 6 Nov 2017 14:17:00 -0500 Received: from localhost (sendmail-bs@127.0.0.1) by localhost with SMTP; 6 Nov 2017 14:17:00 -0500 Date: Mon, 6 Nov 2017 14:17:00 -0500 (EST) From: Alan Stern X-X-Sender: stern@iolanthe.rowland.org To: wlf Subject: Re: [PATCH] usb: dwc2: host: fix isoc urb actual length In-Reply-To: <392af079-7805-a22e-d332-cd7615adf6ba@rock-chips.com> Message-ID: MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20171106_111726_847171_66F6F273 X-CRM114-Status: GOOD ( 23.45 ) X-BeenThere: linux-rockchip@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: Upstream kernel work for Rockchip platforms List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: "huangtao@rock-chips.com" , "balbi@kernel.org" , "heiko@sntech.de" , "frank.wang@rock-chips.com" , "gregkh@linuxfoundation.org" , "linux-usb@vger.kernel.org" , Minas Harutyunyan , "John.Youn@synopsys.com" , "linux-rockchip@lists.infradead.org" , "fml@rock-chips.com" , William Wu , "dianders@google.com" , "daniel.meng@rock-chips.com" , "linux-kernel@vger.kernel.org" Sender: "Linux-rockchip" Errors-To: linux-rockchip-bounces+patchwork-linux-rockchip=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP On Mon, 6 Nov 2017, wlf wrote: > Hi Minas, > > 在 2017年11月06日 17:28, Minas Harutyunyan 写道: > > Hi, > > > > On 11/6/2017 12:46 PM, William Wu wrote: > >> The actual_length in dwc2_hcd_urb structure is used > >> to indicate the total data length transferred so far, > >> but in dwc2_update_isoc_urb_state(), it just updates > >> the actual_length of isoc frame, and don't update the > >> urb actual_length at the same time, this will cause > >> device drivers working error which depend on the urb > >> actual_length. > >> > >> we can easily find this issue if use an USB camera, > >> the userspace use libusb to get USB data from kernel > >> via devio driver.In usb devio driver, processcompl() > >> function will process urb complete and copy data to > >> userspace depending on urb actual_length. > >> > >> Let's update the urb actual_length if the isoc frame > >> is valid. > >> > >> Signed-off-by: William Wu > >> --- > >> drivers/usb/dwc2/hcd_intr.c | 2 ++ > >> 1 file changed, 2 insertions(+) > >> > >> diff --git a/drivers/usb/dwc2/hcd_intr.c b/drivers/usb/dwc2/hcd_intr.c > >> index 28a8210..01b1e13 100644 > >> --- a/drivers/usb/dwc2/hcd_intr.c > >> +++ b/drivers/usb/dwc2/hcd_intr.c > >> @@ -580,6 +580,7 @@ static enum dwc2_halt_status dwc2_update_isoc_urb_state( > >> frame_desc->status = 0; > >> frame_desc->actual_length = dwc2_get_actual_xfer_length(hsotg, > >> chan, chnum, qtd, halt_status, NULL); > >> + urb->actual_length += frame_desc->actual_length; > >> break; > >> case DWC2_HC_XFER_FRAME_OVERRUN: > >> urb->error_count++; > >> @@ -599,6 +600,7 @@ static enum dwc2_halt_status dwc2_update_isoc_urb_state( > >> frame_desc->status = -EPROTO; > >> frame_desc->actual_length = dwc2_get_actual_xfer_length(hsotg, > >> chan, chnum, qtd, halt_status, NULL); > >> + urb->actual_length += frame_desc->actual_length; > >> > >> /* Skip whole frame */ > >> if (chan->qh->do_split && > >> > > According urb description in usb.h urb->actual_length used for non-iso > > transfers: > > > > "@actual_length: This is read in non-iso completion functions, and ... > > > > * ISO transfer status is reported in the status and actual_length fields > > * of the iso_frame_desc array, ...." > Yes, urb->actual_length is used for non-iso transfers. And for ISO > transfer, the most > usb class drivers can only use iso frame status and actual_length to > handle usb data, > like: kernel v4.4 drivers/media/usb/uvc/uvc_video.c > > But the usb devio driver really need the urb actual_length in the > processcompl() if > handle ISO transfer, just as I mentioned in the commit message. > > And I also found the same issue on raspberrypi board: > https://github.com/raspberrypi/linux/issues/903 > > So do you think we need to fix the usb devio driver, rather than fix dwc2? > I think maybe we can use urb actual length for ISO transfer, it seems that > don't cause any side-effect. That sounds like a good idea. Minas, does the following patch fix your problem? In theory we could do this calculation for every isochronous URB, not just those coming from usbfs. But I don't think there's any point, since the USB class drivers don't use it. Alan Stern Index: usb-4.x/drivers/usb/core/devio.c =================================================================== --- usb-4.x.orig/drivers/usb/core/devio.c +++ usb-4.x/drivers/usb/core/devio.c @@ -1828,6 +1828,18 @@ static int proc_unlinkurb(struct usb_dev return 0; } +static void compute_isochronous_actual_length(struct urb *urb) +{ + unsigned i; + + if (urb->number_of_packets > 0) { + urb->actual_length = 0; + for (i = 0; i < urb->number_of_packets; i++) + urb->actual_length += + urb->iso_frame_desc[i].actual_length; + } +} + static int processcompl(struct async *as, void __user * __user *arg) { struct urb *urb = as->urb; @@ -1835,6 +1847,8 @@ static int processcompl(struct async *as void __user *addr = as->userurb; unsigned int i; + compute_isochronous_actual_length(urb); + if (as->userbuffer && urb->actual_length) { if (copy_urb_data_to_user(as->userbuffer, urb)) goto err_out; @@ -2003,6 +2017,8 @@ static int processcompl_compat(struct as void __user *addr = as->userurb; unsigned int i; + compute_isochronous_actual_length(urb); + if (as->userbuffer && urb->actual_length) { if (copy_urb_data_to_user(as->userbuffer, urb)) return -EFAULT;