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