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