From patchwork Wed Oct 30 18:39:53 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jack Pham X-Patchwork-Id: 11219939 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1B32D912 for ; Wed, 30 Oct 2019 18:41:14 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id EC78A20856 for ; Wed, 30 Oct 2019 18:41:13 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="key not found in DNS" (0-bit key) header.d=codeaurora.org header.i=@codeaurora.org header.b="Y70aRTAu"; dkim=fail reason="key not found in DNS" (0-bit key) header.d=codeaurora.org header.i=@codeaurora.org header.b="Bld0le9P" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728137AbfJ3SlN (ORCPT ); Wed, 30 Oct 2019 14:41:13 -0400 Received: from smtp.codeaurora.org ([198.145.29.96]:33738 "EHLO smtp.codeaurora.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726242AbfJ3SlM (ORCPT ); Wed, 30 Oct 2019 14:41:12 -0400 Received: by smtp.codeaurora.org (Postfix, from userid 1000) id 0B5736043F; Wed, 30 Oct 2019 18:41:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1572460872; bh=qczos0G7s6BLPmMS+/bsvHdT6H1rTJzzwmEr8cfv8c4=; h=From:To:Cc:Subject:Date:From; b=Y70aRTAuktZ1QsIE4Lz0RnqenJXmVuuTrsy+fYILauG0pb2E9w/AyOHOluTWiHQDN YQElMnKci04uDHrhBzHzqYwcLO/InTeLC21hjP5mShWf0mvWgm7zVDXHYrQ6PM+jaE mEpcJnOZA58Pm8mkF/EkTg01JbPEVKOkOQfffzBw= X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on pdx-caf-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=2.0 tests=ALL_TRUSTED,BAYES_00, DKIM_INVALID,DKIM_SIGNED,SPF_NONE autolearn=no autolearn_force=no version=3.4.0 Received: from jackp-linux.qualcomm.com (i-global254.qualcomm.com [199.106.103.254]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: jackp@smtp.codeaurora.org) by smtp.codeaurora.org (Postfix) with ESMTPSA id 255456043F; Wed, 30 Oct 2019 18:41:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1572460871; bh=qczos0G7s6BLPmMS+/bsvHdT6H1rTJzzwmEr8cfv8c4=; h=From:To:Cc:Subject:Date:From; b=Bld0le9PqeDpelT2Hxyqg2viDC+ZYmGm+Fj9aJSZ+6FtjXzmsujM3tArRnJusRn1d 5pqPMeSLingIcJepk86pl5B+pyiifnrAX3Ip2YPyw6MBCtywUXVN0pvqeSMlQBDrIG nWuGb+bKmpjiTkLCFbxBX2+PuwDmRmo222TLC9bg= DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 255456043F Authentication-Results: pdx-caf-mail.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: pdx-caf-mail.web.codeaurora.org; spf=none smtp.mailfrom=jackp@codeaurora.org From: Jack Pham To: Felipe Balbi , Greg Kroah-Hartman Cc: linux-usb@vger.kernel.org, Jack Pham Subject: [PATCH v3 1/2] usb: gadget: composite: Fix bMaxPower for SuperSpeedPlus Date: Wed, 30 Oct 2019 11:39:53 -0700 Message-Id: <20191030183954.9791-1-jackp@codeaurora.org> X-Mailer: git-send-email 2.21.0 MIME-Version: 1.0 Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org SuperSpeedPlus peripherals must report their bMaxPower of the configuration descriptor in units of 8mA as per the USB 3.2 specification. The current switch statement in encode_bMaxPower() only checks for USB_SPEED_SUPER but not USB_SPEED_SUPER_PLUS so the latter falls back to USB 2.0 encoding which uses 2mA units. Replace the switch with a simple if/else. Fixes: eae5820b852f ("usb: gadget: composite: Write SuperSpeedPlus config descriptors") Signed-off-by: Jack Pham --- drivers/usb/gadget/composite.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index d516e8d6cd7f..e1db94d1fe2e 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -437,12 +437,10 @@ static u8 encode_bMaxPower(enum usb_device_speed speed, val = CONFIG_USB_GADGET_VBUS_DRAW; if (!val) return 0; - switch (speed) { - case USB_SPEED_SUPER: - return DIV_ROUND_UP(val, 8); - default: + if (speed < USB_SPEED_SUPER) return DIV_ROUND_UP(val, 2); - } + else + return DIV_ROUND_UP(val, 8); } static int config_buf(struct usb_configuration *config, From patchwork Wed Oct 30 18:39:54 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jack Pham X-Patchwork-Id: 11219941 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 516B1912 for ; Wed, 30 Oct 2019 18:41:24 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 2ECE82087E for ; Wed, 30 Oct 2019 18:41:24 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="key not found in DNS" (0-bit key) header.d=codeaurora.org header.i=@codeaurora.org header.b="ivPmOubR"; dkim=fail reason="key not found in DNS" (0-bit key) header.d=codeaurora.org header.i=@codeaurora.org header.b="A1Y5ICfl" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728260AbfJ3SlX (ORCPT ); Wed, 30 Oct 2019 14:41:23 -0400 Received: from smtp.codeaurora.org ([198.145.29.96]:33882 "EHLO smtp.codeaurora.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726242AbfJ3SlX (ORCPT ); Wed, 30 Oct 2019 14:41:23 -0400 Received: by smtp.codeaurora.org (Postfix, from userid 1000) id 59843607EF; Wed, 30 Oct 2019 18:41:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1572460882; bh=DgP1Gd6SQ180sPb/6jjaHdtoCDqkLu1O44BBHC2Kq24=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ivPmOubR3V5KDaD8iK5tJrnKaEP/wLdrJGXtUR2ISF7E4ZxQwzhPjR1wTNzAM0F9i a0kUc3Aw3g8IurRz0GAknGOfXjX7qxXNOlv/WgQp4aS/ddwQSdkqCsAMPoeThBI2nA 3HBBmUlb0vEZyh5lbtGkeqRHaP3q2vm/jRtrber4= X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on pdx-caf-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=2.0 tests=ALL_TRUSTED,BAYES_00, DKIM_INVALID,DKIM_SIGNED,SPF_NONE autolearn=no autolearn_force=no version=3.4.0 Received: from jackp-linux.qualcomm.com (i-global254.qualcomm.com [199.106.103.254]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: jackp@smtp.codeaurora.org) by smtp.codeaurora.org (Postfix) with ESMTPSA id 8597D6079C; Wed, 30 Oct 2019 18:41:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1572460878; bh=DgP1Gd6SQ180sPb/6jjaHdtoCDqkLu1O44BBHC2Kq24=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=A1Y5ICfliTl3yeY5+Ff1SN7TBvPjAyojZI0oYa0zLcHRbppRgrhl6SWox/dTVr15x ok0xQyacaiT3Z67DQQfs7dxFa6v+/SZmaieZy9uogiRSm49gaUIpkBHBCSf2HdzjPz 7O4MjBN4/UtpcwtQRz2W4B3SAHuCpwyIVfeD9LxM= DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 8597D6079C Authentication-Results: pdx-caf-mail.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: pdx-caf-mail.web.codeaurora.org; spf=none smtp.mailfrom=jackp@codeaurora.org From: Jack Pham To: Felipe Balbi , Greg Kroah-Hartman Cc: linux-usb@vger.kernel.org, Jack Pham Subject: [PATCH v3 2/2] usb: gadget: composite: Support more than 500mA MaxPower Date: Wed, 30 Oct 2019 11:39:54 -0700 Message-Id: <20191030183954.9791-2-jackp@codeaurora.org> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20191030183954.9791-1-jackp@codeaurora.org> References: <20191030183954.9791-1-jackp@codeaurora.org> MIME-Version: 1.0 Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org USB 3.x SuperSpeed peripherals can draw up to 900mA of VBUS power when in configured state. However, if a configuration wanting to take advantage of this is added with MaxPower greater than 500 (currently possible if using a ConfigFS gadget) the composite driver fails to accommodate this for a couple reasons: - usb_gadget_vbus_draw() when called from set_config() and composite_resume() will be passed the MaxPower value without regard for the current connection speed, resulting in a violation for USB 2.0 since the max is 500mA. - the bMaxPower of the configuration descriptor would be incorrectly encoded, again if the connection speed is only at USB 2.0 or below, likely wrapping around U8_MAX since the 2mA multiplier corresponds to a maximum of 510mA. Fix these by adding checks against the current gadget->speed when the c->MaxPower value is used (set_config() and composite_resume()) and appropriately limit based on whether it is currently at a low-/full-/high- or super-speed connection. Because 900 is not divisible by 8, with the round-up division currently used in encode_bMaxPower() a MaxPower of 900mA will result in an encoded value of 0x71. When a host stack (including Linux and Windows) enumerates this on a single port root hub, it reads this value back and decodes (multiplies by 8) to get 904mA which is strictly greater than 900mA that is typically budgeted for that port, causing it to reject the configuration. Instead, we should be using the round-down behavior of normal integral division so that 900 / 8 -> 0x70 or 896mA to stay within range. And we might as well change it for the high/full/low case as well for consistency. N.B. USB 3.2 Gen N x 2 allows for up to 1500mA but there doesn't seem to be any any peripheral controller supported by Linux that does two lane operation, so for now keeping the clamp at 900 should be fine. Signed-off-by: Jack Pham --- v3: Change round-up to round-down division. Fixed up checks in composite_resume() to look more like that in set_config(). v2: Fix typos in commit text and reworded the blurb about rounding drivers/usb/gadget/composite.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index e1db94d1fe2e..3c5b81311959 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -438,9 +438,13 @@ static u8 encode_bMaxPower(enum usb_device_speed speed, if (!val) return 0; if (speed < USB_SPEED_SUPER) - return DIV_ROUND_UP(val, 2); + return min(val, 500U) / 2; else - return DIV_ROUND_UP(val, 8); + /* + * USB 3.x supports up to 900mA, but since 900 isn't divisible + * by 8 the integral division will effectively cap to 896mA. + */ + return min(val, 900U) / 8; } static int config_buf(struct usb_configuration *config, @@ -852,6 +856,10 @@ static int set_config(struct usb_composite_dev *cdev, /* when we return, be sure our power usage is valid */ power = c->MaxPower ? c->MaxPower : CONFIG_USB_GADGET_VBUS_DRAW; + if (gadget->speed < USB_SPEED_SUPER) + power = min(power, 500U); + else + power = min(power, 900U); done: usb_gadget_vbus_draw(gadget, power); if (result >= 0 && cdev->delayed_status) @@ -2274,7 +2282,7 @@ void composite_resume(struct usb_gadget *gadget) { struct usb_composite_dev *cdev = get_gadget_data(gadget); struct usb_function *f; - u16 maxpower; + unsigned maxpower; /* REVISIT: should we have config level * suspend/resume callbacks? @@ -2288,10 +2296,14 @@ void composite_resume(struct usb_gadget *gadget) f->resume(f); } - maxpower = cdev->config->MaxPower; + maxpower = cdev->config->MaxPower ? + cdev->config->MaxPower : CONFIG_USB_GADGET_VBUS_DRAW; + if (gadget->speed < USB_SPEED_SUPER) + maxpower = min(maxpower, 500U); + else + maxpower = min(maxpower, 900U); - usb_gadget_vbus_draw(gadget, maxpower ? - maxpower : CONFIG_USB_GADGET_VBUS_DRAW); + usb_gadget_vbus_draw(gadget, maxpower); } cdev->suspended = 0;