Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
c30ae138
K
Kernel
项目概览
openeuler
/
Kernel
接近 2 年 前同步成功
通知
8
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
Kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
c30ae138
编写于
12月 02, 2010
作者:
J
John W. Linville
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'master' of
git://git.kernel.org/pub/scm/linux/kernel/git/padovan/bluetooth-next-2.6
上级
78b85956
be21871f
变更
19
显示空白变更内容
内联
并排
Showing
19 changed file
with
363 addition
and
212 deletion
+363
-212
drivers/bluetooth/ath3k.c
drivers/bluetooth/ath3k.c
+4
-0
drivers/bluetooth/btusb.c
drivers/bluetooth/btusb.c
+9
-3
include/net/bluetooth/hci.h
include/net/bluetooth/hci.h
+8
-8
include/net/bluetooth/hci_core.h
include/net/bluetooth/hci_core.h
+7
-7
include/net/bluetooth/l2cap.h
include/net/bluetooth/l2cap.h
+11
-11
include/net/bluetooth/rfcomm.h
include/net/bluetooth/rfcomm.h
+9
-9
include/net/bluetooth/sco.h
include/net/bluetooth/sco.h
+10
-10
net/bluetooth/bnep/core.c
net/bluetooth/bnep/core.c
+1
-0
net/bluetooth/cmtp/core.c
net/bluetooth/cmtp/core.c
+1
-0
net/bluetooth/hci_conn.c
net/bluetooth/hci_conn.c
+15
-8
net/bluetooth/hci_core.c
net/bluetooth/hci_core.c
+42
-24
net/bluetooth/hci_event.c
net/bluetooth/hci_event.c
+125
-52
net/bluetooth/hci_sock.c
net/bluetooth/hci_sock.c
+11
-6
net/bluetooth/hidp/core.c
net/bluetooth/hidp/core.c
+1
-1
net/bluetooth/l2cap.c
net/bluetooth/l2cap.c
+63
-31
net/bluetooth/rfcomm/core.c
net/bluetooth/rfcomm/core.c
+4
-4
net/bluetooth/rfcomm/sock.c
net/bluetooth/rfcomm/sock.c
+10
-14
net/bluetooth/rfcomm/tty.c
net/bluetooth/rfcomm/tty.c
+16
-12
net/bluetooth/sco.c
net/bluetooth/sco.c
+16
-12
未找到文件。
drivers/bluetooth/ath3k.c
浏览文件 @
c30ae138
...
...
@@ -35,6 +35,10 @@
static
struct
usb_device_id
ath3k_table
[]
=
{
/* Atheros AR3011 */
{
USB_DEVICE
(
0x0CF3
,
0x3000
)
},
/* Atheros AR3011 with sflash firmware*/
{
USB_DEVICE
(
0x0CF3
,
0x3002
)
},
{
}
/* Terminating entry */
};
...
...
drivers/bluetooth/btusb.c
浏览文件 @
c30ae138
...
...
@@ -99,6 +99,9 @@ static struct usb_device_id blacklist_table[] = {
/* Broadcom BCM2033 without firmware */
{
USB_DEVICE
(
0x0a5c
,
0x2033
),
.
driver_info
=
BTUSB_IGNORE
},
/* Atheros 3011 with sflash firmware */
{
USB_DEVICE
(
0x0cf3
,
0x3002
),
.
driver_info
=
BTUSB_IGNORE
},
/* Broadcom BCM2035 */
{
USB_DEVICE
(
0x0a5c
,
0x2035
),
.
driver_info
=
BTUSB_WRONG_SCO_MTU
},
{
USB_DEVICE
(
0x0a5c
,
0x200a
),
.
driver_info
=
BTUSB_WRONG_SCO_MTU
},
...
...
@@ -239,6 +242,7 @@ static void btusb_intr_complete(struct urb *urb)
err
=
usb_submit_urb
(
urb
,
GFP_ATOMIC
);
if
(
err
<
0
)
{
if
(
err
!=
-
EPERM
)
BT_ERR
(
"%s urb %p failed to resubmit (%d)"
,
hdev
->
name
,
urb
,
-
err
);
usb_unanchor_urb
(
urb
);
...
...
@@ -323,6 +327,7 @@ static void btusb_bulk_complete(struct urb *urb)
err
=
usb_submit_urb
(
urb
,
GFP_ATOMIC
);
if
(
err
<
0
)
{
if
(
err
!=
-
EPERM
)
BT_ERR
(
"%s urb %p failed to resubmit (%d)"
,
hdev
->
name
,
urb
,
-
err
);
usb_unanchor_urb
(
urb
);
...
...
@@ -412,6 +417,7 @@ static void btusb_isoc_complete(struct urb *urb)
err
=
usb_submit_urb
(
urb
,
GFP_ATOMIC
);
if
(
err
<
0
)
{
if
(
err
!=
-
EPERM
)
BT_ERR
(
"%s urb %p failed to resubmit (%d)"
,
hdev
->
name
,
urb
,
-
err
);
usb_unanchor_urb
(
urb
);
...
...
include/net/bluetooth/hci.h
浏览文件 @
c30ae138
include/net/bluetooth/hci_core.h
浏览文件 @
c30ae138
...
...
@@ -215,8 +215,8 @@ extern rwlock_t hci_dev_list_lock;
extern
rwlock_t
hci_cb_list_lock
;
/* ----- Inquiry cache ----- */
#define INQUIRY_CACHE_AGE_MAX (HZ*30) /
/ 30 seconds
#define INQUIRY_ENTRY_AGE_MAX (HZ*60) /
/ 60 seconds
#define INQUIRY_CACHE_AGE_MAX (HZ*30)
/
* 30 seconds */
#define INQUIRY_ENTRY_AGE_MAX (HZ*60)
/
* 60 seconds */
#define inquiry_cache_lock(c) spin_lock(&c->lock)
#define inquiry_cache_unlock(c) spin_unlock(&c->lock)
...
...
include/net/bluetooth/l2cap.h
浏览文件 @
c30ae138
...
...
@@ -417,11 +417,11 @@ static inline int l2cap_tx_window_full(struct sock *sk)
return
sub
==
pi
->
remote_tx_win
;
}
#define __get_txseq(ctrl)
((ctrl) & L2CAP_CTRL_TXSEQ) >> 1
#define __get_reqseq(ctrl)
((ctrl) & L2CAP_CTRL_REQSEQ) >> 8
#define __is_iframe(ctrl)
!((ctrl) & L2CAP_CTRL_FRAME_TYPE
)
#define __is_sframe(ctrl)
(ctrl) & L2CAP_CTRL_FRAME_TYPE
#define __is_sar_start(ctrl)
((ctrl) & L2CAP_CTRL_SAR) == L2CAP_SDU_START
#define __get_txseq(ctrl)
(((ctrl) & L2CAP_CTRL_TXSEQ) >> 1)
#define __get_reqseq(ctrl)
(((ctrl) & L2CAP_CTRL_REQSEQ) >> 8)
#define __is_iframe(ctrl)
(!((ctrl) & L2CAP_CTRL_FRAME_TYPE)
)
#define __is_sframe(ctrl)
((ctrl) & L2CAP_CTRL_FRAME_TYPE)
#define __is_sar_start(ctrl)
(((ctrl) & L2CAP_CTRL_SAR) == L2CAP_SDU_START)
void
l2cap_load
(
void
);
...
...
include/net/bluetooth/rfcomm.h
浏览文件 @
c30ae138
/*
RFCOMM implementation for Linux Bluetooth stack (BlueZ)
.
RFCOMM implementation for Linux Bluetooth stack (BlueZ)
Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>
Copyright (C) 2002 Marcel Holtmann <marcel@holtmann.org>
...
...
@@ -105,7 +105,7 @@
struct
rfcomm_hdr
{
u8
addr
;
u8
ctrl
;
u8
len
;
/
/ Actual size can be 2 bytes
u8
len
;
/
* Actual size can be 2 bytes */
}
__packed
;
struct
rfcomm_cmd
{
...
...
include/net/bluetooth/sco.h
浏览文件 @
c30ae138
net/bluetooth/bnep/core.c
浏览文件 @
c30ae138
...
...
@@ -648,6 +648,7 @@ int bnep_del_connection(struct bnep_conndel_req *req)
static
void
__bnep_copy_ci
(
struct
bnep_conninfo
*
ci
,
struct
bnep_session
*
s
)
{
memset
(
ci
,
0
,
sizeof
(
*
ci
));
memcpy
(
ci
->
dst
,
s
->
eh
.
h_source
,
ETH_ALEN
);
strcpy
(
ci
->
device
,
s
->
dev
->
name
);
ci
->
flags
=
s
->
flags
;
...
...
net/bluetooth/cmtp/core.c
浏览文件 @
c30ae138
...
...
@@ -78,6 +78,7 @@ static void __cmtp_unlink_session(struct cmtp_session *session)
static
void
__cmtp_copy_session
(
struct
cmtp_session
*
session
,
struct
cmtp_conninfo
*
ci
)
{
memset
(
ci
,
0
,
sizeof
(
*
ci
));
bacpy
(
&
ci
->
bdaddr
,
&
session
->
bdaddr
);
ci
->
flags
=
session
->
flags
;
...
...
net/bluetooth/hci_conn.c
浏览文件 @
c30ae138
...
...
@@ -39,7 +39,7 @@
#include <net/sock.h>
#include <asm/system.h>
#include <
asm
/uaccess.h>
#include <
linux
/uaccess.h>
#include <asm/unaligned.h>
#include <net/bluetooth/bluetooth.h>
...
...
@@ -66,7 +66,8 @@ void hci_acl_connect(struct hci_conn *conn)
bacpy
(
&
cp
.
bdaddr
,
&
conn
->
dst
);
cp
.
pscan_rep_mode
=
0x02
;
if
((
ie
=
hci_inquiry_cache_lookup
(
hdev
,
&
conn
->
dst
)))
{
ie
=
hci_inquiry_cache_lookup
(
hdev
,
&
conn
->
dst
);
if
(
ie
)
{
if
(
inquiry_entry_age
(
ie
)
<=
INQUIRY_ENTRY_AGE_MAX
)
{
cp
.
pscan_rep_mode
=
ie
->
data
.
pscan_rep_mode
;
cp
.
pscan_mode
=
ie
->
data
.
pscan_mode
;
...
...
@@ -368,8 +369,10 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8
BT_DBG
(
"%s dst %s"
,
hdev
->
name
,
batostr
(
dst
));
if
(
!
(
acl
=
hci_conn_hash_lookup_ba
(
hdev
,
ACL_LINK
,
dst
)))
{
if
(
!
(
acl
=
hci_conn_add
(
hdev
,
ACL_LINK
,
dst
)))
acl
=
hci_conn_hash_lookup_ba
(
hdev
,
ACL_LINK
,
dst
);
if
(
!
acl
)
{
acl
=
hci_conn_add
(
hdev
,
ACL_LINK
,
dst
);
if
(
!
acl
)
return
NULL
;
}
...
...
@@ -389,8 +392,10 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8
if
(
type
==
ACL_LINK
)
return
acl
;
if
(
!
(
sco
=
hci_conn_hash_lookup_ba
(
hdev
,
type
,
dst
)))
{
if
(
!
(
sco
=
hci_conn_add
(
hdev
,
type
,
dst
)))
{
sco
=
hci_conn_hash_lookup_ba
(
hdev
,
type
,
dst
);
if
(
!
sco
)
{
sco
=
hci_conn_add
(
hdev
,
type
,
dst
);
if
(
!
sco
)
{
hci_conn_put
(
acl
);
return
NULL
;
}
...
...
@@ -647,10 +652,12 @@ int hci_get_conn_list(void __user *arg)
size
=
sizeof
(
req
)
+
req
.
conn_num
*
sizeof
(
*
ci
);
if
(
!
(
cl
=
kmalloc
(
size
,
GFP_KERNEL
)))
cl
=
kmalloc
(
size
,
GFP_KERNEL
);
if
(
!
cl
)
return
-
ENOMEM
;
if
(
!
(
hdev
=
hci_dev_get
(
req
.
dev_id
)))
{
hdev
=
hci_dev_get
(
req
.
dev_id
);
if
(
!
hdev
)
{
kfree
(
cl
);
return
-
ENODEV
;
}
...
...
net/bluetooth/hci_core.c
浏览文件 @
c30ae138
...
...
@@ -44,7 +44,7 @@
#include <net/sock.h>
#include <asm/system.h>
#include <
asm
/uaccess.h>
#include <
linux
/uaccess.h>
#include <asm/unaligned.h>
#include <net/bluetooth/bluetooth.h>
...
...
@@ -349,20 +349,23 @@ struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, bdaddr_t *b
void
hci_inquiry_cache_update
(
struct
hci_dev
*
hdev
,
struct
inquiry_data
*
data
)
{
struct
inquiry_cache
*
cache
=
&
hdev
->
inq_cache
;
struct
inquiry_entry
*
e
;
struct
inquiry_entry
*
i
e
;
BT_DBG
(
"cache %p, %s"
,
cache
,
batostr
(
&
data
->
bdaddr
));
if
(
!
(
e
=
hci_inquiry_cache_lookup
(
hdev
,
&
data
->
bdaddr
)))
{
ie
=
hci_inquiry_cache_lookup
(
hdev
,
&
data
->
bdaddr
);
if
(
!
ie
)
{
/* Entry not in the cache. Add new one. */
if
(
!
(
e
=
kzalloc
(
sizeof
(
struct
inquiry_entry
),
GFP_ATOMIC
)))
ie
=
kzalloc
(
sizeof
(
struct
inquiry_entry
),
GFP_ATOMIC
);
if
(
!
ie
)
return
;
e
->
next
=
cache
->
list
;
cache
->
list
=
e
;
ie
->
next
=
cache
->
list
;
cache
->
list
=
ie
;
}
memcpy
(
&
e
->
data
,
data
,
sizeof
(
*
data
));
e
->
timestamp
=
jiffies
;
memcpy
(
&
i
e
->
data
,
data
,
sizeof
(
*
data
));
i
e
->
timestamp
=
jiffies
;
cache
->
timestamp
=
jiffies
;
}
...
...
@@ -430,8 +433,12 @@ int hci_inquiry(void __user *arg)
hci_dev_unlock_bh
(
hdev
);
timeo
=
ir
.
length
*
msecs_to_jiffies
(
2000
);
if
(
do_inquiry
&&
(
err
=
hci_request
(
hdev
,
hci_inq_req
,
(
unsigned
long
)
&
ir
,
timeo
))
<
0
)
if
(
do_inquiry
)
{
err
=
hci_request
(
hdev
,
hci_inq_req
,
(
unsigned
long
)
&
ir
,
timeo
);
if
(
err
<
0
)
goto
done
;
}
/* for unlimited number of responses we will use buffer with 255 entries */
max_rsp
=
(
ir
.
num_rsp
==
0
)
?
255
:
ir
.
num_rsp
;
...
...
@@ -439,7 +446,8 @@ int hci_inquiry(void __user *arg)
/* cache_dump can't sleep. Therefore we allocate temp buffer and then
* copy it to the user space.
*/
if
(
!
(
buf
=
kmalloc
(
sizeof
(
struct
inquiry_info
)
*
max_rsp
,
GFP_KERNEL
)))
{
buf
=
kmalloc
(
sizeof
(
struct
inquiry_info
)
*
max_rsp
,
GFP_KERNEL
);
if
(
!
buf
)
{
err
=
-
ENOMEM
;
goto
done
;
}
...
...
@@ -611,7 +619,8 @@ int hci_dev_close(__u16 dev)
struct
hci_dev
*
hdev
;
int
err
;
if
(
!
(
hdev
=
hci_dev_get
(
dev
)))
hdev
=
hci_dev_get
(
dev
);
if
(
!
hdev
)
return
-
ENODEV
;
err
=
hci_dev_do_close
(
hdev
);
hci_dev_put
(
hdev
);
...
...
@@ -623,7 +632,8 @@ int hci_dev_reset(__u16 dev)
struct
hci_dev
*
hdev
;
int
ret
=
0
;
if
(
!
(
hdev
=
hci_dev_get
(
dev
)))
hdev
=
hci_dev_get
(
dev
);
if
(
!
hdev
)
return
-
ENODEV
;
hci_req_lock
(
hdev
);
...
...
@@ -663,7 +673,8 @@ int hci_dev_reset_stat(__u16 dev)
struct
hci_dev
*
hdev
;
int
ret
=
0
;
if
(
!
(
hdev
=
hci_dev_get
(
dev
)))
hdev
=
hci_dev_get
(
dev
);
if
(
!
hdev
)
return
-
ENODEV
;
memset
(
&
hdev
->
stat
,
0
,
sizeof
(
struct
hci_dev_stats
));
...
...
@@ -682,7 +693,8 @@ int hci_dev_cmd(unsigned int cmd, void __user *arg)
if
(
copy_from_user
(
&
dr
,
arg
,
sizeof
(
dr
)))
return
-
EFAULT
;
if
(
!
(
hdev
=
hci_dev_get
(
dr
.
dev_id
)))
hdev
=
hci_dev_get
(
dr
.
dev_id
);
if
(
!
hdev
)
return
-
ENODEV
;
switch
(
cmd
)
{
...
...
@@ -763,7 +775,8 @@ int hci_get_dev_list(void __user *arg)
size
=
sizeof
(
*
dl
)
+
dev_num
*
sizeof
(
*
dr
);
if
(
!
(
dl
=
kzalloc
(
size
,
GFP_KERNEL
)))
dl
=
kzalloc
(
size
,
GFP_KERNEL
);
if
(
!
dl
)
return
-
ENOMEM
;
dr
=
dl
->
dev_req
;
...
...
@@ -797,7 +810,8 @@ int hci_get_dev_info(void __user *arg)
if
(
copy_from_user
(
&
di
,
arg
,
sizeof
(
di
)))
return
-
EFAULT
;
if
(
!
(
hdev
=
hci_dev_get
(
di
.
dev_id
)))
hdev
=
hci_dev_get
(
di
.
dev_id
);
if
(
!
hdev
)
return
-
ENODEV
;
strcpy
(
di
.
name
,
hdev
->
name
);
...
...
@@ -905,7 +919,7 @@ int hci_register_dev(struct hci_dev *hdev)
hdev
->
sniff_max_interval
=
800
;
hdev
->
sniff_min_interval
=
80
;
tasklet_init
(
&
hdev
->
cmd_task
,
hci_cmd_task
,(
unsigned
long
)
hdev
);
tasklet_init
(
&
hdev
->
cmd_task
,
hci_cmd_task
,
(
unsigned
long
)
hdev
);
tasklet_init
(
&
hdev
->
rx_task
,
hci_rx_task
,
(
unsigned
long
)
hdev
);
tasklet_init
(
&
hdev
->
tx_task
,
hci_tx_task
,
(
unsigned
long
)
hdev
);
...
...
@@ -1368,7 +1382,8 @@ void hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags)
bt_cb
(
skb
)
->
pkt_type
=
HCI_ACLDATA_PKT
;
hci_add_acl_hdr
(
skb
,
conn
->
handle
,
flags
|
ACL_START
);
if
(
!
(
list
=
skb_shinfo
(
skb
)
->
frag_list
))
{
list
=
skb_shinfo
(
skb
)
->
frag_list
;
if
(
!
list
)
{
/* Non fragmented */
BT_DBG
(
"%s nonfrag skb %p len %d"
,
hdev
->
name
,
skb
,
skb
->
len
);
...
...
@@ -1609,7 +1624,8 @@ static inline void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
hci_conn_enter_active_mode
(
conn
);
/* Send to upper protocol */
if
((
hp
=
hci_proto
[
HCI_PROTO_L2CAP
])
&&
hp
->
recv_acldata
)
{
hp
=
hci_proto
[
HCI_PROTO_L2CAP
];
if
(
hp
&&
hp
->
recv_acldata
)
{
hp
->
recv_acldata
(
conn
,
skb
,
flags
);
return
;
}
...
...
@@ -1644,7 +1660,8 @@ static inline void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
register
struct
hci_proto
*
hp
;
/* Send to upper protocol */
if
((
hp
=
hci_proto
[
HCI_PROTO_SCO
])
&&
hp
->
recv_scodata
)
{
hp
=
hci_proto
[
HCI_PROTO_SCO
];
if
(
hp
&&
hp
->
recv_scodata
)
{
hp
->
recv_scodata
(
conn
,
skb
);
return
;
}
...
...
@@ -1727,7 +1744,8 @@ static void hci_cmd_task(unsigned long arg)
if
(
atomic_read
(
&
hdev
->
cmd_cnt
)
&&
(
skb
=
skb_dequeue
(
&
hdev
->
cmd_q
)))
{
kfree_skb
(
hdev
->
sent_cmd
);
if
((
hdev
->
sent_cmd
=
skb_clone
(
skb
,
GFP_ATOMIC
)))
{
hdev
->
sent_cmd
=
skb_clone
(
skb
,
GFP_ATOMIC
);
if
(
hdev
->
sent_cmd
)
{
atomic_dec
(
&
hdev
->
cmd_cnt
);
hci_send_frame
(
skb
);
hdev
->
cmd_last_tx
=
jiffies
;
...
...
net/bluetooth/hci_event.c
浏览文件 @
c30ae138
...
...
@@ -39,7 +39,7 @@
#include <net/sock.h>
#include <asm/system.h>
#include <
asm
/uaccess.h>
#include <
linux
/uaccess.h>
#include <asm/unaligned.h>
#include <net/bluetooth/bluetooth.h>
...
...
@@ -677,9 +677,50 @@ static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
hci_dev_unlock
(
hdev
);
}
static
int
hci_outgoing_auth_needed
(
struct
hci_dev
*
hdev
,
struct
hci_conn
*
conn
)
{
if
(
conn
->
state
!=
BT_CONFIG
||
!
conn
->
out
)
return
0
;
if
(
conn
->
sec_level
==
BT_SECURITY_SDP
)
return
0
;
/* Only request authentication for SSP connections or non-SSP
* devices with sec_level HIGH */
if
(
!
(
hdev
->
ssp_mode
>
0
&&
conn
->
ssp_mode
>
0
)
&&
conn
->
sec_level
!=
BT_SECURITY_HIGH
)
return
0
;
return
1
;
}
static
void
hci_cs_remote_name_req
(
struct
hci_dev
*
hdev
,
__u8
status
)
{
struct
hci_cp_remote_name_req
*
cp
;
struct
hci_conn
*
conn
;
BT_DBG
(
"%s status 0x%x"
,
hdev
->
name
,
status
);
/* If successful wait for the name req complete event before
* checking for the need to do authentication */
if
(
!
status
)
return
;
cp
=
hci_sent_cmd_data
(
hdev
,
HCI_OP_REMOTE_NAME_REQ
);
if
(
!
cp
)
return
;
hci_dev_lock
(
hdev
);
conn
=
hci_conn_hash_lookup_ba
(
hdev
,
ACL_LINK
,
&
cp
->
bdaddr
);
if
(
conn
&&
hci_outgoing_auth_needed
(
hdev
,
conn
))
{
struct
hci_cp_auth_requested
cp
;
cp
.
handle
=
__cpu_to_le16
(
conn
->
handle
);
hci_send_cmd
(
hdev
,
HCI_OP_AUTH_REQUESTED
,
sizeof
(
cp
),
&
cp
);
}
hci_dev_unlock
(
hdev
);
}
static
void
hci_cs_read_remote_features
(
struct
hci_dev
*
hdev
,
__u8
status
)
...
...
@@ -955,12 +996,14 @@ static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *sk
hci_dev_lock
(
hdev
);
if
((
ie
=
hci_inquiry_cache_lookup
(
hdev
,
&
ev
->
bdaddr
)))
ie
=
hci_inquiry_cache_lookup
(
hdev
,
&
ev
->
bdaddr
);
if
(
ie
)
memcpy
(
ie
->
data
.
dev_class
,
ev
->
dev_class
,
3
);
conn
=
hci_conn_hash_lookup_ba
(
hdev
,
ev
->
link_type
,
&
ev
->
bdaddr
);
if
(
!
conn
)
{
if
(
!
(
conn
=
hci_conn_add
(
hdev
,
ev
->
link_type
,
&
ev
->
bdaddr
)))
{
conn
=
hci_conn_add
(
hdev
,
ev
->
link_type
,
&
ev
->
bdaddr
);
if
(
!
conn
)
{
BT_ERR
(
"No memory for new connection"
);
hci_dev_unlock
(
hdev
);
return
;
...
...
@@ -1090,9 +1133,23 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s
static
inline
void
hci_remote_name_evt
(
struct
hci_dev
*
hdev
,
struct
sk_buff
*
skb
)
{
struct
hci_ev_remote_name
*
ev
=
(
void
*
)
skb
->
data
;
struct
hci_conn
*
conn
;
BT_DBG
(
"%s"
,
hdev
->
name
);
hci_conn_check_pending
(
hdev
);
hci_dev_lock
(
hdev
);
conn
=
hci_conn_hash_lookup_ba
(
hdev
,
ACL_LINK
,
&
ev
->
bdaddr
);
if
(
conn
&&
hci_outgoing_auth_needed
(
hdev
,
conn
))
{
struct
hci_cp_auth_requested
cp
;
cp
.
handle
=
__cpu_to_le16
(
conn
->
handle
);
hci_send_cmd
(
hdev
,
HCI_OP_AUTH_REQUESTED
,
sizeof
(
cp
),
&
cp
);
}
hci_dev_unlock
(
hdev
);
}
static
inline
void
hci_encrypt_change_evt
(
struct
hci_dev
*
hdev
,
struct
sk_buff
*
skb
)
...
...
@@ -1162,33 +1219,39 @@ static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff
hci_dev_lock
(
hdev
);
conn
=
hci_conn_hash_lookup_handle
(
hdev
,
__le16_to_cpu
(
ev
->
handle
));
if
(
conn
)
{
if
(
!
conn
)
goto
unlock
;
if
(
!
ev
->
status
)
memcpy
(
conn
->
features
,
ev
->
features
,
8
);
if
(
conn
->
state
==
BT_CONFIG
)
{
if
(
!
ev
->
status
&&
lmp_ssp_capable
(
hdev
)
&&
lmp_ssp_capable
(
conn
))
{
if
(
conn
->
state
!=
BT_CONFIG
)
goto
unlock
;
if
(
!
ev
->
status
&&
lmp_ssp_capable
(
hdev
)
&&
lmp_ssp_capable
(
conn
))
{
struct
hci_cp_read_remote_ext_features
cp
;
cp
.
handle
=
ev
->
handle
;
cp
.
page
=
0x01
;
hci_send_cmd
(
hdev
,
HCI_OP_READ_REMOTE_EXT_FEATURES
,
hci_send_cmd
(
hdev
,
HCI_OP_READ_REMOTE_EXT_FEATURES
,
sizeof
(
cp
),
&
cp
);
}
else
if
(
!
ev
->
status
&&
conn
->
out
&&
conn
->
sec_level
==
BT_SECURITY_HIGH
)
{
struct
hci_cp_auth_requested
cp
;
cp
.
handle
=
ev
->
handle
;
hci_send_cmd
(
hdev
,
HCI_OP_AUTH_REQUESTED
,
sizeof
(
cp
),
&
cp
);
}
else
{
goto
unlock
;
}
if
(
!
ev
->
status
)
{
struct
hci_cp_remote_name_req
cp
;
memset
(
&
cp
,
0
,
sizeof
(
cp
));
bacpy
(
&
cp
.
bdaddr
,
&
conn
->
dst
);
cp
.
pscan_rep_mode
=
0x02
;
hci_send_cmd
(
hdev
,
HCI_OP_REMOTE_NAME_REQ
,
sizeof
(
cp
),
&
cp
);
}
if
(
!
hci_outgoing_auth_needed
(
hdev
,
conn
))
{
conn
->
state
=
BT_CONNECTED
;
hci_proto_connect_cfm
(
conn
,
ev
->
status
);
hci_conn_put
(
conn
);
}
}
}
unlock:
hci_dev_unlock
(
hdev
);
}
...
...
@@ -1449,10 +1512,12 @@ static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *s
conn
->
sent
-=
count
;
if
(
conn
->
type
==
ACL_LINK
)
{
if
((
hdev
->
acl_cnt
+=
count
)
>
hdev
->
acl_pkts
)
hdev
->
acl_cnt
+=
count
;
if
(
hdev
->
acl_cnt
>
hdev
->
acl_pkts
)
hdev
->
acl_cnt
=
hdev
->
acl_pkts
;
}
else
{
if
((
hdev
->
sco_cnt
+=
count
)
>
hdev
->
sco_pkts
)
hdev
->
sco_cnt
+=
count
;
if
(
hdev
->
sco_cnt
>
hdev
->
sco_pkts
)
hdev
->
sco_cnt
=
hdev
->
sco_pkts
;
}
}
...
...
@@ -1547,7 +1612,8 @@ static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *sk
if
(
conn
&&
!
ev
->
status
)
{
struct
inquiry_entry
*
ie
;
if
((
ie
=
hci_inquiry_cache_lookup
(
hdev
,
&
conn
->
dst
)))
{
ie
=
hci_inquiry_cache_lookup
(
hdev
,
&
conn
->
dst
);
if
(
ie
)
{
ie
->
data
.
clock_offset
=
ev
->
clock_offset
;
ie
->
timestamp
=
jiffies
;
}
...
...
@@ -1581,7 +1647,8 @@ static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *
hci_dev_lock
(
hdev
);
if
((
ie
=
hci_inquiry_cache_lookup
(
hdev
,
&
ev
->
bdaddr
)))
{
ie
=
hci_inquiry_cache_lookup
(
hdev
,
&
ev
->
bdaddr
);
if
(
ie
)
{
ie
->
data
.
pscan_rep_mode
=
ev
->
pscan_rep_mode
;
ie
->
timestamp
=
jiffies
;
}
...
...
@@ -1646,32 +1713,37 @@ static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_b
hci_dev_lock
(
hdev
);
conn
=
hci_conn_hash_lookup_handle
(
hdev
,
__le16_to_cpu
(
ev
->
handle
));
if
(
conn
)
{
if
(
!
conn
)
goto
unlock
;
if
(
!
ev
->
status
&&
ev
->
page
==
0x01
)
{
struct
inquiry_entry
*
ie
;
if
((
ie
=
hci_inquiry_cache_lookup
(
hdev
,
&
conn
->
dst
)))
ie
=
hci_inquiry_cache_lookup
(
hdev
,
&
conn
->
dst
);
if
(
ie
)
ie
->
data
.
ssp_mode
=
(
ev
->
features
[
0
]
&
0x01
);
conn
->
ssp_mode
=
(
ev
->
features
[
0
]
&
0x01
);
}
if
(
conn
->
state
==
BT_CONFIG
)
{
if
(
!
ev
->
status
&&
hdev
->
ssp_mode
>
0
&&
conn
->
ssp_mode
>
0
&&
conn
->
out
&&
conn
->
sec_level
!=
BT_SECURITY_SDP
)
{
struct
hci_cp_auth_requested
cp
;
cp
.
handle
=
ev
->
handle
;
hci_send_cmd
(
hdev
,
HCI_OP_AUTH_REQUESTED
,
sizeof
(
cp
),
&
cp
);
}
else
{
if
(
conn
->
state
!=
BT_CONFIG
)
goto
unlock
;
if
(
!
ev
->
status
)
{
struct
hci_cp_remote_name_req
cp
;
memset
(
&
cp
,
0
,
sizeof
(
cp
));
bacpy
(
&
cp
.
bdaddr
,
&
conn
->
dst
);
cp
.
pscan_rep_mode
=
0x02
;
hci_send_cmd
(
hdev
,
HCI_OP_REMOTE_NAME_REQ
,
sizeof
(
cp
),
&
cp
);
}
if
(
!
hci_outgoing_auth_needed
(
hdev
,
conn
))
{
conn
->
state
=
BT_CONNECTED
;
hci_proto_connect_cfm
(
conn
,
ev
->
status
);
hci_conn_put
(
conn
);
}
}
}
unlock:
hci_dev_unlock
(
hdev
);
}
...
...
@@ -1821,7 +1893,8 @@ static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_
hci_dev_lock
(
hdev
);
if
((
ie
=
hci_inquiry_cache_lookup
(
hdev
,
&
ev
->
bdaddr
)))
ie
=
hci_inquiry_cache_lookup
(
hdev
,
&
ev
->
bdaddr
);
if
(
ie
)
ie
->
data
.
ssp_mode
=
(
ev
->
features
[
0
]
&
0x01
);
hci_dev_unlock
(
hdev
);
...
...
net/bluetooth/hci_sock.c
浏览文件 @
c30ae138
...
...
@@ -43,7 +43,7 @@
#include <net/sock.h>
#include <asm/system.h>
#include <
asm
/uaccess.h>
#include <
linux
/uaccess.h>
#include <asm/unaligned.h>
#include <net/bluetooth/bluetooth.h>
...
...
@@ -125,7 +125,8 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb)
continue
;
}
if
(
!
(
nskb
=
skb_clone
(
skb
,
GFP_ATOMIC
)))
nskb
=
skb_clone
(
skb
,
GFP_ATOMIC
);
if
(
!
nskb
)
continue
;
/* Put type byte before the data */
...
...
@@ -370,7 +371,8 @@ static int hci_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_le
}
if
(
haddr
->
hci_dev
!=
HCI_DEV_NONE
)
{
if
(
!
(
hdev
=
hci_dev_get
(
haddr
->
hci_dev
)))
{
hdev
=
hci_dev_get
(
haddr
->
hci_dev
);
if
(
!
hdev
)
{
err
=
-
ENODEV
;
goto
done
;
}
...
...
@@ -457,7 +459,8 @@ static int hci_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
if
(
sk
->
sk_state
==
BT_CLOSED
)
return
0
;
if
(
!
(
skb
=
skb_recv_datagram
(
sk
,
flags
,
noblock
,
&
err
)))
skb
=
skb_recv_datagram
(
sk
,
flags
,
noblock
,
&
err
);
if
(
!
skb
)
return
err
;
msg
->
msg_namelen
=
0
;
...
...
@@ -499,7 +502,8 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
lock_sock
(
sk
);
if
(
!
(
hdev
=
hci_pi
(
sk
)
->
hdev
))
{
hdev
=
hci_pi
(
sk
)
->
hdev
;
if
(
!
hdev
)
{
err
=
-
EBADFD
;
goto
done
;
}
...
...
@@ -509,7 +513,8 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
goto
done
;
}
if
(
!
(
skb
=
bt_skb_send_alloc
(
sk
,
len
,
msg
->
msg_flags
&
MSG_DONTWAIT
,
&
err
)))
skb
=
bt_skb_send_alloc
(
sk
,
len
,
msg
->
msg_flags
&
MSG_DONTWAIT
,
&
err
);
if
(
!
skb
)
goto
done
;
if
(
memcpy_fromiovec
(
skb_put
(
skb
,
len
),
msg
->
msg_iov
,
len
))
{
...
...
net/bluetooth/hidp/core.c
浏览文件 @
c30ae138
...
...
@@ -107,6 +107,7 @@ static void __hidp_unlink_session(struct hidp_session *session)
static
void
__hidp_copy_session
(
struct
hidp_session
*
session
,
struct
hidp_conninfo
*
ci
)
{
memset
(
ci
,
0
,
sizeof
(
*
ci
));
bacpy
(
&
ci
->
bdaddr
,
&
session
->
bdaddr
);
ci
->
flags
=
session
->
flags
;
...
...
@@ -115,7 +116,6 @@ static void __hidp_copy_session(struct hidp_session *session, struct hidp_connin
ci
->
vendor
=
0x0000
;
ci
->
product
=
0x0000
;
ci
->
version
=
0x0000
;
memset
(
ci
->
name
,
0
,
128
);
if
(
session
->
input
)
{
ci
->
vendor
=
session
->
input
->
id
.
vendor
;
...
...
net/bluetooth/l2cap.c
浏览文件 @
c30ae138
...
...
@@ -57,7 +57,7 @@
#define VERSION "2.15"
static
int
disable_ertm
=
0
;
static
int
disable_ertm
;
static
u32
l2cap_feat_mask
=
L2CAP_FEAT_FIXED_CHAN
;
static
u8
l2cap_fixed_chan
[
8
]
=
{
0x02
,
};
...
...
@@ -83,6 +83,18 @@ static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
static
int
l2cap_ertm_data_rcv
(
struct
sock
*
sk
,
struct
sk_buff
*
skb
);
/* ---- L2CAP timers ---- */
static
void
l2cap_sock_set_timer
(
struct
sock
*
sk
,
long
timeout
)
{
BT_DBG
(
"sk %p state %d timeout %ld"
,
sk
,
sk
->
sk_state
,
timeout
);
sk_reset_timer
(
sk
,
&
sk
->
sk_timer
,
jiffies
+
timeout
);
}
static
void
l2cap_sock_clear_timer
(
struct
sock
*
sk
)
{
BT_DBG
(
"sock %p state %d"
,
sk
,
sk
->
sk_state
);
sk_stop_timer
(
sk
,
&
sk
->
sk_timer
);
}
static
void
l2cap_sock_timeout
(
unsigned
long
arg
)
{
struct
sock
*
sk
=
(
struct
sock
*
)
arg
;
...
...
@@ -92,6 +104,14 @@ static void l2cap_sock_timeout(unsigned long arg)
bh_lock_sock
(
sk
);
if
(
sock_owned_by_user
(
sk
))
{
/* sk is owned by user. Try again later */
l2cap_sock_set_timer
(
sk
,
HZ
/
5
);
bh_unlock_sock
(
sk
);
sock_put
(
sk
);
return
;
}
if
(
sk
->
sk_state
==
BT_CONNECTED
||
sk
->
sk_state
==
BT_CONFIG
)
reason
=
ECONNREFUSED
;
else
if
(
sk
->
sk_state
==
BT_CONNECT
&&
...
...
@@ -108,18 +128,6 @@ static void l2cap_sock_timeout(unsigned long arg)
sock_put
(
sk
);
}
static
void
l2cap_sock_set_timer
(
struct
sock
*
sk
,
long
timeout
)
{
BT_DBG
(
"sk %p state %d timeout %ld"
,
sk
,
sk
->
sk_state
,
timeout
);
sk_reset_timer
(
sk
,
&
sk
->
sk_timer
,
jiffies
+
timeout
);
}
static
void
l2cap_sock_clear_timer
(
struct
sock
*
sk
)
{
BT_DBG
(
"sock %p state %d"
,
sk
,
sk
->
sk_state
);
sk_stop_timer
(
sk
,
&
sk
->
sk_timer
);
}
/* ---- L2CAP channels ---- */
static
struct
sock
*
__l2cap_get_chan_by_dcid
(
struct
l2cap_chan_list
*
l
,
u16
cid
)
{
...
...
@@ -743,11 +751,13 @@ static struct sock *__l2cap_get_sock_by_addr(__le16 psm, bdaddr_t *src)
/* Find socket with psm and source bdaddr.
* Returns closest match.
*/
static
struct
sock
*
__
l2cap_get_sock_by_psm
(
int
state
,
__le16
psm
,
bdaddr_t
*
src
)
static
struct
sock
*
l2cap_get_sock_by_psm
(
int
state
,
__le16
psm
,
bdaddr_t
*
src
)
{
struct
sock
*
sk
=
NULL
,
*
sk1
=
NULL
;
struct
hlist_node
*
node
;
read_lock
(
&
l2cap_sk_list
.
lock
);
sk_for_each
(
sk
,
node
,
&
l2cap_sk_list
.
head
)
{
if
(
state
&&
sk
->
sk_state
!=
state
)
continue
;
...
...
@@ -762,20 +772,10 @@ static struct sock *__l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src
sk1
=
sk
;
}
}
return
node
?
sk
:
sk1
;
}
/* Find socket with given address (psm, src).
* Returns locked socket */
static
inline
struct
sock
*
l2cap_get_sock_by_psm
(
int
state
,
__le16
psm
,
bdaddr_t
*
src
)
{
struct
sock
*
s
;
read_lock
(
&
l2cap_sk_list
.
lock
);
s
=
__l2cap_get_sock_by_psm
(
state
,
psm
,
src
);
if
(
s
)
bh_lock_sock
(
s
);
read_unlock
(
&
l2cap_sk_list
.
lock
);
return
s
;
return
node
?
sk
:
sk1
;
}
static
void
l2cap_sock_destruct
(
struct
sock
*
sk
)
...
...
@@ -2926,6 +2926,8 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd
goto
sendresp
;
}
bh_lock_sock
(
parent
);
/* Check if the ACL is secure enough (if not SDP) */
if
(
psm
!=
cpu_to_le16
(
0x0001
)
&&
!
hci_conn_check_link_mode
(
conn
->
hcon
))
{
...
...
@@ -3078,6 +3080,14 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd
break
;
default:
/* don't delete l2cap channel if sk is owned by user */
if
(
sock_owned_by_user
(
sk
))
{
sk
->
sk_state
=
BT_DISCONN
;
l2cap_sock_clear_timer
(
sk
);
l2cap_sock_set_timer
(
sk
,
HZ
/
5
);
break
;
}
l2cap_chan_del
(
sk
,
ECONNREFUSED
);
break
;
}
...
...
@@ -3283,6 +3293,15 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd
sk
->
sk_shutdown
=
SHUTDOWN_MASK
;
/* don't delete l2cap channel if sk is owned by user */
if
(
sock_owned_by_user
(
sk
))
{
sk
->
sk_state
=
BT_DISCONN
;
l2cap_sock_clear_timer
(
sk
);
l2cap_sock_set_timer
(
sk
,
HZ
/
5
);
bh_unlock_sock
(
sk
);
return
0
;
}
l2cap_chan_del
(
sk
,
ECONNRESET
);
bh_unlock_sock
(
sk
);
...
...
@@ -3305,6 +3324,15 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd
if
(
!
sk
)
return
0
;
/* don't delete l2cap channel if sk is owned by user */
if
(
sock_owned_by_user
(
sk
))
{
sk
->
sk_state
=
BT_DISCONN
;
l2cap_sock_clear_timer
(
sk
);
l2cap_sock_set_timer
(
sk
,
HZ
/
5
);
bh_unlock_sock
(
sk
);
return
0
;
}
l2cap_chan_del
(
sk
,
0
);
bh_unlock_sock
(
sk
);
...
...
@@ -4134,12 +4162,11 @@ static inline void l2cap_data_channel_rrframe(struct sock *sk, u16 rx_control)
__mod_retrans_timer
();
pi
->
conn_state
&=
~
L2CAP_CONN_REMOTE_BUSY
;
if
(
pi
->
conn_state
&
L2CAP_CONN_SREJ_SENT
)
{
if
(
pi
->
conn_state
&
L2CAP_CONN_SREJ_SENT
)
l2cap_send_ack
(
pi
);
}
else
{
else
l2cap_ertm_send
(
sk
);
}
}
}
static
inline
void
l2cap_data_channel_rejframe
(
struct
sock
*
sk
,
u16
rx_control
)
...
...
@@ -4430,6 +4457,8 @@ static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, str
if
(
!
sk
)
goto
drop
;
bh_lock_sock
(
sk
);
BT_DBG
(
"sk %p, len %d"
,
sk
,
skb
->
len
);
if
(
sk
->
sk_state
!=
BT_BOUND
&&
sk
->
sk_state
!=
BT_CONNECTED
)
...
...
@@ -4841,8 +4870,10 @@ static int __init l2cap_init(void)
return
err
;
_busy_wq
=
create_singlethread_workqueue
(
"l2cap"
);
if
(
!
_busy_wq
)
goto
error
;
if
(
!
_busy_wq
)
{
proto_unregister
(
&
l2cap_proto
);
return
-
ENOMEM
;
}
err
=
bt_sock_register
(
BTPROTO_L2CAP
,
&
l2cap_sock_family_ops
);
if
(
err
<
0
)
{
...
...
@@ -4870,6 +4901,7 @@ static int __init l2cap_init(void)
return
0
;
error:
destroy_workqueue
(
_busy_wq
);
proto_unregister
(
&
l2cap_proto
);
return
err
;
}
...
...
net/bluetooth/rfcomm/core.c
浏览文件 @
c30ae138
...
...
@@ -41,7 +41,7 @@
#include <linux/slab.h>
#include <net/sock.h>
#include <
asm
/uaccess.h>
#include <
linux
/uaccess.h>
#include <asm/unaligned.h>
#include <net/bluetooth/bluetooth.h>
...
...
@@ -51,10 +51,10 @@
#define VERSION "1.11"
static
int
disable_cfc
=
0
;
static
int
disable_cfc
;
static
int
l2cap_ertm
;
static
int
channel_mtu
=
-
1
;
static
unsigned
int
l2cap_mtu
=
RFCOMM_MAX_L2CAP_MTU
;
static
int
l2cap_ertm
=
0
;
static
struct
task_struct
*
rfcomm_thread
;
...
...
@@ -1901,7 +1901,7 @@ static inline void rfcomm_check_connection(struct rfcomm_session *s)
BT_DBG
(
"%p state %ld"
,
s
,
s
->
state
);
switch
(
sk
->
sk_state
)
{
switch
(
sk
->
sk_state
)
{
case
BT_CONNECTED
:
s
->
state
=
BT_CONNECT
;
...
...
net/bluetooth/rfcomm/sock.c
浏览文件 @
c30ae138
...
...
@@ -45,7 +45,7 @@
#include <net/sock.h>
#include <asm/system.h>
#include <
asm
/uaccess.h>
#include <
linux
/uaccess.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
...
...
@@ -140,11 +140,13 @@ static struct sock *__rfcomm_get_sock_by_addr(u8 channel, bdaddr_t *src)
/* Find socket with channel and source bdaddr.
* Returns closest match.
*/
static
struct
sock
*
__
rfcomm_get_sock_by_channel
(
int
state
,
u8
channel
,
bdaddr_t
*
src
)
static
struct
sock
*
rfcomm_get_sock_by_channel
(
int
state
,
u8
channel
,
bdaddr_t
*
src
)
{
struct
sock
*
sk
=
NULL
,
*
sk1
=
NULL
;
struct
hlist_node
*
node
;
read_lock
(
&
rfcomm_sk_list
.
lock
);
sk_for_each
(
sk
,
node
,
&
rfcomm_sk_list
.
head
)
{
if
(
state
&&
sk
->
sk_state
!=
state
)
continue
;
...
...
@@ -159,19 +161,10 @@ static struct sock *__rfcomm_get_sock_by_channel(int state, u8 channel, bdaddr_t
sk1
=
sk
;
}
}
return
node
?
sk
:
sk1
;
}
/* Find socket with given address (channel, src).
* Returns locked socket */
static
inline
struct
sock
*
rfcomm_get_sock_by_channel
(
int
state
,
u8
channel
,
bdaddr_t
*
src
)
{
struct
sock
*
s
;
read_lock
(
&
rfcomm_sk_list
.
lock
);
s
=
__rfcomm_get_sock_by_channel
(
state
,
channel
,
src
);
if
(
s
)
bh_lock_sock
(
s
);
read_unlock
(
&
rfcomm_sk_list
.
lock
);
return
s
;
return
node
?
sk
:
sk1
;
}
static
void
rfcomm_sock_destruct
(
struct
sock
*
sk
)
...
...
@@ -895,7 +888,8 @@ static int rfcomm_sock_shutdown(struct socket *sock, int how)
BT_DBG
(
"sock %p, sk %p"
,
sock
,
sk
);
if
(
!
sk
)
return
0
;
if
(
!
sk
)
return
0
;
lock_sock
(
sk
);
if
(
!
sk
->
sk_shutdown
)
{
...
...
@@ -945,6 +939,8 @@ int rfcomm_connect_ind(struct rfcomm_session *s, u8 channel, struct rfcomm_dlc *
if
(
!
parent
)
return
0
;
bh_lock_sock
(
parent
);
/* Check for backlog size */
if
(
sk_acceptq_is_full
(
parent
))
{
BT_DBG
(
"backlog full %d"
,
parent
->
sk_ack_backlog
);
...
...
net/bluetooth/rfcomm/tty.c
浏览文件 @
c30ae138
...
...
@@ -431,7 +431,8 @@ static int rfcomm_release_dev(void __user *arg)
BT_DBG
(
"dev_id %d flags 0x%x"
,
req
.
dev_id
,
req
.
flags
);
if
(
!
(
dev
=
rfcomm_dev_get
(
req
.
dev_id
)))
dev
=
rfcomm_dev_get
(
req
.
dev_id
);
if
(
!
dev
)
return
-
ENODEV
;
if
(
dev
->
flags
!=
NOCAP_FLAGS
&&
!
capable
(
CAP_NET_ADMIN
))
{
...
...
@@ -470,7 +471,8 @@ static int rfcomm_get_dev_list(void __user *arg)
size
=
sizeof
(
*
dl
)
+
dev_num
*
sizeof
(
*
di
);
if
(
!
(
dl
=
kmalloc
(
size
,
GFP_KERNEL
)))
dl
=
kmalloc
(
size
,
GFP_KERNEL
);
if
(
!
dl
)
return
-
ENOMEM
;
di
=
dl
->
dev_info
;
...
...
@@ -513,7 +515,8 @@ static int rfcomm_get_dev_info(void __user *arg)
if
(
copy_from_user
(
&
di
,
arg
,
sizeof
(
di
)))
return
-
EFAULT
;
if
(
!
(
dev
=
rfcomm_dev_get
(
di
.
id
)))
dev
=
rfcomm_dev_get
(
di
.
id
);
if
(
!
dev
)
return
-
ENODEV
;
di
.
flags
=
dev
->
flags
;
...
...
@@ -561,7 +564,8 @@ static void rfcomm_dev_data_ready(struct rfcomm_dlc *dlc, struct sk_buff *skb)
return
;
}
if
(
!
(
tty
=
dev
->
tty
)
||
!
skb_queue_empty
(
&
dev
->
pending
))
{
tty
=
dev
->
tty
;
if
(
!
tty
||
!
skb_queue_empty
(
&
dev
->
pending
))
{
skb_queue_tail
(
&
dev
->
pending
,
skb
);
return
;
}
...
...
@@ -796,7 +800,8 @@ static int rfcomm_tty_write(struct tty_struct *tty, const unsigned char *buf, in
memcpy
(
skb_put
(
skb
,
size
),
buf
+
sent
,
size
);
if
((
err
=
rfcomm_dlc_send
(
dlc
,
skb
))
<
0
)
{
err
=
rfcomm_dlc_send
(
dlc
,
skb
);
if
(
err
<
0
)
{
kfree_skb
(
skb
);
break
;
}
...
...
@@ -892,7 +897,7 @@ static void rfcomm_tty_set_termios(struct tty_struct *tty, struct ktermios *old)
/* Parity on/off and when on, odd/even */
if
(((
old
->
c_cflag
&
PARENB
)
!=
(
new
->
c_cflag
&
PARENB
))
||
((
old
->
c_cflag
&
PARODD
)
!=
(
new
->
c_cflag
&
PARODD
))
)
{
((
old
->
c_cflag
&
PARODD
)
!=
(
new
->
c_cflag
&
PARODD
)))
{
changes
|=
RFCOMM_RPN_PM_PARITY
;
BT_DBG
(
"Parity change detected."
);
}
...
...
@@ -937,11 +942,10 @@ static void rfcomm_tty_set_termios(struct tty_struct *tty, struct ktermios *old)
/* POSIX does not support 1.5 stop bits and RFCOMM does not
* support 2 stop bits. So a request for 2 stop bits gets
* translated to 1.5 stop bits */
if
(
new
->
c_cflag
&
CSTOPB
)
{
if
(
new
->
c_cflag
&
CSTOPB
)
stop_bits
=
RFCOMM_RPN_STOP_15
;
}
else
{
else
stop_bits
=
RFCOMM_RPN_STOP_1
;
}
/* Handle number of data bits [5-8] */
if
((
old
->
c_cflag
&
CSIZE
)
!=
(
new
->
c_cflag
&
CSIZE
))
...
...
net/bluetooth/sco.c
浏览文件 @
c30ae138
...
...
@@ -44,7 +44,7 @@
#include <net/sock.h>
#include <asm/system.h>
#include <
asm
/uaccess.h>
#include <
linux
/uaccess.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
...
...
@@ -52,7 +52,7 @@
#define VERSION "0.6"
static
int
disable_esco
=
0
;
static
int
disable_esco
;
static
const
struct
proto_ops
sco_sock_ops
;
...
...
@@ -138,16 +138,17 @@ static inline struct sock *sco_chan_get(struct sco_conn *conn)
static
int
sco_conn_del
(
struct
hci_conn
*
hcon
,
int
err
)
{
struct
sco_conn
*
conn
;
struct
sco_conn
*
conn
=
hcon
->
sco_data
;
struct
sock
*
sk
;
if
(
!
(
conn
=
hcon
->
sco_data
)
)
if
(
!
conn
)
return
0
;
BT_DBG
(
"hcon %p conn %p, err %d"
,
hcon
,
conn
,
err
);
/* Kill socket */
if
((
sk
=
sco_chan_get
(
conn
)))
{
sk
=
sco_chan_get
(
conn
);
if
(
sk
)
{
bh_lock_sock
(
sk
);
sco_sock_clear_timer
(
sk
);
sco_chan_del
(
sk
,
err
);
...
...
@@ -185,7 +186,8 @@ static int sco_connect(struct sock *sk)
BT_DBG
(
"%s -> %s"
,
batostr
(
src
),
batostr
(
dst
));
if
(
!
(
hdev
=
hci_get_route
(
dst
,
src
)))
hdev
=
hci_get_route
(
dst
,
src
);
if
(
!
hdev
)
return
-
EHOSTUNREACH
;
hci_dev_lock_bh
(
hdev
);
...
...
@@ -510,7 +512,8 @@ static int sco_sock_connect(struct socket *sock, struct sockaddr *addr, int alen
/* Set destination address and psm */
bacpy
(
&
bt_sk
(
sk
)
->
dst
,
&
sa
->
sco_bdaddr
);
if
((
err
=
sco_connect
(
sk
)))
err
=
sco_connect
(
sk
);
if
(
err
)
goto
done
;
err
=
bt_sock_wait_state
(
sk
,
BT_CONNECTED
,
...
...
@@ -828,13 +831,14 @@ static void sco_chan_del(struct sock *sk, int err)
static
void
sco_conn_ready
(
struct
sco_conn
*
conn
)
{
struct
sock
*
parent
,
*
sk
;
struct
sock
*
parent
;
struct
sock
*
sk
=
conn
->
sk
;
BT_DBG
(
"conn %p"
,
conn
);
sco_conn_lock
(
conn
);
if
(
(
sk
=
conn
->
sk
)
)
{
if
(
sk
)
{
sco_sock_clear_timer
(
sk
);
bh_lock_sock
(
sk
);
sk
->
sk_state
=
BT_CONNECTED
;
...
...
@@ -882,7 +886,7 @@ static int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type)
int
lm
=
0
;
if
(
type
!=
SCO_LINK
&&
type
!=
ESCO_LINK
)
return
0
;
return
-
EINVAL
;
BT_DBG
(
"hdev %s, bdaddr %s"
,
hdev
->
name
,
batostr
(
bdaddr
));
...
...
@@ -908,7 +912,7 @@ static int sco_connect_cfm(struct hci_conn *hcon, __u8 status)
BT_DBG
(
"hcon %p bdaddr %s status %d"
,
hcon
,
batostr
(
&
hcon
->
dst
),
status
);
if
(
hcon
->
type
!=
SCO_LINK
&&
hcon
->
type
!=
ESCO_LINK
)
return
0
;
return
-
EINVAL
;
if
(
!
status
)
{
struct
sco_conn
*
conn
;
...
...
@@ -927,7 +931,7 @@ static int sco_disconn_cfm(struct hci_conn *hcon, __u8 reason)
BT_DBG
(
"hcon %p reason %d"
,
hcon
,
reason
);
if
(
hcon
->
type
!=
SCO_LINK
&&
hcon
->
type
!=
ESCO_LINK
)
return
0
;
return
-
EINVAL
;
sco_conn_del
(
hcon
,
bt_err
(
reason
));
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录