From patchwork Thu Jun 20 21:09:49 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Cooper X-Patchwork-Id: 11008167 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id CE81F1932 for ; Thu, 20 Jun 2019 21:10:39 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C0A99281C3 for ; Thu, 20 Jun 2019 21:10:39 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B48752847B; Thu, 20 Jun 2019 21:10:39 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI 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 9FAE6281C3 for ; Thu, 20 Jun 2019 21:10:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726943AbfFTVKd (ORCPT ); Thu, 20 Jun 2019 17:10:33 -0400 Received: from mail-pl1-f194.google.com ([209.85.214.194]:37689 "EHLO mail-pl1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726734AbfFTVKQ (ORCPT ); Thu, 20 Jun 2019 17:10:16 -0400 Received: by mail-pl1-f194.google.com with SMTP id bh12so1887045plb.4; Thu, 20 Jun 2019 14:10:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=yUxHr0hNOMB2xE/tt9UalgG6ujmd92ZRH1krBwmSmgY=; b=E4lqWYrRkM6KJNjQ2DdXr2dcOiHpEGX2YRmNRNuIGzZisK03dVPjlXa+lAsoEPO5Hh Gqvhzx4fd8Y51hbboeQtdjvM2X0V6OQUtzOkYN7m29YNGNF8A64XTvGme42xbGtwE/3/ 16okdMQxaLDPooy0IqkFhpvK1aehYqCG82uUQB1ehc56NBXLDF9U28CDTFhoEZo0B4XW LlMUSMn3cQ93elqet52/RzUkirP2EUvoJvYFxRVLpQ6eZNY3LFm0qON76XiihtegDSw7 y81apneBMySgv734LUTJlCnNOwzbOuyVT7od+80xEcdU+dpNY7x+DF50O+ckJG/7Jzpt FgAw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=yUxHr0hNOMB2xE/tt9UalgG6ujmd92ZRH1krBwmSmgY=; b=BM3k/y3JLZ7CHs2FjT1EEjIWFDNluzSyXZN7uPlSNUZcB7krEloLCo6yPYFT+tdJmh 36iQzavFJTWrQi+VXY7H5JmrUt+daMI26AGb8Ixg2Cfooy8BE8EuPUtG4P8GJZTWOLYa trpr6bicEm47rpp+VWYsBK40BiK+O0Xs33IUGMS5+6K0GB7OYMZCAiSr1JqOQclWZJWB P2kfkuYuHHATSz/gxmw4P4PU7w8pAXOpGuJeIfKBJPq4qMHw4lfUVnJIJ2IMYDXpT2ZP Xnsxi6jiPDQeDVbUr6hE4FGlFK3VAt+/6Y19Yge5hNTILpKI2nAppYAEwWOMUu0EgFjw WFVA== X-Gm-Message-State: APjAAAX+vvptjLfTkZ3XzlGVztCkvsLUf8ysoVCUcSZJ8ryX0blBMkNX +tI2lMZ0Z7P8ympSp8QfQiiZRBfI6As= X-Google-Smtp-Source: APXvYqweQXsePQOeD1QPqsLfAMJ2XNXS6TyEIzqv76S2fzeWoPA1Sn43mDciVODO5YNLQLkKVML5NQ== X-Received: by 2002:a17:902:28e9:: with SMTP id f96mr78619023plb.114.1561065015001; Thu, 20 Jun 2019 14:10:15 -0700 (PDT) Received: from stbsrv-and-3.and.broadcom.com ([192.19.231.250]) by smtp.gmail.com with ESMTPSA id p1sm386805pff.74.2019.06.20.14.10.13 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 20 Jun 2019 14:10:14 -0700 (PDT) From: Al Cooper To: linux-kernel@vger.kernel.org Cc: Al Cooper , devicetree@vger.kernel.org, Felipe Balbi , Greg Kroah-Hartman , linux-usb@vger.kernel.org, Luis Chamberlain , Mark Rutland , Rob Herring Subject: [PATCH 4/6] usb: bdc: Fix bug causing crash after multiple disconnects Date: Thu, 20 Jun 2019 17:09:49 -0400 Message-Id: <1561064991-16874-5-git-send-email-alcooperx@gmail.com> X-Mailer: git-send-email 1.9.0.138.g2de3478 In-Reply-To: <1561064991-16874-1-git-send-email-alcooperx@gmail.com> References: <1561064991-16874-1-git-send-email-alcooperx@gmail.com> 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 Multiple connects/disconnects can cause a crash on the second disconnect. The driver had a problem where it would try to send endpoint commands after it was disconnected which is not allowed by the hardware. The fix is to only allow the endpoint commands when the endpoint is connected. This will also fix issues that showed up when using configfs to create gadgets. Signed-off-by: Al Cooper --- drivers/usb/gadget/udc/bdc/bdc_core.c | 4 ++++ drivers/usb/gadget/udc/bdc/bdc_ep.c | 16 ++++++++++------ 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/drivers/usb/gadget/udc/bdc/bdc_core.c b/drivers/usb/gadget/udc/bdc/bdc_core.c index c794890d785b..15e28790142d 100644 --- a/drivers/usb/gadget/udc/bdc/bdc_core.c +++ b/drivers/usb/gadget/udc/bdc/bdc_core.c @@ -282,6 +282,7 @@ static void bdc_mem_init(struct bdc *bdc, bool reinit) * in that case reinit is passed as 1 */ if (reinit) { + int i; /* Enable interrupts */ temp = bdc_readl(bdc->regs, BDC_BDCSC); temp |= BDC_GIE; @@ -291,6 +292,9 @@ static void bdc_mem_init(struct bdc *bdc, bool reinit) /* Initialize SRR to 0 */ memset(bdc->srr.sr_bds, 0, NUM_SR_ENTRIES * sizeof(struct bdc_bd)); + /* clear ep flags to avoid post disconnect stops/deconfigs */ + for (i = 1; i < bdc->num_eps; ++i) + bdc->bdc_ep_array[i]->flags = 0; } else { /* One time initiaization only */ /* Enable status report function pointers */ diff --git a/drivers/usb/gadget/udc/bdc/bdc_ep.c b/drivers/usb/gadget/udc/bdc/bdc_ep.c index a4d9b5e1e50e..3f34d10939d0 100644 --- a/drivers/usb/gadget/udc/bdc/bdc_ep.c +++ b/drivers/usb/gadget/udc/bdc/bdc_ep.c @@ -615,7 +615,6 @@ int bdc_ep_enable(struct bdc_ep *ep) } bdc_dbg_bd_list(bdc, ep); /* only for ep0: config ep is called for ep0 from connect event */ - ep->flags |= BDC_EP_ENABLED; if (ep->ep_num == 1) return ret; @@ -759,10 +758,13 @@ static int ep_dequeue(struct bdc_ep *ep, struct bdc_req *req) __func__, ep->name, start_bdi, end_bdi); dev_dbg(bdc->dev, "ep_dequeue ep=%p ep->desc=%p\n", ep, (void *)ep->usb_ep.desc); - /* Stop the ep to see where the HW is ? */ - ret = bdc_stop_ep(bdc, ep->ep_num); - /* if there is an issue with stopping ep, then no need to go further */ - if (ret) + /* if still connected, stop the ep to see where the HW is ? */ + if (!(bdc_readl(bdc->regs, BDC_USPC) & BDC_PST_MASK)) { + ret = bdc_stop_ep(bdc, ep->ep_num); + /* if there is an issue, then no need to go further */ + if (ret) + return 0; + } else return 0; /* @@ -1911,7 +1913,9 @@ static int bdc_gadget_ep_disable(struct usb_ep *_ep) __func__, ep->name, ep->flags); if (!(ep->flags & BDC_EP_ENABLED)) { - dev_warn(bdc->dev, "%s is already disabled\n", ep->name); + if (bdc->gadget.speed != USB_SPEED_UNKNOWN) + dev_warn(bdc->dev, "%s is already disabled\n", + ep->name); return 0; } spin_lock_irqsave(&bdc->lock, flags);