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