Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
a7fca0cc
cloud-kernel
项目概览
openanolis
/
cloud-kernel
12 个月 前同步成功
通知
152
Star
36
Fork
7
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
10
列表
看板
标记
里程碑
合并请求
2
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
cloud-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
10
Issue
10
列表
看板
标记
里程碑
合并请求
2
合并请求
2
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
a7fca0cc
编写于
12月 03, 2009
作者:
D
David S. Miller
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'master' of
git://git.kernel.org/pub/scm/linux/kernel/git/holtmann/bluetooth-next-2.6
上级
424eff97
2861453b
变更
14
隐藏空白更改
内联
并排
Showing
14 changed file
with
192 addition
and
116 deletion
+192
-116
drivers/bluetooth/btmrvl_debugfs.c
drivers/bluetooth/btmrvl_debugfs.c
+0
-1
drivers/bluetooth/btmrvl_drv.h
drivers/bluetooth/btmrvl_drv.h
+1
-0
drivers/bluetooth/btmrvl_main.c
drivers/bluetooth/btmrvl_main.c
+33
-22
drivers/bluetooth/btmrvl_sdio.c
drivers/bluetooth/btmrvl_sdio.c
+4
-0
drivers/bluetooth/hci_vhci.c
drivers/bluetooth/hci_vhci.c
+3
-17
include/net/bluetooth/hci_core.h
include/net/bluetooth/hci_core.h
+1
-38
include/net/bluetooth/l2cap.h
include/net/bluetooth/l2cap.h
+1
-1
net/bluetooth/bnep/core.c
net/bluetooth/bnep/core.c
+4
-1
net/bluetooth/hci_core.c
net/bluetooth/hci_core.c
+34
-5
net/bluetooth/hci_event.c
net/bluetooth/hci_event.c
+3
-3
net/bluetooth/hci_sock.c
net/bluetooth/hci_sock.c
+8
-3
net/bluetooth/hidp/core.c
net/bluetooth/hidp/core.c
+9
-0
net/bluetooth/l2cap.c
net/bluetooth/l2cap.c
+85
-25
net/bluetooth/rfcomm/core.c
net/bluetooth/rfcomm/core.c
+6
-0
未找到文件。
drivers/bluetooth/btmrvl_debugfs.c
浏览文件 @
a7fca0cc
...
...
@@ -29,7 +29,6 @@ struct btmrvl_debugfs_data {
struct
dentry
*
root_dir
,
*
config_dir
,
*
status_dir
;
/* config */
struct
dentry
*
drvdbg
;
struct
dentry
*
psmode
;
struct
dentry
*
pscmd
;
struct
dentry
*
hsmode
;
...
...
drivers/bluetooth/btmrvl_drv.h
浏览文件 @
a7fca0cc
...
...
@@ -131,6 +131,7 @@ void btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb);
int
btmrvl_process_event
(
struct
btmrvl_private
*
priv
,
struct
sk_buff
*
skb
);
int
btmrvl_send_module_cfg_cmd
(
struct
btmrvl_private
*
priv
,
int
subcmd
);
int
btmrvl_enable_ps
(
struct
btmrvl_private
*
priv
);
int
btmrvl_prepare_command
(
struct
btmrvl_private
*
priv
);
#ifdef CONFIG_DEBUG_FS
...
...
drivers/bluetooth/btmrvl_main.c
浏览文件 @
a7fca0cc
...
...
@@ -189,6 +189,38 @@ int btmrvl_send_module_cfg_cmd(struct btmrvl_private *priv, int subcmd)
}
EXPORT_SYMBOL_GPL
(
btmrvl_send_module_cfg_cmd
);
int
btmrvl_enable_ps
(
struct
btmrvl_private
*
priv
)
{
struct
sk_buff
*
skb
;
struct
btmrvl_cmd
*
cmd
;
skb
=
bt_skb_alloc
(
sizeof
(
*
cmd
),
GFP_ATOMIC
);
if
(
skb
==
NULL
)
{
BT_ERR
(
"No free skb"
);
return
-
ENOMEM
;
}
cmd
=
(
struct
btmrvl_cmd
*
)
skb_put
(
skb
,
sizeof
(
*
cmd
));
cmd
->
ocf_ogf
=
cpu_to_le16
(
hci_opcode_pack
(
OGF
,
BT_CMD_AUTO_SLEEP_MODE
));
cmd
->
length
=
1
;
if
(
priv
->
btmrvl_dev
.
psmode
)
cmd
->
data
[
0
]
=
BT_PS_ENABLE
;
else
cmd
->
data
[
0
]
=
BT_PS_DISABLE
;
bt_cb
(
skb
)
->
pkt_type
=
MRVL_VENDOR_PKT
;
skb
->
dev
=
(
void
*
)
priv
->
btmrvl_dev
.
hcidev
;
skb_queue_head
(
&
priv
->
adapter
->
tx_queue
,
skb
);
BT_DBG
(
"Queue PSMODE Command:%d"
,
cmd
->
data
[
0
]);
return
0
;
}
EXPORT_SYMBOL_GPL
(
btmrvl_enable_ps
);
static
int
btmrvl_enable_hs
(
struct
btmrvl_private
*
priv
)
{
struct
sk_buff
*
skb
;
...
...
@@ -258,28 +290,7 @@ int btmrvl_prepare_command(struct btmrvl_private *priv)
if
(
priv
->
btmrvl_dev
.
pscmd
)
{
priv
->
btmrvl_dev
.
pscmd
=
0
;
skb
=
bt_skb_alloc
(
sizeof
(
*
cmd
),
GFP_ATOMIC
);
if
(
skb
==
NULL
)
{
BT_ERR
(
"No free skb"
);
return
-
ENOMEM
;
}
cmd
=
(
struct
btmrvl_cmd
*
)
skb_put
(
skb
,
sizeof
(
*
cmd
));
cmd
->
ocf_ogf
=
cpu_to_le16
(
hci_opcode_pack
(
OGF
,
BT_CMD_AUTO_SLEEP_MODE
));
cmd
->
length
=
1
;
if
(
priv
->
btmrvl_dev
.
psmode
)
cmd
->
data
[
0
]
=
BT_PS_ENABLE
;
else
cmd
->
data
[
0
]
=
BT_PS_DISABLE
;
bt_cb
(
skb
)
->
pkt_type
=
MRVL_VENDOR_PKT
;
skb
->
dev
=
(
void
*
)
priv
->
btmrvl_dev
.
hcidev
;
skb_queue_head
(
&
priv
->
adapter
->
tx_queue
,
skb
);
BT_DBG
(
"Queue PSMODE Command:%d"
,
cmd
->
data
[
0
]);
btmrvl_enable_ps
(
priv
);
}
if
(
priv
->
btmrvl_dev
.
hscmd
)
{
...
...
drivers/bluetooth/btmrvl_sdio.c
浏览文件 @
a7fca0cc
...
...
@@ -930,6 +930,8 @@ static int btmrvl_sdio_probe(struct sdio_func *func,
priv
->
hw_wakeup_firmware
=
btmrvl_sdio_wakeup_fw
;
btmrvl_send_module_cfg_cmd
(
priv
,
MODULE_BRINGUP_REQ
);
priv
->
btmrvl_dev
.
psmode
=
1
;
btmrvl_enable_ps
(
priv
);
return
0
;
...
...
@@ -1001,3 +1003,5 @@ MODULE_AUTHOR("Marvell International Ltd.");
MODULE_DESCRIPTION
(
"Marvell BT-over-SDIO driver ver "
VERSION
);
MODULE_VERSION
(
VERSION
);
MODULE_LICENSE
(
"GPL v2"
);
MODULE_FIRMWARE
(
"sd8688_helper.bin"
);
MODULE_FIRMWARE
(
"sd8688.bin"
);
drivers/bluetooth/hci_vhci.c
浏览文件 @
a7fca0cc
...
...
@@ -41,8 +41,6 @@
#define VERSION "1.3"
static
int
minor
=
MISC_DYNAMIC_MINOR
;
struct
vhci_data
{
struct
hci_dev
*
hdev
;
...
...
@@ -218,12 +216,6 @@ static unsigned int vhci_poll(struct file *file, poll_table *wait)
return
POLLOUT
|
POLLWRNORM
;
}
static
int
vhci_ioctl
(
struct
inode
*
inode
,
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
return
-
EINVAL
;
}
static
int
vhci_open
(
struct
inode
*
inode
,
struct
file
*
file
)
{
struct
vhci_data
*
data
;
...
...
@@ -284,10 +276,10 @@ static int vhci_release(struct inode *inode, struct file *file)
}
static
const
struct
file_operations
vhci_fops
=
{
.
owner
=
THIS_MODULE
,
.
read
=
vhci_read
,
.
write
=
vhci_write
,
.
poll
=
vhci_poll
,
.
ioctl
=
vhci_ioctl
,
.
open
=
vhci_open
,
.
release
=
vhci_release
,
};
...
...
@@ -302,18 +294,12 @@ static int __init vhci_init(void)
{
BT_INFO
(
"Virtual HCI driver ver %s"
,
VERSION
);
if
(
misc_register
(
&
vhci_miscdev
)
<
0
)
{
BT_ERR
(
"Can't register misc device with minor %d"
,
minor
);
return
-
EIO
;
}
return
0
;
return
misc_register
(
&
vhci_miscdev
);
}
static
void
__exit
vhci_exit
(
void
)
{
if
(
misc_deregister
(
&
vhci_miscdev
)
<
0
)
BT_ERR
(
"Can't unregister misc device with minor %d"
,
minor
);
misc_deregister
(
&
vhci_miscdev
);
}
module_init
(
vhci_init
);
...
...
include/net/bluetooth/hci_core.h
浏览文件 @
a7fca0cc
...
...
@@ -367,22 +367,6 @@ static inline void hci_conn_put(struct hci_conn *conn)
}
}
/* ----- HCI tasks ----- */
static
inline
void
hci_sched_cmd
(
struct
hci_dev
*
hdev
)
{
tasklet_schedule
(
&
hdev
->
cmd_task
);
}
static
inline
void
hci_sched_rx
(
struct
hci_dev
*
hdev
)
{
tasklet_schedule
(
&
hdev
->
rx_task
);
}
static
inline
void
hci_sched_tx
(
struct
hci_dev
*
hdev
)
{
tasklet_schedule
(
&
hdev
->
tx_task
);
}
/* ----- HCI Devices ----- */
static
inline
void
__hci_dev_put
(
struct
hci_dev
*
d
)
{
...
...
@@ -437,28 +421,7 @@ int hci_inquiry(void __user *arg);
void
hci_event_packet
(
struct
hci_dev
*
hdev
,
struct
sk_buff
*
skb
);
/* Receive frame from HCI drivers */
static
inline
int
hci_recv_frame
(
struct
sk_buff
*
skb
)
{
struct
hci_dev
*
hdev
=
(
struct
hci_dev
*
)
skb
->
dev
;
if
(
!
hdev
||
(
!
test_bit
(
HCI_UP
,
&
hdev
->
flags
)
&&
!
test_bit
(
HCI_INIT
,
&
hdev
->
flags
)))
{
kfree_skb
(
skb
);
return
-
ENXIO
;
}
/* Incomming skb */
bt_cb
(
skb
)
->
incoming
=
1
;
/* Time stamp */
__net_timestamp
(
skb
);
/* Queue frame for rx task */
skb_queue_tail
(
&
hdev
->
rx_q
,
skb
);
hci_sched_rx
(
hdev
);
return
0
;
}
int
hci_recv_frame
(
struct
sk_buff
*
skb
);
int
hci_recv_fragment
(
struct
hci_dev
*
hdev
,
int
type
,
void
*
data
,
int
count
);
int
hci_register_sysfs
(
struct
hci_dev
*
hdev
);
...
...
include/net/bluetooth/l2cap.h
浏览文件 @
a7fca0cc
...
...
@@ -324,7 +324,6 @@ struct l2cap_pinfo {
__u8
next_tx_seq
;
__u8
expected_ack_seq
;
__u8
req_seq
;
__u8
expected_tx_seq
;
__u8
buffer_seq
;
__u8
buffer_seq_srej
;
...
...
@@ -375,6 +374,7 @@ struct l2cap_pinfo {
#define L2CAP_CONN_SEND_PBIT 0x10
#define L2CAP_CONN_REMOTE_BUSY 0x20
#define L2CAP_CONN_LOCAL_BUSY 0x40
#define L2CAP_CONN_REJ_ACT 0x80
#define __mod_retrans_timer() mod_timer(&l2cap_pi(sk)->retrans_timer, \
jiffies + msecs_to_jiffies(L2CAP_DEFAULT_RETRANS_TO));
...
...
net/bluetooth/bnep/core.c
浏览文件 @
a7fca0cc
...
...
@@ -230,7 +230,6 @@ static int bnep_rx_control(struct bnep_session *s, void *data, int len)
switch
(
cmd
)
{
case
BNEP_CMD_NOT_UNDERSTOOD
:
case
BNEP_SETUP_CONN_REQ
:
case
BNEP_SETUP_CONN_RSP
:
case
BNEP_FILTER_NET_TYPE_RSP
:
case
BNEP_FILTER_MULTI_ADDR_RSP
:
...
...
@@ -245,6 +244,10 @@ static int bnep_rx_control(struct bnep_session *s, void *data, int len)
err
=
bnep_ctrl_set_mcfilter
(
s
,
data
,
len
);
break
;
case
BNEP_SETUP_CONN_REQ
:
err
=
bnep_send_rsp
(
s
,
BNEP_SETUP_CONN_RSP
,
BNEP_CONN_NOT_ALLOWED
);
break
;
default:
{
u8
pkt
[
3
];
pkt
[
0
]
=
BNEP_CONTROL
;
...
...
net/bluetooth/hci_core.c
浏览文件 @
a7fca0cc
...
...
@@ -193,8 +193,9 @@ static void hci_init_req(struct hci_dev *hdev, unsigned long opt)
while
((
skb
=
skb_dequeue
(
&
hdev
->
driver_init
)))
{
bt_cb
(
skb
)
->
pkt_type
=
HCI_COMMAND_PKT
;
skb
->
dev
=
(
void
*
)
hdev
;
skb_queue_tail
(
&
hdev
->
cmd_q
,
skb
);
hci_sched_cmd
(
hdev
);
tasklet_schedule
(
&
hdev
->
cmd_task
);
}
skb_queue_purge
(
&
hdev
->
driver_init
);
...
...
@@ -987,6 +988,30 @@ int hci_resume_dev(struct hci_dev *hdev)
}
EXPORT_SYMBOL
(
hci_resume_dev
);
/* Receive frame from HCI drivers */
int
hci_recv_frame
(
struct
sk_buff
*
skb
)
{
struct
hci_dev
*
hdev
=
(
struct
hci_dev
*
)
skb
->
dev
;
if
(
!
hdev
||
(
!
test_bit
(
HCI_UP
,
&
hdev
->
flags
)
&&
!
test_bit
(
HCI_INIT
,
&
hdev
->
flags
)))
{
kfree_skb
(
skb
);
return
-
ENXIO
;
}
/* Incomming skb */
bt_cb
(
skb
)
->
incoming
=
1
;
/* Time stamp */
__net_timestamp
(
skb
);
/* Queue frame for rx task */
skb_queue_tail
(
&
hdev
->
rx_q
,
skb
);
tasklet_schedule
(
&
hdev
->
rx_task
);
return
0
;
}
EXPORT_SYMBOL
(
hci_recv_frame
);
/* Receive packet type fragment */
#define __reassembly(hdev, type) ((hdev)->reassembly[(type) - 2])
...
...
@@ -1193,8 +1218,9 @@ int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param)
bt_cb
(
skb
)
->
pkt_type
=
HCI_COMMAND_PKT
;
skb
->
dev
=
(
void
*
)
hdev
;
skb_queue_tail
(
&
hdev
->
cmd_q
,
skb
);
hci_sched_cmd
(
hdev
);
tasklet_schedule
(
&
hdev
->
cmd_task
);
return
0
;
}
...
...
@@ -1271,7 +1297,8 @@ int hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags)
spin_unlock_bh
(
&
conn
->
data_q
.
lock
);
}
hci_sched_tx
(
hdev
);
tasklet_schedule
(
&
hdev
->
tx_task
);
return
0
;
}
EXPORT_SYMBOL
(
hci_send_acl
);
...
...
@@ -1298,8 +1325,10 @@ int hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
skb
->
dev
=
(
void
*
)
hdev
;
bt_cb
(
skb
)
->
pkt_type
=
HCI_SCODATA_PKT
;
skb_queue_tail
(
&
conn
->
data_q
,
skb
);
hci_sched_tx
(
hdev
);
tasklet_schedule
(
&
hdev
->
tx_task
);
return
0
;
}
EXPORT_SYMBOL
(
hci_send_sco
);
...
...
@@ -1612,7 +1641,7 @@ static void hci_cmd_task(unsigned long arg)
hdev
->
cmd_last_tx
=
jiffies
;
}
else
{
skb_queue_head
(
&
hdev
->
cmd_q
,
skb
);
hci_sched_cmd
(
hdev
);
tasklet_schedule
(
&
hdev
->
cmd_task
);
}
}
}
net/bluetooth/hci_event.c
浏览文件 @
a7fca0cc
...
...
@@ -1320,7 +1320,7 @@ static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *sk
if
(
ev
->
ncmd
)
{
atomic_set
(
&
hdev
->
cmd_cnt
,
1
);
if
(
!
skb_queue_empty
(
&
hdev
->
cmd_q
))
hci_sched_cmd
(
hdev
);
tasklet_schedule
(
&
hdev
->
cmd_task
);
}
}
...
...
@@ -1386,7 +1386,7 @@ static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
if
(
ev
->
ncmd
)
{
atomic_set
(
&
hdev
->
cmd_cnt
,
1
);
if
(
!
skb_queue_empty
(
&
hdev
->
cmd_q
))
hci_sched_cmd
(
hdev
);
tasklet_schedule
(
&
hdev
->
cmd_task
);
}
}
...
...
@@ -1454,7 +1454,7 @@ static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *s
}
}
hci_sched_tx
(
hdev
);
tasklet_schedule
(
&
hdev
->
tx_task
);
tasklet_enable
(
&
hdev
->
tx_task
);
}
...
...
net/bluetooth/hci_sock.c
浏览文件 @
a7fca0cc
...
...
@@ -414,6 +414,11 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
goto
done
;
}
if
(
!
test_bit
(
HCI_UP
,
&
hdev
->
flags
))
{
err
=
-
ENETDOWN
;
goto
done
;
}
if
(
!
(
skb
=
bt_skb_send_alloc
(
sk
,
len
,
msg
->
msg_flags
&
MSG_DONTWAIT
,
&
err
)))
goto
done
;
...
...
@@ -440,10 +445,10 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
if
(
test_bit
(
HCI_RAW
,
&
hdev
->
flags
)
||
(
ogf
==
0x3f
))
{
skb_queue_tail
(
&
hdev
->
raw_q
,
skb
);
hci_sched_tx
(
hdev
);
tasklet_schedule
(
&
hdev
->
tx_task
);
}
else
{
skb_queue_tail
(
&
hdev
->
cmd_q
,
skb
);
hci_sched_cmd
(
hdev
);
tasklet_schedule
(
&
hdev
->
cmd_task
);
}
}
else
{
if
(
!
capable
(
CAP_NET_RAW
))
{
...
...
@@ -452,7 +457,7 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
}
skb_queue_tail
(
&
hdev
->
raw_q
,
skb
);
hci_sched_tx
(
hdev
);
tasklet_schedule
(
&
hdev
->
tx_task
);
}
err
=
len
;
...
...
net/bluetooth/hidp/core.c
浏览文件 @
a7fca0cc
...
...
@@ -280,6 +280,13 @@ static int hidp_send_report(struct hidp_session *session, struct hid_report *rep
return
hidp_queue_report
(
session
,
buf
,
rsize
);
}
static
int
hidp_output_raw_report
(
struct
hid_device
*
hid
,
unsigned
char
*
data
,
size_t
count
)
{
if
(
hidp_queue_report
(
hid
->
driver_data
,
data
,
count
))
return
-
ENOMEM
;
return
count
;
}
static
void
hidp_idle_timeout
(
unsigned
long
arg
)
{
struct
hidp_session
*
session
=
(
struct
hidp_session
*
)
arg
;
...
...
@@ -785,6 +792,8 @@ static int hidp_setup_hid(struct hidp_session *session,
hid
->
dev
.
parent
=
hidp_get_device
(
session
);
hid
->
ll_driver
=
&
hidp_hid_driver
;
hid
->
hid_output_raw_report
=
hidp_output_raw_report
;
err
=
hid_add_device
(
hid
);
if
(
err
<
0
)
goto
failed
;
...
...
net/bluetooth/l2cap.c
浏览文件 @
a7fca0cc
...
...
@@ -54,6 +54,7 @@
#define VERSION "2.14"
static
int
enable_ertm
=
0
;
static
int
max_transmit
=
L2CAP_DEFAULT_MAX_TX
;
static
u32
l2cap_feat_mask
=
L2CAP_FEAT_FIXED_CHAN
;
static
u8
l2cap_fixed_chan
[
8
]
=
{
0x02
,
};
...
...
@@ -373,6 +374,8 @@ static inline int l2cap_send_rr_or_rnr(struct l2cap_pinfo *pi, u16 control)
else
control
|=
L2CAP_SUPER_RCV_READY
;
control
|=
pi
->
buffer_seq
<<
L2CAP_CTRL_REQSEQ_SHIFT
;
return
l2cap_send_sframe
(
pi
,
control
);
}
...
...
@@ -1333,7 +1336,7 @@ static int l2cap_retransmit_frame(struct sock *sk, u8 tx_seq)
tx_skb
=
skb_clone
(
skb
,
GFP_ATOMIC
);
bt_cb
(
skb
)
->
retries
++
;
control
=
get_unaligned_le16
(
tx_skb
->
data
+
L2CAP_HDR_SIZE
);
control
|=
(
pi
->
req
_seq
<<
L2CAP_CTRL_REQSEQ_SHIFT
)
control
|=
(
pi
->
buffer
_seq
<<
L2CAP_CTRL_REQSEQ_SHIFT
)
|
(
tx_seq
<<
L2CAP_CTRL_TXSEQ_SHIFT
);
put_unaligned_le16
(
control
,
tx_skb
->
data
+
L2CAP_HDR_SIZE
);
...
...
@@ -1375,7 +1378,7 @@ static int l2cap_ertm_send(struct sock *sk)
bt_cb
(
skb
)
->
retries
++
;
control
=
get_unaligned_le16
(
tx_skb
->
data
+
L2CAP_HDR_SIZE
);
control
|=
(
pi
->
req
_seq
<<
L2CAP_CTRL_REQSEQ_SHIFT
)
control
|=
(
pi
->
buffer
_seq
<<
L2CAP_CTRL_REQSEQ_SHIFT
)
|
(
pi
->
next_tx_seq
<<
L2CAP_CTRL_TXSEQ_SHIFT
);
put_unaligned_le16
(
control
,
tx_skb
->
data
+
L2CAP_HDR_SIZE
);
...
...
@@ -2173,6 +2176,21 @@ static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
*
ptr
+=
L2CAP_CONF_OPT_SIZE
+
len
;
}
static
inline
void
l2cap_ertm_init
(
struct
sock
*
sk
)
{
l2cap_pi
(
sk
)
->
expected_ack_seq
=
0
;
l2cap_pi
(
sk
)
->
unacked_frames
=
0
;
l2cap_pi
(
sk
)
->
buffer_seq
=
0
;
l2cap_pi
(
sk
)
->
num_to_ack
=
0
;
setup_timer
(
&
l2cap_pi
(
sk
)
->
retrans_timer
,
l2cap_retrans_timeout
,
(
unsigned
long
)
sk
);
setup_timer
(
&
l2cap_pi
(
sk
)
->
monitor_timer
,
l2cap_monitor_timeout
,
(
unsigned
long
)
sk
);
__skb_queue_head_init
(
SREJ_QUEUE
(
sk
));
}
static
int
l2cap_mode_supported
(
__u8
mode
,
__u32
feat_mask
)
{
u32
local_feat_mask
=
l2cap_feat_mask
;
...
...
@@ -2236,7 +2254,7 @@ static int l2cap_build_conf_req(struct sock *sk, void *data)
case
L2CAP_MODE_ERTM
:
rfc
.
mode
=
L2CAP_MODE_ERTM
;
rfc
.
txwin_size
=
L2CAP_DEFAULT_TX_WINDOW
;
rfc
.
max_transmit
=
L2CAP_DEFAULT_MAX_TX
;
rfc
.
max_transmit
=
max_transmit
;
rfc
.
retrans_timeout
=
0
;
rfc
.
monitor_timeout
=
0
;
rfc
.
max_pdu_size
=
cpu_to_le16
(
L2CAP_DEFAULT_MAX_PDU_SIZE
);
...
...
@@ -2761,17 +2779,13 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr
l2cap_pi
(
sk
)
->
fcs
=
L2CAP_FCS_CRC16
;
sk
->
sk_state
=
BT_CONNECTED
;
l2cap_pi
(
sk
)
->
next_tx_seq
=
0
;
l2cap_pi
(
sk
)
->
expected_ack_seq
=
0
;
l2cap_pi
(
sk
)
->
unacked_frames
=
0
;
setup_timer
(
&
l2cap_pi
(
sk
)
->
retrans_timer
,
l2cap_retrans_timeout
,
(
unsigned
long
)
sk
);
setup_timer
(
&
l2cap_pi
(
sk
)
->
monitor_timer
,
l2cap_monitor_timeout
,
(
unsigned
long
)
sk
);
l2cap_pi
(
sk
)
->
next_tx_seq
=
0
;
l2cap_pi
(
sk
)
->
expected_tx_seq
=
0
;
__skb_queue_head_init
(
TX_QUEUE
(
sk
));
__skb_queue_head_init
(
SREJ_QUEUE
(
sk
));
if
(
l2cap_pi
(
sk
)
->
mode
==
L2CAP_MODE_ERTM
)
l2cap_ertm_init
(
sk
);
l2cap_chan_ready
(
sk
);
goto
unlock
;
}
...
...
@@ -2850,11 +2864,12 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
l2cap_pi
(
sk
)
->
fcs
=
L2CAP_FCS_CRC16
;
sk
->
sk_state
=
BT_CONNECTED
;
l2cap_pi
(
sk
)
->
next_tx_seq
=
0
;
l2cap_pi
(
sk
)
->
expected_tx_seq
=
0
;
l2cap_pi
(
sk
)
->
buffer_seq
=
0
;
l2cap_pi
(
sk
)
->
num_to_ack
=
0
;
__skb_queue_head_init
(
TX_QUEUE
(
sk
));
__skb_queue_head_init
(
SREJ_QUEUE
(
sk
));
if
(
l2cap_pi
(
sk
)
->
mode
==
L2CAP_MODE_ERTM
)
l2cap_ertm_init
(
sk
);
l2cap_chan_ready
(
sk
);
}
...
...
@@ -2886,9 +2901,12 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd
sk
->
sk_shutdown
=
SHUTDOWN_MASK
;
skb_queue_purge
(
TX_QUEUE
(
sk
));
skb_queue_purge
(
SREJ_QUEUE
(
sk
));
del_timer
(
&
l2cap_pi
(
sk
)
->
retrans_timer
);
del_timer
(
&
l2cap_pi
(
sk
)
->
monitor_timer
);
if
(
l2cap_pi
(
sk
)
->
mode
==
L2CAP_MODE_ERTM
)
{
skb_queue_purge
(
SREJ_QUEUE
(
sk
));
del_timer
(
&
l2cap_pi
(
sk
)
->
retrans_timer
);
del_timer
(
&
l2cap_pi
(
sk
)
->
monitor_timer
);
}
l2cap_chan_del
(
sk
,
ECONNRESET
);
bh_unlock_sock
(
sk
);
...
...
@@ -2913,9 +2931,12 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd
return
0
;
skb_queue_purge
(
TX_QUEUE
(
sk
));
skb_queue_purge
(
SREJ_QUEUE
(
sk
));
del_timer
(
&
l2cap_pi
(
sk
)
->
retrans_timer
);
del_timer
(
&
l2cap_pi
(
sk
)
->
monitor_timer
);
if
(
l2cap_pi
(
sk
)
->
mode
==
L2CAP_MODE_ERTM
)
{
skb_queue_purge
(
SREJ_QUEUE
(
sk
));
del_timer
(
&
l2cap_pi
(
sk
)
->
retrans_timer
);
del_timer
(
&
l2cap_pi
(
sk
)
->
monitor_timer
);
}
l2cap_chan_del
(
sk
,
0
);
bh_unlock_sock
(
sk
);
...
...
@@ -3280,12 +3301,16 @@ static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, str
{
struct
l2cap_pinfo
*
pi
=
l2cap_pi
(
sk
);
u8
tx_seq
=
__get_txseq
(
rx_control
);
u8
req_seq
=
__get_reqseq
(
rx_control
);
u16
tx_control
=
0
;
u8
sar
=
rx_control
>>
L2CAP_CTRL_SAR_SHIFT
;
int
err
=
0
;
BT_DBG
(
"sk %p rx_control 0x%4.4x len %d"
,
sk
,
rx_control
,
skb
->
len
);
pi
->
expected_ack_seq
=
req_seq
;
l2cap_drop_acked_frames
(
sk
);
if
(
tx_seq
==
pi
->
expected_tx_seq
)
goto
expected
;
...
...
@@ -3340,6 +3365,16 @@ static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, str
return
0
;
}
if
(
rx_control
&
L2CAP_CTRL_FINAL
)
{
if
(
pi
->
conn_state
&
L2CAP_CONN_REJ_ACT
)
pi
->
conn_state
&=
~
L2CAP_CONN_REJ_ACT
;
else
{
sk
->
sk_send_head
=
TX_QUEUE
(
sk
)
->
next
;
pi
->
next_tx_seq
=
pi
->
expected_ack_seq
;
l2cap_ertm_send
(
sk
);
}
}
pi
->
buffer_seq
=
(
pi
->
buffer_seq
+
1
)
%
64
;
err
=
l2cap_sar_reassembly_sdu
(
sk
,
skb
,
rx_control
);
...
...
@@ -3376,6 +3411,14 @@ static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, str
pi
->
expected_ack_seq
=
tx_seq
;
l2cap_drop_acked_frames
(
sk
);
if
(
pi
->
conn_state
&
L2CAP_CONN_REJ_ACT
)
pi
->
conn_state
&=
~
L2CAP_CONN_REJ_ACT
;
else
{
sk
->
sk_send_head
=
TX_QUEUE
(
sk
)
->
next
;
pi
->
next_tx_seq
=
pi
->
expected_ack_seq
;
l2cap_ertm_send
(
sk
);
}
if
(
!
(
pi
->
conn_state
&
L2CAP_CONN_WAIT_F
))
break
;
...
...
@@ -3403,10 +3446,24 @@ static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, str
pi
->
expected_ack_seq
=
__get_reqseq
(
rx_control
);
l2cap_drop_acked_frames
(
sk
);
sk
->
sk_send_head
=
TX_QUEUE
(
sk
)
->
next
;
pi
->
next_tx_seq
=
pi
->
expected_ack_seq
;
if
(
rx_control
&
L2CAP_CTRL_FINAL
)
{
if
(
pi
->
conn_state
&
L2CAP_CONN_REJ_ACT
)
pi
->
conn_state
&=
~
L2CAP_CONN_REJ_ACT
;
else
{
sk
->
sk_send_head
=
TX_QUEUE
(
sk
)
->
next
;
pi
->
next_tx_seq
=
pi
->
expected_ack_seq
;
l2cap_ertm_send
(
sk
);
}
}
else
{
sk
->
sk_send_head
=
TX_QUEUE
(
sk
)
->
next
;
pi
->
next_tx_seq
=
pi
->
expected_ack_seq
;
l2cap_ertm_send
(
sk
);
l2cap_ertm_send
(
sk
);
if
(
pi
->
conn_state
&
L2CAP_CONN_WAIT_F
)
{
pi
->
srej_save_reqseq
=
tx_seq
;
pi
->
conn_state
|=
L2CAP_CONN_REJ_ACT
;
}
}
break
;
...
...
@@ -3425,7 +3482,7 @@ static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, str
}
else
if
(
rx_control
&
L2CAP_CTRL_FINAL
)
{
if
((
pi
->
conn_state
&
L2CAP_CONN_SREJ_ACT
)
&&
pi
->
srej_save_reqseq
==
tx_seq
)
pi
->
srej_save_reqseq
&=
~
L2CAP_CONN_SREJ_ACT
;
pi
->
conn_state
&=
~
L2CAP_CONN_SREJ_ACT
;
else
l2cap_retransmit_frame
(
sk
,
tx_seq
);
}
...
...
@@ -4004,6 +4061,9 @@ module_exit(l2cap_exit);
module_param
(
enable_ertm
,
bool
,
0644
);
MODULE_PARM_DESC
(
enable_ertm
,
"Enable enhanced retransmission mode"
);
module_param
(
max_transmit
,
uint
,
0644
);
MODULE_PARM_DESC
(
max_transmit
,
"Max transmit value (default = 3)"
);
MODULE_AUTHOR
(
"Marcel Holtmann <marcel@holtmann.org>"
);
MODULE_DESCRIPTION
(
"Bluetooth L2CAP ver "
VERSION
);
MODULE_VERSION
(
VERSION
);
...
...
net/bluetooth/rfcomm/core.c
浏览文件 @
a7fca0cc
...
...
@@ -51,6 +51,7 @@
static
int
disable_cfc
=
0
;
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
;
...
...
@@ -702,6 +703,8 @@ static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, bdaddr_t *dst
sk
=
sock
->
sk
;
lock_sock
(
sk
);
l2cap_pi
(
sk
)
->
imtu
=
l2cap_mtu
;
if
(
l2cap_ertm
)
l2cap_pi
(
sk
)
->
mode
=
L2CAP_MODE_ERTM
;
release_sock
(
sk
);
s
=
rfcomm_session_add
(
sock
,
BT_BOUND
);
...
...
@@ -2185,6 +2188,9 @@ MODULE_PARM_DESC(channel_mtu, "Default MTU for the RFCOMM channel");
module_param
(
l2cap_mtu
,
uint
,
0644
);
MODULE_PARM_DESC
(
l2cap_mtu
,
"Default MTU for the L2CAP connection"
);
module_param
(
l2cap_ertm
,
bool
,
0644
);
MODULE_PARM_DESC
(
l2cap_ertm
,
"Use L2CAP ERTM mode for connection"
);
MODULE_AUTHOR
(
"Marcel Holtmann <marcel@holtmann.org>"
);
MODULE_DESCRIPTION
(
"Bluetooth RFCOMM ver "
VERSION
);
MODULE_VERSION
(
VERSION
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录