usb keyboard attach crashes process usb0 (under FreeBSD4.11)

Norbert Koch nkoch at demig.de
Tue Apr 3 09:53:58 UTC 2007


Hello.

First of all, I understand that there is no interest here in solving
FreeBSD 4.11 problems. I only post this because there
may be a chance that this could be a problem in CURRENT too.
(If no, may be someone likes to dive into ancient software bugs ;-)

I am running an embedded system under FreeBSD 4.11.
Sometimes after booting FreBSD the USB keyboard is not found
and so not automatically attached by usbd.
If I then unplug the keyboard and plug it in again the
kernel crashes with page fault in process 3 (usb0).
I currently have no debug kernel and cannot get a
kernel crash dump as I only have some limited flash memory.

But, so far I found that the crash address is in
usbdi.c, usbd_ar_pipe() at this line:
  pipe->repeat=0.

The function seems to be only called from usbd_abort_pipe().
My guess is that usbd_abort_pipe() is called from ukbd_enable_intr()
in ukbd.c with a null pointer as usbd_pipe_handle.

The parts of the source I inspected seem to be unchanged in
CURRENT, so may be someone with more understanding of the
usb code has an idea about that.

So, first of all I will add a null pointer check in my
kernel source and see if it helps.

Further information: I am seeing this with and without kbdmux
(I modified an earlier and perhaps buggy kbdmux to work under 4.11).
Without kbdmux my usbd.conf contains these lines:
device "USB keyboard"
 devname "ukbd0"
  attach "/usr/sbin/kbdcontrol -k /dev/kdb1 < /dev/console"
  detach "/usr/sbin/kbdcontrol -k /dev/kdb0 < /dev/console"

I also have the following modification in ukbd.c which has been suggested
earlier on this list by Hans Petter Selasky. It reports a specific
ukbd detach event to be catched by usbd. Without that patch the detach line
in usbd.conf won't work:

--- /usr/local/jail/usr/src/sys//dev/usb/ukbd.c Mon Mar  1 21:56:02 2004
+++ ./dev/usb/ukbd.c    Thu Feb 23 09:57:59 2006
@@ -195,6 +195,22 @@
        USB_ATTACH_SUCCESS_RETURN;
 }

+
+static void
+usbd_add_device_detach_event(device_t self)
+{
+        struct usb_event ue;
+
+        bzero(&ue, sizeof(ue));
+
+        strncpy(ue.u.ue_device.udi_devnames[0],
+                device_get_nameunit(self), USB_MAX_DEVNAMELEN);
+        ue.u.ue_device.udi_devnames[0][USB_MAX_DEVNAMELEN - 1] = '\0';
+
+        usb_add_event(USB_EVENT_DEVICE_DETACH, &ue);
+}
+
+
 int
 ukbd_detach(device_t self)
 {
@@ -219,6 +235,8 @@
                return error;

        DPRINTF(("%s: disconnected\n", USBDEVNAME(self)));
+       
+        usbd_add_device_detach_event(self);

        return (0);
 }



Thank you for any help or comment,

Norbert Koch


More information about the freebsd-hackers mailing list