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