Index: sys/arch/hppa/gsc/gsckbc.c
===================================================================
RCS file: /cvs/src/sys/arch/hppa/gsc/gsckbc.c,v
retrieving revision 1.19
diff -u -p -u -p -r1.19 gsckbc.c
--- sys/arch/hppa/gsc/gsckbc.c	24 May 2015 10:57:47 -0000	1.19
+++ sys/arch/hppa/gsc/gsckbc.c	28 Jun 2015 19:22:02 -0000
@@ -459,7 +459,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;
@@ -558,7 +558,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
@@ -570,7 +570,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 */
@@ -645,7 +645,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;
 		}
@@ -686,7 +686,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: sys/dev/ic/i8042reg.h
===================================================================
RCS file: /cvs/src/sys/dev/ic/i8042reg.h,v
retrieving revision 1.9
diff -u -p -u -p -r1.9 i8042reg.h
--- sys/dev/ic/i8042reg.h	5 May 2015 16:27:20 -0000	1.9
+++ sys/dev/ic/i8042reg.h	28 Jun 2015 19:22:04 -0000
@@ -49,3 +49,18 @@
 #define	KCID_KBD1	0xAB
 #define	KCID_KBD2	0x83
 #define	KCID_MOUSE	0x00
+
+/*
+ * 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: sys/dev/ic/pckbc.c
===================================================================
RCS file: /cvs/src/sys/dev/ic/pckbc.c,v
retrieving revision 1.49
diff -u -p -u -p -r1.49 pckbc.c
--- sys/dev/ic/pckbc.c	24 May 2015 10:57:47 -0000	1.49
+++ sys/dev/ic/pckbc.c	28 Jun 2015 19:22:05 -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,32 +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;
 			CPU_BUSY_CYCLE();
 			c = bus_space_read_1(iot, ioh_d, 0);
-			if (checkaux && (stat & KBS_AUXDATA)) {
-				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 & KBS_AUXDATA)
+					active = PCKBC_AUX_SLOT + (stat >> 6);
+				else
+					active = PCKBC_KBD_SLOT;
+			} else
+#endif
+				active = stat & KBS_AUXDATA ?
+				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);
 		}
@@ -183,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;
@@ -216,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);
 	}
@@ -312,7 +357,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)) {
@@ -336,7 +381,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.
@@ -376,7 +421,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)) {
 		/*
@@ -392,7 +437,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);
 		}
 	}
@@ -407,8 +452,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
@@ -439,7 +497,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);
 }
 
@@ -485,8 +543,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
@@ -496,8 +553,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 */
@@ -546,13 +602,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)
@@ -606,8 +677,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;
 		}
@@ -646,8 +716,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;
 		}
@@ -710,10 +779,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]);
 }
 
 /*
@@ -766,11 +836,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);
 }
@@ -996,8 +1068,16 @@ pckbcintr_internal(struct pckbc_internal
 
 		served = 1;
 
-		slot = (t->t_haveaux && (stat & KBS_AUXDATA)) ?
-		    PCKBC_AUX_SLOT : PCKBC_KBD_SLOT;
+#ifdef PCKBC_APM
+		if (t->t_apmver >= 0) { /* implies t->t_haveaux != 0 */
+			if (stat & KBS_AUXDATA)
+				slot = PCKBC_AUX_SLOT + (stat >> 6);
+			else
+				slot = PCKBC_KBD_SLOT;
+		} else
+#endif
+			slot = (t->t_haveaux && (stat & KBS_AUXDATA)) ?
+			    PCKBC_AUX_SLOT : PCKBC_KBD_SLOT;
 		q = t->t_slotdata[slot];
 
 		if (!q) {
@@ -1034,6 +1114,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)
@@ -1057,7 +1220,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: sys/dev/ic/pckbcvar.h
===================================================================
RCS file: /cvs/src/sys/dev/ic/pckbcvar.h,v
retrieving revision 1.15
diff -u -p -u -p -r1.15 pckbcvar.h
--- sys/dev/ic/pckbcvar.h	24 May 2015 10:57:47 -0000	1.15
+++ sys/dev/ic/pckbcvar.h	28 Jun 2015 19:22:05 -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];
 
@@ -97,8 +112,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: sys/dev/isa/pckbc_isa.c
===================================================================
RCS file: /cvs/src/sys/dev/isa/pckbc_isa.c,v
retrieving revision 1.18
diff -u -p -u -p -r1.18 pckbc_isa.c
--- sys/dev/isa/pckbc_isa.c	24 May 2015 10:57:47 -0000	1.18
+++ sys/dev/isa/pckbc_isa.c	28 Jun 2015 19:22:05 -0000
@@ -55,6 +55,9 @@ pckbc_isa_match(struct device *parent, v
 	bus_space_tag_t iot = ia->ia_iot;
 	bus_space_handle_t ioh_d, ioh_c;
 	int res;
+#ifdef PCKBC_APM
+	uint slot;
+#endif
 
 	/* If values are hardwired to something that they can't be, punt. */
 	if ((ia->ia_iobase != IOBASEUNK && ia->ia_iobase != IO_KBD) ||
@@ -70,12 +73,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;
@@ -89,7 +92,12 @@ pckbc_isa_match(struct device *parent, v
 	ia->ia_msize = 0x0;
 	ia->ipa_nirq = PCKBC_NSLOTS;
 	ia->ipa_irq[PCKBC_KBD_SLOT].num = 1;
+#ifdef PCKBC_APM
+	for (slot = PCKBC_AUX_SLOT; slot < PCKBC_NSLOTS; slot++)
+		ia->ipa_irq[slot].num = 12;
+#else
 	ia->ipa_irq[PCKBC_AUX_SLOT].num = 12;
+#endif
 
 	return (1);
 
Index: sys/dev/pckbc/pms.c
===================================================================
RCS file: /cvs/src/sys/dev/pckbc/pms.c,v
retrieving revision 1.62
diff -u -p -u -p -r1.62 pms.c
--- sys/dev/pckbc/pms.c	8 Jun 2015 06:39:22 -0000	1.62
+++ sys/dev/pckbc/pms.c	28 Jun 2015 19:22:06 -0000
@@ -169,6 +169,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
@@ -426,10 +427,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);
 	}
 }
@@ -651,7 +652,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. */
@@ -679,8 +680,9 @@ pmsattach(struct device *parent, struct 
 	struct wsmousedev_attach_args a;
 
 	sc->sc_kbctag = pa->pa_tag;
+	sc->sc_slot = pa->pa_slot;
 
-	pckbc_set_inputhandler(sc->sc_kbctag, PCKBC_AUX_SLOT,
+	pckbc_set_inputhandler(sc->sc_kbctag, sc->sc_slot,
 	    pmsinput, sc, DEVNAME(sc));
 
 	printf("\n");
@@ -757,10 +759,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);
 		if (sc->protocol->enable != NULL &&
@@ -776,7 +778,7 @@ pms_change_state(struct pms_softc *sc, i
 		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;
 	}
 
