Received: by 10.223.164.202 with SMTP id h10csp128215wrb; Tue, 7 Nov 2017 04:04:40 -0800 (PST) X-Google-Smtp-Source: ABhQp+TmKPhCSVTFRHN3ebT0dA70YClUCWUjhFWhBYohaUd+sfLRY/ArDEAWrbOuiOtKLD6/dZJ6 X-Received: by 10.84.244.74 with SMTP id e10mr18391561plt.112.1510056280515; Tue, 07 Nov 2017 04:04:40 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1510056280; cv=none; d=google.com; s=arc-20160816; b=EZx/e86lcqQD7kSTmswn3JcLHB1R43n5LgjNWlEf/jjVh9fq+TsYrmHiN7mLT/8dEJ QzowV5P8TqYAd7pYfqRxs+cPI8wiKVRiMRod4nbDXetdOcewB1rkbgEc+k70C1p9vUq7 VK7cqEB0uKJO39rt5y4YlhNq9TgtlNpwhh6GEKYrjcv4bv6ThSEa6udReJRtiEN7+F1b grFINJT10tAvLC1lwiGQa5lde1BpCl68ywmd8b++JQJQJW3cUuFmIgnvb4U52lxS0P5I ngf6mnA5dexbr+xCFYa7IYi12lrJss/SZ9Wl2dTUU9gCgOUJYPUapZciITa7vQKGmnPe SOjg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-language :content-transfer-encoding:in-reply-to:mime-version:user-agent:date :message-id:from:references:cc:to:subject:arc-authentication-results; bh=MKWg6zLFSx6BfUdG/l/V4DO8sJzmGeuHF5Vt8ZXvBWM=; b=WimsXSfRBpPwFz8we6bo7h5YOafBKxpdXkOaIoQXHkMAVVqSPTBvFzW24Caq3AeULy rjsbZujIav8SLNUVwH4fd1qd/1r2E6WjCVAxboVSf+M9HfwGV/ZTGBHm5E7viQXZwMgd d4V5X8Ve3UJm9YEiW/4jjSlcQC89LOxvVkCHrOwROsX7EsHOfyPglC39+hMr07e2NOkm CcLloot61V2qjtLqBMx8jFqeDml4+OjdsRX2n8z6mXeoPLDn11qZRZU7Hq+CFf4GhE2a fRiZmsD4gi62G7Ej8S01619qZEnofwZ+G9OsUfj+IaCvMUvo5K2ie7TKRRfxqhOpLXxk LzuQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id b96si1049564pli.387.2017.11.07.04.04.27; Tue, 07 Nov 2017 04:04:40 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755925AbdKGJ66 (ORCPT + 91 others); Tue, 7 Nov 2017 04:58:58 -0500 Received: from regular1.263xmail.com ([211.150.99.136]:55732 "EHLO regular1.263xmail.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752715AbdKGJ6y (ORCPT ); Tue, 7 Nov 2017 04:58:54 -0500 Received: from wulf?rock-chips.com (unknown [192.168.167.235]) by regular1.263xmail.com (Postfix) with ESMTP id 0F8C440; Tue, 7 Nov 2017 17:58:51 +0800 (CST) X-263anti-spam: KSV:0; X-MAIL-GRAY: 0 X-MAIL-DELIVERY: 1 X-KSVirus-check: 0 X-ABS-CHECKED: 4 Received: from [172.16.12.36] (localhost [127.0.0.1]) by smtp.263.net (Postfix) with ESMTPA id 9A3DE3D2; Tue, 7 Nov 2017 17:58:47 +0800 (CST) X-RL-SENDER: wulf@rock-chips.com X-FST-TO: fml@rock-chips.com X-SENDER-IP: 58.22.7.114 X-LOGIN-NAME: wulf@rock-chips.com X-UNIQUE-TAG: <24e2c061774a359709e392132f6d6cd7> X-ATTACHMENT-NUM: 0 X-SENDER: wulf@rock-chips.com X-DNS-TYPE: 0 Received: from [172.16.12.36] (unknown [58.22.7.114]) by smtp.263.net (Postfix) whith ESMTP id 14389BKH5CR; Tue, 07 Nov 2017 17:58:50 +0800 (CST) Subject: Re: [PATCH] usb: dwc2: host: fix isoc urb actual length To: Alan Stern Cc: Minas Harutyunyan , William Wu , "John.Youn@synopsys.com" , "balbi@kernel.org" , "gregkh@linuxfoundation.org" , "heiko@sntech.de" , "linux-kernel@vger.kernel.org" , "linux-usb@vger.kernel.org" , "linux-rockchip@lists.infradead.org" , "frank.wang@rock-chips.com" , "huangtao@rock-chips.com" , "dianders@google.com" , "daniel.meng@rock-chips.com" , "fml@rock-chips.com" References: From: wlf Message-ID: Date: Tue, 7 Nov 2017 17:58:47 +0800 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.1.1 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit Content-Language: en-US Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi Alan, 在 2017年11月07日 03:17, Alan Stern 写道: > 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; > > Yeah, it's a good idea to calculate the urb actual length in the devio driver. Your patch seems good, and I think we can do a small optimization base your patch, like the following patch: diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index bd94192..a2e7b97 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -1664,6 +1664,9 @@ static int processcompl(struct async *as, void __user * __user *arg) void __user *addr = as->userurb; unsigned int i; + if (usb_endpoint_xfer_isoc(&urb->ep->desc)) + compute_isochronous_actual_length(urb); + if (as->userbuffer && urb->actual_length) { if (copy_urb_data_to_user(as->userbuffer, urb)) goto err_out; @@ -1833,6 +1836,9 @@ static int processcompl_compat(struct async *as, void __user * __user *arg) void __user *addr = as->userurb; unsigned int i; + if (usb_endpoint_xfer_isoc(&urb->ep->desc)) + compute_isochronous_actual_length(urb); + if (as->userbuffer && urb->actual_length) { if (copy_urb_data_to_user(as->userbuffer, urb)) return -EFAULT; > -- 吴良峰 William.Wu 福建省福州市铜盘路软件大道89号软件园A区21号楼 No.21 Building, A District, No.89,software Boulevard Fuzhou,Fujian, PRC 手机: 13685012275 座机: 0591-83991906-8520 邮件:wulf@rock-chips.com From 1583351387032982048@xxx Mon Nov 06 20:52:31 +0000 2017 X-GM-THRID: 1583305738476220776 X-Gmail-Labels: Inbox,Category Forums,HistoricalUnread