The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/bluetooth/bthci.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: bthci.c,v 1.15 2004/01/04 05:39:35 dsainty Exp $       */
    2 
    3 /*
    4  * Copyright (c) 2002, 2003 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by Lennart Augustsson (lennart@augustsson.net) and
    9  * David Sainty (David.Sainty@dtsp.co.nz).
   10  *
   11  * Redistribution and use in source and binary forms, with or without
   12  * modification, are permitted provided that the following conditions
   13  * are met:
   14  * 1. Redistributions of source code must retain the above copyright
   15  *    notice, this list of conditions and the following disclaimer.
   16  * 2. Redistributions in binary form must reproduce the above copyright
   17  *    notice, this list of conditions and the following disclaimer in the
   18  *    documentation and/or other materials provided with the distribution.
   19  * 3. All advertising materials mentioning features or use of this software
   20  *    must display the following acknowledgement:
   21  *        This product includes software developed by the NetBSD
   22  *        Foundation, Inc. and its contributors.
   23  * 4. Neither the name of The NetBSD Foundation nor the names of its
   24  *    contributors may be used to endorse or promote products derived
   25  *    from this software without specific prior written permission.
   26  *
   27  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   28  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   29  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   30  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   31  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   32  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   33  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   34  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   35  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   36  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   37  * POSSIBILITY OF SUCH DAMAGE.
   38  */
   39 
   40 #include <sys/cdefs.h>
   41 __KERNEL_RCSID(0, "$NetBSD: bthci.c,v 1.15 2004/01/04 05:39:35 dsainty Exp $");
   42 
   43 #include "bthcidrv.h"
   44 
   45 #include <sys/param.h>
   46 #include <sys/systm.h>
   47 #include <sys/ioctl.h>
   48 #include <sys/kernel.h>
   49 #include <sys/device.h>
   50 #include <sys/conf.h>
   51 #include <sys/malloc.h>
   52 #include <sys/poll.h>
   53 #include <sys/select.h>
   54 #include <sys/vnode.h>
   55 
   56 #include <dev/bluetooth/bluetooth.h>
   57 #include <dev/bluetooth/bthci_util.h>
   58 #include <dev/bluetooth/bthcivar.h>
   59 
   60 #ifdef BTHCI_DEBUG
   61 #define DPRINTF(x)      if (bthcidebug) printf x
   62 #define DPRINTFN(n,x)   if (bthcidebug>(n)) printf x
   63 #define Static
   64 int bthcidebug = 99;
   65 #else
   66 #define DPRINTF(x)
   67 #define DPRINTFN(n,x)
   68 #define Static static
   69 #endif
   70 
   71 struct bthci_softc {
   72         struct  device                  sc_dev;
   73         struct btframe_methods const    *sc_methods;
   74         void                            *sc_handle;
   75 
   76         u_int8_t                        *sc_rd_buf;
   77         size_t                          sc_rd_len;
   78         struct selinfo                  sc_rd_sel;
   79 
   80         int                             sc_refcnt;
   81         int                             sc_outputready;
   82         char                            sc_open;
   83         char                            sc_dying;
   84 };
   85 
   86 int bthci_match(struct device *parent, struct cfdata *match, void *aux);
   87 void bthci_attach(struct device *parent, struct device *self, void *aux);
   88 int bthci_activate(struct device *self, enum devact act);
   89 int bthci_detach(struct device *self, int flags);
   90 
   91 #if NBTHCIDRV == 0
   92 /* In case we just have tty attachment. */
   93 struct cfdriver bthci_cd = {
   94         NULL, "bthci", DV_DULL
   95 };
   96 #endif
   97 
   98 CFATTACH_DECL(bthci, sizeof(struct bthci_softc),
   99     bthci_match, bthci_attach, bthci_detach, bthci_activate);
  100 
  101 extern struct cfdriver bthci_cd;
  102 
  103 dev_type_open(bthciopen);
  104 dev_type_close(bthciclose);
  105 dev_type_poll(bthcipoll);
  106 dev_type_kqfilter(bthcikqfilter);
  107 
  108 static int bthciread(dev_t dev, struct uio *uio, int flag);
  109 static int bthciwrite(dev_t dev, struct uio *uio, int flag);
  110 
  111 static void bthci_recveventdata(void *h, u_int8_t *data, size_t len);
  112 static void bthci_recvacldata(void *h, u_int8_t *data, size_t len);
  113 static void bthci_recvscodata(void *h, u_int8_t *data, size_t len);
  114 
  115 const struct cdevsw bthci_cdevsw = {
  116         bthciopen, bthciclose, bthciread, bthciwrite, noioctl,
  117         nostop, notty, bthcipoll, nommap, bthcikqfilter,
  118 };
  119 
  120 #define BTHCIUNIT(dev) (minor(dev))
  121 
  122 struct btframe_callback_methods const bthci_callbacks = {
  123         bthci_recveventdata, bthci_recvacldata, bthci_recvscodata
  124 };
  125 
  126 int
  127 bthci_match(struct device *parent, struct cfdata *match, void *aux)
  128 {
  129         /*struct bt_attach_args *bt = aux;*/
  130 
  131         return (1);
  132 }
  133 
  134 void
  135 bthci_attach(struct device *parent, struct device *self, void *aux)
  136 {
  137         struct bthci_softc *sc = (struct bthci_softc *)self;
  138         struct bt_attach_args *bt = aux;
  139 
  140         sc->sc_methods = bt->bt_methods;
  141         sc->sc_handle = bt->bt_handle;
  142 
  143         *bt->bt_cb = &bthci_callbacks;
  144 
  145 #ifdef DIAGNOSTIC
  146         if (sc->sc_methods->bt_open == NULL ||
  147             sc->sc_methods->bt_close == NULL ||
  148 
  149             sc->sc_methods->bt_control.bt_alloc == NULL ||
  150             sc->sc_methods->bt_control.bt_send == NULL ||
  151 
  152             sc->sc_methods->bt_acldata.bt_alloc == NULL ||
  153             sc->sc_methods->bt_acldata.bt_send == NULL ||
  154 
  155             sc->sc_methods->bt_scodata.bt_alloc == NULL ||
  156             sc->sc_methods->bt_scodata.bt_send == NULL)
  157                 panic("%s: missing methods", sc->sc_dev.dv_xname);
  158 #endif
  159 
  160         printf("\n");
  161 }
  162 
  163 int
  164 bthci_activate(struct device *self, enum devact act)
  165 {
  166         /*struct bthci_softc *sc = (struct bthci_softc *)self;*/
  167 
  168         switch (act) {
  169         case DVACT_ACTIVATE:
  170                 return (EOPNOTSUPP);
  171                 break;
  172 
  173         case DVACT_DEACTIVATE:
  174                 break;
  175         }
  176         return (0);
  177 }
  178 
  179 static void
  180 bthci_abortdealloc(struct bthci_softc *sc)
  181 {
  182         DPRINTFN(0, ("%s: sc=%p\n", __func__, sc));
  183 
  184         if (sc->sc_rd_buf != NULL) {
  185                 free(sc->sc_rd_buf, M_TEMP);
  186                 sc->sc_rd_buf = NULL;
  187         }
  188 }
  189 
  190 int
  191 bthci_detach(struct device *self, int flags)
  192 {
  193         struct bthci_softc *sc = (struct bthci_softc *)self;
  194         int maj, mn;
  195 
  196         sc->sc_dying = 1;
  197         wakeup(&sc->sc_outputready);
  198 
  199         DPRINTFN(1, ("%s: waiting for refcount (%d)\n",
  200                      __func__, sc->sc_refcnt));
  201 
  202         if (--sc->sc_refcnt >= 0)
  203                 tsleep(&sc->sc_refcnt, PZERO, "bthcdt", 0);
  204 
  205         DPRINTFN(1, ("%s: refcount complete\n", __func__));
  206 
  207         bthci_abortdealloc(sc);
  208 
  209         /* locate the major number */
  210         maj = cdevsw_lookup_major(&bthci_cdevsw);
  211 
  212         /* Nuke the vnodes for any open instances (calls close). */
  213         mn = self->dv_unit;
  214         vdevgone(maj, mn, mn, VCHR);
  215 
  216         DPRINTFN(1, ("%s: driver detached\n", __func__));
  217 
  218         return (0);
  219 }
  220 
  221 int
  222 bthciopen(dev_t dev, int flag, int mode, struct proc *p)
  223 {
  224         struct bthci_softc *sc;
  225         int error;
  226 
  227         sc = device_lookup(&bthci_cd, BTHCIUNIT(dev));
  228         if (sc == NULL)
  229                 return (ENXIO);
  230         if ((sc->sc_dev.dv_flags & DVF_ACTIVE) == 0)
  231                 return (EIO);
  232         if (sc->sc_open)
  233                 return (EBUSY);
  234 
  235         sc->sc_rd_buf = malloc(BTHCI_ACL_DATA_MAX_LEN + 1, M_TEMP, M_NOWAIT);
  236         if (sc->sc_rd_buf == NULL)
  237                 return (ENOMEM);
  238 
  239         sc->sc_refcnt++;
  240 
  241         if (sc->sc_methods->bt_open != NULL) {
  242                 error = sc->sc_methods->bt_open(sc->sc_handle, flag, mode, p);
  243                 if (error)
  244                         goto bad;
  245         }
  246 
  247         if (--sc->sc_refcnt < 0)
  248                 wakeup(&sc->sc_refcnt);
  249 
  250         sc->sc_open = 1;
  251         return (0);
  252 
  253  bad:
  254         free(sc->sc_rd_buf, M_TEMP);
  255         sc->sc_rd_buf = NULL;
  256 
  257         return error;
  258 }
  259 
  260 int
  261 bthciclose(dev_t dev, int flag, int mode, struct proc *p)
  262 {
  263         struct bthci_softc *sc;
  264         int error;
  265 
  266         sc = device_lookup(&bthci_cd, BTHCIUNIT(dev));
  267         if (sc == NULL)
  268                 return (ENXIO);
  269 
  270         if (!sc->sc_open)
  271                 return (0);
  272 
  273         sc->sc_refcnt++;
  274 
  275         sc->sc_open = 0;
  276 
  277         if (sc->sc_methods->bt_close != NULL)
  278                 error = sc->sc_methods->bt_close(sc->sc_handle, flag, mode, p);
  279         else
  280                 error = 0;
  281 
  282         bthci_abortdealloc(sc);
  283 
  284         if (--sc->sc_refcnt < 0)
  285                 wakeup(&sc->sc_refcnt);
  286 
  287         return (error);
  288 }
  289 
  290 static int
  291 bthciread(dev_t dev, struct uio *uio, int flag)
  292 {
  293         struct bthci_softc *sc;
  294         int error;
  295         int s;
  296 
  297         sc = device_lookup(&bthci_cd, BTHCIUNIT(dev));
  298         if (sc == NULL)
  299                 return (ENXIO);
  300 
  301         if ((sc->sc_dev.dv_flags & DVF_ACTIVE) == 0 ||
  302             !sc->sc_open || sc->sc_dying)
  303                 return (EIO);
  304 
  305         DPRINTFN(1, ("%s: length=%lu\n", __func__,
  306                      (unsigned long)uio->uio_resid));
  307 
  308         sc->sc_refcnt++;
  309 
  310         s = sc->sc_methods->bt_splraise();
  311         while (!sc->sc_outputready) {
  312                 DPRINTFN(5,("%s: calling tsleep()\n", __func__));
  313                 error = tsleep(&sc->sc_outputready, PZERO | PCATCH,
  314                                "bthcrd", 0);
  315                 if (sc->sc_dying)
  316                         error = EIO;
  317                 if (error) {
  318                         splx(s);
  319                         DPRINTFN(0, ("%s: tsleep() = %d\n",
  320                                      __func__, error));
  321                         goto ret;
  322                 }
  323         }
  324         splx(s);
  325 
  326         if (uio->uio_resid < sc->sc_rd_len) {
  327 #ifdef DIAGNOSTIC
  328                 printf("bthciread: short read %ld < %ld\n",
  329                     (long)uio->uio_resid, (long)sc->sc_rd_len);
  330 #endif
  331                 error = EINVAL;
  332                 goto ret;
  333         }
  334 
  335         error = uiomove(sc->sc_rd_buf, sc->sc_rd_len, uio);
  336 
  337         if (!error) {
  338                 sc->sc_outputready = 0;
  339                 sc->sc_rd_len = 0;
  340         }
  341 
  342  ret:
  343         if (--sc->sc_refcnt < 0)
  344                 wakeup(&sc->sc_refcnt);
  345 
  346         return error;
  347 }
  348 
  349 static int
  350 bthcichanwrite(struct bthci_softc *sc,
  351                struct btframe_channel const *btchannel, struct uio *uio)
  352 {
  353         struct btframe_buffer *btframebuf;
  354         u_int8_t *btbuf;
  355         int error;
  356         size_t uiolen;
  357 
  358         sc->sc_refcnt++;
  359 
  360         uiolen = uio->uio_resid;
  361 
  362         btbuf = btchannel->bt_alloc(sc->sc_handle, uiolen, &btframebuf);
  363         if (btbuf == NULL) {
  364                 error = ENOMEM;
  365                 goto ret;
  366         }
  367 
  368         error = uiomove(btbuf, uiolen, uio);
  369         if (error)
  370                 goto ret;
  371 
  372         error = btchannel->bt_send(sc->sc_handle, btframebuf, uiolen);
  373 
  374  ret:
  375         if (--sc->sc_refcnt < 0)
  376                 wakeup(&sc->sc_refcnt);
  377 
  378         return error;
  379 }
  380 
  381 static int
  382 bthciwrite(dev_t dev, struct uio *uio, int flag)
  383 {
  384         struct bthci_softc *sc;
  385         struct btframe_channel const *btchannel;
  386         int error;
  387         size_t uiolen;
  388         u_int8_t bthcitype;
  389 
  390         sc = device_lookup(&bthci_cd, BTHCIUNIT(dev));
  391         if (sc == NULL)
  392                 return (ENXIO);
  393 
  394         if ((sc->sc_dev.dv_flags & DVF_ACTIVE) == 0 || !sc->sc_open)
  395                 return (EIO);
  396 
  397         uiolen = uio->uio_resid;
  398 
  399         DPRINTFN(1, ("%s: length=%lu\n", __func__, (unsigned long)uiolen));
  400 
  401         if (uiolen > BTHCI_ACL_DATA_MAX_LEN + 1) {
  402 #ifdef DIAGNOSTIC
  403                 printf("bthciread: long write %ld\n", (long)uio->uio_resid);
  404 #endif
  405                 return (EINVAL);
  406         }
  407 
  408         if (uiolen <= 1) {
  409 #ifdef DIAGNOSTIC
  410                 printf("bthciread: short write %ld\n", (long)uio->uio_resid);
  411 #endif
  412                 return (EINVAL);
  413         }
  414 
  415         error = uiomove(&bthcitype, 1, uio);
  416         if (error)
  417                 return (error);
  418 
  419         if (bthcitype == BTHCI_PKTID_COMMAND) {
  420                 /* Command */
  421                 btchannel = &sc->sc_methods->bt_control;
  422         } else if (bthcitype == BTHCI_PKTID_ACL_DATA) {
  423                 /* ACL data */
  424                 btchannel = &sc->sc_methods->bt_acldata;
  425         } else if (bthcitype == BTHCI_PKTID_SCO_DATA) {
  426                 /* SCO data */
  427                 btchannel = &sc->sc_methods->bt_scodata;
  428         } else {
  429                 /* Bad packet type */
  430                 return (EINVAL);
  431         }
  432 
  433         return (bthcichanwrite(sc, btchannel, uio));
  434 }
  435 
  436 #if 0
  437 int
  438 bthciioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
  439 {
  440         struct bthci_softc *sc;
  441         void *vaddr = addr;
  442         int error;
  443 
  444         sc = device_lookup(&bthci_cd, BTHCIUNIT(dev));
  445         if (sc == NULL)
  446                 return (ENXIO);
  447         if ((sc->sc_dev.dv_flags & DVF_ACTIVE) == 0 || !sc->sc_open)
  448                 return (EIO);
  449 
  450         switch (cmd) {
  451         case FIONBIO:
  452                 /* All handled in the upper FS layer. */
  453                 error = 0;
  454                 break;
  455 
  456         default:
  457                 error = EINVAL;
  458                 break;
  459         }
  460         return (error);
  461 }
  462 #endif
  463 
  464 int
  465 bthcipoll(dev_t dev, int events, struct proc *p)
  466 {
  467         struct bthci_softc *sc;
  468         int revents;
  469         int s;
  470 
  471         sc = device_lookup(&bthci_cd, BTHCIUNIT(dev));
  472         if (sc == NULL)
  473                 return (ENXIO);
  474         if ((sc->sc_dev.dv_flags & DVF_ACTIVE) == 0 || !sc->sc_open)
  475                 return (EIO);
  476 
  477         revents = events & (POLLOUT | POLLWRNORM);
  478 
  479         if (events & (POLLIN | POLLRDNORM)) {
  480                 s = sc->sc_methods->bt_splraise();
  481                 if (sc->sc_outputready) {
  482                         DPRINTFN(2,("%s: have data\n", __func__));
  483                         revents |= events & (POLLIN | POLLRDNORM);
  484                 } else {
  485                         DPRINTFN(2,("%s: recording read select\n",
  486                                     __func__));
  487                         selrecord(p, &sc->sc_rd_sel);
  488                 }
  489                 splx(s);
  490         }
  491 
  492         return revents;
  493 }
  494 
  495 static void
  496 filt_bthcirdetach(struct knote *kn)
  497 {
  498         struct bthci_softc *sc = kn->kn_hook;
  499         int s;
  500 
  501         s = sc->sc_methods->bt_splraise();
  502         SLIST_REMOVE(&sc->sc_rd_sel.sel_klist, kn, knote, kn_selnext);
  503         splx(s);
  504 }
  505 
  506 /* ARGSUSED */
  507 static int
  508 filt_bthciread(struct knote *kn, long hint)
  509 {
  510         struct bthci_softc *sc = kn->kn_hook;
  511 
  512         kn->kn_data = sc->sc_rd_len;
  513         return (kn->kn_data > 0);
  514 }
  515 
  516 static const struct filterops bthciread_filtops =
  517         { 1, NULL, filt_bthcirdetach, filt_bthciread };
  518 
  519 int
  520 bthcikqfilter(dev_t dev, struct knote *kn)
  521 {
  522         struct bthci_softc *sc;
  523         struct klist *klist;
  524         int s;
  525 
  526         sc = device_lookup(&bthci_cd, BTHCIUNIT(dev));
  527         if (sc == NULL)
  528                 return (ENXIO);
  529         if ((sc->sc_dev.dv_flags & DVF_ACTIVE) == 0 || !sc->sc_open)
  530                 return (EIO);
  531 
  532         switch (kn->kn_filter) {
  533         case EVFILT_READ:
  534                 klist = &sc->sc_rd_sel.sel_klist;
  535                 kn->kn_fop = &bthciread_filtops;
  536                 break;
  537         default:
  538                 return (1);
  539         }
  540 
  541         kn->kn_hook = sc;
  542 
  543         s = sc->sc_methods->bt_splraise();
  544         SLIST_INSERT_HEAD(klist, kn, kn_selnext);
  545         splx(s);
  546 
  547         return (0);
  548 }
  549 
  550 static void
  551 bthci_recveventdata(void *h, u_int8_t *data, size_t len)
  552 {
  553         struct bthci_softc *sc = h;
  554         size_t pktlength;
  555         unsigned int ecode;
  556 
  557         if (len < BTHCI_EVENT_MIN_LEN || len > BTHCI_EVENT_MAX_LEN) {
  558                 DPRINTFN(1,("%s: invalid sized event, size=%u\n",
  559                             __func__, (unsigned int)len));
  560                 return;
  561         }
  562 
  563         ecode = data[0];
  564         DPRINTFN(1,("%s: received event: %02x (%s)\n", __func__,
  565                     ecode, bthci_eventstr(ecode)));
  566 
  567         pktlength = data[BTHCI_EVENT_LEN_OFFT] + BTHCI_EVENT_LEN_OFFT +
  568                 BTHCI_EVENT_LEN_LENGTH;
  569         if (pktlength != len) {
  570                 DPRINTFN(1,("%s: event length didn't match, "
  571                             "pktlen=%u size=%u\n",
  572                             __func__, (unsigned int)pktlength,
  573                             (unsigned int)len));
  574                 return;
  575         }
  576 
  577         if (!sc->sc_open)
  578                 return;
  579 
  580         if (sc->sc_rd_len != 0) {
  581                 DPRINTFN(1,("%s: dropping an event, size=%u\n",
  582                             __func__, (unsigned int)len));
  583                 return;
  584         }
  585 
  586         sc->sc_rd_buf[0] = BTHCI_PKTID_EVENT;
  587         memcpy(&sc->sc_rd_buf[1], data, len);
  588         sc->sc_rd_len = len + 1;
  589         sc->sc_outputready = 1;
  590 
  591         wakeup(&sc->sc_outputready);
  592         selnotify(&sc->sc_rd_sel, 0);
  593 }
  594 
  595 static void
  596 bthci_recvacldata(void *h, u_int8_t *data, size_t len)
  597 {
  598         struct bthci_softc *sc = h;
  599         size_t pktlength;
  600 
  601         if (!sc->sc_open)
  602                 return;
  603 
  604         if (len < BTHCI_ACL_DATA_MIN_LEN || len > BTHCI_ACL_DATA_MAX_LEN) {
  605                 DPRINTFN(1,("%s: invalid acl packet, size=%u\n",
  606                             __func__, (unsigned int)len));
  607                 return;
  608         }
  609 
  610         pktlength = BTGETW(&data[BTHCI_ACL_DATA_LEN_OFFT]) +
  611                 BTHCI_ACL_DATA_LEN_OFFT +
  612                 BTHCI_ACL_DATA_LEN_LENGTH;
  613 
  614         if (pktlength != len) {
  615                 DPRINTFN(1,("%s: acl packet length didn't match, "
  616                             "pktlen=%u size=%u\n",
  617                             __func__, (unsigned int)pktlength,
  618                             (unsigned int)len));
  619                 return;
  620         }
  621 
  622         if (sc->sc_rd_len != 0) {
  623                 DPRINTFN(1,("%s: dropping an acl packet, size=%u\n",
  624                             __func__, (unsigned int)len));
  625                 return;
  626         }
  627 
  628         sc->sc_rd_buf[0] = BTHCI_PKTID_ACL_DATA;
  629         memcpy(&sc->sc_rd_buf[1], data, len);
  630         sc->sc_rd_len = len + 1;
  631         sc->sc_outputready = 1;
  632 
  633         wakeup(&sc->sc_outputready);
  634         selnotify(&sc->sc_rd_sel, 0);
  635 }
  636 
  637 static void
  638 bthci_recvscodata(void *h, u_int8_t *data, size_t len)
  639 {
  640         struct bthci_softc *sc = h;
  641 
  642         if (!sc->sc_open)
  643                 return;
  644 }

Cache object: 28743c86c17ce8d183bb7e95d145bfec


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.