1 /* $NetBSD: usbdi.c,v 1.20 1999/01/08 11:58:26 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 #include <sys/kernel.h>
44 #if defined(__NetBSD__)
45 #include <sys/device.h>
47 #include <sys/module.h>
51 #include <sys/malloc.h>
54 #include <dev/usb/usb.h>
56 #include <dev/usb/usbdi.h>
57 #include <dev/usb/usbdi_util.h>
58 #include <dev/usb/usbdivar.h>
60 #if defined(__FreeBSD__)
65 #define DPRINTF(x) if (usbdebug) printf x
66 #define DPRINTFN(n,x) if (usbdebug>(n)) printf x
73 static usbd_status usbd_ar_pipe __P((usbd_pipe_handle pipe));
74 static usbd_status usbd_ar_iface __P((usbd_interface_handle iface));
75 static void usbd_transfer_cb __P((usbd_request_handle reqh));
76 static void usbd_sync_transfer_cb __P((usbd_request_handle reqh));
77 static usbd_status usbd_do_transfer __P((usbd_request_handle reqh));
78 void usbd_do_request_async_cb
79 __P((usbd_request_handle, usbd_private_handle, usbd_status));
81 static SIMPLEQ_HEAD(, usbd_request) usbd_free_requests;
83 #if defined(__FreeBSD__)
84 #define USB_CDEV_MAJOR 108
86 extern struct cdevsw usb_cdevsw;
90 usbd_open_pipe(iface, address, flags, pipe)
91 usbd_interface_handle iface;
94 usbd_pipe_handle *pipe;
97 struct usbd_endpoint *ep;
101 if (iface->state != USBD_INTERFACE_ACTIVE)
102 return (USBD_INTERFACE_NOT_ACTIVE);
103 for (i = 0; i < iface->idesc->bNumEndpoints; i++) {
104 ep = &iface->endpoints[i];
105 if (ep->edesc->bEndpointAddress == address)
108 return (USBD_BAD_ADDRESS);
110 if ((flags & USBD_EXCLUSIVE_USE) &&
112 return (USBD_IN_USE);
113 r = usbd_setup_pipe(iface->device, iface, ep, &p);
114 if (r != USBD_NORMAL_COMPLETION)
116 LIST_INSERT_HEAD(&iface->pipes, p, next);
118 return (USBD_NORMAL_COMPLETION);
122 usbd_open_pipe_intr(iface, address, flags, pipe, priv, buffer, length, cb)
123 usbd_interface_handle iface;
126 usbd_pipe_handle *pipe;
127 usbd_private_handle priv;
133 usbd_request_handle reqh;
134 usbd_pipe_handle ipipe;
136 reqh = usbd_alloc_request();
139 r = usbd_open_pipe(iface, address, USBD_EXCLUSIVE_USE, &ipipe);
140 if (r != USBD_NORMAL_COMPLETION)
142 r = usbd_setup_request(reqh, ipipe, priv, buffer, length,
143 USBD_XFER_IN | flags, USBD_NO_TIMEOUT, cb);
144 if (r != USBD_NORMAL_COMPLETION)
146 ipipe->intrreqh = reqh;
147 r = usbd_transfer(reqh);
149 if (r != USBD_IN_PROGRESS)
151 return (USBD_NORMAL_COMPLETION);
156 usbd_close_pipe(ipipe);
158 usbd_free_request(reqh);
163 usbd_open_pipe_iso(iface, address, flags, pipe, priv, bufsize, nbuf, cb)
164 usbd_interface_handle iface;
167 usbd_pipe_handle *pipe;
168 usbd_private_handle priv;
176 r = usbd_open_pipe(iface, address, USBD_EXCLUSIVE_USE, &p);
177 if (r != USBD_NORMAL_COMPLETION)
179 if (!p->methods->isobuf) {
183 r = p->methods->isobuf(p, bufsize, nbuf);
184 if (r != USBD_NORMAL_COMPLETION) {
193 usbd_close_pipe(pipe)
194 usbd_pipe_handle pipe;
196 if (pipe->iface->state != USBD_INTERFACE_ACTIVE)
197 return (USBD_INTERFACE_NOT_ACTIVE);
198 if (--pipe->refcnt != 0)
199 return (USBD_NORMAL_COMPLETION);
200 if (SIMPLEQ_FIRST(&pipe->queue) != 0)
201 return (USBD_PENDING_REQUESTS);
202 LIST_REMOVE(pipe, next);
203 pipe->endpoint->refcnt--;
204 pipe->methods->close(pipe);
206 usbd_free_request(pipe->intrreqh);
208 return (USBD_NORMAL_COMPLETION);
213 usbd_request_handle reqh;
215 reqh->xfercb = usbd_transfer_cb;
216 return (usbd_do_transfer(reqh));
220 usbd_do_transfer(reqh)
221 usbd_request_handle reqh;
223 usbd_pipe_handle pipe = reqh->pipe;
225 DPRINTFN(10,("usbd_do_transfer: reqh=%p\n", reqh));
227 return (pipe->methods->transfer(reqh));
233 usbd_request_handle reqh;
235 reqh = SIMPLEQ_FIRST(&usbd_free_requests);
237 SIMPLEQ_REMOVE_HEAD(&usbd_free_requests, reqh, next);
239 reqh = malloc(sizeof(*reqh), M_USB, M_NOWAIT);
242 memset(reqh, 0, sizeof *reqh);
247 usbd_free_request(reqh)
248 usbd_request_handle reqh;
250 SIMPLEQ_INSERT_HEAD(&usbd_free_requests, reqh, next);
251 return (USBD_NORMAL_COMPLETION);
255 usbd_setup_request(reqh, pipe, priv, buffer, length, flags, timeout, callback)
256 usbd_request_handle reqh;
257 usbd_pipe_handle pipe;
258 usbd_private_handle priv;
263 void (*callback) __P((usbd_request_handle,
270 reqh->buffer = buffer;
271 reqh->length = length;
274 reqh->callback = callback;
275 reqh->status = USBD_NOT_STARTED;
277 return (USBD_NORMAL_COMPLETION);
281 usbd_setup_device_request(reqh, req)
282 usbd_request_handle reqh;
283 usb_device_request_t *req;
286 reqh->request = *req;
287 return (USBD_NORMAL_COMPLETION);
291 usbd_setup_default_request(reqh, dev, priv, timeout, req, buffer,
292 length, flags, callback)
293 usbd_request_handle reqh;
294 usbd_device_handle dev;
295 usbd_private_handle priv;
297 usb_device_request_t *req;
301 void (*callback) __P((usbd_request_handle,
305 reqh->pipe = dev->default_pipe;
307 reqh->buffer = buffer;
308 reqh->length = length;
311 reqh->timeout = timeout;
312 reqh->status = USBD_NOT_STARTED;
313 reqh->callback = callback;
314 reqh->request = *req;
317 return (USBD_NORMAL_COMPLETION);
321 usbd_set_request_timeout(reqh, timeout)
322 usbd_request_handle reqh;
325 reqh->timeout = timeout;
326 return (USBD_NORMAL_COMPLETION);
330 usbd_get_request_status(reqh, priv, buffer, count, status)
331 usbd_request_handle reqh;
332 usbd_private_handle *priv;
338 *buffer = reqh->buffer;
339 *count = reqh->actlen;
340 *status = reqh->status;
341 return (USBD_NORMAL_COMPLETION);
345 usbd_request_device_data(reqh, req)
346 usbd_request_handle reqh;
347 usb_device_request_t *req;
351 *req = reqh->request;
352 return (USBD_NORMAL_COMPLETION);
357 usbd_get_descriptor(iface, desc_type)
358 usbd_interface_handle *iface;
363 usb_config_descriptor_t *
364 usbd_get_config_descriptor(dev)
365 usbd_device_handle dev;
370 usb_interface_descriptor_t *
371 usbd_get_interface_descriptor(iface)
372 usbd_interface_handle iface;
374 return (iface->idesc);
377 usb_device_descriptor_t *
378 usbd_get_device_descriptor(dev)
379 usbd_device_handle dev;
381 return (&dev->ddesc);
384 usb_endpoint_descriptor_t *
385 usbd_interface2endpoint_descriptor(iface, index)
386 usbd_interface_handle iface;
389 if (index >= iface->idesc->bNumEndpoints)
391 return (iface->endpoints[index].edesc);
395 usbd_set_configuration(dev, conf)
396 usbd_device_handle dev;
399 return usbd_set_config_no(dev, conf, 0);
403 usbd_retry_request(reqh, retry_count)
404 usbd_request_handle reqh;
405 u_int32_t retry_count;
409 r = usbd_set_pipe_state(reqh->pipe, USBD_PIPE_ACTIVE);
410 if (r != USBD_NORMAL_COMPLETION)
412 reqh->retries = retry_count;
413 return (usbd_transfer(reqh));
417 usbd_abort_pipe(pipe)
418 usbd_pipe_handle pipe;
423 if (pipe->iface->state != USBD_INTERFACE_ACTIVE)
424 return (USBD_INTERFACE_NOT_ACTIVE);
427 r = usbd_ar_pipe(pipe);
434 usbd_abort_interface(iface)
435 usbd_interface_handle iface;
442 r = usbd_ar_iface(iface);
449 usbd_reset_pipe(pipe)
450 usbd_pipe_handle pipe;
455 if (pipe->iface->state != USBD_INTERFACE_ACTIVE)
456 return (USBD_INTERFACE_NOT_ACTIVE);
458 r = usbd_ar_pipe(pipe);
459 /* XXX anything else */
460 pipe->state = USBD_PIPE_ACTIVE;
466 usbd_reset_interface(iface)
467 usbd_interface_handle iface;
473 r = usbd_ar_iface(iface);
474 /* XXX anything else */
475 iface->state = USBD_INTERFACE_ACTIVE;
481 usbd_clear_endpoint_stall(pipe)
482 usbd_pipe_handle pipe;
484 usbd_device_handle dev = pipe->device;
485 usb_device_request_t req;
488 req.bmRequestType = UT_WRITE_ENDPOINT;
489 req.bRequest = UR_CLEAR_FEATURE;
490 USETW(req.wValue, UF_ENDPOINT_HALT);
491 USETW(req.wIndex, pipe->endpoint->edesc->bEndpointAddress);
492 USETW(req.wLength, 0);
493 r = usbd_do_request(dev, &req, 0);
495 XXX should we do this?
496 if (r == USBD_NORMAL_COMPLETION) {
497 pipe->state = USBD_PIPE_ACTIVE;
498 /* XXX activate pipe */
505 usbd_clear_endpoint_stall_async(pipe)
506 usbd_pipe_handle pipe;
508 usbd_device_handle dev = pipe->device;
509 usb_device_request_t req;
512 req.bmRequestType = UT_WRITE_ENDPOINT;
513 req.bRequest = UR_CLEAR_FEATURE;
514 USETW(req.wValue, UF_ENDPOINT_HALT);
515 USETW(req.wIndex, pipe->endpoint->edesc->bEndpointAddress);
516 USETW(req.wLength, 0);
517 r = usbd_do_request_async(dev, &req, 0);
522 usbd_set_pipe_state(pipe, state)
523 usbd_pipe_handle pipe;
524 usbd_pipe_state state;
528 usbd_request_handle reqh;
530 if (pipe->iface->state != USBD_INTERFACE_ACTIVE)
531 return (USBD_INTERFACE_NOT_ACTIVE);
532 if (state != USBD_PIPE_ACTIVE &&
533 state != USBD_PIPE_STALLED &&
534 state != USBD_PIPE_IDLE)
537 r = USBD_NORMAL_COMPLETION;
538 if (state == USBD_PIPE_ACTIVE) {
540 if (!pipe->running) {
541 reqh = SIMPLEQ_FIRST(&pipe->queue);
545 r = pipe->methods->start(reqh);
555 usbd_get_pipe_state(pipe, state, endpoint_state, request_count)
556 usbd_pipe_handle pipe;
557 usbd_pipe_state *state;
558 u_int32_t *endpoint_state;
559 u_int32_t *request_count;
562 usbd_request_handle r;
564 *state = pipe->state;
565 *endpoint_state = pipe->endpoint->state;
566 for (r = SIMPLEQ_FIRST(&pipe->queue), n = 0;
568 r = SIMPLEQ_NEXT(r, next), n++)
571 return (USBD_NORMAL_COMPLETION);
575 usbd_set_interface_state(iface, state)
576 usbd_interface_handle iface;
577 usbd_interface_state state;
582 if (state == USBD_INTERFACE_ACTIVE)
583 ps = USBD_PIPE_ACTIVE;
584 else if (state == USBD_INTERFACE_STALLED)
585 ps = USBD_PIPE_STALLED;
586 else if (state == USBD_INTERFACE_IDLE)
590 iface->state = USBD_INTERFACE_ACTIVE; /* to allow setting the pipe */
591 for (p = LIST_FIRST(&iface->pipes); p != 0; p = LIST_NEXT(p, next))
592 usbd_set_pipe_state(p, ps);
593 iface->state = state;
594 return (USBD_NORMAL_COMPLETION);
598 usbd_get_interface_state(iface, state)
599 usbd_interface_handle iface;
600 usbd_interface_state *state;
602 *state = iface->state;
603 return (USBD_NORMAL_COMPLETION);
607 usbd_get_device_state(dev, state)
608 usbd_device_handle dev;
609 usbd_device_state *state;
612 return (USBD_NORMAL_COMPLETION);
617 usbd_set_device_state(dev, state)
618 usbd_device_handle dev;
619 usbd_device_state state;
624 usbd_device_address(dev, address)
625 usbd_device_handle dev;
628 *address = dev->address;
629 return (USBD_NORMAL_COMPLETION);
633 usbd_endpoint_address(pipe, address)
634 usbd_pipe_handle pipe;
637 *address = pipe->endpoint->edesc->bEndpointAddress;
638 return (USBD_NORMAL_COMPLETION);
642 usbd_endpoint_count(iface, count)
643 usbd_interface_handle iface;
646 *count = iface->idesc->bNumEndpoints;
647 return (USBD_NORMAL_COMPLETION);
651 usbd_interface_count(dev, count)
652 usbd_device_handle dev;
656 return (USBD_NOT_CONFIGURED);
657 *count = dev->cdesc->bNumInterface;
658 return (USBD_NORMAL_COMPLETION);
665 return (usb_bus_count());
669 usbd_get_bus_handle(index, bus)
671 usbd_bus_handle *bus;
673 return (usb_get_bus_handle(index, bus));
678 usbd_get_root_hub(bus, dev)
680 usbd_device_handle *dev;
682 *dev = bus->root_hub;
683 return (USBD_NORMAL_COMPLETION);
687 usbd_port_count(dev, nports)
688 usbd_device_handle dev;
693 *nports = dev->hub->hubdesc.bNbrPorts;
694 return (USBD_NORMAL_COMPLETION);
698 usbd_hub2device_handle(dev, port, devp)
699 usbd_device_handle dev;
701 usbd_device_handle *devp;
703 if (dev->hub == 0 || port >= dev->hub->hubdesc.bNbrPorts ||
704 dev->hub->ports[port].device == 0)
706 *devp = dev->hub->ports[port].device;
707 return (USBD_NORMAL_COMPLETION);
711 usbd_request2pipe_handle(reqh, pipe)
712 usbd_request_handle reqh;
713 usbd_pipe_handle *pipe;
716 return (USBD_NORMAL_COMPLETION);
720 usbd_pipe2interface_handle(pipe, iface)
721 usbd_pipe_handle pipe;
722 usbd_interface_handle *iface;
724 *iface = pipe->iface;
725 return (USBD_NORMAL_COMPLETION);
729 usbd_interface2device_handle(iface, dev)
730 usbd_interface_handle iface;
731 usbd_device_handle *dev;
733 *dev = iface->device;
734 return (USBD_NORMAL_COMPLETION);
738 usbd_device2bus_handle(dev, bus)
739 usbd_device_handle dev;
740 usbd_bus_handle *bus;
743 return (USBD_NORMAL_COMPLETION);
747 usbd_device2interface_handle(dev, ifaceno, iface)
748 usbd_device_handle dev;
750 usbd_interface_handle *iface;
753 return (USBD_NOT_CONFIGURED);
754 if (ifaceno >= dev->cdesc->bNumInterface)
756 *iface = &dev->ifaces[ifaceno];
757 return (USBD_NORMAL_COMPLETION);
761 usbd_set_interface_private_handle(iface, priv)
762 usbd_interface_handle iface;
763 usbd_private_handle priv;
766 return (USBD_NORMAL_COMPLETION);
770 usbd_get_interface_private_handle(iface, priv)
771 usbd_interface_handle iface;
772 usbd_private_handle *priv;
775 return (USBD_NORMAL_COMPLETION);
779 usbd_reference_pipe(pipe)
780 usbd_pipe_handle pipe;
783 return (USBD_NORMAL_COMPLETION);
787 usbd_dereference_pipe(pipe)
788 usbd_pipe_handle pipe;
791 return (USBD_NORMAL_COMPLETION);
809 usbd_set_interface(iface, altidx)
810 usbd_interface_handle iface;
813 usb_device_request_t req;
816 if (LIST_FIRST(&iface->pipes) != 0)
817 return (USBD_IN_USE);
819 if (iface->endpoints)
820 free(iface->endpoints, M_USB);
821 iface->endpoints = 0;
823 iface->state = USBD_INTERFACE_IDLE;
825 r = usbd_fill_iface_data(iface->device, iface->index, altidx);
826 if (r != USBD_NORMAL_COMPLETION)
829 req.bmRequestType = UT_WRITE_INTERFACE;
830 req.bRequest = UR_SET_INTERFACE;
831 USETW(req.wValue, iface->idesc->bAlternateSetting);
832 USETW(req.wIndex, iface->idesc->bInterfaceNumber);
833 USETW(req.wLength, 0);
834 return usbd_do_request(iface->device, &req, 0);
838 usbd_get_no_alts(cdesc, ifaceno)
839 usb_config_descriptor_t *cdesc;
842 char *p = (char *)cdesc;
843 char *end = p + UGETW(cdesc->wTotalLength);
844 usb_interface_descriptor_t *d;
847 for (n = 0; p < end; p += d->bLength) {
848 d = (usb_interface_descriptor_t *)p;
849 if (p + d->bLength <= end &&
850 d->bDescriptorType == UDESC_INTERFACE &&
851 d->bInterfaceNumber == ifaceno)
858 usbd_get_interface_altindex(iface)
859 usbd_interface_handle iface;
861 return (iface->altindex);
865 usbd_get_interface(iface, aiface)
866 usbd_interface_handle iface;
869 usb_device_request_t req;
871 req.bmRequestType = UT_READ_INTERFACE;
872 req.bRequest = UR_GET_INTERFACE;
873 USETW(req.wValue, 0);
874 USETW(req.wIndex, iface->idesc->bInterfaceNumber);
875 USETW(req.wLength, 1);
876 return usbd_do_request(iface->device, &req, aiface);
879 /*** Internal routines ***/
881 /* Dequeue all pipe operations, called at splusb(). */
884 usbd_pipe_handle pipe;
886 usbd_request_handle reqh;
890 reqh = SIMPLEQ_FIRST(&pipe->queue);
893 SIMPLEQ_REMOVE_HEAD(&pipe->queue, reqh, next);
894 reqh->status = USBD_CANCELLED;
896 reqh->callback(reqh, reqh->priv, reqh->status);
899 while ((reqh = SIMPLEQ_FIRST(&pipe->queue))) {
900 pipe->methods->abort(reqh);
901 SIMPLEQ_REMOVE_HEAD(&pipe->queue, reqh, next);
904 return (USBD_NORMAL_COMPLETION);
907 /* Dequeue all interface operations, called at splusb(). */
910 usbd_interface_handle iface;
913 usbd_status r, ret = USBD_NORMAL_COMPLETION;
915 for (p = LIST_FIRST(&iface->pipes); p != 0; p = LIST_NEXT(p, next)) {
917 if (r != USBD_NORMAL_COMPLETION)
923 static int usbd_global_init_done = 0;
928 #if defined(__FreeBSD__)
932 if (!usbd_global_init_done) {
933 usbd_global_init_done = 1;
934 SIMPLEQ_INIT(&usbd_free_requests);
936 #if defined(__FreeBSD__)
937 dev = makedev(USB_CDEV_MAJOR, 0);
938 cdevsw_add(&dev, &usb_cdevsw, NULL);
944 usbd_transfer_cb(reqh)
945 usbd_request_handle reqh;
947 usbd_pipe_handle pipe = reqh->pipe;
949 /* Count completed transfers. */
950 ++pipe->device->bus->stats.requests
951 [pipe->endpoint->edesc->bmAttributes & UE_XFERTYPE];
953 /* XXX check retry count */
955 if (reqh->status == USBD_NORMAL_COMPLETION &&
956 reqh->actlen < reqh->length &&
957 !(reqh->flags & USBD_SHORT_XFER_OK)) {
958 DPRINTFN(-1, ("usbd_transfer_cb: short xfer %d<%d (bytes)\n",
959 reqh->actlen, reqh->length));
960 reqh->status = USBD_SHORT_XFER;
963 reqh->callback(reqh, reqh->priv, reqh->status);
967 usbd_sync_transfer_cb(reqh)
968 usbd_request_handle reqh;
970 usbd_transfer_cb(reqh);
971 if (!reqh->pipe->device->bus->use_polling)
975 /* Like usbd_transfer(), but waits for completion. */
977 usbd_sync_transfer(reqh)
978 usbd_request_handle reqh;
983 reqh->xfercb = usbd_sync_transfer_cb;
984 r = usbd_do_transfer(reqh);
985 if (r != USBD_IN_PROGRESS)
989 if (reqh->pipe->device->bus->use_polling)
990 panic("usbd_sync_transfer: not done\n");
991 tsleep(reqh, PRIBIO, "usbsyn", 0);
994 return (reqh->status);
998 usbd_do_request(dev, req, data)
999 usbd_device_handle dev;
1000 usb_device_request_t *req;
1003 return (usbd_do_request_flags(dev, req, data, 0, 0));
1007 usbd_do_request_flags(dev, req, data, flags, actlen)
1008 usbd_device_handle dev;
1009 usb_device_request_t *req;
1014 usbd_request_handle reqh;
1019 printf("usbd_do_request: not in process context\n");
1024 reqh = usbd_alloc_request();
1026 return (USBD_NOMEM);
1027 r = usbd_setup_default_request(
1028 reqh, dev, 0, USBD_DEFAULT_TIMEOUT, req, data,
1029 UGETW(req->wLength), flags, 0);
1030 if (r != USBD_NORMAL_COMPLETION)
1032 r = usbd_sync_transfer(reqh);
1033 #if defined(USB_DEBUG) || defined(DIAGNOSTIC)
1034 if (reqh->actlen > reqh->length)
1035 printf("usbd_do_request: overrun addr=%d type=0x%02x req=0x"
1036 "%02x val=%d index=%d rlen=%d length=%d actlen=%d\n",
1037 dev->address, reqh->request.bmRequestType,
1038 reqh->request.bRequest, UGETW(reqh->request.wValue),
1039 UGETW(reqh->request.wIndex),
1040 UGETW(reqh->request.wLength),
1041 reqh->length, reqh->actlen);
1044 *actlen = reqh->actlen;
1045 if (r == USBD_STALLED) {
1047 * The control endpoint has stalled. Control endpoints
1048 * should not halt, but some may do so anyway so clear
1049 * any halt condition.
1051 usb_device_request_t treq;
1052 usb_status_t status;
1056 treq.bmRequestType = UT_READ_ENDPOINT;
1057 treq.bRequest = UR_GET_STATUS;
1058 USETW(treq.wValue, 0);
1059 USETW(treq.wIndex, 0);
1060 USETW(treq.wLength, sizeof(usb_status_t));
1061 nr = usbd_setup_default_request(
1062 reqh, dev, 0, USBD_DEFAULT_TIMEOUT, &treq, &status,
1063 sizeof(usb_status_t), 0, 0);
1064 if (nr != USBD_NORMAL_COMPLETION)
1066 nr = usbd_sync_transfer(reqh);
1067 if (nr != USBD_NORMAL_COMPLETION)
1069 s = UGETW(status.wStatus);
1070 DPRINTF(("usbd_do_request: status = 0x%04x\n", s));
1071 if (!(s & UES_HALT))
1073 treq.bmRequestType = UT_WRITE_ENDPOINT;
1074 treq.bRequest = UR_CLEAR_FEATURE;
1075 USETW(treq.wValue, UF_ENDPOINT_HALT);
1076 USETW(treq.wIndex, 0);
1077 USETW(treq.wLength, 0);
1078 nr = usbd_setup_default_request(
1079 reqh, dev, 0, USBD_DEFAULT_TIMEOUT, &treq, &status,
1081 if (nr != USBD_NORMAL_COMPLETION)
1083 nr = usbd_sync_transfer(reqh);
1084 if (nr != USBD_NORMAL_COMPLETION)
1089 usbd_free_request(reqh);
1094 usbd_do_request_async_cb(reqh, priv, status)
1095 usbd_request_handle reqh;
1096 usbd_private_handle priv;
1099 #if defined(USB_DEBUG) || defined(DIAGNOSTIC)
1100 if (reqh->actlen > reqh->length)
1101 printf("usbd_do_request: overrun addr=%d type=0x%02x req=0x"
1102 "%02x val=%d index=%d rlen=%d length=%d actlen=%d\n",
1103 reqh->pipe->device->address,
1104 reqh->request.bmRequestType,
1105 reqh->request.bRequest, UGETW(reqh->request.wValue),
1106 UGETW(reqh->request.wIndex),
1107 UGETW(reqh->request.wLength),
1108 reqh->length, reqh->actlen);
1110 usbd_free_request(reqh);
1114 * Execute a request without waiting for completion.
1115 * Can be used from interrupt context.
1118 usbd_do_request_async(dev, req, data)
1119 usbd_device_handle dev;
1120 usb_device_request_t *req;
1123 usbd_request_handle reqh;
1126 reqh = usbd_alloc_request();
1128 return (USBD_NOMEM);
1129 r = usbd_setup_default_request(
1130 reqh, dev, 0, USBD_DEFAULT_TIMEOUT, req, data,
1131 UGETW(req->wLength), 0, usbd_do_request_async_cb);
1132 if (r != USBD_NORMAL_COMPLETION) {
1133 usbd_free_request(reqh);
1136 r = usbd_transfer(reqh);
1137 if (r != USBD_IN_PROGRESS)
1139 return (USBD_NORMAL_COMPLETION);
1142 struct usbd_quirks *
1143 usbd_get_quirks(dev)
1144 usbd_device_handle dev;
1146 return (dev->quirks);
1150 usbd_set_disco(p, hdl, data)
1152 void (*hdl) __P((void *));
1159 /* XXX do periodic free() of free list */
1162 * Called from keyboard driver when in polling mode.
1166 usbd_interface_handle iface;
1168 iface->device->bus->do_poll(iface->device->bus);
1172 usbd_set_polling(iface, on)
1173 usbd_interface_handle iface;
1176 iface->device->bus->use_polling = on;
1180 usb_endpoint_descriptor_t *
1181 usbd_get_endpoint_descriptor(iface, address)
1182 usbd_interface_handle iface;
1185 struct usbd_endpoint *ep;
1188 for (i = 0; i < iface->idesc->bNumEndpoints; i++) {
1189 ep = &iface->endpoints[i];
1190 if (ep->edesc->bEndpointAddress == address)
1191 return (iface->endpoints[i].edesc);
1196 #if defined(__FreeBSD__)
1198 usbd_print_child(device_t parent, device_t child)
1201 struct usb_softc *sc = device_get_softc(child);
1204 printf(" at %s%d", device_get_name(parent), device_get_unit(parent));
1206 /* XXX How do we get to the usbd_device_handle???
1207 usbd_device_handle dev = invalidadosch;
1209 printf(" addr %d", dev->addr);
1213 printf(", lowspeed");
1214 if (dev->self_powered)
1215 printf(", self powered");
1217 printf(", %dmA", dev->power);
1218 printf(", config %d", dev->config);
1223 /* Reconfigure all the USB busses in the system. */
1225 usbd_driver_load(module_t mod, int what, void *arg)
1227 devclass_t usb_devclass = devclass_find("usb");
1228 devclass_t ugen_devclass = devclass_find("ugen");
1237 return 0; /* just ignore call */
1239 if (ugen_devclass) {
1240 /* detach devices from generic driver if possible */
1241 error = devclass_get_devices(ugen_devclass, &devlist,
1244 for (devcount--; devcount >= 0; devcount--)
1245 (void)DEVICE_DETACH(devlist[devcount]);
1248 error = devclass_get_devices(usb_devclass, &devlist, &devcount);
1250 return 0; /* XXX maybe transient, or error? */
1252 for (; devcount; devcount--)
1253 USB_RECONFIGURE(devlist[devcount]);
1255 free(devlist, M_TEMP);
1259 return 0; /* nothing to do by us */
1262 /* Set the description of the device including a malloc and copy. */
1264 usbd_device_set_desc(device_t device, char *devinfo)
1270 l = strlen(devinfo);
1271 desc = malloc(l+1, M_USB, M_NOWAIT);
1273 memcpy(desc, devinfo, l+1);
1277 device_set_desc(device, desc);
1281 usbd_devname(bdevice *bdev)
1283 static char buf[20];
1284 /* XXX a static buffer is not exactly a good idea, but the only
1285 * thing that goes wrong is the string that is being printed
1288 sprintf(buf, "%s%d", device_get_name(*bdev), device_get_unit(*bdev));