Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
adb35b9d
Commit
adb35b9d
authored
Feb 21, 2003
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge
bk://linux-bt.bkbits.net/bt-2.5
into home.transmeta.com:/home/torvalds/v2.5/linux
parents
b4274bcf
d5b82b88
Changes
30
Show whitespace changes
Inline
Side-by-side
Showing
30 changed files
with
1290 additions
and
331 deletions
+1290
-331
arch/sparc64/kernel/ioctl32.c
arch/sparc64/kernel/ioctl32.c
+21
-0
drivers/bluetooth/Kconfig
drivers/bluetooth/Kconfig
+33
-9
drivers/bluetooth/Makefile
drivers/bluetooth/Makefile
+1
-0
drivers/bluetooth/bluecard_cs.c
drivers/bluetooth/bluecard_cs.c
+2
-4
drivers/bluetooth/bt3c_cs.c
drivers/bluetooth/bt3c_cs.c
+2
-4
drivers/bluetooth/btuart_cs.c
drivers/bluetooth/btuart_cs.c
+903
-0
drivers/bluetooth/dtl1_cs.c
drivers/bluetooth/dtl1_cs.c
+2
-4
drivers/bluetooth/hci_ldisc.c
drivers/bluetooth/hci_ldisc.c
+4
-7
drivers/bluetooth/hci_usb.c
drivers/bluetooth/hci_usb.c
+4
-7
drivers/bluetooth/hci_vhci.c
drivers/bluetooth/hci_vhci.c
+2
-3
include/net/bluetooth/hci.h
include/net/bluetooth/hci.h
+30
-22
include/net/bluetooth/hci_core.h
include/net/bluetooth/hci_core.h
+24
-5
include/net/bluetooth/l2cap.h
include/net/bluetooth/l2cap.h
+2
-0
net/bluetooth/Kconfig
net/bluetooth/Kconfig
+7
-7
net/bluetooth/af_bluetooth.c
net/bluetooth/af_bluetooth.c
+3
-1
net/bluetooth/bnep/Kconfig
net/bluetooth/bnep/Kconfig
+2
-2
net/bluetooth/bnep/bnep.h
net/bluetooth/bnep/bnep.h
+14
-14
net/bluetooth/bnep/core.c
net/bluetooth/bnep/core.c
+37
-35
net/bluetooth/bnep/sock.c
net/bluetooth/bnep/sock.c
+12
-12
net/bluetooth/hci_conn.c
net/bluetooth/hci_conn.c
+2
-3
net/bluetooth/hci_core.c
net/bluetooth/hci_core.c
+14
-51
net/bluetooth/hci_proc.c
net/bluetooth/hci_proc.c
+3
-3
net/bluetooth/hci_sock.c
net/bluetooth/hci_sock.c
+36
-20
net/bluetooth/l2cap.c
net/bluetooth/l2cap.c
+71
-67
net/bluetooth/rfcomm/Kconfig
net/bluetooth/rfcomm/Kconfig
+1
-1
net/bluetooth/rfcomm/core.c
net/bluetooth/rfcomm/core.c
+30
-23
net/bluetooth/rfcomm/sock.c
net/bluetooth/rfcomm/sock.c
+10
-10
net/bluetooth/rfcomm/tty.c
net/bluetooth/rfcomm/tty.c
+9
-9
net/bluetooth/sco.c
net/bluetooth/sco.c
+8
-7
net/bluetooth/syms.c
net/bluetooth/syms.c
+1
-1
No files found.
arch/sparc64/kernel/ioctl32.c
View file @
adb35b9d
...
...
@@ -97,6 +97,7 @@
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci.h>
#include <net/bluetooth/rfcomm.h>
#include <linux/usb.h>
#include <linux/usbdevice_fs.h>
...
...
@@ -4264,6 +4265,15 @@ static int do_blkgetsize64(unsigned int fd, unsigned int cmd,
return
sys_ioctl
(
fd
,
BLKGETSIZE64
,
arg
);
}
/* Bluetooth ioctls */
#define HCIUARTSETPROTO _IOW('U', 200, int)
#define HCIUARTGETPROTO _IOR('U', 201, int)
#define BNEPCONNADD _IOW('B', 200, int)
#define BNEPCONNDEL _IOW('B', 201, int)
#define BNEPGETCONNLIST _IOR('B', 210, int)
#define BNEPGETCONNINFO _IOR('B', 211, int)
struct
ioctl_trans
{
unsigned
int
cmd
;
unsigned
int
handler
;
...
...
@@ -4957,6 +4967,17 @@ COMPATIBLE_IOCTL(HCISETLINKMODE)
COMPATIBLE_IOCTL
(
HCISETACLMTU
)
COMPATIBLE_IOCTL
(
HCISETSCOMTU
)
COMPATIBLE_IOCTL
(
HCIINQUIRY
)
COMPATIBLE_IOCTL
(
HCIUARTSETPROTO
)
COMPATIBLE_IOCTL
(
HCIUARTGETPROTO
)
COMPATIBLE_IOCTL
(
RFCOMMCREATEDEV
)
COMPATIBLE_IOCTL
(
RFCOMMRELEASEDEV
)
COMPATIBLE_IOCTL
(
RFCOMMGETDEVLIST
)
COMPATIBLE_IOCTL
(
RFCOMMGETDEVINFO
)
COMPATIBLE_IOCTL
(
RFCOMMSTEALDLC
)
COMPATIBLE_IOCTL
(
BNEPCONNADD
)
COMPATIBLE_IOCTL
(
BNEPCONNDEL
)
COMPATIBLE_IOCTL
(
BNEPGETCONNLIST
)
COMPATIBLE_IOCTL
(
BNEPGETCONNINFO
)
/* Misc. */
COMPATIBLE_IOCTL
(
0x41545900
)
/* ATYIO_CLKR */
COMPATIBLE_IOCTL
(
0x41545901
)
/* ATYIO_CLKW */
...
...
drivers/bluetooth/Kconfig
View file @
adb35b9d
menu "Bluetooth device drivers"
depends on BT
!=n
depends on BT
config BT_HCIUSB
tristate "HCI USB driver"
...
...
@@ -57,6 +57,14 @@ config BT_HCIUART_BCSP
Say Y here to compile support for HCI BCSP protocol.
config BT_HCIUART_BCSP_TXCRC
bool "Transmit CRC with every BCSP packet"
depends on BT_HCIUART_BCSP
help
If you say Y here, a 16-bit CRC checksum will be transmitted along with
every BCSP (BlueCore Serial Protocol) packet sent to the Bluetooth chip.
This increases reliability, but slightly reduces efficiency.
config BT_HCIDTL1
tristate "HCI DTL1 (PC Card) driver"
depends on PCMCIA && BT
...
...
@@ -73,7 +81,7 @@ config BT_HCIDTL1
config BT_HCIBT3C
tristate "HCI BT3C (PC Card) driver"
depends on PCMCIA && BT
---help---
help
Bluetooth HCI BT3C (PC Card) driver.
This driver provides support for Bluetooth PCMCIA devices with
3Com BT3C interface:
...
...
@@ -97,6 +105,22 @@ config BT_HCIBLUECARD
Anycom Bluetooth CF Card
Say Y here to compile support for HCI BlueCard devices into the
kernel or say M to compile it as module (bluecard_cs.o).
config BT_HCIBTUART
tristate "HCI UART (PC Card) device driver"
depends on PCMCIA && BT
help
Bluetooth HCI UART (PC Card) driver.
This driver provides support for Bluetooth PCMCIA devices with
an UART interface:
Xircom CreditCard Bluetooth Adapter
Xircom RealPort2 Bluetooth Adapter
Sphinx PICO Card
H-Soft blue+Card
Cyber-blue Compact Flash Card
Say Y here to compile support for HCI UART devices into the
kernel or say M to compile it as module (bluecard_cs).
config BT_HCIVHCI
...
...
drivers/bluetooth/Makefile
View file @
adb35b9d
...
...
@@ -8,6 +8,7 @@ obj-$(CONFIG_BT_HCIUART) += hci_uart.o
obj-$(CONFIG_BT_HCIDTL1)
+=
dtl1_cs.o
obj-$(CONFIG_BT_HCIBT3C)
+=
bt3c_cs.o
obj-$(CONFIG_BT_HCIBLUECARD)
+=
bluecard_cs.o
obj-$(CONFIG_BT_HCIBTUART)
+=
btuart_cs.o
hci_uart-y
:=
hci_ldisc.o
hci_uart-$(CONFIG_BT_HCIUART_H4)
+=
hci_h4.o
...
...
drivers/bluetooth/bluecard_cs.c
View file @
adb35b9d
...
...
@@ -789,6 +789,8 @@ int bluecard_open(bluecard_info_t *info)
hdev
->
destruct
=
bluecard_hci_destruct
;
hdev
->
ioctl
=
bluecard_hci_ioctl
;
hdev
->
owner
=
THIS_MODULE
;
if
(
hci_register_dev
(
hdev
)
<
0
)
{
printk
(
KERN_WARNING
"bluecard_cs: Can't register HCI device %s.
\n
"
,
hdev
->
name
);
return
-
ENODEV
;
...
...
@@ -1002,8 +1004,6 @@ void bluecard_config(dev_link_t *link)
goto
failed
;
}
MOD_INC_USE_COUNT
;
if
(
bluecard_open
(
info
)
!=
0
)
goto
failed
;
...
...
@@ -1029,8 +1029,6 @@ void bluecard_release(u_long arg)
if
(
link
->
state
&
DEV_PRESENT
)
bluecard_close
(
info
);
MOD_DEC_USE_COUNT
;
link
->
dev
=
NULL
;
CardServices
(
ReleaseConfiguration
,
link
->
handle
);
...
...
drivers/bluetooth/bt3c_cs.c
View file @
adb35b9d
...
...
@@ -546,6 +546,8 @@ int bt3c_open(bt3c_info_t *info)
hdev
->
destruct
=
bt3c_hci_destruct
;
hdev
->
ioctl
=
bt3c_hci_ioctl
;
hdev
->
owner
=
THIS_MODULE
;
if
(
hci_register_dev
(
hdev
)
<
0
)
{
printk
(
KERN_WARNING
"bt3c_cs: Can't register HCI device %s.
\n
"
,
hdev
->
name
);
return
-
ENODEV
;
...
...
@@ -788,8 +790,6 @@ void bt3c_config(dev_link_t *link)
goto
failed
;
}
MOD_INC_USE_COUNT
;
if
(
bt3c_open
(
info
)
!=
0
)
goto
failed
;
...
...
@@ -815,8 +815,6 @@ void bt3c_release(u_long arg)
if
(
link
->
state
&
DEV_PRESENT
)
bt3c_close
(
info
);
MOD_DEC_USE_COUNT
;
link
->
dev
=
NULL
;
CardServices
(
ReleaseConfiguration
,
link
->
handle
);
...
...
drivers/bluetooth/btuart_cs.c
0 → 100644
View file @
adb35b9d
/*
*
* Driver for Bluetooth PCMCIA cards with HCI UART interface
*
* Copyright (C) 2001-2002 Marcel Holtmann <marcel@holtmann.org>
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The initial developer of the original code is David A. Hinds
* <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
* are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
*
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/sched.h>
#include <linux/timer.h>
#include <linux/errno.h>
#include <linux/ptrace.h>
#include <linux/ioport.h>
#include <linux/spinlock.h>
#include <linux/skbuff.h>
#include <linux/string.h>
#include <linux/serial.h>
#include <linux/serial_reg.h>
#include <asm/system.h>
#include <asm/bitops.h>
#include <asm/io.h>
#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
#include <pcmcia/ciscode.h>
#include <pcmcia/ds.h>
#include <pcmcia/cisreg.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
/* ======================== Module parameters ======================== */
/* Bit map of interrupts to choose from */
static
u_int
irq_mask
=
0xffff
;
static
int
irq_list
[
4
]
=
{
-
1
};
MODULE_PARM
(
irq_mask
,
"i"
);
MODULE_PARM
(
irq_list
,
"1-4i"
);
MODULE_AUTHOR
(
"Marcel Holtmann <marcel@holtmann.org>"
);
MODULE_DESCRIPTION
(
"Bluetooth driver for Bluetooth PCMCIA cards with HCI UART interface"
);
MODULE_LICENSE
(
"GPL"
);
/* ======================== Local structures ======================== */
typedef
struct
btuart_info_t
{
dev_link_t
link
;
dev_node_t
node
;
struct
hci_dev
hdev
;
spinlock_t
lock
;
/* For serializing operations */
struct
sk_buff_head
txq
;
unsigned
long
tx_state
;
unsigned
long
rx_state
;
unsigned
long
rx_count
;
struct
sk_buff
*
rx_skb
;
}
btuart_info_t
;
void
btuart_config
(
dev_link_t
*
link
);
void
btuart_release
(
u_long
arg
);
int
btuart_event
(
event_t
event
,
int
priority
,
event_callback_args_t
*
args
);
static
dev_info_t
dev_info
=
"btuart_cs"
;
dev_link_t
*
btuart_attach
(
void
);
void
btuart_detach
(
dev_link_t
*
);
static
dev_link_t
*
dev_list
=
NULL
;
/* Maximum baud rate */
#define SPEED_MAX 115200
/* Default baud rate: 57600, 115200, 230400 or 460800 */
#define DEFAULT_BAUD_RATE 115200
/* Transmit states */
#define XMIT_SENDING 1
#define XMIT_WAKEUP 2
#define XMIT_WAITING 8
/* Receiver states */
#define RECV_WAIT_PACKET_TYPE 0
#define RECV_WAIT_EVENT_HEADER 1
#define RECV_WAIT_ACL_HEADER 2
#define RECV_WAIT_SCO_HEADER 3
#define RECV_WAIT_DATA 4
/* ======================== Interrupt handling ======================== */
static
int
btuart_write
(
unsigned
int
iobase
,
int
fifo_size
,
__u8
*
buf
,
int
len
)
{
int
actual
=
0
;
/* Tx FIFO should be empty */
if
(
!
(
inb
(
iobase
+
UART_LSR
)
&
UART_LSR_THRE
))
return
0
;
/* Fill FIFO with current frame */
while
((
fifo_size
--
>
0
)
&&
(
actual
<
len
))
{
/* Transmit next byte */
outb
(
buf
[
actual
],
iobase
+
UART_TX
);
actual
++
;
}
return
actual
;
}
static
void
btuart_write_wakeup
(
btuart_info_t
*
info
)
{
if
(
!
info
)
{
printk
(
KERN_WARNING
"btuart_cs: Call of write_wakeup for unknown device.
\n
"
);
return
;
}
if
(
test_and_set_bit
(
XMIT_SENDING
,
&
(
info
->
tx_state
)))
{
set_bit
(
XMIT_WAKEUP
,
&
(
info
->
tx_state
));
return
;
}
do
{
register
unsigned
int
iobase
=
info
->
link
.
io
.
BasePort1
;
register
struct
sk_buff
*
skb
;
register
int
len
;
clear_bit
(
XMIT_WAKEUP
,
&
(
info
->
tx_state
));
if
(
!
(
info
->
link
.
state
&
DEV_PRESENT
))
return
;
if
(
!
(
skb
=
skb_dequeue
(
&
(
info
->
txq
))))
break
;
/* Send frame */
len
=
btuart_write
(
iobase
,
16
,
skb
->
data
,
skb
->
len
);
set_bit
(
XMIT_WAKEUP
,
&
(
info
->
tx_state
));
if
(
len
==
skb
->
len
)
{
kfree_skb
(
skb
);
}
else
{
skb_pull
(
skb
,
len
);
skb_queue_head
(
&
(
info
->
txq
),
skb
);
}
info
->
hdev
.
stat
.
byte_tx
+=
len
;
}
while
(
test_bit
(
XMIT_WAKEUP
,
&
(
info
->
tx_state
)));
clear_bit
(
XMIT_SENDING
,
&
(
info
->
tx_state
));
}
static
void
btuart_receive
(
btuart_info_t
*
info
)
{
unsigned
int
iobase
;
int
boguscount
=
0
;
if
(
!
info
)
{
printk
(
KERN_WARNING
"btuart_cs: Call of receive for unknown device.
\n
"
);
return
;
}
iobase
=
info
->
link
.
io
.
BasePort1
;
do
{
info
->
hdev
.
stat
.
byte_rx
++
;
/* Allocate packet */
if
(
info
->
rx_skb
==
NULL
)
{
info
->
rx_state
=
RECV_WAIT_PACKET_TYPE
;
info
->
rx_count
=
0
;
if
(
!
(
info
->
rx_skb
=
bt_skb_alloc
(
HCI_MAX_FRAME_SIZE
,
GFP_ATOMIC
)))
{
printk
(
KERN_WARNING
"btuart_cs: Can't allocate mem for new packet.
\n
"
);
return
;
}
}
if
(
info
->
rx_state
==
RECV_WAIT_PACKET_TYPE
)
{
info
->
rx_skb
->
dev
=
(
void
*
)
&
(
info
->
hdev
);
info
->
rx_skb
->
pkt_type
=
inb
(
iobase
+
UART_RX
);
switch
(
info
->
rx_skb
->
pkt_type
)
{
case
HCI_EVENT_PKT
:
info
->
rx_state
=
RECV_WAIT_EVENT_HEADER
;
info
->
rx_count
=
HCI_EVENT_HDR_SIZE
;
break
;
case
HCI_ACLDATA_PKT
:
info
->
rx_state
=
RECV_WAIT_ACL_HEADER
;
info
->
rx_count
=
HCI_ACL_HDR_SIZE
;
break
;
case
HCI_SCODATA_PKT
:
info
->
rx_state
=
RECV_WAIT_SCO_HEADER
;
info
->
rx_count
=
HCI_SCO_HDR_SIZE
;
break
;
default:
/* Unknown packet */
printk
(
KERN_WARNING
"btuart_cs: Unknown HCI packet with type 0x%02x received.
\n
"
,
info
->
rx_skb
->
pkt_type
);
info
->
hdev
.
stat
.
err_rx
++
;
clear_bit
(
HCI_RUNNING
,
&
(
info
->
hdev
.
flags
));
kfree_skb
(
info
->
rx_skb
);
info
->
rx_skb
=
NULL
;
break
;
}
}
else
{
*
skb_put
(
info
->
rx_skb
,
1
)
=
inb
(
iobase
+
UART_RX
);
info
->
rx_count
--
;
if
(
info
->
rx_count
==
0
)
{
int
dlen
;
struct
hci_event_hdr
*
eh
;
struct
hci_acl_hdr
*
ah
;
struct
hci_sco_hdr
*
sh
;
switch
(
info
->
rx_state
)
{
case
RECV_WAIT_EVENT_HEADER
:
eh
=
(
struct
hci_event_hdr
*
)(
info
->
rx_skb
->
data
);
info
->
rx_state
=
RECV_WAIT_DATA
;
info
->
rx_count
=
eh
->
plen
;
break
;
case
RECV_WAIT_ACL_HEADER
:
ah
=
(
struct
hci_acl_hdr
*
)(
info
->
rx_skb
->
data
);
dlen
=
__le16_to_cpu
(
ah
->
dlen
);
info
->
rx_state
=
RECV_WAIT_DATA
;
info
->
rx_count
=
dlen
;
break
;
case
RECV_WAIT_SCO_HEADER
:
sh
=
(
struct
hci_sco_hdr
*
)(
info
->
rx_skb
->
data
);
info
->
rx_state
=
RECV_WAIT_DATA
;
info
->
rx_count
=
sh
->
dlen
;
break
;
case
RECV_WAIT_DATA
:
hci_recv_frame
(
info
->
rx_skb
);
info
->
rx_skb
=
NULL
;
break
;
}
}
}
/* Make sure we don't stay here to long */
if
(
boguscount
++
>
16
)
break
;
}
while
(
inb
(
iobase
+
UART_LSR
)
&
UART_LSR_DR
);
}
void
btuart_interrupt
(
int
irq
,
void
*
dev_inst
,
struct
pt_regs
*
regs
)
{
btuart_info_t
*
info
=
dev_inst
;
unsigned
int
iobase
;
int
boguscount
=
0
;
int
iir
,
lsr
;
if
(
!
info
)
{
printk
(
KERN_WARNING
"btuart_cs: Call of irq %d for unknown device.
\n
"
,
irq
);
return
;
}
iobase
=
info
->
link
.
io
.
BasePort1
;
spin_lock
(
&
(
info
->
lock
));
iir
=
inb
(
iobase
+
UART_IIR
)
&
UART_IIR_ID
;
while
(
iir
)
{
/* Clear interrupt */
lsr
=
inb
(
iobase
+
UART_LSR
);
switch
(
iir
)
{
case
UART_IIR_RLSI
:
printk
(
KERN_NOTICE
"btuart_cs: RLSI
\n
"
);
break
;
case
UART_IIR_RDI
:
/* Receive interrupt */
btuart_receive
(
info
);
break
;
case
UART_IIR_THRI
:
if
(
lsr
&
UART_LSR_THRE
)
{
/* Transmitter ready for data */
btuart_write_wakeup
(
info
);
}
break
;
default:
printk
(
KERN_NOTICE
"btuart_cs: Unhandled IIR=%#x
\n
"
,
iir
);
break
;
}
/* Make sure we don't stay here to long */
if
(
boguscount
++
>
100
)
break
;
iir
=
inb
(
iobase
+
UART_IIR
)
&
UART_IIR_ID
;
}
spin_unlock
(
&
(
info
->
lock
));
}
static
void
btuart_change_speed
(
btuart_info_t
*
info
,
unsigned
int
speed
)
{
unsigned
long
flags
;
unsigned
int
iobase
;
int
fcr
;
/* FIFO control reg */
int
lcr
;
/* Line control reg */
int
divisor
;
if
(
!
info
)
{
printk
(
KERN_WARNING
"btuart_cs: Call of change speed for unknown device.
\n
"
);
return
;
}
iobase
=
info
->
link
.
io
.
BasePort1
;
spin_lock_irqsave
(
&
(
info
->
lock
),
flags
);
/* Turn off interrupts */
outb
(
0
,
iobase
+
UART_IER
);
divisor
=
SPEED_MAX
/
speed
;
fcr
=
UART_FCR_ENABLE_FIFO
|
UART_FCR_CLEAR_RCVR
|
UART_FCR_CLEAR_XMIT
;
/*
* Use trigger level 1 to avoid 3 ms. timeout delay at 9600 bps, and
* almost 1,7 ms at 19200 bps. At speeds above that we can just forget
* about this timeout since it will always be fast enough.
*/
if
(
speed
<
38400
)
fcr
|=
UART_FCR_TRIGGER_1
;
else
fcr
|=
UART_FCR_TRIGGER_14
;
/* Bluetooth cards use 8N1 */
lcr
=
UART_LCR_WLEN8
;
outb
(
UART_LCR_DLAB
|
lcr
,
iobase
+
UART_LCR
);
/* Set DLAB */
outb
(
divisor
&
0xff
,
iobase
+
UART_DLL
);
/* Set speed */
outb
(
divisor
>>
8
,
iobase
+
UART_DLM
);
outb
(
lcr
,
iobase
+
UART_LCR
);
/* Set 8N1 */
outb
(
fcr
,
iobase
+
UART_FCR
);
/* Enable FIFO's */
/* Turn on interrups */
outb
(
UART_IER_RLSI
|
UART_IER_RDI
|
UART_IER_THRI
,
iobase
+
UART_IER
);
spin_unlock_irqrestore
(
&
(
info
->
lock
),
flags
);
}
/* ======================== HCI interface ======================== */
static
int
btuart_hci_flush
(
struct
hci_dev
*
hdev
)
{
btuart_info_t
*
info
=
(
btuart_info_t
*
)(
hdev
->
driver_data
);
/* Drop TX queue */
skb_queue_purge
(
&
(
info
->
txq
));
return
0
;
}
static
int
btuart_hci_open
(
struct
hci_dev
*
hdev
)
{
set_bit
(
HCI_RUNNING
,
&
(
hdev
->
flags
));
return
0
;
}
static
int
btuart_hci_close
(
struct
hci_dev
*
hdev
)
{
if
(
!
test_and_clear_bit
(
HCI_RUNNING
,
&
(
hdev
->
flags
)))
return
0
;
btuart_hci_flush
(
hdev
);
return
0
;
}
static
int
btuart_hci_send_frame
(
struct
sk_buff
*
skb
)
{
btuart_info_t
*
info
;
struct
hci_dev
*
hdev
=
(
struct
hci_dev
*
)(
skb
->
dev
);
if
(
!
hdev
)
{
printk
(
KERN_WARNING
"btuart_cs: Frame for unknown HCI device (hdev=NULL)."
);
return
-
ENODEV
;
}
info
=
(
btuart_info_t
*
)(
hdev
->
driver_data
);
switch
(
skb
->
pkt_type
)
{
case
HCI_COMMAND_PKT
:
hdev
->
stat
.
cmd_tx
++
;
break
;
case
HCI_ACLDATA_PKT
:
hdev
->
stat
.
acl_tx
++
;
break
;
case
HCI_SCODATA_PKT
:
hdev
->
stat
.
sco_tx
++
;
break
;
};
/* Prepend skb with frame type */
memcpy
(
skb_push
(
skb
,
1
),
&
(
skb
->
pkt_type
),
1
);
skb_queue_tail
(
&
(
info
->
txq
),
skb
);
btuart_write_wakeup
(
info
);
return
0
;
}
static
void
btuart_hci_destruct
(
struct
hci_dev
*
hdev
)
{
}
static
int
btuart_hci_ioctl
(
struct
hci_dev
*
hdev
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
return
-
ENOIOCTLCMD
;
}
/* ======================== Card services HCI interaction ======================== */
int
btuart_open
(
btuart_info_t
*
info
)
{
unsigned
long
flags
;
unsigned
int
iobase
=
info
->
link
.
io
.
BasePort1
;
struct
hci_dev
*
hdev
;
spin_lock_init
(
&
(
info
->
lock
));
skb_queue_head_init
(
&
(
info
->
txq
));
info
->
rx_state
=
RECV_WAIT_PACKET_TYPE
;
info
->
rx_count
=
0
;
info
->
rx_skb
=
NULL
;
spin_lock_irqsave
(
&
(
info
->
lock
),
flags
);
/* Reset UART */
outb
(
0
,
iobase
+
UART_MCR
);
/* Turn off interrupts */
outb
(
0
,
iobase
+
UART_IER
);
/* Initialize UART */
outb
(
UART_LCR_WLEN8
,
iobase
+
UART_LCR
);
/* Reset DLAB */
outb
((
UART_MCR_DTR
|
UART_MCR_RTS
|
UART_MCR_OUT2
),
iobase
+
UART_MCR
);
/* Turn on interrupts */
// outb(UART_IER_RLSI | UART_IER_RDI | UART_IER_THRI, iobase + UART_IER);
spin_unlock_irqrestore
(
&
(
info
->
lock
),
flags
);
btuart_change_speed
(
info
,
DEFAULT_BAUD_RATE
);
/* Timeout before it is safe to send the first HCI packet */
set_current_state
(
TASK_INTERRUPTIBLE
);
schedule_timeout
(
HZ
);
/* Initialize and register HCI device */
hdev
=
&
(
info
->
hdev
);
hdev
->
type
=
HCI_PCCARD
;
hdev
->
driver_data
=
info
;
hdev
->
open
=
btuart_hci_open
;
hdev
->
close
=
btuart_hci_close
;
hdev
->
flush
=
btuart_hci_flush
;
hdev
->
send
=
btuart_hci_send_frame
;
hdev
->
destruct
=
btuart_hci_destruct
;
hdev
->
ioctl
=
btuart_hci_ioctl
;
hdev
->
owner
=
THIS_MODULE
;
if
(
hci_register_dev
(
hdev
)
<
0
)
{
printk
(
KERN_WARNING
"btuart_cs: Can't register HCI device %s.
\n
"
,
hdev
->
name
);
return
-
ENODEV
;
}
return
0
;
}
int
btuart_close
(
btuart_info_t
*
info
)
{
unsigned
long
flags
;
unsigned
int
iobase
=
info
->
link
.
io
.
BasePort1
;
struct
hci_dev
*
hdev
=
&
(
info
->
hdev
);
btuart_hci_close
(
hdev
);
spin_lock_irqsave
(
&
(
info
->
lock
),
flags
);
/* Reset UART */
outb
(
0
,
iobase
+
UART_MCR
);
/* Turn off interrupts */
outb
(
0
,
iobase
+
UART_IER
);
spin_unlock_irqrestore
(
&
(
info
->
lock
),
flags
);
if
(
hci_unregister_dev
(
hdev
)
<
0
)
printk
(
KERN_WARNING
"btuart_cs: Can't unregister HCI device %s.
\n
"
,
hdev
->
name
);
return
0
;
}
/* ======================== Card services ======================== */
static
void
cs_error
(
client_handle_t
handle
,
int
func
,
int
ret
)
{
error_info_t
err
=
{
func
,
ret
};
CardServices
(
ReportError
,
handle
,
&
err
);
}
dev_link_t
*
btuart_attach
(
void
)
{
btuart_info_t
*
info
;
client_reg_t
client_reg
;
dev_link_t
*
link
;
int
i
,
ret
;
/* Create new info device */
info
=
kmalloc
(
sizeof
(
*
info
),
GFP_KERNEL
);
if
(
!
info
)
return
NULL
;
memset
(
info
,
0
,
sizeof
(
*
info
));
link
=
&
info
->
link
;
link
->
priv
=
info
;
init_timer
(
&
link
->
release
);
link
->
release
.
function
=
&
btuart_release
;
link
->
release
.
data
=
(
u_long
)
link
;
link
->
io
.
Attributes1
=
IO_DATA_PATH_WIDTH_8
;
link
->
io
.
NumPorts1
=
8
;
link
->
irq
.
Attributes
=
IRQ_TYPE_EXCLUSIVE
|
IRQ_HANDLE_PRESENT
;
link
->
irq
.
IRQInfo1
=
IRQ_INFO2_VALID
|
IRQ_LEVEL_ID
;
if
(
irq_list
[
0
]
==
-
1
)
link
->
irq
.
IRQInfo2
=
irq_mask
;
else
for
(
i
=
0
;
i
<
4
;
i
++
)
link
->
irq
.
IRQInfo2
|=
1
<<
irq_list
[
i
];
link
->
irq
.
Handler
=
btuart_interrupt
;
link
->
irq
.
Instance
=
info
;
link
->
conf
.
Attributes
=
CONF_ENABLE_IRQ
;
link
->
conf
.
Vcc
=
50
;
link
->
conf
.
IntType
=
INT_MEMORY_AND_IO
;
/* Register with Card Services */
link
->
next
=
dev_list
;
dev_list
=
link
;
client_reg
.
dev_info
=
&
dev_info
;
client_reg
.
Attributes
=
INFO_IO_CLIENT
|
INFO_CARD_SHARE
;
client_reg
.
EventMask
=
CS_EVENT_CARD_INSERTION
|
CS_EVENT_CARD_REMOVAL
|
CS_EVENT_RESET_PHYSICAL
|
CS_EVENT_CARD_RESET
|
CS_EVENT_PM_SUSPEND
|
CS_EVENT_PM_RESUME
;
client_reg
.
event_handler
=
&
btuart_event
;
client_reg
.
Version
=
0x0210
;
client_reg
.
event_callback_args
.
client_data
=
link
;
ret
=
CardServices
(
RegisterClient
,
&
link
->
handle
,
&
client_reg
);
if
(
ret
!=
CS_SUCCESS
)
{
cs_error
(
link
->
handle
,
RegisterClient
,
ret
);
btuart_detach
(
link
);
return
NULL
;
}
return
link
;
}
void
btuart_detach
(
dev_link_t
*
link
)
{
btuart_info_t
*
info
=
link
->
priv
;
dev_link_t
**
linkp
;
int
ret
;
/* Locate device structure */
for
(
linkp
=
&
dev_list
;
*
linkp
;
linkp
=
&
(
*
linkp
)
->
next
)
if
(
*
linkp
==
link
)
break
;
if
(
*
linkp
==
NULL
)
return
;
del_timer
(
&
link
->
release
);
if
(
link
->
state
&
DEV_CONFIG
)
btuart_release
((
u_long
)
link
);
if
(
link
->
handle
)
{
ret
=
CardServices
(
DeregisterClient
,
link
->
handle
);
if
(
ret
!=
CS_SUCCESS
)
cs_error
(
link
->
handle
,
DeregisterClient
,
ret
);
}
/* Unlink device structure, free bits */
*
linkp
=
link
->
next
;
kfree
(
info
);
}
static
int
get_tuple
(
int
fn
,
client_handle_t
handle
,
tuple_t
*
tuple
,
cisparse_t
*
parse
)
{
int
i
;
i
=
CardServices
(
fn
,
handle
,
tuple
);
if
(
i
!=
CS_SUCCESS
)
return
CS_NO_MORE_ITEMS
;
i
=
CardServices
(
GetTupleData
,
handle
,
tuple
);
if
(
i
!=
CS_SUCCESS
)
return
i
;
return
CardServices
(
ParseTuple
,
handle
,
tuple
,
parse
);
}
#define first_tuple(a, b, c) get_tuple(GetFirstTuple, a, b, c)
#define next_tuple(a, b, c) get_tuple(GetNextTuple, a, b, c)
void
btuart_config
(
dev_link_t
*
link
)
{
static
ioaddr_t
base
[
5
]
=
{
0x3f8
,
0x2f8
,
0x3e8
,
0x2e8
,
0x0
};
client_handle_t
handle
=
link
->
handle
;
btuart_info_t
*
info
=
link
->
priv
;
tuple_t
tuple
;
u_short
buf
[
256
];
cisparse_t
parse
;
cistpl_cftable_entry_t
*
cf
=
&
parse
.
cftable_entry
;
config_info_t
config
;
int
i
,
j
,
try
,
last_ret
,
last_fn
;
tuple
.
TupleData
=
(
cisdata_t
*
)
buf
;
tuple
.
TupleOffset
=
0
;
tuple
.
TupleDataMax
=
255
;
tuple
.
Attributes
=
0
;
/* Get configuration register information */
tuple
.
DesiredTuple
=
CISTPL_CONFIG
;
last_ret
=
first_tuple
(
handle
,
&
tuple
,
&
parse
);
if
(
last_ret
!=
CS_SUCCESS
)
{
last_fn
=
ParseTuple
;
goto
cs_failed
;
}
link
->
conf
.
ConfigBase
=
parse
.
config
.
base
;
link
->
conf
.
Present
=
parse
.
config
.
rmask
[
0
];
/* Configure card */
link
->
state
|=
DEV_CONFIG
;
i
=
CardServices
(
GetConfigurationInfo
,
handle
,
&
config
);
link
->
conf
.
Vcc
=
config
.
Vcc
;
/* First pass: look for a config entry that looks normal. */
tuple
.
TupleData
=
(
cisdata_t
*
)
buf
;
tuple
.
TupleOffset
=
0
;
tuple
.
TupleDataMax
=
255
;
tuple
.
Attributes
=
0
;
tuple
.
DesiredTuple
=
CISTPL_CFTABLE_ENTRY
;
/* Two tries: without IO aliases, then with aliases */
for
(
try
=
0
;
try
<
2
;
try
++
)
{
i
=
first_tuple
(
handle
,
&
tuple
,
&
parse
);
while
(
i
!=
CS_NO_MORE_ITEMS
)
{
if
(
i
!=
CS_SUCCESS
)
goto
next_entry
;
if
(
cf
->
vpp1
.
present
&
(
1
<<
CISTPL_POWER_VNOM
))
link
->
conf
.
Vpp1
=
link
->
conf
.
Vpp2
=
cf
->
vpp1
.
param
[
CISTPL_POWER_VNOM
]
/
10000
;
if
((
cf
->
io
.
nwin
>
0
)
&&
(
cf
->
io
.
win
[
0
].
len
==
8
)
&&
(
cf
->
io
.
win
[
0
].
base
!=
0
))
{
link
->
conf
.
ConfigIndex
=
cf
->
index
;
link
->
io
.
BasePort1
=
cf
->
io
.
win
[
0
].
base
;
link
->
io
.
IOAddrLines
=
(
try
==
0
)
?
16
:
cf
->
io
.
flags
&
CISTPL_IO_LINES_MASK
;
i
=
CardServices
(
RequestIO
,
link
->
handle
,
&
link
->
io
);
if
(
i
==
CS_SUCCESS
)
goto
found_port
;
}
next_entry:
i
=
next_tuple
(
handle
,
&
tuple
,
&
parse
);
}
}
/* Second pass: try to find an entry that isn't picky about
its base address, then try to grab any standard serial port
address, and finally try to get any free port. */
i
=
first_tuple
(
handle
,
&
tuple
,
&
parse
);
while
(
i
!=
CS_NO_MORE_ITEMS
)
{
if
((
i
==
CS_SUCCESS
)
&&
(
cf
->
io
.
nwin
>
0
)
&&
((
cf
->
io
.
flags
&
CISTPL_IO_LINES_MASK
)
<=
3
))
{
link
->
conf
.
ConfigIndex
=
cf
->
index
;
for
(
j
=
0
;
j
<
5
;
j
++
)
{
link
->
io
.
BasePort1
=
base
[
j
];
link
->
io
.
IOAddrLines
=
base
[
j
]
?
16
:
3
;
i
=
CardServices
(
RequestIO
,
link
->
handle
,
&
link
->
io
);
if
(
i
==
CS_SUCCESS
)
goto
found_port
;
}
}
i
=
next_tuple
(
handle
,
&
tuple
,
&
parse
);
}
found_port:
if
(
i
!=
CS_SUCCESS
)
{
printk
(
KERN_NOTICE
"btuart_cs: No usable port range found. Giving up.
\n
"
);
cs_error
(
link
->
handle
,
RequestIO
,
i
);
goto
failed
;
}
i
=
CardServices
(
RequestIRQ
,
link
->
handle
,
&
link
->
irq
);
if
(
i
!=
CS_SUCCESS
)
{
cs_error
(
link
->
handle
,
RequestIRQ
,
i
);
link
->
irq
.
AssignedIRQ
=
0
;
}
i
=
CardServices
(
RequestConfiguration
,
link
->
handle
,
&
link
->
conf
);
if
(
i
!=
CS_SUCCESS
)
{
cs_error
(
link
->
handle
,
RequestConfiguration
,
i
);
goto
failed
;
}
if
(
btuart_open
(
info
)
!=
0
)
goto
failed
;
strcpy
(
info
->
node
.
dev_name
,
info
->
hdev
.
name
);
link
->
dev
=
&
info
->
node
;
link
->
state
&=
~
DEV_CONFIG_PENDING
;
return
;
cs_failed:
cs_error
(
link
->
handle
,
last_fn
,
last_ret
);
failed:
btuart_release
((
u_long
)
link
);
}
void
btuart_release
(
u_long
arg
)
{
dev_link_t
*
link
=
(
dev_link_t
*
)
arg
;
btuart_info_t
*
info
=
link
->
priv
;
if
(
link
->
state
&
DEV_PRESENT
)
btuart_close
(
info
);
link
->
dev
=
NULL
;
CardServices
(
ReleaseConfiguration
,
link
->
handle
);
CardServices
(
ReleaseIO
,
link
->
handle
,
&
link
->
io
);
CardServices
(
ReleaseIRQ
,
link
->
handle
,
&
link
->
irq
);
link
->
state
&=
~
DEV_CONFIG
;
}
int
btuart_event
(
event_t
event
,
int
priority
,
event_callback_args_t
*
args
)
{
dev_link_t
*
link
=
args
->
client_data
;
btuart_info_t
*
info
=
link
->
priv
;
switch
(
event
)
{
case
CS_EVENT_CARD_REMOVAL
:
link
->
state
&=
~
DEV_PRESENT
;
if
(
link
->
state
&
DEV_CONFIG
)
{
btuart_close
(
info
);
mod_timer
(
&
link
->
release
,
jiffies
+
HZ
/
20
);
}
break
;
case
CS_EVENT_CARD_INSERTION
:
link
->
state
|=
DEV_PRESENT
|
DEV_CONFIG_PENDING
;
btuart_config
(
link
);
break
;
case
CS_EVENT_PM_SUSPEND
:
link
->
state
|=
DEV_SUSPEND
;
/* Fall through... */
case
CS_EVENT_RESET_PHYSICAL
:
if
(
link
->
state
&
DEV_CONFIG
)
CardServices
(
ReleaseConfiguration
,
link
->
handle
);
break
;
case
CS_EVENT_PM_RESUME
:
link
->
state
&=
~
DEV_SUSPEND
;
/* Fall through... */
case
CS_EVENT_CARD_RESET
:
if
(
DEV_OK
(
link
))
CardServices
(
RequestConfiguration
,
link
->
handle
,
&
link
->
conf
);
break
;
}
return
0
;
}
/* ======================== Module initialization ======================== */
int
__init
init_btuart_cs
(
void
)
{
servinfo_t
serv
;
int
err
;
CardServices
(
GetCardServicesInfo
,
&
serv
);
if
(
serv
.
Revision
!=
CS_RELEASE_CODE
)
{
printk
(
KERN_NOTICE
"btuart_cs: Card Services release does not match!
\n
"
);
return
-
1
;
}
err
=
register_pccard_driver
(
&
dev_info
,
&
btuart_attach
,
&
btuart_detach
);
return
err
;
}
void
__exit
exit_btuart_cs
(
void
)
{
unregister_pccard_driver
(
&
dev_info
);
while
(
dev_list
!=
NULL
)
btuart_detach
(
dev_list
);
}
module_init
(
init_btuart_cs
);
module_exit
(
exit_btuart_cs
);
drivers/bluetooth/dtl1_cs.c
View file @
adb35b9d
...
...
@@ -520,6 +520,8 @@ int dtl1_open(dtl1_info_t *info)
hdev
->
destruct
=
dtl1_hci_destruct
;
hdev
->
ioctl
=
dtl1_hci_ioctl
;
hdev
->
owner
=
THIS_MODULE
;
if
(
hci_register_dev
(
hdev
)
<
0
)
{
printk
(
KERN_WARNING
"dtl1_cs: Can't register HCI device %s.
\n
"
,
hdev
->
name
);
return
-
ENODEV
;
...
...
@@ -747,8 +749,6 @@ void dtl1_config(dev_link_t *link)
goto
failed
;
}
MOD_INC_USE_COUNT
;
if
(
dtl1_open
(
info
)
!=
0
)
goto
failed
;
...
...
@@ -774,8 +774,6 @@ void dtl1_release(u_long arg)
if
(
link
->
state
&
DEV_PRESENT
)
dtl1_close
(
info
);
MOD_DEC_USE_COUNT
;
link
->
dev
=
NULL
;
CardServices
(
ReleaseConfiguration
,
link
->
handle
);
...
...
drivers/bluetooth/hci_ldisc.c
View file @
adb35b9d
...
...
@@ -250,8 +250,6 @@ static void hci_uart_destruct(struct hci_dev *hdev)
hu
=
(
struct
hci_uart
*
)
hdev
->
driver_data
;
kfree
(
hu
);
MOD_DEC_USE_COUNT
;
}
/* ------ LDISC part ------ */
...
...
@@ -291,7 +289,6 @@ static int hci_uart_tty_open(struct tty_struct *tty)
if
(
tty
->
driver
.
flush_buffer
)
tty
->
driver
.
flush_buffer
(
tty
);
MOD_INC_USE_COUNT
;
return
0
;
}
...
...
@@ -317,8 +314,6 @@ static void hci_uart_tty_close(struct tty_struct *tty)
hu
->
proto
->
close
(
hu
);
hci_unregister_dev
(
hdev
);
}
MOD_DEC_USE_COUNT
;
}
}
...
...
@@ -411,11 +406,13 @@ static int hci_uart_register_dev(struct hci_uart *hu)
hdev
->
send
=
hci_uart_send_frame
;
hdev
->
destruct
=
hci_uart_destruct
;
hdev
->
owner
=
THIS_MODULE
;
if
(
hci_register_dev
(
hdev
)
<
0
)
{
BT_ERR
(
"Can't register HCI device %s"
,
hdev
->
name
);
return
-
ENODEV
;
}
MOD_INC_USE_COUNT
;
return
0
;
}
...
...
drivers/bluetooth/hci_usb.c
View file @
adb35b9d
...
...
@@ -207,18 +207,15 @@ static int hci_usb_open(struct hci_dev *hdev)
if
(
test_and_set_bit
(
HCI_RUNNING
,
&
hdev
->
flags
))
return
0
;
MOD_INC_USE_COUNT
;
write_lock_irqsave
(
&
husb
->
completion_lock
,
flags
);
err
=
hci_usb_enable_intr
(
husb
);
if
(
!
err
)
{
for
(
i
=
0
;
i
<
HCI_MAX_BULK_RX
;
i
++
)
hci_usb_rx_submit
(
husb
,
NULL
);
}
else
{
}
else
clear_bit
(
HCI_RUNNING
,
&
hdev
->
flags
);
MOD_DEC_USE_COUNT
;
}
write_unlock_irqrestore
(
&
husb
->
completion_lock
,
flags
);
return
err
;
...
...
@@ -271,8 +268,6 @@ static int hci_usb_close(struct hci_dev *hdev)
hci_usb_flush
(
hdev
);
write_unlock_irqrestore
(
&
husb
->
completion_lock
,
flags
);
MOD_DEC_USE_COUNT
;
return
0
;
}
...
...
@@ -758,6 +753,8 @@ int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
hdev
->
send
=
hci_usb_send_frame
;
hdev
->
destruct
=
hci_usb_destruct
;
hdev
->
owner
=
THIS_MODULE
;
if
(
hci_register_dev
(
hdev
)
<
0
)
{
BT_ERR
(
"Can't register HCI device"
);
goto
probe_error
;
...
...
drivers/bluetooth/hci_vhci.c
View file @
adb35b9d
...
...
@@ -84,8 +84,6 @@ static void hci_vhci_destruct(struct hci_dev *hdev)
vhci
=
(
struct
hci_vhci_struct
*
)
hdev
->
driver_data
;
kfree
(
vhci
);
MOD_DEC_USE_COUNT
;
}
static
int
hci_vhci_send_frame
(
struct
sk_buff
*
skb
)
...
...
@@ -288,11 +286,12 @@ static int hci_vhci_chr_open(struct inode *inode, struct file * file)
hdev
->
send
=
hci_vhci_send_frame
;
hdev
->
destruct
=
hci_vhci_destruct
;
hdev
->
owner
=
THIS_MODULE
;
if
(
hci_register_dev
(
hdev
)
<
0
)
{
kfree
(
hci_vhci
);
return
-
EBUSY
;
}
MOD_INC_USE_COUNT
;
file
->
private_data
=
hci_vhci
;
return
0
;
...
...
include/net/bluetooth/hci.h
View file @
adb35b9d
...
...
@@ -48,6 +48,7 @@
#define HCI_PCCARD 2
#define HCI_UART 3
#define HCI_RS232 4
#define HCI_PCI 5
/* HCI device flags */
enum
{
...
...
@@ -84,6 +85,7 @@ enum {
#define HCISETLINKMODE _IOW('H', 226, int)
#define HCISETACLMTU _IOW('H', 227, int)
#define HCISETSCOMTU _IOW('H', 228, int)
#define HCISETRAWVND _IOW('H', 229, int)
#define HCIINQUIRY _IOR('H', 240, int)
...
...
@@ -385,6 +387,12 @@ struct hci_rp_write_link_policy {
/* Status params */
#define OGF_STATUS_PARAM 0x05
/* Testing commands */
#define OGF_TESTING_CMD 0x3E
/* Vendor specific commands */
#define OGF_VENDOR_CMD 0x3F
/* ---- HCI Events ---- */
#define HCI_EV_INQUIRY_COMPLETE 0x01
...
...
include/net/bluetooth/hci_core.h
View file @
adb35b9d
...
...
@@ -118,6 +118,8 @@ struct hci_dev {
struct
proc_dir_entry
*
proc
;
#endif
struct
module
*
owner
;
int
(
*
open
)(
struct
hci_dev
*
hdev
);
int
(
*
close
)(
struct
hci_dev
*
hdev
);
int
(
*
flush
)(
struct
hci_dev
*
hdev
);
...
...
@@ -299,12 +301,30 @@ static inline void hci_sched_tx(struct hci_dev *hdev)
}
/* ----- HCI Devices ----- */
static
inline
void
hci_dev_put
(
struct
hci_dev
*
d
)
static
inline
void
__
hci_dev_put
(
struct
hci_dev
*
d
)
{
if
(
atomic_dec_and_test
(
&
d
->
refcnt
))
d
->
destruct
(
d
);
}
#define hci_dev_hold(d) atomic_inc(&d->refcnt)
static
inline
void
hci_dev_put
(
struct
hci_dev
*
d
)
{
__hci_dev_put
(
d
);
module_put
(
d
->
owner
);
}
static
inline
struct
hci_dev
*
__hci_dev_hold
(
struct
hci_dev
*
d
)
{
atomic_inc
(
&
d
->
refcnt
);
return
d
;
}
static
inline
struct
hci_dev
*
hci_dev_hold
(
struct
hci_dev
*
d
)
{
if
(
try_module_get
(
d
->
owner
))
return
__hci_dev_hold
(
d
);
return
NULL
;
}
#define hci_dev_lock(d) spin_lock(&d->lock)
#define hci_dev_unlock(d) spin_unlock(&d->lock)
...
...
@@ -452,7 +472,6 @@ int hci_unregister_notifier(struct notifier_block *nb);
int
hci_send_cmd
(
struct
hci_dev
*
hdev
,
__u16
ogf
,
__u16
ocf
,
__u32
plen
,
void
*
param
);
int
hci_send_acl
(
struct
hci_conn
*
conn
,
struct
sk_buff
*
skb
,
__u16
flags
);
int
hci_send_sco
(
struct
hci_conn
*
conn
,
struct
sk_buff
*
skb
);
int
hci_send_raw
(
struct
sk_buff
*
skb
);
void
*
hci_sent_cmd_data
(
struct
hci_dev
*
hdev
,
__u16
ogf
,
__u16
ocf
);
...
...
@@ -470,7 +489,7 @@ struct hci_pinfo {
};
/* HCI security filter */
#define HCI_SFLT_MAX_OGF
4
#define HCI_SFLT_MAX_OGF
5
struct
hci_sec_filter
{
unsigned
long
type_mask
;
...
...
include/net/bluetooth/l2cap.h
View file @
adb35b9d
...
...
@@ -224,6 +224,8 @@ struct l2cap_pinfo {
__u8
ident
;
__u16
sport
;
struct
l2cap_conn
*
conn
;
struct
sock
*
next_c
;
struct
sock
*
prev_c
;
...
...
net/bluetooth/Kconfig
View file @
adb35b9d
...
...
@@ -7,7 +7,7 @@ menu "Bluetooth support"
config BT
tristate "Bluetooth subsystem support"
---help---
help
Bluetooth is low-cost, low-power, short-range wireless technology.
It was designed as a replacement for cables and other short-range
technologies like IrDA. Bluetooth operates in personal area range
...
...
net/bluetooth/af_bluetooth.c
View file @
adb35b9d
...
...
@@ -335,6 +335,8 @@ static int __init bt_init(void)
BT_INFO
(
"Core ver %s"
,
VERSION
);
proc_bt
=
proc_mkdir
(
"bluetooth"
,
NULL
);
if
(
proc_bt
)
proc_bt
->
owner
=
THIS_MODULE
;
/* Init socket cache */
bt_sock_cache
=
kmem_cache_create
(
"bt_sock"
,
...
...
net/bluetooth/bnep/Kconfig
View file @
adb35b9d
config BT_BNEP
tristate "BNEP protocol support"
depends on BT_L2CAP
---help---
depends on BT
&& BT
_L2CAP
help
BNEP (Bluetooth Network Encapsulation Protocol) is Ethernet
emulation layer on top of Bluetooth. BNEP is required for Bluetooth
PAN (Personal Area Network).
...
...
net/bluetooth/bnep/bnep.h
View file @
adb35b9d
...
...
@@ -111,25 +111,25 @@ struct bnep_ext_hdr {
__u8
data
[
0
];
}
__attribute__
((
packed
));
/
/ Ioctl interface
#define BNEPCON
ADD 1
#define BNEPCON
DEL 2
#define BNEPGETCON
LIST 3
#define BNEPGETCON
INFO 4
/
* BNEP ioctl defines */
#define BNEPCON
NADD _IOW('B', 200, int)
#define BNEPCON
NDEL _IOW('B', 201, int)
#define BNEPGETCON
NLIST _IOR('B', 210, int)
#define BNEPGETCON
NINFO _IOR('B', 211, int)
struct
bnep_conadd_req
{
struct
bnep_con
n
add_req
{
int
sock
;
// Connected socket
__u32
flags
;
__u16
role
;
char
device
[
16
];
// Name of the Ethernet device
};
struct
bnep_condel_req
{
struct
bnep_con
n
del_req
{
__u32
flags
;
__u8
dst
[
ETH_ALEN
];
};
struct
bnep_coninfo
{
struct
bnep_con
n
info
{
__u32
flags
;
__u16
role
;
__u16
state
;
...
...
@@ -137,9 +137,9 @@ struct bnep_coninfo {
char
device
[
16
];
};
struct
bnep_conlist_req
{
struct
bnep_con
n
list_req
{
__u32
cnum
;
struct
bnep_coninfo
*
ci
;
struct
bnep_con
n
info
*
ci
;
};
struct
bnep_proto_filter
{
...
...
@@ -147,10 +147,10 @@ struct bnep_proto_filter {
__u16
end
;
};
int
bnep_add_connection
(
struct
bnep_conadd_req
*
req
,
struct
socket
*
sock
);
int
bnep_del_connection
(
struct
bnep_condel_req
*
req
);
int
bnep_get_con
list
(
struct
bnep_co
nlist_req
*
req
);
int
bnep_get_con
info
(
struct
bnep_co
ninfo
*
ci
);
int
bnep_add_connection
(
struct
bnep_con
n
add_req
*
req
,
struct
socket
*
sock
);
int
bnep_del_connection
(
struct
bnep_con
n
del_req
*
req
);
int
bnep_get_con
nlist
(
struct
bnep_con
nlist_req
*
req
);
int
bnep_get_con
ninfo
(
struct
bnep_con
ninfo
*
ci
);
// BNEP sessions
struct
bnep_session
{
...
...
net/bluetooth/bnep/core.c
View file @
adb35b9d
...
...
@@ -128,18 +128,17 @@ static int bnep_send_rsp(struct bnep_session *s, u8 ctrl, u16 resp)
return
bnep_send
(
s
,
&
rsp
,
sizeof
(
rsp
));
}
static
int
bnep_ctrl_set_netfilter
(
struct
bnep_session
*
s
,
struct
sk_buff
*
skb
)
static
int
bnep_ctrl_set_netfilter
(
struct
bnep_session
*
s
,
u16
*
data
,
int
len
)
{
u16
*
data
;
int
n
;
data
=
(
void
*
)
skb
->
data
;
if
(
!
skb_pull
(
skb
,
2
))
if
(
len
<
2
)
return
-
EILSEQ
;
n
=
ntohs
(
get_unaligned
(
data
));
data
++
;
len
-=
2
;
data
=
(
void
*
)
skb
->
data
;
if
(
!
skb_pull
(
skb
,
n
))
if
(
len
<
n
)
return
-
EILSEQ
;
BT_DBG
(
"filter len %d"
,
n
);
...
...
@@ -170,18 +169,17 @@ static int bnep_ctrl_set_netfilter(struct bnep_session *s, struct sk_buff *skb)
return
0
;
}
static
int
bnep_ctrl_set_mcfilter
(
struct
bnep_session
*
s
,
struct
sk_buff
*
skb
)
static
int
bnep_ctrl_set_mcfilter
(
struct
bnep_session
*
s
,
u8
*
data
,
int
len
)
{
u8
*
data
;
int
n
;
data
=
(
void
*
)
skb
->
data
;
if
(
!
skb_pull
(
skb
,
2
))
if
(
len
<
2
)
return
-
EILSEQ
;
n
=
ntohs
(
get_unaligned
((
u16
*
)
data
));
data
+=
2
;
len
-=
2
;
data
=
(
void
*
)
skb
->
data
;
if
(
!
skb_pull
(
skb
,
n
))
if
(
len
<
n
)
return
-
EILSEQ
;
BT_DBG
(
"filter len %d"
,
n
);
...
...
@@ -225,11 +223,12 @@ static int bnep_ctrl_set_mcfilter(struct bnep_session *s, struct sk_buff *skb)
return
0
;
}
static
int
bnep_rx_control
(
struct
bnep_session
*
s
,
struct
sk_buff
*
skb
)
static
int
bnep_rx_control
(
struct
bnep_session
*
s
,
void
*
data
,
int
len
)
{
u8
cmd
=
*
(
u8
*
)
data
;
int
err
=
0
;
u8
cmd
=
*
(
u8
*
)
skb
->
data
;
skb_pull
(
skb
,
1
)
;
data
++
;
len
--
;
switch
(
cmd
)
{
case
BNEP_CMD_NOT_UNDERSTOOD
:
...
...
@@ -241,11 +240,11 @@ static int bnep_rx_control(struct bnep_session *s, struct sk_buff *skb)
break
;
case
BNEP_FILTER_NET_TYPE_SET
:
err
=
bnep_ctrl_set_netfilter
(
s
,
skb
);
err
=
bnep_ctrl_set_netfilter
(
s
,
data
,
len
);
break
;
case
BNEP_FILTER_MULTI_ADDR_SET
:
err
=
bnep_ctrl_set_mcfilter
(
s
,
skb
);
err
=
bnep_ctrl_set_mcfilter
(
s
,
data
,
len
);
break
;
default:
{
...
...
@@ -277,12 +276,15 @@ static int bnep_rx_extension(struct bnep_session *s, struct sk_buff *skb)
switch
(
h
->
type
&
BNEP_TYPE_MASK
)
{
case
BNEP_EXT_CONTROL
:
err
=
bnep_rx_control
(
s
,
skb
);
bnep_rx_control
(
s
,
skb
->
data
,
skb
->
len
);
break
;
default:
/* Unknown extension */
if
(
!
skb_pull
(
skb
,
h
->
len
))
/* Unknown extension, skip it. */
break
;
}
if
(
!
skb_pull
(
skb
,
h
->
len
))
{
err
=
-
EILSEQ
;
break
;
}
...
...
@@ -315,7 +317,7 @@ static inline int bnep_rx_frame(struct bnep_session *s, struct sk_buff *skb)
goto
badframe
;
if
((
type
&
BNEP_TYPE_MASK
)
==
BNEP_CONTROL
)
{
bnep_rx_control
(
s
,
skb
);
bnep_rx_control
(
s
,
skb
->
data
,
skb
->
len
);
kfree_skb
(
skb
);
return
0
;
}
...
...
@@ -525,7 +527,7 @@ static int bnep_session(void *arg)
return
0
;
}
int
bnep_add_connection
(
struct
bnep_conadd_req
*
req
,
struct
socket
*
sock
)
int
bnep_add_connection
(
struct
bnep_con
n
add_req
*
req
,
struct
socket
*
sock
)
{
struct
net_device
*
dev
;
struct
bnep_session
*
s
,
*
ss
;
...
...
@@ -616,7 +618,7 @@ int bnep_add_connection(struct bnep_conadd_req *req, struct socket *sock)
return
err
;
}
int
bnep_del_connection
(
struct
bnep_condel_req
*
req
)
int
bnep_del_connection
(
struct
bnep_con
n
del_req
*
req
)
{
struct
bnep_session
*
s
;
int
err
=
0
;
...
...
@@ -641,7 +643,7 @@ int bnep_del_connection(struct bnep_condel_req *req)
return
err
;
}
static
void
__bnep_copy_ci
(
struct
bnep_coninfo
*
ci
,
struct
bnep_session
*
s
)
static
void
__bnep_copy_ci
(
struct
bnep_con
n
info
*
ci
,
struct
bnep_session
*
s
)
{
memcpy
(
ci
->
dst
,
s
->
eh
.
h_source
,
ETH_ALEN
);
strcpy
(
ci
->
device
,
s
->
dev
.
name
);
...
...
@@ -650,7 +652,7 @@ static void __bnep_copy_ci(struct bnep_coninfo *ci, struct bnep_session *s)
ci
->
role
=
s
->
role
;
}
int
bnep_get_con
list
(
struct
bnep_co
nlist_req
*
req
)
int
bnep_get_con
nlist
(
struct
bnep_con
nlist_req
*
req
)
{
struct
list_head
*
p
;
int
err
=
0
,
n
=
0
;
...
...
@@ -659,7 +661,7 @@ int bnep_get_conlist(struct bnep_conlist_req *req)
list_for_each
(
p
,
&
bnep_session_list
)
{
struct
bnep_session
*
s
;
struct
bnep_coninfo
ci
;
struct
bnep_con
n
info
ci
;
s
=
list_entry
(
p
,
struct
bnep_session
,
list
);
...
...
@@ -681,7 +683,7 @@ int bnep_get_conlist(struct bnep_conlist_req *req)
return
err
;
}
int
bnep_get_con
info
(
struct
bnep_co
ninfo
*
ci
)
int
bnep_get_con
ninfo
(
struct
bnep_con
ninfo
*
ci
)
{
struct
bnep_session
*
s
;
int
err
=
0
;
...
...
net/bluetooth/bnep/sock.c
View file @
adb35b9d
...
...
@@ -73,17 +73,17 @@ static int bnep_sock_release(struct socket *sock)
static
int
bnep_sock_ioctl
(
struct
socket
*
sock
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
struct
bnep_conlist_req
cl
;
struct
bnep_conadd_req
ca
;
struct
bnep_condel_req
cd
;
struct
bnep_coninfo
ci
;
struct
bnep_con
n
list_req
cl
;
struct
bnep_con
n
add_req
ca
;
struct
bnep_con
n
del_req
cd
;
struct
bnep_con
n
info
ci
;
struct
socket
*
nsock
;
int
err
;
BT_DBG
(
"cmd %x arg %lx"
,
cmd
,
arg
);
switch
(
cmd
)
{
case
BNEPCONADD
:
case
BNEPCON
N
ADD
:
if
(
!
capable
(
CAP_NET_ADMIN
))
return
-
EACCES
;
...
...
@@ -106,7 +106,7 @@ static int bnep_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long
return
err
;
case
BNEPCONDEL
:
case
BNEPCON
N
DEL
:
if
(
!
capable
(
CAP_NET_ADMIN
))
return
-
EACCES
;
...
...
@@ -115,24 +115,24 @@ static int bnep_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long
return
bnep_del_connection
(
&
cd
);
case
BNEPGETCONLIST
:
case
BNEPGETCON
N
LIST
:
if
(
copy_from_user
(
&
cl
,
(
void
*
)
arg
,
sizeof
(
cl
)))
return
-
EFAULT
;
if
(
cl
.
cnum
<=
0
)
return
-
EINVAL
;
err
=
bnep_get_conlist
(
&
cl
);
err
=
bnep_get_con
n
list
(
&
cl
);
if
(
!
err
&&
copy_to_user
((
void
*
)
arg
,
&
cl
,
sizeof
(
cl
)))
return
-
EFAULT
;
return
err
;
case
BNEPGETCONINFO
:
case
BNEPGETCON
N
INFO
:
if
(
copy_from_user
(
&
ci
,
(
void
*
)
arg
,
sizeof
(
ci
)))
return
-
EFAULT
;
err
=
bnep_get_coninfo
(
&
ci
);
err
=
bnep_get_con
n
info
(
&
ci
);
if
(
!
err
&&
copy_to_user
((
void
*
)
arg
,
&
ci
,
sizeof
(
ci
)))
return
-
EFAULT
;
...
...
@@ -192,13 +192,13 @@ static struct net_proto_family bnep_sock_family_ops = {
.
create
=
bnep_sock_create
};
int
bnep_sock_init
(
void
)
int
__init
bnep_sock_init
(
void
)
{
bt_sock_register
(
BTPROTO_BNEP
,
&
bnep_sock_family_ops
);
return
0
;
}
int
bnep_sock_cleanup
(
void
)
int
__exit
bnep_sock_cleanup
(
void
)
{
if
(
bt_sock_unregister
(
BTPROTO_BNEP
))
BT_ERR
(
"Can't unregister BNEP socket"
);
...
...
net/bluetooth/hci_conn.c
View file @
adb35b9d
...
...
@@ -218,8 +218,7 @@ struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src)
read_lock_bh
(
&
hci_dev_list_lock
);
list_for_each
(
p
,
&
hci_dev_list
)
{
struct
hci_dev
*
d
;
d
=
list_entry
(
p
,
struct
hci_dev
,
list
);
struct
hci_dev
*
d
=
list_entry
(
p
,
struct
hci_dev
,
list
);
if
(
!
test_bit
(
HCI_UP
,
&
d
->
flags
))
continue
;
...
...
@@ -241,7 +240,7 @@ struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src)
}
if
(
hdev
)
hci_dev_hold
(
hdev
);
h
dev
=
h
ci_dev_hold
(
hdev
);
read_unlock_bh
(
&
hci_dev_list_lock
);
return
hdev
;
...
...
net/bluetooth/hci_core.c
View file @
adb35b9d
...
...
@@ -287,10 +287,10 @@ static void hci_encrypt_req(struct hci_dev *hdev, unsigned long opt)
}
/* Get HCI device by index.
* Device is
locke
d on return. */
* Device is
hel
d on return. */
struct
hci_dev
*
hci_dev_get
(
int
index
)
{
struct
hci_dev
*
hdev
;
struct
hci_dev
*
hdev
=
NULL
;
struct
list_head
*
p
;
BT_DBG
(
"%d"
,
index
);
...
...
@@ -300,14 +300,12 @@ struct hci_dev *hci_dev_get(int index)
read_lock
(
&
hci_dev_list_lock
);
list_for_each
(
p
,
&
hci_dev_list
)
{
hdev
=
list_entry
(
p
,
struct
hci_dev
,
list
);
if
(
hdev
->
id
==
index
)
{
h
ci_dev_hold
(
hdev
);
goto
done
;
struct
hci_dev
*
d
=
list_entry
(
p
,
struct
hci_dev
,
list
);
if
(
d
->
id
==
index
)
{
h
dev
=
hci_dev_hold
(
d
);
break
;
}
}
hdev
=
NULL
;
done:
read_unlock
(
&
hci_dev_list_lock
);
return
hdev
;
}
...
...
@@ -483,6 +481,7 @@ int hci_dev_open(__u16 dev)
}
if
(
!
ret
)
{
hci_dev_hold
(
hdev
);
set_bit
(
HCI_UP
,
&
hdev
->
flags
);
hci_notify
(
hdev
,
HCI_DEV_UP
);
}
else
{
...
...
@@ -567,6 +566,8 @@ static int hci_dev_do_close(struct hci_dev *hdev)
hdev
->
flags
=
0
;
hci_req_unlock
(
hdev
);
hci_dev_put
(
hdev
);
return
0
;
}
...
...
@@ -718,7 +719,7 @@ int hci_get_dev_list(unsigned long arg)
if
(
!
dev_num
)
return
-
EINVAL
;
size
=
dev_num
*
sizeof
(
struct
hci_dev_req
)
+
sizeof
(
__u16
);
size
=
dev_num
*
sizeof
(
*
dr
)
+
sizeof
(
*
dl
);
if
(
verify_area
(
VERIFY_WRITE
,
(
void
*
)
arg
,
size
))
return
-
EFAULT
;
...
...
@@ -739,7 +740,7 @@ int hci_get_dev_list(unsigned long arg)
read_unlock_bh
(
&
hci_dev_list_lock
);
dl
->
dev_num
=
n
;
size
=
n
*
sizeof
(
struct
hci_dev_req
)
+
sizeof
(
__u16
);
size
=
n
*
sizeof
(
*
dr
)
+
sizeof
(
*
dl
);
copy_to_user
((
void
*
)
arg
,
dl
,
size
);
kfree
(
dl
);
...
...
@@ -790,7 +791,7 @@ int hci_register_dev(struct hci_dev *hdev)
struct
list_head
*
head
=
&
hci_dev_list
,
*
p
;
int
id
=
0
;
BT_DBG
(
"%p name %s type %d
"
,
hdev
,
hdev
->
name
,
hdev
->
type
);
BT_DBG
(
"%p name %s type %d
owner %p"
,
hdev
,
hdev
->
name
,
hdev
->
type
,
hdev
->
owner
);
if
(
!
hdev
->
open
||
!
hdev
->
close
||
!
hdev
->
destruct
)
return
-
EINVAL
;
...
...
@@ -834,8 +835,6 @@ int hci_register_dev(struct hci_dev *hdev)
atomic_set
(
&
hdev
->
promisc
,
0
);
MOD_INC_USE_COUNT
;
write_unlock_bh
(
&
hci_dev_list_lock
);
hci_dev_proc_init
(
hdev
);
...
...
@@ -862,9 +861,7 @@ int hci_unregister_dev(struct hci_dev *hdev)
hci_notify
(
hdev
,
HCI_DEV_UNREG
);
hci_run_hotplug
(
hdev
->
name
,
"unregister"
);
hci_dev_put
(
hdev
);
MOD_DEC_USE_COUNT
;
__hci_dev_put
(
hdev
);
return
0
;
}
...
...
@@ -954,40 +951,6 @@ static int hci_send_frame(struct sk_buff *skb)
return
hdev
->
send
(
skb
);
}
/* Send raw HCI frame */
int
hci_send_raw
(
struct
sk_buff
*
skb
)
{
struct
hci_dev
*
hdev
=
(
struct
hci_dev
*
)
skb
->
dev
;
if
(
!
hdev
)
{
kfree_skb
(
skb
);
return
-
ENODEV
;
}
BT_DBG
(
"%s type %d len %d"
,
hdev
->
name
,
skb
->
pkt_type
,
skb
->
len
);
if
(
!
test_bit
(
HCI_RAW
,
&
hdev
->
flags
))
{
/* Queue frame according it's type */
switch
(
skb
->
pkt_type
)
{
case
HCI_COMMAND_PKT
:
skb_queue_tail
(
&
hdev
->
cmd_q
,
skb
);
hci_sched_cmd
(
hdev
);
return
0
;
case
HCI_ACLDATA_PKT
:
case
HCI_SCODATA_PKT
:
/* FIXME:
* Check header here and queue to apropriate connection.
*/
break
;
}
}
skb_queue_tail
(
&
hdev
->
raw_q
,
skb
);
hci_sched_tx
(
hdev
);
return
0
;
}
/* Send HCI command */
int
hci_send_cmd
(
struct
hci_dev
*
hdev
,
__u16
ogf
,
__u16
ocf
,
__u32
plen
,
void
*
param
)
{
...
...
net/bluetooth/hci_proc.c
View file @
adb35b9d
...
...
@@ -157,7 +157,7 @@ int __init hci_proc_init(void)
return
0
;
}
void
__
in
it
hci_proc_cleanup
(
void
)
void
__
ex
it
hci_proc_cleanup
(
void
)
{
remove_proc_entry
(
"hci"
,
proc_bt
);
}
...
...
@@ -179,7 +179,7 @@ int __init hci_proc_init(void)
return
0
;
}
void
__
in
it
hci_proc_cleanup
(
void
)
void
__
ex
it
hci_proc_cleanup
(
void
)
{
return
;
}
...
...
net/bluetooth/hci_sock.c
View file @
adb35b9d
...
...
@@ -49,6 +49,7 @@
#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/unaligned.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
...
...
@@ -68,14 +69,17 @@ static struct hci_sec_filter hci_sec_filter = {
{
0xd9fe
,
0x0
},
/* Commands */
{
{
0x0
},
/* OGF_LINK_CTL */
{
0x2a000002
,
0x0
,
0x0
,
0x0
},
/* OGF_LINK_POLICY */
{
0x1200
,
0x0
,
0x0
,
0x0
},
/* OGF_HOST_CTL */
{
0x80100000
,
0xa
,
0x0
,
0x0
},
{
0x80100000
,
0x
2
a
,
0x0
,
0x0
},
/* OGF_INFO_PARAM */
{
0x22a
,
0x0
,
0x0
,
0x0
}
{
0x22a
,
0x0
,
0x0
,
0x0
},
/* OGF_STATUS_PARAM */
{
0x2e
,
0x0
,
0x0
,
0x0
}
}
};
...
...
@@ -388,25 +392,37 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct msgh
skb
->
pkt_type
=
*
((
unsigned
char
*
)
skb
->
data
);
skb_pull
(
skb
,
1
);
if
(
!
capable
(
CAP_NET_RAW
))
{
err
=
-
EPERM
;
skb
->
dev
=
(
void
*
)
hdev
;
if
(
skb
->
pkt_type
==
HCI_COMMAND_PKT
)
{
u16
opcode
=
__le16_to_cpu
(
*
(
__u16
*
)
skb
->
data
);
u16
ogf
=
hci_opcode_ogf
(
opcode
)
-
1
;
u16
ocf
=
hci_opcode_ocf
(
opcode
)
&
HCI_FLT_OCF_BITS
;
u16
opcode
=
__le16_to_cpu
(
get_unaligned
((
u16
*
)
skb
->
data
)
);
u16
ogf
=
hci_opcode_ogf
(
opcode
)
;
u16
ocf
=
hci_opcode_ocf
(
opcode
)
;
if
(
ogf
>
HCI_SFLT_MAX_OGF
||
!
test_bit
(
ocf
,
hci_sec_filter
.
ocf_mask
[
ogf
]))
if
(((
ogf
>
HCI_SFLT_MAX_OGF
)
||
!
test_bit
(
ocf
&
HCI_FLT_OCF_BITS
,
hci_sec_filter
.
ocf_mask
[
ogf
]))
&&
!
capable
(
CAP_NET_RAW
))
{
err
=
-
EPERM
;
goto
drop
;
}
else
}
if
(
test_bit
(
HCI_RAW
,
&
hdev
->
flags
)
||
(
ogf
==
OGF_VENDOR_CMD
))
{
skb_queue_tail
(
&
hdev
->
raw_q
,
skb
);
hci_sched_tx
(
hdev
);
}
else
{
skb_queue_tail
(
&
hdev
->
cmd_q
,
skb
);
hci_sched_cmd
(
hdev
);
}
}
else
{
if
(
!
capable
(
CAP_NET_RAW
))
{
err
=
-
EPERM
;
goto
drop
;
}
/* Send frame to HCI core */
skb
->
dev
=
(
void
*
)
hdev
;
hci_send_raw
(
skb
);
skb_queue_tail
(
&
hdev
->
raw_q
,
skb
);
hci_sched_tx
(
hdev
);
}
err
=
len
;
done:
...
...
@@ -625,7 +641,7 @@ struct notifier_block hci_sock_nblock = {
.
notifier_call
=
hci_sock_dev_event
};
int
hci_sock_init
(
void
)
int
__init
hci_sock_init
(
void
)
{
if
(
bt_sock_register
(
BTPROTO_HCI
,
&
hci_sock_family_ops
))
{
BT_ERR
(
"HCI socket registration failed"
);
...
...
@@ -639,7 +655,7 @@ int hci_sock_init(void)
return
0
;
}
int
hci_sock_cleanup
(
void
)
int
__exit
hci_sock_cleanup
(
void
)
{
if
(
bt_sock_unregister
(
BTPROTO_HCI
))
BT_ERR
(
"HCI socket unregistration failed"
);
...
...
net/bluetooth/l2cap.c
View file @
adb35b9d
...
...
@@ -186,69 +186,12 @@ static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, stru
write_unlock
(
&
l
->
lock
);
}
int
l2cap_connect
(
struct
sock
*
sk
)
{
bdaddr_t
*
src
=
&
bt_sk
(
sk
)
->
src
;
bdaddr_t
*
dst
=
&
bt_sk
(
sk
)
->
dst
;
struct
l2cap_conn
*
conn
;
struct
hci_conn
*
hcon
;
struct
hci_dev
*
hdev
;
int
err
=
0
;
BT_DBG
(
"%s -> %s psm 0x%2.2x"
,
batostr
(
src
),
batostr
(
dst
),
l2cap_pi
(
sk
)
->
psm
);
if
(
!
(
hdev
=
hci_get_route
(
dst
,
src
)))
return
-
EHOSTUNREACH
;
hci_dev_lock_bh
(
hdev
);
err
=
-
ENOMEM
;
hcon
=
hci_connect
(
hdev
,
ACL_LINK
,
dst
);
if
(
!
hcon
)
goto
done
;
conn
=
l2cap_conn_add
(
hcon
,
0
);
if
(
!
conn
)
{
hci_conn_put
(
hcon
);
goto
done
;
}
err
=
0
;
/* Update source addr of the socket */
bacpy
(
src
,
conn
->
src
);
l2cap_chan_add
(
conn
,
sk
,
NULL
);
sk
->
state
=
BT_CONNECT
;
l2cap_sock_set_timer
(
sk
,
sk
->
sndtimeo
);
if
(
hcon
->
state
==
BT_CONNECTED
)
{
if
(
sk
->
type
==
SOCK_SEQPACKET
)
{
struct
l2cap_conn_req
req
;
req
.
scid
=
__cpu_to_le16
(
l2cap_pi
(
sk
)
->
scid
);
req
.
psm
=
l2cap_pi
(
sk
)
->
psm
;
l2cap_send_req
(
conn
,
L2CAP_CONN_REQ
,
sizeof
(
req
),
&
req
);
}
else
{
l2cap_sock_clear_timer
(
sk
);
sk
->
state
=
BT_CONNECTED
;
}
}
done:
hci_dev_unlock_bh
(
hdev
);
hci_dev_put
(
hdev
);
return
err
;
}
/* ---- Socket interface ---- */
static
struct
sock
*
__l2cap_get_sock_by_addr
(
u16
psm
,
bdaddr_t
*
src
)
{
struct
sock
*
sk
;
for
(
sk
=
l2cap_sk_list
.
head
;
sk
;
sk
=
sk
->
next
)
{
if
(
l2cap_pi
(
sk
)
->
psm
==
psm
&&
!
bacmp
(
&
bt_sk
(
sk
)
->
src
,
src
))
if
(
l2cap_pi
(
sk
)
->
sport
==
psm
&&
!
bacmp
(
&
bt_sk
(
sk
)
->
src
,
src
))
break
;
}
return
sk
;
...
...
@@ -438,6 +381,9 @@ static int l2cap_sock_create(struct socket *sock, int protocol)
if
(
sock
->
type
!=
SOCK_SEQPACKET
&&
sock
->
type
!=
SOCK_DGRAM
&&
sock
->
type
!=
SOCK_RAW
)
return
-
ESOCKTNOSUPPORT
;
if
(
sock
->
type
==
SOCK_RAW
&&
!
capable
(
CAP_NET_RAW
))
return
-
EPERM
;
sock
->
ops
=
&
l2cap_sock_ops
;
sk
=
l2cap_sock_alloc
(
sock
,
protocol
,
GFP_KERNEL
);
...
...
@@ -473,6 +419,7 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_
/* Save source address */
bacpy
(
&
bt_sk
(
sk
)
->
src
,
&
la
->
l2_bdaddr
);
l2cap_pi
(
sk
)
->
psm
=
la
->
l2_psm
;
l2cap_pi
(
sk
)
->
sport
=
la
->
l2_psm
;
sk
->
state
=
BT_BOUND
;
}
write_unlock_bh
(
&
l2cap_sk_list
.
lock
);
...
...
@@ -482,6 +429,62 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_
return
err
;
}
static
int
l2cap_do_connect
(
struct
sock
*
sk
)
{
bdaddr_t
*
src
=
&
bt_sk
(
sk
)
->
src
;
bdaddr_t
*
dst
=
&
bt_sk
(
sk
)
->
dst
;
struct
l2cap_conn
*
conn
;
struct
hci_conn
*
hcon
;
struct
hci_dev
*
hdev
;
int
err
=
0
;
BT_DBG
(
"%s -> %s psm 0x%2.2x"
,
batostr
(
src
),
batostr
(
dst
),
l2cap_pi
(
sk
)
->
psm
);
if
(
!
(
hdev
=
hci_get_route
(
dst
,
src
)))
return
-
EHOSTUNREACH
;
hci_dev_lock_bh
(
hdev
);
err
=
-
ENOMEM
;
hcon
=
hci_connect
(
hdev
,
ACL_LINK
,
dst
);
if
(
!
hcon
)
goto
done
;
conn
=
l2cap_conn_add
(
hcon
,
0
);
if
(
!
conn
)
{
hci_conn_put
(
hcon
);
goto
done
;
}
err
=
0
;
/* Update source addr of the socket */
bacpy
(
src
,
conn
->
src
);
l2cap_chan_add
(
conn
,
sk
,
NULL
);
sk
->
state
=
BT_CONNECT
;
l2cap_sock_set_timer
(
sk
,
sk
->
sndtimeo
);
if
(
hcon
->
state
==
BT_CONNECTED
)
{
if
(
sk
->
type
==
SOCK_SEQPACKET
)
{
struct
l2cap_conn_req
req
;
req
.
scid
=
__cpu_to_le16
(
l2cap_pi
(
sk
)
->
scid
);
req
.
psm
=
l2cap_pi
(
sk
)
->
psm
;
l2cap_send_req
(
conn
,
L2CAP_CONN_REQ
,
sizeof
(
req
),
&
req
);
}
else
{
l2cap_sock_clear_timer
(
sk
);
sk
->
state
=
BT_CONNECTED
;
}
}
done:
hci_dev_unlock_bh
(
hdev
);
hci_dev_put
(
hdev
);
return
err
;
}
static
int
l2cap_sock_connect
(
struct
socket
*
sock
,
struct
sockaddr
*
addr
,
int
alen
,
int
flags
)
{
struct
sockaddr_l2
*
la
=
(
struct
sockaddr_l2
*
)
addr
;
...
...
@@ -527,7 +530,7 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al
bacpy
(
&
bt_sk
(
sk
)
->
dst
,
&
la
->
l2_bdaddr
);
l2cap_pi
(
sk
)
->
psm
=
la
->
l2_psm
;
if
((
err
=
l2cap_connect
(
sk
)))
if
((
err
=
l2cap_
do_
connect
(
sk
)))
goto
done
;
wait:
...
...
@@ -2056,11 +2059,12 @@ static int __init l2cap_proc_init(void)
struct
proc_dir_entry
*
p
=
create_proc_entry
(
"l2cap"
,
S_IRUGO
,
proc_bt
);
if
(
!
p
)
return
-
ENOMEM
;
p
->
owner
=
THIS_MODULE
;
p
->
proc_fops
=
&
l2cap_seq_fops
;
return
0
;
}
static
void
__
in
it
l2cap_proc_cleanup
(
void
)
static
void
__
ex
it
l2cap_proc_cleanup
(
void
)
{
remove_proc_entry
(
"l2cap"
,
proc_bt
);
}
...
...
@@ -2072,9 +2076,9 @@ static int __init l2cap_proc_init(void)
return
0
;
}
static
void
__
in
it
l2cap_proc_cleanup
(
void
)
static
void
__
ex
it
l2cap_proc_cleanup
(
void
)
{
return
0
;
return
;
}
#endif
/* CONFIG_PROC_FS */
...
...
@@ -2136,7 +2140,7 @@ int __init l2cap_init(void)
return
0
;
}
void
l2cap_cleanup
(
void
)
void
__exit
l2cap_cleanup
(
void
)
{
l2cap_proc_cleanup
();
...
...
net/bluetooth/rfcomm/Kconfig
View file @
adb35b9d
config BT_RFCOMM
tristate "RFCOMM protocol support"
depends on BT_L2CAP
depends on BT
&& BT
_L2CAP
help
RFCOMM provides connection oriented stream transport. RFCOMM
support is required for Dialup Networking, OBEX and other Bluetooth
...
...
net/bluetooth/rfcomm/core.c
View file @
adb35b9d
...
...
@@ -263,7 +263,7 @@ static void rfcomm_dlc_unlink(struct rfcomm_dlc *d)
rfcomm_session_put
(
s
);
}
static
struct
rfcomm_dlc
*
rfcomm_dlc_get
(
struct
rfcomm_session
*
s
,
int
dlci
)
static
struct
rfcomm_dlc
*
rfcomm_dlc_get
(
struct
rfcomm_session
*
s
,
u8
dlci
)
{
struct
rfcomm_dlc
*
d
;
struct
list_head
*
p
;
...
...
@@ -279,7 +279,8 @@ static struct rfcomm_dlc *rfcomm_dlc_get(struct rfcomm_session *s, int dlci)
static
int
__rfcomm_dlc_open
(
struct
rfcomm_dlc
*
d
,
bdaddr_t
*
src
,
bdaddr_t
*
dst
,
u8
channel
)
{
struct
rfcomm_session
*
s
;
int
err
=
0
,
dlci
=
__dlci
(
0
,
channel
);
u8
dlci
=
__dlci
(
0
,
channel
);
int
err
=
0
;
BT_DBG
(
"dlc %p state %ld %s %s channel %d dlci %d"
,
d
,
d
->
state
,
batostr
(
src
),
batostr
(
dst
),
channel
,
dlci
);
...
...
@@ -923,7 +924,7 @@ static void rfcomm_make_uih(struct sk_buff *skb, u8 addr)
}
/* ---- RFCOMM frame reception ---- */
static
int
rfcomm_recv_ua
(
struct
rfcomm_session
*
s
,
int
dlci
)
static
int
rfcomm_recv_ua
(
struct
rfcomm_session
*
s
,
u8
dlci
)
{
BT_DBG
(
"session %p state %ld dlci %d"
,
s
,
s
->
state
,
dlci
);
...
...
@@ -964,7 +965,7 @@ static int rfcomm_recv_ua(struct rfcomm_session *s, int dlci)
return
0
;
}
static
int
rfcomm_recv_dm
(
struct
rfcomm_session
*
s
,
int
dlci
)
static
int
rfcomm_recv_dm
(
struct
rfcomm_session
*
s
,
u8
dlci
)
{
int
err
=
0
;
...
...
@@ -994,7 +995,7 @@ static int rfcomm_recv_dm(struct rfcomm_session *s, int dlci)
return
0
;
}
static
int
rfcomm_recv_disc
(
struct
rfcomm_session
*
s
,
int
dlci
)
static
int
rfcomm_recv_disc
(
struct
rfcomm_session
*
s
,
u8
dlci
)
{
int
err
=
0
;
...
...
@@ -1030,10 +1031,10 @@ static int rfcomm_recv_disc(struct rfcomm_session *s, int dlci)
return
0
;
}
static
int
rfcomm_recv_sabm
(
struct
rfcomm_session
*
s
,
int
dlci
)
static
int
rfcomm_recv_sabm
(
struct
rfcomm_session
*
s
,
u8
dlci
)
{
struct
rfcomm_dlc
*
d
;
int
channel
;
u8
channel
;
BT_DBG
(
"session %p state %ld dlci %d"
,
s
,
s
->
state
,
dlci
);
...
...
@@ -1116,7 +1117,7 @@ static int rfcomm_recv_pn(struct rfcomm_session *s, int cr, struct sk_buff *skb)
{
struct
rfcomm_pn
*
pn
=
(
void
*
)
skb
->
data
;
struct
rfcomm_dlc
*
d
;
int
dlci
=
pn
->
dlci
;
u8
dlci
=
pn
->
dlci
;
BT_DBG
(
"session %p state %ld dlci %d"
,
s
,
s
->
state
,
dlci
);
...
...
@@ -1141,7 +1142,7 @@ static int rfcomm_recv_pn(struct rfcomm_session *s, int cr, struct sk_buff *skb)
}
}
}
else
{
int
channel
=
__srv_channel
(
dlci
);
u8
channel
=
__srv_channel
(
dlci
);
if
(
!
cr
)
return
0
;
...
...
@@ -1167,7 +1168,7 @@ static int rfcomm_recv_pn(struct rfcomm_session *s, int cr, struct sk_buff *skb)
static
int
rfcomm_recv_rpn
(
struct
rfcomm_session
*
s
,
int
cr
,
int
len
,
struct
sk_buff
*
skb
)
{
struct
rfcomm_rpn
*
rpn
=
(
void
*
)
skb
->
data
;
int
dlci
=
__get_dlci
(
rpn
->
dlci
);
u8
dlci
=
__get_dlci
(
rpn
->
dlci
);
u8
bit_rate
=
0
;
u8
data_bits
=
0
;
...
...
@@ -1257,7 +1258,7 @@ static int rfcomm_recv_msc(struct rfcomm_session *s, int cr, struct sk_buff *skb
{
struct
rfcomm_msc
*
msc
=
(
void
*
)
skb
->
data
;
struct
rfcomm_dlc
*
d
;
int
dlci
=
__get_dlci
(
msc
->
dlci
);
u8
dlci
=
__get_dlci
(
msc
->
dlci
);
BT_DBG
(
"dlci %d cr %d v24 0x%x"
,
dlci
,
cr
,
msc
->
v24_sig
);
...
...
@@ -1312,6 +1313,9 @@ static int rfcomm_recv_mcc(struct rfcomm_session *s, struct sk_buff *skb)
rfcomm_send_test
(
s
,
0
,
skb
->
data
,
skb
->
len
);
break
;
case
RFCOMM_NSC
:
break
;
default:
BT_ERR
(
"Unknown control type 0x%02x"
,
type
);
rfcomm_send_nsc
(
s
,
cr
,
type
);
...
...
@@ -1320,7 +1324,7 @@ static int rfcomm_recv_mcc(struct rfcomm_session *s, struct sk_buff *skb)
return
0
;
}
static
int
rfcomm_recv_data
(
struct
rfcomm_session
*
s
,
int
dlci
,
int
pf
,
struct
sk_buff
*
skb
)
static
int
rfcomm_recv_data
(
struct
rfcomm_session
*
s
,
u8
dlci
,
int
pf
,
struct
sk_buff
*
skb
)
{
struct
rfcomm_dlc
*
d
;
...
...
@@ -1442,7 +1446,7 @@ static inline int rfcomm_process_tx(struct rfcomm_dlc *d)
/* Send pending MSC */
if
(
test_and_clear_bit
(
RFCOMM_MSC_PENDING
,
&
d
->
flags
))
rfcomm_send_msc
(
d
->
session
,
d
->
dlci
,
1
,
d
->
v24_sig
);
rfcomm_send_msc
(
d
->
session
,
1
,
d
->
dlci
,
d
->
v24_sig
);
if
(
d
->
credits
)
{
/* CFC enabled.
...
...
@@ -1804,14 +1808,17 @@ static int __init rfcomm_proc_init(void)
struct
proc_dir_entry
*
p
;
proc_bt_rfcomm
=
proc_mkdir
(
"rfcomm"
,
proc_bt
);
if
(
proc_bt_rfcomm
)
{
proc_bt_rfcomm
->
owner
=
THIS_MODULE
;
p
=
create_proc_entry
(
"dlc"
,
S_IRUGO
,
proc_bt_rfcomm
);
if
(
p
)
p
->
proc_fops
=
&
rfcomm_seq_fops
;
}
return
0
;
}
static
void
__
in
it
rfcomm_proc_cleanup
(
void
)
static
void
__
ex
it
rfcomm_proc_cleanup
(
void
)
{
remove_proc_entry
(
"dlc"
,
proc_bt_rfcomm
);
...
...
@@ -1825,9 +1832,9 @@ static int __init rfcomm_proc_init(void)
return
0
;
}
static
void
__
in
it
rfcomm_proc_cleanup
(
void
)
static
void
__
ex
it
rfcomm_proc_cleanup
(
void
)
{
return
0
;
return
;
}
#endif
/* CONFIG_PROC_FS */
...
...
@@ -1849,7 +1856,7 @@ int __init rfcomm_init(void)
return
0
;
}
void
rfcomm_cleanup
(
void
)
void
__exit
rfcomm_cleanup
(
void
)
{
/* Terminate working thread.
* ie. Set terminate flag and wake it up */
...
...
net/bluetooth/rfcomm/sock.c
View file @
adb35b9d
...
...
@@ -112,7 +112,7 @@ static void rfcomm_sk_state_change(struct rfcomm_dlc *d, int err)
}
/* ---- Socket functions ---- */
static
struct
sock
*
__rfcomm_get_sock_by_addr
(
int
channel
,
bdaddr_t
*
src
)
static
struct
sock
*
__rfcomm_get_sock_by_addr
(
u8
channel
,
bdaddr_t
*
src
)
{
struct
sock
*
sk
;
...
...
@@ -128,7 +128,7 @@ static struct sock *__rfcomm_get_sock_by_addr(int channel, bdaddr_t *src)
/* Find socket with channel and source bdaddr.
* Returns closest match.
*/
static
struct
sock
*
__rfcomm_get_sock_by_channel
(
int
state
,
__u16
channel
,
bdaddr_t
*
src
)
static
struct
sock
*
__rfcomm_get_sock_by_channel
(
int
state
,
u8
channel
,
bdaddr_t
*
src
)
{
struct
sock
*
sk
,
*
sk1
=
NULL
;
...
...
@@ -151,7 +151,7 @@ static struct sock *__rfcomm_get_sock_by_channel(int state, __u16 channel, bdadd
/* Find socket with given address (channel, src).
* Returns locked socket */
static
inline
struct
sock
*
rfcomm_get_sock_by_channel
(
int
state
,
__u16
channel
,
bdaddr_t
*
src
)
static
inline
struct
sock
*
rfcomm_get_sock_by_channel
(
int
state
,
u8
channel
,
bdaddr_t
*
src
)
{
struct
sock
*
s
;
read_lock
(
&
rfcomm_sk_list
.
lock
);
...
...
@@ -837,7 +837,7 @@ static int __init rfcomm_sock_proc_init(void)
return
0
;
}
static
void
__
in
it
rfcomm_sock_proc_cleanup
(
void
)
static
void
__
ex
it
rfcomm_sock_proc_cleanup
(
void
)
{
remove_proc_entry
(
"sock"
,
proc_bt_rfcomm
);
}
...
...
@@ -849,9 +849,9 @@ static int __init rfcomm_sock_proc_init(void)
return
0
;
}
static
void
__
in
it
rfcomm_sock_proc_cleanup
(
void
)
static
void
__
ex
it
rfcomm_sock_proc_cleanup
(
void
)
{
return
0
;
return
;
}
#endif
/* CONFIG_PROC_FS */
...
...
@@ -879,7 +879,7 @@ static struct net_proto_family rfcomm_sock_family_ops = {
.
create
=
rfcomm_sock_create
};
int
rfcomm_init_sockets
(
void
)
int
__init
rfcomm_init_sockets
(
void
)
{
int
err
;
...
...
@@ -894,7 +894,7 @@ int rfcomm_init_sockets(void)
return
0
;
}
void
rfcomm_cleanup_sockets
(
void
)
void
__exit
rfcomm_cleanup_sockets
(
void
)
{
int
err
;
...
...
net/bluetooth/rfcomm/tty.c
View file @
adb35b9d
...
...
@@ -257,7 +257,7 @@ static inline void rfcomm_set_owner_w(struct sk_buff *skb, struct rfcomm_dev *de
static
struct
sk_buff
*
rfcomm_wmalloc
(
struct
rfcomm_dev
*
dev
,
unsigned
long
size
,
int
priority
)
{
if
(
size
||
atomic_read
(
&
dev
->
wmem_alloc
)
<
dev
->
sndbuf
)
{
if
(
atomic_read
(
&
dev
->
wmem_alloc
)
<
dev
->
sndbuf
)
{
struct
sk_buff
*
skb
=
alloc_skb
(
size
,
priority
);
if
(
skb
)
{
rfcomm_set_owner_w
(
skb
,
dev
);
...
...
@@ -442,7 +442,7 @@ static void rfcomm_dev_data_ready(struct rfcomm_dlc *dlc, struct sk_buff *skb)
struct
tty_struct
*
tty
;
if
(
!
dev
||
!
(
tty
=
dev
->
tty
))
{
kfree
(
skb
);
kfree
_skb
(
skb
);
return
;
}
...
...
@@ -669,12 +669,12 @@ static int rfcomm_tty_set_modem_status(uint cmd, struct rfcomm_dlc *dlc, uint st
else
rfcomm_dlc_get_modem_status
(
dlc
,
&
v24_sig
);
mask
=
(
status
&
TIOCM_DSR
)
?
RFCOMM_V24_RTC
:
0
|
(
status
&
TIOCM_DTR
)
?
RFCOMM_V24_RTC
:
0
|
(
status
&
TIOCM_RTS
)
?
RFCOMM_V24_RTR
:
0
|
(
status
&
TIOCM_CTS
)
?
RFCOMM_V24_RTR
:
0
|
(
status
&
TIOCM_RI
)
?
RFCOMM_V24_IC
:
0
|
(
status
&
TIOCM_CD
)
?
RFCOMM_V24_DV
:
0
;
mask
=
(
(
status
&
TIOCM_DSR
)
?
RFCOMM_V24_RTC
:
0
)
|
(
(
status
&
TIOCM_DTR
)
?
RFCOMM_V24_RTC
:
0
)
|
(
(
status
&
TIOCM_RTS
)
?
RFCOMM_V24_RTR
:
0
)
|
(
(
status
&
TIOCM_CTS
)
?
RFCOMM_V24_RTR
:
0
)
|
(
(
status
&
TIOCM_RI
)
?
RFCOMM_V24_IC
:
0
)
|
(
(
status
&
TIOCM_CD
)
?
RFCOMM_V24_DV
:
0
)
;
if
(
cmd
==
TIOCMBIC
)
v24_sig
&=
~
mask
;
...
...
@@ -854,7 +854,7 @@ static struct tty_driver rfcomm_tty_driver = {
#ifdef CONFIG_DEVFS_FS
.
name
=
"bluetooth/rfcomm/%d"
,
#else
.
name
=
"rfcomm
%d
"
,
.
name
=
"rfcomm"
,
#endif
.
major
=
RFCOMM_TTY_MAJOR
,
.
minor_start
=
RFCOMM_TTY_MINOR
,
...
...
net/bluetooth/sco.c
View file @
adb35b9d
...
...
@@ -698,7 +698,7 @@ int sco_sock_getsockopt(struct socket *sock, int level, int optname, char *optva
opts
.
mtu
=
sco_pi
(
sk
)
->
conn
->
mtu
;
BT_
INFO
(
"mtu %d"
,
opts
.
mtu
);
BT_
DBG
(
"mtu %d"
,
opts
.
mtu
);
len
=
min_t
(
unsigned
int
,
len
,
sizeof
(
opts
));
if
(
copy_to_user
(
optval
,
(
char
*
)
&
opts
,
len
))
...
...
@@ -944,11 +944,12 @@ static int __init sco_proc_init(void)
struct
proc_dir_entry
*
p
=
create_proc_entry
(
"sco"
,
S_IRUGO
,
proc_bt
);
if
(
!
p
)
return
-
ENOMEM
;
p
->
owner
=
THIS_MODULE
;
p
->
proc_fops
=
&
sco_seq_fops
;
return
0
;
}
static
void
__
in
it
sco_proc_cleanup
(
void
)
static
void
__
ex
it
sco_proc_cleanup
(
void
)
{
remove_proc_entry
(
"sco"
,
proc_bt
);
}
...
...
@@ -960,9 +961,9 @@ static int __init sco_proc_init(void)
return
0
;
}
static
void
__
in
it
sco_proc_cleanup
(
void
)
static
void
__
ex
it
sco_proc_cleanup
(
void
)
{
return
0
;
return
;
}
#endif
/* CONFIG_PROC_FS */
...
...
@@ -1021,7 +1022,7 @@ int __init sco_init(void)
return
0
;
}
void
sco_cleanup
(
void
)
void
__exit
sco_cleanup
(
void
)
{
int
err
;
...
...
net/bluetooth/syms.c
View file @
adb35b9d
...
...
@@ -58,7 +58,7 @@ EXPORT_SYMBOL(hci_conn_encrypt);
EXPORT_SYMBOL
(
hci_send_acl
);
EXPORT_SYMBOL
(
hci_send_sco
);
EXPORT_SYMBOL
(
hci_send_
raw
);
EXPORT_SYMBOL
(
hci_send_
cmd
);
EXPORT_SYMBOL
(
hci_si_event
);
/* Bluetooth lib */
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment