The case of the missing USB controllers

Bill Paul wpaul at FreeBSD.ORG
Sun Oct 23 20:16:15 PDT 2005

> In message: <20051024021606.5BB9D16A420 at>
>             wpaul at (Bill Paul) writes:
> : Well, after some investigation and experimentation, I came up with the
> : following patch for src/sys/dev/pci/pci.c which seems to fix the problem,
> : at least on my machine:
> : 
> :
> : 
> : I'm not entirely sure why this works, but it does. The pci_add_children()
> : routine traverses each PCI bus by trying to read the header type field
> : at offset 0x0e. It does this for each possible slot number from 0 to 31.
> : A value of 0xFF indicates a failure to read the PCI config space at a
> : given slot number, which usually means there's no device there.
> Usually, but not always.
> : Unfortunately, it appears that sometimes it gets back 0xFF when trying
> : to read the header type field for the USB controllers (which are actually
> : three function at a single device index), even though the device is
> : really there.
> Then chances are there's something else wrong.  You also get 0xff when
> you have a child device of pci bridge whose bus/secbus/subbus is setup
> wrong.  I have some patches cooking to solve this problem that some
> people are seeing on some laptops.
> When it returns 0xff, that should be > the 2, and we should ignore the
> device...
> It looks like what you are saying that if you read the vendor ID then
> the header type wil read back correctly?  Is that the case?

Yes. However, another patch which seems equally effective is and has
no side effects is:

*** pci.c.orig  Sun Oct 23 15:31:23 2005
--- pci.c       Sun Oct 23 20:07:58 2005
*** 991,996 ****
--- 991,997 ----
        for (s = 0; s <= maxslots; s++) {
                pcifunchigh = 0;
                f = 0;
+               DELAY(100);
                hdrtype = REG(PCIR_HDRTYPE, 1);
                if ((hdrtype & PCIM_HDRTYPE) > PCI_MAXHDRTYPE)

Note that the devices in question are NEC ohci and ehci controllers.
It appears that there's a single device containing three functions
(two ohci + one ehci). The AMD8111 has built-in USB support, but
this has been disabled and an external device used instead because
the USB 2.0 support in the AMD8111 is broken.

The configuration for the PCI-PCI bridge where the USB devices live
doesn't seem to change between a good boot and a bad one, so I don't
really know what to look for.

> : I rummaged around a bit and found the OpenSolaris source code that
> : enumerates PCI buses, and that code uses a slightly different algorithm:
> : for each slot number, it first tries to read the PCI vendor ID field.
> : If that value is valid, then it tries to read the header type field.
> : The patch above implements the Solaris behavior and seems to allow
> : FreeBSD/amd64 to detect the USB ports reliably. (I've rebooted the
> : system a bunch of times and so far it's been successful.)
> : 
> : Logically, this should not have any negative impact in any other cases.
> : Can someone else who has this problem test this patch and tell me if it
> : helps? Can anyone think of a reason why this patch shouldn't be checked
> : in?
> Yes.  We went through a lot of consternation with some PCI ethernet
> cards made by sun.  They have 0xffff listed as the function 0 vendor,
> but the header type was correct.  The ethernet lived in function 1.
> You change will break those.  We used to implement what you suggested,
> but purposely changed it away from that.

That's sort of peculiar. I looked at:

And in enumerate_bus_devs() it says:

    331 			venid = pci_getw(bus, dev, func, PCI_CONF_VENID);
    332 			if ((venid == 0xffff) || (venid == 0)) {
    333 				/* no function at this address */
    334 				continue;
    335 			}

Probably the cards in question were designed for SPARC machines and
depended on some special OpenFirware magic to be detected correctly.


-Bill Paul            (510) 749-2329 | Senior Engineer, Master of Unix-Fu
                 wpaul at | Wind River Systems
              <adamw> you're just BEGGING to face the moose

More information about the freebsd-current mailing list