Home | History | Annotate | Line # | Download | only in usb
usb.c revision 1.28.4.1
      1  1.28.4.1      fvdl /*	$NetBSD: usb.c,v 1.28.4.1 1999/11/15 00:41:38 fvdl Exp $	*/
      2       1.1  augustss 
      3       1.1  augustss /*
      4       1.1  augustss  * Copyright (c) 1998 The NetBSD Foundation, Inc.
      5       1.1  augustss  * All rights reserved.
      6       1.1  augustss  *
      7       1.5  augustss  * This code is derived from software contributed to The NetBSD Foundation
      8       1.5  augustss  * by Lennart Augustsson (augustss (at) carlstedt.se) at
      9       1.5  augustss  * Carlstedt Research & Technology.
     10       1.1  augustss  *
     11       1.1  augustss  * Redistribution and use in source and binary forms, with or without
     12       1.1  augustss  * modification, are permitted provided that the following conditions
     13       1.1  augustss  * are met:
     14       1.1  augustss  * 1. Redistributions of source code must retain the above copyright
     15       1.1  augustss  *    notice, this list of conditions and the following disclaimer.
     16       1.1  augustss  * 2. Redistributions in binary form must reproduce the above copyright
     17       1.1  augustss  *    notice, this list of conditions and the following disclaimer in the
     18       1.1  augustss  *    documentation and/or other materials provided with the distribution.
     19       1.1  augustss  * 3. All advertising materials mentioning features or use of this software
     20       1.1  augustss  *    must display the following acknowledgement:
     21       1.1  augustss  *        This product includes software developed by the NetBSD
     22       1.1  augustss  *        Foundation, Inc. and its contributors.
     23       1.1  augustss  * 4. Neither the name of The NetBSD Foundation nor the names of its
     24       1.1  augustss  *    contributors may be used to endorse or promote products derived
     25       1.1  augustss  *    from this software without specific prior written permission.
     26       1.1  augustss  *
     27       1.1  augustss  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     28       1.1  augustss  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     29       1.1  augustss  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     30       1.1  augustss  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     31       1.1  augustss  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     32       1.1  augustss  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     33       1.1  augustss  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     34       1.1  augustss  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     35       1.1  augustss  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     36       1.1  augustss  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     37       1.1  augustss  * POSSIBILITY OF SUCH DAMAGE.
     38       1.1  augustss  */
     39       1.1  augustss 
     40       1.1  augustss /*
     41       1.8  augustss  * USB specifications and other documentation can be found at
     42       1.8  augustss  * http://www.usb.org/developers/data/ and
     43       1.8  augustss  * http://www.usb.org/developers/index.html .
     44       1.1  augustss  */
     45       1.1  augustss 
     46       1.1  augustss #include <sys/param.h>
     47       1.1  augustss #include <sys/systm.h>
     48       1.1  augustss #include <sys/kernel.h>
     49       1.1  augustss #include <sys/malloc.h>
     50      1.17  augustss #if defined(__NetBSD__) || defined(__OpenBSD__)
     51       1.1  augustss #include <sys/device.h>
     52      1.13  augustss #include <sys/kthread.h>
     53       1.7  augustss #elif defined(__FreeBSD__)
     54       1.7  augustss #include <sys/module.h>
     55       1.7  augustss #include <sys/bus.h>
     56       1.7  augustss #include <sys/ioccom.h>
     57       1.7  augustss #include <sys/uio.h>
     58       1.7  augustss #endif
     59      1.22  augustss #include <sys/conf.h>
     60       1.1  augustss #include <sys/poll.h>
     61       1.1  augustss #include <sys/proc.h>
     62       1.1  augustss #include <sys/select.h>
     63      1.26  augustss #include <sys/vnode.h>
     64      1.26  augustss #include <sys/signalvar.h>
     65       1.1  augustss 
     66       1.1  augustss #include <dev/usb/usb.h>
     67      1.13  augustss #include <dev/usb/usbdi.h>
     68      1.13  augustss #include <dev/usb/usbdi_util.h>
     69       1.1  augustss 
     70      1.26  augustss #define USB_DEV_MINOR 255
     71      1.26  augustss 
     72       1.7  augustss #if defined(__FreeBSD__)
     73       1.7  augustss MALLOC_DEFINE(M_USB, "USB", "USB");
     74       1.7  augustss MALLOC_DEFINE(M_USBDEV, "USBdev", "USB device");
     75      1.13  augustss MALLOC_DEFINE(M_USBHC, "USBHC", "USB host controller");
     76       1.7  augustss 
     77       1.7  augustss #include "usb_if.h"
     78       1.7  augustss #endif /* defined(__FreeBSD__) */
     79      1.20  augustss 
     80      1.20  augustss #include <machine/bus.h>
     81       1.7  augustss 
     82       1.1  augustss #include <dev/usb/usbdivar.h>
     83       1.1  augustss #include <dev/usb/usb_quirks.h>
     84       1.1  augustss 
     85       1.1  augustss #ifdef USB_DEBUG
     86      1.16  augustss #define DPRINTF(x)	if (usbdebug) logprintf x
     87      1.16  augustss #define DPRINTFN(n,x)	if (usbdebug>(n)) logprintf x
     88       1.1  augustss int	usbdebug = 0;
     89       1.1  augustss int	uhcidebug;
     90       1.1  augustss int	ohcidebug;
     91      1.21  augustss int	usb_noexplore = 0;
     92       1.1  augustss #else
     93       1.1  augustss #define DPRINTF(x)
     94       1.1  augustss #define DPRINTFN(n,x)
     95       1.1  augustss #endif
     96       1.1  augustss 
     97       1.1  augustss struct usb_softc {
     98      1.22  augustss 	USBBASEDEVICE	sc_dev;		/* base device */
     99       1.1  augustss 	usbd_bus_handle sc_bus;		/* USB controller */
    100       1.1  augustss 	struct usbd_port sc_port;	/* dummy port for root hub */
    101      1.25  augustss 
    102      1.22  augustss 	struct selinfo	sc_consel;	/* waiting for connect change */
    103      1.22  augustss 	struct proc    *sc_event_thread;
    104      1.25  augustss 
    105      1.25  augustss 	char		sc_dying;
    106       1.1  augustss };
    107       1.1  augustss 
    108      1.17  augustss #if defined(__NetBSD__) || defined(__OpenBSD__)
    109      1.22  augustss cdev_decl(usb);
    110       1.7  augustss #elif defined(__FreeBSD__)
    111       1.7  augustss d_open_t  usbopen;
    112       1.7  augustss d_close_t usbclose;
    113       1.7  augustss d_ioctl_t usbioctl;
    114       1.7  augustss int usbpoll __P((dev_t, int, struct proc *));
    115       1.7  augustss 
    116       1.7  augustss struct cdevsw usb_cdevsw = {
    117      1.28  augustss 	/* open */      usbopen,
    118      1.28  augustss 	/* close */     usbclose,
    119      1.28  augustss 	/* read */      noread,
    120      1.28  augustss 	/* write */     nowrite,
    121      1.28  augustss 	/* ioctl */     usbioctl,
    122      1.28  augustss 	/* poll */      usbpoll,
    123      1.28  augustss 	/* mmap */      nommap,
    124      1.28  augustss 	/* strategy */  nostrategy,
    125      1.28  augustss 	/* name */      "usb",
    126      1.28  augustss 	/* maj */       USB_CDEV_MAJOR,
    127      1.28  augustss 	/* dump */      nodump,
    128      1.28  augustss 	/* psize */     nopsize,
    129      1.28  augustss 	/* flags */     0,
    130      1.28  augustss 	/* bmaj */      -1
    131       1.7  augustss };
    132       1.7  augustss #endif
    133       1.7  augustss 
    134  1.28.4.1      fvdl static usbd_status usb_discover __P((struct usb_softc *));
    135  1.28.4.1      fvdl static void	usb_create_event_thread __P((void *));
    136  1.28.4.1      fvdl static void	usb_event_thread __P((void *));
    137       1.1  augustss 
    138      1.26  augustss #define USB_MAX_EVENTS 50
    139      1.26  augustss struct usb_event_q {
    140      1.26  augustss 	struct usb_event ue;
    141      1.26  augustss 	SIMPLEQ_ENTRY(usb_event_q) next;
    142      1.26  augustss };
    143  1.28.4.1      fvdl static SIMPLEQ_HEAD(, usb_event_q) usb_events =
    144  1.28.4.1      fvdl 	SIMPLEQ_HEAD_INITIALIZER(usb_events);
    145  1.28.4.1      fvdl static int usb_nevents = 0;
    146  1.28.4.1      fvdl static struct selinfo usb_selevent;
    147  1.28.4.1      fvdl static struct proc *usb_async_proc;  /* process who wants USB SIGIO */
    148  1.28.4.1      fvdl static int usb_dev_open = 0;
    149      1.26  augustss 
    150  1.28.4.1      fvdl static int usb_get_next_event __P((struct usb_event *));
    151      1.26  augustss 
    152      1.23  augustss /* Flag to see if we are in the cold boot process. */
    153      1.23  augustss extern int cold;
    154      1.23  augustss 
    155      1.28  augustss USB_DECLARE_DRIVER(usb);
    156       1.1  augustss 
    157       1.7  augustss USB_MATCH(usb)
    158       1.1  augustss {
    159       1.1  augustss 	DPRINTF(("usbd_match\n"));
    160       1.7  augustss 	return (UMATCH_GENERIC);
    161       1.1  augustss }
    162       1.1  augustss 
    163       1.7  augustss USB_ATTACH(usb)
    164       1.1  augustss {
    165      1.17  augustss #if defined(__NetBSD__) || defined(__OpenBSD__)
    166       1.1  augustss 	struct usb_softc *sc = (struct usb_softc *)self;
    167       1.7  augustss #elif defined(__FreeBSD__)
    168      1.11  augustss 	struct usb_softc *sc = device_get_softc(self);
    169      1.11  augustss 	void *aux = device_get_ivars(self);
    170       1.7  augustss #endif
    171       1.1  augustss 	usbd_device_handle dev;
    172  1.28.4.1      fvdl 	usbd_status err;
    173       1.1  augustss 
    174      1.17  augustss #if defined(__NetBSD__) || defined(__OpenBSD__)
    175       1.4  augustss 	printf("\n");
    176       1.7  augustss #elif defined(__FreeBSD__)
    177      1.11  augustss 	sc->sc_dev = self;
    178       1.7  augustss #endif
    179       1.4  augustss 
    180       1.1  augustss 	DPRINTF(("usbd_attach\n"));
    181       1.4  augustss 	usbd_init();
    182       1.1  augustss 	sc->sc_bus = aux;
    183       1.1  augustss 	sc->sc_bus->usbctl = sc;
    184       1.1  augustss 	sc->sc_port.power = USB_MAX_POWER;
    185  1.28.4.1      fvdl 	err = usbd_new_device(USBDEV(sc->sc_dev), sc->sc_bus, 0, 0, 0,
    186  1.28.4.1      fvdl 		  &sc->sc_port);
    187       1.7  augustss 
    188  1.28.4.1      fvdl 	if (!err) {
    189       1.1  augustss 		dev = sc->sc_port.device;
    190  1.28.4.1      fvdl 		if (dev->hub == NULL) {
    191      1.22  augustss 			sc->sc_dying = 1;
    192       1.7  augustss 			printf("%s: root device is not a hub\n",
    193       1.7  augustss 			       USBDEVNAME(sc->sc_dev));
    194       1.7  augustss 			USB_ATTACH_ERROR_RETURN;
    195       1.1  augustss 		}
    196       1.1  augustss 		sc->sc_bus->root_hub = dev;
    197      1.24  augustss #if 1
    198      1.24  augustss 		/*
    199      1.24  augustss 		 * Turning this code off will delay attachment of USB devices
    200      1.24  augustss 		 * until the USB event thread is running, which means that
    201      1.24  augustss 		 * the keyboard will not work until after cold boot.
    202      1.24  augustss 		 */
    203      1.24  augustss 		if (cold) {
    204      1.24  augustss 			sc->sc_bus->use_polling++;
    205      1.24  augustss 			dev->hub->explore(sc->sc_bus->root_hub);
    206      1.24  augustss 			sc->sc_bus->use_polling--;
    207      1.24  augustss 		}
    208      1.24  augustss #endif
    209       1.1  augustss 	} else {
    210       1.1  augustss 		printf("%s: root hub problem, error=%d\n",
    211  1.28.4.1      fvdl 		       USBDEVNAME(sc->sc_dev), err);
    212      1.22  augustss 		sc->sc_dying = 1;
    213       1.1  augustss 	}
    214       1.7  augustss 
    215      1.28  augustss #if defined(__NetBSD__) || defined(__OpenBSD__)
    216      1.14   thorpej 	kthread_create(usb_create_event_thread, sc);
    217      1.28  augustss #endif
    218      1.28  augustss 
    219      1.28  augustss #if defined(__FreeBSD__)
    220      1.28  augustss 	make_dev(&usb_cdevsw, device_get_unit(self), UID_ROOT, GID_OPERATOR,
    221      1.28  augustss 		 0644, "usb%d", device_get_unit(self));
    222      1.28  augustss #endif
    223      1.13  augustss 
    224       1.7  augustss 	USB_ATTACH_SUCCESS_RETURN;
    225       1.1  augustss }
    226       1.1  augustss 
    227      1.28  augustss #if defined(__NetBSD__) || defined(__OpenBSD__)
    228      1.13  augustss void
    229      1.13  augustss usb_create_event_thread(arg)
    230      1.13  augustss 	void *arg;
    231      1.13  augustss {
    232      1.13  augustss 	struct usb_softc *sc = arg;
    233      1.13  augustss 
    234      1.22  augustss 	if (kthread_create1(usb_event_thread, sc, &sc->sc_event_thread,
    235      1.13  augustss 			   "%s", sc->sc_dev.dv_xname)) {
    236      1.13  augustss 		printf("%s: unable to create event thread for\n",
    237      1.13  augustss 		       sc->sc_dev.dv_xname);
    238      1.13  augustss 		panic("usb_create_event_thread");
    239      1.13  augustss 	}
    240      1.13  augustss }
    241      1.13  augustss 
    242      1.13  augustss void
    243      1.13  augustss usb_event_thread(arg)
    244      1.13  augustss 	void *arg;
    245      1.13  augustss {
    246      1.13  augustss 	struct usb_softc *sc = arg;
    247      1.13  augustss 
    248      1.27  augustss 	DPRINTF(("usb_event_thread: start\n"));
    249      1.27  augustss 
    250      1.22  augustss 	while (!sc->sc_dying) {
    251      1.21  augustss #ifdef USB_DEBUG
    252      1.22  augustss 		if (!usb_noexplore)
    253      1.21  augustss #endif
    254      1.22  augustss 		usb_discover(sc);
    255      1.22  augustss 		(void)tsleep(&sc->sc_bus->needs_explore,
    256      1.22  augustss 			     PWAIT, "usbevt", hz*60);
    257      1.13  augustss 		DPRINTFN(2,("usb_event_thread: woke up\n"));
    258      1.13  augustss 	}
    259      1.22  augustss 	sc->sc_event_thread = 0;
    260      1.13  augustss 
    261      1.13  augustss 	/* In case parent is waiting for us to exit. */
    262      1.13  augustss 	wakeup(sc);
    263      1.13  augustss 
    264      1.27  augustss 	DPRINTF(("usb_event_thread: exit\n"));
    265      1.13  augustss 	kthread_exit(0);
    266      1.13  augustss }
    267      1.13  augustss 
    268       1.1  augustss int
    269       1.1  augustss usbctlprint(aux, pnp)
    270       1.1  augustss 	void *aux;
    271       1.1  augustss 	const char *pnp;
    272       1.1  augustss {
    273       1.1  augustss 	/* only "usb"es can attach to host controllers */
    274       1.1  augustss 	if (pnp)
    275       1.1  augustss 		printf("usb at %s", pnp);
    276       1.1  augustss 
    277       1.1  augustss 	return (UNCONF);
    278       1.1  augustss }
    279      1.28  augustss #endif /* defined(__NetBSD__) || defined(__OpenBSD__) */
    280       1.7  augustss 
    281       1.1  augustss int
    282       1.1  augustss usbopen(dev, flag, mode, p)
    283       1.1  augustss 	dev_t dev;
    284       1.1  augustss 	int flag, mode;
    285       1.1  augustss 	struct proc *p;
    286       1.1  augustss {
    287      1.26  augustss 	int unit = minor(dev);
    288      1.26  augustss 	struct usb_softc *sc;
    289      1.26  augustss 
    290      1.26  augustss 	if (unit == USB_DEV_MINOR) {
    291      1.26  augustss 		if (usb_dev_open)
    292      1.26  augustss 			return (EBUSY);
    293      1.26  augustss 		usb_dev_open = 1;
    294      1.26  augustss 		usb_async_proc = 0;
    295      1.26  augustss 		return (0);
    296      1.26  augustss 	}
    297      1.26  augustss 
    298      1.26  augustss 	USB_GET_SC_OPEN(usb, unit, sc);
    299       1.1  augustss 
    300      1.22  augustss 	if (sc->sc_dying)
    301      1.22  augustss 		return (EIO);
    302       1.1  augustss 
    303       1.1  augustss 	return (0);
    304       1.1  augustss }
    305       1.1  augustss 
    306       1.1  augustss int
    307      1.26  augustss usbread(dev, uio, flag)
    308      1.26  augustss 	dev_t dev;
    309      1.26  augustss 	struct uio *uio;
    310      1.26  augustss 	int flag;
    311      1.26  augustss {
    312      1.26  augustss 	struct usb_event ue;
    313      1.26  augustss 	int s, error, n;
    314      1.26  augustss 
    315      1.26  augustss 	if (minor(dev) != USB_DEV_MINOR)
    316      1.26  augustss 		return (ENXIO);
    317      1.26  augustss 
    318      1.26  augustss 	if (uio->uio_resid != sizeof(struct usb_event))
    319      1.26  augustss 		return (EINVAL);
    320      1.26  augustss 
    321      1.26  augustss 	error = 0;
    322      1.26  augustss 	s = splusb();
    323      1.26  augustss 	for (;;) {
    324      1.26  augustss 		n = usb_get_next_event(&ue);
    325      1.26  augustss 		if (n != 0)
    326      1.26  augustss 			break;
    327      1.26  augustss 		if (flag & IO_NDELAY) {
    328      1.26  augustss 			error = EWOULDBLOCK;
    329      1.26  augustss 			break;
    330      1.26  augustss 		}
    331      1.26  augustss 		error = tsleep(&usb_events, PZERO | PCATCH, "usbrea", 0);
    332      1.26  augustss 		if (error)
    333      1.26  augustss 			break;
    334      1.26  augustss 	}
    335      1.26  augustss 	splx(s);
    336      1.26  augustss 	if (!error)
    337      1.26  augustss 		error = uiomove(&ue, uio->uio_resid, uio);
    338      1.26  augustss 
    339      1.26  augustss 	return (error);
    340      1.26  augustss }
    341      1.26  augustss 
    342      1.26  augustss int
    343       1.1  augustss usbclose(dev, flag, mode, p)
    344       1.1  augustss 	dev_t dev;
    345       1.1  augustss 	int flag, mode;
    346       1.1  augustss 	struct proc *p;
    347       1.1  augustss {
    348      1.26  augustss 	int unit = minor(dev);
    349      1.26  augustss 
    350      1.26  augustss 	if (unit == USB_DEV_MINOR) {
    351      1.26  augustss 		usb_async_proc = 0;
    352      1.26  augustss 		usb_dev_open = 0;
    353      1.26  augustss 	}
    354      1.26  augustss 
    355       1.1  augustss 	return (0);
    356       1.1  augustss }
    357       1.1  augustss 
    358       1.1  augustss int
    359      1.28  augustss usbioctl(devt, cmd, data, flag, p)
    360      1.28  augustss 	dev_t devt;
    361       1.1  augustss 	u_long cmd;
    362       1.1  augustss 	caddr_t data;
    363       1.1  augustss 	int flag;
    364       1.1  augustss 	struct proc *p;
    365       1.1  augustss {
    366      1.26  augustss 	struct usb_softc *sc;
    367      1.28  augustss 	int unit = minor(devt);
    368      1.26  augustss 
    369      1.26  augustss 	if (unit == USB_DEV_MINOR) {
    370      1.26  augustss 		switch (cmd) {
    371      1.26  augustss 		case FIONBIO:
    372      1.26  augustss 			/* All handled in the upper FS layer. */
    373      1.26  augustss 			return (0);
    374      1.26  augustss 
    375      1.26  augustss 		case FIOASYNC:
    376      1.26  augustss 			if (*(int *)data)
    377      1.26  augustss 				usb_async_proc = p;
    378      1.26  augustss 			else
    379      1.26  augustss 				usb_async_proc = 0;
    380      1.26  augustss 			return (0);
    381      1.26  augustss 
    382      1.26  augustss 		default:
    383      1.26  augustss 			return (EINVAL);
    384      1.26  augustss 		}
    385      1.26  augustss 	}
    386      1.26  augustss 
    387      1.26  augustss 	USB_GET_SC(usb, unit, sc);
    388       1.1  augustss 
    389      1.22  augustss 	if (sc->sc_dying)
    390      1.22  augustss 		return (EIO);
    391      1.22  augustss 
    392       1.1  augustss 	switch (cmd) {
    393      1.28  augustss #if defined(__FreeBSD__)
    394      1.28  augustss   	case USB_DISCOVER:
    395      1.28  augustss   		usb_discover(sc);
    396      1.28  augustss   		break;
    397      1.28  augustss #endif
    398       1.1  augustss #ifdef USB_DEBUG
    399       1.1  augustss 	case USB_SETDEBUG:
    400       1.1  augustss 		usbdebug = uhcidebug = ohcidebug = *(int *)data;
    401       1.1  augustss 		break;
    402       1.1  augustss #endif
    403       1.1  augustss 	case USB_REQUEST:
    404       1.1  augustss 	{
    405       1.1  augustss 		struct usb_ctl_request *ur = (void *)data;
    406       1.1  augustss 		int len = UGETW(ur->request.wLength);
    407       1.1  augustss 		struct iovec iov;
    408       1.1  augustss 		struct uio uio;
    409       1.1  augustss 		void *ptr = 0;
    410       1.1  augustss 		int addr = ur->addr;
    411  1.28.4.1      fvdl 		usbd_status err;
    412       1.1  augustss 		int error = 0;
    413       1.1  augustss 
    414       1.9  augustss 		DPRINTF(("usbioctl: USB_REQUEST addr=%d len=%d\n", addr, len));
    415       1.1  augustss 		if (len < 0 || len > 32768)
    416       1.9  augustss 			return (EINVAL);
    417       1.1  augustss 		if (addr < 0 || addr >= USB_MAX_DEVICES ||
    418       1.1  augustss 		    sc->sc_bus->devices[addr] == 0)
    419       1.9  augustss 			return (EINVAL);
    420       1.1  augustss 		if (len != 0) {
    421       1.1  augustss 			iov.iov_base = (caddr_t)ur->data;
    422       1.1  augustss 			iov.iov_len = len;
    423       1.1  augustss 			uio.uio_iov = &iov;
    424       1.1  augustss 			uio.uio_iovcnt = 1;
    425       1.1  augustss 			uio.uio_resid = len;
    426       1.1  augustss 			uio.uio_offset = 0;
    427       1.1  augustss 			uio.uio_segflg = UIO_USERSPACE;
    428       1.1  augustss 			uio.uio_rw =
    429       1.1  augustss 				ur->request.bmRequestType & UT_READ ?
    430       1.1  augustss 				UIO_READ : UIO_WRITE;
    431       1.1  augustss 			uio.uio_procp = p;
    432       1.1  augustss 			ptr = malloc(len, M_TEMP, M_WAITOK);
    433       1.1  augustss 			if (uio.uio_rw == UIO_WRITE) {
    434       1.1  augustss 				error = uiomove(ptr, len, &uio);
    435       1.1  augustss 				if (error)
    436       1.1  augustss 					goto ret;
    437       1.1  augustss 			}
    438       1.1  augustss 		}
    439  1.28.4.1      fvdl 		err = usbd_do_request_flags(sc->sc_bus->devices[addr],
    440  1.28.4.1      fvdl 			  &ur->request, ptr, ur->flags, &ur->actlen);
    441  1.28.4.1      fvdl 		if (err) {
    442       1.1  augustss 			error = EIO;
    443       1.1  augustss 			goto ret;
    444       1.1  augustss 		}
    445       1.1  augustss 		if (len != 0) {
    446       1.1  augustss 			if (uio.uio_rw == UIO_READ) {
    447       1.1  augustss 				error = uiomove(ptr, len, &uio);
    448       1.1  augustss 				if (error)
    449       1.1  augustss 					goto ret;
    450       1.1  augustss 			}
    451       1.1  augustss 		}
    452       1.1  augustss 	ret:
    453       1.1  augustss 		if (ptr)
    454       1.1  augustss 			free(ptr, M_TEMP);
    455       1.1  augustss 		return (error);
    456       1.1  augustss 	}
    457       1.1  augustss 
    458       1.1  augustss 	case USB_DEVICEINFO:
    459       1.1  augustss 	{
    460       1.1  augustss 		struct usb_device_info *di = (void *)data;
    461       1.1  augustss 		int addr = di->addr;
    462      1.26  augustss 		usbd_device_handle devh;
    463       1.1  augustss 
    464       1.1  augustss 		if (addr < 1 || addr >= USB_MAX_DEVICES)
    465       1.1  augustss 			return (EINVAL);
    466      1.26  augustss 		devh = sc->sc_bus->devices[addr];
    467      1.26  augustss 		if (devh == 0)
    468       1.1  augustss 			return (ENXIO);
    469      1.26  augustss 		usbd_fill_deviceinfo(devh, di);
    470       1.1  augustss 		break;
    471       1.1  augustss 	}
    472       1.2  augustss 
    473       1.2  augustss 	case USB_DEVICESTATS:
    474       1.2  augustss 		*(struct usb_device_stats *)data = sc->sc_bus->stats;
    475       1.2  augustss 		break;
    476       1.1  augustss 
    477       1.1  augustss 	default:
    478      1.26  augustss 		return (EINVAL);
    479       1.1  augustss 	}
    480       1.1  augustss 	return (0);
    481       1.1  augustss }
    482       1.1  augustss 
    483       1.1  augustss int
    484       1.1  augustss usbpoll(dev, events, p)
    485       1.1  augustss 	dev_t dev;
    486       1.1  augustss 	int events;
    487       1.1  augustss 	struct proc *p;
    488       1.1  augustss {
    489      1.26  augustss 	int revents, mask, s;
    490       1.1  augustss 
    491      1.26  augustss 	if (minor(dev) != USB_DEV_MINOR)
    492      1.26  augustss 		return (ENXIO);
    493      1.22  augustss 
    494      1.26  augustss 	revents = 0;
    495       1.1  augustss 	s = splusb();
    496      1.26  augustss 	mask = POLLIN | POLLRDNORM;
    497      1.26  augustss 	if (events & mask)
    498      1.26  augustss 		if (usb_nevents > 0)
    499      1.26  augustss 			revents |= events & mask;
    500      1.26  augustss 
    501       1.1  augustss 	DPRINTFN(2, ("usbpoll: revents=0x%x\n", revents));
    502       1.1  augustss 	if (revents == 0) {
    503      1.26  augustss 		if (events & mask) {
    504       1.1  augustss 			DPRINTFN(2, ("usbpoll: selrecord\n"));
    505      1.26  augustss 			selrecord(p, &usb_selevent);
    506       1.1  augustss 		}
    507       1.1  augustss 	}
    508       1.1  augustss 	splx(s);
    509       1.1  augustss 	return (revents);
    510       1.1  augustss }
    511       1.1  augustss 
    512      1.25  augustss /* Explore device tree from the root. */
    513       1.1  augustss usbd_status
    514       1.1  augustss usb_discover(sc)
    515       1.1  augustss 	struct usb_softc *sc;
    516       1.1  augustss {
    517      1.25  augustss 	/*
    518      1.25  augustss 	 * We need mutual exclusion while traversing the device tree,
    519      1.25  augustss 	 * but this is guaranteed since this function is only called
    520      1.25  augustss 	 * from the event thread for the controller.
    521      1.25  augustss 	 */
    522      1.13  augustss 	do {
    523      1.13  augustss 		sc->sc_bus->needs_explore = 0;
    524      1.13  augustss 		sc->sc_bus->root_hub->hub->explore(sc->sc_bus->root_hub);
    525      1.22  augustss 	} while (sc->sc_bus->needs_explore && !sc->sc_dying);
    526      1.13  augustss 	return (USBD_NORMAL_COMPLETION);
    527       1.1  augustss }
    528       1.1  augustss 
    529       1.1  augustss void
    530       1.1  augustss usb_needs_explore(bus)
    531       1.1  augustss 	usbd_bus_handle bus;
    532       1.1  augustss {
    533       1.1  augustss 	bus->needs_explore = 1;
    534      1.13  augustss 	wakeup(&bus->needs_explore);
    535       1.1  augustss }
    536       1.7  augustss 
    537      1.26  augustss /* Called at splusb() */
    538      1.26  augustss int
    539      1.26  augustss usb_get_next_event(ue)
    540      1.26  augustss 	struct usb_event *ue;
    541      1.26  augustss {
    542      1.26  augustss 	struct usb_event_q *ueq;
    543      1.26  augustss 
    544      1.26  augustss 	if (usb_nevents <= 0)
    545      1.26  augustss 		return (0);
    546      1.26  augustss 	ueq = SIMPLEQ_FIRST(&usb_events);
    547      1.26  augustss 	*ue = ueq->ue;
    548      1.26  augustss 	SIMPLEQ_REMOVE_HEAD(&usb_events, ueq, next);
    549      1.26  augustss 	free(ueq, M_USBDEV);
    550      1.26  augustss 	usb_nevents--;
    551      1.26  augustss 	return (1);
    552      1.26  augustss }
    553      1.26  augustss 
    554      1.26  augustss void
    555      1.26  augustss usbd_add_event(type, devh)
    556      1.26  augustss 	int type;
    557      1.26  augustss 	usbd_device_handle devh;
    558      1.26  augustss {
    559      1.26  augustss 	struct usb_event_q *ueq;
    560      1.26  augustss 	struct usb_event ue;
    561      1.26  augustss 	struct timeval thetime;
    562      1.26  augustss 	int s;
    563      1.26  augustss 
    564      1.26  augustss 	s = splusb();
    565      1.26  augustss 	if (++usb_nevents >= USB_MAX_EVENTS) {
    566      1.26  augustss 		/* Too many queued events, drop an old one. */
    567      1.26  augustss 		DPRINTFN(-1,("usb: event dropped\n"));
    568      1.26  augustss 		(void)usb_get_next_event(&ue);
    569      1.26  augustss 	}
    570      1.26  augustss 	/* Don't want to wait here inside splusb() */
    571      1.26  augustss 	ueq = malloc(sizeof *ueq, M_USBDEV, M_NOWAIT);
    572  1.28.4.1      fvdl 	if (ueq == NULL) {
    573      1.26  augustss 		printf("usb: no memory, event dropped\n");
    574      1.26  augustss 		splx(s);
    575      1.26  augustss 		return;
    576      1.26  augustss 	}
    577      1.26  augustss 	ueq->ue.ue_type = type;
    578      1.26  augustss 	ueq->ue.ue_cookie = devh->cookie;
    579      1.26  augustss 	usbd_fill_deviceinfo(devh, &ueq->ue.ue_device);
    580      1.26  augustss 	microtime(&thetime);
    581      1.26  augustss 	TIMEVAL_TO_TIMESPEC(&thetime, &ueq->ue.ue_time);
    582      1.26  augustss 	SIMPLEQ_INSERT_TAIL(&usb_events, ueq, next);
    583      1.26  augustss 	wakeup(&usb_events);
    584      1.26  augustss 	selwakeup(&usb_selevent);
    585  1.28.4.1      fvdl 	if (usb_async_proc != NULL)
    586      1.26  augustss 		psignal(usb_async_proc, SIGIO);
    587      1.26  augustss 	splx(s);
    588      1.26  augustss }
    589      1.26  augustss 
    590      1.28  augustss #if defined(__NetBSD__) || defined(__OpenBSD__)
    591       1.7  augustss int
    592      1.13  augustss usb_activate(self, act)
    593      1.19  augustss 	device_ptr_t self;
    594      1.13  augustss 	enum devact act;
    595       1.7  augustss {
    596      1.22  augustss 	struct usb_softc *sc = (struct usb_softc *)self;
    597      1.25  augustss 	usbd_device_handle dev = sc->sc_port.device;
    598      1.25  augustss 	int i, rv = 0;
    599      1.22  augustss 
    600      1.22  augustss 	switch (act) {
    601      1.22  augustss 	case DVACT_ACTIVATE:
    602      1.22  augustss 		return (EOPNOTSUPP);
    603      1.22  augustss 		break;
    604      1.22  augustss 
    605      1.22  augustss 	case DVACT_DEACTIVATE:
    606      1.22  augustss 		sc->sc_dying = 1;
    607      1.25  augustss 		if (dev && dev->cdesc && dev->subdevs) {
    608      1.25  augustss 			for (i = 0; dev->subdevs[i]; i++)
    609      1.25  augustss 				rv |= config_deactivate(dev->subdevs[i]);
    610      1.25  augustss 		}
    611      1.22  augustss 		break;
    612      1.22  augustss 	}
    613      1.22  augustss 	return (rv);
    614      1.13  augustss }
    615       1.7  augustss 
    616      1.13  augustss int
    617      1.13  augustss usb_detach(self, flags)
    618      1.19  augustss 	device_ptr_t self;
    619      1.13  augustss 	int flags;
    620      1.13  augustss {
    621      1.22  augustss 	struct usb_softc *sc = (struct usb_softc *)self;
    622      1.22  augustss 
    623      1.27  augustss 	DPRINTF(("usb_detach: start\n"));
    624      1.27  augustss 
    625      1.22  augustss 	sc->sc_dying = 1;
    626      1.22  augustss 
    627      1.22  augustss 	/* Make all devices disconnect. */
    628      1.25  augustss 	if (sc->sc_port.device)
    629      1.27  augustss 		usb_disconnect_port(&sc->sc_port, self);
    630      1.22  augustss 
    631      1.22  augustss 	/* Kill off event thread. */
    632      1.22  augustss 	if (sc->sc_event_thread) {
    633      1.22  augustss 		wakeup(&sc->sc_bus->needs_explore);
    634      1.22  augustss 		if (tsleep(sc, PWAIT, "usbdet", hz * 60))
    635      1.22  augustss 			printf("%s: event thread didn't die\n",
    636      1.22  augustss 			       USBDEVNAME(sc->sc_dev));
    637      1.27  augustss 		DPRINTF(("usb_detach: event thread dead\n"));
    638      1.22  augustss 	}
    639      1.22  augustss 
    640      1.26  augustss 	usbd_finish();
    641       1.7  augustss 	return (0);
    642       1.7  augustss }
    643      1.28  augustss #elif defined(__FreeBSD__)
    644      1.28  augustss int
    645      1.28  augustss usb_detach(device_t self)
    646      1.28  augustss {
    647      1.28  augustss 	DPRINTF(("%s: unload, prevented\n", USBDEVNAME(self)));
    648      1.28  augustss 
    649      1.28  augustss 	return (EINVAL);
    650      1.28  augustss }
    651      1.28  augustss #endif
    652      1.28  augustss 
    653       1.7  augustss 
    654      1.13  augustss #if defined(__FreeBSD__)
    655      1.28  augustss DRIVER_MODULE(usb, ohci, usb_driver, usb_devclass, 0, 0);
    656      1.28  augustss DRIVER_MODULE(usb, uhci, usb_driver, usb_devclass, 0, 0);
    657       1.7  augustss #endif
    658