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>
index | next in thread | previous in thread | raw e-mail
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
help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.3.95q.970514155612.947P-100000>
