The following diff adds a workaround for an issue with the VIA VT6202
EHCI controller hogging the PCI bus and causing poor performance for
IDE and possibly other devices in the system.
Please test if your system has a VIA VT6202 EHCI controller and
provide a dmesg. If the workaround is being applied for the
chipset you have then a message will be printed (this is temporary
only to verify it is being applied for the appropriate revision
of the chipset).
>From Linux
Index: ehci_pci.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/ehci_pci.c,v
retrieving revision 1.16
diff -u -p -r1.16 ehci_pci.c
--- ehci_pci.c 25 Jun 2009 01:01:44 -0000 1.16
+++ ehci_pci.c 25 Jun 2009 01:57:55 -0000
@@ -69,6 +69,7 @@ int ehci_sb700_match(struct pci_attach_a
#define EHCI_SBx00_WORKAROUND_REG 0x50
#define EHCI_SBx00_WORKAROUND_ENABLE (1 << 3)
+#define EHCI_VT6202_WORKAROUND_REG 0x4b
int ehci_pci_match(struct device *, void *, void *);
void ehci_pci_attach(struct device *, struct device *, void *);
@@ -127,18 +128,40 @@ ehci_pci_attach(struct device *parent, s
EOWRITE2(&sc->sc, EHCI_USBINTR, 0);
/* Handle quirks */
- if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_ATI &&
- ((PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ATI_SB600_EHCI ||
- (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ATI_SB700_EHCI &&
- pci_find_device(NULL, ehci_sb700_match))))) {
- pcireg_t value;
-
- /* apply the ATI SB600/SB700 workaround */
- value = pci_conf_read(sc->sc_pc, sc->sc_tag,
- EHCI_SBx00_WORKAROUND_REG);
- pci_conf_write(sc->sc_pc, sc->sc_tag,
- EHCI_SBx00_WORKAROUND_REG, value |
- EHCI_SBx00_WORKAROUND_ENABLE);
+ switch (PCI_VENDOR(pa->pa_id)) {
+ case PCI_VENDOR_ATI:
+ if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ATI_SB600_EHCI ||
+ (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ATI_SB700_EHCI &&
+ pci_find_device(NULL, ehci_sb700_match))) {
+ pcireg_t value;
+
+ /* apply the ATI SB600/SB700 workaround */
+ value = pci_conf_read(sc->sc_pc, sc->sc_tag,
+ EHCI_SBx00_WORKAROUND_REG);
+ pci_conf_write(sc->sc_pc, sc->sc_tag,
+ EHCI_SBx00_WORKAROUND_REG, value |
+ EHCI_SBx00_WORKAROUND_ENABLE);
+ }
+ break;
+
+ case PCI_VENDOR_VIATECH:
+ if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_VIATECH_VT6202 &&
+ (PCI_REVISION(pa->pa_class) & 0xf0) == 0x60) {
+ pcireg_t value;
+
+ /*
+ * The VT6202 defaults to a 1 usec EHCI sleep time
+ * which hogs the PCI bus *badly*. Setting bit 5 of
+ * the register makes that sleep time use the
conventional
+ * 10 usec.
+ */
+ printf(", applying VIA VT6202 controller workaround");
+ value = pci_conf_read(sc->sc_pc, sc->sc_tag,
+ EHCI_VT6202_WORKAROUND_REG);
+ pci_conf_write(sc->sc_pc, sc->sc_tag,
+ EHCI_VT6202_WORKAROUND_REG, value | 0x20);
+ }
+ break;
}
/* Map and establish the interrupt. */
--
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.