1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 1998 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * Copyright (c) 2020, 2025 Vladimir Kondratyev <wulf@FreeBSD.org> 7 * 8 * This code is derived from software contributed to The NetBSD Foundation 9 * by Lennart Augustsson (lennart@augustsson.net) at 10 * Carlstedt Research & Technology. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 * POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 /* 35 * HID spec: http://www.usb.org/developers/devclass_docs/HID1_11.pdf 36 */ 37 38 #include <sys/cdefs.h> 39 #include "opt_hid.h" 40 41 #include <sys/param.h> 42 #ifdef COMPAT_FREEBSD32 43 #include <sys/abi_compat.h> 44 #endif 45 #include <sys/bus.h> 46 #include <sys/conf.h> 47 #include <sys/fcntl.h> 48 #include <sys/filio.h> 49 #include <sys/ioccom.h> 50 #include <sys/kernel.h> 51 #include <sys/lock.h> 52 #include <sys/malloc.h> 53 #include <sys/module.h> 54 #include <sys/mutex.h> 55 #include <sys/poll.h> 56 #include <sys/priv.h> 57 #include <sys/proc.h> 58 #include <sys/selinfo.h> 59 #include <sys/sysctl.h> 60 #include <sys/systm.h> 61 #include <sys/tty.h> 62 #include <sys/uio.h> 63 64 #define HID_DEBUG_VAR hidraw_debug 65 #include <dev/hid/hid.h> 66 #include <dev/hid/hidbus.h> 67 #include <dev/hid/hidraw.h> 68 69 #ifdef HID_DEBUG 70 static int hidraw_debug = 0; 71 static SYSCTL_NODE(_hw_hid, OID_AUTO, hidraw, CTLFLAG_RW, 0, 72 "HID raw interface"); 73 SYSCTL_INT(_hw_hid_hidraw, OID_AUTO, debug, CTLFLAG_RWTUN, 74 &hidraw_debug, 0, "Debug level"); 75 #endif 76 77 #define HIDRAW_INDEX 0xFF /* Arbitrary high value */ 78 79 #define HIDRAW_LOCAL_BUFSIZE 64 /* Size of on-stack buffer. */ 80 #define HIDRAW_LOCAL_ALLOC(local_buf, size) \ 81 (sizeof(local_buf) > (size) ? (local_buf) : \ 82 malloc((size), M_DEVBUF, M_ZERO | M_WAITOK)) 83 #define HIDRAW_LOCAL_FREE(local_buf, buf) \ 84 if ((local_buf) != (buf)) { \ 85 free((buf), M_DEVBUF); \ 86 } 87 88 #ifdef HIDRAW_MAKE_UHID_ALIAS 89 #define HIDRAW_NAME "uhid" 90 #else 91 #define HIDRAW_NAME "hidraw" 92 #endif 93 94 struct hidraw_softc { 95 device_t sc_dev; /* base device */ 96 97 struct mtx sc_mtx; /* hidbus private mutex */ 98 99 struct hid_rdesc_info *sc_rdesc; 100 const struct hid_device_info *sc_hw; 101 102 uint8_t *sc_q; 103 hid_size_t *sc_qlen; 104 int sc_head; 105 int sc_tail; 106 int sc_sleepcnt; 107 108 struct selinfo sc_rsel; 109 struct proc *sc_async; /* process that wants SIGIO */ 110 struct { /* driver state */ 111 bool open:1; /* device is open */ 112 bool aslp:1; /* waiting for device data in read() */ 113 bool sel:1; /* waiting for device data in poll() */ 114 bool quiet:1; /* Ignore input data */ 115 bool immed:1; /* return read data immediately */ 116 bool uhid:1; /* driver switched in to uhid mode */ 117 bool lock:1; /* input queue sleepable lock */ 118 bool flush:1; /* do not wait for data in read() */ 119 } sc_state; 120 int sc_fflags; /* access mode for open lifetime */ 121 122 struct cdev *dev; 123 }; 124 125 #ifdef COMPAT_FREEBSD32 126 struct hidraw_gen_descriptor32 { 127 uint32_t hgd_data; /* void * */ 128 uint16_t hgd_lang_id; 129 uint16_t hgd_maxlen; 130 uint16_t hgd_actlen; 131 uint16_t hgd_offset; 132 uint8_t hgd_config_index; 133 uint8_t hgd_string_index; 134 uint8_t hgd_iface_index; 135 uint8_t hgd_altif_index; 136 uint8_t hgd_endpt_index; 137 uint8_t hgd_report_type; 138 uint8_t reserved[8]; 139 }; 140 #define HIDRAW_GET_REPORT_DESC32 \ 141 _IOC_NEWTYPE(HIDRAW_GET_REPORT_DESC, struct hidraw_gen_descriptor32) 142 #define HIDRAW_GET_REPORT32 \ 143 _IOC_NEWTYPE(HIDRAW_GET_REPORT, struct hidraw_gen_descriptor32) 144 #define HIDRAW_SET_REPORT_DESC32 \ 145 _IOC_NEWTYPE(HIDRAW_SET_REPORT_DESC, struct hidraw_gen_descriptor32) 146 #define HIDRAW_SET_REPORT32 \ 147 _IOC_NEWTYPE(HIDRAW_SET_REPORT, struct hidraw_gen_descriptor32) 148 #endif 149 150 static d_open_t hidraw_open; 151 static d_read_t hidraw_read; 152 static d_write_t hidraw_write; 153 static d_ioctl_t hidraw_ioctl; 154 static d_poll_t hidraw_poll; 155 static d_kqfilter_t hidraw_kqfilter; 156 157 static d_priv_dtor_t hidraw_dtor; 158 159 static struct cdevsw hidraw_cdevsw = { 160 .d_version = D_VERSION, 161 .d_open = hidraw_open, 162 .d_read = hidraw_read, 163 .d_write = hidraw_write, 164 .d_ioctl = hidraw_ioctl, 165 .d_poll = hidraw_poll, 166 .d_kqfilter = hidraw_kqfilter, 167 .d_name = "hidraw", 168 }; 169 170 static hid_intr_t hidraw_intr; 171 172 static device_identify_t hidraw_identify; 173 static device_probe_t hidraw_probe; 174 static device_attach_t hidraw_attach; 175 static device_detach_t hidraw_detach; 176 177 static int hidraw_kqread(struct knote *, long); 178 static void hidraw_kqdetach(struct knote *); 179 static void hidraw_notify(struct hidraw_softc *); 180 181 static const struct filterops hidraw_filterops_read = { 182 .f_isfd = 1, 183 .f_detach = hidraw_kqdetach, 184 .f_event = hidraw_kqread, 185 .f_copy = knote_triv_copy, 186 }; 187 188 static void 189 hidraw_identify(driver_t *driver, device_t parent) 190 { 191 device_t child; 192 193 if (device_find_child(parent, HIDRAW_NAME, DEVICE_UNIT_ANY) == NULL) { 194 child = BUS_ADD_CHILD(parent, 0, HIDRAW_NAME, 195 device_get_unit(parent)); 196 if (child != NULL) 197 hidbus_set_index(child, HIDRAW_INDEX); 198 } 199 } 200 201 static int 202 hidraw_probe(device_t self) 203 { 204 205 if (hidbus_get_index(self) != HIDRAW_INDEX) 206 return (ENXIO); 207 208 hidbus_set_desc(self, "Raw HID Device"); 209 210 return (BUS_PROBE_GENERIC); 211 } 212 213 static int 214 hidraw_attach(device_t self) 215 { 216 struct hidraw_softc *sc = device_get_softc(self); 217 struct make_dev_args mda; 218 int error; 219 220 sc->sc_dev = self; 221 sc->sc_rdesc = hidbus_get_rdesc_info(self); 222 sc->sc_hw = hid_get_device_info(self); 223 224 /* Hidraw mode does not require report descriptor to work */ 225 if (sc->sc_rdesc->data == NULL || sc->sc_rdesc->len == 0) 226 device_printf(self, "no report descriptor\n"); 227 228 mtx_init(&sc->sc_mtx, "hidraw lock", NULL, MTX_DEF); 229 knlist_init_mtx(&sc->sc_rsel.si_note, &sc->sc_mtx); 230 231 make_dev_args_init(&mda); 232 mda.mda_flags = MAKEDEV_WAITOK; 233 mda.mda_devsw = &hidraw_cdevsw; 234 mda.mda_uid = UID_ROOT; 235 mda.mda_gid = GID_OPERATOR; 236 mda.mda_mode = 0600; 237 mda.mda_si_drv1 = sc; 238 239 error = make_dev_s(&mda, &sc->dev, "hidraw%d", device_get_unit(self)); 240 if (error) { 241 device_printf(self, "Can not create character device\n"); 242 hidraw_detach(self); 243 return (error); 244 } 245 #ifdef HIDRAW_MAKE_UHID_ALIAS 246 (void)make_dev_alias(sc->dev, "uhid%d", device_get_unit(self)); 247 #endif 248 249 hidbus_set_lock(self, &sc->sc_mtx); 250 hidbus_set_intr(self, hidraw_intr, sc); 251 252 return (0); 253 } 254 255 static int 256 hidraw_detach(device_t self) 257 { 258 struct hidraw_softc *sc = device_get_softc(self); 259 260 DPRINTF("sc=%p\n", sc); 261 262 if (sc->dev != NULL) { 263 mtx_lock(&sc->sc_mtx); 264 sc->dev->si_drv1 = NULL; 265 /* Wake everyone */ 266 hidraw_notify(sc); 267 mtx_unlock(&sc->sc_mtx); 268 destroy_dev(sc->dev); 269 } 270 271 knlist_clear(&sc->sc_rsel.si_note, 0); 272 knlist_destroy(&sc->sc_rsel.si_note); 273 seldrain(&sc->sc_rsel); 274 mtx_destroy(&sc->sc_mtx); 275 276 return (0); 277 } 278 279 void 280 hidraw_intr(void *context, void *buf, hid_size_t len) 281 { 282 struct hidraw_softc *sc = context; 283 int next; 284 285 DPRINTFN(5, "len=%d\n", len); 286 DPRINTFN(5, "data = %*D\n", len, buf, " "); 287 288 next = (sc->sc_tail + 1) % HIDRAW_BUFFER_SIZE; 289 if (sc->sc_state.quiet || next == sc->sc_head) 290 return; 291 292 bcopy(buf, sc->sc_q + sc->sc_tail * sc->sc_rdesc->rdsize, len); 293 294 /* Make sure we don't process old data */ 295 if (len < sc->sc_rdesc->rdsize) 296 bzero(sc->sc_q + sc->sc_tail * sc->sc_rdesc->rdsize + len, 297 sc->sc_rdesc->isize - len); 298 299 sc->sc_qlen[sc->sc_tail] = len; 300 sc->sc_tail = next; 301 302 hidraw_notify(sc); 303 } 304 305 static inline int 306 hidraw_lock_queue(struct hidraw_softc *sc, bool flush) 307 { 308 int error = 0; 309 310 mtx_assert(&sc->sc_mtx, MA_OWNED); 311 312 if (flush) 313 sc->sc_state.flush = true; 314 ++sc->sc_sleepcnt; 315 while (sc->sc_state.lock && error == 0) { 316 /* Flush is requested. Wakeup all readers and forbid sleeps */ 317 if (flush && sc->sc_state.aslp) { 318 sc->sc_state.aslp = false; 319 DPRINTFN(5, "waking %p\n", &sc->sc_q); 320 wakeup(&sc->sc_q); 321 } 322 error = mtx_sleep(&sc->sc_sleepcnt, &sc->sc_mtx, 323 PZERO | PCATCH, "hidrawio", 0); 324 } 325 --sc->sc_sleepcnt; 326 if (flush) 327 sc->sc_state.flush = false; 328 if (error == 0) 329 sc->sc_state.lock = true; 330 331 return (error); 332 } 333 334 static inline void 335 hidraw_unlock_queue(struct hidraw_softc *sc) 336 { 337 338 mtx_assert(&sc->sc_mtx, MA_OWNED); 339 KASSERT(sc->sc_state.lock, ("input buffer is not locked")); 340 341 if (sc->sc_sleepcnt != 0) 342 wakeup_one(&sc->sc_sleepcnt); 343 sc->sc_state.lock = false; 344 } 345 346 static int 347 hidraw_open(struct cdev *dev, int flag, int mode, struct thread *td) 348 { 349 struct hidraw_softc *sc; 350 int error; 351 352 sc = dev->si_drv1; 353 if (sc == NULL) 354 return (ENXIO); 355 356 DPRINTF("sc=%p\n", sc); 357 358 mtx_lock(&sc->sc_mtx); 359 if (sc->sc_state.open) { 360 mtx_unlock(&sc->sc_mtx); 361 return (EBUSY); 362 } 363 sc->sc_state.open = true; 364 mtx_unlock(&sc->sc_mtx); 365 366 error = devfs_set_cdevpriv(sc, hidraw_dtor); 367 if (error != 0) { 368 mtx_lock(&sc->sc_mtx); 369 sc->sc_state.open = false; 370 mtx_unlock(&sc->sc_mtx); 371 return (error); 372 } 373 374 sc->sc_q = malloc(sc->sc_rdesc->rdsize * HIDRAW_BUFFER_SIZE, M_DEVBUF, 375 M_ZERO | M_WAITOK); 376 sc->sc_qlen = malloc(sizeof(hid_size_t) * HIDRAW_BUFFER_SIZE, M_DEVBUF, 377 M_ZERO | M_WAITOK); 378 379 /* Set up interrupt pipe. */ 380 sc->sc_state.immed = false; 381 sc->sc_async = 0; 382 sc->sc_state.uhid = false; /* hidraw mode is default */ 383 sc->sc_state.quiet = false; 384 sc->sc_head = sc->sc_tail = 0; 385 sc->sc_fflags = flag; 386 387 hid_intr_start(sc->sc_dev); 388 389 return (0); 390 } 391 392 static void 393 hidraw_dtor(void *data) 394 { 395 struct hidraw_softc *sc = data; 396 397 DPRINTF("sc=%p\n", sc); 398 399 /* Disable interrupts. */ 400 hid_intr_stop(sc->sc_dev); 401 402 sc->sc_tail = sc->sc_head = 0; 403 sc->sc_async = 0; 404 free(sc->sc_q, M_DEVBUF); 405 free(sc->sc_qlen, M_DEVBUF); 406 sc->sc_q = NULL; 407 408 mtx_lock(&sc->sc_mtx); 409 sc->sc_state.open = false; 410 mtx_unlock(&sc->sc_mtx); 411 } 412 413 static int 414 hidraw_read(struct cdev *dev, struct uio *uio, int flag) 415 { 416 struct hidraw_softc *sc; 417 size_t length; 418 int error; 419 420 DPRINTFN(1, "\n"); 421 422 sc = dev->si_drv1; 423 if (sc == NULL) 424 return (EIO); 425 426 mtx_lock(&sc->sc_mtx); 427 error = dev->si_drv1 == NULL ? EIO : hidraw_lock_queue(sc, false); 428 if (error != 0) { 429 mtx_unlock(&sc->sc_mtx); 430 return (error); 431 } 432 433 if (sc->sc_state.immed) { 434 mtx_unlock(&sc->sc_mtx); 435 DPRINTFN(1, "immed\n"); 436 437 error = hid_get_report(sc->sc_dev, sc->sc_q, 438 sc->sc_rdesc->isize, NULL, HID_INPUT_REPORT, 439 sc->sc_rdesc->iid); 440 if (error == 0) 441 error = uiomove(sc->sc_q, sc->sc_rdesc->isize, uio); 442 mtx_lock(&sc->sc_mtx); 443 goto exit; 444 } 445 446 while (sc->sc_tail == sc->sc_head && !sc->sc_state.flush) { 447 if (flag & O_NONBLOCK) { 448 error = EWOULDBLOCK; 449 goto exit; 450 } 451 sc->sc_state.aslp = true; 452 DPRINTFN(5, "sleep on %p\n", &sc->sc_q); 453 error = mtx_sleep(&sc->sc_q, &sc->sc_mtx, PZERO | PCATCH, 454 "hidrawrd", 0); 455 DPRINTFN(5, "woke, error=%d\n", error); 456 if (dev->si_drv1 == NULL) 457 error = EIO; 458 if (error) { 459 sc->sc_state.aslp = false; 460 goto exit; 461 } 462 } 463 464 while (sc->sc_tail != sc->sc_head && uio->uio_resid > 0) { 465 length = min(uio->uio_resid, sc->sc_state.uhid ? 466 sc->sc_rdesc->isize : sc->sc_qlen[sc->sc_head]); 467 mtx_unlock(&sc->sc_mtx); 468 469 /* Copy the data to the user process. */ 470 DPRINTFN(5, "got %lu chars\n", (u_long)length); 471 error = uiomove(sc->sc_q + sc->sc_head * sc->sc_rdesc->rdsize, 472 length, uio); 473 474 mtx_lock(&sc->sc_mtx); 475 if (error != 0) 476 goto exit; 477 /* Remove a small chunk from the input queue. */ 478 sc->sc_head = (sc->sc_head + 1) % HIDRAW_BUFFER_SIZE; 479 /* 480 * In uhid mode transfer as many chunks as possible. Hidraw 481 * packets are transferred one by one due to different length. 482 */ 483 if (!sc->sc_state.uhid) 484 goto exit; 485 } 486 exit: 487 hidraw_unlock_queue(sc); 488 mtx_unlock(&sc->sc_mtx); 489 490 return (error); 491 } 492 493 static int 494 hidraw_write(struct cdev *dev, struct uio *uio, int flag) 495 { 496 uint8_t local_buf[HIDRAW_LOCAL_BUFSIZE], *buf; 497 struct hidraw_softc *sc; 498 int error; 499 int size; 500 size_t buf_offset; 501 uint8_t id = 0; 502 503 DPRINTFN(1, "\n"); 504 505 sc = dev->si_drv1; 506 if (sc == NULL) 507 return (EIO); 508 509 if (sc->sc_rdesc->osize == 0) 510 return (EOPNOTSUPP); 511 512 buf_offset = 0; 513 if (sc->sc_state.uhid) { 514 size = sc->sc_rdesc->osize; 515 if (uio->uio_resid != size) 516 return (EINVAL); 517 } else { 518 size = uio->uio_resid; 519 if (size < 2) 520 return (EINVAL); 521 /* Strip leading 0 if the device doesnt use numbered reports */ 522 error = uiomove(&id, 1, uio); 523 if (error) 524 return (error); 525 if (id != 0) 526 buf_offset++; 527 else 528 size--; 529 /* Check if underlying driver could process this request */ 530 if (size > sc->sc_rdesc->wrsize) 531 return (ENOBUFS); 532 } 533 buf = HIDRAW_LOCAL_ALLOC(local_buf, size); 534 buf[0] = id; 535 error = uiomove(buf + buf_offset, uio->uio_resid, uio); 536 if (error == 0) 537 error = hid_write(sc->sc_dev, buf, size); 538 HIDRAW_LOCAL_FREE(local_buf, buf); 539 540 return (error); 541 } 542 543 #ifdef COMPAT_FREEBSD32 544 static void 545 update_hgd32(const struct hidraw_gen_descriptor *hgd, 546 struct hidraw_gen_descriptor32 *hgd32) 547 { 548 /* Don't update hgd_data pointer */ 549 CP(*hgd, *hgd32, hgd_lang_id); 550 CP(*hgd, *hgd32, hgd_maxlen); 551 CP(*hgd, *hgd32, hgd_actlen); 552 CP(*hgd, *hgd32, hgd_offset); 553 CP(*hgd, *hgd32, hgd_config_index); 554 CP(*hgd, *hgd32, hgd_string_index); 555 CP(*hgd, *hgd32, hgd_iface_index); 556 CP(*hgd, *hgd32, hgd_altif_index); 557 CP(*hgd, *hgd32, hgd_endpt_index); 558 CP(*hgd, *hgd32, hgd_report_type); 559 /* Don't update reserved */ 560 } 561 #endif 562 563 static int 564 hidraw_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, 565 struct thread *td) 566 { 567 uint8_t local_buf[HIDRAW_LOCAL_BUFSIZE]; 568 #ifdef COMPAT_FREEBSD32 569 struct hidraw_gen_descriptor local_hgd; 570 struct hidraw_gen_descriptor32 *hgd32 = NULL; 571 #endif 572 void *buf; 573 struct hidraw_softc *sc; 574 struct hidraw_device_info *hdi; 575 struct hidraw_gen_descriptor *hgd; 576 struct hidraw_report_descriptor *hrd; 577 struct hidraw_devinfo *hd; 578 const char *devname; 579 uint32_t size; 580 hid_size_t actsize; 581 int id, len; 582 int error = 0; 583 uint8_t reptype; 584 585 DPRINTFN(2, "cmd=%lx\n", cmd); 586 587 sc = dev->si_drv1; 588 if (sc == NULL) 589 return (EIO); 590 591 hgd = (struct hidraw_gen_descriptor *)addr; 592 593 #ifdef COMPAT_FREEBSD32 594 switch (cmd) { 595 case HIDRAW_GET_REPORT_DESC32: 596 case HIDRAW_GET_REPORT32: 597 case HIDRAW_SET_REPORT_DESC32: 598 case HIDRAW_SET_REPORT32: 599 cmd = _IOC_NEWTYPE(cmd, struct hidraw_gen_descriptor); 600 hgd32 = (struct hidraw_gen_descriptor32 *)addr; 601 hgd = &local_hgd; 602 PTRIN_CP(*hgd32, *hgd, hgd_data); 603 CP(*hgd32, *hgd, hgd_lang_id); 604 CP(*hgd32, *hgd, hgd_maxlen); 605 CP(*hgd32, *hgd, hgd_actlen); 606 CP(*hgd32, *hgd, hgd_offset); 607 CP(*hgd32, *hgd, hgd_config_index); 608 CP(*hgd32, *hgd, hgd_string_index); 609 CP(*hgd32, *hgd, hgd_iface_index); 610 CP(*hgd32, *hgd, hgd_altif_index); 611 CP(*hgd32, *hgd, hgd_endpt_index); 612 CP(*hgd32, *hgd, hgd_report_type); 613 /* Don't copy reserved */ 614 break; 615 } 616 #endif 617 618 /* fixed-length ioctls handling */ 619 switch (cmd) { 620 case FIONBIO: 621 /* All handled in the upper FS layer. */ 622 return (0); 623 624 case FIOASYNC: 625 mtx_lock(&sc->sc_mtx); 626 if (*(int *)addr) { 627 if (sc->sc_async == NULL) { 628 sc->sc_async = td->td_proc; 629 DPRINTF("FIOASYNC %p\n", sc->sc_async); 630 } else 631 error = EBUSY; 632 } else 633 sc->sc_async = NULL; 634 mtx_unlock(&sc->sc_mtx); 635 return (error); 636 637 /* XXX this is not the most general solution. */ 638 case TIOCSPGRP: 639 mtx_lock(&sc->sc_mtx); 640 if (sc->sc_async == NULL) 641 error = EINVAL; 642 else if (*(int *)addr != sc->sc_async->p_pgid) 643 error = EPERM; 644 mtx_unlock(&sc->sc_mtx); 645 return (error); 646 647 case HIDRAW_GET_REPORT_DESC: 648 if (sc->sc_rdesc->data == NULL || sc->sc_rdesc->len == 0) 649 return (EOPNOTSUPP); 650 mtx_lock(&sc->sc_mtx); 651 sc->sc_state.uhid = true; 652 mtx_unlock(&sc->sc_mtx); 653 if (sc->sc_rdesc->len > hgd->hgd_maxlen) { 654 size = hgd->hgd_maxlen; 655 } else { 656 size = sc->sc_rdesc->len; 657 } 658 hgd->hgd_actlen = size; 659 #ifdef COMPAT_FREEBSD32 660 if (hgd32 != NULL) 661 update_hgd32(hgd, hgd32); 662 #endif 663 if (hgd->hgd_data == NULL) 664 return (0); /* descriptor length only */ 665 666 return (copyout(sc->sc_rdesc->data, hgd->hgd_data, size)); 667 668 669 case HIDRAW_SET_REPORT_DESC: 670 if (!(sc->sc_fflags & FWRITE)) 671 return (EPERM); 672 673 /* check privileges */ 674 error = priv_check(curthread, PRIV_DRIVER); 675 if (error) 676 return (error); 677 678 /* Stop interrupts and clear input report buffer */ 679 mtx_lock(&sc->sc_mtx); 680 sc->sc_tail = sc->sc_head = 0; 681 error = hidraw_lock_queue(sc, true); 682 if (error == 0) 683 sc->sc_state.quiet = true; 684 mtx_unlock(&sc->sc_mtx); 685 if (error != 0) 686 return (error); 687 688 buf = HIDRAW_LOCAL_ALLOC(local_buf, hgd->hgd_maxlen); 689 error = copyin(hgd->hgd_data, buf, hgd->hgd_maxlen); 690 if (error == 0) { 691 bus_topo_lock(); 692 error = hid_set_report_descr(sc->sc_dev, buf, 693 hgd->hgd_maxlen); 694 bus_topo_unlock(); 695 } 696 HIDRAW_LOCAL_FREE(local_buf, buf); 697 698 /* Realloc hidraw input queue */ 699 if (error == 0) 700 sc->sc_q = realloc(sc->sc_q, 701 sc->sc_rdesc->rdsize * HIDRAW_BUFFER_SIZE, 702 M_DEVBUF, M_ZERO | M_WAITOK); 703 704 /* Start interrupts again */ 705 mtx_lock(&sc->sc_mtx); 706 sc->sc_state.quiet = false; 707 hidraw_unlock_queue(sc); 708 mtx_unlock(&sc->sc_mtx); 709 return (error); 710 case HIDRAW_SET_IMMED: 711 if (!(sc->sc_fflags & FREAD)) 712 return (EPERM); 713 if (*(int *)addr) { 714 /* XXX should read into ibuf, but does it matter? */ 715 size = sc->sc_rdesc->isize; 716 buf = HIDRAW_LOCAL_ALLOC(local_buf, size); 717 error = hid_get_report(sc->sc_dev, buf, size, NULL, 718 HID_INPUT_REPORT, sc->sc_rdesc->iid); 719 HIDRAW_LOCAL_FREE(local_buf, buf); 720 if (error) 721 return (EOPNOTSUPP); 722 723 mtx_lock(&sc->sc_mtx); 724 sc->sc_state.immed = true; 725 mtx_unlock(&sc->sc_mtx); 726 } else { 727 mtx_lock(&sc->sc_mtx); 728 sc->sc_state.immed = false; 729 mtx_unlock(&sc->sc_mtx); 730 } 731 return (0); 732 733 case HIDRAW_GET_REPORT: 734 if (!(sc->sc_fflags & FREAD)) 735 return (EPERM); 736 switch (hgd->hgd_report_type) { 737 case HID_INPUT_REPORT: 738 size = sc->sc_rdesc->isize; 739 id = sc->sc_rdesc->iid; 740 break; 741 case HID_OUTPUT_REPORT: 742 size = sc->sc_rdesc->osize; 743 id = sc->sc_rdesc->oid; 744 break; 745 case HID_FEATURE_REPORT: 746 size = sc->sc_rdesc->fsize; 747 id = sc->sc_rdesc->fid; 748 break; 749 default: 750 return (EINVAL); 751 } 752 if (id != 0) { 753 error = copyin(hgd->hgd_data, &id, 1); 754 if (error != 0) 755 return (error); 756 } 757 size = MIN(hgd->hgd_maxlen, size); 758 buf = HIDRAW_LOCAL_ALLOC(local_buf, size); 759 actsize = 0; 760 error = hid_get_report(sc->sc_dev, buf, size, &actsize, 761 hgd->hgd_report_type, id); 762 if (!error) 763 error = copyout(buf, hgd->hgd_data, actsize); 764 HIDRAW_LOCAL_FREE(local_buf, buf); 765 hgd->hgd_actlen = actsize; 766 #ifdef COMPAT_FREEBSD32 767 if (hgd32 != NULL) 768 update_hgd32(hgd, hgd32); 769 #endif 770 return (error); 771 772 case HIDRAW_SET_REPORT: 773 if (!(sc->sc_fflags & FWRITE)) 774 return (EPERM); 775 switch (hgd->hgd_report_type) { 776 case HID_INPUT_REPORT: 777 size = sc->sc_rdesc->isize; 778 id = sc->sc_rdesc->iid; 779 break; 780 case HID_OUTPUT_REPORT: 781 size = sc->sc_rdesc->osize; 782 id = sc->sc_rdesc->oid; 783 break; 784 case HID_FEATURE_REPORT: 785 size = sc->sc_rdesc->fsize; 786 id = sc->sc_rdesc->fid; 787 break; 788 default: 789 return (EINVAL); 790 } 791 size = MIN(hgd->hgd_maxlen, size); 792 buf = HIDRAW_LOCAL_ALLOC(local_buf, size); 793 error = copyin(hgd->hgd_data, buf, size); 794 if (error == 0) { 795 if (id != 0) 796 id = *(uint8_t *)buf; 797 error = hid_set_report(sc->sc_dev, buf, size, 798 hgd->hgd_report_type, id); 799 } 800 HIDRAW_LOCAL_FREE(local_buf, buf); 801 return (error); 802 803 case HIDRAW_GET_REPORT_ID: 804 *(int *)addr = 0; /* XXX: we only support reportid 0? */ 805 return (0); 806 807 case HIDRAW_GET_DEVICEINFO: 808 hdi = (struct hidraw_device_info *)addr; 809 bzero(hdi, sizeof(struct hidraw_device_info)); 810 hdi->hdi_product = sc->sc_hw->idProduct; 811 hdi->hdi_vendor = sc->sc_hw->idVendor; 812 hdi->hdi_version = sc->sc_hw->idVersion; 813 hdi->hdi_bustype = sc->sc_hw->idBus; 814 strlcpy(hdi->hdi_name, sc->sc_hw->name, 815 sizeof(hdi->hdi_name)); 816 strlcpy(hdi->hdi_phys, device_get_nameunit(sc->sc_dev), 817 sizeof(hdi->hdi_phys)); 818 strlcpy(hdi->hdi_uniq, sc->sc_hw->serial, 819 sizeof(hdi->hdi_uniq)); 820 snprintf(hdi->hdi_release, sizeof(hdi->hdi_release), "%x.%02x", 821 sc->sc_hw->idVersion >> 8, sc->sc_hw->idVersion & 0xff); 822 return(0); 823 824 case HIDIOCGRDESCSIZE: 825 *(int *)addr = sc->sc_hw->rdescsize; 826 return (0); 827 828 case HIDIOCGRDESC: 829 hrd = *(struct hidraw_report_descriptor **)addr; 830 error = copyin(&hrd->size, &size, sizeof(uint32_t)); 831 if (error) 832 return (error); 833 /* 834 * HID_MAX_DESCRIPTOR_SIZE-1 is a limit of report descriptor 835 * size in current Linux implementation. 836 */ 837 if (size >= HID_MAX_DESCRIPTOR_SIZE) 838 return (EINVAL); 839 mtx_lock(&sc->sc_mtx); 840 sc->sc_state.uhid = false; 841 mtx_unlock(&sc->sc_mtx); 842 buf = HIDRAW_LOCAL_ALLOC(local_buf, size); 843 error = hid_get_rdesc(sc->sc_dev, buf, size); 844 if (error == 0) { 845 size = MIN(size, sc->sc_rdesc->len); 846 error = copyout(buf, hrd->value, size); 847 } 848 HIDRAW_LOCAL_FREE(local_buf, buf); 849 return (error); 850 851 case HIDIOCGRAWINFO: 852 hd = (struct hidraw_devinfo *)addr; 853 hd->bustype = sc->sc_hw->idBus; 854 hd->vendor = sc->sc_hw->idVendor; 855 hd->product = sc->sc_hw->idProduct; 856 return (0); 857 } 858 859 /* variable-length ioctls handling */ 860 len = IOCPARM_LEN(cmd); 861 switch (IOCBASECMD(cmd)) { 862 case HIDIOCGRAWNAME(0): 863 strlcpy(addr, sc->sc_hw->name, len); 864 td->td_retval[0] = min(strlen(sc->sc_hw->name) + 1, len); 865 return (0); 866 867 case HIDIOCGRAWPHYS(0): 868 devname = device_get_nameunit(sc->sc_dev); 869 strlcpy(addr, devname, len); 870 td->td_retval[0] = min(strlen(devname) + 1, len); 871 return (0); 872 873 case HIDIOCSFEATURE(0): 874 case HIDIOCSINPUT(0): 875 case HIDIOCSOUTPUT(0): 876 if (!(sc->sc_fflags & FWRITE)) 877 return (EPERM); 878 if (len < 2) 879 return (EINVAL); 880 id = *(uint8_t *)addr; 881 if (id == 0) { 882 addr = (uint8_t *)addr + 1; 883 len--; 884 } 885 switch (IOCBASECMD(cmd)) { 886 case HIDIOCSFEATURE(0): 887 reptype = HID_FEATURE_REPORT; 888 break; 889 case HIDIOCSINPUT(0): 890 reptype = HID_INPUT_REPORT; 891 break; 892 case HIDIOCSOUTPUT(0): 893 reptype = HID_OUTPUT_REPORT; 894 break; 895 default: 896 panic("Invalid report type"); 897 } 898 error = hid_set_report(sc->sc_dev, addr, len, reptype, id); 899 if (error == 0) 900 td->td_retval[0] = IOCPARM_LEN(cmd); 901 return (error); 902 903 case HIDIOCGFEATURE(0): 904 case HIDIOCGINPUT(0): 905 case HIDIOCGOUTPUT(0): 906 if (!(sc->sc_fflags & FREAD)) 907 return (EPERM); 908 if (len < 2) 909 return (EINVAL); 910 id = *(uint8_t *)addr; 911 if (id == 0) { 912 addr = (uint8_t *)addr + 1; 913 len--; 914 } 915 switch (IOCBASECMD(cmd)) { 916 case HIDIOCGFEATURE(0): 917 reptype = HID_FEATURE_REPORT; 918 break; 919 case HIDIOCGINPUT(0): 920 reptype = HID_INPUT_REPORT; 921 break; 922 case HIDIOCGOUTPUT(0): 923 reptype = HID_OUTPUT_REPORT; 924 break; 925 default: 926 panic("Invalid report type"); 927 } 928 error = hid_get_report(sc->sc_dev, addr, len, &actsize, 929 reptype, id); 930 if (error == 0) { 931 if (id == 0) 932 actsize++; 933 td->td_retval[0] = actsize; 934 } 935 return (error); 936 937 case HIDIOCGRAWUNIQ(0): 938 strlcpy(addr, sc->sc_hw->serial, len); 939 td->td_retval[0] = min(strlen(sc->sc_hw->serial) + 1, len); 940 return (0); 941 } 942 943 return (EINVAL); 944 } 945 946 static int 947 hidraw_poll(struct cdev *dev, int events, struct thread *td) 948 { 949 struct hidraw_softc *sc; 950 int revents = 0; 951 952 sc = dev->si_drv1; 953 if (sc == NULL) 954 return (POLLHUP); 955 956 if (events & (POLLOUT | POLLWRNORM) && (sc->sc_fflags & FWRITE)) 957 revents |= events & (POLLOUT | POLLWRNORM); 958 if (events & (POLLIN | POLLRDNORM) && (sc->sc_fflags & FREAD)) { 959 mtx_lock(&sc->sc_mtx); 960 if (sc->sc_head != sc->sc_tail) 961 revents |= events & (POLLIN | POLLRDNORM); 962 else { 963 sc->sc_state.sel = true; 964 selrecord(td, &sc->sc_rsel); 965 } 966 mtx_unlock(&sc->sc_mtx); 967 } 968 969 return (revents); 970 } 971 972 static int 973 hidraw_kqfilter(struct cdev *dev, struct knote *kn) 974 { 975 struct hidraw_softc *sc; 976 977 sc = dev->si_drv1; 978 if (sc == NULL) 979 return (ENXIO); 980 981 switch(kn->kn_filter) { 982 case EVFILT_READ: 983 if (sc->sc_fflags & FREAD) { 984 kn->kn_fop = &hidraw_filterops_read; 985 break; 986 } 987 /* FALLTHROUGH */ 988 default: 989 return(EINVAL); 990 } 991 kn->kn_hook = sc; 992 993 knlist_add(&sc->sc_rsel.si_note, kn, 0); 994 return (0); 995 } 996 997 static int 998 hidraw_kqread(struct knote *kn, long hint) 999 { 1000 struct hidraw_softc *sc; 1001 int ret; 1002 1003 sc = kn->kn_hook; 1004 1005 mtx_assert(&sc->sc_mtx, MA_OWNED); 1006 1007 if (sc->dev->si_drv1 == NULL) { 1008 kn->kn_flags |= EV_EOF; 1009 ret = 1; 1010 } else 1011 ret = (sc->sc_head != sc->sc_tail) ? 1 : 0; 1012 1013 return (ret); 1014 } 1015 1016 static void 1017 hidraw_kqdetach(struct knote *kn) 1018 { 1019 struct hidraw_softc *sc; 1020 1021 sc = kn->kn_hook; 1022 knlist_remove(&sc->sc_rsel.si_note, kn, 0); 1023 } 1024 1025 static void 1026 hidraw_notify(struct hidraw_softc *sc) 1027 { 1028 1029 mtx_assert(&sc->sc_mtx, MA_OWNED); 1030 1031 if (sc->sc_state.aslp) { 1032 sc->sc_state.aslp = false; 1033 DPRINTFN(5, "waking %p\n", &sc->sc_q); 1034 wakeup(&sc->sc_q); 1035 } 1036 if (sc->sc_state.sel) { 1037 sc->sc_state.sel = false; 1038 selwakeuppri(&sc->sc_rsel, PZERO); 1039 } 1040 if (sc->sc_async != NULL) { 1041 DPRINTFN(3, "sending SIGIO %p\n", sc->sc_async); 1042 PROC_LOCK(sc->sc_async); 1043 kern_psignal(sc->sc_async, SIGIO); 1044 PROC_UNLOCK(sc->sc_async); 1045 } 1046 KNOTE_LOCKED(&sc->sc_rsel.si_note, 0); 1047 } 1048 1049 static device_method_t hidraw_methods[] = { 1050 /* Device interface */ 1051 DEVMETHOD(device_identify, hidraw_identify), 1052 DEVMETHOD(device_probe, hidraw_probe), 1053 DEVMETHOD(device_attach, hidraw_attach), 1054 DEVMETHOD(device_detach, hidraw_detach), 1055 1056 DEVMETHOD_END 1057 }; 1058 1059 static driver_t hidraw_driver = { 1060 HIDRAW_NAME, 1061 hidraw_methods, 1062 sizeof(struct hidraw_softc) 1063 }; 1064 1065 DRIVER_MODULE(hidraw, hidbus, hidraw_driver, NULL, NULL); 1066 MODULE_DEPEND(hidraw, hidbus, 1, 1, 1); 1067 MODULE_DEPEND(hidraw, hid, 1, 1, 1); 1068 MODULE_VERSION(hidraw, 1); 1069