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