NAME
pckbport,
pckbport_attach,
pckbport_attach_slot,
pckbport_cnattach,
pckbportintr,
pckbport_set_inputhandler,
pckbport_flush,
pckbport_poll_cmd,
pckbport_enqueue_cmd,
pckbport_poll_data,
pckbport_set_poll,
pckbport_xt_translation,
pckbport_slot_enable —
PC keyboard
port interface
SYNOPSIS
#include <dev/pckbport/pckbportvar.h>
pckbport_tag_t
pckbport_attach(
void
*,
struct
pckbport_accessops const *);
struct device *
pckbport_attach_slot(
struct
device *,
pckbport_tag_t,
pckbport_slot_t);
int
pckbport_cnattach(
void
*,
struct
pckbport_accessops const *,
pckbport_slot_t);
void
pckbportintr(
pckbport_tag_t,
pckbport_slot_t,
int);
void
pckbport_set_inputhandler(
pckbport_tag_t,
pckbport_slot_t,
pckbport_inputfcn,
void *,
char *);
void
pckbport_flush(
pckbport_tag_t,
pckbport_slot_t);
int
pckbport_poll_cmd(
pckbport_tag_t,
pckbport_slot_t,
u_char *,
int,
int,
u_char *,
int);
int
pckbport_enqueue_cmd(
pckbport_tag_t,
pckbport_slot_t,
u_char *,
int,
int,
int,
u_char *);
int
pckbport_poll_data(
pckbport_tag_t,
pckbport_slot_t);
void
pckbport_set_poll(
pckbport_tag_t,
pckbport_slot_t,
int);
int
pckbport_xt_translation(
pckbport_tag_t,
pckbport_slot_t,
int);
void
pckbport_slot_enable(
pckbport_tag_t,
pckbport_slot_t,
int);
DESCRIPTION
The machine-independent
pckbport subsystem provides an
interface layer corresponding to the serial keyboard and mouse interface used
on the IBM PS/2 and many other machines. It interfaces a controller driver
such as
pckbc(4) to device
drivers such as
pckbd(4) and
pms(4).
A single controller can have up to two ports (known as “slots”), and
these are identified by values of type
pckbport_slot_t.
The values
PCKBPORT_KBD_SLOT
and
PCKBPORT_AUX_SLOT
should be used for keyboard and
mouse ports respectively. Each controller is identified by an opaque value of
type
pckbport_tag_t.
Controller interface
A PC keyboard controller registers itself by calling
pckbport_attach(
cookie,
ops), with
ops being a pointer to
a
struct pckbport_accessops containing pointers to
functions for driving the controller, which will all be called with
cookie as their first argument.
pckbport_attach() returns the
pckbport_tag_t assigned to the controller. The
controller is then expected to call
pckbport_attach_slot()
for each slot with which it is equipped, passing the
struct
device * corresponding to the controller. This function returns a
pointer to the child device attached to the slot, or
NULL
if no such device was attached.
The elements of
struct pckbport_accessops each take as
their first two arguments the
cookie passed to
pckbport_attach() and the slot in question. The elements
are:
-
-
- int
(*t_xt_translation)(void *cookie,
pckbport_slot_t slot, int
on)
- If on is non-zero, enable, otherwise
disable, AT-to-XT keycode translation on the slot specified. Returns 1 on
success, 0 on failure (or if the controller does not support such
translation).
-
-
- int
(*t_send_devcmd)(void *cookie,
pckbport_slot_t slot, u_char
byte)
- Send a single byte to the device
without waiting for completion. Returns 1 on success, 0 on failure.
-
-
- int
(*t_poll_data1)(void *cookie,
pckbport_slot_t slot)
- Wait for and return one byte of data from the device,
without using interrupts. This function will only be called after
(*t_set_poll)() has been used to put the slot in polling
mode. If no data are forthcoming from the device after about 100ms, return
-1.
-
-
- void
(*t_slot_enable)(void *cookie,
pckbport_slot_t slot, int
on)
- If on is non-zero, enable, otherwise
disable, the slot. If a slot is disabled, it can be powered down, and is
not expected to generate any interrupts. When first attached, ports should
be disabled.
-
-
- void
(*t_intr_establish)(void *cookie,
pckbport_slot_t slot)
- Set up an interrupt handler for the slot. Called when a
device gets attached to it.
-
-
- void
(*t_set_poll)(void *cookie,
pckbport_slot_t slot, int
on)
- If on is non-zero, enable, otherwise
disable, polling mode on the slot. In polling mode, data received from the
device are provided to (*t_poll_data1)() and not passed
to pckbportintr(), whether or not interrupts are
enabled. In non-polling mode, data from the device are expected to cause
interrupts. The controller interrupt handler should call
pckbportintr(tag,
slot, byte) once for each
byte received from the device. When first attached,
a port should be in non-polling mode.
Device interface
Devices that attach to
pckbport controllers do so using the
normal
autoconf(9) mechanism.
Their
(*ca_match)() and
(*ca_attach)()
functions get passed a
struct pckbport_attach_args which
contains the controller and slot number where the device was found. Device
drivers can use the following functions to communicate with the controller.
Each takes
tag and
slot arguments
to specify the slot to be acted on.
-
-
- pckbport_set_inputhandler(tag,
slot, fn,
arg, name)
- Arrange for fn to be called with
argument arg whenever an unsolicited byte is
received from the slot. The function will be called at
spltty().
-
-
- pckbport_flush(tag,
slot)
- Ensure that there is no pending input from the slot.
-
-
- pckbport_poll_cmd(tag,
slot, cmd,
len, responselen,
respbuf, slow)
- Issue a complete device command, cmd,
len bytes long, expecting a response
responselen bytes long, which will be placed in
respbuf. If slow is true, the
command is expected to take over a second to execute.
pckbport_poll_cmd() handles getting an acknowledgement
from the device and retrying the command if necessary. Returns 0 on
success, and an error value on failure. This function should only be
called during autoconfiguration or when the slot has been placed into
polling mode by pckbport_set_poll().
-
-
- pckbport_enqueue_cmd(tag,
slot, cmd,
len, responselen,
sync, respbuf)
- Issue a complete device command, cmd,
len bytes long, expecting a response
responselen bytes long, which will be places in
respbuf. If sync is true,
pckbport_enqueue_cmd() waits for the command to complete
before returning, otherwise it returns immediately. It is not safe to set
sync when calling from an interrupt context. The
pckbport layer handles getting an acknowledgement from
the device and retrying the command if necessary. Returns 0 on success,
and an error value on failure.
-
-
- pckbport_poll_data(tag,
slot)
- Low-level command to poll for a single byte of data from
the device, but ignoring bytes that are part of the response to a command
issued through pckbport_enqueue_command().
-
-
- pckbport_set_poll(tag,
slot, on)
- If on is true, enable polling on the
slot, otherwise disable it. In polling mode,
pckbport_poll_cmd() can be used to issue commands and
pckbport_poll_data() to read unsolicited data, without
enabling interrupts. In non-polling mode, commands should be issued using
pckbport_enqueue_cmd(), unsolicited data are handled by
the input function, and disabling interrupts will suspend
pckbport operation.
-
-
- pckbport_xt_translation(tag,
slot, on)
- Passthrough of (*t_xt_translation)() (see
above).
-
-
- pckbport_slot(enable,
tag, slot,
on)
- Passthrough of (*t_slot_enable)() (see
above).
Console interface
On systems that can attach consoles through
pckbport, the
controller's console attachment function (called very early in
autoconfiguration) calls
pckbport_cnattach(
cookie,
ops,
slot). The first two
arguments are the same as for
pckbport_attach(), while the
third indicates which slot the console keyboard is attached to.
pckbport_cnattach() either calls
pckbd_cnattach(), if it is available, or
pckbport_machdep_cnattach(). The latter allows
machine-dependent keyboard drivers to attach themselves, but it is only called
if a device with the
‘
pckbport_machdep_cnattach
’ attribute is
configured into the system.
pckbport_cnattach() returns 0 on
success and an error value on failure.
pckbport_machdep_cnattach() is expected to do the same.
CODE REFERENCES
The
pckbport code, and the
pckbd(4) and
pms(4) device drivers are in
sys/dev/pckbport.
SEE ALSO
pckbc(4),
pckbd(4),
pms(4),
autoconf(9),
spl(9)
HISTORY
The
pckbport system appeared in
NetBSD
2.0. Before that,
pckbd(4)
and
pms(4) attached directly to
pckbc(4) without any sensible way
of using a different controller.