Skip site navigation (1)Skip section navigation (2)
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>