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