Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 14 May 1997 16:27:37 +0100 (BST)
From:      Doug Rabson <dfr@nlsystems.com>
To:        Stefan Esser <se@freebsd.org>
Cc:        Michael Smith <msmith@atrad.adelaide.edu.au>, current@freebsd.org
Subject:   Re: Backwards compatibiliy for isa_driver
Message-ID:  <Pine.BSF.3.95q.970514155612.947P-100000@herring.nlsystems.com>
In-Reply-To: <19970513114307.17799@x14.mi.uni-koeln.de>

next in thread | previous in thread | raw e-mail | index | archive | help
On Tue, 13 May 1997, Stefan Esser wrote:

> On May 13, Michael Smith <msmith@atrad.adelaide.edu.au> wrote:
> > Before you go any further with this, you should check with the
> > Alpha people, and have a look at the NetBSD code for the 
> > same thing.
> 
> Yes, I'm willing to do that ...
> 
> > Whilst I found the documentation for the NetBSD approach to
> > be pathetic (read: nonexistent), it was relatively easy to
> > find enough examples to get something going.
> 
> > The NetBSD approach blurs the distinction between "bus" and
> > "device", which I think is _the_ critical point.  A nested
> > bus is a "device" on its parent bus, but a "bus" to devices
> > below it.
> 
> Yes, I fully agree. That's exactly what I was planning.
> I have seperated the data into several data structures:
> 
> 1) Structure common to all devices, values private per
>    device instance:
> 
> 	- Unit number
> 	- Operational state

OK.

> 
> 2) Structure depends on bus type, values private per
>    device instance, maintained by the "device" above,
>    which happens to be a "bus device":
> 
> 	- "wired position" (e.g. "at pci1 slot 4")
> 	- probemessage()
> 	- resources

While I was daydreaming about this stuff, I imagined that the resources
could be stored in a database (sysctl?).  This would be filled in from
various sources, isa static device data, isapnp device data, pci etc.

Since the location of the data is hidden, instead of in explicit memory
structures, it can be read into the kernel from a config file.  The kernel
could then load the appropriate drivers and call the probe routines.

For instance:

	dev			Root of all device resources
	dev.isa			All isa devices
	dev.isa.ed		All resources for ed devices
	dev.isa.ed.0		Resources for ed0 device
	dev.isa.ed.0.port	Integer for first ioport
	dev.isa.ed.0.portsize	Integer for ioport range
	dev.isa.ed.0.mem	Memory region
	dev.isa.ed.0.memsize	Memory region size
	dev.isa.ed.0.irq	etc.

The probe (and attach) routine would get a handle to the node containing
its resources:

edprobe(..., sysctl_node_t resources)
{
	...
	port = sysctl_read_integer(resources, "port");
	sysctl_write_integer(resources, "portsize", ED_PORT_RANGE);
}

Actually, now that I think about it, the resources should be more uniform:

	dev.isa.ed.0.port.type = io
	dev.isa.ed.0.port.start = 0x3d0
	dev.isa.ed.0.port.size = 0x10
	dev.isa.ed.0.mem.type = mem
	dev.isa.ed.0.mem.start = 0xd0000
	dev.isa.ed.0.mem.size = 0x1000
	dev.isa.ed.0.irq.type = irq
	dev.isa.ed.0.irq.start = 5
	dev.isa.ed.0.irq.size = 1

Then one could write code like:

	ports = sysctl_get_handle(resources, "port");
	sc->sc_port = sysctl_read_integer(ports, "start");
	sysctl_write_integer(ports, "size", real_port_range);
	if (error = resource_check(ports))
		giveup;

The resource_check function would figure out the type of the resource and
act appropriately.

> 
> 3) Driver specific data structure, values private per
>    device instance:
> 
> 	- xxx_softc
> 
> 4) Common data structure, values private per driver but
>    shared by all instances of this device type:
> 
> 	- drvname
> 	- numunits
> 	- maxunits
> 	- probe()
> 	- attach()
> 	- shutdown()
> 
> Of course, the struct components are not meant to be a
> complete list, just a few typical examples ...

I would add detach() to that list.  I want all drivers to be loadable
*and* unloadable.  The detach() routine would be called when the driver is
unloaded.

> 
> > Hmm, Doug R. and I are just opening a discussion on a "resource manager"
> > (someone just threw a PnP card at me, heh) which might well be relevant 
> > in this context.
> 
> I found a $15 PnP sound card, which I bought just for
> playing with ISA PnP ... :)
> 
> My implementation of resource management uses the 
> following functions:
> 
> 	devdata *resource_check (unsigned type, unsigned flags, 
> 				 addr_t low, addr_t high);
> 
> 	int resource_claim (devdata *dev, unsigned type, unsigned flags, 
> 			    addr_t low, addr_t high);
> 
> 	void resource_free (devdata *dev);
> 
> The following resource types are currently defined:
> 
> 	#define REST_NONE	0x00
> 	#define REST_MEM	0x01
> 	#define REST_PORT	0x02
> 	#define REST_INT	0x03
> 	#define REST_DMA	0x04
> 	#define REST_MAX	0x04
> 
> And these are the only valid "flags" values, currently:
> 
> 	#define RESF_NONE	0x00
> 	#define RESF_SHARED	0x01
> 
> Simplified example:
> 
> 	if ((otherdev = resource_check(REST_IRQ, RESF_SHARED, irq, irq) != NULL)
> 	{
> 		printf("irq conflict with device: %s", devname(otherdev));
> 		return -1;
> 	}
> 
> The actual resource check can be either a function of the
> "bus device" operating on data from section 2) above, or
> (in my current implementation) is a common function, which
> maintains its own resource database (and needs the function
> resource_claim() to add resources to this database).
> 
> > There was mention of a NetBSD "extent allocator" which I need to follow
> > through. 
> > 
> > Jason T., are you reading this?  A few quick words in summary would
> > be handy...
> 
> I'd be very interested in pointers to further information,
> too ...

I just read through NetBSD's extent allocator (sys/kern/subr_extent.c) and
it looks pretty useful.  You could certainly use it as the implementation
of your resource functions.

--
Doug Rabson				Mail:  dfr@nlsystems.com
Nonlinear Systems Ltd.			Phone: +44 181 951 1891




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.3.95q.970514155612.947P-100000>