kernel - Remove D_KQFILTER flag
[dragonfly.git] / sys / bus / usb / usb.c
... / ...
CommitLineData
1/*
2 * $NetBSD: usb.c,v 1.68 2002/02/20 20:30:12 christos Exp $
3 * $FreeBSD: src/sys/dev/usb/usb.c,v 1.106 2005/03/27 15:31:23 iedowse Exp $
4 * $DragonFly: src/sys/bus/usb/usb.c,v 1.50 2008/09/26 08:21:22 hasso Exp $
5 */
6
7/* Also already merged from NetBSD:
8 * $NetBSD: usb.c,v 1.70 2002/05/09 21:54:32 augustss Exp $
9 * $NetBSD: usb.c,v 1.71 2002/06/01 23:51:04 lukem Exp $
10 * $NetBSD: usb.c,v 1.73 2002/09/23 05:51:19 simonb Exp $
11 * $NetBSD: usb.c,v 1.80 2003/11/07 17:03:25 wiz Exp $
12 */
13
14/*
15 * Copyright (c) 1998 The NetBSD Foundation, Inc.
16 * All rights reserved.
17 *
18 * This code is derived from software contributed to The NetBSD Foundation
19 * by Lennart Augustsson (lennart@augustsson.net) at
20 * Carlstedt Research & Technology.
21 *
22 * Redistribution and use in source and binary forms, with or without
23 * modification, are permitted provided that the following conditions
24 * are met:
25 * 1. Redistributions of source code must retain the above copyright
26 * notice, this list of conditions and the following disclaimer.
27 * 2. Redistributions in binary form must reproduce the above copyright
28 * notice, this list of conditions and the following disclaimer in the
29 * documentation and/or other materials provided with the distribution.
30 * 3. All advertising materials mentioning features or use of this software
31 * must display the following acknowledgement:
32 * This product includes software developed by the NetBSD
33 * Foundation, Inc. and its contributors.
34 * 4. Neither the name of The NetBSD Foundation nor the names of its
35 * contributors may be used to endorse or promote products derived
36 * from this software without specific prior written permission.
37 *
38 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
39 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
40 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
41 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
42 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
43 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
44 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
45 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
46 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
47 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
48 * POSSIBILITY OF SUCH DAMAGE.
49 */
50
51/*
52 * USB specifications and other documentation can be found at
53 * http://www.usb.org/developers/docs/ and
54 * http://www.usb.org/developers/devclass_docs/
55 */
56
57#include <sys/param.h>
58#include <sys/systm.h>
59#include <sys/kernel.h>
60#include <sys/lock.h>
61#include <sys/malloc.h>
62#include <sys/unistd.h>
63#include <sys/module.h>
64#include <sys/bus.h>
65#include <sys/fcntl.h>
66#include <sys/filio.h>
67#include <sys/uio.h>
68#include <sys/kthread.h>
69#include <sys/proc.h>
70#include <sys/conf.h>
71#include <sys/device.h>
72#include <sys/event.h>
73#include <sys/vnode.h>
74#include <sys/signalvar.h>
75#include <sys/sysctl.h>
76#include <sys/thread2.h>
77
78#include <bus/usb/usb.h>
79#include <bus/usb/usbdi.h>
80#include <bus/usb/usbdi_util.h>
81
82#define USBUNIT(d) (minor(d)) /* usb_discover device nodes, kthread */
83#define USB_DEV_MINOR 255 /* event queue device */
84
85MALLOC_DEFINE(M_USB, "USB", "USB");
86MALLOC_DEFINE(M_USBDEV, "USBdev", "USB device");
87MALLOC_DEFINE(M_USBHC, "USBHC", "USB host controller");
88
89#include "usb_if.h"
90
91#include <bus/usb/usbdivar.h>
92#include <bus/usb/usb_quirks.h>
93
94/* Define this unconditionally in case a kernel module is loaded that
95 * has been compiled with debugging options.
96 */
97SYSCTL_NODE(_hw, OID_AUTO, usb, CTLFLAG_RW, 0, "USB debugging");
98
99/*
100 * XXX: This is a hack! If your USB keyboard doesn't work
101 * early at boot, try setting this tunable to 0 from
102 * bootleader:
103 *
104 * set hw.usb.hack_defer_exploration=0
105 */
106static int hack_defer_exploration = 1;
107
108#ifdef USB_DEBUG
109#define DPRINTF(x) if (usbdebug) kprintf x
110#define DPRINTFN(n,x) if (usbdebug>(n)) kprintf x
111int usbdebug = 0;
112SYSCTL_INT(_hw_usb, OID_AUTO, debug, CTLFLAG_RW,
113 &usbdebug, 0, "usb debug level");
114
115/*
116 * 0 - do usual exploration
117 * 1 - do not use timeout exploration
118 * >1 - do no exploration
119 */
120int usb_noexplore = 0;
121#else
122#define DPRINTF(x)
123#define DPRINTFN(n,x)
124#endif
125
126struct usb_softc {
127 cdev_t sc_usbdev;
128 TAILQ_ENTRY(usb_softc) sc_coldexplist; /* cold needs-explore list */
129 usbd_bus_handle sc_bus; /* USB controller */
130 struct usbd_port sc_port; /* dummy port for root hub */
131
132 struct thread *sc_event_thread;
133
134 char sc_dying;
135};
136
137struct usb_taskq {
138 TAILQ_HEAD(, usb_task) tasks;
139 struct thread *task_thread_proc;
140 const char *name;
141 int taskcreated; /* task thread exists. */
142};
143static struct usb_taskq usb_taskq[USB_NUM_TASKQS];
144
145d_open_t usbopen;
146d_close_t usbclose;
147d_read_t usbread;
148d_ioctl_t usbioctl;
149d_kqfilter_t usbkqfilter;
150
151static void usbfilt_detach(struct knote *);
152static int usbfilt(struct knote *, long);
153
154struct dev_ops usb_ops = {
155 { "usb", USB_CDEV_MAJOR, 0 },
156 .d_open = usbopen,
157 .d_close = usbclose,
158 .d_read = usbread,
159 .d_ioctl = usbioctl,
160 .d_kqfilter = usbkqfilter
161};
162
163static void usb_discover(device_t);
164static bus_child_detached_t usb_child_detached;
165static void usb_create_event_thread(device_t);
166static void usb_event_thread(void *);
167static void usb_task_thread(void *);
168
169static cdev_t usb_dev; /* The /dev/usb device. */
170static int usb_ndevs; /* Number of /dev/usbN devices. */
171/* Busses to explore at the end of boot-time device configuration */
172static TAILQ_HEAD(, usb_softc) usb_coldexplist =
173 TAILQ_HEAD_INITIALIZER(usb_coldexplist);
174
175#define USB_MAX_EVENTS 100
176struct usb_event_q {
177 struct usb_event ue;
178 TAILQ_ENTRY(usb_event_q) next;
179};
180static TAILQ_HEAD(, usb_event_q) usb_events =
181 TAILQ_HEAD_INITIALIZER(usb_events);
182static int usb_nevents = 0;
183static struct kqinfo usb_kqevent;
184static struct proc *usb_async_proc; /* process that wants USB SIGIO */
185static int usb_dev_open = 0;
186static void usb_add_event(int, struct usb_event *);
187
188static int usb_get_next_event(struct usb_event *);
189
190static const char *usbrev_str[] = USBREV_STR;
191
192static device_probe_t usb_match;
193static device_attach_t usb_attach;
194static device_detach_t usb_detach;
195
196static devclass_t usb_devclass;
197
198static kobj_method_t usb_methods[] = {
199 DEVMETHOD(device_probe, usb_match),
200 DEVMETHOD(device_attach, usb_attach),
201 DEVMETHOD(device_detach, usb_detach),
202 DEVMETHOD(bus_child_detached, usb_child_detached),
203 DEVMETHOD(device_suspend, bus_generic_suspend),
204 DEVMETHOD(device_resume, bus_generic_resume),
205 DEVMETHOD(device_shutdown, bus_generic_shutdown),
206 {0,0}
207};
208
209static driver_t usb_driver = {
210 "usb",
211 usb_methods,
212 sizeof(struct usb_softc)
213};
214
215MODULE_DEPEND(usb, usb, 1, 1, 1);
216MODULE_VERSION(usb, 1);
217
218static int
219usb_match(device_t self)
220{
221 DPRINTF(("usb_match\n"));
222 return (UMATCH_GENERIC);
223}
224
225static int
226usb_attach(device_t self)
227{
228 struct usb_softc *sc = device_get_softc(self);
229 void *aux = device_get_ivars(self);
230 cdev_t tmp_dev;
231 usbd_device_handle dev;
232 usbd_status err;
233 int usbrev;
234 int speed;
235 struct usb_event ue;
236
237 TUNABLE_INT_FETCH("hw.usb.hack_defer_exploration",
238 &hack_defer_exploration);
239
240 DPRINTF(("usb_attach\n"));
241
242 usbd_init();
243 sc->sc_bus = aux;
244 sc->sc_bus->usbctl = sc;
245 sc->sc_port.power = USB_MAX_POWER;
246
247 usbrev = sc->sc_bus->usbrev;
248 device_printf(self, "USB revision %s", usbrev_str[usbrev]);
249 switch (usbrev) {
250 case USBREV_1_0:
251 case USBREV_1_1:
252 speed = USB_SPEED_FULL;
253 break;
254 case USBREV_2_0:
255 speed = USB_SPEED_HIGH;
256 break;
257 default:
258 kprintf(", not supported\n");
259 sc->sc_dying = 1;
260 return ENXIO;
261 }
262 kprintf("\n");
263
264 /* Make sure not to use tsleep() if we are cold booting. */
265 if (hack_defer_exploration && cold)
266 sc->sc_bus->use_polling++;
267
268 ue.u.ue_ctrlr.ue_bus = device_get_unit(self);
269 usb_add_event(USB_EVENT_CTRLR_ATTACH, &ue);
270
271#ifdef USB_USE_SOFTINTR
272 callout_init(&sc->sc_bus->softi);
273#endif
274
275 err = usbd_new_device(self, sc->sc_bus, 0, speed, 0, &sc->sc_port);
276 if (!err) {
277 dev = sc->sc_port.device;
278 if (dev->hub == NULL) {
279 sc->sc_dying = 1;
280 device_printf(self,
281 "root device is not a hub\n");
282 return ENXIO;
283 }
284 sc->sc_bus->root_hub = dev;
285#if 1
286 /*
287 * Turning this code off will delay attachment of USB devices
288 * until the USB event thread is running, which means that
289 * the keyboard will not work until after cold boot.
290 */
291 if (cold) {
292 if (hack_defer_exploration) {
293 /* Explore high-speed busses before others. */
294 if (speed == USB_SPEED_HIGH)
295 dev->hub->explore(sc->sc_bus->root_hub);
296 else
297 TAILQ_INSERT_TAIL(&usb_coldexplist, sc,
298 sc_coldexplist);
299 } else {
300 /*
301 * XXX Exploring high speed devices here will
302 * hang the system.
303 */
304 if (speed != USB_SPEED_HIGH)
305 dev->hub->explore(sc->sc_bus->root_hub);
306 }
307 }
308#endif
309 } else {
310 device_printf(self,
311 "root hub problem, error=%d\n", err);
312 sc->sc_dying = 1;
313 }
314 if (hack_defer_exploration && cold)
315 sc->sc_bus->use_polling--;
316
317 usb_create_event_thread(self);
318
319 /*
320 * The per controller devices (used for usb_discover)
321 * XXX This is redundant now, but old usbd's will want it
322 */
323 tmp_dev = make_dev(&usb_ops, device_get_unit(self),
324 UID_ROOT, GID_OPERATOR, 0660,
325 "usb%d", device_get_unit(self));
326 sc->sc_usbdev = reference_dev(tmp_dev);
327 if (usb_ndevs++ == 0) {
328 /* The device spitting out events */
329 tmp_dev = make_dev(&usb_ops, USB_DEV_MINOR,
330 UID_ROOT, GID_OPERATOR, 0660, "usb");
331 usb_dev = reference_dev(tmp_dev);
332 }
333
334 return 0;
335}
336
337static const char *taskq_names[] = USB_TASKQ_NAMES;
338
339void
340usb_create_event_thread(device_t self)
341{
342 struct usb_softc *sc = device_get_softc(self);
343 int i;
344
345 if (kthread_create(usb_event_thread, self, &sc->sc_event_thread,
346 "%s", device_get_nameunit(self))) {
347 device_printf(self,
348 "unable to create event thread for\n");
349 panic("usb_create_event_thread");
350 }
351
352 for (i = 0; i < USB_NUM_TASKQS; i++) {
353 struct usb_taskq *taskq = &usb_taskq[i];
354
355 if (taskq->taskcreated == 0) {
356 taskq->taskcreated = 1;
357 taskq->name = taskq_names[i];
358 TAILQ_INIT(&taskq->tasks);
359 if (kthread_create(usb_task_thread, taskq,
360 &taskq->task_thread_proc, taskq->name)) {
361 kprintf("unable to create task thread\n");
362 panic("usb_create_event_thread task");
363 }
364 }
365 }
366}
367
368/*
369 * Add a task to be performed by the task thread. This function can be
370 * called from any context and the task will be executed in a process
371 * context ASAP.
372 */
373void
374usb_add_task(usbd_device_handle dev, struct usb_task *task, int queue)
375{
376 struct usb_taskq *taskq;
377
378 crit_enter();
379
380 taskq = &usb_taskq[queue];
381 if (task->queue == -1) {
382 DPRINTFN(2,("usb_add_task: task=%p\n", task));
383 TAILQ_INSERT_TAIL(&taskq->tasks, task, next);
384 task->queue = queue;
385 } else {
386 DPRINTFN(3,("usb_add_task: task=%p on q\n", task));
387 }
388 wakeup(&taskq->tasks);
389
390 crit_exit();
391}
392
393void
394usb_do_task(usbd_device_handle dev, struct usb_task *task, int queue,
395 int time_out)
396{
397 struct usb_taskq *taskq;
398
399 crit_enter();
400
401 taskq = &usb_taskq[queue];
402 if (task->queue == -1) {
403 DPRINTFN(2,("usb_add_task: task=%p\n", task));
404 TAILQ_INSERT_TAIL(&taskq->tasks, task, next);
405 task->queue = queue;
406 } else {
407 DPRINTFN(3,("usb_add_task: task=%p on q\n", task));
408 }
409 wakeup(&taskq->tasks);
410
411 /* Wait until task is finished */
412 tsleep((&taskq->tasks + 1), 0, "usbdotsk", time_out);
413
414 crit_exit();
415}
416
417void
418usb_rem_task(usbd_device_handle dev, struct usb_task *task)
419{
420 crit_enter();
421 if (task->queue != -1) {
422 TAILQ_REMOVE(&usb_taskq[task->queue].tasks, task, next);
423 task->queue = -1;
424 }
425 crit_exit();
426}
427
428void
429usb_event_thread(void *arg)
430{
431 device_t self = arg;
432 struct usb_softc *sc = device_get_softc(self);
433
434 DPRINTF(("usb_event_thread: start\n"));
435
436 /*
437 * In case this controller is a companion controller to an
438 * EHCI controller we need to wait until the EHCI controller
439 * has grabbed the port.
440 * XXX It would be nicer to do this with a tsleep(), but I don't
441 * know how to synchronize the creation of the threads so it
442 * will work.
443 */
444 usb_delay_ms(sc->sc_bus, 500);
445
446 crit_enter();
447
448 /* Make sure first discover does something. */
449 sc->sc_bus->needs_explore = 1;
450 usb_discover(self);
451
452 while (!sc->sc_dying) {
453#ifdef USB_DEBUG
454 if (usb_noexplore < 2)
455#endif
456 usb_discover(self);
457#ifdef USB_DEBUG
458 tsleep(&sc->sc_bus->needs_explore, 0, "usbevt",
459 usb_noexplore ? 0 : hz * 60);
460#else
461 tsleep(&sc->sc_bus->needs_explore, 0, "usbevt", hz * 60);
462#endif
463 DPRINTFN(2,("usb_event_thread: woke up\n"));
464 }
465 sc->sc_event_thread = NULL;
466
467 crit_exit();
468
469 /* In case parent is waiting for us to exit. */
470 wakeup(sc);
471
472 DPRINTF(("usb_event_thread: exit\n"));
473 kthread_exit();
474}
475
476void
477usb_task_thread(void *arg)
478{
479 struct usb_task *task;
480 struct usb_taskq *taskq;
481
482 crit_enter();
483
484 taskq = arg;
485 DPRINTF(("usb_task_thread: start taskq %s\n", taskq->name));
486
487 while (usb_ndevs > 0) {
488 task = TAILQ_FIRST(&taskq->tasks);
489 if (task == NULL) {
490 tsleep(&taskq->tasks, 0, "usbtsk", 0);
491 task = TAILQ_FIRST(&taskq->tasks);
492 }
493 DPRINTFN(2,("usb_task_thread: woke up task=%p\n", task));
494 if (task != NULL) {
495 TAILQ_REMOVE(&taskq->tasks, task, next);
496 task->queue = -1;
497 crit_exit();
498 task->fun(task->arg);
499 crit_enter();
500 wakeup((&taskq->tasks + 1));
501 }
502 }
503
504 crit_exit();
505
506 taskq->taskcreated = 0;
507 wakeup(&taskq->taskcreated);
508
509 DPRINTF(("usb_event_thread: exit\n"));
510}
511
512int
513usbopen(struct dev_open_args *ap)
514{
515 cdev_t dev = ap->a_head.a_dev;
516 int unit = USBUNIT(dev);
517 struct usb_softc *sc;
518
519 if (unit == USB_DEV_MINOR) {
520 if (usb_dev_open)
521 return (EBUSY);
522 usb_dev_open = 1;
523 usb_async_proc = NULL;
524 return (0);
525 }
526
527 sc = devclass_get_softc(usb_devclass, unit);
528 if (sc == NULL)
529 return (ENXIO);
530
531 if (sc->sc_dying)
532 return (EIO);
533
534 return (0);
535}
536
537int
538usbread(struct dev_read_args *ap)
539{
540 cdev_t dev = ap->a_head.a_dev;
541 struct uio *uio = ap->a_uio;
542 struct usb_event ue;
543 int unit = USBUNIT(dev);
544 int error, n;
545
546 if (unit != USB_DEV_MINOR)
547 return (ENODEV);
548
549 if (uio->uio_resid != sizeof(struct usb_event))
550 return (EINVAL);
551
552 error = 0;
553 crit_enter();
554 for (;;) {
555 n = usb_get_next_event(&ue);
556 if (n != 0)
557 break;
558 if (ap->a_ioflag & IO_NDELAY) {
559 error = EWOULDBLOCK;
560 break;
561 }
562 error = tsleep(&usb_events, PCATCH, "usbrea", 0);
563 if (error)
564 break;
565 }
566 crit_exit();
567 if (!error)
568 error = uiomove((void *)&ue, uio->uio_resid, uio);
569
570 return (error);
571}
572
573int
574usbclose(struct dev_close_args *ap)
575{
576 cdev_t dev = ap->a_head.a_dev;
577 int unit = USBUNIT(dev);
578
579 if (unit == USB_DEV_MINOR) {
580 usb_async_proc = NULL;
581 usb_dev_open = 0;
582 }
583
584 return (0);
585}
586
587int
588usbioctl(struct dev_ioctl_args *ap)
589{
590 cdev_t devt = ap->a_head.a_dev;
591 struct usb_softc *sc;
592 int unit = USBUNIT(devt);
593
594 if (unit == USB_DEV_MINOR) {
595 switch (ap->a_cmd) {
596 case FIOASYNC:
597 if (*(int *)ap->a_data)
598 usb_async_proc = curproc;
599 else
600 usb_async_proc = NULL;
601 return (0);
602
603 default:
604 return (EINVAL);
605 }
606 }
607
608 sc = devclass_get_softc(usb_devclass, unit);
609
610 if (sc->sc_dying)
611 return (EIO);
612
613 switch (ap->a_cmd) {
614 /* This part should be deleted */
615 case USB_DISCOVER:
616 break;
617 case USB_REQUEST:
618 {
619 struct usb_ctl_request *ur = (void *)ap->a_data;
620 size_t len = UGETW(ur->ucr_request.wLength);
621 struct iovec iov;
622 struct uio uio;
623 void *ptr = 0;
624 int addr = ur->ucr_addr;
625 usbd_status err;
626 int error = 0;
627
628 DPRINTF(("usbioctl: USB_REQUEST addr=%d len=%zu\n", addr, len));
629 if (len > 32768)
630 return (EINVAL);
631 if (addr < 0 || addr >= USB_MAX_DEVICES ||
632 sc->sc_bus->devices[addr] == 0)
633 return (EINVAL);
634 if (len != 0) {
635 iov.iov_base = (caddr_t)ur->ucr_data;
636 iov.iov_len = len;
637 uio.uio_iov = &iov;
638 uio.uio_iovcnt = 1;
639 uio.uio_resid = len;
640 uio.uio_offset = 0;
641 uio.uio_segflg = UIO_USERSPACE;
642 uio.uio_rw =
643 ur->ucr_request.bmRequestType & UT_READ ?
644 UIO_READ : UIO_WRITE;
645 uio.uio_td = curthread;
646 ptr = kmalloc(len, M_TEMP, M_WAITOK);
647 if (uio.uio_rw == UIO_WRITE) {
648 error = uiomove(ptr, len, &uio);
649 if (error)
650 goto ret;
651 }
652 }
653 err = usbd_do_request_flags(sc->sc_bus->devices[addr],
654 &ur->ucr_request, ptr, ur->ucr_flags, &ur->ucr_actlen,
655 USBD_DEFAULT_TIMEOUT);
656 if (err) {
657 error = EIO;
658 goto ret;
659 }
660 if (len != 0) {
661 if (uio.uio_rw == UIO_READ) {
662 error = uiomove(ptr, len, &uio);
663 if (error)
664 goto ret;
665 }
666 }
667 ret:
668 if (ptr)
669 kfree(ptr, M_TEMP);
670 return (error);
671 }
672
673 case USB_DEVICEINFO:
674 {
675 struct usb_device_info *di = (void *)ap->a_data;
676 int addr = di->udi_addr;
677 usbd_device_handle dev;
678
679 if (addr < 1 || addr >= USB_MAX_DEVICES)
680 return (EINVAL);
681 dev = sc->sc_bus->devices[addr];
682 if (dev == NULL)
683 return (ENXIO);
684 usbd_fill_deviceinfo(dev, di, 1);
685 break;
686 }
687
688 case USB_DEVICESTATS:
689 *(struct usb_device_stats *)ap->a_data = sc->sc_bus->stats;
690 break;
691
692 default:
693 return (EINVAL);
694 }
695 return (0);
696}
697
698static struct filterops usbfiltops =
699 { FILTEROP_ISFD, NULL, usbfilt_detach, usbfilt };
700
701int
702usbkqfilter(struct dev_kqfilter_args *ap)
703{
704 cdev_t dev = ap->a_head.a_dev;
705 struct knote *kn = ap->a_kn;
706 struct klist *klist;
707
708 ap->a_result = 0;
709
710 switch (kn->kn_filter) {
711 case EVFILT_READ:
712 kn->kn_fop = &usbfiltops;
713 kn->kn_hook = (caddr_t)dev;
714 break;
715 default:
716 ap->a_result = EOPNOTSUPP;
717 return (0);
718 }
719
720 klist = &usb_kqevent.ki_note;
721 knote_insert(klist, kn);
722
723 return (0);
724}
725
726static void
727usbfilt_detach(struct knote *kn)
728{
729 struct klist *klist;
730
731 klist = &usb_kqevent.ki_note;
732 knote_remove(klist, kn);
733}
734
735static int
736usbfilt(struct knote *kn, long hint)
737{
738 cdev_t dev = (cdev_t)kn->kn_hook;
739 int unit = USBUNIT(dev);
740 int ready = 0;
741
742 if (unit == USB_DEV_MINOR) {
743 crit_enter();
744 if (usb_nevents > 0)
745 ready = 1;
746 crit_exit();
747 }
748
749 return (ready);
750}
751
752/* Explore device tree from the root. */
753static void
754usb_discover(device_t self)
755{
756 struct usb_softc *sc = device_get_softc(self);
757
758 DPRINTFN(2,("usb_discover\n"));
759#ifdef USB_DEBUG
760 if (usb_noexplore > 1)
761 return;
762#endif
763
764 /*
765 * We need mutual exclusion while traversing the device tree,
766 * but this is guaranteed since this function is only called
767 * from the event thread for the controller.
768 */
769 crit_enter();
770 while (sc->sc_bus->needs_explore && !sc->sc_dying) {
771 sc->sc_bus->needs_explore = 0;
772
773 crit_exit();
774 sc->sc_bus->root_hub->hub->explore(sc->sc_bus->root_hub);
775 crit_enter();
776
777 }
778 crit_exit();
779}
780
781void
782usb_needs_explore(usbd_device_handle dev)
783{
784 DPRINTFN(2,("usb_needs_explore\n"));
785 dev->bus->needs_explore = 1;
786 wakeup(&dev->bus->needs_explore);
787}
788
789/* Called from a critical section */
790int
791usb_get_next_event(struct usb_event *ue)
792{
793 struct usb_event_q *ueq;
794
795 if (usb_nevents <= 0)
796 return (0);
797 ueq = TAILQ_FIRST(&usb_events);
798#ifdef DIAGNOSTIC
799 if (ueq == NULL) {
800 kprintf("usb: usb_nevents got out of sync! %d\n", usb_nevents);
801 usb_nevents = 0;
802 return (0);
803 }
804#endif
805 if (ue)
806 *ue = ueq->ue;
807 TAILQ_REMOVE(&usb_events, ueq, next);
808 kfree(ueq, M_USBDEV);
809 usb_nevents--;
810 return (1);
811}
812
813void
814usbd_add_dev_event(int type, usbd_device_handle udev)
815{
816 struct usb_event ue;
817
818 usbd_fill_deviceinfo(udev, &ue.u.ue_device, USB_EVENT_IS_ATTACH(type));
819 usb_add_event(type, &ue);
820}
821
822void
823usbd_add_drv_event(int type, usbd_device_handle udev, device_t dev)
824{
825 struct usb_event ue;
826
827 ue.u.ue_driver.ue_cookie = udev->cookie;
828 strncpy(ue.u.ue_driver.ue_devname, device_get_nameunit(dev),
829 sizeof ue.u.ue_driver.ue_devname);
830 usb_add_event(type, &ue);
831}
832
833void
834usb_add_event(int type, struct usb_event *uep)
835{
836 struct usb_event_q *ueq;
837 struct timeval thetime;
838
839 ueq = kmalloc(sizeof *ueq, M_USBDEV, M_INTWAIT);
840 ueq->ue = *uep;
841 ueq->ue.ue_type = type;
842 microtime(&thetime);
843 TIMEVAL_TO_TIMESPEC(&thetime, &ueq->ue.ue_time);
844
845 crit_enter();
846 if (USB_EVENT_IS_DETACH(type)) {
847 struct usb_event_q *ueqi, *ueqi_next;
848
849 for (ueqi = TAILQ_FIRST(&usb_events); ueqi; ueqi = ueqi_next) {
850 ueqi_next = TAILQ_NEXT(ueqi, next);
851 if (ueqi->ue.u.ue_driver.ue_cookie.cookie ==
852 uep->u.ue_device.udi_cookie.cookie) {
853 TAILQ_REMOVE(&usb_events, ueqi, next);
854 kfree(ueqi, M_USBDEV);
855 usb_nevents--;
856 ueqi_next = TAILQ_FIRST(&usb_events);
857 }
858 }
859 }
860 if (usb_nevents >= USB_MAX_EVENTS) {
861 /* Too many queued events, drop an old one. */
862 DPRINTF(("usb: event dropped\n"));
863 usb_get_next_event(NULL);
864 }
865 TAILQ_INSERT_TAIL(&usb_events, ueq, next);
866 usb_nevents++;
867 wakeup(&usb_events);
868 KNOTE(&usb_kqevent.ki_note, 0);
869 if (usb_async_proc != NULL) {
870 ksignal(usb_async_proc, SIGIO);
871 }
872 crit_exit();
873}
874
875void
876usb_schedsoftintr(usbd_bus_handle bus)
877{
878 DPRINTFN(10,("usb_schedsoftintr: polling=%d\n", bus->use_polling));
879#ifdef USB_USE_SOFTINTR
880 if (bus->use_polling) {
881 bus->methods->soft_intr(bus);
882 } else {
883 if (!callout_pending(&bus->softi))
884 callout_reset(&bus->softi, 0, bus->methods->soft_intr,
885 bus);
886 }
887#else
888 bus->methods->soft_intr(bus);
889#endif /* USB_USE_SOFTINTR */
890}
891
892static int
893usb_detach(device_t self)
894{
895 struct usb_softc *sc = device_get_softc(self);
896 struct usb_event ue;
897
898 DPRINTF(("usb_detach: start\n"));
899
900 sc->sc_dying = 1;
901
902 /* Make all devices disconnect. */
903 if (sc->sc_port.device != NULL)
904 usb_disconnect_port(&sc->sc_port, self);
905
906 /* Kill off event thread. */
907 if (sc->sc_event_thread != NULL) {
908 wakeup(&sc->sc_bus->needs_explore);
909 if (tsleep(sc, 0, "usbdet", hz * 60))
910 device_printf(self,
911 "event thread didn't die\n");
912 DPRINTF(("usb_detach: event thread dead\n"));
913 }
914
915 release_dev(sc->sc_usbdev);
916
917 if (--usb_ndevs == 0) {
918 int i;
919
920 release_dev(usb_dev);
921 dev_ops_remove_minor(&usb_ops, USB_DEV_MINOR);
922 usb_dev = NULL;
923
924 for (i = 0; i < USB_NUM_TASKQS; i++) {
925 struct usb_taskq *taskq = &usb_taskq[i];
926 wakeup(&taskq->tasks);
927 if (tsleep(&taskq->taskcreated, 0, "usbtdt",
928 hz * 60)) {
929 kprintf("usb task thread %s didn't die\n",
930 taskq->name);
931 }
932 }
933 }
934
935 usbd_finish();
936
937#ifdef USB_USE_SOFTINTR
938 callout_stop(&sc->sc_bus->softi);
939#endif
940
941 ue.u.ue_ctrlr.ue_bus = device_get_unit(self);
942 usb_add_event(USB_EVENT_CTRLR_DETACH, &ue);
943
944 return (0);
945}
946
947static void
948usb_child_detached(device_t self, device_t child)
949{
950 struct usb_softc *sc = device_get_softc(self);
951
952 /* XXX, should check it is the right device. */
953 sc->sc_port.device = NULL;
954}
955
956/* Explore USB busses at the end of device configuration */
957static void
958usb_cold_explore(void *arg)
959{
960 struct usb_softc *sc;
961
962 TUNABLE_INT_FETCH("hw.usb.hack_defer_exploration",
963 &hack_defer_exploration);
964
965 if (!hack_defer_exploration)
966 return;
967
968 KASSERT(cold || TAILQ_EMPTY(&usb_coldexplist),
969 ("usb_cold_explore: busses to explore when !cold"));
970 while (!TAILQ_EMPTY(&usb_coldexplist)) {
971 sc = TAILQ_FIRST(&usb_coldexplist);
972 TAILQ_REMOVE(&usb_coldexplist, sc, sc_coldexplist);
973
974 sc->sc_bus->use_polling++;
975 sc->sc_port.device->hub->explore(sc->sc_bus->root_hub);
976 sc->sc_bus->use_polling--;
977 }
978}
979
980struct usbd_bus *
981usb_getbushandle(struct usb_softc *sc)
982{
983 return (sc->sc_bus);
984}
985
986
987SYSINIT(usb_cold_explore, SI_SUB_CONFIGURE, SI_ORDER_MIDDLE,
988 usb_cold_explore, NULL);
989
990DRIVER_MODULE(usb, ohci, usb_driver, usb_devclass, 0, 0);
991DRIVER_MODULE(usb, uhci, usb_driver, usb_devclass, 0, 0);
992DRIVER_MODULE(usb, ehci, usb_driver, usb_devclass, 0, 0);