git: 85c3bd4595ba - main - usb: support SSP/SSPx2 devices in all-speed consumers
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 02 Nov 2026 03:02:46 UTC
The branch main has been updated by aokblast:
URL: https://cgit.FreeBSD.org/src/commit/?id=85c3bd4595ba3d213ef570a51b517d82cd481d0a
commit 85c3bd4595ba3d213ef570a51b517d82cd481d0a
Author: ShengYi Hung <aokblast@FreeBSD.org>
AuthorDate: 2026-05-22 15:48:49 +0000
Commit: ShengYi Hung <aokblast@FreeBSD.org>
CommitDate: 2026-11-02 03:02:11 +0000
usb: support SSP/SSPx2 devices in all-speed consumers
Handle the new speeds wherever USB_SPEED_SUPER was checked. Most
consumers treat them as SS.
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D57198
---
sys/dev/rtwn/rtl8812a/usb/r12au_attach.c | 2 +-
sys/dev/usb/controller/usb_controller.c | 12 ++++++++++++
sys/dev/usb/controller/xhci.c | 4 ++--
sys/dev/usb/net/if_muge.c | 6 ++++++
sys/dev/usb/net/if_ure.c | 9 ++++++---
sys/dev/usb/storage/umass.c | 8 ++++++++
sys/dev/usb/template/usb_template.c | 9 +++++++++
sys/dev/usb/usb_device.c | 2 +-
sys/dev/usb/usb_request.c | 5 ++---
sys/dev/usb/usb_transfer.c | 18 ++++++++++++++++++
10 files changed, 65 insertions(+), 10 deletions(-)
diff --git a/sys/dev/rtwn/rtl8812a/usb/r12au_attach.c b/sys/dev/rtwn/rtl8812a/usb/r12au_attach.c
index 069fb28d5be7..57e4d8b0091c 100644
--- a/sys/dev/rtwn/rtl8812a/usb/r12au_attach.c
+++ b/sys/dev/rtwn/rtl8812a/usb/r12au_attach.c
@@ -78,7 +78,7 @@ r12au_postattach(struct rtwn_softc *sc)
struct rtwn_usb_softc *uc = RTWN_USB_SOFTC(sc);
struct r12a_softc *rs = sc->sc_priv;
- if (usbd_get_speed(uc->uc_udev) == USB_SPEED_SUPER) {
+ if (usbd_get_speed(uc->uc_udev) >= USB_SPEED_SUPER) {
rs->ac_usb_dma_size = 0x07;
rs->ac_usb_dma_time = 0x1a;
} else {
diff --git a/sys/dev/usb/controller/usb_controller.c b/sys/dev/usb/controller/usb_controller.c
index 3eb632124b4c..46377551d51d 100644
--- a/sys/dev/usb/controller/usb_controller.c
+++ b/sys/dev/usb/controller/usb_controller.c
@@ -737,6 +737,18 @@ usb_bus_attach(struct usb_proc_msg *pm)
device_printf(bus->bdev, "5.0Gbps Super Speed USB v3.0\n");
break;
+ case USB_REV_3_1:
+ speed = USB_SPEED_SUPER_PLUS;
+ device_printf(bus->bdev,
+ "10Gbps Super Speed Plus USB v3.1\n");
+ break;
+
+ case USB_REV_3_2:
+ speed = USB_SPEED_SUPER_PLUS_GEN2_X2;
+ device_printf(bus->bdev,
+ "20Gbps Super Speed Plus USB v3.2\n");
+ break;
+
default:
device_printf(bus->bdev, "Unsupported USB revision\n");
#if USB_HAVE_ROOT_MOUNT_HOLD
diff --git a/sys/dev/usb/controller/xhci.c b/sys/dev/usb/controller/xhci.c
index 72a0b704b9b6..acc6eee525b0 100644
--- a/sys/dev/usb/controller/xhci.c
+++ b/sys/dev/usb/controller/xhci.c
@@ -4537,9 +4537,9 @@ xhci_set_endpoint_mode(struct usb_device *udev, struct usb_endpoint *ep,
case USB_EP_MODE_DEFAULT:
return (0);
case USB_EP_MODE_STREAMS:
- if (xhcistreams == 0 ||
+ if (xhcistreams == 0 ||
(ep->edesc->bmAttributes & UE_XFERTYPE) != UE_BULK ||
- udev->speed != USB_SPEED_SUPER)
+ udev->speed < USB_SPEED_SUPER)
return (USB_ERR_INVAL);
return (0);
default:
diff --git a/sys/dev/usb/net/if_muge.c b/sys/dev/usb/net/if_muge.c
index a39343b2e3c9..56ffa0c67d9a 100644
--- a/sys/dev/usb/net/if_muge.c
+++ b/sys/dev/usb/net/if_muge.c
@@ -817,6 +817,9 @@ lan78xx_miibus_statchg(device_t dev)
/* XXX Flow control settings obtained from Microchip's driver. */
switch(usbd_get_speed(sc->sc_ue.ue_udev)) {
case USB_SPEED_SUPER:
+ case USB_SPEED_SUPER_PLUS:
+ case USB_SPEED_SUPER_PLUS_X2:
+ case USB_SPEED_SUPER_PLUS_GEN2_X2:
fct_flow = 0x817;
break;
case USB_SPEED_HIGH:
@@ -1023,6 +1026,9 @@ lan78xx_chip_init(struct muge_softc *sc)
/* Configuring the burst cap. */
switch (usbd_get_speed(sc->sc_ue.ue_udev)) {
case USB_SPEED_SUPER:
+ case USB_SPEED_SUPER_PLUS:
+ case USB_SPEED_SUPER_PLUS_X2:
+ case USB_SPEED_SUPER_PLUS_GEN2_X2:
burst_cap = MUGE_DEFAULT_BURST_CAP_SIZE/MUGE_SS_USB_PKT_SIZE;
break;
case USB_SPEED_HIGH:
diff --git a/sys/dev/usb/net/if_ure.c b/sys/dev/usb/net/if_ure.c
index 81e1232a0e64..a3468d7869f4 100644
--- a/sys/dev/usb/net/if_ure.c
+++ b/sys/dev/usb/net/if_ure.c
@@ -1151,6 +1151,9 @@ ure_init(struct usb_ether *ue)
/* Set RX EARLY timeout and size */
if (sc->sc_flags & URE_FLAG_8153) {
switch (usbd_get_speed(sc->sc_ue.ue_udev)) {
+ case USB_SPEED_SUPER_PLUS_GEN2_X2:
+ case USB_SPEED_SUPER_PLUS_X2:
+ case USB_SPEED_SUPER_PLUS:
case USB_SPEED_SUPER:
reg = URE_COALESCE_SUPER / 8;
break;
@@ -1701,7 +1704,7 @@ ure_rtl8153_init(struct ure_softc *sc)
URE_CLRBIT_2(sc, URE_PLA_LED_FEATURE, URE_MCU_TYPE_PLA, URE_LED_MODE_MASK);
if ((sc->sc_chip & URE_CHIP_VER_5C10) &&
- usbd_get_speed(sc->sc_ue.ue_udev) != USB_SPEED_SUPER)
+ usbd_get_speed(sc->sc_ue.ue_udev) < USB_SPEED_SUPER)
val = URE_LPM_TIMER_500MS;
else
val = URE_LPM_TIMER_500US;
@@ -1883,7 +1886,7 @@ ure_rtl8153b_init(struct ure_softc *sc)
ure_write_1(sc, URE_PLA_CRWECR, URE_MCU_TYPE_PLA, URE_CRWECR_NORAML);
/* Enable U1U2 */
- if (usbd_get_speed(sc->sc_ue.ue_udev) == USB_SPEED_SUPER)
+ if (usbd_get_speed(sc->sc_ue.ue_udev) >= USB_SPEED_SUPER)
URE_SETBIT_2(sc, URE_USB_LPM_CONFIG, URE_MCU_TYPE_USB, URE_LPM_U1U2_EN);
if (sc->sc_flags & URE_FLAG_8156B) {
@@ -2050,7 +2053,7 @@ ure_rtl8153b_nic_reset(struct ure_softc *sc)
}
/* Enable U1U2 */
- if (usbd_get_speed(sc->sc_ue.ue_udev) == USB_SPEED_SUPER)
+ if (usbd_get_speed(sc->sc_ue.ue_udev) >= USB_SPEED_SUPER)
URE_SETBIT_2(sc, URE_USB_LPM_CONFIG, URE_MCU_TYPE_USB, URE_LPM_U1U2_EN);
}
diff --git a/sys/dev/usb/storage/umass.c b/sys/dev/usb/storage/umass.c
index 0ee6ea992fa7..adab90d30690 100644
--- a/sys/dev/usb/storage/umass.c
+++ b/sys/dev/usb/storage/umass.c
@@ -222,6 +222,7 @@ SYSCTL_INT(_hw_usb_umass, OID_AUTO, throttle, CTLFLAG_RWTUN,
#define UMASS_FULL_TRANSFER_SPEED 1000
#define UMASS_HIGH_TRANSFER_SPEED 40000
#define UMASS_SUPER_TRANSFER_SPEED 400000
+#define UMASS_SUPER_PLUS_TRANSFER_SPEED 1000000
#define UMASS_FLOPPY_TRANSFER_SPEED 20
#define UMASS_TIMEOUT 5000 /* ms */
@@ -2409,6 +2410,13 @@ umass_cam_action(struct cam_sim *sim, union ccb *ccb)
UMASS_FLOPPY_TRANSFER_SPEED;
} else {
switch (usbd_get_speed(sc->sc_udev)) {
+ case USB_SPEED_SUPER_PLUS_GEN2_X2:
+ case USB_SPEED_SUPER_PLUS_X2:
+ case USB_SPEED_SUPER_PLUS:
+ cpi->base_transfer_speed =
+ UMASS_SUPER_PLUS_TRANSFER_SPEED;
+ cpi->maxio = maxphys;
+ break;
case USB_SPEED_SUPER:
cpi->base_transfer_speed =
UMASS_SUPER_TRANSFER_SPEED;
diff --git a/sys/dev/usb/template/usb_template.c b/sys/dev/usb/template/usb_template.c
index 6e9de2a6dcce..a26c643a860d 100644
--- a/sys/dev/usb/template/usb_template.c
+++ b/sys/dev/usb/template/usb_template.c
@@ -593,6 +593,15 @@ usb_make_device_desc(struct usb_temp_setup *temp,
USETW(utd->udd.bcdUSB, 0x0300);
utd->udd.bMaxPacketSize = 9; /* 2**9 = 512 bytes */
break;
+ case USB_SPEED_SUPER_PLUS:
+ USETW(utd->udd.bcdUSB, 0x0310);
+ utd->udd.bMaxPacketSize = 9; /* 2**9 = 512 bytes */
+ break;
+ case USB_SPEED_SUPER_PLUS_X2:
+ case USB_SPEED_SUPER_PLUS_GEN2_X2:
+ USETW(utd->udd.bcdUSB, 0x0320);
+ utd->udd.bMaxPacketSize = 9; /* 2**9 = 512 bytes */
+ break;
default:
temp->err = USB_ERR_INVAL;
break;
diff --git a/sys/dev/usb/usb_device.c b/sys/dev/usb/usb_device.c
index 4e0268110787..24cce9a47f50 100644
--- a/sys/dev/usb/usb_device.c
+++ b/sys/dev/usb/usb_device.c
@@ -524,7 +524,7 @@ usb_init_endpoint(struct usb_device *udev, uint8_t iface_index,
return;
/* check for SUPER-speed streams mode endpoint */
- if (udev->speed == USB_SPEED_SUPER && ecomp != NULL &&
+ if (udev->speed >= USB_SPEED_SUPER && ecomp != NULL &&
(edesc->bmAttributes & UE_XFERTYPE) == UE_BULK &&
(UE_GET_BULK_STREAMS(ecomp->bmAttributes) != 0)) {
usbd_set_endpoint_mode(udev, ep, USB_EP_MODE_STREAMS);
diff --git a/sys/dev/usb/usb_request.c b/sys/dev/usb/usb_request.c
index 55e5f04194d9..879d57f00eec 100644
--- a/sys/dev/usb/usb_request.c
+++ b/sys/dev/usb/usb_request.c
@@ -2081,8 +2081,7 @@ retry:
* Try to reset the High Speed parent HUB of a LOW- or FULL-
* speed device, if any.
*/
- if (udev->parent_hs_hub != NULL &&
- udev->speed != USB_SPEED_HIGH) {
+ if (udev->parent_hs_hub != NULL && udev->speed < USB_SPEED_HIGH) {
DPRINTF("Trying to reset parent High Speed TT.\n");
if (udev->parent_hs_hub == parent_hub &&
(uhub_count_active_host_ports(parent_hub, USB_SPEED_LOW) +
@@ -2103,7 +2102,7 @@ retry:
}
#endif
/* Try to warm reset first */
- if (parent_hub->speed == USB_SPEED_SUPER)
+ if (parent_hub->speed >= USB_SPEED_SUPER)
usbd_req_warm_reset_port(parent_hub, mtx, udev->port_no);
/* Try to reset the parent HUB port. */
diff --git a/sys/dev/usb/usb_transfer.c b/sys/dev/usb/usb_transfer.c
index d41121ed3a06..751014699a44 100644
--- a/sys/dev/usb/usb_transfer.c
+++ b/sys/dev/usb/usb_transfer.c
@@ -407,6 +407,9 @@ usbd_get_max_frame_length(const struct usb_endpoint_descriptor *edesc,
max_packet_size &= 0x7FF;
break;
case USB_SPEED_SUPER:
+ case USB_SPEED_SUPER_PLUS:
+ case USB_SPEED_SUPER_PLUS_X2:
+ case USB_SPEED_SUPER_PLUS_GEN2_X2:
max_packet_count += (max_packet_size >> 11) & 3;
if (ecomp != NULL)
@@ -517,6 +520,9 @@ usbd_transfer_setup_sub(struct usb_setup_params *parm)
xfer->max_packet_size &= 0x7FF;
break;
case USB_SPEED_SUPER:
+ case USB_SPEED_SUPER_PLUS:
+ case USB_SPEED_SUPER_PLUS_X2:
+ case USB_SPEED_SUPER_PLUS_GEN2_X2:
xfer->max_packet_count += (xfer->max_packet_size >> 11) & 3;
if (ecomp != NULL)
@@ -3534,6 +3540,9 @@ usbd_get_std_packet_size(struct usb_std_packet_size *ptr,
[USB_SPEED_HIGH] = 1024,
[USB_SPEED_VARIABLE] = 1024,
[USB_SPEED_SUPER] = 1024,
+ [USB_SPEED_SUPER_PLUS] = 1024,
+ [USB_SPEED_SUPER_PLUS_X2] = 1024,
+ [USB_SPEED_SUPER_PLUS_GEN2_X2] = 1024,
};
static const uint16_t isoc_range_max[USB_SPEED_MAX] = {
@@ -3542,6 +3551,9 @@ usbd_get_std_packet_size(struct usb_std_packet_size *ptr,
[USB_SPEED_HIGH] = 1024,
[USB_SPEED_VARIABLE] = 3584,
[USB_SPEED_SUPER] = 1024,
+ [USB_SPEED_SUPER_PLUS] = 1024,
+ [USB_SPEED_SUPER_PLUS_X2] = 1024,
+ [USB_SPEED_SUPER_PLUS_GEN2_X2] = 1024,
};
static const uint16_t control_min[USB_SPEED_MAX] = {
@@ -3550,6 +3562,9 @@ usbd_get_std_packet_size(struct usb_std_packet_size *ptr,
[USB_SPEED_HIGH] = 64,
[USB_SPEED_VARIABLE] = 512,
[USB_SPEED_SUPER] = 512,
+ [USB_SPEED_SUPER_PLUS] = 512,
+ [USB_SPEED_SUPER_PLUS_X2] = 512,
+ [USB_SPEED_SUPER_PLUS_GEN2_X2] = 512,
};
static const uint16_t bulk_min[USB_SPEED_MAX] = {
@@ -3558,6 +3573,9 @@ usbd_get_std_packet_size(struct usb_std_packet_size *ptr,
[USB_SPEED_HIGH] = 512,
[USB_SPEED_VARIABLE] = 512,
[USB_SPEED_SUPER] = 1024,
+ [USB_SPEED_SUPER_PLUS] = 1024,
+ [USB_SPEED_SUPER_PLUS_X2] = 1024,
+ [USB_SPEED_SUPER_PLUS_GEN2_X2] = 1024,
};
uint16_t temp;