NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: kern/57359 (10.0_BETA failed to detect USB 2.0 Hub on AMD SB600)
The following reply was made to PR kern/57359; it has been noted by GNATS.
From: Izumi Tsutsui <tsutsui%ceres.dti.ne.jp@localhost>
To: gnats-bugs%netbsd.org@localhost
Cc: tsutsui%ceres.dti.ne.jp@localhost
Subject: Re: kern/57359 (10.0_BETA failed to detect USB 2.0 Hub on AMD SB600)
Date: Sat, 25 Apr 2026 06:13:08 +0900
It turns out that the previous fix on netbsd-10, which moved the SB600
quirk application after enabling the device, is not sufficient on
netbsd-11, at least 11.0_RC2 and 11.0_RC3.
On my ASRock M3A-UCC / AMD SB600 system with NetBSD/i386 11.0_RC3,
USB 2.0 devices are still not detected after a cold boot. The same
devices are detected after re-attaching ehci0 by the following commands:
# drvctl -d ehci0 ; drvctl -r pci0
It is also confirmed that reverting sys/dev/pci/pci_map.c rev 1.40
(disable I/O or mem decode before probing BAR size) on netbsd-11
makes the USB 2.0 devices detected again from cold boot.
I tried several changes around ehci_pci_attach(), including adding
delays and changing the order of BAR mapping, interrupt setup,
ownership handling, and SB600 quirk application, but these did not
fix the problem.
I also tried small netbsd-10-like reversions around the netbsd-11 EHCI
transfer path:
- control transfer start ordering
- QH/qTD descriptor allocation
- QH overlay zeroization
But none of these fixed the problem either.
Debug prints in ehci.c show that the EHCI root port reset succeeds.
The affected ports become enabled, but the first address-0 control
transfer does not complete.
The EHCI controller reports the async schedule as running:
- USBCMD: RS | ASE | PSE
- USBSTS: ASS | PSS
- the async QH ring also exists in memory
In the failing case, the first control qTD remains ACTIVE until timeout,
and EHCI_ASYNCLISTADDR looked to differ from the software async head.
I'm not sure whether this readback value is valid or not while the async
schedule is running, but reloading EHCI_ASYNCLISTADDR after linking
the qTD chain makes enumeration work. (see the following patch for details)
This looks like the controller is not processing the first async
control qTD, rather than a USB transaction error.
The current workaround patch is here:
---
Index: sys/dev/usb/ehci.c
===================================================================
RCS file: /cvsroot/src/sys/dev/usb/ehci.c,v
retrieving revision 1.332.2.1
diff -u -p -d -r1.332.2.1 ehci.c
--- sys/dev/usb/ehci.c 1 Oct 2025 17:21:19 -0000 1.332.2.1
+++ sys/dev/usb/ehci.c 24 Apr 2026 18:39:22 -0000
@@ -3836,6 +3836,20 @@ ehci_device_ctrl_start(struct usbd_xfer
/* Insert qTD in QH list - also does usb_syncmem(sqh) */
ehci_set_qh_qtd(sqh, setup);
+
+ /*
+ * Workaround SB600 first address-0 control transfer failure after
+ * cold boot. Reload ASYNCLISTADDR after linking the qTD chan so
+ * the controller resumes walking the asyn list properly.
+ * See PR/57359 for details.
+ */
+ if ((sc->sc_flags & EHCIF_SB600_ASYNCLIST_RELOAD) != 0 &&
+ epipe->pipe.up_dev->ud_addr == 0) {
+ sc->sc_flags &= ~EHCIF_SB600_ASYNCLIST_RELOAD;
+ EOWRITE4(sc, EHCI_ASYNCLISTADDR,
+ sc->sc_async_head->physaddr | EHCI_LINK_QH);
+ }
+
ehci_add_intr_list(sc, exfer);
xfer->ux_status = USBD_IN_PROGRESS;
usbd_xfer_schedule_timeout(xfer);
Index: sys/dev/usb/ehcivar.h
===================================================================
RCS file: /cvsroot/src/sys/dev/usb/ehcivar.h,v
retrieving revision 1.53
diff -u -p -d -r1.53 ehcivar.h
--- sys/dev/usb/ehcivar.h 23 Sep 2024 10:07:26 -0000 1.53
+++ sys/dev/usb/ehcivar.h 24 Apr 2026 18:39:26 -0000
@@ -172,6 +172,7 @@ typedef struct ehci_softc {
#define EHCIF_DROPPED_INTR_WORKAROUND 0x01
#define EHCIF_ETTF 0x02 /* Emb. Transaction Translater func. */
#define EHCIF_32BIT_ACCESS 0x04 /* 32-bit MMIO access req'd */
+#define EHCIF_SB600_ASYNCLIST_RELOAD 0x08 /* SB600 quirk (PR/57359) */
uint32_t sc_cmd; /* shadow of cmd reg during suspend */
Index: sys/dev/pci/ehci_pci.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/ehci_pci.c,v
retrieving revision 1.78.2.1
diff -u -p -d -r1.78.2.1 ehci_pci.c
--- sys/dev/pci/ehci_pci.c 8 Jan 2026 10:43:25 -0000 1.78.2.1
+++ sys/dev/pci/ehci_pci.c 24 Apr 2026 18:39:26 -0000
@@ -181,6 +181,7 @@ ehci_pci_attach(device_t parent, device_
switch (quirk) {
case EHCI_PCI_QUIRK_AMD_SB600:
ehci_apply_amd_quirks(sc);
+ sc->sc.sc_flags |= EHCIF_SB600_ASYNCLIST_RELOAD;
break;
case EHCI_PCI_QUIRK_AMD_SB700:
if (pci_find_device(NULL, ehci_sb700_match))
---
This patch does the following:
- set EHCIF_SB600_ASYNCLIST_RELOAD quirk flag for SB600 in ehci_pci.c
- checks this flag once in ehci_device_ctrl_start()
- after ehci_set_qh_qtd() links the first address-0 control qTD chain,
write EHCI_ASYNCLISTADDR again using the same value as ehci_init()
- normal transfers and later device enumeration are not affected
However, I do not yet have a proper scenario why netbsd-10 does not
need this extra reload while netbsd-11 does.
My guess is that the SB600 EHCI state after cold boot is sensitive to
the pci_map.c rev 1.40 BAR probing sequence. The BIOS may already
leave the controller in a state which hides part of the SB600 problem,
and temporarily disabling/restoring PCI memory decoding while sizing
the BAR by pci_map.c rev 1.40 may disturb that state.
The difference between netbsd-10 and netbsd-11 may simply be enough
timing or EHCI descriptor handling difference to expose the same SB600
issue in one branch but not the other.
I still do not fully understand the exact reason, but at least on
netbsd-11 the failure is reproducible:
- the first address-0 control qTD remains ACTIVE until timeout
- reloading EHCI_ASYNCLISTADDR after the qTD chain is linked makes
USB 2.0 enumeration work on my SB600
If there are no objections to this approach, I would like to commit this
and request a pullup to netbsd-11.
Thanks,
---
Izumi Tsutsui
Home |
Main Index |
Thread Index |
Old Index