Scott Long wrote:
Bruce Evans wrote:

On Sat, 8 Nov 2003, Morten Johansen wrote:


Scott Long wrote:

Bruce Evans wrote:

[... possibly too much trimmed]


The problem here is that the keyboard controller driver tries to be too
smart. If it detects that the hardware FIFO is full, it'll drain it into
a per-softc, per-function ring buffer. So having psm(4) just directly
read the hardware is insufficient in this scheme.



What is the per-function part? (I'm not very familar with psm, but once understood simpler versions of the keyboard driver.) Several layers of buffering might not be too bad for slow devices. The i/o times tend to dominate unless you do silly things like a context switch to move each character from one buffer to other, and even that can be fast enough (I believe it is normal for interactive input on ptys; then there's often a remote IPC or two per character as well).


The atkbdc (keyboard controller, not keyboard) contains two 'kqueue' objects, one for the keyboard device and one for the 'aux' device.
This 'kqueue' is a linked list of buffers for holding characters when
the driver detects that the hardware FIFO is full. Unfortunately, it
checks all over the place, and tends to check both the 'kbd' and 'aux'
ports at the same time (the 'aux' port is for psm, presumably). So,
this complicates the locking of psm quite a bit since it calls
read_aux_data_no_wait() which looks at the aux kqueue and also services
the keyboard queue at the same time.


My gut feeling is that by making the kbd and psm drivers be INTR_FAST
(or INTR_DIRECT as it should be called), there is little chance that the
hardware fifo will overflow before the isr can run.  The driver
interrupt handlers can then have their own private queues with some
simple locking or atomic lists that get serviced by a taskqueue.
However, I'm not sure if my assumption is correct on very old hardware
like 486/586 and old Alphas.  Also, I'm unclear on whether you need
to read the status register before reading the data register.  Hanging
out for 7us in the isr in order to do the back-to-back reads doesn't
thrill me.

Scott


FWIW, this is what the Linux (2.6) driver does:


static inline int i8042_read_data(void)
{
    return inb(I8042_DATA_REG);
}

static inline int i8042_read_status(void)
{
    return inb(I8042_STATUS_REG);
}

... and in the isr:

while (j < I8042_BUFFER_SIZE &&
    (buffer[j].str = i8042_read_status()) & I8042_STR_OBF)
     buffer[j++].data = i8042_read_data();

... this isr then figures out if it's kbd or aux data (based on status register) and calls the appropriate "sub"-isr (i.e. ps/2) with the data.

There are noe delays as far as I can see.

Why did we need the delays? Can they be removed?


Morten


_______________________________________________
[EMAIL PROTECTED] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "[EMAIL PROTECTED]"

Reply via email to