[GIT PULL] USB changes for v5.4 merge window
Hi Greg, Here's my pull request for the next merge window. The biggest chunk is the addition of Cadence USB3 DRD Driver which, finally, compiles on x86, ARM and ARM64 without any issues. I haven't gotten any failure reports from 0-day either. Relevant changes have been testing on platforms I have access to. Most importantly the generalization of the dwc3 control request decoders didn't cause any visible regressions that I could trigger. Let me know if you want anything to be changed. cheers < New Driver > \ ^__^ \ (oo)\___ (__)\ )\/\ ||w | || || The following changes since commit e21a712a9685488f5ce80495b37b9fdbe96c230d: Linux 5.3-rc3 (2019-08-04 18:40:12 -0700) are available in the Git repository at: git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb.git tags/usb-for-v5.4 for you to fetch changes up to 18a93cd38be3e69ac5b067c570a78a369b79e31d: usb: gadget: net2280: Add workaround for AB chip Errata 11 (2019-08-30 09:27:33 +0300) USB: Changes for v5.4 merge window With only 45 non-merge commits, we have a small merge window from the Gadget perspective. The biggest change here is the addition of the Cadence USB3 DRD Driver. All other changes are small, non-critical fixes or smaller new features like the improvement to BESL handling in dwc3. Signed-off-by: Felipe Balbi Andrey Smirnov (2): usb: dwc3: Use devres to get clocks usb: dwc3: Use clk_bulk_prepare_enable() Andy Shevchenko (2): usb: dwc2: Switch to use device_property_count_u32() usb: dwc3: Switch to use device_property_count_u32() Benjamin Herrenschmidt (12): usb: gadget: aspeed: Don't set port enable change bit on reset usb: gadget: aspeed: Cleanup EP0 state on port reset usb: gadget: aspeed: Fix EP0 stall handling usb: gadget: aspeed: Don't reject requests on suspended devices usb: gadget: aspeed: Check suspend/resume callback existence usb: gadget: aspeed: Rework the reset logic usb: gadget: aspeed: Remove unused "suspended" flag usb: gadget: aspeed: Improve debugging when nuking usb: Add definitions for the USB2.0 hub TT requests usb: gadget: aspeed: Implement dummy hub TT requests usb: gadget: net2280: Move all "ll" registers in one structure usb: gadget: net2280: Add workaround for AB chip Errata 11 Chuhong Yuan (1): usb: gadget: pch_udc: Use dev_get_drvdata Gustavo A. R. Silva (3): USB: gadget: udc: s3c2410_udc: Mark expected switch fall-throughs usb: gadget: atmel_usba_udc: Mark expected switch fall-through usb: udc: lpc32xx: silence fall-through warning John Keeping (1): usb: dwc2: gadget: Fix kill_all_requests race Mao Wenan (1): usb: udc: lpc32xx: remove set but not used 3 variables Marek Szyprowski (1): usb: dwc3: remove generic PHYs forwarding for XHCI device Masahiro Yamada (1): usb: dwc3: omap: squash include/linux/platform_data/dwc3-omap.h Neil Armstrong (1): usb: dwc3: meson-g12a: fix suspend resume regulator unbalanced disables Nishka Dasgupta (3): usb: dwc3: st: Add of_node_put() before return in probe function usb: dwc3: st: Add of_dev_put() in probe function usb: phy: phy-fsl-usb: Make structure fsl_otg_initdata constant Pawel Laszczak (6): dt-bindings: add binding for USBSS-DRD controller. usb: common: Separated decoding functions from dwc3 driver. usb: common: Patch simplify usb_decode_set_clear_feature function. usb: common: Simplify usb_decode_get_set_descriptor function. usb: cdns3: Add Cadence USB3 DRD Driver usb:cdns3 Fix for stuck packets in on-chip OUT buffer. Roger Quadros (2): usb: dwc3: don't set gadget->is_otg flag usb: gadget: udc: core: Fix segfault if udc_bind_to_driver() for pending driver fails Thinh Nguyen (6): usb: dwc3: Update soft-reset wait polling rate usb: gadget: Export recommended BESL values usb: dwc3: Separate field holding multiple properties usb: dwc3: gadget: Set BESL config parameter usb: gadget: composite: Set recommended BESL values usb: dwc3: gadget: Workaround Mirosoft's BESL check YueHaibing (3): usb: dwc3: meson-g12a: use devm_platform_ioremap_resource() to simplify code usb: dwc3: omap: use devm_platform_ioremap_resource() to simplify code usb: dwc3: keystone: use devm_platform_ioremap_resource() to simplify code .../devicetree/bindings/usb/cdns-usb3.txt | 45 + drivers/usb/Kconfig|2 + drivers/usb/Makefile |2 + drivers/usb/cdns3/Kconfig | 46 + drivers/usb/cdns3/Makefile | 16 + drivers/usb/cdns3/cdns3-pci-w
Re: RK3288 dwc2 USB OTG + macOS
On 22/08/2019 17:06, Jack Mitchell wrote: > I'm having issues on a Firefly rk3288 board when trying to use USB > gadget ethernet on macOS. The dr_mode is set to "otg" and it works fine > with my Linux desktop. > > If I set the dr_mode to "peripheral" macOS will work, but still takes > around 10 seconds to enumerate the device which makes me think it's only > just working. However, I need the port to be in "otg" mode as it will > switch between peripheral/host use cases. > > I've attached a log from the dwc2 driver from mainline Linux 5.2 when > being plugged into the macOS device for 30 seconds, then removed. The > mac in this case is a 2013 macbook pro. Any pointers in the right > direction would be greatly appreciated. > > Regards, > Jack. > I've been poking about with this some more and I've managed to bisect the issue down to the following commit 729cac693eecfebdb9e152ead358ae2decb7 usb: dwc2: Change ISOC DDMA flow If I build before this commit everything works fine with a g_ether gadget device on mac. Unfortunately it's a rather large change which I can't just revert in master as it's got multiple dependant commits later. So, any advice on what could be causing this or how to help debug it would be much appreciated, as at the moment I've just forward ported the working 4.16 version of the driver over the 5.3-rc6 broken driver which isn't very sustainable in the long run. Regards, Jack.
[PATCH 3/4] xhci: add TSP bitflag to TRB tracing
Software can set a Transfer State Preserve (TSP) flag to maintain data toggle and sequence number when issuing a reset endpoint command. xhci driver is using TSP for soft retry, we want to show TSP usage in tracing as well Signed-off-by: Mathias Nyman --- drivers/usb/host/xhci.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index f5c41448d067..f9f88626a57a 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -2337,12 +2337,13 @@ static inline const char *xhci_decode_trb(u32 field0, u32 field1, u32 field2, break; case TRB_RESET_EP: sprintf(str, - "%s: ctx %08x%08x slot %d ep %d flags %c", + "%s: ctx %08x%08x slot %d ep %d flags %c:%c", xhci_trb_type_string(type), field1, field0, TRB_TO_SLOT_ID(field3), /* Macro decrements 1, maybe it shouldn't?!? */ TRB_TO_EP_INDEX(field3) + 1, + field3 & TRB_TSP ? 'T' : 't', field3 & TRB_CYCLE ? 'C' : 'c'); break; case TRB_STOP_RING: -- 2.7.4
[PATCH 1/4] usb: xhci: dbc: Simplify error handling in 'xhci_dbc_alloc_requests()'
From: Christophe JAILLET If the 'kmalloc()' fails, we need to undo the previous 'dbc_alloc_request()' call. Because of the more similar function name, it is more logical to use 'dbc_free_request()' instead of 'xhci_dbc_free_req()'. Both are equivalent here because: static void xhci_dbc_free_req(struct dbc_ep *dep, struct dbc_request *req) { kfree(req->buf); dbc_free_request(dep, req); } and 'req->buf' is known to be NULL at this point Signed-off-by: Christophe JAILLET Signed-off-by: Mathias Nyman --- drivers/usb/host/xhci-dbgtty.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/host/xhci-dbgtty.c b/drivers/usb/host/xhci-dbgtty.c index aff79ff5aba4..845939f8a0b8 100644 --- a/drivers/usb/host/xhci-dbgtty.c +++ b/drivers/usb/host/xhci-dbgtty.c @@ -146,7 +146,7 @@ xhci_dbc_alloc_requests(struct dbc_ep *dep, struct list_head *head, req->length = DBC_MAX_PACKET; req->buf = kmalloc(req->length, GFP_KERNEL); if (!req->buf) { - xhci_dbc_free_req(dep, req); + dbc_free_request(dep, req); break; } -- 2.7.4
[PATCH 0/4] xhci features for usb-next
Hi Greg Minor xhci tuneups for usb-next. The memory leak fix might look like it belongs to usb-linus and stable, but is really about a leak possibility on a very unlikely error path. Nice to have it fixed, but not sure it's stable material. -Mathias Christophe JAILLET (2): usb: xhci: dbc: Simplify error handling in 'xhci_dbc_alloc_requests()' usb: xhci: dbc: Use GFP_KERNEL instead of GFP_ATOMIC in 'xhci_dbc_alloc_requests()' Ikjoon Jang (1): xhci: fix possible memleak on setup address fails. Mathias Nyman (1): xhci: add TSP bitflag to TRB tracing drivers/usb/host/xhci-dbgtty.c | 4 ++-- drivers/usb/host/xhci.c| 3 ++- drivers/usb/host/xhci.h| 3 ++- 3 files changed, 6 insertions(+), 4 deletions(-) -- 2.7.4
[PATCH 4/4] xhci: fix possible memleak on setup address fails.
From: Ikjoon Jang Xhci re-enables a slot on transaction error in set_address using xhci_disable_slot() + xhci_alloc_dev(). But in this case, xhci_alloc_dev() creates debugfs entries upon an existing device without cleaning up old entries, thus memory leaks. So this patch simply moves calling xhci_debugfs_free_dev() from xhci_free_dev() to xhci_disable_slot(). [added "possible" to header as this is about failure codepath -Mathias] Signed-off-by: Ikjoon Jang Signed-off-by: Mathias Nyman --- drivers/usb/host/xhci.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index e315c0158e90..500865975687 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -3814,7 +3814,6 @@ static void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev) virt_dev->eps[i].ep_state &= ~EP_STOP_CMD_PENDING; del_timer_sync(&virt_dev->eps[i].stop_cmd_timer); } - xhci_debugfs_remove_slot(xhci, udev->slot_id); virt_dev->udev = NULL; ret = xhci_disable_slot(xhci, udev->slot_id); if (ret) @@ -3832,6 +3831,8 @@ int xhci_disable_slot(struct xhci_hcd *xhci, u32 slot_id) if (!command) return -ENOMEM; + xhci_debugfs_remove_slot(xhci, slot_id); + spin_lock_irqsave(&xhci->lock, flags); /* Don't disable the slot if the host controller is dead. */ state = readl(&xhci->op_regs->status); -- 2.7.4
[PATCH 2/4] usb: xhci: dbc: Use GFP_KERNEL instead of GFP_ATOMIC in 'xhci_dbc_alloc_requests()'
From: Christophe JAILLET There is no need to use GFP_ATOMIC to allocate 'req'. GFP_KERNEL should be enough and is already used for another allocation juste a few lines below. Signed-off-by: Christophe JAILLET Signed-off-by: Mathias Nyman --- drivers/usb/host/xhci-dbgtty.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/host/xhci-dbgtty.c b/drivers/usb/host/xhci-dbgtty.c index 845939f8a0b8..be726c791323 100644 --- a/drivers/usb/host/xhci-dbgtty.c +++ b/drivers/usb/host/xhci-dbgtty.c @@ -139,7 +139,7 @@ xhci_dbc_alloc_requests(struct dbc_ep *dep, struct list_head *head, struct dbc_request *req; for (i = 0; i < DBC_QUEUE_SIZE; i++) { - req = dbc_alloc_request(dep, GFP_ATOMIC); + req = dbc_alloc_request(dep, GFP_KERNEL); if (!req) break; -- 2.7.4
[PATCH 0/3] Add get/set ethernet address functions and ACPI MAC address pass through functionality to cdc_ncm driver
In recent testing of a Dell Universal Dock D6000, I found that MAC address pass through is not supported in the Linux drivers. However, this same device is supported in Windows 10 (Pro) on my personal computer, in as much as I was able to tell Windows to assign a new MAC address of my choosing, and I saw through wireshark the new MAC address was pushed out to the device. Afterward, Windows reported a new IP address and I was able to view web pages. This series of patches give support to cdc_ncm USB based Ethernet controllers for programming a MAC address to the device, and also to retrieve the device's MAC address. This patch series further adds ACPI MAC address pass through support specifically for the cdc_ncm driver, and generally for any other driver that may need or want it, in furtherance of Dell's enterprise IT policy efforts. It was this latter that I initially found lacking when testing a D6000 with a Dell laptop, and then I found ifconfig was unable to set a MAC address into the device. These patches bring a similar level of functionality to cdc_ncm driver as is available with the Realtek r8152 driver, and is available with Windows. The cdc_ncm driver limits the ACPI MAC address pass through support to only the Dell Universal Dock D6000, so no other cdc_ncm device will be impacted. Charles Hyde (3): net: cdc_ncm: add get/set ethernet address functions ACPI: move ACPI functionality out of r8152 driver net: cdc_ncm: Add ACPI MAC address pass through functionality drivers/acpi/Makefile| 1 + drivers/acpi/acpi_mac_passthru.c | 63 ++ drivers/net/usb/cdc_ncm.c| 141 ++- drivers/net/usb/r8152.c | 44 +- include/acpi/acpi_mac_passthru.h | 29 +++ 5 files changed, 234 insertions(+), 44 deletions(-) create mode 100644 drivers/acpi/acpi_mac_passthru.c create mode 100644 include/acpi/acpi_mac_passthru.h -- 2.20.1
[PATCH 1/3] net: cdc_ncm: add get/set ethernet address functions
This patch adds support for pushing a MAC address out to USB based ethernet controllers driven by cdc_ncm. With this change, ifconfig can now set the device's MAC address. For example, the Dell Universal Dock D6000 is driven by cdc_ncm. The D6000 can now have its MAC address set by ifconfig, as it can be done in Windows. This was tested with a D6000 using ifconfig on an x86 based chromebook, where iproute2 is not available. Signed-off-by: Charles Hyde Cc: Mario Limonciello Cc: Oliver Neukum Cc: linux-usb@vger.kernel.org --- drivers/net/usb/cdc_ncm.c | 74 ++- 1 file changed, 73 insertions(+), 1 deletion(-) diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c index 50c05d0f44cb..85093579612f 100644 --- a/drivers/net/usb/cdc_ncm.c +++ b/drivers/net/usb/cdc_ncm.c @@ -750,6 +750,78 @@ int cdc_ncm_change_mtu(struct net_device *net, int new_mtu) } EXPORT_SYMBOL_GPL(cdc_ncm_change_mtu); +/* Provide method to get MAC address from the USB device's ethernet controller. + * If the device supports CDC_GET_ADDRESS, we should receive just six bytes. + * Otherwise, use the prior method by asking for the descriptor. + */ +static int cdc_ncm_get_ethernet_address(struct usbnet *dev, + struct cdc_ncm_ctx *ctx) +{ + int ret; + char *buf; + + buf = kmalloc(ETH_ALEN, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + ret = usbnet_read_cmd(dev, USB_CDC_GET_NET_ADDRESS, + USB_DIR_IN | USB_TYPE_CLASS + | USB_RECIP_INTERFACE, 0, + USB_REQ_SET_ADDRESS, buf, ETH_ALEN); + if (ret == ETH_ALEN) { + memcpy(dev->net->dev_addr, buf, ETH_ALEN); + ret = 0;/* success */ + } else { + ret = usbnet_get_ethernet_addr(dev, + ctx->ether_desc->iMACAddress); + } + kfree(buf); + return ret; +} + +/* Provide method to push MAC address to the USB device's ethernet controller. + * If the device does not support CDC_SET_ADDRESS, there is no harm and we + * proceed as before. + */ +static int cdc_ncm_set_ethernet_address(struct usbnet *dev, + struct sockaddr *addr) +{ + int ret; + char *buf; + + buf = kmalloc(ETH_ALEN, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + memcpy(buf, addr->sa_data, ETH_ALEN); + ret = usbnet_write_cmd(dev, USB_CDC_SET_NET_ADDRESS, + USB_DIR_OUT | USB_TYPE_CLASS + | USB_RECIP_INTERFACE, 0, + USB_REQ_SET_ADDRESS, buf, ETH_ALEN); + if (ret == ETH_ALEN) + ret = 0;/* success */ + else if (ret < 0) + dev_dbg(&dev->udev->dev, "bad MAC address put, %d\n", ret); + + kfree(buf); + return ret; +} + +/* Provide method to push MAC address to the USB device's ethernet controller. + */ +int cdc_ncm_set_mac_addr(struct net_device *net, void *p) +{ + struct usbnet *dev = netdev_priv(net); + + /* Try to push the MAC address out to the device. Ignore any errors, +* to be compatible with prior versions of this source. +*/ + cdc_ncm_set_ethernet_address(dev, (struct sockaddr *)p); + + return eth_mac_addr(net, p); +} +EXPORT_SYMBOL_GPL(cdc_ncm_set_mac_addr); + static const struct net_device_ops cdc_ncm_netdev_ops = { .ndo_open= usbnet_open, .ndo_stop= usbnet_stop, @@ -757,7 +829,7 @@ static const struct net_device_ops cdc_ncm_netdev_ops = { .ndo_tx_timeout = usbnet_tx_timeout, .ndo_get_stats64 = usbnet_get_stats64, .ndo_change_mtu = cdc_ncm_change_mtu, - .ndo_set_mac_address = eth_mac_addr, + .ndo_set_mac_address = cdc_ncm_set_mac_addr, .ndo_validate_addr = eth_validate_addr, }; -- 2.20.1
[PATCH 2/3] ACPI: move ACPI functionality out of r8152 driver
This change moves ACPI functionality out of the Realtek r8152 driver to its own source and header file, making it available to other drivers as needed now and into the future. At the time this ACPI snippet was introduced in 2016, only the Realtek driver made use of it in support of Dell's enterprise IT policy efforts. There comes now a need for this same support in a different driver, also in support of Dell's enterprise IT policy efforts. Signed-off-by: Charles Hyde Cc: Mario Limonciello Cc: Realtek linux nic maintainers Cc: Rafael J. Wysocki Cc: Len Brown Cc: linux-usb@vger.kernel.org Cc: linux-a...@vger.kernel.org --- drivers/acpi/Makefile| 1 + drivers/acpi/acpi_mac_passthru.c | 63 drivers/net/usb/r8152.c | 44 ++ include/acpi/acpi_mac_passthru.h | 29 +++ 4 files changed, 97 insertions(+), 40 deletions(-) create mode 100644 drivers/acpi/acpi_mac_passthru.c create mode 100644 include/acpi/acpi_mac_passthru.h diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index 5d361e4e3405..6bc2748f0e00 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile @@ -66,6 +66,7 @@ acpi-$(CONFIG_ACPI_WATCHDOG) += acpi_watchdog.o acpi-$(CONFIG_ACPI_ADXL) += acpi_adxl.o # These are (potentially) separate modules +acpi-y += acpi_mac_passthru.o # IPMI may be used by other drivers, so it has to initialise before them obj-$(CONFIG_ACPI_IPMI)+= acpi_ipmi.o diff --git a/drivers/acpi/acpi_mac_passthru.c b/drivers/acpi/acpi_mac_passthru.c new file mode 100644 index ..37d7e2388c0b --- /dev/null +++ b/drivers/acpi/acpi_mac_passthru.c @@ -0,0 +1,63 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * acpi_mac_passthru.c - ACPI MAC address pass through driver + * + * Copyright (c) 2019 Dell Technology. All rights reserved. + * + * Search for MAC Address Pass Through information, and return the MAC address + * found. This is set through enterprise policy settings, and expected to be + * read by ethernet drivers that have software programmable MAC addresses. + * Failure to find the needed information results in -ENODEV. + */ + +#include +#include +#include +#include +#include + +ACPI_MODULE_NAME("mapt"); + +MODULE_AUTHOR("Charles Hyde"); +MODULE_DESCRIPTION("ACPI MAPT Driver"); +MODULE_LICENSE("GPL"); + +int get_acpi_mac_passthru(char *macAddress) +{ + acpi_status status; + struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; + union acpi_object *obj; + int ret = -EINVAL; + unsigned char buf[6]; + + /* returns _AUXMAC_#AABBCCDDEEFF# */ + status = acpi_evaluate_object(NULL, "\\_SB.AMAC", NULL, &buffer); + obj = (union acpi_object *)buffer.pointer; + if (!ACPI_SUCCESS(status)) + return -ENODEV; + if (obj->type != ACPI_TYPE_BUFFER || obj->string.length != 0x17) { + acpi_info("Invalid buffer for pass-thru MAC addr: (%d, %d)\n", + obj->type, obj->string.length); + goto amacout; + } + if (strncmp(obj->string.pointer, "_AUXMAC_#", 9) != 0 || + strncmp(obj->string.pointer + 0x15, "#", 1) != 0) { + acpi_info("Invalid header when reading pass-thru MAC addr\n"); + goto amacout; + } + ret = hex2bin(buf, obj->string.pointer + 9, 6); + if (!(ret == 0 && is_valid_ether_addr(buf))) { + acpi_info("Invalid MAC for pass-thru MAC addr: %d, %pM\n", + ret, buf); + ret = -EINVAL; + goto amacout; + } + memcpy(macAddress, buf, 6); + acpi_info("Pass-thru MAC addr %pM\n", macAddress); + +amacout: + kfree(obj); + return ret; + +} +EXPORT_SYMBOL_GPL(get_acpi_mac_passthru); diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index eee0f5007ee3..5336c96006cf 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -23,6 +23,7 @@ #include #include #include +#include /* Information for net-next */ #define NETNEXT_VERSION"09" @@ -1178,12 +1179,7 @@ static int rtl8152_set_mac_address(struct net_device *netdev, void *p) */ static int vendor_mac_passthru_addr_read(struct r8152 *tp, struct sockaddr *sa) { - acpi_status status; - struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; - union acpi_object *obj; - int ret = -EINVAL; u32 ocp_data; - unsigned char buf[6]; /* test for -AD variant of RTL8153 */ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_MISC_0); @@ -1204,39 +1200,7 @@ static int vendor_mac_passthru_addr_read(struct r8152 *tp, struct sockaddr *sa) return -ENODEV; } } - - /* returns _AUXMAC_#AABBCCDDEEFF# */ - status = acpi_evaluate_object(NULL, "\\_SB.AMAC", NULL, &buffer); - obj = (union acpi_object
[PATCH 3/3] net: cdc_ncm: Add ACPI MAC address pass through functionality
This change adds support to cdc_ncm for ACPI MAC address pass through functionality that also exists in the Realtek r8152 driver. This is in support of Dell's Universal Dock D6000, to give it the same feature capability as is currently available in Windows and advertized on Dell's product web site. Signed-off-by: Charles Hyde Cc: Mario Limonciello Cc: Oliver Neukum Cc: Rafael J. Wysocki Cc: Len Brown Cc: linux-usb@vger.kernel.org Cc: linux-a...@vger.kernel.org --- drivers/net/usb/cdc_ncm.c | 67 +-- 1 file changed, 64 insertions(+), 3 deletions(-) diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c index 85093579612f..11a04dc2298d 100644 --- a/drivers/net/usb/cdc_ncm.c +++ b/drivers/net/usb/cdc_ncm.c @@ -52,6 +52,7 @@ #include #include #include +#include #if IS_ENABLED(CONFIG_USB_NET_CDC_MBIM) static bool prefer_mbim = true; @@ -984,11 +985,30 @@ int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_ usb_set_intfdata(ctx->control, dev); if (ctx->ether_desc) { - temp = usbnet_get_ethernet_addr(dev, ctx->ether_desc->iMACAddress); + struct sockaddr sa; + + temp = cdc_ncm_get_ethernet_address(dev, ctx); if (temp) { dev_dbg(&intf->dev, "failed to get mac address\n"); goto error2; } + + /* Check for a Dell Universal Dock D6000 before checking if +* ACPI supports MAC address pass through. +*/ + if (!strstr(dev->udev->product, "D6000")) + goto skip_acpi_mapt_in_bind; + + if (get_acpi_mac_passthru(sa.sa_data) != 0) + goto skip_acpi_mapt_in_bind; + + if (memcmp(dev->net->dev_addr, sa.sa_data, ETH_ALEN) == 0) + goto skip_acpi_mapt_in_bind; + + if (cdc_ncm_set_ethernet_address(dev, &sa) == 0) + memcpy(dev->net->dev_addr, sa.sa_data, ETH_ALEN); + +skip_acpi_mapt_in_bind: dev_info(&intf->dev, "MAC-Address: %pM\n", dev->net->dev_addr); } @@ -1716,6 +1736,47 @@ static void cdc_ncm_status(struct usbnet *dev, struct urb *urb) } } +static int cdc_ncm_resume(struct usb_interface *intf) +{ + struct usbnet *dev = usb_get_intfdata(intf); + struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0]; + int ret; + + ret = usbnet_resume(intf); + if (ret != 0) + goto error2; + + if (ctx->ether_desc) { + struct sockaddr sa; + + if (cdc_ncm_get_ethernet_address(dev, ctx)) { + dev_dbg(&intf->dev, "failed to get mac address\n"); + goto error2; + } + + /* Check for a Dell Universal Dock D6000 before checking if +* ACPI supports MAC address pass through. +*/ + if (!strstr(dev->udev->product, "D6000")) + goto skip_acpi_mapt_in_resume; + + if (get_acpi_mac_passthru(sa.sa_data) != 0) + goto skip_acpi_mapt_in_resume; + + if (memcmp(dev->net->dev_addr, sa.sa_data, ETH_ALEN) == 0) + goto skip_acpi_mapt_in_resume; + + if (cdc_ncm_set_ethernet_address(dev, &sa) == 0) + memcpy(dev->net->dev_addr, sa.sa_data, ETH_ALEN); + +skip_acpi_mapt_in_resume: + dev_info(&intf->dev, "MAC-Address: %pM\n", dev->net->dev_addr); + } + +error2: + return ret; +} + static const struct driver_info cdc_ncm_info = { .description = "CDC NCM", .flags = FLAG_POINTTOPOINT | FLAG_NO_SETINT | FLAG_MULTI_PACKET @@ -1848,8 +1909,8 @@ static struct usb_driver cdc_ncm_driver = { .probe = usbnet_probe, .disconnect = usbnet_disconnect, .suspend = usbnet_suspend, - .resume = usbnet_resume, - .reset_resume = usbnet_resume, + .resume = cdc_ncm_resume, + .reset_resume = cdc_ncm_resume, .supports_autosuspend = 1, .disable_hub_initiated_lpm = 1, }; -- 2.20.1
hi
Good day to you, this is the second times which I am sending this same message to you , I have good news for you but I will like us to know each other a little first of all before I will tell you all about the good news which I have to share with you, With love from. Barbra
[PATCH 1/4] usb: musb: omap2430: Wait on enable to avoid babble
We can babble interrupt if we attempt to switch to USB host mode too soon after enabling musb. Let's fix the issue by waiting a bit in runtime_resume. Cc: Jacopo Mondi Cc: Marcel Partap Cc: Merlijn Wajer Cc: Michael Scott Cc: NeKit Cc: Pavel Machek Cc: Sebastian Reichel Signed-off-by: Tony Lindgren --- drivers/usb/musb/omap2430.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -552,6 +552,9 @@ static int omap2430_runtime_resume(struct device *dev) musb_writel(musb->mregs, OTG_INTERFSEL, musb->context.otg_interfsel); + /* Wait for musb to get oriented. Otherwise we can get babble */ + usleep_range(20, 25); + return 0; } -- 2.23.0
[PATCH 0/4] musb host improvments mostly for omap2430 glue
Hi all, So I ended up cleaning up omap2430 glue layer a bit for host mode with the various reproducable errors I was seeing docking droid4 to a lapdock. There are a few fixes, and then we end up removing all the devctl register tinkering for omap2430 glue layer. Regards, Tony Tony Lindgren (4): usb: musb: omap2430: Wait on enable to avoid babble usb: musb: omap2430: Handle multiple ID ground interrupts usb: musb: Add musb_set_host and peripheral and use them for omap2430 usb: musb: omap2430: Clean up enable and remove devctl tinkering drivers/usb/musb/musb_core.c | 103 ++ drivers/usb/musb/musb_core.h | 3 + drivers/usb/musb/omap2430.c | 118 +-- 3 files changed, 149 insertions(+), 75 deletions(-) -- 2.23.0
[PATCH 2/4] usb: musb: omap2430: Handle multiple ID ground interrupts
We currently get "unhandled DISCONNECT transition" warnings from musb core on device disconnect as things are wrongly set to OTG_STATE_A_IDLE in host mode when enumerating devices. We can also get "Failed to write reg index" errors after enumerating. This is happening at least with cpcap phy where we get multiple ID ground interrupts. Looks like it's VBUS keeps timing out and needs to be kicked when the phy sends multiple ID ground interrupts during host mode. Cc: Jacopo Mondi Cc: Marcel Partap Cc: Merlijn Wajer Cc: Michael Scott Cc: NeKit Cc: Pavel Machek Cc: Sebastian Reichel Signed-off-by: Tony Lindgren --- drivers/usb/musb/omap2430.c | 25 +++-- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -151,13 +151,26 @@ static void omap_musb_set_mailbox(struct omap2430_glue *glue) switch (glue->status) { case MUSB_ID_GROUND: dev_dbg(musb->controller, "ID GND\n"); - - musb->xceiv->otg->state = OTG_STATE_A_IDLE; - musb->xceiv->last_event = USB_EVENT_ID; - if (musb->gadget_driver) { - omap_control_usb_set_mode(glue->control_otghs, - USB_MODE_HOST); + switch (musb->xceiv->otg->state) { + case OTG_STATE_A_WAIT_VRISE: + case OTG_STATE_A_WAIT_BCON: + case OTG_STATE_A_HOST: + case OTG_STATE_A_IDLE: + /* +* On multiple ID ground interrupts just keep enabling +* VBUS. At least cpcap VBUS shuts down otherwise. +*/ omap2430_musb_set_vbus(musb, 1); + break; + default: + musb->xceiv->otg->state = OTG_STATE_A_IDLE; + musb->xceiv->last_event = USB_EVENT_ID; + if (musb->gadget_driver) { + omap_control_usb_set_mode(glue->control_otghs, + USB_MODE_HOST); + omap2430_musb_set_vbus(musb, 1); + } + break; } break; -- 2.23.0
[PATCH 3/4] usb: musb: Add musb_set_host and peripheral and use them for omap2430
At least some revisions of musb core need to set devctl session bit in peripheral mode to force musb to host mode. And we have places clearing the devctl session bit. Let's add a generic function to do this, and use it for omap2430. This should get us a bit closer to completely removing devctl register tinkering in the SoC glue code. Before making use of this code for the other glue layers, things need to be tested carefully as there may be a approximately a 200 ms delay needed between powering up musb and calling musb_set_host() to avoid. Otherwise the system hangs at least with omap2430 glue layer. Signed-off-by: Tony Lindgren --- drivers/usb/musb/musb_core.c | 103 +++ drivers/usb/musb/musb_core.h | 3 + drivers/usb/musb/omap2430.c | 70 +++- 3 files changed, 127 insertions(+), 49 deletions(-) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -73,6 +73,7 @@ #include #include #include +#include #include #include #include @@ -414,6 +415,108 @@ void musb_write_fifo(struct musb_hw_ep *hw_ep, u16 len, const u8 *src) return hw_ep->musb->io.write_fifo(hw_ep, len, src); } +static u8 musb_read_devctl(struct musb *musb) +{ + return musb_readb(musb->mregs, MUSB_DEVCTL); +} + +/** + * musb_set_host - set and initialize host mode + * @musb: musb controller driver data + * + * At least some musb revisions need to enable devctl session bit in + * peripheral mode to switch to host mode. Initializes things to host + * mode and sets A_IDLE. SoC glue needs to advance state further + * based on phy provided VBUS state. + * + * Note that the SoC glue code may need to wait for musb to settle + * on enable before calling this to avoid babble. + */ +int musb_set_host(struct musb *musb) +{ + int error = 0; + u8 devctl; + + if (!musb) + return -EINVAL; + + devctl = musb_read_devctl(musb); + if (!(devctl & MUSB_DEVCTL_BDEVICE)) { + dev_info(musb->controller, +"%s: already in host mode: %02x\n", +__func__, devctl); + goto init_data; + } + + devctl |= MUSB_DEVCTL_SESSION; + musb_writeb(musb->mregs, MUSB_DEVCTL, devctl); + + error = readx_poll_timeout(musb_read_devctl, musb, devctl, + !(devctl & MUSB_DEVCTL_BDEVICE), 5000, + 100); + if (error) { + dev_err(musb->controller, "%s: could not set host: %02x\n", + __func__, devctl); + + return error; + } + +init_data: + musb->is_active = 1; + musb->xceiv->otg->state = OTG_STATE_A_IDLE; + MUSB_HST_MODE(musb); + + return error; +} +EXPORT_SYMBOL_GPL(musb_set_host); + +/** + * musb_set_peripheral - set and initialize peripheral mode + * @musb: musb controller driver data + * + * Clears devctl session bit and initializes things for peripheral + * mode and sets B_IDLE. SoC glue needs to advance state further + * based on phy provided VBUS state. + */ +int musb_set_peripheral(struct musb *musb) +{ + int error = 0; + u8 devctl; + + if (!musb) + return -EINVAL; + + devctl = musb_read_devctl(musb); + if (devctl & MUSB_DEVCTL_BDEVICE) { + dev_info(musb->controller, +"%s: already in peripheral mode: %02x\n", +__func__, devctl); + + goto init_data; + } + + devctl &= ~MUSB_DEVCTL_SESSION; + musb_writeb(musb->mregs, MUSB_DEVCTL, devctl); + + error = readx_poll_timeout(musb_read_devctl, musb, devctl, + devctl & MUSB_DEVCTL_BDEVICE, 5000, + 100); + if (error) { + dev_err(musb->controller, "%s: could not set periperal: %02x\n", + __func__, devctl); + + return error; + } + +init_data: + musb->is_active = 0; + musb->xceiv->otg->state = OTG_STATE_B_IDLE; + MUSB_DEV_MODE(musb); + + return error; +} +EXPORT_SYMBOL_GPL(musb_set_peripheral); + /*-*/ /* for high speed test mode; see USB 2.0 spec 7.1.20 */ diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h @@ -487,6 +487,9 @@ extern void musb_start(struct musb *musb); extern void musb_write_fifo(struct musb_hw_ep *ep, u16 len, const u8 *src); extern void musb_read_fifo(struct musb_hw_ep *ep, u16 len, u8 *dst); +extern int musb_set_host(struct musb *musb); +extern int musb_set_peripheral(struct musb *musb); + extern void musb_load_testpacket(struct musb *); extern irqreturn_t musb_interrupt(struct musb *); diff --git a
[PATCH 4/4] usb: musb: omap2430: Clean up enable and remove devctl tinkering
There should be no need to tinker with devctl in enable in the SoC glue code. We have musb_start() to take care of handling it already. Signed-off-by: Tony Lindgren --- drivers/usb/musb/omap2430.c | 20 1 file changed, 20 deletions(-) diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -275,33 +275,13 @@ static int omap2430_musb_init(struct musb *musb) static void omap2430_musb_enable(struct musb *musb) { - u8 devctl; - unsigned long timeout = jiffies + msecs_to_jiffies(1000); struct device *dev = musb->controller; struct omap2430_glue *glue = dev_get_drvdata(dev->parent); - struct musb_hdrc_platform_data *pdata = dev_get_platdata(dev); - struct omap_musb_board_data *data = pdata->board_data; - switch (glue->status) { case MUSB_ID_GROUND: omap_control_usb_set_mode(glue->control_otghs, USB_MODE_HOST); - if (data->interface_type != MUSB_INTERFACE_UTMI) - break; - devctl = musb_readb(musb->mregs, MUSB_DEVCTL); - /* start the session */ - devctl |= MUSB_DEVCTL_SESSION; - musb_writeb(musb->mregs, MUSB_DEVCTL, devctl); - while (musb_readb(musb->mregs, MUSB_DEVCTL) & - MUSB_DEVCTL_BDEVICE) { - cpu_relax(); - - if (time_after(jiffies, timeout)) { - dev_err(dev, "configured as A device timeout"); - break; - } - } break; case MUSB_VBUS_VALID: -- 2.23.0