xref: /freebsd-13-stable/sys/dev/hid/hidraw.c (revision ca6cd0e57cca4a39a2947c35b9e5f0ef11979fb5)
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 #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 struct filterops hidraw_filterops_read = {
176 	.f_isfd =	1,
177 	.f_detach =	hidraw_kqdetach,
178 	.f_event =	hidraw_kqread,
179 };
180 
181 static void
hidraw_identify(driver_t * driver,device_t parent)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
hidraw_probe(device_t self)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
hidraw_attach(device_t self)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
hidraw_detach(device_t self)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
hidraw_intr(void * context,void * buf,hid_size_t len)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
hidraw_lock_queue(struct hidraw_softc * sc,bool flush)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
hidraw_unlock_queue(struct hidraw_softc * sc)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
hidraw_open(struct cdev * dev,int flag,int mode,struct thread * td)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 	hidbus_intr_start(sc->sc_dev);
381 
382 	return (0);
383 }
384 
385 static void
hidraw_dtor(void * data)386 hidraw_dtor(void *data)
387 {
388 	struct hidraw_softc *sc = data;
389 
390 	DPRINTF("sc=%p\n", sc);
391 
392 	/* Disable interrupts. */
393 	hidbus_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
hidraw_read(struct cdev * dev,struct uio * uio,int flag)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
hidraw_write(struct cdev * dev,struct uio * uio,int flag)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
update_hgd32(const struct hidraw_gen_descriptor * hgd,struct hidraw_gen_descriptor32 * hgd32)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
hidraw_ioctl(struct cdev * dev,u_long cmd,caddr_t addr,int flag,struct thread * td)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 
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 		error = copyin(hgd->hgd_data, buf, hgd->hgd_maxlen);
682 		if (error == 0) {
683 			/* Lock newbus around set_report_descr call */
684 			mtx_lock(&Giant);
685 			error = hid_set_report_descr(sc->sc_dev, buf,
686 			    hgd->hgd_maxlen);
687 			mtx_unlock(&Giant);
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 		buf = HIDRAW_LOCAL_ALLOC(local_buf, size);
833 		error = hid_get_rdesc(sc->sc_dev, buf, size);
834 		if (error == 0) {
835 			size = MIN(size, sc->sc_rdesc->len);
836 			error = copyout(buf, hrd->value, size);
837 		}
838 		HIDRAW_LOCAL_FREE(local_buf, buf);
839 		return (error);
840 
841 	case HIDIOCGRAWINFO:
842 		hd = (struct hidraw_devinfo *)addr;
843 		hd->bustype = sc->sc_hw->idBus;
844 		hd->vendor = sc->sc_hw->idVendor;
845 		hd->product = sc->sc_hw->idProduct;
846 		return (0);
847 	}
848 
849 	/* variable-length ioctls handling */
850 	len = IOCPARM_LEN(cmd);
851 	switch (IOCBASECMD(cmd)) {
852 	case HIDIOCGRAWNAME(0):
853 		strlcpy(addr, sc->sc_hw->name, len);
854 		td->td_retval[0] = min(strlen(sc->sc_hw->name) + 1, len);
855 		return (0);
856 
857 	case HIDIOCGRAWPHYS(0):
858 		devname = device_get_nameunit(sc->sc_dev);
859 		strlcpy(addr, devname, len);
860 		td->td_retval[0] = min(strlen(devname) + 1, len);
861 		return (0);
862 
863 	case HIDIOCSFEATURE(0):
864 		if (!(sc->sc_fflags & FWRITE))
865 			return (EPERM);
866 		if (len < 2)
867 			return (EINVAL);
868 		id = *(uint8_t *)addr;
869 		if (id == 0) {
870 			addr = (uint8_t *)addr + 1;
871 			len--;
872 		}
873 		return (hid_set_report(sc->sc_dev, addr, len,
874 		    HID_FEATURE_REPORT, id));
875 
876 	case HIDIOCGFEATURE(0):
877 		if (!(sc->sc_fflags & FREAD))
878 			return (EPERM);
879 		if (len < 2)
880 			return (EINVAL);
881 		id = *(uint8_t *)addr;
882 		if (id == 0) {
883 			addr = (uint8_t *)addr + 1;
884 			len--;
885 		}
886 		return (hid_get_report(sc->sc_dev, addr, len, NULL,
887 		    HID_FEATURE_REPORT, id));
888 
889 	case HIDIOCGRAWUNIQ(0):
890 		strlcpy(addr, sc->sc_hw->serial, len);
891 		td->td_retval[0] = min(strlen(sc->sc_hw->serial) + 1, len);
892 		return (0);
893 	}
894 
895 	return (EINVAL);
896 }
897 
898 static int
hidraw_poll(struct cdev * dev,int events,struct thread * td)899 hidraw_poll(struct cdev *dev, int events, struct thread *td)
900 {
901 	struct hidraw_softc *sc;
902 	int revents = 0;
903 
904 	sc = dev->si_drv1;
905 	if (sc == NULL)
906 		return (POLLHUP);
907 
908 	if (events & (POLLOUT | POLLWRNORM) && (sc->sc_fflags & FWRITE))
909 		revents |= events & (POLLOUT | POLLWRNORM);
910 	if (events & (POLLIN | POLLRDNORM) && (sc->sc_fflags & FREAD)) {
911 		mtx_lock(&sc->sc_mtx);
912 		if (sc->sc_head != sc->sc_tail)
913 			revents |= events & (POLLIN | POLLRDNORM);
914 		else {
915 			sc->sc_state.sel = true;
916 			selrecord(td, &sc->sc_rsel);
917 		}
918 		mtx_unlock(&sc->sc_mtx);
919 	}
920 
921 	return (revents);
922 }
923 
924 static int
hidraw_kqfilter(struct cdev * dev,struct knote * kn)925 hidraw_kqfilter(struct cdev *dev, struct knote *kn)
926 {
927 	struct hidraw_softc *sc;
928 
929 	sc = dev->si_drv1;
930 	if (sc == NULL)
931 		return (ENXIO);
932 
933 	switch(kn->kn_filter) {
934 	case EVFILT_READ:
935 		if (sc->sc_fflags & FREAD) {
936 			kn->kn_fop = &hidraw_filterops_read;
937 			break;
938 		}
939 		/* FALLTHROUGH */
940 	default:
941 		return(EINVAL);
942 	}
943 	kn->kn_hook = sc;
944 
945 	knlist_add(&sc->sc_rsel.si_note, kn, 0);
946 	return (0);
947 }
948 
949 static int
hidraw_kqread(struct knote * kn,long hint)950 hidraw_kqread(struct knote *kn, long hint)
951 {
952 	struct hidraw_softc *sc;
953 	int ret;
954 
955 	sc = kn->kn_hook;
956 
957 	mtx_assert(&sc->sc_mtx, MA_OWNED);
958 
959 	if (sc->dev->si_drv1 == NULL) {
960 		kn->kn_flags |= EV_EOF;
961 		ret = 1;
962 	} else
963 		ret = (sc->sc_head != sc->sc_tail) ? 1 : 0;
964 
965 	return (ret);
966 }
967 
968 static void
hidraw_kqdetach(struct knote * kn)969 hidraw_kqdetach(struct knote *kn)
970 {
971 	struct hidraw_softc *sc;
972 
973 	sc = kn->kn_hook;
974 	knlist_remove(&sc->sc_rsel.si_note, kn, 0);
975 }
976 
977 static void
hidraw_notify(struct hidraw_softc * sc)978 hidraw_notify(struct hidraw_softc *sc)
979 {
980 
981 	mtx_assert(&sc->sc_mtx, MA_OWNED);
982 
983 	if (sc->sc_state.aslp) {
984 		sc->sc_state.aslp = false;
985 		DPRINTFN(5, "waking %p\n", &sc->sc_q);
986 		wakeup(&sc->sc_q);
987 	}
988 	if (sc->sc_state.sel) {
989 		sc->sc_state.sel = false;
990 		selwakeuppri(&sc->sc_rsel, PZERO);
991 	}
992 	if (sc->sc_async != NULL) {
993 		DPRINTFN(3, "sending SIGIO %p\n", sc->sc_async);
994 		PROC_LOCK(sc->sc_async);
995 		kern_psignal(sc->sc_async, SIGIO);
996 		PROC_UNLOCK(sc->sc_async);
997 	}
998 	KNOTE_LOCKED(&sc->sc_rsel.si_note, 0);
999 }
1000 
1001 static device_method_t hidraw_methods[] = {
1002 	/* Device interface */
1003 	DEVMETHOD(device_identify,	hidraw_identify),
1004 	DEVMETHOD(device_probe,		hidraw_probe),
1005 	DEVMETHOD(device_attach,	hidraw_attach),
1006 	DEVMETHOD(device_detach,	hidraw_detach),
1007 
1008 	DEVMETHOD_END
1009 };
1010 
1011 static driver_t hidraw_driver = {
1012 	"hidraw",
1013 	hidraw_methods,
1014 	sizeof(struct hidraw_softc)
1015 };
1016 
1017 #ifndef HIDRAW_MAKE_UHID_ALIAS
1018 devclass_t hidraw_devclass;
1019 #endif
1020 
1021 DRIVER_MODULE(hidraw, hidbus, hidraw_driver, hidraw_devclass, NULL, 0);
1022 MODULE_DEPEND(hidraw, hidbus, 1, 1, 1);
1023 MODULE_DEPEND(hidraw, hid, 1, 1, 1);
1024 MODULE_DEPEND(hidraw, usb, 1, 1, 1);
1025 MODULE_VERSION(hidraw, 1);
1026