PCKBPORT(9)
π NAME π
Meet the whole pckbport friend group: 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. This is the pckbport(9) page, and itβs literally the group chat between the keyboard/mouse controller layer and the device drivers that vibe with it π
β¨
β¨ 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 π
Okay so bestie, the machine-independent pckbport subsystem gives you 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). Iconic middle-friend energy, no cap π«Ά
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. Slay, but make it autoconf π
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)β Ifonis non-zero, enable, otherwise disable, AT-to-XT keycode translation on the slot specified. Returns1on success,0on 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. Returns1on success,0on 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 about100ms, return-1.void (*t_slot_enable)(void *cookie, pckbport_slot_t slot, int on)β Ifonis 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)β Ifonis 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 topckbportintr(), whether or not interrupts are enabled. In non-polling mode, data from the device are expected to cause interrupts. The controller interrupt handler should callpckbportintr(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. Main character device-driver behavior, fr fr π¦
pckbport_set_inputhandler(tag, slot, fn, arg, name)β Arrange forfnto be called with argumentargwhenever an unsolicited byte is received from the slot. The function will be called atspltty().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,lenbytes long, expecting a responseresponselenbytes long, which will be placed inrespbuf. Ifslowis 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. Returns0on 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 bypckbport_set_poll().pckbport_enqueue_cmd(tag, slot, cmd, len, responselen, sync, respbuf)β Issue a complete device command,cmd,lenbytes long, expecting a responseresponselenbytes long, which will be places inrespbuf. Ifsyncis true,pckbport_enqueue_cmd()waits for the command to complete before returning, otherwise it returns immediately. It is not safe to setsyncwhen calling from an interrupt context. The pckbport layer handles getting an acknowledgement from the device and retrying the command if necessary. Returns0on 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 throughpckbport_enqueue_command().pckbport_set_poll(tag, slot, on)β Ifonis true, enable polling on the slot, otherwise disable it. In polling mode,pckbport_poll_cmd()can be used to issue commands andpckbport_poll_data()to read unsolicited data, without enabling interrupts. In non-polling mode, commands should be issued usingpckbport_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).
π¨ Technical caveat bestie: it is not safe to setsyncwhen callingpckbport_enqueue_cmd()from an interrupt context. Periodt.
πΈ 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. Go look, iykyk π₯
π₯ 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. Glow-up story, honestly π
xoxo, Debian β August 5, 2004 β PCKBPORT(9) signing off ππ
π¦ where this page comes from
- nixpkgs unstable: netbsd-source 11.0
- Copyright (c) 2004 Ben Harris
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms