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
a7fca0cc
Commit
a7fca0cc
authored
Dec 03, 2009
by
David S. Miller
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' of
git://git.kernel.org/pub/scm/linux/kernel/git/holtmann/bluetooth-next-2.6
parents
424eff97
2861453b
Changes
14
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
192 additions
and
116 deletions
+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
No files found.
drivers/bluetooth/btmrvl_debugfs.c
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
);
...
...
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