xref: /netbsd-src/sys/dev/usb/usb.c (revision 466a16a118933bd295a8a104f095714fadf9cf68)
1 /*	$NetBSD: usb.c,v 1.115 2008/05/26 18:00:33 drochner Exp $	*/
2 
3 /*
4  * Copyright (c) 1998, 2002, 2008 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 (lennart@augustsson.net) 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  *
20  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 /*
34  * USB specifications and other documentation can be found at
35  * http://www.usb.org/developers/docs/ and
36  * http://www.usb.org/developers/devclass_docs/
37  */
38 
39 #include <sys/cdefs.h>
40 __KERNEL_RCSID(0, "$NetBSD: usb.c,v 1.115 2008/05/26 18:00:33 drochner Exp $");
41 
42 #include "opt_compat_netbsd.h"
43 
44 #include "ohci.h"
45 #include "uhci.h"
46 
47 #include <sys/param.h>
48 #include <sys/systm.h>
49 #include <sys/kernel.h>
50 #include <sys/malloc.h>
51 #include <sys/device.h>
52 #include <sys/kthread.h>
53 #include <sys/proc.h>
54 #include <sys/conf.h>
55 #include <sys/fcntl.h>
56 #include <sys/poll.h>
57 #include <sys/select.h>
58 #include <sys/vnode.h>
59 #include <sys/signalvar.h>
60 #include <sys/intr.h>
61 
62 #include <dev/usb/usb.h>
63 #include <dev/usb/usbdi.h>
64 #include <dev/usb/usbdi_util.h>
65 
66 #define USB_DEV_MINOR 255
67 
68 #include <sys/bus.h>
69 
70 #include <dev/usb/usbdivar.h>
71 #include <dev/usb/usb_quirks.h>
72 
73 #ifdef USB_DEBUG
74 #define DPRINTF(x)	if (usbdebug) logprintf x
75 #define DPRINTFN(n,x)	if (usbdebug>(n)) logprintf x
76 int	usbdebug = 0;
77 #if defined(UHCI_DEBUG) && NUHCI > 0
78 extern int	uhcidebug;
79 #endif
80 #if defined(OHCI_DEBUG) && NOHCI > 0
81 extern int	ohcidebug;
82 #endif
83 /*
84  * 0  - do usual exploration
85  * 1  - do not use timeout exploration
86  * >1 - do no exploration
87  */
88 int	usb_noexplore = 0;
89 #else
90 #define DPRINTF(x)
91 #define DPRINTFN(n,x)
92 #endif
93 
94 struct usb_softc {
95 #if 0
96 	USBBASEDEVICE	sc_dev;		/* base device */
97 #endif
98 	usbd_bus_handle sc_bus;		/* USB controller */
99 	struct usbd_port sc_port;	/* dummy port for root hub */
100 
101 	struct lwp	*sc_event_thread;
102 
103 	char		sc_dying;
104 };
105 
106 struct usb_taskq {
107 	TAILQ_HEAD(, usb_task) tasks;
108 	struct lwp *task_thread_lwp;
109 	const char *name;
110 	int taskcreated;	/* task thread exists. */
111 };
112 
113 static struct usb_taskq usb_taskq[USB_NUM_TASKQS];
114 
115 dev_type_open(usbopen);
116 dev_type_close(usbclose);
117 dev_type_read(usbread);
118 dev_type_ioctl(usbioctl);
119 dev_type_poll(usbpoll);
120 dev_type_kqfilter(usbkqfilter);
121 
122 const struct cdevsw usb_cdevsw = {
123 	usbopen, usbclose, usbread, nowrite, usbioctl,
124 	nostop, notty, usbpoll, nommap, usbkqfilter, D_OTHER,
125 };
126 
127 Static void	usb_discover(struct usb_softc *);
128 Static void	usb_create_event_thread(device_t);
129 Static void	usb_event_thread(void *);
130 Static void	usb_task_thread(void *);
131 
132 #define USB_MAX_EVENTS 100
133 struct usb_event_q {
134 	struct usb_event ue;
135 	SIMPLEQ_ENTRY(usb_event_q) next;
136 };
137 Static SIMPLEQ_HEAD(, usb_event_q) usb_events =
138 	SIMPLEQ_HEAD_INITIALIZER(usb_events);
139 Static int usb_nevents = 0;
140 Static struct selinfo usb_selevent;
141 Static usb_proc_ptr usb_async_proc;  /* process that wants USB SIGIO */
142 Static void *usb_async_sih;
143 Static int usb_dev_open = 0;
144 Static struct usb_event *usb_alloc_event(void);
145 Static void usb_free_event(struct usb_event *);
146 Static void usb_add_event(int, struct usb_event *);
147 Static int usb_get_next_event(struct usb_event *);
148 Static void usb_async_intr(void *);
149 
150 #ifdef COMPAT_30
151 Static void usb_copy_old_devinfo(struct usb_device_info_old *, const struct usb_device_info *);
152 #endif
153 
154 Static const char *usbrev_str[] = USBREV_STR;
155 
156 static int usb_match(device_t, struct cfdata *, void *);
157 static void usb_attach(device_t, device_t, void *);
158 static int usb_detach(device_t, int);
159 static int usb_activate(device_t, enum devact);
160 static void usb_childdet(device_t, device_t);
161 static void usb_doattach(device_t);
162 
163 extern struct cfdriver usb_cd;
164 
165 CFATTACH_DECL2_NEW(usb, sizeof(struct usb_softc),
166     usb_match, usb_attach, usb_detach, usb_activate, NULL, usb_childdet);
167 
168 USB_MATCH(usb)
169 {
170 	DPRINTF(("usbd_match\n"));
171 	return (UMATCH_GENERIC);
172 }
173 
174 USB_ATTACH(usb)
175 {
176 	struct usb_softc *sc = device_private(self);
177 	int usbrev;
178 
179 	sc->sc_bus = aux;
180 	usbrev = sc->sc_bus->usbrev;
181 
182 	aprint_naive("\n");
183 	aprint_normal(": USB revision %s", usbrev_str[usbrev]);
184 	switch (usbrev) {
185 	case USBREV_1_0:
186 	case USBREV_1_1:
187 	case USBREV_2_0:
188 		break;
189 	default:
190 		aprint_error(", not supported\n");
191 		sc->sc_dying = 1;
192 		USB_ATTACH_ERROR_RETURN;
193 	}
194 	aprint_normal("\n");
195 
196 	config_interrupts(self, usb_doattach);
197 }
198 
199 static void
200 usb_doattach(device_t self)
201 {
202 	static bool usb_selevent_init;	/* XXX */
203 	struct usb_softc *sc = device_private(self);
204 	usbd_device_handle dev;
205 	usbd_status err;
206 	int speed;
207 	struct usb_event *ue;
208 
209 	if (!usb_selevent_init) {
210 		selinit(&usb_selevent);
211 		usb_selevent_init = true;
212 	}
213 	DPRINTF(("usbd_doattach\n"));
214 
215 	sc->sc_bus->usbctl = self;
216 	sc->sc_port.power = USB_MAX_POWER;
217 
218 	switch (sc->sc_bus->usbrev) {
219 	case USBREV_1_0:
220 	case USBREV_1_1:
221 		speed = USB_SPEED_FULL;
222 		break;
223 	case USBREV_2_0:
224 		speed = USB_SPEED_HIGH;
225 		break;
226 	default:
227 		panic("usb_doattach");
228 	}
229 
230 	ue = usb_alloc_event();
231 	ue->u.ue_ctrlr.ue_bus = device_unit(self);
232 	usb_add_event(USB_EVENT_CTRLR_ATTACH, ue);
233 
234 #ifdef USB_USE_SOFTINTR
235 	/* XXX we should have our own level */
236 	sc->sc_bus->soft = softint_establish(SOFTINT_NET,
237 	    sc->sc_bus->methods->soft_intr, sc->sc_bus);
238 	if (sc->sc_bus->soft == NULL) {
239 		aprint_error("%s: can't register softintr\n",
240 			     device_xname(self));
241 		sc->sc_dying = 1;
242 		USB_ATTACH_ERROR_RETURN;
243 	}
244 #endif
245 
246 	err = usbd_new_device(self, sc->sc_bus, 0, speed, 0,
247 		  &sc->sc_port);
248 	if (!err) {
249 		dev = sc->sc_port.device;
250 		if (dev->hub == NULL) {
251 			sc->sc_dying = 1;
252 			aprint_error("%s: root device is not a hub\n",
253 				     device_xname(self));
254 			USB_ATTACH_ERROR_RETURN;
255 		}
256 		sc->sc_bus->root_hub = dev;
257 #if 1
258 		/*
259 		 * Turning this code off will delay attachment of USB devices
260 		 * until the USB event thread is running, which means that
261 		 * the keyboard will not work until after cold boot.
262 		 */
263 		if (cold && (device_cfdata(self)->cf_flags & 1))
264 			dev->hub->explore(sc->sc_bus->root_hub);
265 #endif
266 	} else {
267 		aprint_error("%s: root hub problem, error=%d\n",
268 			     device_xname(self), err);
269 		sc->sc_dying = 1;
270 	}
271 
272 	config_pending_incr();
273 	usb_create_event_thread(self);
274 
275 	if (!pmf_device_register(self, NULL, NULL))
276 		aprint_error_dev(self, "couldn't establish power handler\n");
277 
278 	usb_async_sih = softint_establish(SOFTINT_CLOCK | SOFTINT_MPSAFE,
279 	   usb_async_intr, NULL);
280 
281 	USB_ATTACH_SUCCESS_RETURN;
282 }
283 
284 static const char *taskq_names[] = USB_TASKQ_NAMES;
285 
286 void
287 usb_create_event_thread(device_t self)
288 {
289 	struct usb_softc *sc = device_private(self);
290 	struct usb_taskq *taskq;
291 	int i;
292 
293 	if (usb_kthread_create1(PRI_NONE, 0, NULL, usb_event_thread, sc,
294 			&sc->sc_event_thread, "%s", device_xname(self))) {
295 		printf("%s: unable to create event thread for\n",
296 		       device_xname(self));
297 		panic("usb_create_event_thread");
298 	}
299 	for (i = 0; i < USB_NUM_TASKQS; i++) {
300 		taskq = &usb_taskq[i];
301 
302 		if (taskq->taskcreated)
303 			continue;
304 
305 		TAILQ_INIT(&taskq->tasks);
306 		taskq->taskcreated = 1;
307 		taskq->name = taskq_names[i];
308 		if (usb_kthread_create1(PRI_NONE, 0, NULL, usb_task_thread,
309 		    taskq, &taskq->task_thread_lwp, taskq->name)) {
310 			printf("unable to create task thread: %s\n", taskq->name);
311 			panic("usb_create_event_thread task");
312 		}
313 	}
314 }
315 
316 /*
317  * Add a task to be performed by the task thread.  This function can be
318  * called from any context and the task will be executed in a process
319  * context ASAP.
320  */
321 void
322 usb_add_task(usbd_device_handle dev, struct usb_task *task, int queue)
323 {
324 	struct usb_taskq *taskq;
325 	int s;
326 
327 	taskq = &usb_taskq[queue];
328 	s = splusb();
329 	if (task->queue == -1) {
330 		DPRINTFN(2,("usb_add_task: task=%p\n", task));
331 		TAILQ_INSERT_TAIL(&taskq->tasks, task, next);
332 		task->queue = queue;
333 	} else {
334 		DPRINTFN(3,("usb_add_task: task=%p on q\n", task));
335 	}
336 	wakeup(&taskq->tasks);
337 	splx(s);
338 }
339 
340 void
341 usb_rem_task(usbd_device_handle dev, struct usb_task *task)
342 {
343 	struct usb_taskq *taskq;
344 	int s;
345 
346 	taskq = &usb_taskq[task->queue];
347 	s = splusb();
348 	if (task->queue != -1) {
349 		TAILQ_REMOVE(&taskq->tasks, task, next);
350 		task->queue = -1;
351 	}
352 	splx(s);
353 }
354 
355 void
356 usb_event_thread(void *arg)
357 {
358 	struct usb_softc *sc = arg;
359 
360 	DPRINTF(("usb_event_thread: start\n"));
361 
362 	/*
363 	 * In case this controller is a companion controller to an
364 	 * EHCI controller we need to wait until the EHCI controller
365 	 * has grabbed the port.
366 	 * XXX It would be nicer to do this with a tsleep(), but I don't
367 	 * know how to synchronize the creation of the threads so it
368 	 * will work.
369 	 */
370 	usb_delay_ms(sc->sc_bus, 500);
371 
372 	/* Make sure first discover does something. */
373 	sc->sc_bus->needs_explore = 1;
374 	usb_discover(sc);
375 	config_pending_decr();
376 
377 	while (!sc->sc_dying) {
378 #ifdef USB_DEBUG
379 		if (usb_noexplore < 2)
380 #endif
381 		usb_discover(sc);
382 #ifdef USB_DEBUG
383 		(void)tsleep(&sc->sc_bus->needs_explore, PWAIT, "usbevt",
384 		    usb_noexplore ? 0 : hz * 60);
385 #else
386 		(void)tsleep(&sc->sc_bus->needs_explore, PWAIT, "usbevt",
387 		    hz * 60);
388 #endif
389 		DPRINTFN(2,("usb_event_thread: woke up\n"));
390 	}
391 	sc->sc_event_thread = NULL;
392 
393 	/* In case parent is waiting for us to exit. */
394 	wakeup(sc);
395 
396 	DPRINTF(("usb_event_thread: exit\n"));
397 	kthread_exit(0);
398 }
399 
400 void
401 usb_task_thread(void *arg)
402 {
403 	struct usb_task *task;
404 	struct usb_taskq *taskq;
405 	int s;
406 
407 	taskq = arg;
408 	DPRINTF(("usb_task_thread: start taskq %s\n", taskq->name));
409 
410 	s = splusb();
411 	for (;;) {
412 		task = TAILQ_FIRST(&taskq->tasks);
413 		if (task == NULL) {
414 			tsleep(&taskq->tasks, PWAIT, "usbtsk", 0);
415 			task = TAILQ_FIRST(&taskq->tasks);
416 		}
417 		DPRINTFN(2,("usb_task_thread: woke up task=%p\n", task));
418 		if (task != NULL) {
419 			TAILQ_REMOVE(&taskq->tasks, task, next);
420 			task->queue = -1;
421 			splx(s);
422 			task->fun(task->arg);
423 			s = splusb();
424 		}
425 	}
426 }
427 
428 int
429 usbctlprint(void *aux, const char *pnp)
430 {
431 	/* only "usb"es can attach to host controllers */
432 	if (pnp)
433 		aprint_normal("usb at %s", pnp);
434 
435 	return (UNCONF);
436 }
437 
438 int
439 usbopen(dev_t dev, int flag, int mode, struct lwp *l)
440 {
441 	int unit = minor(dev);
442 	struct usb_softc *sc;
443 
444 	if (unit == USB_DEV_MINOR) {
445 		if (usb_dev_open)
446 			return (EBUSY);
447 		usb_dev_open = 1;
448 		mutex_enter(proc_lock);
449 		usb_async_proc = 0;
450 		mutex_exit(proc_lock);
451 		return (0);
452 	}
453 
454 	sc = device_lookup_private(&usb_cd, unit);
455 	if (!sc)
456 		return (ENXIO);
457 
458 	if (sc->sc_dying)
459 		return (EIO);
460 
461 	return (0);
462 }
463 
464 int
465 usbread(dev_t dev, struct uio *uio, int flag)
466 {
467 	struct usb_event *ue;
468 #ifdef COMPAT_30
469 	struct usb_event_old *ueo = NULL;	/* XXXGCC */
470 #endif
471 	int s, error, n, useold;
472 
473 	if (minor(dev) != USB_DEV_MINOR)
474 		return (ENXIO);
475 
476 	useold = 0;
477 	switch (uio->uio_resid) {
478 #ifdef COMPAT_30
479 	case sizeof(struct usb_event_old):
480 		ueo = malloc(sizeof(struct usb_event_old), M_USBDEV,
481 			     M_WAITOK|M_ZERO);
482 		useold = 1;
483 		/* FALLTHRU */
484 #endif
485 	case sizeof(struct usb_event):
486 		ue = usb_alloc_event();
487 		break;
488 	default:
489 		return (EINVAL);
490 	}
491 
492 	error = 0;
493 	s = splusb();
494 	for (;;) {
495 		n = usb_get_next_event(ue);
496 		if (n != 0)
497 			break;
498 		if (flag & IO_NDELAY) {
499 			error = EWOULDBLOCK;
500 			break;
501 		}
502 		error = tsleep(&usb_events, PZERO | PCATCH, "usbrea", 0);
503 		if (error)
504 			break;
505 	}
506 	splx(s);
507 	if (!error) {
508 #ifdef COMPAT_30
509 		if (useold) { /* copy fields to old struct */
510 			ueo->ue_type = ue->ue_type;
511 			memcpy(&ueo->ue_time, &ue->ue_time,
512 			      sizeof(struct timespec));
513 			switch (ue->ue_type) {
514 				case USB_EVENT_DEVICE_ATTACH:
515 				case USB_EVENT_DEVICE_DETACH:
516 					usb_copy_old_devinfo(&ueo->u.ue_device, &ue->u.ue_device);
517 					break;
518 
519 				case USB_EVENT_CTRLR_ATTACH:
520 				case USB_EVENT_CTRLR_DETACH:
521 					ueo->u.ue_ctrlr.ue_bus=ue->u.ue_ctrlr.ue_bus;
522 					break;
523 
524 				case USB_EVENT_DRIVER_ATTACH:
525 				case USB_EVENT_DRIVER_DETACH:
526 					ueo->u.ue_driver.ue_cookie=ue->u.ue_driver.ue_cookie;
527 					memcpy(ueo->u.ue_driver.ue_devname,
528 					       ue->u.ue_driver.ue_devname,
529 					       sizeof(ue->u.ue_driver.ue_devname));
530 					break;
531 				default:
532 					;
533 			}
534 
535 			error = uiomove((void *)ueo, sizeof *ueo, uio);
536 		} else
537 #endif
538 			error = uiomove((void *)ue, sizeof *ue, uio);
539 	}
540 	usb_free_event(ue);
541 #ifdef COMPAT_30
542 	if (useold)
543 		free(ueo, M_USBDEV);
544 #endif
545 
546 	return (error);
547 }
548 
549 int
550 usbclose(dev_t dev, int flag, int mode,
551     struct lwp *l)
552 {
553 	int unit = minor(dev);
554 
555 	if (unit == USB_DEV_MINOR) {
556 		mutex_enter(proc_lock);
557 		usb_async_proc = 0;
558 		mutex_exit(proc_lock);
559 		usb_dev_open = 0;
560 	}
561 
562 	return (0);
563 }
564 
565 int
566 usbioctl(dev_t devt, u_long cmd, void *data, int flag, struct lwp *l)
567 {
568 	struct usb_softc *sc;
569 	int unit = minor(devt);
570 
571 	if (unit == USB_DEV_MINOR) {
572 		switch (cmd) {
573 		case FIONBIO:
574 			/* All handled in the upper FS layer. */
575 			return (0);
576 
577 		case FIOASYNC:
578 			mutex_enter(proc_lock);
579 			if (*(int *)data)
580 				usb_async_proc = l->l_proc;
581 			else
582 				usb_async_proc = 0;
583 			mutex_exit(proc_lock);
584 			return (0);
585 
586 		default:
587 			return (EINVAL);
588 		}
589 	}
590 
591 	sc = device_lookup_private(&usb_cd, unit);
592 
593 	if (sc->sc_dying)
594 		return (EIO);
595 
596 	switch (cmd) {
597 #ifdef USB_DEBUG
598 	case USB_SETDEBUG:
599 		if (!(flag & FWRITE))
600 			return (EBADF);
601 		usbdebug  = ((*(int *)data) & 0x000000ff);
602 #if defined(UHCI_DEBUG) && NUHCI > 0
603 		uhcidebug = ((*(int *)data) & 0x0000ff00) >> 8;
604 #endif
605 #if defined(OHCI_DEBUG) && NOHCI > 0
606 		ohcidebug = ((*(int *)data) & 0x00ff0000) >> 16;
607 #endif
608 		break;
609 #endif /* USB_DEBUG */
610 	case USB_REQUEST:
611 	{
612 		struct usb_ctl_request *ur = (void *)data;
613 		int len = UGETW(ur->ucr_request.wLength);
614 		struct iovec iov;
615 		struct uio uio;
616 		void *ptr = 0;
617 		int addr = ur->ucr_addr;
618 		usbd_status err;
619 		int error = 0;
620 
621 		if (!(flag & FWRITE))
622 			return (EBADF);
623 
624 		DPRINTF(("usbioctl: USB_REQUEST addr=%d len=%d\n", addr, len));
625 		if (len < 0 || len > 32768)
626 			return (EINVAL);
627 		if (addr < 0 || addr >= USB_MAX_DEVICES ||
628 		    sc->sc_bus->devices[addr] == 0)
629 			return (EINVAL);
630 		if (len != 0) {
631 			iov.iov_base = (void *)ur->ucr_data;
632 			iov.iov_len = len;
633 			uio.uio_iov = &iov;
634 			uio.uio_iovcnt = 1;
635 			uio.uio_resid = len;
636 			uio.uio_offset = 0;
637 			uio.uio_rw =
638 				ur->ucr_request.bmRequestType & UT_READ ?
639 				UIO_READ : UIO_WRITE;
640 			uio.uio_vmspace = l->l_proc->p_vmspace;
641 			ptr = malloc(len, M_TEMP, M_WAITOK);
642 			if (uio.uio_rw == UIO_WRITE) {
643 				error = uiomove(ptr, len, &uio);
644 				if (error)
645 					goto ret;
646 			}
647 		}
648 		err = usbd_do_request_flags(sc->sc_bus->devices[addr],
649 			  &ur->ucr_request, ptr, ur->ucr_flags, &ur->ucr_actlen,
650 			  USBD_DEFAULT_TIMEOUT);
651 		if (err) {
652 			error = EIO;
653 			goto ret;
654 		}
655 		if (len > ur->ucr_actlen)
656 			len = ur->ucr_actlen;
657 		if (len != 0) {
658 			if (uio.uio_rw == UIO_READ) {
659 				error = uiomove(ptr, len, &uio);
660 				if (error)
661 					goto ret;
662 			}
663 		}
664 	ret:
665 		if (ptr)
666 			free(ptr, M_TEMP);
667 		return (error);
668 	}
669 
670 	case USB_DEVICEINFO:
671 	{
672 		usbd_device_handle dev;
673 		struct usb_device_info *di = (void *)data;
674 		int addr = di->udi_addr;
675 
676 		if (addr < 1 || addr >= USB_MAX_DEVICES)
677 			return EINVAL;
678 		if ((dev = sc->sc_bus->devices[addr]) == NULL)
679 			return ENXIO;
680 		usbd_fill_deviceinfo(dev, di, 1);
681 		break;
682 	}
683 
684 #ifdef COMPAT_30
685 	case USB_DEVICEINFO_OLD:
686 	{
687 		usbd_device_handle dev;
688 		struct usb_device_info_old *di = (void *)data;
689 		int addr = di->udi_addr;
690 
691 		if (addr < 1 || addr >= USB_MAX_DEVICES)
692 			return EINVAL;
693 		if ((dev = sc->sc_bus->devices[addr]) == NULL)
694 			return ENXIO;
695 		usbd_fill_deviceinfo_old(dev, di, 1);
696 		break;
697 	}
698 #endif
699 
700 	case USB_DEVICESTATS:
701 		*(struct usb_device_stats *)data = sc->sc_bus->stats;
702 		break;
703 
704 	default:
705 		return (EINVAL);
706 	}
707 	return (0);
708 }
709 
710 int
711 usbpoll(dev_t dev, int events, struct lwp *l)
712 {
713 	int revents, mask, s;
714 
715 	if (minor(dev) == USB_DEV_MINOR) {
716 		revents = 0;
717 		mask = POLLIN | POLLRDNORM;
718 
719 		s = splusb();
720 		if (events & mask && usb_nevents > 0)
721 			revents |= events & mask;
722 		if (revents == 0 && events & mask)
723 			selrecord(l, &usb_selevent);
724 		splx(s);
725 
726 		return (revents);
727 	} else {
728 		return (0);
729 	}
730 }
731 
732 static void
733 filt_usbrdetach(struct knote *kn)
734 {
735 	int s;
736 
737 	s = splusb();
738 	SLIST_REMOVE(&usb_selevent.sel_klist, kn, knote, kn_selnext);
739 	splx(s);
740 }
741 
742 static int
743 filt_usbread(struct knote *kn, long hint)
744 {
745 
746 	if (usb_nevents == 0)
747 		return (0);
748 
749 	kn->kn_data = sizeof(struct usb_event);
750 	return (1);
751 }
752 
753 static const struct filterops usbread_filtops =
754 	{ 1, NULL, filt_usbrdetach, filt_usbread };
755 
756 int
757 usbkqfilter(dev_t dev, struct knote *kn)
758 {
759 	struct klist *klist;
760 	int s;
761 
762 	switch (kn->kn_filter) {
763 	case EVFILT_READ:
764 		if (minor(dev) != USB_DEV_MINOR)
765 			return (1);
766 		klist = &usb_selevent.sel_klist;
767 		kn->kn_fop = &usbread_filtops;
768 		break;
769 
770 	default:
771 		return (EINVAL);
772 	}
773 
774 	kn->kn_hook = NULL;
775 
776 	s = splusb();
777 	SLIST_INSERT_HEAD(klist, kn, kn_selnext);
778 	splx(s);
779 
780 	return (0);
781 }
782 
783 /* Explore device tree from the root. */
784 Static void
785 usb_discover(struct usb_softc *sc)
786 {
787 
788 	DPRINTFN(2,("usb_discover\n"));
789 #ifdef USB_DEBUG
790 	if (usb_noexplore > 1)
791 		return;
792 #endif
793 	/*
794 	 * We need mutual exclusion while traversing the device tree,
795 	 * but this is guaranteed since this function is only called
796 	 * from the event thread for the controller.
797 	 */
798 	while (sc->sc_bus->needs_explore && !sc->sc_dying) {
799 		sc->sc_bus->needs_explore = 0;
800 		sc->sc_bus->root_hub->hub->explore(sc->sc_bus->root_hub);
801 	}
802 }
803 
804 void
805 usb_needs_explore(usbd_device_handle dev)
806 {
807 	DPRINTFN(2,("usb_needs_explore\n"));
808 	dev->bus->needs_explore = 1;
809 	wakeup(&dev->bus->needs_explore);
810 }
811 
812 void
813 usb_needs_reattach(usbd_device_handle dev)
814 {
815 	DPRINTFN(2,("usb_needs_reattach\n"));
816 	dev->powersrc->reattach = 1;
817 	dev->bus->needs_explore = 1;
818 	wakeup(&dev->bus->needs_explore);
819 }
820 
821 /* Called at splusb() */
822 int
823 usb_get_next_event(struct usb_event *ue)
824 {
825 	struct usb_event_q *ueq;
826 
827 	if (usb_nevents <= 0)
828 		return (0);
829 	ueq = SIMPLEQ_FIRST(&usb_events);
830 #ifdef DIAGNOSTIC
831 	if (ueq == NULL) {
832 		printf("usb: usb_nevents got out of sync! %d\n", usb_nevents);
833 		usb_nevents = 0;
834 		return (0);
835 	}
836 #endif
837 	if (ue)
838 		*ue = ueq->ue;
839 	SIMPLEQ_REMOVE_HEAD(&usb_events, next);
840 	usb_free_event((struct usb_event *)(void *)ueq);
841 	usb_nevents--;
842 	return (1);
843 }
844 
845 void
846 usbd_add_dev_event(int type, usbd_device_handle udev)
847 {
848 	struct usb_event *ue = usb_alloc_event();
849 
850 	usbd_fill_deviceinfo(udev, &ue->u.ue_device, USB_EVENT_IS_ATTACH(type));
851 	usb_add_event(type, ue);
852 }
853 
854 void
855 usbd_add_drv_event(int type, usbd_device_handle udev, device_ptr_t dev)
856 {
857 	struct usb_event *ue = usb_alloc_event();
858 
859 	ue->u.ue_driver.ue_cookie = udev->cookie;
860 	strncpy(ue->u.ue_driver.ue_devname, USBDEVPTRNAME(dev),
861 	    sizeof ue->u.ue_driver.ue_devname);
862 	usb_add_event(type, ue);
863 }
864 
865 Static struct usb_event *
866 usb_alloc_event(void)
867 {
868 	/* Yes, this is right; we allocate enough so that we can use it later */
869 	return malloc(sizeof(struct usb_event_q), M_USBDEV, M_WAITOK|M_ZERO);
870 }
871 
872 Static void
873 usb_free_event(struct usb_event *uep)
874 {
875 	free(uep, M_USBDEV);
876 }
877 
878 Static void
879 usb_add_event(int type, struct usb_event *uep)
880 {
881 	struct usb_event_q *ueq;
882 	struct timeval thetime;
883 	int s;
884 
885 	microtime(&thetime);
886 	/* Don't want to wait here inside splusb() */
887 	ueq = (struct usb_event_q *)(void *)uep;
888 	ueq->ue = *uep;
889 	ueq->ue.ue_type = type;
890 	TIMEVAL_TO_TIMESPEC(&thetime, &ueq->ue.ue_time);
891 
892 	s = splusb();
893 	if (++usb_nevents >= USB_MAX_EVENTS) {
894 		/* Too many queued events, drop an old one. */
895 		DPRINTFN(-1,("usb: event dropped\n"));
896 		(void)usb_get_next_event(0);
897 	}
898 	SIMPLEQ_INSERT_TAIL(&usb_events, ueq, next);
899 	wakeup(&usb_events);
900 	selnotify(&usb_selevent, 0, 0);
901 	if (usb_async_proc != NULL) {
902 		softint_schedule(usb_async_sih);
903 	}
904 	splx(s);
905 }
906 
907 Static void
908 usb_async_intr(void *cookie)
909 {
910 	proc_t *proc;
911 
912 	mutex_enter(proc_lock);
913 	if ((proc = usb_async_proc) != NULL)
914 		psignal(proc, SIGIO);
915 	mutex_exit(proc_lock);
916 }
917 
918 void
919 usb_schedsoftintr(usbd_bus_handle bus)
920 {
921 	DPRINTFN(10,("usb_schedsoftintr: polling=%d\n", bus->use_polling));
922 #ifdef USB_USE_SOFTINTR
923 	if (bus->use_polling) {
924 		bus->methods->soft_intr(bus);
925 	} else {
926 		softint_schedule(bus->soft);
927 	}
928 #else
929 	bus->methods->soft_intr(bus);
930 #endif /* USB_USE_SOFTINTR */
931 }
932 
933 int
934 usb_activate(device_t self, enum devact act)
935 {
936 	struct usb_softc *sc = device_private(self);
937 	usbd_device_handle dev = sc->sc_port.device;
938 	int i, rv = 0;
939 
940 	switch (act) {
941 	case DVACT_ACTIVATE:
942 		return (EOPNOTSUPP);
943 
944 	case DVACT_DEACTIVATE:
945 		sc->sc_dying = 1;
946 		if (dev != NULL && dev->cdesc != NULL && dev->subdevlen > 0) {
947 			for (i = 0; i < dev->subdevlen; i++) {
948 				if (!dev->subdevs[i])
949 					continue;
950 				rv |= config_deactivate(dev->subdevs[i]);
951 			}
952 		}
953 		break;
954 	}
955 	return (rv);
956 }
957 
958 void
959 usb_childdet(device_t self, device_t child)
960 {
961 	int i;
962 	struct usb_softc *sc = device_private(self);
963 	struct usbd_device *dev;
964 
965 	if ((dev = sc->sc_port.device) == NULL || dev->subdevlen == 0)
966 		return;
967 
968 	for (i = 0; i < dev->subdevlen; i++)
969 		if (dev->subdevs[i] == child)
970 			dev->subdevs[i] = NULL;
971 }
972 
973 int
974 usb_detach(device_t self, int flags)
975 {
976 	struct usb_softc *sc = device_private(self);
977 	struct usb_event *ue;
978 
979 	DPRINTF(("usb_detach: start\n"));
980 
981 	pmf_device_deregister(self);
982 	/* Kill off event thread. */
983 	while (sc->sc_event_thread != NULL) {
984 		wakeup(&sc->sc_bus->needs_explore);
985 		tsleep(sc, PWAIT, "usbdet", hz * 60);
986 	}
987 	DPRINTF(("usb_detach: event thread dead\n"));
988 
989 	/* Make all devices disconnect. */
990 	if (sc->sc_port.device != NULL)
991 		usb_disconnect_port(&sc->sc_port, self);
992 
993 #ifdef USB_USE_SOFTINTR
994 	if (sc->sc_bus->soft != NULL) {
995 		softint_disestablish(sc->sc_bus->soft);
996 		sc->sc_bus->soft = NULL;
997 	}
998 #endif
999 
1000 	ue = usb_alloc_event();
1001 	ue->u.ue_ctrlr.ue_bus = device_unit(self);
1002 	usb_add_event(USB_EVENT_CTRLR_DETACH, ue);
1003 
1004 	return (0);
1005 }
1006 
1007 #ifdef COMPAT_30
1008 Static void
1009 usb_copy_old_devinfo(struct usb_device_info_old *uo,
1010 		     const struct usb_device_info *ue)
1011 {
1012 	const unsigned char *p;
1013 	unsigned char *q;
1014 	int i, n;
1015 
1016 	uo->udi_bus = ue->udi_bus;
1017 	uo->udi_addr = ue->udi_addr;
1018 	uo->udi_cookie = ue->udi_cookie;
1019 	for (i = 0, p = (const unsigned char *)ue->udi_product,
1020 	     q = (unsigned char *)uo->udi_product;
1021 	     *p && i < USB_MAX_STRING_LEN - 1; p++) {
1022 		if (*p < 0x80)
1023 			q[i++] = *p;
1024 		else {
1025 			q[i++] = '?';
1026 			if ((*p & 0xe0) == 0xe0)
1027 				p++;
1028 			p++;
1029 		}
1030 	}
1031 	q[i] = 0;
1032 
1033 	for (i = 0, p = ue->udi_vendor, q = uo->udi_vendor;
1034 	     *p && i < USB_MAX_STRING_LEN - 1; p++) {
1035 		if (* p < 0x80)
1036 			q[i++] = *p;
1037 		else {
1038 			q[i++] = '?';
1039 			p++;
1040 			if ((*p & 0xe0) == 0xe0)
1041 				p++;
1042 		}
1043 	}
1044 	q[i] = 0;
1045 
1046 	memcpy(uo->udi_release, ue->udi_release, sizeof(uo->udi_release));
1047 
1048 	uo->udi_productNo = ue->udi_productNo;
1049 	uo->udi_vendorNo = ue->udi_vendorNo;
1050 	uo->udi_releaseNo = ue->udi_releaseNo;
1051 	uo->udi_class = ue->udi_class;
1052 	uo->udi_subclass = ue->udi_subclass;
1053 	uo->udi_protocol = ue->udi_protocol;
1054 	uo->udi_config = ue->udi_config;
1055 	uo->udi_speed = ue->udi_speed;
1056 	uo->udi_power = ue->udi_power;
1057 	uo->udi_nports = ue->udi_nports;
1058 
1059 	for (n=0; n<USB_MAX_DEVNAMES; n++)
1060 		memcpy(uo->udi_devnames[n],
1061 		       ue->udi_devnames[n], USB_MAX_DEVNAMELEN);
1062 	memcpy(uo->udi_ports, ue->udi_ports, sizeof(uo->udi_ports));
1063 }
1064 #endif
1065