Date: Mon, 31 May 1999 19:09:23 -0400 (EDT) From: Bill Paul <wpaul@skynet.ctr.columbia.edu> To: hackers@freebsd.org Cc: dfr@freebsd.org Subject: Using newbus to hang a custom bus off a device Message-ID: <199905312309.TAA04790@skynet.ctr.columbia.edu>
next in thread | raw e-mail | index | archive | help
Well, after a bit of head scratching, I finally think I've gotten the
hang of the new bus architecture stuff (in general that is, not just
the new ISA and PCI stuff). I'm trying to create an miibus framework so
that I can have an miibus attached to those PCI ethernet drivers which
support MII-based transceivers, to which I can attach transceiver
drivers. I'm still a little confused by something though, probably
because I'm trying to do the development on 3.2-RELEASE (I don't have
a machine that I can clobber with -current just at the moment).
Basically what I have is this:
- An miibus_if.m file which describes the methods implemented by miibus
drivers. There are three methodes: a readreg method, which lets you
read a given register from a given PHY on the MII bus, a writereg
method, which lets you write a value to a given register on a given
PHY on the MII bus, and a status change method, which lets you tell
the driver which implements the miibus support that the status of a
PHY has changed and that the controller needs to update some state to
match it. (This is mainly to deal with controllers that have speed
and duplex settings that operate independently of the PHY: if the
PHY negotiates 100Mbps full duplex, then the controller chip to which
the PHY is attached may also need to be explicitly programmed for
100Mbps full duplex to match the PHY.)
- A stub mii PHY driver, which has its own probe and attach functions,
and which uses the following DRIVER_MODULE() macro:
DRIVER_MODULE(miigeneric, miibus, mii_driver, mii_devclass, 0, 0);
- Some stub code to be inserted into a NIC driver which implements
the miibus support. The code provides a probe routine (which checks
for MII support on the controller) but uses bus_generic_attach for
its attach routine. This, I believe, allows all of the mii driver
probes to be invoked after the bus is attached. The NIC driver also
uses a DRIVER_MODULE() macro like this:
DRIVER_MODULE(miibus, ax, miibus_driver, miibus_devclass, 0, 0);
(Here, "ax" represents the if_ax driver, which is what I used for
testing since the ASIX chipset uses an MII-based transeiver.)
So, here's how I understand this: the MII driver is declared to be
in the 'miibus' devclass. And the if_ax driver declares an miibus device
which is attached to the ax devclass. Since this is 3.2-RELEASE,
I manually attach the ax device to the root_bus devclass using
device_add_child(). Then I do the following:
miibus = device_add_child(sc->ax_device, "miibus", -1, NULL);
if (device_probe_and_attach(miibus)) {
device_delete_child(sc->ax_device, miibus);
return(ENODEV);
}
Now, this is where I had to do some looking around: the fact that you
need to use device_add_child() is not clearly spelled out in the man
pages. Basically, the fact that the DRIVER_MODULE() modules declare
the driver hierarchy does not mean than device instances are actually
created. The DRIVER_MODULE() macros basically tell the system to expect
that an miibus could be created as a child of an ax device instance, and
that an miigeneric device could be created as a child of an miibus instance,
but you actually need to use device_add_child() to call the device
instance into existence.
Similarly, in the miibus probe routine, you have to check for PHYs
on the miibus and call device_add_child() to create a device node
for each PHY on the bus. (I use device_add_child(dev, NULL, -1, NULL)
for this, because you don't know ahead of time exactly which driver
will be attached.) Then, bus_generic_attach() will call the probe
routines of all the PHY drivers that are declared to be in the miibus
devclass, and whichever driver supports the discovered PHY claims the
device instance.
Now, given all that, here are the questions that I have:
- In -current, assuming that a PCI NIC driver has been properly
newbus-ified, is it still necessary for the driver to manually
call device_add_child() to create the miibus device instance and then
call device_probe_and_attach() to get the PHY drivers into the
picture? I think the answer is yes, because I don't see any other
way for it to work.
- Suppose that I want to probe for PHYs on the miibus in a particular
order? All MII-compliant PHYs implement a standard set of registers,
so in theory it's possible to write just a single generic PHY driver
which will handle all PHYs. However, sometimes a given PHY will
require some special handling. So, what I want to do is have expliclt
PHY drivers to handle certain PHYs and have a catch-all generic driver
to handle any other device that isn't handled by one of the explicit
PHY drivers. This implies that the probe routine of the generic device
will be invoked last. If the generic device probe is invoked first,
then all PHYs will get the generic driver attached, which is not what
I want. Is there some way to weight the drivers such that the specific
ones will have a higher priority than the generic one, thereby forcing
the specific probes to be called first?
-Bill
--
=============================================================================
-Bill Paul (212) 854-6020 | System Manager, Master of Unix-Fu
Work: wpaul@ctr.columbia.edu | Center for Telecommunications Research
Home: wpaul@skynet.ctr.columbia.edu | Columbia University, New York City
=============================================================================
"It is not I who am crazy; it is I who am mad!" - Ren Hoek, "Space Madness"
=============================================================================
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199905312309.TAA04790>
