Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 20 May 1997 10:43:42 +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.970520102420.15296L-100000@herring.nlsystems.com>
In-Reply-To: <19970519202743.46906@x14.mi.uni-koeln.de>

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

> 
> On May 15, Doug Rabson <dfr@nlsystems.com> wrote:
> > How about this:
> 
> Seems we agree on all the stuff that I deleted ... :)
> 
> > #define ISA_RESOURCE_PORTS	0
> > #define ISA_RESOURCE_MEMORY	1
> > #define ISA_RESOURCE_IRQ	2
> > #define ISA_RESOURCE_DRQ	3
> > 
> > #define PCI_RESOURCE_MAP0	0
> > #define PCI_RESOURCE_MAP1	1
> > .....
> > 
> > 
> > enum resource_type {
> > 	RESOURCE_TYPE_PORT,
> > 	RESOURCE_TYPE_MEMORY,
> > 	RESOURCE_TYPE_IRQ,
> > 	RESOURCE_TYPE_DRQ
> > };
> > 
> > struct resource {
> > 	enum resource_type	type;
> > 	u_int			start;
> > 	u_int			size;
> > };
> > 
> > struct bus_ops {
> > 	...
> > 	struct resource *(*get_resource)(struct bus *bus, void *instance,
> > 					 int which);
> > 	int *(*map_resource)(struct bus *bus, void *instance, int which);
> > 	int *(*unmap_resource)(struct bus *bus, void *instance,
> > 			       int which);
> > 	int *(*change_resource(struct bus *bus, void *instance, int which,
> > 			       struct resource *);
> > }
> > 
> > struct bus {
> > 	...
> > 	struct bus_ops	*ops;
> > };
> > 
> > int edprobe(struct bus *bus, void *instance)
> > {
> > 	struct resource *ports;
> > 	struct resource *memory;
> > 	struct resource *irq;
> > 
> > 	ports = bus->ops->get_resource(bus, instance, ISA_RESOURCE_PORTS);
> 
> Hmmm, you are mixing a generic mechanism with a bus dependent
> constant here ...
> If you are using ISA_RESOURCE_PORTS, then you could as well 
> call just some global function get_resource() ...
> 
> > 	memory  = bus->ops->get_resource(bus, instance, 
> > 					ISA_RESOURCE_MEMORY);
> > 	irq = bus->ops->get_resource(bus, instance, ISA_RESOURCE_IRQ);
> > 	ports->size = 0x10;
> > 	bus->ops->change_resource(bus, instance, ISA_RESOURCE_PORTS);
> > 
> > 	bus->ops->map_resource(bus, instance, ISA_RESOURCE_PORTS);
> > 	bus->ops->map_resource(bus, instance, ISA_RESOURCE_MEMORY);
> > 	bus->ops->map_resource(bus, instance, ISA_RESOURCE_IRQ);
> > 
> > 	probe the device.
> > 
> > 	if (probe failed) {
> > 		bus->ops->unmap_resource(bus, instance,
> > 					ISA_RESOURCE_PORTS);
> > 		bus->ops->unmap_resource(bus, instance,
> > 					ISA_RESOURCE_MEMORY);
> > 		bus->ops->unmap_resource(bus, instance, ISA_RESOURCE_IRQ);
> > 	}
> > }
> 
> No, I don't like this, sorry..
> We are forced to use some data representation for the resource
> structure, that will be cast in stone, if we return pointers to
> data structures as you suggest for get_resource().
> 
> You do not treat the "struct resource" as an opaque data type
> (as obvious from the assignment to "ports->size"), and thus we
> have an unlucky mix of complex data structures and lack of 
> flexibility ...
> 
> I'd rather have a function that retrieves config info (which is
> not part of the resource management code) and then do conflicts
> checks and finally try to probe/attach the device. After the 
> attach succeeded, the resources will be known because of the 
> device's "isa_device" structure (or rather some more generic 
> data structure as suggested in an earlier message) will be 
> known to the resource management code ...

I realised this as soon as I started implementing it.  I now have two
kinds of operation on a bus, operations which read and write config data
and operations which manipulate resources.  The driver never accesses
config data directly (no accesses to struct isa_device) which allows the
bus to change data format or add instance variables while maintaining
binary and source compatability with old drivers.

> 
> I don't think this needs to be put into every driver, if we
> find a good concept. And that's what I'm after :)

The problem for ISA devices is that the number of ports used isn't known
until after the probe.  The bus can't manage the resources since it
doesn't know how large they are.

> 
> > Each bus and each bridge could provide its own ops vector.  Each device
> > attached to a bus would have a set of resources.  The instance pointer
> > above is a handle to the device resources.
> 
> Each device and device "location" should have an ops vector.
> The location is not just the bus, it could be a PCI to PCI bridge 
> (which behaves slightly different from a CPU to PCI bridge, and
> needs slightly different resource conflict checks for that reason).

Thats what I meant.  If a bus is something to which devices are attached
then a PCI to PCI bridge is a bus.  In my current experimentation, I have
a hierarchy of busses.  At each level in the hierarchy a bus has both a
device part (attached to the parent bus) and a bus part (for child devices
to attach to).

> [config file stuff snipped]
> > Shouldn't this be:
> > 
> > 	sd:0:char:13:0:0640:ROOT:OPERATOR:...
> > 	sd:0:block:4:0:...
> > 
> > Translating to english:
> > 
> > 	Data for sd, unit zero, type is character device
> > 		(major=13,minor=0,...)
> > 	Data for sd, unit zero, type is block device
> > 		(major=4,minor=0,...)
> 
> No, it shouldn't :)
> But I was also wrong with the excample I gave ...
> 
> It should be:
> 
> 	char:13:sd
> 	sd:0:devfs:0640:ROOT:OPERATOR
> 	sd:-1:devfs:0600:ROOT:OPERATOR
> 
> (This is my suggestion for a wild card unit number, but this would be
> handled by a program asking for the config data in such a way, that
> wherever this is appropriate, config data for unit -1 is retrieved, 
> if nothing could be found for the actual unit.)

I still don't understand.  All the entries for different major numbers
would then have a different type:

	char:3:wd
	char:13:sd
	char:29:mcd

I hate major numbers anyway.  Devfs should dynamically allocate majors and
everyone should use devfs.  That means making devfs work properly...

> No, I don't think we want the compiled in defaults :)
> 
> Well, kind of: I'd have "config" create a textual representation similar
> to that found in the config file. If a request for config data can't be 
> satisfied from the file's data, then the kernel's text array will be 
> scanned for it. Guess we should have three separate config "texts",
> in fact:
> 
> 1) compiled in
> 2) loaded into RAM by the boot loader
> 3) dynamically allocated by userconfig
> 
> and config data should be preferred from the higher number "texts".

As long as there is some config data compiled into the kernel to fall back
to, I don't care what form its in.  This sounds fine to me.  It should
also be possible to add config data at runtime for dynamically loaded
devices.

--
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.970520102420.15296L-100000>