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