[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.62

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

CVSweb <webmaster@jp.NetBSD.org>