The current heuristic to try and detect that the pckbc device we talk to
is actually an USB controller in legacy mode fail on a few systems,
especially some Toshiba laptops.

I have noticed that, when the code decides not to attach pckbd, a mouse
device will attach anyway. On an USB emulation, this should never be the
case.

Therefore I have changed the logic to force attachment of the keyboard
if the aux port is detected. This ought to fix the Toshiba laptops
(except that pms will attach before pckbd now), and should not make
anything else worse.

Please try this on systems which don't correctly detect the keyboard, as
well as on truly legacy free systems, to confirm this does not cause
pckbd0 to reappear.

Miod

Index: pckbc.c
===================================================================
RCS file: /cvs/src/sys/dev/ic/pckbc.c,v
retrieving revision 1.23
diff -u -p -r1.23 pckbc.c
--- pckbc.c     22 Jul 2010 14:27:44 -0000      1.23
+++ pckbc.c     5 Aug 2010 11:28:33 -0000
@@ -73,6 +73,7 @@ struct pckbc_slotdata {
 
 void pckbc_init_slotdata(struct pckbc_slotdata *);
-int pckbc_attach_slot(struct pckbc_softc *, pckbc_slot_t);
+int pckbc_attach_slot(struct pckbc_softc *, pckbc_slot_t, int);
+int pckbc_submatch_locators(struct device *, void *, void *);
 int pckbc_submatch(struct device *, void *, void *);
 int pckbcprint(void *, const char *);
 
@@ -246,7 +247,7 @@ pckbc_is_console(iot, addr)
 }
 
 int
-pckbc_submatch(parent, match, aux)
+pckbc_submatch_locators(parent, match, aux)
        struct device *parent;
        void *match;
        void *aux;
@@ -257,13 +258,27 @@ pckbc_submatch(parent, match, aux)
        if (cf->cf_loc[PCKBCCF_SLOT] != PCKBCCF_SLOT_DEFAULT &&
            cf->cf_loc[PCKBCCF_SLOT] != pa->pa_slot)
                return (0);
+       return (1);
+}
+
+int
+pckbc_submatch(parent, match, aux)
+       struct device *parent;
+       void *match;
+       void *aux;
+{
+       struct cfdata *cf = match;
+
+       if (pckbc_submatch_locators(parent, match, aux) == 0)
+               return (0);
        return ((*cf->cf_attach->ca_match)(parent, cf, aux));
 }
 
 int
-pckbc_attach_slot(sc, slot)
+pckbc_attach_slot(sc, slot, force)
        struct pckbc_softc *sc;
        pckbc_slot_t slot;
+       int force;
 {
        struct pckbc_internal *t = sc->id;
        struct pckbc_attach_args pa;
@@ -271,8 +286,8 @@ pckbc_attach_slot(sc, slot)
 
        pa.pa_tag = t;
        pa.pa_slot = slot;
-       found = (config_found_sm((struct device *)sc, &pa,
-                                pckbcprint, pckbc_submatch) != NULL);
+       found = (config_found_sm((struct device *)sc, &pa, pckbcprint,
+           force ? pckbc_submatch_locators : pckbc_submatch) != NULL);
 
        if (found && !t->t_slotdata[slot]) {
                t->t_slotdata[slot] = malloc(sizeof(struct pckbc_slotdata),
@@ -335,7 +350,7 @@ pckbc_attach(sc, flags)
                if (res != 0)
                        printf("kbc: returned %x on kbd slot test\n", res);
 #endif
-               if (pckbc_attach_slot(sc, PCKBC_KBD_SLOT)) {
+               if (pckbc_attach_slot(sc, PCKBC_KBD_SLOT, 0)) {
                        cmdbits |= KC8_KENABLE;
                        haskbd = 1;
                }
@@ -344,30 +359,11 @@ pckbc_attach(sc, flags)
                return;
        }
 #else
-       if (pckbc_attach_slot(sc, PCKBC_KBD_SLOT)) {
+       if (pckbc_attach_slot(sc, PCKBC_KBD_SLOT, 0)) {
                cmdbits |= KC8_KENABLE;
                haskbd = 1;
        }
 #endif /* 0 */
-#if defined(__i386__) || defined(__amd64__)
-       if (haskbd == 0 && !ISSET(flags, PCKBCF_FORCE_KEYBOARD_PRESENT)) {
-               /*
-                * If there is no keyboard present, yet we are the console,
-                * we might be on a legacy-free PC where the PS/2 emulated
-                * keyboard was elected as console, but went away as soon
-                * as the USB controller drivers attached.
-                *
-                * In that case, we want to release ourselves from console
-                * duties.
-                */
-               if (pckbc_console != 0) {
-                       extern void wscn_input_init(int);
-
-                       pckbc_console = 0;
-                       wscn_input_init(1);
-               }
-       }
-#endif
 
        /*
         * Check aux port ok.
@@ -418,7 +414,7 @@ pckbc_attach(sc, flags)
                printf("kbc: aux echo: %x\n", res);
 #endif
                t->t_haveaux = 1;
-               if (pckbc_attach_slot(sc, PCKBC_AUX_SLOT))
+               if (pckbc_attach_slot(sc, PCKBC_AUX_SLOT, 0))
                        cmdbits |= KC8_MENABLE;
        }
 #ifdef PCKBCDEBUG
@@ -426,6 +422,34 @@ pckbc_attach(sc, flags)
                printf("kbc: aux echo test failed\n");
 #endif
 
+#if defined(__i386__) || defined(__amd64__)
+       if (haskbd == 0 && !ISSET(flags, PCKBCF_FORCE_KEYBOARD_PRESENT)) {
+               /*
+                * If there is no keyboard present, yet we are the console,
+                * we might be on a legacy-free PC where the PS/2 emulated
+                * keyboard was elected as console, but went away as soon
+                * as the USB controller drivers attached.
+                *
+                * In that case, we want to release ourselves from console
+                * duties, unless we have been able to attach a mouse,
+                * which would mean this is a real PS/2 controller
+                * afterwards.
+                */
+
+               if (t->t_haveaux) {
+                       if (pckbc_attach_slot(sc, PCKBC_KBD_SLOT, 1))
+                               cmdbits |= KC8_KENABLE;
+               } else {
+                       if (pckbc_console != 0) {
+                               extern void wscn_input_init(int);
+
+                               pckbc_console = 0;
+                               wscn_input_init(1);
+                       }
+               }
+       }
+#endif
+
 nomouse:
        /* enable needed interrupts */
        t->t_cmdbyte |= cmdbits;

Reply via email to