[PATCH 1/1] ax88179_178a: Remove AX_MEDIUM_ALWAYS_ONE bit in AX_MEDIUM_STATUS_MODE register to avoid TX throttling
From: Freddy Xin Remove AX_MEDIUM_ALWAYS_ONE in AX_MEDIUM_STATUS_MODE register. Setting this bit may cause TX throttling in Half-Duplex mode. Signed-off-by: Freddy Xin --- drivers/net/usb/ax88179_178a.c | 11 +-- 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c index 846cc19..8e8d0fc 100644 --- a/drivers/net/usb/ax88179_178a.c +++ b/drivers/net/usb/ax88179_178a.c @@ -78,7 +78,6 @@ #define AX_MEDIUM_STATUS_MODE 0x22 #define AX_MEDIUM_GIGAMODE 0x01 #define AX_MEDIUM_FULL_DUPLEX 0x02 - #define AX_MEDIUM_ALWAYS_ONE0x04 #define AX_MEDIUM_EN_125MHZ 0x08 #define AX_MEDIUM_RXFLOW_CTRLEN 0x10 #define AX_MEDIUM_TXFLOW_CTRLEN 0x20 @@ -1065,8 +1064,8 @@ static int ax88179_bind(struct usbnet *dev, struct usb_interface *intf) /* Configure default medium type => giga */ *tmp16 = AX_MEDIUM_RECEIVE_EN | AX_MEDIUM_TXFLOW_CTRLEN | -AX_MEDIUM_RXFLOW_CTRLEN | AX_MEDIUM_ALWAYS_ONE | -AX_MEDIUM_FULL_DUPLEX | AX_MEDIUM_GIGAMODE; +AX_MEDIUM_RXFLOW_CTRLEN | AX_MEDIUM_FULL_DUPLEX | +AX_MEDIUM_GIGAMODE; ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE, 2, 2, tmp16); @@ -1225,7 +1224,7 @@ static int ax88179_link_reset(struct usbnet *dev) } mode = AX_MEDIUM_RECEIVE_EN | AX_MEDIUM_TXFLOW_CTRLEN | - AX_MEDIUM_RXFLOW_CTRLEN | AX_MEDIUM_ALWAYS_ONE; + AX_MEDIUM_RXFLOW_CTRLEN; ax88179_read_cmd(dev, AX_ACCESS_MAC, PHYSICAL_LINK_STATUS, 1, 1, &link_sts); @@ -1339,8 +1338,8 @@ static int ax88179_reset(struct usbnet *dev) /* Configure default medium type => giga */ *tmp16 = AX_MEDIUM_RECEIVE_EN | AX_MEDIUM_TXFLOW_CTRLEN | -AX_MEDIUM_RXFLOW_CTRLEN | AX_MEDIUM_ALWAYS_ONE | -AX_MEDIUM_FULL_DUPLEX | AX_MEDIUM_GIGAMODE; +AX_MEDIUM_RXFLOW_CTRLEN | AX_MEDIUM_FULL_DUPLEX | +AX_MEDIUM_GIGAMODE; ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE, 2, 2, tmp16); -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC PATCH 02/15] usbcore: introduce usb_domain for tracking port-connector relationships
Platform firmware identifies ports that share a connector. This information is relevant for port power control since we do not want a device to reconnect on its peer port in a connector when pm has decided to power-off its currently connected port. In the case of xhci, peer ports are attached through separate root hubs (and zero or more integrated hubs). 'struct usb_domain' is introduced so that each root hub 'hcd' can register its ports to a unified 'platform' domain where connector relationships can be evaluated. A connector is formed when two ports are registered with identical 'match data'. ACPI defines connectors by specifying a common 'group token' and 'group position' property for the port [1]. Outside of this match data there is nothing firmware specific about this implementation, hence the creation of the common rountines in usb-platform.c. [1] ACPI 5.0 Section 6.1.8 _PLD (Physical Device Location) Signed-off-by: Dan Williams --- drivers/usb/core/Kconfig|4 + drivers/usb/core/Makefile |1 drivers/usb/core/hcd-pci.c | 17 +++- drivers/usb/core/hcd.c |2 drivers/usb/core/hub.h |8 ++ drivers/usb/core/usb-acpi.c | 69 +++-- drivers/usb/core/usb-platform.c | 162 +++ drivers/usb/core/usb-platform.h | 44 +++ drivers/usb/host/xhci-pci.c | 16 +++- include/linux/usb/hcd.h |9 ++ 10 files changed, 320 insertions(+), 12 deletions(-) create mode 100644 drivers/usb/core/usb-platform.c create mode 100644 drivers/usb/core/usb-platform.h diff --git a/drivers/usb/core/Kconfig b/drivers/usb/core/Kconfig index db535b0aa172..e439a14b0210 100644 --- a/drivers/usb/core/Kconfig +++ b/drivers/usb/core/Kconfig @@ -89,3 +89,7 @@ config USB_OTG_BLACKLIST_HUB and software costs by not supporting external hubs. So are "Embedded Hosts" that don't offer OTG support. +config USB_PLATFORM + bool + default y if ACPI + diff --git a/drivers/usb/core/Makefile b/drivers/usb/core/Makefile index 5e847ad2f58a..b534b9b28c69 100644 --- a/drivers/usb/core/Makefile +++ b/drivers/usb/core/Makefile @@ -11,5 +11,6 @@ usbcore-y += port.o usbcore-$(CONFIG_PCI) += hcd-pci.o usbcore-$(CONFIG_ACPI) += usb-acpi.o +usbcore-$(CONFIG_USB_PLATFORM) += usb-platform.o obj-$(CONFIG_USB) += usbcore.o diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c index dfe9d0f22978..542dc0f6ef74 100644 --- a/drivers/usb/core/hcd-pci.c +++ b/drivers/usb/core/hcd-pci.c @@ -161,20 +161,23 @@ static void ehci_wait_for_companions(struct pci_dev *pdev, struct usb_hcd *hcd, /* always called with process context; sleeping is OK */ /** - * usb_hcd_pci_probe - initialize PCI-based HCDs + * usb_hcd_pci_probe_domain - initialize PCI-based HCDs * @dev: USB Host Controller being probed * @id: pci hotplug id connecting controller to HCD framework + * @domain: if this hcd coordinates port activity with another hcd from pdev * Context: !in_interrupt() * * Allocates basic PCI resources for this USB host controller, and * then invokes the start() method for the HCD associated with it * through the hotplug entry's driver_data. * - * Store this function in the HCD's struct pci_driver as probe(). + * Note the usb_domain is not to be confused with companion controllers which + * multiplex the same phy with multiple controllers. * * Return: 0 if successful. */ -int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) +int usb_hcd_pci_probe_domain(struct pci_dev *dev, struct usb_domain *udom, +const struct pci_device_id *id) { struct hc_driver*driver; struct usb_hcd *hcd; @@ -215,6 +218,7 @@ int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) goto disable_pci; } + hcd->domain = usb_get_domain(udom); hcd->amd_resume_bug = (usb_hcd_amd_remote_wakeup_quirk(dev) && driver->flags & (HCD_USB11 | HCD_USB3)) ? 1 : 0; @@ -301,6 +305,13 @@ disable_pci: dev_err(&dev->dev, "init %s fail, %d\n", pci_name(dev), retval); return retval; } +EXPORT_SYMBOL_GPL(usb_hcd_pci_probe_domain); + + +int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) +{ + return usb_hcd_pci_probe_domain(dev, NULL, id); +} EXPORT_SYMBOL_GPL(usb_hcd_pci_probe); diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 6bffb8c87bc9..892574f439a4 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -2505,6 +2505,8 @@ static void hcd_release (struct kref *kref) kfree(hcd->bandwidth_mutex); else hcd->shared_hcd->shared_hcd = NULL; + + usb_put_domain(hcd->domain); kfree(hcd); } diff --git a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h index 4e4790dea343..9ea075d1b7a3 100644 ---
[RFC PATCH 00/15] rework port power control
Summary: Address the following issues for port power control: 1/ Port power policy needs 'connector' awareness. 2/ Reliable port power control requires coordination with khubd. 3/ Userspace needs full control, but also help coordinating port power policy. Even with these changes port power control still defaults to disabled (ports are always on). This is 3.14 material. Details: 1/ Port power policy needs 'connector' awareness. It is a recipe for unintended device disconnects to turn off a port while leaving its peer active. The attached device, provided it is not a hub may, switch from the USB3 connection to USB2. Introduce a 'connector' object to track ports from different hcds (for example the two hcds provided by XHCI). A 'connector' is distinct from 'companion' ports which share the same data lines across multiple hcds. Port-connector membership data comes from platorm firmware. 2/ Reliable port power control requires coordination with khubd. The existing implementation makes attempts to mitigate the damage of khubd running in the middle of a port power control event, but makes no guarantees. We need to support both suspending hubs with live ports (to receive wakeup events) and fully powering down the port when userspace policy allows. 3/ Userspace needs full control, but also help coordinating port power policy. Augment the existing controls portX/power/pm_qos_no_power_off and portX/power/control with connector awareness (i.e. propagate control settings across ports in a connector), but also add policies based on the connector type ('hotplug' ports never power down as compared to 'hardwired'). Even with these changes port power control still defaults to on. When enabled (pm_qos_no_power_off=0) it tries to do the right thing for connectors and hotplug capable ports. At all times userspace can override what acpi has defined (pm_qos_no_notify_flags to stop propagating settings to 'peers', connect_type to override whether the port is hotplug capable, or usbcore.noacpi to turn it all off). --- Dan Williams (15): usb: xhci: fix memleak on module removal usbcore: introduce usb_domain for tracking port-connector relationships usbcore: add sysfs linkage for connector peers PM / Runtime: Allow drivers to intercept pm qos flag changes usbcore: port power policy / prep for usb_port as usb_device parent usbcore: make usb_port a proper parent of a usb_device usbcore: pm_runtime honor children usbcore: kill ->is_power_on and ->did_runtime_put usbcore: convert khubd to a workqueue and flush khubd on port power off usbcore: cleanup hub_port_connect_change and hub_power_on usbcore: power down peer port on endpoint connect usbcore: allow the connect_type of ports to be changed usbcore: show port power policy usbcore: add usbcore.noacpi checkpatch: allow list_for_each helper macros Documentation/ABI/testing/sysfs-devices-power | 21 + Documentation/kernel-parameters.txt |4 Documentation/power/pm_qos_interface.txt | 15 - drivers/base/power/qos.c | 48 +++ drivers/base/power/sysfs.c| 45 ++- drivers/usb/core/Kconfig |4 drivers/usb/core/Makefile |1 drivers/usb/core/hcd-pci.c| 17 + drivers/usb/core/hcd.c|2 drivers/usb/core/hub.c| 252 --- drivers/usb/core/hub.h| 29 +- drivers/usb/core/port.c | 171 +++--- drivers/usb/core/usb-acpi.c | 76 drivers/usb/core/usb-platform.c | 425 + drivers/usb/core/usb-platform.h | 56 +++ drivers/usb/core/usb.c| 14 + drivers/usb/host/xhci-pci.c | 16 + drivers/usb/host/xhci.c |6 include/linux/pm.h|5 include/linux/pm_qos.h|5 include/linux/usb/hcd.h |9 + scripts/checkpatch.pl |1 22 files changed, 931 insertions(+), 291 deletions(-) create mode 100644 drivers/usb/core/usb-platform.c create mode 100644 drivers/usb/core/usb-platform.h -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC PATCH 03/15] usbcore: add sysfs linkage for connector peers
Use the "connector" association information provided by platform firmware to create links between peer ports in a connector. Signed-off-by: Dan Williams --- drivers/usb/core/usb-platform.c | 51 +-- 1 files changed, 49 insertions(+), 2 deletions(-) diff --git a/drivers/usb/core/usb-platform.c b/drivers/usb/core/usb-platform.c index 476ac3fa47c2..6b39d1fde8e4 100644 --- a/drivers/usb/core/usb-platform.c +++ b/drivers/usb/core/usb-platform.c @@ -11,6 +11,10 @@ #include #include "usb-platform.h" +#define for_each_connector_peer(peer, port, c) \ + list_for_each_entry(peer, &(c)->ports, node) \ + if (port != peer) + static void domain_release(struct kref *kref) { struct usb_domain *udom = container_of(kref, struct usb_domain, kref); @@ -85,15 +89,58 @@ static void check_connector(struct usb_connector *uconn, static void add_port_connector(struct usb_port *port_dev, struct usb_connector *uconn) { + struct device *dev = &port_dev->dev; + struct usb_port *peer; + char name[40], name2[40]; + list_add(&port_dev->node, &uconn->ports); port_dev->connector = uconn; check_connector(uconn, port_dev); + + for_each_connector_peer(peer, port_dev, uconn) { + struct device *tgt = &peer->dev; + int rc; + + rc = snprintf(name, sizeof(name), "peer:%s-%s", + dev_name(dev->parent), dev_name(dev)); + if (rc >= sizeof(name) + || sysfs_create_link(&tgt->kobj, &dev->kobj, name) != 0) + continue; + + rc = snprintf(name2, sizeof(name), "peer:%s-%s", + dev_name(tgt->parent), dev_name(tgt)); + if (rc >= sizeof(name2) + || sysfs_create_link(&dev->kobj, &tgt->kobj, name2) != 0) + sysfs_remove_link(&tgt->kobj, name); + } } -static void remove_port_connector(struct usb_port *port_dev) +static void remove_port_connector(struct usb_port *port_dev, + struct usb_connector *uconn) { + struct device *dev = &port_dev->dev; + struct usb_port *peer; + char name[40]; + list_del_init(&port_dev->node); port_dev->connector = NULL; + + for_each_connector_peer(peer, port_dev, uconn) { + struct device *tgt = &peer->dev; + int rc; + + rc = snprintf(name, sizeof(name), "peer:%s-%s", + dev_name(dev->parent), dev_name(dev)); + if (rc >= sizeof(name)) + continue; + sysfs_remove_link(&tgt->kobj, name); + + rc = snprintf(name, sizeof(name), "peer:%s-%s", + dev_name(tgt->parent), dev_name(tgt)); + if (rc >= sizeof(name)) + continue; + sysfs_remove_link(&dev->kobj, name); + } } int usb_domain_pair_port(struct usb_domain *udom, struct usb_port *port_dev, @@ -144,7 +191,7 @@ void usb_domain_remove_port(struct usb_domain *udom, struct usb_port *port_dev) list_for_each_entry(p, &uconn->ports, node) if (p == port_dev) { - remove_port_connector(port_dev); + remove_port_connector(port_dev, uconn); break; } -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC PATCH 01/15] usb: xhci: fix memleak on module removal
We currently leak the ->shared_hcd because ->stop() clears the pointer thus preventing xhci_pci_remove() from doing its cleanup of the USB3 hcd. Regarding the cases mentioned in the comment the code is prepared to either abort initialization and continue the startup, or relies on ->shared_hcd being set to trigger usb_remove_hcd() to be called. Signed-off-by: Dan Williams --- drivers/usb/host/xhci.c |6 -- 1 files changed, 0 insertions(+), 6 deletions(-) diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 4265b48856f6..0ea11724c5d1 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -646,12 +646,6 @@ static void xhci_only_stop_hcd(struct usb_hcd *hcd) spin_lock_irq(&xhci->lock); xhci_halt(xhci); - - /* The shared_hcd is going to be deallocated shortly (the USB core only -* calls this function when allocation fails in usb_add_hcd(), or -* usb_remove_hcd() is called). So we need to unset xHCI's pointer. -*/ - xhci->shared_hcd = NULL; spin_unlock_irq(&xhci->lock); } -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC PATCH 04/15] PM / Runtime: Allow drivers to intercept pm qos flag changes
...because struct dev_pm_ops is too clean and uniform. USB port power management needs to manage ports that are colocated in a given connector. If we power down a connector we need to arrange for the peer port in the connector to also be suspended. If the peer connector stays active it may cause the device to disconnect on the initial (suspended) port and reconnect on the other. Notification of when userspace disables pm_qos_no_power_off allows the driver to arrange for the peer port to be suspended before the primary port suspends. Alternatives considered: 1/ force power down the peer port: denies userspace control over power policy 2/ try to synchronize port power management within the USB core: proved difficult to find a non-racy way to synchronize peer connections against power management changes. 3/ create infrastructure to expose the concept of peer devices in the pm_runtime system... maybe defer until other use cases outside of USB pop up. For now, punting the notification to the driver is sufficient. As stated this notification allows the kernel to keep power-policy consistent across a connector. If userspace wants to regain per-port control (at the risk of unexpected disconnects) it can set the pm_qos_no_notify flag to prevent ports from coordinating as a connector. pm_qos_no_notify blocks flags synchronization, restoring the traditional behavior of one pm_qos_no_power_off manipulation only affecting one device. Cc: Rafael J. Wysocki Cc: Greg Kroah-Hartman Cc: Alan Stern Cc: Sarah Sharp Signed-off-by: Dan Williams --- Documentation/ABI/testing/sysfs-devices-power | 21 +++ Documentation/power/pm_qos_interface.txt | 15 drivers/base/power/qos.c | 48 ++--- drivers/base/power/sysfs.c| 45 --- drivers/usb/core/port.c |7 drivers/usb/core/usb-platform.c | 38 drivers/usb/core/usb-platform.h |1 + include/linux/pm.h|5 +++ include/linux/pm_qos.h|5 +++ 9 files changed, 159 insertions(+), 26 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-devices-power b/Documentation/ABI/testing/sysfs-devices-power index efe449bdf811..36d1603ab3bb 100644 --- a/Documentation/ABI/testing/sysfs-devices-power +++ b/Documentation/ABI/testing/sysfs-devices-power @@ -235,3 +235,24 @@ Description: This attribute has no effect on system-wide suspend/resume and hibernation. + +What: /sys/devices/.../power/pm_qos_no_notify_flags +Date: October 2013 +Contact: Dan Williams +Description: + The /sys/devices/.../power/pm_qos_no_notify_flags attribute is + used for determining whether the kernel is permitted to forward + changes to the the PM QoS flags (no_power_off, remote_wakeup) to + other devices it deems to be related in the system. When this + flag is set userspace is indicating that it wants exclusive + control of the flags and takes responsibility for situations + where a driver would want the power control setting unified + amongst a set of devices. In the case of USB a relationship is + indicating by a "peer:-port" link in the + /port directory. + + Not all drivers support this attribute. If it isn't supported, + it is not present. + + This attribute has no effect on system-wide suspend/resume and + hibernation. diff --git a/Documentation/power/pm_qos_interface.txt b/Documentation/power/pm_qos_interface.txt index 483632087788..a63ad55dbf6f 100644 --- a/Documentation/power/pm_qos_interface.txt +++ b/Documentation/power/pm_qos_interface.txt @@ -94,8 +94,8 @@ flags. Values are updated in response to changes of the request list. Target latency value is simply the minimum of the request values held in the parameter list elements. The PM QoS flags aggregate value is a gather (bitwise -OR) of all list elements' values. Two device PM QoS flags are defined currently: -PM_QOS_FLAG_NO_POWER_OFF and PM_QOS_FLAG_REMOTE_WAKEUP. +OR) of all list elements' values. Three device PM QoS flags are defined currently: +PM_QOS_FLAG_NO_POWER_OFF, PM_QOS_FLAG_REMOTE_WAKEUP, PM_QOS_FLAG_NO_NOTIFY. Note: the aggregated target value is implemented as an atomic variable so that reading the aggregated value does not require any locking mechanism. @@ -148,13 +148,14 @@ from the device's power directory. int dev_pm_qos_expose_flags(device, value) Add a request to the device's PM QoS list of flags and create sysfs attributes -pm_qos_no_power_off and pm_qos_remote_wakeup under the device's power directory -allowing user space to change these flags' value. +pm_qos_no_power_off, pm_qos_remote_wak
[RFC PATCH 05/15] usbcore: port power policy / prep for usb_port as usb_device parent
To simplify and harden port power management the port needs to be a proper parent of a connected child, and the hub needs to check whether a port has power before performing actions on it. However, we also want the capability to suspend hubs and connected devices while port power is enabled. So, before moving a port_dev into the hdev->udev hierarchy implement the following port power policies: power policy 'on': port is forced on, port suspend is a nop allowing the hub to suspend power policy 'off': manage port power on idle, hub suspend will be blocked until all power policy off ports are suspended. Otherwise changing the device model hierarchy will result in a regression of not suspending hubs while port power is enabled. Summary of the policy change (when combined with a device model change): Events: | Proposed pm lifetime: | Current: | Power: State: Count: | Power: State: Count: pm_qos_no_power_off=1 | on suspend 0 | on active 0 device connect| on active child | on active 1 (explicit get) pm_qos_no_power_off=0 | on active child | on active 1 device sleep | offsuspend 0 | offsuspend 0 (explicit put) device wake | on active child | on active 1 (explicit get) device disconnect | offsuspend 0 | offsuspend 0 (explicit put) Proposed hotplug policy (enable/disable hotplug in another patch) pm_qos_no_power_off=1 | on suspend 0 enable hotplug| on suspend 0 device connect| on active child pm_qos_no_power_off=0 | on active child device sleep | on suspend 0 device wake | on active child device disconnect | on suspend 0 disable hotplug | offsuspend 0 Signed-off-by: Dan Williams --- drivers/usb/core/port.c | 73 --- 1 files changed, 43 insertions(+), 30 deletions(-) diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c index 237b91bb2079..259ed86f56d2 100644 --- a/drivers/usb/core/port.c +++ b/drivers/usb/core/port.c @@ -71,7 +71,20 @@ static void usb_port_device_release(struct device *dev) } #ifdef CONFIG_PM_RUNTIME -static int usb_port_runtime_resume(struct device *dev) + +static bool is_power_policy_on(struct usb_port *port_dev) +{ + int flag = PM_QOS_FLAG_NO_POWER_OFF; + + if (port_dev->connect_type <= USB_PORT_CONNECT_TYPE_HOT_PLUG) + return true; + if (dev_pm_qos_flags(&port_dev->dev, flag) == PM_QOS_FLAGS_ALL) + return true; + + return false; +} + +static int usb_port_runtime_poweron(struct device *dev) { struct usb_port *port_dev = to_usb_port(dev); struct usb_device *hdev = to_usb_device(dev->parent->parent); @@ -83,6 +96,14 @@ static int usb_port_runtime_resume(struct device *dev) if (!hub) return -EINVAL; + /* if the policy is 'on' then we did not disable port power on +* the suspend path. when turning the policy to 'off' we are +* guaranteed to be resumed under the 'on' policy before being +* requested to resume a powered down port +*/ + if (is_power_policy_on(port_dev)) + return 0; + usb_autopm_get_interface(intf); set_bit(port1, hub->busy_bits); @@ -107,7 +128,7 @@ static int usb_port_runtime_resume(struct device *dev) return retval; } -static int usb_port_runtime_suspend(struct device *dev) +static int usb_port_runtime_poweroff(struct device *dev) { struct usb_port *port_dev = to_usb_port(dev); struct usb_device *hdev = to_usb_device(dev->parent->parent); @@ -119,9 +140,8 @@ static int usb_port_runtime_suspend(struct device *dev) if (!hub) return -EINVAL; - if (dev_pm_qos_flags(&port_dev->dev, PM_QOS_FLAG_NO_POWER_OFF) - == PM_QOS_FLAGS_ALL) - return -EAGAIN; + if (is_power_policy_on(port_dev)) + return 0; usb_autopm_get_interface(intf); set_bit(port1, hub->busy_bits); @@ -141,8 +161,8 @@ static bool usb_port_notify_flags(struct device *dev, s32 mask, bool set) static const struct dev_pm_ops usb_port_pm_ops = { #ifdef CONFIG_PM_RUNTIME - .runtime_suspend = usb_port_runtime_suspend, - .runtime_resume = usb_port_runtime_resume, + .runtime_suspend = usb_port_runtime_poweroff, + .runtime_resume = usb_port_runtime_poweron, .notify_flags = usb_port_notify_flags, #endif }; @@ -156,13 +176,11 @@ struct device_type usb_port_device_type = { int usb_hub_create_port_device(struct usb_hub *hub, int port1) { struct usb_port *port_dev = NULL; - int retval; + int retval, flag = PM_QOS_FLAG_NO_POWER_OFF; port_dev = kzalloc(sizeof(*port_dev), GFP_KERNEL); - if (!port_dev) { - retval = -ENOMEM; -
[RFC PATCH 13/15] usbcore: show port power policy
Let userspace determine the effective power policy of the port. Reading the power policy returns the effective idle state for the port. If the power policy is set to off this file effectively becomes the power/runtime_status of an attached child device, otherwise it reflects the state of pm_qos_no_power_off + connect_type + peer port constraints. Signed-off-by: Dan Williams --- drivers/usb/core/port.c | 13 + 1 files changed, 13 insertions(+), 0 deletions(-) diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c index 71fbedaf8a93..6073b4521d03 100644 --- a/drivers/usb/core/port.c +++ b/drivers/usb/core/port.c @@ -79,8 +79,21 @@ static ssize_t connect_type_store(struct device *dev, struct device_attribute *a static DEVICE_ATTR_RW(connect_type); +static ssize_t power_policy_show(struct device *dev, +struct device_attribute *attr, char *buf) +{ + struct usb_port *port_dev = to_usb_port(dev); + + if (usb_port_power_enabled(port_dev)) + return sprintf(buf, "on\n"); + else + return sprintf(buf, "off\n"); +} +static DEVICE_ATTR_RO(power_policy); + static struct attribute *port_dev_attrs[] = { &dev_attr_connect_type.attr, + &dev_attr_power_policy.attr, NULL, }; -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC PATCH 09/15] usbcore: convert khubd to a workqueue and flush khubd on port power off
For reliable port power management we want to be sure that khubd is only taking actions on active ports. Towards that end we need to mark the ports us undergoing a power transition and stop khubd actions on the port. The existing hub->busy_bits attempt this notification, but it is not synchronized with power transitions. When we go to disable port power flush khubd to make sure it never takes action on powered down port, or races actions against a port in the middle of transitioning. This requires that khubd never trigger a synchronous suspend otherwise it will deadlock, hence the conversions to the async pm_runtime_put interfaces. Cc: Greg Kroah-Hartman Cc: Alan Stern Cc: Sarah Sharp Signed-off-by: Dan Williams --- drivers/usb/core/hub.c | 118 --- drivers/usb/core/hub.h |3 - drivers/usb/core/port.c | 30 3 files changed, 51 insertions(+), 100 deletions(-) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 2e0812eff0ae..3324cf5fd253 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -22,11 +22,10 @@ #include #include #include -#include #include -#include #include #include +#include #include #include @@ -53,14 +52,7 @@ static inline int hub_is_superspeed(struct usb_device *hdev) * change to USB_STATE_NOTATTACHED even when the semaphore isn't held. */ static DEFINE_SPINLOCK(device_state_lock); -/* khubd's worklist and its lock */ -static DEFINE_SPINLOCK(hub_event_lock); -static LIST_HEAD(hub_event_list); /* List of hubs needing servicing */ - -/* Wakes up khubd */ -static DECLARE_WAIT_QUEUE_HEAD(khubd_wait); - -static struct task_struct *khubd_task; +static struct workqueue_struct *khubd_wq; /* cycle leds on hubs that aren't blinking for attention */ static bool blinkenlights = 0; @@ -575,20 +567,18 @@ static int hub_port_status(struct usb_hub *hub, int port1, return ret; } +static void hub_release(struct kref *); static void kick_khubd(struct usb_hub *hub) { - unsigned long flags; + struct usb_interface *intf = to_usb_interface(hub->intfdev); - spin_lock_irqsave(&hub_event_lock, flags); - if (!hub->disconnected && list_empty(&hub->event_list)) { - list_add_tail(&hub->event_list, &hub_event_list); - - /* Suppress autosuspend until khubd runs */ - usb_autopm_get_interface_no_resume( - to_usb_interface(hub->intfdev)); - wake_up(&khubd_wait); + /* Suppress autosuspend until khubd runs */ + usb_autopm_get_interface_no_resume(intf); + kref_get(&hub->kref); + if (!queue_work(khubd_wq, &hub->event_work)) { + usb_autopm_put_interface_async(intf); + kref_put(&hub->kref, hub_release); } - spin_unlock_irqrestore(&hub_event_lock, flags); } void usb_kick_khubd(struct usb_device *hdev) @@ -959,7 +949,7 @@ int usb_remove_device(struct usb_device *udev) usb_autopm_get_interface(intf); set_bit(udev->portnum, hub->removed_bits); hub_port_logical_disconnect(hub, udev->portnum); - usb_autopm_put_interface(intf); + usb_autopm_put_interface_async(intf); return 0; } @@ -1576,13 +1566,10 @@ static void hub_disconnect(struct usb_interface *intf) int i; /* Take the hub off the event list and don't let it be added again */ - spin_lock_irq(&hub_event_lock); - if (!list_empty(&hub->event_list)) { - list_del_init(&hub->event_list); + if (cancel_work_sync(&hub->event_work)) { usb_autopm_put_interface_no_suspend(intf); + kref_put(&hub->kref, hub_release); } - hub->disconnected = 1; - spin_unlock_irq(&hub_event_lock); /* Disconnect all children and quiesce the hub */ hub->error = 0; @@ -1606,6 +1593,7 @@ static void hub_disconnect(struct usb_interface *intf) kref_put(&hub->kref, hub_release); } +static void hub_events(struct work_struct *); static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_host_interface *desc; @@ -1696,7 +1684,7 @@ descriptor_error: } kref_init(&hub->kref); - INIT_LIST_HEAD(&hub->event_list); + INIT_WORK(&hub->event_work, hub_events); hub->intfdev = &intf->dev; hub->hdev = hdev; INIT_DELAYED_WORK(&hub->leds, led_work); @@ -2342,7 +2330,7 @@ int usb_new_device(struct usb_device *udev) (void) usb_create_ep_devs(&udev->dev, &udev->ep0, udev); usb_mark_last_busy(udev); - pm_runtime_put_sync_autosuspend(&udev->dev); + pm_runtime_put_autosuspend(&udev->dev); return err; fail: @@ -4574,13 +4562,12 @@ static int hub_handle_remote_wakeup(struct usb_hub *hub, unsigned int port, return connect_change; } -static void hub_events(void) +static void hub_events(struct w
[RFC PATCH 14/15] usbcore: add usbcore.noacpi
Port power management places a lot of trust in the firmware api tables. Set this flag if it turns out that trust was misplaced. Signed-off-by: Dan Williams --- Documentation/kernel-parameters.txt |4 drivers/usb/core/usb-acpi.c |7 +++ 2 files changed, 11 insertions(+), 0 deletions(-) diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index fcbb736d55fe..bd6fb49c2a66 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -3240,6 +3240,10 @@ bytes respectively. Such letter suffixes can also be entirely omitted. USB_REQ_GET_DESCRIPTOR request in milliseconds (default 5000 = 5.0 seconds). + usbcore.noacpi= [USB] Disable port power management, connection + type reporting, and any other USB functionality + enabled by ACPI. + usbhid.mousepoll= [USBHID] The interval which mice are to be polled at. diff --git a/drivers/usb/core/usb-acpi.c b/drivers/usb/core/usb-acpi.c index fab4a8288803..0886fab67e99 100644 --- a/drivers/usb/core/usb-acpi.c +++ b/drivers/usb/core/usb-acpi.c @@ -21,6 +21,9 @@ #include "hub.h" #include "usb-platform.h" +static bool noacpi; +module_param(noacpi, bool, 0444); + /** * usb_acpi_power_manageable - check whether usb port has * acpi power resource. @@ -284,6 +287,10 @@ static struct acpi_bus_type usb_acpi_bus = { int usb_acpi_register(void) { + if (noacpi) { + pr_info("%s: USB ACPI support disabled\n", usbcore_name); + return 0; + } return register_acpi_bus_type(&usb_acpi_bus); } -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC PATCH 08/15] usbcore: kill ->is_power_on and ->did_runtime_put
->is_power_on can now be reliably determined by looking at the power policy and the runtime status. ->did_runtime_put is handled automatically by the pm_runtime parent-child relationship. A few other cleanups fall out: 1/ No longer any need for usb_hub_set_port_power 2/ hub_power_on() only ever re-enables ports that should otherwise be powered Yes, this is still racy, but no worse than the current solution, synchronization to come. Cc: Sarah Sharp Signed-off-by: Dan Williams --- drivers/usb/core/hub.c | 95 --- drivers/usb/core/hub.h | 14 ++- drivers/usb/core/port.c | 11 - 3 files changed, 29 insertions(+), 91 deletions(-) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index e06a457094fd..2e0812eff0ae 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -409,7 +409,7 @@ int usb_clear_port_feature(struct usb_device *hdev, int port1, int feature) /* * USB 2.0 spec Section 11.24.2.13 */ -static int set_port_feature(struct usb_device *hdev, int port1, int feature) +int usb_set_port_feature(struct usb_device *hdev, int port1, int feature) { return usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0), USB_REQ_SET_FEATURE, USB_RT_PORT, feature, port1, @@ -426,7 +426,7 @@ static void set_port_led( int selector ) { - int status = set_port_feature(hub->hdev, (selector << 8) | port1, + int status = usb_set_port_feature(hub->hdev, (selector << 8) | port1, USB_PORT_FEAT_INDICATOR); if (status < 0) dev_dbg (hub->intfdev, @@ -731,34 +731,6 @@ static void hub_tt_work(struct work_struct *work) } /** - * usb_hub_set_port_power - control hub port's power state - * @hdev: USB device belonging to the usb hub - * @hub: target hub - * @port1: port index - * @set: expected status - * - * call this function to control port's power via setting or - * clearing the port's PORT_POWER feature. - * - * Return: 0 if successful. A negative error code otherwise. - */ -int usb_hub_set_port_power(struct usb_device *hdev, struct usb_hub *hub, - int port1, bool set) -{ - int ret; - struct usb_port *port_dev = hub->ports[port1 - 1]; - - if (set) - ret = set_port_feature(hdev, port1, USB_PORT_FEAT_POWER); - else - ret = usb_clear_port_feature(hdev, port1, USB_PORT_FEAT_POWER); - - if (!ret) - port_dev->power_is_on = set; - return ret; -} - -/** * usb_hub_clear_tt_buffer - clear control/bulk TT state in high speed hub * @urb: an URB associated with the failed or incomplete split transaction * @@ -836,11 +808,9 @@ static unsigned hub_power_on(struct usb_hub *hub, bool do_delay) dev_dbg(hub->intfdev, "trying to enable port power on " "non-switchable hub\n"); for (port1 = 1; port1 <= hub->hdev->maxchild; port1++) - if (hub->ports[port1 - 1]->power_is_on) - set_port_feature(hub->hdev, port1, USB_PORT_FEAT_POWER); - else - usb_clear_port_feature(hub->hdev, port1, - USB_PORT_FEAT_POWER); + if (usb_port_power_enabled(hub->ports[port1 - 1])) + usb_set_port_feature(hub->hdev, port1, +USB_PORT_FEAT_POWER); /* Wait at least 100 msec for power to become stable */ delay = max(pgood_delay, (unsigned) 100); @@ -872,7 +842,7 @@ static int hub_hub_status(struct usb_hub *hub, static int hub_set_port_link_state(struct usb_hub *hub, int port1, unsigned int link_status) { - return set_port_feature(hub->hdev, + return usb_set_port_feature(hub->hdev, port1 | (link_status << 3), USB_PORT_FEAT_LINK_STATE); } @@ -1092,6 +1062,9 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) struct usb_device *udev = hub->ports[port1 - 1]->child; u16 portstatus, portchange; + if (!usb_port_power_enabled(hub->ports[port1 - 1])) + continue; + portstatus = portchange = 0; status = hub_port_status(hub, port1, &portstatus, &portchange); if (udev || (portstatus & USB_PORT_STAT_CONNECTION)) @@ -1174,17 +1147,10 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) set_bit(port1, hub->change_bits); } else if (udev->persist_enabled) { - struct usb_port *port_dev = hub->ports[port1 - 1]; - #ifdef CONFIG_PM udev->reset_resume = 1; #endif - /* Don't set the change_bits when the device -* was powered off. -
[RFC PATCH 10/15] usbcore: cleanup hub_port_connect_change and hub_power_on
Before adding another hub->ports[port1 - 1] invocation just convert to local port_dev. Signed-off-by: Dan Williams --- drivers/usb/core/hub.c |9 + 1 files changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 3324cf5fd253..d1a08d00e7bb 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -4284,6 +4284,7 @@ hub_power_remaining (struct usb_hub *hub) static void hub_port_connect_change(struct usb_hub *hub, int port1, u16 portstatus, u16 portchange) { + struct usb_port *port_dev = hub->ports[port1 - 1]; struct usb_device *hdev = hub->hdev; struct device *hub_dev = hub->intfdev; struct usb_hcd *hcd = bus_to_hcd(hdev->bus); @@ -4310,7 +4311,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, #endif /* Try to resuscitate an existing device */ - udev = hub->ports[port1 - 1]->child; + udev = port_dev->child; if ((portstatus & USB_PORT_STAT_CONNECTION) && udev && udev->state != USB_STATE_NOTATTACHED) { usb_lock_device(udev); @@ -4342,7 +4343,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, if (hcd->phy && !hdev->parent && !(portstatus & USB_PORT_STAT_CONNECTION)) usb_phy_notify_disconnect(hcd->phy, udev->speed); - usb_disconnect(&hub->ports[port1 - 1]->child); + usb_disconnect(&port_dev->child); } clear_bit(port1, hub->change_bits); @@ -4476,7 +4477,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, if (hdev->state == USB_STATE_NOTATTACHED) status = -ENOTCONN; else - hub->ports[port1 - 1]->child = udev; + port_dev->child = udev; spin_unlock_irq(&device_state_lock); /* Run it through the hoops (find a driver, etc) */ @@ -4484,7 +4485,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, status = usb_new_device(udev); if (status) { spin_lock_irq(&device_state_lock); - hub->ports[port1 - 1]->child = NULL; + port_dev->child = NULL; spin_unlock_irq(&device_state_lock); } } -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC PATCH 06/15] usbcore: make usb_port a proper parent of a usb_device
We jump through a few hoops to support maintaining a usb_port as a sibling of a usb_device. Namely ->power_is_on and ->did_runtime_put are artifacts of pm_ignore_children and the organization of the device tree. Re-organize the hierarchy to enable using the runtime_status as the indicator of whether a port should be active. To preserve the userspace abi a link from the hub to the child device is provided. Before: # readlink -f /sys/devices/pci:00/:00:14.0/usb2/2-1 /sys/devices/pci:00/:00:14.0/usb2/2-1 +---+ | hub | +---^---+ | +-++ | | +---+---+ +---+---+ | intf | |device | +---^---+ +---+ | +---+---+ | port | +---+ After: # readlink -f /sys/devices/pci:00/:00:14.0/usb2/2-1 /sys/devices/pci:00/:00:14.0/usb2/2-0:1.0/port1/2-1 +---+ | hub | +---^---+ | +---+---+ | intf | +---^---+ | +---+---+ | port | +---^---+ | +---+---+ |device | +---+ Cc: Greg Kroah-Hartman Cc: Alan Stern Signed-off-by: Dan Williams --- drivers/usb/core/hub.c | 16 +--- drivers/usb/core/usb.c | 14 -- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 06cec635e703..b78eb4cdf5ed 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -2066,9 +2066,9 @@ void usb_disconnect(struct usb_device **pdev) if (udev->parent) { struct usb_hub *hub = usb_hub_to_struct_hub(udev->parent); struct usb_port *port_dev = hub->ports[udev->portnum - 1]; + struct usb_device *hdev = udev->parent; - sysfs_remove_link(&udev->dev.kobj, "port"); - sysfs_remove_link(&port_dev->dev.kobj, "device"); + sysfs_remove_link(&hdev->dev.kobj, dev_name(&udev->dev)); if (!port_dev->did_runtime_put) pm_runtime_put(&port_dev->dev); @@ -2377,19 +2377,13 @@ int usb_new_device(struct usb_device *udev) if (udev->parent) { struct usb_hub *hub = usb_hub_to_struct_hub(udev->parent); struct usb_port *port_dev = hub->ports[udev->portnum - 1]; + struct usb_device *hdev = udev->parent; - err = sysfs_create_link(&udev->dev.kobj, - &port_dev->dev.kobj, "port"); + err = sysfs_create_link(&hdev->dev.kobj, &udev->dev.kobj, + dev_name(&udev->dev)); if (err) goto fail; - err = sysfs_create_link(&port_dev->dev.kobj, - &udev->dev.kobj, "device"); - if (err) { - sysfs_remove_link(&udev->dev.kobj, "port"); - goto fail; - } - pm_runtime_get_sync(&port_dev->dev); } diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 4d1144990d4c..c55711420222 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -42,7 +42,7 @@ #include #include -#include "usb.h" +#include "hub.h" const char *usbcore_name = "usbcore"; @@ -458,6 +458,13 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent, dev_set_name(&dev->dev, "usb%d", bus->busnum); root_hub = 1; } else { + struct usb_hub *hub = usb_hub_to_struct_hub(parent); + + if (!hub) { + kfree(dev); + return NULL; + } + /* match any labeling on the hubs; it's one-based */ if (parent->devpath[0] == '0') { snprintf(dev->devpath, sizeof dev->devpath, @@ -476,7 +483,10 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent, (15 << ((parent->level - 1)*4)); } - dev->dev.parent = &parent->dev; + /* usb hierarchy is hub->device device-model hierarchy is +* hub->intf->port->device +*/ + dev->dev.parent = &hub->ports[port1 - 1]->dev; dev_set_name(&dev->dev, "%d-%s", bus->busnum, dev->devpath); /* hub driver sets up TT records */ -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC PATCH 12/15] usbcore: allow the connect_type of ports to be changed
hotplug ports maintain power awaiting hotplug events. Allow userspace to override this disctinction on a per port basis. Signed-off-by: Dan Williams --- drivers/usb/core/port.c | 32 +- drivers/usb/core/usb-platform.c | 42 +++ drivers/usb/core/usb-platform.h |2 ++ 3 files changed, 75 insertions(+), 1 deletions(-) diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c index d609b25746d2..71fbedaf8a93 100644 --- a/drivers/usb/core/port.c +++ b/drivers/usb/core/port.c @@ -47,7 +47,37 @@ static ssize_t connect_type_show(struct device *dev, return sprintf(buf, "%s\n", result); } -static DEVICE_ATTR_RO(connect_type); + + +static ssize_t connect_type_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t len) +{ + struct usb_port *port_dev = to_usb_port(dev); + ssize_t sz = len; + int i; + struct action { const char *str; enum usb_port_connect_type type; }; + static const struct action action[] = { + { .str = "hotplug", .type = USB_PORT_CONNECT_TYPE_HOT_PLUG, }, + { .str = "hardwired", .type = USB_PORT_CONNECT_TYPE_HARD_WIRED }, + }; + + if (buf[len-1] == '\n' || buf[len-1] == '\0') + sz--; + + for (i = 0; i < ARRAY_SIZE(action); i++) { + const struct action *act = &action[i]; + + if (sz == strlen(act->str) + && strncmp(buf, act->str, sz) == 0) { + usb_connector_set_connect_type(port_dev, act->type); + return len; + } + } + + return -EINVAL; +} + +static DEVICE_ATTR_RW(connect_type); static struct attribute *port_dev_attrs[] = { &dev_attr_connect_type.attr, diff --git a/drivers/usb/core/usb-platform.c b/drivers/usb/core/usb-platform.c index 0e24110e8ba2..ce559994760e 100644 --- a/drivers/usb/core/usb-platform.c +++ b/drivers/usb/core/usb-platform.c @@ -91,6 +91,48 @@ bool usb_connector_notify_flags(struct usb_port *port_dev, s32 mask, bool set) return true; } +void usb_connector_set_connect_type(struct usb_port *port_dev, + enum usb_port_connect_type type) +{ + LIST_HEAD(tmp); + struct usb_port *p; + struct usb_domain *udom; + int flag = PM_QOS_FLAG_NO_NOTIFY; + struct usb_connector *uconn = port_dev->connector; + + /* if for some reason userspace does not want hotplug settings +* synced +*/ + if (dev_pm_qos_flags(&port_dev->dev, flag) == PM_QOS_FLAGS_ALL + || !uconn) { + pm_runtime_get_sync(&port_dev->dev); + port_dev->connect_type = type; + pm_runtime_put(&port_dev->dev); + } + + udom = uconn->domain; + mutex_lock(&udom->lock); + uconn->connect_type = type; + list_for_each_entry(port_dev, &uconn->ports, node) { + pm_runtime_get_sync(&port_dev->dev); + port_dev->connect_type = type; + } + + /* order the resulting suspensions disconnected ports first */ + list_for_each_entry_safe(port_dev, p, &uconn->ports, node) { + if (port_dev->child) + list_move(&port_dev->node, &tmp); + else + pm_runtime_put(&port_dev->dev); + } + + list_for_each_entry_safe(port_dev, p, &tmp, node) { + list_move(&port_dev->node, &uconn->ports); + pm_runtime_put(&port_dev->dev); + } + mutex_unlock(&udom->lock); +} + static struct usb_connector *create_connector(struct usb_domain *udom, struct usb_port *port_dev, size_t pair_data) diff --git a/drivers/usb/core/usb-platform.h b/drivers/usb/core/usb-platform.h index 648dbe6d9e54..f73bc309eef3 100644 --- a/drivers/usb/core/usb-platform.h +++ b/drivers/usb/core/usb-platform.h @@ -52,3 +52,5 @@ bool usb_connector_notify_flags(struct usb_port *port_dev, s32 mask, bool set); enum usb_connector_state usb_connector_state(struct usb_port *port_dev); void usb_connector_connect(struct usb_port *port_dev); void usb_connector_disconnect(struct usb_port *port_dev); +void usb_connector_set_connect_type(struct usb_port *port_dev, + enum usb_port_connect_type type); -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC PATCH 15/15] checkpatch: allow list_for_each helper macros
Permit list_for_each redifinitions like: #define for_each_connector_peer(peer, port, c) \ list_for_each_entry(peer, &(c)->ports, node) \ if (port != peer) ...which triggers: ERROR: Macros with complex values should be enclosed in parenthesis Cc: Andrew Morton Cc: Joe Perches Cc: Andy Whitcroft Signed-off-by: Dan Williams --- scripts/checkpatch.pl |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 66cad506b8a2..efaf92a43c2f 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -3492,6 +3492,7 @@ sub process { $dstat !~ /^for\s*$Constant$/ && # for (...) $dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ && # for (...) bar() $dstat !~ /^do\s*{/ && # do {... + $dstat !~ /^list_for_each$Ident($Constant)/ && # list_for_each.*(...) $dstat !~ /^\({/ && # ({... $ctx !~ /^.\s*#\s*define\s+TRACE_(?:SYSTEM|INCLUDE_FILE|INCLUDE_PATH)\b/) { -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC PATCH 11/15] usbcore: power down peer port on endpoint connect
Once a port connects to a non-hub device disable its peer until disconnect. This enables safe power cycling of the port that is to remain connected. Otherwise, if a connected port is powered off while the peer remains powered the device may attempt to change speeds and connect to the secondary port when it loses power on its current connection. This implementation toggles the power policy for the peer port. When force_off is set the port will be scheduled for poweroff provided the current pm_qos_no_power_off setting allows. On disconnect the port returns to being powered on by default if it is a hotplug port. Updated summary of the port power management rules: Events: | Power: State: Count: pm_qos_no_power_off=1 | on suspend 0 enable hotplug| on suspend 0 device connect| on active child pm_qos_no_power_off=0 | on active child device sleep | on suspend 0 device wake | on active child device disconnect | on suspend 0 peer connect | offsuspend 0 peer disconnect | on suspend 0 disable hotplug | offsuspend 0 Signed-off-by: Dan Williams --- drivers/usb/core/hub.c | 18 - drivers/usb/core/hub.h |4 + drivers/usb/core/port.c |3 + drivers/usb/core/usb-platform.c | 140 ++- drivers/usb/core/usb-platform.h |9 +++ 5 files changed, 167 insertions(+), 7 deletions(-) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index d1a08d00e7bb..9ebb58168199 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -31,6 +31,7 @@ #include #include "hub.h" +#include "usb-platform.h" /* if we are in debug mode, always announce new devices */ #ifdef DEBUG @@ -2016,9 +2017,12 @@ void usb_disconnect(struct usb_device **pdev) usb_hcd_synchronize_unlinks(udev); if (udev->parent) { + struct usb_hub *hub = usb_hub_to_struct_hub(udev->parent); + struct usb_port *port_dev = hub->ports[udev->portnum - 1]; struct usb_device *hdev = udev->parent; sysfs_remove_link(&hdev->dev.kobj, dev_name(&udev->dev)); + usb_connector_disconnect(port_dev); } usb_remove_ep_devs(&udev->ep0); @@ -2321,11 +2325,15 @@ int usb_new_device(struct usb_device *udev) /* Create link files between child device and usb port device. */ if (udev->parent) { struct usb_device *hdev = udev->parent; + struct usb_hub *hub = usb_hub_to_struct_hub(hdev); + struct usb_port *port_dev = hub->ports[udev->portnum - 1]; err = sysfs_create_link(&hdev->dev.kobj, &udev->dev.kobj, dev_name(&udev->dev)); if (err) goto fail; + + usb_connector_connect(port_dev); } (void) usb_create_ep_devs(&udev->dev, &udev->ep0, udev); @@ -4367,11 +4375,13 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, } } - /* Return now if debouncing failed or nothing is connected or -* the device was "removed". + /* Return now if debouncing failed, nothing is connected, the +* device was "removed", or the connector is occupied by a +* non-hub device */ - if (!(portstatus & USB_PORT_STAT_CONNECTION) || - test_bit(port1, hub->removed_bits)) { + if (!(portstatus & USB_PORT_STAT_CONNECTION) + || test_bit(port1, hub->removed_bits) + || usb_connector_state(port_dev) == USB_CONNECTION_EXCLUSIVE) { /* maybe switch power back on (e.g. root hub was reset) */ if ((wHubCharacteristics & HUB_CHAR_LPSM) < 2 diff --git a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h index 915f76fe64c7..14439e98e573 100644 --- a/drivers/usb/core/hub.h +++ b/drivers/usb/core/hub.h @@ -87,6 +87,9 @@ struct usb_hub { * @port_owner: port's owner * @connect_type: port's connect type * @portnum: port index num based one + * @force_off: peer port in a connector has exclusive conncection + * + * Note force_off is still beholden to pm_qos_no_power_off */ struct usb_port { struct usb_device *child; @@ -96,6 +99,7 @@ struct usb_port { struct dev_state *port_owner; enum usb_port_connect_type connect_type; u8 portnum; + unsigned force_off:1; }; #define to_usb_port(_dev) \ diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c index bef75e5adff2..d609b25746d2 100644 --- a/drivers/usb/core/port.c +++ b/drivers/usb/core/port.c @@ -76,7 +76,8 @@ static bool is_power_policy_on(struct usb_port *port_dev) { int flag = PM_QOS_FLAG_NO_POWER_OFF; - if (port_dev->connect_type <= USB_PORT_CONNECT_TYPE_HOT_PLUG) + if (port_dev->connect_type <= USB_PORT_CONNECT_TYPE_HOT_PLUG +
[RFC PATCH 07/15] usbcore: pm_runtime honor children
Now that ports are in the hierarchy above endpoints we can take advantage of the automatic power management of the device tree. There is now no need to power manage the hub in usb_port_runtime_{suspend|resume} Signed-off-by: Dan Williams --- drivers/usb/core/hub.c |2 -- drivers/usb/core/port.c |6 -- 2 files changed, 0 insertions(+), 8 deletions(-) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index b78eb4cdf5ed..e06a457094fd 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -1637,7 +1637,6 @@ static void hub_disconnect(struct usb_interface *intf) kfree(hub->status); kfree(hub->buffer); - pm_suspend_ignore_children(&intf->dev, false); kref_put(&hub->kref, hub_release); } @@ -1740,7 +1739,6 @@ descriptor_error: usb_set_intfdata (intf, hub); intf->needs_remote_wakeup = 1; - pm_suspend_ignore_children(&intf->dev, true); if (hdev->speed == USB_SPEED_HIGH) highspeed_hubs++; diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c index 259ed86f56d2..3c20cea08d50 100644 --- a/drivers/usb/core/port.c +++ b/drivers/usb/core/port.c @@ -88,7 +88,6 @@ static int usb_port_runtime_poweron(struct device *dev) { struct usb_port *port_dev = to_usb_port(dev); struct usb_device *hdev = to_usb_device(dev->parent->parent); - struct usb_interface *intf = to_usb_interface(dev->parent); struct usb_hub *hub = usb_hub_to_struct_hub(hdev); int port1 = port_dev->portnum; int retval; @@ -104,7 +103,6 @@ static int usb_port_runtime_poweron(struct device *dev) if (is_power_policy_on(port_dev)) return 0; - usb_autopm_get_interface(intf); set_bit(port1, hub->busy_bits); retval = usb_hub_set_port_power(hdev, hub, port1, true); @@ -124,7 +122,6 @@ static int usb_port_runtime_poweron(struct device *dev) } clear_bit(port1, hub->busy_bits); - usb_autopm_put_interface(intf); return retval; } @@ -132,7 +129,6 @@ static int usb_port_runtime_poweroff(struct device *dev) { struct usb_port *port_dev = to_usb_port(dev); struct usb_device *hdev = to_usb_device(dev->parent->parent); - struct usb_interface *intf = to_usb_interface(dev->parent); struct usb_hub *hub = usb_hub_to_struct_hub(hdev); int port1 = port_dev->portnum; int retval; @@ -143,13 +139,11 @@ static int usb_port_runtime_poweroff(struct device *dev) if (is_power_policy_on(port_dev)) return 0; - usb_autopm_get_interface(intf); set_bit(port1, hub->busy_bits); retval = usb_hub_set_port_power(hdev, hub, port1, false); usb_clear_port_feature(hdev, port1, USB_PORT_FEAT_C_CONNECTION); usb_clear_port_feature(hdev, port1, USB_PORT_FEAT_C_ENABLE); clear_bit(port1, hub->busy_bits); - usb_autopm_put_interface(intf); return retval; } -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH 04/15] PM / Runtime: Allow drivers to intercept pm qos flag changes
[ adding Rafael ] On Thu, Oct 24, 2013 at 12:35 AM, Dan Williams wrote: > ...because struct dev_pm_ops is too clean and uniform. > > USB port power management needs to manage ports that are colocated in a > given connector. If we power down a connector we need to arrange for > the peer port in the connector to also be suspended. If the peer > connector stays active it may cause the device to disconnect on the initial > (suspended) port and reconnect on the other. > > Notification of when userspace disables pm_qos_no_power_off allows the > driver to arrange for the peer port to be suspended before the primary > port suspends. > > Alternatives considered: > 1/ force power down the peer port: denies userspace control over power >policy > > 2/ try to synchronize port power management within the USB core: >proved difficult to find a non-racy way to synchronize peer >connections against power management changes. > > 3/ create infrastructure to expose the concept of peer devices in the >pm_runtime system... maybe defer until other use cases outside of USB pop >up. For now, punting the notification to the driver is sufficient. > > As stated this notification allows the kernel to keep power-policy > consistent across a connector. If userspace wants to regain per-port > control (at the risk of unexpected disconnects) it can set the > pm_qos_no_notify flag to prevent ports from coordinating as a connector. > pm_qos_no_notify blocks flags synchronization, restoring the traditional > behavior of one pm_qos_no_power_off manipulation only affecting one > device. > > Cc: Rafael J. Wysocki > Cc: Greg Kroah-Hartman > Cc: Alan Stern > Cc: Sarah Sharp > Signed-off-by: Dan Williams > --- > Documentation/ABI/testing/sysfs-devices-power | 21 +++ > Documentation/power/pm_qos_interface.txt | 15 > drivers/base/power/qos.c | 48 > ++--- > drivers/base/power/sysfs.c| 45 --- > drivers/usb/core/port.c |7 > drivers/usb/core/usb-platform.c | 38 > drivers/usb/core/usb-platform.h |1 + > include/linux/pm.h|5 +++ > include/linux/pm_qos.h|5 +++ > 9 files changed, 159 insertions(+), 26 deletions(-) > > diff --git a/Documentation/ABI/testing/sysfs-devices-power > b/Documentation/ABI/testing/sysfs-devices-power > index efe449bdf811..36d1603ab3bb 100644 > --- a/Documentation/ABI/testing/sysfs-devices-power > +++ b/Documentation/ABI/testing/sysfs-devices-power > @@ -235,3 +235,24 @@ Description: > > This attribute has no effect on system-wide suspend/resume and > hibernation. > + > +What: /sys/devices/.../power/pm_qos_no_notify_flags > +Date: October 2013 > +Contact: Dan Williams > +Description: > + The /sys/devices/.../power/pm_qos_no_notify_flags attribute is > + used for determining whether the kernel is permitted to > forward > + changes to the the PM QoS flags (no_power_off, remote_wakeup) > to > + other devices it deems to be related in the system. When this > + flag is set userspace is indicating that it wants exclusive > + control of the flags and takes responsibility for situations > + where a driver would want the power control setting unified > + amongst a set of devices. In the case of USB a relationship > is > + indicating by a "peer:-port" link in the > + /port directory. > + > + Not all drivers support this attribute. If it isn't > supported, > + it is not present. > + > + This attribute has no effect on system-wide suspend/resume and > + hibernation. > diff --git a/Documentation/power/pm_qos_interface.txt > b/Documentation/power/pm_qos_interface.txt > index 483632087788..a63ad55dbf6f 100644 > --- a/Documentation/power/pm_qos_interface.txt > +++ b/Documentation/power/pm_qos_interface.txt > @@ -94,8 +94,8 @@ flags. Values are updated in response to changes of the > request list. > > Target latency value is simply the minimum of the request values held in the > parameter list elements. The PM QoS flags aggregate value is a gather > (bitwise > -OR) of all list elements' values. Two device PM QoS flags are defined > currently: > -PM_QOS_FLAG_NO_POWER_OFF and PM_QOS_FLAG_REMOTE_WAKEUP. > +OR) of all list elements' values. Three device PM QoS flags are defined > currently: > +PM_QOS_FLAG_NO_POWER_OFF, PM_QOS_FLAG_REMOTE_WAKEUP, PM_QOS_FLAG_NO_NOTIFY. > > Note: the aggregated target value is implemented as an atomic variable so > that > reading the aggregated value does not require any locking mechanism. > @@ -148,13 +148,14 @@ from the device's power directory. > > int dev_pm_qo
Re: [PATCH 1/4] usb: usbtest: support bos descriptor test for usb 3.0
On Mon, Oct 21, 2013 at 11:50:39AM -0400, Alan Stern wrote: > On Mon, 21 Oct 2013, Huang Rui wrote: > > > In Test 9 of usbtest module, it is used for performing chapter 9 tests N > > times. This patch adds to support getting bos descriptor test scenario for > > USB 3.0. > > > > Signed-off-by: Huang Rui > > --- > > drivers/usb/misc/usbtest.c | 13 + > > 1 file changed, 13 insertions(+) > > > > diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c > > index 3e91d3e9..a22f0d0 100644 > > --- a/drivers/usb/misc/usbtest.c > > +++ b/drivers/usb/misc/usbtest.c > > @@ -689,6 +689,19 @@ static int ch9_postconfig(struct usbtest_dev *dev) > > return (retval < 0) ? retval : -EDOM; > > } > > > > + /* > > +* there's always [9.4.3] a bos device descriptor [9.6.2] in USB > > +* 3.0 spec > > +*/ > > + if (le16_to_cpu(udev->descriptor.bcdUSB) == 0x0300) { > > When USB 3.1 is announced, won't you want to test those devices too? > Shouldn't the test be >= 0x0300? > That's right, will update in v2. Thanks, Rui -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH 15/15] checkpatch: allow list_for_each helper macros
[ adding Andy and Joe ] On Thu, Oct 24, 2013 at 12:36 AM, Dan Williams wrote: > Permit list_for_each redifinitions like: > > #define for_each_connector_peer(peer, port, c) \ >list_for_each_entry(peer, &(c)->ports, node) \ >if (port != peer) > > ...which triggers: > ERROR: Macros with complex values should be enclosed in parenthesis > > Cc: Andrew Morton > Cc: Joe Perches > Cc: Andy Whitcroft > Signed-off-by: Dan Williams > --- > scripts/checkpatch.pl |1 + > 1 files changed, 1 insertions(+), 0 deletions(-) > > diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl > index 66cad506b8a2..efaf92a43c2f 100755 > --- a/scripts/checkpatch.pl > +++ b/scripts/checkpatch.pl > @@ -3492,6 +3492,7 @@ sub process { > $dstat !~ /^for\s*$Constant$/ && > # for (...) > $dstat !~ > /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ && # for (...) bar() > $dstat !~ /^do\s*{/ && > # do {... > + $dstat !~ /^list_for_each$Ident($Constant)/ && > # list_for_each.*(...) > $dstat !~ /^\({/ && > # ({... > $ctx !~ > /^.\s*#\s*define\s+TRACE_(?:SYSTEM|INCLUDE_FILE|INCLUDE_PATH)\b/) > { > -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 4/4] usb: wusbcore: change WA_SEGS_MAX to a legal value
On Wed, 2013-10-23 at 14:44 -0500, Thomas Pugliese wrote: > change WA_SEGS_MAX to a number that is legal according to the WUSB > spec. > > Signed-off-by: Thomas Pugliese This should go to stable. Regards Oliver -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/4] usb: wusbcore: set the RPIPE wMaxPacketSize value correctly
On Wed, 2013-10-23 at 16:14 -0500, Thomas Pugliese wrote: > > On Thu, 24 Oct 2013, Sergei Shtylyov wrote: > > > Hello. > > > > On 10/23/2013 11:44 PM, Thomas Pugliese wrote: > > > > > For isochronous endpoints, set the RPIPE wMaxPacketSize value using > > > wOverTheAirPacketSize from the endpoint companion descriptor instead of > > > wMaxPacketSize from the normal endpoint descriptor. > > > > > Signed-off-by: Thomas Pugliese > > > --- > > > drivers/usb/wusbcore/wa-rpipe.c |5 - > > > 1 file changed, 4 insertions(+), 1 deletion(-) > > > > > diff --git a/drivers/usb/wusbcore/wa-rpipe.c > > > b/drivers/usb/wusbcore/wa-rpipe.c > > > index 1ed068a..b48e74c 100644 > > > --- a/drivers/usb/wusbcore/wa-rpipe.c > > > +++ b/drivers/usb/wusbcore/wa-rpipe.c > > > @@ -334,7 +334,10 @@ static int rpipe_aim(struct wa_rpipe *rpipe, struct > > > wahc *wa, > > > /* FIXME: compute so seg_size > ep->maxpktsize */ > > > rpipe->descr.wBlocks = cpu_to_le16(16); /* given */ > > > /* ep0 maxpktsize is 0x200 (WUSB1.0[4.8.1]) */ > > > - rpipe->descr.wMaxPacketSize = cpu_to_le16(ep->desc.wMaxPacketSize); > > > + if (usb_endpoint_xfer_isoc(&ep->desc)) > > > + rpipe->descr.wMaxPacketSize = epcd->wOverTheAirPacketSize; > > > + else > > > + rpipe->descr.wMaxPacketSize = ep->desc.wMaxPacketSize; > > > >Did you intentionally remove cpu_to_le16()? It doesn't seem to go > > together > > well with the above statement... > > > > WBR, Sergei > > > > > > Yes, removing the cpu_to_le16 is intentional. Both sides of the > assignment are fields of USB descriptors and are already __le16 so > byteswapping would be the wrong thing to do. I forgot to mention that. In this case the fix should also go to stable. Regards Oliver -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: LTE vodafone K5150 (hilink) 12d1 1f16 ; 12d1 1575 mbim?
Thomas Schäfer writes: > Hi, > > I have some news about this device. Under Windows 8.1 (6.3)(testversion) > with these IDs: > > USB\VID_12D1&PID_1F16&REV_0102&MI_00 > USB\VID_12D1&PID_1F16&MI_00 > > USB\Class_02&SubClass_0e&Prot_00 > USB\Class_02&SubClass_0e > USB\Class_02 > > > the device works as mobile broadband device with IPv6. > So I think the firmware is ok, or Microsoft has patched its driver a little > bit more. This is the device which sends NS messages to the host, isn't it? If the fact that Linux does not respond to these is the reason it doesn't work on Linux, then I'd say the firmware is far from OK. MBIM has no neighbour concept at all, and requiring a NA to work is so wrong it's not even funny. But we don't know if this is really the problem. Any chance you could snoop the Windows IPv6 session? I'm interesting in seeing the NS and NA messages. In particular any NA from Windows. Don't need many packets, only the part where the modem tries to discover the host "L2 address". Did you try any of the ND tuning controls on Linux? Turning on ARP before bringing up the interface might work on IPv6 (but fail for IPv4): ifconfig wwan0 arp Trying sysctl -w net.ipv6.conf.wwan0.ndisc_notify = 1 would also be interesting (although I have no idea what the effect would be in combination with IFF_NOARP). Another interesting test would be adding the solicited node multicast address manually, but I can't figure out how to do that using e.g. "ip maddr" You can certainly do it with setsockopt(), but that's a bit more work than it should be. Anyway, after discussing the issue on netdev I am convinced that, although not formally correct, not joining this multicast group does give the wanted and expected result. We could make the behaviour absolutely correct by joining the group and add additional code to prevent responses to any received NS, but the net result would be the same. Responding to NS when we have disabled ARP (which has a dual IPv4/IPv6 neighbour discovery meaning here), would be wrong. And ARP is impossible on MBIM, so we cannot enable that (at least not with the typical modems fake dhcp server, which will configure a fake subnet). We can either add workaround code to make the driver fake NAs if necessary, or we can rewrite the ndisc code so that it's possible for a driver to fine tune the wanted response pattern. But I'd really like to confirm that this is necessary first. The first solution is simple but ugly. The second is more generic, but probably wasting netdevice flags for a single buggy firmware on a single device on a single driver... Bjørn -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 2/3] usb: chipidea: add freescale imx28 special write register method
According to Freescale imx28 Errata, "ENGR119653 USB: ARM to USB register error issue", All USB register write operations must use the ARM SWP instruction. So, we implement special hw_write and hw_test_and_clear for imx28. Discussion for it at below: http://marc.info/?l=linux-usb&m=137996395529294&w=2 Signed-off-by: Peter Chen --- drivers/usb/chipidea/ci.h| 23 +++ drivers/usb/chipidea/core.c |2 ++ drivers/usb/chipidea/host.c |1 + include/linux/usb/chipidea.h |1 + 4 files changed, 27 insertions(+), 0 deletions(-) diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h index 1c94fc5..4eb61d0 100644 --- a/drivers/usb/chipidea/ci.h +++ b/drivers/usb/chipidea/ci.h @@ -173,6 +173,8 @@ struct ci_hdrc { struct dentry *debugfs; boolid_event; boolb_sess_valid_event; + /* imx28 needs swp instruction for writing */ + boolimx28_write_fix; }; static inline struct ci_role_driver *ci_role(struct ci_hdrc *ci) @@ -253,6 +255,13 @@ static inline u32 hw_read(struct ci_hdrc *ci, enum ci_hw_regs reg, u32 mask) return ioread32(ci->hw_bank.regmap[reg]) & mask; } +#ifdef CONFIG_SOC_IMX28 +static inline void imx28_ci_writel(u32 val32, volatile u32 *addr) +{ + __asm__ ("swp %0, %0, [%1]" : : "r"(val32), "r"(addr)); +} +#endif + /** * hw_write: writes to a hw register * @reg: register index @@ -266,7 +275,14 @@ static inline void hw_write(struct ci_hdrc *ci, enum ci_hw_regs reg, data = (ioread32(ci->hw_bank.regmap[reg]) & ~mask) | (data & mask); +#ifdef CONFIG_SOC_IMX28 + if (ci->imx28_write_fix) + imx28_ci_writel(data, ci->hw_bank.regmap[reg]); + else + iowrite32(data, ci->hw_bank.regmap[reg]); +#else iowrite32(data, ci->hw_bank.regmap[reg]); +#endif } /** @@ -281,7 +297,14 @@ static inline u32 hw_test_and_clear(struct ci_hdrc *ci, enum ci_hw_regs reg, { u32 val = ioread32(ci->hw_bank.regmap[reg]) & mask; +#ifdef CONFIG_SOC_IMX28 + if (ci->imx28_write_fix) + imx28_ci_writel(val, ci->hw_bank.regmap[reg]); + else + iowrite32(val, ci->hw_bank.regmap[reg]); +#else iowrite32(val, ci->hw_bank.regmap[reg]); +#endif return val; } diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 06204b7..357a059 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -551,6 +551,8 @@ static int ci_hdrc_probe(struct platform_device *pdev) ci->dev = dev; ci->platdata = dev->platform_data; + ci->imx28_write_fix = !!(ci->platdata->flags & + CI_HDRC_IMX28_WRITE_FIX); ret = hw_device_init(ci, base); if (ret < 0) { diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c index 59e6020..06fd042 100644 --- a/drivers/usb/chipidea/host.c +++ b/drivers/usb/chipidea/host.c @@ -65,6 +65,7 @@ static int host_start(struct ci_hdrc *ci) ehci->caps = ci->hw_bank.cap; ehci->has_hostpc = ci->hw_bank.lpm; ehci->has_tdi_phy_lpm = ci->hw_bank.lpm; + ehci->imx28_write_fix = ci->imx28_write_fix; if (ci->platdata->reg_vbus) { ret = regulator_enable(ci->platdata->reg_vbus); diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h index 7d39967..708bd11 100644 --- a/include/linux/usb/chipidea.h +++ b/include/linux/usb/chipidea.h @@ -24,6 +24,7 @@ struct ci_hdrc_platform_data { * but otg is not supported (no register otgsc). */ #define CI_HDRC_DUAL_ROLE_NOT_OTG BIT(4) +#define CI_HDRC_IMX28_WRITE_FIXBIT(5) enum usb_dr_modedr_mode; #define CI_HDRC_CONTROLLER_RESET_EVENT 0 #define CI_HDRC_CONTROLLER_STOPPED_EVENT 1 -- 1.7.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 1/3] usb: ehci: add freescale imx28 special write register method
According to Freescale imx28 Errata, "ENGR119653 USB: ARM to USB register error issue", All USB register write operations must use the ARM SWP instruction. So, we implement a special ehci_write for imx28. Discussion for it at below: http://marc.info/?l=linux-usb&m=137996395529294&w=2 Signed-off-by: Peter Chen Acked-by: Alan Stern --- Changes for v2: Add Acked-by from Alan Stern drivers/usb/host/ehci.h | 13 + 1 files changed, 13 insertions(+), 0 deletions(-) diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index e8f41c5..535aa8b 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -225,6 +225,7 @@ struct ehci_hcd { /* one per controller */ unsignedhas_synopsys_hc_bug:1; /* Synopsys HC */ unsignedframe_index_bug:1; /* MosChip (AKA NetMos) */ unsignedneed_oc_pp_cycle:1; /* MPC834X port power */ + unsignedimx28_write_fix:1; /* For Freescale i.MX28 */ /* required for usb32 quirk */ #define OHCI_CTRL_HCFS (3 << 6) @@ -728,6 +729,13 @@ static inline unsigned int ehci_readl(const struct ehci_hcd *ehci, #endif } +#ifdef CONFIG_SOC_IMX28 +static inline void imx28_ehci_writel(u32 val32, volatile u32 *addr) +{ + __asm__ ("swp %0, %0, [%1]" : : "r"(val32), "r"(addr)); +} +#endif + static inline void ehci_writel(const struct ehci_hcd *ehci, const unsigned int val, __u32 __iomem *regs) { @@ -735,6 +743,11 @@ static inline void ehci_writel(const struct ehci_hcd *ehci, ehci_big_endian_mmio(ehci) ? writel_be(val, regs) : writel(val, regs); +#elif defined(CONFIG_SOC_IMX28) + if (ehci->imx28_write_fix) + imx28_ehci_writel(val, regs); + else + writel(val, regs); #else writel(val, regs); #endif -- 1.7.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 3/3] usb: chipidea: imx: set CI_HDRC_IMX28_WRITE_FIX for imx28
Due to imx28 needs ARM swp instruction for writing, we set CI_HDRC_IMX28_WRITE_FIX for imx28. Signed-off-by: Peter Chen --- Changes for v2: - Using of_device_id->data to get platform's flag drivers/usb/chipidea/ci_hdrc_imx.c | 32 ++-- 1 files changed, 26 insertions(+), 6 deletions(-) diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c index 023d3cb..68f7f5e 100644 --- a/drivers/usb/chipidea/ci_hdrc_imx.c +++ b/drivers/usb/chipidea/ci_hdrc_imx.c @@ -23,6 +23,26 @@ #include "ci.h" #include "ci_hdrc_imx.h" +#define CI_HDRC_IMX_IMX28_WRITE_FIX BIT(0) + +struct ci_hdrc_imx_platform_flag { + unsigned int flags; +}; + +static const struct ci_hdrc_imx_platform_flag imx27_usb_data = { +}; + +static const struct ci_hdrc_imx_platform_flag imx28_usb_data = { + .flags = CI_HDRC_IMX_IMX28_WRITE_FIX, +}; + +static const struct of_device_id ci_hdrc_imx_dt_ids[] = { + { .compatible = "fsl,imx28-usb", .data = &imx28_usb_data}, + { .compatible = "fsl,imx27-usb", .data = &imx27_usb_data}, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, ci_hdrc_imx_dt_ids); + struct ci_hdrc_imx_data { struct usb_phy *phy; struct platform_device *ci_pdev; @@ -82,6 +102,9 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) CI_HDRC_DISABLE_STREAMING, }; int ret; + const struct of_device_id *of_id = + of_match_device(ci_hdrc_imx_dt_ids, &pdev->dev); + const struct ci_hdrc_imx_platform_flag *imx_platform_flag = of_id->data; data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); if (!data) { @@ -115,6 +138,9 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) pdata.phy = data->phy; + if (imx_platform_flag->flags & CI_HDRC_IMX_IMX28_WRITE_FIX) + pdata.flags |= CI_HDRC_IMX28_WRITE_FIX; + if (!pdev->dev.dma_mask) pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask; if (!pdev->dev.coherent_dma_mask) @@ -174,12 +200,6 @@ static int ci_hdrc_imx_remove(struct platform_device *pdev) return 0; } -static const struct of_device_id ci_hdrc_imx_dt_ids[] = { - { .compatible = "fsl,imx27-usb", }, - { /* sentinel */ } -}; -MODULE_DEVICE_TABLE(of, ci_hdrc_imx_dt_ids); - static struct platform_driver ci_hdrc_imx_driver = { .probe = ci_hdrc_imx_probe, .remove = ci_hdrc_imx_remove, -- 1.7.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 4/4] usb: wusbcore: change WA_SEGS_MAX to a legal value
On Thu, Oct 24, 2013 at 10:04:08AM +0200, Oliver Neukum wrote: > On Wed, 2013-10-23 at 14:44 -0500, Thomas Pugliese wrote: > > change WA_SEGS_MAX to a number that is legal according to the WUSB > > spec. > > > > Signed-off-by: Thomas Pugliese > > This should go to stable. Good catch, I'll do that. thanks, greg k-h -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
usb mass storage bug
https://bugzilla.kernel.org/show_bug.cgi?id=63611 Bug ID: 63611 Summary: cant connect sony phones in mass storage mode -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [Patch v2 09/10] usb: chipidea: host: add ehci quirk for imx controller
Hi, On Thu, Oct 24, 2013 at 09:33:26AM +0800, Peter Chen wrote: > On Wed, Oct 23, 2013 at 02:45:39PM -0400, Alan Stern wrote: > > On Wed, 23 Oct 2013, Felipe Balbi wrote: > > > > > Hi, > > > > > > On Wed, Oct 23, 2013 at 10:46:09AM -0400, Alan Stern wrote: > > > > On Tue, 22 Oct 2013, Peter Chen wrote: > > > > > > > > > When the port goes to suspend or finishes resme, it needs to > > > > > notify PHY, it is not a standard EHCI operation, so we add a > > > > > quirk for it. > > > > > > > > Actually, this _should_ be a standard EHCI operation. But we have to > > > > figure out a way to do it that will work on all platforms. > > > > > > > > Felipe, any ideas? > > > > > > isn't it enough to call usb_phy_set_suspend() at apropriate places ? > > > > > > This should work on all platforms if the PHY driver is implemented > > > correctly. > > > > On Tue, 22 Oct 2013, Peter Chen wrote: > > > > > + /* > > > + * notify the USB PHY, it is for global > > > + * suspend case. > > > + */ > > > + usb_phy_notify_suspend(hcd->phy, > > > + USB_SPEED_HIGH); > > > > Hmmm. This calls usb_phy_notify_suspend(), and later on, > > usb_phy_notify_resume(). AFAICT, those routines don't exist. > > > > Hi Alan and Felipe, > > It is at my another patchset: "Add power management support for MXS PHY" > http://marc.info/?l=linux-usb&m=138242248913823&w=2 > Since they are two things, one is from PHY, the other is for controller. > I split them to two patchset. > > For these two notifications, please see: > [Patch v2 07/14] usb: phy: add notify suspend and resume callback > http://marc.info/?l=linux-usb&m=138242252713848&w=2 > > [Patch v2 08/14] usb: phy-mxs: Add implementation of > nofity_suspend and notify_resume > http://marc.info/?l=linux-usb&m=138242253313856&w=2 > > > Instead we have usb_phy_set_suspend(), as Felipe mentioned. It has a > > different interface, because the second argument specifies whether we > > are entering or leaving suspend, not the connection speed. > > > > Peter, you need to straighten this out. > > .set_suspend is different with .notify_suspend. > > .set_suspend is called when the PHY enters suspend. > .notify_suspend is called when port enters suspends (setting portsc.suspendM, > and stop sending SOF). > > After calling .notify_suspend, the PHY may still need to access, > eg, set PHY wakeup setting, etc. right, this just means we need usage counters for the PHY layer. So that usb_phy_set_suspend() only decreaments a counter and will only suspend the PHY when said counter reaches zero. Also, why can't you *always* setup wakeup events for the PHY ? Everytime you're about to suspend the PHY, enable its wakeup events. > The .notify_suspend is in ehci operation, .set_suspend can be at > controller driver, since when to put the PHY enters suspend may > platform specific. not really, what's platform specific is *HOW* to suspend the PHY. *WHERE* to tell it to suspend is really more of a policy decision. > > Also, there's the question of where are the appropriate places to make > > the calls? After the root hub goes into suspend, I suppose. But when > > is the right time during resume? > > > > If we can take it as standard EHCI operation, we need to put it at below > places: > > For .notify_suspend, we need to put it after set portsc.suspendM. why do you need this notification for suspendM ? PHY should automatically enter a lower power state automatically when suspendM signal is asserted. -- balbi signature.asc Description: Digital signature
pl2303 driver regression after commit 61fa8d694b854
Hi, Just noticed that after commit 61fa8d694b854 (usb: pl2303: also use the divisor based baud rate encoding method for baud rates < 115200 with HX chips) my TRENDnet TU-S9 USB-to-serial adapter started corrupting data. I added baud <= 115200 check back to the comparison which makes the device work for me again (I'm using it at 115200 bps): if (type == type_0 || type == type_1 || type == HX_CLONE || baud <= 115200) baud = pl2303_baudrate_encode_direct(baud, type, buf); The PL2303 chip has following markings if it helps: PL-2303HX LF10482D TP37331HD and here is the output of 'lsusb -vv' of that device: Bus 002 Device 116: ID 067b:2303 Prolific Technology, Inc. PL2303 Serial Port Device Descriptor: bLength18 bDescriptorType 1 bcdUSB 1.10 bDeviceClass0 (Defined at Interface level) bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize064 idVendor 0x067b Prolific Technology, Inc. idProduct 0x2303 PL2303 Serial Port bcdDevice4.00 iManufacturer 1 Prolific Technology Inc. iProduct2 USB-Serial Controller D iSerial 0 bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 39 bNumInterfaces 1 bConfigurationValue 1 iConfiguration 0 bmAttributes 0x80 (Bus Powered) MaxPower 100mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber0 bAlternateSetting 0 bNumEndpoints 3 bInterfaceClass 255 Vendor Specific Class bInterfaceSubClass 0 bInterfaceProtocol 0 iInterface 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x81 EP 1 IN bmAttributes3 Transfer TypeInterrupt Synch Type None Usage Type Data wMaxPacketSize 0x000a 1x 10 bytes bInterval 1 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x02 EP 2 OUT bmAttributes2 Transfer TypeBulk Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x83 EP 3 IN bmAttributes2 Transfer TypeBulk Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 0 Device Status: 0x (Bus Powered) -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [Patch v2 09/10] usb: chipidea: host: add ehci quirk for imx controller
On Thu, Oct 24, 2013 at 07:04:11AM -0500, Felipe Balbi wrote: > Hi, > > On Thu, Oct 24, 2013 at 09:33:26AM +0800, Peter Chen wrote: > > On Wed, Oct 23, 2013 at 02:45:39PM -0400, Alan Stern wrote: > > > On Wed, 23 Oct 2013, Felipe Balbi wrote: > > > > > > > Hi, > > > > > > > > On Wed, Oct 23, 2013 at 10:46:09AM -0400, Alan Stern wrote: > > > > > On Tue, 22 Oct 2013, Peter Chen wrote: > > > > > > > > > > > When the port goes to suspend or finishes resme, it needs to > > > > > > notify PHY, it is not a standard EHCI operation, so we add a > > > > > > quirk for it. > > > > > > > > > > Actually, this _should_ be a standard EHCI operation. But we have to > > > > > figure out a way to do it that will work on all platforms. > > > > > > > > > > Felipe, any ideas? > > > > > > > > isn't it enough to call usb_phy_set_suspend() at apropriate places ? > > > > > > > > This should work on all platforms if the PHY driver is implemented > > > > correctly. > > > > > > On Tue, 22 Oct 2013, Peter Chen wrote: > > > > > > > + /* > > > > +* notify the USB PHY, it is for global > > > > +* suspend case. > > > > +*/ > > > > + usb_phy_notify_suspend(hcd->phy, > > > > + USB_SPEED_HIGH); > > > > > > Hmmm. This calls usb_phy_notify_suspend(), and later on, > > > usb_phy_notify_resume(). AFAICT, those routines don't exist. > > > > > > > Hi Alan and Felipe, > > > > It is at my another patchset: "Add power management support for MXS PHY" > > http://marc.info/?l=linux-usb&m=138242248913823&w=2 > > Since they are two things, one is from PHY, the other is for controller. > > I split them to two patchset. > > > > For these two notifications, please see: > > [Patch v2 07/14] usb: phy: add notify suspend and resume callback > > http://marc.info/?l=linux-usb&m=138242252713848&w=2 > > > > [Patch v2 08/14] usb: phy-mxs: Add implementation of > > nofity_suspend and notify_resume > > http://marc.info/?l=linux-usb&m=138242253313856&w=2 > > > > > Instead we have usb_phy_set_suspend(), as Felipe mentioned. It has a > > > different interface, because the second argument specifies whether we > > > are entering or leaving suspend, not the connection speed. > > > > > > Peter, you need to straighten this out. > > > > .set_suspend is different with .notify_suspend. > > > > .set_suspend is called when the PHY enters suspend. > > .notify_suspend is called when port enters suspends (setting > > portsc.suspendM, > > and stop sending SOF). > > > > After calling .notify_suspend, the PHY may still need to access, > > eg, set PHY wakeup setting, etc. > > right, this just means we need usage counters for the PHY layer. So that > usb_phy_set_suspend() only decreaments a counter and will only suspend > the PHY when said counter reaches zero. > > Also, why can't you *always* setup wakeup events for the PHY ? Everytime > you're about to suspend the PHY, enable its wakeup events. Most of cases, the user doesn't want USB wakeup event. At these cases, if the PHY's wakeup is set, when external signal changes (id/vbus/dpdm), the PHY will be woken up and more power consumption will be. > > > The .notify_suspend is in ehci operation, .set_suspend can be at > > controller driver, since when to put the PHY enters suspend may > > platform specific. > > not really, what's platform specific is *HOW* to suspend the PHY. > *WHERE* to tell it to suspend is really more of a policy decision. > How to suspend the PHY is indeed platform specific, but sometimes, the whole suspend PHY operation may not only include PHY register, but also needs controller register, Eg, for chipidea controller, if we have not used chipidea PHY, we need to control both controller register (portsc.phcd) and PHY's register (Different register mapping), so it is hard to include two operations at usb_phy_set_suspend, we have to put them at controller's suspend. > > > Also, there's the question of where are the appropriate places to make > > > the calls? After the root hub goes into suspend, I suppose. But when > > > is the right time during resume? > > > > > > > If we can take it as standard EHCI operation, we need to put it at below > > places: > > > > For .notify_suspend, we need to put it after set portsc.suspendM. > > why do you need this notification for suspendM ? PHY should > automatically enter a lower power state automatically when suspendM > signal is asserted. > For some PHYs, it may correct. For chipidea controller, it needs to set portsc.phcd to let the PHY enter suspend. The software needs to control it. -- Best Regards, Peter Chen -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: pl2303 driver regression after commit 61fa8d694b854
Am 24.10.2013 14:21, schrieb Mika Westerberg: > Hi, > > Just noticed that after commit 61fa8d694b854 (usb: pl2303: also use the > divisor based baud rate encoding method for baud rates < 115200 with HX > chips) my TRENDnet TU-S9 USB-to-serial adapter started corrupting data. > > I added baud <= 115200 check back to the comparison which makes the device > work for me again (I'm using it at 115200 bps): > > if (type == type_0 || type == type_1 || type == HX_CLONE || baud <= 115200) > baud = pl2303_baudrate_encode_direct(baud, type, buf); There's a better way to fix this... > > The PL2303 chip has following markings if it helps: > > PL-2303HX > LF10482D > TP37331HD > > and here is the output of 'lsusb -vv' of that device: > > Bus 002 Device 116: ID 067b:2303 Prolific Technology, Inc. PL2303 Serial Port > Device Descriptor: > bLength18 > bDescriptorType 1 > bcdUSB 1.10 > bDeviceClass0 (Defined at Interface level) > bDeviceSubClass 0 > bDeviceProtocol 0 > bMaxPacketSize064 > idVendor 0x067b Prolific Technology, Inc. > idProduct 0x2303 PL2303 Serial Port > bcdDevice4.00 > iManufacturer 1 Prolific Technology Inc. > iProduct2 USB-Serial Controller D Ok, this seems to be a HXD (HX rev. D) chip. Could you please validate by checking what Prolifics CheckChipVersion tool toll sais ? It would also be very nice if you could provide a USB-log of what this tool does, because we are currently not able to distinguish between HXD and EA, RA, SA chips. Are baudrates > 115200 working ? Regards, Frank Schäfer > iSerial 0 > bNumConfigurations 1 > Configuration Descriptor: > bLength 9 > bDescriptorType 2 > wTotalLength 39 > bNumInterfaces 1 > bConfigurationValue 1 > iConfiguration 0 > bmAttributes 0x80 > (Bus Powered) > MaxPower 100mA > Interface Descriptor: > bLength 9 > bDescriptorType 4 > bInterfaceNumber0 > bAlternateSetting 0 > bNumEndpoints 3 > bInterfaceClass 255 Vendor Specific Class > bInterfaceSubClass 0 > bInterfaceProtocol 0 > iInterface 0 > Endpoint Descriptor: > bLength 7 > bDescriptorType 5 > bEndpointAddress 0x81 EP 1 IN > bmAttributes3 > Transfer TypeInterrupt > Synch Type None > Usage Type Data > wMaxPacketSize 0x000a 1x 10 bytes > bInterval 1 > Endpoint Descriptor: > bLength 7 > bDescriptorType 5 > bEndpointAddress 0x02 EP 2 OUT > bmAttributes2 > Transfer TypeBulk > Synch Type None > Usage Type Data > wMaxPacketSize 0x0040 1x 64 bytes > bInterval 0 > Endpoint Descriptor: > bLength 7 > bDescriptorType 5 > bEndpointAddress 0x83 EP 3 IN > bmAttributes2 > Transfer TypeBulk > Synch Type None > Usage Type Data > wMaxPacketSize 0x0040 1x 64 bytes > bInterval 0 > Device Status: 0x > (Bus Powered) -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Controller's wakeup setting at usb_add_hcd
On Thu, 24 Oct 2013, Peter Chen wrote: > > If the HC is deleted and the UDC is added then the wakeup settings > > should be determined by the UDC, not by the HC. The next time the > > system goes to sleep, the UDC driver should be responsible for enabling > > or disabling wakeup. > > > > I agree both of your points, but after thinking more, I doubt > that why hcd (or udc) needs to control its parent wakeup setting? > Why not let controller driver decide it? I"m not quite sure what you're asking. To start with, we are talking about two different wakeup settings: The software flag, which is controlled by userspace writing to the power/wakeup attribute or by the driver calling device_wakeup_enable(), device_wakeup_disable(), or device_set_wakeup_enable(); The physical wakeup setting in the hardware. In general, the controller driver does not control the software flag, except that the driver may initialize the flag. usb_add_hcd() always initializes the controller's flag to 1, but the driver can override it afterward. After it is initialized, the flag is controlled entirely by userspace. The physical wakeup setting is controlled by both the controller driver and the platform driver. For example, with a PCI-based EHCI controller, ehci-hub.c sets the various port wakeup flags and the PCI subsystem enables or disables PME. However this shouldn't matter, because these drivers should always tell the hardware to do what the software flag says. That is, if device_may_wakeup() is true then the hardware wakeup should be enabled; otherwise it should be disabled. Alan Stern -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 4/4] usb: wusbcore: change WA_SEGS_MAX to a legal value
On Thu, 24 Oct 2013, Greg KH wrote: > On Thu, Oct 24, 2013 at 10:04:08AM +0200, Oliver Neukum wrote: > > On Wed, 2013-10-23 at 14:44 -0500, Thomas Pugliese wrote: > > > change WA_SEGS_MAX to a number that is legal according to the WUSB > > > spec. > > > > > > Signed-off-by: Thomas Pugliese > > > > This should go to stable. > > Good catch, I'll do that. > > thanks, > > greg k-h > This patch and the other one Oliver commented on will probably not apply cleanly to the stable trees due to the changes that have gone into 3.13. I will backport them to stable and submit those patches separately. Thomas -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Controller's wakeup setting at usb_add_hcd
On Thu, Oct 24, 2013 at 10:25:25AM -0400, Alan Stern wrote: > On Thu, 24 Oct 2013, Peter Chen wrote: > > > > If the HC is deleted and the UDC is added then the wakeup settings > > > should be determined by the UDC, not by the HC. The next time the > > > system goes to sleep, the UDC driver should be responsible for enabling > > > or disabling wakeup. > > > > > > > I agree both of your points, but after thinking more, I doubt > > that why hcd (or udc) needs to control its parent wakeup setting? > > Why not let controller driver decide it? > > I"m not quite sure what you're asking. > > To start with, we are talking about two different wakeup settings: > > The software flag, which is controlled by userspace writing > to the power/wakeup attribute or by the driver calling > device_wakeup_enable(), device_wakeup_disable(), or > device_set_wakeup_enable(); > > The physical wakeup setting in the hardware. > > In general, the controller driver does not control the software flag, > except that the driver may initialize the flag. usb_add_hcd() always > initializes the controller's flag to 1, but the driver can override it > afterward. After it is initialized, the flag is controlled entirely by > userspace. > > The physical wakeup setting is controlled by both the controller driver > and the platform driver. For example, with a PCI-based EHCI > controller, ehci-hub.c sets the various port wakeup flags and the PCI > subsystem enables or disables PME. However this shouldn't matter, > because these drivers should always tell the hardware to do what the > software flag says. That is, if device_may_wakeup() is true then the > hardware wakeup should be enabled; otherwise it should be disabled. > It is the same which the embedded world does, that is the physical wakeup setting is controlled by software flag. Since it is the controller's wakeup, why the controller driver does not go to control the software flag in general? The current problem for me is: usb_add_hcd initializes the controller's flag to 1, the controller driver needs to override it as 0. It will delete the hcd on the fly (call usb_remove_hcd) for otg controller due to plug in Micro B-to-A cable (ID 0->1), and later, the user may plug out this cable (ID 1->0), the hcd will be added again, at this time, the wakeup flag is set by hcd again. If I want to keep the wakeup flag as 0 by default, I need to clear it again. Just like you said: > The physical wakeup setting is controlled by both the controller driver > and the platform driver. But currently, it is controlled (or affected) by hcd layer. -- Best Regards, Peter Chen -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: transmit lockup using smsc95xx ethernet on usb3
> Have you tried the latest stable kernel or the latest -rc kernel? I've built a kernel based on Linus's tree from last Friday, 3.12-rc6 ish. Commented out the trace for short reads - happens all the time. I've not seen an error on a Bo yet, the failure rate is depressingly low. I have had an error that started with an interrupt completion (I think from the root), that leads to a full unplug-replug sequence that overfilled the kernel message buffer (rebuilt with a much bigger buffer). I've just got a error -71 from a Bi. This generates: (There are actually two separated by a Bo completion and setup. [175908.563068] xhci_hcd :00:14.0: Transfer error on endpoint [175908.563070] xhci_hcd :00:14.0: Cleaning up stalled endpoint ring [175908.563072] xhci_hcd :00:14.0: Finding segment containing stopped TRB. [175908.563074] xhci_hcd :00:14.0: Finding endpoint context [175908.563076] xhci_hcd :00:14.0: Finding segment containing last TRB in TD. [175908.563078] xhci_hcd :00:14.0: Cycle state = 0x1 [175908.563081] xhci_hcd :00:14.0: New dequeue segment = 8800d6a817e0 (virtual) [175908.563089] xhci_hcd :00:14.0: New dequeue pointer = 0x2137a4b90 (DMA) [175908.563096] xhci_hcd :00:14.0: Queueing new dequeue state [175908.563104] xhci_hcd :00:14.0: Set TR Deq Ptr cmd, new deq seg = 8800d6a817e0 (0x2137a4800 dma), new deq ptr = 8802137a4b90 (0x2137a4b90 dma), new cycle = 1 [175908.563110] xhci_hcd :00:14.0: // Ding dong! [175908.563119] xhci_hcd :00:14.0: Giveback URB 8802114fd9c0, len = 0, expected = 18944, status = -71 [175908.563122] xhci_hcd :00:14.0: Ignoring reset ep completion code of 1 [175908.563125] xhci_hcd :00:14.0: Successful Set TR Deq Ptr cmd, deq = @2137a4b91 What is interesting is that the usbmon trace then shows only 2 Bi URB being used (rather than 4). After 125ms (assuming the usbmon timestamps are us) another 2 URB are added. Since the URB are usually recycled (or at least freed and immediately realloced so getting the same address) I wonder if this is a memory leak? In any case waiting that long before adding the URB back doesn't seem right. I don't think I've seen an error that only affected the Bi side before, so don't know whether the recover behaviour has changed. FWIW we have identified something 'sub-optimal' with the pcb layout that might be responsible for noise on the USB data/clock source. However the xhci driver should recover from such errors. If the hw guys fix the pcb I'm going to need to keep a failing system! David -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] usb: wusbcore: change WA_SEGS_MAX to a legal value
Change WA_SEGS_MAX to a number that is legal according to the WUSB spec and correct the test for exceeding this value. This patch is against 3.11.6 and is intended for -stable. Signed-off-by: Thomas Pugliese Cc: --- drivers/usb/wusbcore/wa-xfer.c |5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/usb/wusbcore/wa-xfer.c b/drivers/usb/wusbcore/wa-xfer.c index d3493ca..19b5d24 100644 --- a/drivers/usb/wusbcore/wa-xfer.c +++ b/drivers/usb/wusbcore/wa-xfer.c @@ -91,7 +91,8 @@ #include "wusbhc.h" enum { - WA_SEGS_MAX = 255, + /* [WUSB] section 8.3.3 allocates 7 bits for the segment index. */ + WA_SEGS_MAX = 128, }; enum wa_seg_status { @@ -444,7 +445,7 @@ static ssize_t __wa_xfer_setup_sizes(struct wa_xfer *xfer, } xfer->seg_size = (xfer->seg_size / maxpktsize) * maxpktsize; xfer->segs = DIV_ROUND_UP(urb->transfer_buffer_length, xfer->seg_size); - if (xfer->segs >= WA_SEGS_MAX) { + if (xfer->segs > WA_SEGS_MAX) { dev_err(dev, "BUG? ops, number of segments %d bigger than %d\n", (int)(urb->transfer_buffer_length / xfer->seg_size), WA_SEGS_MAX); -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] usb: wusbcore: remove unneccessary byte-swap when assigning RPIPE wMaxPacketSize
This patch removes an unneccessary byte-swap when assigning RPIPE wMaxPacketSize. Both sides of the assignment are __le16 members of a USB descriptor so no byte swap is needed. This patch is against 3.11.6 and is intended for -stable. Signed-off-by: Thomas Pugliese Cc: --- drivers/usb/wusbcore/wa-rpipe.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/wusbcore/wa-rpipe.c b/drivers/usb/wusbcore/wa-rpipe.c index 9a595c1..5645af0 100644 --- a/drivers/usb/wusbcore/wa-rpipe.c +++ b/drivers/usb/wusbcore/wa-rpipe.c @@ -333,7 +333,7 @@ static int rpipe_aim(struct wa_rpipe *rpipe, struct wahc *wa, /* FIXME: compute so seg_size > ep->maxpktsize */ rpipe->descr.wBlocks = cpu_to_le16(16); /* given */ /* ep0 maxpktsize is 0x200 (WUSB1.0[4.8.1]) */ - rpipe->descr.wMaxPacketSize = cpu_to_le16(ep->desc.wMaxPacketSize); + rpipe->descr.wMaxPacketSize = ep->desc.wMaxPacketSize; rpipe->descr.hwa_bMaxBurst = max(min_t(unsigned int, epcd->bMaxBurst, 16U), 1U); -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [GIT PULL] USB patches
On Mon, Oct 21, 2013 at 06:50:42AM -0500, Felipe Balbi wrote: > Hi Greg, > > Here's a large set of patches for v3.13 merge window. All patches have > been pending in linux-usb for quite a while and soaked in linux-next > for a bit too. > > Please consider merging on top of your usb-next branch or let me know > which changes you may want. > > cheers > > The following changes since commit 15c03dd4859ab16f9212238f29dd315654aa94f6: > > Linux 3.12-rc3 (2013-09-29 15:02:38 -0700) > > are available in the git repository at: > > git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb.git > tags/usb-for-v3.13 Pulled and pushed out, thanks. greg k-h -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: LTE vodafone K5150 (hilink) 12d1 1f16 ; 12d1 1575 mbim?
Am 24.10.2013 11:45, schrieb Bjørn Mork: Any chance you could snoop the Windows IPv6 session? I'm interesting in seeing the NS and NA messages. In particular any NA from Windows. Don't need many packets, only the part where the modem tries to discover the host "L2 address". To answering one question for the moment. Wireshark did not work (interface does not appear) . But nm3.4 does. Because of the size I will store this capture file here for a while. http://www.cis.uni-muenchen.de/~thomas/k5150-nm-capture.cap ra, dhcpv6(DNS) and the ms-connections-test (ncsi) are there. I hope, you see also the things you want to know. Regards, Thomas -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [GIT PULL] USB patches
On Thu, Oct 24, 2013 at 04:20:43PM +0100, Greg KH wrote: > On Mon, Oct 21, 2013 at 06:50:42AM -0500, Felipe Balbi wrote: > > Hi Greg, > > > > Here's a large set of patches for v3.13 merge window. All patches have > > been pending in linux-usb for quite a while and soaked in linux-next > > for a bit too. > > > > Please consider merging on top of your usb-next branch or let me know > > which changes you may want. > > > > cheers > > > > The following changes since commit 15c03dd4859ab16f9212238f29dd315654aa94f6: > > > > Linux 3.12-rc3 (2013-09-29 15:02:38 -0700) > > > > are available in the git repository at: > > > > git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb.git > > tags/usb-for-v3.13 > > Pulled and pushed out, thanks. Thanks Greg -- balbi signature.asc Description: Digital signature
Re: choice =y selection becomes lost after having multiple entries =m with depends on
Sebastian Andrzej Siewior writes: > On 10/23/2013 01:23 PM, Yann E. MORIN wrote: >> Sebastian, All, > > Hi Yann, > >> So, I've tried your tests here, and indeed it does not behave as >> expected. Yet, I can observe a slight deviation from your observations: >> the third time I enter the "USB Gadget Support" sub-menu, the "USB >> Gadget Drivers" choice is back to 'M', not 'Y'. But that's still >> considered an issue. > > Yes, that is what I meant. Everything goes back M. Hi Sebastian, I was looking at what you described and initially had a hard time to reproduce the problem, probably because I tried it after `make mrproper'. I am only able to reproduce the problem with an existing .config of my running kernel, for example. Just to make sure that I am correctly trying to reproduce the problem: did you already try to do what you described after a `make mrproper' and do you then also notice the described problems? If not, could you please try that? Thanks, Dirk >>> So the problem exists only if the item itself has a "depends on" line. >>> Anyone aware of such kconfig limitation? >> >> I'll try to come up with a smaller test-case to investigate, but since >> I'm at the LinuxCon Europe and ELCE this week (hey! Party tonight!), I >> won't have much time to look at it before the start of next week. Be >> sure to ping me later next week if you do not see any reply (and in case >> no one else solves the issue in the meantime, that is). > > Okay, thanks. > >> >> Thanks for this bug report. >> >> Regards, >> Yann E. MORIN. >> > > Sebastian > -- > To unsubscribe from this list: send the line "unsubscribe linux-kbuild" in > the body of a message to majord...@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: usb mass storage bug
On Thu, 24 Oct 2013, [iso-8859-2] J�nosi Zoli wrote: > https://bugzilla.kernel.org/show_bug.cgi?id=63611 > � > Bug ID: 63611 > Summary: cant connect sony phones in mass storage mode Is CONFIG_USB_OTG turned on in your kernel's .config? If it is, try building a new kernel with it turned off. Felipe: Is the usb_enumerate_device_otg() routine really correct? It looks like it will try to enable HNP whenever CONFIG_USB_OTG is set, even if the root hub isn't OTG-capable. The routine does this: /* enable HNP before suspend, it's simpler */ if (port1 == bus->otg_port) bus->b_hnp_enable = 1; err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), USB_REQ_SET_FEATURE, 0, bus->b_hnp_enable ? USB_DEVICE_B_HNP_ENABLE : USB_DEVICE_A_ALT_HNP_SUPPORT, 0, NULL, 0, USB_CTRL_SET_TIMEOUT); if (err < 0) { /* OTG MESSAGE: report errors here, * customize to match your product. */ dev_info(&udev->dev, "can't set HNP mode: %d\n", err); bus->b_hnp_enable = 0; } Maybe the usb_control_msg and the error check should be inside the first "if" statement? Alan Stern -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: choice =y selection becomes lost after having multiple entries =m with depends on
On 10/24/2013 05:30 PM, Dirk Gouders wrote: > Hi Sebastian, Hi Dirk, > I was looking at what you described and initially had a hard time to > reproduce the problem, probably because I tried it after `make > mrproper'. I am only able to reproduce the problem with an existing > .config of my running kernel, for example. > > Just to make sure that I am correctly trying to reproduce the problem: > did you already try to do what you described after a `make mrproper' and > do you then also notice the described problems? If not, could you > please try that? What is the purpose behind mrproper? The key to reproduce it is to have a .config with atleast two items within a choice statement which also have a "depends on" statement and those set to =m. If you don't have this after mrproper (with your fresh .config) then you don't see it. > > Thanks, > > Dirk Sebastian -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: choice =y selection becomes lost after having multiple entries =m with depends on
Sebastian Andrzej Siewior writes: > On 10/24/2013 05:30 PM, Dirk Gouders wrote: >> Hi Sebastian, > > Hi Dirk, > >> I was looking at what you described and initially had a hard time to >> reproduce the problem, probably because I tried it after `make >> mrproper'. I am only able to reproduce the problem with an existing >> .config of my running kernel, for example. >> >> Just to make sure that I am correctly trying to reproduce the problem: >> did you already try to do what you described after a `make mrproper' and >> do you then also notice the described problems? If not, could you >> please try that? > > What is the purpose behind mrproper? > The key to reproduce it is to have a .config with atleast two items > within a choice statement which also have a "depends on" statement and > those set to =m. If you don't have this after mrproper (with your fresh > .config) then you don't see it. Hi Sebastian, what I meant was that you start all steps that you previously described with one initial mrproper, i.e.: 1) make mrproper 2) make menuconfig and select the gadgets with 'm', then save and exit 3) make menuconfig and select 'y' for "USB Gadget Drivers", then save and exit. 4) Check for problems either with menuconfig or directly in .config With that initial mrproper I was not able to reproduce the problem and therefore I suspect some content of an existing .config causing the problems. Dirk PS: Probably `make mrproper' can be replaced by `rm .config' but I tested it only once and cannot say for sure.) >> >> Thanks, >> >> Dirk > > Sebastian -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Controller's wakeup setting at usb_add_hcd
On Thu, 24 Oct 2013, Peter Chen wrote: > It is the same which the embedded world does, that is the physical wakeup > setting is controlled by software flag. Since it is the controller's wakeup, > why the controller driver does not go to control the software flag in general? > > The current problem for me is: usb_add_hcd initializes the controller's flag > to 1, the controller driver needs to override it as 0. It will delete the > hcd on the fly (call usb_remove_hcd) for otg controller due to plug in Micro > B-to-A > cable (ID 0->1), and later, the user may plug out this cable (ID 1->0), the > hcd will be added again, at this time, the wakeup flag is set by hcd again. > If I want to keep the wakeup flag as 0 by default, I need to clear it again. Yes. > Just like you said: > > The physical wakeup setting is controlled by both the controller driver > > and the platform driver. > But currently, it is controlled (or affected) by hcd layer. It is _initialized_ by the HCD layer. The platform driver can always override this. It's easy; just call device_set_wakeup_enable(dev, 0) after usb_add_hcd(). In fact, your platform driver probably should remember the current wakeup setting when the HC is removed. The next time it is added you should change the wakeup setting to the remembered value. That way, if the user adjusts the setting and switches between host and device mode, the desired setting will persist. Alan Stern -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 0/7] uas: Final set of uas fixes
Hi All, This is / should be my final set of uas fixes. After this set my uas to-do list is empty and uas should be in good shape to go into 3.14 . Regards, Hans -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/7] uas: Move uas detect code to uas-detect.h
This is a preparation patch for teaching usb-storage to not bind to uas devices. Signed-off-by: Hans de Goede --- drivers/usb/storage/uas-detect.h | 40 drivers/usb/storage/uas.c| 40 ++-- 2 files changed, 42 insertions(+), 38 deletions(-) create mode 100644 drivers/usb/storage/uas-detect.h diff --git a/drivers/usb/storage/uas-detect.h b/drivers/usb/storage/uas-detect.h new file mode 100644 index 000..28101c7 --- /dev/null +++ b/drivers/usb/storage/uas-detect.h @@ -0,0 +1,40 @@ +#include +#include + +static int uas_is_interface(struct usb_host_interface *intf) +{ + return (intf->desc.bInterfaceClass == USB_CLASS_MASS_STORAGE && + intf->desc.bInterfaceSubClass == USB_SC_SCSI && + intf->desc.bInterfaceProtocol == USB_PR_UAS); +} + +static int uas_isnt_supported(struct usb_device *udev) +{ + struct usb_hcd *hcd = bus_to_hcd(udev->bus); + + dev_warn(&udev->dev, "The driver for the USB controller %s does not " + "support scatter-gather which is\n", + hcd->driver->description); + dev_warn(&udev->dev, "required by the UAS driver. Please try an" + "alternative USB controller if you wish to use UAS.\n"); + return -ENODEV; +} + +static int uas_find_uas_alt_setting(struct usb_interface *intf) +{ + int i; + struct usb_device *udev = interface_to_usbdev(intf); + int sg_supported = udev->bus->sg_tablesize != 0; + + for (i = 0; i < intf->num_altsetting; i++) { + struct usb_host_interface *alt = &intf->altsetting[i]; + + if (uas_is_interface(alt)) { + if (!sg_supported) + return uas_isnt_supported(udev); + return alt->desc.bAlternateSetting; + } + } + + return -ENODEV; +} diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index b0a96c2..9969632 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -25,6 +25,8 @@ #include #include +#include "uas-detect.h" + /* * The r00-r01c specs define this version of the SENSE IU data structure. * It's still in use by several different firmware releases. @@ -873,44 +875,6 @@ static struct usb_device_id uas_usb_ids[] = { }; MODULE_DEVICE_TABLE(usb, uas_usb_ids); -static int uas_is_interface(struct usb_host_interface *intf) -{ - return (intf->desc.bInterfaceClass == USB_CLASS_MASS_STORAGE && - intf->desc.bInterfaceSubClass == USB_SC_SCSI && - intf->desc.bInterfaceProtocol == USB_PR_UAS); -} - -static int uas_isnt_supported(struct usb_device *udev) -{ - struct usb_hcd *hcd = bus_to_hcd(udev->bus); - - dev_warn(&udev->dev, "The driver for the USB controller %s does not " - "support scatter-gather which is\n", - hcd->driver->description); - dev_warn(&udev->dev, "required by the UAS driver. Please try an" - "alternative USB controller if you wish to use UAS.\n"); - return -ENODEV; -} - -static int uas_find_uas_alt_setting(struct usb_interface *intf) -{ - int i; - struct usb_device *udev = interface_to_usbdev(intf); - int sg_supported = udev->bus->sg_tablesize != 0; - - for (i = 0; i < intf->num_altsetting; i++) { - struct usb_host_interface *alt = &intf->altsetting[i]; - - if (uas_is_interface(alt)) { - if (!sg_supported) - return uas_isnt_supported(udev); - return alt->desc.bAlternateSetting; - } - } - - return -ENODEV; -} - static int uas_switch_interface(struct usb_device *udev, struct usb_interface *intf) { -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 7/7] uas: Use all available stream ids
If we get ie 16 streams we can use stream-id 1-16, not 1-15. Signed-off-by: Hans de Goede --- drivers/usb/storage/uas.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index c543bdb..d6a575b 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -726,7 +726,7 @@ static int uas_eh_task_mgmt(struct scsi_cmnd *cmnd, { struct Scsi_Host *shost = cmnd->device->host; struct uas_dev_info *devinfo = (void *)shost->hostdata[0]; - u16 tag = devinfo->qdepth - 1; + u16 tag = devinfo->qdepth; unsigned long flags; int r; @@ -850,7 +850,7 @@ static int uas_slave_configure(struct scsi_device *sdev) { struct uas_dev_info *devinfo = sdev->hostdata; scsi_set_tag_type(sdev, MSG_ORDERED_TAG); - scsi_activate_tcq(sdev, devinfo->qdepth - 3); + scsi_activate_tcq(sdev, devinfo->qdepth - 2); return 0; } @@ -1007,7 +1007,7 @@ static int uas_probe(struct usb_interface *intf, const struct usb_device_id *id) INIT_LIST_HEAD(&devinfo->dead_list); uas_configure_endpoints(devinfo); - result = scsi_init_shared_tag_map(shost, devinfo->qdepth - 3); + result = scsi_init_shared_tag_map(shost, devinfo->qdepth - 2); if (result) goto free_streams; -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/7] usb-storage: Don't bind to uas devices if the uas driver is enabled
uas devices have 2 alternative settings on their usb-storage interface, one for usb-storage and one for uas. Using the uas driver is preferred, so if the uas driver is enabled, and the device has an uas alt setting, don't bind. Signed-off-by: Hans de Goede --- drivers/usb/storage/usb.c | 10 ++ 1 file changed, 10 insertions(+) diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index 5c4fe07..d16c3de 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c @@ -73,6 +73,10 @@ #include "sierra_ms.h" #include "option_ms.h" +#if IS_ENABLED(CONFIG_USB_UAS) +#include "uas-detect.h" +#endif + /* Some informational data */ MODULE_AUTHOR("Matthew Dharm "); MODULE_DESCRIPTION("USB Mass Storage driver for Linux"); @@ -1036,6 +1040,12 @@ static int storage_probe(struct usb_interface *intf, int result; int size; + /* If uas is enabled and this device can do uas then ignore it. */ +#if IS_ENABLED(CONFIG_USB_UAS) + if (uas_find_uas_alt_setting(intf) >= 0) + return -ENXIO; +#endif + /* * If the device isn't standard (is handled by a subdriver * module) then don't accept it. -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/7] uas: Add a uas_find_uas_alt_setting helper function
This is a preparation patch for teaching usb-storage to not bind to uas devices. Signed-off-by: Hans de Goede --- drivers/usb/storage/uas.c | 21 - 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index 357f14d..b0a96c2 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -892,10 +892,10 @@ static int uas_isnt_supported(struct usb_device *udev) return -ENODEV; } -static int uas_switch_interface(struct usb_device *udev, - struct usb_interface *intf) +static int uas_find_uas_alt_setting(struct usb_interface *intf) { int i; + struct usb_device *udev = interface_to_usbdev(intf); int sg_supported = udev->bus->sg_tablesize != 0; for (i = 0; i < intf->num_altsetting; i++) { @@ -904,15 +904,26 @@ static int uas_switch_interface(struct usb_device *udev, if (uas_is_interface(alt)) { if (!sg_supported) return uas_isnt_supported(udev); - return usb_set_interface(udev, - alt->desc.bInterfaceNumber, - alt->desc.bAlternateSetting); + return alt->desc.bAlternateSetting; } } return -ENODEV; } +static int uas_switch_interface(struct usb_device *udev, + struct usb_interface *intf) +{ + int alt; + + alt = uas_find_uas_alt_setting(intf); + if (alt < 0) + return alt; + + return usb_set_interface(udev, + intf->altsetting[0].desc.bInterfaceNumber, alt); +} + static void uas_configure_endpoints(struct uas_dev_info *devinfo) { struct usb_host_endpoint *eps[4] = { }; -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 4/7] uas: Pack iu struct definitions
The iu struct definitions are usb packet definitions, so no alignment should happen. Notice for most of the structs this does not make a difference (assuming 32 bit alignment). The only case this actually makes a difference for is the response_ui struct, which keeps all its members at the same place, but its size is changed from 8 bytes to 7 bytes. Signed-off-by: Hans de Goede --- include/linux/usb/uas.h | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/include/linux/usb/uas.h b/include/linux/usb/uas.h index 5499ab5..90a0b7b 100644 --- a/include/linux/usb/uas.h +++ b/include/linux/usb/uas.h @@ -9,7 +9,7 @@ struct iu { __u8 iu_id; __u8 rsvd1; __be16 tag; -}; +} __attribute__((__packed__)); enum { IU_ID_COMMAND = 0x01, @@ -52,7 +52,7 @@ struct command_iu { __u8 rsvd7; struct scsi_lun lun; __u8 cdb[16]; /* XXX: Overflow-checking tools may misunderstand */ -}; +} __attribute__((__packed__)); struct task_mgmt_iu { __u8 iu_id; @@ -62,7 +62,7 @@ struct task_mgmt_iu { __u8 rsvd2; __be16 task_tag; struct scsi_lun lun; -}; +} __attribute__((__packed__)); /* * Also used for the Read Ready and Write Ready IUs since they have the @@ -77,7 +77,7 @@ struct sense_iu { __u8 rsvd7[7]; __be16 len; __u8 sense[SCSI_SENSE_BUFFERSIZE]; -}; +} __attribute__((__packed__)); struct response_ui { __u8 iu_id; @@ -85,7 +85,7 @@ struct response_ui { __be16 tag; __be16 add_response_info; __u8 response_code; -}; +} __attribute__((__packed__)); struct usb_pipe_usage_descriptor { __u8 bLength; -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 5/7] uas: s/response_ui/response_iu/
Signed-off-by: Hans de Goede --- drivers/usb/storage/uas.c | 2 +- include/linux/usb/uas.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index 9969632..c618c01 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -48,7 +48,7 @@ struct uas_dev_info { struct usb_anchor sense_urbs; struct usb_anchor data_urbs; int qdepth, resetting; - struct response_ui response; + struct response_iu response; unsigned cmd_pipe, status_pipe, data_in_pipe, data_out_pipe; unsigned use_streams:1; unsigned uas_sense_old:1; diff --git a/include/linux/usb/uas.h b/include/linux/usb/uas.h index 90a0b7b..34b803d 100644 --- a/include/linux/usb/uas.h +++ b/include/linux/usb/uas.h @@ -79,7 +79,7 @@ struct sense_iu { __u8 sense[SCSI_SENSE_BUFFERSIZE]; } __attribute__((__packed__)); -struct response_ui { +struct response_iu { __u8 iu_id; __u8 rsvd1; __be16 tag; -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 6/7] uas: Use proper packet size when submitting reponse urbs
Signed-off-by: Hans de Goede --- drivers/usb/storage/uas.c | 19 --- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index c618c01..c543bdb 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -431,7 +431,8 @@ static struct urb *uas_alloc_data_urb(struct uas_dev_info *devinfo, gfp_t gfp, return urb; } -static struct urb *uas_alloc_sense_urb(struct uas_dev_info *devinfo, gfp_t gfp, +static struct urb *uas_alloc_sense_urb(struct uas_dev_info *devinfo, + int size, gfp_t gfp, struct Scsi_Host *shost, u16 stream_id) { struct usb_device *udev = devinfo->udev; @@ -441,11 +442,11 @@ static struct urb *uas_alloc_sense_urb(struct uas_dev_info *devinfo, gfp_t gfp, if (!urb) goto out; - iu = kzalloc(sizeof(*iu), gfp); + iu = kzalloc(size, gfp); if (!iu) goto free; - usb_fill_bulk_urb(urb, udev, devinfo->status_pipe, iu, sizeof(*iu), + usb_fill_bulk_urb(urb, udev, devinfo->status_pipe, iu, size, uas_stat_cmplt, shost); urb->stream_id = stream_id; urb->transfer_flags |= URB_FREE_BUFFER; @@ -550,13 +551,13 @@ err: * daft to me. */ -static int uas_submit_sense_urb(struct Scsi_Host *shost, +static int uas_submit_sense_urb(struct Scsi_Host *shost, int size, gfp_t gfp, unsigned int stream) { struct uas_dev_info *devinfo = (void *)shost->hostdata[0]; struct urb *urb; - urb = uas_alloc_sense_urb(devinfo, gfp, shost, stream); + urb = uas_alloc_sense_urb(devinfo, size, gfp, shost, stream); if (!urb) return SCSI_MLQUEUE_DEVICE_BUSY; usb_anchor_urb(urb, &devinfo->sense_urbs); @@ -578,7 +579,8 @@ static int uas_submit_urbs(struct scsi_cmnd *cmnd, WARN_ON_ONCE(!spin_is_locked(&devinfo->lock)); if (cmdinfo->state & SUBMIT_STATUS_URB) { - err = uas_submit_sense_urb(cmnd->device->host, gfp, + err = uas_submit_sense_urb(cmnd->device->host, + sizeof(struct sense_iu), gfp, cmdinfo->stream); if (err) { return err; @@ -726,10 +728,13 @@ static int uas_eh_task_mgmt(struct scsi_cmnd *cmnd, struct uas_dev_info *devinfo = (void *)shost->hostdata[0]; u16 tag = devinfo->qdepth - 1; unsigned long flags; + int r; spin_lock_irqsave(&devinfo->lock, flags); memset(&devinfo->response, 0, sizeof(devinfo->response)); - if (uas_submit_sense_urb(shost, GFP_ATOMIC, tag)) { + r = uas_submit_sense_urb(shost, sizeof(struct response_iu), +GFP_ATOMIC, tag); + if (r != 0) { shost_printk(KERN_INFO, shost, "%s: %s: submit sense urb failed\n", __func__, fname); -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/7] uas: Add a uas_find_uas_alt_setting helper function
Hi, I forgot one important note. This is currently only tested with qemu's emulated uas device. I'll test it with real hardware when I get back home this weekend. Regards, Hans On 10/24/2013 06:13 PM, Hans de Goede wrote: This is a preparation patch for teaching usb-storage to not bind to uas devices. Signed-off-by: Hans de Goede --- drivers/usb/storage/uas.c | 21 - 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index 357f14d..b0a96c2 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -892,10 +892,10 @@ static int uas_isnt_supported(struct usb_device *udev) return -ENODEV; } -static int uas_switch_interface(struct usb_device *udev, - struct usb_interface *intf) +static int uas_find_uas_alt_setting(struct usb_interface *intf) { int i; + struct usb_device *udev = interface_to_usbdev(intf); int sg_supported = udev->bus->sg_tablesize != 0; for (i = 0; i < intf->num_altsetting; i++) { @@ -904,15 +904,26 @@ static int uas_switch_interface(struct usb_device *udev, if (uas_is_interface(alt)) { if (!sg_supported) return uas_isnt_supported(udev); - return usb_set_interface(udev, - alt->desc.bInterfaceNumber, - alt->desc.bAlternateSetting); + return alt->desc.bAlternateSetting; } } return -ENODEV; } +static int uas_switch_interface(struct usb_device *udev, + struct usb_interface *intf) +{ + int alt; + + alt = uas_find_uas_alt_setting(intf); + if (alt < 0) + return alt; + + return usb_set_interface(udev, + intf->altsetting[0].desc.bInterfaceNumber, alt); +} + static void uas_configure_endpoints(struct uas_dev_info *devinfo) { struct usb_host_endpoint *eps[4] = { }; -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH 00/15] rework port power control
On Thu, 24 Oct 2013, Dan Williams wrote: > Summary: > Address the following issues for port power control: > 1/ Port power policy needs 'connector' awareness. > 2/ Reliable port power control requires coordination with khubd. > 3/ Userspace needs full control, but also help coordinating port >power policy. > > Even with these changes port power control still defaults to disabled > (ports are always on). This is 3.14 material. I find these descriptions rather unclear... > Details: > 1/ Port power policy needs 'connector' awareness. > >It is a recipe for unintended device disconnects to turn off a >port while leaving its peer active. "It is a recipe" -- what is "it"? Do you mean that under the current implementation, an unintended device disconnect turns off a port while leaving the port's peer turned on? Or do you mean that this series of patches creates a mechanism for doing this? Which disconnects count as "unintended"? What is a port's "peer"? > The attached device, provided >it is not a hub may, switch from the USB3 connection to USB2. Are you still talking about unintended disconnects? If you are, how can there be an attached device if it has just disconnected? Or are you referring to a device attached to the port's peer (whatever that is)? Note that most USB-3 devices are not allowed to connect to the both USB-3 and USB-2 buses at the same time. Hubs are exceptions; they are required to do so (and consequently each USB-3 hub appears to the system as two separate and unrelated hubs; one that is USB-3 and one that is USB-2). >Introduce a 'connector' object to track ports from different hcds >(for example the two hcds provided by XHCI). Exactly what ports will these "connectors" track? The USB-2 and USB-3 logical ports that share the same physical port on a USB-3 hub? > A 'connector' is >distinct from 'companion' ports which share the same data lines >across multiple hcds. Why treat "companion" ports differently? > Port-connector membership data comes from >platorm firmware. What about port-connector membership data for ports on external hubs? They aren't described by platform firmware. > 2/ Reliable port power control requires coordination with khubd. > >The existing implementation makes attempts to mitigate the damage of >khubd running in the middle of a port power control event, but >makes no guarantees. Sure it does. What damage are you talking about? > We need to support both suspending hubs with >live ports (to receive wakeup events) and fully powering down the >port when userspace policy allows. Don't we support this already? > 3/ Userspace needs full control, but also help coordinating port >power policy. > >Augment the existing controls portX/power/pm_qos_no_power_off and >portX/power/control with connector awareness (i.e. propagate control >settings across ports in a connector), but also add policies based >on the connector type ('hotplug' ports never power down as compared >to 'hardwired'). Isn't this already implemented, at least in part? I thought we treated hotpluggable ports differently from hardwired ports. > Even with these changes port power control still defaults to on. > > When enabled (pm_qos_no_power_off=0) it tries to do the right thing > for connectors and hotplug capable ports. At all times userspace > can override what acpi has defined (pm_qos_no_notify_flags to stop > propagating settings to 'peers', connect_type to override whether > the port is hotplug capable, or usbcore.noacpi to turn it all off). It might help to put somewhere a complete description of all the mechanisms involved in port power control, and how they interact, together with a description of which items (and attribute files) can be changed by userspace. Alan Stern -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 3/7] usb-storage: Don't bind to uas devices if the uas driver is enabled
On Thu, 24 Oct 2013, Hans de Goede wrote: > uas devices have 2 alternative settings on their usb-storage interface, > one for usb-storage and one for uas. Using the uas driver is preferred, so if > the uas driver is enabled, and the device has an uas alt setting, don't bind. We need a mechanism for the user to force a device into usb-storage mode, even if the device claims to support UAS. It would not be at all surprising to find some devices whose UAS support is broken. Alan Stern -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Account Upgrade
Dear Email User, Your mailbox has exceeded the storage limit which is 20.00 GB as set by your administrator, you are currently running on 19.99 GB, you may not be able to send or receive new mail until you re-validate your email box. Kindly click the link below to re-validate your email account, If the page does not appear on your browser, you can copy and paste the link into your browser and fill in your account details, Click on "VERIFY" for account update. http://tiny.cc/wjqe5w Thanks! WebMail Administrator! Case Number: 894162/2013 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH 00/15] rework port power control
Hi Alan, thanks for taking a look. On Thu, Oct 24, 2013 at 10:25 AM, Alan Stern wrote: > On Thu, 24 Oct 2013, Dan Williams wrote: > >> Summary: >> Address the following issues for port power control: >> 1/ Port power policy needs 'connector' awareness. >> 2/ Reliable port power control requires coordination with khubd. >> 3/ Userspace needs full control, but also help coordinating port >>power policy. >> >> Even with these changes port power control still defaults to disabled >> (ports are always on). This is 3.14 material. > > I find these descriptions rather unclear... No problem. I have been steeping in this rework for a bit, so it's good to step back and clarify the approach. > >> Details: >> 1/ Port power policy needs 'connector' awareness. >> >>It is a recipe for unintended device disconnects to turn off a >>port while leaving its peer active. > > "It is a recipe" -- what is "it"? Do you mean that under the current > implementation, an unintended device disconnect turns off a port while > leaving the port's peer turned on? Or do you mean that this series of > patches creates a mechanism for doing this? The current implementation is unaware of cases where it is turning off a USB3 port that has a related USB2 port. These patches create mechanisms to turn off both ports in concert. > Which disconnects count as "unintended"? A device connecting to the USB2 port when power is lost on the USB3 port. > What is a port's "peer"? See patch 2 [1]. For example ACPI enumerates when a USB2 port is peered (colocated in the same physical plug) with a USB3 for the XHCI controller. >> The attached device, provided >>it is not a hub may, switch from the USB3 connection to USB2. > > Are you still talking about unintended disconnects? If you are, how > can there be an attached device if it has just disconnected? Or are > you referring to a device attached to the port's peer (whatever that > is)? Yes, the naming is confusing. I'm defining a 'connector' as a physical plug with one or more port members. Sarah and I went back and forth on a good name for these items. At least the XHCI spec calls the relationship 'connectors' in Appendix D. > Note that most USB-3 devices are not allowed to connect to the both > USB-3 and USB-2 buses at the same time. Hubs are exceptions; they are > required to do so (and consequently each USB-3 hub appears to the > system as two separate and unrelated hubs; one that is USB-3 and one > that is USB-2). I special case hubs in the code as devices that are allowed to be connected to both ports in a connector simultaneously. There will be no peer power management in that case. Are there other devices that are expected to dual connect? >>Introduce a 'connector' object to track ports from different hcds >>(for example the two hcds provided by XHCI). > > Exactly what ports will these "connectors" track? The USB-2 and USB-3 > logical ports that share the same physical port on a USB-3 hub? Hmm, only the ones defined by ACPI... That's a fairly large hole not covered in these patches. Of course 'connectors' need to be created for downstream USB-3 hub ports. >> A 'connector' is >>distinct from 'companion' ports which share the same data lines >>across multiple hcds. > > Why treat "companion" ports differently? > Companion-ports share 1 physical connection among controllers, 'connectors' co-locate multiple physical connections in one plug. >> Port-connector membership data comes from >>platorm firmware. > > What about port-connector membership data for ports on external hubs? > They aren't described by platform firmware. > Yup, exactly the facepalm realization I made a comment or two back. That's incremental to this set, will add. >> 2/ Reliable port power control requires coordination with khubd. >> >>The existing implementation makes attempts to mitigate the damage of >>khubd running in the middle of a port power control event, but >>makes no guarantees. > > Sure it does. What damage are you talking about? Unless I missed it I did not see what prevents the port from being powered down mid khubd run? We have the busy_bits check but what does that synchronize against? We also used to have this usb_port_runtime_resume: static int usb_port_runtime_resume(struct device *dev) {... usb_autopm_get_interface(intf); ...} Which arranges for hub_activate() to run on a known powered down port. We would subsequently notice the connection gone and disconnect the device. I could reliably reproduce this after just a few power toggles... fixed now. khubd now ignores powered down ports and we no longer have confusing code like this in hub_power_on(): static unsigned hub_power_on(struct usb_hub *hub, bool do_delay) {... for (port1 = 1; port1 <= hub->hdev->maxchild; port1++) usb_hub_set_port_power(hub->hdev, hub, port1, hub->ports[port1 - 1]->power_is_on); ...
Account Upgrade
Dear Email User, Your mailbox has exceeded the storage limit which is 20.00 GB as set by your administrator, you are currently running on 19.99 GB, you may not be able to send or receive new mail until you re-validate your email box. Kindly click the link below to re-validate your email account, If the page does not appear on your browser, you can copy and paste the link into your browser and fill in your account details, Click on "VERIFY" for account update. http://tiny.cc/wjqe5w Thanks! WebMail Administrator! Case Number: 894162/2013 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: usb mass storage bug
On Thu, 24 Oct 2013, Jánosi Zoli wrote: > I can confirm, that its working without usb otg config. it was the problem > since kernel version 3.10. Then you can close out the Bugzilla entry. Alan Stern > Date: Thu, 24 Oct 2013 12:09:03 -0400 > From: st...@rowland.harvard.edu > To: janosiz...@hotmail.com; ba...@ti.com > CC: linux-usb@vger.kernel.org > Subject: Re: usb mass storage bug > > On Thu, 24 Oct 2013, [iso-8859-2] J�nosi Zoli wrote: > >> https://bugzilla.kernel.org/show_bug.cgi?id=63611 >> � >> Bug ID: 63611 >> Summary: cant connect sony phones in mass storage mode > > Is CONFIG_USB_OTG turned on in your kernel's .config? If it is, try > building a new kernel with it turned off. -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH 04/15] PM / Runtime: Allow drivers to intercept pm qos flag changes
On Thursday, October 24, 2013 12:42:36 AM Dan Williams wrote: > [ adding Rafael ] First, this is not the right address to Cc (please check MAINTAINERS in 3.12-rc6), but it still kind of works yet. Second, quite frankly, I don't like this change. > On Thu, Oct 24, 2013 at 12:35 AM, Dan Williams > wrote: > > ...because struct dev_pm_ops is too clean and uniform. > > > > USB port power management needs to manage ports that are colocated in a > > given connector. If we power down a connector we need to arrange for > > the peer port in the connector to also be suspended. If the peer > > connector stays active it may cause the device to disconnect on the initial > > (suspended) port and reconnect on the other. > > > > Notification of when userspace disables pm_qos_no_power_off allows the > > driver to arrange for the peer port to be suspended before the primary > > port suspends. > > > > Alternatives considered: > > 1/ force power down the peer port: denies userspace control over power > >policy > > > > 2/ try to synchronize port power management within the USB core: > >proved difficult to find a non-racy way to synchronize peer > >connections against power management changes. > > > > 3/ create infrastructure to expose the concept of peer devices in the > >pm_runtime system... maybe defer until other use cases outside of USB pop > >up. For now, punting the notification to the driver is sufficient. > > > > As stated this notification allows the kernel to keep power-policy > > consistent across a connector. If userspace wants to regain per-port > > control (at the risk of unexpected disconnects) it can set the > > pm_qos_no_notify flag to prevent ports from coordinating as a connector. > > pm_qos_no_notify blocks flags synchronization, restoring the traditional > > behavior of one pm_qos_no_power_off manipulation only affecting one > > device. > > > > Cc: Rafael J. Wysocki > > Cc: Greg Kroah-Hartman > > Cc: Alan Stern > > Cc: Sarah Sharp > > Signed-off-by: Dan Williams > > --- > > Documentation/ABI/testing/sysfs-devices-power | 21 +++ > > Documentation/power/pm_qos_interface.txt | 15 > > drivers/base/power/qos.c | 48 > > ++--- > > drivers/base/power/sysfs.c| 45 > > --- > > drivers/usb/core/port.c |7 > > drivers/usb/core/usb-platform.c | 38 > > drivers/usb/core/usb-platform.h |1 + > > include/linux/pm.h|5 +++ > > include/linux/pm_qos.h|5 +++ > > 9 files changed, 159 insertions(+), 26 deletions(-) > > > > diff --git a/Documentation/ABI/testing/sysfs-devices-power > > b/Documentation/ABI/testing/sysfs-devices-power > > index efe449bdf811..36d1603ab3bb 100644 > > --- a/Documentation/ABI/testing/sysfs-devices-power > > +++ b/Documentation/ABI/testing/sysfs-devices-power > > @@ -235,3 +235,24 @@ Description: > > > > This attribute has no effect on system-wide suspend/resume > > and > > hibernation. > > + > > +What: /sys/devices/.../power/pm_qos_no_notify_flags > > +Date: October 2013 > > +Contact: Dan Williams > > +Description: > > + The /sys/devices/.../power/pm_qos_no_notify_flags attribute > > is > > + used for determining whether the kernel is permitted to > > forward > > + changes to the the PM QoS flags (no_power_off, > > remote_wakeup) to > > + other devices it deems to be related in the system. When > > this > > + flag is set userspace is indicating that it wants exclusive > > + control This is aganist the way the PM QoS flags were designed. There is no exclusive control over them and user space cannot expect specific behavior when one of them is unset in sysfs. Specifically, "no power off" unset doesn't mean "power off is required". It merely means "I have no objections against powering off if that's what you decide to do". > > of the flags and takes responsibility for situations > > + where a driver would want the power control setting unified > > + amongst a set of devices. In the case of USB a > > relationship is > > + indicating by a "peer:-port" link in the > > + /port directory. I'm not sure what you're trying to achieve with this, but almost certainly this isn't the right way to go. Admittedly, I'm a bit tired now, so it's better if I have a fresh look at this tomorrow. > > + Not all drivers support this attribute. If it isn't > > supported, > > + it is not present. > > + > > + This attribute has no effect on system-wide suspend/resume > > and > > + hibernation. Thanks! -- I speak only for myself. Rafael J. Wysocki, Intel Open Source Te
Re: [PATCH 3/7] usb-storage: Don't bind to uas devices if the uas driver is enabled
Hi, On 10/24/2013 06:32 PM, Alan Stern wrote: On Thu, 24 Oct 2013, Hans de Goede wrote: uas devices have 2 alternative settings on their usb-storage interface, one for usb-storage and one for uas. Using the uas driver is preferred, so if the uas driver is enabled, and the device has an uas alt setting, don't bind. We need a mechanism for the user to force a device into usb-storage mode, even if the device claims to support UAS. It would not be at all surprising to find some devices whose UAS support is broken. Agreed, this is one of the reasons why I want to share the uas-detect code between the uas and usb-storage drivers, so that we can have a single place for a blacklist. So I think the best way to provide such a user override would be a kernel module option. But that needs to belong to a single module, so I see 2 options; 1) Turn uas-detect into a separate module 2) Use the existing unusual_dev stuff for this and make uas depend on usb-storage to get the unusual_dev (included user added extra quirks) from usb-storage 2. Makes the most sense to me, since usb-storage will get loaded anyways when uas is loaded as they both match on the same usb class. If you agree that 2. is probably best then I can do an addon patch adding support for a NO_UAS quirk which will cause the uas-detect code to bail with an error if present. Regards, Hans -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH 04/15] PM / Runtime: Allow drivers to intercept pm qos flag changes
Hi Rafael, sorry about the email mix up. On Thu, Oct 24, 2013 at 4:08 PM, Rafael J. Wysocki wrote: >> > + >> > +What: /sys/devices/.../power/pm_qos_no_notify_flags >> > +Date: October 2013 >> > +Contact: Dan Williams >> > +Description: >> > + The /sys/devices/.../power/pm_qos_no_notify_flags >> > attribute is >> > + used for determining whether the kernel is permitted to >> > forward >> > + changes to the the PM QoS flags (no_power_off, >> > remote_wakeup) to >> > + other devices it deems to be related in the system. When >> > this >> > + flag is set userspace is indicating that it wants exclusive >> > + control > > This is aganist the way the PM QoS flags were designed. There is no exclusive > control over them and user space cannot expect specific behavior when one of > them is unset in sysfs. Specifically, "no power off" unset doesn't mean > "power > off is required". It merely means "I have no objections against powering off > if that's what you decide to do". 'Exclusive control' was the wrong choice of terms. This admittedly ugly pm_qos_no_notify_flags flag would disable propagating the pm_qos_no_power_off setting to another device. The problem I am trying to solve is that deviceA can only safely be powered off depending on the state of deviceB. The kernel knows this relationship and in most cases when userspace says "I don't have any objections to powering off deviceA it almost certainly means I have no objections to you coordinating poweroff of deviceA + deviceB". I could skip this flag and keep this knowledge internal. I.e. userspace would just need to know that clearing pm_qos_no_power_off on deviceA will not enable power off until the same setting is performed on deviceB. I do place a link from deviceA to deviceB in sysfs. Although ordering becomes trickier without notification... Alternatively I could just power manage deviceB behind userspace's back when taking action on deviceA, but I think that is even more of a hack and takes away configuration ability from userspace. -- Dan -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [RFC PATCH 15/15] checkpatch: allow list_for_each helper macros
> From: Dan Williams > Sent: Thursday, October 24, 2013 12:45 AM > > On Thu, Oct 24, 2013 at 12:36 AM, Dan Williams > wrote: > > Permit list_for_each redifinitions like: > > > > #define for_each_connector_peer(peer, port, c) \ > >list_for_each_entry(peer, &(c)->ports, node) \ > >if (port != peer) > > > > ...which triggers: > > ERROR: Macros with complex values should be enclosed in parenthesis Kind of off-topic, but that macro looks a little dangerous. From what I have seen in the kernel, it's usually done something like this: #define for_each_connector_peer(peer, port, c) \ list_for_each_entry(peer, &(c)->ports, node) \ if (port == peer) {} else -- Paul -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH 15/15] checkpatch: allow list_for_each helper macros
On Fri, 2013-10-25 at 03:52 +, Paul Zimmerman wrote: > > From: Dan Williams > > Sent: Thursday, October 24, 2013 12:45 AM > > > > On Thu, Oct 24, 2013 at 12:36 AM, Dan Williams > > wrote: > > > Permit list_for_each redifinitions like: > > > > > > #define for_each_connector_peer(peer, port, c) \ > > >list_for_each_entry(peer, &(c)->ports, node) \ > > >if (port != peer) > > > > > > ...which triggers: > > > ERROR: Macros with complex values should be enclosed in parenthesis > > Kind of off-topic, but that macro looks a little dangerous. From what I have > seen in the kernel, it's usually done something like this: > > #define for_each_connector_peer(peer, port, c) \ > list_for_each_entry(peer, &(c)->ports, node) \ > if (port == peer) {} else That seems pretty non-standard. Look at include/linux/list.h or $ git grep -E "\{\s*\}\s*else" Is there any effective difference? -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [RFC PATCH 15/15] checkpatch: allow list_for_each helper macros
> From: Joe Perches [mailto:j...@perches.com] > Sent: Thursday, October 24, 2013 9:34 PM > > On Fri, 2013-10-25 at 03:52 +, Paul Zimmerman wrote: > > > From: Dan Williams > > > Sent: Thursday, October 24, 2013 12:45 AM > > > > > > On Thu, Oct 24, 2013 at 12:36 AM, Dan Williams > > > wrote: > > > > Permit list_for_each redifinitions like: > > > > > > > > #define for_each_connector_peer(peer, port, c) \ > > > >list_for_each_entry(peer, &(c)->ports, node) \ > > > >if (port != peer) > > > > > > > > ...which triggers: > > > > ERROR: Macros with complex values should be enclosed in parenthesis > > > > Kind of off-topic, but that macro looks a little dangerous. From what I have > > seen in the kernel, it's usually done something like this: > > > > #define for_each_connector_peer(peer, port, c) \ > > list_for_each_entry(peer, &(c)->ports, node) \ > > if (port == peer) {} else > > That seems pretty non-standard. > Look at include/linux/list.h or > $ git grep -E "\{\s*\}\s*else" > > Is there any effective difference? I fail to see your point. There are no similar constructs in list.h that I can see, and the output from git grep agrees with what I wrote. The difference is that with Dan's macro, this: if (foo) for_each_connector_peer(peer, port, c) bar(); else ... Will not interpreted by the compiler as the programmer intended. -- Paul -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH 15/15] checkpatch: allow list_for_each helper macros
On Thu, Oct 24, 2013 at 9:48 PM, Paul Zimmerman wrote: >> From: Joe Perches [mailto:j...@perches.com] >> Sent: Thursday, October 24, 2013 9:34 PM >> >> On Fri, 2013-10-25 at 03:52 +, Paul Zimmerman wrote: >> > > From: Dan Williams >> > > Sent: Thursday, October 24, 2013 12:45 AM >> > > >> > > On Thu, Oct 24, 2013 at 12:36 AM, Dan Williams >> > > wrote: >> > > > Permit list_for_each redifinitions like: >> > > > >> > > > #define for_each_connector_peer(peer, port, c) \ >> > > >list_for_each_entry(peer, &(c)->ports, node) \ >> > > >if (port != peer) >> > > > >> > > > ...which triggers: >> > > > ERROR: Macros with complex values should be enclosed in parenthesis >> > >> > Kind of off-topic, but that macro looks a little dangerous. From what I >> > have >> > seen in the kernel, it's usually done something like this: >> > >> > #define for_each_connector_peer(peer, port, c) \ >> > list_for_each_entry(peer, &(c)->ports, node) \ >> > if (port == peer) {} else >> >> That seems pretty non-standard. >> Look at include/linux/list.h or >> $ git grep -E "\{\s*\}\s*else" >> >> Is there any effective difference? > > I fail to see your point. There are no similar constructs in list.h that I > can see, and the output from git grep agrees with what I wrote. > > The difference is that with Dan's macro, this: > > if (foo) > for_each_connector_peer(peer, port, c) > bar(); > else > ... > > Will not interpreted by the compiler as the programmer intended. Ah yes, that would be nasty. Thanks. -- Dan -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 5/5] ARM: dts: imx28: changing usb compatible string as only "fsl,imx28-usb"
Due to imx28 usb has special write request, it is not compatible with other imx27 sytle usb controllers. Signed-off-by: Peter Chen --- arch/arm/boot/dts/imx28.dtsi |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/imx28.dtsi b/arch/arm/boot/dts/imx28.dtsi index 7363fde..6cd2607 100644 --- a/arch/arm/boot/dts/imx28.dtsi +++ b/arch/arm/boot/dts/imx28.dtsi @@ -1041,7 +1041,7 @@ ranges; usb0: usb@8008 { - compatible = "fsl,imx28-usb", "fsl,imx27-usb"; + compatible = "fsl,imx28-usb"; reg = <0x8008 0x1>; interrupts = <93>; clocks = <&clks 60>; @@ -1050,7 +1050,7 @@ }; usb1: usb@8009 { - compatible = "fsl,imx28-usb", "fsl,imx27-usb"; + compatible = "fsl,imx28-usb"; reg = <0x8009 0x1>; interrupts = <92>; clocks = <&clks 61>; -- 1.7.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 4/5] usb: doc: chipidea: imx: add compatiable string for imx28 SoC
Due to imx28 usb has special write requirement compared to other imx SoCs. Signed-off-by: Peter Chen --- Changes for v3: - 4/5, 5/5 are added .../devicetree/bindings/usb/ci13xxx-imx.txt|3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/Documentation/devicetree/bindings/usb/ci13xxx-imx.txt b/Documentation/devicetree/bindings/usb/ci13xxx-imx.txt index b4b5b79..a502d41 100644 --- a/Documentation/devicetree/bindings/usb/ci13xxx-imx.txt +++ b/Documentation/devicetree/bindings/usb/ci13xxx-imx.txt @@ -1,7 +1,8 @@ * Freescale i.MX ci13xxx usb controllers Required properties: -- compatible: Should be "fsl,imx27-usb" +- compatible: "fsl,imx28-usb" for imx28 SoC, "fsl,imx27-usb" for +non-imx28 SoC. - reg: Should contain registers location and length - interrupts: Should contain controller interrupt -- 1.7.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 2/5] usb: chipidea: add freescale imx28 special write register method
According to Freescale imx28 Errata, "ENGR119653 USB: ARM to USB register error issue", All USB register write operations must use the ARM SWP instruction. So, we implement special hw_write and hw_test_and_clear for imx28. Discussion for it at below: http://marc.info/?l=linux-usb&m=137996395529294&w=2 Signed-off-by: Peter Chen --- Changes for v2: - Rebase to latest usb-next tree drivers/usb/chipidea/ci.h| 23 +++ drivers/usb/chipidea/core.c |2 ++ drivers/usb/chipidea/host.c |1 + include/linux/usb/chipidea.h |1 + 4 files changed, 27 insertions(+), 0 deletions(-) diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h index 1c94fc5..4eb61d0 100644 --- a/drivers/usb/chipidea/ci.h +++ b/drivers/usb/chipidea/ci.h @@ -173,6 +173,8 @@ struct ci_hdrc { struct dentry *debugfs; boolid_event; boolb_sess_valid_event; + /* imx28 needs swp instruction for writing */ + boolimx28_write_fix; }; static inline struct ci_role_driver *ci_role(struct ci_hdrc *ci) @@ -253,6 +255,13 @@ static inline u32 hw_read(struct ci_hdrc *ci, enum ci_hw_regs reg, u32 mask) return ioread32(ci->hw_bank.regmap[reg]) & mask; } +#ifdef CONFIG_SOC_IMX28 +static inline void imx28_ci_writel(u32 val32, volatile u32 *addr) +{ + __asm__ ("swp %0, %0, [%1]" : : "r"(val32), "r"(addr)); +} +#endif + /** * hw_write: writes to a hw register * @reg: register index @@ -266,7 +275,14 @@ static inline void hw_write(struct ci_hdrc *ci, enum ci_hw_regs reg, data = (ioread32(ci->hw_bank.regmap[reg]) & ~mask) | (data & mask); +#ifdef CONFIG_SOC_IMX28 + if (ci->imx28_write_fix) + imx28_ci_writel(data, ci->hw_bank.regmap[reg]); + else + iowrite32(data, ci->hw_bank.regmap[reg]); +#else iowrite32(data, ci->hw_bank.regmap[reg]); +#endif } /** @@ -281,7 +297,14 @@ static inline u32 hw_test_and_clear(struct ci_hdrc *ci, enum ci_hw_regs reg, { u32 val = ioread32(ci->hw_bank.regmap[reg]) & mask; +#ifdef CONFIG_SOC_IMX28 + if (ci->imx28_write_fix) + imx28_ci_writel(val, ci->hw_bank.regmap[reg]); + else + iowrite32(val, ci->hw_bank.regmap[reg]); +#else iowrite32(val, ci->hw_bank.regmap[reg]); +#endif return val; } diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 06204b7..357a059 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -551,6 +551,8 @@ static int ci_hdrc_probe(struct platform_device *pdev) ci->dev = dev; ci->platdata = dev->platform_data; + ci->imx28_write_fix = !!(ci->platdata->flags & + CI_HDRC_IMX28_WRITE_FIX); ret = hw_device_init(ci, base); if (ret < 0) { diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c index 59e6020..06fd042 100644 --- a/drivers/usb/chipidea/host.c +++ b/drivers/usb/chipidea/host.c @@ -65,6 +65,7 @@ static int host_start(struct ci_hdrc *ci) ehci->caps = ci->hw_bank.cap; ehci->has_hostpc = ci->hw_bank.lpm; ehci->has_tdi_phy_lpm = ci->hw_bank.lpm; + ehci->imx28_write_fix = ci->imx28_write_fix; if (ci->platdata->reg_vbus) { ret = regulator_enable(ci->platdata->reg_vbus); diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h index 7d39967..708bd11 100644 --- a/include/linux/usb/chipidea.h +++ b/include/linux/usb/chipidea.h @@ -24,6 +24,7 @@ struct ci_hdrc_platform_data { * but otg is not supported (no register otgsc). */ #define CI_HDRC_DUAL_ROLE_NOT_OTG BIT(4) +#define CI_HDRC_IMX28_WRITE_FIXBIT(5) enum usb_dr_modedr_mode; #define CI_HDRC_CONTROLLER_RESET_EVENT 0 #define CI_HDRC_CONTROLLER_STOPPED_EVENT 1 -- 1.7.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 1/5] usb: ehci: add freescale imx28 special write register method
According to Freescale imx28 Errata, "ENGR119653 USB: ARM to USB register error issue", All USB register write operations must use the ARM SWP instruction. So, we implement a special ehci_write for imx28. Discussion for it at below: http://marc.info/?l=linux-usb&m=137996395529294&w=2 Signed-off-by: Peter Chen --- drivers/usb/host/ehci.h | 13 + 1 files changed, 13 insertions(+), 0 deletions(-) diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index e8f41c5..535aa8b 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -225,6 +225,7 @@ struct ehci_hcd { /* one per controller */ unsignedhas_synopsys_hc_bug:1; /* Synopsys HC */ unsignedframe_index_bug:1; /* MosChip (AKA NetMos) */ unsignedneed_oc_pp_cycle:1; /* MPC834X port power */ + unsignedimx28_write_fix:1; /* For Freescale i.MX28 */ /* required for usb32 quirk */ #define OHCI_CTRL_HCFS (3 << 6) @@ -728,6 +729,13 @@ static inline unsigned int ehci_readl(const struct ehci_hcd *ehci, #endif } +#ifdef CONFIG_SOC_IMX28 +static inline void imx28_ehci_writel(u32 val32, volatile u32 *addr) +{ + __asm__ ("swp %0, %0, [%1]" : : "r"(val32), "r"(addr)); +} +#endif + static inline void ehci_writel(const struct ehci_hcd *ehci, const unsigned int val, __u32 __iomem *regs) { @@ -735,6 +743,11 @@ static inline void ehci_writel(const struct ehci_hcd *ehci, ehci_big_endian_mmio(ehci) ? writel_be(val, regs) : writel(val, regs); +#elif defined(CONFIG_SOC_IMX28) + if (ehci->imx28_write_fix) + imx28_ehci_writel(val, regs); + else + writel(val, regs); #else writel(val, regs); #endif -- 1.7.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 3/5] usb: chipidea: imx: set CI_HDRC_IMX28_WRITE_FIX for imx28
Due to imx28 needs ARM swp instruction for writing, we set CI_HDRC_IMX28_WRITE_FIX for imx28. Signed-off-by: Peter Chen --- drivers/usb/chipidea/ci_hdrc_imx.c | 32 ++-- 1 files changed, 26 insertions(+), 6 deletions(-) diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c index 023d3cb..68f7f5e 100644 --- a/drivers/usb/chipidea/ci_hdrc_imx.c +++ b/drivers/usb/chipidea/ci_hdrc_imx.c @@ -23,6 +23,26 @@ #include "ci.h" #include "ci_hdrc_imx.h" +#define CI_HDRC_IMX_IMX28_WRITE_FIX BIT(0) + +struct ci_hdrc_imx_platform_flag { + unsigned int flags; +}; + +static const struct ci_hdrc_imx_platform_flag imx27_usb_data = { +}; + +static const struct ci_hdrc_imx_platform_flag imx28_usb_data = { + .flags = CI_HDRC_IMX_IMX28_WRITE_FIX, +}; + +static const struct of_device_id ci_hdrc_imx_dt_ids[] = { + { .compatible = "fsl,imx28-usb", .data = &imx28_usb_data}, + { .compatible = "fsl,imx27-usb", .data = &imx27_usb_data}, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, ci_hdrc_imx_dt_ids); + struct ci_hdrc_imx_data { struct usb_phy *phy; struct platform_device *ci_pdev; @@ -82,6 +102,9 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) CI_HDRC_DISABLE_STREAMING, }; int ret; + const struct of_device_id *of_id = + of_match_device(ci_hdrc_imx_dt_ids, &pdev->dev); + const struct ci_hdrc_imx_platform_flag *imx_platform_flag = of_id->data; data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); if (!data) { @@ -115,6 +138,9 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) pdata.phy = data->phy; + if (imx_platform_flag->flags & CI_HDRC_IMX_IMX28_WRITE_FIX) + pdata.flags |= CI_HDRC_IMX28_WRITE_FIX; + if (!pdev->dev.dma_mask) pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask; if (!pdev->dev.coherent_dma_mask) @@ -174,12 +200,6 @@ static int ci_hdrc_imx_remove(struct platform_device *pdev) return 0; } -static const struct of_device_id ci_hdrc_imx_dt_ids[] = { - { .compatible = "fsl,imx27-usb", }, - { /* sentinel */ } -}; -MODULE_DEVICE_TABLE(of, ci_hdrc_imx_dt_ids); - static struct platform_driver ci_hdrc_imx_driver = { .probe = ci_hdrc_imx_probe, .remove = ci_hdrc_imx_remove, -- 1.7.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html