From 6a6319f45d604426d15e8aa4886d3ecd65acc163 Mon Sep 17 00:00:00 2001 From: Stefan Wahren Date: Tue, 29 Dec 2015 16:41:09 +0000 Subject: dt-bindings: ci-hdrc-usb2: add missing compatibles This patch adds the missing compatible strings from ci_hdrc_imx. Signed-off-by: Stefan Wahren Signed-off-by: Peter Chen --- Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt index 781296bfbe4f..1e8350987ad8 100644 --- a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt +++ b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt @@ -2,7 +2,14 @@ Required properties: - compatible: should be one of: + "fsl,imx23-usb" "fsl,imx27-usb" + "fsl,imx28-usb" + "fsl,imx6q-usb" + "fsl,imx6sl-usb" + "fsl,imx6sx-usb" + "fsl,imx6ul-usb" + "fsl,imx7d-usb" "lsi,zevio-usb" "qcom,ci-hdrc" "chipidea,usb2" -- cgit v1.2.3-59-g8ed1b From 4670ba6c9e6334d6d518d52499628f6bcb08fa95 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Mon, 1 Feb 2016 14:28:57 +0800 Subject: doc: usb: ci-hdrc-usb2: add property non-zero-ttctrl-ttha If this property is not set, the max packet size is 1023 bytes, and if the total of packet size for pervious transactions are more than 256 bytes, it can't accept any transactions within this frame. The use case is single transaction, but higher frame rate. If this property is set, the max packet size is 188 bytes, it can handle more transactions than above case, it can accept transactions until it considers the left room size within frame is less than 188 bytes, software needs to make sure it does not send more than 90% maximum_periodic_data_per_frame. The use case is multiple transactions, but less frame rate. Signed-off-by: Peter Chen --- Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt index 1e8350987ad8..1084e2bcbe1c 100644 --- a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt +++ b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt @@ -60,6 +60,22 @@ Optional properties: be specified. - phy-clkgate-delay-us: the delay time (us) between putting the PHY into low power mode and gating the PHY clock. +- non-zero-ttctrl-ttha: after setting this property, the value of register + ttctrl.ttha will be 0x7f; if not, the value will be 0x0, this is the default + value. It needs to be very carefully for setting this property, it is + recommended that consult with your IC engineer before setting this value. + On the most of chipidea platforms, the "usage_tt" flag at RTL is 0, so this + property only affects siTD. + If this property is not set, the max packet size is 1023 bytes, and if + the total of packet size for pervious transactions are more than 256 bytes, + it can't accept any transactions within this frame. The use case is single + transaction, but higher frame rate. + If this property is set, the max packet size is 188 bytes, it can handle + more transactions than above case, it can accept transactions until it + considers the left room size within frame is less than 188 bytes, software + needs to make sure it does not send more than 90% + maximum_periodic_data_per_frame. The use case is multiple transactions, but + less frame rate. i.mx specific properties - fsl,usbmisc: phandler of non-core register device, with one -- cgit v1.2.3-59-g8ed1b From 7ed0c9613bcb959f4dd0cd7e44e320e94b6f44de Mon Sep 17 00:00:00 2001 From: Shawn Lin Date: Tue, 5 Jan 2016 09:07:14 +0800 Subject: Documentation: bindings: add dt documentation for Rockchip eMMC PHY This patch adds a binding that describes the Rockchip eMMC PHYs found on Rockchip SoCs eMMC interface. Signed-off-by: Shawn Lin Signed-off-by: Kishon Vijay Abraham I --- .../devicetree/bindings/phy/rockchip-emmc-phy.txt | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 Documentation/devicetree/bindings/phy/rockchip-emmc-phy.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/phy/rockchip-emmc-phy.txt b/Documentation/devicetree/bindings/phy/rockchip-emmc-phy.txt new file mode 100644 index 000000000000..61916f15a949 --- /dev/null +++ b/Documentation/devicetree/bindings/phy/rockchip-emmc-phy.txt @@ -0,0 +1,19 @@ +Rockchip EMMC PHY +----------------------- + +Required properties: + - compatible: rockchip,rk3399-emmc-phy + - rockchip,grf : phandle to the syscon managing the "general + register files" + - #phy-cells: must be 0 + - reg: PHY configure reg address offset in "general + register files" + +Example: + +emmcphy: phy { + compatible = "rockchip,rk3399-emmc-phy"; + rockchip,grf = <&grf>; + reg = <0xf780>; + #phy-cells = <0>; +}; -- cgit v1.2.3-59-g8ed1b From 12df9c50568a08db0b38fb70f088b80ec2793191 Mon Sep 17 00:00:00 2001 From: Yakir Yang Date: Mon, 15 Feb 2016 19:01:43 +0800 Subject: dt-bindings: add document for rockchip dp phy Add dt binding documentation for rockchip display port PHY. Signed-off-by: Yakir Yang Acked-by: Rob Herring Reviewed-by: Heiko Stuebner Signed-off-by: Kishon Vijay Abraham I --- .../devicetree/bindings/phy/rockchip-dp-phy.txt | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 Documentation/devicetree/bindings/phy/rockchip-dp-phy.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/phy/rockchip-dp-phy.txt b/Documentation/devicetree/bindings/phy/rockchip-dp-phy.txt new file mode 100644 index 000000000000..50c4f9b00adf --- /dev/null +++ b/Documentation/devicetree/bindings/phy/rockchip-dp-phy.txt @@ -0,0 +1,22 @@ +Rockchip specific extensions to the Analogix Display Port PHY +------------------------------------ + +Required properties: +- compatible : should be one of the following supported values: + - "rockchip.rk3288-dp-phy" +- clocks: from common clock binding: handle to dp clock. + of memory mapped region. +- clock-names: from common clock binding: + Required elements: "24m" +- rockchip,grf: phandle to the syscon managing the "general register files" +- #phy-cells : from the generic PHY bindings, must be 0; + +Example: + +edp_phy: edp-phy { + compatible = "rockchip,rk3288-dp-phy"; + rockchip,grf = <&grf>; + clocks = <&cru SCLK_EDP_24M>; + clock-names = "24m"; + #phy-cells = <0>; +}; -- cgit v1.2.3-59-g8ed1b From 605df8af33a7b206611a7bda01384b2b46d80e17 Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Mon, 22 Feb 2016 12:55:01 +0100 Subject: phy: rockchip-usb: add handler for usb-uart functionality Most newer Rockchip SoCs provide the possibility to use a usb-phy as passthrough for the debug uart (uart2), making it possible to for example get console output without needing to open the device. This patch adds an early_initcall to enable this functionality conditionally via the commandline and also disables the corresponding usb controller in the devicetree. Currently only data for the rk3288 is provided, but at least the rk3188 and arm64 rk3368 also provide this functionality and will be enabled later. On a spliced usb cable the signals are tx on white wire(D+) and rx on green wire(D-). The one caveat is that currently the reconfiguration of the phy happens as early_initcall, as the code depends on the unflattened devicetree being available. Everything is fine if only a regular console is active as the console-replay will happen after the reconfiguation. But with earlycon active output up to smp-init currently will get lost. The phy is an optional property for the connected dwc2 controller, so we still provide the phy device but fail all phy-ops with -EBUSY to make sure the dwc2 does not try to transmit anything on the repurposed phy. Signed-off-by: Heiko Stuebner Signed-off-by: Kishon Vijay Abraham I --- Documentation/kernel-parameters.txt | 6 + drivers/phy/phy-rockchip-usb.c | 233 ++++++++++++++++++++++++++++++------ 2 files changed, 203 insertions(+), 36 deletions(-) (limited to 'Documentation') diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 87d40a72f6a1..d91417b6c88e 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -3486,6 +3486,12 @@ bytes respectively. Such letter suffixes can also be entirely omitted. ro [KNL] Mount root device read-only on boot + rockchip.usb_uart + Enable the uart passthrough on the designated usb port + on Rockchip SoCs. When active, the signals of the + debug-uart get routed to the D+ and D- pins of the usb + port and the regular usb controller gets disabled. + root= [KNL] Root filesystem See name_to_dev_t comment in init/do_mounts.c. diff --git a/drivers/phy/phy-rockchip-usb.c b/drivers/phy/phy-rockchip-usb.c index 33a80eba1cb4..f62d899063a3 100644 --- a/drivers/phy/phy-rockchip-usb.c +++ b/drivers/phy/phy-rockchip-usb.c @@ -30,21 +30,23 @@ #include #include -/* - * The higher 16-bit of this register is used for write protection - * only if BIT(13 + 16) set to 1 the BIT(13) can be written. - */ -#define SIDDQ_WRITE_ENA BIT(29) -#define SIDDQ_ON BIT(13) -#define SIDDQ_OFF (0 << 13) +static int enable_usb_uart; + +#define HIWORD_UPDATE(val, mask) \ + ((val) | (mask) << 16) + +#define UOC_CON0_SIDDQ BIT(13) struct rockchip_usb_phys { int reg; const char *pll_name; }; +struct rockchip_usb_phy_base; struct rockchip_usb_phy_pdata { struct rockchip_usb_phys *phys; + int (*init_usb_uart)(struct regmap *grf); + int usb_uart_phy; }; struct rockchip_usb_phy_base { @@ -61,13 +63,15 @@ struct rockchip_usb_phy { struct clk *clk480m; struct clk_hw clk480m_hw; struct phy *phy; + bool uart_enabled; }; static int rockchip_usb_phy_power(struct rockchip_usb_phy *phy, bool siddq) { - return regmap_write(phy->base->reg_base, phy->reg_offset, - SIDDQ_WRITE_ENA | (siddq ? SIDDQ_ON : SIDDQ_OFF)); + u32 val = HIWORD_UPDATE(siddq ? UOC_CON0_SIDDQ : 0, UOC_CON0_SIDDQ); + + return regmap_write(phy->base->reg_base, phy->reg_offset, val); } static unsigned long rockchip_usb_phy480m_recalc_rate(struct clk_hw *hw, @@ -108,7 +112,7 @@ static int rockchip_usb_phy480m_is_enabled(struct clk_hw *hw) if (ret < 0) return ret; - return (val & SIDDQ_ON) ? 0 : 1; + return (val & UOC_CON0_SIDDQ) ? 0 : 1; } static const struct clk_ops rockchip_usb_phy480m_ops = { @@ -122,6 +126,9 @@ static int rockchip_usb_phy_power_off(struct phy *_phy) { struct rockchip_usb_phy *phy = phy_get_drvdata(_phy); + if (phy->uart_enabled) + return -EBUSY; + clk_disable_unprepare(phy->clk480m); return 0; @@ -131,6 +138,9 @@ static int rockchip_usb_phy_power_on(struct phy *_phy) { struct rockchip_usb_phy *phy = phy_get_drvdata(_phy); + if (phy->uart_enabled) + return -EBUSY; + return clk_prepare_enable(phy->clk480m); } @@ -144,8 +154,10 @@ static void rockchip_usb_phy_action(void *data) { struct rockchip_usb_phy *rk_phy = data; - of_clk_del_provider(rk_phy->np); - clk_unregister(rk_phy->clk480m); + if (!rk_phy->uart_enabled) { + of_clk_del_provider(rk_phy->np); + clk_unregister(rk_phy->clk480m); + } if (rk_phy->clk) clk_put(rk_phy->clk); @@ -194,30 +206,35 @@ static int rockchip_usb_phy_init(struct rockchip_usb_phy_base *base, return -EINVAL; } - if (rk_phy->clk) { - clk_name = __clk_get_name(rk_phy->clk); - init.flags = 0; - init.parent_names = &clk_name; - init.num_parents = 1; + if (enable_usb_uart && base->pdata->usb_uart_phy == i) { + dev_dbg(base->dev, "phy%d used as uart output\n", i); + rk_phy->uart_enabled = true; } else { - init.flags = CLK_IS_ROOT; - init.parent_names = NULL; - init.num_parents = 0; - } + if (rk_phy->clk) { + clk_name = __clk_get_name(rk_phy->clk); + init.flags = 0; + init.parent_names = &clk_name; + init.num_parents = 1; + } else { + init.flags = CLK_IS_ROOT; + init.parent_names = NULL; + init.num_parents = 0; + } - init.ops = &rockchip_usb_phy480m_ops; - rk_phy->clk480m_hw.init = &init; + init.ops = &rockchip_usb_phy480m_ops; + rk_phy->clk480m_hw.init = &init; - rk_phy->clk480m = clk_register(base->dev, &rk_phy->clk480m_hw); - if (IS_ERR(rk_phy->clk480m)) { - err = PTR_ERR(rk_phy->clk480m); - goto err_clk; - } + rk_phy->clk480m = clk_register(base->dev, &rk_phy->clk480m_hw); + if (IS_ERR(rk_phy->clk480m)) { + err = PTR_ERR(rk_phy->clk480m); + goto err_clk; + } - err = of_clk_add_provider(child, of_clk_src_simple_get, - rk_phy->clk480m); - if (err < 0) - goto err_clk_prov; + err = of_clk_add_provider(child, of_clk_src_simple_get, + rk_phy->clk480m); + if (err < 0) + goto err_clk_prov; + } err = devm_add_action(base->dev, rockchip_usb_phy_action, rk_phy); if (err) @@ -230,13 +247,21 @@ static int rockchip_usb_phy_init(struct rockchip_usb_phy_base *base, } phy_set_drvdata(rk_phy->phy, rk_phy); - /* only power up usb phy when it use, so disable it when init*/ - return rockchip_usb_phy_power(rk_phy, 1); + /* + * When acting as uart-pipe, just keep clock on otherwise + * only power up usb phy when it use, so disable it when init + */ + if (rk_phy->uart_enabled) + return clk_prepare_enable(rk_phy->clk); + else + return rockchip_usb_phy_power(rk_phy, 1); err_devm_action: - of_clk_del_provider(child); + if (!rk_phy->uart_enabled) + of_clk_del_provider(child); err_clk_prov: - clk_unregister(rk_phy->clk480m); + if (!rk_phy->uart_enabled) + clk_unregister(rk_phy->clk480m); err_clk: if (rk_phy->clk) clk_put(rk_phy->clk); @@ -259,6 +284,86 @@ static const struct rockchip_usb_phy_pdata rk3188_pdata = { }, }; +#define RK3288_UOC0_CON0 0x320 +#define RK3288_UOC0_CON0_COMMON_ON_N BIT(0) +#define RK3288_UOC0_CON0_DISABLE BIT(4) + +#define RK3288_UOC0_CON2 0x328 +#define RK3288_UOC0_CON2_SOFT_CON_SEL BIT(2) + +#define RK3288_UOC0_CON3 0x32c +#define RK3288_UOC0_CON3_UTMI_SUSPENDN BIT(0) +#define RK3288_UOC0_CON3_UTMI_OPMODE_NODRIVING (1 << 1) +#define RK3288_UOC0_CON3_UTMI_OPMODE_MASK (3 << 1) +#define RK3288_UOC0_CON3_UTMI_XCVRSEELCT_FSTRANSC (1 << 3) +#define RK3288_UOC0_CON3_UTMI_XCVRSEELCT_MASK (3 << 3) +#define RK3288_UOC0_CON3_UTMI_TERMSEL_FULLSPEED BIT(5) +#define RK3288_UOC0_CON3_BYPASSDMEN BIT(6) +#define RK3288_UOC0_CON3_BYPASSSEL BIT(7) + +/* + * Enable the bypass of uart2 data through the otg usb phy. + * Original description in the TRM. + * 1. Disable the OTG block by setting OTGDISABLE0 to 1’b1. + * 2. Disable the pull-up resistance on the D+ line by setting + * OPMODE0[1:0] to 2’b01. + * 3. To ensure that the XO, Bias, and PLL blocks are powered down in Suspend + * mode, set COMMONONN to 1’b1. + * 4. Place the USB PHY in Suspend mode by setting SUSPENDM0 to 1’b0. + * 5. Set BYPASSSEL0 to 1’b1. + * 6. To transmit data, controls BYPASSDMEN0, and BYPASSDMDATA0. + * To receive data, monitor FSVPLUS0. + * + * The actual code in the vendor kernel does some things differently. + */ +static int __init rk3288_init_usb_uart(struct regmap *grf) +{ + u32 val; + int ret; + + /* + * COMMON_ON and DISABLE settings are described in the TRM, + * but were not present in the original code. + * Also disable the analog phy components to save power. + */ + val = HIWORD_UPDATE(RK3288_UOC0_CON0_COMMON_ON_N + | RK3288_UOC0_CON0_DISABLE + | UOC_CON0_SIDDQ, + RK3288_UOC0_CON0_COMMON_ON_N + | RK3288_UOC0_CON0_DISABLE + | UOC_CON0_SIDDQ); + ret = regmap_write(grf, RK3288_UOC0_CON0, val); + if (ret) + return ret; + + val = HIWORD_UPDATE(RK3288_UOC0_CON2_SOFT_CON_SEL, + RK3288_UOC0_CON2_SOFT_CON_SEL); + ret = regmap_write(grf, RK3288_UOC0_CON2, val); + if (ret) + return ret; + + val = HIWORD_UPDATE(RK3288_UOC0_CON3_UTMI_OPMODE_NODRIVING + | RK3288_UOC0_CON3_UTMI_XCVRSEELCT_FSTRANSC + | RK3288_UOC0_CON3_UTMI_TERMSEL_FULLSPEED, + RK3288_UOC0_CON3_UTMI_SUSPENDN + | RK3288_UOC0_CON3_UTMI_OPMODE_MASK + | RK3288_UOC0_CON3_UTMI_XCVRSEELCT_MASK + | RK3288_UOC0_CON3_UTMI_TERMSEL_FULLSPEED); + ret = regmap_write(grf, RK3288_UOC0_CON3, val); + if (ret) + return ret; + + val = HIWORD_UPDATE(RK3288_UOC0_CON3_BYPASSSEL + | RK3288_UOC0_CON3_BYPASSDMEN, + RK3288_UOC0_CON3_BYPASSSEL + | RK3288_UOC0_CON3_BYPASSDMEN); + ret = regmap_write(grf, RK3288_UOC0_CON3, val); + if (ret) + return ret; + + return 0; +} + static const struct rockchip_usb_phy_pdata rk3288_pdata = { .phys = (struct rockchip_usb_phys[]){ { .reg = 0x320, .pll_name = "sclk_otgphy0_480m" }, @@ -266,6 +371,8 @@ static const struct rockchip_usb_phy_pdata rk3288_pdata = { { .reg = 0x348, .pll_name = "sclk_otgphy2_480m" }, { /* sentinel */ } }, + .init_usb_uart = rk3288_init_usb_uart, + .usb_uart_phy = 0, }; static int rockchip_usb_phy_probe(struct platform_device *pdev) @@ -328,6 +435,60 @@ static struct platform_driver rockchip_usb_driver = { module_platform_driver(rockchip_usb_driver); +#ifndef MODULE +static int __init rockchip_init_usb_uart(void) +{ + const struct of_device_id *match; + const struct rockchip_usb_phy_pdata *data; + struct device_node *np; + struct regmap *grf; + int ret; + + if (!enable_usb_uart) + return 0; + + np = of_find_matching_node_and_match(NULL, rockchip_usb_phy_dt_ids, + &match); + if (!np) { + pr_err("%s: failed to find usbphy node\n", __func__); + return -ENOTSUPP; + } + + pr_debug("%s: using settings for %s\n", __func__, match->compatible); + data = match->data; + + if (!data->init_usb_uart) { + pr_err("%s: usb-uart not available on %s\n", + __func__, match->compatible); + return -ENOTSUPP; + } + + grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf"); + if (IS_ERR(grf)) { + pr_err("%s: Missing rockchip,grf property, %lu\n", + __func__, PTR_ERR(grf)); + return PTR_ERR(grf); + } + + ret = data->init_usb_uart(grf); + if (ret) { + pr_err("%s: could not init usb_uart, %d\n", __func__, ret); + enable_usb_uart = 0; + return ret; + } + + return 0; +} +early_initcall(rockchip_init_usb_uart); + +static int __init rockchip_usb_uart(char *buf) +{ + enable_usb_uart = true; + return 0; +} +early_param("rockchip.usb_uart", rockchip_usb_uart); +#endif + MODULE_AUTHOR("Yunzhi Li "); MODULE_DESCRIPTION("Rockchip USB 2.0 PHY driver"); MODULE_LICENSE("GPL v2"); -- cgit v1.2.3-59-g8ed1b From b956401699472605e5673b93de87bc248b9609c2 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Thu, 7 Jan 2016 18:16:44 +0900 Subject: phy: rcar-gen3-usb2: remove HSUSB registers handling Since the related driver (CPG/MSSR driver) only manages the first module clock, this driver should not handle the HSUSB registers. So, this patch removes the HSUSB registers handling. Signed-off-by: Yoshihiro Shimoda Acked-by: Rob Herring Signed-off-by: Kishon Vijay Abraham I --- .../devicetree/bindings/phy/rcar-gen3-phy-usb2.txt | 15 ++-- drivers/phy/phy-rcar-gen3-usb2.c | 83 +++------------------- 2 files changed, 15 insertions(+), 83 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb2.txt b/Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb2.txt index 2390e4e9c84c..eaf7e9b7ce6b 100644 --- a/Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb2.txt +++ b/Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb2.txt @@ -7,33 +7,26 @@ Required properties: - compatible: "renesas,usb2-phy-r8a7795" if the device is a part of an R8A7795 SoC. - reg: offset and length of the partial USB 2.0 Host register block. -- reg-names: must be "usb2_host". - clocks: clock phandle and specifier pair(s). - #phy-cells: see phy-bindings.txt in the same directory, must be <0>. Optional properties: To use a USB channel where USB 2.0 Host and HSUSB (USB 2.0 Peripheral) are -combined, the device tree node should set HSUSB properties to reg and reg-names -properties. This is because HSUSB has registers to select USB 2.0 host or -peripheral at that channel: -- reg: offset and length of the partial HSUSB register block. -- reg-names: must be "hsusb". +combined, the device tree node should set interrupt properties to use the +channel as USB OTG: - interrupts: interrupt specifier for the PHY. Example (R-Car H3): usb-phy@ee080200 { compatible = "renesas,usb2-phy-r8a7795"; - reg = <0 0xee080200 0 0x700>, <0 0xe6590100 0 0x100>; - reg-names = "usb2_host", "hsusb"; + reg = <0 0xee080200 0 0x700>; interrupts = ; - clocks = <&mstp7_clks R8A7795_CLK_EHCI0>, - <&mstp7_clks R8A7795_CLK_HSUSB>; + clocks = <&mstp7_clks R8A7795_CLK_EHCI0>; }; usb-phy@ee0a0200 { compatible = "renesas,usb2-phy-r8a7795"; reg = <0 0xee0a0200 0 0x700>; - reg-names = "usb2_host"; clocks = <&mstp7_clks R8A7795_CLK_EHCI0>; }; diff --git a/drivers/phy/phy-rcar-gen3-usb2.c b/drivers/phy/phy-rcar-gen3-usb2.c index ef332ef4abc7..bc4f7dd821aa 100644 --- a/drivers/phy/phy-rcar-gen3-usb2.c +++ b/drivers/phy/phy-rcar-gen3-usb2.c @@ -74,20 +74,6 @@ #define USB2_ADPCTRL_IDPULLUP BIT(5) /* 1 = ID sampling is enabled */ #define USB2_ADPCTRL_DRVVBUS BIT(4) -/******* HSUSB registers (original offset is +0x100) *******/ -#define HSUSB_LPSTS 0x02 -#define HSUSB_UGCTRL2 0x84 - -/* Low Power Status register (LPSTS) */ -#define HSUSB_LPSTS_SUSPM 0x4000 - -/* USB General control register 2 (UGCTRL2) */ -#define HSUSB_UGCTRL2_MASK 0x00000031 /* bit[31:6] should be 0 */ -#define HSUSB_UGCTRL2_USB0SEL 0x00000030 -#define HSUSB_UGCTRL2_USB0SEL_HOST 0x00000010 -#define HSUSB_UGCTRL2_USB0SEL_HS_USB 0x00000020 -#define HSUSB_UGCTRL2_USB0SEL_OTG 0x00000030 - struct rcar_gen3_data { void __iomem *base; struct clk *clk; @@ -95,8 +81,8 @@ struct rcar_gen3_data { struct rcar_gen3_chan { struct rcar_gen3_data usb2; - struct rcar_gen3_data hsusb; struct phy *phy; + bool has_otg; }; static void rcar_gen3_set_host_mode(struct rcar_gen3_chan *ch, int host) @@ -202,24 +188,15 @@ static int rcar_gen3_phy_usb2_init(struct phy *p) { struct rcar_gen3_chan *channel = phy_get_drvdata(p); void __iomem *usb2_base = channel->usb2.base; - void __iomem *hsusb_base = channel->hsusb.base; - u32 val; /* Initialize USB2 part */ writel(USB2_INT_ENABLE_INIT, usb2_base + USB2_INT_ENABLE); writel(USB2_SPD_RSM_TIMSET_INIT, usb2_base + USB2_SPD_RSM_TIMSET); writel(USB2_OC_TIMSET_INIT, usb2_base + USB2_OC_TIMSET); - /* Initialize HSUSB part */ - if (hsusb_base) { - val = readl(hsusb_base + HSUSB_UGCTRL2); - val = (val & ~HSUSB_UGCTRL2_USB0SEL) | - HSUSB_UGCTRL2_USB0SEL_OTG; - writel(val & HSUSB_UGCTRL2_MASK, hsusb_base + HSUSB_UGCTRL2); - - /* Initialize otg part */ + /* Initialize otg part */ + if (channel->has_otg) rcar_gen3_init_otg(channel); - } return 0; } @@ -237,7 +214,6 @@ static int rcar_gen3_phy_usb2_power_on(struct phy *p) { struct rcar_gen3_chan *channel = phy_get_drvdata(p); void __iomem *usb2_base = channel->usb2.base; - void __iomem *hsusb_base = channel->hsusb.base; u32 val; val = readl(usb2_base + USB2_USBCTR); @@ -246,33 +222,6 @@ static int rcar_gen3_phy_usb2_power_on(struct phy *p) val &= ~USB2_USBCTR_PLL_RST; writel(val, usb2_base + USB2_USBCTR); - /* - * TODO: To reduce power consuming, this driver should set the SUSPM - * after the PHY detects ID pin as peripheral. - */ - if (hsusb_base) { - /* Power on HSUSB PHY */ - val = readw(hsusb_base + HSUSB_LPSTS); - val |= HSUSB_LPSTS_SUSPM; - writew(val, hsusb_base + HSUSB_LPSTS); - } - - return 0; -} - -static int rcar_gen3_phy_usb2_power_off(struct phy *p) -{ - struct rcar_gen3_chan *channel = phy_get_drvdata(p); - void __iomem *hsusb_base = channel->hsusb.base; - u32 val; - - if (hsusb_base) { - /* Power off HSUSB PHY */ - val = readw(hsusb_base + HSUSB_LPSTS); - val &= ~HSUSB_LPSTS_SUSPM; - writew(val, hsusb_base + HSUSB_LPSTS); - } - return 0; } @@ -280,7 +229,6 @@ static struct phy_ops rcar_gen3_phy_usb2_ops = { .init = rcar_gen3_phy_usb2_init, .exit = rcar_gen3_phy_usb2_exit, .power_on = rcar_gen3_phy_usb2_power_on, - .power_off = rcar_gen3_phy_usb2_power_off, .owner = THIS_MODULE, }; @@ -313,6 +261,7 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev) struct rcar_gen3_chan *channel; struct phy_provider *provider; struct resource *res; + int irq; if (!dev->of_node) { dev_err(dev, "This driver needs device tree\n"); @@ -323,29 +272,19 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev) if (!channel) return -ENOMEM; - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "usb2_host"); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); channel->usb2.base = devm_ioremap_resource(dev, res); if (IS_ERR(channel->usb2.base)) return PTR_ERR(channel->usb2.base); - /* "hsusb" memory resource is optional */ - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hsusb"); - - /* To avoid error message by devm_ioremap_resource() */ - if (res) { - int irq; - - channel->hsusb.base = devm_ioremap_resource(dev, res); - if (IS_ERR(channel->hsusb.base)) - channel->hsusb.base = NULL; - /* call request_irq for OTG */ - irq = platform_get_irq(pdev, 0); - if (irq >= 0) - irq = devm_request_irq(dev, irq, rcar_gen3_phy_usb2_irq, - IRQF_SHARED, dev_name(dev), - channel); + /* call request_irq for OTG */ + irq = platform_get_irq(pdev, 0); + if (irq >= 0) { + irq = devm_request_irq(dev, irq, rcar_gen3_phy_usb2_irq, + IRQF_SHARED, dev_name(dev), channel); if (irq < 0) dev_err(dev, "No irq handler (%d)\n", irq); + channel->has_otg = true; } /* devm_phy_create() will call pm_runtime_enable(dev); */ -- cgit v1.2.3-59-g8ed1b From f1bbdc3b0402061ac52fc1b34cc018b0c227f4a4 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Thu, 18 Feb 2016 17:55:49 +0200 Subject: usb: host: xhci-plat: add R-Car Gen2 and Gen3 fallback compatibility strings Add fallback compatibility strings for R-Car Gen2 and Gen3. This is in keeping with the fallback scheme being adopted wherever appropriate for drivers for Renesas SoCs. Signed-off-by: Simon Horman Acked-by: Geert Uytterhoeven Acked-by: Gregory CLEMENT Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/usb/usb-xhci.txt | 21 +++++++++++++++++---- drivers/usb/host/xhci-plat.c | 5 +++++ 2 files changed, 22 insertions(+), 4 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/usb/usb-xhci.txt b/Documentation/devicetree/bindings/usb/usb-xhci.txt index 082573289f1e..6a17aa85c4d5 100644 --- a/Documentation/devicetree/bindings/usb/usb-xhci.txt +++ b/Documentation/devicetree/bindings/usb/usb-xhci.txt @@ -1,10 +1,23 @@ USB xHCI controllers Required properties: - - compatible: should be one of "generic-xhci", - "marvell,armada-375-xhci", "marvell,armada-380-xhci", - "renesas,xhci-r8a7790", "renesas,xhci-r8a7791", "renesas,xhci-r8a7793", - "renesas,xhci-r8a7795" (deprecated: "xhci-platform"). + - compatible: should be one or more of + + - "generic-xhci" for generic XHCI device + - "marvell,armada-375-xhci" for Armada 375 SoCs + - "marvell,armada-380-xhci" for Armada 38x SoCs + - "renesas,xhci-r8a7790" for r8a7790 SoC + - "renesas,xhci-r8a7791" for r8a7791 SoC + - "renesas,xhci-r8a7793" for r8a7793 SoC + - "renesas,xhci-r8a7795" for r8a7795 SoC + - "renesas,rcar-gen2-xhci" for a generic R-Car Gen2 compatible device + - "renesas,rcar-gen3-xhci" for a generic R-Car Gen3 compatible device + - "xhci-platform" (deprecated) + + When compatible with the generic version, nodes must list the + SoC-specific version corresponding to the platform first + followed by the generic version. + - reg: should contain address and length of the standard XHCI register set for the device. - interrupts: one XHCI interrupt should be described here. diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index d39d6bf1d090..3aede6eb9637 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c @@ -110,6 +110,11 @@ static const struct of_device_id usb_xhci_of_match[] = { .compatible = "renesas,xhci-r8a7795", .data = &xhci_plat_renesas_rcar_gen3, }, { + .compatible = "renesas,rcar-gen2-xhci", + .data = &xhci_plat_renesas_rcar_gen2, + }, { + .compatible = "renesas,rcar-gen3-xhci", + .data = &xhci_plat_renesas_rcar_gen3, }, }; MODULE_DEVICE_TABLE(of, usb_xhci_of_match); -- cgit v1.2.3-59-g8ed1b From a6d6fc2b671aba52da2ca0ca4f3cdd25e03e90cf Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Wed, 24 Feb 2016 19:30:35 +0100 Subject: usbip: move usbip_protocol.txt to Documentation The usbip_protocol.txt, a document which describes usbip's inner workings is currently located in the projects source directory (drivers/usb/usbip/...). This patch moves it to Documentation/usb. This discussion was brought up by Guy Harris [0] during the review of the USBIP dissector I wrote. For anyone interested: support is available with the latest wireshark master/dev tree. Simply select a packet from the usbip's tcp-stream you are intrested on and select the USBIP as the protocol in the "Decode As" dialog box [1]. Signed-off-by: Christian Lamparter [0] [1] Signed-off-by: Greg Kroah-Hartman --- Documentation/usb/usbip_protocol.txt | 358 +++++++++++++++++++++++++++++++++++ MAINTAINERS | 1 + drivers/usb/usbip/usbip_protocol.txt | 358 ----------------------------------- 3 files changed, 359 insertions(+), 358 deletions(-) create mode 100644 Documentation/usb/usbip_protocol.txt delete mode 100644 drivers/usb/usbip/usbip_protocol.txt (limited to 'Documentation') diff --git a/Documentation/usb/usbip_protocol.txt b/Documentation/usb/usbip_protocol.txt new file mode 100644 index 000000000000..16b6fe27284c --- /dev/null +++ b/Documentation/usb/usbip_protocol.txt @@ -0,0 +1,358 @@ +PRELIMINARY DRAFT, MAY CONTAIN MISTAKES! +28 Jun 2011 + +The USB/IP protocol follows a server/client architecture. The server exports the +USB devices and the clients imports them. The device driver for the exported +USB device runs on the client machine. + +The client may ask for the list of the exported USB devices. To get the list the +client opens a TCP/IP connection towards the server, and sends an OP_REQ_DEVLIST +packet on top of the TCP/IP connection (so the actual OP_REQ_DEVLIST may be sent +in one or more pieces at the low level transport layer). The server sends back +the OP_REP_DEVLIST packet which lists the exported USB devices. Finally the +TCP/IP connection is closed. + + virtual host controller usb host + "client" "server" + (imports USB devices) (exports USB devices) + | | + | OP_REQ_DEVLIST | + | ----------------------------------------------> | + | | + | OP_REP_DEVLIST | + | <---------------------------------------------- | + | | + +Once the client knows the list of exported USB devices it may decide to use one +of them. First the client opens a TCP/IP connection towards the server and +sends an OP_REQ_IMPORT packet. The server replies with OP_REP_IMPORT. If the +import was successful the TCP/IP connection remains open and will be used +to transfer the URB traffic between the client and the server. The client may +send two types of packets: the USBIP_CMD_SUBMIT to submit an URB, and +USBIP_CMD_UNLINK to unlink a previously submitted URB. The answers of the +server may be USBIP_RET_SUBMIT and USBIP_RET_UNLINK respectively. + + virtual host controller usb host + "client" "server" + (imports USB devices) (exports USB devices) + | | + | OP_REQ_IMPORT | + | ----------------------------------------------> | + | | + | OP_REP_IMPORT | + | <---------------------------------------------- | + | | + | | + | USBIP_CMD_SUBMIT(seqnum = n) | + | ----------------------------------------------> | + | | + | USBIP_RET_SUBMIT(seqnum = n) | + | <---------------------------------------------- | + | . | + | : | + | | + | USBIP_CMD_SUBMIT(seqnum = m) | + | ----------------------------------------------> | + | | + | USBIP_CMD_SUBMIT(seqnum = m+1) | + | ----------------------------------------------> | + | | + | USBIP_CMD_SUBMIT(seqnum = m+2) | + | ----------------------------------------------> | + | | + | USBIP_RET_SUBMIT(seqnum = m) | + | <---------------------------------------------- | + | | + | USBIP_CMD_SUBMIT(seqnum = m+3) | + | ----------------------------------------------> | + | | + | USBIP_RET_SUBMIT(seqnum = m+1) | + | <---------------------------------------------- | + | | + | USBIP_CMD_SUBMIT(seqnum = m+4) | + | ----------------------------------------------> | + | | + | USBIP_RET_SUBMIT(seqnum = m+2) | + | <---------------------------------------------- | + | . | + | : | + | | + | USBIP_CMD_UNLINK | + | ----------------------------------------------> | + | | + | USBIP_RET_UNLINK | + | <---------------------------------------------- | + | | + +The fields are in network (big endian) byte order meaning that the most significant +byte (MSB) is stored at the lowest address. + + +OP_REQ_DEVLIST: Retrieve the list of exported USB devices. + + Offset | Length | Value | Description +-----------+--------+------------+--------------------------------------------------- + 0 | 2 | 0x0100 | Binary-coded decimal USBIP version number: v1.0.0 +-----------+--------+------------+--------------------------------------------------- + 2 | 2 | 0x8005 | Command code: Retrieve the list of exported USB + | | | devices. +-----------+--------+------------+--------------------------------------------------- + 4 | 4 | 0x00000000 | Status: unused, shall be set to 0 + +OP_REP_DEVLIST: Reply with the list of exported USB devices. + + Offset | Length | Value | Description +-----------+--------+------------+--------------------------------------------------- + 0 | 2 | 0x0100 | Binary-coded decimal USBIP version number: v1.0.0. +-----------+--------+------------+--------------------------------------------------- + 2 | 2 | 0x0005 | Reply code: The list of exported USB devices. +-----------+--------+------------+--------------------------------------------------- + 4 | 4 | 0x00000000 | Status: 0 for OK +-----------+--------+------------+--------------------------------------------------- + 8 | 4 | n | Number of exported devices: 0 means no exported + | | | devices. +-----------+--------+------------+--------------------------------------------------- + 0x0C | | | From now on the exported n devices are described, + | | | if any. If no devices are exported the message + | | | ends with the previous "number of exported + | | | devices" field. +-----------+--------+------------+--------------------------------------------------- + | 256 | | path: Path of the device on the host exporting the + | | | USB device, string closed with zero byte, e.g. + | | | "/sys/devices/pci0000:00/0000:00:1d.1/usb3/3-2" + | | | The unused bytes shall be filled with zero + | | | bytes. +-----------+--------+------------+--------------------------------------------------- + 0x10C | 32 | | busid: Bus ID of the exported device, string + | | | closed with zero byte, e.g. "3-2". The unused + | | | bytes shall be filled with zero bytes. +-----------+--------+------------+--------------------------------------------------- + 0x12C | 4 | | busnum +-----------+--------+------------+--------------------------------------------------- + 0x130 | 4 | | devnum +-----------+--------+------------+--------------------------------------------------- + 0x134 | 4 | | speed +-----------+--------+------------+--------------------------------------------------- + 0x138 | 2 | | idVendor +-----------+--------+------------+--------------------------------------------------- + 0x13A | 2 | | idProduct +-----------+--------+------------+--------------------------------------------------- + 0x13C | 2 | | bcdDevice +-----------+--------+------------+--------------------------------------------------- + 0x13E | 1 | | bDeviceClass +-----------+--------+------------+--------------------------------------------------- + 0x13F | 1 | | bDeviceSubClass +-----------+--------+------------+--------------------------------------------------- + 0x140 | 1 | | bDeviceProtocol +-----------+--------+------------+--------------------------------------------------- + 0x141 | 1 | | bConfigurationValue +-----------+--------+------------+--------------------------------------------------- + 0x142 | 1 | | bNumConfigurations +-----------+--------+------------+--------------------------------------------------- + 0x143 | 1 | | bNumInterfaces +-----------+--------+------------+--------------------------------------------------- + 0x144 | | m_0 | From now on each interface is described, all + | | | together bNumInterfaces times, with the + | | | the following 4 fields: +-----------+--------+------------+--------------------------------------------------- + | 1 | | bInterfaceClass +-----------+--------+------------+--------------------------------------------------- + 0x145 | 1 | | bInterfaceSubClass +-----------+--------+------------+--------------------------------------------------- + 0x146 | 1 | | bInterfaceProtocol +-----------+--------+------------+--------------------------------------------------- + 0x147 | 1 | | padding byte for alignment, shall be set to zero +-----------+--------+------------+--------------------------------------------------- + 0xC + | | | The second exported USB device starts at i=1 + i*0x138 + | | | with the busid field. + m_(i-1)*4 | | | + +OP_REQ_IMPORT: Request to import (attach) a remote USB device. + + Offset | Length | Value | Description +-----------+--------+------------+--------------------------------------------------- + 0 | 2 | 0x0100 | Binary-coded decimal USBIP version number: v1.0.0 +-----------+--------+------------+--------------------------------------------------- + 2 | 2 | 0x8003 | Command code: import a remote USB device. +-----------+--------+------------+--------------------------------------------------- + 4 | 4 | 0x00000000 | Status: unused, shall be set to 0 +-----------+--------+------------+--------------------------------------------------- + 8 | 32 | | busid: the busid of the exported device on the + | | | remote host. The possible values are taken + | | | from the message field OP_REP_DEVLIST.busid. + | | | A string closed with zero, the unused bytes + | | | shall be filled with zeros. +-----------+--------+------------+--------------------------------------------------- + +OP_REP_IMPORT: Reply to import (attach) a remote USB device. + + Offset | Length | Value | Description +-----------+--------+------------+--------------------------------------------------- + 0 | 2 | 0x0100 | Binary-coded decimal USBIP version number: v1.0.0 +-----------+--------+------------+--------------------------------------------------- + 2 | 2 | 0x0003 | Reply code: Reply to import. +-----------+--------+------------+--------------------------------------------------- + 4 | 4 | 0x00000000 | Status: 0 for OK + | | | 1 for error +-----------+--------+------------+--------------------------------------------------- + 8 | | | From now on comes the details of the imported + | | | device, if the previous status field was OK (0), + | | | otherwise the reply ends with the status field. +-----------+--------+------------+--------------------------------------------------- + | 256 | | path: Path of the device on the host exporting the + | | | USB device, string closed with zero byte, e.g. + | | | "/sys/devices/pci0000:00/0000:00:1d.1/usb3/3-2" + | | | The unused bytes shall be filled with zero + | | | bytes. +-----------+--------+------------+--------------------------------------------------- + 0x108 | 32 | | busid: Bus ID of the exported device, string + | | | closed with zero byte, e.g. "3-2". The unused + | | | bytes shall be filled with zero bytes. +-----------+--------+------------+--------------------------------------------------- + 0x128 | 4 | | busnum +-----------+--------+------------+--------------------------------------------------- + 0x12C | 4 | | devnum +-----------+--------+------------+--------------------------------------------------- + 0x130 | 4 | | speed +-----------+--------+------------+--------------------------------------------------- + 0x134 | 2 | | idVendor +-----------+--------+------------+--------------------------------------------------- + 0x136 | 2 | | idProduct +-----------+--------+------------+--------------------------------------------------- + 0x138 | 2 | | bcdDevice +-----------+--------+------------+--------------------------------------------------- + 0x139 | 1 | | bDeviceClass +-----------+--------+------------+--------------------------------------------------- + 0x13A | 1 | | bDeviceSubClass +-----------+--------+------------+--------------------------------------------------- + 0x13B | 1 | | bDeviceProtocol +-----------+--------+------------+--------------------------------------------------- + 0x13C | 1 | | bConfigurationValue +-----------+--------+------------+--------------------------------------------------- + 0x13D | 1 | | bNumConfigurations +-----------+--------+------------+--------------------------------------------------- + 0x13E | 1 | | bNumInterfaces + +USBIP_CMD_SUBMIT: Submit an URB + + Offset | Length | Value | Description +-----------+--------+------------+--------------------------------------------------- + 0 | 4 | 0x00000001 | command: Submit an URB +-----------+--------+------------+--------------------------------------------------- + 4 | 4 | | seqnum: the sequence number of the URB to submit +-----------+--------+------------+--------------------------------------------------- + 8 | 4 | | devid +-----------+--------+------------+--------------------------------------------------- + 0xC | 4 | | direction: 0: USBIP_DIR_OUT + | | | 1: USBIP_DIR_IN +-----------+--------+------------+--------------------------------------------------- + 0x10 | 4 | | ep: endpoint number, possible values are: 0...15 +-----------+--------+------------+--------------------------------------------------- + 0x14 | 4 | | transfer_flags: possible values depend on the + | | | URB transfer type, see below +-----------+--------+------------+--------------------------------------------------- + 0x18 | 4 | | transfer_buffer_length +-----------+--------+------------+--------------------------------------------------- + 0x1C | 4 | | start_frame: specify the selected frame to + | | | transmit an ISO frame, ignored if URB_ISO_ASAP + | | | is specified at transfer_flags +-----------+--------+------------+--------------------------------------------------- + 0x20 | 4 | | number_of_packets: number of ISO packets +-----------+--------+------------+--------------------------------------------------- + 0x24 | 4 | | interval: maximum time for the request on the + | | | server-side host controller +-----------+--------+------------+--------------------------------------------------- + 0x28 | 8 | | setup: data bytes for USB setup, filled with + | | | zeros if not used +-----------+--------+------------+--------------------------------------------------- + 0x30 | | | URB data. For ISO transfers the padding between + | | | each ISO packets is not transmitted. + + + Allowed transfer_flags | value | control | interrupt | bulk | isochronous + -------------------------+------------+---------+-----------+----------+------------- + URB_SHORT_NOT_OK | 0x00000001 | only in | only in | only in | no + URB_ISO_ASAP | 0x00000002 | no | no | no | yes + URB_NO_TRANSFER_DMA_MAP | 0x00000004 | yes | yes | yes | yes + URB_NO_FSBR | 0x00000020 | yes | no | no | no + URB_ZERO_PACKET | 0x00000040 | no | no | only out | no + URB_NO_INTERRUPT | 0x00000080 | yes | yes | yes | yes + URB_FREE_BUFFER | 0x00000100 | yes | yes | yes | yes + URB_DIR_MASK | 0x00000200 | yes | yes | yes | yes + + +USBIP_RET_SUBMIT: Reply for submitting an URB + + Offset | Length | Value | Description +-----------+--------+------------+--------------------------------------------------- + 0 | 4 | 0x00000003 | command +-----------+--------+------------+--------------------------------------------------- + 4 | 4 | | seqnum: URB sequence number +-----------+--------+------------+--------------------------------------------------- + 8 | 4 | | devid +-----------+--------+------------+--------------------------------------------------- + 0xC | 4 | | direction: 0: USBIP_DIR_OUT + | | | 1: USBIP_DIR_IN +-----------+--------+------------+--------------------------------------------------- + 0x10 | 4 | | ep: endpoint number +-----------+--------+------------+--------------------------------------------------- + 0x14 | 4 | | status: zero for successful URB transaction, + | | | otherwise some kind of error happened. +-----------+--------+------------+--------------------------------------------------- + 0x18 | 4 | n | actual_length: number of URB data bytes +-----------+--------+------------+--------------------------------------------------- + 0x1C | 4 | | start_frame: for an ISO frame the actually + | | | selected frame for transmit. +-----------+--------+------------+--------------------------------------------------- + 0x20 | 4 | | number_of_packets +-----------+--------+------------+--------------------------------------------------- + 0x24 | 4 | | error_count +-----------+--------+------------+--------------------------------------------------- + 0x28 | 8 | | setup: data bytes for USB setup, filled with + | | | zeros if not used +-----------+--------+------------+--------------------------------------------------- + 0x30 | n | | URB data bytes. For ISO transfers the padding + | | | between each ISO packets is not transmitted. + +USBIP_CMD_UNLINK: Unlink an URB + + Offset | Length | Value | Description +-----------+--------+------------+--------------------------------------------------- + 0 | 4 | 0x00000002 | command: URB unlink command +-----------+--------+------------+--------------------------------------------------- + 4 | 4 | | seqnum: URB sequence number to unlink: FIXME: is this so? +-----------+--------+------------+--------------------------------------------------- + 8 | 4 | | devid +-----------+--------+------------+--------------------------------------------------- + 0xC | 4 | | direction: 0: USBIP_DIR_OUT + | | | 1: USBIP_DIR_IN +-----------+--------+------------+--------------------------------------------------- + 0x10 | 4 | | ep: endpoint number: zero +-----------+--------+------------+--------------------------------------------------- + 0x14 | 4 | | seqnum: the URB sequence number given previously + | | | at USBIP_CMD_SUBMIT.seqnum field +-----------+--------+------------+--------------------------------------------------- + 0x30 | n | | URB data bytes. For ISO transfers the padding + | | | between each ISO packets is not transmitted. + +USBIP_RET_UNLINK: Reply for URB unlink + + Offset | Length | Value | Description +-----------+--------+------------+--------------------------------------------------- + 0 | 4 | 0x00000004 | command: reply for the URB unlink command +-----------+--------+------------+--------------------------------------------------- + 4 | 4 | | seqnum: the unlinked URB sequence number +-----------+--------+------------+--------------------------------------------------- + 8 | 4 | | devid +-----------+--------+------------+--------------------------------------------------- + 0xC | 4 | | direction: 0: USBIP_DIR_OUT + | | | 1: USBIP_DIR_IN +-----------+--------+------------+--------------------------------------------------- + 0x10 | 4 | | ep: endpoint number +-----------+--------+------------+--------------------------------------------------- + 0x14 | 4 | | status: This is the value contained in the + | | | urb->status in the URB completition handler. + | | | FIXME: a better explanation needed. +-----------+--------+------------+--------------------------------------------------- + 0x30 | n | | URB data bytes. For ISO transfers the padding + | | | between each ISO packets is not transmitted. diff --git a/MAINTAINERS b/MAINTAINERS index a1477a7429ab..c55b37e4fa3b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -11380,6 +11380,7 @@ M: Valentina Manea M: Shuah Khan L: linux-usb@vger.kernel.org S: Maintained +F: Documentation/usb/usbip_protocol.txt F: drivers/usb/usbip/ F: tools/usb/usbip/ diff --git a/drivers/usb/usbip/usbip_protocol.txt b/drivers/usb/usbip/usbip_protocol.txt deleted file mode 100644 index 16b6fe27284c..000000000000 --- a/drivers/usb/usbip/usbip_protocol.txt +++ /dev/null @@ -1,358 +0,0 @@ -PRELIMINARY DRAFT, MAY CONTAIN MISTAKES! -28 Jun 2011 - -The USB/IP protocol follows a server/client architecture. The server exports the -USB devices and the clients imports them. The device driver for the exported -USB device runs on the client machine. - -The client may ask for the list of the exported USB devices. To get the list the -client opens a TCP/IP connection towards the server, and sends an OP_REQ_DEVLIST -packet on top of the TCP/IP connection (so the actual OP_REQ_DEVLIST may be sent -in one or more pieces at the low level transport layer). The server sends back -the OP_REP_DEVLIST packet which lists the exported USB devices. Finally the -TCP/IP connection is closed. - - virtual host controller usb host - "client" "server" - (imports USB devices) (exports USB devices) - | | - | OP_REQ_DEVLIST | - | ----------------------------------------------> | - | | - | OP_REP_DEVLIST | - | <---------------------------------------------- | - | | - -Once the client knows the list of exported USB devices it may decide to use one -of them. First the client opens a TCP/IP connection towards the server and -sends an OP_REQ_IMPORT packet. The server replies with OP_REP_IMPORT. If the -import was successful the TCP/IP connection remains open and will be used -to transfer the URB traffic between the client and the server. The client may -send two types of packets: the USBIP_CMD_SUBMIT to submit an URB, and -USBIP_CMD_UNLINK to unlink a previously submitted URB. The answers of the -server may be USBIP_RET_SUBMIT and USBIP_RET_UNLINK respectively. - - virtual host controller usb host - "client" "server" - (imports USB devices) (exports USB devices) - | | - | OP_REQ_IMPORT | - | ----------------------------------------------> | - | | - | OP_REP_IMPORT | - | <---------------------------------------------- | - | | - | | - | USBIP_CMD_SUBMIT(seqnum = n) | - | ----------------------------------------------> | - | | - | USBIP_RET_SUBMIT(seqnum = n) | - | <---------------------------------------------- | - | . | - | : | - | | - | USBIP_CMD_SUBMIT(seqnum = m) | - | ----------------------------------------------> | - | | - | USBIP_CMD_SUBMIT(seqnum = m+1) | - | ----------------------------------------------> | - | | - | USBIP_CMD_SUBMIT(seqnum = m+2) | - | ----------------------------------------------> | - | | - | USBIP_RET_SUBMIT(seqnum = m) | - | <---------------------------------------------- | - | | - | USBIP_CMD_SUBMIT(seqnum = m+3) | - | ----------------------------------------------> | - | | - | USBIP_RET_SUBMIT(seqnum = m+1) | - | <---------------------------------------------- | - | | - | USBIP_CMD_SUBMIT(seqnum = m+4) | - | ----------------------------------------------> | - | | - | USBIP_RET_SUBMIT(seqnum = m+2) | - | <---------------------------------------------- | - | . | - | : | - | | - | USBIP_CMD_UNLINK | - | ----------------------------------------------> | - | | - | USBIP_RET_UNLINK | - | <---------------------------------------------- | - | | - -The fields are in network (big endian) byte order meaning that the most significant -byte (MSB) is stored at the lowest address. - - -OP_REQ_DEVLIST: Retrieve the list of exported USB devices. - - Offset | Length | Value | Description ------------+--------+------------+--------------------------------------------------- - 0 | 2 | 0x0100 | Binary-coded decimal USBIP version number: v1.0.0 ------------+--------+------------+--------------------------------------------------- - 2 | 2 | 0x8005 | Command code: Retrieve the list of exported USB - | | | devices. ------------+--------+------------+--------------------------------------------------- - 4 | 4 | 0x00000000 | Status: unused, shall be set to 0 - -OP_REP_DEVLIST: Reply with the list of exported USB devices. - - Offset | Length | Value | Description ------------+--------+------------+--------------------------------------------------- - 0 | 2 | 0x0100 | Binary-coded decimal USBIP version number: v1.0.0. ------------+--------+------------+--------------------------------------------------- - 2 | 2 | 0x0005 | Reply code: The list of exported USB devices. ------------+--------+------------+--------------------------------------------------- - 4 | 4 | 0x00000000 | Status: 0 for OK ------------+--------+------------+--------------------------------------------------- - 8 | 4 | n | Number of exported devices: 0 means no exported - | | | devices. ------------+--------+------------+--------------------------------------------------- - 0x0C | | | From now on the exported n devices are described, - | | | if any. If no devices are exported the message - | | | ends with the previous "number of exported - | | | devices" field. ------------+--------+------------+--------------------------------------------------- - | 256 | | path: Path of the device on the host exporting the - | | | USB device, string closed with zero byte, e.g. - | | | "/sys/devices/pci0000:00/0000:00:1d.1/usb3/3-2" - | | | The unused bytes shall be filled with zero - | | | bytes. ------------+--------+------------+--------------------------------------------------- - 0x10C | 32 | | busid: Bus ID of the exported device, string - | | | closed with zero byte, e.g. "3-2". The unused - | | | bytes shall be filled with zero bytes. ------------+--------+------------+--------------------------------------------------- - 0x12C | 4 | | busnum ------------+--------+------------+--------------------------------------------------- - 0x130 | 4 | | devnum ------------+--------+------------+--------------------------------------------------- - 0x134 | 4 | | speed ------------+--------+------------+--------------------------------------------------- - 0x138 | 2 | | idVendor ------------+--------+------------+--------------------------------------------------- - 0x13A | 2 | | idProduct ------------+--------+------------+--------------------------------------------------- - 0x13C | 2 | | bcdDevice ------------+--------+------------+--------------------------------------------------- - 0x13E | 1 | | bDeviceClass ------------+--------+------------+--------------------------------------------------- - 0x13F | 1 | | bDeviceSubClass ------------+--------+------------+--------------------------------------------------- - 0x140 | 1 | | bDeviceProtocol ------------+--------+------------+--------------------------------------------------- - 0x141 | 1 | | bConfigurationValue ------------+--------+------------+--------------------------------------------------- - 0x142 | 1 | | bNumConfigurations ------------+--------+------------+--------------------------------------------------- - 0x143 | 1 | | bNumInterfaces ------------+--------+------------+--------------------------------------------------- - 0x144 | | m_0 | From now on each interface is described, all - | | | together bNumInterfaces times, with the - | | | the following 4 fields: ------------+--------+------------+--------------------------------------------------- - | 1 | | bInterfaceClass ------------+--------+------------+--------------------------------------------------- - 0x145 | 1 | | bInterfaceSubClass ------------+--------+------------+--------------------------------------------------- - 0x146 | 1 | | bInterfaceProtocol ------------+--------+------------+--------------------------------------------------- - 0x147 | 1 | | padding byte for alignment, shall be set to zero ------------+--------+------------+--------------------------------------------------- - 0xC + | | | The second exported USB device starts at i=1 - i*0x138 + | | | with the busid field. - m_(i-1)*4 | | | - -OP_REQ_IMPORT: Request to import (attach) a remote USB device. - - Offset | Length | Value | Description ------------+--------+------------+--------------------------------------------------- - 0 | 2 | 0x0100 | Binary-coded decimal USBIP version number: v1.0.0 ------------+--------+------------+--------------------------------------------------- - 2 | 2 | 0x8003 | Command code: import a remote USB device. ------------+--------+------------+--------------------------------------------------- - 4 | 4 | 0x00000000 | Status: unused, shall be set to 0 ------------+--------+------------+--------------------------------------------------- - 8 | 32 | | busid: the busid of the exported device on the - | | | remote host. The possible values are taken - | | | from the message field OP_REP_DEVLIST.busid. - | | | A string closed with zero, the unused bytes - | | | shall be filled with zeros. ------------+--------+------------+--------------------------------------------------- - -OP_REP_IMPORT: Reply to import (attach) a remote USB device. - - Offset | Length | Value | Description ------------+--------+------------+--------------------------------------------------- - 0 | 2 | 0x0100 | Binary-coded decimal USBIP version number: v1.0.0 ------------+--------+------------+--------------------------------------------------- - 2 | 2 | 0x0003 | Reply code: Reply to import. ------------+--------+------------+--------------------------------------------------- - 4 | 4 | 0x00000000 | Status: 0 for OK - | | | 1 for error ------------+--------+------------+--------------------------------------------------- - 8 | | | From now on comes the details of the imported - | | | device, if the previous status field was OK (0), - | | | otherwise the reply ends with the status field. ------------+--------+------------+--------------------------------------------------- - | 256 | | path: Path of the device on the host exporting the - | | | USB device, string closed with zero byte, e.g. - | | | "/sys/devices/pci0000:00/0000:00:1d.1/usb3/3-2" - | | | The unused bytes shall be filled with zero - | | | bytes. ------------+--------+------------+--------------------------------------------------- - 0x108 | 32 | | busid: Bus ID of the exported device, string - | | | closed with zero byte, e.g. "3-2". The unused - | | | bytes shall be filled with zero bytes. ------------+--------+------------+--------------------------------------------------- - 0x128 | 4 | | busnum ------------+--------+------------+--------------------------------------------------- - 0x12C | 4 | | devnum ------------+--------+------------+--------------------------------------------------- - 0x130 | 4 | | speed ------------+--------+------------+--------------------------------------------------- - 0x134 | 2 | | idVendor ------------+--------+------------+--------------------------------------------------- - 0x136 | 2 | | idProduct ------------+--------+------------+--------------------------------------------------- - 0x138 | 2 | | bcdDevice ------------+--------+------------+--------------------------------------------------- - 0x139 | 1 | | bDeviceClass ------------+--------+------------+--------------------------------------------------- - 0x13A | 1 | | bDeviceSubClass ------------+--------+------------+--------------------------------------------------- - 0x13B | 1 | | bDeviceProtocol ------------+--------+------------+--------------------------------------------------- - 0x13C | 1 | | bConfigurationValue ------------+--------+------------+--------------------------------------------------- - 0x13D | 1 | | bNumConfigurations ------------+--------+------------+--------------------------------------------------- - 0x13E | 1 | | bNumInterfaces - -USBIP_CMD_SUBMIT: Submit an URB - - Offset | Length | Value | Description ------------+--------+------------+--------------------------------------------------- - 0 | 4 | 0x00000001 | command: Submit an URB ------------+--------+------------+--------------------------------------------------- - 4 | 4 | | seqnum: the sequence number of the URB to submit ------------+--------+------------+--------------------------------------------------- - 8 | 4 | | devid ------------+--------+------------+--------------------------------------------------- - 0xC | 4 | | direction: 0: USBIP_DIR_OUT - | | | 1: USBIP_DIR_IN ------------+--------+------------+--------------------------------------------------- - 0x10 | 4 | | ep: endpoint number, possible values are: 0...15 ------------+--------+------------+--------------------------------------------------- - 0x14 | 4 | | transfer_flags: possible values depend on the - | | | URB transfer type, see below ------------+--------+------------+--------------------------------------------------- - 0x18 | 4 | | transfer_buffer_length ------------+--------+------------+--------------------------------------------------- - 0x1C | 4 | | start_frame: specify the selected frame to - | | | transmit an ISO frame, ignored if URB_ISO_ASAP - | | | is specified at transfer_flags ------------+--------+------------+--------------------------------------------------- - 0x20 | 4 | | number_of_packets: number of ISO packets ------------+--------+------------+--------------------------------------------------- - 0x24 | 4 | | interval: maximum time for the request on the - | | | server-side host controller ------------+--------+------------+--------------------------------------------------- - 0x28 | 8 | | setup: data bytes for USB setup, filled with - | | | zeros if not used ------------+--------+------------+--------------------------------------------------- - 0x30 | | | URB data. For ISO transfers the padding between - | | | each ISO packets is not transmitted. - - - Allowed transfer_flags | value | control | interrupt | bulk | isochronous - -------------------------+------------+---------+-----------+----------+------------- - URB_SHORT_NOT_OK | 0x00000001 | only in | only in | only in | no - URB_ISO_ASAP | 0x00000002 | no | no | no | yes - URB_NO_TRANSFER_DMA_MAP | 0x00000004 | yes | yes | yes | yes - URB_NO_FSBR | 0x00000020 | yes | no | no | no - URB_ZERO_PACKET | 0x00000040 | no | no | only out | no - URB_NO_INTERRUPT | 0x00000080 | yes | yes | yes | yes - URB_FREE_BUFFER | 0x00000100 | yes | yes | yes | yes - URB_DIR_MASK | 0x00000200 | yes | yes | yes | yes - - -USBIP_RET_SUBMIT: Reply for submitting an URB - - Offset | Length | Value | Description ------------+--------+------------+--------------------------------------------------- - 0 | 4 | 0x00000003 | command ------------+--------+------------+--------------------------------------------------- - 4 | 4 | | seqnum: URB sequence number ------------+--------+------------+--------------------------------------------------- - 8 | 4 | | devid ------------+--------+------------+--------------------------------------------------- - 0xC | 4 | | direction: 0: USBIP_DIR_OUT - | | | 1: USBIP_DIR_IN ------------+--------+------------+--------------------------------------------------- - 0x10 | 4 | | ep: endpoint number ------------+--------+------------+--------------------------------------------------- - 0x14 | 4 | | status: zero for successful URB transaction, - | | | otherwise some kind of error happened. ------------+--------+------------+--------------------------------------------------- - 0x18 | 4 | n | actual_length: number of URB data bytes ------------+--------+------------+--------------------------------------------------- - 0x1C | 4 | | start_frame: for an ISO frame the actually - | | | selected frame for transmit. ------------+--------+------------+--------------------------------------------------- - 0x20 | 4 | | number_of_packets ------------+--------+------------+--------------------------------------------------- - 0x24 | 4 | | error_count ------------+--------+------------+--------------------------------------------------- - 0x28 | 8 | | setup: data bytes for USB setup, filled with - | | | zeros if not used ------------+--------+------------+--------------------------------------------------- - 0x30 | n | | URB data bytes. For ISO transfers the padding - | | | between each ISO packets is not transmitted. - -USBIP_CMD_UNLINK: Unlink an URB - - Offset | Length | Value | Description ------------+--------+------------+--------------------------------------------------- - 0 | 4 | 0x00000002 | command: URB unlink command ------------+--------+------------+--------------------------------------------------- - 4 | 4 | | seqnum: URB sequence number to unlink: FIXME: is this so? ------------+--------+------------+--------------------------------------------------- - 8 | 4 | | devid ------------+--------+------------+--------------------------------------------------- - 0xC | 4 | | direction: 0: USBIP_DIR_OUT - | | | 1: USBIP_DIR_IN ------------+--------+------------+--------------------------------------------------- - 0x10 | 4 | | ep: endpoint number: zero ------------+--------+------------+--------------------------------------------------- - 0x14 | 4 | | seqnum: the URB sequence number given previously - | | | at USBIP_CMD_SUBMIT.seqnum field ------------+--------+------------+--------------------------------------------------- - 0x30 | n | | URB data bytes. For ISO transfers the padding - | | | between each ISO packets is not transmitted. - -USBIP_RET_UNLINK: Reply for URB unlink - - Offset | Length | Value | Description ------------+--------+------------+--------------------------------------------------- - 0 | 4 | 0x00000004 | command: reply for the URB unlink command ------------+--------+------------+--------------------------------------------------- - 4 | 4 | | seqnum: the unlinked URB sequence number ------------+--------+------------+--------------------------------------------------- - 8 | 4 | | devid ------------+--------+------------+--------------------------------------------------- - 0xC | 4 | | direction: 0: USBIP_DIR_OUT - | | | 1: USBIP_DIR_IN ------------+--------+------------+--------------------------------------------------- - 0x10 | 4 | | ep: endpoint number ------------+--------+------------+--------------------------------------------------- - 0x14 | 4 | | status: This is the value contained in the - | | | urb->status in the URB completition handler. - | | | FIXME: a better explanation needed. ------------+--------+------------+--------------------------------------------------- - 0x30 | n | | URB data bytes. For ISO transfers the padding - | | | between each ISO packets is not transmitted. -- cgit v1.2.3-59-g8ed1b From dfbae3309568f296e5dccfe1ec10db0f6804b756 Mon Sep 17 00:00:00 2001 From: Li Jun Date: Fri, 19 Feb 2016 10:04:47 +0800 Subject: Documentation: usb: chipidea: Update test procedure for HNP polling Update HNP test procedure as HNP polling is supported. Acked-by: Peter Chen Signed-off-by: Li Jun Signed-off-by: Felipe Balbi --- Documentation/usb/chipidea.txt | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'Documentation') diff --git a/Documentation/usb/chipidea.txt b/Documentation/usb/chipidea.txt index 05f735a1b5a5..678741b0f213 100644 --- a/Documentation/usb/chipidea.txt +++ b/Documentation/usb/chipidea.txt @@ -26,16 +26,17 @@ cat /sys/kernel/debug/ci_hdrc.0/registers On B-device: echo 1 > /sys/bus/platform/devices/ci_hdrc.0/inputs/b_bus_req - if HNP polling is not supported, also need: - On A-device: - echo 0 > /sys/bus/platform/devices/ci_hdrc.0/inputs/a_bus_req - B-device should take host role and enumrate A-device. 4) A-device switch back to host. On B-device: echo 0 > /sys/bus/platform/devices/ci_hdrc.0/inputs/b_bus_req + or, by introducing HNP polling, B-Host can know when A-peripheral wish + to be host role, so this role switch also can be trigged in A-peripheral + side by answering the polling from B-Host, this can be done on A-device: + echo 1 > /sys/bus/platform/devices/ci_hdrc.0/inputs/a_bus_req + A-device should switch back to host and enumrate B-device. 5) Remove B-device(unplug micro B plug) and insert again in 10 seconds, -- cgit v1.2.3-59-g8ed1b From 6c0c0951bbf8c2c216675fe277fba4c42aa0a2bf Mon Sep 17 00:00:00 2001 From: Antti Seppälä Date: Sat, 27 Feb 2016 12:31:24 +0200 Subject: usb: dwc2: Add support for Lantiq ARX and XRX SoCs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support for Lantiq ARX and XRX SoC families to the dwc2 driver. Acked-by: John Youn Signed-off-by: Antti Seppälä Signed-off-by: Felipe Balbi --- Documentation/devicetree/bindings/usb/dwc2.txt | 2 ++ drivers/usb/dwc2/platform.c | 34 ++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/usb/dwc2.txt b/Documentation/devicetree/bindings/usb/dwc2.txt index 221368207ca4..20a68bf2b4e7 100644 --- a/Documentation/devicetree/bindings/usb/dwc2.txt +++ b/Documentation/devicetree/bindings/usb/dwc2.txt @@ -8,6 +8,8 @@ Required properties: - rockchip,rk3066-usb: The DWC2 USB controller instance in the rk3066 Soc; - "rockchip,rk3188-usb", "rockchip,rk3066-usb", "snps,dwc2": for rk3188 Soc; - "rockchip,rk3288-usb", "rockchip,rk3066-usb", "snps,dwc2": for rk3288 Soc; + - "lantiq,arx100-usb": The DWC2 USB controller instance in Lantiq ARX SoCs; + - "lantiq,xrx200-usb": The DWC2 USB controller instance in Lantiq XRX SoCs; - snps,dwc2: A generic DWC2 USB controller with default parameters. - reg : Should contain 1 register range (address and length) - interrupts : Should contain 1 interrupt diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index bc3f2a45a2bc..88629bed6614 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -149,6 +149,38 @@ static const struct dwc2_core_params params_rk3066 = { .hibernation = -1, }; +static const struct dwc2_core_params params_ltq = { + .otg_cap = 2, /* non-HNP/non-SRP */ + .otg_ver = -1, + .dma_enable = -1, + .dma_desc_enable = -1, + .dma_desc_fs_enable = -1, + .speed = -1, + .enable_dynamic_fifo = -1, + .en_multiple_tx_fifo = -1, + .host_rx_fifo_size = 288, /* 288 DWORDs */ + .host_nperio_tx_fifo_size = 128, /* 128 DWORDs */ + .host_perio_tx_fifo_size = 96, /* 96 DWORDs */ + .max_transfer_size = 65535, + .max_packet_count = 511, + .host_channels = -1, + .phy_type = -1, + .phy_utmi_width = -1, + .phy_ulpi_ddr = -1, + .phy_ulpi_ext_vbus = -1, + .i2c_enable = -1, + .ulpi_fs_ls = -1, + .host_support_fs_ls_low_power = -1, + .host_ls_low_power_phy_clk = -1, + .ts_dline = -1, + .reload_ctl = -1, + .ahbcfg = GAHBCFG_HBSTLEN_INCR16 << + GAHBCFG_HBSTLEN_SHIFT, + .uframe_sched = -1, + .external_id_pin_ctl = -1, + .hibernation = -1, +}; + /* * Check the dr_mode against the module configuration and hardware * capabilities. @@ -428,6 +460,8 @@ static const struct of_device_id dwc2_of_match_table[] = { { .compatible = "brcm,bcm2835-usb", .data = ¶ms_bcm2835 }, { .compatible = "hisilicon,hi6220-usb", .data = ¶ms_hi6220 }, { .compatible = "rockchip,rk3066-usb", .data = ¶ms_rk3066 }, + { .compatible = "lantiq,arx100-usb", .data = ¶ms_ltq }, + { .compatible = "lantiq,xrx200-usb", .data = ¶ms_ltq }, { .compatible = "snps,dwc2", .data = NULL }, { .compatible = "samsung,s3c6400-hsotg", .data = NULL}, {}, -- cgit v1.2.3-59-g8ed1b From d883f52e1f6d2eca8378e3795f333c1396943873 Mon Sep 17 00:00:00 2001 From: Reilly Grant Date: Sun, 21 Feb 2016 18:38:01 -0300 Subject: usb: devio: Add ioctl to disallow detaching kernel USB drivers. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The new USBDEVFS_DROP_PRIVILEGES ioctl allows a process to voluntarily relinquish the ability to issue other ioctls that may interfere with other processes and drivers that have claimed an interface on the device. This commit also includes a simple utility to be able to test the ioctl, located at Documentation/usb/usbdevfs-drop-permissions.c Example (with qemu-kvm's input device): $ lsusb ... Bus 001 Device 002: ID 0627:0001 Adomax Technology Co., Ltd $ usb-devices ... C: #Ifs= 1 Cfg#= 1 Atr=a0 MxPwr=100mA I: If#= 0 Alt= 0 #EPs= 1 Cls=03(HID ) Sub=00 Prot=02 Driver=usbhid $ sudo ./usbdevfs-drop-permissions /dev/bus/usb/001/002 OK: privileges dropped! Available options: [0] Exit now [1] Reset device. Should fail if device is in use [2] Claim 4 interfaces. Should succeed where not in use [3] Narrow interface permission mask Which option shall I run?: 1 ERROR: USBDEVFS_RESET failed! (1 - Operation not permitted) Which test shall I run next?: 2 ERROR claiming if 0 (1 - Operation not permitted) ERROR claiming if 1 (1 - Operation not permitted) ERROR claiming if 2 (1 - Operation not permitted) ERROR claiming if 3 (1 - Operation not permitted) Which test shall I run next?: 0 After unbinding usbhid: $ usb-devices ... I: If#= 0 Alt= 0 #EPs= 1 Cls=03(HID ) Sub=00 Prot=02 Driver=(none) $ sudo ./usbdevfs-drop-permissions /dev/bus/usb/001/002 ... Which option shall I run?: 2 OK: claimed if 0 ERROR claiming if 1 (1 - Operation not permitted) ERROR claiming if 2 (1 - Operation not permitted) ERROR claiming if 3 (1 - Operation not permitted) Which test shall I run next?: 1 OK: USBDEVFS_RESET succeeded Which test shall I run next?: 0 After unbinding usbhid and restricting the mask: $ sudo ./usbdevfs-drop-permissions /dev/bus/usb/001/002 ... Which option shall I run?: 3 Insert new mask: 0 OK: privileges dropped! Which test shall I run next?: 2 ERROR claiming if 0 (1 - Operation not permitted) ERROR claiming if 1 (1 - Operation not permitted) ERROR claiming if 2 (1 - Operation not permitted) ERROR claiming if 3 (1 - Operation not permitted) Signed-off-by: Reilly Grant Acked-by: Alan Stern Signed-off-by: Emilio López Signed-off-by: Greg Kroah-Hartman --- Documentation/DocBook/usb.tmpl | 12 +++ Documentation/usb/usbdevfs-drop-permissions.c | 120 ++++++++++++++++++++++++++ drivers/usb/core/devio.c | 63 ++++++++++++-- include/uapi/linux/usbdevice_fs.h | 2 + 4 files changed, 192 insertions(+), 5 deletions(-) create mode 100644 Documentation/usb/usbdevfs-drop-permissions.c (limited to 'Documentation') diff --git a/Documentation/DocBook/usb.tmpl b/Documentation/DocBook/usb.tmpl index 4cd5b2cd0f3d..bc776be0f19c 100644 --- a/Documentation/DocBook/usb.tmpl +++ b/Documentation/DocBook/usb.tmpl @@ -732,6 +732,18 @@ usbdev_ioctl (int fd, int ifno, unsigned request, void *param) or SET_INTERFACE. + USBDEVFS_DROP_PRIVILEGES + This is used to relinquish the ability + to do certain operations which are considered to be + privileged on a usbfs file descriptor. + This includes claiming arbitrary interfaces, resetting + a device on which there are currently claimed interfaces + from other users, and issuing USBDEVFS_IOCTL calls. + The ioctl parameter is a 32 bit mask of interfaces + the user is allowed to claim on this file descriptor. + You may issue this ioctl more than one time to narrow + said mask. + diff --git a/Documentation/usb/usbdevfs-drop-permissions.c b/Documentation/usb/usbdevfs-drop-permissions.c new file mode 100644 index 000000000000..6b8da6ef0c9a --- /dev/null +++ b/Documentation/usb/usbdevfs-drop-permissions.c @@ -0,0 +1,120 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* For building without an updated set of headers */ +#ifndef USBDEVFS_DROP_PRIVILEGES +#define USBDEVFS_DROP_PRIVILEGES _IOW('U', 30, __u32) +#define USBDEVFS_CAP_DROP_PRIVILEGES 0x40 +#endif + +void drop_privileges(int fd, uint32_t mask) +{ + int res; + + res = ioctl(fd, USBDEVFS_DROP_PRIVILEGES, &mask); + if (res) + printf("ERROR: USBDEVFS_DROP_PRIVILEGES returned %d\n", res); + else + printf("OK: privileges dropped!\n"); +} + +void reset_device(int fd) +{ + int res; + + res = ioctl(fd, USBDEVFS_RESET); + if (!res) + printf("OK: USBDEVFS_RESET succeeded\n"); + else + printf("ERROR: reset failed! (%d - %s)\n", + -res, strerror(-res)); +} + +void claim_some_intf(int fd) +{ + int i, res; + + for (i = 0; i < 4; i++) { + res = ioctl(fd, USBDEVFS_CLAIMINTERFACE, &i); + if (!res) + printf("OK: claimed if %d\n", i); + else + printf("ERROR claiming if %d (%d - %s)\n", + i, -res, strerror(-res)); + } +} + +int main(int argc, char *argv[]) +{ + uint32_t mask, caps; + int c, fd; + + fd = open(argv[1], O_RDWR); + if (fd < 0) { + printf("Failed to open file\n"); + goto err_fd; + } + + /* + * check if dropping privileges is supported, + * bail on systems where the capability is not present + */ + ioctl(fd, USBDEVFS_GET_CAPABILITIES, &caps); + if (!(caps & USBDEVFS_CAP_DROP_PRIVILEGES)) { + printf("DROP_PRIVILEGES not supported\n"); + goto err; + } + + /* + * Drop privileges but keep the ability to claim all + * free interfaces (i.e., those not used by kernel drivers) + */ + drop_privileges(fd, -1U); + + printf("Available options:\n" + "[0] Exit now\n" + "[1] Reset device. Should fail if device is in use\n" + "[2] Claim 4 interfaces. Should succeed where not in use\n" + "[3] Narrow interface permission mask\n" + "Which option shall I run?: "); + + while (scanf("%d", &c) == 1) { + switch (c) { + case 0: + goto exit; + case 1: + reset_device(fd); + break; + case 2: + claim_some_intf(fd); + break; + case 3: + printf("Insert new mask: "); + scanf("%x", &mask); + drop_privileges(fd, mask); + break; + default: + printf("I don't recognize that\n"); + } + + printf("Which test shall I run next?: "); + } + +exit: + close(fd); + return 0; + +err: + close(fd); +err_fd: + return 1; +} diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 39da1662b76f..52c4461dfccd 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -79,6 +79,8 @@ struct usb_dev_state { unsigned long ifclaimed; u32 secid; u32 disabled_bulk_eps; + bool privileges_dropped; + unsigned long interface_allowed_mask; }; struct usb_memory { @@ -748,6 +750,10 @@ static int claimintf(struct usb_dev_state *ps, unsigned int ifnum) if (test_bit(ifnum, &ps->ifclaimed)) return 0; + if (ps->privileges_dropped && + !test_bit(ifnum, &ps->interface_allowed_mask)) + return -EACCES; + intf = usb_ifnum_to_if(dev, ifnum); if (!intf) err = -ENOENT; @@ -985,7 +991,7 @@ static int usbdev_open(struct inode *inode, struct file *file) int ret; ret = -ENOMEM; - ps = kmalloc(sizeof(struct usb_dev_state), GFP_KERNEL); + ps = kzalloc(sizeof(struct usb_dev_state), GFP_KERNEL); if (!ps) goto out_free_ps; @@ -1013,17 +1019,15 @@ static int usbdev_open(struct inode *inode, struct file *file) ps->dev = dev; ps->file = file; + ps->interface_allowed_mask = 0xFFFFFFFF; /* 32 bits */ spin_lock_init(&ps->lock); INIT_LIST_HEAD(&ps->list); INIT_LIST_HEAD(&ps->async_pending); INIT_LIST_HEAD(&ps->async_completed); INIT_LIST_HEAD(&ps->memory_list); init_waitqueue_head(&ps->wait); - ps->discsignr = 0; ps->disc_pid = get_pid(task_pid(current)); ps->cred = get_current_cred(); - ps->disccontext = NULL; - ps->ifclaimed = 0; security_task_getsecid(current, &ps->secid); smp_wmb(); list_add_tail(&ps->list, &dev->filelist); @@ -1324,6 +1328,28 @@ static int proc_connectinfo(struct usb_dev_state *ps, void __user *arg) static int proc_resetdevice(struct usb_dev_state *ps) { + struct usb_host_config *actconfig = ps->dev->actconfig; + struct usb_interface *interface; + int i, number; + + /* Don't allow a device reset if the process has dropped the + * privilege to do such things and any of the interfaces are + * currently claimed. + */ + if (ps->privileges_dropped && actconfig) { + for (i = 0; i < actconfig->desc.bNumInterfaces; ++i) { + interface = actconfig->interface[i]; + number = interface->cur_altsetting->desc.bInterfaceNumber; + if (usb_interface_claimed(interface) && + !test_bit(number, &ps->ifclaimed)) { + dev_warn(&ps->dev->dev, + "usbfs: interface %d claimed by %s while '%s' resets device\n", + number, interface->dev.driver->name, current->comm); + return -EACCES; + } + } + } + return usb_reset_device(ps->dev); } @@ -2090,6 +2116,9 @@ static int proc_ioctl(struct usb_dev_state *ps, struct usbdevfs_ioctl *ctl) struct usb_interface *intf = NULL; struct usb_driver *driver = NULL; + if (ps->privileges_dropped) + return -EACCES; + /* alloc buffer */ size = _IOC_SIZE(ctl->ioctl_code); if (size > 0) { @@ -2215,7 +2244,8 @@ static int proc_get_capabilities(struct usb_dev_state *ps, void __user *arg) __u32 caps; caps = USBDEVFS_CAP_ZERO_PACKET | USBDEVFS_CAP_NO_PACKET_SIZE_LIM | - USBDEVFS_CAP_REAP_AFTER_DISCONNECT | USBDEVFS_CAP_MMAP; + USBDEVFS_CAP_REAP_AFTER_DISCONNECT | USBDEVFS_CAP_MMAP | + USBDEVFS_CAP_DROP_PRIVILEGES; if (!ps->dev->bus->no_stop_on_short) caps |= USBDEVFS_CAP_BULK_CONTINUATION; if (ps->dev->bus->sg_tablesize) @@ -2242,6 +2272,9 @@ static int proc_disconnect_claim(struct usb_dev_state *ps, void __user *arg) if (intf->dev.driver) { struct usb_driver *driver = to_usb_driver(intf->dev.driver); + if (ps->privileges_dropped) + return -EACCES; + if ((dc.flags & USBDEVFS_DISCONNECT_CLAIM_IF_DRIVER) && strncmp(dc.driver, intf->dev.driver->name, sizeof(dc.driver)) != 0) @@ -2298,6 +2331,23 @@ static int proc_free_streams(struct usb_dev_state *ps, void __user *arg) return r; } +static int proc_drop_privileges(struct usb_dev_state *ps, void __user *arg) +{ + u32 data; + + if (copy_from_user(&data, arg, sizeof(data))) + return -EFAULT; + + /* This is an one way operation. Once privileges are + * dropped, you cannot regain them. You may however reissue + * this ioctl to shrink the allowed interfaces mask. + */ + ps->interface_allowed_mask &= data; + ps->privileges_dropped = true; + + return 0; +} + /* * NOTE: All requests here that have interface numbers as parameters * are assuming that somehow the configuration has been prevented from @@ -2486,6 +2536,9 @@ static long usbdev_do_ioctl(struct file *file, unsigned int cmd, case USBDEVFS_FREE_STREAMS: ret = proc_free_streams(ps, p); break; + case USBDEVFS_DROP_PRIVILEGES: + ret = proc_drop_privileges(ps, p); + break; } done: diff --git a/include/uapi/linux/usbdevice_fs.h b/include/uapi/linux/usbdevice_fs.h index ecbd17650e6c..a8653a6f40df 100644 --- a/include/uapi/linux/usbdevice_fs.h +++ b/include/uapi/linux/usbdevice_fs.h @@ -135,6 +135,7 @@ struct usbdevfs_hub_portinfo { #define USBDEVFS_CAP_BULK_SCATTER_GATHER 0x08 #define USBDEVFS_CAP_REAP_AFTER_DISCONNECT 0x10 #define USBDEVFS_CAP_MMAP 0x20 +#define USBDEVFS_CAP_DROP_PRIVILEGES 0x40 /* USBDEVFS_DISCONNECT_CLAIM flags & struct */ @@ -188,5 +189,6 @@ struct usbdevfs_streams { #define USBDEVFS_DISCONNECT_CLAIM _IOR('U', 27, struct usbdevfs_disconnect_claim) #define USBDEVFS_ALLOC_STREAMS _IOR('U', 28, struct usbdevfs_streams) #define USBDEVFS_FREE_STREAMS _IOR('U', 29, struct usbdevfs_streams) +#define USBDEVFS_DROP_PRIVILEGES _IOW('U', 30, __u32) #endif /* _UAPI_LINUX_USBDEVICE_FS_H */ -- cgit v1.2.3-59-g8ed1b From 69bec725985324e79b1c47ea287815ac4ddb0521 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Fri, 19 Feb 2016 17:26:15 +0800 Subject: USB: core: let USB device know device node Although most of USB devices are hot-plug's, there are still some devices are hard wired on the board, eg, for HSIC and SSIC interface USB devices. If these kinds of USB devices are multiple functions, and they can supply other interfaces like i2c, gpios for other devices, we may need to describe these at device tree. In this commit, it uses "reg" in dts as physical port number to match the phyiscal port number decided by USB core, if they are the same, then the device node is for the device we are creating for USB core. Signed-off-by: Peter Chen Acked-by: Philipp Zabel Acked-by: Alan Stern Acked-by: Rob Herring Acked-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- .../devicetree/bindings/usb/usb-device.txt | 28 +++++++++++++ drivers/usb/core/Makefile | 2 +- drivers/usb/core/of.c | 47 ++++++++++++++++++++++ drivers/usb/core/usb.c | 10 +++++ include/linux/usb/of.h | 7 ++++ 5 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 Documentation/devicetree/bindings/usb/usb-device.txt create mode 100644 drivers/usb/core/of.c (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/usb/usb-device.txt b/Documentation/devicetree/bindings/usb/usb-device.txt new file mode 100644 index 000000000000..1c35e7b665e1 --- /dev/null +++ b/Documentation/devicetree/bindings/usb/usb-device.txt @@ -0,0 +1,28 @@ +Generic USB Device Properties + +Usually, we only use device tree for hard wired USB device. +The reference binding doc is from: +http://www.firmware.org/1275/bindings/usb/usb-1_0.ps + +Required properties: +- compatible: usbVID,PID. The textual representation of VID, PID shall + be in lower case hexadecimal with leading zeroes suppressed. The + other compatible strings from the above standard binding could also + be used, but a device adhering to this binding may leave out all except + for usbVID,PID. +- reg: the port number which this device is connecting to, the range + is 1-31. + +Example: + +&usb1 { + status = "okay"; + + #address-cells = <1>; + #size-cells = <0>; + + hub: genesys@1 { + compatible = "usb5e3,608"; + reg = <1>; + }; +} diff --git a/drivers/usb/core/Makefile b/drivers/usb/core/Makefile index 2f6f93220046..9780877010b4 100644 --- a/drivers/usb/core/Makefile +++ b/drivers/usb/core/Makefile @@ -5,7 +5,7 @@ usbcore-y := usb.o hub.o hcd.o urb.o message.o driver.o usbcore-y += config.o file.o buffer.o sysfs.o endpoint.o usbcore-y += devio.o notify.o generic.o quirks.o devices.o -usbcore-y += port.o +usbcore-y += port.o of.o usbcore-$(CONFIG_PCI) += hcd-pci.o usbcore-$(CONFIG_ACPI) += usb-acpi.o diff --git a/drivers/usb/core/of.c b/drivers/usb/core/of.c new file mode 100644 index 000000000000..2289700c31d6 --- /dev/null +++ b/drivers/usb/core/of.c @@ -0,0 +1,47 @@ +/* + * of.c The helpers for hcd device tree support + * + * Copyright (C) 2016 Freescale Semiconductor, Inc. + * Author: Peter Chen + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 of + * the License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +/** + * usb_of_get_child_node - Find the device node match port number + * @parent: the parent device node + * @portnum: the port number which device is connecting + * + * Find the node from device tree according to its port number. + * + * Return: On success, a pointer to the device node, %NULL on failure. + */ +struct device_node *usb_of_get_child_node(struct device_node *parent, + int portnum) +{ + struct device_node *node; + u32 port; + + for_each_child_of_node(parent, node) { + if (!of_property_read_u32(node, "reg", &port)) { + if (port == portnum) + return node; + } + } + + return NULL; +} +EXPORT_SYMBOL_GPL(usb_of_get_child_node); + diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 524c9822d2bb..ffa5cf13ffe1 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -470,6 +471,7 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent, dev->route = 0; dev->dev.parent = bus->controller; + dev->dev.of_node = bus->controller->of_node; dev_set_name(&dev->dev, "usb%d", bus->busnum); root_hub = 1; } else { @@ -494,6 +496,14 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent, dev->dev.parent = &parent->dev; dev_set_name(&dev->dev, "%d-%s", bus->busnum, dev->devpath); + if (!parent->parent) { + /* device under root hub's port */ + port1 = usb_hcd_find_raw_port_number(usb_hcd, + port1); + } + dev->dev.of_node = usb_of_get_child_node(parent->dev.of_node, + port1); + /* hub driver sets up TT records */ } diff --git a/include/linux/usb/of.h b/include/linux/usb/of.h index 974bce93aa28..de3237fce6b2 100644 --- a/include/linux/usb/of.h +++ b/include/linux/usb/of.h @@ -16,6 +16,8 @@ enum usb_dr_mode of_usb_get_dr_mode_by_phy(struct device_node *phy_np); bool of_usb_host_tpl_support(struct device_node *np); int of_usb_update_otg_caps(struct device_node *np, struct usb_otg_caps *otg_caps); +struct device_node *usb_of_get_child_node(struct device_node *parent, + int portnum); #else static inline enum usb_dr_mode of_usb_get_dr_mode_by_phy(struct device_node *phy_np) @@ -31,6 +33,11 @@ static inline int of_usb_update_otg_caps(struct device_node *np, { return 0; } +static inline struct device_node *usb_of_get_child_node + (struct device_node *parent, int portnum) +{ + return NULL; +} #endif #if IS_ENABLED(CONFIG_OF) && IS_ENABLED(CONFIG_USB_SUPPORT) -- cgit v1.2.3-59-g8ed1b