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