]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/hid/hidbus.c
zfs: merge openzfs/zfs@bdd11cbb9 (master) into main
[FreeBSD/FreeBSD.git] / sys / dev / hid / hidbus.c
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2019-2020 Vladimir Kondratyev <wulf@FreeBSD.org>
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  */
27
28 #include <sys/cdefs.h>
29 __FBSDID("$FreeBSD$");
30
31 #include <sys/param.h>
32 #include <sys/bus.h>
33 #include <sys/ck.h>
34 #include <sys/epoch.h>
35 #include <sys/kdb.h>
36 #include <sys/kernel.h>
37 #include <sys/libkern.h>
38 #include <sys/lock.h>
39 #include <sys/malloc.h>
40 #include <sys/module.h>
41 #include <sys/mutex.h>
42 #include <sys/proc.h>
43 #include <sys/sbuf.h>
44 #include <sys/sx.h>
45 #include <sys/systm.h>
46
47 #define HID_DEBUG_VAR   hid_debug
48 #include <dev/hid/hid.h>
49 #include <dev/hid/hidbus.h>
50 #include <dev/hid/hidquirk.h>
51
52 #include "hid_if.h"
53
54 #define INPUT_EPOCH     global_epoch_preempt
55 #define HID_RSIZE_MAX   1024
56
57 static hid_intr_t       hidbus_intr;
58
59 static device_probe_t   hidbus_probe;
60 static device_attach_t  hidbus_attach;
61 static device_detach_t  hidbus_detach;
62
63 struct hidbus_ivars {
64         int32_t                         usage;
65         uint8_t                         index;
66         uint32_t                        flags;
67         uintptr_t                       driver_info;    /* for internal use */
68         struct mtx                      *mtx;           /* child intr mtx */
69         hid_intr_t                      *intr_handler;  /* executed under mtx*/
70         void                            *intr_ctx;
71         unsigned int                    refcnt;         /* protected by mtx */
72         struct epoch_context            epoch_ctx;
73         CK_STAILQ_ENTRY(hidbus_ivars)   link;
74 };
75
76 struct hidbus_softc {
77         device_t                        dev;
78         struct sx                       sx;
79         struct mtx                      mtx;
80
81         bool                            nowrite;
82
83         struct hid_rdesc_info           rdesc;
84         bool                            overloaded;
85         int                             nest;   /* Child attach nesting lvl */
86         int                             nauto;  /* Number of autochildren */
87
88         CK_STAILQ_HEAD(, hidbus_ivars)  tlcs;
89 };
90
91 static int
92 hidbus_fill_rdesc_info(struct hid_rdesc_info *hri, const void *data,
93     hid_size_t len)
94 {
95         int error = 0;
96
97         hri->data = __DECONST(void *, data);
98         hri->len = len;
99
100         /*
101          * If report descriptor is not available yet, set maximal
102          * report sizes high enough to allow hidraw to work.
103          */
104         hri->isize = len == 0 ? HID_RSIZE_MAX :
105             hid_report_size_max(data, len, hid_input, &hri->iid);
106         hri->osize = len == 0 ? HID_RSIZE_MAX :
107             hid_report_size_max(data, len, hid_output, &hri->oid);
108         hri->fsize = len == 0 ? HID_RSIZE_MAX :
109             hid_report_size_max(data, len, hid_feature, &hri->fid);
110
111         if (hri->isize > HID_RSIZE_MAX) {
112                 DPRINTF("input size is too large, %u bytes (truncating)\n",
113                     hri->isize);
114                 hri->isize = HID_RSIZE_MAX;
115                 error = EOVERFLOW;
116         }
117         if (hri->osize > HID_RSIZE_MAX) {
118                 DPRINTF("output size is too large, %u bytes (truncating)\n",
119                     hri->osize);
120                 hri->osize = HID_RSIZE_MAX;
121                 error = EOVERFLOW;
122         }
123         if (hri->fsize > HID_RSIZE_MAX) {
124                 DPRINTF("feature size is too large, %u bytes (truncating)\n",
125                     hri->fsize);
126                 hri->fsize = HID_RSIZE_MAX;
127                 error = EOVERFLOW;
128         }
129
130         return (error);
131 }
132
133 int
134 hidbus_locate(const void *desc, hid_size_t size, int32_t u, enum hid_kind k,
135     uint8_t tlc_index, uint8_t index, struct hid_location *loc,
136     uint32_t *flags, uint8_t *id, struct hid_absinfo *ai)
137 {
138         struct hid_data *d;
139         struct hid_item h;
140         int i;
141
142         d = hid_start_parse(desc, size, 1 << k);
143         HIDBUS_FOREACH_ITEM(d, &h, tlc_index) {
144                 for (i = 0; i < h.nusages; i++) {
145                         if (h.kind == k && h.usages[i] == u) {
146                                 if (index--)
147                                         break;
148                                 if (loc != NULL)
149                                         *loc = h.loc;
150                                 if (flags != NULL)
151                                         *flags = h.flags;
152                                 if (id != NULL)
153                                         *id = h.report_ID;
154                                 if (ai != NULL && (h.flags&HIO_RELATIVE) == 0)
155                                         *ai = (struct hid_absinfo) {
156                                             .max = h.logical_maximum,
157                                             .min = h.logical_minimum,
158                                             .res = hid_item_resolution(&h),
159                                         };
160                                 hid_end_parse(d);
161                                 return (1);
162                         }
163                 }
164         }
165         if (loc != NULL)
166                 loc->size = 0;
167         if (flags != NULL)
168                 *flags = 0;
169         if (id != NULL)
170                 *id = 0;
171         hid_end_parse(d);
172         return (0);
173 }
174
175 static device_t
176 hidbus_add_child(device_t dev, u_int order, const char *name, int unit)
177 {
178         struct hidbus_softc *sc = device_get_softc(dev);
179         struct hidbus_ivars *tlc;
180         device_t child;
181
182         child = device_add_child_ordered(dev, order, name, unit);
183         if (child == NULL)
184                         return (child);
185
186         tlc = malloc(sizeof(struct hidbus_ivars), M_DEVBUF, M_WAITOK | M_ZERO);
187         tlc->mtx = &sc->mtx;
188         device_set_ivars(child, tlc);
189         sx_xlock(&sc->sx);
190         CK_STAILQ_INSERT_TAIL(&sc->tlcs, tlc, link);
191         sx_unlock(&sc->sx);
192
193         return (child);
194 }
195
196 static int
197 hidbus_enumerate_children(device_t dev, const void* data, hid_size_t len)
198 {
199         struct hidbus_softc *sc = device_get_softc(dev);
200         struct hid_data *hd;
201         struct hid_item hi;
202         device_t child;
203         uint8_t index = 0;
204
205         if (data == NULL || len == 0)
206                 return (ENXIO);
207
208         /* Add a child for each top level collection */
209         hd = hid_start_parse(data, len, 1 << hid_input);
210         while (hid_get_item(hd, &hi)) {
211                 if (hi.kind != hid_collection || hi.collevel != 1)
212                         continue;
213                 child = BUS_ADD_CHILD(dev, 0, NULL, -1);
214                 if (child == NULL) {
215                         device_printf(dev, "Could not add HID device\n");
216                         continue;
217                 }
218                 hidbus_set_index(child, index);
219                 hidbus_set_usage(child, hi.usage);
220                 hidbus_set_flags(child, HIDBUS_FLAG_AUTOCHILD);
221                 index++;
222                 DPRINTF("Add child TLC: 0x%04x:0x%04x\n",
223                     HID_GET_USAGE_PAGE(hi.usage), HID_GET_USAGE(hi.usage));
224         }
225         hid_end_parse(hd);
226
227         if (index == 0)
228                 return (ENXIO);
229
230         sc->nauto = index;
231
232         return (0);
233 }
234
235 static int
236 hidbus_attach_children(device_t dev)
237 {
238         struct hidbus_softc *sc = device_get_softc(dev);
239         int error;
240
241         HID_INTR_SETUP(device_get_parent(dev), hidbus_intr, sc, &sc->rdesc);
242
243         error = hidbus_enumerate_children(dev, sc->rdesc.data, sc->rdesc.len);
244         if (error != 0)
245                 DPRINTF("failed to enumerate children: error %d\n", error);
246
247         /*
248          * hidbus_attach_children() can recurse through device_identify->
249          * hid_set_report_descr() call sequence. Do not perform children
250          * attach twice in that case.
251          */
252         sc->nest++;
253         bus_generic_probe(dev);
254         sc->nest--;
255         if (sc->nest != 0)
256                 return (0);
257
258         if (hid_is_keyboard(sc->rdesc.data, sc->rdesc.len) != 0)
259                 error = bus_generic_attach(dev);
260         else
261                 error = bus_delayed_attach_children(dev);
262         if (error != 0)
263                 device_printf(dev, "failed to attach child: error %d\n", error);
264
265         return (error);
266 }
267
268 static int
269 hidbus_detach_children(device_t dev)
270 {
271         device_t *children, bus;
272         bool is_bus;
273         int i, error;
274
275         error = 0;
276
277         is_bus = device_get_devclass(dev) == hidbus_devclass;
278         bus = is_bus ? dev : device_get_parent(dev);
279
280         KASSERT(device_get_devclass(bus) == hidbus_devclass,
281             ("Device is not hidbus or it's child"));
282
283         if (is_bus) {
284                 /* If hidbus is passed, delete all children. */
285                 bus_generic_detach(bus);
286                 device_delete_children(bus);
287         } else {
288                 /*
289                  * If hidbus child is passed, delete all hidbus children
290                  * except caller. Deleting the caller may result in deadlock.
291                  */
292                 error = device_get_children(bus, &children, &i);
293                 if (error != 0)
294                         return (error);
295                 while (i-- > 0) {
296                         if (children[i] == dev)
297                                 continue;
298                         DPRINTF("Delete child. index=%d (%s)\n",
299                             hidbus_get_index(children[i]),
300                             device_get_nameunit(children[i]));
301                         error = device_delete_child(bus, children[i]);
302                         if (error) {
303                                 DPRINTF("Failed deleting %s\n",
304                                     device_get_nameunit(children[i]));
305                                 break;
306                         }
307                 }
308                 free(children, M_TEMP);
309         }
310
311         HID_INTR_UNSETUP(device_get_parent(bus));
312
313         return (error);
314 }
315
316 static int
317 hidbus_probe(device_t dev)
318 {
319
320         device_set_desc(dev, "HID bus");
321
322         /* Allow other subclasses to override this driver. */
323         return (BUS_PROBE_GENERIC);
324 }
325
326 static int
327 hidbus_attach(device_t dev)
328 {
329         struct hidbus_softc *sc = device_get_softc(dev);
330         struct hid_device_info *devinfo = device_get_ivars(dev);
331         void *d_ptr = NULL;
332         hid_size_t d_len;
333         int error;
334
335         sc->dev = dev;
336         CK_STAILQ_INIT(&sc->tlcs);
337         mtx_init(&sc->mtx, "hidbus ivar lock", NULL, MTX_DEF);
338         sx_init(&sc->sx, "hidbus ivar list lock");
339
340         /*
341          * Ignore error. It is possible for non-HID device e.g. XBox360 gamepad
342          * to emulate HID through overloading of report descriptor.
343          */
344         d_len = devinfo->rdescsize;
345         if (d_len != 0) {
346                 d_ptr = malloc(d_len, M_DEVBUF, M_ZERO | M_WAITOK);
347                 error = hid_get_rdesc(dev, d_ptr, d_len);
348                 if (error != 0) {
349                         free(d_ptr, M_DEVBUF);
350                         d_len = 0;
351                         d_ptr = NULL;
352                 }
353         }
354
355         hidbus_fill_rdesc_info(&sc->rdesc, d_ptr, d_len);
356
357         sc->nowrite = hid_test_quirk(devinfo, HQ_NOWRITE);
358
359         error = hidbus_attach_children(dev);
360         if (error != 0) {
361                 hidbus_detach(dev);
362                 return (ENXIO);
363         }
364
365         return (0);
366 }
367
368 static int
369 hidbus_detach(device_t dev)
370 {
371         struct hidbus_softc *sc = device_get_softc(dev);
372
373         hidbus_detach_children(dev);
374         sx_destroy(&sc->sx);
375         mtx_destroy(&sc->mtx);
376         free(sc->rdesc.data, M_DEVBUF);
377
378         return (0);
379 }
380
381 static void
382 hidbus_child_detached(device_t bus, device_t child)
383 {
384         struct hidbus_softc *sc = device_get_softc(bus);
385         struct hidbus_ivars *tlc = device_get_ivars(child);
386
387         KASSERT(tlc->refcnt == 0, ("Child device is running"));
388         tlc->mtx = &sc->mtx;
389         tlc->intr_handler = NULL;
390         tlc->flags &= ~HIDBUS_FLAG_CAN_POLL;
391 }
392
393 /*
394  * Epoch callback indicating tlc is safe to destroy
395  */
396 static void
397 hidbus_ivar_dtor(epoch_context_t ctx)
398 {
399         struct hidbus_ivars *tlc;
400
401         tlc = __containerof(ctx, struct hidbus_ivars, epoch_ctx);
402         free(tlc, M_DEVBUF);
403 }
404
405 static void
406 hidbus_child_deleted(device_t bus, device_t child)
407 {
408         struct hidbus_softc *sc = device_get_softc(bus);
409         struct hidbus_ivars *tlc = device_get_ivars(child);
410
411         sx_xlock(&sc->sx);
412         KASSERT(tlc->refcnt == 0, ("Child device is running"));
413         CK_STAILQ_REMOVE(&sc->tlcs, tlc, hidbus_ivars, link);
414         sx_unlock(&sc->sx);
415         epoch_call(INPUT_EPOCH, hidbus_ivar_dtor, &tlc->epoch_ctx);
416 }
417
418 static int
419 hidbus_read_ivar(device_t bus, device_t child, int which, uintptr_t *result)
420 {
421         struct hidbus_softc *sc = device_get_softc(bus);
422         struct hidbus_ivars *tlc = device_get_ivars(child);
423
424         switch (which) {
425         case HIDBUS_IVAR_INDEX:
426                 *result = tlc->index;
427                 break;
428         case HIDBUS_IVAR_USAGE:
429                 *result = tlc->usage;
430                 break;
431         case HIDBUS_IVAR_FLAGS:
432                 *result = tlc->flags;
433                 break;
434         case HIDBUS_IVAR_DRIVER_INFO:
435                 *result = tlc->driver_info;
436                 break;
437         case HIDBUS_IVAR_LOCK:
438                 *result = (uintptr_t)(tlc->mtx == &sc->mtx ? NULL : tlc->mtx);
439                 break;
440         default:
441                 return (EINVAL);
442         }
443         return (0);
444 }
445
446 static int
447 hidbus_write_ivar(device_t bus, device_t child, int which, uintptr_t value)
448 {
449         struct hidbus_softc *sc = device_get_softc(bus);
450         struct hidbus_ivars *tlc = device_get_ivars(child);
451
452         switch (which) {
453         case HIDBUS_IVAR_INDEX:
454                 tlc->index = value;
455                 break;
456         case HIDBUS_IVAR_USAGE:
457                 tlc->usage = value;
458                 break;
459         case HIDBUS_IVAR_FLAGS:
460                 tlc->flags = value;
461                 if ((value & HIDBUS_FLAG_CAN_POLL) != 0)
462                         HID_INTR_SETUP(
463                             device_get_parent(bus), NULL, NULL, NULL);
464                 break;
465         case HIDBUS_IVAR_DRIVER_INFO:
466                 tlc->driver_info = value;
467                 break;
468         case HIDBUS_IVAR_LOCK:
469                 tlc->mtx = (struct mtx *)value == NULL ?
470                     &sc->mtx : (struct mtx *)value;
471                 break;
472         default:
473                 return (EINVAL);
474         }
475         return (0);
476 }
477
478 /* Location hint for devctl(8) */
479 static int
480 hidbus_child_location(device_t bus, device_t child, struct sbuf *sb)
481 {
482         struct hidbus_ivars *tlc = device_get_ivars(child);
483
484         sbuf_printf(sb, "index=%hhu", tlc->index);
485         return (0);
486 }
487
488 /* PnP information for devctl(8) */
489 static int
490 hidbus_child_pnpinfo(device_t bus, device_t child, struct sbuf *sb)
491 {
492         struct hidbus_ivars *tlc = device_get_ivars(child);
493         struct hid_device_info *devinfo = device_get_ivars(bus);
494
495         sbuf_printf(sb, "page=0x%04x usage=0x%04x bus=0x%02hx "
496             "vendor=0x%04hx product=0x%04hx version=0x%04hx%s%s",
497             HID_GET_USAGE_PAGE(tlc->usage), HID_GET_USAGE(tlc->usage),
498             devinfo->idBus, devinfo->idVendor, devinfo->idProduct,
499             devinfo->idVersion, devinfo->idPnP[0] == '\0' ? "" : " _HID=",
500             devinfo->idPnP[0] == '\0' ? "" : devinfo->idPnP);
501         return (0);
502 }
503
504 void
505 hidbus_set_desc(device_t child, const char *suffix)
506 {
507         device_t bus = device_get_parent(child);
508         struct hidbus_softc *sc = device_get_softc(bus);
509         struct hid_device_info *devinfo = device_get_ivars(bus);
510         struct hidbus_ivars *tlc = device_get_ivars(child);
511         char buf[80];
512
513         /* Do not add NULL suffix or if device name already contains it. */
514         if (suffix != NULL && strcasestr(devinfo->name, suffix) == NULL &&
515             (sc->nauto > 1 || (tlc->flags & HIDBUS_FLAG_AUTOCHILD) == 0)) {
516                 snprintf(buf, sizeof(buf), "%s %s", devinfo->name, suffix);
517                 device_set_desc_copy(child, buf);
518         } else
519                 device_set_desc(child, devinfo->name);
520 }
521
522 device_t
523 hidbus_find_child(device_t bus, int32_t usage)
524 {
525         device_t *children, child;
526         int ccount, i;
527
528         GIANT_REQUIRED;
529
530         /* Get a list of all hidbus children */
531         if (device_get_children(bus, &children, &ccount) != 0)
532                 return (NULL);
533
534         /* Scan through to find required TLC */
535         for (i = 0, child = NULL; i < ccount; i++) {
536                 if (hidbus_get_usage(children[i]) == usage) {
537                         child = children[i];
538                         break;
539                 }
540         }
541         free(children, M_TEMP);
542
543         return (child);
544 }
545
546 void
547 hidbus_intr(void *context, void *buf, hid_size_t len)
548 {
549         struct hidbus_softc *sc = context;
550         struct hidbus_ivars *tlc;
551         struct epoch_tracker et;
552
553         /*
554          * Broadcast input report to all subscribers.
555          * TODO: Add check for input report ID.
556          *
557          * Relock mutex on every TLC item as we can't hold any locks over whole
558          * TLC list here due to LOR with open()/close() handlers.
559          */
560         if (!HID_IN_POLLING_MODE())
561                 epoch_enter_preempt(INPUT_EPOCH, &et);
562         CK_STAILQ_FOREACH(tlc, &sc->tlcs, link) {
563                 if (tlc->refcnt == 0 || tlc->intr_handler == NULL)
564                         continue;
565                 if (HID_IN_POLLING_MODE()) {
566                         if ((tlc->flags & HIDBUS_FLAG_CAN_POLL) != 0)
567                                 tlc->intr_handler(tlc->intr_ctx, buf, len);
568                 } else {
569                         mtx_lock(tlc->mtx);
570                         tlc->intr_handler(tlc->intr_ctx, buf, len);
571                         mtx_unlock(tlc->mtx);
572                 }
573         }
574         if (!HID_IN_POLLING_MODE())
575                 epoch_exit_preempt(INPUT_EPOCH, &et);
576 }
577
578 void
579 hidbus_set_intr(device_t child, hid_intr_t *handler, void *context)
580 {
581         struct hidbus_ivars *tlc = device_get_ivars(child);
582
583         tlc->intr_handler = handler;
584         tlc->intr_ctx = context;
585 }
586
587 int
588 hidbus_intr_start(device_t child)
589 {
590         device_t bus = device_get_parent(child);
591         struct hidbus_softc *sc = device_get_softc(bus);
592         struct hidbus_ivars *ivar = device_get_ivars(child);
593         struct hidbus_ivars *tlc;
594         int refcnt = 0;
595         int error;
596
597         if (sx_xlock_sig(&sc->sx) != 0)
598                 return (EINTR);
599         CK_STAILQ_FOREACH(tlc, &sc->tlcs, link) {
600                 refcnt += tlc->refcnt;
601                 if (tlc == ivar) {
602                         mtx_lock(tlc->mtx);
603                         ++tlc->refcnt;
604                         mtx_unlock(tlc->mtx);
605                 }
606         }
607         error = refcnt != 0 ? 0 : HID_INTR_START(device_get_parent(bus));
608         sx_unlock(&sc->sx);
609
610         return (error);
611 }
612
613 int
614 hidbus_intr_stop(device_t child)
615 {
616         device_t bus = device_get_parent(child);
617         struct hidbus_softc *sc = device_get_softc(bus);
618         struct hidbus_ivars *ivar = device_get_ivars(child);
619         struct hidbus_ivars *tlc;
620         bool refcnt = 0;
621         int error;
622
623         if (sx_xlock_sig(&sc->sx) != 0)
624                 return (EINTR);
625         CK_STAILQ_FOREACH(tlc, &sc->tlcs, link) {
626                 if (tlc == ivar) {
627                         mtx_lock(tlc->mtx);
628                         MPASS(tlc->refcnt != 0);
629                         --tlc->refcnt;
630                         mtx_unlock(tlc->mtx);
631                 }
632                 refcnt += tlc->refcnt;
633         }
634         error = refcnt != 0 ? 0 : HID_INTR_STOP(device_get_parent(bus));
635         sx_unlock(&sc->sx);
636
637         return (error);
638 }
639
640 void
641 hidbus_intr_poll(device_t child)
642 {
643         device_t bus = device_get_parent(child);
644
645         HID_INTR_POLL(device_get_parent(bus));
646 }
647
648 struct hid_rdesc_info *
649 hidbus_get_rdesc_info(device_t child)
650 {
651         device_t bus = device_get_parent(child);
652         struct hidbus_softc *sc = device_get_softc(bus);
653
654         return (&sc->rdesc);
655 }
656
657 /*
658  * HID interface.
659  *
660  * Hidbus as well as any hidbus child can be passed as first arg.
661  */
662
663 /* Read cached report descriptor */
664 int
665 hid_get_report_descr(device_t dev, void **data, hid_size_t *len)
666 {
667         device_t bus;
668         struct hidbus_softc *sc;
669
670         bus = device_get_devclass(dev) == hidbus_devclass ?
671             dev : device_get_parent(dev);
672         sc = device_get_softc(bus);
673
674         /*
675          * Do not send request to a transport backend.
676          * Use cached report descriptor instead of it.
677          */
678         if (sc->rdesc.data == NULL || sc->rdesc.len == 0)
679                 return (ENXIO);
680
681         if (data != NULL)
682                 *data = sc->rdesc.data;
683         if (len != NULL)
684                 *len = sc->rdesc.len;
685
686         return (0);
687 }
688
689 /*
690  * Replace cached report descriptor with top level driver provided one.
691  *
692  * It deletes all hidbus children except caller and enumerates them again after
693  * new descriptor has been registered. Currently it can not be called from
694  * autoenumerated (by report's TLC) child device context as it results in child
695  * duplication. To overcome this limitation hid_set_report_descr() should be
696  * called from device_identify driver's handler with hidbus itself passed as
697  * 'device_t dev' parameter.
698  */
699 int
700 hid_set_report_descr(device_t dev, const void *data, hid_size_t len)
701 {
702         struct hid_rdesc_info rdesc;
703         device_t bus;
704         struct hidbus_softc *sc;
705         bool is_bus;
706         int error;
707
708         GIANT_REQUIRED;
709
710         is_bus = device_get_devclass(dev) == hidbus_devclass;
711         bus = is_bus ? dev : device_get_parent(dev);
712         sc = device_get_softc(bus);
713
714         /*
715          * Do not overload already overloaded report descriptor in
716          * device_identify handler. It causes infinite recursion loop.
717          */
718         if (is_bus && sc->overloaded)
719                 return(0);
720
721         DPRINTFN(5, "len=%d\n", len);
722         DPRINTFN(5, "data = %*D\n", len, data, " ");
723
724         error = hidbus_fill_rdesc_info(&rdesc, data, len);
725         if (error != 0)
726                 return (error);
727
728         error = hidbus_detach_children(dev);
729         if (error != 0)
730                 return(error);
731
732         /* Make private copy to handle a case of dynamicaly allocated data. */
733         rdesc.data = malloc(len, M_DEVBUF, M_ZERO | M_WAITOK);
734         bcopy(data, rdesc.data, len);
735         sc->overloaded = true;
736         free(sc->rdesc.data, M_DEVBUF);
737         bcopy(&rdesc, &sc->rdesc, sizeof(struct hid_rdesc_info));
738
739         error = hidbus_attach_children(bus);
740
741         return (error);
742 }
743
744 static int
745 hidbus_write(device_t dev, const void *data, hid_size_t len)
746 {
747         struct hidbus_softc *sc;
748         uint8_t id;
749
750         sc = device_get_softc(dev);
751         /*
752          * Output interrupt endpoint is often optional. If HID device
753          * does not provide it, send reports via control pipe.
754          */
755         if (sc->nowrite) {
756                 /* try to extract the ID byte */
757                 id = (sc->rdesc.oid & (len > 0)) ? *(const uint8_t*)data : 0;
758                 return (hid_set_report(dev, data, len, HID_OUTPUT_REPORT, id));
759         }
760
761         return (hid_write(dev, data, len));
762 }
763
764 /*------------------------------------------------------------------------*
765  *      hidbus_lookup_id
766  *
767  * This functions takes an array of "struct hid_device_id" and tries
768  * to match the entries with the information in "struct hid_device_info".
769  *
770  * Return values:
771  * NULL: No match found.
772  * Else: Pointer to matching entry.
773  *------------------------------------------------------------------------*/
774 const struct hid_device_id *
775 hidbus_lookup_id(device_t dev, const struct hid_device_id *id, int nitems_id)
776 {
777         const struct hid_device_id *id_end;
778         const struct hid_device_info *info;
779         int32_t usage;
780         bool is_child;
781
782         if (id == NULL) {
783                 goto done;
784         }
785
786         id_end = id + nitems_id;
787         info = hid_get_device_info(dev);
788         is_child = device_get_devclass(dev) != hidbus_devclass;
789         if (is_child)
790                 usage = hidbus_get_usage(dev);
791
792         /*
793          * Keep on matching array entries until we find a match or
794          * until we reach the end of the matching array:
795          */
796         for (; id != id_end; id++) {
797
798                 if (is_child && (id->match_flag_page) &&
799                     (id->page != HID_GET_USAGE_PAGE(usage))) {
800                         continue;
801                 }
802                 if (is_child && (id->match_flag_usage) &&
803                     (id->usage != HID_GET_USAGE(usage))) {
804                         continue;
805                 }
806                 if ((id->match_flag_bus) &&
807                     (id->idBus != info->idBus)) {
808                         continue;
809                 }
810                 if ((id->match_flag_vendor) &&
811                     (id->idVendor != info->idVendor)) {
812                         continue;
813                 }
814                 if ((id->match_flag_product) &&
815                     (id->idProduct != info->idProduct)) {
816                         continue;
817                 }
818                 if ((id->match_flag_ver_lo) &&
819                     (id->idVersion_lo > info->idVersion)) {
820                         continue;
821                 }
822                 if ((id->match_flag_ver_hi) &&
823                     (id->idVersion_hi < info->idVersion)) {
824                         continue;
825                 }
826                 if (id->match_flag_pnp &&
827                     strncmp(id->idPnP, info->idPnP, HID_PNP_ID_SIZE) != 0) {
828                         continue;
829                 }
830                 /* We found a match! */
831                 return (id);
832         }
833
834 done:
835         return (NULL);
836 }
837
838 /*------------------------------------------------------------------------*
839  *      hidbus_lookup_driver_info - factored out code
840  *
841  * Return values:
842  *    0: Success
843  * Else: Failure
844  *------------------------------------------------------------------------*/
845 int
846 hidbus_lookup_driver_info(device_t child, const struct hid_device_id *id,
847     int nitems_id)
848 {
849
850         id = hidbus_lookup_id(child, id, nitems_id);
851         if (id) {
852                 /* copy driver info */
853                 hidbus_set_driver_info(child, id->driver_info);
854                 return (0);
855         }
856         return (ENXIO);
857 }
858
859 const struct hid_device_info *
860 hid_get_device_info(device_t dev)
861 {
862         device_t bus;
863
864         bus = device_get_devclass(dev) == hidbus_devclass ?
865             dev : device_get_parent(dev);
866
867         return (device_get_ivars(bus));
868 }
869
870 static device_method_t hidbus_methods[] = {
871         /* device interface */
872         DEVMETHOD(device_probe,         hidbus_probe),
873         DEVMETHOD(device_attach,        hidbus_attach),
874         DEVMETHOD(device_detach,        hidbus_detach),
875         DEVMETHOD(device_suspend,       bus_generic_suspend),
876         DEVMETHOD(device_resume,        bus_generic_resume),
877
878         /* bus interface */
879         DEVMETHOD(bus_add_child,        hidbus_add_child),
880         DEVMETHOD(bus_child_detached,   hidbus_child_detached),
881         DEVMETHOD(bus_child_deleted,    hidbus_child_deleted),
882         DEVMETHOD(bus_read_ivar,        hidbus_read_ivar),
883         DEVMETHOD(bus_write_ivar,       hidbus_write_ivar),
884         DEVMETHOD(bus_child_pnpinfo,    hidbus_child_pnpinfo),
885         DEVMETHOD(bus_child_location,   hidbus_child_location),
886
887         /* hid interface */
888         DEVMETHOD(hid_get_rdesc,        hid_get_rdesc),
889         DEVMETHOD(hid_read,             hid_read),
890         DEVMETHOD(hid_write,            hidbus_write),
891         DEVMETHOD(hid_get_report,       hid_get_report),
892         DEVMETHOD(hid_set_report,       hid_set_report),
893         DEVMETHOD(hid_set_idle,         hid_set_idle),
894         DEVMETHOD(hid_set_protocol,     hid_set_protocol),
895
896         DEVMETHOD_END
897 };
898
899 devclass_t hidbus_devclass;
900 driver_t hidbus_driver = {
901         "hidbus",
902         hidbus_methods,
903         sizeof(struct hidbus_softc),
904 };
905
906 MODULE_DEPEND(hidbus, hid, 1, 1, 1);
907 MODULE_VERSION(hidbus, 1);
908 DRIVER_MODULE(hidbus, iichid, hidbus_driver, hidbus_devclass, 0, 0);
909 DRIVER_MODULE(hidbus, usbhid, hidbus_driver, hidbus_devclass, 0, 0);