Skip to content

Commit f46a6e1

Browse files
matnymangregkh
authored andcommitted
usb: Add tunnel_mode parameter to usb device structure
Add 'tunnel_mode' enum to usb device structure to describe if a USB3 link is tunneled over USB4, or connected directly using native USB2/USB3 protocols. Tunneled devices depend on USB4 NHI host to maintain the tunnel. Knowledge about tunneled devices is important to ensure correct suspend and resume order between USB4 hosts and tunneled devices. i.e. make sure tunnel is up before the USB device using it resumes. USB hosts such as xHCI may have vendor specific ways to detect tunneled connections. This 'tunnel_mode' parameter can be set by USB3 host driver during hcd->driver->update_device(hcd, udev) callback. tunnel_mode can be set to: USB_LINK_UNKNOWN = 0 USB_LINK_NATIVE USB_LINK_TUNNELED USB_LINK_UNKNOWN is used in case host is not capable of detecting tunneled links. Signed-off-by: Mathias Nyman <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 948ce83 commit f46a6e1

File tree

4 files changed

+24
-8
lines changed

4 files changed

+24
-8
lines changed

drivers/usb/host/xhci-hub.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -763,9 +763,12 @@ static int xhci_exit_test_mode(struct xhci_hcd *xhci)
763763
*
764764
* A USB3 device must be connected to the port to detect the tunnel.
765765
*
766-
* Return: true if USB3 connection is tunneled over USB4
766+
* Return: link tunnel mode enum, USB_LINK_UNKNOWN if host is incapable of
767+
* detecting USB3 over USB4 tunnels. USB_LINK_NATIVE or USB_LINK_TUNNELED
768+
* otherwise.
767769
*/
768-
bool xhci_port_is_tunneled(struct xhci_hcd *xhci, struct xhci_port *port)
770+
enum usb_link_tunnel_mode xhci_port_is_tunneled(struct xhci_hcd *xhci,
771+
struct xhci_port *port)
769772
{
770773
void __iomem *base;
771774
u32 offset;
@@ -777,10 +780,12 @@ bool xhci_port_is_tunneled(struct xhci_hcd *xhci, struct xhci_port *port)
777780
offset = XHCI_INTEL_SPR_ESS_PORT_OFFSET + port->hcd_portnum * 0x20;
778781

779782
if (readl(base + offset) & XHCI_INTEL_SPR_TUNEN)
780-
return true;
783+
return USB_LINK_TUNNELED;
784+
else
785+
return USB_LINK_NATIVE;
781786
}
782787

783-
return false;
788+
return USB_LINK_UNKNOWN;
784789
}
785790

786791
void xhci_set_link_state(struct xhci_hcd *xhci, struct xhci_port *port,

drivers/usb/host/xhci.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4529,9 +4529,12 @@ static int xhci_update_device(struct usb_hcd *hcd, struct usb_device *udev)
45294529
if (hcd->speed >= HCD_USB3 && !udev->parent->parent) {
45304530
port = xhci->usb3_rhub.ports[udev->portnum - 1];
45314531

4532-
if (xhci_port_is_tunneled(xhci, port))
4532+
udev->tunnel_mode = xhci_port_is_tunneled(xhci, port);
4533+
if (udev->tunnel_mode == USB_LINK_UNKNOWN)
4534+
dev_dbg(&udev->dev, "link tunnel state unknown\n");
4535+
else if (udev->tunnel_mode == USB_LINK_TUNNELED)
45334536
dev_dbg(&udev->dev, "tunneled over USB4 link\n");
4534-
else
4537+
else if (udev->tunnel_mode == USB_LINK_NATIVE)
45354538
dev_dbg(&udev->dev, "native USB 3.x link\n");
45364539
return 0;
45374540
}

drivers/usb/host/xhci.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1929,8 +1929,8 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex,
19291929
int xhci_hub_status_data(struct usb_hcd *hcd, char *buf);
19301930
int xhci_find_raw_port_number(struct usb_hcd *hcd, int port1);
19311931
struct xhci_hub *xhci_get_rhub(struct usb_hcd *hcd);
1932-
bool xhci_port_is_tunneled(struct xhci_hcd *xhci, struct xhci_port *port);
1933-
1932+
enum usb_link_tunnel_mode xhci_port_is_tunneled(struct xhci_hcd *xhci,
1933+
struct xhci_port *port);
19341934
void xhci_hc_died(struct xhci_hcd *xhci);
19351935

19361936
#ifdef CONFIG_PM

include/linux/usb.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,12 @@ struct usb_dev_state;
495495

496496
struct usb_tt;
497497

498+
enum usb_link_tunnel_mode {
499+
USB_LINK_UNKNOWN = 0,
500+
USB_LINK_NATIVE,
501+
USB_LINK_TUNNELED,
502+
};
503+
498504
enum usb_port_connect_type {
499505
USB_PORT_CONNECT_TYPE_UNKNOWN = 0,
500506
USB_PORT_CONNECT_TYPE_HOT_PLUG,
@@ -605,6 +611,7 @@ struct usb3_lpm_parameters {
605611
* WUSB devices are not, until we authorize them from user space.
606612
* FIXME -- complete doc
607613
* @authenticated: Crypto authentication passed
614+
* @tunnel_mode: Connection native or tunneled over USB4
608615
* @lpm_capable: device supports LPM
609616
* @lpm_devinit_allow: Allow USB3 device initiated LPM, exit latency is in range
610617
* @usb2_hw_lpm_capable: device can perform USB2 hardware LPM
@@ -714,6 +721,7 @@ struct usb_device {
714721
unsigned do_remote_wakeup:1;
715722
unsigned reset_resume:1;
716723
unsigned port_is_suspended:1;
724+
enum usb_link_tunnel_mode tunnel_mode;
717725

718726
int slot_id;
719727
struct usb2_lpm_parameters l1_params;

0 commit comments

Comments
 (0)