usbdi.c revision 1.40 1 /* $NetBSD: usbdi.c,v 1.40 1999/09/13 21:33:25 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 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/kernel.h>
43 #if defined(__NetBSD__) || defined(__OpenBSD__)
44 #include <sys/device.h>
45 #else
46 #include <sys/module.h>
47 #include <sys/bus.h>
48 #include <sys/conf.h>
49 #endif
50 #include <sys/malloc.h>
51 #include <sys/proc.h>
52
53 #include <machine/bus.h>
54
55 #include <dev/usb/usb.h>
56 #include <dev/usb/usbdi.h>
57 #include <dev/usb/usbdi_util.h>
58 #include <dev/usb/usbdivar.h>
59 #include <dev/usb/usb_mem.h>
60
61 #if defined(__FreeBSD__)
62 #include "usb_if.h"
63 #endif
64
65 #ifdef USB_DEBUG
66 #define DPRINTF(x) if (usbdebug) logprintf x
67 #define DPRINTFN(n,x) if (usbdebug>(n)) logprintf x
68 extern int usbdebug;
69 #else
70 #define DPRINTF(x)
71 #define DPRINTFN(n,x)
72 #endif
73
74 static usbd_status usbd_ar_pipe __P((usbd_pipe_handle pipe));
75 void usbd_do_request_async_cb
76 __P((usbd_request_handle, usbd_private_handle, usbd_status));
77 void usbd_start_next __P((usbd_pipe_handle pipe));
78
79 static SIMPLEQ_HEAD(, usbd_request) usbd_free_requests;
80
81 #if defined(__FreeBSD__)
82 #define USB_CDEV_MAJOR 108
83
84 extern struct cdevsw usb_cdevsw;
85 #endif
86
87 static __inline int usbd_reqh_isread __P((usbd_request_handle reqh));
88 static __inline int
89 usbd_reqh_isread(reqh)
90 usbd_request_handle reqh;
91 {
92 if (reqh->rqflags & URQ_REQUEST)
93 return (reqh->request.bmRequestType & UT_READ);
94 else
95 return (reqh->pipe->endpoint->edesc->bEndpointAddress &
96 UE_DIR_IN);
97 }
98
99 #ifdef USB_DEBUG
100 void usbd_dump_queue __P((usbd_pipe_handle));
101
102 void
103 usbd_dump_queue(pipe)
104 usbd_pipe_handle pipe;
105 {
106 usbd_request_handle reqh;
107
108 printf("usbd_dump_queue: pipe=%p\n", pipe);
109 for (reqh = SIMPLEQ_FIRST(&pipe->queue);
110 reqh;
111 reqh = SIMPLEQ_NEXT(reqh, next)) {
112 printf(" reqh=%p\n", reqh);
113 }
114 }
115 #endif
116
117 usbd_status
118 usbd_open_pipe(iface, address, flags, pipe)
119 usbd_interface_handle iface;
120 u_int8_t address;
121 u_int8_t flags;
122 usbd_pipe_handle *pipe;
123 {
124 usbd_pipe_handle p;
125 struct usbd_endpoint *ep;
126 usbd_status r;
127 int i;
128
129 for (i = 0; i < iface->idesc->bNumEndpoints; i++) {
130 ep = &iface->endpoints[i];
131 if (ep->edesc->bEndpointAddress == address)
132 goto found;
133 }
134 return (USBD_BAD_ADDRESS);
135 found:
136 if ((flags & USBD_EXCLUSIVE_USE) &&
137 ep->refcnt != 0)
138 return (USBD_IN_USE);
139 r = usbd_setup_pipe(iface->device, iface, ep, &p);
140 if (r != USBD_NORMAL_COMPLETION)
141 return (r);
142 LIST_INSERT_HEAD(&iface->pipes, p, next);
143 *pipe = p;
144 return (USBD_NORMAL_COMPLETION);
145 }
146
147 usbd_status
148 usbd_open_pipe_intr(iface, address, flags, pipe, priv, buffer, length, cb)
149 usbd_interface_handle iface;
150 u_int8_t address;
151 u_int8_t flags;
152 usbd_pipe_handle *pipe;
153 usbd_private_handle priv;
154 void *buffer;
155 u_int32_t length;
156 usbd_callback cb;
157 {
158 usbd_status r;
159 usbd_request_handle reqh;
160 usbd_pipe_handle ipipe;
161
162 r = usbd_open_pipe(iface, address, USBD_EXCLUSIVE_USE, &ipipe);
163 if (r != USBD_NORMAL_COMPLETION)
164 return (r);
165 reqh = usbd_alloc_request(iface->device);
166 if (reqh == 0) {
167 r = USBD_NOMEM;
168 goto bad1;
169 }
170 usbd_setup_request(reqh, ipipe, priv, buffer, length, flags,
171 USBD_NO_TIMEOUT, cb);
172 ipipe->intrreqh = reqh;
173 ipipe->repeat = 1;
174 r = usbd_transfer(reqh);
175 *pipe = ipipe;
176 if (r != USBD_IN_PROGRESS)
177 goto bad2;
178 return (USBD_NORMAL_COMPLETION);
179
180 bad2:
181 ipipe->intrreqh = 0;
182 ipipe->repeat = 0;
183 usbd_free_request(reqh);
184 bad1:
185 usbd_close_pipe(ipipe);
186 return r;
187 }
188
189 usbd_status
190 usbd_close_pipe(pipe)
191 usbd_pipe_handle pipe;
192 {
193 #ifdef DIAGNOSTIC
194 if (pipe == 0) {
195 printf("usbd_close_pipe: pipe==NULL\n");
196 return (USBD_NORMAL_COMPLETION);
197 }
198 #endif
199
200 if (--pipe->refcnt != 0)
201 return (USBD_NORMAL_COMPLETION);
202 if (SIMPLEQ_FIRST(&pipe->queue) != 0)
203 return (USBD_PENDING_REQUESTS);
204 LIST_REMOVE(pipe, next);
205 pipe->endpoint->refcnt--;
206 pipe->methods->close(pipe);
207 if (pipe->intrreqh)
208 usbd_free_request(pipe->intrreqh);
209 free(pipe, M_USB);
210 return (USBD_NORMAL_COMPLETION);
211 }
212
213 usbd_status
214 usbd_transfer(reqh)
215 usbd_request_handle reqh;
216 {
217 usbd_pipe_handle pipe = reqh->pipe;
218 usb_dma_t *dmap = &reqh->dmabuf;
219 usbd_status r;
220 u_int size;
221 int s;
222
223 DPRINTFN(5,("usbd_transfer: reqh=%p, flags=%d, pipe=%p, running=%d\n",
224 reqh, reqh->flags, pipe, pipe->running));
225 #ifdef USB_DEBUG
226 if (usbdebug > 5)
227 usbd_dump_queue(pipe);
228 #endif
229 reqh->done = 0;
230
231 size = reqh->length;
232 /* If there is no buffer, allocate one. */
233 if (!(reqh->rqflags & URQ_DEV_DMABUF) && size != 0) {
234 struct usbd_bus *bus = pipe->device->bus;
235
236 #ifdef DIAGNOSTIC
237 if (reqh->rqflags & URQ_AUTO_DMABUF)
238 printf("usbd_transfer: has old buffer!\n");
239 #endif
240 r = bus->methods->allocm(bus, dmap, size);
241 if (r != USBD_NORMAL_COMPLETION)
242 return (r);
243 reqh->rqflags |= URQ_AUTO_DMABUF;
244 }
245
246 /* Copy data if going out. */
247 if (!(reqh->flags & USBD_NO_COPY) && size != 0 &&
248 !usbd_reqh_isread(reqh))
249 memcpy(KERNADDR(dmap), reqh->buffer, size);
250
251 r = pipe->methods->transfer(reqh);
252
253 if (r != USBD_IN_PROGRESS && r != USBD_NORMAL_COMPLETION) {
254 /* The transfer has not been queued, so free buffer. */
255 if (reqh->rqflags & URQ_AUTO_DMABUF) {
256 struct usbd_bus *bus = pipe->device->bus;
257
258 bus->methods->freem(bus, &reqh->dmabuf);
259 reqh->rqflags &= ~URQ_AUTO_DMABUF;
260 }
261 }
262
263 if (!(reqh->flags & USBD_SYNCHRONOUS))
264 return (r);
265
266 /* Sync transfer, wait for completion. */
267 if (r != USBD_IN_PROGRESS)
268 return (r);
269 s = splusb();
270 if (!reqh->done) {
271 if (pipe->device->bus->use_polling)
272 panic("usbd_transfer: not done\n");
273 tsleep(reqh, PRIBIO, "usbsyn", 0);
274 }
275 splx(s);
276 return (reqh->status);
277 }
278
279 /* Like usbd_transfer(), but waits for completion. */
280 usbd_status
281 usbd_sync_transfer(reqh)
282 usbd_request_handle reqh;
283 {
284 reqh->flags |= USBD_SYNCHRONOUS;
285 return (usbd_transfer(reqh));
286 }
287
288 void *
289 usbd_alloc_buffer(reqh, size)
290 usbd_request_handle reqh;
291 u_int32_t size;
292 {
293 struct usbd_bus *bus = reqh->device->bus;
294 usbd_status r;
295
296 r = bus->methods->allocm(bus, &reqh->dmabuf, size);
297 if (r != USBD_NORMAL_COMPLETION)
298 return (0);
299 reqh->rqflags |= URQ_DEV_DMABUF;
300 return (KERNADDR(&reqh->dmabuf));
301 }
302
303 void
304 usbd_free_buffer(reqh)
305 usbd_request_handle reqh;
306 {
307 #ifdef DIAGNOSTIC
308 if (!(reqh->rqflags & (URQ_DEV_DMABUF | URQ_AUTO_DMABUF))) {
309 printf("usbd_free_buffer: no buffer\n");
310 return;
311 }
312 #endif
313 reqh->rqflags &= ~(URQ_DEV_DMABUF | URQ_AUTO_DMABUF);
314 reqh->device->bus->methods->freem(reqh->device->bus, &reqh->dmabuf);
315 }
316
317 void *
318 usbd_get_buffer(reqh)
319 usbd_request_handle reqh;
320 {
321 if (!(reqh->rqflags & URQ_DEV_DMABUF))
322 return (0);
323 return (KERNADDR(&reqh->dmabuf));
324 }
325
326 usbd_request_handle
327 usbd_alloc_request(dev)
328 usbd_device_handle dev;
329 {
330 usbd_request_handle reqh;
331
332 reqh = SIMPLEQ_FIRST(&usbd_free_requests);
333 if (reqh)
334 SIMPLEQ_REMOVE_HEAD(&usbd_free_requests, reqh, next);
335 else
336 reqh = malloc(sizeof(*reqh), M_USB, M_NOWAIT);
337 if (!reqh)
338 return (0);
339 memset(reqh, 0, sizeof *reqh);
340 reqh->device = dev;
341 DPRINTFN(5,("usbd_alloc_request() = %p\n", reqh));
342 return (reqh);
343 }
344
345 usbd_status
346 usbd_free_request(reqh)
347 usbd_request_handle reqh;
348 {
349 DPRINTFN(5,("usbd_free_request: %p\n", reqh));
350 if (reqh->rqflags & (URQ_DEV_DMABUF | URQ_AUTO_DMABUF))
351 usbd_free_buffer(reqh);
352 SIMPLEQ_INSERT_HEAD(&usbd_free_requests, reqh, next);
353 return (USBD_NORMAL_COMPLETION);
354 }
355
356 void
357 usbd_setup_request(reqh, pipe, priv, buffer, length, flags, timeout, callback)
358 usbd_request_handle reqh;
359 usbd_pipe_handle pipe;
360 usbd_private_handle priv;
361 void *buffer;
362 u_int32_t length;
363 u_int16_t flags;
364 u_int32_t timeout;
365 void (*callback) __P((usbd_request_handle,
366 usbd_private_handle,
367 usbd_status));
368 {
369 reqh->pipe = pipe;
370 reqh->priv = priv;
371 reqh->buffer = buffer;
372 reqh->length = length;
373 reqh->actlen = 0;
374 reqh->flags = flags;
375 reqh->timeout = timeout;
376 reqh->status = USBD_NOT_STARTED;
377 reqh->callback = callback;
378 reqh->rqflags &= ~URQ_REQUEST;
379 reqh->nframes = 0;
380 }
381
382 void
383 usbd_setup_default_request(reqh, dev, priv, timeout, req, buffer,
384 length, flags, callback)
385 usbd_request_handle reqh;
386 usbd_device_handle dev;
387 usbd_private_handle priv;
388 u_int32_t timeout;
389 usb_device_request_t *req;
390 void *buffer;
391 u_int32_t length;
392 u_int16_t flags;
393 void (*callback) __P((usbd_request_handle,
394 usbd_private_handle,
395 usbd_status));
396 {
397 reqh->pipe = dev->default_pipe;
398 reqh->priv = priv;
399 reqh->buffer = buffer;
400 reqh->length = length;
401 reqh->actlen = 0;
402 reqh->flags = flags;
403 reqh->timeout = timeout;
404 reqh->status = USBD_NOT_STARTED;
405 reqh->callback = callback;
406 reqh->request = *req;
407 reqh->rqflags |= URQ_REQUEST;
408 reqh->nframes = 0;
409 }
410
411 void
412 usbd_setup_isoc_request(reqh, pipe, priv, frlengths, nframes, flags, callback)
413 usbd_request_handle reqh;
414 usbd_pipe_handle pipe;
415 usbd_private_handle priv;
416 u_int16_t *frlengths;
417 u_int32_t nframes;
418 u_int16_t flags;
419 usbd_callback callback;
420 {
421 reqh->pipe = pipe;
422 reqh->priv = priv;
423 reqh->buffer = 0;
424 reqh->length = 0;
425 reqh->actlen = 0;
426 reqh->flags = flags;
427 reqh->timeout = USBD_NO_TIMEOUT;
428 reqh->status = USBD_NOT_STARTED;
429 reqh->callback = callback;
430 reqh->rqflags &= ~URQ_REQUEST;
431 reqh->frlengths = frlengths;
432 reqh->nframes = nframes;
433 }
434
435 void
436 usbd_get_request_status(reqh, priv, buffer, count, status)
437 usbd_request_handle reqh;
438 usbd_private_handle *priv;
439 void **buffer;
440 u_int32_t *count;
441 usbd_status *status;
442 {
443 if (priv)
444 *priv = reqh->priv;
445 if (buffer)
446 *buffer = reqh->buffer;
447 if (count)
448 *count = reqh->actlen;
449 if (status)
450 *status = reqh->status;
451 }
452
453 usb_config_descriptor_t *
454 usbd_get_config_descriptor(dev)
455 usbd_device_handle dev;
456 {
457 return (dev->cdesc);
458 }
459
460 usb_interface_descriptor_t *
461 usbd_get_interface_descriptor(iface)
462 usbd_interface_handle iface;
463 {
464 return (iface->idesc);
465 }
466
467 usb_device_descriptor_t *
468 usbd_get_device_descriptor(dev)
469 usbd_device_handle dev;
470 {
471 return (&dev->ddesc);
472 }
473
474 usb_endpoint_descriptor_t *
475 usbd_interface2endpoint_descriptor(iface, index)
476 usbd_interface_handle iface;
477 u_int8_t index;
478 {
479 if (index >= iface->idesc->bNumEndpoints)
480 return (0);
481 return (iface->endpoints[index].edesc);
482 }
483
484 usbd_status
485 usbd_abort_pipe(pipe)
486 usbd_pipe_handle pipe;
487 {
488 usbd_status r;
489 int s;
490
491 #ifdef DIAGNOSTIC
492 if (pipe == 0) {
493 printf("usbd_close_pipe: pipe==NULL\n");
494 return (USBD_NORMAL_COMPLETION);
495 }
496 #endif
497 s = splusb();
498 r = usbd_ar_pipe(pipe);
499 splx(s);
500 return (r);
501 }
502
503 usbd_status
504 usbd_clear_endpoint_stall(pipe)
505 usbd_pipe_handle pipe;
506 {
507 usbd_device_handle dev = pipe->device;
508 usb_device_request_t req;
509 usbd_status r;
510
511 DPRINTFN(8, ("usbd_clear_endpoint_stall\n"));
512
513 /*
514 * Clearing en endpoint stall resets the enpoint toggle, so
515 * do the same to the HC toggle.
516 */
517 pipe->methods->cleartoggle(pipe);
518
519 req.bmRequestType = UT_WRITE_ENDPOINT;
520 req.bRequest = UR_CLEAR_FEATURE;
521 USETW(req.wValue, UF_ENDPOINT_HALT);
522 USETW(req.wIndex, pipe->endpoint->edesc->bEndpointAddress);
523 USETW(req.wLength, 0);
524 r = usbd_do_request(dev, &req, 0);
525 #if 0
526 XXX should we do this?
527 if (r == USBD_NORMAL_COMPLETION) {
528 pipe->state = USBD_PIPE_ACTIVE;
529 /* XXX activate pipe */
530 }
531 #endif
532 return (r);
533 }
534
535 usbd_status
536 usbd_clear_endpoint_stall_async(pipe)
537 usbd_pipe_handle pipe;
538 {
539 usbd_device_handle dev = pipe->device;
540 usb_device_request_t req;
541 usbd_status r;
542
543 pipe->methods->cleartoggle(pipe);
544
545 req.bmRequestType = UT_WRITE_ENDPOINT;
546 req.bRequest = UR_CLEAR_FEATURE;
547 USETW(req.wValue, UF_ENDPOINT_HALT);
548 USETW(req.wIndex, pipe->endpoint->edesc->bEndpointAddress);
549 USETW(req.wLength, 0);
550 r = usbd_do_request_async(dev, &req, 0);
551 return (r);
552 }
553
554 usbd_status
555 usbd_endpoint_count(iface, count)
556 usbd_interface_handle iface;
557 u_int8_t *count;
558 {
559 *count = iface->idesc->bNumEndpoints;
560 return (USBD_NORMAL_COMPLETION);
561 }
562
563 usbd_status
564 usbd_interface_count(dev, count)
565 usbd_device_handle dev;
566 u_int8_t *count;
567 {
568 if (!dev->cdesc)
569 return (USBD_NOT_CONFIGURED);
570 *count = dev->cdesc->bNumInterface;
571 return (USBD_NORMAL_COMPLETION);
572 }
573
574 usbd_status
575 usbd_interface2device_handle(iface, dev)
576 usbd_interface_handle iface;
577 usbd_device_handle *dev;
578 {
579 *dev = iface->device;
580 return (USBD_NORMAL_COMPLETION);
581 }
582
583 usbd_status
584 usbd_device2interface_handle(dev, ifaceno, iface)
585 usbd_device_handle dev;
586 u_int8_t ifaceno;
587 usbd_interface_handle *iface;
588 {
589 if (!dev->cdesc)
590 return (USBD_NOT_CONFIGURED);
591 if (ifaceno >= dev->cdesc->bNumInterface)
592 return (USBD_INVAL);
593 *iface = &dev->ifaces[ifaceno];
594 return (USBD_NORMAL_COMPLETION);
595 }
596
597 usbd_device_handle
598 usbd_pipe2device_handle(pipe)
599 usbd_pipe_handle pipe;
600 {
601 return (pipe->device);
602 }
603
604 /* XXXX use altno */
605 usbd_status
606 usbd_set_interface(iface, altidx)
607 usbd_interface_handle iface;
608 int altidx;
609 {
610 usb_device_request_t req;
611 usbd_status r;
612
613 if (LIST_FIRST(&iface->pipes) != 0)
614 return (USBD_IN_USE);
615
616 if (iface->endpoints)
617 free(iface->endpoints, M_USB);
618 iface->endpoints = 0;
619 iface->idesc = 0;
620
621 r = usbd_fill_iface_data(iface->device, iface->index, altidx);
622 if (r != USBD_NORMAL_COMPLETION)
623 return (r);
624
625 req.bmRequestType = UT_WRITE_INTERFACE;
626 req.bRequest = UR_SET_INTERFACE;
627 USETW(req.wValue, iface->idesc->bAlternateSetting);
628 USETW(req.wIndex, iface->idesc->bInterfaceNumber);
629 USETW(req.wLength, 0);
630 return usbd_do_request(iface->device, &req, 0);
631 }
632
633 int
634 usbd_get_no_alts(cdesc, ifaceno)
635 usb_config_descriptor_t *cdesc;
636 int ifaceno;
637 {
638 char *p = (char *)cdesc;
639 char *end = p + UGETW(cdesc->wTotalLength);
640 usb_interface_descriptor_t *d;
641 int n;
642
643 for (n = 0; p < end; p += d->bLength) {
644 d = (usb_interface_descriptor_t *)p;
645 if (p + d->bLength <= end &&
646 d->bDescriptorType == UDESC_INTERFACE &&
647 d->bInterfaceNumber == ifaceno)
648 n++;
649 }
650 return (n);
651 }
652
653 int
654 usbd_get_interface_altindex(iface)
655 usbd_interface_handle iface;
656 {
657 return (iface->altindex);
658 }
659
660 usbd_status
661 usbd_get_interface(iface, aiface)
662 usbd_interface_handle iface;
663 u_int8_t *aiface;
664 {
665 usb_device_request_t req;
666
667 req.bmRequestType = UT_READ_INTERFACE;
668 req.bRequest = UR_GET_INTERFACE;
669 USETW(req.wValue, 0);
670 USETW(req.wIndex, iface->idesc->bInterfaceNumber);
671 USETW(req.wLength, 1);
672 return usbd_do_request(iface->device, &req, aiface);
673 }
674
675 /*** Internal routines ***/
676
677 /* Dequeue all pipe operations, called at splusb(). */
678 static usbd_status
679 usbd_ar_pipe(pipe)
680 usbd_pipe_handle pipe;
681 {
682 usbd_request_handle reqh;
683
684 SPLUSBCHECK;
685
686 DPRINTFN(2,("usbd_ar_pipe: pipe=%p\n", pipe));
687 #ifdef USB_DEBUG
688 if (usbdebug > 5)
689 usbd_dump_queue(pipe);
690 #endif
691 while ((reqh = SIMPLEQ_FIRST(&pipe->queue))) {
692 DPRINTFN(2,("usbd_ar_pipe: pipe=%p reqh=%p (methods=%p)\n",
693 pipe, reqh, pipe->methods));
694 /* Make the HC abort it (and invoke the callback). */
695 pipe->methods->abort(reqh);
696 /* XXX only for non-0 usbd_clear_endpoint_stall(pipe); */
697 }
698 return (USBD_NORMAL_COMPLETION);
699 }
700
701 static int usbd_global_init_done = 0;
702
703 void
704 usbd_init()
705 {
706 #if defined(__FreeBSD__)
707 dev_t dev;
708 #endif
709
710 if (!usbd_global_init_done) {
711 usbd_global_init_done = 1;
712 SIMPLEQ_INIT(&usbd_free_requests);
713
714 #if defined(__FreeBSD__)
715 dev = makedev(USB_CDEV_MAJOR, 0);
716 cdevsw_add(&dev, &usb_cdevsw, NULL);
717 #endif
718 }
719 }
720
721 /* Called at splusb() */
722 void
723 usb_transfer_complete(reqh)
724 usbd_request_handle reqh;
725 {
726 usbd_pipe_handle pipe = reqh->pipe;
727 usb_dma_t *dmap = &reqh->dmabuf;
728 int polling;
729
730 SPLUSBCHECK;
731
732 DPRINTFN(5, ("usb_transfer_complete: pipe=%p reqh=%p status=%d actlen=%d\n",
733 pipe, reqh, reqh->status, reqh->actlen));
734
735 #ifdef DIAGNOSTIC
736 if (!pipe) {
737 printf("usbd_transfer_cb: pipe==0, reqh=%p\n", reqh);
738 return;
739 }
740 #endif
741 polling = pipe->device->bus->use_polling;
742 /* XXXX */
743 if (polling)
744 pipe->running = 0;
745
746 if (!(reqh->flags & USBD_NO_COPY) && reqh->actlen != 0 &&
747 usbd_reqh_isread(reqh))
748 memcpy(reqh->buffer, KERNADDR(dmap), reqh->actlen);
749
750 /* if we allocated the buffer in usbd_transfer() we free it here. */
751 if (reqh->rqflags & URQ_AUTO_DMABUF) {
752 if (!pipe->repeat) {
753 struct usbd_bus *bus = pipe->device->bus;
754 bus->methods->freem(bus, dmap);
755 reqh->rqflags &= ~URQ_AUTO_DMABUF;
756 }
757 }
758
759 if (pipe->methods->done)
760 pipe->methods->done(reqh);
761
762 /* Remove request from queue. */
763 SIMPLEQ_REMOVE_HEAD(&pipe->queue, reqh, next);
764
765 /* Count completed transfers. */
766 ++pipe->device->bus->stats.requests
767 [pipe->endpoint->edesc->bmAttributes & UE_XFERTYPE];
768
769 reqh->done = 1;
770 if (reqh->status == USBD_NORMAL_COMPLETION &&
771 reqh->actlen < reqh->length &&
772 !(reqh->flags & USBD_SHORT_XFER_OK)) {
773 DPRINTFN(-1, ("usbd_transfer_cb: short xfer %d<%d (bytes)\n",
774 reqh->actlen, reqh->length));
775 reqh->status = USBD_SHORT_XFER;
776 }
777
778 if (reqh->callback)
779 reqh->callback(reqh, reqh->priv, reqh->status);
780
781 if ((reqh->flags & USBD_SYNCHRONOUS) && !polling)
782 wakeup(reqh);
783
784 if (!pipe->repeat) {
785 /* XXX should we stop the queue on all errors? */
786 if (reqh->status == USBD_CANCELLED ||
787 reqh->status == USBD_TIMEOUT)
788 pipe->running = 0;
789 else
790 usbd_start_next(pipe);
791 }
792 }
793
794 usbd_status
795 usb_insert_transfer(reqh)
796 usbd_request_handle reqh;
797 {
798 usbd_pipe_handle pipe = reqh->pipe;
799 usbd_status r;
800 int s;
801
802 DPRINTFN(5,("usb_insert_transfer: pipe=%p running=%d timeout=%d\n",
803 pipe, pipe->running, reqh->timeout));
804 s = splusb();
805 SIMPLEQ_INSERT_TAIL(&pipe->queue, reqh, next);
806 if (pipe->running)
807 r = USBD_IN_PROGRESS;
808 else {
809 pipe->running = 1;
810 r = USBD_NORMAL_COMPLETION;
811 }
812 splx(s);
813 return (r);
814 }
815
816 /* Called at splusb() */
817 void
818 usbd_start_next(pipe)
819 usbd_pipe_handle pipe;
820 {
821 usbd_request_handle reqh;
822 usbd_status r;
823
824 SPLUSBCHECK;
825
826 DPRINTFN(10, ("usbd_start_next: pipe=%p\n", pipe));
827
828 #ifdef DIAGNOSTIC
829 if (!pipe) {
830 printf("usbd_start_next: pipe == 0\n");
831 return;
832 }
833 if (!pipe->methods || !pipe->methods->start) {
834 printf("usbd_start_next: no start method\n");
835 return;
836 }
837 #endif
838
839 /* Get next request in queue. */
840 reqh = SIMPLEQ_FIRST(&pipe->queue);
841 DPRINTFN(5, ("usbd_start_next: pipe=%p start reqh=%p\n", pipe, reqh));
842 if (!reqh)
843 pipe->running = 0;
844 else {
845 r = pipe->methods->start(reqh);
846 if (r != USBD_IN_PROGRESS) {
847 printf("usbd_start_next: error=%d\n", r);
848 pipe->running = 0;
849 /* XXX do what? */
850 }
851 }
852 }
853
854 usbd_status
855 usbd_do_request(dev, req, data)
856 usbd_device_handle dev;
857 usb_device_request_t *req;
858 void *data;
859 {
860 return (usbd_do_request_flags(dev, req, data, 0, 0));
861 }
862
863 usbd_status
864 usbd_do_request_flags(dev, req, data, flags, actlen)
865 usbd_device_handle dev;
866 usb_device_request_t *req;
867 void *data;
868 u_int16_t flags;
869 int *actlen;
870 {
871 usbd_request_handle reqh;
872 usbd_status r;
873
874 #ifdef DIAGNOSTIC
875 if (dev->bus->intr_context) {
876 printf("usbd_do_request: not in process context\n");
877 return (USBD_INVAL);
878 }
879 #endif
880
881 reqh = usbd_alloc_request(dev);
882 if (reqh == 0)
883 return (USBD_NOMEM);
884 usbd_setup_default_request(reqh, dev, 0, USBD_DEFAULT_TIMEOUT, req,
885 data, UGETW(req->wLength), flags, 0);
886 r = usbd_sync_transfer(reqh);
887 #if defined(USB_DEBUG) || defined(DIAGNOSTIC)
888 if (reqh->actlen > reqh->length)
889 DPRINTF(("usbd_do_request: overrun addr=%d type=0x%02x req=0x"
890 "%02x val=%d index=%d rlen=%d length=%d actlen=%d\n",
891 dev->address, reqh->request.bmRequestType,
892 reqh->request.bRequest, UGETW(reqh->request.wValue),
893 UGETW(reqh->request.wIndex),
894 UGETW(reqh->request.wLength),
895 reqh->length, reqh->actlen));
896 #endif
897 if (actlen)
898 *actlen = reqh->actlen;
899 if (r == USBD_STALLED) {
900 /*
901 * The control endpoint has stalled. Control endpoints
902 * should not halt, but some may do so anyway so clear
903 * any halt condition.
904 */
905 usb_device_request_t treq;
906 usb_status_t status;
907 u_int16_t s;
908 usbd_status nr;
909
910 treq.bmRequestType = UT_READ_ENDPOINT;
911 treq.bRequest = UR_GET_STATUS;
912 USETW(treq.wValue, 0);
913 USETW(treq.wIndex, 0);
914 USETW(treq.wLength, sizeof(usb_status_t));
915 usbd_setup_default_request(reqh, dev, 0, USBD_DEFAULT_TIMEOUT,
916 &treq, &status,sizeof(usb_status_t),
917 0, 0);
918 nr = usbd_sync_transfer(reqh);
919 if (nr != USBD_NORMAL_COMPLETION)
920 goto bad;
921 s = UGETW(status.wStatus);
922 DPRINTF(("usbd_do_request: status = 0x%04x\n", s));
923 if (!(s & UES_HALT))
924 goto bad;
925 treq.bmRequestType = UT_WRITE_ENDPOINT;
926 treq.bRequest = UR_CLEAR_FEATURE;
927 USETW(treq.wValue, UF_ENDPOINT_HALT);
928 USETW(treq.wIndex, 0);
929 USETW(treq.wLength, 0);
930 usbd_setup_default_request(reqh, dev, 0, USBD_DEFAULT_TIMEOUT,
931 &treq, &status, 0, 0, 0);
932 nr = usbd_sync_transfer(reqh);
933 if (nr != USBD_NORMAL_COMPLETION)
934 goto bad;
935 }
936
937 bad:
938 usbd_free_request(reqh);
939 return (r);
940 }
941
942 void
943 usbd_do_request_async_cb(reqh, priv, status)
944 usbd_request_handle reqh;
945 usbd_private_handle priv;
946 usbd_status status;
947 {
948 #if defined(USB_DEBUG) || defined(DIAGNOSTIC)
949 if (reqh->actlen > reqh->length)
950 DPRINTF(("usbd_do_request: overrun addr=%d type=0x%02x req=0x"
951 "%02x val=%d index=%d rlen=%d length=%d actlen=%d\n",
952 reqh->pipe->device->address,
953 reqh->request.bmRequestType,
954 reqh->request.bRequest, UGETW(reqh->request.wValue),
955 UGETW(reqh->request.wIndex),
956 UGETW(reqh->request.wLength),
957 reqh->length, reqh->actlen));
958 #endif
959 usbd_free_request(reqh);
960 }
961
962 /*
963 * Execute a request without waiting for completion.
964 * Can be used from interrupt context.
965 */
966 usbd_status
967 usbd_do_request_async(dev, req, data)
968 usbd_device_handle dev;
969 usb_device_request_t *req;
970 void *data;
971 {
972 usbd_request_handle reqh;
973 usbd_status r;
974
975 reqh = usbd_alloc_request(dev);
976 if (reqh == 0)
977 return (USBD_NOMEM);
978 usbd_setup_default_request(reqh, dev, 0, USBD_DEFAULT_TIMEOUT, req, data,
979 UGETW(req->wLength), 0,
980 usbd_do_request_async_cb);
981 r = usbd_transfer(reqh);
982 if (r != USBD_IN_PROGRESS) {
983 usbd_free_request(reqh);
984 return (r);
985 }
986 return (USBD_NORMAL_COMPLETION);
987 }
988
989 struct usbd_quirks *
990 usbd_get_quirks(dev)
991 usbd_device_handle dev;
992 {
993 return (dev->quirks);
994 }
995
996 /* XXX do periodic free() of free list */
997
998 /*
999 * Called from keyboard driver when in polling mode.
1000 */
1001 void
1002 usbd_dopoll(iface)
1003 usbd_interface_handle iface;
1004 {
1005 iface->device->bus->methods->do_poll(iface->device->bus);
1006 }
1007
1008 void
1009 usbd_set_polling(iface, on)
1010 usbd_interface_handle iface;
1011 int on;
1012 {
1013 iface->device->bus->use_polling = on;
1014 }
1015
1016
1017 usb_endpoint_descriptor_t *
1018 usbd_get_endpoint_descriptor(iface, address)
1019 usbd_interface_handle iface;
1020 u_int8_t address;
1021 {
1022 struct usbd_endpoint *ep;
1023 int i;
1024
1025 for (i = 0; i < iface->idesc->bNumEndpoints; i++) {
1026 ep = &iface->endpoints[i];
1027 if (ep->edesc->bEndpointAddress == address)
1028 return (iface->endpoints[i].edesc);
1029 }
1030 return (0);
1031 }
1032
1033 #if defined(__FreeBSD__)
1034 void
1035 usbd_print_child(device_t parent, device_t child)
1036 {
1037 /*
1038 struct usb_softc *sc = device_get_softc(child);
1039 */
1040
1041 printf(" at %s%d", device_get_name(parent), device_get_unit(parent));
1042
1043 /* XXX How do we get to the usbd_device_handle???
1044 usbd_device_handle dev = invalidadosch;
1045
1046 printf(" addr %d", dev->addr);
1047
1048 if (bootverbose) {
1049 if (dev->lowspeed)
1050 printf(", lowspeed");
1051 if (dev->self_powered)
1052 printf(", self powered");
1053 else
1054 printf(", %dmA", dev->power);
1055 printf(", config %d", dev->config);
1056 }
1057 */
1058 }
1059
1060 /* Reconfigure all the USB busses in the system. */
1061 int
1062 usbd_driver_load(module_t mod, int what, void *arg)
1063 {
1064 devclass_t usb_devclass = devclass_find("usb");
1065 devclass_t ugen_devclass = devclass_find("ugen");
1066 device_t *devlist;
1067 int devcount;
1068 int error;
1069
1070 switch (what) {
1071 case MOD_LOAD:
1072 case MOD_UNLOAD:
1073 if (!usb_devclass)
1074 return 0; /* just ignore call */
1075
1076 if (ugen_devclass) {
1077 /* detach devices from generic driver if possible */
1078 error = devclass_get_devices(ugen_devclass, &devlist,
1079 &devcount);
1080 if (!error)
1081 for (devcount--; devcount >= 0; devcount--)
1082 (void)DEVICE_DETACH(devlist[devcount]);
1083 }
1084
1085 error = devclass_get_devices(usb_devclass, &devlist, &devcount);
1086 if (error)
1087 return 0; /* XXX maybe transient, or error? */
1088
1089 for (devcount--; devcount >= 0; devcount--)
1090 USB_RECONFIGURE(devlist[devcount]);
1091
1092 free(devlist, M_TEMP);
1093 return 0;
1094 }
1095
1096 return 0; /* nothing to do by us */
1097 }
1098
1099 /* Set the description of the device including a malloc and copy. */
1100 void
1101 usbd_device_set_desc(device_t device, char *devinfo)
1102 {
1103 size_t l;
1104 char *desc;
1105
1106 if ( devinfo ) {
1107 l = strlen(devinfo);
1108 desc = malloc(l+1, M_USB, M_NOWAIT);
1109 if (desc)
1110 memcpy(desc, devinfo, l+1);
1111 } else
1112 desc = NULL;
1113
1114 device_set_desc(device, desc);
1115 }
1116
1117 char *
1118 usbd_devname(device_t bdev)
1119 {
1120 static char buf[20];
1121 /*
1122 * A static buffer is a loss if this routine is used from an interrupt,
1123 * but it's not fatal.
1124 */
1125
1126 sprintf(buf, "%s%d", device_get_name(bdev), device_get_unit(bdev));
1127 return (buf);
1128 }
1129
1130 #endif
1131