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

Annotation of src/sys/dev/usb/ubt.c, Revision 1.21

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

CVSweb <webmaster@jp.NetBSD.org>