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;
        }
 

Reply via email to