View | Details | Raw Unified | Return to bug 263995 | Differences between
and this patch

Collapse All | Expand All

(-)b/sys/conf/files (+1 lines)
Lines 1812-1817 dev/gpio/gpiobus_if.m optional gpio Link Here
1812
dev/gpio/gpiopps.c		optional gpiopps fdt
1812
dev/gpio/gpiopps.c		optional gpiopps fdt
1813
dev/gpio/ofw_gpiobus.c		optional fdt gpio
1813
dev/gpio/ofw_gpiobus.c		optional fdt gpio
1814
dev/hid/bcm5974.c		optional bcm5974
1814
dev/hid/bcm5974.c		optional bcm5974
1815
dev/hid/fido.c			optional fido
1815
dev/hid/hconf.c			optional hconf
1816
dev/hid/hconf.c			optional hconf
1816
dev/hid/hcons.c			optional hcons
1817
dev/hid/hcons.c			optional hcons
1817
dev/hid/hgame.c			optional hgame
1818
dev/hid/hgame.c			optional hgame
(-)b/sys/dev/hid/fido.c (+592 lines)
Added Link Here
1
/*-
2
 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3
 *
4
 * Copyright (c) 2022 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 "opt_hid.h"
29
30
#include <sys/param.h>
31
#ifdef COMPAT_FREEBSD32
32
#include <sys/abi_compat.h>
33
#endif
34
#include <sys/bus.h>
35
#include <sys/conf.h>
36
#include <sys/fcntl.h>
37
#include <sys/filio.h>
38
#include <sys/ioccom.h>
39
#include <sys/kernel.h>
40
#include <sys/lock.h>
41
#include <sys/malloc.h>
42
#include <sys/module.h>
43
#include <sys/mutex.h>
44
#include <sys/poll.h>
45
#include <sys/priv.h>
46
#include <sys/proc.h>
47
#include <sys/selinfo.h>
48
#include <sys/sysctl.h>
49
#include <sys/systm.h>
50
#include <sys/uio.h>
51
52
#include <dev/evdev/input.h>
53
54
#define HID_DEBUG_VAR	fido_debug
55
#include <dev/hid/hid.h>
56
#include <dev/hid/hidbus.h>
57
#include <dev/hid/hidquirk.h>
58
59
#include <dev/usb/usb_ioctl.h>
60
61
#ifdef HID_DEBUG
62
static int fido_debug = 0;
63
static SYSCTL_NODE(_hw_hid, OID_AUTO, fido, CTLFLAG_RW, 0, "Yubico FIDO key");
64
SYSCTL_INT(_hw_hid_fido, OID_AUTO, debug, CTLFLAG_RWTUN,
65
    &fido_debug, 0, "Debug level");
66
#endif
67
68
#define	FIDO_MAKE_UHID_ALIAS
69
#define	GID_U2F			116
70
#define	FIDO_MAX_REPORT_SIZE	64
71
72
/* A match on these entries will load hms */
73
static const struct hid_device_id fido_devs[] = {
74
	{ HID_BUS(BUS_USB), HID_TLC(HUP_FIDO, HUF_U2FHID) },
75
};
76
77
struct fido_softc {
78
	device_t sc_dev;		/* base device */
79
	struct cdev *dev;
80
81
	struct mtx sc_mtx;		/* hidbus private mutex */
82
	void *sc_rdesc;
83
	hid_size_t sc_rdesc_size;
84
	hid_size_t sc_isize;
85
	hid_size_t sc_osize;
86
	struct selinfo sc_rsel;
87
	struct {			/* driver state */
88
		bool	open:1;		/* device is open */
89
		bool	aslp:1;		/* waiting for device data in read() */
90
		bool	sel:1;		/* waiting for device data in poll() */
91
		bool	data:1;		/* input report is stored in sc_buf */
92
		int	reserved:28;
93
	} sc_state;
94
	int sc_fflags;			/* access mode for open lifetime */
95
96
	uint8_t sc_buf[FIDO_MAX_REPORT_SIZE];
97
};
98
99
static d_open_t		fido_open;
100
static d_read_t		fido_read;
101
static d_write_t	fido_write;
102
static d_ioctl_t	fido_ioctl;
103
static d_poll_t		fido_poll;
104
static d_kqfilter_t	fido_kqfilter;
105
106
static d_priv_dtor_t	fido_dtor;
107
108
static struct cdevsw fido_cdevsw = {
109
	.d_version =	D_VERSION,
110
	.d_open =	fido_open,
111
	.d_read =	fido_read,
112
	.d_write =	fido_write,
113
	.d_ioctl =	fido_ioctl,
114
	.d_poll =	fido_poll,
115
	.d_kqfilter =	fido_kqfilter,
116
	.d_name =	"fido",
117
};
118
119
static hid_intr_t	fido_intr;
120
121
static device_probe_t	fido_probe;
122
static device_attach_t	fido_attach;
123
static device_detach_t	fido_detach;
124
125
static int		fido_kqread(struct knote *, long);
126
static void		fido_kqdetach(struct knote *);
127
static void		fido_notify(struct fido_softc *);
128
129
static struct filterops fido_filterops_read = {
130
	.f_isfd =	1,
131
	.f_detach =	fido_kqdetach,
132
	.f_event =	fido_kqread,
133
};
134
135
static int
136
fido_probe(device_t dev)
137
{
138
	int error;
139
140
	error = HIDBUS_LOOKUP_DRIVER_INFO(dev, fido_devs);
141
	if (error != 0)
142
                return (error);
143
144
	hidbus_set_desc(dev, NULL);
145
146
	return (BUS_PROBE_GENERIC);
147
}
148
149
static int
150
fido_attach(device_t dev)
151
{
152
	struct fido_softc *sc = device_get_softc(dev);
153
	struct hid_device_info *hw = __DECONST(struct hid_device_info *,
154
	    hid_get_device_info(dev));
155
	struct make_dev_args mda;
156
	int error;
157
158
	sc->sc_dev = dev;
159
160
	error = hid_get_report_descr(dev, &sc->sc_rdesc, &sc->sc_rdesc_size);
161
	if (error != 0)
162
		return (ENXIO);
163
	sc->sc_isize = hid_report_size_max(sc->sc_rdesc, sc->sc_rdesc_size,
164
	    hid_input, NULL);
165
	if (sc->sc_isize > FIDO_MAX_REPORT_SIZE) {
166
		device_printf(dev, "Input report size too large. Truncate.\n");
167
		sc->sc_isize = FIDO_MAX_REPORT_SIZE;
168
	}
169
	sc->sc_osize = hid_report_size_max(sc->sc_rdesc, sc->sc_rdesc_size,
170
	    hid_output, NULL);
171
	if (sc->sc_osize > FIDO_MAX_REPORT_SIZE) {
172
		device_printf(dev, "Output report size too large. Truncate.\n");
173
		sc->sc_osize = FIDO_MAX_REPORT_SIZE;
174
	}
175
176
	mtx_init(&sc->sc_mtx, "fido lock", NULL, MTX_DEF);
177
	knlist_init_mtx(&sc->sc_rsel.si_note, &sc->sc_mtx);
178
179
	make_dev_args_init(&mda);
180
	mda.mda_flags = MAKEDEV_WAITOK;
181
	mda.mda_devsw = &fido_cdevsw;
182
	mda.mda_uid = UID_ROOT;
183
	mda.mda_gid = GID_U2F;
184
	mda.mda_mode = 0660;
185
	mda.mda_si_drv1 = sc;
186
187
	error = make_dev_s(&mda, &sc->dev, "fido%d", device_get_unit(dev));
188
	if (error) {
189
		device_printf(dev, "Can not create character device\n");
190
		fido_detach(dev);
191
		return (error);
192
	}
193
#ifdef FIDO_MAKE_UHID_ALIAS
194
	(void)make_dev_alias(sc->dev, "uhid%d", device_get_unit(dev));
195
#endif
196
197
	hid_add_dynamic_quirk(hw, HQ_NO_READAHEAD);
198
199
	hidbus_set_lock(dev, &sc->sc_mtx);
200
	hidbus_set_intr(dev, fido_intr, sc);
201
202
	return (0);
203
}
204
205
static int
206
fido_detach(device_t dev)
207
{
208
	struct fido_softc *sc = device_get_softc(dev);
209
210
	DPRINTF("sc=%p\n", sc);
211
212
	if (sc->dev != NULL) {
213
		mtx_lock(&sc->sc_mtx);
214
		sc->dev->si_drv1 = NULL;
215
		/* Wake everyone */
216
		fido_notify(sc);
217
		mtx_unlock(&sc->sc_mtx);
218
		destroy_dev(sc->dev);
219
	}
220
221
	knlist_clear(&sc->sc_rsel.si_note, 0);
222
	knlist_destroy(&sc->sc_rsel.si_note);
223
	seldrain(&sc->sc_rsel);
224
	mtx_destroy(&sc->sc_mtx);
225
226
	return (0);
227
}
228
229
void
230
fido_intr(void *context, void *buf, hid_size_t len)
231
{
232
	struct fido_softc *sc = context;
233
234
	mtx_assert(&sc->sc_mtx, MA_OWNED);
235
236
	DPRINTFN(5, "len=%d\n", len);
237
	DPRINTFN(5, "data = %*D\n", len, buf, " ");
238
239
	if (sc->sc_state.data)
240
		return;
241
242
	if (len > sc->sc_isize)
243
		len = sc->sc_isize;
244
245
	bcopy(buf, sc->sc_buf, len);
246
247
	/* Make sure we don't process old data */
248
	if (len < sc->sc_isize)
249
		bzero(sc->sc_buf + len, sc->sc_isize - len);
250
251
	sc->sc_state.data = true;
252
253
	fido_notify(sc);
254
}
255
256
static int
257
fido_open(struct cdev *dev, int flag, int mode, struct thread *td)
258
{
259
	struct fido_softc *sc = dev->si_drv1;
260
	int error;
261
262
	if (sc == NULL)
263
		return (ENXIO);
264
265
	DPRINTF("sc=%p\n", sc);
266
267
	mtx_lock(&sc->sc_mtx);
268
	if (sc->sc_state.open) {
269
		mtx_unlock(&sc->sc_mtx);
270
		return (EBUSY);
271
	}
272
	sc->sc_state.open = true;
273
	mtx_unlock(&sc->sc_mtx);
274
275
	error = devfs_set_cdevpriv(sc, fido_dtor);
276
	if (error != 0) {
277
		mtx_lock(&sc->sc_mtx);
278
		sc->sc_state.open = false;
279
		mtx_unlock(&sc->sc_mtx);
280
		return (error);
281
	}
282
283
	/* Set up interrupt pipe. */
284
	sc->sc_state.data = false;
285
	sc->sc_fflags = flag;
286
287
	return (0);
288
}
289
290
291
static void
292
fido_dtor(void *data)
293
{
294
	struct fido_softc *sc = data;
295
296
	/* Disable interrupts. */
297
	hidbus_intr_stop(sc->sc_dev);
298
299
	mtx_lock(&sc->sc_mtx);
300
	sc->sc_state.open = false;
301
	mtx_unlock(&sc->sc_mtx);
302
}
303
304
static int
305
fido_read(struct cdev *dev, struct uio *uio, int flag)
306
{
307
	struct fido_softc *sc = dev->si_drv1;
308
	size_t length;
309
	int error;
310
311
	DPRINTFN(1, "\n");
312
313
	if (sc == NULL)
314
		return (EIO);
315
316
	if (!sc->sc_state.data)
317
		hidbus_intr_start(sc->sc_dev);
318
319
	mtx_lock(&sc->sc_mtx);
320
	if (dev->si_drv1 == NULL) {
321
		error = EIO;
322
		goto exit;
323
	}
324
325
	while (!sc->sc_state.data) {
326
		if (flag & O_NONBLOCK) {
327
			error = EWOULDBLOCK;
328
			goto exit;
329
		}
330
		sc->sc_state.aslp = true;
331
		DPRINTFN(5, "sleep on %p\n", &sc->sc_buf);
332
		error = mtx_sleep(&sc->sc_buf, &sc->sc_mtx, PZERO | PCATCH,
333
		    "fidord", 0);
334
		DPRINTFN(5, "woke, error=%d\n", error);
335
		if (dev->si_drv1 == NULL)
336
			error = EIO;
337
		if (error) {
338
			sc->sc_state.aslp = false;
339
			goto exit;
340
		}
341
	}
342
343
	if (sc->sc_state.data && uio->uio_resid > 0) {
344
		length = min(uio->uio_resid, sc->sc_isize);
345
		mtx_unlock(&sc->sc_mtx);
346
347
		/* Copy the data to the user process. */
348
		DPRINTFN(5, "got %lu chars\n", (u_long)length);
349
		error = uiomove(sc->sc_buf, length, uio);
350
351
		mtx_lock(&sc->sc_mtx);
352
		if (error != 0)
353
			goto exit;
354
		sc->sc_state.data = false;
355
	}
356
exit:
357
	mtx_unlock(&sc->sc_mtx);
358
359
	return (error);
360
}
361
362
static int
363
fido_write(struct cdev *dev, struct uio *uio, int flag)
364
{
365
	uint8_t buf[FIDO_MAX_REPORT_SIZE];
366
	struct fido_softc *sc = dev->si_drv1;
367
	int error;
368
369
	DPRINTFN(1, "\n");
370
371
	if (sc == NULL)
372
		return (EIO);
373
374
	if (uio->uio_resid != sc->sc_osize)
375
		return (EINVAL);
376
	error = uiomove(buf, uio->uio_resid, uio);
377
	if (error == 0)
378
		error = hid_write(sc->sc_dev, buf, sc->sc_osize);
379
380
	return (error);
381
}
382
383
#ifdef COMPAT_FREEBSD32
384
static void
385
update_ugd32(const struct usb_gen_descriptor *ugd,
386
    struct usb_gen_descriptor32 *ugd32)
387
{
388
	/* Don't update hgd_data pointer */
389
	CP(*ugd, *ugd32, ugd_lang_id);
390
	CP(*ugd, *ugd32, ugd_maxlen);
391
	CP(*ugd, *ugd32, ugd_actlen);
392
	CP(*ugd, *ugd32, ugd_offset);
393
	CP(*ugd, *ugd32, ugd_config_index);
394
	CP(*ugd, *ugd32, ugd_string_index);
395
	CP(*ugd, *ugd32, ugd_iface_index);
396
	CP(*ugd, *ugd32, ugd_altif_index);
397
	CP(*ugd, *ugd32, ugd_endpt_index);
398
	CP(*ugd, *ugd32, ugd_report_type);
399
	/* Don't update reserved */
400
}
401
#endif
402
403
static int
404
fido_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
405
    struct thread *td)
406
{
407
#ifdef COMPAT_FREEBSD32
408
	struct usb_gen_descriptor local_ugd;
409
	struct usb_gen_descriptor32 *ugd32 = NULL;
410
#endif
411
	struct fido_softc *sc = dev->si_drv1;
412
	struct usb_gen_descriptor *ugd = (struct usb_gen_descriptor *)addr;
413
	uint32_t size;
414
415
	DPRINTFN(2, "cmd=%lx\n", cmd);
416
417
	if (sc == NULL)
418
		return (EIO);
419
420
#ifdef COMPAT_FREEBSD32
421
	switch (cmd) {
422
	case USB_GET_REPORT_DESC32:
423
		cmd = _IOC_NEWTYPE(cmd, struct usb_gen_descriptor);
424
		ugd32 = (struct usb_gen_descriptor32 *)addr;
425
		ugd = &local_ugd;
426
		PTRIN_CP(*ugd32, *ugd, ugd_data);
427
		CP(*ugd32, *ugd, ugd_lang_id);
428
		CP(*ugd32, *ugd, ugd_maxlen);
429
		CP(*ugd32, *ugd, ugd_actlen);
430
		CP(*ugd32, *ugd, ugd_offset);
431
		CP(*ugd32, *ugd, ugd_config_index);
432
		CP(*ugd32, *ugd, ugd_string_index);
433
		CP(*ugd32, *ugd, ugd_iface_index);
434
		CP(*ugd32, *ugd, ugd_altif_index);
435
		CP(*ugd32, *ugd, ugd_endpt_index);
436
		CP(*ugd32, *ugd, ugd_report_type);
437
		/* Don't copy reserved */
438
		break;
439
	}
440
#endif
441
442
	/* fixed-length ioctls handling */
443
	switch (cmd) {
444
	case FIONBIO:
445
		/* All handled in the upper FS layer. */
446
		return (0);
447
448
	case USB_GET_REPORT_DESC:
449
		size = MIN(sc->sc_rdesc_size, ugd->ugd_maxlen);
450
		ugd->ugd_actlen = size;
451
#ifdef COMPAT_FREEBSD32
452
		if (ugd32 != NULL)
453
			update_ugd32(ugd, ugd32);
454
#endif
455
		if (ugd->ugd_data == NULL)
456
			return (0);		/* descriptor length only */
457
458
		return (copyout(sc->sc_rdesc, ugd->ugd_data, size));
459
460
	case USB_GET_DEVICEINFO:
461
		return(hid_ioctl(
462
		    sc->sc_dev, USB_GET_DEVICEINFO, (uintptr_t)addr));
463
	}
464
465
	return (EINVAL);
466
}
467
468
static int
469
fido_poll(struct cdev *dev, int events, struct thread *td)
470
{
471
	struct fido_softc *sc = dev->si_drv1;
472
	int revents = 0;
473
474
	if (sc == NULL)
475
                return (POLLHUP);
476
477
	if (events & (POLLOUT | POLLWRNORM) && (sc->sc_fflags & FWRITE))
478
		revents |= events & (POLLOUT | POLLWRNORM);
479
	if (events & (POLLIN | POLLRDNORM) && (sc->sc_fflags & FREAD)) {
480
		if (!sc->sc_state.data)
481
			hidbus_intr_start(sc->sc_dev);
482
		mtx_lock(&sc->sc_mtx);
483
		if (sc->sc_state.data)
484
			revents |= events & (POLLIN | POLLRDNORM);
485
		else {
486
			sc->sc_state.sel = true;
487
			selrecord(td, &sc->sc_rsel);
488
		}
489
		mtx_unlock(&sc->sc_mtx);
490
	}
491
492
	return (revents);
493
}
494
495
static int
496
fido_kqfilter(struct cdev *dev, struct knote *kn)
497
{
498
	struct fido_softc *sc = dev->si_drv1;
499
500
	if (sc == NULL)
501
		return (ENXIO);
502
503
	switch(kn->kn_filter) {
504
	case EVFILT_READ:
505
		if (sc->sc_fflags & FREAD) {
506
			if (!sc->sc_state.data)
507
				hidbus_intr_start(sc->sc_dev);
508
			kn->kn_fop = &fido_filterops_read;
509
			break;
510
		}
511
		/* FALLTHROUGH */
512
	default:
513
		return(EINVAL);
514
	}
515
	kn->kn_hook = sc;
516
517
	knlist_add(&sc->sc_rsel.si_note, kn, 0);
518
	return (0);
519
}
520
521
static int
522
fido_kqread(struct knote *kn, long hint)
523
{
524
	struct fido_softc *sc = kn->kn_hook;
525
	int ret;
526
527
	mtx_assert(&sc->sc_mtx, MA_OWNED);
528
529
	if (sc->dev->si_drv1 == NULL) {
530
		kn->kn_flags |= EV_EOF;
531
		ret = 1;
532
	} else
533
		ret = sc->sc_state.data ? 1 : 0;
534
535
	return (ret);
536
}
537
538
static void
539
fido_kqdetach(struct knote *kn)
540
{
541
	struct fido_softc *sc = kn->kn_hook;
542
543
	knlist_remove(&sc->sc_rsel.si_note, kn, 0);
544
}
545
546
static void
547
fido_notify(struct fido_softc *sc)
548
{
549
	mtx_assert(&sc->sc_mtx, MA_OWNED);
550
551
	if (sc->sc_state.aslp) {
552
		sc->sc_state.aslp = false;
553
		DPRINTFN(5, "waking %p\n", &sc->sc_buf);
554
		wakeup(&sc->sc_buf);
555
	}
556
	if (sc->sc_state.sel) {
557
		sc->sc_state.sel = false;
558
		selwakeuppri(&sc->sc_rsel, PZERO);
559
	}
560
	KNOTE_LOCKED(&sc->sc_rsel.si_note, 0);
561
}
562
563
static device_method_t fido_methods[] = {
564
	/* Device interface */
565
	DEVMETHOD(device_probe,		fido_probe),
566
	DEVMETHOD(device_attach,	fido_attach),
567
	DEVMETHOD(device_detach,	fido_detach),
568
569
	DEVMETHOD_END
570
};
571
572
static driver_t fido_driver = {
573
#ifdef FIDO_MAKE_UHID_ALIAS
574
	"uhid",
575
#else
576
	"fido",
577
#endif
578
	fido_methods,
579
	sizeof(struct fido_softc)
580
};
581
582
#if __FreeBSD_version < 1400014
583
devclass_t fido_devclass;
584
DRIVER_MODULE(fido, hidbus, fido_driver, fido_devclass, NULL, NULL);
585
#else
586
DRIVER_MODULE(fido, hidbus, fido_driver, NULL, NULL);
587
#endif
588
MODULE_DEPEND(fido, hidbus, 1, 1, 1);
589
MODULE_DEPEND(fido, hid, 1, 1, 1);
590
MODULE_DEPEND(fido, usb, 1, 1, 1);
591
MODULE_VERSION(fido, 1);
592
HID_PNP_INFO(fido_devs);
(-)b/sys/dev/hid/hid.h (+4 lines)
Lines 58-63 Link Here
58
#define	HUP_SCALE		0x008c
58
#define	HUP_SCALE		0x008c
59
#define	HUP_CAMERA_CONTROL	0x0090
59
#define	HUP_CAMERA_CONTROL	0x0090
60
#define	HUP_ARCADE		0x0091
60
#define	HUP_ARCADE		0x0091
61
#define	HUP_FIDO		0xf1d0
61
#define	HUP_MICROSOFT		0xff00
62
#define	HUP_MICROSOFT		0xff00
62
63
63
/* Usages, generic desktop */
64
/* Usages, generic desktop */
Lines 162-167 Link Here
162
#define	HUC_HEADPHONE		0x0005
163
#define	HUC_HEADPHONE		0x0005
163
#define	HUC_AC_PAN		0x0238
164
#define	HUC_AC_PAN		0x0238
164
165
166
/* Usages, FIDO */
167
#define	HUF_U2FHID		0x0001
168
165
#define	HID_USAGE2(p,u)		(((p) << 16) | (u))
169
#define	HID_USAGE2(p,u)		(((p) << 16) | (u))
166
#define	HID_GET_USAGE(u)	((u) & 0xffff)
170
#define	HID_GET_USAGE(u)	((u) & 0xffff)
167
#define	HID_GET_USAGE_PAGE(u)	(((u) >> 16) & 0xffff)
171
#define	HID_GET_USAGE_PAGE(u)	(((u) >> 16) & 0xffff)
(-)b/sys/dev/hid/hidbus.c (-26 / +15 lines)
Lines 68-74 struct hidbus_ivars { Link Here
68
	struct mtx			*mtx;		/* child intr mtx */
68
	struct mtx			*mtx;		/* child intr mtx */
69
	hid_intr_t			*intr_handler;	/* executed under mtx*/
69
	hid_intr_t			*intr_handler;	/* executed under mtx*/
70
	void				*intr_ctx;
70
	void				*intr_ctx;
71
	unsigned int			refcnt;		/* protected by mtx */
71
	bool				active;		/* protected by mtx */
72
	struct epoch_context		epoch_ctx;
72
	struct epoch_context		epoch_ctx;
73
	CK_STAILQ_ENTRY(hidbus_ivars)	link;
73
	CK_STAILQ_ENTRY(hidbus_ivars)	link;
74
};
74
};
Lines 403-409 hidbus_child_detached(device_t bus, device_t child) Link Here
403
	struct hidbus_softc *sc = device_get_softc(bus);
403
	struct hidbus_softc *sc = device_get_softc(bus);
404
	struct hidbus_ivars *tlc = device_get_ivars(child);
404
	struct hidbus_ivars *tlc = device_get_ivars(child);
405
405
406
	KASSERT(tlc->refcnt == 0, ("Child device is running"));
406
	KASSERT(!tlc->active, ("Child device is running"));
407
	tlc->mtx = &sc->mtx;
407
	tlc->mtx = &sc->mtx;
408
	tlc->intr_handler = NULL;
408
	tlc->intr_handler = NULL;
409
	tlc->flags &= ~HIDBUS_FLAG_CAN_POLL;
409
	tlc->flags &= ~HIDBUS_FLAG_CAN_POLL;
Lines 428-434 hidbus_child_deleted(device_t bus, device_t child) Link Here
428
	struct hidbus_ivars *tlc = device_get_ivars(child);
428
	struct hidbus_ivars *tlc = device_get_ivars(child);
429
429
430
	sx_xlock(&sc->sx);
430
	sx_xlock(&sc->sx);
431
	KASSERT(tlc->refcnt == 0, ("Child device is running"));
431
	KASSERT(!tlc->active, ("Child device is running"));
432
	CK_STAILQ_REMOVE(&sc->tlcs, tlc, hidbus_ivars, link);
432
	CK_STAILQ_REMOVE(&sc->tlcs, tlc, hidbus_ivars, link);
433
	sx_unlock(&sc->sx);
433
	sx_unlock(&sc->sx);
434
	epoch_call(INPUT_EPOCH, hidbus_ivar_dtor, &tlc->epoch_ctx);
434
	epoch_call(INPUT_EPOCH, hidbus_ivar_dtor, &tlc->epoch_ctx);
Lines 579-585 hidbus_intr(void *context, void *buf, hid_size_t len) Link Here
579
	if (!HID_IN_POLLING_MODE())
579
	if (!HID_IN_POLLING_MODE())
580
		epoch_enter_preempt(INPUT_EPOCH, &et);
580
		epoch_enter_preempt(INPUT_EPOCH, &et);
581
	CK_STAILQ_FOREACH(tlc, &sc->tlcs, link) {
581
	CK_STAILQ_FOREACH(tlc, &sc->tlcs, link) {
582
		if (tlc->refcnt == 0 || tlc->intr_handler == NULL)
582
		if (!tlc->active || tlc->intr_handler == NULL)
583
			continue;
583
			continue;
584
		if (HID_IN_POLLING_MODE()) {
584
		if (HID_IN_POLLING_MODE()) {
585
			if ((tlc->flags & HIDBUS_FLAG_CAN_POLL) != 0)
585
			if ((tlc->flags & HIDBUS_FLAG_CAN_POLL) != 0)
Lines 609-629 hidbus_intr_start(device_t child) Link Here
609
	device_t bus = device_get_parent(child);
609
	device_t bus = device_get_parent(child);
610
	struct hidbus_softc *sc = device_get_softc(bus);
610
	struct hidbus_softc *sc = device_get_softc(bus);
611
	struct hidbus_ivars *ivar = device_get_ivars(child);
611
	struct hidbus_ivars *ivar = device_get_ivars(child);
612
	struct hidbus_ivars *tlc;
613
	bool refcnted = false;
614
	int error;
612
	int error;
615
613
616
	if (sx_xlock_sig(&sc->sx) != 0)
614
	if (sx_xlock_sig(&sc->sx) != 0)
617
		return (EINTR);
615
		return (EINTR);
618
	CK_STAILQ_FOREACH(tlc, &sc->tlcs, link) {
616
	mtx_lock(ivar->mtx);
619
		refcnted |= (tlc->refcnt != 0);
617
	ivar->active = true;
620
		if (tlc == ivar) {
618
	mtx_unlock(ivar->mtx);
621
			mtx_lock(tlc->mtx);
619
	error = HID_INTR_START(device_get_parent(bus));
622
			++tlc->refcnt;
623
			mtx_unlock(tlc->mtx);
624
		}
625
	}
626
	error = refcnted ? 0 : HID_INTR_START(device_get_parent(bus));
627
	sx_unlock(&sc->sx);
620
	sx_unlock(&sc->sx);
628
621
629
	return (error);
622
	return (error);
Lines 636-656 hidbus_intr_stop(device_t child) Link Here
636
	struct hidbus_softc *sc = device_get_softc(bus);
629
	struct hidbus_softc *sc = device_get_softc(bus);
637
	struct hidbus_ivars *ivar = device_get_ivars(child);
630
	struct hidbus_ivars *ivar = device_get_ivars(child);
638
	struct hidbus_ivars *tlc;
631
	struct hidbus_ivars *tlc;
639
	bool refcnted = false;
632
	bool active = false;
640
	int error;
633
	int error;
641
634
642
	if (sx_xlock_sig(&sc->sx) != 0)
635
	if (sx_xlock_sig(&sc->sx) != 0)
643
		return (EINTR);
636
		return (EINTR);
644
	CK_STAILQ_FOREACH(tlc, &sc->tlcs, link) {
637
	mtx_lock(ivar->mtx);
645
		if (tlc == ivar) {
638
	ivar->active = false;
646
			mtx_lock(tlc->mtx);
639
	mtx_unlock(ivar->mtx);
647
			MPASS(tlc->refcnt != 0);
640
	CK_STAILQ_FOREACH(tlc, &sc->tlcs, link)
648
			--tlc->refcnt;
641
		active |= tlc->active;
649
			mtx_unlock(tlc->mtx);
642
	error = active ? 0 : HID_INTR_STOP(device_get_parent(bus));
650
		}
651
		refcnted |= (tlc->refcnt != 0);
652
	}
653
	error = refcnted ? 0 : HID_INTR_STOP(device_get_parent(bus));
654
	sx_unlock(&sc->sx);
643
	sx_unlock(&sc->sx);
655
644
656
	return (error);
645
	return (error);
(-)b/sys/dev/hid/hidquirk.h (+1 lines)
Lines 51-56 Link Here
51
	HQ(IS_XBOX360GP), 	/* device is XBox 360 GamePad */	\
51
	HQ(IS_XBOX360GP), 	/* device is XBox 360 GamePad */	\
52
	HQ(NOWRITE),		/* device does not support writes */	\
52
	HQ(NOWRITE),		/* device does not support writes */	\
53
	HQ(IICHID_SAMPLING),	/* IIC backend runs in sampling mode */	\
53
	HQ(IICHID_SAMPLING),	/* IIC backend runs in sampling mode */	\
54
	HQ(NO_READAHEAD),	/* Disable interrupt after one report */\
54
									\
55
									\
55
	/* Various quirks */						\
56
	/* Various quirks */						\
56
	HQ(HID_IGNORE),		/* device should be ignored by hid class */ \
57
	HQ(HID_IGNORE),		/* device should be ignored by hid class */ \
(-)b/sys/dev/hid/hidraw.c (-8 / +59 lines)
Lines 66-71 __FBSDID("$FreeBSD$"); Link Here
66
#define HID_DEBUG_VAR	hidraw_debug
66
#define HID_DEBUG_VAR	hidraw_debug
67
#include <dev/hid/hid.h>
67
#include <dev/hid/hid.h>
68
#include <dev/hid/hidbus.h>
68
#include <dev/hid/hidbus.h>
69
#include <dev/hid/hidquirk.h>
69
#include <dev/hid/hidraw.h>
70
#include <dev/hid/hidraw.h>
70
71
71
#ifdef HID_DEBUG
72
#ifdef HID_DEBUG
Lines 112-117 struct hidraw_softc { Link Here
112
		bool	uhid:1;		/* driver switched in to uhid mode */
113
		bool	uhid:1;		/* driver switched in to uhid mode */
113
		bool	lock:1;		/* input queue sleepable lock */
114
		bool	lock:1;		/* input queue sleepable lock */
114
		bool	flush:1;	/* do not wait for data in read() */
115
		bool	flush:1;	/* do not wait for data in read() */
116
		bool	nora:1;		/* read-ahead is disabled */
117
		bool	run:1;		/* interrupt handler is started */
115
	} sc_state;
118
	} sc_state;
116
	int sc_fflags;			/* access mode for open lifetime */
119
	int sc_fflags;			/* access mode for open lifetime */
117
120
Lines 271-276 hidraw_detach(device_t self) Link Here
271
	return (0);
274
	return (0);
272
}
275
}
273
276
277
inline static void
278
hidraw_intr_start(struct hidraw_softc *sc)
279
{
280
	bool empty;
281
282
	if (sc->sc_state.nora) {
283
		mtx_lock(&sc->sc_mtx);
284
		empty = (sc->sc_tail == sc->sc_head);
285
		mtx_unlock(&sc->sc_mtx);
286
		if (empty)
287
			hidbus_intr_start(sc->sc_dev);
288
	} else if (!sc->sc_state.run) {
289
		mtx_lock(&sc->sc_mtx);
290
		sc->sc_state.run = true;
291
		mtx_unlock(&sc->sc_mtx);
292
		hidbus_intr_start(sc->sc_dev);
293
	}
294
}
295
296
inline static void
297
hidraw_intr_stop(struct hidraw_softc *sc)
298
{
299
	hidbus_intr_stop(sc->sc_dev);
300
}
301
274
void
302
void
275
hidraw_intr(void *context, void *buf, hid_size_t len)
303
hidraw_intr(void *context, void *buf, hid_size_t len)
276
{
304
{
Lines 371-376 hidraw_open(struct cdev *dev, int flag, int mode, struct thread *td) Link Here
371
	sc->sc_qlen = malloc(sizeof(hid_size_t) * HIDRAW_BUFFER_SIZE, M_DEVBUF,
399
	sc->sc_qlen = malloc(sizeof(hid_size_t) * HIDRAW_BUFFER_SIZE, M_DEVBUF,
372
	    M_ZERO | M_WAITOK);
400
	    M_ZERO | M_WAITOK);
373
401
402
	sc->sc_state.nora = hid_test_quirk(sc->sc_hw, HQ_NO_READAHEAD);
403
	sc->sc_state.run = false;
404
374
	/* Set up interrupt pipe. */
405
	/* Set up interrupt pipe. */
375
	sc->sc_state.immed = false;
406
	sc->sc_state.immed = false;
376
	sc->sc_async = 0;
407
	sc->sc_async = 0;
Lines 379-386 hidraw_open(struct cdev *dev, int flag, int mode, struct thread *td) Link Here
379
	sc->sc_head = sc->sc_tail = 0;
410
	sc->sc_head = sc->sc_tail = 0;
380
	sc->sc_fflags = flag;
411
	sc->sc_fflags = flag;
381
412
382
	hidbus_intr_start(sc->sc_dev);
383
384
	return (0);
413
	return (0);
385
}
414
}
386
415
Lines 392-398 hidraw_dtor(void *data) Link Here
392
	DPRINTF("sc=%p\n", sc);
421
	DPRINTF("sc=%p\n", sc);
393
422
394
	/* Disable interrupts. */
423
	/* Disable interrupts. */
395
	hidbus_intr_stop(sc->sc_dev);
424
	hidraw_intr_stop(sc);
396
425
397
	sc->sc_tail = sc->sc_head = 0;
426
	sc->sc_tail = sc->sc_head = 0;
398
	sc->sc_async = 0;
427
	sc->sc_async = 0;
Lines 418-423 hidraw_read(struct cdev *dev, struct uio *uio, int flag) Link Here
418
	if (sc == NULL)
447
	if (sc == NULL)
419
		return (EIO);
448
		return (EIO);
420
449
450
	hidraw_intr_start(sc);
451
421
	mtx_lock(&sc->sc_mtx);
452
	mtx_lock(&sc->sc_mtx);
422
	error = dev->si_drv1 == NULL ? EIO : hidraw_lock_queue(sc, false);
453
	error = dev->si_drv1 == NULL ? EIO : hidraw_lock_queue(sc, false);
423
	if (error != 0) {
454
	if (error != 0) {
Lines 566-574 hidraw_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, Link Here
566
#endif
597
#endif
567
	void *buf;
598
	void *buf;
568
	struct hidraw_softc *sc;
599
	struct hidraw_softc *sc;
600
	struct hidraw_device_info *hdi;
569
	struct hidraw_gen_descriptor *hgd;
601
	struct hidraw_gen_descriptor *hgd;
570
	struct hidraw_report_descriptor *hrd;
602
	struct hidraw_report_descriptor *hrd;
571
	struct hidraw_devinfo *hdi;
603
	struct hidraw_devinfo *hd;
572
	const char *devname;
604
	const char *devname;
573
	uint32_t size;
605
	uint32_t size;
574
	int id, len;
606
	int id, len;
Lines 788-793 hidraw_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, Link Here
788
		*(int *)addr = 0;	/* XXX: we only support reportid 0? */
820
		*(int *)addr = 0;	/* XXX: we only support reportid 0? */
789
		return (0);
821
		return (0);
790
822
823
	case HIDRAW_GET_DEVICEINFO:
824
		hdi = (struct hidraw_device_info *)addr;
825
		bzero(hdi, sizeof(struct hidraw_device_info));
826
		hdi->hdi_product = sc->sc_hw->idProduct;
827
		hdi->hdi_vendor = sc->sc_hw->idVendor;
828
		hdi->hdi_version = sc->sc_hw->idVersion;
829
		hdi->hdi_bustype = sc->sc_hw->idBus;
830
		strlcpy(hdi->hdi_name, sc->sc_hw->name,
831
		    sizeof(hdi->hdi_name));
832
		strlcpy(hdi->hdi_phys, device_get_nameunit(sc->sc_dev),
833
		    sizeof(hdi->hdi_phys));
834
		strlcpy(hdi->hdi_uniq, sc->sc_hw->serial,
835
		    sizeof(hdi->hdi_uniq));
836
		snprintf(hdi->hdi_release, sizeof(hdi->hdi_release), "%x.%02x",
837
		    sc->sc_hw->idVersion >> 8, sc->sc_hw->idVersion & 0xff);
838
		return(0);
839
791
	case HIDIOCGRDESCSIZE:
840
	case HIDIOCGRDESCSIZE:
792
		*(int *)addr = sc->sc_hw->rdescsize;
841
		*(int *)addr = sc->sc_hw->rdescsize;
793
		return (0);
842
		return (0);
Lines 813-822 hidraw_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, Link Here
813
		return (error);
862
		return (error);
814
863
815
	case HIDIOCGRAWINFO:
864
	case HIDIOCGRAWINFO:
816
		hdi = (struct hidraw_devinfo *)addr;
865
		hd = (struct hidraw_devinfo *)addr;
817
		hdi->bustype = sc->sc_hw->idBus;
866
		hd->bustype = sc->sc_hw->idBus;
818
		hdi->vendor = sc->sc_hw->idVendor;
867
		hd->vendor = sc->sc_hw->idVendor;
819
		hdi->product = sc->sc_hw->idProduct;
868
		hd->product = sc->sc_hw->idProduct;
820
		return (0);
869
		return (0);
821
	}
870
	}
822
871
Lines 882-887 hidraw_poll(struct cdev *dev, int events, struct thread *td) Link Here
882
	if (events & (POLLOUT | POLLWRNORM) && (sc->sc_fflags & FWRITE))
931
	if (events & (POLLOUT | POLLWRNORM) && (sc->sc_fflags & FWRITE))
883
		revents |= events & (POLLOUT | POLLWRNORM);
932
		revents |= events & (POLLOUT | POLLWRNORM);
884
	if (events & (POLLIN | POLLRDNORM) && (sc->sc_fflags & FREAD)) {
933
	if (events & (POLLIN | POLLRDNORM) && (sc->sc_fflags & FREAD)) {
934
		hidraw_intr_start(sc);
885
		mtx_lock(&sc->sc_mtx);
935
		mtx_lock(&sc->sc_mtx);
886
		if (sc->sc_head != sc->sc_tail)
936
		if (sc->sc_head != sc->sc_tail)
887
			revents |= events & (POLLIN | POLLRDNORM);
937
			revents |= events & (POLLIN | POLLRDNORM);
Lines 907-912 hidraw_kqfilter(struct cdev *dev, struct knote *kn) Link Here
907
	switch(kn->kn_filter) {
957
	switch(kn->kn_filter) {
908
	case EVFILT_READ:
958
	case EVFILT_READ:
909
		if (sc->sc_fflags & FREAD) {
959
		if (sc->sc_fflags & FREAD) {
960
			hidraw_intr_start(sc);
910
			kn->kn_fop = &hidraw_filterops_read;
961
			kn->kn_fop = &hidraw_filterops_read;
911
			break;
962
			break;
912
		}
963
		}
(-)b/sys/dev/hid/hidraw.h (+15 lines)
Lines 51-56 struct hidraw_gen_descriptor { Link Here
51
	uint8_t reserved[8];
51
	uint8_t reserved[8];
52
};
52
};
53
53
54
/* Compatible with usb_device_info structure */
55
struct hidraw_device_info {
56
	uint16_t	hdi_product;
57
	uint16_t	hdi_vendor;
58
	uint16_t	hdi_version;
59
	uint8_t		occupied[18];	/* by usb_device_info */
60
	uint16_t	hdi_bustype;
61
	uint8_t		reserved[14];	/* leave space for the future */
62
	char		hdi_name[128];
63
	char		hdi_phys[128];
64
	char		hdi_uniq[64];
65
	char		hdi_release[8];	/* decrypted USB bcdDevice */
66
};
67
54
struct hidraw_report_descriptor {
68
struct hidraw_report_descriptor {
55
	uint32_t	size;
69
	uint32_t	size;
56
	uint8_t		value[HID_MAX_DESCRIPTOR_SIZE];
70
	uint8_t		value[HID_MAX_DESCRIPTOR_SIZE];
Lines 69-74 struct hidraw_devinfo { Link Here
69
#define	HIDRAW_SET_REPORT	_IOW ('U', 24, struct hidraw_gen_descriptor)
83
#define	HIDRAW_SET_REPORT	_IOW ('U', 24, struct hidraw_gen_descriptor)
70
#define	HIDRAW_GET_REPORT_ID	_IOR ('U', 25, int)
84
#define	HIDRAW_GET_REPORT_ID	_IOR ('U', 25, int)
71
#define	HIDRAW_SET_REPORT_DESC	_IOW ('U', 26, struct hidraw_gen_descriptor)
85
#define	HIDRAW_SET_REPORT_DESC	_IOW ('U', 26, struct hidraw_gen_descriptor)
86
#define	HIDRAW_GET_DEVICEINFO	_IOR ('U', 112, struct hidraw_device_info)
72
87
73
/* Linux hidraw-compatible ioctl interface */
88
/* Linux hidraw-compatible ioctl interface */
74
#define	HIDIOCGRDESCSIZE	_IOR('U', 30, int)
89
#define	HIDIOCGRDESCSIZE	_IOR('U', 30, int)
(-)b/sys/dev/hid/ietp.c (-8 / +23 lines)
Lines 105-110 struct ietp_softc { Link Here
105
	device_t		dev;
105
	device_t		dev;
106
106
107
	struct evdev_dev	*evdev;
107
	struct evdev_dev	*evdev;
108
	bool			open;
108
	uint8_t			report_id;
109
	uint8_t			report_id;
109
	hid_size_t		report_len;
110
	hid_size_t		report_len;
110
111
Lines 208-220 static const struct evdev_methods ietp_evdev_methods = { Link Here
208
static int
209
static int
209
ietp_ev_open(struct evdev_dev *evdev)
210
ietp_ev_open(struct evdev_dev *evdev)
210
{
211
{
211
	return (hidbus_intr_start(evdev_get_softc(evdev)));
212
	struct ietp_softc *sc = evdev_get_softc(evdev);
213
	int error;
214
215
	error = hidbus_intr_start(sc->dev);
216
	if (error == 0)
217
		sc->open = true;
218
	return (error);
212
}
219
}
213
220
214
static int
221
static int
215
ietp_ev_close(struct evdev_dev *evdev)
222
ietp_ev_close(struct evdev_dev *evdev)
216
{
223
{
217
	return (hidbus_intr_stop(evdev_get_softc(evdev)));
224
	struct ietp_softc *sc = evdev_get_softc(evdev);
225
	int error;
226
227
	error = hidbus_intr_stop(sc->dev);
228
	if (error == 0)
229
		sc->open = false;
230
	return (error);
218
}
231
}
219
232
220
static int
233
static int
Lines 266-272 ietp_attach(struct ietp_softc *sc) Link Here
266
	evdev_set_id(sc->evdev, hw->idBus, hw->idVendor, hw->idProduct,
279
	evdev_set_id(sc->evdev, hw->idBus, hw->idVendor, hw->idProduct,
267
	    hw->idVersion);
280
	    hw->idVersion);
268
	evdev_set_serial(sc->evdev, hw->serial);
281
	evdev_set_serial(sc->evdev, hw->serial);
269
	evdev_set_methods(sc->evdev, sc->dev, &ietp_evdev_methods);
282
	evdev_set_methods(sc->evdev, sc, &ietp_evdev_methods);
270
	evdev_set_flag(sc->evdev, EVDEV_FLAG_MT_STCOMPAT);
283
	evdev_set_flag(sc->evdev, EVDEV_FLAG_MT_STCOMPAT);
271
	evdev_set_flag(sc->evdev, EVDEV_FLAG_EXT_EPOCH); /* hidbus child */
284
	evdev_set_flag(sc->evdev, EVDEV_FLAG_EXT_EPOCH); /* hidbus child */
272
285
Lines 541-551 ietp_iic_set_absolute_mode(device_t dev, bool enable) Link Here
541
	 * Some ASUS touchpads need to be powered on to enter absolute mode.
554
	 * Some ASUS touchpads need to be powered on to enter absolute mode.
542
	 */
555
	 */
543
	require_wakeup = false;
556
	require_wakeup = false;
544
	for (i = 0; i < nitems(special_fw); i++) {
557
	if (!sc->open) {
545
		if (sc->ic_type == special_fw[i].ic_type &&
558
		for (i = 0; i < nitems(special_fw); i++) {
546
		    sc->product_id == special_fw[i].product_id) {
559
			if (sc->ic_type == special_fw[i].ic_type &&
547
			require_wakeup = true;
560
			    sc->product_id == special_fw[i].product_id) {
548
			break;
561
				require_wakeup = true;
562
				break;
563
			}
549
		}
564
		}
550
	}
565
	}
551
566
(-)b/sys/dev/iicbus/iichid.c (-1 / +2 lines)
Lines 838-844 iichid_intr_start(device_t dev) Link Here
838
838
839
	sc = device_get_softc(dev);
839
	sc = device_get_softc(dev);
840
	DPRINTF(sc, "iichid device open\n");
840
	DPRINTF(sc, "iichid device open\n");
841
	iichid_set_power_state(sc, IICHID_PS_ON, IICHID_PS_NULL);
841
	if (!sc->open)
842
		iichid_set_power_state(sc, IICHID_PS_ON, IICHID_PS_NULL);
842
843
843
	return (0);
844
	return (0);
844
}
845
}
(-)b/sys/dev/usb/input/uhid.c (-1 / +2 lines)
Lines 687-697 static int Link Here
687
uhid_ioctl_post(struct usb_fifo *fifo, u_long cmd, void *addr,
687
uhid_ioctl_post(struct usb_fifo *fifo, u_long cmd, void *addr,
688
    int fflags)
688
    int fflags)
689
{
689
{
690
	struct uhid_softc *sc = usb_fifo_softc(fifo);
690
	int error;
691
	int error;
691
692
692
	switch (cmd) {
693
	switch (cmd) {
693
	case USB_GET_DEVICEINFO:
694
	case USB_GET_DEVICEINFO:
694
		error = ugen_fill_deviceinfo(fifo, addr);
695
		error = ugen_fill_deviceinfo(sc->sc_udev, addr);
695
		break;
696
		break;
696
697
697
	default:
698
	default:
(-)b/sys/dev/usb/input/usbhid.c (-1 / +8 lines)
Lines 69-74 __FBSDID("$FreeBSD$"); Link Here
69
#include <dev/usb/usbhid.h>
69
#include <dev/usb/usbhid.h>
70
#include <dev/usb/usb_core.h>
70
#include <dev/usb/usb_core.h>
71
#include <dev/usb/usb_ioctl.h>
71
#include <dev/usb/usb_ioctl.h>
72
#include <dev/usb/usb_generic.h>
72
#include <dev/usb/usb_util.h>
73
#include <dev/usb/usb_util.h>
73
74
74
#define	USB_DEBUG_VAR usbhid_debug
75
#define	USB_DEBUG_VAR usbhid_debug
Lines 117-122 struct usbhid_xfer_ctx { Link Here
117
	void *cb_ctx;
118
	void *cb_ctx;
118
	int waiters;
119
	int waiters;
119
	bool influx;
120
	bool influx;
121
	bool no_readahead;
120
};
122
};
121
123
122
struct usbhid_softc {
124
struct usbhid_softc {
Lines 275-281 usbhid_intr_handler_cb(struct usbhid_xfer_ctx *xfer_ctx) Link Here
275
	sc->sc_intr_handler(sc->sc_intr_ctx, xfer_ctx->buf,
277
	sc->sc_intr_handler(sc->sc_intr_ctx, xfer_ctx->buf,
276
	    xfer_ctx->req.intr.actlen);
278
	    xfer_ctx->req.intr.actlen);
277
279
278
	return (0);
280
	return (xfer_ctx->no_readahead ? ECANCELED : 0);
279
}
281
}
280
282
281
static int
283
static int
Lines 433-438 usbhid_intr_start(device_t dev) Link Here
433
		.cb = usbhid_intr_handler_cb,
435
		.cb = usbhid_intr_handler_cb,
434
		.cb_ctx = sc,
436
		.cb_ctx = sc,
435
		.buf = sc->sc_intr_buf,
437
		.buf = sc->sc_intr_buf,
438
		.no_readahead = hid_test_quirk(&sc->sc_hw, HQ_NO_READAHEAD),
436
	};
439
	};
437
	sc->sc_xfer_ctx[POLL_XFER(USBHID_INTR_IN_DT)] = (struct usbhid_xfer_ctx) {
440
	sc->sc_xfer_ctx[POLL_XFER(USBHID_INTR_IN_DT)] = (struct usbhid_xfer_ctx) {
438
		.req.intr.maxlen =
441
		.req.intr.maxlen =
Lines 703-708 usbhid_ioctl(device_t dev, unsigned long cmd, uintptr_t data) Link Here
703
		if (error == 0)
706
		if (error == 0)
704
			ucr->ucr_actlen = UGETW(req.ctrl.wLength);
707
			ucr->ucr_actlen = UGETW(req.ctrl.wLength);
705
		break;
708
		break;
709
	case USB_GET_DEVICEINFO:
710
		error = ugen_fill_deviceinfo(sc->sc_udev,
711
		    (struct usb_device_info *)data);
712
		break;
706
	default:
713
	default:
707
		error = EINVAL;
714
		error = EINVAL;
708
	}
715
	}
(-)b/sys/dev/usb/usb_generic.c (-5 / +5 lines)
Lines 53-58 Link Here
53
#include <sys/conf.h>
53
#include <sys/conf.h>
54
#include <sys/fcntl.h>
54
#include <sys/fcntl.h>
55
55
56
#include <dev/evdev/input.h>
57
56
#include <dev/usb/usb.h>
58
#include <dev/usb/usb.h>
57
#include <dev/usb/usb_ioctl.h>
59
#include <dev/usb/usb_ioctl.h>
58
#include <dev/usb/usbdi.h>
60
#include <dev/usb/usbdi.h>
Lines 829-841 ugen_get_iface_driver(struct usb_fifo *f, struct usb_gen_descriptor *ugd) Link Here
829
 * Else: Failure
831
 * Else: Failure
830
 *------------------------------------------------------------------------*/
832
 *------------------------------------------------------------------------*/
831
int
833
int
832
ugen_fill_deviceinfo(struct usb_fifo *f, struct usb_device_info *di)
834
ugen_fill_deviceinfo(struct usb_device *udev, struct usb_device_info *di)
833
{
835
{
834
	struct usb_device *udev;
835
	struct usb_device *hub;
836
	struct usb_device *hub;
836
837
837
	udev = f->udev;
838
839
	bzero(di, sizeof(di[0]));
838
	bzero(di, sizeof(di[0]));
840
839
841
	di->udi_bus = device_get_unit(udev->bus->bdev);
840
	di->udi_bus = device_get_unit(udev->bus->bdev);
Lines 859-864 ugen_fill_deviceinfo(struct usb_fifo *f, struct usb_device_info *di) Link Here
859
	di->udi_mode = udev->flags.usb_mode;
858
	di->udi_mode = udev->flags.usb_mode;
860
	di->udi_power_mode = udev->power_mode;
859
	di->udi_power_mode = udev->power_mode;
861
	di->udi_suspended = udev->flags.peer_suspended;
860
	di->udi_suspended = udev->flags.peer_suspended;
861
	di->udi_bustypeNo = BUS_USB;
862
862
863
	hub = udev->parent_hub;
863
	hub = udev->parent_hub;
864
	if (hub) {
864
	if (hub) {
Lines 2307-2313 ugen_ioctl_post(struct usb_fifo *f, u_long cmd, void *addr, int fflags) Link Here
2307
2307
2308
	case USB_DEVICEINFO:
2308
	case USB_DEVICEINFO:
2309
	case USB_GET_DEVICEINFO:
2309
	case USB_GET_DEVICEINFO:
2310
		error = ugen_fill_deviceinfo(f, addr);
2310
		error = ugen_fill_deviceinfo(f->udev, addr);
2311
		break;
2311
		break;
2312
2312
2313
	case USB_DEVICESTATS:
2313
	case USB_DEVICESTATS:
(-)b/sys/dev/usb/usb_generic.h (-1 / +2 lines)
Lines 31-36 Link Here
31
31
32
extern struct usb_fifo_methods usb_ugen_methods;
32
extern struct usb_fifo_methods usb_ugen_methods;
33
int	ugen_do_request(struct usb_fifo *f, struct usb_ctl_request *ur);
33
int	ugen_do_request(struct usb_fifo *f, struct usb_ctl_request *ur);
34
int	ugen_fill_deviceinfo(struct usb_fifo *f, struct usb_device_info *di);
34
int	ugen_fill_deviceinfo(struct usb_device *udev,
35
	    struct usb_device_info *di);
35
36
36
#endif					/* _USB_GENERIC_H_ */
37
#endif					/* _USB_GENERIC_H_ */
(-)b/sys/dev/usb/usb_ioctl.h (-1 / +2 lines)
Lines 120-126 struct usb_device_info { Link Here
120
	uint8_t	udi_hubport;		/* parent HUB port */
120
	uint8_t	udi_hubport;		/* parent HUB port */
121
	uint8_t	udi_power_mode;		/* see "USB_POWER_MODE_XXX" */
121
	uint8_t	udi_power_mode;		/* see "USB_POWER_MODE_XXX" */
122
	uint8_t	udi_suspended;		/* set if device is suspended */
122
	uint8_t	udi_suspended;		/* set if device is suspended */
123
	uint8_t	udi_reserved[16];	/* leave space for the future */
123
	uint16_t udi_bustypeNo;
124
	uint8_t	udi_reserved[14];	/* leave space for the future */
124
	char	udi_product[128];
125
	char	udi_product[128];
125
	char	udi_vendor[128];
126
	char	udi_vendor[128];
126
	char	udi_serial[64];
127
	char	udi_serial[64];
(-)b/sys/modules/hid/Makefile (+1 lines)
Lines 9-14 SUBDIR = \ Link Here
9
9
10
SUBDIR += \
10
SUBDIR += \
11
	bcm5974 \
11
	bcm5974 \
12
	fido \
12
	hconf \
13
	hconf \
13
	hcons \
14
	hcons \
14
	hgame \
15
	hgame \
(-)b/sys/modules/hid/fido/Makefile (+10 lines)
Added Link Here
1
# $FreeBSD$
2
3
.PATH: ${SRCTOP}/sys/dev/hid
4
5
KMOD=	fido
6
SRCS=	fido.c
7
SRCS+=	opt_hid.h
8
SRCS+=	bus_if.h device_if.h
9
10
.include <bsd.kmod.mk>

Return to bug 263995