mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-05 09:14:03 +00:00
- Properly keep track of I/O port resources.
- Use bus_space_read/write() to access the ports.
This commit is contained in:
parent
49ec367311
commit
db3e34cb71
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=58271
@ -36,6 +36,9 @@
|
||||
#include <sys/proc.h>
|
||||
#include <sys/malloc.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <machine/resource.h>
|
||||
|
||||
#ifdef __i386__
|
||||
#include <machine/md_var.h>
|
||||
#include <machine/psl.h>
|
||||
@ -55,7 +58,7 @@
|
||||
static timeout_t atkbd_timeout;
|
||||
|
||||
int
|
||||
atkbd_probe_unit(int unit, int port, int irq, int flags)
|
||||
atkbd_probe_unit(int unit, int ctlr, int irq, int flags)
|
||||
{
|
||||
keyboard_switch_t *sw;
|
||||
int args[2];
|
||||
@ -65,7 +68,7 @@ atkbd_probe_unit(int unit, int port, int irq, int flags)
|
||||
if (sw == NULL)
|
||||
return ENXIO;
|
||||
|
||||
args[0] = port;
|
||||
args[0] = ctlr;
|
||||
args[1] = irq;
|
||||
error = (*sw->probe)(unit, args, flags);
|
||||
if (error)
|
||||
@ -74,7 +77,7 @@ atkbd_probe_unit(int unit, int port, int irq, int flags)
|
||||
}
|
||||
|
||||
int
|
||||
atkbd_attach_unit(int unit, keyboard_t **kbd, int port, int irq, int flags)
|
||||
atkbd_attach_unit(int unit, keyboard_t **kbd, int ctlr, int irq, int flags)
|
||||
{
|
||||
keyboard_switch_t *sw;
|
||||
int args[2];
|
||||
@ -85,7 +88,7 @@ atkbd_attach_unit(int unit, keyboard_t **kbd, int port, int irq, int flags)
|
||||
return ENXIO;
|
||||
|
||||
/* reset, initialize and enable the device */
|
||||
args[0] = port;
|
||||
args[0] = ctlr;
|
||||
args[1] = irq;
|
||||
*kbd = NULL;
|
||||
error = (*sw->probe)(unit, args, flags);
|
||||
@ -311,7 +314,7 @@ static int
|
||||
atkbd_probe(int unit, void *arg, int flags)
|
||||
{
|
||||
KBDC kbdc;
|
||||
int *data = (int *)arg;
|
||||
int *data = (int *)arg; /* data[0]: controller, data[1]: irq */
|
||||
|
||||
/* XXX */
|
||||
if (unit == ATKBD_DEFAULT) {
|
||||
@ -319,7 +322,7 @@ atkbd_probe(int unit, void *arg, int flags)
|
||||
return 0;
|
||||
}
|
||||
|
||||
kbdc = kbdc_open(data[0]);
|
||||
kbdc = atkbdc_open(data[0]);
|
||||
if (kbdc == NULL)
|
||||
return ENXIO;
|
||||
if (probe_keyboard(kbdc, flags)) {
|
||||
@ -340,7 +343,7 @@ atkbd_init(int unit, keyboard_t **kbdp, void *arg, int flags)
|
||||
fkeytab_t *fkeymap;
|
||||
int fkeymap_size;
|
||||
int delay[2];
|
||||
int *data = (int *)arg;
|
||||
int *data = (int *)arg; /* data[0]: controller, data[1]: irq */
|
||||
|
||||
/* XXX */
|
||||
if (unit == ATKBD_DEFAULT) {
|
||||
@ -390,11 +393,11 @@ atkbd_init(int unit, keyboard_t **kbdp, void *arg, int flags)
|
||||
}
|
||||
|
||||
if (!KBD_IS_PROBED(kbd)) {
|
||||
state->kbdc = kbdc_open(data[0]);
|
||||
state->kbdc = atkbdc_open(data[0]);
|
||||
if (state->kbdc == NULL)
|
||||
return ENXIO;
|
||||
kbd_init_struct(kbd, ATKBD_DRIVER_NAME, KB_OTHER, unit, flags,
|
||||
data[0], IO_KBDSIZE);
|
||||
0, 0);
|
||||
bcopy(&key_map, keymap, sizeof(key_map));
|
||||
bcopy(&accent_map, accmap, sizeof(accent_map));
|
||||
bcopy(fkey_tab, fkeymap,
|
||||
|
@ -31,13 +31,11 @@
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/tty.h>
|
||||
#include <sys/bus.h>
|
||||
#include <machine/bus.h>
|
||||
#include <sys/rman.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <machine/resource.h>
|
||||
#include <sys/rman.h>
|
||||
|
||||
#include <dev/kbd/kbdreg.h>
|
||||
#include <dev/kbd/atkbdreg.h>
|
||||
@ -46,6 +44,11 @@
|
||||
#include <isa/isareg.h>
|
||||
#include <isa/isavar.h>
|
||||
|
||||
typedef struct {
|
||||
struct resource *intr;
|
||||
void *ih;
|
||||
} atkbd_softc_t;
|
||||
|
||||
devclass_t atkbd_devclass;
|
||||
|
||||
static int atkbdprobe(device_t dev);
|
||||
@ -61,52 +64,54 @@ static device_method_t atkbd_methods[] = {
|
||||
static driver_t atkbd_driver = {
|
||||
ATKBD_DRIVER_NAME,
|
||||
atkbd_methods,
|
||||
1,
|
||||
sizeof(atkbd_softc_t),
|
||||
};
|
||||
|
||||
static int
|
||||
atkbdprobe(device_t dev)
|
||||
{
|
||||
uintptr_t port;
|
||||
uintptr_t irq;
|
||||
uintptr_t flags;
|
||||
|
||||
device_set_desc(dev, "AT Keyboard");
|
||||
|
||||
/* obtain parameters */
|
||||
BUS_READ_IVAR(device_get_parent(dev), dev, KBDC_IVAR_PORT, &port);
|
||||
BUS_READ_IVAR(device_get_parent(dev), dev, KBDC_IVAR_IRQ, &irq);
|
||||
BUS_READ_IVAR(device_get_parent(dev), dev, KBDC_IVAR_FLAGS, &flags);
|
||||
|
||||
/* probe the device */
|
||||
return atkbd_probe_unit(device_get_unit(dev), port, irq, flags);
|
||||
return atkbd_probe_unit(device_get_unit(dev),
|
||||
device_get_unit(device_get_parent(dev)),
|
||||
irq, flags);
|
||||
}
|
||||
|
||||
static int
|
||||
atkbdattach(device_t dev)
|
||||
{
|
||||
atkbd_softc_t *sc;
|
||||
keyboard_t *kbd;
|
||||
uintptr_t port;
|
||||
uintptr_t irq;
|
||||
uintptr_t flags;
|
||||
struct resource *res;
|
||||
void *ih;
|
||||
int zero = 0;
|
||||
int rid;
|
||||
int error;
|
||||
|
||||
BUS_READ_IVAR(device_get_parent(dev), dev, KBDC_IVAR_PORT, &port);
|
||||
sc = device_get_softc(dev);
|
||||
|
||||
BUS_READ_IVAR(device_get_parent(dev), dev, KBDC_IVAR_IRQ, &irq);
|
||||
BUS_READ_IVAR(device_get_parent(dev), dev, KBDC_IVAR_FLAGS, &flags);
|
||||
|
||||
error = atkbd_attach_unit(device_get_unit(dev), &kbd, port, irq, flags);
|
||||
error = atkbd_attach_unit(device_get_unit(dev), &kbd,
|
||||
device_get_unit(device_get_parent(dev)),
|
||||
irq, flags);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
/* declare our interrupt handler */
|
||||
res = bus_alloc_resource(dev, SYS_RES_IRQ, &zero, irq, irq, 1,
|
||||
RF_SHAREABLE | RF_ACTIVE);
|
||||
BUS_SETUP_INTR(device_get_parent(dev), dev, res, INTR_TYPE_TTY,
|
||||
atkbd_isa_intr, kbd, &ih);
|
||||
rid = 0;
|
||||
sc->intr = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, irq, irq, 1,
|
||||
RF_SHAREABLE | RF_ACTIVE);
|
||||
BUS_SETUP_INTR(device_get_parent(dev), dev, sc->intr, INTR_TYPE_TTY,
|
||||
atkbd_isa_intr, kbd, &sc->ih);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -31,13 +31,11 @@
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/tty.h>
|
||||
#include <sys/bus.h>
|
||||
#include <machine/bus.h>
|
||||
#include <sys/rman.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <machine/resource.h>
|
||||
#include <sys/rman.h>
|
||||
|
||||
#include <dev/kbd/kbdreg.h>
|
||||
#include <dev/kbd/atkbdreg.h>
|
||||
@ -46,6 +44,11 @@
|
||||
#include <isa/isareg.h>
|
||||
#include <isa/isavar.h>
|
||||
|
||||
typedef struct {
|
||||
struct resource *intr;
|
||||
void *ih;
|
||||
} atkbd_softc_t;
|
||||
|
||||
devclass_t atkbd_devclass;
|
||||
|
||||
static int atkbdprobe(device_t dev);
|
||||
@ -61,52 +64,54 @@ static device_method_t atkbd_methods[] = {
|
||||
static driver_t atkbd_driver = {
|
||||
ATKBD_DRIVER_NAME,
|
||||
atkbd_methods,
|
||||
1,
|
||||
sizeof(atkbd_softc_t),
|
||||
};
|
||||
|
||||
static int
|
||||
atkbdprobe(device_t dev)
|
||||
{
|
||||
uintptr_t port;
|
||||
uintptr_t irq;
|
||||
uintptr_t flags;
|
||||
|
||||
device_set_desc(dev, "AT Keyboard");
|
||||
|
||||
/* obtain parameters */
|
||||
BUS_READ_IVAR(device_get_parent(dev), dev, KBDC_IVAR_PORT, &port);
|
||||
BUS_READ_IVAR(device_get_parent(dev), dev, KBDC_IVAR_IRQ, &irq);
|
||||
BUS_READ_IVAR(device_get_parent(dev), dev, KBDC_IVAR_FLAGS, &flags);
|
||||
|
||||
/* probe the device */
|
||||
return atkbd_probe_unit(device_get_unit(dev), port, irq, flags);
|
||||
return atkbd_probe_unit(device_get_unit(dev),
|
||||
device_get_unit(device_get_parent(dev)),
|
||||
irq, flags);
|
||||
}
|
||||
|
||||
static int
|
||||
atkbdattach(device_t dev)
|
||||
{
|
||||
atkbd_softc_t *sc;
|
||||
keyboard_t *kbd;
|
||||
uintptr_t port;
|
||||
uintptr_t irq;
|
||||
uintptr_t flags;
|
||||
struct resource *res;
|
||||
void *ih;
|
||||
int zero = 0;
|
||||
int rid;
|
||||
int error;
|
||||
|
||||
BUS_READ_IVAR(device_get_parent(dev), dev, KBDC_IVAR_PORT, &port);
|
||||
sc = device_get_softc(dev);
|
||||
|
||||
BUS_READ_IVAR(device_get_parent(dev), dev, KBDC_IVAR_IRQ, &irq);
|
||||
BUS_READ_IVAR(device_get_parent(dev), dev, KBDC_IVAR_FLAGS, &flags);
|
||||
|
||||
error = atkbd_attach_unit(device_get_unit(dev), &kbd, port, irq, flags);
|
||||
error = atkbd_attach_unit(device_get_unit(dev), &kbd,
|
||||
device_get_unit(device_get_parent(dev)),
|
||||
irq, flags);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
/* declare our interrupt handler */
|
||||
res = bus_alloc_resource(dev, SYS_RES_IRQ, &zero, irq, irq, 1,
|
||||
RF_SHAREABLE | RF_ACTIVE);
|
||||
BUS_SETUP_INTR(device_get_parent(dev), dev, res, INTR_TYPE_TTY,
|
||||
atkbd_isa_intr, kbd, &ih);
|
||||
rid = 0;
|
||||
sc->intr = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, irq, irq, 1,
|
||||
RF_SHAREABLE | RF_ACTIVE);
|
||||
BUS_SETUP_INTR(device_get_parent(dev), dev, sc->intr, INTR_TYPE_TTY,
|
||||
atkbd_isa_intr, kbd, &sc->ih);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -36,9 +36,13 @@
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/syslog.h>
|
||||
#include <machine/bus_pio.h>
|
||||
#include <machine/bus.h>
|
||||
#include <machine/resource.h>
|
||||
#include <sys/rman.h>
|
||||
|
||||
#include <machine/clock.h>
|
||||
|
||||
@ -65,6 +69,13 @@
|
||||
#define emptyq(q) ((q)->tail = (q)->head = 0)
|
||||
#endif
|
||||
|
||||
#define read_data(k) (bus_space_read_1((k)->iot, (k)->ioh0, 0))
|
||||
#define read_status(k) (bus_space_read_1((k)->iot, (k)->ioh1, 0))
|
||||
#define write_data(k, d) \
|
||||
(bus_space_write_1((k)->iot, (k)->ioh0, 0, (d)))
|
||||
#define write_command(k, d) \
|
||||
(bus_space_write_1((k)->iot, (k)->ioh1, 0, (d)))
|
||||
|
||||
/* local variables */
|
||||
|
||||
/*
|
||||
@ -80,7 +91,8 @@ static int verbose = KBDIO_DEBUG;
|
||||
|
||||
/* function prototypes */
|
||||
|
||||
static int atkbdc_setup(atkbdc_softc_t *sc, int port);
|
||||
static int atkbdc_setup(atkbdc_softc_t *sc, bus_space_tag_t tag,
|
||||
bus_space_handle_t h0, bus_space_handle_t h1);
|
||||
static int addq(kqueue *q, int c);
|
||||
static int removeq(kqueue *q);
|
||||
static int wait_while_controller_busy(atkbdc_softc_t *kbdc);
|
||||
@ -104,39 +116,68 @@ atkbdc_softc_t
|
||||
if (sc == NULL)
|
||||
return NULL;
|
||||
bzero(sc, sizeof(*sc));
|
||||
sc->port = -1; /* XXX */
|
||||
}
|
||||
return sc;
|
||||
}
|
||||
|
||||
int
|
||||
atkbdc_probe_unit(int unit, int port)
|
||||
atkbdc_probe_unit(int unit, struct resource *port0, struct resource *port1)
|
||||
{
|
||||
if (port <= 0)
|
||||
if (rman_get_start(port0) <= 0)
|
||||
return ENXIO;
|
||||
if (rman_get_start(port1) <= 0)
|
||||
return ENXIO;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
atkbdc_attach_unit(int unit, atkbdc_softc_t *sc, int port)
|
||||
atkbdc_attach_unit(int unit, atkbdc_softc_t *sc, struct resource *port0,
|
||||
struct resource *port1)
|
||||
{
|
||||
return atkbdc_setup(sc, port);
|
||||
return atkbdc_setup(sc, rman_get_bustag(port0),
|
||||
rman_get_bushandle(port0),
|
||||
rman_get_bushandle(port1));
|
||||
}
|
||||
|
||||
/* the backdoor to the keyboard controller! XXX */
|
||||
int
|
||||
atkbdc_configure(void)
|
||||
{
|
||||
return atkbdc_setup(atkbdc_softc[0], -1);
|
||||
bus_space_tag_t tag;
|
||||
bus_space_handle_t h0;
|
||||
bus_space_handle_t h1;
|
||||
int port0;
|
||||
int port1;
|
||||
|
||||
port0 = IO_KBD;
|
||||
resource_int_value("atkbdc", 0, "port", &port0);
|
||||
port1 = IO_KBD + KBD_STATUS_PORT;
|
||||
#if 0
|
||||
resource_int_value("atkbdc", 0, "port", &port0);
|
||||
#endif
|
||||
|
||||
/* XXX: tag should be passed from the caller */
|
||||
#if defined(__i386__)
|
||||
tag = I386_BUS_SPACE_IO;
|
||||
#elif defined(__alpha__)
|
||||
tag = ALPHA_BUS_SPACE_IO;
|
||||
#endif
|
||||
|
||||
#if notyet
|
||||
bus_space_map(tag, port0, IO_KBDSIZE, 0, &h0);
|
||||
bus_space_map(tag, port1, IO_KBDSIZE, 0, &h1);
|
||||
#else
|
||||
h0 = (bus_space_handle_t)port0;
|
||||
h1 = (bus_space_handle_t)port1;
|
||||
#endif
|
||||
return atkbdc_setup(atkbdc_softc[0], tag, h0, h1);
|
||||
}
|
||||
|
||||
static int
|
||||
atkbdc_setup(atkbdc_softc_t *sc, int port)
|
||||
atkbdc_setup(atkbdc_softc_t *sc, bus_space_tag_t tag, bus_space_handle_t h0,
|
||||
bus_space_handle_t h1)
|
||||
{
|
||||
if (port <= 0)
|
||||
port = IO_KBD;
|
||||
|
||||
if (sc->port <= 0) {
|
||||
if (sc->ioh0 == 0) { /* XXX */
|
||||
sc->command_byte = -1;
|
||||
sc->command_mask = 0;
|
||||
sc->lock = FALSE;
|
||||
@ -149,37 +190,23 @@ atkbdc_setup(atkbdc_softc_t *sc, int port)
|
||||
sc->aux.qcount = sc->aux.max_qcount = 0;
|
||||
#endif
|
||||
}
|
||||
sc->port = port; /* may override the previous value */
|
||||
sc->iot = tag;
|
||||
sc->ioh0 = h0;
|
||||
sc->ioh1 = h1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* associate a port number with a KBDC */
|
||||
|
||||
/* open a keyboard controller */
|
||||
KBDC
|
||||
kbdc_open(int port)
|
||||
atkbdc_open(int unit)
|
||||
{
|
||||
int s;
|
||||
int i;
|
||||
|
||||
if (port <= 0)
|
||||
port = IO_KBD;
|
||||
|
||||
s = spltty();
|
||||
for (i = 0; i < sizeof(atkbdc_softc)/sizeof(atkbdc_softc[0]); ++i) {
|
||||
if (atkbdc_softc[i] == NULL)
|
||||
continue;
|
||||
if (atkbdc_softc[i]->port == port) {
|
||||
splx(s);
|
||||
return (KBDC)atkbdc_softc[i];
|
||||
}
|
||||
if (atkbdc_softc[i]->port <= 0) {
|
||||
if (atkbdc_setup(atkbdc_softc[i], port))
|
||||
break;
|
||||
splx(s);
|
||||
return (KBDC)atkbdc_softc[i];
|
||||
}
|
||||
}
|
||||
splx(s);
|
||||
if (unit <= 0)
|
||||
unit = 0;
|
||||
if (unit >= MAXKBDC)
|
||||
return NULL;
|
||||
if ((atkbdc_softc[unit]->port0 != NULL)
|
||||
|| (atkbdc_softc[unit]->ioh0 != 0)) /* XXX */
|
||||
return (KBDC)atkbdc_softc[unit];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -238,7 +265,7 @@ int
|
||||
kbdc_data_ready(KBDC p)
|
||||
{
|
||||
return (availq(&kbdcp(p)->kbd) || availq(&kbdcp(p)->aux)
|
||||
|| (inb(kbdcp(p)->port + KBD_STATUS_PORT) & KBDS_ANY_BUFFER_FULL));
|
||||
|| (read_status(kbdcp(p)) & KBDS_ANY_BUFFER_FULL));
|
||||
}
|
||||
|
||||
/* queuing functions */
|
||||
@ -284,16 +311,15 @@ wait_while_controller_busy(struct atkbdc_softc *kbdc)
|
||||
{
|
||||
/* CPU will stay inside the loop for 100msec at most */
|
||||
int retry = 5000;
|
||||
int port = kbdc->port;
|
||||
int f;
|
||||
|
||||
while ((f = inb(port + KBD_STATUS_PORT)) & KBDS_INPUT_BUFFER_FULL) {
|
||||
while ((f = read_status(kbdc)) & KBDS_INPUT_BUFFER_FULL) {
|
||||
if ((f & KBDS_BUFFER_FULL) == KBDS_KBD_BUFFER_FULL) {
|
||||
DELAY(KBDD_DELAYTIME);
|
||||
addq(&kbdc->kbd, inb(port + KBD_DATA_PORT));
|
||||
addq(&kbdc->kbd, read_data(kbdc));
|
||||
} else if ((f & KBDS_BUFFER_FULL) == KBDS_AUX_BUFFER_FULL) {
|
||||
DELAY(KBDD_DELAYTIME);
|
||||
addq(&kbdc->aux, inb(port + KBD_DATA_PORT));
|
||||
addq(&kbdc->aux, read_data(kbdc));
|
||||
}
|
||||
DELAY(KBDC_DELAYTIME);
|
||||
if (--retry < 0)
|
||||
@ -311,10 +337,9 @@ wait_for_data(struct atkbdc_softc *kbdc)
|
||||
{
|
||||
/* CPU will stay inside the loop for 200msec at most */
|
||||
int retry = 10000;
|
||||
int port = kbdc->port;
|
||||
int f;
|
||||
|
||||
while ((f = inb(port + KBD_STATUS_PORT) & KBDS_ANY_BUFFER_FULL) == 0) {
|
||||
while ((f = read_status(kbdc) & KBDS_ANY_BUFFER_FULL) == 0) {
|
||||
DELAY(KBDC_DELAYTIME);
|
||||
if (--retry < 0)
|
||||
return 0;
|
||||
@ -329,14 +354,13 @@ wait_for_kbd_data(struct atkbdc_softc *kbdc)
|
||||
{
|
||||
/* CPU will stay inside the loop for 200msec at most */
|
||||
int retry = 10000;
|
||||
int port = kbdc->port;
|
||||
int f;
|
||||
|
||||
while ((f = inb(port + KBD_STATUS_PORT) & KBDS_BUFFER_FULL)
|
||||
while ((f = read_status(kbdc) & KBDS_BUFFER_FULL)
|
||||
!= KBDS_KBD_BUFFER_FULL) {
|
||||
if (f == KBDS_AUX_BUFFER_FULL) {
|
||||
DELAY(KBDD_DELAYTIME);
|
||||
addq(&kbdc->aux, inb(port + KBD_DATA_PORT));
|
||||
addq(&kbdc->aux, read_data(kbdc));
|
||||
}
|
||||
DELAY(KBDC_DELAYTIME);
|
||||
if (--retry < 0)
|
||||
@ -355,14 +379,13 @@ wait_for_kbd_ack(struct atkbdc_softc *kbdc)
|
||||
{
|
||||
/* CPU will stay inside the loop for 200msec at most */
|
||||
int retry = 10000;
|
||||
int port = kbdc->port;
|
||||
int f;
|
||||
int b;
|
||||
|
||||
while (retry-- > 0) {
|
||||
if ((f = inb(port + KBD_STATUS_PORT)) & KBDS_ANY_BUFFER_FULL) {
|
||||
if ((f = read_status(kbdc)) & KBDS_ANY_BUFFER_FULL) {
|
||||
DELAY(KBDD_DELAYTIME);
|
||||
b = inb(port + KBD_DATA_PORT);
|
||||
b = read_data(kbdc);
|
||||
if ((f & KBDS_BUFFER_FULL) == KBDS_KBD_BUFFER_FULL) {
|
||||
if ((b == KBD_ACK) || (b == KBD_RESEND)
|
||||
|| (b == KBD_RESET_FAIL))
|
||||
@ -383,14 +406,13 @@ wait_for_aux_data(struct atkbdc_softc *kbdc)
|
||||
{
|
||||
/* CPU will stay inside the loop for 200msec at most */
|
||||
int retry = 10000;
|
||||
int port = kbdc->port;
|
||||
int f;
|
||||
|
||||
while ((f = inb(port + KBD_STATUS_PORT) & KBDS_BUFFER_FULL)
|
||||
while ((f = read_status(kbdc) & KBDS_BUFFER_FULL)
|
||||
!= KBDS_AUX_BUFFER_FULL) {
|
||||
if (f == KBDS_KBD_BUFFER_FULL) {
|
||||
DELAY(KBDD_DELAYTIME);
|
||||
addq(&kbdc->kbd, inb(port + KBD_DATA_PORT));
|
||||
addq(&kbdc->kbd, read_data(kbdc));
|
||||
}
|
||||
DELAY(KBDC_DELAYTIME);
|
||||
if (--retry < 0)
|
||||
@ -409,14 +431,13 @@ wait_for_aux_ack(struct atkbdc_softc *kbdc)
|
||||
{
|
||||
/* CPU will stay inside the loop for 200msec at most */
|
||||
int retry = 10000;
|
||||
int port = kbdc->port;
|
||||
int f;
|
||||
int b;
|
||||
|
||||
while (retry-- > 0) {
|
||||
if ((f = inb(port + KBD_STATUS_PORT)) & KBDS_ANY_BUFFER_FULL) {
|
||||
if ((f = read_status(kbdc)) & KBDS_ANY_BUFFER_FULL) {
|
||||
DELAY(KBDD_DELAYTIME);
|
||||
b = inb(port + KBD_DATA_PORT);
|
||||
b = read_data(kbdc);
|
||||
if ((f & KBDS_BUFFER_FULL) == KBDS_AUX_BUFFER_FULL) {
|
||||
if ((b == PSM_ACK) || (b == PSM_RESEND)
|
||||
|| (b == PSM_RESET_FAIL))
|
||||
@ -437,7 +458,7 @@ write_controller_command(KBDC p, int c)
|
||||
{
|
||||
if (!wait_while_controller_busy(kbdcp(p)))
|
||||
return FALSE;
|
||||
outb(kbdcp(p)->port + KBD_COMMAND_PORT, c);
|
||||
write_command(kbdcp(p), c);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -447,7 +468,7 @@ write_controller_data(KBDC p, int c)
|
||||
{
|
||||
if (!wait_while_controller_busy(kbdcp(p)))
|
||||
return FALSE;
|
||||
outb(kbdcp(p)->port + KBD_DATA_PORT, c);
|
||||
write_data(kbdcp(p), c);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -457,7 +478,7 @@ write_kbd_command(KBDC p, int c)
|
||||
{
|
||||
if (!wait_while_controller_busy(kbdcp(p)))
|
||||
return FALSE;
|
||||
outb(kbdcp(p)->port + KBD_DATA_PORT, c);
|
||||
write_data(kbdcp(p), c);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -586,7 +607,7 @@ read_controller_data(KBDC p)
|
||||
return removeq(&kbdcp(p)->aux);
|
||||
if (!wait_for_data(kbdcp(p)))
|
||||
return -1; /* timeout */
|
||||
return inb(kbdcp(p)->port + KBD_DATA_PORT);
|
||||
return read_data(kbdcp(p));
|
||||
}
|
||||
|
||||
#if KBDIO_DEBUG >= 2
|
||||
@ -611,7 +632,7 @@ read_kbd_data(KBDC p)
|
||||
return removeq(&kbdcp(p)->kbd);
|
||||
if (!wait_for_kbd_data(kbdcp(p)))
|
||||
return -1; /* timeout */
|
||||
return inb(kbdcp(p)->port + KBD_DATA_PORT);
|
||||
return read_data(kbdcp(p));
|
||||
}
|
||||
|
||||
/* read one byte from the keyboard, but return immediately if
|
||||
@ -634,15 +655,15 @@ read_kbd_data_no_wait(KBDC p)
|
||||
|
||||
if (availq(&kbdcp(p)->kbd))
|
||||
return removeq(&kbdcp(p)->kbd);
|
||||
f = inb(kbdcp(p)->port + KBD_STATUS_PORT) & KBDS_BUFFER_FULL;
|
||||
f = read_status(kbdcp(p)) & KBDS_BUFFER_FULL;
|
||||
if (f == KBDS_AUX_BUFFER_FULL) {
|
||||
DELAY(KBDD_DELAYTIME);
|
||||
addq(&kbdcp(p)->aux, inb(kbdcp(p)->port + KBD_DATA_PORT));
|
||||
f = inb(kbdcp(p)->port + KBD_STATUS_PORT) & KBDS_BUFFER_FULL;
|
||||
addq(&kbdcp(p)->aux, read_data(kbdcp(p)));
|
||||
f = read_status(kbdcp(p)) & KBDS_BUFFER_FULL;
|
||||
}
|
||||
if (f == KBDS_KBD_BUFFER_FULL) {
|
||||
DELAY(KBDD_DELAYTIME);
|
||||
return inb(kbdcp(p)->port + KBD_DATA_PORT);
|
||||
return read_data(kbdcp(p));
|
||||
}
|
||||
return -1; /* no data */
|
||||
}
|
||||
@ -655,7 +676,7 @@ read_aux_data(KBDC p)
|
||||
return removeq(&kbdcp(p)->aux);
|
||||
if (!wait_for_aux_data(kbdcp(p)))
|
||||
return -1; /* timeout */
|
||||
return inb(kbdcp(p)->port + KBD_DATA_PORT);
|
||||
return read_data(kbdcp(p));
|
||||
}
|
||||
|
||||
/* read one byte from the aux device, but return immediately if
|
||||
@ -668,15 +689,15 @@ read_aux_data_no_wait(KBDC p)
|
||||
|
||||
if (availq(&kbdcp(p)->aux))
|
||||
return removeq(&kbdcp(p)->aux);
|
||||
f = inb(kbdcp(p)->port + KBD_STATUS_PORT) & KBDS_BUFFER_FULL;
|
||||
f = read_status(kbdcp(p)) & KBDS_BUFFER_FULL;
|
||||
if (f == KBDS_KBD_BUFFER_FULL) {
|
||||
DELAY(KBDD_DELAYTIME);
|
||||
addq(&kbdcp(p)->kbd, inb(kbdcp(p)->port + KBD_DATA_PORT));
|
||||
f = inb(kbdcp(p)->port + KBD_STATUS_PORT) & KBDS_BUFFER_FULL;
|
||||
addq(&kbdcp(p)->kbd, read_data(kbdcp(p)));
|
||||
f = read_status(kbdcp(p)) & KBDS_BUFFER_FULL;
|
||||
}
|
||||
if (f == KBDS_AUX_BUFFER_FULL) {
|
||||
DELAY(KBDD_DELAYTIME);
|
||||
return inb(kbdcp(p)->port + KBD_DATA_PORT);
|
||||
return read_data(kbdcp(p));
|
||||
}
|
||||
return -1; /* no data */
|
||||
}
|
||||
@ -695,9 +716,9 @@ empty_kbd_buffer(KBDC p, int wait)
|
||||
int delta = 2;
|
||||
|
||||
for (t = wait; t > 0; ) {
|
||||
if ((f = inb(kbdcp(p)->port + KBD_STATUS_PORT)) & KBDS_ANY_BUFFER_FULL) {
|
||||
if ((f = read_status(kbdcp(p))) & KBDS_ANY_BUFFER_FULL) {
|
||||
DELAY(KBDD_DELAYTIME);
|
||||
b = inb(kbdcp(p)->port + KBD_DATA_PORT);
|
||||
b = read_data(kbdcp(p));
|
||||
if ((f & KBDS_BUFFER_FULL) == KBDS_AUX_BUFFER_FULL) {
|
||||
addq(&kbdcp(p)->aux, b);
|
||||
#if KBDIO_DEBUG >= 2
|
||||
@ -734,9 +755,9 @@ empty_aux_buffer(KBDC p, int wait)
|
||||
int delta = 2;
|
||||
|
||||
for (t = wait; t > 0; ) {
|
||||
if ((f = inb(kbdcp(p)->port + KBD_STATUS_PORT)) & KBDS_ANY_BUFFER_FULL) {
|
||||
if ((f = read_status(kbdcp(p))) & KBDS_ANY_BUFFER_FULL) {
|
||||
DELAY(KBDD_DELAYTIME);
|
||||
b = inb(kbdcp(p)->port + KBD_DATA_PORT);
|
||||
b = read_data(kbdcp(p));
|
||||
if ((f & KBDS_BUFFER_FULL) == KBDS_KBD_BUFFER_FULL) {
|
||||
addq(&kbdcp(p)->kbd, b);
|
||||
#if KBDIO_DEBUG >= 2
|
||||
@ -772,9 +793,9 @@ empty_both_buffers(KBDC p, int wait)
|
||||
int delta = 2;
|
||||
|
||||
for (t = wait; t > 0; ) {
|
||||
if ((f = inb(kbdcp(p)->port + KBD_STATUS_PORT)) & KBDS_ANY_BUFFER_FULL) {
|
||||
if ((f = read_status(kbdcp(p))) & KBDS_ANY_BUFFER_FULL) {
|
||||
DELAY(KBDD_DELAYTIME);
|
||||
(void)inb(kbdcp(p)->port + KBD_DATA_PORT);
|
||||
(void)read_data(kbdcp(p));
|
||||
#if KBDIO_DEBUG >= 2
|
||||
if ((f & KBDS_BUFFER_FULL) == KBDS_KBD_BUFFER_FULL)
|
||||
++c1;
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <machine/bus_pio.h>
|
||||
#include <machine/bus.h>
|
||||
#include <machine/resource.h>
|
||||
#include <sys/rman.h>
|
||||
@ -87,32 +88,54 @@ static driver_t atkbdc_driver = {
|
||||
sizeof(atkbdc_softc_t *),
|
||||
};
|
||||
|
||||
static struct isa_pnp_id atkbdc_ids[] = {
|
||||
{ 0x0303d041, "Keyboard controller (i8042)" }, /* PNP0303 */
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static int
|
||||
atkbdc_probe(device_t dev)
|
||||
{
|
||||
int error;
|
||||
int rid;
|
||||
struct resource *port;
|
||||
struct resource *port0;
|
||||
struct resource *port1;
|
||||
int error;
|
||||
int rid;
|
||||
|
||||
/* Check isapnp ids */
|
||||
if (isa_get_vendorid(dev))
|
||||
return (ENXIO);
|
||||
|
||||
device_set_desc(dev, "keyboard controller (i8042)");
|
||||
rid = 0;
|
||||
port = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
|
||||
0, ~0, IO_KBDSIZE, RF_ACTIVE);
|
||||
if (!port)
|
||||
/* check PnP IDs */
|
||||
if (ISA_PNP_PROBE(device_get_parent(dev), dev, atkbdc_ids) == ENXIO)
|
||||
return ENXIO;
|
||||
error = atkbdc_probe_unit(device_get_unit(dev), rman_get_start(port));
|
||||
bus_release_resource(dev, SYS_RES_IOPORT, rid, port);
|
||||
|
||||
device_set_desc(dev, "Keyboard controller (i8042)");
|
||||
|
||||
rid = 0;
|
||||
port0 = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1,
|
||||
RF_ACTIVE);
|
||||
if (port0 == NULL)
|
||||
return ENXIO;
|
||||
/* XXX */
|
||||
if (bus_get_resource_start(dev, SYS_RES_IOPORT, 1) <= 0) {
|
||||
bus_set_resource(dev, SYS_RES_IOPORT, 1,
|
||||
rman_get_start(port0) + KBD_STATUS_PORT, 1);
|
||||
}
|
||||
rid = 1;
|
||||
port1 = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1,
|
||||
RF_ACTIVE);
|
||||
if (port1 == NULL) {
|
||||
bus_release_resource(dev, SYS_RES_IOPORT, 0, port0);
|
||||
return ENXIO;
|
||||
}
|
||||
|
||||
error = atkbdc_probe_unit(device_get_unit(dev), port0, port1);
|
||||
|
||||
bus_release_resource(dev, SYS_RES_IOPORT, 0, port0);
|
||||
bus_release_resource(dev, SYS_RES_IOPORT, 1, port1);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static void
|
||||
atkbdc_add_device(device_t dev, const char *name, int unit)
|
||||
{
|
||||
atkbdc_softc_t *sc = *(atkbdc_softc_t **)device_get_softc(dev);
|
||||
atkbdc_device_t *kdev;
|
||||
device_t child;
|
||||
int t;
|
||||
@ -125,8 +148,6 @@ atkbdc_add_device(device_t dev, const char *name, int unit)
|
||||
return;
|
||||
bzero(kdev, sizeof *kdev);
|
||||
|
||||
kdev->port = sc->port;
|
||||
|
||||
if (resource_int_value(name, unit, "irq", &t) == 0)
|
||||
kdev->irq = t;
|
||||
else
|
||||
@ -145,7 +166,6 @@ static int
|
||||
atkbdc_attach(device_t dev)
|
||||
{
|
||||
atkbdc_softc_t *sc;
|
||||
struct resource *port;
|
||||
int unit;
|
||||
int error;
|
||||
int rid;
|
||||
@ -166,15 +186,25 @@ atkbdc_attach(device_t dev)
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
/* XXX should track resource in softc */
|
||||
rid = 0;
|
||||
port = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
|
||||
0, ~0, IO_KBDSIZE, RF_ACTIVE);
|
||||
if (!port)
|
||||
sc->port0 = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1,
|
||||
RF_ACTIVE);
|
||||
if (sc->port0 == NULL)
|
||||
return ENXIO;
|
||||
error = atkbdc_attach_unit(unit, sc, rman_get_start(port));
|
||||
if (error)
|
||||
rid = 1;
|
||||
sc->port1 = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1,
|
||||
RF_ACTIVE);
|
||||
if (sc->port1 == NULL) {
|
||||
bus_release_resource(dev, SYS_RES_IOPORT, 0, sc->port0);
|
||||
return ENXIO;
|
||||
}
|
||||
|
||||
error = atkbdc_attach_unit(unit, sc, sc->port0, sc->port1);
|
||||
if (error) {
|
||||
bus_release_resource(dev, SYS_RES_IOPORT, 0, sc->port0);
|
||||
bus_release_resource(dev, SYS_RES_IOPORT, 1, sc->port1);
|
||||
return error;
|
||||
}
|
||||
*(atkbdc_softc_t **)device_get_softc(dev) = sc;
|
||||
|
||||
/*
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <machine/bus_pio.h>
|
||||
#include <machine/bus.h>
|
||||
#include <machine/resource.h>
|
||||
#include <sys/rman.h>
|
||||
@ -87,32 +88,54 @@ static driver_t atkbdc_driver = {
|
||||
sizeof(atkbdc_softc_t *),
|
||||
};
|
||||
|
||||
static struct isa_pnp_id atkbdc_ids[] = {
|
||||
{ 0x0303d041, "Keyboard controller (i8042)" }, /* PNP0303 */
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static int
|
||||
atkbdc_probe(device_t dev)
|
||||
{
|
||||
int error;
|
||||
int rid;
|
||||
struct resource *port;
|
||||
struct resource *port0;
|
||||
struct resource *port1;
|
||||
int error;
|
||||
int rid;
|
||||
|
||||
/* Check isapnp ids */
|
||||
if (isa_get_vendorid(dev))
|
||||
return (ENXIO);
|
||||
|
||||
device_set_desc(dev, "keyboard controller (i8042)");
|
||||
rid = 0;
|
||||
port = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
|
||||
0, ~0, IO_KBDSIZE, RF_ACTIVE);
|
||||
if (!port)
|
||||
/* check PnP IDs */
|
||||
if (ISA_PNP_PROBE(device_get_parent(dev), dev, atkbdc_ids) == ENXIO)
|
||||
return ENXIO;
|
||||
error = atkbdc_probe_unit(device_get_unit(dev), rman_get_start(port));
|
||||
bus_release_resource(dev, SYS_RES_IOPORT, rid, port);
|
||||
|
||||
device_set_desc(dev, "Keyboard controller (i8042)");
|
||||
|
||||
rid = 0;
|
||||
port0 = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1,
|
||||
RF_ACTIVE);
|
||||
if (port0 == NULL)
|
||||
return ENXIO;
|
||||
/* XXX */
|
||||
if (bus_get_resource_start(dev, SYS_RES_IOPORT, 1) <= 0) {
|
||||
bus_set_resource(dev, SYS_RES_IOPORT, 1,
|
||||
rman_get_start(port0) + KBD_STATUS_PORT, 1);
|
||||
}
|
||||
rid = 1;
|
||||
port1 = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1,
|
||||
RF_ACTIVE);
|
||||
if (port1 == NULL) {
|
||||
bus_release_resource(dev, SYS_RES_IOPORT, 0, port0);
|
||||
return ENXIO;
|
||||
}
|
||||
|
||||
error = atkbdc_probe_unit(device_get_unit(dev), port0, port1);
|
||||
|
||||
bus_release_resource(dev, SYS_RES_IOPORT, 0, port0);
|
||||
bus_release_resource(dev, SYS_RES_IOPORT, 1, port1);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static void
|
||||
atkbdc_add_device(device_t dev, const char *name, int unit)
|
||||
{
|
||||
atkbdc_softc_t *sc = *(atkbdc_softc_t **)device_get_softc(dev);
|
||||
atkbdc_device_t *kdev;
|
||||
device_t child;
|
||||
int t;
|
||||
@ -125,8 +148,6 @@ atkbdc_add_device(device_t dev, const char *name, int unit)
|
||||
return;
|
||||
bzero(kdev, sizeof *kdev);
|
||||
|
||||
kdev->port = sc->port;
|
||||
|
||||
if (resource_int_value(name, unit, "irq", &t) == 0)
|
||||
kdev->irq = t;
|
||||
else
|
||||
@ -145,7 +166,6 @@ static int
|
||||
atkbdc_attach(device_t dev)
|
||||
{
|
||||
atkbdc_softc_t *sc;
|
||||
struct resource *port;
|
||||
int unit;
|
||||
int error;
|
||||
int rid;
|
||||
@ -166,15 +186,25 @@ atkbdc_attach(device_t dev)
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
/* XXX should track resource in softc */
|
||||
rid = 0;
|
||||
port = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
|
||||
0, ~0, IO_KBDSIZE, RF_ACTIVE);
|
||||
if (!port)
|
||||
sc->port0 = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1,
|
||||
RF_ACTIVE);
|
||||
if (sc->port0 == NULL)
|
||||
return ENXIO;
|
||||
error = atkbdc_attach_unit(unit, sc, rman_get_start(port));
|
||||
if (error)
|
||||
rid = 1;
|
||||
sc->port1 = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1,
|
||||
RF_ACTIVE);
|
||||
if (sc->port1 == NULL) {
|
||||
bus_release_resource(dev, SYS_RES_IOPORT, 0, sc->port0);
|
||||
return ENXIO;
|
||||
}
|
||||
|
||||
error = atkbdc_attach_unit(unit, sc, sc->port0, sc->port1);
|
||||
if (error) {
|
||||
bus_release_resource(dev, SYS_RES_IOPORT, 0, sc->port0);
|
||||
bus_release_resource(dev, SYS_RES_IOPORT, 1, sc->port1);
|
||||
return error;
|
||||
}
|
||||
*(atkbdc_softc_t **)device_get_softc(dev) = sc;
|
||||
|
||||
/*
|
||||
|
@ -184,8 +184,14 @@ typedef struct _kqueue {
|
||||
#endif
|
||||
} kqueue;
|
||||
|
||||
struct resource;
|
||||
|
||||
typedef struct atkbdc_softc {
|
||||
int port; /* base port address */
|
||||
struct resource *port0; /* data port */
|
||||
struct resource *port1; /* status port */
|
||||
bus_space_tag_t iot;
|
||||
bus_space_handle_t ioh0;
|
||||
bus_space_handle_t ioh1;
|
||||
int command_byte; /* current command byte value */
|
||||
int command_mask; /* command byte mask bits for kbd/aux devices */
|
||||
int lock; /* FIXME: XXX not quite a semaphore... */
|
||||
@ -194,9 +200,12 @@ typedef struct atkbdc_softc {
|
||||
} atkbdc_softc_t;
|
||||
|
||||
enum kbdc_device_ivar {
|
||||
KBDC_IVAR_PORT,
|
||||
KBDC_IVAR_IRQ,
|
||||
KBDC_IVAR_FLAGS,
|
||||
KBDC_IVAR_VENDORID,
|
||||
KBDC_IVAR_SERIAL,
|
||||
KBDC_IVAR_LOGICALID,
|
||||
KBDC_IVAR_COMPATID,
|
||||
};
|
||||
|
||||
typedef caddr_t KBDC;
|
||||
@ -204,11 +213,12 @@ typedef caddr_t KBDC;
|
||||
/* function prototypes */
|
||||
|
||||
atkbdc_softc_t *atkbdc_get_softc(int unit);
|
||||
int atkbdc_probe_unit(int unit, int port);
|
||||
int atkbdc_attach_unit(int unit, atkbdc_softc_t *sc, int port);
|
||||
int atkbdc_probe_unit(int unit, struct resource *port0, struct resource *port1);
|
||||
int atkbdc_attach_unit(int unit, atkbdc_softc_t *sc, struct resource *port0,
|
||||
struct resource *port1);
|
||||
int atkbdc_configure(void);
|
||||
|
||||
KBDC kbdc_open(int port);
|
||||
KBDC atkbdc_open(int unit);
|
||||
int kbdc_lock(KBDC kbdc, int lock);
|
||||
int kbdc_data_ready(KBDC kbdc);
|
||||
|
||||
|
@ -38,9 +38,9 @@
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
int atkbd_probe_unit(int unit, int port, int irq, int flags);
|
||||
int atkbd_probe_unit(int unit, int ctlr, int irq, int flags);
|
||||
int atkbd_attach_unit(int unit, keyboard_t **kbd,
|
||||
int port, int irq, int flags);
|
||||
int ctlr, int irq, int flags);
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -36,6 +36,9 @@
|
||||
#include <sys/proc.h>
|
||||
#include <sys/malloc.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <machine/resource.h>
|
||||
|
||||
#ifdef __i386__
|
||||
#include <machine/md_var.h>
|
||||
#include <machine/psl.h>
|
||||
@ -55,7 +58,7 @@
|
||||
static timeout_t atkbd_timeout;
|
||||
|
||||
int
|
||||
atkbd_probe_unit(int unit, int port, int irq, int flags)
|
||||
atkbd_probe_unit(int unit, int ctlr, int irq, int flags)
|
||||
{
|
||||
keyboard_switch_t *sw;
|
||||
int args[2];
|
||||
@ -65,7 +68,7 @@ atkbd_probe_unit(int unit, int port, int irq, int flags)
|
||||
if (sw == NULL)
|
||||
return ENXIO;
|
||||
|
||||
args[0] = port;
|
||||
args[0] = ctlr;
|
||||
args[1] = irq;
|
||||
error = (*sw->probe)(unit, args, flags);
|
||||
if (error)
|
||||
@ -74,7 +77,7 @@ atkbd_probe_unit(int unit, int port, int irq, int flags)
|
||||
}
|
||||
|
||||
int
|
||||
atkbd_attach_unit(int unit, keyboard_t **kbd, int port, int irq, int flags)
|
||||
atkbd_attach_unit(int unit, keyboard_t **kbd, int ctlr, int irq, int flags)
|
||||
{
|
||||
keyboard_switch_t *sw;
|
||||
int args[2];
|
||||
@ -85,7 +88,7 @@ atkbd_attach_unit(int unit, keyboard_t **kbd, int port, int irq, int flags)
|
||||
return ENXIO;
|
||||
|
||||
/* reset, initialize and enable the device */
|
||||
args[0] = port;
|
||||
args[0] = ctlr;
|
||||
args[1] = irq;
|
||||
*kbd = NULL;
|
||||
error = (*sw->probe)(unit, args, flags);
|
||||
@ -311,7 +314,7 @@ static int
|
||||
atkbd_probe(int unit, void *arg, int flags)
|
||||
{
|
||||
KBDC kbdc;
|
||||
int *data = (int *)arg;
|
||||
int *data = (int *)arg; /* data[0]: controller, data[1]: irq */
|
||||
|
||||
/* XXX */
|
||||
if (unit == ATKBD_DEFAULT) {
|
||||
@ -319,7 +322,7 @@ atkbd_probe(int unit, void *arg, int flags)
|
||||
return 0;
|
||||
}
|
||||
|
||||
kbdc = kbdc_open(data[0]);
|
||||
kbdc = atkbdc_open(data[0]);
|
||||
if (kbdc == NULL)
|
||||
return ENXIO;
|
||||
if (probe_keyboard(kbdc, flags)) {
|
||||
@ -340,7 +343,7 @@ atkbd_init(int unit, keyboard_t **kbdp, void *arg, int flags)
|
||||
fkeytab_t *fkeymap;
|
||||
int fkeymap_size;
|
||||
int delay[2];
|
||||
int *data = (int *)arg;
|
||||
int *data = (int *)arg; /* data[0]: controller, data[1]: irq */
|
||||
|
||||
/* XXX */
|
||||
if (unit == ATKBD_DEFAULT) {
|
||||
@ -390,11 +393,11 @@ atkbd_init(int unit, keyboard_t **kbdp, void *arg, int flags)
|
||||
}
|
||||
|
||||
if (!KBD_IS_PROBED(kbd)) {
|
||||
state->kbdc = kbdc_open(data[0]);
|
||||
state->kbdc = atkbdc_open(data[0]);
|
||||
if (state->kbdc == NULL)
|
||||
return ENXIO;
|
||||
kbd_init_struct(kbd, ATKBD_DRIVER_NAME, KB_OTHER, unit, flags,
|
||||
data[0], IO_KBDSIZE);
|
||||
0, 0);
|
||||
bcopy(&key_map, keymap, sizeof(key_map));
|
||||
bcopy(&accent_map, accmap, sizeof(accent_map));
|
||||
bcopy(fkey_tab, fkeymap,
|
||||
|
@ -36,9 +36,13 @@
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/syslog.h>
|
||||
#include <machine/bus_pio.h>
|
||||
#include <machine/bus.h>
|
||||
#include <machine/resource.h>
|
||||
#include <sys/rman.h>
|
||||
|
||||
#include <machine/clock.h>
|
||||
|
||||
@ -65,6 +69,13 @@
|
||||
#define emptyq(q) ((q)->tail = (q)->head = 0)
|
||||
#endif
|
||||
|
||||
#define read_data(k) (bus_space_read_1((k)->iot, (k)->ioh0, 0))
|
||||
#define read_status(k) (bus_space_read_1((k)->iot, (k)->ioh1, 0))
|
||||
#define write_data(k, d) \
|
||||
(bus_space_write_1((k)->iot, (k)->ioh0, 0, (d)))
|
||||
#define write_command(k, d) \
|
||||
(bus_space_write_1((k)->iot, (k)->ioh1, 0, (d)))
|
||||
|
||||
/* local variables */
|
||||
|
||||
/*
|
||||
@ -80,7 +91,8 @@ static int verbose = KBDIO_DEBUG;
|
||||
|
||||
/* function prototypes */
|
||||
|
||||
static int atkbdc_setup(atkbdc_softc_t *sc, int port);
|
||||
static int atkbdc_setup(atkbdc_softc_t *sc, bus_space_tag_t tag,
|
||||
bus_space_handle_t h0, bus_space_handle_t h1);
|
||||
static int addq(kqueue *q, int c);
|
||||
static int removeq(kqueue *q);
|
||||
static int wait_while_controller_busy(atkbdc_softc_t *kbdc);
|
||||
@ -104,39 +116,68 @@ atkbdc_softc_t
|
||||
if (sc == NULL)
|
||||
return NULL;
|
||||
bzero(sc, sizeof(*sc));
|
||||
sc->port = -1; /* XXX */
|
||||
}
|
||||
return sc;
|
||||
}
|
||||
|
||||
int
|
||||
atkbdc_probe_unit(int unit, int port)
|
||||
atkbdc_probe_unit(int unit, struct resource *port0, struct resource *port1)
|
||||
{
|
||||
if (port <= 0)
|
||||
if (rman_get_start(port0) <= 0)
|
||||
return ENXIO;
|
||||
if (rman_get_start(port1) <= 0)
|
||||
return ENXIO;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
atkbdc_attach_unit(int unit, atkbdc_softc_t *sc, int port)
|
||||
atkbdc_attach_unit(int unit, atkbdc_softc_t *sc, struct resource *port0,
|
||||
struct resource *port1)
|
||||
{
|
||||
return atkbdc_setup(sc, port);
|
||||
return atkbdc_setup(sc, rman_get_bustag(port0),
|
||||
rman_get_bushandle(port0),
|
||||
rman_get_bushandle(port1));
|
||||
}
|
||||
|
||||
/* the backdoor to the keyboard controller! XXX */
|
||||
int
|
||||
atkbdc_configure(void)
|
||||
{
|
||||
return atkbdc_setup(atkbdc_softc[0], -1);
|
||||
bus_space_tag_t tag;
|
||||
bus_space_handle_t h0;
|
||||
bus_space_handle_t h1;
|
||||
int port0;
|
||||
int port1;
|
||||
|
||||
port0 = IO_KBD;
|
||||
resource_int_value("atkbdc", 0, "port", &port0);
|
||||
port1 = IO_KBD + KBD_STATUS_PORT;
|
||||
#if 0
|
||||
resource_int_value("atkbdc", 0, "port", &port0);
|
||||
#endif
|
||||
|
||||
/* XXX: tag should be passed from the caller */
|
||||
#if defined(__i386__)
|
||||
tag = I386_BUS_SPACE_IO;
|
||||
#elif defined(__alpha__)
|
||||
tag = ALPHA_BUS_SPACE_IO;
|
||||
#endif
|
||||
|
||||
#if notyet
|
||||
bus_space_map(tag, port0, IO_KBDSIZE, 0, &h0);
|
||||
bus_space_map(tag, port1, IO_KBDSIZE, 0, &h1);
|
||||
#else
|
||||
h0 = (bus_space_handle_t)port0;
|
||||
h1 = (bus_space_handle_t)port1;
|
||||
#endif
|
||||
return atkbdc_setup(atkbdc_softc[0], tag, h0, h1);
|
||||
}
|
||||
|
||||
static int
|
||||
atkbdc_setup(atkbdc_softc_t *sc, int port)
|
||||
atkbdc_setup(atkbdc_softc_t *sc, bus_space_tag_t tag, bus_space_handle_t h0,
|
||||
bus_space_handle_t h1)
|
||||
{
|
||||
if (port <= 0)
|
||||
port = IO_KBD;
|
||||
|
||||
if (sc->port <= 0) {
|
||||
if (sc->ioh0 == 0) { /* XXX */
|
||||
sc->command_byte = -1;
|
||||
sc->command_mask = 0;
|
||||
sc->lock = FALSE;
|
||||
@ -149,37 +190,23 @@ atkbdc_setup(atkbdc_softc_t *sc, int port)
|
||||
sc->aux.qcount = sc->aux.max_qcount = 0;
|
||||
#endif
|
||||
}
|
||||
sc->port = port; /* may override the previous value */
|
||||
sc->iot = tag;
|
||||
sc->ioh0 = h0;
|
||||
sc->ioh1 = h1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* associate a port number with a KBDC */
|
||||
|
||||
/* open a keyboard controller */
|
||||
KBDC
|
||||
kbdc_open(int port)
|
||||
atkbdc_open(int unit)
|
||||
{
|
||||
int s;
|
||||
int i;
|
||||
|
||||
if (port <= 0)
|
||||
port = IO_KBD;
|
||||
|
||||
s = spltty();
|
||||
for (i = 0; i < sizeof(atkbdc_softc)/sizeof(atkbdc_softc[0]); ++i) {
|
||||
if (atkbdc_softc[i] == NULL)
|
||||
continue;
|
||||
if (atkbdc_softc[i]->port == port) {
|
||||
splx(s);
|
||||
return (KBDC)atkbdc_softc[i];
|
||||
}
|
||||
if (atkbdc_softc[i]->port <= 0) {
|
||||
if (atkbdc_setup(atkbdc_softc[i], port))
|
||||
break;
|
||||
splx(s);
|
||||
return (KBDC)atkbdc_softc[i];
|
||||
}
|
||||
}
|
||||
splx(s);
|
||||
if (unit <= 0)
|
||||
unit = 0;
|
||||
if (unit >= MAXKBDC)
|
||||
return NULL;
|
||||
if ((atkbdc_softc[unit]->port0 != NULL)
|
||||
|| (atkbdc_softc[unit]->ioh0 != 0)) /* XXX */
|
||||
return (KBDC)atkbdc_softc[unit];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -238,7 +265,7 @@ int
|
||||
kbdc_data_ready(KBDC p)
|
||||
{
|
||||
return (availq(&kbdcp(p)->kbd) || availq(&kbdcp(p)->aux)
|
||||
|| (inb(kbdcp(p)->port + KBD_STATUS_PORT) & KBDS_ANY_BUFFER_FULL));
|
||||
|| (read_status(kbdcp(p)) & KBDS_ANY_BUFFER_FULL));
|
||||
}
|
||||
|
||||
/* queuing functions */
|
||||
@ -284,16 +311,15 @@ wait_while_controller_busy(struct atkbdc_softc *kbdc)
|
||||
{
|
||||
/* CPU will stay inside the loop for 100msec at most */
|
||||
int retry = 5000;
|
||||
int port = kbdc->port;
|
||||
int f;
|
||||
|
||||
while ((f = inb(port + KBD_STATUS_PORT)) & KBDS_INPUT_BUFFER_FULL) {
|
||||
while ((f = read_status(kbdc)) & KBDS_INPUT_BUFFER_FULL) {
|
||||
if ((f & KBDS_BUFFER_FULL) == KBDS_KBD_BUFFER_FULL) {
|
||||
DELAY(KBDD_DELAYTIME);
|
||||
addq(&kbdc->kbd, inb(port + KBD_DATA_PORT));
|
||||
addq(&kbdc->kbd, read_data(kbdc));
|
||||
} else if ((f & KBDS_BUFFER_FULL) == KBDS_AUX_BUFFER_FULL) {
|
||||
DELAY(KBDD_DELAYTIME);
|
||||
addq(&kbdc->aux, inb(port + KBD_DATA_PORT));
|
||||
addq(&kbdc->aux, read_data(kbdc));
|
||||
}
|
||||
DELAY(KBDC_DELAYTIME);
|
||||
if (--retry < 0)
|
||||
@ -311,10 +337,9 @@ wait_for_data(struct atkbdc_softc *kbdc)
|
||||
{
|
||||
/* CPU will stay inside the loop for 200msec at most */
|
||||
int retry = 10000;
|
||||
int port = kbdc->port;
|
||||
int f;
|
||||
|
||||
while ((f = inb(port + KBD_STATUS_PORT) & KBDS_ANY_BUFFER_FULL) == 0) {
|
||||
while ((f = read_status(kbdc) & KBDS_ANY_BUFFER_FULL) == 0) {
|
||||
DELAY(KBDC_DELAYTIME);
|
||||
if (--retry < 0)
|
||||
return 0;
|
||||
@ -329,14 +354,13 @@ wait_for_kbd_data(struct atkbdc_softc *kbdc)
|
||||
{
|
||||
/* CPU will stay inside the loop for 200msec at most */
|
||||
int retry = 10000;
|
||||
int port = kbdc->port;
|
||||
int f;
|
||||
|
||||
while ((f = inb(port + KBD_STATUS_PORT) & KBDS_BUFFER_FULL)
|
||||
while ((f = read_status(kbdc) & KBDS_BUFFER_FULL)
|
||||
!= KBDS_KBD_BUFFER_FULL) {
|
||||
if (f == KBDS_AUX_BUFFER_FULL) {
|
||||
DELAY(KBDD_DELAYTIME);
|
||||
addq(&kbdc->aux, inb(port + KBD_DATA_PORT));
|
||||
addq(&kbdc->aux, read_data(kbdc));
|
||||
}
|
||||
DELAY(KBDC_DELAYTIME);
|
||||
if (--retry < 0)
|
||||
@ -355,14 +379,13 @@ wait_for_kbd_ack(struct atkbdc_softc *kbdc)
|
||||
{
|
||||
/* CPU will stay inside the loop for 200msec at most */
|
||||
int retry = 10000;
|
||||
int port = kbdc->port;
|
||||
int f;
|
||||
int b;
|
||||
|
||||
while (retry-- > 0) {
|
||||
if ((f = inb(port + KBD_STATUS_PORT)) & KBDS_ANY_BUFFER_FULL) {
|
||||
if ((f = read_status(kbdc)) & KBDS_ANY_BUFFER_FULL) {
|
||||
DELAY(KBDD_DELAYTIME);
|
||||
b = inb(port + KBD_DATA_PORT);
|
||||
b = read_data(kbdc);
|
||||
if ((f & KBDS_BUFFER_FULL) == KBDS_KBD_BUFFER_FULL) {
|
||||
if ((b == KBD_ACK) || (b == KBD_RESEND)
|
||||
|| (b == KBD_RESET_FAIL))
|
||||
@ -383,14 +406,13 @@ wait_for_aux_data(struct atkbdc_softc *kbdc)
|
||||
{
|
||||
/* CPU will stay inside the loop for 200msec at most */
|
||||
int retry = 10000;
|
||||
int port = kbdc->port;
|
||||
int f;
|
||||
|
||||
while ((f = inb(port + KBD_STATUS_PORT) & KBDS_BUFFER_FULL)
|
||||
while ((f = read_status(kbdc) & KBDS_BUFFER_FULL)
|
||||
!= KBDS_AUX_BUFFER_FULL) {
|
||||
if (f == KBDS_KBD_BUFFER_FULL) {
|
||||
DELAY(KBDD_DELAYTIME);
|
||||
addq(&kbdc->kbd, inb(port + KBD_DATA_PORT));
|
||||
addq(&kbdc->kbd, read_data(kbdc));
|
||||
}
|
||||
DELAY(KBDC_DELAYTIME);
|
||||
if (--retry < 0)
|
||||
@ -409,14 +431,13 @@ wait_for_aux_ack(struct atkbdc_softc *kbdc)
|
||||
{
|
||||
/* CPU will stay inside the loop for 200msec at most */
|
||||
int retry = 10000;
|
||||
int port = kbdc->port;
|
||||
int f;
|
||||
int b;
|
||||
|
||||
while (retry-- > 0) {
|
||||
if ((f = inb(port + KBD_STATUS_PORT)) & KBDS_ANY_BUFFER_FULL) {
|
||||
if ((f = read_status(kbdc)) & KBDS_ANY_BUFFER_FULL) {
|
||||
DELAY(KBDD_DELAYTIME);
|
||||
b = inb(port + KBD_DATA_PORT);
|
||||
b = read_data(kbdc);
|
||||
if ((f & KBDS_BUFFER_FULL) == KBDS_AUX_BUFFER_FULL) {
|
||||
if ((b == PSM_ACK) || (b == PSM_RESEND)
|
||||
|| (b == PSM_RESET_FAIL))
|
||||
@ -437,7 +458,7 @@ write_controller_command(KBDC p, int c)
|
||||
{
|
||||
if (!wait_while_controller_busy(kbdcp(p)))
|
||||
return FALSE;
|
||||
outb(kbdcp(p)->port + KBD_COMMAND_PORT, c);
|
||||
write_command(kbdcp(p), c);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -447,7 +468,7 @@ write_controller_data(KBDC p, int c)
|
||||
{
|
||||
if (!wait_while_controller_busy(kbdcp(p)))
|
||||
return FALSE;
|
||||
outb(kbdcp(p)->port + KBD_DATA_PORT, c);
|
||||
write_data(kbdcp(p), c);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -457,7 +478,7 @@ write_kbd_command(KBDC p, int c)
|
||||
{
|
||||
if (!wait_while_controller_busy(kbdcp(p)))
|
||||
return FALSE;
|
||||
outb(kbdcp(p)->port + KBD_DATA_PORT, c);
|
||||
write_data(kbdcp(p), c);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -586,7 +607,7 @@ read_controller_data(KBDC p)
|
||||
return removeq(&kbdcp(p)->aux);
|
||||
if (!wait_for_data(kbdcp(p)))
|
||||
return -1; /* timeout */
|
||||
return inb(kbdcp(p)->port + KBD_DATA_PORT);
|
||||
return read_data(kbdcp(p));
|
||||
}
|
||||
|
||||
#if KBDIO_DEBUG >= 2
|
||||
@ -611,7 +632,7 @@ read_kbd_data(KBDC p)
|
||||
return removeq(&kbdcp(p)->kbd);
|
||||
if (!wait_for_kbd_data(kbdcp(p)))
|
||||
return -1; /* timeout */
|
||||
return inb(kbdcp(p)->port + KBD_DATA_PORT);
|
||||
return read_data(kbdcp(p));
|
||||
}
|
||||
|
||||
/* read one byte from the keyboard, but return immediately if
|
||||
@ -634,15 +655,15 @@ read_kbd_data_no_wait(KBDC p)
|
||||
|
||||
if (availq(&kbdcp(p)->kbd))
|
||||
return removeq(&kbdcp(p)->kbd);
|
||||
f = inb(kbdcp(p)->port + KBD_STATUS_PORT) & KBDS_BUFFER_FULL;
|
||||
f = read_status(kbdcp(p)) & KBDS_BUFFER_FULL;
|
||||
if (f == KBDS_AUX_BUFFER_FULL) {
|
||||
DELAY(KBDD_DELAYTIME);
|
||||
addq(&kbdcp(p)->aux, inb(kbdcp(p)->port + KBD_DATA_PORT));
|
||||
f = inb(kbdcp(p)->port + KBD_STATUS_PORT) & KBDS_BUFFER_FULL;
|
||||
addq(&kbdcp(p)->aux, read_data(kbdcp(p)));
|
||||
f = read_status(kbdcp(p)) & KBDS_BUFFER_FULL;
|
||||
}
|
||||
if (f == KBDS_KBD_BUFFER_FULL) {
|
||||
DELAY(KBDD_DELAYTIME);
|
||||
return inb(kbdcp(p)->port + KBD_DATA_PORT);
|
||||
return read_data(kbdcp(p));
|
||||
}
|
||||
return -1; /* no data */
|
||||
}
|
||||
@ -655,7 +676,7 @@ read_aux_data(KBDC p)
|
||||
return removeq(&kbdcp(p)->aux);
|
||||
if (!wait_for_aux_data(kbdcp(p)))
|
||||
return -1; /* timeout */
|
||||
return inb(kbdcp(p)->port + KBD_DATA_PORT);
|
||||
return read_data(kbdcp(p));
|
||||
}
|
||||
|
||||
/* read one byte from the aux device, but return immediately if
|
||||
@ -668,15 +689,15 @@ read_aux_data_no_wait(KBDC p)
|
||||
|
||||
if (availq(&kbdcp(p)->aux))
|
||||
return removeq(&kbdcp(p)->aux);
|
||||
f = inb(kbdcp(p)->port + KBD_STATUS_PORT) & KBDS_BUFFER_FULL;
|
||||
f = read_status(kbdcp(p)) & KBDS_BUFFER_FULL;
|
||||
if (f == KBDS_KBD_BUFFER_FULL) {
|
||||
DELAY(KBDD_DELAYTIME);
|
||||
addq(&kbdcp(p)->kbd, inb(kbdcp(p)->port + KBD_DATA_PORT));
|
||||
f = inb(kbdcp(p)->port + KBD_STATUS_PORT) & KBDS_BUFFER_FULL;
|
||||
addq(&kbdcp(p)->kbd, read_data(kbdcp(p)));
|
||||
f = read_status(kbdcp(p)) & KBDS_BUFFER_FULL;
|
||||
}
|
||||
if (f == KBDS_AUX_BUFFER_FULL) {
|
||||
DELAY(KBDD_DELAYTIME);
|
||||
return inb(kbdcp(p)->port + KBD_DATA_PORT);
|
||||
return read_data(kbdcp(p));
|
||||
}
|
||||
return -1; /* no data */
|
||||
}
|
||||
@ -695,9 +716,9 @@ empty_kbd_buffer(KBDC p, int wait)
|
||||
int delta = 2;
|
||||
|
||||
for (t = wait; t > 0; ) {
|
||||
if ((f = inb(kbdcp(p)->port + KBD_STATUS_PORT)) & KBDS_ANY_BUFFER_FULL) {
|
||||
if ((f = read_status(kbdcp(p))) & KBDS_ANY_BUFFER_FULL) {
|
||||
DELAY(KBDD_DELAYTIME);
|
||||
b = inb(kbdcp(p)->port + KBD_DATA_PORT);
|
||||
b = read_data(kbdcp(p));
|
||||
if ((f & KBDS_BUFFER_FULL) == KBDS_AUX_BUFFER_FULL) {
|
||||
addq(&kbdcp(p)->aux, b);
|
||||
#if KBDIO_DEBUG >= 2
|
||||
@ -734,9 +755,9 @@ empty_aux_buffer(KBDC p, int wait)
|
||||
int delta = 2;
|
||||
|
||||
for (t = wait; t > 0; ) {
|
||||
if ((f = inb(kbdcp(p)->port + KBD_STATUS_PORT)) & KBDS_ANY_BUFFER_FULL) {
|
||||
if ((f = read_status(kbdcp(p))) & KBDS_ANY_BUFFER_FULL) {
|
||||
DELAY(KBDD_DELAYTIME);
|
||||
b = inb(kbdcp(p)->port + KBD_DATA_PORT);
|
||||
b = read_data(kbdcp(p));
|
||||
if ((f & KBDS_BUFFER_FULL) == KBDS_KBD_BUFFER_FULL) {
|
||||
addq(&kbdcp(p)->kbd, b);
|
||||
#if KBDIO_DEBUG >= 2
|
||||
@ -772,9 +793,9 @@ empty_both_buffers(KBDC p, int wait)
|
||||
int delta = 2;
|
||||
|
||||
for (t = wait; t > 0; ) {
|
||||
if ((f = inb(kbdcp(p)->port + KBD_STATUS_PORT)) & KBDS_ANY_BUFFER_FULL) {
|
||||
if ((f = read_status(kbdcp(p))) & KBDS_ANY_BUFFER_FULL) {
|
||||
DELAY(KBDD_DELAYTIME);
|
||||
(void)inb(kbdcp(p)->port + KBD_DATA_PORT);
|
||||
(void)read_data(kbdcp(p));
|
||||
#if KBDIO_DEBUG >= 2
|
||||
if ((f & KBDS_BUFFER_FULL) == KBDS_KBD_BUFFER_FULL)
|
||||
++c1;
|
||||
|
@ -184,8 +184,14 @@ typedef struct _kqueue {
|
||||
#endif
|
||||
} kqueue;
|
||||
|
||||
struct resource;
|
||||
|
||||
typedef struct atkbdc_softc {
|
||||
int port; /* base port address */
|
||||
struct resource *port0; /* data port */
|
||||
struct resource *port1; /* status port */
|
||||
bus_space_tag_t iot;
|
||||
bus_space_handle_t ioh0;
|
||||
bus_space_handle_t ioh1;
|
||||
int command_byte; /* current command byte value */
|
||||
int command_mask; /* command byte mask bits for kbd/aux devices */
|
||||
int lock; /* FIXME: XXX not quite a semaphore... */
|
||||
@ -194,9 +200,12 @@ typedef struct atkbdc_softc {
|
||||
} atkbdc_softc_t;
|
||||
|
||||
enum kbdc_device_ivar {
|
||||
KBDC_IVAR_PORT,
|
||||
KBDC_IVAR_IRQ,
|
||||
KBDC_IVAR_FLAGS,
|
||||
KBDC_IVAR_VENDORID,
|
||||
KBDC_IVAR_SERIAL,
|
||||
KBDC_IVAR_LOGICALID,
|
||||
KBDC_IVAR_COMPATID,
|
||||
};
|
||||
|
||||
typedef caddr_t KBDC;
|
||||
@ -204,11 +213,12 @@ typedef caddr_t KBDC;
|
||||
/* function prototypes */
|
||||
|
||||
atkbdc_softc_t *atkbdc_get_softc(int unit);
|
||||
int atkbdc_probe_unit(int unit, int port);
|
||||
int atkbdc_attach_unit(int unit, atkbdc_softc_t *sc, int port);
|
||||
int atkbdc_probe_unit(int unit, struct resource *port0, struct resource *port1);
|
||||
int atkbdc_attach_unit(int unit, atkbdc_softc_t *sc, struct resource *port0,
|
||||
struct resource *port1);
|
||||
int atkbdc_configure(void);
|
||||
|
||||
KBDC kbdc_open(int port);
|
||||
KBDC atkbdc_open(int unit);
|
||||
int kbdc_lock(KBDC kbdc, int lock);
|
||||
int kbdc_data_ready(KBDC kbdc);
|
||||
|
||||
|
@ -38,9 +38,9 @@
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
int atkbd_probe_unit(int unit, int port, int irq, int flags);
|
||||
int atkbd_probe_unit(int unit, int ctlr, int irq, int flags);
|
||||
int atkbd_attach_unit(int unit, keyboard_t **kbd,
|
||||
int port, int irq, int flags);
|
||||
int ctlr, int irq, int flags);
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -90,6 +90,8 @@
|
||||
|
||||
#include <i386/isa/pcvt/pcvt_conf.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
|
||||
#include <dev/kbd/kbdreg.h>
|
||||
#include <dev/kbd/atkbdcreg.h>
|
||||
|
||||
|
@ -31,13 +31,11 @@
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/tty.h>
|
||||
#include <sys/bus.h>
|
||||
#include <machine/bus.h>
|
||||
#include <sys/rman.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <machine/resource.h>
|
||||
#include <sys/rman.h>
|
||||
|
||||
#include <dev/kbd/kbdreg.h>
|
||||
#include <dev/kbd/atkbdreg.h>
|
||||
@ -46,6 +44,11 @@
|
||||
#include <isa/isareg.h>
|
||||
#include <isa/isavar.h>
|
||||
|
||||
typedef struct {
|
||||
struct resource *intr;
|
||||
void *ih;
|
||||
} atkbd_softc_t;
|
||||
|
||||
devclass_t atkbd_devclass;
|
||||
|
||||
static int atkbdprobe(device_t dev);
|
||||
@ -61,52 +64,54 @@ static device_method_t atkbd_methods[] = {
|
||||
static driver_t atkbd_driver = {
|
||||
ATKBD_DRIVER_NAME,
|
||||
atkbd_methods,
|
||||
1,
|
||||
sizeof(atkbd_softc_t),
|
||||
};
|
||||
|
||||
static int
|
||||
atkbdprobe(device_t dev)
|
||||
{
|
||||
uintptr_t port;
|
||||
uintptr_t irq;
|
||||
uintptr_t flags;
|
||||
|
||||
device_set_desc(dev, "AT Keyboard");
|
||||
|
||||
/* obtain parameters */
|
||||
BUS_READ_IVAR(device_get_parent(dev), dev, KBDC_IVAR_PORT, &port);
|
||||
BUS_READ_IVAR(device_get_parent(dev), dev, KBDC_IVAR_IRQ, &irq);
|
||||
BUS_READ_IVAR(device_get_parent(dev), dev, KBDC_IVAR_FLAGS, &flags);
|
||||
|
||||
/* probe the device */
|
||||
return atkbd_probe_unit(device_get_unit(dev), port, irq, flags);
|
||||
return atkbd_probe_unit(device_get_unit(dev),
|
||||
device_get_unit(device_get_parent(dev)),
|
||||
irq, flags);
|
||||
}
|
||||
|
||||
static int
|
||||
atkbdattach(device_t dev)
|
||||
{
|
||||
atkbd_softc_t *sc;
|
||||
keyboard_t *kbd;
|
||||
uintptr_t port;
|
||||
uintptr_t irq;
|
||||
uintptr_t flags;
|
||||
struct resource *res;
|
||||
void *ih;
|
||||
int zero = 0;
|
||||
int rid;
|
||||
int error;
|
||||
|
||||
BUS_READ_IVAR(device_get_parent(dev), dev, KBDC_IVAR_PORT, &port);
|
||||
sc = device_get_softc(dev);
|
||||
|
||||
BUS_READ_IVAR(device_get_parent(dev), dev, KBDC_IVAR_IRQ, &irq);
|
||||
BUS_READ_IVAR(device_get_parent(dev), dev, KBDC_IVAR_FLAGS, &flags);
|
||||
|
||||
error = atkbd_attach_unit(device_get_unit(dev), &kbd, port, irq, flags);
|
||||
error = atkbd_attach_unit(device_get_unit(dev), &kbd,
|
||||
device_get_unit(device_get_parent(dev)),
|
||||
irq, flags);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
/* declare our interrupt handler */
|
||||
res = bus_alloc_resource(dev, SYS_RES_IRQ, &zero, irq, irq, 1,
|
||||
RF_SHAREABLE | RF_ACTIVE);
|
||||
BUS_SETUP_INTR(device_get_parent(dev), dev, res, INTR_TYPE_TTY,
|
||||
atkbd_isa_intr, kbd, &ih);
|
||||
rid = 0;
|
||||
sc->intr = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, irq, irq, 1,
|
||||
RF_SHAREABLE | RF_ACTIVE);
|
||||
BUS_SETUP_INTR(device_get_parent(dev), dev, sc->intr, INTR_TYPE_TTY,
|
||||
atkbd_isa_intr, kbd, &sc->ih);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <machine/bus_pio.h>
|
||||
#include <machine/bus.h>
|
||||
#include <machine/resource.h>
|
||||
#include <sys/rman.h>
|
||||
@ -87,32 +88,54 @@ static driver_t atkbdc_driver = {
|
||||
sizeof(atkbdc_softc_t *),
|
||||
};
|
||||
|
||||
static struct isa_pnp_id atkbdc_ids[] = {
|
||||
{ 0x0303d041, "Keyboard controller (i8042)" }, /* PNP0303 */
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static int
|
||||
atkbdc_probe(device_t dev)
|
||||
{
|
||||
int error;
|
||||
int rid;
|
||||
struct resource *port;
|
||||
struct resource *port0;
|
||||
struct resource *port1;
|
||||
int error;
|
||||
int rid;
|
||||
|
||||
/* Check isapnp ids */
|
||||
if (isa_get_vendorid(dev))
|
||||
return (ENXIO);
|
||||
|
||||
device_set_desc(dev, "keyboard controller (i8042)");
|
||||
rid = 0;
|
||||
port = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
|
||||
0, ~0, IO_KBDSIZE, RF_ACTIVE);
|
||||
if (!port)
|
||||
/* check PnP IDs */
|
||||
if (ISA_PNP_PROBE(device_get_parent(dev), dev, atkbdc_ids) == ENXIO)
|
||||
return ENXIO;
|
||||
error = atkbdc_probe_unit(device_get_unit(dev), rman_get_start(port));
|
||||
bus_release_resource(dev, SYS_RES_IOPORT, rid, port);
|
||||
|
||||
device_set_desc(dev, "Keyboard controller (i8042)");
|
||||
|
||||
rid = 0;
|
||||
port0 = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1,
|
||||
RF_ACTIVE);
|
||||
if (port0 == NULL)
|
||||
return ENXIO;
|
||||
/* XXX */
|
||||
if (bus_get_resource_start(dev, SYS_RES_IOPORT, 1) <= 0) {
|
||||
bus_set_resource(dev, SYS_RES_IOPORT, 1,
|
||||
rman_get_start(port0) + KBD_STATUS_PORT, 1);
|
||||
}
|
||||
rid = 1;
|
||||
port1 = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1,
|
||||
RF_ACTIVE);
|
||||
if (port1 == NULL) {
|
||||
bus_release_resource(dev, SYS_RES_IOPORT, 0, port0);
|
||||
return ENXIO;
|
||||
}
|
||||
|
||||
error = atkbdc_probe_unit(device_get_unit(dev), port0, port1);
|
||||
|
||||
bus_release_resource(dev, SYS_RES_IOPORT, 0, port0);
|
||||
bus_release_resource(dev, SYS_RES_IOPORT, 1, port1);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static void
|
||||
atkbdc_add_device(device_t dev, const char *name, int unit)
|
||||
{
|
||||
atkbdc_softc_t *sc = *(atkbdc_softc_t **)device_get_softc(dev);
|
||||
atkbdc_device_t *kdev;
|
||||
device_t child;
|
||||
int t;
|
||||
@ -125,8 +148,6 @@ atkbdc_add_device(device_t dev, const char *name, int unit)
|
||||
return;
|
||||
bzero(kdev, sizeof *kdev);
|
||||
|
||||
kdev->port = sc->port;
|
||||
|
||||
if (resource_int_value(name, unit, "irq", &t) == 0)
|
||||
kdev->irq = t;
|
||||
else
|
||||
@ -145,7 +166,6 @@ static int
|
||||
atkbdc_attach(device_t dev)
|
||||
{
|
||||
atkbdc_softc_t *sc;
|
||||
struct resource *port;
|
||||
int unit;
|
||||
int error;
|
||||
int rid;
|
||||
@ -166,15 +186,25 @@ atkbdc_attach(device_t dev)
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
/* XXX should track resource in softc */
|
||||
rid = 0;
|
||||
port = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
|
||||
0, ~0, IO_KBDSIZE, RF_ACTIVE);
|
||||
if (!port)
|
||||
sc->port0 = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1,
|
||||
RF_ACTIVE);
|
||||
if (sc->port0 == NULL)
|
||||
return ENXIO;
|
||||
error = atkbdc_attach_unit(unit, sc, rman_get_start(port));
|
||||
if (error)
|
||||
rid = 1;
|
||||
sc->port1 = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1,
|
||||
RF_ACTIVE);
|
||||
if (sc->port1 == NULL) {
|
||||
bus_release_resource(dev, SYS_RES_IOPORT, 0, sc->port0);
|
||||
return ENXIO;
|
||||
}
|
||||
|
||||
error = atkbdc_attach_unit(unit, sc, sc->port0, sc->port1);
|
||||
if (error) {
|
||||
bus_release_resource(dev, SYS_RES_IOPORT, 0, sc->port0);
|
||||
bus_release_resource(dev, SYS_RES_IOPORT, 1, sc->port1);
|
||||
return error;
|
||||
}
|
||||
*(atkbdc_softc_t **)device_get_softc(dev) = sc;
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user