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
f4f314bf
Commit
f4f314bf
authored
Feb 18, 2011
by
John W. Linville
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' of
git://git.kernel.org/pub/scm/linux/kernel/git/padovan/bluetooth-next-2.6
parents
c269a203
8ffd8784
Changes
24
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
24 changed files
with
1196 additions
and
236 deletions
+1196
-236
drivers/bluetooth/ath3k.c
drivers/bluetooth/ath3k.c
+279
-0
drivers/bluetooth/btusb.c
drivers/bluetooth/btusb.c
+6
-7
drivers/bluetooth/hci_ldisc.c
drivers/bluetooth/hci_ldisc.c
+1
-0
include/net/bluetooth/bluetooth.h
include/net/bluetooth/bluetooth.h
+28
-0
include/net/bluetooth/hci.h
include/net/bluetooth/hci.h
+65
-0
include/net/bluetooth/hci_core.h
include/net/bluetooth/hci_core.h
+58
-34
include/net/bluetooth/l2cap.h
include/net/bluetooth/l2cap.h
+21
-2
include/net/bluetooth/smp.h
include/net/bluetooth/smp.h
+76
-0
net/bluetooth/Kconfig
net/bluetooth/Kconfig
+2
-8
net/bluetooth/Makefile
net/bluetooth/Makefile
+2
-3
net/bluetooth/af_bluetooth.c
net/bluetooth/af_bluetooth.c
+31
-3
net/bluetooth/bnep/core.c
net/bluetooth/bnep/core.c
+0
-2
net/bluetooth/bnep/sock.c
net/bluetooth/bnep/sock.c
+1
-0
net/bluetooth/cmtp/core.c
net/bluetooth/cmtp/core.c
+0
-2
net/bluetooth/hci_conn.c
net/bluetooth/hci_conn.c
+74
-3
net/bluetooth/hci_core.c
net/bluetooth/hci_core.c
+96
-19
net/bluetooth/hci_event.c
net/bluetooth/hci_event.c
+148
-17
net/bluetooth/hci_sysfs.c
net/bluetooth/hci_sysfs.c
+3
-3
net/bluetooth/hidp/core.c
net/bluetooth/hidp/core.c
+0
-2
net/bluetooth/l2cap_core.c
net/bluetooth/l2cap_core.c
+268
-87
net/bluetooth/l2cap_sock.c
net/bluetooth/l2cap_sock.c
+33
-27
net/bluetooth/mgmt.c
net/bluetooth/mgmt.c
+1
-1
net/bluetooth/rfcomm/core.c
net/bluetooth/rfcomm/core.c
+0
-2
net/bluetooth/sco.c
net/bluetooth/sco.c
+3
-14
No files found.
drivers/bluetooth/ath3k.c
View file @
f4f314bf
...
@@ -31,6 +31,30 @@
...
@@ -31,6 +31,30 @@
#define VERSION "1.0"
#define VERSION "1.0"
#define ATH3K_DNLOAD 0x01
#define ATH3K_GETSTATE 0x05
#define ATH3K_SET_NORMAL_MODE 0x07
#define ATH3K_GETVERSION 0x09
#define USB_REG_SWITCH_VID_PID 0x0a
#define ATH3K_MODE_MASK 0x3F
#define ATH3K_NORMAL_MODE 0x0E
#define ATH3K_PATCH_UPDATE 0x80
#define ATH3K_SYSCFG_UPDATE 0x40
#define ATH3K_XTAL_FREQ_26M 0x00
#define ATH3K_XTAL_FREQ_40M 0x01
#define ATH3K_XTAL_FREQ_19P2 0x02
#define ATH3K_NAME_LEN 0xFF
struct
ath3k_version
{
unsigned
int
rom_version
;
unsigned
int
build_version
;
unsigned
int
ram_version
;
unsigned
char
ref_clock
;
unsigned
char
reserved
[
0x07
];
};
static
struct
usb_device_id
ath3k_table
[]
=
{
static
struct
usb_device_id
ath3k_table
[]
=
{
/* Atheros AR3011 */
/* Atheros AR3011 */
...
@@ -41,13 +65,29 @@ static struct usb_device_id ath3k_table[] = {
...
@@ -41,13 +65,29 @@ static struct usb_device_id ath3k_table[] = {
/* Atheros AR9285 Malbec with sflash firmware */
/* Atheros AR9285 Malbec with sflash firmware */
{
USB_DEVICE
(
0x03F0
,
0x311D
)
},
{
USB_DEVICE
(
0x03F0
,
0x311D
)
},
/* Atheros AR3012 with sflash firmware*/
{
USB_DEVICE
(
0x0CF3
,
0x3004
)
},
{
}
/* Terminating entry */
{
}
/* Terminating entry */
};
};
MODULE_DEVICE_TABLE
(
usb
,
ath3k_table
);
MODULE_DEVICE_TABLE
(
usb
,
ath3k_table
);
#define BTUSB_ATH3012 0x80
/* This table is to load patch and sysconfig files
* for AR3012 */
static
struct
usb_device_id
ath3k_blist_tbl
[]
=
{
/* Atheros AR3012 with sflash firmware*/
{
USB_DEVICE
(
0x0cf3
,
0x3004
),
.
driver_info
=
BTUSB_ATH3012
},
{
}
/* Terminating entry */
};
#define USB_REQ_DFU_DNLOAD 1
#define USB_REQ_DFU_DNLOAD 1
#define BULK_SIZE 4096
#define BULK_SIZE 4096
#define FW_HDR_SIZE 20
static
int
ath3k_load_firmware
(
struct
usb_device
*
udev
,
static
int
ath3k_load_firmware
(
struct
usb_device
*
udev
,
const
struct
firmware
*
firmware
)
const
struct
firmware
*
firmware
)
...
@@ -103,6 +143,215 @@ static int ath3k_load_firmware(struct usb_device *udev,
...
@@ -103,6 +143,215 @@ static int ath3k_load_firmware(struct usb_device *udev,
return
err
;
return
err
;
}
}
static
int
ath3k_get_state
(
struct
usb_device
*
udev
,
unsigned
char
*
state
)
{
int
pipe
=
0
;
pipe
=
usb_rcvctrlpipe
(
udev
,
0
);
return
usb_control_msg
(
udev
,
pipe
,
ATH3K_GETSTATE
,
USB_TYPE_VENDOR
|
USB_DIR_IN
,
0
,
0
,
state
,
0x01
,
USB_CTRL_SET_TIMEOUT
);
}
static
int
ath3k_get_version
(
struct
usb_device
*
udev
,
struct
ath3k_version
*
version
)
{
int
pipe
=
0
;
pipe
=
usb_rcvctrlpipe
(
udev
,
0
);
return
usb_control_msg
(
udev
,
pipe
,
ATH3K_GETVERSION
,
USB_TYPE_VENDOR
|
USB_DIR_IN
,
0
,
0
,
version
,
sizeof
(
struct
ath3k_version
),
USB_CTRL_SET_TIMEOUT
);
}
static
int
ath3k_load_fwfile
(
struct
usb_device
*
udev
,
const
struct
firmware
*
firmware
)
{
u8
*
send_buf
;
int
err
,
pipe
,
len
,
size
,
count
,
sent
=
0
;
int
ret
;
count
=
firmware
->
size
;
send_buf
=
kmalloc
(
BULK_SIZE
,
GFP_ATOMIC
);
if
(
!
send_buf
)
{
BT_ERR
(
"Can't allocate memory chunk for firmware"
);
return
-
ENOMEM
;
}
size
=
min_t
(
uint
,
count
,
FW_HDR_SIZE
);
memcpy
(
send_buf
,
firmware
->
data
,
size
);
pipe
=
usb_sndctrlpipe
(
udev
,
0
);
ret
=
usb_control_msg
(
udev
,
pipe
,
ATH3K_DNLOAD
,
USB_TYPE_VENDOR
,
0
,
0
,
send_buf
,
size
,
USB_CTRL_SET_TIMEOUT
);
if
(
ret
<
0
)
{
BT_ERR
(
"Can't change to loading configuration err"
);
kfree
(
send_buf
);
return
ret
;
}
sent
+=
size
;
count
-=
size
;
while
(
count
)
{
size
=
min_t
(
uint
,
count
,
BULK_SIZE
);
pipe
=
usb_sndbulkpipe
(
udev
,
0x02
);
memcpy
(
send_buf
,
firmware
->
data
+
sent
,
size
);
err
=
usb_bulk_msg
(
udev
,
pipe
,
send_buf
,
size
,
&
len
,
3000
);
if
(
err
||
(
len
!=
size
))
{
BT_ERR
(
"Error in firmware loading err = %d,"
"len = %d, size = %d"
,
err
,
len
,
size
);
kfree
(
send_buf
);
return
err
;
}
sent
+=
size
;
count
-=
size
;
}
kfree
(
send_buf
);
return
0
;
}
static
int
ath3k_switch_pid
(
struct
usb_device
*
udev
)
{
int
pipe
=
0
;
pipe
=
usb_sndctrlpipe
(
udev
,
0
);
return
usb_control_msg
(
udev
,
pipe
,
USB_REG_SWITCH_VID_PID
,
USB_TYPE_VENDOR
,
0
,
0
,
NULL
,
0
,
USB_CTRL_SET_TIMEOUT
);
}
static
int
ath3k_set_normal_mode
(
struct
usb_device
*
udev
)
{
unsigned
char
fw_state
;
int
pipe
=
0
,
ret
;
ret
=
ath3k_get_state
(
udev
,
&
fw_state
);
if
(
ret
<
0
)
{
BT_ERR
(
"Can't get state to change to normal mode err"
);
return
ret
;
}
if
((
fw_state
&
ATH3K_MODE_MASK
)
==
ATH3K_NORMAL_MODE
)
{
BT_DBG
(
"firmware was already in normal mode"
);
return
0
;
}
pipe
=
usb_sndctrlpipe
(
udev
,
0
);
return
usb_control_msg
(
udev
,
pipe
,
ATH3K_SET_NORMAL_MODE
,
USB_TYPE_VENDOR
,
0
,
0
,
NULL
,
0
,
USB_CTRL_SET_TIMEOUT
);
}
static
int
ath3k_load_patch
(
struct
usb_device
*
udev
)
{
unsigned
char
fw_state
;
char
filename
[
ATH3K_NAME_LEN
]
=
{
0
};
const
struct
firmware
*
firmware
;
struct
ath3k_version
fw_version
,
pt_version
;
int
ret
;
ret
=
ath3k_get_state
(
udev
,
&
fw_state
);
if
(
ret
<
0
)
{
BT_ERR
(
"Can't get state to change to load ram patch err"
);
return
ret
;
}
if
(
fw_state
&
ATH3K_PATCH_UPDATE
)
{
BT_DBG
(
"Patch was already downloaded"
);
return
0
;
}
ret
=
ath3k_get_version
(
udev
,
&
fw_version
);
if
(
ret
<
0
)
{
BT_ERR
(
"Can't get version to change to load ram patch err"
);
return
ret
;
}
snprintf
(
filename
,
ATH3K_NAME_LEN
,
"ar3k/AthrBT_0x%08x.dfu"
,
fw_version
.
rom_version
);
ret
=
request_firmware
(
&
firmware
,
filename
,
&
udev
->
dev
);
if
(
ret
<
0
)
{
BT_ERR
(
"Patch file not found %s"
,
filename
);
return
ret
;
}
pt_version
.
rom_version
=
*
(
int
*
)(
firmware
->
data
+
firmware
->
size
-
8
);
pt_version
.
build_version
=
*
(
int
*
)
(
firmware
->
data
+
firmware
->
size
-
4
);
if
((
pt_version
.
rom_version
!=
fw_version
.
rom_version
)
||
(
pt_version
.
build_version
<=
fw_version
.
build_version
))
{
BT_ERR
(
"Patch file version did not match with firmware"
);
release_firmware
(
firmware
);
return
-
EINVAL
;
}
ret
=
ath3k_load_fwfile
(
udev
,
firmware
);
release_firmware
(
firmware
);
return
ret
;
}
static
int
ath3k_load_syscfg
(
struct
usb_device
*
udev
)
{
unsigned
char
fw_state
;
char
filename
[
ATH3K_NAME_LEN
]
=
{
0
};
const
struct
firmware
*
firmware
;
struct
ath3k_version
fw_version
;
int
clk_value
,
ret
;
ret
=
ath3k_get_state
(
udev
,
&
fw_state
);
if
(
ret
<
0
)
{
BT_ERR
(
"Can't get state to change to load configration err"
);
return
-
EBUSY
;
}
ret
=
ath3k_get_version
(
udev
,
&
fw_version
);
if
(
ret
<
0
)
{
BT_ERR
(
"Can't get version to change to load ram patch err"
);
return
ret
;
}
switch
(
fw_version
.
ref_clock
)
{
case
ATH3K_XTAL_FREQ_26M
:
clk_value
=
26
;
break
;
case
ATH3K_XTAL_FREQ_40M
:
clk_value
=
40
;
break
;
case
ATH3K_XTAL_FREQ_19P2
:
clk_value
=
19
;
break
;
default:
clk_value
=
0
;
break
;
}
snprintf
(
filename
,
ATH3K_NAME_LEN
,
"ar3k/ramps_0x%08x_%d%s"
,
fw_version
.
rom_version
,
clk_value
,
".dfu"
);
ret
=
request_firmware
(
&
firmware
,
filename
,
&
udev
->
dev
);
if
(
ret
<
0
)
{
BT_ERR
(
"Configuration file not found %s"
,
filename
);
return
ret
;
}
ret
=
ath3k_load_fwfile
(
udev
,
firmware
);
release_firmware
(
firmware
);
return
ret
;
}
static
int
ath3k_probe
(
struct
usb_interface
*
intf
,
static
int
ath3k_probe
(
struct
usb_interface
*
intf
,
const
struct
usb_device_id
*
id
)
const
struct
usb_device_id
*
id
)
{
{
...
@@ -115,7 +364,37 @@ static int ath3k_probe(struct usb_interface *intf,
...
@@ -115,7 +364,37 @@ static int ath3k_probe(struct usb_interface *intf,
if
(
intf
->
cur_altsetting
->
desc
.
bInterfaceNumber
!=
0
)
if
(
intf
->
cur_altsetting
->
desc
.
bInterfaceNumber
!=
0
)
return
-
ENODEV
;
return
-
ENODEV
;
/* match device ID in ath3k blacklist table */
if
(
!
id
->
driver_info
)
{
const
struct
usb_device_id
*
match
;
match
=
usb_match_id
(
intf
,
ath3k_blist_tbl
);
if
(
match
)
id
=
match
;
}
/* load patch and sysconfig files for AR3012 */
if
(
id
->
driver_info
&
BTUSB_ATH3012
)
{
ret
=
ath3k_load_patch
(
udev
);
if
(
ret
<
0
)
{
BT_ERR
(
"Loading patch file failed"
);
return
ret
;
}
ret
=
ath3k_load_syscfg
(
udev
);
if
(
ret
<
0
)
{
BT_ERR
(
"Loading sysconfig file failed"
);
return
ret
;
}
ret
=
ath3k_set_normal_mode
(
udev
);
if
(
ret
<
0
)
{
BT_ERR
(
"Set normal mode failed"
);
return
ret
;
}
ath3k_switch_pid
(
udev
);
return
0
;
}
if
(
request_firmware
(
&
firmware
,
"ath3k-1.fw"
,
&
udev
->
dev
)
<
0
)
{
if
(
request_firmware
(
&
firmware
,
"ath3k-1.fw"
,
&
udev
->
dev
)
<
0
)
{
BT_ERR
(
"Error loading firmware"
);
return
-
EIO
;
return
-
EIO
;
}
}
...
...
drivers/bluetooth/btusb.c
View file @
f4f314bf
...
@@ -105,6 +105,9 @@ static struct usb_device_id blacklist_table[] = {
...
@@ -105,6 +105,9 @@ static struct usb_device_id blacklist_table[] = {
/* Atheros AR9285 Malbec with sflash firmware */
/* Atheros AR9285 Malbec with sflash firmware */
{
USB_DEVICE
(
0x03f0
,
0x311d
),
.
driver_info
=
BTUSB_IGNORE
},
{
USB_DEVICE
(
0x03f0
,
0x311d
),
.
driver_info
=
BTUSB_IGNORE
},
/* Atheros 3012 with sflash firmware */
{
USB_DEVICE
(
0x0cf3
,
0x3004
),
.
driver_info
=
BTUSB_IGNORE
},
/* Broadcom BCM2035 */
/* Broadcom BCM2035 */
{
USB_DEVICE
(
0x0a5c
,
0x2035
),
.
driver_info
=
BTUSB_WRONG_SCO_MTU
},
{
USB_DEVICE
(
0x0a5c
,
0x2035
),
.
driver_info
=
BTUSB_WRONG_SCO_MTU
},
{
USB_DEVICE
(
0x0a5c
,
0x200a
),
.
driver_info
=
BTUSB_WRONG_SCO_MTU
},
{
USB_DEVICE
(
0x0a5c
,
0x200a
),
.
driver_info
=
BTUSB_WRONG_SCO_MTU
},
...
@@ -711,15 +714,11 @@ static int btusb_send_frame(struct sk_buff *skb)
...
@@ -711,15 +714,11 @@ static int btusb_send_frame(struct sk_buff *skb)
pipe
=
usb_sndisocpipe
(
data
->
udev
,
pipe
=
usb_sndisocpipe
(
data
->
udev
,
data
->
isoc_tx_ep
->
bEndpointAddress
);
data
->
isoc_tx_ep
->
bEndpointAddress
);
urb
->
dev
=
data
->
udev
;
usb_fill_int_urb
(
urb
,
data
->
udev
,
pipe
,
urb
->
pipe
=
pipe
;
skb
->
data
,
skb
->
len
,
btusb_isoc_tx_complete
,
urb
->
context
=
skb
;
skb
,
data
->
isoc_tx_ep
->
bInterval
);
urb
->
complete
=
btusb_isoc_tx_complete
;
urb
->
interval
=
data
->
isoc_tx_ep
->
bInterval
;
urb
->
transfer_flags
=
URB_ISO_ASAP
;
urb
->
transfer_flags
=
URB_ISO_ASAP
;
urb
->
transfer_buffer
=
skb
->
data
;
urb
->
transfer_buffer_length
=
skb
->
len
;
__fill_isoc_descriptor
(
urb
,
skb
->
len
,
__fill_isoc_descriptor
(
urb
,
skb
->
len
,
le16_to_cpu
(
data
->
isoc_tx_ep
->
wMaxPacketSize
));
le16_to_cpu
(
data
->
isoc_tx_ep
->
wMaxPacketSize
));
...
...
drivers/bluetooth/hci_ldisc.c
View file @
f4f314bf
...
@@ -398,6 +398,7 @@ static int hci_uart_register_dev(struct hci_uart *hu)
...
@@ -398,6 +398,7 @@ static int hci_uart_register_dev(struct hci_uart *hu)
hdev
->
flush
=
hci_uart_flush
;
hdev
->
flush
=
hci_uart_flush
;
hdev
->
send
=
hci_uart_send_frame
;
hdev
->
send
=
hci_uart_send_frame
;
hdev
->
destruct
=
hci_uart_destruct
;
hdev
->
destruct
=
hci_uart_destruct
;
hdev
->
parent
=
hu
->
tty
->
dev
;
hdev
->
owner
=
THIS_MODULE
;
hdev
->
owner
=
THIS_MODULE
;
...
...
include/net/bluetooth/bluetooth.h
View file @
f4f314bf
...
@@ -205,4 +205,32 @@ extern void bt_sysfs_cleanup(void);
...
@@ -205,4 +205,32 @@ extern void bt_sysfs_cleanup(void);
extern
struct
dentry
*
bt_debugfs
;
extern
struct
dentry
*
bt_debugfs
;
#ifdef CONFIG_BT_L2CAP
int
l2cap_init
(
void
);
void
l2cap_exit
(
void
);
#else
static
inline
int
l2cap_init
(
void
)
{
return
0
;
}
static
inline
void
l2cap_exit
(
void
)
{
}
#endif
#ifdef CONFIG_BT_SCO
int
sco_init
(
void
);
void
sco_exit
(
void
);
#else
static
inline
int
sco_init
(
void
)
{
return
0
;
}
static
inline
void
sco_exit
(
void
)
{
}
#endif
#endif
/* __BLUETOOTH_H */
#endif
/* __BLUETOOTH_H */
include/net/bluetooth/hci.h
View file @
f4f314bf
...
@@ -119,6 +119,7 @@ enum {
...
@@ -119,6 +119,7 @@ enum {
#define HCI_PAIRING_TIMEOUT (60000)
/* 60 seconds */
#define HCI_PAIRING_TIMEOUT (60000)
/* 60 seconds */
#define HCI_IDLE_TIMEOUT (6000)
/* 6 seconds */
#define HCI_IDLE_TIMEOUT (6000)
/* 6 seconds */
#define HCI_INIT_TIMEOUT (10000)
/* 10 seconds */
#define HCI_INIT_TIMEOUT (10000)
/* 10 seconds */
#define HCI_CMD_TIMEOUT (1000)
/* 1 seconds */
/* HCI data types */
/* HCI data types */
#define HCI_COMMAND_PKT 0x01
#define HCI_COMMAND_PKT 0x01
...
@@ -168,6 +169,8 @@ enum {
...
@@ -168,6 +169,8 @@ enum {
#define SCO_LINK 0x00
#define SCO_LINK 0x00
#define ACL_LINK 0x01
#define ACL_LINK 0x01
#define ESCO_LINK 0x02
#define ESCO_LINK 0x02
/* Low Energy links do not have defined link type. Use invented one */
#define LE_LINK 0x80
/* LMP features */
/* LMP features */
#define LMP_3SLOT 0x01
#define LMP_3SLOT 0x01
...
@@ -242,6 +245,8 @@ enum {
...
@@ -242,6 +245,8 @@ enum {
#define HCI_AT_GENERAL_BONDING_MITM 0x05
#define HCI_AT_GENERAL_BONDING_MITM 0x05
/* ----- HCI Commands ---- */
/* ----- HCI Commands ---- */
#define HCI_OP_NOP 0x0000
#define HCI_OP_INQUIRY 0x0401
#define HCI_OP_INQUIRY 0x0401
struct
hci_cp_inquiry
{
struct
hci_cp_inquiry
{
__u8
lap
[
3
];
__u8
lap
[
3
];
...
@@ -642,6 +647,47 @@ struct hci_rp_read_bd_addr {
...
@@ -642,6 +647,47 @@ struct hci_rp_read_bd_addr {
bdaddr_t
bdaddr
;
bdaddr_t
bdaddr
;
}
__packed
;
}
__packed
;
#define HCI_OP_LE_SET_EVENT_MASK 0x2001
struct
hci_cp_le_set_event_mask
{
__u8
mask
[
8
];
}
__packed
;
#define HCI_OP_LE_READ_BUFFER_SIZE 0x2002
struct
hci_rp_le_read_buffer_size
{
__u8
status
;
__le16
le_mtu
;
__u8
le_max_pkt
;
}
__packed
;
#define HCI_OP_LE_CREATE_CONN 0x200d
struct
hci_cp_le_create_conn
{
__le16
scan_interval
;
__le16
scan_window
;
__u8
filter_policy
;
__u8
peer_addr_type
;
bdaddr_t
peer_addr
;
__u8
own_address_type
;
__le16
conn_interval_min
;
__le16
conn_interval_max
;
__le16
conn_latency
;
__le16
supervision_timeout
;
__le16
min_ce_len
;
__le16
max_ce_len
;
}
__packed
;
#define HCI_OP_LE_CREATE_CONN_CANCEL 0x200e
#define HCI_OP_LE_CONN_UPDATE 0x2013
struct
hci_cp_le_conn_update
{
__le16
handle
;
__le16
conn_interval_min
;
__le16
conn_interval_max
;
__le16
conn_latency
;
__le16
supervision_timeout
;
__le16
min_ce_len
;
__le16
max_ce_len
;
}
__packed
;
/* ---- HCI Events ---- */
/* ---- HCI Events ---- */
#define HCI_EV_INQUIRY_COMPLETE 0x01
#define HCI_EV_INQUIRY_COMPLETE 0x01
...
@@ -902,6 +948,25 @@ struct hci_ev_remote_host_features {
...
@@ -902,6 +948,25 @@ struct hci_ev_remote_host_features {
__u8
features
[
8
];
__u8
features
[
8
];
}
__packed
;
}
__packed
;
#define HCI_EV_LE_META 0x3e
struct
hci_ev_le_meta
{
__u8
subevent
;
}
__packed
;
/* Low energy meta events */
#define HCI_EV_LE_CONN_COMPLETE 0x01
struct
hci_ev_le_conn_complete
{
__u8
status
;
__le16
handle
;
__u8
role
;
__u8
bdaddr_type
;
bdaddr_t
bdaddr
;
__le16
interval
;
__le16
latency
;
__le16
supervision_timeout
;
__u8
clk_accurancy
;
}
__packed
;
/* Internal events generated by Bluetooth stack */
/* Internal events generated by Bluetooth stack */
#define HCI_EV_STACK_INTERNAL 0xfd
#define HCI_EV_STACK_INTERNAL 0xfd
struct
hci_ev_stack_internal
{
struct
hci_ev_stack_internal
{
...
...
include/net/bluetooth/hci_core.h
View file @
f4f314bf
...
@@ -60,6 +60,7 @@ struct hci_conn_hash {
...
@@ -60,6 +60,7 @@ struct hci_conn_hash {
spinlock_t
lock
;
spinlock_t
lock
;
unsigned
int
acl_num
;
unsigned
int
acl_num
;
unsigned
int
sco_num
;
unsigned
int
sco_num
;
unsigned
int
le_num
;
};
};
struct
bdaddr_list
{
struct
bdaddr_list
{
...
@@ -122,15 +123,18 @@ struct hci_dev {
...
@@ -122,15 +123,18 @@ struct hci_dev {
atomic_t
cmd_cnt
;
atomic_t
cmd_cnt
;
unsigned
int
acl_cnt
;
unsigned
int
acl_cnt
;
unsigned
int
sco_cnt
;
unsigned
int
sco_cnt
;
unsigned
int
le_cnt
;
unsigned
int
acl_mtu
;
unsigned
int
acl_mtu
;
unsigned
int
sco_mtu
;
unsigned
int
sco_mtu
;
unsigned
int
le_mtu
;
unsigned
int
acl_pkts
;
unsigned
int
acl_pkts
;
unsigned
int
sco_pkts
;
unsigned
int
sco_pkts
;
unsigned
int
le_pkts
;
unsigned
long
cmd_last_tx
;
unsigned
long
acl_last_tx
;
unsigned
long
acl_last_tx
;
unsigned
long
sco_last_tx
;
unsigned
long
sco_last_tx
;
unsigned
long
le_last_tx
;
struct
workqueue_struct
*
workqueue
;
struct
workqueue_struct
*
workqueue
;
...
@@ -138,6 +142,7 @@ struct hci_dev {
...
@@ -138,6 +142,7 @@ struct hci_dev {
struct
work_struct
power_off
;
struct
work_struct
power_off
;
struct
timer_list
off_timer
;
struct
timer_list
off_timer
;
struct
timer_list
cmd_timer
;
struct
tasklet_struct
cmd_task
;
struct
tasklet_struct
cmd_task
;
struct
tasklet_struct
rx_task
;
struct
tasklet_struct
rx_task
;
struct
tasklet_struct
tx_task
;
struct
tasklet_struct
tx_task
;
...
@@ -194,37 +199,37 @@ struct hci_dev {
...
@@ -194,37 +199,37 @@ struct hci_dev {
struct
hci_conn
{
struct
hci_conn
{
struct
list_head
list
;
struct
list_head
list
;
atomic_t
refcnt
;
atomic_t
refcnt
;
spinlock_t
lock
;
spinlock_t
lock
;
bdaddr_t
dst
;
bdaddr_t
dst
;
__u16
handle
;
__u16
handle
;
__u16
state
;
__u16
state
;
__u8
mode
;
__u8
mode
;
__u8
type
;
__u8
type
;
__u8
out
;
__u8
out
;
__u8
attempt
;
__u8
attempt
;
__u8
dev_class
[
3
];
__u8
dev_class
[
3
];
__u8
features
[
8
];
__u8
features
[
8
];
__u8
ssp_mode
;
__u8
ssp_mode
;
__u16
interval
;
__u16
interval
;
__u16
pkt_type
;
__u16
pkt_type
;
__u16
link_policy
;
__u16
link_policy
;
__u32
link_mode
;
__u32
link_mode
;
__u8
auth_type
;
__u8
auth_type
;
__u8
sec_level
;
__u8
sec_level
;
__u8
pending_sec_level
;
__u8
pending_sec_level
;
__u8
pin_length
;
__u8
pin_length
;
__u8
io_capability
;
__u8
io_capability
;
__u8
power_save
;
__u8
power_save
;
__u16
disc_timeout
;
__u16
disc_timeout
;
unsigned
long
pend
;
unsigned
long
pend
;
__u8
remote_cap
;
__u8
remote_cap
;
__u8
remote_oob
;
__u8
remote_oob
;
__u8
remote_auth
;
__u8
remote_auth
;
unsigned
int
sent
;
unsigned
int
sent
;
struct
sk_buff_head
data_q
;
struct
sk_buff_head
data_q
;
...
@@ -309,24 +314,40 @@ static inline void hci_conn_hash_add(struct hci_dev *hdev, struct hci_conn *c)
...
@@ -309,24 +314,40 @@ static inline void hci_conn_hash_add(struct hci_dev *hdev, struct hci_conn *c)
{
{
struct
hci_conn_hash
*
h
=
&
hdev
->
conn_hash
;
struct
hci_conn_hash
*
h
=
&
hdev
->
conn_hash
;
list_add
(
&
c
->
list
,
&
h
->
list
);
list_add
(
&
c
->
list
,
&
h
->
list
);
if
(
c
->
type
==
ACL_LINK
)
switch
(
c
->
type
)
{
case
ACL_LINK
:
h
->
acl_num
++
;
h
->
acl_num
++
;
else
break
;
case
LE_LINK
:
h
->
le_num
++
;
break
;
case
SCO_LINK
:
case
ESCO_LINK
:
h
->
sco_num
++
;
h
->
sco_num
++
;
break
;
}
}
}
static
inline
void
hci_conn_hash_del
(
struct
hci_dev
*
hdev
,
struct
hci_conn
*
c
)
static
inline
void
hci_conn_hash_del
(
struct
hci_dev
*
hdev
,
struct
hci_conn
*
c
)
{
{
struct
hci_conn_hash
*
h
=
&
hdev
->
conn_hash
;
struct
hci_conn_hash
*
h
=
&
hdev
->
conn_hash
;
list_del
(
&
c
->
list
);
list_del
(
&
c
->
list
);
if
(
c
->
type
==
ACL_LINK
)
switch
(
c
->
type
)
{
case
ACL_LINK
:
h
->
acl_num
--
;
h
->
acl_num
--
;
else
break
;
case
LE_LINK
:
h
->
le_num
--
;
break
;
case
SCO_LINK
:
case
ESCO_LINK
:
h
->
sco_num
--
;
h
->
sco_num
--
;
break
;
}
}
}
static
inline
struct
hci_conn
*
hci_conn_hash_lookup_handle
(
struct
hci_dev
*
hdev
,
static
inline
struct
hci_conn
*
hci_conn_hash_lookup_handle
(
struct
hci_dev
*
hdev
,
__u16
handle
)
__u16
handle
)
{
{
struct
hci_conn_hash
*
h
=
&
hdev
->
conn_hash
;
struct
hci_conn_hash
*
h
=
&
hdev
->
conn_hash
;
struct
list_head
*
p
;
struct
list_head
*
p
;
...
@@ -341,7 +362,7 @@ static inline struct hci_conn *hci_conn_hash_lookup_handle(struct hci_dev *hdev,
...
@@ -341,7 +362,7 @@ static inline struct hci_conn *hci_conn_hash_lookup_handle(struct hci_dev *hdev,
}
}
static
inline
struct
hci_conn
*
hci_conn_hash_lookup_ba
(
struct
hci_dev
*
hdev
,
static
inline
struct
hci_conn
*
hci_conn_hash_lookup_ba
(
struct
hci_dev
*
hdev
,
__u8
type
,
bdaddr_t
*
ba
)
__u8
type
,
bdaddr_t
*
ba
)
{
{
struct
hci_conn_hash
*
h
=
&
hdev
->
conn_hash
;
struct
hci_conn_hash
*
h
=
&
hdev
->
conn_hash
;
struct
list_head
*
p
;
struct
list_head
*
p
;
...
@@ -356,7 +377,7 @@ static inline struct hci_conn *hci_conn_hash_lookup_ba(struct hci_dev *hdev,
...
@@ -356,7 +377,7 @@ static inline struct hci_conn *hci_conn_hash_lookup_ba(struct hci_dev *hdev,
}
}
static
inline
struct
hci_conn
*
hci_conn_hash_lookup_state
(
struct
hci_dev
*
hdev
,
static
inline
struct
hci_conn
*
hci_conn_hash_lookup_state
(
struct
hci_dev
*
hdev
,
__u8
type
,
__u16
state
)
__u8
type
,
__u16
state
)
{
{
struct
hci_conn_hash
*
h
=
&
hdev
->
conn_hash
;
struct
hci_conn_hash
*
h
=
&
hdev
->
conn_hash
;
struct
list_head
*
p
;
struct
list_head
*
p
;
...
@@ -504,6 +525,7 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
...
@@ -504,6 +525,7 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
#define lmp_esco_capable(dev) ((dev)->features[3] & LMP_ESCO)
#define lmp_esco_capable(dev) ((dev)->features[3] & LMP_ESCO)
#define lmp_ssp_capable(dev) ((dev)->features[6] & LMP_SIMPLE_PAIR)
#define lmp_ssp_capable(dev) ((dev)->features[6] & LMP_SIMPLE_PAIR)
#define lmp_no_flush_capable(dev) ((dev)->features[6] & LMP_NO_FLUSH)
#define lmp_no_flush_capable(dev) ((dev)->features[6] & LMP_NO_FLUSH)
#define lmp_le_capable(dev) ((dev)->features[4] & LMP_LE)
/* ----- HCI protocols ----- */
/* ----- HCI protocols ----- */
struct
hci_proto
{
struct
hci_proto
{
...
@@ -755,4 +777,6 @@ struct hci_sec_filter {
...
@@ -755,4 +777,6 @@ struct hci_sec_filter {
void
hci_req_complete
(
struct
hci_dev
*
hdev
,
__u16
cmd
,
int
result
);
void
hci_req_complete
(
struct
hci_dev
*
hdev
,
__u16
cmd
,
int
result
);
void
hci_le_conn_update
(
struct
hci_conn
*
conn
,
u16
min
,
u16
max
,
u16
latency
,
u16
to_multiplier
);
#endif
/* __HCI_CORE_H */
#endif
/* __HCI_CORE_H */
include/net/bluetooth/l2cap.h
View file @
f4f314bf
...
@@ -38,6 +38,7 @@
...
@@ -38,6 +38,7 @@
#define L2CAP_DEFAULT_MAX_PDU_SIZE 1009
/* Sized for 3-DH5 packet */
#define L2CAP_DEFAULT_MAX_PDU_SIZE 1009
/* Sized for 3-DH5 packet */
#define L2CAP_DEFAULT_ACK_TO 200
#define L2CAP_DEFAULT_ACK_TO 200
#define L2CAP_LOCAL_BUSY_TRIES 12
#define L2CAP_LOCAL_BUSY_TRIES 12
#define L2CAP_LE_DEFAULT_MTU 23
#define L2CAP_CONN_TIMEOUT (40000)
/* 40 seconds */
#define L2CAP_CONN_TIMEOUT (40000)
/* 40 seconds */
#define L2CAP_INFO_TIMEOUT (4000)
/* 4 seconds */
#define L2CAP_INFO_TIMEOUT (4000)
/* 4 seconds */
...
@@ -88,6 +89,8 @@ struct l2cap_conninfo {
...
@@ -88,6 +89,8 @@ struct l2cap_conninfo {
#define L2CAP_ECHO_RSP 0x09
#define L2CAP_ECHO_RSP 0x09
#define L2CAP_INFO_REQ 0x0a
#define L2CAP_INFO_REQ 0x0a
#define L2CAP_INFO_RSP 0x0b
#define L2CAP_INFO_RSP 0x0b
#define L2CAP_CONN_PARAM_UPDATE_REQ 0x12
#define L2CAP_CONN_PARAM_UPDATE_RSP 0x13
/* L2CAP feature mask */
/* L2CAP feature mask */
#define L2CAP_FEAT_FLOWCTL 0x00000001
#define L2CAP_FEAT_FLOWCTL 0x00000001
...
@@ -160,6 +163,9 @@ struct l2cap_conn_rsp {
...
@@ -160,6 +163,9 @@ struct l2cap_conn_rsp {
/* channel indentifier */
/* channel indentifier */
#define L2CAP_CID_SIGNALING 0x0001
#define L2CAP_CID_SIGNALING 0x0001
#define L2CAP_CID_CONN_LESS 0x0002
#define L2CAP_CID_CONN_LESS 0x0002
#define L2CAP_CID_LE_DATA 0x0004
#define L2CAP_CID_LE_SIGNALING 0x0005
#define L2CAP_CID_SMP 0x0006
#define L2CAP_CID_DYN_START 0x0040
#define L2CAP_CID_DYN_START 0x0040
#define L2CAP_CID_DYN_END 0xffff
#define L2CAP_CID_DYN_END 0xffff
...
@@ -255,6 +261,21 @@ struct l2cap_info_rsp {
...
@@ -255,6 +261,21 @@ struct l2cap_info_rsp {
#define L2CAP_IR_SUCCESS 0x0000
#define L2CAP_IR_SUCCESS 0x0000
#define L2CAP_IR_NOTSUPP 0x0001
#define L2CAP_IR_NOTSUPP 0x0001
struct
l2cap_conn_param_update_req
{
__le16
min
;
__le16
max
;
__le16
latency
;
__le16
to_multiplier
;
}
__packed
;
struct
l2cap_conn_param_update_rsp
{
__le16
result
;
}
__packed
;
/* Connection Parameters result */
#define L2CAP_CONN_PARAM_ACCEPTED 0x0000
#define L2CAP_CONN_PARAM_REJECTED 0x0001
/* ----- L2CAP connections ----- */
/* ----- L2CAP connections ----- */
struct
l2cap_chan_list
{
struct
l2cap_chan_list
{
struct
sock
*
head
;
struct
sock
*
head
;
...
@@ -455,6 +476,4 @@ void l2cap_send_disconn_req(struct l2cap_conn *conn, struct sock *sk, int err);
...
@@ -455,6 +476,4 @@ void l2cap_send_disconn_req(struct l2cap_conn *conn, struct sock *sk, int err);
void
l2cap_chan_del
(
struct
sock
*
sk
,
int
err
);
void
l2cap_chan_del
(
struct
sock
*
sk
,
int
err
);
int
l2cap_do_connect
(
struct
sock
*
sk
);
int
l2cap_do_connect
(
struct
sock
*
sk
);
void
l2cap_load
(
void
);
#endif
/* __L2CAP_H */
#endif
/* __L2CAP_H */
include/net/bluetooth/smp.h
0 → 100644
View file @
f4f314bf
#ifndef __SMP_H
#define __SMP_H
struct
smp_command_hdr
{
__u8
code
;
}
__packed
;
#define SMP_CMD_PAIRING_REQ 0x01
#define SMP_CMD_PAIRING_RSP 0x02
struct
smp_cmd_pairing
{
__u8
io_capability
;
__u8
oob_flag
;
__u8
auth_req
;
__u8
max_key_size
;
__u8
init_key_dist
;
__u8
resp_key_dist
;
}
__packed
;
#define SMP_CMD_PAIRING_CONFIRM 0x03
struct
smp_cmd_pairing_confirm
{
__u8
confirm_val
[
16
];
}
__packed
;
#define SMP_CMD_PAIRING_RANDOM 0x04
struct
smp_cmd_pairing_random
{
__u8
rand_val
[
16
];
}
__packed
;
#define SMP_CMD_PAIRING_FAIL 0x05
struct
smp_cmd_pairing_fail
{
__u8
reason
;
}
__packed
;
#define SMP_CMD_ENCRYPT_INFO 0x06
struct
smp_cmd_encrypt_info
{
__u8
ltk
[
16
];
}
__packed
;
#define SMP_CMD_MASTER_IDENT 0x07
struct
smp_cmd_master_ident
{
__u16
ediv
;
__u8
rand
[
8
];
}
__packed
;
#define SMP_CMD_IDENT_INFO 0x08
struct
smp_cmd_ident_info
{
__u8
irk
[
16
];
}
__packed
;
#define SMP_CMD_IDENT_ADDR_INFO 0x09
struct
smp_cmd_ident_addr_info
{
__u8
addr_type
;
bdaddr_t
bdaddr
;
}
__packed
;
#define SMP_CMD_SIGN_INFO 0x0a
struct
smp_cmd_sign_info
{
__u8
csrk
[
16
];
}
__packed
;
#define SMP_CMD_SECURITY_REQ 0x0b
struct
smp_cmd_security_req
{
__u8
auth_req
;
}
__packed
;
#define SMP_PASSKEY_ENTRY_FAILED 0x01
#define SMP_OOB_NOT_AVAIL 0x02
#define SMP_AUTH_REQUIREMENTS 0x03
#define SMP_CONFIRM_FAILED 0x04
#define SMP_PAIRING_NOTSUPP 0x05
#define SMP_ENC_KEY_SIZE 0x06
#define SMP_CMD_NOTSUPP 0x07
#define SMP_UNSPECIFIED 0x08
#define SMP_REPEATED_ATTEMPTS 0x09
#endif
/* __SMP_H */
net/bluetooth/Kconfig
View file @
f4f314bf
...
@@ -32,7 +32,7 @@ menuconfig BT
...
@@ -32,7 +32,7 @@ menuconfig BT
more information, see <http://www.bluez.org/>.
more information, see <http://www.bluez.org/>.
config BT_L2CAP
config BT_L2CAP
tristate
"L2CAP protocol support"
bool
"L2CAP protocol support"
depends on BT
depends on BT
select CRC16
select CRC16
help
help
...
@@ -40,19 +40,13 @@ config BT_L2CAP
...
@@ -40,19 +40,13 @@ config BT_L2CAP
connection oriented and connection-less data transport. L2CAP
connection oriented and connection-less data transport. L2CAP
support is required for most Bluetooth applications.
support is required for most Bluetooth applications.
Say Y here to compile L2CAP support into the kernel or say M to
compile it as module (l2cap).
config BT_SCO
config BT_SCO
tristate
"SCO links support"
bool
"SCO links support"
depends on BT
depends on BT
help
help
SCO link provides voice transport over Bluetooth. SCO support is
SCO link provides voice transport over Bluetooth. SCO support is
required for voice applications like Headset and Audio.
required for voice applications like Headset and Audio.
Say Y here to compile SCO support into the kernel or say M to
compile it as module (sco).
source "net/bluetooth/rfcomm/Kconfig"
source "net/bluetooth/rfcomm/Kconfig"
source "net/bluetooth/bnep/Kconfig"
source "net/bluetooth/bnep/Kconfig"
...
...
net/bluetooth/Makefile
View file @
f4f314bf
...
@@ -3,12 +3,11 @@
...
@@ -3,12 +3,11 @@
#
#
obj-$(CONFIG_BT)
+=
bluetooth.o
obj-$(CONFIG_BT)
+=
bluetooth.o
obj-$(CONFIG_BT_L2CAP)
+=
l2cap.o
obj-$(CONFIG_BT_SCO)
+=
sco.o
obj-$(CONFIG_BT_RFCOMM)
+=
rfcomm/
obj-$(CONFIG_BT_RFCOMM)
+=
rfcomm/
obj-$(CONFIG_BT_BNEP)
+=
bnep/
obj-$(CONFIG_BT_BNEP)
+=
bnep/
obj-$(CONFIG_BT_CMTP)
+=
cmtp/
obj-$(CONFIG_BT_CMTP)
+=
cmtp/
obj-$(CONFIG_BT_HIDP)
+=
hidp/
obj-$(CONFIG_BT_HIDP)
+=
hidp/
bluetooth-y
:=
af_bluetooth.o hci_core.o hci_conn.o hci_event.o mgmt.o hci_sock.o hci_sysfs.o lib.o
bluetooth-y
:=
af_bluetooth.o hci_core.o hci_conn.o hci_event.o mgmt.o hci_sock.o hci_sysfs.o lib.o
l2cap-y
:=
l2cap_core.o l2cap_sock.o
bluetooth-$(CONFIG_BT_L2CAP)
+=
l2cap_core.o l2cap_sock.o
bluetooth-$(CONFIG_BT_SCO)
+=
sco.o
net/bluetooth/af_bluetooth.c
View file @
f4f314bf
...
@@ -40,7 +40,7 @@
...
@@ -40,7 +40,7 @@
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/bluetooth.h>
#define VERSION "2.1
5
"
#define VERSION "2.1
6
"
/* Bluetooth sockets */
/* Bluetooth sockets */
#define BT_MAX_PROTO 8
#define BT_MAX_PROTO 8
...
@@ -397,7 +397,7 @@ static inline unsigned int bt_accept_poll(struct sock *parent)
...
@@ -397,7 +397,7 @@ static inline unsigned int bt_accept_poll(struct sock *parent)
return
0
;
return
0
;
}
}
unsigned
int
bt_sock_poll
(
struct
file
*
file
,
struct
socket
*
sock
,
poll_table
*
wait
)
unsigned
int
bt_sock_poll
(
struct
file
*
file
,
struct
socket
*
sock
,
poll_table
*
wait
)
{
{
struct
sock
*
sk
=
sock
->
sk
;
struct
sock
*
sk
=
sock
->
sk
;
unsigned
int
mask
=
0
;
unsigned
int
mask
=
0
;
...
@@ -545,13 +545,41 @@ static int __init bt_init(void)
...
@@ -545,13 +545,41 @@ static int __init bt_init(void)
BT_INFO
(
"HCI device and connection manager initialized"
);
BT_INFO
(
"HCI device and connection manager initialized"
);
hci_sock_init
();
err
=
hci_sock_init
();
if
(
err
<
0
)
goto
error
;
err
=
l2cap_init
();
if
(
err
<
0
)
{
hci_sock_cleanup
();
goto
sock_err
;
}
err
=
sco_init
();
if
(
err
<
0
)
{
l2cap_exit
();
goto
sock_err
;
}
return
0
;
return
0
;
sock_err:
hci_sock_cleanup
();
error:
sock_unregister
(
PF_BLUETOOTH
);
bt_sysfs_cleanup
();
return
err
;
}
}
static
void
__exit
bt_exit
(
void
)
static
void
__exit
bt_exit
(
void
)
{
{
sco_exit
();
l2cap_exit
();
hci_sock_cleanup
();
hci_sock_cleanup
();
sock_unregister
(
PF_BLUETOOTH
);
sock_unregister
(
PF_BLUETOOTH
);
...
...
net/bluetooth/bnep/core.c
View file @
f4f314bf
...
@@ -708,8 +708,6 @@ static int __init bnep_init(void)
...
@@ -708,8 +708,6 @@ static int __init bnep_init(void)
{
{
char
flt
[
50
]
=
""
;
char
flt
[
50
]
=
""
;
l2cap_load
();
#ifdef CONFIG_BT_BNEP_PROTO_FILTER
#ifdef CONFIG_BT_BNEP_PROTO_FILTER
strcat
(
flt
,
"protocol "
);
strcat
(
flt
,
"protocol "
);
#endif
#endif
...
...
net/bluetooth/bnep/sock.c
View file @
f4f314bf
...
@@ -88,6 +88,7 @@ static int bnep_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long
...
@@ -88,6 +88,7 @@ static int bnep_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long
sockfd_put
(
nsock
);
sockfd_put
(
nsock
);
return
-
EBADFD
;
return
-
EBADFD
;
}
}
ca
.
device
[
sizeof
(
ca
.
device
)
-
1
]
=
0
;
err
=
bnep_add_connection
(
&
ca
,
nsock
);
err
=
bnep_add_connection
(
&
ca
,
nsock
);
if
(
!
err
)
{
if
(
!
err
)
{
...
...
net/bluetooth/cmtp/core.c
View file @
f4f314bf
...
@@ -469,8 +469,6 @@ int cmtp_get_conninfo(struct cmtp_conninfo *ci)
...
@@ -469,8 +469,6 @@ int cmtp_get_conninfo(struct cmtp_conninfo *ci)
static
int
__init
cmtp_init
(
void
)
static
int
__init
cmtp_init
(
void
)
{
{
l2cap_load
();
BT_INFO
(
"CMTP (CAPI Emulation) ver %s"
,
VERSION
);
BT_INFO
(
"CMTP (CAPI Emulation) ver %s"
,
VERSION
);
cmtp_init_sockets
();
cmtp_init_sockets
();
...
...
net/bluetooth/hci_conn.c
View file @
f4f314bf
...
@@ -45,6 +45,33 @@
...
@@ -45,6 +45,33 @@
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
#include <net/bluetooth/hci_core.h>
static
void
hci_le_connect
(
struct
hci_conn
*
conn
)
{
struct
hci_dev
*
hdev
=
conn
->
hdev
;
struct
hci_cp_le_create_conn
cp
;
conn
->
state
=
BT_CONNECT
;
conn
->
out
=
1
;
conn
->
link_mode
|=
HCI_LM_MASTER
;
memset
(
&
cp
,
0
,
sizeof
(
cp
));
cp
.
scan_interval
=
cpu_to_le16
(
0x0004
);
cp
.
scan_window
=
cpu_to_le16
(
0x0004
);
bacpy
(
&
cp
.
peer_addr
,
&
conn
->
dst
);
cp
.
conn_interval_min
=
cpu_to_le16
(
0x0008
);
cp
.
conn_interval_max
=
cpu_to_le16
(
0x0100
);
cp
.
supervision_timeout
=
cpu_to_le16
(
0x0064
);
cp
.
min_ce_len
=
cpu_to_le16
(
0x0001
);
cp
.
max_ce_len
=
cpu_to_le16
(
0x0001
);
hci_send_cmd
(
hdev
,
HCI_OP_LE_CREATE_CONN
,
sizeof
(
cp
),
&
cp
);
}
static
void
hci_le_connect_cancel
(
struct
hci_conn
*
conn
)
{
hci_send_cmd
(
conn
->
hdev
,
HCI_OP_LE_CREATE_CONN_CANCEL
,
0
,
NULL
);
}
void
hci_acl_connect
(
struct
hci_conn
*
conn
)
void
hci_acl_connect
(
struct
hci_conn
*
conn
)
{
{
struct
hci_dev
*
hdev
=
conn
->
hdev
;
struct
hci_dev
*
hdev
=
conn
->
hdev
;
...
@@ -156,6 +183,26 @@ void hci_setup_sync(struct hci_conn *conn, __u16 handle)
...
@@ -156,6 +183,26 @@ void hci_setup_sync(struct hci_conn *conn, __u16 handle)
hci_send_cmd
(
hdev
,
HCI_OP_SETUP_SYNC_CONN
,
sizeof
(
cp
),
&
cp
);
hci_send_cmd
(
hdev
,
HCI_OP_SETUP_SYNC_CONN
,
sizeof
(
cp
),
&
cp
);
}
}
void
hci_le_conn_update
(
struct
hci_conn
*
conn
,
u16
min
,
u16
max
,
u16
latency
,
u16
to_multiplier
)
{
struct
hci_cp_le_conn_update
cp
;
struct
hci_dev
*
hdev
=
conn
->
hdev
;
memset
(
&
cp
,
0
,
sizeof
(
cp
));
cp
.
handle
=
cpu_to_le16
(
conn
->
handle
);
cp
.
conn_interval_min
=
cpu_to_le16
(
min
);
cp
.
conn_interval_max
=
cpu_to_le16
(
max
);
cp
.
conn_latency
=
cpu_to_le16
(
latency
);
cp
.
supervision_timeout
=
cpu_to_le16
(
to_multiplier
);
cp
.
min_ce_len
=
cpu_to_le16
(
0x0001
);
cp
.
max_ce_len
=
cpu_to_le16
(
0x0001
);
hci_send_cmd
(
hdev
,
HCI_OP_LE_CONN_UPDATE
,
sizeof
(
cp
),
&
cp
);
}
EXPORT_SYMBOL
(
hci_le_conn_update
);
/* Device _must_ be locked */
/* Device _must_ be locked */
void
hci_sco_setup
(
struct
hci_conn
*
conn
,
__u8
status
)
void
hci_sco_setup
(
struct
hci_conn
*
conn
,
__u8
status
)
{
{
...
@@ -193,8 +240,12 @@ static void hci_conn_timeout(unsigned long arg)
...
@@ -193,8 +240,12 @@ static void hci_conn_timeout(unsigned long arg)
switch
(
conn
->
state
)
{
switch
(
conn
->
state
)
{
case
BT_CONNECT
:
case
BT_CONNECT
:
case
BT_CONNECT2
:
case
BT_CONNECT2
:
if
(
conn
->
type
==
ACL_LINK
&&
conn
->
out
)
if
(
conn
->
out
)
{
hci_acl_connect_cancel
(
conn
);
if
(
conn
->
type
==
ACL_LINK
)
hci_acl_connect_cancel
(
conn
);
else
if
(
conn
->
type
==
LE_LINK
)
hci_le_connect_cancel
(
conn
);
}
break
;
break
;
case
BT_CONFIG
:
case
BT_CONFIG
:
case
BT_CONNECTED
:
case
BT_CONNECTED
:
...
@@ -296,6 +347,11 @@ int hci_conn_del(struct hci_conn *conn)
...
@@ -296,6 +347,11 @@ int hci_conn_del(struct hci_conn *conn)
/* Unacked frames */
/* Unacked frames */
hdev
->
acl_cnt
+=
conn
->
sent
;
hdev
->
acl_cnt
+=
conn
->
sent
;
}
else
if
(
conn
->
type
==
LE_LINK
)
{
if
(
hdev
->
le_pkts
)
hdev
->
le_cnt
+=
conn
->
sent
;
else
hdev
->
acl_cnt
+=
conn
->
sent
;
}
else
{
}
else
{
struct
hci_conn
*
acl
=
conn
->
link
;
struct
hci_conn
*
acl
=
conn
->
link
;
if
(
acl
)
{
if
(
acl
)
{
...
@@ -361,15 +417,30 @@ struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src)
...
@@ -361,15 +417,30 @@ struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src)
}
}
EXPORT_SYMBOL
(
hci_get_route
);
EXPORT_SYMBOL
(
hci_get_route
);
/* Create SCO
or ACL
connection.
/* Create SCO
, ACL or LE
connection.
* Device _must_ be locked */
* Device _must_ be locked */
struct
hci_conn
*
hci_connect
(
struct
hci_dev
*
hdev
,
int
type
,
bdaddr_t
*
dst
,
__u8
sec_level
,
__u8
auth_type
)
struct
hci_conn
*
hci_connect
(
struct
hci_dev
*
hdev
,
int
type
,
bdaddr_t
*
dst
,
__u8
sec_level
,
__u8
auth_type
)
{
{
struct
hci_conn
*
acl
;
struct
hci_conn
*
acl
;
struct
hci_conn
*
sco
;
struct
hci_conn
*
sco
;
struct
hci_conn
*
le
;
BT_DBG
(
"%s dst %s"
,
hdev
->
name
,
batostr
(
dst
));
BT_DBG
(
"%s dst %s"
,
hdev
->
name
,
batostr
(
dst
));
if
(
type
==
LE_LINK
)
{
le
=
hci_conn_hash_lookup_ba
(
hdev
,
LE_LINK
,
dst
);
if
(
!
le
)
le
=
hci_conn_add
(
hdev
,
LE_LINK
,
dst
);
if
(
!
le
)
return
NULL
;
if
(
le
->
state
==
BT_OPEN
)
hci_le_connect
(
le
);
hci_conn_hold
(
le
);
return
le
;
}
acl
=
hci_conn_hash_lookup_ba
(
hdev
,
ACL_LINK
,
dst
);
acl
=
hci_conn_hash_lookup_ba
(
hdev
,
ACL_LINK
,
dst
);
if
(
!
acl
)
{
if
(
!
acl
)
{
acl
=
hci_conn_add
(
hdev
,
ACL_LINK
,
dst
);
acl
=
hci_conn_add
(
hdev
,
ACL_LINK
,
dst
);
...
...
net/bluetooth/hci_core.c
View file @
f4f314bf
...
@@ -41,6 +41,7 @@
...
@@ -41,6 +41,7 @@
#include <linux/interrupt.h>
#include <linux/interrupt.h>
#include <linux/notifier.h>
#include <linux/notifier.h>
#include <linux/rfkill.h>
#include <linux/rfkill.h>
#include <linux/timer.h>
#include <net/sock.h>
#include <net/sock.h>
#include <asm/system.h>
#include <asm/system.h>
...
@@ -123,7 +124,7 @@ static void hci_req_cancel(struct hci_dev *hdev, int err)
...
@@ -123,7 +124,7 @@ static void hci_req_cancel(struct hci_dev *hdev, int err)
/* Execute request and wait for completion. */
/* Execute request and wait for completion. */
static
int
__hci_request
(
struct
hci_dev
*
hdev
,
void
(
*
req
)(
struct
hci_dev
*
hdev
,
unsigned
long
opt
),
static
int
__hci_request
(
struct
hci_dev
*
hdev
,
void
(
*
req
)(
struct
hci_dev
*
hdev
,
unsigned
long
opt
),
unsigned
long
opt
,
__u32
timeout
)
unsigned
long
opt
,
__u32
timeout
)
{
{
DECLARE_WAITQUEUE
(
wait
,
current
);
DECLARE_WAITQUEUE
(
wait
,
current
);
int
err
=
0
;
int
err
=
0
;
...
@@ -165,7 +166,7 @@ static int __hci_request(struct hci_dev *hdev, void (*req)(struct hci_dev *hdev,
...
@@ -165,7 +166,7 @@ static int __hci_request(struct hci_dev *hdev, void (*req)(struct hci_dev *hdev,
}
}
static
inline
int
hci_request
(
struct
hci_dev
*
hdev
,
void
(
*
req
)(
struct
hci_dev
*
hdev
,
unsigned
long
opt
),
static
inline
int
hci_request
(
struct
hci_dev
*
hdev
,
void
(
*
req
)(
struct
hci_dev
*
hdev
,
unsigned
long
opt
),
unsigned
long
opt
,
__u32
timeout
)
unsigned
long
opt
,
__u32
timeout
)
{
{
int
ret
;
int
ret
;
...
@@ -263,6 +264,14 @@ static void hci_init_req(struct hci_dev *hdev, unsigned long opt)
...
@@ -263,6 +264,14 @@ static void hci_init_req(struct hci_dev *hdev, unsigned long opt)
hci_send_cmd
(
hdev
,
HCI_OP_DELETE_STORED_LINK_KEY
,
sizeof
(
cp
),
&
cp
);
hci_send_cmd
(
hdev
,
HCI_OP_DELETE_STORED_LINK_KEY
,
sizeof
(
cp
),
&
cp
);
}
}
static
void
hci_le_init_req
(
struct
hci_dev
*
hdev
,
unsigned
long
opt
)
{
BT_DBG
(
"%s"
,
hdev
->
name
);
/* Read LE buffer size */
hci_send_cmd
(
hdev
,
HCI_OP_LE_READ_BUFFER_SIZE
,
0
,
NULL
);
}
static
void
hci_scan_req
(
struct
hci_dev
*
hdev
,
unsigned
long
opt
)
static
void
hci_scan_req
(
struct
hci_dev
*
hdev
,
unsigned
long
opt
)
{
{
__u8
scan
=
opt
;
__u8
scan
=
opt
;
...
@@ -456,7 +465,7 @@ int hci_inquiry(void __user *arg)
...
@@ -456,7 +465,7 @@ int hci_inquiry(void __user *arg)
/* cache_dump can't sleep. Therefore we allocate temp buffer and then
/* cache_dump can't sleep. Therefore we allocate temp buffer and then
* copy it to the user space.
* copy it to the user space.
*/
*/
buf
=
kmalloc
(
sizeof
(
struct
inquiry_info
)
*
max_rsp
,
GFP_KERNEL
);
buf
=
kmalloc
(
sizeof
(
struct
inquiry_info
)
*
max_rsp
,
GFP_KERNEL
);
if
(
!
buf
)
{
if
(
!
buf
)
{
err
=
-
ENOMEM
;
err
=
-
ENOMEM
;
goto
done
;
goto
done
;
...
@@ -525,10 +534,13 @@ int hci_dev_open(__u16 dev)
...
@@ -525,10 +534,13 @@ int hci_dev_open(__u16 dev)
set_bit
(
HCI_INIT
,
&
hdev
->
flags
);
set_bit
(
HCI_INIT
,
&
hdev
->
flags
);
hdev
->
init_last_cmd
=
0
;
hdev
->
init_last_cmd
=
0
;
//__hci_request(hdev, hci_reset_req, 0, HZ);
ret
=
__hci_request
(
hdev
,
hci_init_req
,
0
,
ret
=
__hci_request
(
hdev
,
hci_init_req
,
0
,
msecs_to_jiffies
(
HCI_INIT_TIMEOUT
));
msecs_to_jiffies
(
HCI_INIT_TIMEOUT
));
if
(
lmp_le_capable
(
hdev
))
ret
=
__hci_request
(
hdev
,
hci_le_init_req
,
0
,
msecs_to_jiffies
(
HCI_INIT_TIMEOUT
));
clear_bit
(
HCI_INIT
,
&
hdev
->
flags
);
clear_bit
(
HCI_INIT
,
&
hdev
->
flags
);
}
}
...
@@ -611,6 +623,7 @@ static int hci_dev_do_close(struct hci_dev *hdev)
...
@@ -611,6 +623,7 @@ static int hci_dev_do_close(struct hci_dev *hdev)
/* Drop last sent command */
/* Drop last sent command */
if
(
hdev
->
sent_cmd
)
{
if
(
hdev
->
sent_cmd
)
{
del_timer_sync
(
&
hdev
->
cmd_timer
);
kfree_skb
(
hdev
->
sent_cmd
);
kfree_skb
(
hdev
->
sent_cmd
);
hdev
->
sent_cmd
=
NULL
;
hdev
->
sent_cmd
=
NULL
;
}
}
...
@@ -671,7 +684,7 @@ int hci_dev_reset(__u16 dev)
...
@@ -671,7 +684,7 @@ int hci_dev_reset(__u16 dev)
hdev
->
flush
(
hdev
);
hdev
->
flush
(
hdev
);
atomic_set
(
&
hdev
->
cmd_cnt
,
1
);
atomic_set
(
&
hdev
->
cmd_cnt
,
1
);
hdev
->
acl_cnt
=
0
;
hdev
->
sco_cnt
=
0
;
hdev
->
acl_cnt
=
0
;
hdev
->
sco_cnt
=
0
;
hdev
->
le_cnt
=
0
;
if
(
!
test_bit
(
HCI_RAW
,
&
hdev
->
flags
))
if
(
!
test_bit
(
HCI_RAW
,
&
hdev
->
flags
))
ret
=
__hci_request
(
hdev
,
hci_reset_req
,
0
,
ret
=
__hci_request
(
hdev
,
hci_reset_req
,
0
,
...
@@ -1054,6 +1067,16 @@ int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
...
@@ -1054,6 +1067,16 @@ int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
return
0
;
return
0
;
}
}
/* HCI command timer function */
static
void
hci_cmd_timer
(
unsigned
long
arg
)
{
struct
hci_dev
*
hdev
=
(
void
*
)
arg
;
BT_ERR
(
"%s command tx timeout"
,
hdev
->
name
);
atomic_set
(
&
hdev
->
cmd_cnt
,
1
);
tasklet_schedule
(
&
hdev
->
cmd_task
);
}
/* Register HCI device */
/* Register HCI device */
int
hci_register_dev
(
struct
hci_dev
*
hdev
)
int
hci_register_dev
(
struct
hci_dev
*
hdev
)
{
{
...
@@ -1100,6 +1123,8 @@ int hci_register_dev(struct hci_dev *hdev)
...
@@ -1100,6 +1123,8 @@ int hci_register_dev(struct hci_dev *hdev)
skb_queue_head_init
(
&
hdev
->
cmd_q
);
skb_queue_head_init
(
&
hdev
->
cmd_q
);
skb_queue_head_init
(
&
hdev
->
raw_q
);
skb_queue_head_init
(
&
hdev
->
raw_q
);
setup_timer
(
&
hdev
->
cmd_timer
,
hci_cmd_timer
,
(
unsigned
long
)
hdev
);
for
(
i
=
0
;
i
<
NUM_REASSEMBLY
;
i
++
)
for
(
i
=
0
;
i
<
NUM_REASSEMBLY
;
i
++
)
hdev
->
reassembly
[
i
]
=
NULL
;
hdev
->
reassembly
[
i
]
=
NULL
;
...
@@ -1187,6 +1212,8 @@ int hci_unregister_dev(struct hci_dev *hdev)
...
@@ -1187,6 +1212,8 @@ int hci_unregister_dev(struct hci_dev *hdev)
hci_unregister_sysfs
(
hdev
);
hci_unregister_sysfs
(
hdev
);
hci_del_off_timer
(
hdev
);
destroy_workqueue
(
hdev
->
workqueue
);
destroy_workqueue
(
hdev
->
workqueue
);
hci_dev_lock_bh
(
hdev
);
hci_dev_lock_bh
(
hdev
);
...
@@ -1672,8 +1699,25 @@ static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int
...
@@ -1672,8 +1699,25 @@ static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int
}
}
if
(
conn
)
{
if
(
conn
)
{
int
cnt
=
(
type
==
ACL_LINK
?
hdev
->
acl_cnt
:
hdev
->
sco_cnt
);
int
cnt
,
q
;
int
q
=
cnt
/
num
;
switch
(
conn
->
type
)
{
case
ACL_LINK
:
cnt
=
hdev
->
acl_cnt
;
break
;
case
SCO_LINK
:
case
ESCO_LINK
:
cnt
=
hdev
->
sco_cnt
;
break
;
case
LE_LINK
:
cnt
=
hdev
->
le_mtu
?
hdev
->
le_cnt
:
hdev
->
acl_cnt
;
break
;
default:
cnt
=
0
;
BT_ERR
(
"Unknown link type"
);
}
q
=
cnt
/
num
;
*
quote
=
q
?
q
:
1
;
*
quote
=
q
?
q
:
1
;
}
else
}
else
*
quote
=
0
;
*
quote
=
0
;
...
@@ -1682,19 +1726,19 @@ static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int
...
@@ -1682,19 +1726,19 @@ static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int
return
conn
;
return
conn
;
}
}
static
inline
void
hci_
acl_tx_to
(
struct
hci_dev
*
hdev
)
static
inline
void
hci_
link_tx_to
(
struct
hci_dev
*
hdev
,
__u8
type
)
{
{
struct
hci_conn_hash
*
h
=
&
hdev
->
conn_hash
;
struct
hci_conn_hash
*
h
=
&
hdev
->
conn_hash
;
struct
list_head
*
p
;
struct
list_head
*
p
;
struct
hci_conn
*
c
;
struct
hci_conn
*
c
;
BT_ERR
(
"%s
ACL
tx timeout"
,
hdev
->
name
);
BT_ERR
(
"%s
link
tx timeout"
,
hdev
->
name
);
/* Kill stalled connections */
/* Kill stalled connections */
list_for_each
(
p
,
&
h
->
list
)
{
list_for_each
(
p
,
&
h
->
list
)
{
c
=
list_entry
(
p
,
struct
hci_conn
,
list
);
c
=
list_entry
(
p
,
struct
hci_conn
,
list
);
if
(
c
->
type
==
ACL_LINK
&&
c
->
sent
)
{
if
(
c
->
type
==
type
&&
c
->
sent
)
{
BT_ERR
(
"%s killing stalled
ACL
connection %s"
,
BT_ERR
(
"%s killing stalled connection %s"
,
hdev
->
name
,
batostr
(
&
c
->
dst
));
hdev
->
name
,
batostr
(
&
c
->
dst
));
hci_acl_disconn
(
c
,
0x13
);
hci_acl_disconn
(
c
,
0x13
);
}
}
...
@@ -1713,7 +1757,7 @@ static inline void hci_sched_acl(struct hci_dev *hdev)
...
@@ -1713,7 +1757,7 @@ static inline void hci_sched_acl(struct hci_dev *hdev)
/* ACL tx timeout must be longer than maximum
/* ACL tx timeout must be longer than maximum
* link supervision timeout (40.9 seconds) */
* link supervision timeout (40.9 seconds) */
if
(
!
hdev
->
acl_cnt
&&
time_after
(
jiffies
,
hdev
->
acl_last_tx
+
HZ
*
45
))
if
(
!
hdev
->
acl_cnt
&&
time_after
(
jiffies
,
hdev
->
acl_last_tx
+
HZ
*
45
))
hci_
acl_tx_to
(
hdev
);
hci_
link_tx_to
(
hdev
,
ACL_LINK
);
}
}
while
(
hdev
->
acl_cnt
&&
(
conn
=
hci_low_sent
(
hdev
,
ACL_LINK
,
&
quote
)))
{
while
(
hdev
->
acl_cnt
&&
(
conn
=
hci_low_sent
(
hdev
,
ACL_LINK
,
&
quote
)))
{
...
@@ -1772,6 +1816,40 @@ static inline void hci_sched_esco(struct hci_dev *hdev)
...
@@ -1772,6 +1816,40 @@ static inline void hci_sched_esco(struct hci_dev *hdev)
}
}
}
}
static
inline
void
hci_sched_le
(
struct
hci_dev
*
hdev
)
{
struct
hci_conn
*
conn
;
struct
sk_buff
*
skb
;
int
quote
,
cnt
;
BT_DBG
(
"%s"
,
hdev
->
name
);
if
(
!
test_bit
(
HCI_RAW
,
&
hdev
->
flags
))
{
/* LE tx timeout must be longer than maximum
* link supervision timeout (40.9 seconds) */
if
(
!
hdev
->
le_cnt
&&
hdev
->
le_pkts
&&
time_after
(
jiffies
,
hdev
->
le_last_tx
+
HZ
*
45
))
hci_link_tx_to
(
hdev
,
LE_LINK
);
}
cnt
=
hdev
->
le_pkts
?
hdev
->
le_cnt
:
hdev
->
acl_cnt
;
while
(
cnt
&&
(
conn
=
hci_low_sent
(
hdev
,
LE_LINK
,
&
quote
)))
{
while
(
quote
--
&&
(
skb
=
skb_dequeue
(
&
conn
->
data_q
)))
{
BT_DBG
(
"skb %p len %d"
,
skb
,
skb
->
len
);
hci_send_frame
(
skb
);
hdev
->
le_last_tx
=
jiffies
;
cnt
--
;
conn
->
sent
++
;
}
}
if
(
hdev
->
le_pkts
)
hdev
->
le_cnt
=
cnt
;
else
hdev
->
acl_cnt
=
cnt
;
}
static
void
hci_tx_task
(
unsigned
long
arg
)
static
void
hci_tx_task
(
unsigned
long
arg
)
{
{
struct
hci_dev
*
hdev
=
(
struct
hci_dev
*
)
arg
;
struct
hci_dev
*
hdev
=
(
struct
hci_dev
*
)
arg
;
...
@@ -1779,7 +1857,8 @@ static void hci_tx_task(unsigned long arg)
...
@@ -1779,7 +1857,8 @@ static void hci_tx_task(unsigned long arg)
read_lock
(
&
hci_task_lock
);
read_lock
(
&
hci_task_lock
);
BT_DBG
(
"%s acl %d sco %d"
,
hdev
->
name
,
hdev
->
acl_cnt
,
hdev
->
sco_cnt
);
BT_DBG
(
"%s acl %d sco %d le %d"
,
hdev
->
name
,
hdev
->
acl_cnt
,
hdev
->
sco_cnt
,
hdev
->
le_cnt
);
/* Schedule queues and send stuff to HCI driver */
/* Schedule queues and send stuff to HCI driver */
...
@@ -1789,6 +1868,8 @@ static void hci_tx_task(unsigned long arg)
...
@@ -1789,6 +1868,8 @@ static void hci_tx_task(unsigned long arg)
hci_sched_esco
(
hdev
);
hci_sched_esco
(
hdev
);
hci_sched_le
(
hdev
);
/* Send next queued raw (unknown type) packet */
/* Send next queued raw (unknown type) packet */
while
((
skb
=
skb_dequeue
(
&
hdev
->
raw_q
)))
while
((
skb
=
skb_dequeue
(
&
hdev
->
raw_q
)))
hci_send_frame
(
skb
);
hci_send_frame
(
skb
);
...
@@ -1936,11 +2017,6 @@ static void hci_cmd_task(unsigned long arg)
...
@@ -1936,11 +2017,6 @@ static void hci_cmd_task(unsigned long arg)
BT_DBG
(
"%s cmd %d"
,
hdev
->
name
,
atomic_read
(
&
hdev
->
cmd_cnt
));
BT_DBG
(
"%s cmd %d"
,
hdev
->
name
,
atomic_read
(
&
hdev
->
cmd_cnt
));
if
(
!
atomic_read
(
&
hdev
->
cmd_cnt
)
&&
time_after
(
jiffies
,
hdev
->
cmd_last_tx
+
HZ
))
{
BT_ERR
(
"%s command tx timeout"
,
hdev
->
name
);
atomic_set
(
&
hdev
->
cmd_cnt
,
1
);
}
/* Send queued commands */
/* Send queued commands */
if
(
atomic_read
(
&
hdev
->
cmd_cnt
))
{
if
(
atomic_read
(
&
hdev
->
cmd_cnt
))
{
skb
=
skb_dequeue
(
&
hdev
->
cmd_q
);
skb
=
skb_dequeue
(
&
hdev
->
cmd_q
);
...
@@ -1953,7 +2029,8 @@ static void hci_cmd_task(unsigned long arg)
...
@@ -1953,7 +2029,8 @@ static void hci_cmd_task(unsigned long arg)
if
(
hdev
->
sent_cmd
)
{
if
(
hdev
->
sent_cmd
)
{
atomic_dec
(
&
hdev
->
cmd_cnt
);
atomic_dec
(
&
hdev
->
cmd_cnt
);
hci_send_frame
(
skb
);
hci_send_frame
(
skb
);
hdev
->
cmd_last_tx
=
jiffies
;
mod_timer
(
&
hdev
->
cmd_timer
,
jiffies
+
msecs_to_jiffies
(
HCI_CMD_TIMEOUT
));
}
else
{
}
else
{
skb_queue_head
(
&
hdev
->
cmd_q
,
skb
);
skb_queue_head
(
&
hdev
->
cmd_q
,
skb
);
tasklet_schedule
(
&
hdev
->
cmd_task
);
tasklet_schedule
(
&
hdev
->
cmd_task
);
...
...
net/bluetooth/hci_event.c
View file @
f4f314bf
...
@@ -776,6 +776,25 @@ static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
...
@@ -776,6 +776,25 @@ static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
mgmt_pin_code_neg_reply_complete
(
hdev
->
id
,
&
rp
->
bdaddr
,
mgmt_pin_code_neg_reply_complete
(
hdev
->
id
,
&
rp
->
bdaddr
,
rp
->
status
);
rp
->
status
);
}
}
static
void
hci_cc_le_read_buffer_size
(
struct
hci_dev
*
hdev
,
struct
sk_buff
*
skb
)
{
struct
hci_rp_le_read_buffer_size
*
rp
=
(
void
*
)
skb
->
data
;
BT_DBG
(
"%s status 0x%x"
,
hdev
->
name
,
rp
->
status
);
if
(
rp
->
status
)
return
;
hdev
->
le_mtu
=
__le16_to_cpu
(
rp
->
le_mtu
);
hdev
->
le_pkts
=
rp
->
le_max_pkt
;
hdev
->
le_cnt
=
hdev
->
le_pkts
;
BT_DBG
(
"%s le mtu %d:%d"
,
hdev
->
name
,
hdev
->
le_mtu
,
hdev
->
le_pkts
);
hci_req_complete
(
hdev
,
HCI_OP_LE_READ_BUFFER_SIZE
,
rp
->
status
);
}
static
inline
void
hci_cs_inquiry
(
struct
hci_dev
*
hdev
,
__u8
status
)
static
inline
void
hci_cs_inquiry
(
struct
hci_dev
*
hdev
,
__u8
status
)
{
{
...
@@ -919,7 +938,7 @@ static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
...
@@ -919,7 +938,7 @@ static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
}
}
static
int
hci_outgoing_auth_needed
(
struct
hci_dev
*
hdev
,
static
int
hci_outgoing_auth_needed
(
struct
hci_dev
*
hdev
,
struct
hci_conn
*
conn
)
struct
hci_conn
*
conn
)
{
{
if
(
conn
->
state
!=
BT_CONFIG
||
!
conn
->
out
)
if
(
conn
->
state
!=
BT_CONFIG
||
!
conn
->
out
)
return
0
;
return
0
;
...
@@ -1107,6 +1126,43 @@ static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
...
@@ -1107,6 +1126,43 @@ static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
hci_dev_unlock
(
hdev
);
hci_dev_unlock
(
hdev
);
}
}
static
void
hci_cs_le_create_conn
(
struct
hci_dev
*
hdev
,
__u8
status
)
{
struct
hci_cp_le_create_conn
*
cp
;
struct
hci_conn
*
conn
;
BT_DBG
(
"%s status 0x%x"
,
hdev
->
name
,
status
);
cp
=
hci_sent_cmd_data
(
hdev
,
HCI_OP_LE_CREATE_CONN
);
if
(
!
cp
)
return
;
hci_dev_lock
(
hdev
);
conn
=
hci_conn_hash_lookup_ba
(
hdev
,
LE_LINK
,
&
cp
->
peer_addr
);
BT_DBG
(
"%s bdaddr %s conn %p"
,
hdev
->
name
,
batostr
(
&
cp
->
peer_addr
),
conn
);
if
(
status
)
{
if
(
conn
&&
conn
->
state
==
BT_CONNECT
)
{
conn
->
state
=
BT_CLOSED
;
hci_proto_connect_cfm
(
conn
,
status
);
hci_conn_del
(
conn
);
}
}
else
{
if
(
!
conn
)
{
conn
=
hci_conn_add
(
hdev
,
LE_LINK
,
&
cp
->
peer_addr
);
if
(
conn
)
conn
->
out
=
1
;
else
BT_ERR
(
"No memory for new connection"
);
}
}
hci_dev_unlock
(
hdev
);
}
static
inline
void
hci_inquiry_complete_evt
(
struct
hci_dev
*
hdev
,
struct
sk_buff
*
skb
)
static
inline
void
hci_inquiry_complete_evt
(
struct
hci_dev
*
hdev
,
struct
sk_buff
*
skb
)
{
{
__u8
status
=
*
((
__u8
*
)
skb
->
data
);
__u8
status
=
*
((
__u8
*
)
skb
->
data
);
...
@@ -1237,7 +1293,8 @@ static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *sk
...
@@ -1237,7 +1293,8 @@ static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *sk
mask
|=
hci_proto_connect_ind
(
hdev
,
&
ev
->
bdaddr
,
ev
->
link_type
);
mask
|=
hci_proto_connect_ind
(
hdev
,
&
ev
->
bdaddr
,
ev
->
link_type
);
if
((
mask
&
HCI_LM_ACCEPT
)
&&
!
hci_blacklist_lookup
(
hdev
,
&
ev
->
bdaddr
))
{
if
((
mask
&
HCI_LM_ACCEPT
)
&&
!
hci_blacklist_lookup
(
hdev
,
&
ev
->
bdaddr
))
{
/* Connection accepted */
/* Connection accepted */
struct
inquiry_entry
*
ie
;
struct
inquiry_entry
*
ie
;
struct
hci_conn
*
conn
;
struct
hci_conn
*
conn
;
...
@@ -1667,11 +1724,18 @@ static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *sk
...
@@ -1667,11 +1724,18 @@ static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *sk
hci_cc_pin_code_neg_reply
(
hdev
,
skb
);
hci_cc_pin_code_neg_reply
(
hdev
,
skb
);
break
;
break
;
case
HCI_OP_LE_READ_BUFFER_SIZE
:
hci_cc_le_read_buffer_size
(
hdev
,
skb
);
break
;
default:
default:
BT_DBG
(
"%s opcode 0x%x"
,
hdev
->
name
,
opcode
);
BT_DBG
(
"%s opcode 0x%x"
,
hdev
->
name
,
opcode
);
break
;
break
;
}
}
if
(
ev
->
opcode
!=
HCI_OP_NOP
)
del_timer
(
&
hdev
->
cmd_timer
);
if
(
ev
->
ncmd
)
{
if
(
ev
->
ncmd
)
{
atomic_set
(
&
hdev
->
cmd_cnt
,
1
);
atomic_set
(
&
hdev
->
cmd_cnt
,
1
);
if
(
!
skb_queue_empty
(
&
hdev
->
cmd_q
))
if
(
!
skb_queue_empty
(
&
hdev
->
cmd_q
))
...
@@ -1738,11 +1802,18 @@ static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
...
@@ -1738,11 +1802,18 @@ static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
mgmt_disconnect_failed
(
hdev
->
id
);
mgmt_disconnect_failed
(
hdev
->
id
);
break
;
break
;
case
HCI_OP_LE_CREATE_CONN
:
hci_cs_le_create_conn
(
hdev
,
ev
->
status
);
break
;
default:
default:
BT_DBG
(
"%s opcode 0x%x"
,
hdev
->
name
,
opcode
);
BT_DBG
(
"%s opcode 0x%x"
,
hdev
->
name
,
opcode
);
break
;
break
;
}
}
if
(
ev
->
opcode
!=
HCI_OP_NOP
)
del_timer
(
&
hdev
->
cmd_timer
);
if
(
ev
->
ncmd
)
{
if
(
ev
->
ncmd
)
{
atomic_set
(
&
hdev
->
cmd_cnt
,
1
);
atomic_set
(
&
hdev
->
cmd_cnt
,
1
);
if
(
!
skb_queue_empty
(
&
hdev
->
cmd_q
))
if
(
!
skb_queue_empty
(
&
hdev
->
cmd_q
))
...
@@ -1808,6 +1879,16 @@ static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *s
...
@@ -1808,6 +1879,16 @@ static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *s
hdev
->
acl_cnt
+=
count
;
hdev
->
acl_cnt
+=
count
;
if
(
hdev
->
acl_cnt
>
hdev
->
acl_pkts
)
if
(
hdev
->
acl_cnt
>
hdev
->
acl_pkts
)
hdev
->
acl_cnt
=
hdev
->
acl_pkts
;
hdev
->
acl_cnt
=
hdev
->
acl_pkts
;
}
else
if
(
conn
->
type
==
LE_LINK
)
{
if
(
hdev
->
le_pkts
)
{
hdev
->
le_cnt
+=
count
;
if
(
hdev
->
le_cnt
>
hdev
->
le_pkts
)
hdev
->
le_cnt
=
hdev
->
le_pkts
;
}
else
{
hdev
->
acl_cnt
+=
count
;
if
(
hdev
->
acl_cnt
>
hdev
->
acl_pkts
)
hdev
->
acl_cnt
=
hdev
->
acl_pkts
;
}
}
else
{
}
else
{
hdev
->
sco_cnt
+=
count
;
hdev
->
sco_cnt
+=
count
;
if
(
hdev
->
sco_cnt
>
hdev
->
sco_pkts
)
if
(
hdev
->
sco_cnt
>
hdev
->
sco_pkts
)
...
@@ -2021,7 +2102,8 @@ static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct
...
@@ -2021,7 +2102,8 @@ static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct
hci_dev_lock
(
hdev
);
hci_dev_lock
(
hdev
);
if
((
skb
->
len
-
1
)
/
num_rsp
!=
sizeof
(
struct
inquiry_info_with_rssi
))
{
if
((
skb
->
len
-
1
)
/
num_rsp
!=
sizeof
(
struct
inquiry_info_with_rssi
))
{
struct
inquiry_info_with_rssi_and_pscan_mode
*
info
=
(
void
*
)
(
skb
->
data
+
1
);
struct
inquiry_info_with_rssi_and_pscan_mode
*
info
;
info
=
(
void
*
)
(
skb
->
data
+
1
);
for
(;
num_rsp
;
num_rsp
--
)
{
for
(;
num_rsp
;
num_rsp
--
)
{
bacpy
(
&
data
.
bdaddr
,
&
info
->
bdaddr
);
bacpy
(
&
data
.
bdaddr
,
&
info
->
bdaddr
);
...
@@ -2162,17 +2244,8 @@ static inline void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buf
...
@@ -2162,17 +2244,8 @@ static inline void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buf
static
inline
void
hci_sniff_subrate_evt
(
struct
hci_dev
*
hdev
,
struct
sk_buff
*
skb
)
static
inline
void
hci_sniff_subrate_evt
(
struct
hci_dev
*
hdev
,
struct
sk_buff
*
skb
)
{
{
struct
hci_ev_sniff_subrate
*
ev
=
(
void
*
)
skb
->
data
;
struct
hci_ev_sniff_subrate
*
ev
=
(
void
*
)
skb
->
data
;
struct
hci_conn
*
conn
;
BT_DBG
(
"%s status %d"
,
hdev
->
name
,
ev
->
status
);
BT_DBG
(
"%s status %d"
,
hdev
->
name
,
ev
->
status
);
hci_dev_lock
(
hdev
);
conn
=
hci_conn_hash_lookup_handle
(
hdev
,
__le16_to_cpu
(
ev
->
handle
));
if
(
conn
)
{
}
hci_dev_unlock
(
hdev
);
}
}
static
inline
void
hci_extended_inquiry_result_evt
(
struct
hci_dev
*
hdev
,
struct
sk_buff
*
skb
)
static
inline
void
hci_extended_inquiry_result_evt
(
struct
hci_dev
*
hdev
,
struct
sk_buff
*
skb
)
...
@@ -2190,12 +2263,12 @@ static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct
...
@@ -2190,12 +2263,12 @@ static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct
for
(;
num_rsp
;
num_rsp
--
)
{
for
(;
num_rsp
;
num_rsp
--
)
{
bacpy
(
&
data
.
bdaddr
,
&
info
->
bdaddr
);
bacpy
(
&
data
.
bdaddr
,
&
info
->
bdaddr
);
data
.
pscan_rep_mode
=
info
->
pscan_rep_mode
;
data
.
pscan_rep_mode
=
info
->
pscan_rep_mode
;
data
.
pscan_period_mode
=
info
->
pscan_period_mode
;
data
.
pscan_period_mode
=
info
->
pscan_period_mode
;
data
.
pscan_mode
=
0x00
;
data
.
pscan_mode
=
0x00
;
memcpy
(
data
.
dev_class
,
info
->
dev_class
,
3
);
memcpy
(
data
.
dev_class
,
info
->
dev_class
,
3
);
data
.
clock_offset
=
info
->
clock_offset
;
data
.
clock_offset
=
info
->
clock_offset
;
data
.
rssi
=
info
->
rssi
;
data
.
rssi
=
info
->
rssi
;
data
.
ssp_mode
=
0x01
;
data
.
ssp_mode
=
0x01
;
info
++
;
info
++
;
hci_inquiry_cache_update
(
hdev
,
&
data
);
hci_inquiry_cache_update
(
hdev
,
&
data
);
...
@@ -2321,6 +2394,60 @@ static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_
...
@@ -2321,6 +2394,60 @@ static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_
hci_dev_unlock
(
hdev
);
hci_dev_unlock
(
hdev
);
}
}
static
inline
void
hci_le_conn_complete_evt
(
struct
hci_dev
*
hdev
,
struct
sk_buff
*
skb
)
{
struct
hci_ev_le_conn_complete
*
ev
=
(
void
*
)
skb
->
data
;
struct
hci_conn
*
conn
;
BT_DBG
(
"%s status %d"
,
hdev
->
name
,
ev
->
status
);
hci_dev_lock
(
hdev
);
conn
=
hci_conn_hash_lookup_ba
(
hdev
,
LE_LINK
,
&
ev
->
bdaddr
);
if
(
!
conn
)
{
conn
=
hci_conn_add
(
hdev
,
LE_LINK
,
&
ev
->
bdaddr
);
if
(
!
conn
)
{
BT_ERR
(
"No memory for new connection"
);
hci_dev_unlock
(
hdev
);
return
;
}
}
if
(
ev
->
status
)
{
hci_proto_connect_cfm
(
conn
,
ev
->
status
);
conn
->
state
=
BT_CLOSED
;
hci_conn_del
(
conn
);
goto
unlock
;
}
conn
->
handle
=
__le16_to_cpu
(
ev
->
handle
);
conn
->
state
=
BT_CONNECTED
;
hci_conn_hold_device
(
conn
);
hci_conn_add_sysfs
(
conn
);
hci_proto_connect_cfm
(
conn
,
ev
->
status
);
unlock:
hci_dev_unlock
(
hdev
);
}
static
inline
void
hci_le_meta_evt
(
struct
hci_dev
*
hdev
,
struct
sk_buff
*
skb
)
{
struct
hci_ev_le_meta
*
le_ev
=
(
void
*
)
skb
->
data
;
skb_pull
(
skb
,
sizeof
(
*
le_ev
));
switch
(
le_ev
->
subevent
)
{
case
HCI_EV_LE_CONN_COMPLETE
:
hci_le_conn_complete_evt
(
hdev
,
skb
);
break
;
default:
break
;
}
}
void
hci_event_packet
(
struct
hci_dev
*
hdev
,
struct
sk_buff
*
skb
)
void
hci_event_packet
(
struct
hci_dev
*
hdev
,
struct
sk_buff
*
skb
)
{
{
struct
hci_event_hdr
*
hdr
=
(
void
*
)
skb
->
data
;
struct
hci_event_hdr
*
hdr
=
(
void
*
)
skb
->
data
;
...
@@ -2461,6 +2588,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
...
@@ -2461,6 +2588,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
hci_remote_host_features_evt
(
hdev
,
skb
);
hci_remote_host_features_evt
(
hdev
,
skb
);
break
;
break
;
case
HCI_EV_LE_META
:
hci_le_meta_evt
(
hdev
,
skb
);
break
;
default:
default:
BT_DBG
(
"%s event 0x%x"
,
hdev
->
name
,
event
);
BT_DBG
(
"%s event 0x%x"
,
hdev
->
name
,
event
);
break
;
break
;
...
...
net/bluetooth/hci_sysfs.c
View file @
f4f314bf
...
@@ -11,7 +11,7 @@
...
@@ -11,7 +11,7 @@
static
struct
class
*
bt_class
;
static
struct
class
*
bt_class
;
struct
dentry
*
bt_debugfs
=
NULL
;
struct
dentry
*
bt_debugfs
;
EXPORT_SYMBOL_GPL
(
bt_debugfs
);
EXPORT_SYMBOL_GPL
(
bt_debugfs
);
static
inline
char
*
link_typetostr
(
int
type
)
static
inline
char
*
link_typetostr
(
int
type
)
...
@@ -51,8 +51,8 @@ static ssize_t show_link_features(struct device *dev, struct device_attribute *a
...
@@ -51,8 +51,8 @@ static ssize_t show_link_features(struct device *dev, struct device_attribute *a
conn
->
features
[
6
],
conn
->
features
[
7
]);
conn
->
features
[
6
],
conn
->
features
[
7
]);
}
}
#define LINK_ATTR(_name,
_mode,_show,
_store) \
#define LINK_ATTR(_name,
_mode, _show,
_store) \
struct device_attribute link_attr_##_name = __ATTR(_name,
_mode,_show,
_store)
struct device_attribute link_attr_##_name = __ATTR(_name,
_mode, _show,
_store)
static
LINK_ATTR
(
type
,
S_IRUGO
,
show_link_type
,
NULL
);
static
LINK_ATTR
(
type
,
S_IRUGO
,
show_link_type
,
NULL
);
static
LINK_ATTR
(
address
,
S_IRUGO
,
show_link_address
,
NULL
);
static
LINK_ATTR
(
address
,
S_IRUGO
,
show_link_address
,
NULL
);
...
...
net/bluetooth/hidp/core.c
View file @
f4f314bf
...
@@ -1019,8 +1019,6 @@ static int __init hidp_init(void)
...
@@ -1019,8 +1019,6 @@ static int __init hidp_init(void)
{
{
int
ret
;
int
ret
;
l2cap_load
();
BT_INFO
(
"HIDP (Human Interface Emulation) ver %s"
,
VERSION
);
BT_INFO
(
"HIDP (Human Interface Emulation) ver %s"
,
VERSION
);
ret
=
hid_register_driver
(
&
hidp_driver
);
ret
=
hid_register_driver
(
&
hidp_driver
);
...
...
net/bluetooth/l2cap_core.c
View file @
f4f314bf
This diff is collapsed.
Click to expand it.
net/bluetooth/l2cap_sock.c
View file @
f4f314bf
...
@@ -103,7 +103,7 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
...
@@ -103,7 +103,7 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
len
=
min_t
(
unsigned
int
,
sizeof
(
la
),
alen
);
len
=
min_t
(
unsigned
int
,
sizeof
(
la
),
alen
);
memcpy
(
&
la
,
addr
,
len
);
memcpy
(
&
la
,
addr
,
len
);
if
(
la
.
l2_cid
)
if
(
la
.
l2_cid
&&
la
.
l2_psm
)
return
-
EINVAL
;
return
-
EINVAL
;
lock_sock
(
sk
);
lock_sock
(
sk
);
...
@@ -145,6 +145,9 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
...
@@ -145,6 +145,9 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
l2cap_pi
(
sk
)
->
sec_level
=
BT_SECURITY_SDP
;
l2cap_pi
(
sk
)
->
sec_level
=
BT_SECURITY_SDP
;
}
}
if
(
la
.
l2_cid
)
l2cap_pi
(
sk
)
->
scid
=
la
.
l2_cid
;
write_unlock_bh
(
&
l2cap_sk_list
.
lock
);
write_unlock_bh
(
&
l2cap_sk_list
.
lock
);
done:
done:
...
@@ -168,13 +171,13 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al
...
@@ -168,13 +171,13 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al
len
=
min_t
(
unsigned
int
,
sizeof
(
la
),
alen
);
len
=
min_t
(
unsigned
int
,
sizeof
(
la
),
alen
);
memcpy
(
&
la
,
addr
,
len
);
memcpy
(
&
la
,
addr
,
len
);
if
(
la
.
l2_cid
)
if
(
la
.
l2_cid
&&
la
.
l2_psm
)
return
-
EINVAL
;
return
-
EINVAL
;
lock_sock
(
sk
);
lock_sock
(
sk
);
if
((
sk
->
sk_type
==
SOCK_SEQPACKET
||
sk
->
sk_type
==
SOCK_STREAM
)
if
((
sk
->
sk_type
==
SOCK_SEQPACKET
||
sk
->
sk_type
==
SOCK_STREAM
)
&&
!
la
.
l2_psm
)
{
&&
!
(
la
.
l2_psm
||
la
.
l2_cid
)
)
{
err
=
-
EINVAL
;
err
=
-
EINVAL
;
goto
done
;
goto
done
;
}
}
...
@@ -216,7 +219,7 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al
...
@@ -216,7 +219,7 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al
/* PSM must be odd and lsb of upper byte must be 0 */
/* PSM must be odd and lsb of upper byte must be 0 */
if
((
__le16_to_cpu
(
la
.
l2_psm
)
&
0x0101
)
!=
0x0001
&&
if
((
__le16_to_cpu
(
la
.
l2_psm
)
&
0x0101
)
!=
0x0001
&&
sk
->
sk_type
!=
SOCK_RAW
)
{
sk
->
sk_type
!=
SOCK_RAW
&&
!
la
.
l2_cid
)
{
err
=
-
EINVAL
;
err
=
-
EINVAL
;
goto
done
;
goto
done
;
}
}
...
@@ -224,6 +227,7 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al
...
@@ -224,6 +227,7 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al
/* Set destination address and psm */
/* Set destination address and psm */
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
;
l2cap_pi
(
sk
)
->
dcid
=
la
.
l2_cid
;
err
=
l2cap_do_connect
(
sk
);
err
=
l2cap_do_connect
(
sk
);
if
(
err
)
if
(
err
)
...
@@ -265,7 +269,7 @@ static int l2cap_sock_listen(struct socket *sock, int backlog)
...
@@ -265,7 +269,7 @@ static int l2cap_sock_listen(struct socket *sock, int backlog)
goto
done
;
goto
done
;
}
}
if
(
!
l2cap_pi
(
sk
)
->
psm
)
{
if
(
!
l2cap_pi
(
sk
)
->
psm
&&
!
l2cap_pi
(
sk
)
->
dcid
)
{
bdaddr_t
*
src
=
&
bt_sk
(
sk
)
->
src
;
bdaddr_t
*
src
=
&
bt_sk
(
sk
)
->
src
;
u16
psm
;
u16
psm
;
...
@@ -392,6 +396,7 @@ static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __us
...
@@ -392,6 +396,7 @@ static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __us
switch
(
optname
)
{
switch
(
optname
)
{
case
L2CAP_OPTIONS
:
case
L2CAP_OPTIONS
:
memset
(
&
opts
,
0
,
sizeof
(
opts
));
opts
.
imtu
=
l2cap_pi
(
sk
)
->
imtu
;
opts
.
imtu
=
l2cap_pi
(
sk
)
->
imtu
;
opts
.
omtu
=
l2cap_pi
(
sk
)
->
omtu
;
opts
.
omtu
=
l2cap_pi
(
sk
)
->
omtu
;
opts
.
flush_to
=
l2cap_pi
(
sk
)
->
flush_to
;
opts
.
flush_to
=
l2cap_pi
(
sk
)
->
flush_to
;
...
@@ -880,6 +885,8 @@ static void l2cap_sock_cleanup_listen(struct sock *parent)
...
@@ -880,6 +885,8 @@ static void l2cap_sock_cleanup_listen(struct sock *parent)
void
__l2cap_sock_close
(
struct
sock
*
sk
,
int
reason
)
void
__l2cap_sock_close
(
struct
sock
*
sk
,
int
reason
)
{
{
struct
l2cap_conn
*
conn
=
l2cap_pi
(
sk
)
->
conn
;
BT_DBG
(
"sk %p state %d socket %p"
,
sk
,
sk
->
sk_state
,
sk
->
sk_socket
);
BT_DBG
(
"sk %p state %d socket %p"
,
sk
,
sk
->
sk_state
,
sk
->
sk_socket
);
switch
(
sk
->
sk_state
)
{
switch
(
sk
->
sk_state
)
{
...
@@ -889,10 +896,9 @@ void __l2cap_sock_close(struct sock *sk, int reason)
...
@@ -889,10 +896,9 @@ void __l2cap_sock_close(struct sock *sk, int reason)
case
BT_CONNECTED
:
case
BT_CONNECTED
:
case
BT_CONFIG
:
case
BT_CONFIG
:
if
(
sk
->
sk_type
==
SOCK_SEQPACKET
||
if
((
sk
->
sk_type
==
SOCK_SEQPACKET
||
sk
->
sk_type
==
SOCK_STREAM
)
{
sk
->
sk_type
==
SOCK_STREAM
)
&&
struct
l2cap_conn
*
conn
=
l2cap_pi
(
sk
)
->
conn
;
conn
->
hcon
->
type
==
ACL_LINK
)
{
l2cap_sock_set_timer
(
sk
,
sk
->
sk_sndtimeo
);
l2cap_sock_set_timer
(
sk
,
sk
->
sk_sndtimeo
);
l2cap_send_disconn_req
(
conn
,
sk
,
reason
);
l2cap_send_disconn_req
(
conn
,
sk
,
reason
);
}
else
}
else
...
@@ -900,9 +906,9 @@ void __l2cap_sock_close(struct sock *sk, int reason)
...
@@ -900,9 +906,9 @@ void __l2cap_sock_close(struct sock *sk, int reason)
break
;
break
;
case
BT_CONNECT2
:
case
BT_CONNECT2
:
if
(
sk
->
sk_type
==
SOCK_SEQPACKET
||
if
(
(
sk
->
sk_type
==
SOCK_SEQPACKET
||
sk
->
sk_type
==
SOCK_STREAM
)
{
sk
->
sk_type
==
SOCK_STREAM
)
&&
struct
l2cap_conn
*
conn
=
l2cap_pi
(
sk
)
->
conn
;
conn
->
hcon
->
type
==
ACL_LINK
)
{
struct
l2cap_conn_rsp
rsp
;
struct
l2cap_conn_rsp
rsp
;
__u16
result
;
__u16
result
;
...
@@ -1121,30 +1127,30 @@ static const struct net_proto_family l2cap_sock_family_ops = {
...
@@ -1121,30 +1127,30 @@ static const struct net_proto_family l2cap_sock_family_ops = {
int
__init
l2cap_init_sockets
(
void
)
int
__init
l2cap_init_sockets
(
void
)
{
{
int
err
;
int
err
;
err
=
proto_register
(
&
l2cap_proto
,
0
);
err
=
proto_register
(
&
l2cap_proto
,
0
);
if
(
err
<
0
)
if
(
err
<
0
)
return
err
;
return
err
;
err
=
bt_sock_register
(
BTPROTO_L2CAP
,
&
l2cap_sock_family_ops
);
err
=
bt_sock_register
(
BTPROTO_L2CAP
,
&
l2cap_sock_family_ops
);
if
(
err
<
0
)
if
(
err
<
0
)
goto
error
;
goto
error
;
BT_INFO
(
"L2CAP socket layer initialized"
);
BT_INFO
(
"L2CAP socket layer initialized"
);
return
0
;
return
0
;
error:
error:
BT_ERR
(
"L2CAP socket registration failed"
);
BT_ERR
(
"L2CAP socket registration failed"
);
proto_unregister
(
&
l2cap_proto
);
proto_unregister
(
&
l2cap_proto
);
return
err
;
return
err
;
}
}
void
l2cap_cleanup_sockets
(
void
)
void
l2cap_cleanup_sockets
(
void
)
{
{
if
(
bt_sock_unregister
(
BTPROTO_L2CAP
)
<
0
)
if
(
bt_sock_unregister
(
BTPROTO_L2CAP
)
<
0
)
BT_ERR
(
"L2CAP socket unregistration failed"
);
BT_ERR
(
"L2CAP socket unregistration failed"
);
proto_unregister
(
&
l2cap_proto
);
proto_unregister
(
&
l2cap_proto
);
}
}
net/bluetooth/mgmt.c
View file @
f4f314bf
...
@@ -22,7 +22,7 @@
...
@@ -22,7 +22,7 @@
/* Bluetooth HCI Management interface */
/* Bluetooth HCI Management interface */
#include <
asm
/uaccess.h>
#include <
linux
/uaccess.h>
#include <asm/unaligned.h>
#include <asm/unaligned.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/bluetooth.h>
...
...
net/bluetooth/rfcomm/core.c
View file @
f4f314bf
...
@@ -2154,8 +2154,6 @@ static int __init rfcomm_init(void)
...
@@ -2154,8 +2154,6 @@ static int __init rfcomm_init(void)
{
{
int
err
;
int
err
;
l2cap_load
();
hci_register_cb
(
&
rfcomm_cb
);
hci_register_cb
(
&
rfcomm_cb
);
rfcomm_thread
=
kthread_run
(
rfcomm_run
,
NULL
,
"krfcommd"
);
rfcomm_thread
=
kthread_run
(
rfcomm_run
,
NULL
,
"krfcommd"
);
...
...
net/bluetooth/sco.c
View file @
f4f314bf
...
@@ -50,8 +50,6 @@
...
@@ -50,8 +50,6 @@
#include <net/bluetooth/hci_core.h>
#include <net/bluetooth/hci_core.h>
#include <net/bluetooth/sco.h>
#include <net/bluetooth/sco.h>
#define VERSION "0.6"
static
int
disable_esco
;
static
int
disable_esco
;
static
const
struct
proto_ops
sco_sock_ops
;
static
const
struct
proto_ops
sco_sock_ops
;
...
@@ -703,6 +701,7 @@ static int sco_sock_getsockopt_old(struct socket *sock, int optname, char __user
...
@@ -703,6 +701,7 @@ static int sco_sock_getsockopt_old(struct socket *sock, int optname, char __user
break
;
break
;
}
}
memset
(
&
cinfo
,
0
,
sizeof
(
cinfo
));
cinfo
.
hci_handle
=
sco_pi
(
sk
)
->
conn
->
hcon
->
handle
;
cinfo
.
hci_handle
=
sco_pi
(
sk
)
->
conn
->
hcon
->
handle
;
memcpy
(
cinfo
.
dev_class
,
sco_pi
(
sk
)
->
conn
->
hcon
->
dev_class
,
3
);
memcpy
(
cinfo
.
dev_class
,
sco_pi
(
sk
)
->
conn
->
hcon
->
dev_class
,
3
);
...
@@ -1023,7 +1022,7 @@ static struct hci_proto sco_hci_proto = {
...
@@ -1023,7 +1022,7 @@ static struct hci_proto sco_hci_proto = {
.
recv_scodata
=
sco_recv_scodata
.
recv_scodata
=
sco_recv_scodata
};
};
static
int
__init
sco_init
(
void
)
int
__init
sco_init
(
void
)
{
{
int
err
;
int
err
;
...
@@ -1051,7 +1050,6 @@ static int __init sco_init(void)
...
@@ -1051,7 +1050,6 @@ static int __init sco_init(void)
BT_ERR
(
"Failed to create SCO debug file"
);
BT_ERR
(
"Failed to create SCO debug file"
);
}
}
BT_INFO
(
"SCO (Voice Link) ver %s"
,
VERSION
);
BT_INFO
(
"SCO socket layer initialized"
);
BT_INFO
(
"SCO socket layer initialized"
);
return
0
;
return
0
;
...
@@ -1061,7 +1059,7 @@ static int __init sco_init(void)
...
@@ -1061,7 +1059,7 @@ static int __init sco_init(void)
return
err
;
return
err
;
}
}
static
void
__exit
sco_exit
(
void
)
void
__exit
sco_exit
(
void
)
{
{
debugfs_remove
(
sco_debugfs
);
debugfs_remove
(
sco_debugfs
);
...
@@ -1074,14 +1072,5 @@ static void __exit sco_exit(void)
...
@@ -1074,14 +1072,5 @@ static void __exit sco_exit(void)
proto_unregister
(
&
sco_proto
);
proto_unregister
(
&
sco_proto
);
}
}
module_init
(
sco_init
);
module_exit
(
sco_exit
);
module_param
(
disable_esco
,
bool
,
0644
);
module_param
(
disable_esco
,
bool
,
0644
);
MODULE_PARM_DESC
(
disable_esco
,
"Disable eSCO connection creation"
);
MODULE_PARM_DESC
(
disable_esco
,
"Disable eSCO connection creation"
);
MODULE_AUTHOR
(
"Marcel Holtmann <marcel@holtmann.org>"
);
MODULE_DESCRIPTION
(
"Bluetooth SCO ver "
VERSION
);
MODULE_VERSION
(
VERSION
);
MODULE_LICENSE
(
"GPL"
);
MODULE_ALIAS
(
"bt-proto-2"
);
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