Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xiphi1978
linux
提交
50b65cc6
L
linux
项目概览
xiphi1978
/
linux
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
L
linux
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
50b65cc6
编写于
7月 11, 2007
作者:
D
David S. Miller
浏览文件
操作
浏览文件
下载
差异文件
Merge master.kernel.org:/pub/scm/linux/kernel/git/holtmann/bluetooth-2.6
上级
29578624
5b7f9909
变更
10
隐藏空白更改
内联
并排
Showing
10 changed file
with
195 addition
and
142 deletion
+195
-142
drivers/bluetooth/hci_usb.c
drivers/bluetooth/hci_usb.c
+2
-86
drivers/bluetooth/hci_usb.h
drivers/bluetooth/hci_usb.h
+2
-3
drivers/bluetooth/hci_vhci.c
drivers/bluetooth/hci_vhci.c
+0
-6
include/net/bluetooth/hci.h
include/net/bluetooth/hci.h
+16
-2
include/net/bluetooth/hci_core.h
include/net/bluetooth/hci_core.h
+5
-0
include/net/bluetooth/rfcomm.h
include/net/bluetooth/rfcomm.h
+1
-0
net/bluetooth/hci_conn.c
net/bluetooth/hci_conn.c
+25
-26
net/bluetooth/hci_core.c
net/bluetooth/hci_core.c
+97
-3
net/bluetooth/hci_event.c
net/bluetooth/hci_event.c
+21
-8
net/bluetooth/rfcomm/tty.c
net/bluetooth/rfcomm/tty.c
+26
-8
未找到文件。
drivers/bluetooth/hci_usb.c
浏览文件 @
50b65cc6
...
...
@@ -199,7 +199,6 @@ static void hci_usb_tx_complete(struct urb *urb);
#define __pending_q(husb, type) (&husb->pending_q[type-1])
#define __completed_q(husb, type) (&husb->completed_q[type-1])
#define __transmit_q(husb, type) (&husb->transmit_q[type-1])
#define __reassembly(husb, type) (husb->reassembly[type-1])
static
inline
struct
_urb
*
__get_completed
(
struct
hci_usb
*
husb
,
int
type
)
{
...
...
@@ -429,12 +428,6 @@ static void hci_usb_unlink_urbs(struct hci_usb *husb)
kfree
(
urb
->
transfer_buffer
);
_urb_free
(
_urb
);
}
/* Release reassembly buffers */
if
(
husb
->
reassembly
[
i
])
{
kfree_skb
(
husb
->
reassembly
[
i
]);
husb
->
reassembly
[
i
]
=
NULL
;
}
}
}
...
...
@@ -671,83 +664,6 @@ static int hci_usb_send_frame(struct sk_buff *skb)
return
0
;
}
static
inline
int
__recv_frame
(
struct
hci_usb
*
husb
,
int
type
,
void
*
data
,
int
count
)
{
BT_DBG
(
"%s type %d data %p count %d"
,
husb
->
hdev
->
name
,
type
,
data
,
count
);
husb
->
hdev
->
stat
.
byte_rx
+=
count
;
while
(
count
)
{
struct
sk_buff
*
skb
=
__reassembly
(
husb
,
type
);
struct
{
int
expect
;
}
*
scb
;
int
len
=
0
;
if
(
!
skb
)
{
/* Start of the frame */
switch
(
type
)
{
case
HCI_EVENT_PKT
:
if
(
count
>=
HCI_EVENT_HDR_SIZE
)
{
struct
hci_event_hdr
*
h
=
data
;
len
=
HCI_EVENT_HDR_SIZE
+
h
->
plen
;
}
else
return
-
EILSEQ
;
break
;
case
HCI_ACLDATA_PKT
:
if
(
count
>=
HCI_ACL_HDR_SIZE
)
{
struct
hci_acl_hdr
*
h
=
data
;
len
=
HCI_ACL_HDR_SIZE
+
__le16_to_cpu
(
h
->
dlen
);
}
else
return
-
EILSEQ
;
break
;
#ifdef CONFIG_BT_HCIUSB_SCO
case
HCI_SCODATA_PKT
:
if
(
count
>=
HCI_SCO_HDR_SIZE
)
{
struct
hci_sco_hdr
*
h
=
data
;
len
=
HCI_SCO_HDR_SIZE
+
h
->
dlen
;
}
else
return
-
EILSEQ
;
break
;
#endif
}
BT_DBG
(
"new packet len %d"
,
len
);
skb
=
bt_skb_alloc
(
len
,
GFP_ATOMIC
);
if
(
!
skb
)
{
BT_ERR
(
"%s no memory for the packet"
,
husb
->
hdev
->
name
);
return
-
ENOMEM
;
}
skb
->
dev
=
(
void
*
)
husb
->
hdev
;
bt_cb
(
skb
)
->
pkt_type
=
type
;
__reassembly
(
husb
,
type
)
=
skb
;
scb
=
(
void
*
)
skb
->
cb
;
scb
->
expect
=
len
;
}
else
{
/* Continuation */
scb
=
(
void
*
)
skb
->
cb
;
len
=
scb
->
expect
;
}
len
=
min
(
len
,
count
);
memcpy
(
skb_put
(
skb
,
len
),
data
,
len
);
scb
->
expect
-=
len
;
if
(
!
scb
->
expect
)
{
/* Complete frame */
__reassembly
(
husb
,
type
)
=
NULL
;
bt_cb
(
skb
)
->
pkt_type
=
type
;
hci_recv_frame
(
skb
);
}
count
-=
len
;
data
+=
len
;
}
return
0
;
}
static
void
hci_usb_rx_complete
(
struct
urb
*
urb
)
{
struct
_urb
*
_urb
=
container_of
(
urb
,
struct
_urb
,
urb
);
...
...
@@ -776,7 +692,7 @@ static void hci_usb_rx_complete(struct urb *urb)
urb
->
iso_frame_desc
[
i
].
actual_length
);
if
(
!
urb
->
iso_frame_desc
[
i
].
status
)
__recv_frame
(
husb
,
_urb
->
type
,
hci_recv_fragment
(
husb
->
hdev
,
_urb
->
type
,
urb
->
transfer_buffer
+
urb
->
iso_frame_desc
[
i
].
offset
,
urb
->
iso_frame_desc
[
i
].
actual_length
);
}
...
...
@@ -784,7 +700,7 @@ static void hci_usb_rx_complete(struct urb *urb)
;
#endif
}
else
{
err
=
__recv_frame
(
husb
,
_urb
->
type
,
urb
->
transfer_buffer
,
count
);
err
=
hci_recv_fragment
(
husb
->
hdev
,
_urb
->
type
,
urb
->
transfer_buffer
,
count
);
if
(
err
<
0
)
{
BT_ERR
(
"%s corrupted packet: type %d count %d"
,
husb
->
hdev
->
name
,
_urb
->
type
,
count
);
...
...
drivers/bluetooth/hci_usb.h
浏览文件 @
50b65cc6
...
...
@@ -102,9 +102,9 @@ struct hci_usb {
struct
hci_dev
*
hdev
;
unsigned
long
state
;
struct
usb_device
*
udev
;
struct
usb_host_endpoint
*
bulk_in_ep
;
struct
usb_host_endpoint
*
bulk_out_ep
;
struct
usb_host_endpoint
*
intr_in_ep
;
...
...
@@ -116,7 +116,6 @@ struct hci_usb {
__u8
ctrl_req
;
struct
sk_buff_head
transmit_q
[
4
];
struct
sk_buff
*
reassembly
[
4
];
/* Reassembly buffers */
rwlock_t
completion_lock
;
...
...
drivers/bluetooth/hci_vhci.c
浏览文件 @
50b65cc6
...
...
@@ -180,11 +180,6 @@ static inline ssize_t vhci_put_user(struct vhci_data *data,
return
total
;
}
static
loff_t
vhci_llseek
(
struct
file
*
file
,
loff_t
offset
,
int
origin
)
{
return
-
ESPIPE
;
}
static
ssize_t
vhci_read
(
struct
file
*
file
,
char
__user
*
buf
,
size_t
count
,
loff_t
*
pos
)
{
...
...
@@ -334,7 +329,6 @@ static int vhci_fasync(int fd, struct file *file, int on)
static
const
struct
file_operations
vhci_fops
=
{
.
owner
=
THIS_MODULE
,
.
llseek
=
vhci_llseek
,
.
read
=
vhci_read
,
.
write
=
vhci_write
,
.
poll
=
vhci_poll
,
...
...
include/net/bluetooth/hci.h
浏览文件 @
50b65cc6
...
...
@@ -107,14 +107,14 @@ enum {
#define HCI_IDLE_TIMEOUT (6000)
/* 6 seconds */
#define HCI_INIT_TIMEOUT (10000)
/* 10 seconds */
/* HCI
Packet
types */
/* HCI
data
types */
#define HCI_COMMAND_PKT 0x01
#define HCI_ACLDATA_PKT 0x02
#define HCI_SCODATA_PKT 0x03
#define HCI_EVENT_PKT 0x04
#define HCI_VENDOR_PKT 0xff
/* HCI
P
acket types */
/* HCI
p
acket types */
#define HCI_DM1 0x0008
#define HCI_DM3 0x0400
#define HCI_DM5 0x4000
...
...
@@ -129,6 +129,14 @@ enum {
#define SCO_PTYPE_MASK (HCI_HV1 | HCI_HV2 | HCI_HV3)
#define ACL_PTYPE_MASK (~SCO_PTYPE_MASK)
/* eSCO packet types */
#define ESCO_HV1 0x0001
#define ESCO_HV2 0x0002
#define ESCO_HV3 0x0004
#define ESCO_EV3 0x0008
#define ESCO_EV4 0x0010
#define ESCO_EV5 0x0020
/* ACL flags */
#define ACL_CONT 0x01
#define ACL_START 0x02
...
...
@@ -138,6 +146,7 @@ enum {
/* Baseband links */
#define SCO_LINK 0x00
#define ACL_LINK 0x01
#define ESCO_LINK 0x02
/* LMP features */
#define LMP_3SLOT 0x01
...
...
@@ -162,6 +171,11 @@ enum {
#define LMP_PSCHEME 0x02
#define LMP_PCONTROL 0x04
#define LMP_ESCO 0x80
#define LMP_EV4 0x01
#define LMP_EV5 0x02
#define LMP_SNIFF_SUBR 0x02
/* Connection modes */
...
...
include/net/bluetooth/hci_core.h
浏览文件 @
50b65cc6
...
...
@@ -78,6 +78,7 @@ struct hci_dev {
__u16
voice_setting
;
__u16
pkt_type
;
__u16
esco_type
;
__u16
link_policy
;
__u16
link_mode
;
...
...
@@ -109,6 +110,7 @@ struct hci_dev {
struct
sk_buff_head
cmd_q
;
struct
sk_buff
*
sent_cmd
;
struct
sk_buff
*
reassembly
[
3
];
struct
semaphore
req_lock
;
wait_queue_head_t
req_wait_q
;
...
...
@@ -437,6 +439,8 @@ static inline int hci_recv_frame(struct sk_buff *skb)
return
0
;
}
int
hci_recv_fragment
(
struct
hci_dev
*
hdev
,
int
type
,
void
*
data
,
int
count
);
int
hci_register_sysfs
(
struct
hci_dev
*
hdev
);
void
hci_unregister_sysfs
(
struct
hci_dev
*
hdev
);
void
hci_conn_add_sysfs
(
struct
hci_conn
*
conn
);
...
...
@@ -449,6 +453,7 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
#define lmp_encrypt_capable(dev) ((dev)->features[0] & LMP_ENCRYPT)
#define lmp_sniff_capable(dev) ((dev)->features[0] & LMP_SNIFF)
#define lmp_sniffsubr_capable(dev) ((dev)->features[5] & LMP_SNIFF_SUBR)
#define lmp_esco_capable(dev) ((dev)->features[3] & LMP_ESCO)
/* ----- HCI protocols ----- */
struct
hci_proto
{
...
...
include/net/bluetooth/rfcomm.h
浏览文件 @
50b65cc6
...
...
@@ -323,6 +323,7 @@ int rfcomm_connect_ind(struct rfcomm_session *s, u8 channel, struct rfcomm_dlc
#define RFCOMM_RELEASE_ONHUP 1
#define RFCOMM_HANGUP_NOW 2
#define RFCOMM_TTY_ATTACHED 3
#define RFCOMM_TTY_RELEASED 4
struct
rfcomm_dev_req
{
s16
dev_id
;
...
...
net/bluetooth/hci_conn.c
浏览文件 @
50b65cc6
...
...
@@ -123,8 +123,8 @@ void hci_add_sco(struct hci_conn *conn, __u16 handle)
conn
->
state
=
BT_CONNECT
;
conn
->
out
=
1
;
cp
.
pkt_type
=
cpu_to_le16
(
hdev
->
pkt_type
&
SCO_PTYPE_MASK
);
cp
.
handle
=
cpu_to_le16
(
handle
);
cp
.
pkt_type
=
cpu_to_le16
(
hdev
->
pkt_type
&
SCO_PTYPE_MASK
);
hci_send_cmd
(
hdev
,
OGF_LINK_CTL
,
OCF_ADD_SCO
,
sizeof
(
cp
),
&
cp
);
}
...
...
@@ -220,19 +220,19 @@ int hci_conn_del(struct hci_conn *conn)
del_timer
(
&
conn
->
disc_timer
);
if
(
conn
->
type
==
SCO_LINK
)
{
struct
hci_conn
*
acl
=
conn
->
link
;
if
(
acl
)
{
acl
->
link
=
NULL
;
hci_conn_put
(
acl
);
}
}
else
{
if
(
conn
->
type
==
ACL_LINK
)
{
struct
hci_conn
*
sco
=
conn
->
link
;
if
(
sco
)
sco
->
link
=
NULL
;
/* Unacked frames */
hdev
->
acl_cnt
+=
conn
->
sent
;
}
else
{
struct
hci_conn
*
acl
=
conn
->
link
;
if
(
acl
)
{
acl
->
link
=
NULL
;
hci_conn_put
(
acl
);
}
}
tasklet_disable
(
&
hdev
->
tx_task
);
...
...
@@ -297,9 +297,10 @@ EXPORT_SYMBOL(hci_get_route);
/* Create SCO or ACL connection.
* Device _must_ be locked */
struct
hci_conn
*
hci_connect
(
struct
hci_dev
*
hdev
,
int
type
,
bdaddr_t
*
dst
)
struct
hci_conn
*
hci_connect
(
struct
hci_dev
*
hdev
,
int
type
,
bdaddr_t
*
dst
)
{
struct
hci_conn
*
acl
;
struct
hci_conn
*
sco
;
BT_DBG
(
"%s dst %s"
,
hdev
->
name
,
batostr
(
dst
));
...
...
@@ -313,28 +314,26 @@ struct hci_conn * hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst)
if
(
acl
->
state
==
BT_OPEN
||
acl
->
state
==
BT_CLOSED
)
hci_acl_connect
(
acl
);
if
(
type
==
SCO_LINK
)
{
struct
hci_conn
*
sco
;
if
(
type
==
ACL_LINK
)
return
acl
;
if
(
!
(
sco
=
hci_conn_hash_lookup_ba
(
hdev
,
SCO_LINK
,
dst
)))
{
if
(
!
(
sco
=
hci_conn_add
(
hdev
,
SCO_LINK
,
dst
)))
{
hci_conn_put
(
acl
);
return
NULL
;
}
if
(
!
(
sco
=
hci_conn_hash_lookup_ba
(
hdev
,
type
,
dst
)))
{
if
(
!
(
sco
=
hci_conn_add
(
hdev
,
type
,
dst
)))
{
hci_conn_put
(
acl
);
return
NULL
;
}
acl
->
link
=
sco
;
sco
->
link
=
acl
;
}
hci_conn_hold
(
sco
);
acl
->
link
=
sco
;
sco
->
link
=
acl
;
if
(
acl
->
state
==
BT_CONNECTED
&&
(
sco
->
state
==
BT_OPEN
||
sco
->
state
==
BT_CLOSED
))
hci_add_sco
(
sco
,
acl
->
handle
);
hci_conn_hold
(
sco
);
return
sco
;
}
else
{
return
acl
;
}
if
(
acl
->
state
==
BT_CONNECTED
&&
(
sco
->
state
==
BT_OPEN
||
sco
->
state
==
BT_CLOSED
))
hci_add_sco
(
sco
,
acl
->
handle
);
return
sco
;
}
EXPORT_SYMBOL
(
hci_connect
);
...
...
net/bluetooth/hci_core.c
浏览文件 @
50b65cc6
...
...
@@ -826,7 +826,7 @@ EXPORT_SYMBOL(hci_free_dev);
int
hci_register_dev
(
struct
hci_dev
*
hdev
)
{
struct
list_head
*
head
=
&
hci_dev_list
,
*
p
;
int
id
=
0
;
int
i
,
i
d
=
0
;
BT_DBG
(
"%p name %s type %d owner %p"
,
hdev
,
hdev
->
name
,
hdev
->
type
,
hdev
->
owner
);
...
...
@@ -851,6 +851,7 @@ int hci_register_dev(struct hci_dev *hdev)
hdev
->
flags
=
0
;
hdev
->
pkt_type
=
(
HCI_DM1
|
HCI_DH1
|
HCI_HV1
);
hdev
->
esco_type
=
(
ESCO_HV1
);
hdev
->
link_mode
=
(
HCI_LM_ACCEPT
);
hdev
->
idle_timeout
=
0
;
...
...
@@ -865,6 +866,9 @@ int hci_register_dev(struct hci_dev *hdev)
skb_queue_head_init
(
&
hdev
->
cmd_q
);
skb_queue_head_init
(
&
hdev
->
raw_q
);
for
(
i
=
0
;
i
<
3
;
i
++
)
hdev
->
reassembly
[
i
]
=
NULL
;
init_waitqueue_head
(
&
hdev
->
req_wait_q
);
init_MUTEX
(
&
hdev
->
req_lock
);
...
...
@@ -889,6 +893,8 @@ EXPORT_SYMBOL(hci_register_dev);
/* Unregister HCI device */
int
hci_unregister_dev
(
struct
hci_dev
*
hdev
)
{
int
i
;
BT_DBG
(
"%p name %s type %d"
,
hdev
,
hdev
->
name
,
hdev
->
type
);
hci_unregister_sysfs
(
hdev
);
...
...
@@ -899,9 +905,13 @@ int hci_unregister_dev(struct hci_dev *hdev)
hci_dev_do_close
(
hdev
);
for
(
i
=
0
;
i
<
3
;
i
++
)
kfree_skb
(
hdev
->
reassembly
[
i
]);
hci_notify
(
hdev
,
HCI_DEV_UNREG
);
__hci_dev_put
(
hdev
);
return
0
;
}
EXPORT_SYMBOL
(
hci_unregister_dev
);
...
...
@@ -922,6 +932,90 @@ int hci_resume_dev(struct hci_dev *hdev)
}
EXPORT_SYMBOL
(
hci_resume_dev
);
/* Receive packet type fragment */
#define __reassembly(hdev, type) ((hdev)->reassembly[(type) - 2])
int
hci_recv_fragment
(
struct
hci_dev
*
hdev
,
int
type
,
void
*
data
,
int
count
)
{
if
(
type
<
HCI_ACLDATA_PKT
||
type
>
HCI_EVENT_PKT
)
return
-
EILSEQ
;
while
(
count
)
{
struct
sk_buff
*
skb
=
__reassembly
(
hdev
,
type
);
struct
{
int
expect
;
}
*
scb
;
int
len
=
0
;
if
(
!
skb
)
{
/* Start of the frame */
switch
(
type
)
{
case
HCI_EVENT_PKT
:
if
(
count
>=
HCI_EVENT_HDR_SIZE
)
{
struct
hci_event_hdr
*
h
=
data
;
len
=
HCI_EVENT_HDR_SIZE
+
h
->
plen
;
}
else
return
-
EILSEQ
;
break
;
case
HCI_ACLDATA_PKT
:
if
(
count
>=
HCI_ACL_HDR_SIZE
)
{
struct
hci_acl_hdr
*
h
=
data
;
len
=
HCI_ACL_HDR_SIZE
+
__le16_to_cpu
(
h
->
dlen
);
}
else
return
-
EILSEQ
;
break
;
case
HCI_SCODATA_PKT
:
if
(
count
>=
HCI_SCO_HDR_SIZE
)
{
struct
hci_sco_hdr
*
h
=
data
;
len
=
HCI_SCO_HDR_SIZE
+
h
->
dlen
;
}
else
return
-
EILSEQ
;
break
;
}
skb
=
bt_skb_alloc
(
len
,
GFP_ATOMIC
);
if
(
!
skb
)
{
BT_ERR
(
"%s no memory for packet"
,
hdev
->
name
);
return
-
ENOMEM
;
}
skb
->
dev
=
(
void
*
)
hdev
;
bt_cb
(
skb
)
->
pkt_type
=
type
;
__reassembly
(
hdev
,
type
)
=
skb
;
scb
=
(
void
*
)
skb
->
cb
;
scb
->
expect
=
len
;
}
else
{
/* Continuation */
scb
=
(
void
*
)
skb
->
cb
;
len
=
scb
->
expect
;
}
len
=
min
(
len
,
count
);
memcpy
(
skb_put
(
skb
,
len
),
data
,
len
);
scb
->
expect
-=
len
;
if
(
scb
->
expect
==
0
)
{
/* Complete frame */
__reassembly
(
hdev
,
type
)
=
NULL
;
bt_cb
(
skb
)
->
pkt_type
=
type
;
hci_recv_frame
(
skb
);
}
count
-=
len
;
data
+=
len
;
}
return
0
;
}
EXPORT_SYMBOL
(
hci_recv_fragment
);
/* ---- Interface to upper protocols ---- */
/* Register/Unregister protocols.
...
...
@@ -1029,7 +1123,7 @@ int hci_send_cmd(struct hci_dev *hdev, __u16 ogf, __u16 ocf, __u32 plen, void *p
skb
=
bt_skb_alloc
(
len
,
GFP_ATOMIC
);
if
(
!
skb
)
{
BT_ERR
(
"%s
Can't allocate memory for HCI
command"
,
hdev
->
name
);
BT_ERR
(
"%s
no memory for
command"
,
hdev
->
name
);
return
-
ENOMEM
;
}
...
...
@@ -1161,7 +1255,7 @@ EXPORT_SYMBOL(hci_send_sco);
static
inline
struct
hci_conn
*
hci_low_sent
(
struct
hci_dev
*
hdev
,
__u8
type
,
int
*
quote
)
{
struct
hci_conn_hash
*
h
=
&
hdev
->
conn_hash
;
struct
hci_conn
*
conn
=
NULL
;
struct
hci_conn
*
conn
=
NULL
;
int
num
=
0
,
min
=
~
0
;
struct
list_head
*
p
;
...
...
net/bluetooth/hci_event.c
浏览文件 @
50b65cc6
...
...
@@ -350,11 +350,24 @@ static void hci_cc_info_param(struct hci_dev *hdev, __u16 ocf, struct sk_buff *s
if
(
hdev
->
features
[
0
]
&
LMP_5SLOT
)
hdev
->
pkt_type
|=
(
HCI_DM5
|
HCI_DH5
);
if
(
hdev
->
features
[
1
]
&
LMP_HV2
)
hdev
->
pkt_type
|=
(
HCI_HV2
);
if
(
hdev
->
features
[
1
]
&
LMP_HV2
)
{
hdev
->
pkt_type
|=
(
HCI_HV2
);
hdev
->
esco_type
|=
(
ESCO_HV2
);
}
if
(
hdev
->
features
[
1
]
&
LMP_HV3
)
{
hdev
->
pkt_type
|=
(
HCI_HV3
);
hdev
->
esco_type
|=
(
ESCO_HV3
);
}
if
(
hdev
->
features
[
1
]
&
LMP_HV3
)
hdev
->
pkt_type
|=
(
HCI_HV3
);
if
(
hdev
->
features
[
3
]
&
LMP_ESCO
)
hdev
->
esco_type
|=
(
ESCO_EV3
);
if
(
hdev
->
features
[
4
]
&
LMP_EV4
)
hdev
->
esco_type
|=
(
ESCO_EV4
);
if
(
hdev
->
features
[
4
]
&
LMP_EV5
)
hdev
->
esco_type
|=
(
ESCO_EV5
);
BT_DBG
(
"%s: features 0x%x 0x%x 0x%x"
,
hdev
->
name
,
lf
->
features
[
0
],
lf
->
features
[
1
],
lf
->
features
[
2
]);
...
...
@@ -881,12 +894,12 @@ static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *s
if
(
conn
)
{
conn
->
sent
-=
count
;
if
(
conn
->
type
==
SCO_LINK
)
{
if
((
hdev
->
sco_cnt
+=
count
)
>
hdev
->
sco_pkts
)
hdev
->
sco_cnt
=
hdev
->
sco_pkts
;
}
else
{
if
(
conn
->
type
==
ACL_LINK
)
{
if
((
hdev
->
acl_cnt
+=
count
)
>
hdev
->
acl_pkts
)
hdev
->
acl_cnt
=
hdev
->
acl_pkts
;
}
else
{
if
((
hdev
->
sco_cnt
+=
count
)
>
hdev
->
sco_pkts
)
hdev
->
sco_cnt
=
hdev
->
sco_pkts
;
}
}
}
...
...
net/bluetooth/rfcomm/tty.c
浏览文件 @
50b65cc6
...
...
@@ -95,6 +95,10 @@ static void rfcomm_dev_destruct(struct rfcomm_dev *dev)
BT_DBG
(
"dev %p dlc %p"
,
dev
,
dlc
);
write_lock_bh
(
&
rfcomm_dev_lock
);
list_del_init
(
&
dev
->
list
);
write_unlock_bh
(
&
rfcomm_dev_lock
);
rfcomm_dlc_lock
(
dlc
);
/* Detach DLC if it's owned by this dev */
if
(
dlc
->
owner
==
dev
)
...
...
@@ -156,8 +160,13 @@ static inline struct rfcomm_dev *rfcomm_dev_get(int id)
read_lock
(
&
rfcomm_dev_lock
);
dev
=
__rfcomm_dev_get
(
id
);
if
(
dev
)
rfcomm_dev_hold
(
dev
);
if
(
dev
)
{
if
(
test_bit
(
RFCOMM_TTY_RELEASED
,
&
dev
->
flags
))
dev
=
NULL
;
else
rfcomm_dev_hold
(
dev
);
}
read_unlock
(
&
rfcomm_dev_lock
);
...
...
@@ -265,6 +274,12 @@ static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc)
dev
->
tty_dev
=
tty_register_device
(
rfcomm_tty_driver
,
dev
->
id
,
NULL
);
if
(
IS_ERR
(
dev
->
tty_dev
))
{
list_del
(
&
dev
->
list
);
kfree
(
dev
);
return
PTR_ERR
(
dev
->
tty_dev
);
}
return
dev
->
id
;
}
...
...
@@ -272,10 +287,7 @@ static void rfcomm_dev_del(struct rfcomm_dev *dev)
{
BT_DBG
(
"dev %p"
,
dev
);
write_lock_bh
(
&
rfcomm_dev_lock
);
list_del_init
(
&
dev
->
list
);
write_unlock_bh
(
&
rfcomm_dev_lock
);
set_bit
(
RFCOMM_TTY_RELEASED
,
&
dev
->
flags
);
rfcomm_dev_put
(
dev
);
}
...
...
@@ -329,7 +341,7 @@ static int rfcomm_create_dev(struct sock *sk, void __user *arg)
if
(
copy_from_user
(
&
req
,
arg
,
sizeof
(
req
)))
return
-
EFAULT
;
BT_DBG
(
"sk %p dev_id %
i
d flags 0x%x"
,
sk
,
req
.
dev_id
,
req
.
flags
);
BT_DBG
(
"sk %p dev_id %d flags 0x%x"
,
sk
,
req
.
dev_id
,
req
.
flags
);
if
(
req
.
flags
!=
NOCAP_FLAGS
&&
!
capable
(
CAP_NET_ADMIN
))
return
-
EPERM
;
...
...
@@ -370,7 +382,7 @@ static int rfcomm_release_dev(void __user *arg)
if
(
copy_from_user
(
&
req
,
arg
,
sizeof
(
req
)))
return
-
EFAULT
;
BT_DBG
(
"dev_id %
i
d flags 0x%x"
,
req
.
dev_id
,
req
.
flags
);
BT_DBG
(
"dev_id %d flags 0x%x"
,
req
.
dev_id
,
req
.
flags
);
if
(
!
(
dev
=
rfcomm_dev_get
(
req
.
dev_id
)))
return
-
ENODEV
;
...
...
@@ -383,6 +395,10 @@ static int rfcomm_release_dev(void __user *arg)
if
(
req
.
flags
&
(
1
<<
RFCOMM_HANGUP_NOW
))
rfcomm_dlc_close
(
dev
->
dlc
,
0
);
/* Shut down TTY synchronously before freeing rfcomm_dev */
if
(
dev
->
tty
)
tty_vhangup
(
dev
->
tty
);
rfcomm_dev_del
(
dev
);
rfcomm_dev_put
(
dev
);
return
0
;
...
...
@@ -415,6 +431,8 @@ static int rfcomm_get_dev_list(void __user *arg)
list_for_each
(
p
,
&
rfcomm_dev_list
)
{
struct
rfcomm_dev
*
dev
=
list_entry
(
p
,
struct
rfcomm_dev
,
list
);
if
(
test_bit
(
RFCOMM_TTY_RELEASED
,
&
dev
->
flags
))
continue
;
(
di
+
n
)
->
id
=
dev
->
id
;
(
di
+
n
)
->
flags
=
dev
->
flags
;
(
di
+
n
)
->
state
=
dev
->
dlc
->
state
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录