Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 25 Apr 1995 16:50:50 +1000
From:      Bruce Evans <bde@zeta.org.au>
To:        bde@zeta.org.au, matt@lkg.dec.com
Cc:        hackers@FreeBSD.org, julian@ref.tfs.com, phk@ref.tfs.com
Subject:   Re: [EISA] related matters
Message-ID:  <199504250650.QAA19925@godzilla.zeta.org.au>

next in thread | raw e-mail | index | archive | help
>> >What we really should have is a TEXT_SET(device_probe...) and kill config...
>> 
>> No linker magic is required or good.  Drivers should register their
>> interrupt masking requirements as late as possible, preferably not
>> until open() completes.

>Not every device has an open routine (like network interfaces).

They have an attach routine.  Maybe the registration could be delayed
until the interface is ifconfig'ed.

>There should be two steps: the first is registration (allow a driver to
>indicate that it will use an IRQ) to detect conflicts, the second is the
>actual enabling of the interrupt handler.

There aren't enough isa interrupts, and isa interrupts can't be shared
(at the same time), so early registration and conflict checking is too
restrictive.  Of course, interrupts for critical devices need to be
reserved early and almost forever.  Examples of time-sharing of
interrupts:

1) COM1 and COM3 both on IRQ4.  Delay the interrupt registration until
open() and unregister the interrupt in close().  This would actually
be easier to handle using a `controller' device that multiplexes
the interrupt internally.

2) Multiple wd disk controllers on IRQ14.  Only one can be active at
a time.  Enable IRQs for the controller that you expect to interrupt
next and disable IRQs for the others.  Again, this is easier to handle
internally.

3) lpt0 on IRQ7 ans something else on IRQ7.  Use IRQ7 for lpt0 if
nothing else wants it.  Otherwise, use IRQ7 for something else and
polling for lpt0.  This is harder to handle because the something else
is probably in another driver and lpt0 needs to be told when its
interrupt is preempted.

>BSD/OS actually has done this in a manner which is quite nice.  There are
>no interrupt handlers defined in the config file.  Every driver must register
>their interrupt handler in their attach routine.

>You can almost achieve the same thing in FreeBSD by setting id->id_intr in
>the attach routine.

I made 2.0 work with existing config files and drivers that don't set
id->id_intr.  This was too successfull - most drivers still don't set
id->id_intr.

>The problem is that the irq class is not so easily set
>in the driver (because of having isa_devtab_xxx in ioconf.c; it would be 
>nicer if the isa_device structure had a id_class field which would be used
>to register the approriate interrupt handler).

I thought of this too, but it was pointed out that the id_class isn't
really necessary - it can by implicit in a registration scheme.

>Right now, my new-improved DECPA driver needs the following config file line
>on FreeBSD:

>	device	di0 at isa? net irq ?

Does BSD/OS support the old config keywords that allow you to specify
too much in the config file?  I'm not sure which keywords are FreeBSD
brokenness.  Supporting both "irq ?" and "irq n" requires more work by
drivers - they should probably honor the request for a particular irq.
Some FreeBSD drivers (bt742.c...) just blow away the request for a
particular irq.

>The "net irq ?" is required so it's put into the right device table.  Under
>BSD/OS, all I need is:

>	di0	at isa?

Don't you have to register the device as being in class `net'?  This
would take more than the 4 characters required for `net ' in the config
file.  Putting it in the config file may be the best approach if the
driver is changed more often than the config file (which is far from
the case when there are many more installations than driver authors).

>The IRQ services in FreeBSD are definitely inferior to BSD/OS.  BSD/OS
>supports shared interrupts for all interrupts (not specific to PCI as
>in FreeBSD).  Some routines that FreeBSD could use are:

>	isa_irqmask_t isa_irqalloc(isa_irqmask_t irqs);
>	isa_irqmask_t isa_forceintr(int (*forceintr)(void *arg));

Yes.  Does BSD/OS use prototypes without __P(()) for everything and
good typedefs for everything?  The isa irq mask type is magic but
since the machine type is fixed, an explicit type can work OK.  OTOH,
irqalloc() is a good interface for all machines with irq masks and
putting isa in its name defeats reuse (does it apply to eisa? :-).
forceintr() is a good interface for all machines except its arg
should be typedef'ed.

forceintr() is difficult to implement.  It can't be implemented for
lpt's (you need a benign printer attached and turned on).

>Modifying my drivers to run under both FreeBSD and BSD/OS has been very
>enlightening.  Some things BSD/OS does better while FreeBSD does better at
>other things.

Isn't it easier to have all configuration stuff outside the driver as
in FreeBSD?  At least if the external configuration is adequate.

Bruce



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199504250650.QAA19925>