xref: /netbsd-src/sys/dev/usb/usb.c (revision 7cc2f76925f078d01ddc9e640a98f4ccfc9f8c3b)
1 /*	$NetBSD: usb.c,v 1.48 2000/12/13 04:05:14 augustss Exp $	*/
2 /*	$FreeBSD: src/sys/dev/usb/usb.c,v 1.20 1999/11/17 22:33:46 n_hibma Exp $	*/
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/malloc.h>
51 #if defined(__NetBSD__) || defined(__OpenBSD__)
52 #include <sys/device.h>
53 #include <sys/kthread.h>
54 #include <sys/proc.h>
55 #elif defined(__FreeBSD__)
56 #include <sys/module.h>
57 #include <sys/bus.h>
58 #include <sys/filio.h>
59 #include <sys/uio.h>
60 #endif
61 #include <sys/conf.h>
62 #include <sys/poll.h>
63 #include <sys/select.h>
64 #include <sys/vnode.h>
65 #include <sys/signalvar.h>
66 
67 #include <dev/usb/usb.h>
68 #include <dev/usb/usbdi.h>
69 #include <dev/usb/usbdi_util.h>
70 
71 #define USB_DEV_MINOR 255
72 
73 #if defined(__FreeBSD__)
74 MALLOC_DEFINE(M_USB, "USB", "USB");
75 MALLOC_DEFINE(M_USBDEV, "USBdev", "USB device");
76 MALLOC_DEFINE(M_USBHC, "USBHC", "USB host controller");
77 
78 #include "usb_if.h"
79 #endif /* defined(__FreeBSD__) */
80 
81 #include <machine/bus.h>
82 
83 #include <dev/usb/usbdivar.h>
84 #include <dev/usb/usb_quirks.h>
85 
86 #ifdef USB_DEBUG
87 #define DPRINTF(x)	if (usbdebug) logprintf x
88 #define DPRINTFN(n,x)	if (usbdebug>(n)) logprintf x
89 int	usbdebug = 0;
90 #ifdef UHCI_DEBUG
91 int	uhcidebug;
92 #endif
93 #ifdef OHCI_DEBUG
94 int	ohcidebug;
95 #endif
96 /*
97  * 0  - do usual exploration
98  * 1  - do not use timeout exploration
99  * >1 - do no exploration
100  */
101 int	usb_noexplore = 0;
102 #else
103 #define DPRINTF(x)
104 #define DPRINTFN(n,x)
105 #endif
106 
107 struct usb_softc {
108 	USBBASEDEVICE	sc_dev;		/* base device */
109 	usbd_bus_handle sc_bus;		/* USB controller */
110 	struct usbd_port sc_port;	/* dummy port for root hub */
111 
112 #if defined(__FreeBSD__)
113 	/* This part should be deleted when kthreads is available */
114 	struct selinfo	sc_consel;	/* waiting for connect change */
115 #else
116 	struct proc    *sc_event_thread;
117 #endif
118 
119 	char		sc_dying;
120 };
121 
122 #if defined(__NetBSD__) || defined(__OpenBSD__)
123 cdev_decl(usb);
124 #elif defined(__FreeBSD__)
125 d_open_t  usbopen;
126 d_close_t usbclose;
127 d_read_t usbread;
128 d_ioctl_t usbioctl;
129 int usbpoll(dev_t, int, struct proc *);
130 
131 struct cdevsw usb_cdevsw = {
132 	/* open */      usbopen,
133 	/* close */     usbclose,
134 	/* read */      noread,
135 	/* write */     nowrite,
136 	/* ioctl */     usbioctl,
137 	/* poll */      usbpoll,
138 	/* mmap */      nommap,
139 	/* strategy */  nostrategy,
140 	/* name */      "usb",
141 	/* maj */       USB_CDEV_MAJOR,
142 	/* dump */      nodump,
143 	/* psize */     nopsize,
144 	/* flags */     0,
145 	/* bmaj */      -1
146 };
147 #endif
148 
149 Static usbd_status usb_discover(struct usb_softc *);
150 Static void	usb_create_event_thread(void *);
151 Static void	usb_event_thread(void *);
152 
153 #define USB_MAX_EVENTS 100
154 struct usb_event_q {
155 	struct usb_event ue;
156 	SIMPLEQ_ENTRY(usb_event_q) next;
157 };
158 Static SIMPLEQ_HEAD(, usb_event_q) usb_events =
159 	SIMPLEQ_HEAD_INITIALIZER(usb_events);
160 Static int usb_nevents = 0;
161 Static struct selinfo usb_selevent;
162 Static struct proc *usb_async_proc;  /* process that wants USB SIGIO */
163 Static int usb_dev_open = 0;
164 Static void usb_add_event(int, struct usb_event *);
165 
166 Static int usb_get_next_event(struct usb_event *);
167 
168 Static const char *usbrev_str[] = USBREV_STR;
169 
170 USB_DECLARE_DRIVER(usb);
171 
172 USB_MATCH(usb)
173 {
174 	DPRINTF(("usbd_match\n"));
175 	return (UMATCH_GENERIC);
176 }
177 
178 USB_ATTACH(usb)
179 {
180 #if defined(__NetBSD__) || defined(__OpenBSD__)
181 	struct usb_softc *sc = (struct usb_softc *)self;
182 #elif defined(__FreeBSD__)
183 	struct usb_softc *sc = device_get_softc(self);
184 	void *aux = device_get_ivars(self);
185 #endif
186 	usbd_device_handle dev;
187 	usbd_status err;
188 	int usbrev;
189 	struct usb_event ue;
190 
191 #if defined(__FreeBSD__)
192 	printf("%s", USBDEVNAME(sc->sc_dev));
193 	sc->sc_dev = self;
194 #endif
195 
196 	DPRINTF(("usbd_attach\n"));
197 
198 	usbd_init();
199 	sc->sc_bus = aux;
200 	sc->sc_bus->usbctl = sc;
201 	sc->sc_port.power = USB_MAX_POWER;
202 
203 	usbrev = sc->sc_bus->usbrev;
204 	printf(": USB revision %s", usbrev_str[usbrev]);
205 	if (usbrev != USBREV_1_0 && usbrev != USBREV_1_1) {
206 		printf(", not supported\n");
207 		USB_ATTACH_ERROR_RETURN;
208 	}
209 	printf("\n");
210 
211 	/* Make sure not to use tsleep() if we are cold booting. */
212 	if (cold)
213 		sc->sc_bus->use_polling++;
214 
215 	ue.u.ue_ctrlr.ue_bus = USBDEVUNIT(sc->sc_dev);
216 	usb_add_event(USB_EVENT_CTRLR_ATTACH, &ue);
217 
218 	err = usbd_new_device(USBDEV(sc->sc_dev), sc->sc_bus, 0, 0, 0,
219 		  &sc->sc_port);
220 	if (!err) {
221 		dev = sc->sc_port.device;
222 		if (dev->hub == NULL) {
223 			sc->sc_dying = 1;
224 			printf("%s: root device is not a hub\n",
225 			       USBDEVNAME(sc->sc_dev));
226 			USB_ATTACH_ERROR_RETURN;
227 		}
228 		sc->sc_bus->root_hub = dev;
229 #if 1
230 		/*
231 		 * Turning this code off will delay attachment of USB devices
232 		 * until the USB event thread is running, which means that
233 		 * the keyboard will not work until after cold boot.
234 		 */
235 		if (cold && (sc->sc_dev.dv_cfdata->cf_flags & 1))
236 			dev->hub->explore(sc->sc_bus->root_hub);
237 #endif
238 	} else {
239 		printf("%s: root hub problem, error=%d\n",
240 		       USBDEVNAME(sc->sc_dev), err);
241 		sc->sc_dying = 1;
242 	}
243 	if (cold)
244 		sc->sc_bus->use_polling--;
245 
246 	config_pending_incr();
247 	usb_kthread_create(usb_create_event_thread, sc);
248 
249 #if defined(__FreeBSD__)
250 	make_dev(&usb_cdevsw, device_get_unit(self), UID_ROOT, GID_OPERATOR,
251 		 0644, "usb%d", device_get_unit(self));
252 #endif
253 
254 	USB_ATTACH_SUCCESS_RETURN;
255 }
256 
257 #if defined(__NetBSD__) || defined(__OpenBSD__)
258 void
259 usb_create_event_thread(void *arg)
260 {
261 	struct usb_softc *sc = arg;
262 
263 	if (usb_kthread_create1(usb_event_thread, sc, &sc->sc_event_thread,
264 			   "%s", sc->sc_dev.dv_xname)) {
265 		printf("%s: unable to create event thread for\n",
266 		       sc->sc_dev.dv_xname);
267 		panic("usb_create_event_thread");
268 	}
269 }
270 
271 void
272 usb_event_thread(void *arg)
273 {
274 	struct usb_softc *sc = arg;
275 	int first = 1;
276 
277 	DPRINTF(("usb_event_thread: start\n"));
278 
279 	/* Make sure first discover does something. */
280 	sc->sc_bus->needs_explore = 1;
281 
282 	while (!sc->sc_dying) {
283 #ifdef USB_DEBUG
284 		if (usb_noexplore < 2)
285 #endif
286 		usb_discover(sc);
287 		if (first) {
288 			config_pending_decr();
289 			first = 0;
290 		}
291 #ifdef USB_DEBUG
292 		(void)tsleep(&sc->sc_bus->needs_explore, PWAIT, "usbevt",
293 		    usb_noexplore ? 0 : hz * 60);
294 #else
295 		(void)tsleep(&sc->sc_bus->needs_explore, PWAIT, "usbevt",
296 		    hz * 60);
297 #endif
298 		DPRINTFN(2,("usb_event_thread: woke up\n"));
299 	}
300 	sc->sc_event_thread = 0;
301 
302 	/* In case parent is waiting for us to exit. */
303 	wakeup(sc);
304 
305 	DPRINTF(("usb_event_thread: exit\n"));
306 	kthread_exit(0);
307 }
308 
309 int
310 usbctlprint(void *aux, const char *pnp)
311 {
312 	/* only "usb"es can attach to host controllers */
313 	if (pnp)
314 		printf("usb at %s", pnp);
315 
316 	return (UNCONF);
317 }
318 #endif /* defined(__NetBSD__) || defined(__OpenBSD__) */
319 
320 int
321 usbopen(dev_t dev, int flag, int mode, struct proc *p)
322 {
323 	int unit = minor(dev);
324 	struct usb_softc *sc;
325 
326 	if (unit == USB_DEV_MINOR) {
327 		if (usb_dev_open)
328 			return (EBUSY);
329 		usb_dev_open = 1;
330 		usb_async_proc = 0;
331 		return (0);
332 	}
333 
334 	USB_GET_SC_OPEN(usb, unit, sc);
335 
336 	if (sc->sc_dying)
337 		return (EIO);
338 
339 	return (0);
340 }
341 
342 int
343 usbread(dev_t dev, struct uio *uio, int flag)
344 {
345 	struct usb_event ue;
346 	int s, error, n;
347 
348 	if (minor(dev) != USB_DEV_MINOR)
349 		return (ENXIO);
350 
351 	if (uio->uio_resid != sizeof(struct usb_event))
352 		return (EINVAL);
353 
354 	error = 0;
355 	s = splusb();
356 	for (;;) {
357 		n = usb_get_next_event(&ue);
358 		if (n != 0)
359 			break;
360 		if (flag & IO_NDELAY) {
361 			error = EWOULDBLOCK;
362 			break;
363 		}
364 		error = tsleep(&usb_events, PZERO | PCATCH, "usbrea", 0);
365 		if (error)
366 			break;
367 	}
368 	splx(s);
369 	if (!error)
370 		error = uiomove((void *)&ue, uio->uio_resid, uio);
371 
372 	return (error);
373 }
374 
375 int
376 usbclose(dev_t dev, int flag, int mode, struct proc *p)
377 {
378 	int unit = minor(dev);
379 
380 	if (unit == USB_DEV_MINOR) {
381 		usb_async_proc = 0;
382 		usb_dev_open = 0;
383 	}
384 
385 	return (0);
386 }
387 
388 int
389 usbioctl(dev_t devt, u_long cmd, caddr_t data, int flag, struct proc *p)
390 {
391 	struct usb_softc *sc;
392 	int unit = minor(devt);
393 
394 	if (unit == USB_DEV_MINOR) {
395 		switch (cmd) {
396 		case FIONBIO:
397 			/* All handled in the upper FS layer. */
398 			return (0);
399 
400 		case FIOASYNC:
401 			if (*(int *)data)
402 				usb_async_proc = p;
403 			else
404 				usb_async_proc = 0;
405 			return (0);
406 
407 		default:
408 			return (EINVAL);
409 		}
410 	}
411 
412 	USB_GET_SC(usb, unit, sc);
413 
414 	if (sc->sc_dying)
415 		return (EIO);
416 
417 	switch (cmd) {
418 #if defined(__FreeBSD__)
419 	/* This part should be deleted when kthreads is available */
420   	case USB_DISCOVER:
421   		usb_discover(sc);
422   		break;
423 #endif
424 #ifdef USB_DEBUG
425 	case USB_SETDEBUG:
426 		usbdebug  = ((*(int *)data) & 0x000000ff);
427 #ifdef UHCI_DEBUG
428 		uhcidebug = ((*(int *)data) & 0x0000ff00) >> 8;
429 #endif
430 #ifdef OHCI_DEBUG
431 		ohcidebug = ((*(int *)data) & 0x00ff0000) >> 16;
432 #endif
433 		break;
434 #endif
435 	case USB_REQUEST:
436 	{
437 		struct usb_ctl_request *ur = (void *)data;
438 		int len = UGETW(ur->request.wLength);
439 		struct iovec iov;
440 		struct uio uio;
441 		void *ptr = 0;
442 		int addr = ur->addr;
443 		usbd_status err;
444 		int error = 0;
445 
446 		DPRINTF(("usbioctl: USB_REQUEST addr=%d len=%d\n", addr, len));
447 		if (len < 0 || len > 32768)
448 			return (EINVAL);
449 		if (addr < 0 || addr >= USB_MAX_DEVICES ||
450 		    sc->sc_bus->devices[addr] == 0)
451 			return (EINVAL);
452 		if (len != 0) {
453 			iov.iov_base = (caddr_t)ur->data;
454 			iov.iov_len = len;
455 			uio.uio_iov = &iov;
456 			uio.uio_iovcnt = 1;
457 			uio.uio_resid = len;
458 			uio.uio_offset = 0;
459 			uio.uio_segflg = UIO_USERSPACE;
460 			uio.uio_rw =
461 				ur->request.bmRequestType & UT_READ ?
462 				UIO_READ : UIO_WRITE;
463 			uio.uio_procp = p;
464 			ptr = malloc(len, M_TEMP, M_WAITOK);
465 			if (uio.uio_rw == UIO_WRITE) {
466 				error = uiomove(ptr, len, &uio);
467 				if (error)
468 					goto ret;
469 			}
470 		}
471 		err = usbd_do_request_flags(sc->sc_bus->devices[addr],
472 			  &ur->request, ptr, ur->flags, &ur->actlen);
473 		if (err) {
474 			error = EIO;
475 			goto ret;
476 		}
477 		if (len != 0) {
478 			if (uio.uio_rw == UIO_READ) {
479 				error = uiomove(ptr, len, &uio);
480 				if (error)
481 					goto ret;
482 			}
483 		}
484 	ret:
485 		if (ptr)
486 			free(ptr, M_TEMP);
487 		return (error);
488 	}
489 
490 	case USB_DEVICEINFO:
491 	{
492 		struct usb_device_info *di = (void *)data;
493 		int addr = di->addr;
494 		usbd_device_handle dev;
495 
496 		if (addr < 1 || addr >= USB_MAX_DEVICES)
497 			return (EINVAL);
498 		dev = sc->sc_bus->devices[addr];
499 		if (dev == NULL)
500 			return (ENXIO);
501 		usbd_fill_deviceinfo(dev, di, 1);
502 		break;
503 	}
504 
505 	case USB_DEVICESTATS:
506 		*(struct usb_device_stats *)data = sc->sc_bus->stats;
507 		break;
508 
509 	default:
510 		return (EINVAL);
511 	}
512 	return (0);
513 }
514 
515 int
516 usbpoll(dev_t dev, int events, struct proc *p)
517 {
518 	int revents, mask, s;
519 
520 	if (minor(dev) == USB_DEV_MINOR) {
521 		revents = 0;
522 		mask = POLLIN | POLLRDNORM;
523 
524 		s = splusb();
525 		if (events & mask && usb_nevents > 0)
526 			revents |= events & mask;
527 		if (revents == 0 && events & mask)
528 			selrecord(p, &usb_selevent);
529 		splx(s);
530 
531 		return (revents);
532 	} else {
533 #if defined(__FreeBSD__)
534 		/* This part should be deleted when kthreads is available */
535 		struct usb_softc *sc;
536 		int unit = minor(dev);
537 
538 		USB_GET_SC(usb, unit, sc);
539 
540 		revents = 0;
541 		mask = POLLOUT | POLLRDNORM;
542 
543 		s = splusb();
544 		if (events & mask && sc->sc_bus->needs_explore)
545 			revents |= events & mask;
546 		if (revents == 0 && events & mask)
547 			selrecord(p, &sc->sc_consel);
548 		splx(s);
549 
550 		return (revents);
551 #else
552 		return (ENXIO);
553 #endif
554 	}
555 }
556 
557 /* Explore device tree from the root. */
558 usbd_status
559 usb_discover(struct usb_softc *sc)
560 {
561 #if defined(__FreeBSD__)
562 	/* The splxxx parts should be deleted when kthreads is available */
563 	int s;
564 #endif
565 
566 	/*
567 	 * We need mutual exclusion while traversing the device tree,
568 	 * but this is guaranteed since this function is only called
569 	 * from the event thread for the controller.
570 	 */
571 #if defined(__FreeBSD__)
572 	s = splusb();
573 #endif
574 	while (sc->sc_bus->needs_explore && !sc->sc_dying) {
575 		sc->sc_bus->needs_explore = 0;
576 #if defined(__FreeBSD__)
577 		splx(s);
578 #endif
579 		sc->sc_bus->root_hub->hub->explore(sc->sc_bus->root_hub);
580 #if defined(__FreeBSD__)
581 		s = splusb();
582 #endif
583 	}
584 #if defined(__FreeBSD__)
585 	splx(s);
586 #endif
587 
588 	return (USBD_NORMAL_COMPLETION);
589 }
590 
591 void
592 usb_needs_explore(usbd_bus_handle bus)
593 {
594 	bus->needs_explore = 1;
595 #if defined(__FreeBSD__)
596 	/* This part should be deleted when kthreads is available */
597 	selwakeup(&bus->usbctl->sc_consel);
598 #endif
599 	wakeup(&bus->needs_explore);
600 }
601 
602 /* Called at splusb() */
603 int
604 usb_get_next_event(struct usb_event *ue)
605 {
606 	struct usb_event_q *ueq;
607 
608 	if (usb_nevents <= 0)
609 		return (0);
610 	ueq = SIMPLEQ_FIRST(&usb_events);
611 	*ue = ueq->ue;
612 	SIMPLEQ_REMOVE_HEAD(&usb_events, ueq, next);
613 	free(ueq, M_USBDEV);
614 	usb_nevents--;
615 	return (1);
616 }
617 
618 void
619 usbd_add_dev_event(int type, usbd_device_handle udev)
620 {
621 	struct usb_event ue;
622 
623 	usbd_fill_deviceinfo(udev, &ue.u.ue_device, USB_EVENT_IS_ATTACH(type));
624 	usb_add_event(type, &ue);
625 }
626 
627 void
628 usbd_add_drv_event(int type, usbd_device_handle udev, device_ptr_t dev)
629 {
630 	struct usb_event ue;
631 
632 	ue.u.ue_driver.ue_cookie = udev->cookie;
633 	strncpy(ue.u.ue_driver.ue_devname, USBDEVPTRNAME(dev),
634 	    sizeof ue.u.ue_driver.ue_devname);
635 	usb_add_event(type, &ue);
636 }
637 
638 Static void
639 usb_add_event(int type, struct usb_event *uep)
640 {
641 	struct usb_event_q *ueq;
642 	struct usb_event ue;
643 	struct timeval thetime;
644 	int s;
645 
646 	microtime(&thetime);
647 	/* Don't want to wait here inside splusb() */
648 	ueq = malloc(sizeof *ueq, M_USBDEV, M_WAITOK);
649 	ueq->ue = *uep;
650 	ueq->ue.ue_type = type;
651 	TIMEVAL_TO_TIMESPEC(&thetime, &ueq->ue.ue_time);
652 
653 	s = splusb();
654 	if (++usb_nevents >= USB_MAX_EVENTS) {
655 		/* Too many queued events, drop an old one. */
656 		DPRINTFN(-1,("usb: event dropped\n"));
657 		(void)usb_get_next_event(&ue);
658 	}
659 	SIMPLEQ_INSERT_TAIL(&usb_events, ueq, next);
660 	wakeup(&usb_events);
661 	selwakeup(&usb_selevent);
662 	if (usb_async_proc != NULL)
663 		psignal(usb_async_proc, SIGIO);
664 	splx(s);
665 }
666 void
667 usb_schedsoftintr(struct usbd_bus *bus)
668 {
669 	bus->methods->soft_intr(bus);
670 }
671 
672 #if defined(__NetBSD__) || defined(__OpenBSD__)
673 int
674 usb_activate(device_ptr_t self, enum devact act)
675 {
676 	struct usb_softc *sc = (struct usb_softc *)self;
677 	usbd_device_handle dev = sc->sc_port.device;
678 	int i, rv = 0;
679 
680 	switch (act) {
681 	case DVACT_ACTIVATE:
682 		return (EOPNOTSUPP);
683 		break;
684 
685 	case DVACT_DEACTIVATE:
686 		sc->sc_dying = 1;
687 		if (dev && dev->cdesc && dev->subdevs) {
688 			for (i = 0; dev->subdevs[i]; i++)
689 				rv |= config_deactivate(dev->subdevs[i]);
690 		}
691 		break;
692 	}
693 	return (rv);
694 }
695 
696 int
697 usb_detach(device_ptr_t self, int flags)
698 {
699 	struct usb_softc *sc = (struct usb_softc *)self;
700 	struct usb_event ue;
701 
702 	DPRINTF(("usb_detach: start\n"));
703 
704 	sc->sc_dying = 1;
705 
706 	/* Make all devices disconnect. */
707 	if (sc->sc_port.device)
708 		usb_disconnect_port(&sc->sc_port, self);
709 
710 	/* Kill off event thread. */
711 	if (sc->sc_event_thread) {
712 		wakeup(&sc->sc_bus->needs_explore);
713 		if (tsleep(sc, PWAIT, "usbdet", hz * 60))
714 			printf("%s: event thread didn't die\n",
715 			       USBDEVNAME(sc->sc_dev));
716 		DPRINTF(("usb_detach: event thread dead\n"));
717 	}
718 
719 	usbd_finish();
720 
721 	ue.u.ue_ctrlr.ue_bus = USBDEVUNIT(sc->sc_dev);
722 	usb_add_event(USB_EVENT_CTRLR_DETACH, &ue);
723 
724 	return (0);
725 }
726 #elif defined(__FreeBSD__)
727 int
728 usb_detach(device_t self)
729 {
730 	DPRINTF(("%s: unload, prevented\n", USBDEVNAME(self)));
731 
732 	return (EINVAL);
733 }
734 #endif
735 
736 
737 #if defined(__FreeBSD__)
738 DRIVER_MODULE(usb, ohci, usb_driver, usb_devclass, 0, 0);
739 DRIVER_MODULE(usb, uhci, usb_driver, usb_devclass, 0, 0);
740 #endif
741