Re: How the hell does one create a new bus?!
[hackers removed from Cc to prevent excessive crossposting] On Sun, 14 Feb 1999, Garrett Wollman wrote: On Sun, 14 Feb 1999 16:44:37 -0800 (PST), Julian Elischer jul...@whistle.com said: The trouble is Doug, that until there IS a developer's guide, the only person capable if moving PCI and ISA to your scheme, is you. and as you pointed out.. you're short of time right now.. No, there are more people than just Doug. Certainly me (if I had time), Nicolas (if he had time), probably Andrew Gallatin since he's done a lot of work on the Alpha side of things (but he probably has no more time than the rest of us). Don't forget Nick Hibma. He should be quite familiar with the system after working on the USB code. There is a proper mailing list for this discussion, and we'd be happy to talk over any doco that someone should choose to write. Please take any followups to new-bus-a...@bostonradio.org. Good idea. -- Doug Rabson Mail: d...@nlsystems.com Nonlinear Systems Ltd. Phone: +44 181 442 9037 To Unsubscribe: send mail to majord...@freebsd.org with unsubscribe freebsd-current in the body of the message
How the hell does one create a new bus?!
G. Alright, I give up: how does one create a new 'bus' layer? By that I mean like /sys/dev/iicbus and /sys/dev/smbus. Yes, I've read the code in these two directories, but I'm confused as to which parts relate to the bus architecture in general and which parts are speficic to the I2C and system management implementation. From what I can tell, you need the following: - foobus_if.m, a file which describes the functions that drivers for devices attached to this kind bus can perform. - foobus.c and foobus.h WHAT EXACTLY GOES IN HERE!? - fooconf.c and fooconf.h WHAT EXACTLY GOES IN HERE!? - Some type of top level driver for the device which implements the bus. - Various drivers for devices attached to the bus. In my particular case, I'm trying to create a bus layer for MII-compliant PHYs attached to ethernet controller chips. The ethernet controller is the bus controller device: each MII management bus can have up to 32 PHY devices attached to it (though in general you rarely have more than two). Each ethernet driver exports three functions to the MII code: mii_read(), mii_write() and mii_statchg(). The first two allow reading and writing of the registers of a PHY at a particular address (i.e. mii_read(dev, phyadd, regaddr), mii_write(dev, phyaddr, regaddr, val)). The mii_statchg() routine is a callback routine: when one of the lower-level PHY drivers does a media change, it calls back to the ethernet driver to let it know. (This is necessary because some media changes also require updating registers on the ethernet controller itself. For instance, on the ThunderLAN chip, if the PHY is set for full duplex, the ThunderLAN chip itself also has to be programmed for full duplex at the same time). The PHY drivers themselves (as they are now) export three functions to the MII glue code: foophy_probe(), foophy_attach() and foophy_service(). The middle MII layer exports mii_phy_probe(), mii_pollstat(), mii_statchg() and mii_tick() back to the ethernet driver. I've faked things up for now using linker sets, but I'd prefer to make everything fit into the bus framework if possible. Unfortunately, there doesn't appear to be a nice generic example that shows how to create a new bus layer, and the existing code confuses the hell out of me. For example, both the iicbus and smbus code use interrupt routines, but the MII code doesn't need interrupts (PHY devices don't normally generate interrupts). Also, how do I know exactly what goes into the foobus.c and fooconf.c modules? The smbconf.c and iiconf.c modules appear to have 'request_bus' routines that do things with tsleep(); what is this for? Does every bus need this or is it specific to the I2C and SMB stuff? The ppbus code is no help as it doesn't actually use this framework, and the usb bus stuff is a mutant pile of macros and #ifdefs. What this stuff needs is a developer's guide; a clearcut explanation of how to create new busses, how to create top level bus drivers and how to create drivers for devices attached to busses. If anyone can point me at such a guide or can just explain to me how this nonsense is supposed to work, I'd be grateful. -Bill -- = -Bill Paul(212) 854-6020 | System Manager, Master of Unix-Fu Work: wp...@ctr.columbia.edu | Center for Telecommunications Research Home: wp...@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 majord...@freebsd.org with unsubscribe freebsd-current in the body of the message
Re: How the hell does one create a new bus?!
On Sun, 14 Feb 1999, Bill Paul wrote: G. Alright, I give up: how does one create a new 'bus' layer? By that I mean like /sys/dev/iicbus and /sys/dev/smbus. Yes, I've read the code in these two directories, but I'm confused as to which parts relate to the bus architecture in general and which parts are speficic to the I2C and system management implementation. From what I can tell, you need the following: - foobus_if.m, a file which describes the functions that drivers for devices attached to this kind bus can perform. Each xxx_if.m file defines a set of functions which are implemented by (some) drivers as you can see. This can be used in a couple of ways: 1. If a number of different types of the 'bus' hardware can have the same set of child devices, one can define an interface which each of the different bus device implements that can be called by the attached child devices to hide the differences between the hardware. Code in the drivers for child devices might look like this: /* * A ficitious 'probe' method for a device attached to a pci bus. */ int foo_probe(device_t dev) { /* Call a function in the PCI interface on our parent */ if (PCI_READ_CONFIG(device_get_parent(dev), dev, 123, 4) == 456) return ENXIO; } 2. If all the devices attached to a bus can perform similar functions (but implement them in different ways), an interface can be defined to describe these functions. This interface can be called by any client which needs to use the device. In this case, each driver would implement the method, looking something like this: /* * Implementation of BOGUS_SET_LEVEL for the foo driver. */ static void foo_set_level(device_t dev, unsigned int level) { ...; } ... static device_method_t foo_methods[] = { /* Device interface */ ...; /* Bogus interface */ DEVMETHOD(bogus_set_level, foo_set_level), { 0, 0 } }; for an interface declaration (bogus_if.m) which looked like this: INTERFACE bogus; METHOD void set_level { device_tdev; unsigned intlevel; }; - foobus.c and foobus.h WHAT EXACTLY GOES IN HERE!? - fooconf.c and fooconf.h WHAT EXACTLY GOES IN HERE!? There really isn't any naming convention for files which make up the implementation of a driver (a bus is just a driver which implements the BUS interface and which contains some kind of support for adding child devices either by a PnP scan or by config(8) supplied tables). For SMB, the implementation of the smbus driver seems to be in smbus.[ch], with some kind of utility functions in smbconf.[ch]. To write a file with a 'minimum' driver (in this case a driver named 'foo' attached to a bus named 'bogus'), you might have something like this: struct foo_softc { ...; }; static devclass_t foo_devclass; #define FOO_SOFTC(unit) (struct foo_softc*) \ devclass_get_softc(foo_devclass, unit) static int foo_probe(device_t dev) { if (device exists) return 0; else return ENXIO; } static int foo_attach(device_t dev) { device_printf(dev, I'm alive\n); return 0; } static device_method_t foo_methods[] = { /* Device interface */ DEVMETHOD(device_probe, foo_probe), DEVMETHOD(device_attach,foo_attach), { 0, 0 } }; static driver_t foo_driver = { foo, /* driver name */ foo_methods,/* implementation */ DRIVER_TYPE_NET,/* interrupt class */ sizeof(struct foo_softc), /* size of driver scratch */ }; DRIVER_MODULE(foo, bogus, foo_driver, foo_devclass, 0, 0); - Some type of top level driver for the device which implements the bus. The implementation of a 'bus' device requires implementing a few extra methods. Typically bus_print_child and bus_read_ivar are implemented by most busses. Generic implementations for many of the bus functions are provided (e.g. bus_generic_print_child) but these must be explicitly specified in the method table (there is no automatic fallback mechanism). Most bus drivers will add child devices to themselves during either probe or attach and will call bus_generic_attach() from their attach method (or just use bus_generic_attach directly instead of having their own implementation of attach) to probe and
Re: How the hell does one create a new bus?!
The trouble is Doug, that until there IS a developer's guide, the only person capable if moving PCI and ISA to your scheme, is you. and as you pointed out.. you're short of time right now.. This stuff is very cryptic. On Mon, 15 Feb 1999, Doug Rabson wrote: I hope I've explained some things. There isn't a developer's guide as yet, I'm afraid and I don't really have time to write one :-(. Perhaps one of the people who has used the code might like to tackle it (or you might if you manage to struggle through implementing this thing...) If anyone wants to write such a guide, please go ahead and feel free to ask me any questions about how the thing is supposed to work. This email in itself has cleared up a few things.. but there is still a nead for a more general overview which should be read before getting to this level of detail.. julian To Unsubscribe: send mail to majord...@freebsd.org with unsubscribe freebsd-current in the body of the message
Re: How the hell does one create a new bus?!
On Sun, 14 Feb 1999 16:44:37 -0800 (PST), Julian Elischer jul...@whistle.com said: The trouble is Doug, that until there IS a developer's guide, the only person capable if moving PCI and ISA to your scheme, is you. and as you pointed out.. you're short of time right now.. No, there are more people than just Doug. Certainly me (if I had time), Nicolas (if he had time), probably Andrew Gallatin since he's done a lot of work on the Alpha side of things (but he probably has no more time than the rest of us). There is a proper mailing list for this discussion, and we'd be happy to talk over any doco that someone should choose to write. Please take any followups to new-bus-a...@bostonradio.org. -GAWollman -- Garrett A. Wollman | O Siem / We are all family / O Siem / We're all the same woll...@lcs.mit.edu | O Siem / The fires of freedom Opinions not those of| Dance in the burning flame MIT, LCS, CRS, or NSA| - Susan Aglukark and Chad Irschick To Unsubscribe: send mail to majord...@freebsd.org with unsubscribe freebsd-current in the body of the message