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
Hide 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 @@
...
@@ -97,6 +97,7 @@
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci.h>
#include <net/bluetooth/hci.h>
#include <net/bluetooth/rfcomm.h>
#include <linux/usb.h>
#include <linux/usb.h>
#include <linux/usbdevice_fs.h>
#include <linux/usbdevice_fs.h>
...
@@ -4264,6 +4265,15 @@ static int do_blkgetsize64(unsigned int fd, unsigned int cmd,
...
@@ -4264,6 +4265,15 @@ static int do_blkgetsize64(unsigned int fd, unsigned int cmd,
return
sys_ioctl
(
fd
,
BLKGETSIZE64
,
arg
);
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
{
struct
ioctl_trans
{
unsigned
int
cmd
;
unsigned
int
cmd
;
unsigned
int
handler
;
unsigned
int
handler
;
...
@@ -4957,6 +4967,17 @@ COMPATIBLE_IOCTL(HCISETLINKMODE)
...
@@ -4957,6 +4967,17 @@ COMPATIBLE_IOCTL(HCISETLINKMODE)
COMPATIBLE_IOCTL
(
HCISETACLMTU
)
COMPATIBLE_IOCTL
(
HCISETACLMTU
)
COMPATIBLE_IOCTL
(
HCISETSCOMTU
)
COMPATIBLE_IOCTL
(
HCISETSCOMTU
)
COMPATIBLE_IOCTL
(
HCIINQUIRY
)
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. */
/* Misc. */
COMPATIBLE_IOCTL
(
0x41545900
)
/* ATYIO_CLKR */
COMPATIBLE_IOCTL
(
0x41545900
)
/* ATYIO_CLKR */
COMPATIBLE_IOCTL
(
0x41545901
)
/* ATYIO_CLKW */
COMPATIBLE_IOCTL
(
0x41545901
)
/* ATYIO_CLKW */
...
...
drivers/bluetooth/Kconfig
View file @
adb35b9d
menu "Bluetooth device drivers"
menu "Bluetooth device drivers"
depends on BT
!=n
depends on BT
config BT_HCIUSB
config BT_HCIUSB
tristate "HCI USB driver"
tristate "HCI USB driver"
...
@@ -52,11 +52,19 @@ config BT_HCIUART_BCSP
...
@@ -52,11 +52,19 @@ config BT_HCIUART_BCSP
help
help
BCSP (BlueCore Serial Protocol) is serial protocol for communication
BCSP (BlueCore Serial Protocol) is serial protocol for communication
between Bluetooth device and host. This protocol is required for non
between Bluetooth device and host. This protocol is required for non
USB Bluetooth devices based on CSR BlueCore chip, including PCMCIA and
USB Bluetooth devices based on CSR BlueCore chip, including PCMCIA and
CF cards.
CF cards.
Say Y here to compile support for HCI BCSP protocol.
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
config BT_HCIDTL1
tristate "HCI DTL1 (PC Card) driver"
tristate "HCI DTL1 (PC Card) driver"
depends on PCMCIA && BT
depends on PCMCIA && BT
...
@@ -64,8 +72,8 @@ config BT_HCIDTL1
...
@@ -64,8 +72,8 @@ config BT_HCIDTL1
Bluetooth HCI DTL1 (PC Card) driver.
Bluetooth HCI DTL1 (PC Card) driver.
This driver provides support for Bluetooth PCMCIA devices with
This driver provides support for Bluetooth PCMCIA devices with
Nokia DTL1 interface:
Nokia DTL1 interface:
Nokia Bluetooth Card
Nokia Bluetooth Card
Socket Bluetooth CF Card
Socket Bluetooth CF Card
Say Y here to compile support for HCI DTL1 devices into the
Say Y here to compile support for HCI DTL1 devices into the
kernel or say M to compile it as module (dtl1_cs).
kernel or say M to compile it as module (dtl1_cs).
...
@@ -73,12 +81,12 @@ config BT_HCIDTL1
...
@@ -73,12 +81,12 @@ config BT_HCIDTL1
config BT_HCIBT3C
config BT_HCIBT3C
tristate "HCI BT3C (PC Card) driver"
tristate "HCI BT3C (PC Card) driver"
depends on PCMCIA && BT
depends on PCMCIA && BT
---help---
help
Bluetooth HCI BT3C (PC Card) driver.
Bluetooth HCI BT3C (PC Card) driver.
This driver provides support for Bluetooth PCMCIA devices with
This driver provides support for Bluetooth PCMCIA devices with
3Com BT3C interface:
3Com BT3C interface:
3Com Bluetooth Card (3CRWB6096)
3Com Bluetooth Card (3CRWB6096)
HP Bluetooth Card
HP Bluetooth Card
The HCI BT3C driver uses external firmware loader program provided in
The HCI BT3C driver uses external firmware loader program provided in
the BlueFW package. For more information, see <http://bluez.sf.net>.
the BlueFW package. For more information, see <http://bluez.sf.net>.
...
@@ -93,10 +101,26 @@ config BT_HCIBLUECARD
...
@@ -93,10 +101,26 @@ config BT_HCIBLUECARD
Bluetooth HCI BlueCard (PC Card) driver.
Bluetooth HCI BlueCard (PC Card) driver.
This driver provides support for Bluetooth PCMCIA devices with
This driver provides support for Bluetooth PCMCIA devices with
Anycom BlueCard interface:
Anycom BlueCard interface:
Anycom Bluetooth PC Card
Anycom Bluetooth PC Card
Anycom Bluetooth CF Card
Anycom Bluetooth CF Card
Say Y here to compile support for HCI BlueCard devices into the
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).
kernel or say M to compile it as module (bluecard_cs).
config BT_HCIVHCI
config BT_HCIVHCI
...
...
drivers/bluetooth/Makefile
View file @
adb35b9d
...
@@ -8,6 +8,7 @@ obj-$(CONFIG_BT_HCIUART) += hci_uart.o
...
@@ -8,6 +8,7 @@ obj-$(CONFIG_BT_HCIUART) += hci_uart.o
obj-$(CONFIG_BT_HCIDTL1)
+=
dtl1_cs.o
obj-$(CONFIG_BT_HCIDTL1)
+=
dtl1_cs.o
obj-$(CONFIG_BT_HCIBT3C)
+=
bt3c_cs.o
obj-$(CONFIG_BT_HCIBT3C)
+=
bt3c_cs.o
obj-$(CONFIG_BT_HCIBLUECARD)
+=
bluecard_cs.o
obj-$(CONFIG_BT_HCIBLUECARD)
+=
bluecard_cs.o
obj-$(CONFIG_BT_HCIBTUART)
+=
btuart_cs.o
hci_uart-y
:=
hci_ldisc.o
hci_uart-y
:=
hci_ldisc.o
hci_uart-$(CONFIG_BT_HCIUART_H4)
+=
hci_h4.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)
...
@@ -789,6 +789,8 @@ int bluecard_open(bluecard_info_t *info)
hdev
->
destruct
=
bluecard_hci_destruct
;
hdev
->
destruct
=
bluecard_hci_destruct
;
hdev
->
ioctl
=
bluecard_hci_ioctl
;
hdev
->
ioctl
=
bluecard_hci_ioctl
;
hdev
->
owner
=
THIS_MODULE
;
if
(
hci_register_dev
(
hdev
)
<
0
)
{
if
(
hci_register_dev
(
hdev
)
<
0
)
{
printk
(
KERN_WARNING
"bluecard_cs: Can't register HCI device %s.
\n
"
,
hdev
->
name
);
printk
(
KERN_WARNING
"bluecard_cs: Can't register HCI device %s.
\n
"
,
hdev
->
name
);
return
-
ENODEV
;
return
-
ENODEV
;
...
@@ -1002,8 +1004,6 @@ void bluecard_config(dev_link_t *link)
...
@@ -1002,8 +1004,6 @@ void bluecard_config(dev_link_t *link)
goto
failed
;
goto
failed
;
}
}
MOD_INC_USE_COUNT
;
if
(
bluecard_open
(
info
)
!=
0
)
if
(
bluecard_open
(
info
)
!=
0
)
goto
failed
;
goto
failed
;
...
@@ -1029,8 +1029,6 @@ void bluecard_release(u_long arg)
...
@@ -1029,8 +1029,6 @@ void bluecard_release(u_long arg)
if
(
link
->
state
&
DEV_PRESENT
)
if
(
link
->
state
&
DEV_PRESENT
)
bluecard_close
(
info
);
bluecard_close
(
info
);
MOD_DEC_USE_COUNT
;
link
->
dev
=
NULL
;
link
->
dev
=
NULL
;
CardServices
(
ReleaseConfiguration
,
link
->
handle
);
CardServices
(
ReleaseConfiguration
,
link
->
handle
);
...
...
drivers/bluetooth/bt3c_cs.c
View file @
adb35b9d
...
@@ -546,6 +546,8 @@ int bt3c_open(bt3c_info_t *info)
...
@@ -546,6 +546,8 @@ int bt3c_open(bt3c_info_t *info)
hdev
->
destruct
=
bt3c_hci_destruct
;
hdev
->
destruct
=
bt3c_hci_destruct
;
hdev
->
ioctl
=
bt3c_hci_ioctl
;
hdev
->
ioctl
=
bt3c_hci_ioctl
;
hdev
->
owner
=
THIS_MODULE
;
if
(
hci_register_dev
(
hdev
)
<
0
)
{
if
(
hci_register_dev
(
hdev
)
<
0
)
{
printk
(
KERN_WARNING
"bt3c_cs: Can't register HCI device %s.
\n
"
,
hdev
->
name
);
printk
(
KERN_WARNING
"bt3c_cs: Can't register HCI device %s.
\n
"
,
hdev
->
name
);
return
-
ENODEV
;
return
-
ENODEV
;
...
@@ -788,8 +790,6 @@ void bt3c_config(dev_link_t *link)
...
@@ -788,8 +790,6 @@ void bt3c_config(dev_link_t *link)
goto
failed
;
goto
failed
;
}
}
MOD_INC_USE_COUNT
;
if
(
bt3c_open
(
info
)
!=
0
)
if
(
bt3c_open
(
info
)
!=
0
)
goto
failed
;
goto
failed
;
...
@@ -815,8 +815,6 @@ void bt3c_release(u_long arg)
...
@@ -815,8 +815,6 @@ void bt3c_release(u_long arg)
if
(
link
->
state
&
DEV_PRESENT
)
if
(
link
->
state
&
DEV_PRESENT
)
bt3c_close
(
info
);
bt3c_close
(
info
);
MOD_DEC_USE_COUNT
;
link
->
dev
=
NULL
;
link
->
dev
=
NULL
;
CardServices
(
ReleaseConfiguration
,
link
->
handle
);
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)
...
@@ -520,6 +520,8 @@ int dtl1_open(dtl1_info_t *info)
hdev
->
destruct
=
dtl1_hci_destruct
;
hdev
->
destruct
=
dtl1_hci_destruct
;
hdev
->
ioctl
=
dtl1_hci_ioctl
;
hdev
->
ioctl
=
dtl1_hci_ioctl
;
hdev
->
owner
=
THIS_MODULE
;
if
(
hci_register_dev
(
hdev
)
<
0
)
{
if
(
hci_register_dev
(
hdev
)
<
0
)
{
printk
(
KERN_WARNING
"dtl1_cs: Can't register HCI device %s.
\n
"
,
hdev
->
name
);
printk
(
KERN_WARNING
"dtl1_cs: Can't register HCI device %s.
\n
"
,
hdev
->
name
);
return
-
ENODEV
;
return
-
ENODEV
;
...
@@ -747,8 +749,6 @@ void dtl1_config(dev_link_t *link)
...
@@ -747,8 +749,6 @@ void dtl1_config(dev_link_t *link)
goto
failed
;
goto
failed
;
}
}
MOD_INC_USE_COUNT
;
if
(
dtl1_open
(
info
)
!=
0
)
if
(
dtl1_open
(
info
)
!=
0
)
goto
failed
;
goto
failed
;
...
@@ -774,8 +774,6 @@ void dtl1_release(u_long arg)
...
@@ -774,8 +774,6 @@ void dtl1_release(u_long arg)
if
(
link
->
state
&
DEV_PRESENT
)
if
(
link
->
state
&
DEV_PRESENT
)
dtl1_close
(
info
);
dtl1_close
(
info
);
MOD_DEC_USE_COUNT
;
link
->
dev
=
NULL
;
link
->
dev
=
NULL
;
CardServices
(
ReleaseConfiguration
,
link
->
handle
);
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)
...
@@ -250,8 +250,6 @@ static void hci_uart_destruct(struct hci_dev *hdev)
hu
=
(
struct
hci_uart
*
)
hdev
->
driver_data
;
hu
=
(
struct
hci_uart
*
)
hdev
->
driver_data
;
kfree
(
hu
);
kfree
(
hu
);
MOD_DEC_USE_COUNT
;
}
}
/* ------ LDISC part ------ */
/* ------ LDISC part ------ */
...
@@ -290,8 +288,7 @@ static int hci_uart_tty_open(struct tty_struct *tty)
...
@@ -290,8 +288,7 @@ static int hci_uart_tty_open(struct tty_struct *tty)
if
(
tty
->
driver
.
flush_buffer
)
if
(
tty
->
driver
.
flush_buffer
)
tty
->
driver
.
flush_buffer
(
tty
);
tty
->
driver
.
flush_buffer
(
tty
);
MOD_INC_USE_COUNT
;
return
0
;
return
0
;
}
}
...
@@ -317,8 +314,6 @@ static void hci_uart_tty_close(struct tty_struct *tty)
...
@@ -317,8 +314,6 @@ static void hci_uart_tty_close(struct tty_struct *tty)
hu
->
proto
->
close
(
hu
);
hu
->
proto
->
close
(
hu
);
hci_unregister_dev
(
hdev
);
hci_unregister_dev
(
hdev
);
}
}
MOD_DEC_USE_COUNT
;
}
}
}
}
...
@@ -411,11 +406,13 @@ static int hci_uart_register_dev(struct hci_uart *hu)
...
@@ -411,11 +406,13 @@ static int hci_uart_register_dev(struct hci_uart *hu)
hdev
->
send
=
hci_uart_send_frame
;
hdev
->
send
=
hci_uart_send_frame
;
hdev
->
destruct
=
hci_uart_destruct
;
hdev
->
destruct
=
hci_uart_destruct
;
hdev
->
owner
=
THIS_MODULE
;
if
(
hci_register_dev
(
hdev
)
<
0
)
{
if
(
hci_register_dev
(
hdev
)
<
0
)
{
BT_ERR
(
"Can't register HCI device %s"
,
hdev
->
name
);
BT_ERR
(
"Can't register HCI device %s"
,
hdev
->
name
);
return
-
ENODEV
;
return
-
ENODEV
;
}
}
MOD_INC_USE_COUNT
;
return
0
;
return
0
;
}
}
...
...
drivers/bluetooth/hci_usb.c
View file @
adb35b9d
...
@@ -207,18 +207,15 @@ static int hci_usb_open(struct hci_dev *hdev)
...
@@ -207,18 +207,15 @@ static int hci_usb_open(struct hci_dev *hdev)
if
(
test_and_set_bit
(
HCI_RUNNING
,
&
hdev
->
flags
))
if
(
test_and_set_bit
(
HCI_RUNNING
,
&
hdev
->
flags
))
return
0
;
return
0
;
MOD_INC_USE_COUNT
;
write_lock_irqsave
(
&
husb
->
completion_lock
,
flags
);
write_lock_irqsave
(
&
husb
->
completion_lock
,
flags
);
err
=
hci_usb_enable_intr
(
husb
);
err
=
hci_usb_enable_intr
(
husb
);
if
(
!
err
)
{
if
(
!
err
)
{
for
(
i
=
0
;
i
<
HCI_MAX_BULK_RX
;
i
++
)
for
(
i
=
0
;
i
<
HCI_MAX_BULK_RX
;
i
++
)
hci_usb_rx_submit
(
husb
,
NULL
);
hci_usb_rx_submit
(
husb
,
NULL
);
}
else
{
}
else
clear_bit
(
HCI_RUNNING
,
&
hdev
->
flags
);
clear_bit
(
HCI_RUNNING
,
&
hdev
->
flags
);
MOD_DEC_USE_COUNT
;
}
write_unlock_irqrestore
(
&
husb
->
completion_lock
,
flags
);
write_unlock_irqrestore
(
&
husb
->
completion_lock
,
flags
);
return
err
;
return
err
;
...
@@ -271,8 +268,6 @@ static int hci_usb_close(struct hci_dev *hdev)
...
@@ -271,8 +268,6 @@ static int hci_usb_close(struct hci_dev *hdev)
hci_usb_flush
(
hdev
);
hci_usb_flush
(
hdev
);
write_unlock_irqrestore
(
&
husb
->
completion_lock
,
flags
);
write_unlock_irqrestore
(
&
husb
->
completion_lock
,
flags
);
MOD_DEC_USE_COUNT
;
return
0
;
return
0
;
}
}
...
@@ -758,6 +753,8 @@ int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
...
@@ -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
->
send
=
hci_usb_send_frame
;
hdev
->
destruct
=
hci_usb_destruct
;
hdev
->
destruct
=
hci_usb_destruct
;
hdev
->
owner
=
THIS_MODULE
;
if
(
hci_register_dev
(
hdev
)
<
0
)
{
if
(
hci_register_dev
(
hdev
)
<
0
)
{
BT_ERR
(
"Can't register HCI device"
);
BT_ERR
(
"Can't register HCI device"
);
goto
probe_error
;
goto
probe_error
;
...
...
drivers/bluetooth/hci_vhci.c
View file @
adb35b9d
...
@@ -84,8 +84,6 @@ static void hci_vhci_destruct(struct hci_dev *hdev)
...
@@ -84,8 +84,6 @@ static void hci_vhci_destruct(struct hci_dev *hdev)
vhci
=
(
struct
hci_vhci_struct
*
)
hdev
->
driver_data
;
vhci
=
(
struct
hci_vhci_struct
*
)
hdev
->
driver_data
;
kfree
(
vhci
);
kfree
(
vhci
);
MOD_DEC_USE_COUNT
;
}
}
static
int
hci_vhci_send_frame
(
struct
sk_buff
*
skb
)
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)
...
@@ -288,11 +286,12 @@ static int hci_vhci_chr_open(struct inode *inode, struct file * file)
hdev
->
send
=
hci_vhci_send_frame
;
hdev
->
send
=
hci_vhci_send_frame
;
hdev
->
destruct
=
hci_vhci_destruct
;
hdev
->
destruct
=
hci_vhci_destruct
;
hdev
->
owner
=
THIS_MODULE
;
if
(
hci_register_dev
(
hdev
)
<
0
)
{
if
(
hci_register_dev
(
hdev
)
<
0
)
{
kfree
(
hci_vhci
);
kfree
(
hci_vhci
);
return
-
EBUSY
;
return
-
EBUSY
;
}
}
MOD_INC_USE_COUNT
;
file
->
private_data
=
hci_vhci
;
file
->
private_data
=
hci_vhci
;
return
0
;
return
0
;
...
...
include/net/bluetooth/hci.h
View file @
adb35b9d
...
@@ -48,6 +48,7 @@
...
@@ -48,6 +48,7 @@
#define HCI_PCCARD 2
#define HCI_PCCARD 2
#define HCI_UART 3
#define HCI_UART 3
#define HCI_RS232 4
#define HCI_RS232 4
#define HCI_PCI 5
/* HCI device flags */
/* HCI device flags */
enum
{
enum
{
...
@@ -65,27 +66,28 @@ enum {
...
@@ -65,27 +66,28 @@ enum {
};
};
/* HCI ioctl defines */
/* HCI ioctl defines */
#define HCIDEVUP _IOW('H', 201, int)
#define HCIDEVUP _IOW('H', 201, int)
#define HCIDEVDOWN _IOW('H', 202, int)
#define HCIDEVDOWN _IOW('H', 202, int)
#define HCIDEVRESET _IOW('H', 203, int)
#define HCIDEVRESET _IOW('H', 203, int)
#define HCIDEVRESTAT _IOW('H', 204, int)
#define HCIDEVRESTAT _IOW('H', 204, int)
#define HCIGETDEVLIST _IOR('H', 210, int)
#define HCIGETDEVLIST _IOR('H', 210, int)
#define HCIGETDEVINFO _IOR('H', 211, int)
#define HCIGETDEVINFO _IOR('H', 211, int)
#define HCIGETCONNLIST _IOR('H', 212, int)
#define HCIGETCONNLIST _IOR('H', 212, int)
#define HCIGETCONNINFO _IOR('H', 213, int)
#define HCIGETCONNINFO _IOR('H', 213, int)
#define HCISETRAW _IOW('H', 220, int)
#define HCISETRAW _IOW('H', 220, int)
#define HCISETSCAN _IOW('H', 221, int)
#define HCISETSCAN _IOW('H', 221, int)
#define HCISETAUTH _IOW('H', 222, int)
#define HCISETAUTH _IOW('H', 222, int)
#define HCISETENCRYPT _IOW('H', 223, int)
#define HCISETENCRYPT _IOW('H', 223, int)
#define HCISETPTYPE _IOW('H', 224, int)
#define HCISETPTYPE _IOW('H', 224, int)
#define HCISETLINKPOL _IOW('H', 225, int)
#define HCISETLINKPOL _IOW('H', 225, int)
#define HCISETLINKMODE _IOW('H', 226, int)
#define HCISETLINKMODE _IOW('H', 226, int)
#define HCISETACLMTU _IOW('H', 227, int)
#define HCISETACLMTU _IOW('H', 227, int)
#define HCISETSCOMTU _IOW('H', 228, int)
#define HCISETSCOMTU _IOW('H', 228, int)
#define HCISETRAWVND _IOW('H', 229, int)
#define HCIINQUIRY _IOR('H', 240, int)
#define HCIINQUIRY _IOR('H', 240, int)
/* HCI timeouts */
/* HCI timeouts */
#define HCI_CONN_TIMEOUT (HZ * 40)
#define HCI_CONN_TIMEOUT (HZ * 40)
...
@@ -383,7 +385,13 @@ struct hci_rp_write_link_policy {
...
@@ -383,7 +385,13 @@ struct hci_rp_write_link_policy {
}
__attribute__
((
packed
));
}
__attribute__
((
packed
));
/* Status params */
/* Status params */
#define OGF_STATUS_PARAM 0x05
#define OGF_STATUS_PARAM 0x05
/* Testing commands */
#define OGF_TESTING_CMD 0x3E
/* Vendor specific commands */
#define OGF_VENDOR_CMD 0x3F
/* ---- HCI Events ---- */
/* ---- HCI Events ---- */
#define HCI_EV_INQUIRY_COMPLETE 0x01
#define HCI_EV_INQUIRY_COMPLETE 0x01
...
...
include/net/bluetooth/hci_core.h
View file @
adb35b9d
...
@@ -118,6 +118,8 @@ struct hci_dev {
...
@@ -118,6 +118,8 @@ struct hci_dev {
struct
proc_dir_entry
*
proc
;
struct
proc_dir_entry
*
proc
;
#endif
#endif
struct
module
*
owner
;
int
(
*
open
)(
struct
hci_dev
*
hdev
);
int
(
*
open
)(
struct
hci_dev
*
hdev
);
int
(
*
close
)(
struct
hci_dev
*
hdev
);
int
(
*
close
)(
struct
hci_dev
*
hdev
);
int
(
*
flush
)(
struct
hci_dev
*
hdev
);
int
(
*
flush
)(
struct
hci_dev
*
hdev
);
...
@@ -299,12 +301,30 @@ static inline void hci_sched_tx(struct hci_dev *hdev)
...
@@ -299,12 +301,30 @@ static inline void hci_sched_tx(struct hci_dev *hdev)
}
}
/* ----- HCI Devices ----- */
/* ----- 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
))
if
(
atomic_dec_and_test
(
&
d
->
refcnt
))
d
->
destruct
(
d
);
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_lock(d) spin_lock(&d->lock)
#define hci_dev_unlock(d) spin_unlock(&d->lock)
#define hci_dev_unlock(d) spin_unlock(&d->lock)
...
@@ -452,7 +472,6 @@ int hci_unregister_notifier(struct notifier_block *nb);
...
@@ -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_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_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_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
);
void
*
hci_sent_cmd_data
(
struct
hci_dev
*
hdev
,
__u16
ogf
,
__u16
ocf
);
...
@@ -470,7 +489,7 @@ struct hci_pinfo {
...
@@ -470,7 +489,7 @@ struct hci_pinfo {
};
};
/* HCI security filter */
/* HCI security filter */
#define HCI_SFLT_MAX_OGF
4
#define HCI_SFLT_MAX_OGF
5
struct
hci_sec_filter
{
struct
hci_sec_filter
{
unsigned
long
type_mask
;
unsigned
long
type_mask
;
...
...
include/net/bluetooth/l2cap.h
View file @
adb35b9d
...
@@ -224,6 +224,8 @@ struct l2cap_pinfo {
...
@@ -224,6 +224,8 @@ struct l2cap_pinfo {
__u8
ident
;
__u8
ident
;
__u16
sport
;
struct
l2cap_conn
*
conn
;
struct
l2cap_conn
*
conn
;
struct
sock
*
next_c
;
struct
sock
*
next_c
;
struct
sock
*
prev_c
;
struct
sock
*
prev_c
;
...
...
net/bluetooth/Kconfig
View file @
adb35b9d
...
@@ -7,7 +7,7 @@ menu "Bluetooth support"
...
@@ -7,7 +7,7 @@ menu "Bluetooth support"
config BT
config BT
tristate "Bluetooth subsystem support"
tristate "Bluetooth subsystem support"
---help---
help
Bluetooth is low-cost, low-power, short-range wireless technology.
Bluetooth is low-cost, low-power, short-range wireless technology.
It was designed as a replacement for cables and other short-range
It was designed as a replacement for cables and other short-range
technologies like IrDA. Bluetooth operates in personal area range
technologies like IrDA. Bluetooth operates in personal area range
...
@@ -15,12 +15,12 @@ config BT
...
@@ -15,12 +15,12 @@ config BT
Bluetooth can be found at <http://www.bluetooth.com/>.
Bluetooth can be found at <http://www.bluetooth.com/>.
Linux Bluetooth subsystem consist of several layers:
Linux Bluetooth subsystem consist of several layers:
Bluetooth Core (HCI device and connection manager, scheduler)
Bluetooth Core (HCI device and connection manager, scheduler)
HCI Device drivers (interface to the hardware)
HCI Device drivers (interface to the hardware)
L2CAP Module (L2CAP protocol)
L2CAP Module (L2CAP protocol)
SCO Module (SCO links)
SCO Module (SCO links)
RFCOMM Module (RFCOMM protocol)
RFCOMM Module (RFCOMM protocol)
BNEP Module (BNEP protocol)
BNEP Module (BNEP protocol)
Say Y here to enable Linux Bluetooth support and to build Bluetooth Core
Say Y here to enable Linux Bluetooth support and to build Bluetooth Core
layer.
layer.
...
...
net/bluetooth/af_bluetooth.c
View file @
adb35b9d
...
@@ -335,7 +335,9 @@ static int __init bt_init(void)
...
@@ -335,7 +335,9 @@ static int __init bt_init(void)
BT_INFO
(
"Core ver %s"
,
VERSION
);
BT_INFO
(
"Core ver %s"
,
VERSION
);
proc_bt
=
proc_mkdir
(
"bluetooth"
,
NULL
);
proc_bt
=
proc_mkdir
(
"bluetooth"
,
NULL
);
if
(
proc_bt
)
proc_bt
->
owner
=
THIS_MODULE
;
/* Init socket cache */
/* Init socket cache */
bt_sock_cache
=
kmem_cache_create
(
"bt_sock"
,
bt_sock_cache
=
kmem_cache_create
(
"bt_sock"
,
sizeof
(
struct
bt_sock
),
0
,
sizeof
(
struct
bt_sock
),
0
,
...
...
net/bluetooth/bnep/Kconfig
View file @
adb35b9d
config BT_BNEP
config BT_BNEP
tristate "BNEP protocol support"
tristate "BNEP protocol support"
depends on BT_L2CAP
depends on BT
&& BT
_L2CAP
---help---
help
BNEP (Bluetooth Network Encapsulation Protocol) is Ethernet
BNEP (Bluetooth Network Encapsulation Protocol) is Ethernet
emulation layer on top of Bluetooth. BNEP is required for Bluetooth
emulation layer on top of Bluetooth. BNEP is required for Bluetooth
PAN (Personal Area Network).
PAN (Personal Area Network).
...
...
net/bluetooth/bnep/bnep.h
View file @
adb35b9d
...
@@ -111,25 +111,25 @@ struct bnep_ext_hdr {
...
@@ -111,25 +111,25 @@ struct bnep_ext_hdr {
__u8
data
[
0
];
__u8
data
[
0
];
}
__attribute__
((
packed
));
}
__attribute__
((
packed
));
/
/ Ioctl interface
/
* BNEP ioctl defines */
#define BNEPCON
ADD 1
#define BNEPCON
NADD _IOW('B', 200, int)
#define BNEPCON
DEL 2
#define BNEPCON
NDEL _IOW('B', 201, int)
#define BNEPGETCON
LIST 3
#define BNEPGETCON
NLIST _IOR('B', 210, int)
#define BNEPGETCON
INFO 4
#define BNEPGETCON
NINFO _IOR('B', 211, int)
struct
bnep_conadd_req
{
struct
bnep_con
n
add_req
{
int
sock
;
// Connected socket
int
sock
;
// Connected socket
__u32
flags
;
__u32
flags
;
__u16
role
;
__u16
role
;
char
device
[
16
];
// Name of the Ethernet device
char
device
[
16
];
// Name of the Ethernet device
};
};
struct
bnep_condel_req
{
struct
bnep_con
n
del_req
{
__u32
flags
;
__u32
flags
;
__u8
dst
[
ETH_ALEN
];
__u8
dst
[
ETH_ALEN
];
};
};
struct
bnep_coninfo
{
struct
bnep_con
n
info
{
__u32
flags
;
__u32
flags
;
__u16
role
;
__u16
role
;
__u16
state
;
__u16
state
;
...
@@ -137,9 +137,9 @@ struct bnep_coninfo {
...
@@ -137,9 +137,9 @@ struct bnep_coninfo {
char
device
[
16
];
char
device
[
16
];
};
};
struct
bnep_conlist_req
{
struct
bnep_con
n
list_req
{
__u32
cnum
;
__u32
cnum
;
struct
bnep_coninfo
*
ci
;
struct
bnep_con
n
info
*
ci
;
};
};
struct
bnep_proto_filter
{
struct
bnep_proto_filter
{
...
@@ -147,10 +147,10 @@ struct bnep_proto_filter {
...
@@ -147,10 +147,10 @@ struct bnep_proto_filter {
__u16
end
;
__u16
end
;
};
};
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
);
int
bnep_del_connection
(
struct
bnep_condel_req
*
req
);
int
bnep_del_connection
(
struct
bnep_con
n
del_req
*
req
);
int
bnep_get_con
list
(
struct
bnep_co
nlist_req
*
req
);
int
bnep_get_con
nlist
(
struct
bnep_con
nlist_req
*
req
);
int
bnep_get_con
info
(
struct
bnep_co
ninfo
*
ci
);
int
bnep_get_con
ninfo
(
struct
bnep_con
ninfo
*
ci
);
// BNEP sessions
// BNEP sessions
struct
bnep_session
{
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)
...
@@ -128,18 +128,17 @@ static int bnep_send_rsp(struct bnep_session *s, u8 ctrl, u16 resp)
return
bnep_send
(
s
,
&
rsp
,
sizeof
(
rsp
));
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
;
int
n
;
data
=
(
void
*
)
skb
->
data
;
if
(
len
<
2
)
if
(
!
skb_pull
(
skb
,
2
))
return
-
EILSEQ
;
return
-
EILSEQ
;
n
=
ntohs
(
get_unaligned
(
data
));
n
=
ntohs
(
get_unaligned
(
data
));
data
++
;
len
-=
2
;
data
=
(
void
*
)
skb
->
data
;
if
(
len
<
n
)
if
(
!
skb_pull
(
skb
,
n
))
return
-
EILSEQ
;
return
-
EILSEQ
;
BT_DBG
(
"filter len %d"
,
n
);
BT_DBG
(
"filter len %d"
,
n
);
...
@@ -170,18 +169,17 @@ static int bnep_ctrl_set_netfilter(struct bnep_session *s, struct sk_buff *skb)
...
@@ -170,18 +169,17 @@ static int bnep_ctrl_set_netfilter(struct bnep_session *s, struct sk_buff *skb)
return
0
;
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
;
int
n
;
data
=
(
void
*
)
skb
->
data
;
if
(
len
<
2
)
if
(
!
skb_pull
(
skb
,
2
))
return
-
EILSEQ
;
return
-
EILSEQ
;
n
=
ntohs
(
get_unaligned
((
u16
*
)
data
));
data
=
(
void
*
)
skb
->
data
;
n
=
ntohs
(
get_unaligned
((
u16
*
)
data
));
if
(
!
skb_pull
(
skb
,
n
))
data
+=
2
;
len
-=
2
;
if
(
len
<
n
)
return
-
EILSEQ
;
return
-
EILSEQ
;
BT_DBG
(
"filter len %d"
,
n
);
BT_DBG
(
"filter len %d"
,
n
);
...
@@ -225,12 +223,13 @@ static int bnep_ctrl_set_mcfilter(struct bnep_session *s, struct sk_buff *skb)
...
@@ -225,12 +223,13 @@ static int bnep_ctrl_set_mcfilter(struct bnep_session *s, struct sk_buff *skb)
return
0
;
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
;
int
err
=
0
;
u8
cmd
=
*
(
u8
*
)
skb
->
data
;
skb_pull
(
skb
,
1
)
;
data
++
;
len
--
;
switch
(
cmd
)
{
switch
(
cmd
)
{
case
BNEP_CMD_NOT_UNDERSTOOD
:
case
BNEP_CMD_NOT_UNDERSTOOD
:
case
BNEP_SETUP_CONN_REQ
:
case
BNEP_SETUP_CONN_REQ
:
...
@@ -239,13 +238,13 @@ static int bnep_rx_control(struct bnep_session *s, struct sk_buff *skb)
...
@@ -239,13 +238,13 @@ static int bnep_rx_control(struct bnep_session *s, struct sk_buff *skb)
case
BNEP_FILTER_MULTI_ADDR_RSP
:
case
BNEP_FILTER_MULTI_ADDR_RSP
:
/* Ignore these for now */
/* Ignore these for now */
break
;
break
;
case
BNEP_FILTER_NET_TYPE_SET
:
case
BNEP_FILTER_NET_TYPE_SET
:
err
=
bnep_ctrl_set_netfilter
(
s
,
skb
);
err
=
bnep_ctrl_set_netfilter
(
s
,
data
,
len
);
break
;
break
;
case
BNEP_FILTER_MULTI_ADDR_SET
:
case
BNEP_FILTER_MULTI_ADDR_SET
:
err
=
bnep_ctrl_set_mcfilter
(
s
,
skb
);
err
=
bnep_ctrl_set_mcfilter
(
s
,
data
,
len
);
break
;
break
;
default:
{
default:
{
...
@@ -274,16 +273,19 @@ static int bnep_rx_extension(struct bnep_session *s, struct sk_buff *skb)
...
@@ -274,16 +273,19 @@ static int bnep_rx_extension(struct bnep_session *s, struct sk_buff *skb)
}
}
BT_DBG
(
"type 0x%x len %d"
,
h
->
type
,
h
->
len
);
BT_DBG
(
"type 0x%x len %d"
,
h
->
type
,
h
->
len
);
switch
(
h
->
type
&
BNEP_TYPE_MASK
)
{
switch
(
h
->
type
&
BNEP_TYPE_MASK
)
{
case
BNEP_EXT_CONTROL
:
case
BNEP_EXT_CONTROL
:
err
=
bnep_rx_control
(
s
,
skb
);
bnep_rx_control
(
s
,
skb
->
data
,
skb
->
len
);
break
;
break
;
default:
default:
/* Unknown extension */
/* Unknown extension, skip it. */
if
(
!
skb_pull
(
skb
,
h
->
len
))
break
;
err
=
-
EILSEQ
;
}
if
(
!
skb_pull
(
skb
,
h
->
len
))
{
err
=
-
EILSEQ
;
break
;
break
;
}
}
}
while
(
!
err
&&
(
h
->
type
&
BNEP_EXT_HEADER
));
}
while
(
!
err
&&
(
h
->
type
&
BNEP_EXT_HEADER
));
...
@@ -315,7 +317,7 @@ static inline int bnep_rx_frame(struct bnep_session *s, struct sk_buff *skb)
...
@@ -315,7 +317,7 @@ static inline int bnep_rx_frame(struct bnep_session *s, struct sk_buff *skb)
goto
badframe
;
goto
badframe
;
if
((
type
&
BNEP_TYPE_MASK
)
==
BNEP_CONTROL
)
{
if
((
type
&
BNEP_TYPE_MASK
)
==
BNEP_CONTROL
)
{
bnep_rx_control
(
s
,
skb
);
bnep_rx_control
(
s
,
skb
->
data
,
skb
->
len
);
kfree_skb
(
skb
);
kfree_skb
(
skb
);
return
0
;
return
0
;
}
}
...
@@ -525,7 +527,7 @@ static int bnep_session(void *arg)
...
@@ -525,7 +527,7 @@ static int bnep_session(void *arg)
return
0
;
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
net_device
*
dev
;
struct
bnep_session
*
s
,
*
ss
;
struct
bnep_session
*
s
,
*
ss
;
...
@@ -616,7 +618,7 @@ int bnep_add_connection(struct bnep_conadd_req *req, struct socket *sock)
...
@@ -616,7 +618,7 @@ int bnep_add_connection(struct bnep_conadd_req *req, struct socket *sock)
return
err
;
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
;
struct
bnep_session
*
s
;
int
err
=
0
;
int
err
=
0
;
...
@@ -641,7 +643,7 @@ int bnep_del_connection(struct bnep_condel_req *req)
...
@@ -641,7 +643,7 @@ int bnep_del_connection(struct bnep_condel_req *req)
return
err
;
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
);
memcpy
(
ci
->
dst
,
s
->
eh
.
h_source
,
ETH_ALEN
);
strcpy
(
ci
->
device
,
s
->
dev
.
name
);
strcpy
(
ci
->
device
,
s
->
dev
.
name
);
...
@@ -650,7 +652,7 @@ static void __bnep_copy_ci(struct bnep_coninfo *ci, struct bnep_session *s)
...
@@ -650,7 +652,7 @@ static void __bnep_copy_ci(struct bnep_coninfo *ci, struct bnep_session *s)
ci
->
role
=
s
->
role
;
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
;
struct
list_head
*
p
;
int
err
=
0
,
n
=
0
;
int
err
=
0
,
n
=
0
;
...
@@ -659,7 +661,7 @@ int bnep_get_conlist(struct bnep_conlist_req *req)
...
@@ -659,7 +661,7 @@ int bnep_get_conlist(struct bnep_conlist_req *req)
list_for_each
(
p
,
&
bnep_session_list
)
{
list_for_each
(
p
,
&
bnep_session_list
)
{
struct
bnep_session
*
s
;
struct
bnep_session
*
s
;
struct
bnep_coninfo
ci
;
struct
bnep_con
n
info
ci
;
s
=
list_entry
(
p
,
struct
bnep_session
,
list
);
s
=
list_entry
(
p
,
struct
bnep_session
,
list
);
...
@@ -681,7 +683,7 @@ int bnep_get_conlist(struct bnep_conlist_req *req)
...
@@ -681,7 +683,7 @@ int bnep_get_conlist(struct bnep_conlist_req *req)
return
err
;
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
;
struct
bnep_session
*
s
;
int
err
=
0
;
int
err
=
0
;
...
@@ -698,7 +700,7 @@ int bnep_get_coninfo(struct bnep_coninfo *ci)
...
@@ -698,7 +700,7 @@ int bnep_get_coninfo(struct bnep_coninfo *ci)
return
err
;
return
err
;
}
}
static
int
__init
bnep_init_module
(
void
)
static
int
__init
bnep_init_module
(
void
)
{
{
char
flt
[
50
]
=
""
;
char
flt
[
50
]
=
""
;
...
...
net/bluetooth/bnep/sock.c
View file @
adb35b9d
...
@@ -73,17 +73,17 @@ static int bnep_sock_release(struct socket *sock)
...
@@ -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
)
static
int
bnep_sock_ioctl
(
struct
socket
*
sock
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
{
struct
bnep_conlist_req
cl
;
struct
bnep_con
n
list_req
cl
;
struct
bnep_conadd_req
ca
;
struct
bnep_con
n
add_req
ca
;
struct
bnep_condel_req
cd
;
struct
bnep_con
n
del_req
cd
;
struct
bnep_coninfo
ci
;
struct
bnep_con
n
info
ci
;
struct
socket
*
nsock
;
struct
socket
*
nsock
;
int
err
;
int
err
;
BT_DBG
(
"cmd %x arg %lx"
,
cmd
,
arg
);
BT_DBG
(
"cmd %x arg %lx"
,
cmd
,
arg
);
switch
(
cmd
)
{
switch
(
cmd
)
{
case
BNEPCONADD
:
case
BNEPCON
N
ADD
:
if
(
!
capable
(
CAP_NET_ADMIN
))
if
(
!
capable
(
CAP_NET_ADMIN
))
return
-
EACCES
;
return
-
EACCES
;
...
@@ -106,7 +106,7 @@ static int bnep_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long
...
@@ -106,7 +106,7 @@ static int bnep_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long
return
err
;
return
err
;
case
BNEPCONDEL
:
case
BNEPCON
N
DEL
:
if
(
!
capable
(
CAP_NET_ADMIN
))
if
(
!
capable
(
CAP_NET_ADMIN
))
return
-
EACCES
;
return
-
EACCES
;
...
@@ -115,24 +115,24 @@ static int bnep_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long
...
@@ -115,24 +115,24 @@ static int bnep_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long
return
bnep_del_connection
(
&
cd
);
return
bnep_del_connection
(
&
cd
);
case
BNEPGETCONLIST
:
case
BNEPGETCON
N
LIST
:
if
(
copy_from_user
(
&
cl
,
(
void
*
)
arg
,
sizeof
(
cl
)))
if
(
copy_from_user
(
&
cl
,
(
void
*
)
arg
,
sizeof
(
cl
)))
return
-
EFAULT
;
return
-
EFAULT
;
if
(
cl
.
cnum
<=
0
)
if
(
cl
.
cnum
<=
0
)
return
-
EINVAL
;
return
-
EINVAL
;
err
=
bnep_get_conlist
(
&
cl
);
err
=
bnep_get_con
n
list
(
&
cl
);
if
(
!
err
&&
copy_to_user
((
void
*
)
arg
,
&
cl
,
sizeof
(
cl
)))
if
(
!
err
&&
copy_to_user
((
void
*
)
arg
,
&
cl
,
sizeof
(
cl
)))
return
-
EFAULT
;
return
-
EFAULT
;
return
err
;
return
err
;
case
BNEPGETCONINFO
:
case
BNEPGETCON
N
INFO
:
if
(
copy_from_user
(
&
ci
,
(
void
*
)
arg
,
sizeof
(
ci
)))
if
(
copy_from_user
(
&
ci
,
(
void
*
)
arg
,
sizeof
(
ci
)))
return
-
EFAULT
;
return
-
EFAULT
;
err
=
bnep_get_coninfo
(
&
ci
);
err
=
bnep_get_con
n
info
(
&
ci
);
if
(
!
err
&&
copy_to_user
((
void
*
)
arg
,
&
ci
,
sizeof
(
ci
)))
if
(
!
err
&&
copy_to_user
((
void
*
)
arg
,
&
ci
,
sizeof
(
ci
)))
return
-
EFAULT
;
return
-
EFAULT
;
...
@@ -192,13 +192,13 @@ static struct net_proto_family bnep_sock_family_ops = {
...
@@ -192,13 +192,13 @@ static struct net_proto_family bnep_sock_family_ops = {
.
create
=
bnep_sock_create
.
create
=
bnep_sock_create
};
};
int
bnep_sock_init
(
void
)
int
__init
bnep_sock_init
(
void
)
{
{
bt_sock_register
(
BTPROTO_BNEP
,
&
bnep_sock_family_ops
);
bt_sock_register
(
BTPROTO_BNEP
,
&
bnep_sock_family_ops
);
return
0
;
return
0
;
}
}
int
bnep_sock_cleanup
(
void
)
int
__exit
bnep_sock_cleanup
(
void
)
{
{
if
(
bt_sock_unregister
(
BTPROTO_BNEP
))
if
(
bt_sock_unregister
(
BTPROTO_BNEP
))
BT_ERR
(
"Can't unregister BNEP socket"
);
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)
...
@@ -218,8 +218,7 @@ struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src)
read_lock_bh
(
&
hci_dev_list_lock
);
read_lock_bh
(
&
hci_dev_list_lock
);
list_for_each
(
p
,
&
hci_dev_list
)
{
list_for_each
(
p
,
&
hci_dev_list
)
{
struct
hci_dev
*
d
;
struct
hci_dev
*
d
=
list_entry
(
p
,
struct
hci_dev
,
list
);
d
=
list_entry
(
p
,
struct
hci_dev
,
list
);
if
(
!
test_bit
(
HCI_UP
,
&
d
->
flags
))
if
(
!
test_bit
(
HCI_UP
,
&
d
->
flags
))
continue
;
continue
;
...
@@ -241,7 +240,7 @@ struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src)
...
@@ -241,7 +240,7 @@ struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src)
}
}
if
(
hdev
)
if
(
hdev
)
hci_dev_hold
(
hdev
);
h
dev
=
h
ci_dev_hold
(
hdev
);
read_unlock_bh
(
&
hci_dev_list_lock
);
read_unlock_bh
(
&
hci_dev_list_lock
);
return
hdev
;
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)
...
@@ -287,10 +287,10 @@ static void hci_encrypt_req(struct hci_dev *hdev, unsigned long opt)
}
}
/* Get HCI device by index.
/* 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
*
hci_dev_get
(
int
index
)
{
{
struct
hci_dev
*
hdev
;
struct
hci_dev
*
hdev
=
NULL
;
struct
list_head
*
p
;
struct
list_head
*
p
;
BT_DBG
(
"%d"
,
index
);
BT_DBG
(
"%d"
,
index
);
...
@@ -300,14 +300,12 @@ struct hci_dev *hci_dev_get(int index)
...
@@ -300,14 +300,12 @@ struct hci_dev *hci_dev_get(int index)
read_lock
(
&
hci_dev_list_lock
);
read_lock
(
&
hci_dev_list_lock
);
list_for_each
(
p
,
&
hci_dev_list
)
{
list_for_each
(
p
,
&
hci_dev_list
)
{
hdev
=
list_entry
(
p
,
struct
hci_dev
,
list
);
struct
hci_dev
*
d
=
list_entry
(
p
,
struct
hci_dev
,
list
);
if
(
hdev
->
id
==
index
)
{
if
(
d
->
id
==
index
)
{
h
ci_dev_hold
(
hdev
);
h
dev
=
hci_dev_hold
(
d
);
goto
done
;
break
;
}
}
}
}
hdev
=
NULL
;
done:
read_unlock
(
&
hci_dev_list_lock
);
read_unlock
(
&
hci_dev_list_lock
);
return
hdev
;
return
hdev
;
}
}
...
@@ -483,6 +481,7 @@ int hci_dev_open(__u16 dev)
...
@@ -483,6 +481,7 @@ int hci_dev_open(__u16 dev)
}
}
if
(
!
ret
)
{
if
(
!
ret
)
{
hci_dev_hold
(
hdev
);
set_bit
(
HCI_UP
,
&
hdev
->
flags
);
set_bit
(
HCI_UP
,
&
hdev
->
flags
);
hci_notify
(
hdev
,
HCI_DEV_UP
);
hci_notify
(
hdev
,
HCI_DEV_UP
);
}
else
{
}
else
{
...
@@ -567,6 +566,8 @@ static int hci_dev_do_close(struct hci_dev *hdev)
...
@@ -567,6 +566,8 @@ static int hci_dev_do_close(struct hci_dev *hdev)
hdev
->
flags
=
0
;
hdev
->
flags
=
0
;
hci_req_unlock
(
hdev
);
hci_req_unlock
(
hdev
);
hci_dev_put
(
hdev
);
return
0
;
return
0
;
}
}
...
@@ -718,7 +719,7 @@ int hci_get_dev_list(unsigned long arg)
...
@@ -718,7 +719,7 @@ int hci_get_dev_list(unsigned long arg)
if
(
!
dev_num
)
if
(
!
dev_num
)
return
-
EINVAL
;
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
))
if
(
verify_area
(
VERIFY_WRITE
,
(
void
*
)
arg
,
size
))
return
-
EFAULT
;
return
-
EFAULT
;
...
@@ -739,7 +740,7 @@ int hci_get_dev_list(unsigned long arg)
...
@@ -739,7 +740,7 @@ int hci_get_dev_list(unsigned long arg)
read_unlock_bh
(
&
hci_dev_list_lock
);
read_unlock_bh
(
&
hci_dev_list_lock
);
dl
->
dev_num
=
n
;
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
);
copy_to_user
((
void
*
)
arg
,
dl
,
size
);
kfree
(
dl
);
kfree
(
dl
);
...
@@ -790,7 +791,7 @@ int hci_register_dev(struct hci_dev *hdev)
...
@@ -790,7 +791,7 @@ int hci_register_dev(struct hci_dev *hdev)
struct
list_head
*
head
=
&
hci_dev_list
,
*
p
;
struct
list_head
*
head
=
&
hci_dev_list
,
*
p
;
int
id
=
0
;
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
)
if
(
!
hdev
->
open
||
!
hdev
->
close
||
!
hdev
->
destruct
)
return
-
EINVAL
;
return
-
EINVAL
;
...
@@ -834,8 +835,6 @@ int hci_register_dev(struct hci_dev *hdev)
...
@@ -834,8 +835,6 @@ int hci_register_dev(struct hci_dev *hdev)
atomic_set
(
&
hdev
->
promisc
,
0
);
atomic_set
(
&
hdev
->
promisc
,
0
);
MOD_INC_USE_COUNT
;
write_unlock_bh
(
&
hci_dev_list_lock
);
write_unlock_bh
(
&
hci_dev_list_lock
);
hci_dev_proc_init
(
hdev
);
hci_dev_proc_init
(
hdev
);
...
@@ -862,9 +861,7 @@ int hci_unregister_dev(struct hci_dev *hdev)
...
@@ -862,9 +861,7 @@ int hci_unregister_dev(struct hci_dev *hdev)
hci_notify
(
hdev
,
HCI_DEV_UNREG
);
hci_notify
(
hdev
,
HCI_DEV_UNREG
);
hci_run_hotplug
(
hdev
->
name
,
"unregister"
);
hci_run_hotplug
(
hdev
->
name
,
"unregister"
);
hci_dev_put
(
hdev
);
__hci_dev_put
(
hdev
);
MOD_DEC_USE_COUNT
;
return
0
;
return
0
;
}
}
...
@@ -954,40 +951,6 @@ static int hci_send_frame(struct sk_buff *skb)
...
@@ -954,40 +951,6 @@ static int hci_send_frame(struct sk_buff *skb)
return
hdev
->
send
(
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 */
/* Send HCI command */
int
hci_send_cmd
(
struct
hci_dev
*
hdev
,
__u16
ogf
,
__u16
ocf
,
__u32
plen
,
void
*
param
)
int
hci_send_cmd
(
struct
hci_dev
*
hdev
,
__u16
ogf
,
__u16
ocf
,
__u32
plen
,
void
*
param
)
{
{
...
@@ -1002,7 +965,7 @@ int hci_send_cmd(struct hci_dev *hdev, __u16 ogf, __u16 ocf, __u32 plen, void *p
...
@@ -1002,7 +965,7 @@ int hci_send_cmd(struct hci_dev *hdev, __u16 ogf, __u16 ocf, __u32 plen, void *p
BT_ERR
(
"%s Can't allocate memory for HCI command"
,
hdev
->
name
);
BT_ERR
(
"%s Can't allocate memory for HCI command"
,
hdev
->
name
);
return
-
ENOMEM
;
return
-
ENOMEM
;
}
}
hdr
=
(
struct
hci_command_hdr
*
)
skb_put
(
skb
,
HCI_COMMAND_HDR_SIZE
);
hdr
=
(
struct
hci_command_hdr
*
)
skb_put
(
skb
,
HCI_COMMAND_HDR_SIZE
);
hdr
->
opcode
=
__cpu_to_le16
(
hci_opcode_pack
(
ogf
,
ocf
));
hdr
->
opcode
=
__cpu_to_le16
(
hci_opcode_pack
(
ogf
,
ocf
));
hdr
->
plen
=
plen
;
hdr
->
plen
=
plen
;
...
...
net/bluetooth/hci_proc.c
View file @
adb35b9d
...
@@ -151,13 +151,13 @@ void hci_dev_proc_cleanup(struct hci_dev *hdev)
...
@@ -151,13 +151,13 @@ void hci_dev_proc_cleanup(struct hci_dev *hdev)
remove_proc_entry
(
id
,
proc_bt_hci
);
remove_proc_entry
(
id
,
proc_bt_hci
);
}
}
int
__init
hci_proc_init
(
void
)
int
__init
hci_proc_init
(
void
)
{
{
proc_bt_hci
=
proc_mkdir
(
"hci"
,
proc_bt
);
proc_bt_hci
=
proc_mkdir
(
"hci"
,
proc_bt
);
return
0
;
return
0
;
}
}
void
__
in
it
hci_proc_cleanup
(
void
)
void
__
ex
it
hci_proc_cleanup
(
void
)
{
{
remove_proc_entry
(
"hci"
,
proc_bt
);
remove_proc_entry
(
"hci"
,
proc_bt
);
}
}
...
@@ -179,7 +179,7 @@ int __init hci_proc_init(void)
...
@@ -179,7 +179,7 @@ int __init hci_proc_init(void)
return
0
;
return
0
;
}
}
void
__
in
it
hci_proc_cleanup
(
void
)
void
__
ex
it
hci_proc_cleanup
(
void
)
{
{
return
;
return
;
}
}
...
...
net/bluetooth/hci_sock.c
View file @
adb35b9d
...
@@ -49,6 +49,7 @@
...
@@ -49,6 +49,7 @@
#include <asm/system.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/uaccess.h>
#include <asm/unaligned.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
#include <net/bluetooth/hci_core.h>
...
@@ -68,14 +69,17 @@ static struct hci_sec_filter hci_sec_filter = {
...
@@ -68,14 +69,17 @@ static struct hci_sec_filter hci_sec_filter = {
{
0xd9fe
,
0x0
},
{
0xd9fe
,
0x0
},
/* Commands */
/* Commands */
{
{
{
0x0
},
/* OGF_LINK_CTL */
/* OGF_LINK_CTL */
{
0x2a000002
,
0x0
,
0x0
,
0x0
},
{
0x2a000002
,
0x0
,
0x0
,
0x0
},
/* OGF_LINK_POLICY */
/* OGF_LINK_POLICY */
{
0x1200
,
0x0
,
0x0
,
0x0
},
{
0x1200
,
0x0
,
0x0
,
0x0
},
/* OGF_HOST_CTL */
/* OGF_HOST_CTL */
{
0x80100000
,
0xa
,
0x0
,
0x0
},
{
0x80100000
,
0x
2
a
,
0x0
,
0x0
},
/* OGF_INFO_PARAM */
/* 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
...
@@ -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
->
pkt_type
=
*
((
unsigned
char
*
)
skb
->
data
);
skb_pull
(
skb
,
1
);
skb_pull
(
skb
,
1
);
skb
->
dev
=
(
void
*
)
hdev
;
if
(
!
capable
(
CAP_NET_RAW
))
{
if
(
skb
->
pkt_type
==
HCI_COMMAND_PKT
)
{
err
=
-
EPERM
;
u16
opcode
=
__le16_to_cpu
(
get_unaligned
((
u16
*
)
skb
->
data
));
u16
ogf
=
hci_opcode_ogf
(
opcode
);
u16
ocf
=
hci_opcode_ocf
(
opcode
);
if
(
skb
->
pkt_type
==
HCI_COMMAND_PKT
)
{
if
(((
ogf
>
HCI_SFLT_MAX_OGF
)
||
u16
opcode
=
__le16_to_cpu
(
*
(
__u16
*
)
skb
->
data
);
!
test_bit
(
ocf
&
HCI_FLT_OCF_BITS
,
hci_sec_filter
.
ocf_mask
[
ogf
]))
&&
u16
ogf
=
hci_opcode_ogf
(
opcode
)
-
1
;
!
capable
(
CAP_NET_RAW
))
{
u16
ocf
=
hci_opcode_ocf
(
opcode
)
&
HCI_FLT_OCF_BITS
;
err
=
-
EPERM
;
goto
drop
;
}
if
(
ogf
>
HCI_SFLT_MAX_OGF
||
if
(
test_bit
(
HCI_RAW
,
&
hdev
->
flags
)
||
(
ogf
==
OGF_VENDOR_CMD
))
{
!
test_bit
(
ocf
,
hci_sec_filter
.
ocf_mask
[
ogf
]))
skb_queue_tail
(
&
hdev
->
raw_q
,
skb
);
goto
drop
;
hci_sched_tx
(
hdev
);
}
else
}
else
{
skb_queue_tail
(
&
hdev
->
cmd_q
,
skb
);
hci_sched_cmd
(
hdev
);
}
}
else
{
if
(
!
capable
(
CAP_NET_RAW
))
{
err
=
-
EPERM
;
goto
drop
;
goto
drop
;
}
skb_queue_tail
(
&
hdev
->
raw_q
,
skb
);
hci_sched_tx
(
hdev
);
}
}
/* Send frame to HCI core */
skb
->
dev
=
(
void
*
)
hdev
;
hci_send_raw
(
skb
);
err
=
len
;
err
=
len
;
done:
done:
...
@@ -625,7 +641,7 @@ struct notifier_block hci_sock_nblock = {
...
@@ -625,7 +641,7 @@ struct notifier_block hci_sock_nblock = {
.
notifier_call
=
hci_sock_dev_event
.
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
))
{
if
(
bt_sock_register
(
BTPROTO_HCI
,
&
hci_sock_family_ops
))
{
BT_ERR
(
"HCI socket registration failed"
);
BT_ERR
(
"HCI socket registration failed"
);
...
@@ -639,7 +655,7 @@ int hci_sock_init(void)
...
@@ -639,7 +655,7 @@ int hci_sock_init(void)
return
0
;
return
0
;
}
}
int
hci_sock_cleanup
(
void
)
int
__exit
hci_sock_cleanup
(
void
)
{
{
if
(
bt_sock_unregister
(
BTPROTO_HCI
))
if
(
bt_sock_unregister
(
BTPROTO_HCI
))
BT_ERR
(
"HCI socket unregistration failed"
);
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
...
@@ -186,69 +186,12 @@ static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, stru
write_unlock
(
&
l
->
lock
);
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 ---- */
/* ---- Socket interface ---- */
static
struct
sock
*
__l2cap_get_sock_by_addr
(
u16
psm
,
bdaddr_t
*
src
)
static
struct
sock
*
__l2cap_get_sock_by_addr
(
u16
psm
,
bdaddr_t
*
src
)
{
{
struct
sock
*
sk
;
struct
sock
*
sk
;
for
(
sk
=
l2cap_sk_list
.
head
;
sk
;
sk
=
sk
->
next
)
{
for
(
sk
=
l2cap_sk_list
.
head
;
sk
;
sk
=
sk
->
next
)
{
if
(
l2cap_pi
(
sk
)
->
psm
==
psm
&&
if
(
l2cap_pi
(
sk
)
->
sport
==
psm
&&
!
bacmp
(
&
bt_sk
(
sk
)
->
src
,
src
))
!
bacmp
(
&
bt_sk
(
sk
)
->
src
,
src
))
break
;
break
;
}
}
return
sk
;
return
sk
;
...
@@ -437,7 +380,10 @@ static int l2cap_sock_create(struct socket *sock, int protocol)
...
@@ -437,7 +380,10 @@ static int l2cap_sock_create(struct socket *sock, int protocol)
if
(
sock
->
type
!=
SOCK_SEQPACKET
&&
sock
->
type
!=
SOCK_DGRAM
&&
sock
->
type
!=
SOCK_RAW
)
if
(
sock
->
type
!=
SOCK_SEQPACKET
&&
sock
->
type
!=
SOCK_DGRAM
&&
sock
->
type
!=
SOCK_RAW
)
return
-
ESOCKTNOSUPPORT
;
return
-
ESOCKTNOSUPPORT
;
if
(
sock
->
type
==
SOCK_RAW
&&
!
capable
(
CAP_NET_RAW
))
return
-
EPERM
;
sock
->
ops
=
&
l2cap_sock_ops
;
sock
->
ops
=
&
l2cap_sock_ops
;
sk
=
l2cap_sock_alloc
(
sock
,
protocol
,
GFP_KERNEL
);
sk
=
l2cap_sock_alloc
(
sock
,
protocol
,
GFP_KERNEL
);
...
@@ -472,7 +418,8 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_
...
@@ -472,7 +418,8 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_
}
else
{
}
else
{
/* Save source address */
/* Save source address */
bacpy
(
&
bt_sk
(
sk
)
->
src
,
&
la
->
l2_bdaddr
);
bacpy
(
&
bt_sk
(
sk
)
->
src
,
&
la
->
l2_bdaddr
);
l2cap_pi
(
sk
)
->
psm
=
la
->
l2_psm
;
l2cap_pi
(
sk
)
->
psm
=
la
->
l2_psm
;
l2cap_pi
(
sk
)
->
sport
=
la
->
l2_psm
;
sk
->
state
=
BT_BOUND
;
sk
->
state
=
BT_BOUND
;
}
}
write_unlock_bh
(
&
l2cap_sk_list
.
lock
);
write_unlock_bh
(
&
l2cap_sk_list
.
lock
);
...
@@ -482,6 +429,62 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_
...
@@ -482,6 +429,62 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_
return
err
;
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
)
static
int
l2cap_sock_connect
(
struct
socket
*
sock
,
struct
sockaddr
*
addr
,
int
alen
,
int
flags
)
{
{
struct
sockaddr_l2
*
la
=
(
struct
sockaddr_l2
*
)
addr
;
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
...
@@ -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
);
bacpy
(
&
bt_sk
(
sk
)
->
dst
,
&
la
->
l2_bdaddr
);
l2cap_pi
(
sk
)
->
psm
=
la
->
l2_psm
;
l2cap_pi
(
sk
)
->
psm
=
la
->
l2_psm
;
if
((
err
=
l2cap_connect
(
sk
)))
if
((
err
=
l2cap_
do_
connect
(
sk
)))
goto
done
;
goto
done
;
wait:
wait:
...
@@ -2051,30 +2054,31 @@ static struct file_operations l2cap_seq_fops = {
...
@@ -2051,30 +2054,31 @@ static struct file_operations l2cap_seq_fops = {
.
release
=
seq_release
,
.
release
=
seq_release
,
};
};
static
int
__init
l2cap_proc_init
(
void
)
static
int
__init
l2cap_proc_init
(
void
)
{
{
struct
proc_dir_entry
*
p
=
create_proc_entry
(
"l2cap"
,
S_IRUGO
,
proc_bt
);
struct
proc_dir_entry
*
p
=
create_proc_entry
(
"l2cap"
,
S_IRUGO
,
proc_bt
);
if
(
!
p
)
if
(
!
p
)
return
-
ENOMEM
;
return
-
ENOMEM
;
p
->
owner
=
THIS_MODULE
;
p
->
proc_fops
=
&
l2cap_seq_fops
;
p
->
proc_fops
=
&
l2cap_seq_fops
;
return
0
;
return
0
;
}
}
static
void
__
in
it
l2cap_proc_cleanup
(
void
)
static
void
__
ex
it
l2cap_proc_cleanup
(
void
)
{
{
remove_proc_entry
(
"l2cap"
,
proc_bt
);
remove_proc_entry
(
"l2cap"
,
proc_bt
);
}
}
#else
/* CONFIG_PROC_FS */
#else
/* CONFIG_PROC_FS */
static
int
__init
l2cap_proc_init
(
void
)
static
int
__init
l2cap_proc_init
(
void
)
{
{
return
0
;
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 */
#endif
/* CONFIG_PROC_FS */
...
@@ -2136,7 +2140,7 @@ int __init l2cap_init(void)
...
@@ -2136,7 +2140,7 @@ int __init l2cap_init(void)
return
0
;
return
0
;
}
}
void
l2cap_cleanup
(
void
)
void
__exit
l2cap_cleanup
(
void
)
{
{
l2cap_proc_cleanup
();
l2cap_proc_cleanup
();
...
...
net/bluetooth/rfcomm/Kconfig
View file @
adb35b9d
config BT_RFCOMM
config BT_RFCOMM
tristate "RFCOMM protocol support"
tristate "RFCOMM protocol support"
depends on BT_L2CAP
depends on BT
&& BT
_L2CAP
help
help
RFCOMM provides connection oriented stream transport. RFCOMM
RFCOMM provides connection oriented stream transport. RFCOMM
support is required for Dialup Networking, OBEX and other Bluetooth
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)
...
@@ -263,7 +263,7 @@ static void rfcomm_dlc_unlink(struct rfcomm_dlc *d)
rfcomm_session_put
(
s
);
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
rfcomm_dlc
*
d
;
struct
list_head
*
p
;
struct
list_head
*
p
;
...
@@ -279,7 +279,8 @@ static struct rfcomm_dlc *rfcomm_dlc_get(struct rfcomm_session *s, int dlci)
...
@@ -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
)
static
int
__rfcomm_dlc_open
(
struct
rfcomm_dlc
*
d
,
bdaddr_t
*
src
,
bdaddr_t
*
dst
,
u8
channel
)
{
{
struct
rfcomm_session
*
s
;
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"
,
BT_DBG
(
"dlc %p state %ld %s %s channel %d dlci %d"
,
d
,
d
->
state
,
batostr
(
src
),
batostr
(
dst
),
channel
,
dlci
);
d
,
d
->
state
,
batostr
(
src
),
batostr
(
dst
),
channel
,
dlci
);
...
@@ -923,7 +924,7 @@ static void rfcomm_make_uih(struct sk_buff *skb, u8 addr)
...
@@ -923,7 +924,7 @@ static void rfcomm_make_uih(struct sk_buff *skb, u8 addr)
}
}
/* ---- RFCOMM frame reception ---- */
/* ---- 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
);
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)
...
@@ -964,7 +965,7 @@ static int rfcomm_recv_ua(struct rfcomm_session *s, int dlci)
return
0
;
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
;
int
err
=
0
;
...
@@ -994,7 +995,7 @@ static int rfcomm_recv_dm(struct rfcomm_session *s, int dlci)
...
@@ -994,7 +995,7 @@ static int rfcomm_recv_dm(struct rfcomm_session *s, int dlci)
return
0
;
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
;
int
err
=
0
;
...
@@ -1030,10 +1031,10 @@ static int rfcomm_recv_disc(struct rfcomm_session *s, int dlci)
...
@@ -1030,10 +1031,10 @@ static int rfcomm_recv_disc(struct rfcomm_session *s, int dlci)
return
0
;
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
;
struct
rfcomm_dlc
*
d
;
int
channel
;
u8
channel
;
BT_DBG
(
"session %p state %ld dlci %d"
,
s
,
s
->
state
,
dlci
);
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)
...
@@ -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_pn
*
pn
=
(
void
*
)
skb
->
data
;
struct
rfcomm_dlc
*
d
;
struct
rfcomm_dlc
*
d
;
int
dlci
=
pn
->
dlci
;
u8
dlci
=
pn
->
dlci
;
BT_DBG
(
"session %p state %ld dlci %d"
,
s
,
s
->
state
,
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)
...
@@ -1141,7 +1142,7 @@ static int rfcomm_recv_pn(struct rfcomm_session *s, int cr, struct sk_buff *skb)
}
}
}
}
}
else
{
}
else
{
int
channel
=
__srv_channel
(
dlci
);
u8
channel
=
__srv_channel
(
dlci
);
if
(
!
cr
)
if
(
!
cr
)
return
0
;
return
0
;
...
@@ -1167,7 +1168,7 @@ static int rfcomm_recv_pn(struct rfcomm_session *s, int cr, struct sk_buff *skb)
...
@@ -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
)
static
int
rfcomm_recv_rpn
(
struct
rfcomm_session
*
s
,
int
cr
,
int
len
,
struct
sk_buff
*
skb
)
{
{
struct
rfcomm_rpn
*
rpn
=
(
void
*
)
skb
->
data
;
struct
rfcomm_rpn
*
rpn
=
(
void
*
)
skb
->
data
;
int
dlci
=
__get_dlci
(
rpn
->
dlci
);
u8
dlci
=
__get_dlci
(
rpn
->
dlci
);
u8
bit_rate
=
0
;
u8
bit_rate
=
0
;
u8
data_bits
=
0
;
u8
data_bits
=
0
;
...
@@ -1257,7 +1258,7 @@ static int rfcomm_recv_msc(struct rfcomm_session *s, int cr, struct sk_buff *skb
...
@@ -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_msc
*
msc
=
(
void
*
)
skb
->
data
;
struct
rfcomm_dlc
*
d
;
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
);
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)
...
@@ -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
);
rfcomm_send_test
(
s
,
0
,
skb
->
data
,
skb
->
len
);
break
;
break
;
case
RFCOMM_NSC
:
break
;
default:
default:
BT_ERR
(
"Unknown control type 0x%02x"
,
type
);
BT_ERR
(
"Unknown control type 0x%02x"
,
type
);
rfcomm_send_nsc
(
s
,
cr
,
type
);
rfcomm_send_nsc
(
s
,
cr
,
type
);
...
@@ -1320,7 +1324,7 @@ static int rfcomm_recv_mcc(struct rfcomm_session *s, struct sk_buff *skb)
...
@@ -1320,7 +1324,7 @@ static int rfcomm_recv_mcc(struct rfcomm_session *s, struct sk_buff *skb)
return
0
;
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
;
struct
rfcomm_dlc
*
d
;
...
@@ -1442,7 +1446,7 @@ static inline int rfcomm_process_tx(struct rfcomm_dlc *d)
...
@@ -1442,7 +1446,7 @@ static inline int rfcomm_process_tx(struct rfcomm_dlc *d)
/* Send pending MSC */
/* Send pending MSC */
if
(
test_and_clear_bit
(
RFCOMM_MSC_PENDING
,
&
d
->
flags
))
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
)
{
if
(
d
->
credits
)
{
/* CFC enabled.
/* CFC enabled.
...
@@ -1799,19 +1803,22 @@ static struct file_operations rfcomm_seq_fops = {
...
@@ -1799,19 +1803,22 @@ static struct file_operations rfcomm_seq_fops = {
.
release
=
seq_release
,
.
release
=
seq_release
,
};
};
static
int
__init
rfcomm_proc_init
(
void
)
static
int
__init
rfcomm_proc_init
(
void
)
{
{
struct
proc_dir_entry
*
p
;
struct
proc_dir_entry
*
p
;
proc_bt_rfcomm
=
proc_mkdir
(
"rfcomm"
,
proc_bt
);
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
);
p
=
create_proc_entry
(
"dlc"
,
S_IRUGO
,
proc_bt_rfcomm
);
if
(
p
)
if
(
p
)
p
->
proc_fops
=
&
rfcomm_seq_fops
;
p
->
proc_fops
=
&
rfcomm_seq_fops
;
}
return
0
;
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
);
remove_proc_entry
(
"dlc"
,
proc_bt_rfcomm
);
...
@@ -1820,19 +1827,19 @@ static void __init rfcomm_proc_cleanup(void)
...
@@ -1820,19 +1827,19 @@ static void __init rfcomm_proc_cleanup(void)
#else
/* CONFIG_PROC_FS */
#else
/* CONFIG_PROC_FS */
static
int
__init
rfcomm_proc_init
(
void
)
static
int
__init
rfcomm_proc_init
(
void
)
{
{
return
0
;
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 */
#endif
/* CONFIG_PROC_FS */
/* ---- Initialization ---- */
/* ---- Initialization ---- */
int
__init
rfcomm_init
(
void
)
int
__init
rfcomm_init
(
void
)
{
{
kernel_thread
(
rfcomm_run
,
NULL
,
CLONE_FS
|
CLONE_FILES
|
CLONE_SIGHAND
);
kernel_thread
(
rfcomm_run
,
NULL
,
CLONE_FS
|
CLONE_FILES
|
CLONE_SIGHAND
);
...
@@ -1849,7 +1856,7 @@ int __init rfcomm_init(void)
...
@@ -1849,7 +1856,7 @@ int __init rfcomm_init(void)
return
0
;
return
0
;
}
}
void
rfcomm_cleanup
(
void
)
void
__exit
rfcomm_cleanup
(
void
)
{
{
/* Terminate working thread.
/* Terminate working thread.
* ie. Set terminate flag and wake it up */
* 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)
...
@@ -112,7 +112,7 @@ static void rfcomm_sk_state_change(struct rfcomm_dlc *d, int err)
}
}
/* ---- Socket functions ---- */
/* ---- 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
;
struct
sock
*
sk
;
...
@@ -128,7 +128,7 @@ static struct sock *__rfcomm_get_sock_by_addr(int channel, bdaddr_t *src)
...
@@ -128,7 +128,7 @@ static struct sock *__rfcomm_get_sock_by_addr(int channel, bdaddr_t *src)
/* Find socket with channel and source bdaddr.
/* Find socket with channel and source bdaddr.
* Returns closest match.
* 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
;
struct
sock
*
sk
,
*
sk1
=
NULL
;
...
@@ -151,7 +151,7 @@ static struct sock *__rfcomm_get_sock_by_channel(int state, __u16 channel, bdadd
...
@@ -151,7 +151,7 @@ static struct sock *__rfcomm_get_sock_by_channel(int state, __u16 channel, bdadd
/* Find socket with given address (channel, src).
/* Find socket with given address (channel, src).
* Returns locked socket */
* 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
;
struct
sock
*
s
;
read_lock
(
&
rfcomm_sk_list
.
lock
);
read_lock
(
&
rfcomm_sk_list
.
lock
);
...
@@ -828,7 +828,7 @@ static struct file_operations rfcomm_seq_fops = {
...
@@ -828,7 +828,7 @@ static struct file_operations rfcomm_seq_fops = {
.
release
=
seq_release
,
.
release
=
seq_release
,
};
};
static
int
__init
rfcomm_sock_proc_init
(
void
)
static
int
__init
rfcomm_sock_proc_init
(
void
)
{
{
struct
proc_dir_entry
*
p
=
create_proc_entry
(
"sock"
,
S_IRUGO
,
proc_bt_rfcomm
);
struct
proc_dir_entry
*
p
=
create_proc_entry
(
"sock"
,
S_IRUGO
,
proc_bt_rfcomm
);
if
(
!
p
)
if
(
!
p
)
...
@@ -837,21 +837,21 @@ static int __init rfcomm_sock_proc_init(void)
...
@@ -837,21 +837,21 @@ static int __init rfcomm_sock_proc_init(void)
return
0
;
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
);
remove_proc_entry
(
"sock"
,
proc_bt_rfcomm
);
}
}
#else
/* CONFIG_PROC_FS */
#else
/* CONFIG_PROC_FS */
static
int
__init
rfcomm_sock_proc_init
(
void
)
static
int
__init
rfcomm_sock_proc_init
(
void
)
{
{
return
0
;
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 */
#endif
/* CONFIG_PROC_FS */
...
@@ -879,7 +879,7 @@ static struct net_proto_family rfcomm_sock_family_ops = {
...
@@ -879,7 +879,7 @@ static struct net_proto_family rfcomm_sock_family_ops = {
.
create
=
rfcomm_sock_create
.
create
=
rfcomm_sock_create
};
};
int
rfcomm_init_sockets
(
void
)
int
__init
rfcomm_init_sockets
(
void
)
{
{
int
err
;
int
err
;
...
@@ -894,7 +894,7 @@ int rfcomm_init_sockets(void)
...
@@ -894,7 +894,7 @@ int rfcomm_init_sockets(void)
return
0
;
return
0
;
}
}
void
rfcomm_cleanup_sockets
(
void
)
void
__exit
rfcomm_cleanup_sockets
(
void
)
{
{
int
err
;
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
...
@@ -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
)
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
);
struct
sk_buff
*
skb
=
alloc_skb
(
size
,
priority
);
if
(
skb
)
{
if
(
skb
)
{
rfcomm_set_owner_w
(
skb
,
dev
);
rfcomm_set_owner_w
(
skb
,
dev
);
...
@@ -442,7 +442,7 @@ static void rfcomm_dev_data_ready(struct rfcomm_dlc *dlc, struct sk_buff *skb)
...
@@ -442,7 +442,7 @@ static void rfcomm_dev_data_ready(struct rfcomm_dlc *dlc, struct sk_buff *skb)
struct
tty_struct
*
tty
;
struct
tty_struct
*
tty
;
if
(
!
dev
||
!
(
tty
=
dev
->
tty
))
{
if
(
!
dev
||
!
(
tty
=
dev
->
tty
))
{
kfree
(
skb
);
kfree
_skb
(
skb
);
return
;
return
;
}
}
...
@@ -669,12 +669,12 @@ static int rfcomm_tty_set_modem_status(uint cmd, struct rfcomm_dlc *dlc, uint st
...
@@ -669,12 +669,12 @@ static int rfcomm_tty_set_modem_status(uint cmd, struct rfcomm_dlc *dlc, uint st
else
else
rfcomm_dlc_get_modem_status
(
dlc
,
&
v24_sig
);
rfcomm_dlc_get_modem_status
(
dlc
,
&
v24_sig
);
mask
=
(
status
&
TIOCM_DSR
)
?
RFCOMM_V24_RTC
:
0
|
mask
=
(
(
status
&
TIOCM_DSR
)
?
RFCOMM_V24_RTC
:
0
)
|
(
status
&
TIOCM_DTR
)
?
RFCOMM_V24_RTC
:
0
|
(
(
status
&
TIOCM_DTR
)
?
RFCOMM_V24_RTC
:
0
)
|
(
status
&
TIOCM_RTS
)
?
RFCOMM_V24_RTR
:
0
|
(
(
status
&
TIOCM_RTS
)
?
RFCOMM_V24_RTR
:
0
)
|
(
status
&
TIOCM_CTS
)
?
RFCOMM_V24_RTR
:
0
|
(
(
status
&
TIOCM_CTS
)
?
RFCOMM_V24_RTR
:
0
)
|
(
status
&
TIOCM_RI
)
?
RFCOMM_V24_IC
:
0
|
(
(
status
&
TIOCM_RI
)
?
RFCOMM_V24_IC
:
0
)
|
(
status
&
TIOCM_CD
)
?
RFCOMM_V24_DV
:
0
;
(
(
status
&
TIOCM_CD
)
?
RFCOMM_V24_DV
:
0
)
;
if
(
cmd
==
TIOCMBIC
)
if
(
cmd
==
TIOCMBIC
)
v24_sig
&=
~
mask
;
v24_sig
&=
~
mask
;
...
@@ -854,7 +854,7 @@ static struct tty_driver rfcomm_tty_driver = {
...
@@ -854,7 +854,7 @@ static struct tty_driver rfcomm_tty_driver = {
#ifdef CONFIG_DEVFS_FS
#ifdef CONFIG_DEVFS_FS
.
name
=
"bluetooth/rfcomm/%d"
,
.
name
=
"bluetooth/rfcomm/%d"
,
#else
#else
.
name
=
"rfcomm
%d
"
,
.
name
=
"rfcomm"
,
#endif
#endif
.
major
=
RFCOMM_TTY_MAJOR
,
.
major
=
RFCOMM_TTY_MAJOR
,
.
minor_start
=
RFCOMM_TTY_MINOR
,
.
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
...
@@ -698,7 +698,7 @@ int sco_sock_getsockopt(struct socket *sock, int level, int optname, char *optva
opts
.
mtu
=
sco_pi
(
sk
)
->
conn
->
mtu
;
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
));
len
=
min_t
(
unsigned
int
,
len
,
sizeof
(
opts
));
if
(
copy_to_user
(
optval
,
(
char
*
)
&
opts
,
len
))
if
(
copy_to_user
(
optval
,
(
char
*
)
&
opts
,
len
))
...
@@ -939,30 +939,31 @@ static struct file_operations sco_seq_fops = {
...
@@ -939,30 +939,31 @@ static struct file_operations sco_seq_fops = {
.
release
=
seq_release
,
.
release
=
seq_release
,
};
};
static
int
__init
sco_proc_init
(
void
)
static
int
__init
sco_proc_init
(
void
)
{
{
struct
proc_dir_entry
*
p
=
create_proc_entry
(
"sco"
,
S_IRUGO
,
proc_bt
);
struct
proc_dir_entry
*
p
=
create_proc_entry
(
"sco"
,
S_IRUGO
,
proc_bt
);
if
(
!
p
)
if
(
!
p
)
return
-
ENOMEM
;
return
-
ENOMEM
;
p
->
owner
=
THIS_MODULE
;
p
->
proc_fops
=
&
sco_seq_fops
;
p
->
proc_fops
=
&
sco_seq_fops
;
return
0
;
return
0
;
}
}
static
void
__
in
it
sco_proc_cleanup
(
void
)
static
void
__
ex
it
sco_proc_cleanup
(
void
)
{
{
remove_proc_entry
(
"sco"
,
proc_bt
);
remove_proc_entry
(
"sco"
,
proc_bt
);
}
}
#else
/* CONFIG_PROC_FS */
#else
/* CONFIG_PROC_FS */
static
int
__init
sco_proc_init
(
void
)
static
int
__init
sco_proc_init
(
void
)
{
{
return
0
;
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 */
#endif
/* CONFIG_PROC_FS */
...
@@ -1021,7 +1022,7 @@ int __init sco_init(void)
...
@@ -1021,7 +1022,7 @@ int __init sco_init(void)
return
0
;
return
0
;
}
}
void
sco_cleanup
(
void
)
void
__exit
sco_cleanup
(
void
)
{
{
int
err
;
int
err
;
...
...
net/bluetooth/syms.c
View file @
adb35b9d
...
@@ -58,7 +58,7 @@ EXPORT_SYMBOL(hci_conn_encrypt);
...
@@ -58,7 +58,7 @@ EXPORT_SYMBOL(hci_conn_encrypt);
EXPORT_SYMBOL
(
hci_send_acl
);
EXPORT_SYMBOL
(
hci_send_acl
);
EXPORT_SYMBOL
(
hci_send_sco
);
EXPORT_SYMBOL
(
hci_send_sco
);
EXPORT_SYMBOL
(
hci_send_
raw
);
EXPORT_SYMBOL
(
hci_send_
cmd
);
EXPORT_SYMBOL
(
hci_si_event
);
EXPORT_SYMBOL
(
hci_si_event
);
/* Bluetooth lib */
/* 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