xref: /freebsd/sys/dev/hid/hidraw.c (revision 8ddb146abcdf061be9f2c0db7e391697dafad85c)
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 #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 		/* Lock newbus around set_report_descr call */
683 		mtx_lock(&Giant);
684 		error = hid_set_report_descr(sc->sc_dev, buf, hgd->hgd_maxlen);
685 		mtx_unlock(&Giant);
686 		HIDRAW_LOCAL_FREE(local_buf, buf);
687 
688 		/* Realloc hidraw input queue */
689 		if (error == 0)
690 			sc->sc_q = realloc(sc->sc_q,
691 			    sc->sc_rdesc->rdsize * HIDRAW_BUFFER_SIZE,
692 			    M_DEVBUF, M_ZERO | M_WAITOK);
693 
694 		/* Start interrupts again */
695 		mtx_lock(&sc->sc_mtx);
696 		sc->sc_state.quiet = false;
697 		hidraw_unlock_queue(sc);
698 		mtx_unlock(&sc->sc_mtx);
699 		return (error);
700 	case HIDRAW_SET_IMMED:
701 		if (!(sc->sc_fflags & FREAD))
702 			return (EPERM);
703 		if (*(int *)addr) {
704 			/* XXX should read into ibuf, but does it matter? */
705 			size = sc->sc_rdesc->isize;
706 			buf = HIDRAW_LOCAL_ALLOC(local_buf, size);
707 			error = hid_get_report(sc->sc_dev, buf, size, NULL,
708 			    HID_INPUT_REPORT, sc->sc_rdesc->iid);
709 			HIDRAW_LOCAL_FREE(local_buf, buf);
710 			if (error)
711 				return (EOPNOTSUPP);
712 
713 			mtx_lock(&sc->sc_mtx);
714 			sc->sc_state.immed = true;
715 			mtx_unlock(&sc->sc_mtx);
716 		} else {
717 			mtx_lock(&sc->sc_mtx);
718 			sc->sc_state.immed = false;
719 			mtx_unlock(&sc->sc_mtx);
720 		}
721 		return (0);
722 
723 	case HIDRAW_GET_REPORT:
724 		if (!(sc->sc_fflags & FREAD))
725 			return (EPERM);
726 		switch (hgd->hgd_report_type) {
727 		case HID_INPUT_REPORT:
728 			size = sc->sc_rdesc->isize;
729 			id = sc->sc_rdesc->iid;
730 			break;
731 		case HID_OUTPUT_REPORT:
732 			size = sc->sc_rdesc->osize;
733 			id = sc->sc_rdesc->oid;
734 			break;
735 		case HID_FEATURE_REPORT:
736 			size = sc->sc_rdesc->fsize;
737 			id = sc->sc_rdesc->fid;
738 			break;
739 		default:
740 			return (EINVAL);
741 		}
742 		if (id != 0)
743 			copyin(hgd->hgd_data, &id, 1);
744 		size = MIN(hgd->hgd_maxlen, size);
745 		buf = HIDRAW_LOCAL_ALLOC(local_buf, size);
746 		error = hid_get_report(sc->sc_dev, buf, size, NULL,
747 		    hgd->hgd_report_type, id);
748 		if (!error)
749 			error = copyout(buf, hgd->hgd_data, size);
750 		HIDRAW_LOCAL_FREE(local_buf, buf);
751 #ifdef COMPAT_FREEBSD32
752 		/*
753 		 * HIDRAW_GET_REPORT is declared _IOWR, but hgd is not written
754 		 * so we don't call update_hgd32().
755 		 */
756 #endif
757 		return (error);
758 
759 	case HIDRAW_SET_REPORT:
760 		if (!(sc->sc_fflags & FWRITE))
761 			return (EPERM);
762 		switch (hgd->hgd_report_type) {
763 		case HID_INPUT_REPORT:
764 			size = sc->sc_rdesc->isize;
765 			id = sc->sc_rdesc->iid;
766 			break;
767 		case HID_OUTPUT_REPORT:
768 			size = sc->sc_rdesc->osize;
769 			id = sc->sc_rdesc->oid;
770 			break;
771 		case HID_FEATURE_REPORT:
772 			size = sc->sc_rdesc->fsize;
773 			id = sc->sc_rdesc->fid;
774 			break;
775 		default:
776 			return (EINVAL);
777 		}
778 		size = MIN(hgd->hgd_maxlen, size);
779 		buf = HIDRAW_LOCAL_ALLOC(local_buf, size);
780 		copyin(hgd->hgd_data, buf, size);
781 		if (id != 0)
782 			id = *(uint8_t *)buf;
783 		error = hid_set_report(sc->sc_dev, buf, size,
784 		    hgd->hgd_report_type, id);
785 		HIDRAW_LOCAL_FREE(local_buf, buf);
786 		return (error);
787 
788 	case HIDRAW_GET_REPORT_ID:
789 		*(int *)addr = 0;	/* XXX: we only support reportid 0? */
790 		return (0);
791 
792 	case HIDIOCGRDESCSIZE:
793 		*(int *)addr = sc->sc_hw->rdescsize;
794 		return (0);
795 
796 	case HIDIOCGRDESC:
797 		hrd = *(struct hidraw_report_descriptor **)addr;
798 		error = copyin(&hrd->size, &size, sizeof(uint32_t));
799 		if (error)
800 			return (error);
801 		/*
802 		 * HID_MAX_DESCRIPTOR_SIZE-1 is a limit of report descriptor
803 		 * size in current Linux implementation.
804 		 */
805 		if (size >= HID_MAX_DESCRIPTOR_SIZE)
806 			return (EINVAL);
807 		buf = HIDRAW_LOCAL_ALLOC(local_buf, size);
808 		error = hid_get_rdesc(sc->sc_dev, buf, size);
809 		if (error == 0) {
810 			size = MIN(size, sc->sc_rdesc->len);
811 			error = copyout(buf, hrd->value, size);
812 		}
813 		HIDRAW_LOCAL_FREE(local_buf, buf);
814 		return (error);
815 
816 	case HIDIOCGRAWINFO:
817 		hdi = (struct hidraw_devinfo *)addr;
818 		hdi->bustype = sc->sc_hw->idBus;
819 		hdi->vendor = sc->sc_hw->idVendor;
820 		hdi->product = sc->sc_hw->idProduct;
821 		return (0);
822 	}
823 
824 	/* variable-length ioctls handling */
825 	len = IOCPARM_LEN(cmd);
826 	switch (IOCBASECMD(cmd)) {
827 	case HIDIOCGRAWNAME(0):
828 		strlcpy(addr, sc->sc_hw->name, len);
829 		td->td_retval[0] = min(strlen(sc->sc_hw->name) + 1, len);
830 		return (0);
831 
832 	case HIDIOCGRAWPHYS(0):
833 		devname = device_get_nameunit(sc->sc_dev);
834 		strlcpy(addr, devname, len);
835 		td->td_retval[0] = min(strlen(devname) + 1, len);
836 		return (0);
837 
838 	case HIDIOCSFEATURE(0):
839 		if (!(sc->sc_fflags & FWRITE))
840 			return (EPERM);
841 		if (len < 2)
842 			return (EINVAL);
843 		id = *(uint8_t *)addr;
844 		if (id == 0) {
845 			addr = (uint8_t *)addr + 1;
846 			len--;
847 		}
848 		return (hid_set_report(sc->sc_dev, addr, len,
849 		    HID_FEATURE_REPORT, id));
850 
851 	case HIDIOCGFEATURE(0):
852 		if (!(sc->sc_fflags & FREAD))
853 			return (EPERM);
854 		if (len < 2)
855 			return (EINVAL);
856 		id = *(uint8_t *)addr;
857 		if (id == 0) {
858 			addr = (uint8_t *)addr + 1;
859 			len--;
860 		}
861 		return (hid_get_report(sc->sc_dev, addr, len, NULL,
862 		    HID_FEATURE_REPORT, id));
863 
864 	case HIDIOCGRAWUNIQ(0):
865 		strlcpy(addr, sc->sc_hw->serial, len);
866 		td->td_retval[0] = min(strlen(sc->sc_hw->serial) + 1, len);
867 		return (0);
868 	}
869 
870 	return (EINVAL);
871 }
872 
873 static int
874 hidraw_poll(struct cdev *dev, int events, struct thread *td)
875 {
876 	struct hidraw_softc *sc;
877 	int revents = 0;
878 
879 	sc = dev->si_drv1;
880 	if (sc == NULL)
881 		return (POLLHUP);
882 
883 	if (events & (POLLOUT | POLLWRNORM) && (sc->sc_fflags & FWRITE))
884 		revents |= events & (POLLOUT | POLLWRNORM);
885 	if (events & (POLLIN | POLLRDNORM) && (sc->sc_fflags & FREAD)) {
886 		mtx_lock(&sc->sc_mtx);
887 		if (sc->sc_head != sc->sc_tail)
888 			revents |= events & (POLLIN | POLLRDNORM);
889 		else {
890 			sc->sc_state.sel = true;
891 			selrecord(td, &sc->sc_rsel);
892 		}
893 		mtx_unlock(&sc->sc_mtx);
894 	}
895 
896 	return (revents);
897 }
898 
899 static int
900 hidraw_kqfilter(struct cdev *dev, struct knote *kn)
901 {
902 	struct hidraw_softc *sc;
903 
904 	sc = dev->si_drv1;
905 	if (sc == NULL)
906 		return (ENXIO);
907 
908 	switch(kn->kn_filter) {
909 	case EVFILT_READ:
910 		if (sc->sc_fflags & FREAD) {
911 			kn->kn_fop = &hidraw_filterops_read;
912 			break;
913 		}
914 		/* FALLTHROUGH */
915 	default:
916 		return(EINVAL);
917 	}
918 	kn->kn_hook = sc;
919 
920 	knlist_add(&sc->sc_rsel.si_note, kn, 0);
921 	return (0);
922 }
923 
924 static int
925 hidraw_kqread(struct knote *kn, long hint)
926 {
927 	struct hidraw_softc *sc;
928 	int ret;
929 
930 	sc = kn->kn_hook;
931 
932 	mtx_assert(&sc->sc_mtx, MA_OWNED);
933 
934 	if (sc->dev->si_drv1 == NULL) {
935 		kn->kn_flags |= EV_EOF;
936 		ret = 1;
937 	} else
938 		ret = (sc->sc_head != sc->sc_tail) ? 1 : 0;
939 
940 	return (ret);
941 }
942 
943 static void
944 hidraw_kqdetach(struct knote *kn)
945 {
946 	struct hidraw_softc *sc;
947 
948 	sc = kn->kn_hook;
949 	knlist_remove(&sc->sc_rsel.si_note, kn, 0);
950 }
951 
952 static void
953 hidraw_notify(struct hidraw_softc *sc)
954 {
955 
956 	mtx_assert(&sc->sc_mtx, MA_OWNED);
957 
958 	if (sc->sc_state.aslp) {
959 		sc->sc_state.aslp = false;
960 		DPRINTFN(5, "waking %p\n", &sc->sc_q);
961 		wakeup(&sc->sc_q);
962 	}
963 	if (sc->sc_state.sel) {
964 		sc->sc_state.sel = false;
965 		selwakeuppri(&sc->sc_rsel, PZERO);
966 	}
967 	if (sc->sc_async != NULL) {
968 		DPRINTFN(3, "sending SIGIO %p\n", sc->sc_async);
969 		PROC_LOCK(sc->sc_async);
970 		kern_psignal(sc->sc_async, SIGIO);
971 		PROC_UNLOCK(sc->sc_async);
972 	}
973 	KNOTE_LOCKED(&sc->sc_rsel.si_note, 0);
974 }
975 
976 static device_method_t hidraw_methods[] = {
977 	/* Device interface */
978 	DEVMETHOD(device_identify,	hidraw_identify),
979 	DEVMETHOD(device_probe,		hidraw_probe),
980 	DEVMETHOD(device_attach,	hidraw_attach),
981 	DEVMETHOD(device_detach,	hidraw_detach),
982 
983 	DEVMETHOD_END
984 };
985 
986 static driver_t hidraw_driver = {
987 	"hidraw",
988 	hidraw_methods,
989 	sizeof(struct hidraw_softc)
990 };
991 
992 DRIVER_MODULE(hidraw, hidbus, hidraw_driver, NULL, NULL);
993 MODULE_DEPEND(hidraw, hidbus, 1, 1, 1);
994 MODULE_DEPEND(hidraw, hid, 1, 1, 1);
995 MODULE_DEPEND(hidraw, usb, 1, 1, 1);
996 MODULE_VERSION(hidraw, 1);
997