root/dev/usb/usbdi.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. usbd_init
  2. usbd_finish
  3. usbd_xfer_isread
  4. usbd_dump_iface
  5. usbd_dump_device
  6. usbd_dump_endpoint
  7. usbd_dump_queue
  8. usbd_dump_pipe
  9. usbd_open_pipe
  10. usbd_open_pipe_ival
  11. usbd_open_pipe_intr
  12. usbd_close_pipe
  13. usbd_transfer
  14. usbd_sync_transfer
  15. usbd_alloc_buffer
  16. usbd_free_buffer
  17. usbd_get_buffer
  18. usbd_alloc_xfer
  19. usbd_free_xfer
  20. usbd_setup_xfer
  21. usbd_setup_default_xfer
  22. usbd_setup_isoc_xfer
  23. usbd_get_xfer_status
  24. usbd_get_config_descriptor
  25. usbd_get_interface_descriptor
  26. usbd_get_device_descriptor
  27. usbd_interface2endpoint_descriptor
  28. usbd_abort_pipe
  29. usbd_clear_endpoint_stall
  30. usbd_clear_endpoint_stall_async
  31. usbd_clear_endpoint_toggle
  32. usbd_endpoint_count
  33. usbd_interface_count
  34. usbd_interface2device_handle
  35. usbd_device2interface_handle
  36. usbd_pipe2device_handle
  37. usbd_set_interface
  38. usbd_get_no_alts
  39. usbd_get_interface_altindex
  40. usbd_get_interface
  41. usbd_ar_pipe
  42. usb_transfer_complete
  43. usb_insert_transfer
  44. usbd_start_next
  45. usbd_do_request
  46. usbd_do_request_flags
  47. usbd_do_request_flags_pipe
  48. usbd_do_request_async_cb
  49. usbd_do_request_async
  50. usbd_get_quirks
  51. usbd_dopoll
  52. usbd_set_polling
  53. usbd_get_endpoint_descriptor
  54. usbd_ratecheck
  55. usb_match_device
  56. usb_desc_iter_init
  57. usb_desc_iter_next

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

/* [<][>][^][v][top][bottom][index][help] */