diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-07-11 15:40:06 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-07-11 15:40:06 -0700 |
| commit | 17a20acaf171124017f43bc70bb4d7ca88070659 (patch) | |
| tree | 8bc639ee52ed71fcfb32496dd4f16e03bdbf29b4 /drivers/usb/core/hub.c | |
| parent | d72619706abc4aa7e540ea882dae883cee7cc3b3 (diff) | |
| parent | 2bc8bb813cba6e699b29fd0b30720288866a5e5d (diff) | |
| download | linux-17a20acaf171124017f43bc70bb4d7ca88070659.tar.gz linux-17a20acaf171124017f43bc70bb4d7ca88070659.tar.bz2 linux-17a20acaf171124017f43bc70bb4d7ca88070659.zip | |
Merge tag 'usb-5.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
Pull USB / PHY updates from Greg KH:
"Here is the big USB and PHY driver pull request for 5.3-rc1.
Lots of stuff here, all of which has been in linux-next for a while
with no reported issues. Nothing is earth-shattering, just constant
forward progress for more devices supported and cleanups and small
fixes:
- USB gadget driver updates and fixes
- new USB gadget driver for some hardware, followed by a quick revert
of those patches as they were not ready to be merged...
- PHY driver updates
- Lots of new driver additions and cleanups with a few fixes mixed
in"
* tag 'usb-5.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (145 commits)
Revert "usb: gadget: storage: Remove warning message"
Revert "dt-bindings: add binding for USBSS-DRD controller."
Revert "usb:gadget Separated decoding functions from dwc3 driver."
Revert "usb:gadget Patch simplify usb_decode_set_clear_feature function."
Revert "usb:gadget Simplify usb_decode_get_set_descriptor function."
Revert "usb:cdns3 Add Cadence USB3 DRD Driver"
Revert "usb:cdns3 Fix for stuck packets in on-chip OUT buffer."
usb :fsl: Change string format for errata property
usb: host: Stops USB controller init if PLL fails to lock
usb: linux/fsl_device: Add platform member has_fsl_erratum_a006918
usb: phy: Workaround for USB erratum-A005728
usb: fsl: Set USB_EN bit to select ULPI phy
usb: Handle USB3 remote wakeup for LPM enabled devices correctly
drivers/usb/typec/tps6598x.c: fix 4CC cmd write
drivers/usb/typec/tps6598x.c: fix portinfo width
usb: storage: scsiglue: Do not skip VPD if try_vpd_pages is set
usb: renesas_usbhs: add a workaround for a race condition of workqueue
usb: gadget: udc: renesas_usb3: remove redundant assignment to ret
usb: dwc2: use a longer AHB idle timeout in dwc2_core_reset()
USB: gadget: function: fix issue Unneeded variable: "value"
...
Diffstat (limited to 'drivers/usb/core/hub.c')
| -rw-r--r-- | drivers/usb/core/hub.c | 45 |
1 files changed, 27 insertions, 18 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 2f94568ba385..236313f41f4a 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -873,7 +873,7 @@ int usb_hub_clear_tt_buffer(struct urb *urb) /* info that CLEAR_TT_BUFFER needs */ clear->tt = tt->multi ? udev->ttport : 1; clear->devinfo = usb_pipeendpoint (pipe); - clear->devinfo |= udev->devnum << 4; + clear->devinfo |= ((u16)udev->devaddr) << 4; clear->devinfo |= usb_pipecontrol(pipe) ? (USB_ENDPOINT_XFER_CONTROL << 11) : (USB_ENDPOINT_XFER_BULK << 11); @@ -2125,6 +2125,8 @@ static void update_devnum(struct usb_device *udev, int devnum) /* The address for a WUSB device is managed by wusbcore. */ if (!udev->wusb) udev->devnum = devnum; + if (!udev->devaddr) + udev->devaddr = (u8)devnum; } static void hub_free_dev(struct usb_device *udev) @@ -2719,7 +2721,7 @@ static bool use_new_scheme(struct usb_device *udev, int retry, } /* Is a USB 3.0 port in the Inactive or Compliance Mode state? - * Port worm reset is required to recover + * Port warm reset is required to recover */ static bool hub_port_warm_reset_required(struct usb_hub *hub, int port1, u16 portstatus) @@ -3617,6 +3619,7 @@ static int hub_handle_remote_wakeup(struct usb_hub *hub, unsigned int port, struct usb_device *hdev; struct usb_device *udev; int connect_change = 0; + u16 link_state; int ret; hdev = hub->hdev; @@ -3626,9 +3629,11 @@ static int hub_handle_remote_wakeup(struct usb_hub *hub, unsigned int port, return 0; usb_clear_port_feature(hdev, port, USB_PORT_FEAT_C_SUSPEND); } else { + link_state = portstatus & USB_PORT_STAT_LINK_STATE; if (!udev || udev->state != USB_STATE_SUSPENDED || - (portstatus & USB_PORT_STAT_LINK_STATE) != - USB_SS_PORT_LS_U0) + (link_state != USB_SS_PORT_LS_U0 && + link_state != USB_SS_PORT_LS_U1 && + link_state != USB_SS_PORT_LS_U2)) return 0; } @@ -3999,6 +4004,9 @@ static int usb_set_lpm_timeout(struct usb_device *udev, * control transfers to set the hub timeout or enable device-initiated U1/U2 * will be successful. * + * If the control transfer to enable device-initiated U1/U2 entry fails, then + * hub-initiated U1/U2 will be disabled. + * * If we cannot set the parent hub U1/U2 timeout, we attempt to let the xHCI * driver know about it. If that call fails, it should be harmless, and just * take up more slightly more bus bandwidth for unnecessary U1/U2 exit latency. @@ -4053,23 +4061,24 @@ static void usb_enable_link_state(struct usb_hcd *hcd, struct usb_device *udev, * host know that this link state won't be enabled. */ hcd->driver->disable_usb3_lpm_timeout(hcd, udev, state); - } else { - /* Only a configured device will accept the Set Feature - * U1/U2_ENABLE - */ - if (udev->actconfig) - usb_set_device_initiated_lpm(udev, state, true); + return; + } - /* As soon as usb_set_lpm_timeout(timeout) returns 0, the - * hub-initiated LPM is enabled. Thus, LPM is enabled no - * matter the result of usb_set_device_initiated_lpm(). - * The only difference is whether device is able to initiate - * LPM. - */ + /* Only a configured device will accept the Set Feature + * U1/U2_ENABLE + */ + if (udev->actconfig && + usb_set_device_initiated_lpm(udev, state, true) == 0) { if (state == USB3_LPM_U1) udev->usb3_lpm_u1_enabled = 1; else if (state == USB3_LPM_U2) udev->usb3_lpm_u2_enabled = 1; + } else { + /* Don't request U1/U2 entry if the device + * cannot transition to U1/U2. + */ + usb_set_lpm_timeout(udev, state, 0); + hcd->driver->disable_usb3_lpm_timeout(hcd, udev, state); } } @@ -4139,7 +4148,7 @@ int usb_disable_lpm(struct usb_device *udev) if (!udev || !udev->parent || udev->speed < USB_SPEED_SUPER || !udev->lpm_capable || - udev->state < USB_STATE_DEFAULT) + udev->state < USB_STATE_CONFIGURED) return 0; hcd = bus_to_hcd(udev->bus); @@ -4198,7 +4207,7 @@ void usb_enable_lpm(struct usb_device *udev) if (!udev || !udev->parent || udev->speed < USB_SPEED_SUPER || !udev->lpm_capable || - udev->state < USB_STATE_DEFAULT) + udev->state < USB_STATE_CONFIGURED) return; udev->lpm_disable_count--; |
