* USB controller broken by zero cacheline size in PCIe to PCI bridge
@ 2026-03-15 0:54 Michal Pecio
2026-03-16 20:06 ` Bjorn Helgaas
0 siblings, 1 reply; 3+ messages in thread
From: Michal Pecio @ 2026-03-15 0:54 UTC (permalink / raw)
To: linux-pci, Bjorn Helgaas; +Cc: Alan Stern
Hi,
I have here a PCIe card with PEX8112 PCIe to PCI bridge and uPD720101
PCI USB controller (OHCI+EHCI) behind the bridge.
The card works in one machine and gets sluggish and barely functional
in another one. Hoping for some PCI misconfiguration, I ran lspci -vv
on both machines for comparison (diff pasted below).
There are surprisingly many differences, so I started to tweak with
setpci on live system until I got it to work after setting
CACHE_LINE_SIZE=10 on the bridge. The original value was zero.
I rebooted and confirmed that this alone is sufficient, and changing
back to zero immediately breaks the controller again.
I know nothing about PCI, so I wonder if this result makes sense and
what may be causing the "bad" system to end up in such sorry state?
Thanks,
Michal
--- bad
+++ good
-07:00.0 PCI bridge: PLX Technology, Inc. PEX8112 x1 Lane PCI Express-to-PCI Bridge (rev aa) (prog-if 00 [Normal decode])
- Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV+ VGASnoop- ParErr- Stepping- SERR+ FastB2B- DisINTx-
+02:00.0 PCI bridge: PLX Technology, Inc. PEX8112 x1 Lane PCI Express-to-PCI Bridge (rev aa) (prog-if 00 [Normal decode])
+ Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV+ VGASnoop- ParErr- Stepping- SERR+ FastB2B- DisINTx-
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
- Latency: 0
- Interrupt: pin A routed to IRQ 28
- IOMMU group: 2
- Bus: primary=07, secondary=08, subordinate=08, sec-latency=0
+ Latency: 0, Cache Line Size: 64 bytes
+ Interrupt: pin A routed to IRQ 18
+ Bus: primary=02, secondary=03, subordinate=03, sec-latency=64
I/O behind bridge: [disabled] [16-bit]
- Memory behind bridge: d0b00000-d0bfffff [size=1M] [32-bit]
+ Memory behind bridge: fe900000-fe9fffff [size=1M] [32-bit]
Prefetchable memory behind bridge: [disabled] [32-bit]
Secondary status: 66MHz+ FastB2B- ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- <SERR- <PERR-
- BridgeCtl: Parity- SERR+ NoISA- VGA- VGA16- MAbort- >Reset- FastB2B-
+ BridgeCtl: Parity+ SERR+ NoISA+ VGA- VGA16- MAbort- >Reset- FastB2B-
PriDiscTmr- SecDiscTmr- DiscTmrStat- DiscTmrSERREn-
Capabilities: [40] Power Management version 2
Flags: PMEClk- DSI- D1+ D2- AuxCurrent=0mA PME(D0+,D1+,D2-,D3hot+,D3cold-)
Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
Capabilities: [50] MSI: Enable- Count=1/1 Maskable- 64bit+
Address: 0000000000000000 Data: 0000
Capabilities: [60] Express (v1) PCI-Express to PCI/PCI-X Bridge, IntMsgNum 0
DevCap: MaxPayload 128 bytes, PhantFunc 0
- ExtTag- AttnBtn- AttnInd- PwrInd- RBE- SlotPowerLimit 0W TEE-IO-
+ ExtTag- AttnBtn- AttnInd- PwrInd- RBE- SlotPowerLimit 25W TEE-IO-
DevCtl: CorrErr- NonFatalErr- FatalErr- UnsupReq-
RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop- BrConfRtry-
MaxPayload 128 bytes, MaxReadReq 512 bytes
DevSta: CorrErr- NonFatalErr+ FatalErr- UnsupReq+ AuxPwr- TransPend-
LnkCap: Port #0, Speed 2.5GT/s, Width x1, ASPM L0s L1, Exit Latency L0s <1us, L1 <16us
ClockPM- Surprise- LLActRep- BwNot- ASPMOptComp-
- LnkCtl: ASPM Disabled; RCB 64 bytes, LnkDisable- CommClk-
+ LnkCtl: ASPM Disabled; RCB 64 bytes, LnkDisable- CommClk+
ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
LnkSta: Speed 2.5GT/s, Width x1
TrErr- Train- SlotClk- DLActive- BWMgmt- ABWMgmt-
Capabilities: [100 v1] Power Budgeting <?>
-08:00.0 USB controller: NEC Corporation OHCI USB Controller (rev 43) (prog-if 10 [OHCI])
+03:00.0 USB controller: NEC Corporation OHCI USB Controller (rev 43) (prog-if 10 [OHCI])
Subsystem: NEC Corporation USB Controller
Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV+ VGASnoop- ParErr- Stepping- SERR+ FastB2B- DisINTx-
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
- Latency: 64 (250ns min, 10500ns max)
- Interrupt: pin A routed to IRQ 28
- IOMMU group: 2
- Region 0: Memory at d0b02000 (32-bit, non-prefetchable) [size=4K]
+ Latency: 64 (250ns min, 10500ns max), Cache Line Size: 64 bytes
+ Interrupt: pin A routed to IRQ 18
+ Region 0: Memory at fe9ff000 (32-bit, non-prefetchable) [size=4K]
Capabilities: [40] Power Management version 2
Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=0mA PME(D0+,D1+,D2+,D3hot+,D3cold-)
Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
Kernel driver in use: ohci-pci
Kernel modules: ohci_pci
-08:00.1 USB controller: NEC Corporation OHCI USB Controller (rev 43) (prog-if 10 [OHCI])
+03:00.1 USB controller: NEC Corporation OHCI USB Controller (rev 43) (prog-if 10 [OHCI])
Subsystem: NEC Corporation USB Controller
Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV+ VGASnoop- ParErr- Stepping- SERR+ FastB2B- DisINTx-
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
- Latency: 64 (250ns min, 10500ns max)
- Interrupt: pin B routed to IRQ 55
- IOMMU group: 2
- Region 0: Memory at d0b01000 (32-bit, non-prefetchable) [size=4K]
+ Latency: 64 (250ns min, 10500ns max), Cache Line Size: 64 bytes
+ Interrupt: pin B routed to IRQ 19
+ Region 0: Memory at fe9fe000 (32-bit, non-prefetchable) [size=4K]
Capabilities: [40] Power Management version 2
Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=0mA PME(D0+,D1+,D2+,D3hot+,D3cold-)
Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
Kernel driver in use: ohci-pci
Kernel modules: ohci_pci
-08:00.2 USB controller: NEC Corporation uPD72010x USB 2.0 Controller (rev 04) (prog-if 20 [EHCI])
+03:00.2 USB controller: NEC Corporation uPD72010x USB 2.0 Controller (rev 04) (prog-if 20 [EHCI])
Subsystem: NEC Corporation uPD72010x USB 2.0 Controller
Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV+ VGASnoop- ParErr- Stepping- SERR+ FastB2B- DisINTx-
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
- Latency: 68 (4000ns min, 8500ns max), Cache Line Size: 64 bytes
- Interrupt: pin C routed to IRQ 44
- IOMMU group: 2
- Region 0: Memory at d0b00000 (32-bit, non-prefetchable) [size=256]
+ Latency: 64 (4000ns min, 8500ns max), Cache Line Size: 64 bytes
+ Interrupt: pin C routed to IRQ 16
+ Region 0: Memory at fe9fdc00 (32-bit, non-prefetchable) [size=256]
Capabilities: [40] Power Management version 2
Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=0mA PME(D0+,D1+,D2+,D3hot+,D3cold-)
Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME+
Kernel driver in use: ehci-pci
Kernel modules: ehci_pci
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: USB controller broken by zero cacheline size in PCIe to PCI bridge
2026-03-15 0:54 USB controller broken by zero cacheline size in PCIe to PCI bridge Michal Pecio
@ 2026-03-16 20:06 ` Bjorn Helgaas
2026-03-17 20:37 ` Michal Pecio
0 siblings, 1 reply; 3+ messages in thread
From: Bjorn Helgaas @ 2026-03-16 20:06 UTC (permalink / raw)
To: Michal Pecio; +Cc: linux-pci, Alan Stern
On Sun, Mar 15, 2026 at 01:54:06AM +0100, Michal Pecio wrote:
> Hi,
>
> I have here a PCIe card with PEX8112 PCIe to PCI bridge and uPD720101
> PCI USB controller (OHCI+EHCI) behind the bridge.
>
> The card works in one machine and gets sluggish and barely functional
> in another one. Hoping for some PCI misconfiguration, I ran lspci -vv
> on both machines for comparison (diff pasted below).
Is there an actual functional problem like data corruption, or is it
purely a performance issue?
> There are surprisingly many differences, so I started to tweak with
> setpci on live system until I got it to work after setting
> CACHE_LINE_SIZE=10 on the bridge. The original value was zero.
>
> I rebooted and confirmed that this alone is sufficient, and changing
> back to zero immediately breaks the controller again.
>
> I know nothing about PCI, so I wonder if this result makes sense and
> what may be causing the "bad" system to end up in such sorry state?
The Cache Line Size depends on the CPU, so maybe the good and bad
machines have different CPUs? Can you collect /proc/cpuinfo for each?
I don't think the Cache Line Size depends on the actual PCI devices,
so the PCI core really should configure it for every bridge and device
during enumeration, but I don't think it does.
In your case, ehci_pci_reinit() might set it for the uPD72010x EHCI
controller, and it looks like Cache Line Size is set to 64 bytes in
both the good and bad systems.
But I don't see any path at all that would configure Cache Line Size
for bridges, so I suspect BIOS configures the PCIe-to-PCI bridge
differently between the machines.
The Cache Line Size configuration (or lack of it) is kind of a
historical mess, and it only applies to conventional PCI, not PCIe, so
I don't really know how to untangle it.
> --- bad
> +++ good
>
> -07:00.0 PCI bridge: PLX Technology, Inc. PEX8112 x1 Lane PCI Express-to-PCI Bridge (rev aa) (prog-if 00 [Normal decode])
> - Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV+ VGASnoop- ParErr- Stepping- SERR+ FastB2B- DisINTx-
> +02:00.0 PCI bridge: PLX Technology, Inc. PEX8112 x1 Lane PCI Express-to-PCI Bridge (rev aa) (prog-if 00 [Normal decode])
> + Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV+ VGASnoop- ParErr- Stepping- SERR+ FastB2B- DisINTx-
> Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
> - Latency: 0
> - Interrupt: pin A routed to IRQ 28
> - IOMMU group: 2
> - Bus: primary=07, secondary=08, subordinate=08, sec-latency=0
> + Latency: 0, Cache Line Size: 64 bytes
> + Interrupt: pin A routed to IRQ 18
> + Bus: primary=02, secondary=03, subordinate=03, sec-latency=64
> I/O behind bridge: [disabled] [16-bit]
> - Memory behind bridge: d0b00000-d0bfffff [size=1M] [32-bit]
> + Memory behind bridge: fe900000-fe9fffff [size=1M] [32-bit]
> Prefetchable memory behind bridge: [disabled] [32-bit]
> Secondary status: 66MHz+ FastB2B- ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- <SERR- <PERR-
> - BridgeCtl: Parity- SERR+ NoISA- VGA- VGA16- MAbort- >Reset- FastB2B-
> + BridgeCtl: Parity+ SERR+ NoISA+ VGA- VGA16- MAbort- >Reset- FastB2B-
> PriDiscTmr- SecDiscTmr- DiscTmrStat- DiscTmrSERREn-
> Capabilities: [40] Power Management version 2
> Flags: PMEClk- DSI- D1+ D2- AuxCurrent=0mA PME(D0+,D1+,D2-,D3hot+,D3cold-)
> Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
> Capabilities: [50] MSI: Enable- Count=1/1 Maskable- 64bit+
> Address: 0000000000000000 Data: 0000
> Capabilities: [60] Express (v1) PCI-Express to PCI/PCI-X Bridge, IntMsgNum 0
> DevCap: MaxPayload 128 bytes, PhantFunc 0
> - ExtTag- AttnBtn- AttnInd- PwrInd- RBE- SlotPowerLimit 0W TEE-IO-
> + ExtTag- AttnBtn- AttnInd- PwrInd- RBE- SlotPowerLimit 25W TEE-IO-
> DevCtl: CorrErr- NonFatalErr- FatalErr- UnsupReq-
> RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop- BrConfRtry-
> MaxPayload 128 bytes, MaxReadReq 512 bytes
> DevSta: CorrErr- NonFatalErr+ FatalErr- UnsupReq+ AuxPwr- TransPend-
> LnkCap: Port #0, Speed 2.5GT/s, Width x1, ASPM L0s L1, Exit Latency L0s <1us, L1 <16us
> ClockPM- Surprise- LLActRep- BwNot- ASPMOptComp-
> - LnkCtl: ASPM Disabled; RCB 64 bytes, LnkDisable- CommClk-
> + LnkCtl: ASPM Disabled; RCB 64 bytes, LnkDisable- CommClk+
> ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
> LnkSta: Speed 2.5GT/s, Width x1
> TrErr- Train- SlotClk- DLActive- BWMgmt- ABWMgmt-
> Capabilities: [100 v1] Power Budgeting <?>
>
> -08:00.0 USB controller: NEC Corporation OHCI USB Controller (rev 43) (prog-if 10 [OHCI])
> +03:00.0 USB controller: NEC Corporation OHCI USB Controller (rev 43) (prog-if 10 [OHCI])
> Subsystem: NEC Corporation USB Controller
> Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV+ VGASnoop- ParErr- Stepping- SERR+ FastB2B- DisINTx-
> Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
> - Latency: 64 (250ns min, 10500ns max)
> - Interrupt: pin A routed to IRQ 28
> - IOMMU group: 2
> - Region 0: Memory at d0b02000 (32-bit, non-prefetchable) [size=4K]
> + Latency: 64 (250ns min, 10500ns max), Cache Line Size: 64 bytes
> + Interrupt: pin A routed to IRQ 18
> + Region 0: Memory at fe9ff000 (32-bit, non-prefetchable) [size=4K]
> Capabilities: [40] Power Management version 2
> Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=0mA PME(D0+,D1+,D2+,D3hot+,D3cold-)
> Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
> Kernel driver in use: ohci-pci
> Kernel modules: ohci_pci
>
> -08:00.1 USB controller: NEC Corporation OHCI USB Controller (rev 43) (prog-if 10 [OHCI])
> +03:00.1 USB controller: NEC Corporation OHCI USB Controller (rev 43) (prog-if 10 [OHCI])
> Subsystem: NEC Corporation USB Controller
> Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV+ VGASnoop- ParErr- Stepping- SERR+ FastB2B- DisINTx-
> Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
> - Latency: 64 (250ns min, 10500ns max)
> - Interrupt: pin B routed to IRQ 55
> - IOMMU group: 2
> - Region 0: Memory at d0b01000 (32-bit, non-prefetchable) [size=4K]
> + Latency: 64 (250ns min, 10500ns max), Cache Line Size: 64 bytes
> + Interrupt: pin B routed to IRQ 19
> + Region 0: Memory at fe9fe000 (32-bit, non-prefetchable) [size=4K]
> Capabilities: [40] Power Management version 2
> Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=0mA PME(D0+,D1+,D2+,D3hot+,D3cold-)
> Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
> Kernel driver in use: ohci-pci
> Kernel modules: ohci_pci
>
> -08:00.2 USB controller: NEC Corporation uPD72010x USB 2.0 Controller (rev 04) (prog-if 20 [EHCI])
> +03:00.2 USB controller: NEC Corporation uPD72010x USB 2.0 Controller (rev 04) (prog-if 20 [EHCI])
> Subsystem: NEC Corporation uPD72010x USB 2.0 Controller
> Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV+ VGASnoop- ParErr- Stepping- SERR+ FastB2B- DisINTx-
> Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
> - Latency: 68 (4000ns min, 8500ns max), Cache Line Size: 64 bytes
> - Interrupt: pin C routed to IRQ 44
> - IOMMU group: 2
> - Region 0: Memory at d0b00000 (32-bit, non-prefetchable) [size=256]
> + Latency: 64 (4000ns min, 8500ns max), Cache Line Size: 64 bytes
> + Interrupt: pin C routed to IRQ 16
> + Region 0: Memory at fe9fdc00 (32-bit, non-prefetchable) [size=256]
> Capabilities: [40] Power Management version 2
> Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=0mA PME(D0+,D1+,D2+,D3hot+,D3cold-)
> Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME+
> Kernel driver in use: ehci-pci
> Kernel modules: ehci_pci
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: USB controller broken by zero cacheline size in PCIe to PCI bridge
2026-03-16 20:06 ` Bjorn Helgaas
@ 2026-03-17 20:37 ` Michal Pecio
0 siblings, 0 replies; 3+ messages in thread
From: Michal Pecio @ 2026-03-17 20:37 UTC (permalink / raw)
To: Bjorn Helgaas; +Cc: linux-pci, Alan Stern
On Mon, 16 Mar 2026 15:06:49 -0500, Bjorn Helgaas wrote:
> Is there an actual functional problem like data corruption, or is it
> purely a performance issue?
It's functional failure - some USB devices don't even enumerate,
storage quickly gets stuck and starts being reset by USB forever,
video camera loses enough data packets that no image shows, etc.
Curiously, Windows 10 64 has similar problems and same solution -
with some hassle I got the pciutils port to work. Windows doesn't
change cache line size on any device in this machine at all.
In my case it seems that CLS only needs to be set on the bridge.
According to bridge datasheet, this value is used to decide when to
use Read, Memory Read Line, Memory Read Multiple and MWI commands.
But per PCI spec, behavior of some commands depends on cache line,
so maybe it should ideally be consistent across the bus.
> The Cache Line Size depends on the CPU, so maybe the good and bad
> machines have different CPUs? Can you collect /proc/cpuinfo for each?
>
> I don't think the Cache Line Size depends on the actual PCI devices,
> so the PCI core really should configure it for every bridge and device
> during enumeration, but I don't think it does.
Good and bad systems are both x86-64 with 64B cache line, and as you
said, it semes that Linux (and Windows) just use what the BIOS left.
I patched pci_setup_device() to print it. On bad system all devices
are zero except one out of two AHCI controllers. On good system most
are 64, though some are zero. My card gets 64. Changing it to zero
breaks the good system too.
The bad machine is a proprietary HP business PC with only PCIe slots.
> In your case, ehci_pci_reinit() might set it for the uPD72010x EHCI
> controller, and it looks like Cache Line Size is set to 64 bytes in
> both the good and bad systems.
It's odd that the kernel sets it here but trusts boot FW otherwise.
I wonder if there are any official rules for this in x86-land.
> The Cache Line Size configuration (or lack of it) is kind of a
> historical mess, and it only applies to conventional PCI, not PCIe,
> so I don't really know how to untangle it.
Not sure either. Setting proper CLS (if known) at boot would fix it.
Question is if it could break something else.
I also don't know if it's a common problem. Looks like it takes a
particular BIOS behavior, maybe a particular bridge, and a particular
device, because OHCI functions of the same NEC chip appear to work,
only EHCI is obviously broken.
Regards,
Michal
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-03-17 20:37 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-15 0:54 USB controller broken by zero cacheline size in PCIe to PCI bridge Michal Pecio
2026-03-16 20:06 ` Bjorn Helgaas
2026-03-17 20:37 ` Michal Pecio
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox