How to add support for Macbook Pro (USB) keyboard?
Christoph Langguth
christoph at rosenkeller.org
Fri May 15 20:13:19 UTC 2009
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
More information about the freebsd-usb
mailing list