1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause-NetBSD 3 * 4 * Copyright (c) 1998 The NetBSD Foundation, Inc. 5 * Copyright (c) 2019 Vladimir Kondratyev <wulf@FreeBSD.org> 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Lennart Augustsson (lennart@augustsson.net) at 9 * Carlstedt Research & Technology. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 #include <sys/cdefs.h> 34 __FBSDID("$FreeBSD$"); 35 36 /* 37 * HID spec: https://www.usb.org/sites/default/files/documents/hid1_11.pdf 38 */ 39 40 #include <sys/stdint.h> 41 #include <sys/stddef.h> 42 #include <sys/param.h> 43 #include <sys/queue.h> 44 #include <sys/types.h> 45 #include <sys/systm.h> 46 #include <sys/kernel.h> 47 #include <sys/bus.h> 48 #include <sys/module.h> 49 #include <sys/lock.h> 50 #include <sys/mutex.h> 51 #include <sys/condvar.h> 52 #include <sys/sysctl.h> 53 #include <sys/sx.h> 54 #include <sys/unistd.h> 55 #include <sys/callout.h> 56 #include <sys/malloc.h> 57 #include <sys/priv.h> 58 #include <sys/conf.h> 59 #include <sys/fcntl.h> 60 61 #include <dev/evdev/input.h> 62 63 #include <dev/hid/hid.h> 64 #include <dev/hid/hidquirk.h> 65 66 #include <dev/usb/usb.h> 67 #include <dev/usb/usbdi.h> 68 #include <dev/usb/usbdi_util.h> 69 #include <dev/usb/usbhid.h> 70 71 #define USB_DEBUG_VAR usbhid_debug 72 #include <dev/usb/usb_debug.h> 73 74 #include <dev/usb/quirk/usb_quirk.h> 75 76 #include "hid_if.h" 77 78 #ifdef USB_DEBUG 79 static int usbhid_debug = 0; 80 81 static SYSCTL_NODE(_hw_usb, OID_AUTO, usbhid, CTLFLAG_RW, 0, "USB usbhid"); 82 SYSCTL_INT(_hw_usb_usbhid, OID_AUTO, debug, CTLFLAG_RWTUN, 83 &usbhid_debug, 0, "Debug level"); 84 #endif 85 86 enum { 87 USBHID_INTR_OUT_DT, 88 USBHID_INTR_IN_DT, 89 USBHID_CTRL_DT, 90 USBHID_N_TRANSFER, 91 }; 92 93 struct usbhid_xfer_ctx; 94 typedef int usbhid_callback_t(struct usbhid_xfer_ctx *xfer_ctx); 95 96 union usbhid_device_request { 97 struct { /* INTR xfers */ 98 uint16_t maxlen; 99 uint16_t actlen; 100 } intr; 101 struct usb_device_request ctrl; /* CTRL xfers */ 102 }; 103 104 /* Syncronous USB transfer context */ 105 struct usbhid_xfer_ctx { 106 union usbhid_device_request req; 107 uint8_t *buf; 108 int error; 109 usbhid_callback_t *cb; 110 void *cb_ctx; 111 int waiters; 112 bool influx; 113 }; 114 115 struct usbhid_softc { 116 hid_intr_t *sc_intr_handler; 117 void *sc_intr_ctx; 118 void *sc_intr_buf; 119 120 struct hid_device_info sc_hw; 121 122 struct mtx sc_mtx; 123 struct usb_config sc_config[USBHID_N_TRANSFER]; 124 struct usb_xfer *sc_xfer[USBHID_N_TRANSFER]; 125 struct usbhid_xfer_ctx sc_xfer_ctx[USBHID_N_TRANSFER]; 126 127 struct usb_device *sc_udev; 128 uint8_t sc_iface_no; 129 uint8_t sc_iface_index; 130 }; 131 132 /* prototypes */ 133 134 static device_probe_t usbhid_probe; 135 static device_attach_t usbhid_attach; 136 static device_detach_t usbhid_detach; 137 138 static usb_callback_t usbhid_intr_out_callback; 139 static usb_callback_t usbhid_intr_in_callback; 140 static usb_callback_t usbhid_ctrl_callback; 141 142 static usbhid_callback_t usbhid_intr_handler_cb; 143 static usbhid_callback_t usbhid_sync_wakeup_cb; 144 145 static void 146 usbhid_intr_out_callback(struct usb_xfer *xfer, usb_error_t error) 147 { 148 struct usbhid_xfer_ctx *xfer_ctx = usbd_xfer_softc(xfer); 149 struct usb_page_cache *pc; 150 int len; 151 152 switch (USB_GET_STATE(xfer)) { 153 case USB_ST_TRANSFERRED: 154 case USB_ST_SETUP: 155 tr_setup: 156 len = xfer_ctx->req.intr.maxlen; 157 if (len == 0) { 158 if (USB_IN_POLLING_MODE_FUNC()) 159 xfer_ctx->error = 0; 160 return; 161 } 162 pc = usbd_xfer_get_frame(xfer, 0); 163 usbd_copy_in(pc, 0, xfer_ctx->buf, len); 164 usbd_xfer_set_frame_len(xfer, 0, len); 165 usbd_transfer_submit(xfer); 166 xfer_ctx->req.intr.maxlen = 0; 167 if (USB_IN_POLLING_MODE_FUNC()) 168 return; 169 xfer_ctx->error = 0; 170 goto tr_exit; 171 172 default: /* Error */ 173 if (error != USB_ERR_CANCELLED) { 174 /* try to clear stall first */ 175 usbd_xfer_set_stall(xfer); 176 goto tr_setup; 177 } 178 xfer_ctx->error = EIO; 179 tr_exit: 180 (void)xfer_ctx->cb(xfer_ctx); 181 return; 182 } 183 } 184 185 static void 186 usbhid_intr_in_callback(struct usb_xfer *xfer, usb_error_t error) 187 { 188 struct usbhid_xfer_ctx *xfer_ctx = usbd_xfer_softc(xfer); 189 struct usb_page_cache *pc; 190 int actlen; 191 192 switch (USB_GET_STATE(xfer)) { 193 case USB_ST_TRANSFERRED: 194 DPRINTF("transferred!\n"); 195 196 usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL); 197 pc = usbd_xfer_get_frame(xfer, 0); 198 usbd_copy_out(pc, 0, xfer_ctx->buf, actlen); 199 xfer_ctx->req.intr.actlen = actlen; 200 if (xfer_ctx->cb(xfer_ctx) != 0) 201 return; 202 203 case USB_ST_SETUP: 204 re_submit: 205 usbd_xfer_set_frame_len(xfer, 0, xfer_ctx->req.intr.maxlen); 206 usbd_transfer_submit(xfer); 207 return; 208 209 default: /* Error */ 210 if (error != USB_ERR_CANCELLED) { 211 /* try to clear stall first */ 212 usbd_xfer_set_stall(xfer); 213 goto re_submit; 214 } 215 return; 216 } 217 } 218 219 static void 220 usbhid_ctrl_callback(struct usb_xfer *xfer, usb_error_t error) 221 { 222 struct usbhid_xfer_ctx *xfer_ctx = usbd_xfer_softc(xfer); 223 struct usb_device_request *req = &xfer_ctx->req.ctrl; 224 struct usb_page_cache *pc; 225 int len = UGETW(req->wLength); 226 bool is_rd = (req->bmRequestType & UT_READ) != 0; 227 228 switch (USB_GET_STATE(xfer)) { 229 case USB_ST_SETUP: 230 if (!is_rd && len != 0) { 231 pc = usbd_xfer_get_frame(xfer, 1); 232 usbd_copy_in(pc, 0, xfer_ctx->buf, len); 233 } 234 235 pc = usbd_xfer_get_frame(xfer, 0); 236 usbd_copy_in(pc, 0, req, sizeof(*req)); 237 usbd_xfer_set_frame_len(xfer, 0, sizeof(*req)); 238 if (len != 0) 239 usbd_xfer_set_frame_len(xfer, 1, len); 240 usbd_xfer_set_frames(xfer, len != 0 ? 2 : 1); 241 usbd_transfer_submit(xfer); 242 return; 243 244 case USB_ST_TRANSFERRED: 245 if (is_rd && len != 0) { 246 pc = usbd_xfer_get_frame(xfer, 0); 247 usbd_copy_out(pc, sizeof(*req), xfer_ctx->buf, len); 248 } 249 xfer_ctx->error = 0; 250 goto tr_exit; 251 252 default: /* Error */ 253 /* bomb out */ 254 DPRINTFN(1, "error=%s\n", usbd_errstr(error)); 255 xfer_ctx->error = EIO; 256 tr_exit: 257 (void)xfer_ctx->cb(xfer_ctx); 258 return; 259 } 260 } 261 262 static int 263 usbhid_intr_handler_cb(struct usbhid_xfer_ctx *xfer_ctx) 264 { 265 struct usbhid_softc *sc = xfer_ctx->cb_ctx; 266 267 sc->sc_intr_handler(sc->sc_intr_ctx, xfer_ctx->buf, 268 xfer_ctx->req.intr.actlen); 269 270 return (0); 271 } 272 273 static int 274 usbhid_sync_wakeup_cb(struct usbhid_xfer_ctx *xfer_ctx) 275 { 276 277 if (!USB_IN_POLLING_MODE_FUNC()) 278 wakeup(xfer_ctx->cb_ctx); 279 280 return (ECANCELED); 281 } 282 283 static const struct usb_config usbhid_config[USBHID_N_TRANSFER] = { 284 285 [USBHID_INTR_OUT_DT] = { 286 .type = UE_INTERRUPT, 287 .endpoint = UE_ADDR_ANY, 288 .direction = UE_DIR_OUT, 289 .flags = {.pipe_bof = 1,.proxy_buffer = 1}, 290 .callback = &usbhid_intr_out_callback, 291 }, 292 [USBHID_INTR_IN_DT] = { 293 .type = UE_INTERRUPT, 294 .endpoint = UE_ADDR_ANY, 295 .direction = UE_DIR_IN, 296 .flags = {.pipe_bof = 1,.short_xfer_ok = 1,.proxy_buffer = 1}, 297 .callback = &usbhid_intr_in_callback, 298 }, 299 [USBHID_CTRL_DT] = { 300 .type = UE_CONTROL, 301 .endpoint = 0x00, /* Control pipe */ 302 .direction = UE_DIR_ANY, 303 .flags = {.proxy_buffer = 1}, 304 .callback = &usbhid_ctrl_callback, 305 .timeout = 1000, /* 1 second */ 306 }, 307 }; 308 309 static void 310 usbhid_intr_setup(device_t dev, hid_intr_t intr, void *context, 311 struct hid_rdesc_info *rdesc) 312 { 313 struct usbhid_softc* sc = device_get_softc(dev); 314 uint16_t n; 315 bool nowrite; 316 int error; 317 318 sc->sc_intr_handler = intr; 319 sc->sc_intr_ctx = context; 320 bcopy(usbhid_config, sc->sc_config, sizeof(usbhid_config)); 321 322 /* Set buffer sizes to match HID report sizes */ 323 sc->sc_config[USBHID_INTR_OUT_DT].bufsize = rdesc->osize; 324 sc->sc_config[USBHID_INTR_IN_DT].bufsize = rdesc->isize; 325 sc->sc_config[USBHID_CTRL_DT].bufsize = 326 MAX(rdesc->isize, MAX(rdesc->osize, rdesc->fsize)); 327 328 nowrite = hid_test_quirk(&sc->sc_hw, HQ_NOWRITE); 329 330 /* 331 * Setup the USB transfers one by one, so they are memory independent 332 * which allows for handling panics triggered by the HID drivers 333 * itself, typically by hkbd via CTRL+ALT+ESC sequences. Or if the HID 334 * keyboard driver was processing a key at the moment of panic. 335 */ 336 for (n = 0; n != USBHID_N_TRANSFER; n++) { 337 if (nowrite && n == USBHID_INTR_OUT_DT) 338 continue; 339 error = usbd_transfer_setup(sc->sc_udev, &sc->sc_iface_index, 340 sc->sc_xfer + n, sc->sc_config + n, 1, 341 (void *)(sc->sc_xfer_ctx + n), &sc->sc_mtx); 342 if (error) 343 break; 344 } 345 346 if (error) 347 DPRINTF("error=%s\n", usbd_errstr(error)); 348 349 rdesc->rdsize = usbd_xfer_max_len(sc->sc_xfer[USBHID_INTR_IN_DT]); 350 rdesc->grsize = usbd_xfer_max_len(sc->sc_xfer[USBHID_CTRL_DT]); 351 rdesc->srsize = rdesc->grsize; 352 rdesc->wrsize = nowrite ? rdesc->srsize : 353 usbd_xfer_max_len(sc->sc_xfer[USBHID_INTR_OUT_DT]); 354 355 sc->sc_intr_buf = malloc(rdesc->rdsize, M_USBDEV, M_ZERO | M_WAITOK); 356 } 357 358 static void 359 usbhid_intr_unsetup(device_t dev) 360 { 361 struct usbhid_softc* sc = device_get_softc(dev); 362 363 usbd_transfer_unsetup(sc->sc_xfer, USBHID_N_TRANSFER); 364 free(sc->sc_intr_buf, M_USBDEV); 365 } 366 367 static int 368 usbhid_intr_start(device_t dev) 369 { 370 struct usbhid_softc* sc = device_get_softc(dev); 371 372 mtx_lock(&sc->sc_mtx); 373 sc->sc_xfer_ctx[USBHID_INTR_IN_DT] = (struct usbhid_xfer_ctx) { 374 .req.intr.maxlen = 375 usbd_xfer_max_len(sc->sc_xfer[USBHID_INTR_IN_DT]), 376 .cb = usbhid_intr_handler_cb, 377 .cb_ctx = sc, 378 .buf = sc->sc_intr_buf, 379 }; 380 usbd_transfer_start(sc->sc_xfer[USBHID_INTR_IN_DT]); 381 mtx_unlock(&sc->sc_mtx); 382 383 return (0); 384 } 385 386 static int 387 usbhid_intr_stop(device_t dev) 388 { 389 struct usbhid_softc* sc = device_get_softc(dev); 390 391 usbd_transfer_drain(sc->sc_xfer[USBHID_INTR_IN_DT]); 392 usbd_transfer_drain(sc->sc_xfer[USBHID_INTR_OUT_DT]); 393 394 return (0); 395 } 396 397 static void 398 usbhid_intr_poll(device_t dev) 399 { 400 struct usbhid_softc* sc = device_get_softc(dev); 401 402 usbd_transfer_poll(sc->sc_xfer + USBHID_INTR_IN_DT, 1); 403 } 404 405 /* 406 * HID interface 407 */ 408 static int 409 usbhid_sync_xfer(struct usbhid_softc* sc, int xfer_idx, 410 union usbhid_device_request *req, void *buf) 411 { 412 int error, timeout; 413 struct usbhid_xfer_ctx *xfer_ctx, save; 414 415 xfer_ctx = sc->sc_xfer_ctx + xfer_idx; 416 417 if (USB_IN_POLLING_MODE_FUNC()) { 418 save = *xfer_ctx; 419 } else { 420 mtx_lock(&sc->sc_mtx); 421 ++xfer_ctx->waiters; 422 while (xfer_ctx->influx) 423 mtx_sleep(&xfer_ctx->waiters, &sc->sc_mtx, 0, 424 "usbhid wt", 0); 425 --xfer_ctx->waiters; 426 xfer_ctx->influx = true; 427 } 428 429 xfer_ctx->buf = buf; 430 xfer_ctx->req = *req; 431 xfer_ctx->error = ETIMEDOUT; 432 xfer_ctx->cb = &usbhid_sync_wakeup_cb; 433 xfer_ctx->cb_ctx = xfer_ctx; 434 timeout = USB_DEFAULT_TIMEOUT; 435 usbd_transfer_start(sc->sc_xfer[xfer_idx]); 436 437 if (USB_IN_POLLING_MODE_FUNC()) 438 while (timeout > 0 && xfer_ctx->error == ETIMEDOUT) { 439 usbd_transfer_poll(sc->sc_xfer + xfer_idx, 1); 440 DELAY(1000); 441 timeout--; 442 } 443 else 444 msleep_sbt(xfer_ctx, &sc->sc_mtx, 0, "usbhid io", 445 SBT_1MS * timeout, 0, C_HARDCLOCK); 446 447 /* Perform usbhid_write() asyncronously to improve pipelining */ 448 if (USB_IN_POLLING_MODE_FUNC() || xfer_ctx->error != 0 || 449 sc->sc_config[xfer_idx].type != UE_INTERRUPT || 450 sc->sc_config[xfer_idx].direction != UE_DIR_OUT) 451 usbd_transfer_stop(sc->sc_xfer[xfer_idx]); 452 error = xfer_ctx->error; 453 if (error == 0) 454 *req = xfer_ctx->req; 455 456 if (USB_IN_POLLING_MODE_FUNC()) { 457 *xfer_ctx = save; 458 } else { 459 xfer_ctx->influx = false; 460 if (xfer_ctx->waiters != 0) 461 wakeup_one(&xfer_ctx->waiters); 462 mtx_unlock(&sc->sc_mtx); 463 } 464 465 if (error) 466 DPRINTF("USB IO error:%d\n", error); 467 468 return (error); 469 } 470 471 static int 472 usbhid_get_rdesc(device_t dev, void *buf, hid_size_t len) 473 { 474 struct usbhid_softc* sc = device_get_softc(dev); 475 int error; 476 477 error = usbd_req_get_report_descriptor(sc->sc_udev, NULL, 478 buf, len, sc->sc_iface_index); 479 480 if (error) 481 DPRINTF("no report descriptor: %s\n", usbd_errstr(error)); 482 483 return (error == 0 ? 0 : ENXIO); 484 } 485 486 static int 487 usbhid_get_report(device_t dev, void *buf, hid_size_t maxlen, 488 hid_size_t *actlen, uint8_t type, uint8_t id) 489 { 490 struct usbhid_softc* sc = device_get_softc(dev); 491 union usbhid_device_request req; 492 int error; 493 494 if (maxlen > usbd_xfer_max_len(sc->sc_xfer[USBHID_CTRL_DT])) 495 return (ENOBUFS); 496 497 req.ctrl.bmRequestType = UT_READ_CLASS_INTERFACE; 498 req.ctrl.bRequest = UR_GET_REPORT; 499 USETW2(req.ctrl.wValue, type, id); 500 req.ctrl.wIndex[0] = sc->sc_iface_no; 501 req.ctrl.wIndex[1] = 0; 502 USETW(req.ctrl.wLength, maxlen); 503 504 error = usbhid_sync_xfer(sc, USBHID_CTRL_DT, &req, buf); 505 if (!error && actlen != NULL) 506 *actlen = maxlen; 507 508 return (error); 509 } 510 511 static int 512 usbhid_set_report(device_t dev, const void *buf, hid_size_t len, uint8_t type, 513 uint8_t id) 514 { 515 struct usbhid_softc* sc = device_get_softc(dev); 516 union usbhid_device_request req; 517 518 if (len > usbd_xfer_max_len(sc->sc_xfer[USBHID_CTRL_DT])) 519 return (ENOBUFS); 520 521 req.ctrl.bmRequestType = UT_WRITE_CLASS_INTERFACE; 522 req.ctrl.bRequest = UR_SET_REPORT; 523 USETW2(req.ctrl.wValue, type, id); 524 req.ctrl.wIndex[0] = sc->sc_iface_no; 525 req.ctrl.wIndex[1] = 0; 526 USETW(req.ctrl.wLength, len); 527 528 return (usbhid_sync_xfer(sc, USBHID_CTRL_DT, &req, 529 __DECONST(void *, buf))); 530 } 531 532 static int 533 usbhid_read(device_t dev, void *buf, hid_size_t maxlen, hid_size_t *actlen) 534 { 535 struct usbhid_softc* sc = device_get_softc(dev); 536 union usbhid_device_request req; 537 int error; 538 539 if (maxlen > usbd_xfer_max_len(sc->sc_xfer[USBHID_INTR_IN_DT])) 540 return (ENOBUFS); 541 542 req.intr.maxlen = maxlen; 543 error = usbhid_sync_xfer(sc, USBHID_INTR_IN_DT, &req, buf); 544 if (error == 0 && actlen != NULL) 545 *actlen = req.intr.actlen; 546 547 return (error); 548 } 549 550 static int 551 usbhid_write(device_t dev, const void *buf, hid_size_t len) 552 { 553 struct usbhid_softc* sc = device_get_softc(dev); 554 union usbhid_device_request req; 555 556 if (len > usbd_xfer_max_len(sc->sc_xfer[USBHID_INTR_OUT_DT])) 557 return (ENOBUFS); 558 559 req.intr.maxlen = len; 560 return (usbhid_sync_xfer(sc, USBHID_INTR_OUT_DT, &req, 561 __DECONST(void *, buf))); 562 } 563 564 static int 565 usbhid_set_idle(device_t dev, uint16_t duration, uint8_t id) 566 { 567 struct usbhid_softc* sc = device_get_softc(dev); 568 union usbhid_device_request req; 569 570 /* Duration is measured in 4 milliseconds per unit. */ 571 req.ctrl.bmRequestType = UT_WRITE_CLASS_INTERFACE; 572 req.ctrl.bRequest = UR_SET_IDLE; 573 USETW2(req.ctrl.wValue, (duration + 3) / 4, id); 574 req.ctrl.wIndex[0] = sc->sc_iface_no; 575 req.ctrl.wIndex[1] = 0; 576 USETW(req.ctrl.wLength, 0); 577 578 return (usbhid_sync_xfer(sc, USBHID_CTRL_DT, &req, NULL)); 579 } 580 581 static int 582 usbhid_set_protocol(device_t dev, uint16_t protocol) 583 { 584 struct usbhid_softc* sc = device_get_softc(dev); 585 union usbhid_device_request req; 586 587 req.ctrl.bmRequestType = UT_WRITE_CLASS_INTERFACE; 588 req.ctrl.bRequest = UR_SET_PROTOCOL; 589 USETW(req.ctrl.wValue, protocol); 590 req.ctrl.wIndex[0] = sc->sc_iface_no; 591 req.ctrl.wIndex[1] = 0; 592 USETW(req.ctrl.wLength, 0); 593 594 return (usbhid_sync_xfer(sc, USBHID_CTRL_DT, &req, NULL)); 595 } 596 597 static void 598 usbhid_init_device_info(struct usb_attach_arg *uaa, struct hid_device_info *hw) 599 { 600 601 hw->idBus = BUS_USB; 602 hw->idVendor = uaa->info.idVendor; 603 hw->idProduct = uaa->info.idProduct; 604 hw->idVersion = uaa->info.bcdDevice; 605 606 /* Set various quirks based on usb_attach_arg */ 607 hid_add_dynamic_quirk(hw, USB_GET_DRIVER_INFO(uaa)); 608 } 609 610 static void 611 usbhid_fill_device_info(struct usb_attach_arg *uaa, struct hid_device_info *hw) 612 { 613 struct usb_device *udev = uaa->device; 614 struct usb_interface *iface = uaa->iface; 615 struct usb_hid_descriptor *hid; 616 struct usb_endpoint *ep; 617 618 snprintf(hw->name, sizeof(hw->name), "%s %s", 619 usb_get_manufacturer(udev), usb_get_product(udev)); 620 strlcpy(hw->serial, usb_get_serial(udev), sizeof(hw->serial)); 621 622 if (uaa->info.bInterfaceClass == UICLASS_HID && 623 iface != NULL && iface->idesc != NULL) { 624 hid = hid_get_descriptor_from_usb( 625 usbd_get_config_descriptor(udev), iface->idesc); 626 if (hid != NULL) 627 hw->rdescsize = 628 UGETW(hid->descrs[0].wDescriptorLength); 629 } 630 631 /* See if there is a interrupt out endpoint. */ 632 ep = usbd_get_endpoint(udev, uaa->info.bIfaceIndex, 633 usbhid_config + USBHID_INTR_OUT_DT); 634 if (ep == NULL || ep->methods == NULL) 635 hid_add_dynamic_quirk(hw, HQ_NOWRITE); 636 } 637 638 static const STRUCT_USB_HOST_ID usbhid_devs[] = { 639 /* the Xbox 360 gamepad doesn't use the HID class */ 640 {USB_IFACE_CLASS(UICLASS_VENDOR), 641 USB_IFACE_SUBCLASS(UISUBCLASS_XBOX360_CONTROLLER), 642 USB_IFACE_PROTOCOL(UIPROTO_XBOX360_GAMEPAD), 643 USB_DRIVER_INFO(HQ_IS_XBOX360GP)}, 644 /* HID keyboard with boot protocol support */ 645 {USB_IFACE_CLASS(UICLASS_HID), 646 USB_IFACE_SUBCLASS(UISUBCLASS_BOOT), 647 USB_IFACE_PROTOCOL(UIPROTO_BOOT_KEYBOARD), 648 USB_DRIVER_INFO(HQ_HAS_KBD_BOOTPROTO)}, 649 /* HID mouse with boot protocol support */ 650 {USB_IFACE_CLASS(UICLASS_HID), 651 USB_IFACE_SUBCLASS(UISUBCLASS_BOOT), 652 USB_IFACE_PROTOCOL(UIPROTO_MOUSE), 653 USB_DRIVER_INFO(HQ_HAS_MS_BOOTPROTO)}, 654 /* generic HID class */ 655 {USB_IFACE_CLASS(UICLASS_HID), USB_DRIVER_INFO(HQ_NONE)}, 656 }; 657 658 static int 659 usbhid_probe(device_t dev) 660 { 661 struct usb_attach_arg *uaa = device_get_ivars(dev); 662 struct usbhid_softc *sc = device_get_softc(dev); 663 int error; 664 665 DPRINTFN(11, "\n"); 666 667 if (uaa->usb_mode != USB_MODE_HOST) 668 return (ENXIO); 669 670 error = usbd_lookup_id_by_uaa(usbhid_devs, sizeof(usbhid_devs), uaa); 671 if (error) 672 return (error); 673 674 if (usb_test_quirk(uaa, UQ_HID_IGNORE)) 675 return (ENXIO); 676 677 /* 678 * Setup temporary hid_device_info so that we can figure out some 679 * basic quirks for this device. 680 */ 681 usbhid_init_device_info(uaa, &sc->sc_hw); 682 683 if (hid_test_quirk(&sc->sc_hw, HQ_HID_IGNORE)) 684 return (ENXIO); 685 686 #ifdef USBHID_ENABLED 687 return (BUS_PROBE_GENERIC + 1); 688 #else 689 return (BUS_PROBE_GENERIC - 1); 690 #endif 691 } 692 693 static int 694 usbhid_attach(device_t dev) 695 { 696 struct usb_attach_arg *uaa = device_get_ivars(dev); 697 struct usbhid_softc *sc = device_get_softc(dev); 698 device_t child; 699 int error = 0; 700 701 DPRINTFN(10, "sc=%p\n", sc); 702 703 device_set_usb_desc(dev); 704 705 sc->sc_udev = uaa->device; 706 sc->sc_iface_no = uaa->info.bIfaceNum; 707 sc->sc_iface_index = uaa->info.bIfaceIndex; 708 709 usbhid_fill_device_info(uaa, &sc->sc_hw); 710 711 error = usbd_req_set_idle(uaa->device, NULL, 712 uaa->info.bIfaceIndex, 0, 0); 713 if (error) 714 DPRINTF("set idle failed, error=%s (ignored)\n", 715 usbd_errstr(error)); 716 717 mtx_init(&sc->sc_mtx, "usbhid lock", NULL, MTX_DEF); 718 719 child = device_add_child(dev, "hidbus", -1); 720 if (child == NULL) { 721 device_printf(dev, "Could not add hidbus device\n"); 722 usbhid_detach(dev); 723 return (ENOMEM); 724 } 725 726 device_set_ivars(child, &sc->sc_hw); 727 error = bus_generic_attach(dev); 728 if (error) { 729 device_printf(dev, "failed to attach child: %d\n", error); 730 usbhid_detach(dev); 731 return (error); 732 } 733 734 return (0); /* success */ 735 } 736 737 static int 738 usbhid_detach(device_t dev) 739 { 740 struct usbhid_softc *sc = device_get_softc(dev); 741 742 device_delete_children(dev); 743 mtx_destroy(&sc->sc_mtx); 744 745 return (0); 746 } 747 748 static devclass_t usbhid_devclass; 749 750 static device_method_t usbhid_methods[] = { 751 DEVMETHOD(device_probe, usbhid_probe), 752 DEVMETHOD(device_attach, usbhid_attach), 753 DEVMETHOD(device_detach, usbhid_detach), 754 755 DEVMETHOD(hid_intr_setup, usbhid_intr_setup), 756 DEVMETHOD(hid_intr_unsetup, usbhid_intr_unsetup), 757 DEVMETHOD(hid_intr_start, usbhid_intr_start), 758 DEVMETHOD(hid_intr_stop, usbhid_intr_stop), 759 DEVMETHOD(hid_intr_poll, usbhid_intr_poll), 760 761 /* HID interface */ 762 DEVMETHOD(hid_get_rdesc, usbhid_get_rdesc), 763 DEVMETHOD(hid_read, usbhid_read), 764 DEVMETHOD(hid_write, usbhid_write), 765 DEVMETHOD(hid_get_report, usbhid_get_report), 766 DEVMETHOD(hid_set_report, usbhid_set_report), 767 DEVMETHOD(hid_set_idle, usbhid_set_idle), 768 DEVMETHOD(hid_set_protocol, usbhid_set_protocol), 769 770 DEVMETHOD_END 771 }; 772 773 static driver_t usbhid_driver = { 774 .name = "usbhid", 775 .methods = usbhid_methods, 776 .size = sizeof(struct usbhid_softc), 777 }; 778 779 DRIVER_MODULE(usbhid, uhub, usbhid_driver, usbhid_devclass, NULL, 0); 780 MODULE_DEPEND(usbhid, usb, 1, 1, 1); 781 MODULE_DEPEND(usbhid, hid, 1, 1, 1); 782 MODULE_DEPEND(usbhid, hidbus, 1, 1, 1); 783 MODULE_VERSION(usbhid, 1); 784 #ifdef USBHID_ENABLED 785 USB_PNP_HOST_INFO(usbhid_devs); 786 #endif 787