Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 9 Jul 2014 20:08:52 +1000 (EST)
From:      Bruce Evans <brde@optusnet.com.au>
To:        Don Lewis <truckman@freebsd.org>
Cc:        arch@freebsd.org, adrian@freebsd.org
Subject:   Re: [patch] axe RF_TIMESHARE?
Message-ID:  <20140709200848.Q1201@besplex.bde.org>
In-Reply-To: <201407082254.s68MsaPS028312@gw.catspoiler.org>
References:  <201407082254.s68MsaPS028312@gw.catspoiler.org>

next in thread | previous in thread | raw e-mail | index | archive | help
yOn Tue, 8 Jul 2014, Don Lewis wrote:

> On  6 Jul, Adrian Chadd wrote:
>> On 6 July 2014 17:47, Don Lewis <truckman@freebsd.org> wrote:
>>> On  6 Jul, Adrian Chadd wrote:
>>>> Hi,
>>>>
>>>> What's it supposed to be used for?
>>>
>>> My understanding it that it is supposed to be used to allow two more
>>> devices to claim the same resource, such as an I/O port range, but only
>>> one device can be active at a time.
>>
>> Interesting. I wonder what kinds of things would want to do this.
>
> Not much of anything that I can think of, which is probably why this
> feature was never used.  The closest thing that I can think of is ISA,
> as Garrett mentioned.  The thing that came to mind for me when I started
> looking at this is ISA attached COM ports.  COM1 and COM3 both want to
> use IRQ 4, and COM2 and COM4 both want to use IRQ 3.  The problem is
> that ISA IRQs can't be shared between slots, so it might be nice if
> RF_TIMESHARE could be used to share IRQ 3 between a modem card
> configured as COM4 and the COM2 serial port and then let the user pick
> the device to enable through software.  Unfortunately this won't work
> because 16550-compatible UARTs don't have a way of disabling their IRQ
> pin drivers, so this has to be done with jumpers ...

No, xx50-compatible UARTs have precisely such a way of disabling their
IRQ pin drivers.  It is the the OUT2 pin in the modem control register.
This is a general purpose pin, but in compatible systems it used to
gate the IRQ pin.  Its name is misspelled MCR_IENABLE in sio and
MCR_IE in uart (this hard-codes its special connection in its very
name, as would be correct if this were hard-wired in the xx50 itself.
It probably is actually hard-wired in ASICs implementing xx50's).

Correct initialization of the OUT2 pin is difficult, and is not done
except in old versions of sio, only on some configurations.  It is
necessary to turn off the OUT2 pin for all devices that might be driving
an interrupt before trying to use the interrupt.  For this, it is first
necessary to know all these devices.  Then become the owner or otherwise
lock all the devices.  Then turn off OUT2 on all except the one where
interrupts will be used.  Then keep owning all the others so as to
keep OUT2 off on them.

This is needed for warm boots from another OS that used the interrupts
in a different way.  Sharing always worked in Linux, so rebooting while
Linux is using COM3 with IRQ4 to FreeBSD configured to only use COM1
with IRQ4 will do it.  At least old BIOSes don't initialize all COM
ports in all cases after a warm boot, perhaps because they have the
same problem as FreeBSD with knowing the complete list.  Cold boots
always work right for unknown xx50 devices, since the hardware reset
resets the device to a known good statet.

The working versions depended on config(8) being used to configure the
complete lists (except it had some internal hard-coded lists, especially
for the COM_ESP case).  This was broken by unapproved commits for
new-bus.  New-bus makes it harder for drivers to hack on the lists
directly, and the direct hacking on the lists just broke.  New-bus
doesn't provide the multiple stages of probe/attach needed to do this
AFAIK. and provides even less control over the ordering than old bus.
Probe shouldn't write or gain ownership of anything.  That means no
writing to OUT2 for even the device being probed at probe time, and
no owning the device from probe to attach so as to keep OUT2 off.  So
the drive should claim all the devices it can without checking if their
interrupts work.  Then attach all devices it can, and turn off their
OUT2's but still not check if interrupts work.  Finally, enable
interrupts for just one, provided it has been determined that enough
have been claimed.  The final step could be done by a second attach
pass or just when devices are first really used.  The latter goes
well with switching on OUT2 only for one being used -- turn off OUT2
on last close and let first open gain control of the interrupt.
Device interrupts can be left on for opens that _don't_ gain control
of the interrupt (these interrupts are gated off by OUT2), but of i/o
to actually work on these opens polled mode must be used.

RF_TIMESHARE doesn't simplify this significantly.  Ownership of the
interrupt should be claimed somewhere so that the interrupt resource
is available at first open time.  That can probably be done using
a super-device or some hack to own the interrupt by the first device
that can share it.  Then you don't need a flag for it.  It seems too
hard (bloated) to generalize RF_TIMESHARE so that all of the OUT2
complications can be handled at the new-bus level.

Bruce



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