Current-Users archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: USB troubles with SB600/SB700 chipsets



Markus W Kilbinger wrote:
>>>>>> "Christoph" == Christoph Egger <Christoph_Egger%gmx.de@localhost> writes:
> 
>     Christoph> Hi, a new version of this patch. It mainly avoids a lot
>     Christoph> of code duplication. The orders how test it still
>     Christoph> apply.
> 
> Your second patch and my 'PCI_REVISION(pa->pa_id)' case 0x02 extension
> yield at least a working kernel again which shows
> 
>   amdehci0 at pci0 dev 18 function 2: ATI Technologies SB700/SB800 USB EHCI 
> Controller (rev. 0x00)
>   amdehci0: interrupting at ioapic0 pin 17
>   amdehci0: dropped intr workaround enabled
>   amdehci0: applying AMD SB600/SB700 USB freeze workaround
>   amdehci0: EHCI version 1.0
>   amdehci0: companion controllers, 3 ports each: ohci0 ohci1
> 
> , but does not change/solve any of my PR 40056's mentioned problems.

hm... maybe the quirk is applied too late. New attached patch version
applies it *before* the chip is enabled.

>     Christoph> Can you show me the dmesg lines of your SMBus Controller, 
> please ?
> 
> Sure:
> 
>   /sbin/dmesg | grep -i smb
>   piixpm0: ATI Technologies SB600/SB700/SB800 SMBus Controller (rev. 0x3a)
> 
> Hmm, shouldn't that be the '0x3a' in the switch-case's?

Yes. Should be fixed in new patch version.

Christoph

Index: sys/dev/pci/ehci_pci.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/ehci_pci.c,v
retrieving revision 1.44
diff -u -p -r1.44 ehci_pci.c
--- sys/dev/pci/ehci_pci.c      26 Apr 2009 09:47:31 -0000      1.44
+++ sys/dev/pci/ehci_pci.c      18 May 2009 06:57:28 -0000
@@ -74,9 +74,87 @@ struct ehci_pci_softc {
        void                    *sc_ih;         /* interrupt vectoring */
 };
 
+static int (*ehci_pci_applyquirks)(struct ehci_pci_softc *) = NULL;
+
 #define EHCI_MAX_BIOS_WAIT             1000 /* ms */
 
 static int
+ehci_pci_match(device_t, cfdata_t, void *);
+static void ehci_pci_attach(device_t, device_t, void *);
+static int ehci_pci_detach(device_t, int);
+
+CFATTACH_DECL3_NEW(ehci_pci, sizeof(struct ehci_pci_softc),
+    ehci_pci_match, ehci_pci_attach, ehci_pci_detach, ehci_activate, NULL,
+    ehci_childdet, DVF_DETACH_SHUTDOWN);
+
+
+static int amdehci_match(device_t, cfdata_t, void *);
+static void amdehci_attach(device_t, device_t, void *);
+
+CFATTACH_DECL3_NEW(amdehci, sizeof(struct ehci_pci_softc),
+    amdehci_match, amdehci_attach, ehci_pci_detach, ehci_activate, NULL,
+    ehci_childdet, DVF_DETACH_SHUTDOWN);
+
+
+static int
+amdehci_sb700_match(struct pci_attach_args *pa)
+{
+       if (!(PCI_VENDOR(pa->pa_id) == PCI_VENDOR_ATI &&
+           PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ATI_SB600_SMB))
+               return 0;
+
+       switch (PCI_REVISION(pa->pa_class)) {
+       case 0x3a:
+       case 0x3b:
+               return 1;
+       }
+
+       return 0;
+}
+
+static int
+amdehci_match(device_t parent, cfdata_t match, void *aux)
+{
+        struct pci_attach_args *pa = (struct pci_attach_args *) aux;
+
+        if (!(PCI_CLASS(pa->pa_class) == PCI_CLASS_SERIALBUS &&
+            PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_SERIALBUS_USB &&
+            PCI_INTERFACE(pa->pa_class) == PCI_INTERFACE_EHCI &&
+            PCI_VENDOR(pa->pa_id) == PCI_VENDOR_ATI))
+                return 0;
+
+        switch (PCI_PRODUCT(pa->pa_id)) {
+        case PCI_PRODUCT_ATI_SB600_USB_EHCI:
+                return 10;    /* beat ehci_pci */
+        case PCI_PRODUCT_ATI_SB700_USB_EHCI:
+                if (pci_find_device(NULL, amdehci_sb700_match))
+                        return 10;    /* beat ehci_pci */
+        default:
+                return 0;
+        }
+}
+
+static int
+amdehci_applyquirks(struct ehci_pci_softc *sc)
+{
+        uint8_t value;
+
+        aprint_normal_dev(sc->sc.sc_dev,
+            "applying AMD SB600/SB700 USB freeze workaround\n");
+        value = pci_conf_read(sc->sc_pc, sc->sc_tag, 0x53);
+        pci_conf_write(sc->sc_pc, sc->sc_tag, 0x53, value | (1U << 3));
+
+        return 0;
+}
+
+static void
+amdehci_attach(device_t parent, device_t self, void *aux)
+{
+       ehci_pci_applyquirks = amdehci_applyquirks;
+       ehci_pci_attach(parent, self, aux);
+}
+
+static int
 ehci_pci_match(device_t parent, cfdata_t match, void *aux)
 {
        struct pci_attach_args *pa = (struct pci_attach_args *) aux;
@@ -131,6 +209,9 @@ ehci_pci_attach(device_t parent, device_
        sc->sc_tag = tag;
        sc->sc.sc_bus.dmatag = pa->pa_dmat;
 
+       if (ehci_pci_applyquirks)
+               ehci_pci_applyquirks(sc);
+
        /* Enable the device. */
        csr = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG);
        pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG,
@@ -265,10 +346,6 @@ ehci_pci_detach(device_t self, int flags
        return 0;
 }
 
-CFATTACH_DECL3_NEW(ehci_pci, sizeof(struct ehci_pci_softc),
-    ehci_pci_match, ehci_pci_attach, ehci_pci_detach, ehci_activate, NULL,
-    ehci_childdet, DVF_DETACH_SHUTDOWN);
-
 #ifdef EHCI_DEBUG
 static void
 ehci_dump_caps(ehci_softc_t *sc, pci_chipset_tag_t pc, pcitag_t tag)
Index: sys/dev/pci/files.pci
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/files.pci,v
retrieving revision 1.314
diff -u -p -r1.314 files.pci
--- sys/dev/pci/files.pci       21 Apr 2009 03:00:29 -0000      1.314
+++ sys/dev/pci/files.pci       18 May 2009 06:57:29 -0000
@@ -588,9 +588,13 @@ file       dev/pci/uhci_pci.c              uhci_pci
 attach ohci at pci with ohci_pci
 file   dev/pci/ohci_pci.c              ohci_pci
 
+# AMD SB600/SB700 EHCI USB controller
+device  amdehci: usbus, usbroothub
+attach amdehci at pci
+
 # EHCI USB controller
 attach ehci at pci with ehci_pci
-file   dev/pci/ehci_pci.c              ehci_pci
+file   dev/pci/ehci_pci.c              ehci_pci | amdehci
 
 file   dev/pci/usb_pci.c               ehci_pci | ehci_cardbus
 


Home | Main Index | Thread Index | Old Index