[BACK]Return to ubt.c CVS log [TXT][DIR] Up to [local] / sys / dev / usb

Annotation of sys/dev/usb/ubt.c, Revision 1.1.1.1

1.1       nbrk        1: /* $OpenBSD: ubt.c,v 1.8 2007/06/14 10:11:15 mbalmer Exp $ */
                      2:
                      3: /*-
                      4:  * Copyright (c) 2006 Itronix Inc.
                      5:  * All rights reserved.
                      6:  *
                      7:  * Written by Iain Hibbert for Itronix Inc.
                      8:  *
                      9:  * Redistribution and use in source and binary forms, with or without
                     10:  * modification, are permitted provided that the following conditions
                     11:  * are met:
                     12:  * 1. Redistributions of source code must retain the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer.
                     14:  * 2. Redistributions in binary form must reproduce the above copyright
                     15:  *    notice, this list of conditions and the following disclaimer in the
                     16:  *    documentation and/or other materials provided with the distribution.
                     17:  * 3. The name of Itronix Inc. may not be used to endorse
                     18:  *    or promote products derived from this software without specific
                     19:  *    prior written permission.
                     20:  *
                     21:  * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND
                     22:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     23:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     24:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
                     25:  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
                     26:  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
                     27:  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
                     28:  * ON ANY THEORY OF LIABILITY, WHETHER IN
                     29:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     30:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     31:  * POSSIBILITY OF SUCH DAMAGE.
                     32:  */
                     33: /*
                     34:  * Copyright (c) 2002, 2003 The NetBSD Foundation, Inc.
                     35:  * All rights reserved.
                     36:  *
                     37:  * This code is derived from software contributed to The NetBSD Foundation
                     38:  * by Lennart Augustsson (lennart@augustsson.net) and
                     39:  * David Sainty (David.Sainty@dtsp.co.nz).
                     40:  *
                     41:  * Redistribution and use in source and binary forms, with or without
                     42:  * modification, are permitted provided that the following conditions
                     43:  * are met:
                     44:  * 1. Redistributions of source code must retain the above copyright
                     45:  *    notice, this list of conditions and the following disclaimer.
                     46:  * 2. Redistributions in binary form must reproduce the above copyright
                     47:  *    notice, this list of conditions and the following disclaimer in the
                     48:  *    documentation and/or other materials provided with the distribution.
                     49:  * 3. All advertising materials mentioning features or use of this software
                     50:  *    must display the following acknowledgement:
                     51:  *        This product includes software developed by the NetBSD
                     52:  *        Foundation, Inc. and its contributors.
                     53:  * 4. Neither the name of The NetBSD Foundation nor the names of its
                     54:  *    contributors may be used to endorse or promote products derived
                     55:  *    from this software without specific prior written permission.
                     56:  *
                     57:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     58:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     59:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     60:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     61:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     62:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     63:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     64:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     65:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     66:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     67:  * POSSIBILITY OF SUCH DAMAGE.
                     68:  */
                     69: /*
                     70:  * This driver originally written by Lennart Augustsson and David Sainty,
                     71:  * but was mostly rewritten for the NetBSD Bluetooth protocol stack by
                     72:  * Iain Hibbert for Itronix, Inc using the FreeBSD ng_ubt.c driver as a
                     73:  * reference.
                     74:  */
                     75:
                     76: #include <sys/cdefs.h>
                     77:
                     78: #include <sys/param.h>
                     79: #include <sys/device.h>
                     80: #include <sys/ioctl.h>
                     81: #include <sys/kernel.h>
                     82: #include <sys/malloc.h>
                     83: #include <sys/mbuf.h>
                     84: #include <sys/proc.h>
                     85: #include <sys/sysctl.h>
                     86: #include <sys/systm.h>
                     87:
                     88: #include <dev/usb/usb.h>
                     89: #include <dev/usb/usbdi.h>
                     90: #include <dev/usb/usbdi_util.h>
                     91: #include <dev/usb/usbdevs.h>
                     92:
                     93: #include <netbt/bluetooth.h>
                     94: #include <netbt/hci.h>
                     95:
                     96: /*******************************************************************************
                     97:  *
                     98:  *     debugging stuff
                     99:  */
                    100: #undef DPRINTF
                    101: #undef DPRINTFN
                    102:
                    103: #ifdef UBT_DEBUG
                    104: int    ubt_debug = UBT_DEBUG;
                    105:
                    106: #define DPRINTF(fmt, args...)          do {            \
                    107:        if (ubt_debug)                                  \
                    108:                printf("%s: "fmt, __func__ , ##args);   \
                    109: } while (/* CONSTCOND */0)
                    110:
                    111: #define DPRINTFN(n, fmt, args...)      do {            \
                    112:        if (ubt_debug > (n))                            \
                    113:                printf("%s: "fmt, __func__ , ##args);   \
                    114: } while (/* CONSTCOND */0)
                    115:
                    116: #else
                    117: #define DPRINTF(...)
                    118: #define DPRINTFN(...)
                    119: #endif
                    120:
                    121: /*******************************************************************************
                    122:  *
                    123:  *     ubt softc structure
                    124:  *
                    125:  */
                    126:
                    127: /* buffer sizes */
                    128: /*
                    129:  * NB: although ACL packets can extend to 65535 bytes, most devices
                    130:  * have max_acl_size at much less (largest I have seen is 384)
                    131:  */
                    132: #define UBT_BUFSIZ_CMD         (HCI_CMD_PKT_SIZE - 1)
                    133: #define UBT_BUFSIZ_ACL         (2048 - 1)
                    134: #define UBT_BUFSIZ_EVENT       (HCI_EVENT_PKT_SIZE - 1)
                    135:
                    136: /* Transmit timeouts */
                    137: #define UBT_CMD_TIMEOUT                USBD_DEFAULT_TIMEOUT
                    138: #define UBT_ACL_TIMEOUT                USBD_DEFAULT_TIMEOUT
                    139:
                    140: /*
                    141:  * ISOC transfers
                    142:  *
                    143:  * xfer buffer size depends on the frame size, and the number
                    144:  * of frames per transfer is fixed, as each frame should be
                    145:  * 1ms worth of data. This keeps the rate that xfers complete
                    146:  * fairly constant. We use multiple xfers to keep the hardware
                    147:  * busy
                    148:  */
                    149: #define UBT_NXFERS             3       /* max xfers to queue */
                    150: #define UBT_NFRAMES            10      /* frames per xfer */
                    151:
                    152: struct ubt_isoc_xfer {
                    153:        struct ubt_softc        *softc;
                    154:        usbd_xfer_handle         xfer;
                    155:        uint8_t                 *buf;
                    156:        uint16_t                 size[UBT_NFRAMES];
                    157:        int                      busy;
                    158: };
                    159:
                    160: struct ubt_softc {
                    161:        struct device            sc_dev;
                    162:        usbd_device_handle       sc_udev;
                    163:        int                      sc_refcnt;
                    164:        int                      sc_dying;
                    165:
                    166:        /* Control Interface */
                    167:        usbd_interface_handle    sc_iface0;
                    168:
                    169:        /* Commands (control) */
                    170:        usbd_xfer_handle         sc_cmd_xfer;
                    171:        uint8_t                 *sc_cmd_buf;
                    172:
                    173:        /* Events (interrupt) */
                    174:        int                      sc_evt_addr;   /* endpoint address */
                    175:        usbd_pipe_handle         sc_evt_pipe;
                    176:        uint8_t                 *sc_evt_buf;
                    177:
                    178:        /* ACL data (in) */
                    179:        int                      sc_aclrd_addr; /* endpoint address */
                    180:        usbd_pipe_handle         sc_aclrd_pipe; /* read pipe */
                    181:        usbd_xfer_handle         sc_aclrd_xfer; /* read xfer */
                    182:        uint8_t                 *sc_aclrd_buf;  /* read buffer */
                    183:        int                      sc_aclrd_busy; /* reading */
                    184:
                    185:        /* ACL data (out) */
                    186:        int                      sc_aclwr_addr; /* endpoint address */
                    187:        usbd_pipe_handle         sc_aclwr_pipe; /* write pipe */
                    188:        usbd_xfer_handle         sc_aclwr_xfer; /* write xfer */
                    189:        uint8_t                 *sc_aclwr_buf;  /* write buffer */
                    190:
                    191:        /* ISOC interface */
                    192:        usbd_interface_handle    sc_iface1;     /* ISOC interface */
                    193:        struct sysctllog        *sc_log;        /* sysctl log */
                    194:        int                      sc_config;     /* current config no */
                    195:        int                      sc_alt_config; /* no of alternates */
                    196:
                    197:        /* SCO data (in) */
                    198:        int                      sc_scord_addr; /* endpoint address */
                    199:        usbd_pipe_handle         sc_scord_pipe; /* read pipe */
                    200:        int                      sc_scord_size; /* frame length */
                    201:        struct ubt_isoc_xfer     sc_scord[UBT_NXFERS];
                    202:        struct mbuf             *sc_scord_mbuf; /* current packet */
                    203:
                    204:        /* SCO data (out) */
                    205:        int                      sc_scowr_addr; /* endpoint address */
                    206:        usbd_pipe_handle         sc_scowr_pipe; /* write pipe */
                    207:        int                      sc_scowr_size; /* frame length */
                    208:        struct ubt_isoc_xfer     sc_scowr[UBT_NXFERS];
                    209:        struct mbuf             *sc_scowr_mbuf; /* current packet */
                    210:
                    211:        /* Protocol structure */
                    212:        struct hci_unit          sc_unit;
                    213:
                    214:        /* Successfully attached */
                    215:        int                      sc_ok;
                    216: };
                    217:
                    218: /*
                    219:  * Bluetooth unit/USB callback routines
                    220:  */
                    221: int ubt_enable(struct hci_unit *);
                    222: void ubt_disable(struct hci_unit *);
                    223:
                    224: void ubt_xmit_cmd_start(struct hci_unit *);
                    225: void ubt_xmit_cmd_complete(usbd_xfer_handle,
                    226:                                usbd_private_handle, usbd_status);
                    227:
                    228: void ubt_xmit_acl_start(struct hci_unit *);
                    229: void ubt_xmit_acl_complete(usbd_xfer_handle,
                    230:                                usbd_private_handle, usbd_status);
                    231:
                    232: void ubt_xmit_sco_start(struct hci_unit *);
                    233: void ubt_xmit_sco_start1(struct ubt_softc *, struct ubt_isoc_xfer *);
                    234: void ubt_xmit_sco_complete(usbd_xfer_handle,
                    235:                                usbd_private_handle, usbd_status);
                    236:
                    237: void ubt_recv_event(usbd_xfer_handle,
                    238:                                usbd_private_handle, usbd_status);
                    239:
                    240: void ubt_recv_acl_start(struct ubt_softc *);
                    241: void ubt_recv_acl_complete(usbd_xfer_handle,
                    242:                                usbd_private_handle, usbd_status);
                    243:
                    244: void ubt_recv_sco_start1(struct ubt_softc *, struct ubt_isoc_xfer *);
                    245: void ubt_recv_sco_complete(usbd_xfer_handle,
                    246:                                usbd_private_handle, usbd_status);
                    247:
                    248: int ubt_match(struct device *, void *, void *);
                    249: void ubt_attach(struct device *, struct device *, void *);
                    250: int ubt_detach(struct device *, int);
                    251: int ubt_activate(struct device *, enum devact);
                    252:
                    253: struct cfdriver ubt_cd = {
                    254:        NULL, "ubt", DV_DULL
                    255: };
                    256:
                    257: const struct cfattach ubt_ca = {
                    258:        sizeof(struct ubt_softc),
                    259:        ubt_match,
                    260:        ubt_attach,
                    261:        ubt_detach,
                    262:        ubt_activate,
                    263: };
                    264:
                    265: static int ubt_set_isoc_config(struct ubt_softc *);
                    266: static void ubt_abortdealloc(struct ubt_softc *);
                    267:
                    268: /*
                    269:  * Match against the whole device, since we want to take
                    270:  * both interfaces. If a device should be ignored then add
                    271:  *
                    272:  *     { VendorID, ProductID }
                    273:  *
                    274:  * to the ubt_ignore list.
                    275:  */
                    276: static const struct usb_devno ubt_ignore[] = {
                    277:        { USB_VENDOR_BROADCOM, USB_PRODUCT_BROADCOM_BCM2033 },
                    278:        { USB_VENDOR_BROADCOM, USB_PRODUCT_BROADCOM_BCM2033NF },
                    279:        { 0, 0 }        /* end of list */
                    280: };
                    281:
                    282: int
                    283: ubt_match(struct device *parent, void *match, void *aux)
                    284: {
                    285:
                    286:        struct usb_attach_arg *uaa = aux;
                    287:        usb_device_descriptor_t *dd = usbd_get_device_descriptor(uaa->device);
                    288:
                    289:        DPRINTFN(50, "ubt_match\n");
                    290:
                    291:        if (usb_lookup(ubt_ignore, uaa->vendor, uaa->product))
                    292:                return UMATCH_NONE;
                    293:
                    294:        if (dd->bDeviceClass == UDCLASS_WIRELESS
                    295:            && dd->bDeviceSubClass == UDSUBCLASS_RF
                    296:            && dd->bDeviceProtocol == UDPROTO_BLUETOOTH)
                    297:                return UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO;
                    298:
                    299:        return UMATCH_NONE;
                    300: }
                    301:
                    302:
                    303: void
                    304: ubt_attach(struct device *parent, struct device *self, void *aux)
                    305: {
                    306:        struct ubt_softc *sc = (struct ubt_softc *)self;
                    307:        struct usb_attach_arg *uaa = aux;
                    308:        usb_config_descriptor_t *cd;
                    309:        usb_endpoint_descriptor_t *ed;
                    310:        char *devinfop;
                    311:        int err;
                    312:        uint8_t count, i;
                    313:
                    314:        DPRINTFN(50, "ubt_attach: sc=%p\n", sc);
                    315:
                    316:        sc->sc_udev = uaa->device;
                    317:
                    318:        devinfop = usbd_devinfo_alloc(sc->sc_udev, 0);
                    319:        printf("\n%s: %s\n", sc->sc_dev.dv_xname, devinfop);
                    320:        usbd_devinfo_free(devinfop);
                    321:
                    322:        /*
                    323:         * Move the device into the configured state
                    324:         */
                    325:        err = usbd_set_config_index(sc->sc_udev, 0, 1);
                    326:        if (err) {
                    327:                printf("%s: failed to set configuration idx 0: %s\n",
                    328:                    sc->sc_dev.dv_xname, usbd_errstr(err));
                    329:
                    330:                return;
                    331:        }
                    332:
                    333:        /*
                    334:         * Interface 0 must have 3 endpoints
                    335:         *      1) Interrupt endpoint to receive HCI events
                    336:         *      2) Bulk IN endpoint to receive ACL data
                    337:         *      3) Bulk OUT endpoint to send ACL data
                    338:         */
                    339:        err = usbd_device2interface_handle(sc->sc_udev, 0, &sc->sc_iface0);
                    340:        if (err) {
                    341:                printf("%s: Could not get interface 0 handle %s (%d)\n",
                    342:                                sc->sc_dev.dv_xname, usbd_errstr(err), err);
                    343:
                    344:                return;
                    345:        }
                    346:
                    347:        sc->sc_evt_addr = -1;
                    348:        sc->sc_aclrd_addr = -1;
                    349:        sc->sc_aclwr_addr = -1;
                    350:
                    351:        count = 0;
                    352:        (void)usbd_endpoint_count(sc->sc_iface0, &count);
                    353:
                    354:        for (i = 0 ; i < count ; i++) {
                    355:                int dir, type;
                    356:
                    357:                ed = usbd_interface2endpoint_descriptor(sc->sc_iface0, i);
                    358:                if (ed == NULL) {
                    359:                        printf("%s: could not read endpoint descriptor %d\n",
                    360:                            sc->sc_dev.dv_xname, i);
                    361:
                    362:                        return;
                    363:                }
                    364:
                    365:                dir = UE_GET_DIR(ed->bEndpointAddress);
                    366:                type = UE_GET_XFERTYPE(ed->bmAttributes);
                    367:
                    368:                if (dir == UE_DIR_IN && type == UE_INTERRUPT)
                    369:                        sc->sc_evt_addr = ed->bEndpointAddress;
                    370:                else if (dir == UE_DIR_IN && type == UE_BULK)
                    371:                        sc->sc_aclrd_addr = ed->bEndpointAddress;
                    372:                else if (dir == UE_DIR_OUT && type == UE_BULK)
                    373:                        sc->sc_aclwr_addr = ed->bEndpointAddress;
                    374:        }
                    375:
                    376:        if (sc->sc_evt_addr == -1) {
                    377:                printf("%s: missing INTERRUPT endpoint on interface 0\n",
                    378:                                sc->sc_dev.dv_xname);
                    379:
                    380:                return;
                    381:        }
                    382:        if (sc->sc_aclrd_addr == -1) {
                    383:                printf("%s: missing BULK IN endpoint on interface 0\n",
                    384:                                sc->sc_dev.dv_xname);
                    385:
                    386:                return;
                    387:        }
                    388:        if (sc->sc_aclwr_addr == -1) {
                    389:                printf("%s: missing BULK OUT endpoint on interface 0\n",
                    390:                                sc->sc_dev.dv_xname);
                    391:
                    392:                return;
                    393:        }
                    394:
                    395:        /*
                    396:         * Interface 1 must have 2 endpoints
                    397:         *      1) Isochronous IN endpoint to receive SCO data
                    398:         *      2) Isochronous OUT endpoint to send SCO data
                    399:         *
                    400:         * and will have several configurations, which can be selected
                    401:         * via a sysctl variable. We select config 0 to start, which
                    402:         * means that no SCO data will be available.
                    403:         */
                    404:        err = usbd_device2interface_handle(sc->sc_udev, 1, &sc->sc_iface1);
                    405:        if (err) {
                    406:                printf("%s: Could not get interface 1 handle %s (%d)\n",
                    407:                                sc->sc_dev.dv_xname, usbd_errstr(err), err);
                    408:
                    409:                return;
                    410:        }
                    411:
                    412:        cd = usbd_get_config_descriptor(sc->sc_udev);
                    413:        if (cd == NULL) {
                    414:                printf("%s: could not get config descriptor\n",
                    415:                        sc->sc_dev.dv_xname);
                    416:
                    417:                return;
                    418:        }
                    419:
                    420:        sc->sc_alt_config = usbd_get_no_alts(cd, 1);
                    421:
                    422:        /* set initial config */
                    423:        err = ubt_set_isoc_config(sc);
                    424:        if (err) {
                    425:                printf("%s: ISOC config failed\n",
                    426:                        sc->sc_dev.dv_xname);
                    427:
                    428:                return;
                    429:        }
                    430:
                    431:        /* Attach HCI */
                    432:        sc->sc_unit.hci_softc = self;
                    433:        sc->sc_unit.hci_devname = sc->sc_dev.dv_xname;
                    434:        sc->sc_unit.hci_enable = ubt_enable;
                    435:        sc->sc_unit.hci_disable = ubt_disable;
                    436:        sc->sc_unit.hci_start_cmd = ubt_xmit_cmd_start;
                    437:        sc->sc_unit.hci_start_acl = ubt_xmit_acl_start;
                    438:        sc->sc_unit.hci_start_sco = ubt_xmit_sco_start;
                    439:        sc->sc_unit.hci_ipl = IPL_USB; /* XXX: IPL_SOFTUSB ?? */
                    440:        hci_attach(&sc->sc_unit);
                    441:
                    442:        usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
                    443:                           &sc->sc_dev);
                    444:
                    445:        sc->sc_ok = 1;
                    446:
                    447:        return;
                    448: }
                    449:
                    450: int
                    451: ubt_detach(struct device *self, int flags)
                    452: {
                    453:        struct ubt_softc *sc = (struct ubt_softc *)self;
                    454:        int s;
                    455:
                    456:        DPRINTF("sc=%p flags=%d\n", sc, flags);
                    457:
                    458:        sc->sc_dying = 1;
                    459:
                    460:        if (!sc->sc_ok)
                    461:                return 0;
                    462:
                    463:        /* Detach HCI interface */
                    464:        hci_detach(&sc->sc_unit);
                    465:
                    466:        /*
                    467:         * Abort all pipes. Causes processes waiting for transfer to wake.
                    468:         *
                    469:         * Actually, hci_detach() above will call ubt_disable() which may
                    470:         * call ubt_abortdealloc(), but lets be sure since doing it twice
                    471:         * wont cause an error.
                    472:         */
                    473:        ubt_abortdealloc(sc);
                    474:
                    475:        /* wait for all processes to finish */
                    476:        s = splusb();
                    477:        if (sc->sc_refcnt-- > 0)
                    478:                usb_detach_wait(&sc->sc_dev);
                    479:
                    480:        splx(s);
                    481:
                    482:        usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
                    483:                           &sc->sc_dev);
                    484:
                    485:        DPRINTFN(1, "driver detached\n");
                    486:
                    487:        return 0;
                    488: }
                    489:
                    490: int
                    491: ubt_activate(struct device *self, enum devact act)
                    492: {
                    493:        struct ubt_softc *sc = (struct ubt_softc *)self;
                    494:        int error = 0;
                    495:
                    496:        DPRINTFN(1, "ubt_activate: sc=%p, act=%d\n", sc, act);
                    497:
                    498:        switch (act) {
                    499:        case DVACT_ACTIVATE:
                    500:                return EOPNOTSUPP;
                    501:                break;
                    502:
                    503:        case DVACT_DEACTIVATE:
                    504:                sc->sc_dying = 1;
                    505:                break;
                    506:        }
                    507:        return error;
                    508: }
                    509:
                    510: /* set ISOC configuration */
                    511: int
                    512: ubt_set_isoc_config(struct ubt_softc *sc)
                    513: {
                    514:        usb_endpoint_descriptor_t *ed;
                    515:        int rd_addr, wr_addr, rd_size, wr_size;
                    516:        uint8_t count, i;
                    517:        int err;
                    518:
                    519:        err = usbd_set_interface(sc->sc_iface1, sc->sc_config);
                    520:        if (err != USBD_NORMAL_COMPLETION) {
                    521:                printf(
                    522:                    "%s: Could not set config %d on ISOC interface. %s (%d)\n",
                    523:                    sc->sc_dev.dv_xname, sc->sc_config, usbd_errstr(err), err);
                    524:
                    525:                return err == USBD_IN_USE ? EBUSY : EIO;
                    526:        }
                    527:
                    528:        /*
                    529:         * We wont get past the above if there are any pipes open, so no
                    530:         * need to worry about buf/xfer/pipe deallocation. If we get an
                    531:         * error after this, the frame quantities will be 0 and no SCO
                    532:         * data will be possible.
                    533:         */
                    534:
                    535:        sc->sc_scord_size = rd_size = 0;
                    536:        sc->sc_scord_addr = rd_addr = -1;
                    537:
                    538:        sc->sc_scowr_size = wr_size = 0;
                    539:        sc->sc_scowr_addr = wr_addr = -1;
                    540:
                    541:        count = 0;
                    542:        (void)usbd_endpoint_count(sc->sc_iface1, &count);
                    543:
                    544:        for (i = 0 ; i < count ; i++) {
                    545:                ed = usbd_interface2endpoint_descriptor(sc->sc_iface1, i);
                    546:                if (ed == NULL) {
                    547:                        printf("%s: could not read endpoint descriptor %d\n",
                    548:                            sc->sc_dev.dv_xname, i);
                    549:
                    550:                        return EIO;
                    551:                }
                    552:
                    553:                DPRINTFN(5, "%s: endpoint type %02x (%02x) addr %02x (%s)\n",
                    554:                        sc->sc_dev.dv_xname,
                    555:                        UE_GET_XFERTYPE(ed->bmAttributes),
                    556:                        UE_GET_ISO_TYPE(ed->bmAttributes),
                    557:                        ed->bEndpointAddress,
                    558:                        UE_GET_DIR(ed->bEndpointAddress) ? "in" : "out");
                    559:
                    560:                if (UE_GET_XFERTYPE(ed->bmAttributes) != UE_ISOCHRONOUS)
                    561:                        continue;
                    562:
                    563:                if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN) {
                    564:                        rd_addr = ed->bEndpointAddress;
                    565:                        rd_size = UGETW(ed->wMaxPacketSize);
                    566:                } else {
                    567:                        wr_addr = ed->bEndpointAddress;
                    568:                        wr_size = UGETW(ed->wMaxPacketSize);
                    569:                }
                    570:        }
                    571:
                    572:        if (rd_addr == -1) {
                    573:                printf(
                    574:                    "%s: missing ISOC IN endpoint on interface config %d\n",
                    575:                    sc->sc_dev.dv_xname, sc->sc_config);
                    576:
                    577:                return ENOENT;
                    578:        }
                    579:        if (wr_addr == -1) {
                    580:                printf(
                    581:                    "%s: missing ISOC OUT endpoint on interface config %d\n",
                    582:                    sc->sc_dev.dv_xname, sc->sc_config);
                    583:
                    584:                return ENOENT;
                    585:        }
                    586:
                    587: #ifdef DIAGNOSTIC
                    588:        if (rd_size > MLEN) {
                    589:                printf("%s: rd_size=%d exceeds MLEN\n",
                    590:                    sc->sc_dev.dv_xname, rd_size);
                    591:
                    592:                return EOVERFLOW;
                    593:        }
                    594:
                    595:        if (wr_size > MLEN) {
                    596:                printf("%s: wr_size=%d exceeds MLEN\n",
                    597:                    sc->sc_dev.dv_xname, wr_size);
                    598:
                    599:                return EOVERFLOW;
                    600:        }
                    601: #endif
                    602:
                    603:        sc->sc_scord_size = rd_size;
                    604:        sc->sc_scord_addr = rd_addr;
                    605:
                    606:        sc->sc_scowr_size = wr_size;
                    607:        sc->sc_scowr_addr = wr_addr;
                    608:
                    609:        return 0;
                    610: }
                    611:
                    612: void
                    613: ubt_abortdealloc(struct ubt_softc *sc)
                    614: {
                    615:        int i;
                    616:
                    617:        DPRINTFN(1, "sc=%p\n", sc);
                    618:
                    619:        /* Abort all pipes */
                    620:        if (sc->sc_evt_pipe != NULL) {
                    621:                usbd_abort_pipe(sc->sc_evt_pipe);
                    622:                usbd_close_pipe(sc->sc_evt_pipe);
                    623:                sc->sc_evt_pipe = NULL;
                    624:        }
                    625:
                    626:        if (sc->sc_aclrd_pipe != NULL) {
                    627:                usbd_abort_pipe(sc->sc_aclrd_pipe);
                    628:                usbd_close_pipe(sc->sc_aclrd_pipe);
                    629:                sc->sc_aclrd_pipe = NULL;
                    630:        }
                    631:
                    632:        if (sc->sc_aclwr_pipe != NULL) {
                    633:                usbd_abort_pipe(sc->sc_aclwr_pipe);
                    634:                usbd_close_pipe(sc->sc_aclwr_pipe);
                    635:                sc->sc_aclwr_pipe = NULL;
                    636:        }
                    637:
                    638:        if (sc->sc_scord_pipe != NULL) {
                    639:                usbd_abort_pipe(sc->sc_scord_pipe);
                    640:                usbd_close_pipe(sc->sc_scord_pipe);
                    641:                sc->sc_scord_pipe = NULL;
                    642:        }
                    643:
                    644:        if (sc->sc_scowr_pipe != NULL) {
                    645:                usbd_abort_pipe(sc->sc_scowr_pipe);
                    646:                usbd_close_pipe(sc->sc_scowr_pipe);
                    647:                sc->sc_scowr_pipe = NULL;
                    648:        }
                    649:
                    650:        /* Free event buffer */
                    651:        if (sc->sc_evt_buf != NULL) {
                    652:                free(sc->sc_evt_buf, M_USBDEV);
                    653:                sc->sc_evt_buf = NULL;
                    654:        }
                    655:
                    656:        /* Free all xfers and xfer buffers (implicit) */
                    657:        if (sc->sc_cmd_xfer != NULL) {
                    658:                usbd_free_xfer(sc->sc_cmd_xfer);
                    659:                sc->sc_cmd_xfer = NULL;
                    660:                sc->sc_cmd_buf = NULL;
                    661:        }
                    662:
                    663:        if (sc->sc_aclrd_xfer != NULL) {
                    664:                usbd_free_xfer(sc->sc_aclrd_xfer);
                    665:                sc->sc_aclrd_xfer = NULL;
                    666:                sc->sc_aclrd_buf = NULL;
                    667:        }
                    668:
                    669:        if (sc->sc_aclwr_xfer != NULL) {
                    670:                usbd_free_xfer(sc->sc_aclwr_xfer);
                    671:                sc->sc_aclwr_xfer = NULL;
                    672:                sc->sc_aclwr_buf = NULL;
                    673:        }
                    674:
                    675:        for (i = 0 ; i < UBT_NXFERS ; i++) {
                    676:                if (sc->sc_scord[i].xfer != NULL) {
                    677:                        usbd_free_xfer(sc->sc_scord[i].xfer);
                    678:                        sc->sc_scord[i].xfer = NULL;
                    679:                        sc->sc_scord[i].buf = NULL;
                    680:                }
                    681:
                    682:                if (sc->sc_scowr[i].xfer != NULL) {
                    683:                        usbd_free_xfer(sc->sc_scowr[i].xfer);
                    684:                        sc->sc_scowr[i].xfer = NULL;
                    685:                        sc->sc_scowr[i].buf = NULL;
                    686:                }
                    687:        }
                    688:
                    689:        /* Free partial SCO packets */
                    690:        if (sc->sc_scord_mbuf != NULL) {
                    691:                m_freem(sc->sc_scord_mbuf);
                    692:                sc->sc_scord_mbuf = NULL;
                    693:        }
                    694:
                    695:        if (sc->sc_scowr_mbuf != NULL) {
                    696:                m_freem(sc->sc_scowr_mbuf);
                    697:                sc->sc_scowr_mbuf = NULL;
                    698:        }
                    699: }
                    700:
                    701: /*******************************************************************************
                    702:  *
                    703:  * Bluetooth Unit/USB callbacks
                    704:  *
                    705:  * All of this will be called at the IPL_ we specified above
                    706:  */
                    707: int
                    708: ubt_enable(struct hci_unit *unit)
                    709: {
                    710:        struct ubt_softc *sc = (struct ubt_softc *)unit->hci_softc;
                    711:        usbd_status err;
                    712:        int i, error;
                    713:
                    714:        DPRINTFN(1, "sc=%p\n", sc);
                    715:
                    716:        if (unit->hci_flags & BTF_RUNNING)
                    717:                return 0;
                    718:
                    719:        /* Events */
                    720:        sc->sc_evt_buf = malloc(UBT_BUFSIZ_EVENT, M_USBDEV, M_NOWAIT);
                    721:        if (sc->sc_evt_buf == NULL) {
                    722:                error = ENOMEM;
                    723:                goto bad;
                    724:        }
                    725:        err = usbd_open_pipe_intr(sc->sc_iface0,
                    726:                                  sc->sc_evt_addr,
                    727:                                  USBD_SHORT_XFER_OK,
                    728:                                  &sc->sc_evt_pipe,
                    729:                                  sc,
                    730:                                  sc->sc_evt_buf,
                    731:                                  UBT_BUFSIZ_EVENT,
                    732:                                  ubt_recv_event,
                    733:                                  USBD_DEFAULT_INTERVAL);
                    734:        if (err != USBD_NORMAL_COMPLETION) {
                    735:                error = EIO;
                    736:                goto bad;
                    737:        }
                    738:
                    739:        /* Commands */
                    740:        sc->sc_cmd_xfer = usbd_alloc_xfer(sc->sc_udev);
                    741:        if (sc->sc_cmd_xfer == NULL) {
                    742:                error = ENOMEM;
                    743:                goto bad;
                    744:        }
                    745:        sc->sc_cmd_buf = usbd_alloc_buffer(sc->sc_cmd_xfer, UBT_BUFSIZ_CMD);
                    746:        if (sc->sc_cmd_buf == NULL) {
                    747:                error = ENOMEM;
                    748:                goto bad;
                    749:        }
                    750:
                    751:        /* ACL read */
                    752:        err = usbd_open_pipe(sc->sc_iface0, sc->sc_aclrd_addr,
                    753:                                USBD_EXCLUSIVE_USE, &sc->sc_aclrd_pipe);
                    754:        if (err != USBD_NORMAL_COMPLETION) {
                    755:                error = EIO;
                    756:                goto bad;
                    757:        }
                    758:        sc->sc_aclrd_xfer = usbd_alloc_xfer(sc->sc_udev);
                    759:        if (sc->sc_aclrd_xfer == NULL) {
                    760:                error = ENOMEM;
                    761:                goto bad;
                    762:        }
                    763:        sc->sc_aclrd_buf = usbd_alloc_buffer(sc->sc_aclrd_xfer, UBT_BUFSIZ_ACL);
                    764:        if (sc->sc_aclrd_buf == NULL) {
                    765:                error = ENOMEM;
                    766:                goto bad;
                    767:        }
                    768:        sc->sc_aclrd_busy = 0;
                    769:        ubt_recv_acl_start(sc);
                    770:
                    771:        /* ACL write */
                    772:        err = usbd_open_pipe(sc->sc_iface0, sc->sc_aclwr_addr,
                    773:                                USBD_EXCLUSIVE_USE, &sc->sc_aclwr_pipe);
                    774:        if (err != USBD_NORMAL_COMPLETION) {
                    775:                error = EIO;
                    776:                goto bad;
                    777:        }
                    778:        sc->sc_aclwr_xfer = usbd_alloc_xfer(sc->sc_udev);
                    779:        if (sc->sc_aclwr_xfer == NULL) {
                    780:                error = ENOMEM;
                    781:                goto bad;
                    782:        }
                    783:        sc->sc_aclwr_buf = usbd_alloc_buffer(sc->sc_aclwr_xfer, UBT_BUFSIZ_ACL);
                    784:        if (sc->sc_aclwr_buf == NULL) {
                    785:                error = ENOMEM;
                    786:                goto bad;
                    787:        }
                    788:
                    789:        /* SCO read */
                    790:        if (sc->sc_scord_size > 0) {
                    791:                err = usbd_open_pipe(sc->sc_iface1, sc->sc_scord_addr,
                    792:                                        USBD_EXCLUSIVE_USE, &sc->sc_scord_pipe);
                    793:                if (err != USBD_NORMAL_COMPLETION) {
                    794:                        error = EIO;
                    795:                        goto bad;
                    796:                }
                    797:
                    798:                for (i = 0 ; i < UBT_NXFERS ; i++) {
                    799:                        sc->sc_scord[i].xfer = usbd_alloc_xfer(sc->sc_udev);
                    800:                        if (sc->sc_scord[i].xfer == NULL) {
                    801:                                error = ENOMEM;
                    802:                                goto bad;
                    803:                        }
                    804:                        sc->sc_scord[i].buf = usbd_alloc_buffer(sc->sc_scord[i].xfer,
                    805:                                                sc->sc_scord_size * UBT_NFRAMES);
                    806:                        if (sc->sc_scord[i].buf == NULL) {
                    807:                                error = ENOMEM;
                    808:                                goto bad;
                    809:                        }
                    810:                        sc->sc_scord[i].softc = sc;
                    811:                        sc->sc_scord[i].busy = 0;
                    812:                        ubt_recv_sco_start1(sc, &sc->sc_scord[i]);
                    813:                }
                    814:        }
                    815:
                    816:        /* SCO write */
                    817:        if (sc->sc_scowr_size > 0) {
                    818:                err = usbd_open_pipe(sc->sc_iface1, sc->sc_scowr_addr,
                    819:                                        USBD_EXCLUSIVE_USE, &sc->sc_scowr_pipe);
                    820:                if (err != USBD_NORMAL_COMPLETION) {
                    821:                        error = EIO;
                    822:                        goto bad;
                    823:                }
                    824:
                    825:                for (i = 0 ; i < UBT_NXFERS ; i++) {
                    826:                        sc->sc_scowr[i].xfer = usbd_alloc_xfer(sc->sc_udev);
                    827:                        if (sc->sc_scowr[i].xfer == NULL) {
                    828:                                error = ENOMEM;
                    829:                                goto bad;
                    830:                        }
                    831:                        sc->sc_scowr[i].buf = usbd_alloc_buffer(sc->sc_scowr[i].xfer,
                    832:                                                sc->sc_scowr_size * UBT_NFRAMES);
                    833:                        if (sc->sc_scowr[i].buf == NULL) {
                    834:                                error = ENOMEM;
                    835:                                goto bad;
                    836:                        }
                    837:                        sc->sc_scowr[i].softc = sc;
                    838:                        sc->sc_scowr[i].busy = 0;
                    839:                }
                    840:        }
                    841:
                    842:        unit->hci_flags &= ~BTF_XMIT;
                    843:        unit->hci_flags |= BTF_RUNNING;
                    844:        return 0;
                    845:
                    846: bad:
                    847:        ubt_abortdealloc(sc);
                    848:        return error;
                    849: }
                    850:
                    851: void
                    852: ubt_disable(struct hci_unit *unit)
                    853: {
                    854:        struct ubt_softc *sc = (struct ubt_softc *)unit->hci_softc;
                    855:
                    856:        DPRINTFN(1, "sc=%p\n", sc);
                    857:
                    858:        if ((unit->hci_flags & BTF_RUNNING) == 0)
                    859:                return;
                    860:
                    861:        ubt_abortdealloc(sc);
                    862:
                    863:        unit->hci_flags &= ~BTF_RUNNING;
                    864: }
                    865:
                    866: void
                    867: ubt_xmit_cmd_start(struct hci_unit *unit)
                    868: {
                    869:        struct ubt_softc *sc = (struct ubt_softc *)unit->hci_softc;
                    870:        usb_device_request_t req;
                    871:        usbd_status status;
                    872:        struct mbuf *m;
                    873:        int len;
                    874:
                    875:        if (sc->sc_dying)
                    876:                return;
                    877:
                    878:        if (IF_IS_EMPTY(&unit->hci_cmdq))
                    879:                return;
                    880:
                    881:        IF_DEQUEUE(&unit->hci_cmdq, m);
                    882:
                    883:        DPRINTFN(15, "%s: xmit CMD packet (%d bytes)\n",
                    884:                        unit->hci_devname, m->m_pkthdr.len);
                    885:
                    886:        sc->sc_refcnt++;
                    887:        unit->hci_flags |= BTF_XMIT_CMD;
                    888:
                    889:        len = m->m_pkthdr.len - 1;
                    890:        m_copydata(m, 1, len, sc->sc_cmd_buf);
                    891:        m_freem(m);
                    892:
                    893:        memset(&req, 0, sizeof(req));
                    894:        req.bmRequestType = UT_WRITE_CLASS_DEVICE;
                    895:        USETW(req.wLength, len);
                    896:
                    897:        usbd_setup_default_xfer(sc->sc_cmd_xfer,
                    898:                                sc->sc_udev,
                    899:                                unit,
                    900:                                UBT_CMD_TIMEOUT,
                    901:                                &req,
                    902:                                sc->sc_cmd_buf,
                    903:                                len,
                    904:                                USBD_NO_COPY | USBD_FORCE_SHORT_XFER,
                    905:                                ubt_xmit_cmd_complete);
                    906:
                    907:        status = usbd_transfer(sc->sc_cmd_xfer);
                    908:
                    909:        KASSERT(status != USBD_NORMAL_COMPLETION);
                    910:
                    911:        if (status != USBD_IN_PROGRESS) {
                    912:                DPRINTF("usbd_transfer status=%s (%d)\n",
                    913:                        usbd_errstr(status), status);
                    914:
                    915:                sc->sc_refcnt--;
                    916:                unit->hci_flags &= ~BTF_XMIT_CMD;
                    917:        }
                    918: }
                    919:
                    920: void
                    921: ubt_xmit_cmd_complete(usbd_xfer_handle xfer,
                    922:                        usbd_private_handle h, usbd_status status)
                    923: {
                    924:        struct hci_unit *unit = h;
                    925:        struct ubt_softc *sc = (struct ubt_softc *)unit->hci_softc;
                    926:        uint32_t count;
                    927:
                    928:        DPRINTFN(15, "%s: CMD complete status=%s (%d)\n",
                    929:                        unit->hci_devname, usbd_errstr(status), status);
                    930:
                    931:        unit->hci_flags &= ~BTF_XMIT_CMD;
                    932:
                    933:        if (--sc->sc_refcnt < 0) {
                    934:                DPRINTF("sc_refcnt=%d\n", sc->sc_refcnt);
                    935:                usb_detach_wakeup(&sc->sc_dev);
                    936:                return;
                    937:        }
                    938:
                    939:        if (sc->sc_dying) {
                    940:                DPRINTF("sc_dying\n");
                    941:                return;
                    942:        }
                    943:
                    944:        if (status != USBD_NORMAL_COMPLETION) {
                    945:                DPRINTF("status=%s (%d)\n",
                    946:                        usbd_errstr(status), status);
                    947:
                    948:                unit->hci_stats.err_tx++;
                    949:                return;
                    950:        }
                    951:
                    952:        usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL);
                    953:        unit->hci_stats.cmd_tx++;
                    954:        unit->hci_stats.byte_tx += count;
                    955:
                    956:        ubt_xmit_cmd_start(unit);
                    957: }
                    958:
                    959: void
                    960: ubt_xmit_acl_start(struct hci_unit *unit)
                    961: {
                    962:        struct ubt_softc *sc = (struct ubt_softc *)unit->hci_softc;
                    963:        struct mbuf *m;
                    964:        usbd_status status;
                    965:        int len;
                    966:
                    967:        if (sc->sc_dying)
                    968:                return;
                    969:
                    970:        if (IF_IS_EMPTY(&unit->hci_acltxq) == NULL)
                    971:                return;
                    972:
                    973:        sc->sc_refcnt++;
                    974:        unit->hci_flags |= BTF_XMIT_ACL;
                    975:
                    976:        IF_DEQUEUE(&unit->hci_acltxq, m);
                    977:
                    978:        DPRINTFN(15, "%s: xmit ACL packet (%d bytes)\n",
                    979:                        unit->hci_devname, m->m_pkthdr.len);
                    980:
                    981:        len = m->m_pkthdr.len - 1;
                    982:        if (len > UBT_BUFSIZ_ACL) {
                    983:                DPRINTF("%s: truncating ACL packet (%d => %d)!\n",
                    984:                        unit->hci_devname, len, UBT_BUFSIZ_ACL);
                    985:
                    986:                len = UBT_BUFSIZ_ACL;
                    987:        }
                    988:
                    989:        m_copydata(m, 1, len, sc->sc_aclwr_buf);
                    990:        m_freem(m);
                    991:
                    992:        unit->hci_stats.acl_tx++;
                    993:        unit->hci_stats.byte_tx += len;
                    994:
                    995:        usbd_setup_xfer(sc->sc_aclwr_xfer,
                    996:                        sc->sc_aclwr_pipe,
                    997:                        unit,
                    998:                        sc->sc_aclwr_buf,
                    999:                        len,
                   1000:                        USBD_NO_COPY | USBD_FORCE_SHORT_XFER,
                   1001:                        UBT_ACL_TIMEOUT,
                   1002:                        ubt_xmit_acl_complete);
                   1003:
                   1004:        status = usbd_transfer(sc->sc_aclwr_xfer);
                   1005:
                   1006:        KASSERT(status != USBD_NORMAL_COMPLETION);
                   1007:
                   1008:        if (status != USBD_IN_PROGRESS) {
                   1009:                DPRINTF("usbd_transfer status=%s (%d)\n",
                   1010:                        usbd_errstr(status), status);
                   1011:
                   1012:                sc->sc_refcnt--;
                   1013:                unit->hci_flags &= ~BTF_XMIT_ACL;
                   1014:        }
                   1015: }
                   1016:
                   1017: void
                   1018: ubt_xmit_acl_complete(usbd_xfer_handle xfer,
                   1019:                usbd_private_handle h, usbd_status status)
                   1020: {
                   1021:        struct hci_unit *unit = h;
                   1022:        struct ubt_softc *sc = (struct ubt_softc *)unit->hci_softc;
                   1023:
                   1024:        DPRINTFN(15, "%s: ACL complete status=%s (%d)\n",
                   1025:                unit->hci_devname, usbd_errstr(status), status);
                   1026:
                   1027:        unit->hci_flags &= ~BTF_XMIT_ACL;
                   1028:
                   1029:        if (--sc->sc_refcnt < 0) {
                   1030:                usb_detach_wakeup(&sc->sc_dev);
                   1031:                return;
                   1032:        }
                   1033:
                   1034:        if (sc->sc_dying)
                   1035:                return;
                   1036:
                   1037:        if (status != USBD_NORMAL_COMPLETION) {
                   1038:                DPRINTF("status=%s (%d)\n",
                   1039:                        usbd_errstr(status), status);
                   1040:
                   1041:                unit->hci_stats.err_tx++;
                   1042:
                   1043:                if (status == USBD_STALLED)
                   1044:                        usbd_clear_endpoint_stall_async(sc->sc_aclwr_pipe);
                   1045:                else
                   1046:                        return;
                   1047:        }
                   1048:
                   1049:        ubt_xmit_acl_start(unit);
                   1050: }
                   1051:
                   1052: void
                   1053: ubt_xmit_sco_start(struct hci_unit *unit)
                   1054: {
                   1055:        struct ubt_softc *sc = (struct ubt_softc *)unit->hci_softc;
                   1056:        int i;
                   1057:
                   1058:        if (sc->sc_dying || sc->sc_scowr_size == 0)
                   1059:                return;
                   1060:
                   1061:        for (i = 0 ; i < UBT_NXFERS ; i++) {
                   1062:                if (sc->sc_scowr[i].busy)
                   1063:                        continue;
                   1064:
                   1065:                ubt_xmit_sco_start1(sc, &sc->sc_scowr[i]);
                   1066:        }
                   1067: }
                   1068:
                   1069: void
                   1070: ubt_xmit_sco_start1(struct ubt_softc *sc, struct ubt_isoc_xfer *isoc)
                   1071: {
                   1072:        struct mbuf *m;
                   1073:        uint8_t *buf;
                   1074:        int num, len, size, space;
                   1075:
                   1076:        space = sc->sc_scowr_size * UBT_NFRAMES;
                   1077:        buf = isoc->buf;
                   1078:        len = 0;
                   1079:
                   1080:        /*
                   1081:         * Fill the request buffer with data from the queue,
                   1082:         * keeping any leftover packet on our private hook.
                   1083:         *
                   1084:         * Complete packets are passed back up to the stack
                   1085:         * for disposal, since we can't rely on the controller
                   1086:         * to tell us when it has finished with them.
                   1087:         */
                   1088:
                   1089:        m = sc->sc_scowr_mbuf;
                   1090:        while (space > 0) {
                   1091:                if (m == NULL) {
                   1092:                        IF_DEQUEUE(&sc->sc_unit.hci_scotxq, m);
                   1093:                        if (m == NULL)
                   1094:                                break;
                   1095:
                   1096:                        m_adj(m, 1);    /* packet type */
                   1097:                }
                   1098:
                   1099:                if (m->m_pkthdr.len > 0) {
                   1100:                        size = MIN(m->m_pkthdr.len, space);
                   1101:
                   1102:                        m_copydata(m, 0, size, buf);
                   1103:                        m_adj(m, size);
                   1104:
                   1105:                        buf += size;
                   1106:                        len += size;
                   1107:                        space -= size;
                   1108:                }
                   1109:
                   1110:                if (m->m_pkthdr.len == 0) {
                   1111:                        sc->sc_unit.hci_stats.sco_tx++;
                   1112:                        hci_complete_sco(&sc->sc_unit, m);
                   1113:                        m = NULL;
                   1114:                }
                   1115:        }
                   1116:        sc->sc_scowr_mbuf = m;
                   1117:
                   1118:        DPRINTFN(15, "isoc=%p, len=%d, space=%d\n", isoc, len, space);
                   1119:
                   1120:        if (len == 0)   /* nothing to send */
                   1121:                return;
                   1122:
                   1123:        sc->sc_refcnt++;
                   1124:        sc->sc_unit.hci_flags |= BTF_XMIT_SCO;
                   1125:        sc->sc_unit.hci_stats.byte_tx += len;
                   1126:        isoc->busy = 1;
                   1127:
                   1128:        /*
                   1129:         * calculate number of isoc frames and sizes
                   1130:         */
                   1131:
                   1132:        for (num = 0 ; len > 0 ; num++) {
                   1133:                size = MIN(sc->sc_scowr_size, len);
                   1134:
                   1135:                isoc->size[num] = size;
                   1136:                len -= size;
                   1137:        }
                   1138:
                   1139:        usbd_setup_isoc_xfer(isoc->xfer,
                   1140:                             sc->sc_scowr_pipe,
                   1141:                             isoc,
                   1142:                             isoc->size,
                   1143:                             num,
                   1144:                             USBD_NO_COPY | USBD_FORCE_SHORT_XFER,
                   1145:                             ubt_xmit_sco_complete);
                   1146:
                   1147:        usbd_transfer(isoc->xfer);
                   1148: }
                   1149:
                   1150: void
                   1151: ubt_xmit_sco_complete(usbd_xfer_handle xfer,
                   1152:                usbd_private_handle h, usbd_status status)
                   1153: {
                   1154:        struct ubt_isoc_xfer *isoc = h;
                   1155:        struct ubt_softc *sc;
                   1156:        int i;
                   1157:
                   1158:        KASSERT(xfer == isoc->xfer);
                   1159:        sc = isoc->softc;
                   1160:
                   1161:        DPRINTFN(15, "isoc=%p, status=%s (%d)\n",
                   1162:                isoc, usbd_errstr(status), status);
                   1163:
                   1164:        isoc->busy = 0;
                   1165:
                   1166:        for (i = 0 ; ; i++) {
                   1167:                if (i == UBT_NXFERS) {
                   1168:                        sc->sc_unit.hci_flags &= ~BTF_XMIT_SCO;
                   1169:                        break;
                   1170:                }
                   1171:
                   1172:                if (sc->sc_scowr[i].busy)
                   1173:                        break;
                   1174:        }
                   1175:
                   1176:        if (--sc->sc_refcnt < 0) {
                   1177:                usb_detach_wakeup(&sc->sc_dev);
                   1178:                return;
                   1179:        }
                   1180:
                   1181:        if (sc->sc_dying)
                   1182:                return;
                   1183:
                   1184:        if (status != USBD_NORMAL_COMPLETION) {
                   1185:                DPRINTF("status=%s (%d)\n",
                   1186:                        usbd_errstr(status), status);
                   1187:
                   1188:                sc->sc_unit.hci_stats.err_tx++;
                   1189:
                   1190:                if (status == USBD_STALLED)
                   1191:                        usbd_clear_endpoint_stall_async(sc->sc_scowr_pipe);
                   1192:                else
                   1193:                        return;
                   1194:        }
                   1195:
                   1196:        ubt_xmit_sco_start(&sc->sc_unit);
                   1197: }
                   1198:
                   1199: /*
                   1200:  * load incoming data into an mbuf with
                   1201:  * leading type byte
                   1202:  */
                   1203: static struct mbuf *
                   1204: ubt_mbufload(uint8_t *buf, int count, uint8_t type)
                   1205: {
                   1206:        struct mbuf *m;
                   1207:
                   1208:        MGETHDR(m, M_DONTWAIT, MT_DATA);
                   1209:        if (m == NULL)
                   1210:                return NULL;
                   1211:
                   1212:        *mtod(m, uint8_t *) = type;
                   1213:        m->m_pkthdr.len = m->m_len = MHLEN;
                   1214:        m_copyback(m, 1, count, buf);   // (extends if necessary)
                   1215:        if (m->m_pkthdr.len != MAX(MHLEN, count + 1)) {
                   1216:                m_free(m);
                   1217:                return NULL;
                   1218:        }
                   1219:
                   1220:        m->m_pkthdr.len = count + 1;
                   1221:        m->m_len = MIN(MHLEN, m->m_pkthdr.len);
                   1222:
                   1223:        return m;
                   1224: }
                   1225:
                   1226: void
                   1227: ubt_recv_event(usbd_xfer_handle xfer, usbd_private_handle h, usbd_status status)
                   1228: {
                   1229:        struct ubt_softc *sc = h;
                   1230:        struct mbuf *m;
                   1231:        uint32_t count;
                   1232:        void *buf;
                   1233:
                   1234:        DPRINTFN(15, "sc=%p status=%s (%d)\n",
                   1235:                    sc, usbd_errstr(status), status);
                   1236:
                   1237:        if (status != USBD_NORMAL_COMPLETION || sc->sc_dying)
                   1238:                return;
                   1239:
                   1240:        usbd_get_xfer_status(xfer, NULL, &buf, &count, NULL);
                   1241:
                   1242:        if (count < sizeof(hci_event_hdr_t) - 1) {
                   1243:                DPRINTF("dumped undersized event (count = %d)\n", count);
                   1244:                sc->sc_unit.hci_stats.err_rx++;
                   1245:                return;
                   1246:        }
                   1247:
                   1248:        sc->sc_unit.hci_stats.evt_rx++;
                   1249:        sc->sc_unit.hci_stats.byte_rx += count;
                   1250:
                   1251:        m = ubt_mbufload(buf, count, HCI_EVENT_PKT);
                   1252:        if (m != NULL)
                   1253:                hci_input_event(&sc->sc_unit, m);
                   1254:        else
                   1255:                sc->sc_unit.hci_stats.err_rx++;
                   1256: }
                   1257:
                   1258: void
                   1259: ubt_recv_acl_start(struct ubt_softc *sc)
                   1260: {
                   1261:        usbd_status status;
                   1262:
                   1263:        DPRINTFN(15, "sc=%p\n", sc);
                   1264:
                   1265:        if (sc->sc_aclrd_busy || sc->sc_dying) {
                   1266:                DPRINTF("sc_aclrd_busy=%d, sc_dying=%d\n",
                   1267:                        sc->sc_aclrd_busy,
                   1268:                        sc->sc_dying);
                   1269:
                   1270:                return;
                   1271:        }
                   1272:
                   1273:        sc->sc_refcnt++;
                   1274:        sc->sc_aclrd_busy = 1;
                   1275:
                   1276:        usbd_setup_xfer(sc->sc_aclrd_xfer,
                   1277:                        sc->sc_aclrd_pipe,
                   1278:                        sc,
                   1279:                        sc->sc_aclrd_buf,
                   1280:                        UBT_BUFSIZ_ACL,
                   1281:                        USBD_NO_COPY | USBD_SHORT_XFER_OK,
                   1282:                        USBD_NO_TIMEOUT,
                   1283:                        ubt_recv_acl_complete);
                   1284:
                   1285:        status = usbd_transfer(sc->sc_aclrd_xfer);
                   1286:
                   1287:        KASSERT(status != USBD_NORMAL_COMPLETION);
                   1288:
                   1289:        if (status != USBD_IN_PROGRESS) {
                   1290:                DPRINTF("usbd_transfer status=%s (%d)\n",
                   1291:                        usbd_errstr(status), status);
                   1292:
                   1293:                sc->sc_refcnt--;
                   1294:                sc->sc_aclrd_busy = 0;
                   1295:        }
                   1296: }
                   1297:
                   1298: void
                   1299: ubt_recv_acl_complete(usbd_xfer_handle xfer,
                   1300:                usbd_private_handle h, usbd_status status)
                   1301: {
                   1302:        struct ubt_softc *sc = h;
                   1303:        struct mbuf *m;
                   1304:        uint32_t count;
                   1305:        void *buf;
                   1306:
                   1307:        DPRINTFN(15, "sc=%p status=%s (%d)\n",
                   1308:                        sc, usbd_errstr(status), status);
                   1309:
                   1310:        sc->sc_aclrd_busy = 0;
                   1311:
                   1312:        if (--sc->sc_refcnt < 0) {
                   1313:                DPRINTF("refcnt = %d\n", sc->sc_refcnt);
                   1314:                usb_detach_wakeup(&sc->sc_dev);
                   1315:                return;
                   1316:        }
                   1317:
                   1318:        if (sc->sc_dying) {
                   1319:                DPRINTF("sc_dying\n");
                   1320:                return;
                   1321:        }
                   1322:
                   1323:        if (status != USBD_NORMAL_COMPLETION) {
                   1324:                DPRINTF("status=%s (%d)\n",
                   1325:                        usbd_errstr(status), status);
                   1326:
                   1327:                sc->sc_unit.hci_stats.err_rx++;
                   1328:
                   1329:                if (status == USBD_STALLED)
                   1330:                        usbd_clear_endpoint_stall_async(sc->sc_aclrd_pipe);
                   1331:                else
                   1332:                        return;
                   1333:        } else {
                   1334:                usbd_get_xfer_status(xfer, NULL, &buf, &count, NULL);
                   1335:
                   1336:                if (count < sizeof(hci_acldata_hdr_t) - 1) {
                   1337:                        DPRINTF("dumped undersized packet (%d)\n", count);
                   1338:                        sc->sc_unit.hci_stats.err_rx++;
                   1339:                } else {
                   1340:                        sc->sc_unit.hci_stats.acl_rx++;
                   1341:                        sc->sc_unit.hci_stats.byte_rx += count;
                   1342:
                   1343:                        m = ubt_mbufload(buf, count, HCI_ACL_DATA_PKT);
                   1344:                        if (m != NULL)
                   1345:                                hci_input_acl(&sc->sc_unit, m);
                   1346:                        else
                   1347:                                sc->sc_unit.hci_stats.err_rx++;
                   1348:                }
                   1349:        }
                   1350:
                   1351:        /* and restart */
                   1352:        ubt_recv_acl_start(sc);
                   1353: }
                   1354:
                   1355: void
                   1356: ubt_recv_sco_start1(struct ubt_softc *sc, struct ubt_isoc_xfer *isoc)
                   1357: {
                   1358:        int i;
                   1359:
                   1360:        DPRINTFN(15, "sc=%p, isoc=%p\n", sc, isoc);
                   1361:
                   1362:        if (isoc->busy || sc->sc_dying || sc->sc_scord_size == 0) {
                   1363:                DPRINTF("%s%s%s\n",
                   1364:                        isoc->busy ? " busy" : "",
                   1365:                        sc->sc_dying ? " dying" : "",
                   1366:                        sc->sc_scord_size == 0 ? " size=0" : "");
                   1367:
                   1368:                return;
                   1369:        }
                   1370:
                   1371:        sc->sc_refcnt++;
                   1372:        isoc->busy = 1;
                   1373:
                   1374:        for (i = 0 ; i < UBT_NFRAMES ; i++)
                   1375:                isoc->size[i] = sc->sc_scord_size;
                   1376:
                   1377:        usbd_setup_isoc_xfer(isoc->xfer,
                   1378:                             sc->sc_scord_pipe,
                   1379:                             isoc,
                   1380:                             isoc->size,
                   1381:                             UBT_NFRAMES,
                   1382:                             USBD_NO_COPY | USBD_SHORT_XFER_OK,
                   1383:                             ubt_recv_sco_complete);
                   1384:
                   1385:        usbd_transfer(isoc->xfer);
                   1386: }
                   1387:
                   1388: void
                   1389: ubt_recv_sco_complete(usbd_xfer_handle xfer,
                   1390:                usbd_private_handle h, usbd_status status)
                   1391: {
                   1392:        struct ubt_isoc_xfer *isoc = h;
                   1393:        struct ubt_softc *sc;
                   1394:        struct mbuf *m;
                   1395:        uint32_t count;
                   1396:        uint8_t *ptr, *frame;
                   1397:        int i, size, got, want;
                   1398:
                   1399:        KASSERT(isoc != NULL);
                   1400:        KASSERT(isoc->xfer == xfer);
                   1401:
                   1402:        sc = isoc->softc;
                   1403:        isoc->busy = 0;
                   1404:
                   1405:        if (--sc->sc_refcnt < 0) {
                   1406:                DPRINTF("refcnt=%d\n", sc->sc_refcnt);
                   1407:                usb_detach_wakeup(&sc->sc_dev);
                   1408:                return;
                   1409:        }
                   1410:
                   1411:        if (sc->sc_dying) {
                   1412:                DPRINTF("sc_dying\n");
                   1413:                return;
                   1414:        }
                   1415:
                   1416:        if (status != USBD_NORMAL_COMPLETION) {
                   1417:                DPRINTF("status=%s (%d)\n",
                   1418:                        usbd_errstr(status), status);
                   1419:
                   1420:                sc->sc_unit.hci_stats.err_rx++;
                   1421:
                   1422:                if (status == USBD_STALLED) {
                   1423:                        usbd_clear_endpoint_stall_async(sc->sc_scord_pipe);
                   1424:                        goto restart;
                   1425:                }
                   1426:
                   1427:                return;
                   1428:        }
                   1429:
                   1430:        usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL);
                   1431:        if (count == 0)
                   1432:                goto restart;
                   1433:
                   1434:        DPRINTFN(15, "sc=%p, isoc=%p, count=%u\n",
                   1435:                        sc, isoc, count);
                   1436:
                   1437:        sc->sc_unit.hci_stats.byte_rx += count;
                   1438:
                   1439:        /*
                   1440:         * Extract SCO packets from ISOC frames. The way we have it,
                   1441:         * no SCO packet can be bigger than MHLEN. This is unlikely
                   1442:         * to actually happen, but if we ran out of mbufs and lost
                   1443:         * sync then we may get spurious data that makes it seem that
                   1444:         * way, so we discard data that wont fit. This doesnt really
                   1445:         * help with the lost sync situation alas.
                   1446:         */
                   1447:
                   1448:        m = sc->sc_scord_mbuf;
                   1449:        if (m != NULL) {
                   1450:                sc->sc_scord_mbuf = NULL;
                   1451:                ptr = mtod(m, uint8_t *) + m->m_pkthdr.len;
                   1452:                got = m->m_pkthdr.len;
                   1453:                want = sizeof(hci_scodata_hdr_t);
                   1454:                if (got >= want)
                   1455:                        want += mtod(m, hci_scodata_hdr_t *)->length ;
                   1456:        } else {
                   1457:                ptr = NULL;
                   1458:                got = 0;
                   1459:                want = 0;
                   1460:        }
                   1461:
                   1462:        for (i = 0 ; i < UBT_NFRAMES ; i++) {
                   1463:                frame = isoc->buf + (i * sc->sc_scord_size);
                   1464:
                   1465:                while (isoc->size[i] > 0) {
                   1466:                        size = isoc->size[i];
                   1467:
                   1468:                        if (m == NULL) {
                   1469:                                MGETHDR(m, M_DONTWAIT, MT_DATA);
                   1470:                                if (m == NULL) {
                   1471:                                        printf("%s: out of memory (xfer halted)\n",
                   1472:                                                sc->sc_dev.dv_xname);
                   1473:
                   1474:                                        sc->sc_unit.hci_stats.err_rx++;
                   1475:                                        return;         /* lost sync */
                   1476:                                }
                   1477:
                   1478:                                ptr = mtod(m, uint8_t *);
                   1479:                                *ptr++ = HCI_SCO_DATA_PKT;
                   1480:                                got = 1;
                   1481:                                want = sizeof(hci_scodata_hdr_t);
                   1482:                        }
                   1483:
                   1484:                        if (got + size > want)
                   1485:                                size = want - got;
                   1486:
                   1487:                        if (got + size > MHLEN)
                   1488:                                memcpy(ptr, frame, MHLEN - got);
                   1489:                        else
                   1490:                                memcpy(ptr, frame, size);
                   1491:
                   1492:                        ptr += size;
                   1493:                        got += size;
                   1494:                        frame += size;
                   1495:
                   1496:                        if (got == want) {
                   1497:                                /*
                   1498:                                 * If we only got a header, add the packet
                   1499:                                 * length to our want count. Send complete
                   1500:                                 * packets up to protocol stack.
                   1501:                                 */
                   1502:                                if (want == sizeof(hci_scodata_hdr_t))
                   1503:                                        want += mtod(m, hci_scodata_hdr_t *)->length;
                   1504:
                   1505:                                if (got == want) {
                   1506:                                        m->m_pkthdr.len = m->m_len = got;
                   1507:                                        sc->sc_unit.hci_stats.sco_rx++;
                   1508:                                        hci_input_sco(&sc->sc_unit, m);
                   1509:                                        m = NULL;
                   1510:                                }
                   1511:                        }
                   1512:
                   1513:                        isoc->size[i] -= size;
                   1514:                }
                   1515:        }
                   1516:
                   1517:        if (m != NULL) {
                   1518:                m->m_pkthdr.len = m->m_len = got;
                   1519:                sc->sc_scord_mbuf = m;
                   1520:        }
                   1521:
                   1522: restart: /* and restart */
                   1523:        ubt_recv_sco_start1(sc, isoc);
                   1524: }

CVSweb