Re: How the hell does one create a new bus?!

1999-02-15 Thread Doug Rabson
[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?!

1999-02-14 Thread Bill Paul
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?!

1999-02-14 Thread Doug Rabson
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?!

1999-02-14 Thread Julian Elischer
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?!

1999-02-14 Thread Garrett Wollman
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