root/dev/usb/ubt.c

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

DEFINITIONS

This source file includes following definitions.
  1. ubt_match
  2. ubt_attach
  3. ubt_detach
  4. ubt_activate
  5. ubt_set_isoc_config
  6. ubt_abortdealloc
  7. ubt_enable
  8. ubt_disable
  9. ubt_xmit_cmd_start
  10. ubt_xmit_cmd_complete
  11. ubt_xmit_acl_start
  12. ubt_xmit_acl_complete
  13. ubt_xmit_sco_start
  14. ubt_xmit_sco_start1
  15. ubt_xmit_sco_complete
  16. ubt_mbufload
  17. ubt_recv_event
  18. ubt_recv_acl_start
  19. ubt_recv_acl_complete
  20. ubt_recv_sco_start1
  21. ubt_recv_sco_complete

    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 }

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