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.

Reply via email to