From nobody Wed Apr 1 08:16:24 2026 Received: from mail-m822136188.xmail.ntesmail.com (mail-m822136188.xmail.ntesmail.com [8.221.36.188]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 47558D531; Wed, 1 Apr 2026 00:10:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=8.221.36.188 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775002225; cv=none; b=u9IDOfFFEgRJDJBFa22mDEvcFsj/4mYsf/6uXeG2ttYD9hcdgkBadcIP3GTri+mSD0MSl4QmbcTpsQn3/fSzjkCn5yNbX9FiJkYC76jTv7OFAPk31+Cm56AQNlPB3E6T9a73bJBe+HKVZh9emOmUFpim6VKL+0FuYM2Y8F5agAk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775002225; c=relaxed/simple; bh=cLlHaEkpEPd+eUffQrKgEEhU4uNRLXVeyyrImwDE1UY=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=MI/4SgeFKY+QOorUGy6WwdU9VB/i8/acngWaVVWmP5E/IET8uaQfH4JMRR4wIC/2NMak5Kf2VUlE/UeOvOx/Rqo1VBK1mMIMAH455V0osC1aShitHI3/GsDxasbSmXqwvDkbourLmhlRtC+mcmMc6diwwmrmJAYfYhy0yQn4YXk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=autochips.com; spf=pass smtp.mailfrom=autochips.com; arc=none smtp.client-ip=8.221.36.188 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=autochips.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=autochips.com Received: from H20F120008.autochips.inc (unknown [223.244.89.246]) by smtp.qiye.163.com (Hmail) with ESMTP id 390cf478f; Wed, 1 Apr 2026 08:10:08 +0800 (GMT+08:00) From: Yongchao Wu To: peter.chen@kernel.org Cc: pawell@cadence.com, rogerq@kernel.org, gregkh@linuxfoundation.org, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, Yongchao Wu , stable@kernel.org Subject: [PATCH v2] usb: cdns3: gadget: fix state inconsistency on gadget init failure Date: Wed, 1 Apr 2026 08:10:00 +0800 Message-ID: <20260401001000.5761-1-yongchao.wu@autochips.com> X-Mailer: git-send-email 2.43.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-HM-Tid: 0a9d4660478f03ackunm44a85ff7299a141 X-HM-MType: 1 X-HM-Spam-Status: e1kfGhgUHx5ZQUpXWQgPGg8OCBgUHx5ZQUlOS1dZFg8aDwILHllBWSg2Ly tZV1koWUFITzdXWS1ZQUlXWQ8JGhUIEh9ZQVlCQk1JVkNMGUxOGR8fTUhOTVYVFAkWGhdVEwETFh oSFyQUDg9ZV1kYEgtZQVlJSUhVSU9PVUNCVUlPTVlXWRYaDxIVHRRZQVlPS0hVSktJT09PSFVKS0 tVSkJLS1kG Content-Type: text/plain; charset="utf-8" When cdns3_gadget_start() fails, the DRD hardware is left in gadget mode while software state remains INACTIVE, creating hardware/software state inconsistency. When switching to host mode via sysfs: echo host > /sys/class/usb_role/13180000.usb-role-switch/role The role state is not set to CDNS_ROLE_STATE_ACTIVE due to the error, so cdns_role_stop() skips cleanup because state is still INACTIVE. This violates the DRD controller design specification (Figure22), which requires returning to idle state before switching roles. This leads to a synchronous external abort in xhci_gen_setup() when setting up the host controller: [ 516.440698] configfs-gadget 13180000.usb: failed to start g1: -19 [ 516.442035] cdns-usb3 13180000.usb: Failed to add gadget [ 516.443278] cdns-usb3 13180000.usb: set role 2 has failed ... [ 1301.375722] xhci-hcd xhci-hcd.1.auto: xHCI Host Controller [ 1301.377716] Internal error: synchronous external abort: 96000010 [#1] PR= EEMPT SMP [ 1301.382485] pc : xhci_gen_setup+0xa4/0x408 [ 1301.393391] backtrace: ... xhci_gen_setup+0xa4/0x408 <-- CRASH xhci_plat_setup+0x44/0x58 usb_add_hcd+0x284/0x678 ... cdns_role_set+0x9c/0xbc <-- Role switch Fix by calling cdns_drd_gadget_off() in the error path to properly clean up the DRD gadget state. Fixes: 7733f6c32e36 ("usb: cdns3: Add Cadence USB3 DRD Driver") Cc: stable@kernel.org Signed-off-by: Yongchao Wu --- Changes in v2: - Update commit title to reflect state inconsistency - Add more detailed description with error logs - Add Fixes tag and Cc to stable --- drivers/usb/cdns3/cdns3-gadget.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/cdns3/cdns3-gadget.c b/drivers/usb/cdns3/cdns3-gad= get.c index d59a60a16..4cc3f2ffb 100644 --- a/drivers/usb/cdns3/cdns3-gadget.c +++ b/drivers/usb/cdns3/cdns3-gadget.c @@ -3428,6 +3428,7 @@ static int __cdns3_gadget_init(struct cdns *cdns) ret =3D cdns3_gadget_start(cdns); if (ret) { pm_runtime_put_sync(cdns->dev); + cdns_drd_gadget_off(cdns); return ret; } =20 --=20 2.43.0