linux/drivers/bluetooth/hci_vhci.c
<<
>>
Prefs
   1/*
   2 *
   3 *  Bluetooth virtual HCI driver
   4 *
   5 *  Copyright (C) 2000-2001  Qualcomm Incorporated
   6 *  Copyright (C) 2002-2003  Maxim Krasnyansky <maxk@qualcomm.com>
   7 *  Copyright (C) 2004-2006  Marcel Holtmann <marcel@holtmann.org>
   8 *
   9 *
  10 *  This program is free software; you can redistribute it and/or modify
  11 *  it under the terms of the GNU General Public License as published by
  12 *  the Free Software Foundation; either version 2 of the License, or
  13 *  (at your option) any later version.
  14 *
  15 *  This program is distributed in the hope that it will be useful,
  16 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  17 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18 *  GNU General Public License for more details.
  19 *
  20 *  You should have received a copy of the GNU General Public License
  21 *  along with this program; if not, write to the Free Software
  22 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  23 *
  24 */
  25
  26#include <linux/module.h>
  27
  28#include <linux/kernel.h>
  29#include <linux/init.h>
  30#include <linux/slab.h>
  31#include <linux/types.h>
  32#include <linux/errno.h>
  33#include <linux/sched.h>
  34#include <linux/poll.h>
  35
  36#include <linux/skbuff.h>
  37#include <linux/miscdevice.h>
  38
  39#include <net/bluetooth/bluetooth.h>
  40#include <net/bluetooth/hci_core.h>
  41
  42#define VERSION "1.3"
  43
  44static bool amp;
  45
  46struct vhci_data {
  47        struct hci_dev *hdev;
  48
  49        unsigned long flags;
  50
  51        wait_queue_head_t read_wait;
  52        struct sk_buff_head readq;
  53};
  54
  55static int vhci_open_dev(struct hci_dev *hdev)
  56{
  57        set_bit(HCI_RUNNING, &hdev->flags);
  58
  59        return 0;
  60}
  61
  62static int vhci_close_dev(struct hci_dev *hdev)
  63{
  64        struct vhci_data *data = hci_get_drvdata(hdev);
  65
  66        if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
  67                return 0;
  68
  69        skb_queue_purge(&data->readq);
  70
  71        return 0;
  72}
  73
  74static int vhci_flush(struct hci_dev *hdev)
  75{
  76        struct vhci_data *data = hci_get_drvdata(hdev);
  77
  78        skb_queue_purge(&data->readq);
  79
  80        return 0;
  81}
  82
  83static int vhci_send_frame(struct sk_buff *skb)
  84{
  85        struct hci_dev* hdev = (struct hci_dev *) skb->dev;
  86        struct vhci_data *data;
  87
  88        if (!hdev) {
  89                BT_ERR("Frame for unknown HCI device (hdev=NULL)");
  90                return -ENODEV;
  91        }
  92
  93        if (!test_bit(HCI_RUNNING, &hdev->flags))
  94                return -EBUSY;
  95
  96        data = hci_get_drvdata(hdev);
  97
  98        memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
  9a>                flags);
hdev);
  50
  9a>                flags< terms of0 the GNU General Public 02 97  91        }
  79
 *  (at your opt04 97        return 0;
  14<05 97EBUSY;
          useruetooth/hci_vhci.c#La>  user class="line" name="L83">  rivers/bluetooth/hci_vhci.c#L86" id="L86" class="line" name="L86">  86       ,s="sref">EBUSY;
flags  _ useruetooth/hci_vhc_ user claL86" class="line"bustatic int (struct skb)
 0*  GNU General Public Li09 97pkt_tys="line" name="L83">  83static int vhci_send_fra/a>
   9<hdev);
 ass="line" namecounuetooth/hci_vhcicounu_fra  hree" name="L83">      MAX_FRAME_SIZE"L93">  93     MAX_FRAME_SIZE_frame(struct flags))
  72}
 *  (at your opttion)114ne" name="L50">  50
vhci_send_fra_vhci.c#L96" id="Lrefhci.alloc_push" class="srefhci.allocskb_push(flags class="liine" name="L14">  14<  92
vhci_send_frame(struct flags))

hdev);
 ush(        ass="line" namecounuetooth/hci_vhcicounu_fram">ass="line" namebustatic int   1comment">  *  GNU General Public Liicens11class="sref">hdev) {
(/a>
  191);
ENODEV;
  91        }
  50
vhci_send_fra> = (struct   9a>                  47        struct   231  50
skb_push(skb, 1), &bt   *(push(* hdev = (struct   9a>                <>/a>
  24<1span 125ne" name="L50">  50
        me/a>

  56{
(/a>
  58ooth/hci_"2ayWscounuetooth/hci_vhcicounu_fra/a>
  60}
          rivers/bluetooth/hci_vhci.c#L86" id="L86" class="line" name="L86">  86       ,s="sref">EBUSY;
  83static int vhci_send_fra, chare" name="L83">  _ useruetooth/hci_vhc_ user claL86" class="line"bustatic int   82
(struct skb)
  _ useruetooth/hci_vhc_ user claL86" class="line"ptruetooth/hci_vhcptr_fra_vhci.c#L96" id="Lrustatic int 
  82
tic int 
hdev);
13ine" name="L97">  97
tic int   48 = (struct tic int 
readq);
ne1t/blu14dev=NULL)&quo7"> ush((  86       ,97">  97
tic int , &n1et/bl141ne" name="L555555555>);
  91        }
1VERSION   50
 *  (at your optis="f14e" name="L53">  53};
bool   50
  9a>                  47   a href="+code=BT_ER4nameline" name="iverame>   .ci.c#L96" id="Lryteluxtatic int 
vhci_witch> ush(skb_push(skb, 1), &bt.c#L88" id="L88" class="line" name="L88">  1="sref">h1ci_dev *  41
  1=ef="incl1i_vhci.c#L48" id="L48" c1lass=14class="sref">hdev) {
  9a>                  47   a href="+code=BT_ER4nameline" name="iverame>   .ci.c#L96" id="Lcmdluxtatic int    ++/a>

  60}
reacasL41">  41
  1">sk_buff1_head   9a>                  47   a href="+code=BT_ER4nameline" name="iverame>   .ci.c#L96" id="Laclluxtatic int    ++/a>
flags
EBUSY;
h1ci_dev *reacasL41">  41
  1"a>struct1_vhci.c#L56" id="L56" cl1ass="15class="sref">flags  9a>                  47   a href="+code=BT_ER4nameline" name="iverame>   .ci.c#L96" id="Lscoluxtatic int    ++/a>
h1->flags
hdev);
  700">  50

        return 0;
h1ci_dev *  72}
  43
      ooth/hci_vhci.c     claL86" class="line"    ooth/hci_vhci.c     cla,s="sref">EBUSY;
flags  _ useruetooth/hci_vhc_ user claL86" class="line"bustatic int   97
poG_frame(struct hdev)
hdev1->vhci_data {
  76        struct   76
h1ass="line" name="L67">  167vhci_data {
vhci_send_fra/a>
  68
        
data1->readq);
  1#L71" id=1"L71" class="line" name=1"L71"172lass="sref">flagsvhci_send_fra struct   78        skb_queue_purge(& ush(c#L88" id="L88" class="line" name="L88">  1#ooth/hci1i_vhci.c#L73" id="L73" c1lass=17class="sref">flags          86       ,97">  97
ass="line" namebustatic int (&flags ush(        (struct flagsflags  78        skb_queue_puetooth/hci_"2ayWss="line" name="ivers/bluetooth/hci_"2ayWss="line";112_3tioref">flagshci_get_d1rvdata(flagsflagsh"sref">h1i_vhci.c#L77" id="L77" c1lass=178lass="sref">flagsflags(/a>
data1->hdev>>>>>>>>break/a>
        return 0;
  60}
flags ush(, 1), &H_HCI_RUNNIcpyO_NONBLOCKref">c#L88" id="L88" class="line" name="L88">  1etooth/hc1i_vhci.c#L82" id="L82" c1lass=183ne" name="L55555555555555555i_send_frame" cre        sk_buff *flags
flags        return 0;
skb->
vhc1i_data *flags  86       a href="+code=BT_ER4d 97  51        EBUSY;
flagsflags
  78        skb_queue_pur>/a>
hdev7"> ush(        (struct "1Frame for unknown HCI de1vice 1hdev=NULL)"
ENODEV;
  91        }
  79ush(        
->EBUSY;
      ooth/hci_vhci.c     claL86" class="line"    ooth/hci_vhci.c     cla,s="sref">EBUSY;
flags  _ useruetooth/hci_vhc_ user claL86" class="line"bustatic int   97
poG_frame(struct skb)
pkt_tys="line" name="L83">  rivers/bluetooth/hci_vhci.c#L76" id="L76" class="line" name="L76">  76        struct   76
hdev);
  700">  50
  useruetooth/hci_vhci.c#La>  user classtruct   86       ,97">  97
(&  72}
 *  (at your op204 9720ine" name="L8">  48      ooth/hci_vhci.c     claL86" class="line"    ooth/hci_vhci.c     cla,e" name="L83">  aol/_tabl+code=bt_cb" claaol/_tabl+ claL86" class="line" 51          72}
hdev)
  75{
  76        struct   76
linux/module.h>
  97
          9a>                   51        
readq);
   92  92
  78        skb_queue_pur>="sref">readq);

  91        }
  79ush(
 *  (at your op2tion)21480        return 0;
  142 */
  54
  in"> uetooth/hci_vhcin"> id="L76" class="line"in"> uetooth/hci_vhcin"> id=",5">  75{
="sref">readq);
hdev)
vhci_data {
  76       /a>
pkt_tys="line" name="L83">  .c#L7s/bluetooth/hci_vhci.c#L47" id="L47" class="line" name="L47">  47        struct   192hdev);
6" class="line" name="L76">  76        struct   rivers/bluetooth/hci_vhci.c#L86" id="m">ass="line" nameGFP_KERNELth/hci_vhci.c#LGFP_KERNELe=watooth/hci_"2ayWss="line";112_3tioref">flag2ong with 2this program; if not, wr2ite t222ev=NULL)&quo7">  92
  9a>                <>oth/hci_"2ayWss="line";112_3tioref">flag2oSoftware2le Place, Suite 330, Bos2ton, 223ne" name="L555555555>))

  232  53};
  24<2span 225ne" name="L50">  50
  78        skb_queue_pur/a>
  95
  78                flag2 THOUT AN2ude/linux/module.h" clas2s="fr22">linux/module.h>
  97
  85      " name="L83">  .c#LallocL7s/bluetooth/hci_vhci.allocL7s/ clastooth/hci_"2ayWss="line";112_3tioref">flag2 ef="incluude/linux/kernel.h" clas2s="fr22ine" name="L57">  87
  2  86       tooth/hci_"2ayWss="line";112_3tioref">flag2
  72}
  50
  9a>                  47      " name="L83">  .ne" name="L47">  47        struct  */
  95
  47   a href="+code=BT_ER4buG" class="sref">buG>      " name="L83">      VIRTUALth/hci_vhci.c#L    VIRTUAL>        struct   56{
  96        data = ass="line" name name="L86">  86       tooth/hci_"2ayWss="line";112_3tioref">flag223               return 0;
 ass="line" nameasse="L86">  86oth/hci_"2ayWss="line";112_3tioref">flag2ooth/blue2tooth.h" class="fref">ne2t/blu24dev=NULL)"  47   a href="+code=BT_ER4      AMPth/hci_vhci.c#L    AMP>        struct n2et/bl24ne" name="L60">  60}
  95
  47   a href="+code=BT_ER4iveruetooth/hci_vhciver clae="L9vhass="line" namev96        struct    50
  47   a href="+code=BT_ER42" idetooth/hci_vhcic" idne" namevhass="line" namev96 *  (at your op2is="f244ne" name="L50">  50
test_bit(bool   50
  47   a href="+code=BT_ER4nen1bluetooth/hci_vhen1 clae="L9vhass="line" namev96
vhci7"> ass="line" nameh6data =   2="sref">h2ci_dev *flagsBT_ERR(hdev) {
  86       tooth/hci_"2ayWss="line";112_3tioref">flag2     unsi2gned long data = flag2 tooth/hc2i_vhci.c#L50" id="L50" c2lass=251ne" name="L555555555>);
  94     2head_t         return 0;
sk_buff2_head   72}
  50
, 1), &  76  76       /a>
  50
 uetooth/hci_vhcin"> id=",56" class="line"    ooth/hci_vhci.c     cla>/a>

struct2_vhci.c#L56" id="L56" cl2ass="25class="sref">9">  79
h2->readq);
  54
  in"> uetooth/hci_vhcin"> id="L76" class="line"in"> uetooth/hci_vhcin"> id=",5">  75{
="sref">readq);
  2etooth/hc2i_vhci.c#L61" id="L61" c2lass=262ev=NULL)&quo">  75{
  76        struct   76
h2ci_dev *  75{
  47   9vhass="line" name name="L76">  76       a href="+code=BT_ER4ine" name="L47">  47        struct   53};
  50
data = flag2etooth/hc2i_vhci.c#L65" id="L65" c2lass=26ine" name="L95">  95
data = flag2ref">hdev2->linux/module.h>
h2ass="line" name="L67">  267  97
, 1), &  76  76        struct   68
  86       tooth/hci_"2ayWss="line";112_3tioref">flag2ref">data2->readq);
  79
        return 0;
  72}
  75{
  2tci_get_d2ci_dev *.ci.c#L96" id="Lowneruetooth/hci_vhcownerne" name="L555vhass="line" nameTHIS_MODULEuetooth/hci_vhcTHIS_MODULEid=",L88" id="L88" class="line" name="L88">  2ttooth/hc2_vhci.c#L75" id="L75" cl2ass="276lass="sref">.ci.c#L96" id="Lruetooth/hci_vhci.cruet cla name="L555vhass="line" namef="drreetooth/hci_vhci.cv96  2tef">hdev2rvdata(.ci.c#L96" id="L21" iuetooth/hci_vhc21" i claname="L555vhass="line" namef="dr21" iuetooth/hci_vhci.c#L21" i cla,L88" id="L88" class="line" name="L88">  2t"sref">h2i_vhci.c#L77" id="L77" c2lass=278lass="sref">.ci.c#L96" id="Laol/bluetooth/hci_vaol/ cla name="L555vhass="line" namef="draol/bluetooth/hci_vv96  2tef="incl2->.ci.c#L96" id="Loveruetooth/hci_vhciver clae="L9="L555vhass="line" namef="driveruetooth/hci_vhci.c#Liver cla,L88" id="L88" class="line" name="L88">  2etooth/hc2i_vhci.c#L79" id="L79" c2lass=28dev=NULL)&quo.ci.c#L96" id="Lruleaidetooth/hci_vhcireleaid clame="L555vhass="line" namef="drreleaidetooth/hci_vhcif="drreleaid cla,L88" id="L88" class="line" name="L88">  2etooth/hc2"L80" class="line" name=2"L80"281ev=NULL)&quo.ci.c#L96" id="Lllseeketooth/hci_vhcillseek clae="L9="L5vhass="line" nameno_llseeketooth/hci_vhcino_llseek cla,L88" id="L88" class="line" name="L88">  2eL71" id=2_vhci.c#L81" id="L81" cl2ass="282lass}/a>
  72}
sk_buff *  75{
  2eci_get_d2_vhci.c#L84" id="L84" cl2ass="285lass="sref">.ci.c#L96" id="Lnluetooth/hci_vhci.n83" cla"L5vhad="L89" class="line" name="L88code=BT_ERR" ,L88" id="L88" class="line" name="L88">  2etooth/hc2">skb->.ci.c#L96" id="Liopsooth/hci_vhci.ciops_fra9L5vhlass="line" name="L7v96  2eef">hdev2i_data *.ci.c#L96" id="Lminoruetooth/hci_vhcminorlass="vhass="line" nameMISC_DYNAMIC_MINO/bluetooth/hci_vMISC_DYNAMIC_MINO/_fra,L88" id="L88" class="line" name="L88">  2e"sref">h2i_vhci.c#L87" id="L87" c2lass=288lass}/a>
readq);
"2Frame for unknown HCI de2vice 29|clasname="L54">  54
="sref">readq);
  2i_vhci.c#2L91" id="L91" class="lin2e" na292ne" name="L95">  95
  95
flag2etooth/hc2i_vhci.c#L92" id="L92" c2lass=29ne" name="L72">  72}
->  79ush(flag2eci_get_d2  return -        return 0;

  54
="sref">readq);
h2i_vhci.c#L97" id="L97" c2lass=298" class="sref">skb)
  68
flag3);
        return 0;
  60}
  68
flag3<3terms o30_vhci.c#L92" id="L92" c303 9730ne" n8">  68
flag3<4terms o30/a>->  53};
  68
  86  97
flag3<6class="30_vhci.c#L95" id="L95" c306 9730ne" nass="line" nameMODULE_PARM_DESCbluetooth/hci_vMODULE_PARM_DESC classtruct   86BT_ERR(linux/module.h>
BT_ERR((  95
flag3" class="3line" name="L9">   93flag3" is free3cceived a copy of the GN3 1 97311ne" ass="line" nameMODULE_LICENSEuetooth/hci_vhcMODULE_LICENSEL89" id="L89" class="line" name=GPLcode=BT_ERR" class="sref">BT_ERR(


The original LXR software by thL41"> 41LXR commun"dy <,9this experimental _ERRion by 1"> 41lxr@eneux.no <.
lxr.eneux.no kindly hosted by 1"> 41Redpill Lnepro AS <,9provider of LneuxLconsultlin and iverme=ons ser s sinces19"5.