usb.c revision 1.26 1 /* $NetBSD: usb.c,v 1.26 1999/10/12 11:54:56 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 while (!sc->sc_dying) {
230 #ifdef USB_DEBUG
231 if (!usb_noexplore)
232 #endif
233 usb_discover(sc);
234 (void)tsleep(&sc->sc_bus->needs_explore,
235 PWAIT, "usbevt", hz*60);
236 DPRINTFN(2,("usb_event_thread: woke up\n"));
237 }
238 sc->sc_event_thread = 0;
239
240 /* In case parent is waiting for us to exit. */
241 wakeup(sc);
242
243 kthread_exit(0);
244 }
245
246 #if defined(__NetBSD__) || defined(__OpenBSD__)
247 int
248 usbctlprint(aux, pnp)
249 void *aux;
250 const char *pnp;
251 {
252 /* only "usb"es can attach to host controllers */
253 if (pnp)
254 printf("usb at %s", pnp);
255
256 return (UNCONF);
257 }
258 #endif
259
260 int
261 usbopen(dev, flag, mode, p)
262 dev_t dev;
263 int flag, mode;
264 struct proc *p;
265 {
266 int unit = minor(dev);
267 struct usb_softc *sc;
268
269 if (unit == USB_DEV_MINOR) {
270 if (usb_dev_open)
271 return (EBUSY);
272 usb_dev_open = 1;
273 usb_async_proc = 0;
274 return (0);
275 }
276
277 USB_GET_SC_OPEN(usb, unit, sc);
278
279 if (sc->sc_dying)
280 return (EIO);
281
282 return (0);
283 }
284
285 int
286 usbread(dev, uio, flag)
287 dev_t dev;
288 struct uio *uio;
289 int flag;
290 {
291 struct usb_event ue;
292 int s, error, n;
293
294 if (minor(dev) != USB_DEV_MINOR)
295 return (ENXIO);
296
297 if (uio->uio_resid != sizeof(struct usb_event))
298 return (EINVAL);
299
300 error = 0;
301 s = splusb();
302 for (;;) {
303 n = usb_get_next_event(&ue);
304 if (n != 0)
305 break;
306 if (flag & IO_NDELAY) {
307 error = EWOULDBLOCK;
308 break;
309 }
310 error = tsleep(&usb_events, PZERO | PCATCH, "usbrea", 0);
311 if (error)
312 break;
313 }
314 splx(s);
315 if (!error)
316 error = uiomove(&ue, uio->uio_resid, uio);
317
318 return (error);
319 }
320
321 int
322 usbclose(dev, flag, mode, p)
323 dev_t dev;
324 int flag, mode;
325 struct proc *p;
326 {
327 int unit = minor(dev);
328
329 if (unit == USB_DEV_MINOR) {
330 usb_async_proc = 0;
331 usb_dev_open = 0;
332 }
333
334 return (0);
335 }
336
337 int
338 usbioctl(dev, cmd, data, flag, p)
339 dev_t dev;
340 u_long cmd;
341 caddr_t data;
342 int flag;
343 struct proc *p;
344 {
345 struct usb_softc *sc;
346 int unit = minor(dev);
347
348 if (unit == USB_DEV_MINOR) {
349 switch (cmd) {
350 case FIONBIO:
351 /* All handled in the upper FS layer. */
352 return (0);
353
354 case FIOASYNC:
355 if (*(int *)data)
356 usb_async_proc = p;
357 else
358 usb_async_proc = 0;
359 return (0);
360
361 default:
362 return (EINVAL);
363 }
364 }
365
366 USB_GET_SC(usb, unit, sc);
367
368 if (sc->sc_dying)
369 return (EIO);
370
371 switch (cmd) {
372 #ifdef USB_DEBUG
373 case USB_SETDEBUG:
374 usbdebug = uhcidebug = ohcidebug = *(int *)data;
375 break;
376 #endif
377 case USB_REQUEST:
378 {
379 struct usb_ctl_request *ur = (void *)data;
380 int len = UGETW(ur->request.wLength);
381 struct iovec iov;
382 struct uio uio;
383 void *ptr = 0;
384 int addr = ur->addr;
385 usbd_status r;
386 int error = 0;
387
388 DPRINTF(("usbioctl: USB_REQUEST addr=%d len=%d\n", addr, len));
389 if (len < 0 || len > 32768)
390 return (EINVAL);
391 if (addr < 0 || addr >= USB_MAX_DEVICES ||
392 sc->sc_bus->devices[addr] == 0)
393 return (EINVAL);
394 if (len != 0) {
395 iov.iov_base = (caddr_t)ur->data;
396 iov.iov_len = len;
397 uio.uio_iov = &iov;
398 uio.uio_iovcnt = 1;
399 uio.uio_resid = len;
400 uio.uio_offset = 0;
401 uio.uio_segflg = UIO_USERSPACE;
402 uio.uio_rw =
403 ur->request.bmRequestType & UT_READ ?
404 UIO_READ : UIO_WRITE;
405 uio.uio_procp = p;
406 ptr = malloc(len, M_TEMP, M_WAITOK);
407 if (uio.uio_rw == UIO_WRITE) {
408 error = uiomove(ptr, len, &uio);
409 if (error)
410 goto ret;
411 }
412 }
413 r = usbd_do_request_flags(sc->sc_bus->devices[addr],
414 &ur->request, ptr,
415 ur->flags, &ur->actlen);
416 if (r != USBD_NORMAL_COMPLETION) {
417 error = EIO;
418 goto ret;
419 }
420 if (len != 0) {
421 if (uio.uio_rw == UIO_READ) {
422 error = uiomove(ptr, len, &uio);
423 if (error)
424 goto ret;
425 }
426 }
427 ret:
428 if (ptr)
429 free(ptr, M_TEMP);
430 return (error);
431 }
432
433 case USB_DEVICEINFO:
434 {
435 struct usb_device_info *di = (void *)data;
436 int addr = di->addr;
437 usbd_device_handle devh;
438
439 if (addr < 1 || addr >= USB_MAX_DEVICES)
440 return (EINVAL);
441 devh = sc->sc_bus->devices[addr];
442 if (devh == 0)
443 return (ENXIO);
444 usbd_fill_deviceinfo(devh, di);
445 break;
446 }
447
448 case USB_DEVICESTATS:
449 *(struct usb_device_stats *)data = sc->sc_bus->stats;
450 break;
451
452 default:
453 return (EINVAL);
454 }
455 return (0);
456 }
457
458 int
459 usbpoll(dev, events, p)
460 dev_t dev;
461 int events;
462 struct proc *p;
463 {
464 int revents, mask, s;
465
466 if (minor(dev) != USB_DEV_MINOR)
467 return (ENXIO);
468
469 revents = 0;
470 s = splusb();
471 mask = POLLIN | POLLRDNORM;
472 if (events & mask)
473 if (usb_nevents > 0)
474 revents |= events & mask;
475
476 DPRINTFN(2, ("usbpoll: revents=0x%x\n", revents));
477 if (revents == 0) {
478 if (events & mask) {
479 DPRINTFN(2, ("usbpoll: selrecord\n"));
480 selrecord(p, &usb_selevent);
481 }
482 }
483 splx(s);
484 return (revents);
485 }
486
487 /* Explore device tree from the root. */
488 usbd_status
489 usb_discover(sc)
490 struct usb_softc *sc;
491 {
492 /*
493 * We need mutual exclusion while traversing the device tree,
494 * but this is guaranteed since this function is only called
495 * from the event thread for the controller.
496 */
497 do {
498 sc->sc_bus->needs_explore = 0;
499 sc->sc_bus->root_hub->hub->explore(sc->sc_bus->root_hub);
500 } while (sc->sc_bus->needs_explore && !sc->sc_dying);
501 return (USBD_NORMAL_COMPLETION);
502 }
503
504 void
505 usb_needs_explore(bus)
506 usbd_bus_handle bus;
507 {
508 bus->needs_explore = 1;
509 wakeup(&bus->needs_explore);
510 }
511
512 /* Called at splusb() */
513 int
514 usb_get_next_event(ue)
515 struct usb_event *ue;
516 {
517 struct usb_event_q *ueq;
518
519 if (usb_nevents <= 0)
520 return (0);
521 ueq = SIMPLEQ_FIRST(&usb_events);
522 *ue = ueq->ue;
523 SIMPLEQ_REMOVE_HEAD(&usb_events, ueq, next);
524 free(ueq, M_USBDEV);
525 usb_nevents--;
526 return (1);
527 }
528
529 void
530 usbd_add_event(type, devh)
531 int type;
532 usbd_device_handle devh;
533 {
534 struct usb_event_q *ueq;
535 struct usb_event ue;
536 struct timeval thetime;
537 int s;
538
539 s = splusb();
540 if (++usb_nevents >= USB_MAX_EVENTS) {
541 /* Too many queued events, drop an old one. */
542 DPRINTFN(-1,("usb: event dropped\n"));
543 (void)usb_get_next_event(&ue);
544 }
545 /* Don't want to wait here inside splusb() */
546 ueq = malloc(sizeof *ueq, M_USBDEV, M_NOWAIT);
547 if (ueq == 0) {
548 printf("usb: no memory, event dropped\n");
549 splx(s);
550 return;
551 }
552 ueq->ue.ue_type = type;
553 ueq->ue.ue_cookie = devh->cookie;
554 usbd_fill_deviceinfo(devh, &ueq->ue.ue_device);
555 microtime(&thetime);
556 TIMEVAL_TO_TIMESPEC(&thetime, &ueq->ue.ue_time);
557 SIMPLEQ_INSERT_TAIL(&usb_events, ueq, next);
558 wakeup(&usb_events);
559 selwakeup(&usb_selevent);
560 if (usb_async_proc)
561 psignal(usb_async_proc, SIGIO);
562 splx(s);
563 }
564
565 int
566 usb_activate(self, act)
567 device_ptr_t self;
568 enum devact act;
569 {
570 struct usb_softc *sc = (struct usb_softc *)self;
571 usbd_device_handle dev = sc->sc_port.device;
572 int i, rv = 0;
573
574 switch (act) {
575 case DVACT_ACTIVATE:
576 return (EOPNOTSUPP);
577 break;
578
579 case DVACT_DEACTIVATE:
580 sc->sc_dying = 1;
581 if (dev && dev->cdesc && dev->subdevs) {
582 for (i = 0; dev->subdevs[i]; i++)
583 rv |= config_deactivate(dev->subdevs[i]);
584 }
585 break;
586 }
587 return (rv);
588 }
589
590 int
591 usb_detach(self, flags)
592 device_ptr_t self;
593 int flags;
594 {
595 struct usb_softc *sc = (struct usb_softc *)self;
596
597 sc->sc_dying = 1;
598
599 /* Make all devices disconnect. */
600 if (sc->sc_port.device)
601 usb_disconnect_port(&sc->sc_port);
602
603 /* Kill off event thread. */
604 if (sc->sc_event_thread) {
605 wakeup(&sc->sc_bus->needs_explore);
606 if (tsleep(sc, PWAIT, "usbdet", hz * 60))
607 printf("%s: event thread didn't die\n",
608 USBDEVNAME(sc->sc_dev));
609 }
610
611 usbd_finish();
612 return (0);
613 }
614
615 #if defined(__FreeBSD__)
616 DRIVER_MODULE(usb, root, usb_driver, usb_devclass, 0, 0);
617 #endif
618