diff options
author | 2013-04-20 08:01:37 +0000 | |
---|---|---|
committer | 2013-04-20 08:01:37 +0000 | |
commit | 5f0427e8cc528eddf9d592b8694e5ece283313b3 (patch) | |
tree | 4df94c40c188ba4248dfe4eaf7fcb169276ee566 | |
parent | Remove unused macro function. (diff) | |
download | wireguard-openbsd-5f0427e8cc528eddf9d592b8694e5ece283313b3.tar.xz wireguard-openbsd-5f0427e8cc528eddf9d592b8694e5ece283313b3.zip |
Enable active PS/2 multiplexing if available.
Supported for i386 and amd64 except SMALL_KERNEL.
Based on Miod's former work on this subject.
ok mpi
-rw-r--r-- | sys/arch/hppa/gsc/gsckbc.c | 12 | ||||
-rw-r--r-- | sys/dev/ic/i8042reg.h | 16 | ||||
-rw-r--r-- | sys/dev/ic/pckbc.c | 248 | ||||
-rw-r--r-- | sys/dev/ic/pckbcvar.h | 21 | ||||
-rw-r--r-- | sys/dev/isa/pckbc_isa.c | 16 | ||||
-rw-r--r-- | sys/dev/pckbc/pms.c | 18 |
6 files changed, 267 insertions, 64 deletions
diff --git a/sys/arch/hppa/gsc/gsckbc.c b/sys/arch/hppa/gsc/gsckbc.c index 3a450c53118..c7624a5ddb3 100644 --- a/sys/arch/hppa/gsc/gsckbc.c +++ b/sys/arch/hppa/gsc/gsckbc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: gsckbc.c,v 1.14 2012/08/10 17:49:31 shadchin Exp $ */ +/* $OpenBSD: gsckbc.c,v 1.15 2013/04/20 08:01:37 tobias Exp $ */ /* * Copyright (c) 2003, Miodrag Vallat. * All rights reserved. @@ -469,7 +469,7 @@ pckbc_poll_data1(iot, ioh, ioh_c, slot, checkaux) bus_space_tag_t iot; bus_space_handle_t ioh, ioh_c; pckbc_slot_t slot; - int checkaux; /* ignored on hppa */ + struct pckbc_internal *t; /* ignored on hppa */ { int i; u_char stat; @@ -568,7 +568,7 @@ pckbc_flush(self, slot) { struct pckbc_internal *t = self; - pckbc_poll_data1(t->t_iot, t->t_ioh_d, t->t_ioh_d, slot, 0); + pckbc_poll_data1(t->t_iot, t->t_ioh_d, t->t_ioh_d, slot, t); } int @@ -580,7 +580,7 @@ pckbc_poll_data(self, slot) struct pckbc_slotdata *q = t->t_slotdata[slot]; int c; - c = pckbc_poll_data1(t->t_iot, t->t_ioh_d, t->t_ioh_d, slot, 0); + c = pckbc_poll_data1(t->t_iot, t->t_ioh_d, t->t_ioh_d, slot, t); if (c != -1 && q && CMD_IN_QUEUE(q)) { /* we jumped into a running command - try to deliver the response */ @@ -655,7 +655,7 @@ pckbc_poll_cmd1(t, slot, cmd) return; } for (i = 10; i; i--) { /* 1s ??? */ - c = pckbc_poll_data1(iot, ioh, ioh, slot, 0); + c = pckbc_poll_data1(iot, ioh, ioh, slot, t); if (c != -1) break; } @@ -696,7 +696,7 @@ pckbc_poll_cmd1(t, slot, cmd) else i = 10; /* 1s ??? */ while (i--) { - c = pckbc_poll_data1(iot, ioh, ioh, slot, 0); + c = pckbc_poll_data1(iot, ioh, ioh, slot, t); if (c != -1) break; } diff --git a/sys/dev/ic/i8042reg.h b/sys/dev/ic/i8042reg.h index adc7102e950..3734c481ed0 100644 --- a/sys/dev/ic/i8042reg.h +++ b/sys/dev/ic/i8042reg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: i8042reg.h,v 1.5 2001/08/18 15:30:39 mickey Exp $ */ +/* $OpenBSD: i8042reg.h,v 1.6 2013/04/20 08:01:37 tobias Exp $ */ /* $NetBSD: i8042reg.h,v 1.7 1998/01/18 14:41:37 drochner Exp $ */ #define KBSTATP 4 /* kbd controller status port (I) */ @@ -44,3 +44,17 @@ #define KC8_MENABLE 0x02 /* enable mouse interrupt */ #define KC8_KENABLE 0x01 /* enable keyboard interrupt */ #define CMDBYTE (KC8_TRANS|KC8_CPU|KC8_MENABLE|KC8_KENABLE) + +/* + * Defines for Active PS/2 Multiplexing + */ + +#define KBC_APM_ENB1 0xf0 +#define KBC_APM_ENB2 0x56 +#define KBC_APM_ENB3 0xa4 + +#define KBC_APM_DIS1 0xf0 +#define KBC_APM_DIS2 0x56 +#define KBC_APM_DIS3 0xa5 + +#define KBC_APM_PREFIX(p) (0x90 | (p)) diff --git a/sys/dev/ic/pckbc.c b/sys/dev/ic/pckbc.c index 1007075b3fc..abce9f1370a 100644 --- a/sys/dev/ic/pckbc.c +++ b/sys/dev/ic/pckbc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pckbc.c,v 1.33 2013/02/15 08:49:51 mpi Exp $ */ +/* $OpenBSD: pckbc.c,v 1.34 2013/04/20 08:01:37 tobias Exp $ */ /* $NetBSD: pckbc.c,v 1.5 2000/06/09 04:58:35 soda Exp $ */ /* @@ -105,8 +105,20 @@ void pckbc_poll(void *); int pckbc_cmdresponse(struct pckbc_internal *, pckbc_slot_t, u_char); void pckbc_start(struct pckbc_internal *, pckbc_slot_t); int pckbcintr_internal(struct pckbc_internal *, struct pckbc_softc *); - -const char *pckbc_slot_names[] = { "kbd", "aux" }; +int pckbc_enable_apm(struct pckbc_internal *); +int pckbc_disable_apm(struct pckbc_internal *); + +const char *pckbc_slot_names[] = { + "kbd slot", +#ifdef PCKBC_APM + "aux slot #0", + "aux slot #1", + "aux slot #2", + "aux slot #3", +#else + "aux slot" +#endif +}; #define KBC_DEVCMD_ACK 0xfa #define KBC_DEVCMD_RESEND 0xfe @@ -137,31 +149,58 @@ pckbc_send_cmd(bus_space_tag_t iot, bus_space_handle_t ioh_c, u_char val) return (1); } +/* + * NOTE: Active PS/2 Multiplexing behaviour is only checked if t != NULL. + * This behaviour is intentional. + */ int pckbc_poll_data1(bus_space_tag_t iot, bus_space_handle_t ioh_d, - bus_space_handle_t ioh_c, pckbc_slot_t slot, int checkaux) + bus_space_handle_t ioh_c, pckbc_slot_t slot, struct pckbc_internal *t) { int i; + int active; u_char stat; /* polls for ~100ms */ for (i = 100; i; i--, delay(1000)) { stat = bus_space_read_1(iot, ioh_c, 0); + /* XXX no error bit handling */ if (stat & KBS_DIB) { register u_char c; KBD_DELAY; c = bus_space_read_1(iot, ioh_d, 0); - if (checkaux && (stat & 0x20)) { /* aux data */ - if (slot != PCKBC_AUX_SLOT) { - DPRINTF("lost aux 0x%x\n", c); - continue; - } - } else { - if (slot == PCKBC_AUX_SLOT) { - DPRINTF("lost kbd 0x%x\n", c); + +#ifdef PCKBC_APM + if (t && t->t_apmver >= 0) { + if (stat & 0x20) + active = PCKBC_AUX_SLOT + (stat >> 6); + else + active = PCKBC_KBD_SLOT; + } else +#endif + active = stat & 0x20 ? + PCKBC_AUX_SLOT : PCKBC_KBD_SLOT; + +#ifdef PCKBC_APM + if (active != PCKBC_KBD_SLOT && + t && t->t_apmver >= 0 && (stat & KBS_WARM)) { + if (c >= 0xfd) { + /* genuine error */ + /* XXX handle hot removal? */ continue; } + DPRINTF("pckbc apm mode reverted?\n"); + /* XXX schedule a switch as soon as possible */ + } +#endif + if (slot != active) { + if ((t && t->t_haveaux) || + slot != PCKBC_KBD_SLOT || + active == PCKBC_KBD_SLOT) + DPRINTF("lost data on slot%d 0x%x\n", + active, c); + continue; } return (c); } @@ -182,8 +221,7 @@ pckbc_get8042cmd(struct pckbc_internal *t) if (!pckbc_send_cmd(iot, ioh_c, K_RDCMDBYTE)) return (0); - data = pckbc_poll_data1(iot, ioh_d, ioh_c, PCKBC_KBD_SLOT, - t->t_haveaux); + data = pckbc_poll_data1(iot, ioh_d, ioh_c, PCKBC_KBD_SLOT, t); if (data == -1) return (0); t->t_cmdbyte = data; @@ -215,7 +253,15 @@ pckbc_send_devcmd(struct pckbc_internal *t, pckbc_slot_t slot, u_char val) bus_space_handle_t ioh_d = t->t_ioh_d; bus_space_handle_t ioh_c = t->t_ioh_c; - if (slot == PCKBC_AUX_SLOT) { + if (slot >= PCKBC_AUX_SLOT) { +#ifdef PCKBC_APM + /* send specific routing prefix if multiplexing */ + if (t->t_apmver >= 0) { + if (pckbc_send_cmd(iot, ioh_c, + KBC_APM_PREFIX(slot - PCKBC_AUX_SLOT)) == 0) + return (0); + } else +#endif if (!pckbc_send_cmd(iot, ioh_c, KBC_AUXWRITE)) return (0); } @@ -299,7 +345,7 @@ pckbc_attach(struct pckbc_softc *sc, int flags) } /* flush */ - (void) pckbc_poll_data1(iot, ioh_d, ioh_c, PCKBC_KBD_SLOT, 0); + (void) pckbc_poll_data1(iot, ioh_d, ioh_c, PCKBC_KBD_SLOT, NULL); /* set initial cmd byte */ if (!pckbc_put8042cmd(t)) { @@ -317,7 +363,7 @@ pckbc_attach(struct pckbc_softc *sc, int flags) */ if (!pckbc_send_cmd(iot, ioh_c, KBC_KBDTEST)) return; - res = pckbc_poll_data1(iot, ioh_d, ioh_c, PCKBC_KBD_SLOT, 0); + res = pckbc_poll_data1(iot, ioh_d, ioh_c, PCKBC_KBD_SLOT, NULL); /* * Normally, we should get a "0" here. @@ -357,7 +403,7 @@ pckbc_attach(struct pckbc_softc *sc, int flags) goto nomouse; } bus_space_write_1(iot, ioh_d, 0, 0x5a); /* a random value */ - res = pckbc_poll_data1(iot, ioh_d, ioh_c, PCKBC_AUX_SLOT, 1); + res = pckbc_poll_data1(iot, ioh_d, ioh_c, PCKBC_AUX_SLOT, NULL); if (ISSET(t->t_flags, PCKBC_NEED_AUXWRITE)) { /* @@ -373,7 +419,7 @@ pckbc_attach(struct pckbc_softc *sc, int flags) goto nomouse; bus_space_write_1(iot, ioh_d, 0, 0x5a); res = pckbc_poll_data1(iot, ioh_d, ioh_c, - PCKBC_AUX_SLOT, 1); + PCKBC_AUX_SLOT, NULL); DPRINTF("kbc: aux echo: %x\n", res); } } @@ -388,8 +434,21 @@ pckbc_attach(struct pckbc_softc *sc, int flags) */ DPRINTF("kbc: aux echo: %x\n", res); t->t_haveaux = 1; - if (pckbc_attach_slot(sc, PCKBC_AUX_SLOT, 0)) + +#ifdef PCKBC_APM + t->t_apmver = -1; + t->t_apmver = pckbc_enable_apm(t); + if (t->t_apmver >= 0) { + printf("%s: Active PS/2 Multiplexing, version %d.%d\n", + sc->sc_dv.dv_xname, t->t_apmver >> 4, + t->t_apmver & 0x0f); cmdbits |= KC8_MENABLE; + for (res = PCKBC_AUX_SLOT; res < PCKBC_NSLOTS; res++) + pckbc_attach_slot(sc, res, 0); + } else +#endif + if (pckbc_attach_slot(sc, PCKBC_AUX_SLOT, 0)) + cmdbits |= KC8_MENABLE; } #ifdef PCKBCDEBUG else @@ -437,7 +496,7 @@ pckbcprint(void *aux, const char *pnp) struct pckbc_attach_args *pa = aux; if (!pnp) - printf(" (%s slot)", pckbc_slot_names[pa->pa_slot]); + printf(" (%s)", pckbc_slot_names[pa->pa_slot]); return (QUIET); } @@ -459,8 +518,7 @@ pckbc_flush(pckbc_tag_t self, pckbc_slot_t slot) { struct pckbc_internal *t = self; - (void) pckbc_poll_data1(t->t_iot, t->t_ioh_d, t->t_ioh_c, - slot, t->t_haveaux); + (void) pckbc_poll_data1(t->t_iot, t->t_ioh_d, t->t_ioh_c, slot, t); } int @@ -470,8 +528,7 @@ pckbc_poll_data(pckbc_tag_t self, pckbc_slot_t slot) struct pckbc_slotdata *q = t->t_slotdata[slot]; int c; - c = pckbc_poll_data1(t->t_iot, t->t_ioh_d, t->t_ioh_c, - slot, t->t_haveaux); + c = pckbc_poll_data1(t->t_iot, t->t_ioh_d, t->t_ioh_c, slot, t); if (c != -1 && q && CMD_IN_QUEUE(q)) { /* we jumped into a running command - try to deliver the response */ @@ -520,13 +577,28 @@ void pckbc_slot_enable(pckbc_tag_t self, pckbc_slot_t slot, int on) { struct pckbc_internal *t = (struct pckbc_internal *)self; - struct pckbc_portcmd *cmd; + const struct pckbc_portcmd *cmd; + int rc; +#ifdef PCKBC_APM + cmd = &pckbc_portcmd[slot >= PCKBC_AUX_SLOT ? PCKBC_AUX_SLOT : slot]; +#else cmd = &pckbc_portcmd[slot]; +#endif - if (!pckbc_send_cmd(t->t_iot, t->t_ioh_c, - on ? cmd->cmd_en : cmd->cmd_dis)) - printf("pckbc_slot_enable(%d) failed\n", on); +#ifdef PCKBC_APM + /* send specific routing prefix if multiplexing */ + if (t->t_apmver >= 0 && slot >= PCKBC_AUX_SLOT) { + rc = pckbc_send_cmd(t->t_iot, t->t_ioh_c, + KBC_APM_PREFIX(slot - PCKBC_AUX_SLOT)); + } else +#endif + rc = 1; + if (rc != 0) + rc = pckbc_send_cmd(t->t_iot, t->t_ioh_c, + on ? cmd->cmd_en : cmd->cmd_dis); + if (rc == 0) + printf("pckbc_slot_enable(%d,%d) failed\n", slot, on); if (slot == PCKBC_KBD_SLOT) { if (on) @@ -580,8 +652,7 @@ pckbc_poll_cmd1(struct pckbc_internal *t, pckbc_slot_t slot, return; } for (i = 10; i; i--) { /* 1s ??? */ - c = pckbc_poll_data1(iot, ioh_d, ioh_c, slot, - t->t_haveaux); + c = pckbc_poll_data1(iot, ioh_d, ioh_c, slot, t); if (c != -1) break; } @@ -620,8 +691,7 @@ pckbc_poll_cmd1(struct pckbc_internal *t, pckbc_slot_t slot, else i = 10; /* 1s ??? */ while (i--) { - c = pckbc_poll_data1(iot, ioh_d, ioh_c, slot, - t->t_haveaux); + c = pckbc_poll_data1(iot, ioh_d, ioh_c, slot, t); if (c != -1) break; } @@ -684,10 +754,11 @@ pckbc_cleanqueue(struct pckbc_slotdata *q) void pckbc_cleanqueues(struct pckbc_internal *t) { - if (t->t_slotdata[PCKBC_KBD_SLOT]) - pckbc_cleanqueue(t->t_slotdata[PCKBC_KBD_SLOT]); - if (t->t_slotdata[PCKBC_AUX_SLOT]) - pckbc_cleanqueue(t->t_slotdata[PCKBC_AUX_SLOT]); + uint slot; + + for (slot = 0; slot < PCKBC_NSLOTS; slot++) + if (t->t_slotdata[slot]) + pckbc_cleanqueue(t->t_slotdata[slot]); } /* @@ -740,11 +811,13 @@ pckbc_reset(struct pckbc_softc *sc) bus_space_tag_t iot = t->t_iot; bus_space_handle_t ioh_d = t->t_ioh_d, ioh_c = t->t_ioh_c; - pckbc_poll_data1(iot, ioh_d, ioh_c, PCKBC_KBD_SLOT, 0); + pckbc_poll_data1(iot, ioh_d, ioh_c, PCKBC_KBD_SLOT, NULL); /* KBC selftest */ if (pckbc_send_cmd(iot, ioh_c, KBC_SELFTEST) == 0) return; - pckbc_poll_data1(iot, ioh_d, ioh_c, PCKBC_KBD_SLOT, 0); + pckbc_poll_data1(iot, ioh_d, ioh_c, PCKBC_KBD_SLOT, NULL); + if (t->t_apmver >= 0) + pckbc_enable_apm(t); (void)pckbc_put8042cmd(t); pckbcintr_internal(t->t_sc->id, t->t_sc); } @@ -972,8 +1045,16 @@ pckbcintr_internal(struct pckbc_internal *t, struct pckbc_softc *sc) served = 1; - slot = (t->t_haveaux && (stat & 0x20)) ? - PCKBC_AUX_SLOT : PCKBC_KBD_SLOT; +#ifdef PCKBC_APM + if (t->t_apmver >= 0) { /* implies t->t_haveaux != 0 */ + if (stat & 0x20) + slot = PCKBC_AUX_SLOT + (stat >> 6); + else + slot = PCKBC_KBD_SLOT; + } else +#endif + slot = (t->t_haveaux && (stat & 0x20)) ? + PCKBC_AUX_SLOT : PCKBC_KBD_SLOT; q = t->t_slotdata[slot]; if (!q) { @@ -1008,6 +1089,89 @@ pckbcintr_internal(struct pckbc_internal *t, struct pckbc_softc *sc) return (served); } +#ifdef PCKBC_APM + +/* + * Disable Active PS/2 Multiplexing. + * Returns nonzero if error. + */ +int +pckbc_disable_apm(struct pckbc_internal *t) +{ + bus_space_tag_t iot = t->t_iot; + bus_space_handle_t ioh_d = t->t_ioh_d, ioh_c = t->t_ioh_c; + int data; + + /* + * Send the three bytes of the disable sequence + */ + + if (pckbc_send_cmd(iot, ioh_c, KBC_AUXECHO) == 0 || + pckbc_wait_output(iot, ioh_c) == 0) + return -1; + bus_space_write_1(iot, ioh_d, 0, KBC_APM_DIS1); + data = pckbc_poll_data1(iot, ioh_d, ioh_c, PCKBC_AUX_SLOT, NULL); + if (data < 0 || data != KBC_APM_DIS1) + return -1; + + if (pckbc_send_cmd(iot, ioh_c, KBC_AUXECHO) == 0 || + pckbc_wait_output(iot, ioh_c) == 0) + return -1; + bus_space_write_1(iot, ioh_d, 0, KBC_APM_DIS2); + data = pckbc_poll_data1(iot, ioh_d, ioh_c, PCKBC_AUX_SLOT, NULL); + if (data < 0 || data != KBC_APM_DIS2) + return -1; + + if (pckbc_send_cmd(iot, ioh_c, KBC_AUXECHO) == 0 || + pckbc_wait_output(iot, ioh_c) == 0) + return -1; + bus_space_write_1(iot, ioh_d, 0, KBC_APM_DIS3); + data = pckbc_poll_data1(iot, ioh_d, ioh_c, PCKBC_AUX_SLOT, NULL); + if (data < 0 || data != t->t_apmver) + return -1; + + return 0; +} + +/* + * Enable Active PS/2 Multiplexing. + * Returns -1 if unavailable or version supported by the controller. + */ +int +pckbc_enable_apm(struct pckbc_internal *t) +{ + bus_space_tag_t iot = t->t_iot; + bus_space_handle_t ioh_d = t->t_ioh_d, ioh_c = t->t_ioh_c; + int data; + + if (pckbc_send_cmd(iot, ioh_c, KBC_AUXECHO) == 0 || + pckbc_wait_output(iot, ioh_c) == 0) + return -1; + bus_space_write_1(iot, ioh_d, 0, KBC_APM_ENB1); + data = pckbc_poll_data1(iot, ioh_d, ioh_c, PCKBC_AUX_SLOT, NULL); + if (data < 0 || data != KBC_APM_ENB1) + return -1; + + if (pckbc_send_cmd(iot, ioh_c, KBC_AUXECHO) == 0 || + pckbc_wait_output(iot, ioh_c) == 0) + return -1; + bus_space_write_1(iot, ioh_d, 0, KBC_APM_ENB2); + data = pckbc_poll_data1(iot, ioh_d, ioh_c, PCKBC_AUX_SLOT, NULL); + if (data < 0 || data != KBC_APM_ENB2) + return -1; + + if (pckbc_send_cmd(iot, ioh_c, KBC_AUXECHO) == 0 || + pckbc_wait_output(iot, ioh_c) == 0) + return -1; + bus_space_write_1(iot, ioh_d, 0, KBC_APM_ENB3); + data = pckbc_poll_data1(iot, ioh_d, ioh_c, PCKBC_AUX_SLOT, NULL); + if (data < 0 || data == KBC_APM_ENB3) + return -1; + + return data; +} +#endif + int pckbc_cnattach(bus_space_tag_t iot, bus_addr_t addr, bus_size_t cmd_offset, int flags) @@ -1031,7 +1195,7 @@ pckbc_cnattach(bus_space_tag_t iot, bus_addr_t addr, bus_size_t cmd_offset, timeout_set(&pckbc_consdata.t_poll, pckbc_poll, &pckbc_consdata); /* flush */ - (void) pckbc_poll_data1(iot, ioh_d, ioh_c, PCKBC_KBD_SLOT, 0); + (void) pckbc_poll_data1(iot, ioh_d, ioh_c, PCKBC_KBD_SLOT, NULL); /* selftest? */ diff --git a/sys/dev/ic/pckbcvar.h b/sys/dev/ic/pckbcvar.h index cfb06718875..0b9549f0a9a 100644 --- a/sys/dev/ic/pckbcvar.h +++ b/sys/dev/ic/pckbcvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pckbcvar.h,v 1.12 2012/08/10 17:49:31 shadchin Exp $ */ +/* $OpenBSD: pckbcvar.h,v 1.13 2013/04/20 08:01:37 tobias Exp $ */ /* $NetBSD: pckbcvar.h,v 1.4 2000/06/09 04:58:35 soda Exp $ */ /* @@ -32,6 +32,14 @@ #include <sys/timeout.h> +/* + * Only compile Active PS/2 Multiplexing support on systems where it might + * be found. + */ +#if (defined(__i386__) || defined(__amd64__)) && !defined(SMALL_KERNEL) +#define PCKBC_APM +#endif + #define PCKBCCF_SLOT 0 #define PCKBCCF_SLOT_DEFAULT -1 @@ -39,7 +47,11 @@ typedef void *pckbc_tag_t; typedef int pckbc_slot_t; #define PCKBC_KBD_SLOT 0 #define PCKBC_AUX_SLOT 1 +#ifdef PCKBC_APM +#define PCKBC_NSLOTS 5 /* 1 KBD + 4 AUX */ +#else #define PCKBC_NSLOTS 2 +#endif /* * external representation (pckbc_tag_t), @@ -55,6 +67,9 @@ struct pckbc_internal { #define PCKBC_CANT_TRANSLATE 0x0001 /* can't translate to XT scancodes */ #define PCKBC_NEED_AUXWRITE 0x0002 /* need auxwrite command to find aux */ int t_haveaux; /* controller has an aux port */ +#ifdef PCKBC_APM + int t_apmver; /* Active PS/2 Multiplexing version */ +#endif struct pckbc_slotdata *t_slotdata[PCKBC_NSLOTS]; @@ -99,8 +114,8 @@ int pckbc_enqueue_cmd(pckbc_tag_t, pckbc_slot_t, u_char *, int, int, int, u_char *); int pckbc_send_cmd(bus_space_tag_t, bus_space_handle_t, u_char); int pckbc_poll_data(pckbc_tag_t, pckbc_slot_t); -int pckbc_poll_data1(bus_space_tag_t, bus_space_handle_t, - bus_space_handle_t, pckbc_slot_t, int); +int pckbc_poll_data1(bus_space_tag_t, bus_space_handle_t, bus_space_handle_t, + pckbc_slot_t, struct pckbc_internal *); void pckbc_set_poll(pckbc_tag_t, pckbc_slot_t, int); int pckbc_xt_translation(pckbc_tag_t); void pckbc_slot_enable(pckbc_tag_t, pckbc_slot_t, int); diff --git a/sys/dev/isa/pckbc_isa.c b/sys/dev/isa/pckbc_isa.c index e9323500302..c06ee55ea03 100644 --- a/sys/dev/isa/pckbc_isa.c +++ b/sys/dev/isa/pckbc_isa.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pckbc_isa.c,v 1.11 2012/02/02 21:40:19 deraadt Exp $ */ +/* $OpenBSD: pckbc_isa.c,v 1.12 2013/04/20 08:01:37 tobias Exp $ */ /* $NetBSD: pckbc_isa.c,v 1.2 2000/03/23 07:01:35 thorpej Exp $ */ /* @@ -80,12 +80,12 @@ pckbc_isa_match(struct device *parent, void *match, void *aux) goto fail; /* flush KBC */ - (void) pckbc_poll_data1(iot, ioh_d, ioh_c, PCKBC_KBD_SLOT, 0); + (void) pckbc_poll_data1(iot, ioh_d, ioh_c, PCKBC_KBD_SLOT, NULL); /* KBC selftest */ if (pckbc_send_cmd(iot, ioh_c, KBC_SELFTEST) == 0) goto fail2; - res = pckbc_poll_data1(iot, ioh_d, ioh_c, PCKBC_KBD_SLOT, 0); + res = pckbc_poll_data1(iot, ioh_d, ioh_c, PCKBC_KBD_SLOT, NULL); if (res != 0x55) { printf("kbc selftest: %x\n", res); goto fail2; @@ -139,6 +139,9 @@ pckbc_isa_attach(struct device *parent, struct device *self, void *aux) struct pckbc_internal *t; bus_space_tag_t iot; bus_space_handle_t ioh_d, ioh_c; +#ifdef PCKBC_APM + uint slot; +#endif isc->sc_ic = ia->ia_ic; iot = ia->ia_iot; @@ -147,7 +150,12 @@ pckbc_isa_attach(struct device *parent, struct device *self, void *aux) * Set up IRQs for "normal" ISA. */ isc->sc_irq[PCKBC_KBD_SLOT] = 1; +#ifdef PCKBC_APM + for (slot = PCKBC_AUX_SLOT; slot < PCKBC_NSLOTS; slot++) + isc->sc_irq[slot] = 12; +#else isc->sc_irq[PCKBC_AUX_SLOT] = 12; +#endif sc->intr_establish = pckbc_isa_intr_establish; @@ -189,7 +197,7 @@ pckbc_isa_intr_establish(struct pckbc_softc *sc, pckbc_slot_t slot) printf("%s: unable to establish interrupt for %s slot\n", sc->sc_dv.dv_xname, pckbc_slot_names[slot]); } else { - printf("%s: using irq %d for %s slot\n", sc->sc_dv.dv_xname, + printf("%s: using irq %d for %s\n", sc->sc_dv.dv_xname, isc->sc_irq[slot], pckbc_slot_names[slot]); } } diff --git a/sys/dev/pckbc/pms.c b/sys/dev/pckbc/pms.c index ca21b2f6bcf..be61a49cf69 100644 --- a/sys/dev/pckbc/pms.c +++ b/sys/dev/pckbc/pms.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pms.c,v 1.40 2013/04/15 09:14:41 mpi Exp $ */ +/* $OpenBSD: pms.c,v 1.41 2013/04/20 08:01:37 tobias Exp $ */ /* $NetBSD: psm.c,v 1.11 2000/06/05 22:20:57 sommerfeld Exp $ */ /*- @@ -134,6 +134,7 @@ struct pms_softc { /* driver status information */ struct device sc_dev; pckbc_tag_t sc_kbctag; + int sc_slot; int sc_state; #define PMS_STATE_DISABLED 0 @@ -373,10 +374,10 @@ int pms_cmd(struct pms_softc *sc, u_char *cmd, int len, u_char *resp, int resplen) { if (sc->poll) { - return pckbc_poll_cmd(sc->sc_kbctag, PCKBC_AUX_SLOT, + return pckbc_poll_cmd(sc->sc_kbctag, sc->sc_slot, cmd, len, resplen, resp, 1); } else { - return pckbc_enqueue_cmd(sc->sc_kbctag, PCKBC_AUX_SLOT, + return pckbc_enqueue_cmd(sc->sc_kbctag, sc->sc_slot, cmd, len, resplen, 1, resp); } } @@ -602,7 +603,7 @@ pmsprobe(struct device *parent, void *match, void *aux) u_char cmd[1], resp[2]; int res; - if (pa->pa_slot != PCKBC_AUX_SLOT) + if (pa->pa_slot < PCKBC_AUX_SLOT) return (0); /* Flush any garbage. */ @@ -630,10 +631,11 @@ pmsattach(struct device *parent, struct device *self, void *aux) struct wsmousedev_attach_args a; sc->sc_kbctag = pa->pa_tag; + sc->sc_slot = pa->pa_slot; printf("\n"); - pckbc_set_inputhandler(sc->sc_kbctag, PCKBC_AUX_SLOT, + pckbc_set_inputhandler(sc->sc_kbctag, sc->sc_slot, pmsinput, sc, DEVNAME(sc)); a.accessops = &pms_accessops; @@ -706,10 +708,10 @@ pms_change_state(struct pms_softc *sc, int newstate, int dev) case PMS_STATE_ENABLED: sc->inputstate = 0; - pckbc_slot_enable(sc->sc_kbctag, PCKBC_AUX_SLOT, 1); + pckbc_slot_enable(sc->sc_kbctag, sc->sc_slot, 1); if (sc->poll) - pckbc_flush(sc->sc_kbctag, PCKBC_AUX_SLOT); + pckbc_flush(sc->sc_kbctag, sc->sc_slot); pms_reset(sc); if (sc->protocol->type == PMS_STANDARD || @@ -725,7 +727,7 @@ pms_change_state(struct pms_softc *sc, int newstate, int dev) if (sc->protocol->disable) sc->protocol->disable(sc); - pckbc_slot_enable(sc->sc_kbctag, PCKBC_AUX_SLOT, 0); + pckbc_slot_enable(sc->sc_kbctag, sc->sc_slot, 0); break; } |