From patchwork Mon Mar 20 10:07:10 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Frank Wang X-Patchwork-Id: 13180884 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 68976C6FD1D for ; Mon, 20 Mar 2023 10:08:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230174AbjCTKIc (ORCPT ); Mon, 20 Mar 2023 06:08:32 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40200 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230120AbjCTKIO (ORCPT ); Mon, 20 Mar 2023 06:08:14 -0400 Received: from mail-m11879.qiye.163.com (mail-m11879.qiye.163.com [115.236.118.79]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EC3BC25280; Mon, 20 Mar 2023 03:07:51 -0700 (PDT) Received: from localhost.localdomain (unknown [58.22.7.114]) by mail-m11879.qiye.163.com (Hmail) with ESMTPA id C8F326806C9; Mon, 20 Mar 2023 18:07:14 +0800 (CST) From: Frank Wang To: linux@roeck-us.net, heikki.krogerus@linux.intel.com, gregkh@linuxfoundation.org, heiko@sntech.de Cc: linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, linux-rockchip@lists.infradead.org, huangtao@rock-chips.com, william.wu@rock-chips.com, jianwei.zheng@rock-chips.com, yubing.zhang@rock-chips.com, wmc@rock-chips.com, Frank Wang Subject: [RESEND PATCH v2 2/3] usb: typec: tcpm: fix multiple times discover svids error Date: Mon, 20 Mar 2023 18:07:10 +0800 Message-Id: <20230320100711.3708-3-frank.wang@rock-chips.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20230320100711.3708-1-frank.wang@rock-chips.com> References: <20230320100711.3708-1-frank.wang@rock-chips.com> X-HM-Spam-Status: e1kfGhgUHx5ZQUpXWQgPGg8OCBgUHx5ZQUlOS1dZFg8aDwILHllBWSg2Ly tZV1koWUFDSUNOT01LS0k3V1ktWUFJV1kPCRoVCBIfWUFZGUlPTlZLH0xCGhkaTksYSh5VEwETFh oSFyQUDg9ZV1kYEgtZQVlOQ1VJSVVMVUpKT1lXWRYaDxIVHRRZQVlPS0hVSkpLSEpMVUpLS1VLWQ Y+ X-HM-Sender-Digest: e1kMHhlZQR0aFwgeV1kSHx4VD1lBWUc6PFE6HDo6Kz0TExE2Mz1MHzxM VhUaCjpVSlVKTUxCSEtNQ0hNT0JPVTMWGhIXVR0JGhUQVQwaFRw7CRQYEFYYExILCFUYFBZFWVdZ EgtZQVlOQ1VJSVVMVUpKT1lXWQgBWUFISEJNNwY+ X-HM-Tid: 0a86fe7cc49d2eb5kusnc8f326806c9 X-HM-MType: 1 Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org PD3.0 Spec 6.4.4.3.2 say that only Responder supports 12 or more SVIDs, the Discover SVIDs Command Shall be executed multiple times until a Discover SVIDs VDO is returned ending either with a SVID value of 0x0000 in the last part of the last VDO or with a VDO containing two SVIDs with values of 0x0000. In the current implementation, if the last VDO does not find that the Discover SVIDs Command would be executed multiple times even if the Responder SVIDs are less than 12, and we found some odd dockers just meet this case. So fix it. Signed-off-by: Frank Wang --- drivers/usb/typec/tcpm/tcpm.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c index 56782dd05e2ec..13830b5e2d09f 100644 --- a/drivers/usb/typec/tcpm/tcpm.c +++ b/drivers/usb/typec/tcpm/tcpm.c @@ -1515,7 +1515,21 @@ static bool svdm_consume_svids(struct tcpm_port *port, const u32 *p, int cnt) pmdata->svids[pmdata->nsvids++] = svid; tcpm_log(port, "SVID %d: 0x%x", pmdata->nsvids, svid); } - return true; + + /* + * PD3.0 Spec 6.4.4.3.2: The SVIDs are returned 2 per VDO (see Table + * 6-43), and can be returned maximum 6 VDOs per response (see Figure + * 6-19). If the Respondersupports 12 or more SVID then the Discover + * SVIDs Command Shall be executed multiple times until a Discover + * SVIDs VDO is returned ending either with a SVID value of 0x0000 in + * the last part of the last VDO or with a VDO containing two SVIDs + * with values of 0x0000. + * + * However, some odd dockers support SVIDs less than 12 but without + * 0x0000 in the last VDO, so we need to break the Discover SVIDs + * request and return false here. + */ + return cnt == 7; abort: tcpm_log(port, "SVID_DISCOVERY_MAX(%d) too low!", SVID_DISCOVERY_MAX); return false;