PERFORCE change 162145 for review
Hans Petter Selasky
hselasky at FreeBSD.org
Sat May 16 06:25:49 UTC 2009
http://perforce.freebsd.org/chv.cgi?CH=162145
Change 162145 by hselasky at hselasky_laptop001 on 2009/05/16 06:25:17
USB input:
- patch for Apple MacBook Pro keyboard.
Reported by: Christoph Langguth
Affected files ...
.. //depot/projects/usb/src/sys/dev/usb/input/ukbd.c#5 edit
Differences ...
==== //depot/projects/usb/src/sys/dev/usb/input/ukbd.c#5 (text+ko) ====
@@ -117,7 +117,6 @@
enum {
UKBD_INTR_DT,
- UKBD_INTR_CS,
UKBD_CTRL_LED,
UKBD_N_TRANSFER = 3,
};
@@ -147,7 +146,6 @@
#define UKBD_FLAG_COMPOSE 0x0001
#define UKBD_FLAG_POLLING 0x0002
#define UKBD_FLAG_SET_LEDS 0x0004
-#define UKBD_FLAG_INTR_STALL 0x0008
#define UKBD_FLAG_ATTACHED 0x0010
#define UKBD_FLAG_GONE 0x0020
@@ -162,6 +160,7 @@
uint8_t sc_leds; /* store for async led requests */
uint8_t sc_iface_index;
uint8_t sc_iface_no;
+ uint8_t sc_hid_id;
};
#define KEY_ERROR 0x01
@@ -452,35 +451,31 @@
}
static void
-ukbd_clear_stall_callback(struct usb2_xfer *xfer)
-{
- struct ukbd_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[UKBD_INTR_DT];
-
- if (usb2_clear_stall_callback(xfer, xfer_other)) {
- DPRINTF("stall cleared\n");
- sc->sc_flags &= ~UKBD_FLAG_INTR_STALL;
- usb2_transfer_start(xfer_other);
- }
-}
-
-static void
ukbd_intr_callback(struct usb2_xfer *xfer)
{
struct ukbd_softc *sc = xfer->priv_sc;
uint16_t len = xfer->actlen;
uint8_t i;
+ uint8_t offset;
switch (USB_GET_STATE(xfer)) {
case USB_ST_TRANSFERRED:
DPRINTF("actlen=%d bytes\n", len);
+ if ((sc->sc_hid_id != 0) && (len != 0)) {
+ /* remove HID ID byte */
+ offset = 1;
+ len--;
+ } else {
+ offset = 0;
+ }
if (len > sizeof(sc->sc_ndata)) {
len = sizeof(sc->sc_ndata);
}
if (len) {
- bzero(&sc->sc_ndata, sizeof(sc->sc_ndata));
- usb2_copy_out(xfer->frbuffers, 0, &sc->sc_ndata, len);
+ memset(&sc->sc_ndata, 0, sizeof(sc->sc_ndata));
+ 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);
@@ -494,27 +489,24 @@
ukbd_interrupt(sc);
}
case USB_ST_SETUP:
- if (sc->sc_flags & UKBD_FLAG_INTR_STALL) {
- usb2_transfer_start(sc->sc_xfer[UKBD_INTR_CS]);
- return;
- }
+tr_setup:
if (sc->sc_inputs < UKBD_IN_BUF_FULL) {
xfer->frlengths[0] = xfer->max_data_length;
usb2_start_hardware(xfer);
} else {
DPRINTF("input queue is full!\n");
}
- return;
+ break;
default: /* Error */
DPRINTF("error=%s\n", usb2_errstr(xfer->error));
if (xfer->error != USB_ERR_CANCELLED) {
/* try to clear stall first */
- sc->sc_flags |= UKBD_FLAG_INTR_STALL;
- usb2_transfer_start(sc->sc_xfer[UKBD_INTR_CS]);
+ xfer->flags.stall_pipe = 1;
+ goto tr_setup;
}
- return;
+ break;
}
}
@@ -567,16 +559,6 @@
.callback = &ukbd_intr_callback,
},
- [UKBD_INTR_CS] = {
- .type = UE_CONTROL,
- .endpoint = 0x00, /* Control pipe */
- .direction = UE_DIR_ANY,
- .bufsize = sizeof(struct usb2_device_request),
- .callback = &ukbd_clear_stall_callback,
- .timeout = 1000, /* 1 second */
- .interval = 50, /* 50ms */
- },
-
[UKBD_CTRL_LED] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
@@ -620,8 +602,10 @@
struct usb2_attach_arg *uaa = device_get_ivars(dev);
int32_t unit = device_get_unit(dev);
keyboard_t *kbd = &sc->sc_kbd;
+ void *hid_ptr = NULL;
usb2_error_t err;
uint16_t n;
+ uint16_t hid_len;
mtx_assert(&Giant, MA_OWNED);
@@ -669,6 +653,14 @@
*/
KBD_PROBE_DONE(kbd);
+ /* figure out if there is an ID byte in the data */
+ err = usb2_req_get_hid_desc(uaa->device, NULL, &hid_ptr,
+ &hid_len, M_TEMP, uaa->info.bIfaceIndex);
+ if (err == 0) {
+ hid_report_size(hid_ptr, hid_len, hid_input, &sc->sc_hid_id);
+ free(hid_ptr, M_TEMP);
+ }
+
/* ignore if SETIDLE fails, hence it is not crucial */
err = usb2_req_set_idle(sc->sc_udev, &Giant, sc->sc_iface_index, 0, 0);
More information about the p4-projects
mailing list