1999-03-17 03:44:05

by David Hinds

[permalink] [raw]
Subject: Ideas for abstracting driver IO from bus implementation?

This is sort-of a PCMCIA specific issue at the moment, but could be
thought of as a more general kernel driver issue, so I thought I'd put
it out for comments, to see if anyone [Alan??] has any clever thoughts.

On a normal x86 (or PowerPC) laptop, PCMCIA bridges are designed to
map cards directly into the host IO and memory spaces at arbitrary
addresses, and a stock ISA or PCI driver generally doesn't care if it
is talking to a normal device or a device on a PCMCIA card. However,
there are a number of PCMCIA architectures in which cards are not
accessed through the same abstractions used to access other types of
system devices. For example, there are SCSI-to-PCMCIA adapters,
parallel-to-PCMCIA adapters, SBUS-to-PCMCIA adapters, and various
specialized bridge chips that sit on the system bus but do not allow
PCMCIA devices to be arbitrarily configured to mimic the corresponding
type of directly connected system device.

In the official PCMCIA way of doing things, say in the Windows world,
these each require a dedicated Card Services stack, and client drivers
that know about how a particular bridging system works. There is some
support for an abstraction layer for memory cards, but that's all, and
I don't know if it is even implemented by any existing software.

So, I'm wondering how to deal with this in some clean fashion. I've
had a whole bunch of inquiries about this in the past month or two,
for all sorts of unusual hardware setups (ARM embedded designs, Sparc
platform, Amiga, etc). And I think it would be nice to handle all of
these cases.

My thought is to have a socket driver publish a set of entry points
for primitive IO operations: effectively, replacements for readw,
writew, inb, outb, and friends. These would be passed out to any
client driver for that socket. Solaris has an equivalent sort of
abstraction layer, where you make a DDI call to indirectly access any
device register. I'm wondering if such an abstraction layer would be
of any use for other types of Linux drivers, and if so, how I should
design my API to make it as broadly useful as possible.

One option is to do it mostly through macro trickery, and make all the
usual Linux calls map to other things behind the scenes. That's not
completely trivial because different sockets in the same system might
have different access methods. I'd like to have the option of
compiling a driver for native or indirect access methods from the same
source code, but this probably means replacing inb(port) with, say,
read_io_byte(sock_handle, port) (or sock_handle->read_io_byte(port),
or io_handle->read_byte(port)), and having a header file that could
collapse this to inb() based on a configuration option.

So I guess my questions are, do people see uses for this sort of thing
for non-PCMCIA drivers? Should I try to implement something like a
stripped-down Solaris DDI layer that isn't PCMCIA-centric, or should I
not worry about generality? In either case, this will cause trouble
with code sharing between PCMCIA and regular Linux drivers: for the
scheme to work, various standard Linux drivers would need to be
retooled to support indirect device accesses. I guess the 8390 driver
has already had something like this hacked in for a special case, so
there's some precedent for it. Any comments?

-- Dave Hinds


1999-03-17 04:02:37

by Matthew Jacob

[permalink] [raw]
Subject: Re: Ideas for abstracting driver IO from bus implementation?


>Solaris has an equivalent sort of abstraction layer, where you make a DDI
>call to indirectly access any device register. I'm wondering if such an
>abstraction layer would be of any use for other types of Linux drivers,
>and if so, how I should design my API to make it as broadly useful as
>possible.

And as Larry McVoy will tell you- he thought that for the Solaris DDI/DKI
we went *way* overboard on this. It isn't even just the indirect register
access, but the whole notion of hierarchies of busses and their
interrelations for both CPU access to devices and DMA accesses to memory
and/or other devices. This really went to town, and cost performance
bigtime. I suspect that if this were done now though the performance could
have been mostly bought back changes in compiler technology since then.

*BSD has a rather nice intermediate approach to this. It doesn't require a
tree hierarchy for devices (which has the the nice property of giving a
digraph for bursts and widths), nor does it really treat DMA precisely
within the same framework, but does encapsulate relatively nicely the
notion that any particular device should be accessed via some sort of
bus_space_WIDTH type of function/macro. Linux sort of has this already in
that each platform has it's own {in,out}foo functions- but that's a bit
limited as you point out (it requires there be no more than one system IO
bustype).

To answer your question above- yes, I could see it being of general use-
it might make drivers a bit easier to share with really wierd
architectures if the access abstraction is simple but strong.




1999-03-17 09:12:59

by David Howells

[permalink] [raw]
Subject: Re: Ideas for abstracting driver IO from bus implementation?

> For example, there are SCSI-to-PCMCIA adapters, parallel-to-PCMCIA adapters,
> SBUS-to-PCMCIA adapters, and various specialized bridge chips that sit on
> the system bus but do not allow PCMCIA devices to be arbitrarily configured
> to mimic the corresponding type of directly connected system device.

Handling this is my ultimate aim with my configuration manager. As well as the
standard four types of resource token (irq, dma, io & mem), I'd like to be
able to have drivers put up other types (such as a SCSI device token or a
parallel device token, though some generic type of indirection token may be
better).

This would, say, allow the following drivers:
* a "SCSI interface" driver
* a "SCSI over PCMCIA interface" driver
* a "pretend all IDE CD-writers are SCSI CD-writers" driver

to create device record and attach to it a SCSI device access token which
would say:
* how to find the driver which acts as an intermediary to the device
* the interface access parameters (such as SCSI LUN)
* further information about the device

[For example]
Take the case of a someone writing a SCSI-CDROM driver. What they'd do is
create a driver structure and register it with the system. This would
specify a set of SCSI device types or classes that it can handle. The system
would then attach any suitable SCSI CD-ROM devices to that driver. The
driver would then be able to pull the SCSI device token out of the device
structure. This would say what low-level driver to go to actually communicate
with the device.

Also I'm currently adding a bus layer to the config manager. This will allow
such a low-level driver to implement a virtual bus representing a SCSI device
chain, whether it be directly over a SCSI interface, or whether it's done
through a PCMCIA interface.

I'm also setting up a new web-site (since my old one vanished). It is at
http://www.astarte.free-online.co.uk, but is incomplete as yet.

David Howells