1 /* $NetBSD: usbdi.c,v 1.60 2000/01/19 00:23:58 augustss Exp $ */
5 * Copyright (c) 1998 The NetBSD Foundation, Inc.
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Lennart Augustsson (augustss@carlstedt.se) at
10 * Carlstedt Research & Technology.
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
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.
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.
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>
51 #if defined(DIAGNOSTIC) && defined(__i386__)
52 #include <machine/cpu.h>
55 #include <sys/malloc.h>
58 #include <machine/bus.h>
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>
66 #if defined(__FreeBSD__)
68 #include <machine/clock.h>
69 #define delay(d) DELAY(d)
73 #define DPRINTF(x) if (usbdebug) logprintf x
74 #define DPRINTFN(n,x) if (usbdebug>(n)) logprintf x
81 static usbd_status usbd_ar_pipe __P((usbd_pipe_handle pipe));
82 static void usbd_do_request_async_cb
83 __P((usbd_xfer_handle, usbd_private_handle, usbd_status));
84 static void usbd_start_next __P((usbd_pipe_handle pipe));
85 static usbd_status usbd_open_pipe_ival
86 __P((usbd_interface_handle, u_int8_t, u_int8_t, usbd_pipe_handle *, int));
88 static int usbd_nbuses = 0;
102 static __inline int usbd_xfer_isread __P((usbd_xfer_handle xfer));
104 usbd_xfer_isread(xfer)
105 usbd_xfer_handle xfer;
107 if (xfer->rqflags & URQ_REQUEST)
108 return (xfer->request.bmRequestType & UT_READ);
110 return (xfer->pipe->endpoint->edesc->bEndpointAddress &
115 void usbd_dump_queue __P((usbd_pipe_handle));
118 usbd_dump_queue(pipe)
119 usbd_pipe_handle pipe;
121 usbd_xfer_handle xfer;
123 printf("usbd_dump_queue: pipe=%p\n", pipe);
124 for (xfer = SIMPLEQ_FIRST(&pipe->queue);
126 xfer = SIMPLEQ_NEXT(xfer, next)) {
127 printf(" xfer=%p\n", xfer);
133 usbd_open_pipe(iface, address, flags, pipe)
134 usbd_interface_handle iface;
137 usbd_pipe_handle *pipe;
139 return (usbd_open_pipe_ival(iface, address, flags, pipe,
140 USBD_DEFAULT_INTERVAL));
144 usbd_open_pipe_ival(iface, address, flags, pipe, ival)
145 usbd_interface_handle iface;
148 usbd_pipe_handle *pipe;
152 struct usbd_endpoint *ep;
156 DPRINTFN(3,("usbd_open_pipe: iface=%p address=0x%x flags=0x%x\n",
157 iface, address, flags));
159 for (i = 0; i < iface->idesc->bNumEndpoints; i++) {
160 ep = &iface->endpoints[i];
161 if (ep->edesc == NULL)
162 return (USBD_IOERROR);
163 if (ep->edesc->bEndpointAddress == address)
166 return (USBD_BAD_ADDRESS);
168 if ((flags & USBD_EXCLUSIVE_USE) && ep->refcnt != 0)
169 return (USBD_IN_USE);
170 err = usbd_setup_pipe(iface->device, iface, ep, ival, &p);
173 LIST_INSERT_HEAD(&iface->pipes, p, next);
175 return (USBD_NORMAL_COMPLETION);
179 usbd_open_pipe_intr(iface, address, flags, pipe, priv, buffer, len, cb, ival)
180 usbd_interface_handle iface;
183 usbd_pipe_handle *pipe;
184 usbd_private_handle priv;
191 usbd_xfer_handle xfer;
192 usbd_pipe_handle ipipe;
194 DPRINTFN(3,("usbd_open_pipe_intr: address=0x%x flags=0x%x len=%d\n",
195 address, flags, len));
197 err = usbd_open_pipe_ival(iface, address, USBD_EXCLUSIVE_USE,
201 xfer = usbd_alloc_xfer(iface->device);
206 usbd_setup_xfer(xfer, ipipe, priv, buffer, len, flags,
207 USBD_NO_TIMEOUT, cb);
208 ipipe->intrxfer = xfer;
210 err = usbd_transfer(xfer);
212 if (err != USBD_IN_PROGRESS)
214 return (USBD_NORMAL_COMPLETION);
217 ipipe->intrxfer = NULL;
219 usbd_free_xfer(xfer);
221 usbd_close_pipe(ipipe);
226 usbd_close_pipe(pipe)
227 usbd_pipe_handle pipe;
231 printf("usbd_close_pipe: pipe==NULL\n");
232 return (USBD_NORMAL_COMPLETION);
236 if (--pipe->refcnt != 0)
237 return (USBD_NORMAL_COMPLETION);
238 if (SIMPLEQ_FIRST(&pipe->queue) != 0)
239 return (USBD_PENDING_REQUESTS);
240 LIST_REMOVE(pipe, next);
241 pipe->endpoint->refcnt--;
242 pipe->methods->close(pipe);
243 if (pipe->intrxfer != NULL)
244 usbd_free_xfer(pipe->intrxfer);
246 return (USBD_NORMAL_COMPLETION);
251 usbd_xfer_handle xfer;
253 usbd_pipe_handle pipe = xfer->pipe;
254 usb_dma_t *dmap = &xfer->dmabuf;
259 DPRINTFN(5,("usbd_transfer: xfer=%p, flags=%d, pipe=%p, running=%d\n",
260 xfer, xfer->flags, pipe, pipe->running));
263 usbd_dump_queue(pipe);
268 /* If there is no buffer, allocate one. */
269 if (!(xfer->rqflags & URQ_DEV_DMABUF) && size != 0) {
270 struct usbd_bus *bus = pipe->device->bus;
273 if (xfer->rqflags & URQ_AUTO_DMABUF)
274 printf("usbd_transfer: has old buffer!\n");
276 err = bus->methods->allocm(bus, dmap, size);
279 xfer->rqflags |= URQ_AUTO_DMABUF;
282 /* Copy data if going out. */
283 if (!(xfer->flags & USBD_NO_COPY) && size != 0 &&
284 !usbd_xfer_isread(xfer))
285 memcpy(KERNADDR(dmap, 0), xfer->buffer, size);
287 err = pipe->methods->transfer(xfer);
289 if (err != USBD_IN_PROGRESS && err) {
290 /* The transfer has not been queued, so free buffer. */
291 if (xfer->rqflags & URQ_AUTO_DMABUF) {
292 struct usbd_bus *bus = pipe->device->bus;
294 bus->methods->freem(bus, &xfer->dmabuf);
295 xfer->rqflags &= ~URQ_AUTO_DMABUF;
299 if (!(xfer->flags & USBD_SYNCHRONOUS))
302 /* Sync transfer, wait for completion. */
303 if (err != USBD_IN_PROGRESS)
307 if (pipe->device->bus->use_polling)
308 panic("usbd_transfer: not done\n");
309 /* XXX Temporary hack XXX */
310 if (xfer->flags & USBD_NO_TSLEEP) {
312 usbd_bus_handle bus = pipe->device->bus;
313 int to = xfer->timeout * 1000;
314 for (i = 0; i < to; i += 10) {
316 bus->methods->do_poll(bus);
321 pipe->methods->abort(xfer);
323 /* XXX End hack XXX */
324 tsleep(xfer, PRIBIO, "usbsyn", 0);
327 return (xfer->status);
330 /* Like usbd_transfer(), but waits for completion. */
332 usbd_sync_transfer(xfer)
333 usbd_xfer_handle xfer;
335 xfer->flags |= USBD_SYNCHRONOUS;
336 return (usbd_transfer(xfer));
340 usbd_alloc_buffer(xfer, size)
341 usbd_xfer_handle xfer;
344 struct usbd_bus *bus = xfer->device->bus;
347 err = bus->methods->allocm(bus, &xfer->dmabuf, size);
350 xfer->rqflags |= URQ_DEV_DMABUF;
351 return (KERNADDR(&xfer->dmabuf, 0));
355 usbd_free_buffer(xfer)
356 usbd_xfer_handle xfer;
359 if (!(xfer->rqflags & (URQ_DEV_DMABUF | URQ_AUTO_DMABUF))) {
360 printf("usbd_free_buffer: no buffer\n");
364 xfer->rqflags &= ~(URQ_DEV_DMABUF | URQ_AUTO_DMABUF);
365 xfer->device->bus->methods->freem(xfer->device->bus, &xfer->dmabuf);
369 usbd_get_buffer(xfer)
370 usbd_xfer_handle xfer;
372 if (!(xfer->rqflags & URQ_DEV_DMABUF))
374 return (KERNADDR(&xfer->dmabuf, 0));
379 usbd_device_handle dev;
381 usbd_xfer_handle xfer;
383 xfer = dev->bus->methods->allocx(dev->bus);
387 DPRINTFN(5,("usbd_alloc_xfer() = %p\n", xfer));
393 usbd_xfer_handle xfer;
395 DPRINTFN(5,("usbd_free_xfer: %p\n", xfer));
396 if (xfer->rqflags & (URQ_DEV_DMABUF | URQ_AUTO_DMABUF))
397 usbd_free_buffer(xfer);
398 xfer->device->bus->methods->freex(xfer->device->bus, xfer);
399 return (USBD_NORMAL_COMPLETION);
403 usbd_setup_xfer(xfer, pipe, priv, buffer, length, flags, timeout, callback)
404 usbd_xfer_handle xfer;
405 usbd_pipe_handle pipe;
406 usbd_private_handle priv;
411 void (*callback) __P((usbd_xfer_handle,
417 xfer->buffer = buffer;
418 xfer->length = length;
421 xfer->timeout = timeout;
422 xfer->status = USBD_NOT_STARTED;
423 xfer->callback = callback;
424 xfer->rqflags &= ~URQ_REQUEST;
429 usbd_setup_default_xfer(xfer, dev, priv, timeout, req, buffer,
430 length, flags, callback)
431 usbd_xfer_handle xfer;
432 usbd_device_handle dev;
433 usbd_private_handle priv;
435 usb_device_request_t *req;
439 void (*callback) __P((usbd_xfer_handle,
443 xfer->pipe = dev->default_pipe;
445 xfer->buffer = buffer;
446 xfer->length = length;
449 xfer->timeout = timeout;
450 xfer->status = USBD_NOT_STARTED;
451 xfer->callback = callback;
452 xfer->request = *req;
453 xfer->rqflags |= URQ_REQUEST;
458 usbd_setup_isoc_xfer(xfer, pipe, priv, frlengths, nframes, flags, callback)
459 usbd_xfer_handle xfer;
460 usbd_pipe_handle pipe;
461 usbd_private_handle priv;
462 u_int16_t *frlengths;
465 usbd_callback callback;
473 xfer->timeout = USBD_NO_TIMEOUT;
474 xfer->status = USBD_NOT_STARTED;
475 xfer->callback = callback;
476 xfer->rqflags &= ~URQ_REQUEST;
477 xfer->frlengths = frlengths;
478 xfer->nframes = nframes;
482 usbd_get_xfer_status(xfer, priv, buffer, count, status)
483 usbd_xfer_handle xfer;
484 usbd_private_handle *priv;
492 *buffer = xfer->buffer;
494 *count = xfer->actlen;
496 *status = xfer->status;
499 usb_config_descriptor_t *
500 usbd_get_config_descriptor(dev)
501 usbd_device_handle dev;
505 printf("usbd_get_config_descriptor: dev == NULL\n");
512 usb_interface_descriptor_t *
513 usbd_get_interface_descriptor(iface)
514 usbd_interface_handle iface;
518 printf("usbd_get_interface_descriptor: dev == NULL\n");
522 return (iface->idesc);
525 usb_device_descriptor_t *
526 usbd_get_device_descriptor(dev)
527 usbd_device_handle dev;
529 return (&dev->ddesc);
532 usb_endpoint_descriptor_t *
533 usbd_interface2endpoint_descriptor(iface, index)
534 usbd_interface_handle iface;
537 if (index >= iface->idesc->bNumEndpoints)
539 return (iface->endpoints[index].edesc);
543 usbd_abort_pipe(pipe)
544 usbd_pipe_handle pipe;
551 printf("usbd_close_pipe: pipe==NULL\n");
552 return (USBD_NORMAL_COMPLETION);
556 err = usbd_ar_pipe(pipe);
562 usbd_clear_endpoint_stall(pipe)
563 usbd_pipe_handle pipe;
565 usbd_device_handle dev = pipe->device;
566 usb_device_request_t req;
569 DPRINTFN(8, ("usbd_clear_endpoint_stall\n"));
572 * Clearing en endpoint stall resets the enpoint toggle, so
573 * do the same to the HC toggle.
575 pipe->methods->cleartoggle(pipe);
577 req.bmRequestType = UT_WRITE_ENDPOINT;
578 req.bRequest = UR_CLEAR_FEATURE;
579 USETW(req.wValue, UF_ENDPOINT_HALT);
580 USETW(req.wIndex, pipe->endpoint->edesc->bEndpointAddress);
581 USETW(req.wLength, 0);
582 err = usbd_do_request(dev, &req, 0);
584 XXX should we do this?
586 pipe->state = USBD_PIPE_ACTIVE;
587 /* XXX activate pipe */
594 usbd_clear_endpoint_stall_async(pipe)
595 usbd_pipe_handle pipe;
597 usbd_device_handle dev = pipe->device;
598 usb_device_request_t req;
601 pipe->methods->cleartoggle(pipe);
603 req.bmRequestType = UT_WRITE_ENDPOINT;
604 req.bRequest = UR_CLEAR_FEATURE;
605 USETW(req.wValue, UF_ENDPOINT_HALT);
606 USETW(req.wIndex, pipe->endpoint->edesc->bEndpointAddress);
607 USETW(req.wLength, 0);
608 err = usbd_do_request_async(dev, &req, 0);
613 usbd_clear_endpoint_toggle(pipe)
614 usbd_pipe_handle pipe;
616 pipe->methods->cleartoggle(pipe);
621 usbd_endpoint_count(iface, count)
622 usbd_interface_handle iface;
625 *count = iface->idesc->bNumEndpoints;
626 return (USBD_NORMAL_COMPLETION);
630 usbd_interface_count(dev, count)
631 usbd_device_handle dev;
634 if (dev->cdesc == NULL)
635 return (USBD_NOT_CONFIGURED);
636 *count = dev->cdesc->bNumInterface;
637 return (USBD_NORMAL_COMPLETION);
641 usbd_interface2device_handle(iface, dev)
642 usbd_interface_handle iface;
643 usbd_device_handle *dev;
645 *dev = iface->device;
646 return (USBD_NORMAL_COMPLETION);
650 usbd_device2interface_handle(dev, ifaceno, iface)
651 usbd_device_handle dev;
653 usbd_interface_handle *iface;
655 if (dev->cdesc == NULL)
656 return (USBD_NOT_CONFIGURED);
657 if (ifaceno >= dev->cdesc->bNumInterface)
659 *iface = &dev->ifaces[ifaceno];
660 return (USBD_NORMAL_COMPLETION);
664 usbd_pipe2device_handle(pipe)
665 usbd_pipe_handle pipe;
667 return (pipe->device);
672 usbd_set_interface(iface, altidx)
673 usbd_interface_handle iface;
676 usb_device_request_t req;
679 if (LIST_FIRST(&iface->pipes) != 0)
680 return (USBD_IN_USE);
682 if (iface->endpoints)
683 free(iface->endpoints, M_USB);
684 iface->endpoints = 0;
687 err = usbd_fill_iface_data(iface->device, iface->index, altidx);
691 req.bmRequestType = UT_WRITE_INTERFACE;
692 req.bRequest = UR_SET_INTERFACE;
693 USETW(req.wValue, iface->idesc->bAlternateSetting);
694 USETW(req.wIndex, iface->idesc->bInterfaceNumber);
695 USETW(req.wLength, 0);
696 return (usbd_do_request(iface->device, &req, 0));
700 usbd_get_no_alts(cdesc, ifaceno)
701 usb_config_descriptor_t *cdesc;
704 char *p = (char *)cdesc;
705 char *end = p + UGETW(cdesc->wTotalLength);
706 usb_interface_descriptor_t *d;
709 for (n = 0; p < end; p += d->bLength) {
710 d = (usb_interface_descriptor_t *)p;
711 if (p + d->bLength <= end &&
712 d->bDescriptorType == UDESC_INTERFACE &&
713 d->bInterfaceNumber == ifaceno)
720 usbd_get_interface_altindex(iface)
721 usbd_interface_handle iface;
723 return (iface->altindex);
727 usbd_get_interface(iface, aiface)
728 usbd_interface_handle iface;
731 usb_device_request_t req;
733 req.bmRequestType = UT_READ_INTERFACE;
734 req.bRequest = UR_GET_INTERFACE;
735 USETW(req.wValue, 0);
736 USETW(req.wIndex, iface->idesc->bInterfaceNumber);
737 USETW(req.wLength, 1);
738 return (usbd_do_request(iface->device, &req, aiface));
741 /*** Internal routines ***/
743 /* Dequeue all pipe operations, called at splusb(). */
746 usbd_pipe_handle pipe;
748 usbd_xfer_handle xfer;
752 DPRINTFN(2,("usbd_ar_pipe: pipe=%p\n", pipe));
755 usbd_dump_queue(pipe);
758 while ((xfer = SIMPLEQ_FIRST(&pipe->queue)) != NULL) {
759 DPRINTFN(2,("usbd_ar_pipe: pipe=%p xfer=%p (methods=%p)\n",
760 pipe, xfer, pipe->methods));
761 /* Make the HC abort it (and invoke the callback). */
762 pipe->methods->abort(xfer);
763 /* XXX only for non-0 usbd_clear_endpoint_stall(pipe); */
765 return (USBD_NORMAL_COMPLETION);
768 /* Called at splusb() */
770 usb_transfer_complete(xfer)
771 usbd_xfer_handle xfer;
773 usbd_pipe_handle pipe = xfer->pipe;
774 usb_dma_t *dmap = &xfer->dmabuf;
775 int repeat = pipe->repeat;
780 DPRINTFN(5, ("usb_transfer_complete: pipe=%p xfer=%p status=%d "
781 "actlen=%d\n", pipe, xfer, xfer->status, xfer->actlen));
785 printf("usbd_transfer_cb: pipe==0, xfer=%p\n", xfer);
789 polling = pipe->device->bus->use_polling;
794 if (!(xfer->flags & USBD_NO_COPY) && xfer->actlen != 0 &&
795 usbd_xfer_isread(xfer)) {
797 if (xfer->actlen > xfer->length) {
798 printf("usb_transfer_complete: actlen > len %d > %d\n",
799 xfer->actlen, xfer->length);
800 xfer->actlen = xfer->length;
803 memcpy(xfer->buffer, KERNADDR(dmap, 0), xfer->actlen);
806 /* if we allocated the buffer in usbd_transfer() we free it here. */
807 if (xfer->rqflags & URQ_AUTO_DMABUF) {
809 struct usbd_bus *bus = pipe->device->bus;
810 bus->methods->freem(bus, dmap);
811 xfer->rqflags &= ~URQ_AUTO_DMABUF;
815 if (pipe->methods->done != NULL)
816 pipe->methods->done(xfer);
819 /* Remove request from queue. */
821 if (xfer != SIMPLEQ_FIRST(&pipe->queue))
822 printf("usb_transfer_complete: bad dequeue %p != %p\n",
823 xfer, SIMPLEQ_FIRST(&pipe->queue));
825 SIMPLEQ_REMOVE_HEAD(&pipe->queue, xfer, next);
828 /* Count completed transfers. */
829 ++pipe->device->bus->stats.requests
830 [pipe->endpoint->edesc->bmAttributes & UE_XFERTYPE];
833 if (!xfer->status && xfer->actlen < xfer->length &&
834 !(xfer->flags & USBD_SHORT_XFER_OK)) {
835 DPRINTFN(-1,("usbd_transfer_cb: short transfer %d<%d\n",
836 xfer->actlen, xfer->length));
837 xfer->status = USBD_SHORT_XFER;
841 xfer->callback(xfer, xfer->priv, xfer->status);
843 if ((xfer->flags & USBD_SYNCHRONOUS) && !polling)
847 /* XXX should we stop the queue on all errors? */
848 if ((xfer->status == USBD_CANCELLED
849 || xfer->status == USBD_TIMEOUT)
850 && pipe->iface != NULL) /* not control pipe */
853 usbd_start_next(pipe);
858 usb_insert_transfer(xfer)
859 usbd_xfer_handle xfer;
861 usbd_pipe_handle pipe = xfer->pipe;
865 DPRINTFN(5,("usb_insert_transfer: pipe=%p running=%d timeout=%d\n",
866 pipe, pipe->running, xfer->timeout));
868 SIMPLEQ_INSERT_TAIL(&pipe->queue, xfer, next);
870 err = USBD_IN_PROGRESS;
873 err = USBD_NORMAL_COMPLETION;
879 /* Called at splusb() */
881 usbd_start_next(pipe)
882 usbd_pipe_handle pipe;
884 usbd_xfer_handle xfer;
891 printf("usbd_start_next: pipe == NULL\n");
894 if (pipe->methods == NULL || pipe->methods->start == NULL) {
895 printf("usbd_start_next: pipe=%p no start method\n", pipe);
900 /* Get next request in queue. */
901 xfer = SIMPLEQ_FIRST(&pipe->queue);
902 DPRINTFN(5, ("usbd_start_next: pipe=%p, xfer=%p\n", pipe, xfer));
906 err = pipe->methods->start(xfer);
907 if (err != USBD_IN_PROGRESS) {
908 printf("usbd_start_next: error=%d\n", err);
916 usbd_do_request(dev, req, data)
917 usbd_device_handle dev;
918 usb_device_request_t *req;
921 return (usbd_do_request_flags(dev, req, data, 0, 0));
925 usbd_do_request_flags(dev, req, data, flags, actlen)
926 usbd_device_handle dev;
927 usb_device_request_t *req;
932 usbd_xfer_handle xfer;
936 #if defined(__i386__) && defined(__FreeBSD__)
937 KASSERT(intr_nesting_level == 0,
938 ("usbd_do_request: in interrupt context"));
940 if (dev->bus->intr_context) {
941 printf("usbd_do_request: not in process context\n");
946 xfer = usbd_alloc_xfer(dev);
949 usbd_setup_default_xfer(xfer, dev, 0, USBD_DEFAULT_TIMEOUT, req,
950 data, UGETW(req->wLength), flags, 0);
951 err = usbd_sync_transfer(xfer);
952 #if defined(USB_DEBUG) || defined(DIAGNOSTIC)
953 if (xfer->actlen > xfer->length)
954 DPRINTF(("usbd_do_request: overrun addr=%d type=0x%02x req=0x"
955 "%02x val=%d index=%d rlen=%d length=%d actlen=%d\n",
956 dev->address, xfer->request.bmRequestType,
957 xfer->request.bRequest, UGETW(xfer->request.wValue),
958 UGETW(xfer->request.wIndex),
959 UGETW(xfer->request.wLength),
960 xfer->length, xfer->actlen));
963 *actlen = xfer->actlen;
964 if (err == USBD_STALLED) {
966 * The control endpoint has stalled. Control endpoints
967 * should not halt, but some may do so anyway so clear
968 * any halt condition.
970 usb_device_request_t treq;
975 treq.bmRequestType = UT_READ_ENDPOINT;
976 treq.bRequest = UR_GET_STATUS;
977 USETW(treq.wValue, 0);
978 USETW(treq.wIndex, 0);
979 USETW(treq.wLength, sizeof(usb_status_t));
980 usbd_setup_default_xfer(xfer, dev, 0, USBD_DEFAULT_TIMEOUT,
981 &treq, &status,sizeof(usb_status_t),
983 nerr = usbd_sync_transfer(xfer);
986 s = UGETW(status.wStatus);
987 DPRINTF(("usbd_do_request: status = 0x%04x\n", s));
990 treq.bmRequestType = UT_WRITE_ENDPOINT;
991 treq.bRequest = UR_CLEAR_FEATURE;
992 USETW(treq.wValue, UF_ENDPOINT_HALT);
993 USETW(treq.wIndex, 0);
994 USETW(treq.wLength, 0);
995 usbd_setup_default_xfer(xfer, dev, 0, USBD_DEFAULT_TIMEOUT,
996 &treq, &status, 0, 0, 0);
997 nerr = usbd_sync_transfer(xfer);
1003 usbd_free_xfer(xfer);
1008 usbd_do_request_async_cb(xfer, priv, status)
1009 usbd_xfer_handle xfer;
1010 usbd_private_handle priv;
1013 #if defined(USB_DEBUG) || defined(DIAGNOSTIC)
1014 if (xfer->actlen > xfer->length)
1015 DPRINTF(("usbd_do_request: overrun addr=%d type=0x%02x req=0x"
1016 "%02x val=%d index=%d rlen=%d length=%d actlen=%d\n",
1017 xfer->pipe->device->address,
1018 xfer->request.bmRequestType,
1019 xfer->request.bRequest, UGETW(xfer->request.wValue),
1020 UGETW(xfer->request.wIndex),
1021 UGETW(xfer->request.wLength),
1022 xfer->length, xfer->actlen));
1024 usbd_free_xfer(xfer);
1028 * Execute a request without waiting for completion.
1029 * Can be used from interrupt context.
1032 usbd_do_request_async(dev, req, data)
1033 usbd_device_handle dev;
1034 usb_device_request_t *req;
1037 usbd_xfer_handle xfer;
1040 xfer = usbd_alloc_xfer(dev);
1042 return (USBD_NOMEM);
1043 usbd_setup_default_xfer(xfer, dev, 0, USBD_DEFAULT_TIMEOUT, req,
1044 data, UGETW(req->wLength), 0, usbd_do_request_async_cb);
1045 err = usbd_transfer(xfer);
1046 if (err != USBD_IN_PROGRESS) {
1047 usbd_free_xfer(xfer);
1050 return (USBD_NORMAL_COMPLETION);
1053 struct usbd_quirks *
1054 usbd_get_quirks(dev)
1055 usbd_device_handle dev;
1057 return (dev->quirks);
1060 /* XXX do periodic free() of free list */
1063 * Called from keyboard driver when in polling mode.
1067 usbd_interface_handle iface;
1069 iface->device->bus->methods->do_poll(iface->device->bus);
1073 usbd_set_polling(iface, on)
1074 usbd_interface_handle iface;
1078 iface->device->bus->use_polling++;
1080 iface->device->bus->use_polling--;
1084 usb_endpoint_descriptor_t *
1085 usbd_get_endpoint_descriptor(iface, address)
1086 usbd_interface_handle iface;
1089 struct usbd_endpoint *ep;
1092 for (i = 0; i < iface->idesc->bNumEndpoints; i++) {
1093 ep = &iface->endpoints[i];
1094 if (ep->edesc->bEndpointAddress == address)
1095 return (iface->endpoints[i].edesc);
1100 #if defined(__FreeBSD__)
1102 usbd_driver_load(module_t mod, int what, void *arg)
1104 /* XXX should implement something like a function that removes all generic devices */