Hi,
this issue is already quite old, but let's see if anyone else has still
issues with active PS/2 multiplexing.
Active PS/2 multiplexing is a method to attach multiple input devices on
your AUX PS/2 slot. This should be as of today of no real use anymore,
since it's easier to just add a USB device instead of getting into this
mess ...
But if you are as lucky as I am, you might have a laptop that uses this
mechanism for your touchpad. Without having this diff active, your
touchpad will behave totally weird, like jumping cursors and random
clicking whenever you touch it. So if you suffer from that, give this
patch a try.
Would like to get some feedback!
Tobias
PS: For the record and previously involved developers: It's basically
Miod's old diff with my fix for suspend and resume to reactive multiplexing
if available.
Index: arch/hppa/gsc/gsckbc.c
===================================================================
RCS file: /var/www/cvs/src/sys/arch/hppa/gsc/gsckbc.c,v
retrieving revision 1.14
diff -u -p -r1.14 gsckbc.c
--- arch/hppa/gsc/gsckbc.c 10 Aug 2012 17:49:31 -0000 1.14
+++ arch/hppa/gsc/gsckbc.c 1 Apr 2013 14:56:22 -0000
@@ -469,7 +469,7 @@ pckbc_poll_data1(iot, ioh, ioh_c, slot,
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;
}
Index: dev/ic/i8042reg.h
===================================================================
RCS file: /var/www/cvs/src/sys/dev/ic/i8042reg.h,v
retrieving revision 1.5
diff -u -p -r1.5 i8042reg.h
--- dev/ic/i8042reg.h 18 Aug 2001 15:30:39 -0000 1.5
+++ dev/ic/i8042reg.h 1 Apr 2013 14:46:09 -0000
@@ -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))
Index: dev/ic/pckbc.c
===================================================================
RCS file: /var/www/cvs/src/sys/dev/ic/pckbc.c,v
retrieving revision 1.33
diff -u -p -r1.33 pckbc.c
--- dev/ic/pckbc.c 15 Feb 2013 08:49:51 -0000 1.33
+++ dev/ic/pckbc.c 1 Apr 2013 15:03:38 -0000
@@ -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 *);
+int pckbc_enable_apm(struct pckbc_internal *);
+int pckbc_disable_apm(struct pckbc_internal *);
-const char *pckbc_slot_names[] = { "kbd", "aux" };
+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_
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 *
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
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
}
/* 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
*/
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
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
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
*/
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
{
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_
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
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
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 *
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
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
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_
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? */
Index: dev/ic/pckbcvar.h
===================================================================
RCS file: /var/www/cvs/src/sys/dev/ic/pckbcvar.h,v
retrieving revision 1.12
diff -u -p -r1.12 pckbcvar.h
--- dev/ic/pckbcvar.h 10 Aug 2012 17:49:31 -0000 1.12
+++ dev/ic/pckbcvar.h 1 Apr 2013 14:46:09 -0000
@@ -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
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);
Index: dev/isa/pckbc_isa.c
===================================================================
RCS file: /var/www/cvs/src/sys/dev/isa/pckbc_isa.c,v
retrieving revision 1.11
diff -u -p -r1.11 pckbc_isa.c
--- dev/isa/pckbc_isa.c 2 Feb 2012 21:40:19 -0000 1.11
+++ dev/isa/pckbc_isa.c 1 Apr 2013 14:56:22 -0000
@@ -80,12 +80,12 @@ pckbc_isa_match(struct device *parent, v
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 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,
* 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_so
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]);
}
}
Index: dev/pckbc/pms.c
===================================================================
RCS file: /var/www/cvs/src/sys/dev/pckbc/pms.c,v
retrieving revision 1.37
diff -u -p -r1.37 pms.c
--- dev/pckbc/pms.c 18 Mar 2013 16:31:01 -0000 1.37
+++ dev/pckbc/pms.c 1 Apr 2013 14:56:22 -0000
@@ -135,6 +135,7 @@ struct pms_softc { /* driver status inf
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);
}
}
@@ -585,7 +586,7 @@ pmsprobe(struct device *parent, void *ma
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. */
@@ -614,10 +615,11 @@ pmsattach(struct device *parent, struct
int i;
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;
@@ -698,10 +700,10 @@ pms_change_state(struct pms_softc *sc, i
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);
@@ -729,7 +731,7 @@ pms_change_state(struct pms_softc *sc, i
if (sc->protocol && 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;
}