[BACK]Return to usbdi.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / dev / usb

Annotation of src/sys/dev/usb/usbdi.c, Revision 1.152.4.1

1.152.4.1! rmind       1: /*     $NetBSD$        */
1.1       augustss    2:
                      3: /*
1.137     mrg         4:  * Copyright (c) 1998, 2012 The NetBSD Foundation, Inc.
1.1       augustss    5:  * All rights reserved.
                      6:  *
1.11      augustss    7:  * This code is derived from software contributed to The NetBSD Foundation
1.72      augustss    8:  * by Lennart Augustsson (lennart@augustsson.net) at
1.137     mrg         9:  * Carlstedt Research & Technology and Matthew R. Green (mrg@eterna.com.au).
1.1       augustss   10:  *
                     11:  * Redistribution and use in source and binary forms, with or without
                     12:  * modification, are permitted provided that the following conditions
                     13:  * are met:
                     14:  * 1. Redistributions of source code must retain the above copyright
                     15:  *    notice, this list of conditions and the following disclaimer.
                     16:  * 2. Redistributions in binary form must reproduce the above copyright
                     17:  *    notice, this list of conditions and the following disclaimer in the
                     18:  *    documentation and/or other materials provided with the distribution.
                     19:  *
                     20:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     21:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     22:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     23:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     24:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     25:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     26:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     27:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     28:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     29:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     30:  * POSSIBILITY OF SUCH DAMAGE.
                     31:  */
1.84      lukem      32:
                     33: #include <sys/cdefs.h>
1.152.4.1! rmind      34: __KERNEL_RCSID(0, "$NetBSD$");
1.115     pavel      35:
1.141     christos   36: #ifdef _KERNEL_OPT
1.115     pavel      37: #include "opt_compat_netbsd.h"
1.141     christos   38: #endif
1.1       augustss   39:
                     40: #include <sys/param.h>
                     41: #include <sys/systm.h>
                     42: #include <sys/kernel.h>
1.15      augustss   43: #include <sys/device.h>
1.1       augustss   44: #include <sys/malloc.h>
                     45: #include <sys/proc.h>
1.121     ad         46: #include <sys/bus.h>
1.136     mrg        47: #include <sys/cpu.h>
1.36      augustss   48:
1.1       augustss   49: #include <dev/usb/usb.h>
                     50: #include <dev/usb/usbdi.h>
                     51: #include <dev/usb/usbdi_util.h>
                     52: #include <dev/usb/usbdivar.h>
1.36      augustss   53: #include <dev/usb/usb_mem.h>
1.105     augustss   54: #include <dev/usb/usb_quirks.h>
1.1       augustss   55:
1.119     drochner   56: /* UTF-8 encoding stuff */
                     57: #include <fs/unicode.h>
                     58:
1.1       augustss   59: #ifdef USB_DEBUG
1.130     dyoung     60: #define DPRINTF(x)     if (usbdebug) printf x
                     61: #define DPRINTFN(n,x)  if (usbdebug>(n)) printf x
1.1       augustss   62: extern int usbdebug;
                     63: #else
                     64: #define DPRINTF(x)
                     65: #define DPRINTFN(n,x)
                     66: #endif
                     67:
1.74      augustss   68: Static usbd_status usbd_ar_pipe(usbd_pipe_handle pipe);
1.102     augustss   69: Static void usbd_do_request_async_cb
1.87      augustss   70:        (usbd_xfer_handle, usbd_private_handle, usbd_status);
1.74      augustss   71: Static void usbd_start_next(usbd_pipe_handle pipe);
1.69      augustss   72: Static usbd_status usbd_open_pipe_ival
1.87      augustss   73:        (usbd_interface_handle, u_int8_t, u_int8_t, usbd_pipe_handle *, int);
1.1       augustss   74:
1.110     perry      75: static inline int
1.74      augustss   76: usbd_xfer_isread(usbd_xfer_handle xfer)
1.37      augustss   77: {
1.48      augustss   78:        if (xfer->rqflags & URQ_REQUEST)
                     79:                return (xfer->request.bmRequestType & UT_READ);
1.37      augustss   80:        else
1.48      augustss   81:                return (xfer->pipe->endpoint->edesc->bEndpointAddress &
1.37      augustss   82:                        UE_DIR_IN);
                     83: }
                     84:
1.151     skrll      85: #if defined(USB_DEBUG) || defined(EHCI_DEBUG) || defined(OHCI_DEBUG)
1.82      augustss   86: void
                     87: usbd_dump_iface(struct usbd_interface *iface)
                     88: {
                     89:        printf("usbd_dump_iface: iface=%p\n", iface);
                     90:        if (iface == NULL)
                     91:                return;
                     92:        printf(" device=%p idesc=%p index=%d altindex=%d priv=%p\n",
                     93:               iface->device, iface->idesc, iface->index, iface->altindex,
                     94:               iface->priv);
                     95: }
                     96:
                     97: void
                     98: usbd_dump_device(struct usbd_device *dev)
                     99: {
                    100:        printf("usbd_dump_device: dev=%p\n", dev);
                    101:        if (dev == NULL)
                    102:                return;
                    103:        printf(" bus=%p default_pipe=%p\n", dev->bus, dev->default_pipe);
1.86      augustss  104:        printf(" address=%d config=%d depth=%d speed=%d self_powered=%d "
                    105:               "power=%d langid=%d\n",
                    106:               dev->address, dev->config, dev->depth, dev->speed,
1.82      augustss  107:               dev->self_powered, dev->power, dev->langid);
                    108: }
                    109:
                    110: void
                    111: usbd_dump_endpoint(struct usbd_endpoint *endp)
                    112: {
                    113:        printf("usbd_dump_endpoint: endp=%p\n", endp);
                    114:        if (endp == NULL)
                    115:                return;
                    116:        printf(" edesc=%p refcnt=%d\n", endp->edesc, endp->refcnt);
                    117:        if (endp->edesc)
                    118:                printf(" bEndpointAddress=0x%02x\n",
                    119:                       endp->edesc->bEndpointAddress);
                    120: }
                    121:
1.28      augustss  122: void
1.74      augustss  123: usbd_dump_queue(usbd_pipe_handle pipe)
1.28      augustss  124: {
1.48      augustss  125:        usbd_xfer_handle xfer;
1.28      augustss  126:
                    127:        printf("usbd_dump_queue: pipe=%p\n", pipe);
1.101     lukem     128:        SIMPLEQ_FOREACH(xfer, &pipe->queue, next) {
1.48      augustss  129:                printf("  xfer=%p\n", xfer);
1.28      augustss  130:        }
1.82      augustss  131: }
                    132:
                    133: void
                    134: usbd_dump_pipe(usbd_pipe_handle pipe)
                    135: {
                    136:        printf("usbd_dump_pipe: pipe=%p\n", pipe);
                    137:        if (pipe == NULL)
                    138:                return;
                    139:        usbd_dump_iface(pipe->iface);
                    140:        usbd_dump_device(pipe->device);
                    141:        usbd_dump_endpoint(pipe->endpoint);
                    142:        printf(" (usbd_dump_pipe:)\n refcnt=%d running=%d aborting=%d\n",
                    143:               pipe->refcnt, pipe->running, pipe->aborting);
1.88      augustss  144:        printf(" intrxfer=%p, repeat=%d, interval=%d\n",
1.82      augustss  145:               pipe->intrxfer, pipe->repeat, pipe->interval);
1.28      augustss  146: }
                    147: #endif
                    148:
1.102     augustss  149: usbd_status
1.74      augustss  150: usbd_open_pipe(usbd_interface_handle iface, u_int8_t address,
                    151:               u_int8_t flags, usbd_pipe_handle *pipe)
1.102     augustss  152: {
                    153:        return (usbd_open_pipe_ival(iface, address, flags, pipe,
1.60      augustss  154:                                    USBD_DEFAULT_INTERVAL));
                    155: }
                    156:
1.102     augustss  157: usbd_status
1.74      augustss  158: usbd_open_pipe_ival(usbd_interface_handle iface, u_int8_t address,
                    159:                    u_int8_t flags, usbd_pipe_handle *pipe, int ival)
1.102     augustss  160: {
1.1       augustss  161:        usbd_pipe_handle p;
                    162:        struct usbd_endpoint *ep;
1.48      augustss  163:        usbd_status err;
1.12      augustss  164:        int i;
1.1       augustss  165:
1.57      augustss  166:        DPRINTFN(3,("usbd_open_pipe: iface=%p address=0x%x flags=0x%x\n",
                    167:                    iface, address, flags));
1.53      augustss  168:
1.1       augustss  169:        for (i = 0; i < iface->idesc->bNumEndpoints; i++) {
                    170:                ep = &iface->endpoints[i];
1.49      augustss  171:                if (ep->edesc == NULL)
                    172:                        return (USBD_IOERROR);
1.1       augustss  173:                if (ep->edesc->bEndpointAddress == address)
                    174:                        goto found;
                    175:        }
                    176:        return (USBD_BAD_ADDRESS);
                    177:  found:
1.60      augustss  178:        if ((flags & USBD_EXCLUSIVE_USE) && ep->refcnt != 0)
1.1       augustss  179:                return (USBD_IN_USE);
1.149     jmcneill  180:        err = usbd_setup_pipe_flags(iface->device, iface, ep, ival, &p, flags);
1.48      augustss  181:        if (err)
                    182:                return (err);
1.1       augustss  183:        LIST_INSERT_HEAD(&iface->pipes, p, next);
                    184:        *pipe = p;
                    185:        return (USBD_NORMAL_COMPLETION);
                    186: }
                    187:
1.102     augustss  188: usbd_status
1.74      augustss  189: usbd_open_pipe_intr(usbd_interface_handle iface, u_int8_t address,
                    190:                    u_int8_t flags, usbd_pipe_handle *pipe,
                    191:                    usbd_private_handle priv, void *buffer, u_int32_t len,
                    192:                    usbd_callback cb, int ival)
1.1       augustss  193: {
1.48      augustss  194:        usbd_status err;
                    195:        usbd_xfer_handle xfer;
1.1       augustss  196:        usbd_pipe_handle ipipe;
                    197:
1.60      augustss  198:        DPRINTFN(3,("usbd_open_pipe_intr: address=0x%x flags=0x%x len=%d\n",
                    199:                    address, flags, len));
1.53      augustss  200:
1.150     jmcneill  201:        err = usbd_open_pipe_ival(iface, address,
                    202:                                  USBD_EXCLUSIVE_USE | (flags & USBD_MPSAFE),
1.60      augustss  203:                                  &ipipe, ival);
1.48      augustss  204:        if (err)
                    205:                return (err);
1.50      augustss  206:        xfer = usbd_alloc_xfer(iface->device);
1.48      augustss  207:        if (xfer == NULL) {
                    208:                err = USBD_NOMEM;
1.1       augustss  209:                goto bad1;
1.36      augustss  210:        }
1.60      augustss  211:        usbd_setup_xfer(xfer, ipipe, priv, buffer, len, flags,
                    212:            USBD_NO_TIMEOUT, cb);
1.48      augustss  213:        ipipe->intrxfer = xfer;
1.25      augustss  214:        ipipe->repeat = 1;
1.48      augustss  215:        err = usbd_transfer(xfer);
1.1       augustss  216:        *pipe = ipipe;
1.48      augustss  217:        if (err != USBD_IN_PROGRESS)
1.36      augustss  218:                goto bad2;
1.1       augustss  219:        return (USBD_NORMAL_COMPLETION);
                    220:
1.36      augustss  221:  bad2:
1.48      augustss  222:        ipipe->intrxfer = NULL;
1.25      augustss  223:        ipipe->repeat = 0;
1.50      augustss  224:        usbd_free_xfer(xfer);
1.36      augustss  225:  bad1:
1.1       augustss  226:        usbd_close_pipe(ipipe);
1.48      augustss  227:        return (err);
1.9       augustss  228: }
                    229:
1.1       augustss  230: usbd_status
1.74      augustss  231: usbd_close_pipe(usbd_pipe_handle pipe)
1.1       augustss  232: {
1.138     mrg       233:        int s;
                    234:
1.26      augustss  235: #ifdef DIAGNOSTIC
1.48      augustss  236:        if (pipe == NULL) {
1.26      augustss  237:                printf("usbd_close_pipe: pipe==NULL\n");
                    238:                return (USBD_NORMAL_COMPLETION);
                    239:        }
                    240: #endif
                    241:
1.138     mrg       242:        usbd_lock_pipe(pipe);
                    243:        if (--pipe->refcnt != 0) {
                    244:                usbd_unlock_pipe(pipe);
1.1       augustss  245:                return (USBD_NORMAL_COMPLETION);
1.138     mrg       246:        }
                    247:        if (! SIMPLEQ_EMPTY(&pipe->queue)) {
                    248:                usbd_unlock_pipe(pipe);
1.1       augustss  249:                return (USBD_PENDING_REQUESTS);
1.138     mrg       250:        }
1.1       augustss  251:        LIST_REMOVE(pipe, next);
                    252:        pipe->endpoint->refcnt--;
                    253:        pipe->methods->close(pipe);
1.138     mrg       254:        usbd_unlock_pipe(pipe);
1.48      augustss  255:        if (pipe->intrxfer != NULL)
1.50      augustss  256:                usbd_free_xfer(pipe->intrxfer);
1.1       augustss  257:        free(pipe, M_USB);
                    258:        return (USBD_NORMAL_COMPLETION);
                    259: }
                    260:
1.31      augustss  261: usbd_status
1.74      augustss  262: usbd_transfer(usbd_xfer_handle xfer)
1.1       augustss  263: {
1.48      augustss  264:        usbd_pipe_handle pipe = xfer->pipe;
                    265:        usb_dma_t *dmap = &xfer->dmabuf;
                    266:        usbd_status err;
1.120     kiyohara  267:        unsigned int size, flags;
1.31      augustss  268:        int s;
1.16      augustss  269:
1.120     kiyohara  270:        DPRINTFN(5,("usbd_transfer: xfer=%p, flags=%#x, pipe=%p, running=%d\n",
1.48      augustss  271:                    xfer, xfer->flags, pipe, pipe->running));
1.134     jmcneill  272:
1.28      augustss  273: #ifdef USB_DEBUG
                    274:        if (usbdebug > 5)
                    275:                usbd_dump_queue(pipe);
                    276: #endif
1.48      augustss  277:        xfer->done = 0;
1.31      augustss  278:
1.71      augustss  279:        if (pipe->aborting)
                    280:                return (USBD_CANCELLED);
                    281:
1.48      augustss  282:        size = xfer->length;
1.38      augustss  283:        /* If there is no buffer, allocate one. */
1.48      augustss  284:        if (!(xfer->rqflags & URQ_DEV_DMABUF) && size != 0) {
1.37      augustss  285:                struct usbd_bus *bus = pipe->device->bus;
                    286:
                    287: #ifdef DIAGNOSTIC
1.48      augustss  288:                if (xfer->rqflags & URQ_AUTO_DMABUF)
1.37      augustss  289:                        printf("usbd_transfer: has old buffer!\n");
                    290: #endif
1.48      augustss  291:                err = bus->methods->allocm(bus, dmap, size);
                    292:                if (err)
                    293:                        return (err);
                    294:                xfer->rqflags |= URQ_AUTO_DMABUF;
1.38      augustss  295:        }
1.37      augustss  296:
1.120     kiyohara  297:        flags = xfer->flags;
                    298:
1.38      augustss  299:        /* Copy data if going out. */
1.120     kiyohara  300:        if (!(flags & USBD_NO_COPY) && size != 0 && !usbd_xfer_isread(xfer))
1.100     augustss  301:                memcpy(KERNADDR(dmap, 0), xfer->buffer, size);
1.37      augustss  302:
1.120     kiyohara  303:        /* xfer is not valid after the transfer method unless synchronous */
1.48      augustss  304:        err = pipe->methods->transfer(xfer);
1.37      augustss  305:
1.51      augustss  306:        if (err != USBD_IN_PROGRESS && err) {
1.37      augustss  307:                /* The transfer has not been queued, so free buffer. */
1.48      augustss  308:                if (xfer->rqflags & URQ_AUTO_DMABUF) {
1.37      augustss  309:                        struct usbd_bus *bus = pipe->device->bus;
                    310:
1.48      augustss  311:                        bus->methods->freem(bus, &xfer->dmabuf);
                    312:                        xfer->rqflags &= ~URQ_AUTO_DMABUF;
1.37      augustss  313:                }
                    314:        }
                    315:
1.120     kiyohara  316:        if (!(flags & USBD_SYNCHRONOUS))
1.48      augustss  317:                return (err);
1.31      augustss  318:
                    319:        /* Sync transfer, wait for completion. */
1.48      augustss  320:        if (err != USBD_IN_PROGRESS)
                    321:                return (err);
1.138     mrg       322:        usbd_lock_pipe(pipe);
1.143     christos  323:        while (!xfer->done) {
1.37      augustss  324:                if (pipe->device->bus->use_polling)
1.103     provos    325:                        panic("usbd_transfer: not done");
1.138     mrg       326:
1.144     christos  327:                err = 0;
1.138     mrg       328:                if ((flags & USBD_SYNCHRONOUS_SIG) != 0) {
                    329:                        if (pipe->device->bus->lock)
1.146     skrll     330:                                err = cv_wait_sig(&xfer->cv, pipe->device->bus->lock);
1.138     mrg       331:                        else
1.144     christos  332:                                err = tsleep(xfer, PZERO|PCATCH, "usbsyn", 0);
1.138     mrg       333:                } else {
                    334:                        if (pipe->device->bus->lock)
                    335:                                cv_wait(&xfer->cv, pipe->device->bus->lock);
                    336:                        else
1.144     christos  337:                                err = tsleep(xfer, PRIBIO, "usbsyn", 0);
1.138     mrg       338:                }
1.152.4.1! rmind     339:                if (err) {
        !           340:                        if (!xfer->done)
        !           341:                                pipe->methods->abort(xfer);
1.144     christos  342:                        break;
1.152.4.1! rmind     343:                }
1.31      augustss  344:        }
1.138     mrg       345:        usbd_unlock_pipe(pipe);
1.48      augustss  346:        return (xfer->status);
1.31      augustss  347: }
                    348:
                    349: /* Like usbd_transfer(), but waits for completion. */
                    350: usbd_status
1.74      augustss  351: usbd_sync_transfer(usbd_xfer_handle xfer)
1.31      augustss  352: {
1.48      augustss  353:        xfer->flags |= USBD_SYNCHRONOUS;
                    354:        return (usbd_transfer(xfer));
1.16      augustss  355: }
                    356:
1.138     mrg       357: /* Like usbd_transfer(), but waits for completion and listens for signals. */
                    358: usbd_status
                    359: usbd_sync_transfer_sig(usbd_xfer_handle xfer)
                    360: {
                    361:        xfer->flags |= USBD_SYNCHRONOUS | USBD_SYNCHRONOUS_SIG;
                    362:        return (usbd_transfer(xfer));
                    363: }
                    364:
1.36      augustss  365: void *
1.74      augustss  366: usbd_alloc_buffer(usbd_xfer_handle xfer, u_int32_t size)
1.36      augustss  367: {
1.48      augustss  368:        struct usbd_bus *bus = xfer->device->bus;
                    369:        usbd_status err;
1.37      augustss  370:
1.92      augustss  371: #ifdef DIAGNOSTIC
                    372:        if (xfer->rqflags & (URQ_DEV_DMABUF | URQ_AUTO_DMABUF))
                    373:                printf("usbd_alloc_buffer: xfer already has a buffer\n");
                    374: #endif
1.48      augustss  375:        err = bus->methods->allocm(bus, &xfer->dmabuf, size);
                    376:        if (err)
1.92      augustss  377:                return (NULL);
1.48      augustss  378:        xfer->rqflags |= URQ_DEV_DMABUF;
1.100     augustss  379:        return (KERNADDR(&xfer->dmabuf, 0));
1.36      augustss  380: }
                    381:
                    382: void
1.74      augustss  383: usbd_free_buffer(usbd_xfer_handle xfer)
1.36      augustss  384: {
1.37      augustss  385: #ifdef DIAGNOSTIC
1.48      augustss  386:        if (!(xfer->rqflags & (URQ_DEV_DMABUF | URQ_AUTO_DMABUF))) {
1.37      augustss  387:                printf("usbd_free_buffer: no buffer\n");
                    388:                return;
                    389:        }
                    390: #endif
1.48      augustss  391:        xfer->rqflags &= ~(URQ_DEV_DMABUF | URQ_AUTO_DMABUF);
                    392:        xfer->device->bus->methods->freem(xfer->device->bus, &xfer->dmabuf);
1.36      augustss  393: }
                    394:
1.38      augustss  395: void *
1.74      augustss  396: usbd_get_buffer(usbd_xfer_handle xfer)
1.38      augustss  397: {
1.48      augustss  398:        if (!(xfer->rqflags & URQ_DEV_DMABUF))
1.152.4.1! rmind     399:                return (NULL);
1.100     augustss  400:        return (KERNADDR(&xfer->dmabuf, 0));
1.38      augustss  401: }
                    402:
1.102     augustss  403: usbd_xfer_handle
1.74      augustss  404: usbd_alloc_xfer(usbd_device_handle dev)
1.1       augustss  405: {
1.48      augustss  406:        usbd_xfer_handle xfer;
1.1       augustss  407:
1.58      augustss  408:        xfer = dev->bus->methods->allocx(dev->bus);
1.48      augustss  409:        if (xfer == NULL)
1.58      augustss  410:                return (NULL);
1.48      augustss  411:        xfer->device = dev;
1.138     mrg       412:        callout_init(&xfer->timeout_handle,
                    413:            dev->bus->methods->get_lock ? CALLOUT_MPSAFE : 0);
                    414:        cv_init(&xfer->cv, "usbxfer");
                    415:        cv_init(&xfer->hccv, "usbhcxfer");
1.50      augustss  416:        DPRINTFN(5,("usbd_alloc_xfer() = %p\n", xfer));
1.48      augustss  417:        return (xfer);
1.1       augustss  418: }
                    419:
1.102     augustss  420: usbd_status
1.74      augustss  421: usbd_free_xfer(usbd_xfer_handle xfer)
1.1       augustss  422: {
1.50      augustss  423:        DPRINTFN(5,("usbd_free_xfer: %p\n", xfer));
1.48      augustss  424:        if (xfer->rqflags & (URQ_DEV_DMABUF | URQ_AUTO_DMABUF))
                    425:                usbd_free_buffer(xfer);
1.123     drochner  426: #if defined(DIAGNOSTIC)
1.68      augustss  427:        if (callout_pending(&xfer->timeout_handle)) {
                    428:                callout_stop(&xfer->timeout_handle);
1.140     skrll     429:                printf("usbd_free_xfer: timeout_handle pending\n");
1.68      augustss  430:        }
1.66      thorpej   431: #endif
1.138     mrg       432:        cv_destroy(&xfer->cv);
                    433:        cv_destroy(&xfer->hccv);
1.58      augustss  434:        xfer->device->bus->methods->freex(xfer->device->bus, xfer);
1.1       augustss  435:        return (USBD_NORMAL_COMPLETION);
                    436: }
                    437:
1.36      augustss  438: void
1.74      augustss  439: usbd_setup_xfer(usbd_xfer_handle xfer, usbd_pipe_handle pipe,
                    440:                usbd_private_handle priv, void *buffer, u_int32_t length,
                    441:                u_int16_t flags, u_int32_t timeout,
                    442:                usbd_callback callback)
1.1       augustss  443: {
1.48      augustss  444:        xfer->pipe = pipe;
                    445:        xfer->priv = priv;
                    446:        xfer->buffer = buffer;
                    447:        xfer->length = length;
                    448:        xfer->actlen = 0;
                    449:        xfer->flags = flags;
                    450:        xfer->timeout = timeout;
                    451:        xfer->status = USBD_NOT_STARTED;
                    452:        xfer->callback = callback;
                    453:        xfer->rqflags &= ~URQ_REQUEST;
                    454:        xfer->nframes = 0;
1.1       augustss  455: }
                    456:
1.36      augustss  457: void
1.74      augustss  458: usbd_setup_default_xfer(usbd_xfer_handle xfer, usbd_device_handle dev,
                    459:                        usbd_private_handle priv, u_int32_t timeout,
                    460:                        usb_device_request_t *req, void *buffer,
                    461:                        u_int32_t length, u_int16_t flags,
                    462:                        usbd_callback callback)
1.1       augustss  463: {
1.48      augustss  464:        xfer->pipe = dev->default_pipe;
                    465:        xfer->priv = priv;
                    466:        xfer->buffer = buffer;
                    467:        xfer->length = length;
                    468:        xfer->actlen = 0;
                    469:        xfer->flags = flags;
                    470:        xfer->timeout = timeout;
                    471:        xfer->status = USBD_NOT_STARTED;
                    472:        xfer->callback = callback;
                    473:        xfer->request = *req;
                    474:        xfer->rqflags |= URQ_REQUEST;
                    475:        xfer->nframes = 0;
1.36      augustss  476: }
                    477:
                    478: void
1.74      augustss  479: usbd_setup_isoc_xfer(usbd_xfer_handle xfer, usbd_pipe_handle pipe,
                    480:                     usbd_private_handle priv, u_int16_t *frlengths,
                    481:                     u_int32_t nframes, u_int16_t flags, usbd_callback callback)
1.36      augustss  482: {
1.48      augustss  483:        xfer->pipe = pipe;
                    484:        xfer->priv = priv;
                    485:        xfer->buffer = 0;
                    486:        xfer->length = 0;
                    487:        xfer->actlen = 0;
                    488:        xfer->flags = flags;
                    489:        xfer->timeout = USBD_NO_TIMEOUT;
                    490:        xfer->status = USBD_NOT_STARTED;
                    491:        xfer->callback = callback;
                    492:        xfer->rqflags &= ~URQ_REQUEST;
                    493:        xfer->frlengths = frlengths;
                    494:        xfer->nframes = nframes;
1.1       augustss  495: }
                    496:
1.31      augustss  497: void
1.74      augustss  498: usbd_get_xfer_status(usbd_xfer_handle xfer, usbd_private_handle *priv,
                    499:                     void **buffer, u_int32_t *count, usbd_status *status)
1.1       augustss  500: {
1.48      augustss  501:        if (priv != NULL)
                    502:                *priv = xfer->priv;
                    503:        if (buffer != NULL)
                    504:                *buffer = xfer->buffer;
                    505:        if (count != NULL)
                    506:                *count = xfer->actlen;
                    507:        if (status != NULL)
                    508:                *status = xfer->status;
1.1       augustss  509: }
                    510:
                    511: usb_config_descriptor_t *
1.74      augustss  512: usbd_get_config_descriptor(usbd_device_handle dev)
1.1       augustss  513: {
1.53      augustss  514: #ifdef DIAGNOSTIC
                    515:        if (dev == NULL) {
                    516:                printf("usbd_get_config_descriptor: dev == NULL\n");
                    517:                return (NULL);
                    518:        }
                    519: #endif
1.1       augustss  520:        return (dev->cdesc);
                    521: }
                    522:
                    523: usb_interface_descriptor_t *
1.74      augustss  524: usbd_get_interface_descriptor(usbd_interface_handle iface)
1.1       augustss  525: {
1.53      augustss  526: #ifdef DIAGNOSTIC
                    527:        if (iface == NULL) {
                    528:                printf("usbd_get_interface_descriptor: dev == NULL\n");
                    529:                return (NULL);
                    530:        }
                    531: #endif
1.1       augustss  532:        return (iface->idesc);
                    533: }
                    534:
                    535: usb_device_descriptor_t *
1.74      augustss  536: usbd_get_device_descriptor(usbd_device_handle dev)
1.1       augustss  537: {
                    538:        return (&dev->ddesc);
                    539: }
                    540:
                    541: usb_endpoint_descriptor_t *
1.74      augustss  542: usbd_interface2endpoint_descriptor(usbd_interface_handle iface, u_int8_t index)
1.1       augustss  543: {
                    544:        if (index >= iface->idesc->bNumEndpoints)
1.152.4.1! rmind     545:                return (NULL);
1.1       augustss  546:        return (iface->endpoints[index].edesc);
                    547: }
                    548:
1.125     jmorse    549: /* Some drivers may wish to abort requests on the default pipe, *
                    550:  * but there is no mechanism for getting a handle on it.        */
                    551: usbd_status
                    552: usbd_abort_default_pipe(struct usbd_device *device)
                    553: {
                    554:
                    555:        return usbd_abort_pipe(device->default_pipe);
                    556: }
                    557:
1.102     augustss  558: usbd_status
1.74      augustss  559: usbd_abort_pipe(usbd_pipe_handle pipe)
1.1       augustss  560: {
1.48      augustss  561:        usbd_status err;
1.24      augustss  562:        int s;
1.127     bouyer    563:        usbd_xfer_handle intrxfer = pipe->intrxfer;
1.1       augustss  564:
1.26      augustss  565: #ifdef DIAGNOSTIC
1.48      augustss  566:        if (pipe == NULL) {
1.126     uebayasi  567:                printf("usbd_abort_pipe: pipe==NULL\n");
1.26      augustss  568:                return (USBD_NORMAL_COMPLETION);
                    569:        }
                    570: #endif
1.138     mrg       571:        usbd_lock_pipe(pipe);
1.48      augustss  572:        err = usbd_ar_pipe(pipe);
1.138     mrg       573:        usbd_unlock_pipe(pipe);
1.127     bouyer    574:        if (pipe->intrxfer != intrxfer)
                    575:                usbd_free_xfer(intrxfer);
1.48      augustss  576:        return (err);
1.1       augustss  577: }
1.102     augustss  578:
                    579: usbd_status
1.74      augustss  580: usbd_clear_endpoint_stall(usbd_pipe_handle pipe)
1.1       augustss  581: {
                    582:        usbd_device_handle dev = pipe->device;
                    583:        usb_device_request_t req;
1.48      augustss  584:        usbd_status err;
1.1       augustss  585:
1.22      augustss  586:        DPRINTFN(8, ("usbd_clear_endpoint_stall\n"));
1.33      augustss  587:
1.102     augustss  588:        /*
1.87      augustss  589:         * Clearing en endpoint stall resets the endpoint toggle, so
1.33      augustss  590:         * do the same to the HC toggle.
                    591:         */
1.30      augustss  592:        pipe->methods->cleartoggle(pipe);
1.33      augustss  593:
1.1       augustss  594:        req.bmRequestType = UT_WRITE_ENDPOINT;
                    595:        req.bRequest = UR_CLEAR_FEATURE;
1.15      augustss  596:        USETW(req.wValue, UF_ENDPOINT_HALT);
1.7       augustss  597:        USETW(req.wIndex, pipe->endpoint->edesc->bEndpointAddress);
1.1       augustss  598:        USETW(req.wLength, 0);
1.48      augustss  599:        err = usbd_do_request(dev, &req, 0);
1.1       augustss  600: #if 0
                    601: XXX should we do this?
1.51      augustss  602:        if (!err) {
1.1       augustss  603:                pipe->state = USBD_PIPE_ACTIVE;
                    604:                /* XXX activate pipe */
                    605:        }
                    606: #endif
1.48      augustss  607:        return (err);
1.1       augustss  608: }
                    609:
1.139     mrg       610: void
                    611: usbd_clear_endpoint_stall_async_cb(void *arg)
1.7       augustss  612: {
1.139     mrg       613:        usbd_pipe_handle pipe = arg;
1.7       augustss  614:        usbd_device_handle dev = pipe->device;
                    615:        usb_device_request_t req;
                    616:
1.30      augustss  617:        pipe->methods->cleartoggle(pipe);
1.33      augustss  618:
1.7       augustss  619:        req.bmRequestType = UT_WRITE_ENDPOINT;
                    620:        req.bRequest = UR_CLEAR_FEATURE;
1.15      augustss  621:        USETW(req.wValue, UF_ENDPOINT_HALT);
1.7       augustss  622:        USETW(req.wIndex, pipe->endpoint->edesc->bEndpointAddress);
                    623:        USETW(req.wLength, 0);
1.139     mrg       624:        (void)usbd_do_request_async(dev, &req, 0);
                    625: }
                    626:
                    627: void
                    628: usbd_clear_endpoint_stall_async(usbd_pipe_handle pipe)
                    629: {
                    630:
                    631:        usb_add_task(pipe->device, &pipe->async_task, USB_TASKQ_DRIVER);
1.7       augustss  632: }
                    633:
1.61      augustss  634: void
1.74      augustss  635: usbd_clear_endpoint_toggle(usbd_pipe_handle pipe)
1.61      augustss  636: {
                    637:        pipe->methods->cleartoggle(pipe);
                    638: }
                    639:
1.102     augustss  640: usbd_status
1.74      augustss  641: usbd_endpoint_count(usbd_interface_handle iface, u_int8_t *count)
1.1       augustss  642: {
1.73      augustss  643: #ifdef DIAGNOSTIC
                    644:        if (iface == NULL || iface->idesc == NULL) {
                    645:                printf("usbd_endpoint_count: NULL pointer\n");
                    646:                return (USBD_INVAL);
                    647:        }
                    648: #endif
1.1       augustss  649:        *count = iface->idesc->bNumEndpoints;
                    650:        return (USBD_NORMAL_COMPLETION);
                    651: }
                    652:
1.102     augustss  653: usbd_status
1.74      augustss  654: usbd_interface_count(usbd_device_handle dev, u_int8_t *count)
1.1       augustss  655: {
1.48      augustss  656:        if (dev->cdesc == NULL)
1.1       augustss  657:                return (USBD_NOT_CONFIGURED);
                    658:        *count = dev->cdesc->bNumInterface;
                    659:        return (USBD_NORMAL_COMPLETION);
                    660: }
                    661:
1.85      augustss  662: void
1.74      augustss  663: usbd_interface2device_handle(usbd_interface_handle iface,
                    664:                             usbd_device_handle *dev)
1.1       augustss  665: {
                    666:        *dev = iface->device;
                    667: }
                    668:
1.102     augustss  669: usbd_status
1.74      augustss  670: usbd_device2interface_handle(usbd_device_handle dev,
                    671:                             u_int8_t ifaceno, usbd_interface_handle *iface)
1.1       augustss  672: {
1.48      augustss  673:        if (dev->cdesc == NULL)
1.1       augustss  674:                return (USBD_NOT_CONFIGURED);
                    675:        if (ifaceno >= dev->cdesc->bNumInterface)
                    676:                return (USBD_INVAL);
                    677:        *iface = &dev->ifaces[ifaceno];
                    678:        return (USBD_NORMAL_COMPLETION);
                    679: }
                    680:
1.36      augustss  681: usbd_device_handle
1.74      augustss  682: usbd_pipe2device_handle(usbd_pipe_handle pipe)
1.36      augustss  683: {
                    684:        return (pipe->device);
                    685: }
                    686:
1.13      augustss  687: /* XXXX use altno */
1.3       augustss  688: usbd_status
1.74      augustss  689: usbd_set_interface(usbd_interface_handle iface, int altidx)
1.3       augustss  690: {
                    691:        usb_device_request_t req;
1.48      augustss  692:        usbd_status err;
1.73      augustss  693:        void *endpoints;
1.13      augustss  694:
                    695:        if (LIST_FIRST(&iface->pipes) != 0)
                    696:                return (USBD_IN_USE);
                    697:
1.76      augustss  698:        endpoints = iface->endpoints;
1.48      augustss  699:        err = usbd_fill_iface_data(iface->device, iface->index, altidx);
                    700:        if (err)
                    701:                return (err);
1.73      augustss  702:
1.76      augustss  703:        /* new setting works, we can free old endpoints */
1.73      augustss  704:        if (endpoints != NULL)
                    705:                free(endpoints, M_USB);
                    706:
                    707: #ifdef DIAGNOSTIC
                    708:        if (iface->idesc == NULL) {
                    709:                printf("usbd_set_interface: NULL pointer\n");
                    710:                return (USBD_INVAL);
                    711:        }
                    712: #endif
1.3       augustss  713:
                    714:        req.bmRequestType = UT_WRITE_INTERFACE;
                    715:        req.bRequest = UR_SET_INTERFACE;
1.13      augustss  716:        USETW(req.wValue, iface->idesc->bAlternateSetting);
1.16      augustss  717:        USETW(req.wIndex, iface->idesc->bInterfaceNumber);
1.3       augustss  718:        USETW(req.wLength, 0);
1.48      augustss  719:        return (usbd_do_request(iface->device, &req, 0));
1.12      augustss  720: }
                    721:
                    722: int
1.74      augustss  723: usbd_get_no_alts(usb_config_descriptor_t *cdesc, int ifaceno)
1.12      augustss  724: {
1.13      augustss  725:        char *p = (char *)cdesc;
                    726:        char *end = p + UGETW(cdesc->wTotalLength);
1.12      augustss  727:        usb_interface_descriptor_t *d;
                    728:        int n;
                    729:
                    730:        for (n = 0; p < end; p += d->bLength) {
                    731:                d = (usb_interface_descriptor_t *)p;
1.102     augustss  732:                if (p + d->bLength <= end &&
1.12      augustss  733:                    d->bDescriptorType == UDESC_INTERFACE &&
1.13      augustss  734:                    d->bInterfaceNumber == ifaceno)
1.12      augustss  735:                        n++;
                    736:        }
                    737:        return (n);
1.13      augustss  738: }
                    739:
                    740: int
1.74      augustss  741: usbd_get_interface_altindex(usbd_interface_handle iface)
1.13      augustss  742: {
                    743:        return (iface->altindex);
1.12      augustss  744: }
                    745:
                    746: usbd_status
1.74      augustss  747: usbd_get_interface(usbd_interface_handle iface, u_int8_t *aiface)
1.12      augustss  748: {
                    749:        usb_device_request_t req;
                    750:
                    751:        req.bmRequestType = UT_READ_INTERFACE;
                    752:        req.bRequest = UR_GET_INTERFACE;
                    753:        USETW(req.wValue, 0);
1.16      augustss  754:        USETW(req.wIndex, iface->idesc->bInterfaceNumber);
1.12      augustss  755:        USETW(req.wLength, 1);
1.48      augustss  756:        return (usbd_do_request(iface->device, &req, aiface));
1.3       augustss  757: }
1.1       augustss  758:
                    759: /*** Internal routines ***/
                    760:
                    761: /* Dequeue all pipe operations, called at splusb(). */
1.69      augustss  762: Static usbd_status
1.74      augustss  763: usbd_ar_pipe(usbd_pipe_handle pipe)
1.1       augustss  764: {
1.48      augustss  765:        usbd_xfer_handle xfer;
1.1       augustss  766:
1.138     mrg       767:        KASSERT(pipe->device->bus->lock == NULL || mutex_owned(pipe->device->bus->lock));
                    768:
1.25      augustss  769:        DPRINTFN(2,("usbd_ar_pipe: pipe=%p\n", pipe));
1.28      augustss  770: #ifdef USB_DEBUG
                    771:        if (usbdebug > 5)
                    772:                usbd_dump_queue(pipe);
                    773: #endif
1.47      augustss  774:        pipe->repeat = 0;
1.71      augustss  775:        pipe->aborting = 1;
1.48      augustss  776:        while ((xfer = SIMPLEQ_FIRST(&pipe->queue)) != NULL) {
1.102     augustss  777:                DPRINTFN(2,("usbd_ar_pipe: pipe=%p xfer=%p (methods=%p)\n",
1.48      augustss  778:                            pipe, xfer, pipe->methods));
1.28      augustss  779:                /* Make the HC abort it (and invoke the callback). */
1.48      augustss  780:                pipe->methods->abort(xfer);
1.33      augustss  781:                /* XXX only for non-0 usbd_clear_endpoint_stall(pipe); */
1.20      augustss  782:        }
1.71      augustss  783:        pipe->aborting = 0;
1.1       augustss  784:        return (USBD_NORMAL_COMPLETION);
                    785: }
                    786:
1.138     mrg       787: /* Called with USB lock held. */
1.31      augustss  788: void
1.74      augustss  789: usb_transfer_complete(usbd_xfer_handle xfer)
1.1       augustss  790: {
1.48      augustss  791:        usbd_pipe_handle pipe = xfer->pipe;
                    792:        usb_dma_t *dmap = &xfer->dmabuf;
1.104     mycroft   793:        int sync = xfer->flags & USBD_SYNCHRONOUS;
                    794:        int erred = xfer->status == USBD_CANCELLED ||
                    795:            xfer->status == USBD_TIMEOUT;
1.152     skrll     796:        int polling = pipe->device->bus->use_polling;
                    797:        int repeat;
1.31      augustss  798:
1.48      augustss  799:        DPRINTFN(5, ("usb_transfer_complete: pipe=%p xfer=%p status=%d "
                    800:                     "actlen=%d\n", pipe, xfer, xfer->status, xfer->actlen));
1.134     jmcneill  801:
1.152     skrll     802:        KASSERT(polling || pipe->device->bus->lock == NULL ||
                    803:            mutex_owned(pipe->device->bus->lock));
1.134     jmcneill  804:
1.93      augustss  805: #ifdef DIAGNOSTIC
                    806:        if (xfer->busy_free != XFER_ONQU) {
1.147     skrll     807:                printf("usb_transfer_complete: xfer=%p not queued 0x%08x\n",
1.93      augustss  808:                       xfer, xfer->busy_free);
                    809:        }
                    810: #endif
1.5       augustss  811:
1.23      augustss  812: #ifdef DIAGNOSTIC
1.48      augustss  813:        if (pipe == NULL) {
1.138     mrg       814:                printf("usb_transfer_complete: pipe==0, xfer=%p\n", xfer);
1.31      augustss  815:                return;
                    816:        }
1.23      augustss  817: #endif
1.111     christos  818:        repeat = pipe->repeat;
1.31      augustss  819:        /* XXXX */
                    820:        if (polling)
                    821:                pipe->running = 0;
                    822:
1.48      augustss  823:        if (!(xfer->flags & USBD_NO_COPY) && xfer->actlen != 0 &&
                    824:            usbd_xfer_isread(xfer)) {
1.43      augustss  825: #ifdef DIAGNOSTIC
1.48      augustss  826:                if (xfer->actlen > xfer->length) {
1.145     skrll     827:                        printf("%s: actlen (%d) > len (%d)\n", __func__,
1.48      augustss  828:                               xfer->actlen, xfer->length);
                    829:                        xfer->actlen = xfer->length;
1.43      augustss  830:                }
                    831: #endif
1.100     augustss  832:                memcpy(xfer->buffer, KERNADDR(dmap, 0), xfer->actlen);
1.43      augustss  833:        }
1.38      augustss  834:
1.37      augustss  835:        /* if we allocated the buffer in usbd_transfer() we free it here. */
1.48      augustss  836:        if (xfer->rqflags & URQ_AUTO_DMABUF) {
1.47      augustss  837:                if (!repeat) {
1.37      augustss  838:                        struct usbd_bus *bus = pipe->device->bus;
                    839:                        bus->methods->freem(bus, dmap);
1.48      augustss  840:                        xfer->rqflags &= ~URQ_AUTO_DMABUF;
1.37      augustss  841:                }
                    842:        }
                    843:
1.47      augustss  844:        if (!repeat) {
                    845:                /* Remove request from queue. */
1.152.4.1! rmind     846:
1.145     skrll     847:                KASSERTMSG(!SIMPLEQ_EMPTY(&pipe->queue),
                    848:                    "pipe %p is empty, but xfer %p wants to complete", pipe,
                    849:                     xfer);
1.47      augustss  850: #ifdef DIAGNOSTIC
1.48      augustss  851:                if (xfer != SIMPLEQ_FIRST(&pipe->queue))
1.145     skrll     852:                        printf("%s: bad dequeue %p != %p\n", __func__,
1.48      augustss  853:                               xfer, SIMPLEQ_FIRST(&pipe->queue));
1.93      augustss  854:                xfer->busy_free = XFER_BUSY;
1.45      augustss  855: #endif
1.129     cegger    856:                SIMPLEQ_REMOVE_HEAD(&pipe->queue, next);
1.47      augustss  857:        }
1.102     augustss  858:        DPRINTFN(5,("usb_transfer_complete: repeat=%d new head=%p\n",
1.61      augustss  859:                    repeat, SIMPLEQ_FIRST(&pipe->queue)));
1.31      augustss  860:
                    861:        /* Count completed transfers. */
1.97      christos  862:        ++pipe->device->bus->stats.uds_requests
1.5       augustss  863:                [pipe->endpoint->edesc->bmAttributes & UE_XFERTYPE];
1.1       augustss  864:
1.48      augustss  865:        xfer->done = 1;
1.52      augustss  866:        if (!xfer->status && xfer->actlen < xfer->length &&
1.48      augustss  867:            !(xfer->flags & USBD_SHORT_XFER_OK)) {
1.138     mrg       868:                DPRINTFN(-1,("usb_transfer_complete: short transfer %d<%d\n",
1.48      augustss  869:                             xfer->actlen, xfer->length));
                    870:                xfer->status = USBD_SHORT_XFER;
1.1       augustss  871:        }
1.31      augustss  872:
1.124     jmcneill  873:        if (repeat) {
1.138     mrg       874:                if (xfer->callback) {
1.152     skrll     875:                        if (pipe->device->bus->lock && !polling)
1.138     mrg       876:                                mutex_exit(pipe->device->bus->lock);
1.148     jmcneill  877:
                    878:                        if (!(pipe->flags & USBD_MPSAFE))
                    879:                                KERNEL_LOCK(1, curlwp);
1.124     jmcneill  880:                        xfer->callback(xfer, xfer->priv, xfer->status);
1.148     jmcneill  881:                        if (!(pipe->flags & USBD_MPSAFE))
                    882:                                KERNEL_UNLOCK_ONE(curlwp);
                    883:
1.152     skrll     884:                        if (pipe->device->bus->lock && !polling)
1.138     mrg       885:                                mutex_enter(pipe->device->bus->lock);
                    886:                }
1.124     jmcneill  887:                pipe->methods->done(xfer);
                    888:        } else {
1.61      augustss  889:                pipe->methods->done(xfer);
1.138     mrg       890:                if (xfer->callback) {
1.152     skrll     891:                        if (pipe->device->bus->lock && !polling)
1.138     mrg       892:                                mutex_exit(pipe->device->bus->lock);
1.148     jmcneill  893:
                    894:                        if (!(pipe->flags & USBD_MPSAFE))
                    895:                                KERNEL_LOCK(1, curlwp);
1.124     jmcneill  896:                        xfer->callback(xfer, xfer->priv, xfer->status);
1.148     jmcneill  897:                        if (!(pipe->flags & USBD_MPSAFE))
                    898:                                KERNEL_UNLOCK_ONE(curlwp);
                    899:
1.152     skrll     900:                        if (pipe->device->bus->lock && !polling)
1.138     mrg       901:                                mutex_enter(pipe->device->bus->lock);
                    902:                }
1.124     jmcneill  903:        }
1.31      augustss  904:
1.138     mrg       905:        if (sync && !polling) {
                    906:                if (pipe->device->bus->lock)
                    907:                        cv_broadcast(&xfer->cv);
                    908:                else
                    909:                        wakeup(xfer);   /* XXXSMP ok */
                    910:        }
1.31      augustss  911:
1.47      augustss  912:        if (!repeat) {
1.40      augustss  913:                /* XXX should we stop the queue on all errors? */
1.104     mycroft   914:                if (erred && pipe->iface != NULL)       /* not control pipe */
1.40      augustss  915:                        pipe->running = 0;
                    916:                else
                    917:                        usbd_start_next(pipe);
                    918:        }
1.1       augustss  919: }
                    920:
1.138     mrg       921: /* Called with USB lock held. */
1.31      augustss  922: usbd_status
1.74      augustss  923: usb_insert_transfer(usbd_xfer_handle xfer)
1.1       augustss  924: {
1.48      augustss  925:        usbd_pipe_handle pipe = xfer->pipe;
                    926:        usbd_status err;
1.31      augustss  927:
1.102     augustss  928:        DPRINTFN(5,("usb_insert_transfer: pipe=%p running=%d timeout=%d\n",
1.48      augustss  929:                    pipe, pipe->running, xfer->timeout));
1.134     jmcneill  930:
1.138     mrg       931:        KASSERT(pipe->device->bus->lock == NULL || mutex_owned(pipe->device->bus->lock));
1.134     jmcneill  932:
1.93      augustss  933: #ifdef DIAGNOSTIC
                    934:        if (xfer->busy_free != XFER_BUSY) {
                    935:                printf("usb_insert_transfer: xfer=%p not busy 0x%08x\n",
                    936:                       xfer, xfer->busy_free);
                    937:                return (USBD_INVAL);
                    938:        }
                    939:        xfer->busy_free = XFER_ONQU;
                    940: #endif
1.48      augustss  941:        SIMPLEQ_INSERT_TAIL(&pipe->queue, xfer, next);
1.31      augustss  942:        if (pipe->running)
1.48      augustss  943:                err = USBD_IN_PROGRESS;
1.37      augustss  944:        else {
                    945:                pipe->running = 1;
1.48      augustss  946:                err = USBD_NORMAL_COMPLETION;
1.37      augustss  947:        }
1.48      augustss  948:        return (err);
1.1       augustss  949: }
                    950:
1.138     mrg       951: /* Called with USB lock held. */
1.31      augustss  952: void
1.74      augustss  953: usbd_start_next(usbd_pipe_handle pipe)
1.31      augustss  954: {
1.48      augustss  955:        usbd_xfer_handle xfer;
                    956:        usbd_status err;
1.40      augustss  957:
1.31      augustss  958: #ifdef DIAGNOSTIC
1.48      augustss  959:        if (pipe == NULL) {
1.51      augustss  960:                printf("usbd_start_next: pipe == NULL\n");
1.31      augustss  961:                return;
                    962:        }
1.48      augustss  963:        if (pipe->methods == NULL || pipe->methods->start == NULL) {
1.51      augustss  964:                printf("usbd_start_next: pipe=%p no start method\n", pipe);
1.31      augustss  965:                return;
                    966:        }
                    967: #endif
                    968:
1.138     mrg       969:        KASSERT(pipe->device->bus->lock == NULL || mutex_owned(pipe->device->bus->lock));
                    970:
1.31      augustss  971:        /* Get next request in queue. */
1.48      augustss  972:        xfer = SIMPLEQ_FIRST(&pipe->queue);
1.51      augustss  973:        DPRINTFN(5, ("usbd_start_next: pipe=%p, xfer=%p\n", pipe, xfer));
                    974:        if (xfer == NULL) {
1.31      augustss  975:                pipe->running = 0;
1.51      augustss  976:        } else {
1.138     mrg       977:                if (pipe->device->bus->lock)
                    978:                        mutex_exit(pipe->device->bus->lock);
1.48      augustss  979:                err = pipe->methods->start(xfer);
1.138     mrg       980:                if (pipe->device->bus->lock)
                    981:                        mutex_enter(pipe->device->bus->lock);
1.48      augustss  982:                if (err != USBD_IN_PROGRESS) {
                    983:                        printf("usbd_start_next: error=%d\n", err);
1.31      augustss  984:                        pipe->running = 0;
                    985:                        /* XXX do what? */
                    986:                }
1.1       augustss  987:        }
1.138     mrg       988:
                    989:        KASSERT(pipe->device->bus->lock == NULL || mutex_owned(pipe->device->bus->lock));
1.1       augustss  990: }
                    991:
                    992: usbd_status
1.74      augustss  993: usbd_do_request(usbd_device_handle dev, usb_device_request_t *req, void *data)
1.1       augustss  994: {
1.99      thorpej   995:        return (usbd_do_request_flags(dev, req, data, 0, 0,
1.98      augustss  996:                                      USBD_DEFAULT_TIMEOUT));
1.17      augustss  997: }
                    998:
                    999: usbd_status
1.74      augustss 1000: usbd_do_request_flags(usbd_device_handle dev, usb_device_request_t *req,
1.96      augustss 1001:                      void *data, u_int16_t flags, int *actlen, u_int32_t timo)
1.17      augustss 1002: {
1.102     augustss 1003:        return (usbd_do_request_flags_pipe(dev, dev->default_pipe, req,
1.96      augustss 1004:                                           data, flags, actlen, timo));
1.77      augustss 1005: }
                   1006:
                   1007: usbd_status
                   1008: usbd_do_request_flags_pipe(usbd_device_handle dev, usbd_pipe_handle pipe,
1.96      augustss 1009:        usb_device_request_t *req, void *data, u_int16_t flags, int *actlen,
                   1010:        u_int32_t timeout)
1.77      augustss 1011: {
1.48      augustss 1012:        usbd_xfer_handle xfer;
                   1013:        usbd_status err;
1.1       augustss 1014:
1.7       augustss 1015: #ifdef DIAGNOSTIC
1.136     mrg      1016:        if (cpu_intr_p() || cpu_softintr_p()) {
1.7       augustss 1017:                printf("usbd_do_request: not in process context\n");
1.37      augustss 1018:                return (USBD_INVAL);
1.7       augustss 1019:        }
                   1020: #endif
                   1021:
1.50      augustss 1022:        xfer = usbd_alloc_xfer(dev);
1.48      augustss 1023:        if (xfer == NULL)
1.1       augustss 1024:                return (USBD_NOMEM);
1.96      augustss 1025:        usbd_setup_default_xfer(xfer, dev, 0, timeout, req,
1.77      augustss 1026:                                data, UGETW(req->wLength), flags, 0);
                   1027:        xfer->pipe = pipe;
1.48      augustss 1028:        err = usbd_sync_transfer(xfer);
1.1       augustss 1029: #if defined(USB_DEBUG) || defined(DIAGNOSTIC)
1.112     dogcow   1030:        if (xfer->actlen > xfer->length) {
1.132     matt     1031:                DPRINTF(("%s: overrun addr=%d type=0x%02x req=0x"
1.35      augustss 1032:                         "%02x val=%d index=%d rlen=%d length=%d actlen=%d\n",
1.132     matt     1033:                         __func__, dev->address, xfer->request.bmRequestType,
1.48      augustss 1034:                         xfer->request.bRequest, UGETW(xfer->request.wValue),
1.102     augustss 1035:                         UGETW(xfer->request.wIndex),
                   1036:                         UGETW(xfer->request.wLength),
1.48      augustss 1037:                         xfer->length, xfer->actlen));
1.112     dogcow   1038:        }
1.1       augustss 1039: #endif
1.48      augustss 1040:        if (actlen != NULL)
                   1041:                *actlen = xfer->actlen;
                   1042:        if (err == USBD_STALLED) {
1.102     augustss 1043:                /*
1.15      augustss 1044:                 * The control endpoint has stalled.  Control endpoints
                   1045:                 * should not halt, but some may do so anyway so clear
                   1046:                 * any halt condition.
                   1047:                 */
                   1048:                usb_device_request_t treq;
                   1049:                usb_status_t status;
                   1050:                u_int16_t s;
1.48      augustss 1051:                usbd_status nerr;
1.15      augustss 1052:
                   1053:                treq.bmRequestType = UT_READ_ENDPOINT;
                   1054:                treq.bRequest = UR_GET_STATUS;
                   1055:                USETW(treq.wValue, 0);
                   1056:                USETW(treq.wIndex, 0);
                   1057:                USETW(treq.wLength, sizeof(usb_status_t));
1.50      augustss 1058:                usbd_setup_default_xfer(xfer, dev, 0, USBD_DEFAULT_TIMEOUT,
1.37      augustss 1059:                                           &treq, &status,sizeof(usb_status_t),
1.36      augustss 1060:                                           0, 0);
1.48      augustss 1061:                nerr = usbd_sync_transfer(xfer);
                   1062:                if (nerr)
1.15      augustss 1063:                        goto bad;
                   1064:                s = UGETW(status.wStatus);
                   1065:                DPRINTF(("usbd_do_request: status = 0x%04x\n", s));
                   1066:                if (!(s & UES_HALT))
                   1067:                        goto bad;
                   1068:                treq.bmRequestType = UT_WRITE_ENDPOINT;
                   1069:                treq.bRequest = UR_CLEAR_FEATURE;
                   1070:                USETW(treq.wValue, UF_ENDPOINT_HALT);
                   1071:                USETW(treq.wIndex, 0);
                   1072:                USETW(treq.wLength, 0);
1.50      augustss 1073:                usbd_setup_default_xfer(xfer, dev, 0, USBD_DEFAULT_TIMEOUT,
1.36      augustss 1074:                                           &treq, &status, 0, 0, 0);
1.48      augustss 1075:                nerr = usbd_sync_transfer(xfer);
                   1076:                if (nerr)
1.15      augustss 1077:                        goto bad;
                   1078:        }
                   1079:
                   1080:  bad:
1.132     matt     1081:        if (err) {
                   1082:                DPRINTF(("%s: returning err=%s\n", __func__, usbd_errstr(err)));
                   1083:        }
1.50      augustss 1084:        usbd_free_xfer(xfer);
1.48      augustss 1085:        return (err);
1.7       augustss 1086: }
                   1087:
                   1088: void
1.113     christos 1089: usbd_do_request_async_cb(usbd_xfer_handle xfer,
1.114     christos 1090:     usbd_private_handle priv, usbd_status status)
1.7       augustss 1091: {
                   1092: #if defined(USB_DEBUG) || defined(DIAGNOSTIC)
1.112     dogcow   1093:        if (xfer->actlen > xfer->length) {
1.35      augustss 1094:                DPRINTF(("usbd_do_request: overrun addr=%d type=0x%02x req=0x"
                   1095:                         "%02x val=%d index=%d rlen=%d length=%d actlen=%d\n",
1.102     augustss 1096:                         xfer->pipe->device->address,
1.48      augustss 1097:                         xfer->request.bmRequestType,
                   1098:                         xfer->request.bRequest, UGETW(xfer->request.wValue),
1.102     augustss 1099:                         UGETW(xfer->request.wIndex),
                   1100:                         UGETW(xfer->request.wLength),
1.48      augustss 1101:                         xfer->length, xfer->actlen));
1.112     dogcow   1102:        }
1.7       augustss 1103: #endif
1.50      augustss 1104:        usbd_free_xfer(xfer);
1.7       augustss 1105: }
                   1106:
                   1107: /*
                   1108:  * Execute a request without waiting for completion.
                   1109:  * Can be used from interrupt context.
                   1110:  */
                   1111: usbd_status
1.74      augustss 1112: usbd_do_request_async(usbd_device_handle dev, usb_device_request_t *req,
                   1113:                      void *data)
1.7       augustss 1114: {
1.48      augustss 1115:        usbd_xfer_handle xfer;
                   1116:        usbd_status err;
1.7       augustss 1117:
1.50      augustss 1118:        xfer = usbd_alloc_xfer(dev);
1.49      augustss 1119:        if (xfer == NULL)
1.7       augustss 1120:                return (USBD_NOMEM);
1.50      augustss 1121:        usbd_setup_default_xfer(xfer, dev, 0, USBD_DEFAULT_TIMEOUT, req,
1.48      augustss 1122:            data, UGETW(req->wLength), 0, usbd_do_request_async_cb);
                   1123:        err = usbd_transfer(xfer);
                   1124:        if (err != USBD_IN_PROGRESS) {
1.50      augustss 1125:                usbd_free_xfer(xfer);
1.48      augustss 1126:                return (err);
1.7       augustss 1127:        }
                   1128:        return (USBD_NORMAL_COMPLETION);
1.1       augustss 1129: }
                   1130:
1.78      augustss 1131: const struct usbd_quirks *
1.74      augustss 1132: usbd_get_quirks(usbd_device_handle dev)
1.1       augustss 1133: {
1.81      augustss 1134: #ifdef DIAGNOSTIC
                   1135:        if (dev == NULL) {
                   1136:                printf("usbd_get_quirks: dev == NULL\n");
                   1137:                return 0;
                   1138:        }
                   1139: #endif
1.1       augustss 1140:        return (dev->quirks);
                   1141: }
                   1142:
                   1143: /* XXX do periodic free() of free list */
                   1144:
1.6       augustss 1145: /*
                   1146:  * Called from keyboard driver when in polling mode.
                   1147:  */
                   1148: void
1.74      augustss 1149: usbd_dopoll(usbd_interface_handle iface)
1.6       augustss 1150: {
1.36      augustss 1151:        iface->device->bus->methods->do_poll(iface->device->bus);
1.8       augustss 1152: }
                   1153:
1.138     mrg      1154: /*
                   1155:  * XXX use this more???  use_polling it touched manually all over
                   1156:  */
1.8       augustss 1157: void
1.74      augustss 1158: usbd_set_polling(usbd_device_handle dev, int on)
1.8       augustss 1159: {
1.42      augustss 1160:        if (on)
1.54      augustss 1161:                dev->bus->use_polling++;
1.42      augustss 1162:        else
1.54      augustss 1163:                dev->bus->use_polling--;
1.133     jmcneill 1164:
                   1165:        /* Kick the host controller when switching modes */
1.138     mrg      1166:        if (dev->bus->lock)
                   1167:                mutex_enter(dev->bus->lock);
                   1168:        (*dev->bus->methods->soft_intr)(dev->bus);
                   1169:        if (dev->bus->lock)
                   1170:                mutex_exit(dev->bus->lock);
                   1171:
1.6       augustss 1172: }
1.12      augustss 1173:
                   1174:
                   1175: usb_endpoint_descriptor_t *
1.74      augustss 1176: usbd_get_endpoint_descriptor(usbd_interface_handle iface, u_int8_t address)
1.12      augustss 1177: {
                   1178:        struct usbd_endpoint *ep;
                   1179:        int i;
                   1180:
                   1181:        for (i = 0; i < iface->idesc->bNumEndpoints; i++) {
                   1182:                ep = &iface->endpoints[i];
                   1183:                if (ep->edesc->bEndpointAddress == address)
                   1184:                        return (iface->endpoints[i].edesc);
                   1185:        }
1.152.4.1! rmind    1186:        return (NULL);
1.63      augustss 1187: }
                   1188:
                   1189: /*
                   1190:  * usbd_ratecheck() can limit the number of error messages that occurs.
                   1191:  * When a device is unplugged it may take up to 0.25s for the hub driver
                   1192:  * to notice it.  If the driver continuosly tries to do I/O operations
                   1193:  * this can generate a large number of messages.
                   1194:  */
                   1195: int
1.74      augustss 1196: usbd_ratecheck(struct timeval *last)
1.63      augustss 1197: {
1.64      augustss 1198:        static struct timeval errinterval = { 0, 250000 }; /* 0.25 s*/
1.63      augustss 1199:
                   1200:        return (ratecheck(last, &errinterval));
1.89      augustss 1201: }
                   1202:
                   1203: /*
                   1204:  * Search for a vendor/product pair in an array.  The item size is
                   1205:  * given as an argument.
                   1206:  */
1.90      augustss 1207: const struct usb_devno *
                   1208: usb_match_device(const struct usb_devno *tbl, u_int nentries, u_int sz,
1.89      augustss 1209:                 u_int16_t vendor, u_int16_t product)
                   1210: {
                   1211:        while (nentries-- > 0) {
1.93      augustss 1212:                u_int16_t tproduct = tbl->ud_product;
                   1213:                if (tbl->ud_vendor == vendor &&
                   1214:                    (tproduct == product || tproduct == USB_PRODUCT_ANY))
1.89      augustss 1215:                        return (tbl);
1.95      augustss 1216:                tbl = (const struct usb_devno *)((const char *)tbl + sz);
1.89      augustss 1217:        }
                   1218:        return (NULL);
1.12      augustss 1219: }
                   1220:
1.105     augustss 1221:
                   1222: void
                   1223: usb_desc_iter_init(usbd_device_handle dev, usbd_desc_iter_t *iter)
                   1224: {
                   1225:        const usb_config_descriptor_t *cd = usbd_get_config_descriptor(dev);
                   1226:
1.108     christos 1227:         iter->cur = (const uByte *)cd;
                   1228:         iter->end = (const uByte *)cd + UGETW(cd->wTotalLength);
1.105     augustss 1229: }
                   1230:
                   1231: const usb_descriptor_t *
                   1232: usb_desc_iter_next(usbd_desc_iter_t *iter)
                   1233: {
                   1234:        const usb_descriptor_t *desc;
                   1235:
                   1236:        if (iter->cur + sizeof(usb_descriptor_t) >= iter->end) {
                   1237:                if (iter->cur != iter->end)
                   1238:                        printf("usb_desc_iter_next: bad descriptor\n");
                   1239:                return NULL;
                   1240:        }
1.108     christos 1241:        desc = (const usb_descriptor_t *)iter->cur;
1.105     augustss 1242:        if (desc->bLength == 0) {
                   1243:                printf("usb_desc_iter_next: descriptor length = 0\n");
                   1244:                return NULL;
                   1245:        }
                   1246:        iter->cur += desc->bLength;
                   1247:        if (iter->cur > iter->end) {
                   1248:                printf("usb_desc_iter_next: descriptor length too large\n");
                   1249:                return NULL;
                   1250:        }
                   1251:        return desc;
                   1252: }
                   1253:
                   1254: usbd_status
                   1255: usbd_get_string(usbd_device_handle dev, int si, char *buf)
                   1256: {
1.115     pavel    1257:        return usbd_get_string0(dev, si, buf, 1);
                   1258: }
                   1259:
                   1260: usbd_status
                   1261: usbd_get_string0(usbd_device_handle dev, int si, char *buf, int unicode)
                   1262: {
1.105     augustss 1263:        int swap = dev->quirks->uq_flags & UQ_SWAP_UNICODE;
                   1264:        usb_string_descriptor_t us;
                   1265:        char *s;
1.116     macallan 1266:        int i, n;
1.105     augustss 1267:        u_int16_t c;
                   1268:        usbd_status err;
                   1269:        int size;
                   1270:
                   1271:        buf[0] = '\0';
                   1272:        if (si == 0)
                   1273:                return (USBD_INVAL);
                   1274:        if (dev->quirks->uq_flags & UQ_NO_STRINGS)
                   1275:                return (USBD_STALLED);
                   1276:        if (dev->langid == USBD_NOLANG) {
                   1277:                /* Set up default language */
                   1278:                err = usbd_get_string_desc(dev, USB_LANGUAGE_TABLE, 0, &us,
                   1279:                    &size);
                   1280:                if (err || size < 4) {
1.106     augustss 1281:                        DPRINTFN(-1,("usbd_get_string: getting lang failed, using 0\n"));
1.105     augustss 1282:                        dev->langid = 0; /* Well, just pick something then */
                   1283:                } else {
                   1284:                        /* Pick the first language as the default. */
                   1285:                        dev->langid = UGETW(us.bString[0]);
                   1286:                }
                   1287:        }
                   1288:        err = usbd_get_string_desc(dev, si, dev->langid, &us, &size);
                   1289:        if (err)
                   1290:                return (err);
                   1291:        s = buf;
                   1292:        n = size / 2 - 1;
1.115     pavel    1293:        if (unicode) {
                   1294:                for (i = 0; i < n; i++) {
                   1295:                        c = UGETW(us.bString[i]);
                   1296:                        if (swap)
                   1297:                                c = (c >> 8) | (c << 8);
1.119     drochner 1298:                        s += wput_utf8(s, 3, c);
1.115     pavel    1299:                }
                   1300:                *s++ = 0;
                   1301:        }
                   1302: #ifdef COMPAT_30
                   1303:        else {
1.119     drochner 1304:                for (i = 0; i < n; i++) {
1.115     pavel    1305:                        c = UGETW(us.bString[i]);
                   1306:                        if (swap)
                   1307:                                c = (c >> 8) | (c << 8);
1.119     drochner 1308:                        *s++ = (c < 0x80) ? c : '?';
1.107     augustss 1309:                }
1.119     drochner 1310:                *s++ = 0;
1.105     augustss 1311:        }
1.115     pavel    1312: #endif
1.105     augustss 1313:        return (USBD_NORMAL_COMPLETION);
                   1314: }

CVSweb <webmaster@jp.NetBSD.org>