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