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
c30ae138
Commit
c30ae138
authored
Dec 02, 2010
by
John W. Linville
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' of
git://git.kernel.org/pub/scm/linux/kernel/git/padovan/bluetooth-next-2.6
parents
78b85956
be21871f
Changes
19
Hide whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
363 additions
and
212 deletions
+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
No files found.
drivers/bluetooth/ath3k.c
View file @
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
View file @
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,7 +242,8 @@ static void btusb_intr_complete(struct urb *urb)
err
=
usb_submit_urb
(
urb
,
GFP_ATOMIC
);
if
(
err
<
0
)
{
BT_ERR
(
"%s urb %p failed to resubmit (%d)"
,
if
(
err
!=
-
EPERM
)
BT_ERR
(
"%s urb %p failed to resubmit (%d)"
,
hdev
->
name
,
urb
,
-
err
);
usb_unanchor_urb
(
urb
);
}
...
...
@@ -323,7 +327,8 @@ static void btusb_bulk_complete(struct urb *urb)
err
=
usb_submit_urb
(
urb
,
GFP_ATOMIC
);
if
(
err
<
0
)
{
BT_ERR
(
"%s urb %p failed to resubmit (%d)"
,
if
(
err
!=
-
EPERM
)
BT_ERR
(
"%s urb %p failed to resubmit (%d)"
,
hdev
->
name
,
urb
,
-
err
);
usb_unanchor_urb
(
urb
);
}
...
...
@@ -412,7 +417,8 @@ static void btusb_isoc_complete(struct urb *urb)
err
=
usb_submit_urb
(
urb
,
GFP_ATOMIC
);
if
(
err
<
0
)
{
BT_ERR
(
"%s urb %p failed to resubmit (%d)"
,
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
View file @
c30ae138
/*
/*
BlueZ - Bluetooth protocol stack for Linux
Copyright (C) 2000-2001 Qualcomm Incorporated
...
...
@@ -12,13 +12,13 @@
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
SOFTWARE IS DISCLAIMED.
*/
...
...
@@ -489,7 +489,7 @@ struct hci_rp_read_local_name {
#define HCI_OP_WRITE_PG_TIMEOUT 0x0c18
#define HCI_OP_WRITE_SCAN_ENABLE
0x0c1a
#define HCI_OP_WRITE_SCAN_ENABLE 0x0c1a
#define SCAN_DISABLED 0x00
#define SCAN_INQUIRY 0x01
#define SCAN_PAGE 0x02
...
...
@@ -874,7 +874,7 @@ struct hci_ev_si_security {
struct
hci_command_hdr
{
__le16
opcode
;
/* OCF & OGF */
__u8
plen
;
__u8
plen
;
}
__packed
;
struct
hci_event_hdr
{
...
...
include/net/bluetooth/hci_core.h
View file @
c30ae138
...
...
@@ -44,15 +44,15 @@ struct inquiry_data {
};
struct
inquiry_entry
{
struct
inquiry_entry
*
next
;
struct
inquiry_entry
*
next
;
__u32
timestamp
;
struct
inquiry_data
data
;
};
struct
inquiry_cache
{
spinlock_t
lock
;
spinlock_t
lock
;
__u32
timestamp
;
struct
inquiry_entry
*
list
;
struct
inquiry_entry
*
list
;
};
struct
hci_conn_hash
{
...
...
@@ -141,7 +141,7 @@ struct hci_dev {
void
*
driver_data
;
void
*
core_data
;
atomic_t
promisc
;
atomic_t
promisc
;
struct
dentry
*
debugfs
;
...
...
@@ -150,7 +150,7 @@ struct hci_dev {
struct
rfkill
*
rfkill
;
struct
module
*
owner
;
struct
module
*
owner
;
int
(
*
open
)(
struct
hci_dev
*
hdev
);
int
(
*
close
)(
struct
hci_dev
*
hdev
);
...
...
@@ -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
View file @
c30ae138
/*
/*
BlueZ - Bluetooth protocol stack for Linux
Copyright (C) 2000-2001 Qualcomm Incorporated
Copyright (C) 2009-2010 Gustavo F. Padovan <gustavo@padovan.org>
...
...
@@ -14,13 +14,13 @@
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
SOFTWARE IS DISCLAIMED.
*/
...
...
@@ -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
View file @
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>
...
...
@@ -11,13 +11,13 @@
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
SOFTWARE IS DISCLAIMED.
*/
...
...
@@ -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
{
...
...
@@ -228,7 +228,7 @@ struct rfcomm_dlc {
/* ---- RFCOMM SEND RPN ---- */
int
rfcomm_send_rpn
(
struct
rfcomm_session
*
s
,
int
cr
,
u8
dlci
,
u8
bit_rate
,
u8
data_bits
,
u8
stop_bits
,
u8
parity
,
u8
flow_ctrl_settings
,
u8
parity
,
u8
flow_ctrl_settings
,
u8
xon_char
,
u8
xoff_char
,
u16
param_mask
);
/* ---- RFCOMM DLCs (channels) ---- */
...
...
include/net/bluetooth/sco.h
View file @
c30ae138
/*
/*
BlueZ - Bluetooth protocol stack for Linux
Copyright (C) 2000-2001 Qualcomm Incorporated
...
...
@@ -12,13 +12,13 @@
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
SOFTWARE IS DISCLAIMED.
*/
...
...
@@ -55,11 +55,11 @@ struct sco_conninfo {
struct
sco_conn
{
struct
hci_conn
*
hcon
;
bdaddr_t
*
dst
;
bdaddr_t
*
src
;
bdaddr_t
*
dst
;
bdaddr_t
*
src
;
spinlock_t
lock
;
struct
sock
*
sk
;
struct
sock
*
sk
;
unsigned
int
mtu
;
};
...
...
net/bluetooth/bnep/core.c
View file @
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
View file @
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
View file @
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
View file @
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
;
}
...
...
@@ -422,16 +425,20 @@ int hci_inquiry(void __user *arg)
hci_dev_lock_bh
(
hdev
);
if
(
inquiry_cache_age
(
hdev
)
>
INQUIRY_CACHE_AGE_MAX
||
inquiry_cache_empty
(
hdev
)
||
ir
.
flags
&
IREQ_CACHE_FLUSH
)
{
inquiry_cache_empty
(
hdev
)
||
ir
.
flags
&
IREQ_CACHE_FLUSH
)
{
inquiry_cache_flush
(
hdev
);
do_inquiry
=
1
;
}
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
)
goto
done
;
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
View file @
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
(
!
ev
->
status
)
memcpy
(
conn
->
features
,
ev
->
features
,
8
);
if
(
!
conn
)
goto
unlock
;
if
(
conn
->
state
==
BT_CONFIG
)
{
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
,
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
,
if
(
!
ev
->
status
)
memcpy
(
conn
->
features
,
ev
->
features
,
8
);
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
,
sizeof
(
cp
),
&
cp
);
}
else
{
conn
->
state
=
BT_CONNECTED
;
hci_proto_connect_cfm
(
conn
,
ev
->
status
);
hci_conn_put
(
conn
);
}
}
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
(
!
ev
->
status
&&
ev
->
page
==
0x01
)
{
struct
inquiry_entry
*
ie
;
if
(
!
conn
)
goto
unlock
;
if
((
ie
=
hci_inquiry_cache_lookup
(
hdev
,
&
conn
->
dst
)))
ie
->
data
.
ssp_mode
=
(
ev
->
features
[
0
]
&
0x01
)
;
if
(
!
ev
->
status
&&
ev
->
page
==
0x01
)
{
struct
inquiry_entry
*
ie
;
conn
->
ssp_mode
=
(
ev
->
features
[
0
]
&
0x01
);
}
ie
=
hci_inquiry_cache_lookup
(
hdev
,
&
conn
->
dst
);
if
(
ie
)
ie
->
data
.
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
{
conn
->
state
=
BT_CONNECTED
;
hci_proto_connect_cfm
(
conn
,
ev
->
status
);
hci_conn_put
(
conn
);
}
}
conn
->
ssp_mode
=
(
ev
->
features
[
0
]
&
0x01
);
}
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
View file @
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
View file @
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
View file @
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,11 +4162,10 @@ 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
);
}
}
}
...
...
@@ -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
View file @
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
View file @
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
View file @
c30ae138
...
...
@@ -58,9 +58,9 @@ struct rfcomm_dev {
bdaddr_t
src
;
bdaddr_t
dst
;
u8
channel
;
u8
channel
;
uint
modem_status
;
uint
modem_status
;
struct
rfcomm_dlc
*
dlc
;
struct
tty_struct
*
tty
;
...
...
@@ -69,7 +69,7 @@ struct rfcomm_dev {
struct
device
*
tty_dev
;
atomic_t
wmem_alloc
;
atomic_t
wmem_alloc
;
struct
sk_buff_head
pending
;
};
...
...
@@ -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
View file @
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
));
...
...
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