Date: Fri, 15 May 2009 21:55:08 +0200 From: Christoph Langguth <christoph@rosenkeller.org> To: freebsd-usb@freebsd.org Subject: How to add support for Macbook Pro (USB) keyboard? Message-ID: <4A0DC89C.6010708@rosenkeller.org>
next in thread | raw e-mail | index | archive | help
Hi all, first off, I have just subscribed to this list, as it seemed the most logical place -- but in case this is the wrong place to ask, please accept my apologies and point me to the right place. Second, I'm sorry for the long mail, but I'm only getting started with this -- not much experience in hacking the kernel yet, and in how it really is organized internally. So I'd really appreciate any help here -- I'd also be willing to contribute, if I can. The problem is the following: I'm trying to get FreeBSD to run on a Macbook Pro (MBP), purchased some time last year. As soon as the FreeBSD kernel is loaded, the keyboard is malfunctioning. (What I mean by this is: at the loader prompt, it still works ok; when it's handled by ukbd, it acts as if the Ctrl key was constantly stuck). So far, I have found one reference to this problem: http://unix.derkeiler.com/Mailing-Lists/FreeBSD/stable/2009-02/msg00031.html The keyboard in question identifies itself like this: marvin# usbconfig -u 5 -a 3 dump_device_desc ugen5.3: <Apple Internal Keyboard / Trackpad Apple, Inc.> at usbus5, cfg=0 md=HOST spd=FULL (12Mbps) pwr=ON bLength = 0x0012 bDescriptorType = 0x0001 bcdUSB = 0x0200 bDeviceClass = 0x0000 bDeviceSubClass = 0x0000 bDeviceProtocol = 0x0000 bMaxPacketSize0 = 0x0008 idVendor = 0x05ac idProduct = 0x0231 bcdDevice = 0x0070 iManufacturer = 0x0001 <Apple, Inc.> iProduct = 0x0002 <Apple Internal Keyboard / Trackpad> iSerialNumber = 0x0000 <no string> bNumConfigurations = 0x0001 I had first tried to pinpoint the problem with the sources that came with the 7.2-RELEASE sources, by turning some USB debugging on, but got stuck when I ended up getting BABBLE reports from uhci, and couldn't figure out how to get any further. I then decided to try to switch to CURRENT and see whether the problem may have been fixed there. Turns out it hasn't been fixed, but since there have obviously been major code rewrites there, I was able to figure out the problem. It's happening in ukbd_intr_callback(): This function is expecting 8 bytes of data (of which the first is the keyboard modifiers). Turns out that the MBP sends 10 bytes instead, with - the first always being 01 (which explains why the Ctrl key seems to be stuck) - indexes 1 to 8 containing the actually "expected" data - the last being 00 or 02, depending on whether the Fn key was pressed. I'm inlining a diff of my changes here: --- ukbd.c.org 2009-05-15 17:38:59.000000000 +0000 +++ ukbd.c 2009-05-15 18:48:01.000000000 +0000 @@ -470,17 +470,24 @@ struct ukbd_softc *sc = xfer->priv_sc; uint16_t len = xfer->actlen; uint8_t i; + uint8_t mydebug[256]; + uint8_t offset = 0; switch (USB_GET_STATE(xfer)) { case USB_ST_TRANSFERRED: DPRINTF("actlen=%d bytes\n", len); + usb2_copy_out(xfer->frbuffers, 0, &mydebug[0], len); + for (i=0; i < len; ++i) { + DPRINTF("dump %02d = %02x\n",i,mydebug[i]); + } if (len > sizeof(sc->sc_ndata)) { len = sizeof(sc->sc_ndata); + offset = 1; } if (len) { bzero(&sc->sc_ndata, sizeof(sc->sc_ndata)); - usb2_copy_out(xfer->frbuffers, 0, &sc->sc_ndata, len); + usb2_copy_out(xfer->frbuffers, offset, &sc->sc_ndata, len); #if USB_DEBUG if (sc->sc_ndata.modifiers) { DPRINTF("mod: 0x%04x\n", sc->sc_ndata.modifiers); (I know that's a hack, it was just for testing and works for me). After having figured this out (and ignoring the Fn "bit" for now), I looked into the existing USB quirks, and there seems to be one named UQ_MS_LEADING_BYTE. I tried (with the original ukbd) to see if applying that quirk resulted in anything -- both by modifying the quirks.c, and by running usbconfig -u 5 -a 3 add_dev_quirk_vplh 0x5ac 0x231 0 0xffff UQ_MS_LEADING_BYTE but the result was exactly the same as before (i.e., the first spurious byte didn't vanish). I might have done something wrong with the quirks, but I guess it's actually just a different case than UQ_MS_LEADING_BYTE. So my question now is: what is the correct approach to add support for this keyboard? The thing I did above is clearly a hack, but I'm just not sure where these things should be handled correctly (Especially in light of the additional "Fn" key being present, and probably requiring some translation table, e.g. to map "fn+backspace" to "del", etc.) What is the correct approach here? Some modified ukbd as an additional module? Modifying the ukbd itself (but how)? I'm also feeling kind of better when running on a -STABLE system for production use, which would require some "backporting" (but as said, I got stuck in the "old" sources because I didn't really understand how things worked there). As I said, I would be willing to invest effort into this, but would need some guidance, so any help is very much appreciated :-) OK, I guess that's it for now, thanks in advance for the replies! -- Chris
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4A0DC89C.6010708>