From patchwork Thu May 24 12:05:25 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Minas Harutyunyan X-Patchwork-Id: 10424557 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 EB20F60327 for ; Thu, 24 May 2018 12:05:42 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D025F29352 for ; Thu, 24 May 2018 12:05:42 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C476B29404; Thu, 24 May 2018 12:05:42 +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=-7.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 406A929352 for ; Thu, 24 May 2018 12:05:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S969500AbeEXMFl (ORCPT ); Thu, 24 May 2018 08:05:41 -0400 Received: from smtprelay6.synopsys.com ([198.182.37.59]:58929 "EHLO smtprelay.synopsys.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S966623AbeEXMFh (ORCPT ); Thu, 24 May 2018 08:05:37 -0400 Received: from mailhost.synopsys.com (mailhost3.synopsys.com [10.12.238.238]) by smtprelay.synopsys.com (Postfix) with ESMTP id B71241E0433 for ; Thu, 24 May 2018 14:05:35 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=synopsys.com; s=mail; t=1527163536; bh=CkHwK+hManTJL6Z3dT4Eiwa8DDv3cuEN8+7UtoK4CLA=; h=Date:From:Subject:To:CC:From; b=DJt7/7iECWOeOGfWi2T5qPc4VAHIdRTu2HYBY1Fge9KCt+JFE8m9NpzisT2GwJJWH 84gwV5qjsW0ZQ9NPIH2EQqHaT5fgAxgn6MZvMcI9ixYT4llOpIXDMfAzWhqD554sb4 wQoordgPn23eaENc67ClPBJYyywRDcJK40k7la5sgQErKamDMzSOTl4QXrrY5Qva3j rpKxvb1II+hLqfo/TGHeNjFvLV2VlBnGcu/c245Wq8mhchTVRAz/E/OU8MYo5x2duu j67cidYcPLxDMnTNVez2xCyxywEYTUth+B0GdqsaaxHpltIF8p1DOr168z3bq+Engt o21RSQP8GPVIQ== Received: from US01WEHTC3.internal.synopsys.com (us01wehtc3.internal.synopsys.com [10.15.84.232]) by mailhost.synopsys.com (Postfix) with ESMTP id 101E44B40; Thu, 24 May 2018 05:05:35 -0700 (PDT) Received: from US01WEHTC1.internal.synopsys.com (10.12.239.235) by US01WEHTC3.internal.synopsys.com (10.15.84.232) with Microsoft SMTP Server (TLS) id 14.3.361.1; Thu, 24 May 2018 05:05:34 -0700 Received: from hminas-z420 (10.13.184.19) by us01wehtc1.internal.synopsys.com (10.12.239.236) with Microsoft SMTP Server (TLS) id 14.3.361.1; Thu, 24 May 2018 05:05:33 -0700 Received: by hminas-z420 (sSMTP sendmail emulation); Thu, 24 May 2018 16:05:25 +0400 Date: Thu, 24 May 2018 16:05:25 +0400 Message-ID: <8b417edae18f3b4f35a11aa3796c1512dfcc4c91.1527163379.git.hminas@synopsys.com> From: Minas Harutyunyan Subject: [PATCH] usb: dwc2: gadget: ISOC's starting flow improvement To: Felipe Balbi , Greg Kroah-Hartman , Minas Harutyunyan , CC: John Youn MIME-Version: 1.0 X-Originating-IP: [10.13.184.19] Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP To start ISOC transfers in handlers dwc2_gadget_handle_nak() and dwc2_gadget_handle_out_token_ep_disabled() driver reads current frame number, based on which, set target frame number to start first ISOC transfer. In case if system's high IRQ latency and multiple EP's asserted interrupt in same frame, there are high probability that when reading current frame number in EP's handlers, actual frame number can be increased. As result for bInterval > 1, starting target frame will be set wrongly and all ISOC packets will be dropped. In patch "usb: dwc2: Change reading of current frame number flow" reading of current frame number done ASAP in common interrupt handler. This frame number stored in frame_number variable which used as starting frame number for ISOC EP's in above mentioned handlers. Signed-off-by: Minas Harutyunyan --- drivers/usb/dwc2/gadget.c | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 676712159980..fedf4dd65cc5 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -2749,23 +2749,16 @@ static void dwc2_gadget_handle_out_token_ep_disabled(struct dwc2_hsotg_ep *ep) struct dwc2_hsotg *hsotg = ep->parent; int dir_in = ep->dir_in; u32 doepmsk; - u32 tmp; if (dir_in || !ep->isochronous) return; - /* - * Store frame in which irq was asserted here, as - * it can change while completing request below. - */ - tmp = dwc2_hsotg_read_frameno(hsotg); - dwc2_hsotg_complete_request(hsotg, ep, get_ep_head(ep), 0); if (using_desc_dma(hsotg)) { if (ep->target_frame == TARGET_FRAME_INITIAL) { /* Start first ISO Out */ - ep->target_frame = tmp; + ep->target_frame = hsotg->frame_number; dwc2_gadget_start_isoc_ddma(ep); } return; @@ -2773,11 +2766,9 @@ static void dwc2_gadget_handle_out_token_ep_disabled(struct dwc2_hsotg_ep *ep) if (ep->interval > 1 && ep->target_frame == TARGET_FRAME_INITIAL) { - u32 dsts; u32 ctrl; - dsts = dwc2_readl(hsotg->regs + DSTS); - ep->target_frame = dwc2_hsotg_read_frameno(hsotg); + ep->target_frame = hsotg->frame_number; dwc2_gadget_incr_frame_num(ep); ctrl = dwc2_readl(hsotg->regs + DOEPCTL(ep->index)); @@ -2813,25 +2804,23 @@ static void dwc2_gadget_handle_nak(struct dwc2_hsotg_ep *hs_ep) { struct dwc2_hsotg *hsotg = hs_ep->parent; int dir_in = hs_ep->dir_in; - u32 tmp; if (!dir_in || !hs_ep->isochronous) return; if (hs_ep->target_frame == TARGET_FRAME_INITIAL) { - tmp = dwc2_hsotg_read_frameno(hsotg); if (using_desc_dma(hsotg)) { dwc2_hsotg_complete_request(hsotg, hs_ep, get_ep_head(hs_ep), 0); - hs_ep->target_frame = tmp; + hs_ep->target_frame = hsotg->frame_number; dwc2_gadget_incr_frame_num(hs_ep); dwc2_gadget_start_isoc_ddma(hs_ep); return; } - hs_ep->target_frame = tmp; + hs_ep->target_frame = hsotg->frame_number; if (hs_ep->interval > 1) { u32 ctrl = dwc2_readl(hsotg->regs + DIEPCTL(hs_ep->index));