Many of us have x86 machines with a USB keyboard that's unusable in
ddb(4).  That's generally because the BIOS presents a fake pckbd(4)
to the OS:

        pckbc0 at isa0 port 0x60/5 irq 1 irq 12
        pckbd0 at pckbc0 (kbd slot)
        wskbd0 at pckbd0: console keyboard, using wsdisplay0

Some BIOSes allow you to disable this emulation.  While this might
allow you to have a working USB keyboard in ddb(4) it generally means
you lose input in the bootloader.

So the diff below introduces a new sysctl(3) to work around this problem.
Adding the following line in your /etc/sysctl.conf will force your first
USB keyboard to re-attach itself after cold boot and become the default
console keyboard.  That means you now have a working keyboard in ddb(4)!

        sysctl machdep.fakepckbc=1

I hope this will improve the content of bug reports.

I'm happy to change the name if you don't like ``fakepckbc'' maybe
``usbconsole''? 

Note that USB keyboards attached to xhci(4) still don't work in ddb(4).

Index: sbin/sysctl/sysctl.8
===================================================================
RCS file: /cvs/src/sbin/sysctl/sysctl.8,v
retrieving revision 1.209
diff -u -p -r1.209 sysctl.8
--- sbin/sysctl/sysctl.8        4 Mar 2017 17:40:23 -0000       1.209
+++ sbin/sysctl/sysctl.8        9 Mar 2017 12:52:32 -0000
@@ -370,6 +370,9 @@ and a few require a kernel compiled with
 .It machdep.sse Ta integer Ta no
 .It machdep.sse2 Ta integer Ta no
 .It machdep.xcrypt Ta integer Ta no
+.It machdep.lidsuspend Ta integer Ta yes
+.It machdep.lidaction Ta integer Ta yes
+.It machdep.fakepckbc Ta integer Ta yes
 .It machdep.allowaperture Ta integer Ta yes
 .It machdep.led_blink Ta integer Ta yes
 .It machdep.ceccerrs Ta integer Ta no
Index: sys/arch/amd64/amd64/machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/amd64/amd64/machdep.c,v
retrieving revision 1.225
diff -u -p -r1.225 machdep.c
--- sys/arch/amd64/amd64/machdep.c      7 Mar 2017 11:49:42 -0000       1.225
+++ sys/arch/amd64/amd64/machdep.c      9 Mar 2017 12:22:52 -0000
@@ -146,6 +146,11 @@ extern int db_console;
 #include <machine/hibernate_var.h>
 #endif /* HIBERNATE */
 
+#include "pckbc.h"
+#if NPCKBC > 0
+#include <dev/ic/pckbcvar.h>
+#endif
+
 /* the following is used externally (sysctl_hw) */
 char machine[] = MACHINE;
 
@@ -189,6 +194,7 @@ paddr_t tramp_pdirpa;
 
 int kbd_reset;
 int lid_action = 1;
+int fake_pckbc;
 
 /*
  * safepri is a safe priority for sleep to set for a spin-wait
@@ -506,6 +512,16 @@ cpu_sysctl(int *name, u_int namelen, voi
                                lid_action = val;
                }
                return (error);
+#if NPCKBC > 0
+       case CPU_FAKEPCKBC:
+               if (fake_pckbc)
+                       return (sysctl_rdint(oldp, oldlenp, newp, fake_pckbc));
+
+               error = sysctl_int(oldp, oldlenp, newp, newlen, &fake_pckbc);
+               if (fake_pckbc)
+                       pckbc_release_console();
+               return (error);
+#endif
        default:
                return (EOPNOTSUPP);
        }
Index: sys/arch/amd64/include/cpu.h
===================================================================
RCS file: /cvs/src/sys/arch/amd64/include/cpu.h,v
retrieving revision 1.108
diff -u -p -r1.108 cpu.h
--- sys/arch/amd64/include/cpu.h        2 Mar 2017 10:38:10 -0000       1.108
+++ sys/arch/amd64/include/cpu.h        9 Mar 2017 12:50:00 -0000
@@ -426,7 +426,8 @@ void mp_setperf_init(void);
 #define CPU_XCRYPT             12      /* supports VIA xcrypt in userland */
 #define CPU_LIDSUSPEND         13      /* lid close causes a suspend */
 #define CPU_LIDACTION          14      /* action caused by lid close */
-#define CPU_MAXID              15      /* number of valid machdep ids */
+#define CPU_FAKEPCKBC          15      /* fake pckbc(4) conroller */
+#define CPU_MAXID              16      /* number of valid machdep ids */
 
 #define        CTL_MACHDEP_NAMES { \
        { 0, 0 }, \
@@ -444,6 +445,7 @@ void mp_setperf_init(void);
        { "xcrypt", CTLTYPE_INT }, \
        { "lidsuspend", CTLTYPE_INT }, \
        { "lidaction", CTLTYPE_INT }, \
+       { "fakepckbc", CTLTYPE_INT }, \
 }
 
 /*
Index: sys/arch/i386/i386/machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/i386/i386/machdep.c,v
retrieving revision 1.597
diff -u -p -r1.597 machdep.c
--- sys/arch/i386/i386/machdep.c        7 Mar 2017 11:49:42 -0000       1.597
+++ sys/arch/i386/i386/machdep.c        9 Mar 2017 12:23:32 -0000
@@ -168,6 +168,11 @@ extern struct proc *npxproc;
 #include <machine/hibernate_var.h>
 #endif /* HIBERNATE */
 
+#include "pckbc.h"
+#if NPCKBC > 0
+#include <dev/ic/pckbcvar.h>
+#endif
+
 #include "vmm.h"
 
 void   replacesmap(void);
@@ -235,6 +240,7 @@ void        via_update_sensor(void *args);
 #endif
 int kbd_reset;
 int lid_action = 1;
+int fake_pckbc;
 
 /*
  * safepri is a safe priority for sleep to set for a spin-wait
@@ -3529,6 +3535,7 @@ int
 cpu_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
     size_t newlen, struct proc *p)
 {
+       int error;
        dev_t dev;
        int val, error;
 
@@ -3606,6 +3613,16 @@ cpu_sysctl(int *name, u_int namelen, voi
                                lid_action = val;
                }
                return (error);
+#if NPCKBC > 0
+       case CPU_FAKEPCKBC:
+               if (fake_pckbc)
+                       return (sysctl_rdint(oldp, oldlenp, newp, fake_pckbc));
+
+               error = sysctl_int(oldp, oldlenp, newp, newlen, &fake_pckbc);
+               if (fake_pckbc)
+                       pckbc_release_console();
+               return (error);
+#endif
        default:
                return (EOPNOTSUPP);
        }
Index: sys/arch/i386/include/cpu.h
===================================================================
RCS file: /cvs/src/sys/arch/i386/include/cpu.h,v
retrieving revision 1.153
diff -u -p -r1.153 cpu.h
--- sys/arch/i386/include/cpu.h 2 Mar 2017 10:38:10 -0000       1.153
+++ sys/arch/i386/include/cpu.h 9 Mar 2017 12:25:18 -0000
@@ -525,7 +525,8 @@ int cpu_paenable(void *);
 #define CPU_XCRYPT             16      /* supports VIA xcrypt in userland */
 #define CPU_LIDSUSPEND         17      /* lid close causes a suspend */
 #define CPU_LIDACTION          18      /* action caused by lid close */
-#define CPU_MAXID              19      /* number of valid machdep ids */
+#define CPU_FAKEPCKBC          19      /* fake pckbc(4) conroller */
+#define CPU_MAXID              20      /* number of valid machdep ids */
 
 #define        CTL_MACHDEP_NAMES { \
        { 0, 0 }, \
@@ -547,6 +548,7 @@ int cpu_paenable(void *);
        { "xcrypt", CTLTYPE_INT }, \
        { "lidsuspend", CTLTYPE_INT }, \
        { "lidaction", CTLTYPE_INT }, \
+       { "fakepckbc", CTLTYPE_INT }, \
 }
 
 /*
Index: sys/dev/hid/hidkbd.c
===================================================================
RCS file: /cvs/src/sys/dev/hid/hidkbd.c,v
retrieving revision 1.1
diff -u -p -r1.1 hidkbd.c
--- sys/dev/hid/hidkbd.c        8 Jan 2016 15:54:13 -0000       1.1
+++ sys/dev/hid/hidkbd.c        9 Mar 2017 12:37:17 -0000
@@ -215,17 +215,6 @@ hidkbd_detach(struct hidkbd *kbd, int fl
        DPRINTF(("hidkbd_detach: sc=%p flags=%d\n", kbd->sc_device, flags));
 
        if (kbd->sc_console_keyboard) {
-#if 0
-               /*
-                * XXX Should probably disconnect our consops,
-                * XXX and either notify some other keyboard that
-                * XXX it can now be the console, or if there aren't
-                * XXX any more USB keyboards, set hidkbd_is_console
-                * XXX back to 1 so that the next USB keyboard attached
-                * XXX to the system will get it.
-                */
-               panic("hidkbd_detach: console keyboard");
-#else
                /*
                 * Disconnect our consops and set hidkbd_is_console
                 * back to 1 so that the next USB keyboard attached
@@ -235,9 +224,7 @@ hidkbd_detach(struct hidkbd *kbd, int fl
                 */
                printf("%s: was console keyboard\n",
                       kbd->sc_device->dv_xname);
-               wskbd_cndetach();
                hidkbd_is_console = 1;
-#endif
        }
        /* No need to do reference counting of hidkbd, wskbd has all the goo */
        if (kbd->sc_wskbddev != NULL)
Index: sys/dev/hil/hilkbd.c
===================================================================
RCS file: /cvs/src/sys/dev/hil/hilkbd.c,v
retrieving revision 1.16
diff -u -p -r1.16 hilkbd.c
--- sys/dev/hil/hilkbd.c        26 Jan 2014 17:48:08 -0000      1.16
+++ sys/dev/hil/hilkbd.c        9 Mar 2017 12:37:29 -0000
@@ -229,7 +229,6 @@ hilkbddetach(struct device *self, int fl
         * as the first device in the loop anyways.
         */
        if (sc->sc_console) {
-               wskbd_cndetach();
                seen_hilkbd_console = 0;
        }
 
Index: sys/dev/ic/pckbc.c
===================================================================
RCS file: /cvs/src/sys/dev/ic/pckbc.c,v
retrieving revision 1.49
diff -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  9 Mar 2017 12:21:26 -0000
@@ -81,12 +81,11 @@ int pckbc_attach_slot(struct pckbc_softc
 int pckbc_submatch_locators(struct device *, void *, void *);
 int pckbc_submatch(struct device *, void *, void *);
 int pckbcprint(void *, const char *);
-void pckbc_release_console(void);
 
 struct pckbc_internal pckbc_consdata;
 int pckbc_console_attached;
 
-static int pckbc_console;
+int pckbc_console;
 static struct pckbc_slotdata pckbc_cons_slotdata;
 
 static int pckbc_wait_output(bus_space_tag_t, bus_space_handle_t);
Index: sys/dev/ic/pckbcvar.h
===================================================================
RCS file: /cvs/src/sys/dev/ic/pckbcvar.h,v
retrieving revision 1.15
diff -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       9 Mar 2017 12:21:26 -0000
@@ -110,6 +110,8 @@ void pckbc_reset(struct pckbc_softc *);
 void pckbc_stop(struct pckbc_softc *);
 int pckbcintr(void *);
 
+void pckbc_release_console(void);
+
 /*
  * Device configuration flags (cf_flags).
  */
Index: sys/dev/usb/ukbd.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/ukbd.c,v
retrieving revision 1.76
diff -u -p -r1.76 ukbd.c
--- sys/dev/usb/ukbd.c  12 Jan 2016 19:16:21 -0000      1.76
+++ sys/dev/usb/ukbd.c  9 Mar 2017 12:48:32 -0000
@@ -57,10 +57,13 @@
 #include <sys/device.h>
 #include <sys/ioctl.h>
 
+#include <machine/bus.h>
+
 #include <dev/usb/usb.h>
 #include <dev/usb/usbhid.h>
 
 #include <dev/usb/usbdi.h>
+#include <dev/usb/usbdivar.h> /* needs_reattach() */
 #include <dev/usb/usbdi_util.h>
 #include <dev/usb/usbdevs.h>
 #include <dev/usb/usb_quirks.h>
@@ -448,12 +451,29 @@ ukbd_cnbell(void *v, u_int pitch, u_int 
 int
 ukbd_cnattach(void)
 {
+       struct ukbd_softc *sc;
+       int i;
+
        /*
         * XXX USB requires too many parts of the kernel to be running
         * XXX in order to work, so we can't do much for the console
         * XXX keyboard until autconfiguration has run its course.
         */
        hidkbd_is_console = 1;
+
+       if (!cold) {
+               /*
+                * When switching console dynamically force all USB keyboards
+                * to re-attach and possibly became the 'console' keyboard.
+                */
+               for (i = 0; i < ukbd_cd.cd_ndevs; i++) {
+                       if ((sc = ukbd_cd.cd_devs[i]) != NULL) {
+                               usb_needs_reattach(sc->sc_hdev.sc_udev);
+                               break;
+                       }
+               }
+       }
+
        return (0);
 }
 
Index: sys/dev/wscons/wskbd.c
===================================================================
RCS file: /cvs/src/sys/dev/wscons/wskbd.c,v
retrieving revision 1.84
diff -u -p -r1.84 wskbd.c
--- sys/dev/wscons/wskbd.c      30 Sep 2016 12:05:46 -0000      1.84
+++ sys/dev/wscons/wskbd.c      9 Mar 2017 12:35:57 -0000
@@ -517,7 +517,7 @@ wskbd_cnattach(const struct wskbd_consop
        wskbd_console_initted = 1;
 }
 
-void    
+void
 wskbd_cndetach(void)
 {
        KASSERT(wskbd_console_initted);
@@ -532,6 +532,7 @@ wskbd_cndetach(void)
        wsdisplay_unset_cons_kbd();
 #endif
 
+       wskbd_console_device = NULL;
        wskbd_console_initted = 0;
 }
 
@@ -608,7 +609,7 @@ wskbd_detach(struct device  *self, int f
 
        if (sc->sc_isconsole) {
                KASSERT(wskbd_console_device == sc);
-               wskbd_console_device = NULL;
+               wskbd_cndetach();
        }
 
        evar = sc->sc_base.me_evp;
@@ -1365,7 +1366,6 @@ wskbd_cngetc(dev_t dev)
 void
 wskbd_cnpollc(dev_t dev, int poll)
 {
-
        if (!wskbd_console_initted)
                return;
 

Reply via email to