Garrett D'Amore wrote: > J?rgen Keil wrote: > > Garrett D'Amore wrote > > > > > >> I believe that Solaris uses keyboards (and maybe mice too) in what is > >> called "BOOT Protocol" mode. > >> > > > > That's true for the USB keyboards. > > > > An USB mouse is used in report mode, though (I think > > otherwise we couldn't have USB mouse wheel support). > > > > Not true. USB wheel mice are fairly easily supported via boot protocol, > IIRC. I do seem to recall doing just this work on the wheel mice > support in the Sun Ray firmware, for example.
Ok, it seems the HID spec defines 3 byte boot mouse protocol reports (for 3 buttons, and X + Y displacement), and allows device specific data appended starting at offset 3. It also specifies that the BIOS should ignore device specific extension data at the end of the reports. But in the Solaris kernel USB implemention, the "hid" kernel module will always enable report protocol for USB hid devices, and the USB keyboard module "usbkbm" is the only one that reverts back to boot protocol mode. So, in the Solaris kernel, USB mice are always used in report protocol mode. > >> This is a simplistic report format that > >> was originally intended to allow simple translation to BIOS-compatible > >> keyboard support. (I.e. so you don't have to have a full HID parser in > >> your BIOS or other embedded environments if you only want basic > >> keyboard/mouse support.) > >> > > > > Yes. > > > > > > > >> Apple doesn't have BIOS, and I *suspect* doesn't support the BOOT > >> protocol in their latest products. > >> > > > > That can't be true, because Solaris' GRUB needs a BIOS, > > and GRUB is working just fine on the MacBook Pro, > > including the internal USB keyboard. > > > > Weird, I didn't know that. > > > Old Apple iMacs didn't have a BIOS, only EFI firmware. But > > at some point a firmware update named "BootCamp" was offered > > by Apple that added the missing BIOS support (to allow installing > > Windows - or Solaris / Linux / ....). > > > > Ah, OK. Not an Apple guru. > > > > > > >> Having a full HID parser would probably solve the problem. > >> > > > > Hmm, usbkbm is already using the HID parser. > > > > http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/uts/common/io/usb/ clients/usbkbm/usbkbm.c#548 > > > > > > And I suspect that's the problem! Since it's using > > the keyboard in boot protocol mode, it shouldn't > > try to find out the keyboard's packet size from > > looking at / parsing the HID descriptor. I suspect > > that would only be a valid strategy if the boot > > protocol is disabled. > > > > Yes, it should be looking at the report descriptor, I think. Hmm... The HID report descriptor? Or the keybords endpoint descriptor? The HID report descriptor on the MacBook Pro's internal USB keyboard doesn't describe the data that is sent in boot keyboard protocol mode; it describes the data that is sent when the keyboard in set to report protocol mode. And the keyboard's endpoint descriptor contains a size of 10 bytes, that won't work for boot keyboard protocol mode, either. Note that Solaris' USB keyboard module forces the use of boot protocol mode! > > I suspect that when an usb keyboard is used in boot > > protocol mode, it should just use an expected keyboard > > data packet size of USB_KBD_DEFAULT_PACKET_SIZE (=8) > > bytes (without looking at the HID descriptors)! > > > > Right. Ah, ok. But that's not how it is implemented in usbkbm. > > > > > >> That might be difficult to get into something the likes of GRUB.... > >> > > > > No, keyboard in GRUB works just fine. > > > > Again, this was a surprise. Btw. when I start the Solaris kernel with options "-kd", the internal USB keyboard doesn't work at the kmdb prompt. I suspect that Apple's BIOS disables USB legacy support too early... But that's a different problem, I think. > >> A question: do the keyboard/mouse work in X11 after the system has > >> booted (assuming you used an external keyboard to get that far)? > >> > > > > Yes: > > > > The external USB keyboard works in X11. The internal USB trackpad > > works in X11. The internal USB keyboard doesn't work in X11, either. > > > > > > dtracing in usbkbm_rput() reveals that the MacBook Pro USB > > keyboard is sending standard 8 bytes boot protocol packets, > > but they are dropped on the floor because the usbkbm module > > thinks that the correct packets size is 0 (zero!) bytes - apparently > > that size of 0 bytes doesn't make any sense at all. > > > > All I have to do is patch the usbkbmd->usbkbm_packet_size > > variable from 0 to 8, and the internal usb MacBook Pro keyboard > > starts to work. > > > > > > So, I think for the MacBook USB keyboard we either need: > > > > replace this block: > > > > 548 if (hidparser_get_packet_size(usbkbmd->usbkbm_report_descr, > > 549 0, HIDPARSER_ITEM_INPUT, (uint32_t *)&packet_size) == > > 550 HIDPARSER_FAILURE) { > > 551 > > 552 USB_DPRINTF_L3(PRINT_MASK_OPEN, > > 553 usbkbm_log_handle, "get_packet_size failed" > > 554 "setting default packet size(8)"); > > 555 > > 556 /* Setting to default packet size = 8 */ > > 557 usbkbmd->usbkbm_packet_size = > > 558 USB_KBD_DEFAULT_PACKET_SIZE; > > 559 } else { > > 560 usbkbmd->usbkbm_packet_size = packet_size/8; > > 561 } > > > > > > with > > > > usbkbmd->usbkbm_packet_size = USB_KBD_DEFAULT_PACKET_SIZE; > > > > > > > > Or we could at least sanity check the packet size value returned by parsing the > > usb keyboard's HID descriptors after line 560. usbkbmd->usbkbm_packet_size == 0 > > doesn't make sense and should be replaced by USB_KBD_DEFAULT_PACKET_SIZE. > > > > A sanity check certainly seems obvious, and probably non-controversial. > I'm not sure about just making it the default. There should be a packet > size for report format HID devices somewhere -- if not in the HID > descriptor, then in some other descriptor. These are the descriptors dumped by ::prtusb -c The only size of 8 I see for the keyboard is in the device descriptor bMaxPacketSize0; but I think that one describes the special enpoint 0, and can't be used for the keyboard. The keyboard's endpoint descriptor has a max packet size of 10, too much for boot protocol mode. And parsing the HID report descriptors would tell us the same size of 10 bytes (if we search for reports with ID 1); or we find no description for reports without report ID prefix bytes (which gets us packet size 0, and is the reason the apple internal usb keyboard doesn't work). INDEX DRIVER INST NODE VID.PID PRODUCT f usb_mid 2 device 05ac.0231 Apple Internal Keyboard / Trackpad Device Descriptor { bLength = 0x12 bDescriptorType = 0x1 bcdUSB = 0x200 bDeviceClass = 0 bDeviceSubClass = 0 bDeviceProtocol = 0 bMaxPacketSize0 = 0x8 idVendor = 0x5ac idProduct = 0x231 bcdDevice = 0x70 iManufacturer = 0x1 iProduct = 0x2 iSerialNumber = 0 bNumConfigurations = 0x1 } -- Active Config Index 0 Configuration Descriptor { bLength = 0x9 bDescriptorType = 0x2 wTotalLength = 0x54 bNumInterfaces = 0x3 bConfigurationValue = 0x1 iConfiguration = 0x0 bmAttributes = 0xa0 bMaxPower = 0x14 } Interface Descriptor { bLength = 0x9 bDescriptorType = 0x4 bInterfaceNumber = 0x0 bAlternateSetting = 0x0 bNumEndpoints = 0x1 bInterfaceClass = 0x3 bInterfaceSubClass = 0x1 bInterfaceProtocol = 0x1 iInterface = 0x3 } HID Descriptor { bLength = 0x9 bDescriptorType = 0x21 bcdHID = 0x111 bCountryCode = 0xd bNumDescriptors = 0x1 bReportDescriptorType = 0x22 wReportDescriptorLength = 0x9c } Endpoint Descriptor { bLength = 0x7 bDescriptorType = 0x5 bEndpointAddress = 0x83 bmAttributes = 0x3 wMaxPacketSize = 0xa bInterval = 0x8 } Interface Descriptor { bLength = 0x9 bDescriptorType = 0x4 bInterfaceNumber = 0x1 bAlternateSetting = 0x0 bNumEndpoints = 0x1 bInterfaceClass = 0x3 bInterfaceSubClass = 0x0 bInterfaceProtocol = 0x0 iInterface = 0x4 } HID Descriptor { bLength = 0x9 bDescriptorType = 0x21 bcdHID = 0x111 bCountryCode = 0x0 bNumDescriptors = 0x1 bReportDescriptorType = 0x22 wReportDescriptorLength = 0x1b } Endpoint Descriptor { bLength = 0x7 bDescriptorType = 0x5 bEndpointAddress = 0x81 bmAttributes = 0x3 wMaxPacketSize = 0x40 bInterval = 0x2 } Interface Descriptor { bLength = 0x9 bDescriptorType = 0x4 bInterfaceNumber = 0x2 bAlternateSetting = 0x0 bNumEndpoints = 0x1 bInterfaceClass = 0x3 bInterfaceSubClass = 0x1 bInterfaceProtocol = 0x2 iInterface = 0x4 } HID Descriptor { bLength = 0x9 bDescriptorType = 0x21 bcdHID = 0x111 bCountryCode = 0x0 bNumDescriptors = 0x1 bReportDescriptorType = 0x22 wReportDescriptorLength = 0x34 } Endpoint Descriptor { bLength = 0x7 bDescriptorType = 0x5 bEndpointAddress = 0x84 bmAttributes = 0x3 wMaxPacketSize = 0x8 bInterval = 0x8 }
