Merge from vendor branch OPENSSL:
[dragonfly.git] / sys / bus / usb / usb.c
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.95 2003/11/09 23:54:21 joe Exp $
4  * $DragonFly: src/sys/bus/usb/usb.c,v 1.14 2004/05/19 22:52:39 dillon 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  */
12
13 /*
14  * Copyright (c) 1998 The NetBSD Foundation, Inc.
15  * All rights reserved.
16  *
17  * This code is derived from software contributed to The NetBSD Foundation
18  * by Lennart Augustsson (lennart@augustsson.net) at
19  * Carlstedt Research & Technology.
20  *
21  * Redistribution and use in source and binary forms, with or without
22  * modification, are permitted provided that the following conditions
23  * are met:
24  * 1. Redistributions of source code must retain the above copyright
25  *    notice, this list of conditions and the following disclaimer.
26  * 2. Redistributions in binary form must reproduce the above copyright
27  *    notice, this list of conditions and the following disclaimer in the
28  *    documentation and/or other materials provided with the distribution.
29  * 3. All advertising materials mentioning features or use of this software
30  *    must display the following acknowledgement:
31  *        This product includes software developed by the NetBSD
32  *        Foundation, Inc. and its contributors.
33  * 4. Neither the name of The NetBSD Foundation nor the names of its
34  *    contributors may be used to endorse or promote products derived
35  *    from this software without specific prior written permission.
36  *
37  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
38  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
39  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
40  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
41  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
42  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
43  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
44  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
45  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
47  * POSSIBILITY OF SUCH DAMAGE.
48  */
49
50 /*
51  * USB specifications and other documentation can be found at
52  * http://www.usb.org/developers/data/ and
53  * http://www.usb.org/developers/index.html .
54  */
55
56 #include <sys/param.h>
57 #include <sys/systm.h>
58 #include <sys/kernel.h>
59 #include <sys/lock.h>
60 #include <sys/malloc.h>
61 #if defined(__FreeBSD__) && __FreeBSD_version >= 500000
62 #include <sys/mutex.h>
63 #endif
64 #if defined(__NetBSD__) || defined(__OpenBSD__)
65 #include <sys/device.h>
66 #elif defined(__FreeBSD__) || defined(__DragonFly__)
67 #include <sys/unistd.h>
68 #include <sys/module.h>
69 #include <sys/bus.h>
70 #include <sys/filio.h>
71 #include <sys/uio.h>
72 #endif
73 #include <sys/kthread.h>
74 #include <sys/proc.h>
75 #include <sys/conf.h>
76 #include <sys/poll.h>
77 #if defined(__FreeBSD__) && __FreeBSD_version >= 500014
78 #include <sys/selinfo.h>
79 #else
80 #include <sys/select.h>
81 #endif
82 #include <sys/vnode.h>
83 #include <sys/signalvar.h>
84 #include <sys/sysctl.h>
85
86 #include "usb.h"
87 #include "usbdi.h"
88 #include "usbdi_util.h"
89
90 #define USBUNIT(d)      (minor(d))      /* usb_discover device nodes, kthread */
91 #define USB_DEV_MINOR   255             /* event queue device */
92
93 #if defined(__FreeBSD__) || defined(__DragonFly__)
94 MALLOC_DEFINE(M_USB, "USB", "USB");
95 MALLOC_DEFINE(M_USBDEV, "USBdev", "USB device");
96 MALLOC_DEFINE(M_USBHC, "USBHC", "USB host controller");
97
98 #include "usb_if.h"
99 #endif /* defined(__FreeBSD__) */
100
101 #include <machine/bus.h>
102
103 #include "usbdivar.h"
104 #include "usb_quirks.h"
105
106 /* Define this unconditionally in case a kernel module is loaded that
107  * has been compiled with debugging options.
108  */
109 SYSCTL_NODE(_hw, OID_AUTO, usb, CTLFLAG_RW, 0, "USB debugging");
110
111 #ifdef USB_DEBUG
112 #define DPRINTF(x)      if (usbdebug) logprintf x
113 #define DPRINTFN(n,x)   if (usbdebug>(n)) logprintf x
114 int     usbdebug = 0;
115 SYSCTL_INT(_hw_usb, OID_AUTO, debug, CTLFLAG_RW,
116            &usbdebug, 0, "usb debug level");
117 /*
118  * 0  - do usual exploration
119  * 1  - do not use timeout exploration
120  * >1 - do no exploration
121  */
122 int     usb_noexplore = 0;
123 #else
124 #define DPRINTF(x)
125 #define DPRINTFN(n,x)
126 #endif
127
128 struct usb_softc {
129         USBBASEDEVICE   sc_dev;         /* base device */
130         usbd_bus_handle sc_bus;         /* USB controller */
131         struct usbd_port sc_port;       /* dummy port for root hub */
132
133         struct thread   *sc_event_thread;
134
135         char            sc_dying;
136 };
137
138 TAILQ_HEAD(, usb_task) usb_all_tasks;
139
140 #if defined(__NetBSD__) || defined(__OpenBSD__)
141 cdev_decl(usb);
142 #elif defined(__FreeBSD__) || defined(__DragonFly__)
143 d_open_t  usbopen;
144 d_close_t usbclose;
145 d_read_t usbread;
146 d_ioctl_t usbioctl;
147 int usbpoll(dev_t, int, usb_proc_ptr);
148
149 struct cdevsw usb_cdevsw = {
150         /* name */      "usb",
151         /* maj */       USB_CDEV_MAJOR,
152         /* flags */     0,
153         /* port */      NULL,
154         /* clone */     NULL,
155
156         /* open */      usbopen,
157         /* close */     usbclose,
158         /* read */      usbread,
159         /* write */     nowrite,
160         /* ioctl */     usbioctl,
161         /* poll */      usbpoll,
162         /* mmap */      nommap,
163         /* strategy */  nostrategy,
164         /* dump */      nodump,
165         /* psize */     nopsize
166 };
167 #endif
168
169 Static void     usb_discover(void *);
170 Static void     usb_create_event_thread(void *);
171 Static void     usb_event_thread(void *);
172 Static void     usb_task_thread(void *);
173 Static usb_proc_ptr     usb_task_thread_proc = NULL;
174
175 #define USB_MAX_EVENTS 100
176 struct usb_event_q {
177         struct usb_event ue;
178         TAILQ_ENTRY(usb_event_q) next;
179 };
180 Static TAILQ_HEAD(, usb_event_q) usb_events =
181         TAILQ_HEAD_INITIALIZER(usb_events);
182 Static int usb_nevents = 0;
183 Static struct selinfo usb_selevent;
184 Static struct proc *usb_async_proc;  /* process that wants USB SIGIO */
185 Static int usb_dev_open = 0;
186 Static void usb_add_event(int, struct usb_event *);
187
188 Static int usb_get_next_event(struct usb_event *);
189
190 #if defined(__NetBSD__) || defined(__OpenBSD__)
191 /* Flag to see if we are in the cold boot process. */
192 extern int cold;
193 #endif
194
195 Static const char *usbrev_str[] = USBREV_STR;
196
197 USB_DECLARE_DRIVER_INIT(usb,
198                         DEVMETHOD(device_suspend, bus_generic_suspend),
199                         DEVMETHOD(device_resume, bus_generic_resume),
200                         DEVMETHOD(device_shutdown, bus_generic_shutdown)
201                         );
202
203 #if defined(__FreeBSD__) || defined(__DragonFly__)
204 MODULE_VERSION(usb, 1);
205 #endif
206
207 USB_MATCH(usb)
208 {
209         DPRINTF(("usbd_match\n"));
210         return (UMATCH_GENERIC);
211 }
212
213 USB_ATTACH(usb)
214 {
215 #if defined(__NetBSD__) || defined(__OpenBSD__)
216         struct usb_softc *sc = (struct usb_softc *)self;
217 #elif defined(__FreeBSD__) || defined(__DragonFly__)
218         struct usb_softc *sc = device_get_softc(self);
219         void *aux = device_get_ivars(self);
220         static int global_init_done = 0;
221 #endif
222         usbd_device_handle dev;
223         usbd_status err;
224         int usbrev;
225         int speed;
226         struct usb_event ue;
227
228         sc->sc_dev = self;
229
230         DPRINTF(("usbd_attach\n"));
231
232         usbd_init();
233         sc->sc_bus = aux;
234         sc->sc_bus->usbctl = sc;
235         sc->sc_port.power = USB_MAX_POWER;
236
237 #if defined(__FreeBSD__) || defined(__DragonFly__)
238         printf("%s", USBDEVNAME(sc->sc_dev));
239 #endif
240         usbrev = sc->sc_bus->usbrev;
241         printf(": USB revision %s", usbrev_str[usbrev]);
242         switch (usbrev) {
243         case USBREV_1_0:
244         case USBREV_1_1:
245                 speed = USB_SPEED_FULL;
246                 break;
247         case USBREV_2_0:
248                 speed = USB_SPEED_HIGH;
249                 break;
250         default:
251                 printf(", not supported\n");
252                 sc->sc_dying = 1;
253                 USB_ATTACH_ERROR_RETURN;
254         }
255         printf("\n");
256
257         /* Make sure not to use tsleep() if we are cold booting. */
258         if (cold)
259                 sc->sc_bus->use_polling++;
260
261         ue.u.ue_ctrlr.ue_bus = USBDEVUNIT(sc->sc_dev);
262         usb_add_event(USB_EVENT_CTRLR_ATTACH, &ue);
263
264 #ifdef USB_USE_SOFTINTR
265 #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
266         /* XXX we should have our own level */
267         sc->sc_bus->soft = softintr_establish(IPL_SOFTNET,
268             sc->sc_bus->methods->soft_intr, sc->sc_bus);
269         if (sc->sc_bus->soft == NULL) {
270                 printf("%s: can't register softintr\n", USBDEVNAME(sc->sc_dev));
271                 sc->sc_dying = 1;
272                 USB_ATTACH_ERROR_RETURN;
273         }
274 #else
275         usb_callout_init(sc->sc_bus->softi);
276 #endif
277 #endif
278
279         err = usbd_new_device(USBDEV(sc->sc_dev), sc->sc_bus, 0, speed, 0,
280                   &sc->sc_port);
281         if (!err) {
282                 dev = sc->sc_port.device;
283                 if (dev->hub == NULL) {
284                         sc->sc_dying = 1;
285                         printf("%s: root device is not a hub\n",
286                                USBDEVNAME(sc->sc_dev));
287                         USB_ATTACH_ERROR_RETURN;
288                 }
289                 sc->sc_bus->root_hub = dev;
290 #if 1
291                 /*
292                  * Turning this code off will delay attachment of USB devices
293                  * until the USB event thread is running, which means that
294                  * the keyboard will not work until after cold boot.
295                  */
296 #if defined(__FreeBSD__) || defined(__DragonFly__)
297                 if (cold)
298 #else
299                 if (cold && (sc->sc_dev.dv_cfdata->cf_flags & 1))
300 #endif
301                         dev->hub->explore(sc->sc_bus->root_hub);
302 #endif
303         } else {
304                 printf("%s: root hub problem, error=%d\n",
305                        USBDEVNAME(sc->sc_dev), err);
306                 sc->sc_dying = 1;
307         }
308         if (cold)
309                 sc->sc_bus->use_polling--;
310
311         config_pending_incr();
312 #if defined(__NetBSD__) || defined(__OpenBSD__)
313         usb_kthread_create(usb_create_event_thread, sc);
314 #endif
315
316 #if defined(__FreeBSD__) || defined(__DragonFly__)
317         usb_create_event_thread(sc);
318         /* The per controller devices (used for usb_discover) */
319         /* XXX This is redundant now, but old usbd's will want it */
320         if (!global_init_done) {
321                 /* The device spitting out events */
322                 cdevsw_add(&usb_cdevsw, -1, USB_DEV_MINOR);
323                 make_dev(&usb_cdevsw, USB_DEV_MINOR, UID_ROOT, GID_OPERATOR,
324                         0660, "usb");
325                 global_init_done = 1;
326         }
327         cdevsw_add(&usb_cdevsw, -1, device_get_unit(self));
328         make_dev(&usb_cdevsw, device_get_unit(self), UID_ROOT, GID_OPERATOR,
329                 0660, "usb%d", device_get_unit(self));
330 #endif
331
332         USB_ATTACH_SUCCESS_RETURN;
333 }
334
335 void
336 usb_create_event_thread(void *arg)
337 {
338         struct usb_softc *sc = arg;
339         static int created = 0;
340
341         if (usb_kthread_create1(usb_event_thread, sc, &sc->sc_event_thread,
342                            "%s", USBDEVNAME(sc->sc_dev))) {
343                 printf("%s: unable to create event thread for\n",
344                        USBDEVNAME(sc->sc_dev));
345                 panic("usb_create_event_thread");
346         }
347         if (!created) {
348                 created = 1;
349                 TAILQ_INIT(&usb_all_tasks);
350                 if (usb_kthread_create2(usb_task_thread, NULL,
351                                         &usb_task_thread_proc, "usbtask")) {
352                         printf("unable to create task thread\n");
353                         panic("usb_create_event_thread task");
354                 }
355         }
356 }
357
358 /*
359  * Add a task to be performed by the task thread.  This function can be
360  * called from any context and the task will be executed in a process
361  * context ASAP.
362  */
363 void
364 usb_add_task(usbd_device_handle dev, struct usb_task *task)
365 {
366         int s;
367
368         s = splusb();
369         if (!task->onqueue) {
370                 DPRINTFN(2,("usb_add_task: task=%p\n", task));
371                 TAILQ_INSERT_TAIL(&usb_all_tasks, task, next);
372                 task->onqueue = 1;
373         } else {
374                 DPRINTFN(3,("usb_add_task: task=%p on q\n", task));
375         }
376         wakeup(&usb_all_tasks);
377         splx(s);
378 }
379
380 void
381 usb_rem_task(usbd_device_handle dev, struct usb_task *task)
382 {
383         int s;
384
385         s = splusb();
386         if (task->onqueue) {
387                 TAILQ_REMOVE(&usb_all_tasks, task, next);
388                 task->onqueue = 0;
389         }
390         splx(s);
391 }
392
393 void
394 usb_event_thread(void *arg)
395 {
396         struct usb_softc *sc = arg;
397
398         DPRINTF(("usb_event_thread: start\n"));
399
400         /*
401          * In case this controller is a companion controller to an
402          * EHCI controller we need to wait until the EHCI controller
403          * has grabbed the port.
404          * XXX It would be nicer to do this with a tsleep(), but I don't
405          * know how to synchronize the creation of the threads so it
406          * will work.
407          */
408         usb_delay_ms(sc->sc_bus, 500);
409
410         /* Make sure first discover does something. */
411         sc->sc_bus->needs_explore = 1;
412         usb_discover(sc);
413         config_pending_decr();
414
415         while (!sc->sc_dying) {
416 #ifdef USB_DEBUG
417                 if (usb_noexplore < 2)
418 #endif
419                 usb_discover(sc);
420 #ifdef USB_DEBUG
421                 (void)tsleep(&sc->sc_bus->needs_explore, 0, "usbevt",
422                         usb_noexplore ? 0 : hz * 60);
423 #else
424                 (void)tsleep(&sc->sc_bus->needs_explore, 0, "usbevt",
425                         hz * 60);
426 #endif
427                 DPRINTFN(2,("usb_event_thread: woke up\n"));
428         }
429         sc->sc_event_thread = NULL;
430
431         /* In case parent is waiting for us to exit. */
432         wakeup(sc);
433
434         DPRINTF(("usb_event_thread: exit\n"));
435         kthread_exit();
436 }
437
438 void
439 usb_task_thread(void *arg)
440 {
441         struct usb_task *task;
442         int s;
443
444 #if defined(__FreeBSD__) && __FreeBSD_version >= 500000
445         mtx_lock(&Giant);
446 #endif
447
448         DPRINTF(("usb_task_thread: start\n"));
449
450         s = splusb();
451         for (;;) {
452                 task = TAILQ_FIRST(&usb_all_tasks);
453                 if (task == NULL) {
454                         tsleep(&usb_all_tasks, 0, "usbtsk", 0);
455                         task = TAILQ_FIRST(&usb_all_tasks);
456                 }
457                 DPRINTFN(2,("usb_task_thread: woke up task=%p\n", task));
458                 if (task != NULL) {
459                         TAILQ_REMOVE(&usb_all_tasks, task, next);
460                         task->onqueue = 0;
461                         splx(s);
462                         task->fun(task->arg);
463                         s = splusb();
464                 }
465         }
466 }
467
468 #if defined(__NetBSD__) || defined(__OpenBSD__)
469 int
470 usbctlprint(void *aux, const char *pnp)
471 {
472         /* only "usb"es can attach to host controllers */
473         if (pnp)
474                 printf("usb at %s", pnp);
475
476         return (UNCONF);
477 }
478 #endif /* defined(__NetBSD__) || defined(__OpenBSD__) */
479
480 int
481 usbopen(dev_t dev, int flag, int mode, usb_proc_ptr p)
482 {
483         int unit = USBUNIT(dev);
484         struct usb_softc *sc;
485
486         if (unit == USB_DEV_MINOR) {
487                 if (usb_dev_open)
488                         return (EBUSY);
489                 usb_dev_open = 1;
490                 usb_async_proc = NULL;
491                 return (0);
492         }
493
494         USB_GET_SC_OPEN(usb, unit, sc);
495
496         if (sc->sc_dying)
497                 return (EIO);
498
499         return (0);
500 }
501
502 int
503 usbread(dev_t dev, struct uio *uio, int flag)
504 {
505         struct usb_event ue;
506         int unit = USBUNIT(dev);
507         int s, error, n;
508
509         if (unit != USB_DEV_MINOR)
510                 return (ENODEV);
511
512         if (uio->uio_resid != sizeof(struct usb_event))
513                 return (EINVAL);
514
515         error = 0;
516         s = splusb();
517         for (;;) {
518                 n = usb_get_next_event(&ue);
519                 if (n != 0)
520                         break;
521                 if (flag & IO_NDELAY) {
522                         error = EWOULDBLOCK;
523                         break;
524                 }
525                 error = tsleep(&usb_events, PCATCH, "usbrea", 0);
526                 if (error)
527                         break;
528         }
529         splx(s);
530         if (!error)
531                 error = uiomove((void *)&ue, uio->uio_resid, uio);
532
533         return (error);
534 }
535
536 int
537 usbclose(dev_t dev, int flag, int mode, usb_proc_ptr p)
538 {
539         int unit = USBUNIT(dev);
540
541         if (unit == USB_DEV_MINOR) {
542                 usb_async_proc = NULL;
543                 usb_dev_open = 0;
544         }
545
546         return (0);
547 }
548
549 int
550 usbioctl(dev_t devt, u_long cmd, caddr_t data, int flag, usb_proc_ptr p)
551 {
552         struct usb_softc *sc;
553         int unit = USBUNIT(devt);
554
555         if (unit == USB_DEV_MINOR) {
556                 switch (cmd) {
557                 case FIONBIO:
558                         /* All handled in the upper FS layer. */
559                         return (0);
560
561                 case FIOASYNC:
562                         if (*(int *)data)
563 #if defined(__DragonFly__)
564                                 usb_async_proc = p->td_proc;
565 #elif __FreeBSD_version >= 500000
566                                 usb_async_proc = p->td_proc;
567 #else
568                                 usb_async_proc = p;
569 #endif
570                         else
571                                 usb_async_proc = NULL;
572                         return (0);
573
574                 default:
575                         return (EINVAL);
576                 }
577         }
578
579         USB_GET_SC(usb, unit, sc);
580
581         if (sc->sc_dying)
582                 return (EIO);
583
584         switch (cmd) {
585 #if defined(__FreeBSD__) || defined(__DragonFly__)
586         /* This part should be deleted */
587         case USB_DISCOVER:
588                 break;
589 #endif
590         case USB_REQUEST:
591         {
592                 struct usb_ctl_request *ur = (void *)data;
593                 int len = UGETW(ur->ucr_request.wLength);
594                 struct iovec iov;
595                 struct uio uio;
596                 void *ptr = 0;
597                 int addr = ur->ucr_addr;
598                 usbd_status err;
599                 int error = 0;
600
601                 DPRINTF(("usbioctl: USB_REQUEST addr=%d len=%d\n", addr, len));
602                 if (len < 0 || len > 32768)
603                         return (EINVAL);
604                 if (addr < 0 || addr >= USB_MAX_DEVICES ||
605                     sc->sc_bus->devices[addr] == 0)
606                         return (EINVAL);
607                 if (len != 0) {
608                         iov.iov_base = (caddr_t)ur->ucr_data;
609                         iov.iov_len = len;
610                         uio.uio_iov = &iov;
611                         uio.uio_iovcnt = 1;
612                         uio.uio_resid = len;
613                         uio.uio_offset = 0;
614                         uio.uio_segflg = UIO_USERSPACE;
615                         uio.uio_rw =
616                                 ur->ucr_request.bmRequestType & UT_READ ?
617                                 UIO_READ : UIO_WRITE;
618                         uio.uio_td = p;
619                         ptr = malloc(len, M_TEMP, M_WAITOK);
620                         if (uio.uio_rw == UIO_WRITE) {
621                                 error = uiomove(ptr, len, &uio);
622                                 if (error)
623                                         goto ret;
624                         }
625                 }
626                 err = usbd_do_request_flags(sc->sc_bus->devices[addr],
627                           &ur->ucr_request, ptr, ur->ucr_flags, &ur->ucr_actlen,
628                           USBD_DEFAULT_TIMEOUT);
629                 if (err) {
630                         error = EIO;
631                         goto ret;
632                 }
633                 if (len != 0) {
634                         if (uio.uio_rw == UIO_READ) {
635                                 error = uiomove(ptr, len, &uio);
636                                 if (error)
637                                         goto ret;
638                         }
639                 }
640         ret:
641                 if (ptr)
642                         free(ptr, M_TEMP);
643                 return (error);
644         }
645
646         case USB_DEVICEINFO:
647         {
648                 struct usb_device_info *di = (void *)data;
649                 int addr = di->udi_addr;
650                 usbd_device_handle dev;
651
652                 if (addr < 1 || addr >= USB_MAX_DEVICES)
653                         return (EINVAL);
654                 dev = sc->sc_bus->devices[addr];
655                 if (dev == NULL)
656                         return (ENXIO);
657                 usbd_fill_deviceinfo(dev, di, 1);
658                 break;
659         }
660
661         case USB_DEVICESTATS:
662                 *(struct usb_device_stats *)data = sc->sc_bus->stats;
663                 break;
664
665         default:
666                 return (EINVAL);
667         }
668         return (0);
669 }
670
671 int
672 usbpoll(dev_t dev, int events, usb_proc_ptr p)
673 {
674         int revents, mask, s;
675         int unit = USBUNIT(dev);
676
677         if (unit == USB_DEV_MINOR) {
678                 revents = 0;
679                 mask = POLLIN | POLLRDNORM;
680
681                 s = splusb();
682                 if (events & mask && usb_nevents > 0)
683                         revents |= events & mask;
684                 if (revents == 0 && events & mask)
685                         selrecord(p, &usb_selevent);
686                 splx(s);
687
688                 return (revents);
689         } else {
690 #if defined(__FreeBSD__) || defined(__DragonFly__)
691                 return (0);     /* select/poll never wakes up - back compat */
692 #else
693                 return (ENXIO);
694 #endif
695         }
696 }
697
698 /* Explore device tree from the root. */
699 Static void
700 usb_discover(void *v)
701 {
702         struct usb_softc *sc = v;
703
704 #if defined(__FreeBSD__) || defined(__DragonFly__)
705         /* splxxx should be changed to mutexes for preemption safety some day */
706         int s;
707 #endif
708
709         DPRINTFN(2,("usb_discover\n"));
710 #ifdef USB_DEBUG
711         if (usb_noexplore > 1)
712                 return;
713 #endif
714
715         /*
716          * We need mutual exclusion while traversing the device tree,
717          * but this is guaranteed since this function is only called
718          * from the event thread for the controller.
719          */
720 #if defined(__FreeBSD__) || defined(__DragonFly__)
721         s = splusb();
722 #endif
723         while (sc->sc_bus->needs_explore && !sc->sc_dying) {
724                 sc->sc_bus->needs_explore = 0;
725 #if defined(__FreeBSD__) || defined(__DragonFly__)
726                 splx(s);
727 #endif
728                 sc->sc_bus->root_hub->hub->explore(sc->sc_bus->root_hub);
729 #if defined(__FreeBSD__) || defined(__DragonFly__)
730                 s = splusb();
731 #endif
732         }
733 #if defined(__FreeBSD__) || defined(__DragonFly__)
734         splx(s);
735 #endif
736 }
737
738 void
739 usb_needs_explore(usbd_device_handle dev)
740 {
741         DPRINTFN(2,("usb_needs_explore\n"));
742         dev->bus->needs_explore = 1;
743         wakeup(&dev->bus->needs_explore);
744 }
745
746 /* Called at splusb() */
747 int
748 usb_get_next_event(struct usb_event *ue)
749 {
750         struct usb_event_q *ueq;
751
752         if (usb_nevents <= 0)
753                 return (0);
754         ueq = TAILQ_FIRST(&usb_events);
755 #ifdef DIAGNOSTIC
756         if (ueq == NULL) {
757                 printf("usb: usb_nevents got out of sync! %d\n", usb_nevents);
758                 usb_nevents = 0;
759                 return (0);
760         }
761 #endif
762         *ue = ueq->ue;
763         TAILQ_REMOVE(&usb_events, ueq, next);
764         free(ueq, M_USBDEV);
765         usb_nevents--;
766         return (1);
767 }
768
769 void
770 usbd_add_dev_event(int type, usbd_device_handle udev)
771 {
772         struct usb_event ue;
773
774         usbd_fill_deviceinfo(udev, &ue.u.ue_device, USB_EVENT_IS_ATTACH(type));
775         usb_add_event(type, &ue);
776 }
777
778 void
779 usbd_add_drv_event(int type, usbd_device_handle udev, device_ptr_t dev)
780 {
781         struct usb_event ue;
782
783         ue.u.ue_driver.ue_cookie = udev->cookie;
784         strncpy(ue.u.ue_driver.ue_devname, USBDEVPTRNAME(dev),
785                 sizeof ue.u.ue_driver.ue_devname);
786         usb_add_event(type, &ue);
787 }
788
789 void
790 usb_add_event(int type, struct usb_event *uep)
791 {
792         struct usb_event_q *ueq;
793         struct usb_event ue;
794         struct timeval thetime;
795         int s;
796
797         ueq = malloc(sizeof *ueq, M_USBDEV, M_INTWAIT);
798         ueq->ue = *uep;
799         ueq->ue.ue_type = type;
800         microtime(&thetime);
801         TIMEVAL_TO_TIMESPEC(&thetime, &ueq->ue.ue_time);
802
803         s = splusb();
804         if (USB_EVENT_IS_DETACH(type)) {
805                 struct usb_event_q *ueqi, *ueqi_next;
806
807                 for (ueqi = TAILQ_FIRST(&usb_events); ueqi; ueqi = ueqi_next) {
808                         ueqi_next = TAILQ_NEXT(ueqi, next);
809                         if (ueqi->ue.u.ue_driver.ue_cookie.cookie ==
810                             uep->u.ue_device.udi_cookie.cookie) {
811                                 TAILQ_REMOVE(&usb_events, ueqi, next);
812                                 free(ueqi, M_USBDEV);
813                                 usb_nevents--;
814                                 ueqi_next = TAILQ_FIRST(&usb_events);
815                         }
816                 }
817         }
818         if (usb_nevents >= USB_MAX_EVENTS) {
819                 /* Too many queued events, drop an old one. */
820                 DPRINTF(("usb: event dropped\n"));
821                 (void)usb_get_next_event(&ue);
822         }
823         TAILQ_INSERT_TAIL(&usb_events, ueq, next);
824         usb_nevents++;
825         wakeup(&usb_events);
826         selwakeuppri(&usb_selevent, 0);
827         if (usb_async_proc != NULL) {
828                 PROC_LOCK(usb_async_proc);
829                 psignal(usb_async_proc, SIGIO);
830                 PROC_UNLOCK(usb_async_proc);
831         }
832         splx(s);
833 }
834
835 void
836 usb_schedsoftintr(usbd_bus_handle bus)
837 {
838         DPRINTFN(10,("usb_schedsoftintr: polling=%d\n", bus->use_polling));
839 #ifdef USB_USE_SOFTINTR
840         if (bus->use_polling) {
841                 bus->methods->soft_intr(bus);
842         } else {
843 #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
844                 softintr_schedule(bus->soft);
845 #else
846                 if (!callout_pending(&bus->softi))
847                         callout_reset(&bus->softi, 0, bus->methods->soft_intr,
848                             bus);
849 #endif /* __HAVE_GENERIC_SOFT_INTERRUPTS */
850         }
851 #else
852         bus->methods->soft_intr(bus);
853 #endif /* USB_USE_SOFTINTR */
854 }
855
856
857 #if defined(__NetBSD__) || defined(__OpenBSD__)
858 int
859 usb_activate(device_ptr_t self, enum devact act)
860 {
861         struct usb_softc *sc = (struct usb_softc *)self;
862         usbd_device_handle dev = sc->sc_port.device;
863         int i, rv = 0;
864
865         switch (act) {
866         case DVACT_ACTIVATE:
867                 return (EOPNOTSUPP);
868
869         case DVACT_DEACTIVATE:
870                 sc->sc_dying = 1;
871                 if (dev != NULL && dev->cdesc != NULL && dev->subdevs != NULL) {
872                         for (i = 0; dev->subdevs[i]; i++)
873                                 rv |= config_deactivate(dev->subdevs[i]);
874                 }
875                 break;
876         }
877         return (rv);
878 }
879
880 int
881 usb_detach(device_ptr_t self, int flags)
882 {
883         struct usb_softc *sc = (struct usb_softc *)self;
884         struct usb_event ue;
885
886         DPRINTF(("usb_detach: start\n"));
887
888         sc->sc_dying = 1;
889
890         /* Make all devices disconnect. */
891         if (sc->sc_port.device != NULL)
892                 usb_disconnect_port(&sc->sc_port, self);
893
894         /* Kill off event thread. */
895         if (sc->sc_event_thread != NULL) {
896                 wakeup(&sc->sc_bus->needs_explore);
897                 if (tsleep(sc, 0, "usbdet", hz * 60))
898                         printf("%s: event thread didn't die\n",
899                                USBDEVNAME(sc->sc_dev));
900                 DPRINTF(("usb_detach: event thread dead\n"));
901         }
902
903         usbd_finish();
904
905 #ifdef USB_USE_SOFTINTR
906 #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
907         if (sc->sc_bus->soft != NULL) {
908                 softintr_disestablish(sc->sc_bus->soft);
909                 sc->sc_bus->soft = NULL;
910         }
911 #else
912         callout_stop(&sc->sc_bus->softi);
913 #endif
914 #endif
915
916         ue.u.ue_ctrlr.ue_bus = USBDEVUNIT(sc->sc_dev);
917         usb_add_event(USB_EVENT_CTRLR_DETACH, &ue);
918
919         return (0);
920 }
921 #elif defined(__FreeBSD__) || defined(__DragonFly__)
922 int
923 usb_detach(device_t self)
924 {
925         DPRINTF(("%s: unload, prevented\n", USBDEVNAME(self)));
926
927         return (EINVAL);
928 }
929 #endif
930
931
932 #if defined(__FreeBSD__) || defined(__DragonFly__)
933 DRIVER_MODULE(usb, ohci, usb_driver, usb_devclass, 0, 0);
934 DRIVER_MODULE(usb, uhci, usb_driver, usb_devclass, 0, 0);
935 DRIVER_MODULE(usb, ehci, usb_driver, usb_devclass, 0, 0);
936 #endif