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
50b65cc6
Commit
50b65cc6
authored
Jul 11, 2007
by
David S. Miller
Browse files
Options
Browse Files
Download
Plain Diff
Merge master.kernel.org:/pub/scm/linux/kernel/git/holtmann/bluetooth-2.6
parents
29578624
5b7f9909
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
195 additions
and
142 deletions
+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
No files found.
drivers/bluetooth/hci_usb.c
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
;
...
...
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