]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/hid/hidraw.c
unbound: Vendor import 1.17.0
[FreeBSD/FreeBSD.git] / sys / dev / hid / hidraw.c
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);