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
Kirill Smelkov
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
Show 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 @@
...
@@ -35,6 +35,10 @@
static
struct
usb_device_id
ath3k_table
[]
=
{
static
struct
usb_device_id
ath3k_table
[]
=
{
/* Atheros AR3011 */
/* Atheros AR3011 */
{
USB_DEVICE
(
0x0CF3
,
0x3000
)
},
{
USB_DEVICE
(
0x0CF3
,
0x3000
)
},
/* Atheros AR3011 with sflash firmware*/
{
USB_DEVICE
(
0x0CF3
,
0x3002
)
},
{
}
/* Terminating entry */
{
}
/* Terminating entry */
};
};
...
...
drivers/bluetooth/btusb.c
View file @
c30ae138
...
@@ -99,6 +99,9 @@ static struct usb_device_id blacklist_table[] = {
...
@@ -99,6 +99,9 @@ static struct usb_device_id blacklist_table[] = {
/* Broadcom BCM2033 without firmware */
/* Broadcom BCM2033 without firmware */
{
USB_DEVICE
(
0x0a5c
,
0x2033
),
.
driver_info
=
BTUSB_IGNORE
},
{
USB_DEVICE
(
0x0a5c
,
0x2033
),
.
driver_info
=
BTUSB_IGNORE
},
/* Atheros 3011 with sflash firmware */
{
USB_DEVICE
(
0x0cf3
,
0x3002
),
.
driver_info
=
BTUSB_IGNORE
},
/* Broadcom BCM2035 */
/* Broadcom BCM2035 */
{
USB_DEVICE
(
0x0a5c
,
0x2035
),
.
driver_info
=
BTUSB_WRONG_SCO_MTU
},
{
USB_DEVICE
(
0x0a5c
,
0x2035
),
.
driver_info
=
BTUSB_WRONG_SCO_MTU
},
{
USB_DEVICE
(
0x0a5c
,
0x200a
),
.
driver_info
=
BTUSB_WRONG_SCO_MTU
},
{
USB_DEVICE
(
0x0a5c
,
0x200a
),
.
driver_info
=
BTUSB_WRONG_SCO_MTU
},
...
@@ -239,6 +242,7 @@ static void btusb_intr_complete(struct urb *urb)
...
@@ -239,6 +242,7 @@ static void btusb_intr_complete(struct urb *urb)
err
=
usb_submit_urb
(
urb
,
GFP_ATOMIC
);
err
=
usb_submit_urb
(
urb
,
GFP_ATOMIC
);
if
(
err
<
0
)
{
if
(
err
<
0
)
{
if
(
err
!=
-
EPERM
)
BT_ERR
(
"%s urb %p failed to resubmit (%d)"
,
BT_ERR
(
"%s urb %p failed to resubmit (%d)"
,
hdev
->
name
,
urb
,
-
err
);
hdev
->
name
,
urb
,
-
err
);
usb_unanchor_urb
(
urb
);
usb_unanchor_urb
(
urb
);
...
@@ -323,6 +327,7 @@ static void btusb_bulk_complete(struct urb *urb)
...
@@ -323,6 +327,7 @@ static void btusb_bulk_complete(struct urb *urb)
err
=
usb_submit_urb
(
urb
,
GFP_ATOMIC
);
err
=
usb_submit_urb
(
urb
,
GFP_ATOMIC
);
if
(
err
<
0
)
{
if
(
err
<
0
)
{
if
(
err
!=
-
EPERM
)
BT_ERR
(
"%s urb %p failed to resubmit (%d)"
,
BT_ERR
(
"%s urb %p failed to resubmit (%d)"
,
hdev
->
name
,
urb
,
-
err
);
hdev
->
name
,
urb
,
-
err
);
usb_unanchor_urb
(
urb
);
usb_unanchor_urb
(
urb
);
...
@@ -412,6 +417,7 @@ static void btusb_isoc_complete(struct urb *urb)
...
@@ -412,6 +417,7 @@ static void btusb_isoc_complete(struct urb *urb)
err
=
usb_submit_urb
(
urb
,
GFP_ATOMIC
);
err
=
usb_submit_urb
(
urb
,
GFP_ATOMIC
);
if
(
err
<
0
)
{
if
(
err
<
0
)
{
if
(
err
!=
-
EPERM
)
BT_ERR
(
"%s urb %p failed to resubmit (%d)"
,
BT_ERR
(
"%s urb %p failed to resubmit (%d)"
,
hdev
->
name
,
urb
,
-
err
);
hdev
->
name
,
urb
,
-
err
);
usb_unanchor_urb
(
urb
);
usb_unanchor_urb
(
urb
);
...
...
include/net/bluetooth/hci.h
View file @
c30ae138
include/net/bluetooth/hci_core.h
View file @
c30ae138
...
@@ -215,8 +215,8 @@ extern rwlock_t hci_dev_list_lock;
...
@@ -215,8 +215,8 @@ extern rwlock_t hci_dev_list_lock;
extern
rwlock_t
hci_cb_list_lock
;
extern
rwlock_t
hci_cb_list_lock
;
/* ----- Inquiry cache ----- */
/* ----- Inquiry cache ----- */
#define INQUIRY_CACHE_AGE_MAX (HZ*30) /
/ 30 seconds
#define INQUIRY_CACHE_AGE_MAX (HZ*30)
/
* 30 seconds */
#define INQUIRY_ENTRY_AGE_MAX (HZ*60) /
/ 60 seconds
#define INQUIRY_ENTRY_AGE_MAX (HZ*60)
/
* 60 seconds */
#define inquiry_cache_lock(c) spin_lock(&c->lock)
#define inquiry_cache_lock(c) spin_lock(&c->lock)
#define inquiry_cache_unlock(c) spin_unlock(&c->lock)
#define inquiry_cache_unlock(c) spin_unlock(&c->lock)
...
...
include/net/bluetooth/l2cap.h
View file @
c30ae138
...
@@ -417,11 +417,11 @@ static inline int l2cap_tx_window_full(struct sock *sk)
...
@@ -417,11 +417,11 @@ static inline int l2cap_tx_window_full(struct sock *sk)
return
sub
==
pi
->
remote_tx_win
;
return
sub
==
pi
->
remote_tx_win
;
}
}
#define __get_txseq(ctrl)
((ctrl) & L2CAP_CTRL_TXSEQ) >> 1
#define __get_txseq(ctrl)
(((ctrl) & L2CAP_CTRL_TXSEQ) >> 1)
#define __get_reqseq(ctrl)
((ctrl) & L2CAP_CTRL_REQSEQ) >> 8
#define __get_reqseq(ctrl)
(((ctrl) & L2CAP_CTRL_REQSEQ) >> 8)
#define __is_iframe(ctrl)
!((ctrl) & L2CAP_CTRL_FRAME_TYPE
)
#define __is_iframe(ctrl)
(!((ctrl) & L2CAP_CTRL_FRAME_TYPE)
)
#define __is_sframe(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 __is_sar_start(ctrl)
(((ctrl) & L2CAP_CTRL_SAR) == L2CAP_SDU_START)
void
l2cap_load
(
void
);
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 Maxim Krasnyansky <maxk@qualcomm.com>
Copyright (C) 2002 Marcel Holtmann <marcel@holtmann.org>
Copyright (C) 2002 Marcel Holtmann <marcel@holtmann.org>
...
@@ -105,7 +105,7 @@
...
@@ -105,7 +105,7 @@
struct
rfcomm_hdr
{
struct
rfcomm_hdr
{
u8
addr
;
u8
addr
;
u8
ctrl
;
u8
ctrl
;
u8
len
;
/
/ Actual size can be 2 bytes
u8
len
;
/
* Actual size can be 2 bytes */
}
__packed
;
}
__packed
;
struct
rfcomm_cmd
{
struct
rfcomm_cmd
{
...
...
include/net/bluetooth/sco.h
View file @
c30ae138
net/bluetooth/bnep/core.c
View file @
c30ae138
...
@@ -648,6 +648,7 @@ int bnep_del_connection(struct bnep_conndel_req *req)
...
@@ -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
)
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
);
memcpy
(
ci
->
dst
,
s
->
eh
.
h_source
,
ETH_ALEN
);
strcpy
(
ci
->
device
,
s
->
dev
->
name
);
strcpy
(
ci
->
device
,
s
->
dev
->
name
);
ci
->
flags
=
s
->
flags
;
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)
...
@@ -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
)
static
void
__cmtp_copy_session
(
struct
cmtp_session
*
session
,
struct
cmtp_conninfo
*
ci
)
{
{
memset
(
ci
,
0
,
sizeof
(
*
ci
));
bacpy
(
&
ci
->
bdaddr
,
&
session
->
bdaddr
);
bacpy
(
&
ci
->
bdaddr
,
&
session
->
bdaddr
);
ci
->
flags
=
session
->
flags
;
ci
->
flags
=
session
->
flags
;
...
...
net/bluetooth/hci_conn.c
View file @
c30ae138
...
@@ -39,7 +39,7 @@
...
@@ -39,7 +39,7 @@
#include <net/sock.h>
#include <net/sock.h>
#include <asm/system.h>
#include <asm/system.h>
#include <
asm
/uaccess.h>
#include <
linux
/uaccess.h>
#include <asm/unaligned.h>
#include <asm/unaligned.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/bluetooth.h>
...
@@ -66,7 +66,8 @@ void hci_acl_connect(struct hci_conn *conn)
...
@@ -66,7 +66,8 @@ void hci_acl_connect(struct hci_conn *conn)
bacpy
(
&
cp
.
bdaddr
,
&
conn
->
dst
);
bacpy
(
&
cp
.
bdaddr
,
&
conn
->
dst
);
cp
.
pscan_rep_mode
=
0x02
;
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
)
{
if
(
inquiry_entry_age
(
ie
)
<=
INQUIRY_ENTRY_AGE_MAX
)
{
cp
.
pscan_rep_mode
=
ie
->
data
.
pscan_rep_mode
;
cp
.
pscan_rep_mode
=
ie
->
data
.
pscan_rep_mode
;
cp
.
pscan_mode
=
ie
->
data
.
pscan_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
...
@@ -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
));
BT_DBG
(
"%s dst %s"
,
hdev
->
name
,
batostr
(
dst
));
if
(
!
(
acl
=
hci_conn_hash_lookup_ba
(
hdev
,
ACL_LINK
,
dst
)))
{
acl
=
hci_conn_hash_lookup_ba
(
hdev
,
ACL_LINK
,
dst
);
if
(
!
(
acl
=
hci_conn_add
(
hdev
,
ACL_LINK
,
dst
)))
if
(
!
acl
)
{
acl
=
hci_conn_add
(
hdev
,
ACL_LINK
,
dst
);
if
(
!
acl
)
return
NULL
;
return
NULL
;
}
}
...
@@ -389,8 +392,10 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8
...
@@ -389,8 +392,10 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8
if
(
type
==
ACL_LINK
)
if
(
type
==
ACL_LINK
)
return
acl
;
return
acl
;
if
(
!
(
sco
=
hci_conn_hash_lookup_ba
(
hdev
,
type
,
dst
)))
{
sco
=
hci_conn_hash_lookup_ba
(
hdev
,
type
,
dst
);
if
(
!
(
sco
=
hci_conn_add
(
hdev
,
type
,
dst
)))
{
if
(
!
sco
)
{
sco
=
hci_conn_add
(
hdev
,
type
,
dst
);
if
(
!
sco
)
{
hci_conn_put
(
acl
);
hci_conn_put
(
acl
);
return
NULL
;
return
NULL
;
}
}
...
@@ -647,10 +652,12 @@ int hci_get_conn_list(void __user *arg)
...
@@ -647,10 +652,12 @@ int hci_get_conn_list(void __user *arg)
size
=
sizeof
(
req
)
+
req
.
conn_num
*
sizeof
(
*
ci
);
size
=
sizeof
(
req
)
+
req
.
conn_num
*
sizeof
(
*
ci
);
if
(
!
(
cl
=
kmalloc
(
size
,
GFP_KERNEL
)))
cl
=
kmalloc
(
size
,
GFP_KERNEL
);
if
(
!
cl
)
return
-
ENOMEM
;
return
-
ENOMEM
;
if
(
!
(
hdev
=
hci_dev_get
(
req
.
dev_id
)))
{
hdev
=
hci_dev_get
(
req
.
dev_id
);
if
(
!
hdev
)
{
kfree
(
cl
);
kfree
(
cl
);
return
-
ENODEV
;
return
-
ENODEV
;
}
}
...
...
net/bluetooth/hci_core.c
View file @
c30ae138
...
@@ -44,7 +44,7 @@
...
@@ -44,7 +44,7 @@
#include <net/sock.h>
#include <net/sock.h>
#include <asm/system.h>
#include <asm/system.h>
#include <
asm
/uaccess.h>
#include <
linux
/uaccess.h>
#include <asm/unaligned.h>
#include <asm/unaligned.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/bluetooth.h>
...
@@ -349,20 +349,23 @@ struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, bdaddr_t *b
...
@@ -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
)
void
hci_inquiry_cache_update
(
struct
hci_dev
*
hdev
,
struct
inquiry_data
*
data
)
{
{
struct
inquiry_cache
*
cache
=
&
hdev
->
inq_cache
;
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
));
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. */
/* 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
;
return
;
e
->
next
=
cache
->
list
;
cache
->
list
=
e
;
ie
->
next
=
cache
->
list
;
cache
->
list
=
ie
;
}
}
memcpy
(
&
e
->
data
,
data
,
sizeof
(
*
data
));
memcpy
(
&
i
e
->
data
,
data
,
sizeof
(
*
data
));
e
->
timestamp
=
jiffies
;
i
e
->
timestamp
=
jiffies
;
cache
->
timestamp
=
jiffies
;
cache
->
timestamp
=
jiffies
;
}
}
...
@@ -430,8 +433,12 @@ int hci_inquiry(void __user *arg)
...
@@ -430,8 +433,12 @@ int hci_inquiry(void __user *arg)
hci_dev_unlock_bh
(
hdev
);
hci_dev_unlock_bh
(
hdev
);
timeo
=
ir
.
length
*
msecs_to_jiffies
(
2000
);
timeo
=
ir
.
length
*
msecs_to_jiffies
(
2000
);
if
(
do_inquiry
&&
(
err
=
hci_request
(
hdev
,
hci_inq_req
,
(
unsigned
long
)
&
ir
,
timeo
))
<
0
)
if
(
do_inquiry
)
{
err
=
hci_request
(
hdev
,
hci_inq_req
,
(
unsigned
long
)
&
ir
,
timeo
);
if
(
err
<
0
)
goto
done
;
goto
done
;
}
/* for unlimited number of responses we will use buffer with 255 entries */
/* for unlimited number of responses we will use buffer with 255 entries */
max_rsp
=
(
ir
.
num_rsp
==
0
)
?
255
:
ir
.
num_rsp
;
max_rsp
=
(
ir
.
num_rsp
==
0
)
?
255
:
ir
.
num_rsp
;
...
@@ -439,7 +446,8 @@ int hci_inquiry(void __user *arg)
...
@@ -439,7 +446,8 @@ int hci_inquiry(void __user *arg)
/* cache_dump can't sleep. Therefore we allocate temp buffer and then
/* cache_dump can't sleep. Therefore we allocate temp buffer and then
* copy it to the user space.
* 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
;
err
=
-
ENOMEM
;
goto
done
;
goto
done
;
}
}
...
@@ -611,7 +619,8 @@ int hci_dev_close(__u16 dev)
...
@@ -611,7 +619,8 @@ int hci_dev_close(__u16 dev)
struct
hci_dev
*
hdev
;
struct
hci_dev
*
hdev
;
int
err
;
int
err
;
if
(
!
(
hdev
=
hci_dev_get
(
dev
)))
hdev
=
hci_dev_get
(
dev
);
if
(
!
hdev
)
return
-
ENODEV
;
return
-
ENODEV
;
err
=
hci_dev_do_close
(
hdev
);
err
=
hci_dev_do_close
(
hdev
);
hci_dev_put
(
hdev
);
hci_dev_put
(
hdev
);
...
@@ -623,7 +632,8 @@ int hci_dev_reset(__u16 dev)
...
@@ -623,7 +632,8 @@ int hci_dev_reset(__u16 dev)
struct
hci_dev
*
hdev
;
struct
hci_dev
*
hdev
;
int
ret
=
0
;
int
ret
=
0
;
if
(
!
(
hdev
=
hci_dev_get
(
dev
)))
hdev
=
hci_dev_get
(
dev
);
if
(
!
hdev
)
return
-
ENODEV
;
return
-
ENODEV
;
hci_req_lock
(
hdev
);
hci_req_lock
(
hdev
);
...
@@ -663,7 +673,8 @@ int hci_dev_reset_stat(__u16 dev)
...
@@ -663,7 +673,8 @@ int hci_dev_reset_stat(__u16 dev)
struct
hci_dev
*
hdev
;
struct
hci_dev
*
hdev
;
int
ret
=
0
;
int
ret
=
0
;
if
(
!
(
hdev
=
hci_dev_get
(
dev
)))
hdev
=
hci_dev_get
(
dev
);
if
(
!
hdev
)
return
-
ENODEV
;
return
-
ENODEV
;
memset
(
&
hdev
->
stat
,
0
,
sizeof
(
struct
hci_dev_stats
));
memset
(
&
hdev
->
stat
,
0
,
sizeof
(
struct
hci_dev_stats
));
...
@@ -682,7 +693,8 @@ int hci_dev_cmd(unsigned int cmd, void __user *arg)
...
@@ -682,7 +693,8 @@ int hci_dev_cmd(unsigned int cmd, void __user *arg)
if
(
copy_from_user
(
&
dr
,
arg
,
sizeof
(
dr
)))
if
(
copy_from_user
(
&
dr
,
arg
,
sizeof
(
dr
)))
return
-
EFAULT
;
return
-
EFAULT
;
if
(
!
(
hdev
=
hci_dev_get
(
dr
.
dev_id
)))
hdev
=
hci_dev_get
(
dr
.
dev_id
);
if
(
!
hdev
)
return
-
ENODEV
;
return
-
ENODEV
;
switch
(
cmd
)
{
switch
(
cmd
)
{
...
@@ -763,7 +775,8 @@ int hci_get_dev_list(void __user *arg)
...
@@ -763,7 +775,8 @@ int hci_get_dev_list(void __user *arg)
size
=
sizeof
(
*
dl
)
+
dev_num
*
sizeof
(
*
dr
);
size
=
sizeof
(
*
dl
)
+
dev_num
*
sizeof
(
*
dr
);
if
(
!
(
dl
=
kzalloc
(
size
,
GFP_KERNEL
)))
dl
=
kzalloc
(
size
,
GFP_KERNEL
);
if
(
!
dl
)
return
-
ENOMEM
;
return
-
ENOMEM
;
dr
=
dl
->
dev_req
;
dr
=
dl
->
dev_req
;
...
@@ -797,7 +810,8 @@ int hci_get_dev_info(void __user *arg)
...
@@ -797,7 +810,8 @@ int hci_get_dev_info(void __user *arg)
if
(
copy_from_user
(
&
di
,
arg
,
sizeof
(
di
)))
if
(
copy_from_user
(
&
di
,
arg
,
sizeof
(
di
)))
return
-
EFAULT
;
return
-
EFAULT
;
if
(
!
(
hdev
=
hci_dev_get
(
di
.
dev_id
)))
hdev
=
hci_dev_get
(
di
.
dev_id
);
if
(
!
hdev
)
return
-
ENODEV
;
return
-
ENODEV
;
strcpy
(
di
.
name
,
hdev
->
name
);
strcpy
(
di
.
name
,
hdev
->
name
);
...
@@ -905,7 +919,7 @@ int hci_register_dev(struct hci_dev *hdev)
...
@@ -905,7 +919,7 @@ int hci_register_dev(struct hci_dev *hdev)
hdev
->
sniff_max_interval
=
800
;
hdev
->
sniff_max_interval
=
800
;
hdev
->
sniff_min_interval
=
80
;
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
->
rx_task
,
hci_rx_task
,
(
unsigned
long
)
hdev
);
tasklet_init
(
&
hdev
->
tx_task
,
hci_tx_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)
...
@@ -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
;
bt_cb
(
skb
)
->
pkt_type
=
HCI_ACLDATA_PKT
;
hci_add_acl_hdr
(
skb
,
conn
->
handle
,
flags
|
ACL_START
);
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 */
/* Non fragmented */
BT_DBG
(
"%s nonfrag skb %p len %d"
,
hdev
->
name
,
skb
,
skb
->
len
);
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)
...
@@ -1609,7 +1624,8 @@ static inline void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
hci_conn_enter_active_mode
(
conn
);
hci_conn_enter_active_mode
(
conn
);
/* Send to upper protocol */
/* 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
);
hp
->
recv_acldata
(
conn
,
skb
,
flags
);
return
;
return
;
}
}
...
@@ -1644,7 +1660,8 @@ static inline void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
...
@@ -1644,7 +1660,8 @@ static inline void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
register
struct
hci_proto
*
hp
;
register
struct
hci_proto
*
hp
;
/* Send to upper protocol */
/* 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
);
hp
->
recv_scodata
(
conn
,
skb
);
return
;
return
;
}
}
...
@@ -1727,7 +1744,8 @@ static void hci_cmd_task(unsigned long arg)
...
@@ -1727,7 +1744,8 @@ static void hci_cmd_task(unsigned long arg)
if
(
atomic_read
(
&
hdev
->
cmd_cnt
)
&&
(
skb
=
skb_dequeue
(
&
hdev
->
cmd_q
)))
{
if
(
atomic_read
(
&
hdev
->
cmd_cnt
)
&&
(
skb
=
skb_dequeue
(
&
hdev
->
cmd_q
)))
{
kfree_skb
(
hdev
->
sent_cmd
);
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
);
atomic_dec
(
&
hdev
->
cmd_cnt
);
hci_send_frame
(
skb
);
hci_send_frame
(
skb
);
hdev
->
cmd_last_tx
=
jiffies
;
hdev
->
cmd_last_tx
=
jiffies
;
...
...
net/bluetooth/hci_event.c
View file @
c30ae138
...
@@ -39,7 +39,7 @@
...
@@ -39,7 +39,7 @@
#include <net/sock.h>
#include <net/sock.h>
#include <asm/system.h>
#include <asm/system.h>
#include <
asm
/uaccess.h>
#include <
linux
/uaccess.h>
#include <asm/unaligned.h>
#include <asm/unaligned.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/bluetooth.h>
...
@@ -677,9 +677,50 @@ static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
...
@@ -677,9 +677,50 @@ static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
hci_dev_unlock
(
hdev
);
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
)
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
);
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
)
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
...
@@ -955,12 +996,14 @@ static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *sk
hci_dev_lock
(
hdev
);
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
);
memcpy
(
ie
->
data
.
dev_class
,
ev
->
dev_class
,
3
);
conn
=
hci_conn_hash_lookup_ba
(
hdev
,
ev
->
link_type
,
&
ev
->
bdaddr
);
conn
=
hci_conn_hash_lookup_ba
(
hdev
,
ev
->
link_type
,
&
ev
->
bdaddr
);
if
(
!
conn
)
{
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"
);
BT_ERR
(
"No memory for new connection"
);
hci_dev_unlock
(
hdev
);
hci_dev_unlock
(
hdev
);
return
;
return
;
...
@@ -1090,9 +1133,23 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s
...
@@ -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
)
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
);
BT_DBG
(
"%s"
,
hdev
->
name
);
hci_conn_check_pending
(
hdev
);
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
)
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
...
@@ -1162,33 +1219,39 @@ static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff
hci_dev_lock
(
hdev
);
hci_dev_lock
(
hdev
);
conn
=
hci_conn_hash_lookup_handle
(
hdev
,
__le16_to_cpu
(
ev
->
handle
));
conn
=
hci_conn_hash_lookup_handle
(
hdev
,
__le16_to_cpu
(
ev
->
handle
));
if
(
conn
)
{
if
(
!
conn
)
goto
unlock
;
if
(
!
ev
->
status
)
if
(
!
ev
->
status
)
memcpy
(
conn
->
features
,
ev
->
features
,
8
);
memcpy
(
conn
->
features
,
ev
->
features
,
8
);
if
(
conn
->
state
==
BT_CONFIG
)
{
if
(
conn
->
state
!=
BT_CONFIG
)
if
(
!
ev
->
status
&&
lmp_ssp_capable
(
hdev
)
&&
goto
unlock
;
lmp_ssp_capable
(
conn
))
{
if
(
!
ev
->
status
&&
lmp_ssp_capable
(
hdev
)
&&
lmp_ssp_capable
(
conn
))
{
struct
hci_cp_read_remote_ext_features
cp
;
struct
hci_cp_read_remote_ext_features
cp
;
cp
.
handle
=
ev
->
handle
;
cp
.
handle
=
ev
->
handle
;
cp
.
page
=
0x01
;
cp
.
page
=
0x01
;
hci_send_cmd
(
hdev
,
hci_send_cmd
(
hdev
,
HCI_OP_READ_REMOTE_EXT_FEATURES
,
HCI_OP_READ_REMOTE_EXT_FEATURES
,
sizeof
(
cp
),
&
cp
);
sizeof
(
cp
),
&
cp
);
}
else
if
(
!
ev
->
status
&&
conn
->
out
&&
goto
unlock
;
conn
->
sec_level
==
BT_SECURITY_HIGH
)
{
}
struct
hci_cp_auth_requested
cp
;
cp
.
handle
=
ev
->
handle
;
if
(
!
ev
->
status
)
{
hci_send_cmd
(
hdev
,
HCI_OP_AUTH_REQUESTED
,
struct
hci_cp_remote_name_req
cp
;
sizeof
(
cp
),
&
cp
);
memset
(
&
cp
,
0
,
sizeof
(
cp
));
}
else
{
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
;
conn
->
state
=
BT_CONNECTED
;
hci_proto_connect_cfm
(
conn
,
ev
->
status
);
hci_proto_connect_cfm
(
conn
,
ev
->
status
);
hci_conn_put
(
conn
);
hci_conn_put
(
conn
);
}
}
}
}
unlock:
hci_dev_unlock
(
hdev
);
hci_dev_unlock
(
hdev
);
}
}
...
@@ -1449,10 +1512,12 @@ static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *s
...
@@ -1449,10 +1512,12 @@ static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *s
conn
->
sent
-=
count
;
conn
->
sent
-=
count
;
if
(
conn
->
type
==
ACL_LINK
)
{
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
;
hdev
->
acl_cnt
=
hdev
->
acl_pkts
;
}
else
{
}
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
;
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
...
@@ -1547,7 +1612,8 @@ static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *sk
if
(
conn
&&
!
ev
->
status
)
{
if
(
conn
&&
!
ev
->
status
)
{
struct
inquiry_entry
*
ie
;
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
->
data
.
clock_offset
=
ev
->
clock_offset
;
ie
->
timestamp
=
jiffies
;
ie
->
timestamp
=
jiffies
;
}
}
...
@@ -1581,7 +1647,8 @@ static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *
...
@@ -1581,7 +1647,8 @@ static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *
hci_dev_lock
(
hdev
);
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
->
data
.
pscan_rep_mode
=
ev
->
pscan_rep_mode
;
ie
->
timestamp
=
jiffies
;
ie
->
timestamp
=
jiffies
;
}
}
...
@@ -1646,32 +1713,37 @@ static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_b
...
@@ -1646,32 +1713,37 @@ static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_b
hci_dev_lock
(
hdev
);
hci_dev_lock
(
hdev
);
conn
=
hci_conn_hash_lookup_handle
(
hdev
,
__le16_to_cpu
(
ev
->
handle
));
conn
=
hci_conn_hash_lookup_handle
(
hdev
,
__le16_to_cpu
(
ev
->
handle
));
if
(
conn
)
{
if
(
!
conn
)
goto
unlock
;
if
(
!
ev
->
status
&&
ev
->
page
==
0x01
)
{
if
(
!
ev
->
status
&&
ev
->
page
==
0x01
)
{
struct
inquiry_entry
*
ie
;
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
.
ssp_mode
=
(
ev
->
features
[
0
]
&
0x01
);
ie
->
data
.
ssp_mode
=
(
ev
->
features
[
0
]
&
0x01
);
conn
->
ssp_mode
=
(
ev
->
features
[
0
]
&
0x01
);
conn
->
ssp_mode
=
(
ev
->
features
[
0
]
&
0x01
);
}
}
if
(
conn
->
state
==
BT_CONFIG
)
{
if
(
conn
->
state
!=
BT_CONFIG
)
if
(
!
ev
->
status
&&
hdev
->
ssp_mode
>
0
&&
goto
unlock
;
conn
->
ssp_mode
>
0
&&
conn
->
out
&&
conn
->
sec_level
!=
BT_SECURITY_SDP
)
{
if
(
!
ev
->
status
)
{
struct
hci_cp_auth_requested
cp
;
struct
hci_cp_remote_name_req
cp
;
cp
.
handle
=
ev
->
handle
;
memset
(
&
cp
,
0
,
sizeof
(
cp
));
hci_send_cmd
(
hdev
,
HCI_OP_AUTH_REQUESTED
,
bacpy
(
&
cp
.
bdaddr
,
&
conn
->
dst
);
sizeof
(
cp
),
&
cp
);
cp
.
pscan_rep_mode
=
0x02
;
}
else
{
hci_send_cmd
(
hdev
,
HCI_OP_REMOTE_NAME_REQ
,
sizeof
(
cp
),
&
cp
);
}
if
(
!
hci_outgoing_auth_needed
(
hdev
,
conn
))
{
conn
->
state
=
BT_CONNECTED
;
conn
->
state
=
BT_CONNECTED
;
hci_proto_connect_cfm
(
conn
,
ev
->
status
);
hci_proto_connect_cfm
(
conn
,
ev
->
status
);
hci_conn_put
(
conn
);
hci_conn_put
(
conn
);
}
}
}
}
unlock:
hci_dev_unlock
(
hdev
);
hci_dev_unlock
(
hdev
);
}
}
...
@@ -1821,7 +1893,8 @@ static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_
...
@@ -1821,7 +1893,8 @@ static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_
hci_dev_lock
(
hdev
);
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
);
ie
->
data
.
ssp_mode
=
(
ev
->
features
[
0
]
&
0x01
);
hci_dev_unlock
(
hdev
);
hci_dev_unlock
(
hdev
);
...
...
net/bluetooth/hci_sock.c
View file @
c30ae138
...
@@ -43,7 +43,7 @@
...
@@ -43,7 +43,7 @@
#include <net/sock.h>
#include <net/sock.h>
#include <asm/system.h>
#include <asm/system.h>
#include <
asm
/uaccess.h>
#include <
linux
/uaccess.h>
#include <asm/unaligned.h>
#include <asm/unaligned.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/bluetooth.h>
...
@@ -125,7 +125,8 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb)
...
@@ -125,7 +125,8 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb)
continue
;
continue
;
}
}
if
(
!
(
nskb
=
skb_clone
(
skb
,
GFP_ATOMIC
)))
nskb
=
skb_clone
(
skb
,
GFP_ATOMIC
);
if
(
!
nskb
)
continue
;
continue
;
/* Put type byte before the data */
/* Put type byte before the data */
...
@@ -370,7 +371,8 @@ static int hci_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_le
...
@@ -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
(
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
;
err
=
-
ENODEV
;
goto
done
;
goto
done
;
}
}
...
@@ -457,7 +459,8 @@ static int hci_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
...
@@ -457,7 +459,8 @@ static int hci_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
if
(
sk
->
sk_state
==
BT_CLOSED
)
if
(
sk
->
sk_state
==
BT_CLOSED
)
return
0
;
return
0
;
if
(
!
(
skb
=
skb_recv_datagram
(
sk
,
flags
,
noblock
,
&
err
)))
skb
=
skb_recv_datagram
(
sk
,
flags
,
noblock
,
&
err
);
if
(
!
skb
)
return
err
;
return
err
;
msg
->
msg_namelen
=
0
;
msg
->
msg_namelen
=
0
;
...
@@ -499,7 +502,8 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
...
@@ -499,7 +502,8 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
lock_sock
(
sk
);
lock_sock
(
sk
);
if
(
!
(
hdev
=
hci_pi
(
sk
)
->
hdev
))
{
hdev
=
hci_pi
(
sk
)
->
hdev
;
if
(
!
hdev
)
{
err
=
-
EBADFD
;
err
=
-
EBADFD
;
goto
done
;
goto
done
;
}
}
...
@@ -509,7 +513,8 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
...
@@ -509,7 +513,8 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
goto
done
;
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
;
goto
done
;
if
(
memcpy_fromiovec
(
skb_put
(
skb
,
len
),
msg
->
msg_iov
,
len
))
{
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)
...
@@ -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
)
static
void
__hidp_copy_session
(
struct
hidp_session
*
session
,
struct
hidp_conninfo
*
ci
)
{
{
memset
(
ci
,
0
,
sizeof
(
*
ci
));
bacpy
(
&
ci
->
bdaddr
,
&
session
->
bdaddr
);
bacpy
(
&
ci
->
bdaddr
,
&
session
->
bdaddr
);
ci
->
flags
=
session
->
flags
;
ci
->
flags
=
session
->
flags
;
...
@@ -115,7 +116,6 @@ static void __hidp_copy_session(struct hidp_session *session, struct hidp_connin
...
@@ -115,7 +116,6 @@ static void __hidp_copy_session(struct hidp_session *session, struct hidp_connin
ci
->
vendor
=
0x0000
;
ci
->
vendor
=
0x0000
;
ci
->
product
=
0x0000
;
ci
->
product
=
0x0000
;
ci
->
version
=
0x0000
;
ci
->
version
=
0x0000
;
memset
(
ci
->
name
,
0
,
128
);
if
(
session
->
input
)
{
if
(
session
->
input
)
{
ci
->
vendor
=
session
->
input
->
id
.
vendor
;
ci
->
vendor
=
session
->
input
->
id
.
vendor
;
...
...
net/bluetooth/l2cap.c
View file @
c30ae138
...
@@ -57,7 +57,7 @@
...
@@ -57,7 +57,7 @@
#define VERSION "2.15"
#define VERSION "2.15"
static
int
disable_ertm
=
0
;
static
int
disable_ertm
;
static
u32
l2cap_feat_mask
=
L2CAP_FEAT_FIXED_CHAN
;
static
u32
l2cap_feat_mask
=
L2CAP_FEAT_FIXED_CHAN
;
static
u8
l2cap_fixed_chan
[
8
]
=
{
0x02
,
};
static
u8
l2cap_fixed_chan
[
8
]
=
{
0x02
,
};
...
@@ -83,6 +83,18 @@ static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
...
@@ -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
);
static
int
l2cap_ertm_data_rcv
(
struct
sock
*
sk
,
struct
sk_buff
*
skb
);
/* ---- L2CAP timers ---- */
/* ---- 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
)
static
void
l2cap_sock_timeout
(
unsigned
long
arg
)
{
{
struct
sock
*
sk
=
(
struct
sock
*
)
arg
;
struct
sock
*
sk
=
(
struct
sock
*
)
arg
;
...
@@ -92,6 +104,14 @@ static void l2cap_sock_timeout(unsigned long arg)
...
@@ -92,6 +104,14 @@ static void l2cap_sock_timeout(unsigned long arg)
bh_lock_sock
(
sk
);
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
)
if
(
sk
->
sk_state
==
BT_CONNECTED
||
sk
->
sk_state
==
BT_CONFIG
)
reason
=
ECONNREFUSED
;
reason
=
ECONNREFUSED
;
else
if
(
sk
->
sk_state
==
BT_CONNECT
&&
else
if
(
sk
->
sk_state
==
BT_CONNECT
&&
...
@@ -108,18 +128,6 @@ static void l2cap_sock_timeout(unsigned long arg)
...
@@ -108,18 +128,6 @@ static void l2cap_sock_timeout(unsigned long arg)
sock_put
(
sk
);
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 ---- */
/* ---- L2CAP channels ---- */
static
struct
sock
*
__l2cap_get_chan_by_dcid
(
struct
l2cap_chan_list
*
l
,
u16
cid
)
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)
...
@@ -743,11 +751,13 @@ static struct sock *__l2cap_get_sock_by_addr(__le16 psm, bdaddr_t *src)
/* Find socket with psm and source bdaddr.
/* Find socket with psm and source bdaddr.
* Returns closest match.
* 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
sock
*
sk
=
NULL
,
*
sk1
=
NULL
;
struct
hlist_node
*
node
;
struct
hlist_node
*
node
;
read_lock
(
&
l2cap_sk_list
.
lock
);
sk_for_each
(
sk
,
node
,
&
l2cap_sk_list
.
head
)
{
sk_for_each
(
sk
,
node
,
&
l2cap_sk_list
.
head
)
{
if
(
state
&&
sk
->
sk_state
!=
state
)
if
(
state
&&
sk
->
sk_state
!=
state
)
continue
;
continue
;
...
@@ -762,20 +772,10 @@ static struct sock *__l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src
...
@@ -762,20 +772,10 @@ static struct sock *__l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src
sk1
=
sk
;
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
);
read_unlock
(
&
l2cap_sk_list
.
lock
);
return
s
;
return
node
?
sk
:
sk1
;
}
}
static
void
l2cap_sock_destruct
(
struct
sock
*
sk
)
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
...
@@ -2926,6 +2926,8 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd
goto
sendresp
;
goto
sendresp
;
}
}
bh_lock_sock
(
parent
);
/* Check if the ACL is secure enough (if not SDP) */
/* Check if the ACL is secure enough (if not SDP) */
if
(
psm
!=
cpu_to_le16
(
0x0001
)
&&
if
(
psm
!=
cpu_to_le16
(
0x0001
)
&&
!
hci_conn_check_link_mode
(
conn
->
hcon
))
{
!
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
...
@@ -3078,6 +3080,14 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd
break
;
break
;
default:
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
);
l2cap_chan_del
(
sk
,
ECONNREFUSED
);
break
;
break
;
}
}
...
@@ -3283,6 +3293,15 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd
...
@@ -3283,6 +3293,15 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd
sk
->
sk_shutdown
=
SHUTDOWN_MASK
;
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
);
l2cap_chan_del
(
sk
,
ECONNRESET
);
bh_unlock_sock
(
sk
);
bh_unlock_sock
(
sk
);
...
@@ -3305,6 +3324,15 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd
...
@@ -3305,6 +3324,15 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd
if
(
!
sk
)
if
(
!
sk
)
return
0
;
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
);
l2cap_chan_del
(
sk
,
0
);
bh_unlock_sock
(
sk
);
bh_unlock_sock
(
sk
);
...
@@ -4134,12 +4162,11 @@ static inline void l2cap_data_channel_rrframe(struct sock *sk, u16 rx_control)
...
@@ -4134,12 +4162,11 @@ static inline void l2cap_data_channel_rrframe(struct sock *sk, u16 rx_control)
__mod_retrans_timer
();
__mod_retrans_timer
();
pi
->
conn_state
&=
~
L2CAP_CONN_REMOTE_BUSY
;
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
);
l2cap_send_ack
(
pi
);
}
else
{
else
l2cap_ertm_send
(
sk
);
l2cap_ertm_send
(
sk
);
}
}
}
}
}
static
inline
void
l2cap_data_channel_rejframe
(
struct
sock
*
sk
,
u16
rx_control
)
static
inline
void
l2cap_data_channel_rejframe
(
struct
sock
*
sk
,
u16
rx_control
)
...
@@ -4430,6 +4457,8 @@ static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, str
...
@@ -4430,6 +4457,8 @@ static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, str
if
(
!
sk
)
if
(
!
sk
)
goto
drop
;
goto
drop
;
bh_lock_sock
(
sk
);
BT_DBG
(
"sk %p, len %d"
,
sk
,
skb
->
len
);
BT_DBG
(
"sk %p, len %d"
,
sk
,
skb
->
len
);
if
(
sk
->
sk_state
!=
BT_BOUND
&&
sk
->
sk_state
!=
BT_CONNECTED
)
if
(
sk
->
sk_state
!=
BT_BOUND
&&
sk
->
sk_state
!=
BT_CONNECTED
)
...
@@ -4841,8 +4870,10 @@ static int __init l2cap_init(void)
...
@@ -4841,8 +4870,10 @@ static int __init l2cap_init(void)
return
err
;
return
err
;
_busy_wq
=
create_singlethread_workqueue
(
"l2cap"
);
_busy_wq
=
create_singlethread_workqueue
(
"l2cap"
);
if
(
!
_busy_wq
)
if
(
!
_busy_wq
)
{
goto
error
;
proto_unregister
(
&
l2cap_proto
);
return
-
ENOMEM
;
}
err
=
bt_sock_register
(
BTPROTO_L2CAP
,
&
l2cap_sock_family_ops
);
err
=
bt_sock_register
(
BTPROTO_L2CAP
,
&
l2cap_sock_family_ops
);
if
(
err
<
0
)
{
if
(
err
<
0
)
{
...
@@ -4870,6 +4901,7 @@ static int __init l2cap_init(void)
...
@@ -4870,6 +4901,7 @@ static int __init l2cap_init(void)
return
0
;
return
0
;
error:
error:
destroy_workqueue
(
_busy_wq
);
proto_unregister
(
&
l2cap_proto
);
proto_unregister
(
&
l2cap_proto
);
return
err
;
return
err
;
}
}
...
...
net/bluetooth/rfcomm/core.c
View file @
c30ae138
...
@@ -41,7 +41,7 @@
...
@@ -41,7 +41,7 @@
#include <linux/slab.h>
#include <linux/slab.h>
#include <net/sock.h>
#include <net/sock.h>
#include <
asm
/uaccess.h>
#include <
linux
/uaccess.h>
#include <asm/unaligned.h>
#include <asm/unaligned.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/bluetooth.h>
...
@@ -51,10 +51,10 @@
...
@@ -51,10 +51,10 @@
#define VERSION "1.11"
#define VERSION "1.11"
static
int
disable_cfc
=
0
;
static
int
disable_cfc
;
static
int
l2cap_ertm
;
static
int
channel_mtu
=
-
1
;
static
int
channel_mtu
=
-
1
;
static
unsigned
int
l2cap_mtu
=
RFCOMM_MAX_L2CAP_MTU
;
static
unsigned
int
l2cap_mtu
=
RFCOMM_MAX_L2CAP_MTU
;
static
int
l2cap_ertm
=
0
;
static
struct
task_struct
*
rfcomm_thread
;
static
struct
task_struct
*
rfcomm_thread
;
...
@@ -1901,7 +1901,7 @@ static inline void rfcomm_check_connection(struct rfcomm_session *s)
...
@@ -1901,7 +1901,7 @@ static inline void rfcomm_check_connection(struct rfcomm_session *s)
BT_DBG
(
"%p state %ld"
,
s
,
s
->
state
);
BT_DBG
(
"%p state %ld"
,
s
,
s
->
state
);
switch
(
sk
->
sk_state
)
{
switch
(
sk
->
sk_state
)
{
case
BT_CONNECTED
:
case
BT_CONNECTED
:
s
->
state
=
BT_CONNECT
;
s
->
state
=
BT_CONNECT
;
...
...
net/bluetooth/rfcomm/sock.c
View file @
c30ae138
...
@@ -45,7 +45,7 @@
...
@@ -45,7 +45,7 @@
#include <net/sock.h>
#include <net/sock.h>
#include <asm/system.h>
#include <asm/system.h>
#include <
asm
/uaccess.h>
#include <
linux
/uaccess.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
#include <net/bluetooth/hci_core.h>
...
@@ -140,11 +140,13 @@ static struct sock *__rfcomm_get_sock_by_addr(u8 channel, bdaddr_t *src)
...
@@ -140,11 +140,13 @@ static struct sock *__rfcomm_get_sock_by_addr(u8 channel, bdaddr_t *src)
/* Find socket with channel and source bdaddr.
/* Find socket with channel and source bdaddr.
* Returns closest match.
* 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
sock
*
sk
=
NULL
,
*
sk1
=
NULL
;
struct
hlist_node
*
node
;
struct
hlist_node
*
node
;
read_lock
(
&
rfcomm_sk_list
.
lock
);
sk_for_each
(
sk
,
node
,
&
rfcomm_sk_list
.
head
)
{
sk_for_each
(
sk
,
node
,
&
rfcomm_sk_list
.
head
)
{
if
(
state
&&
sk
->
sk_state
!=
state
)
if
(
state
&&
sk
->
sk_state
!=
state
)
continue
;
continue
;
...
@@ -159,19 +161,10 @@ static struct sock *__rfcomm_get_sock_by_channel(int state, u8 channel, bdaddr_t
...
@@ -159,19 +161,10 @@ static struct sock *__rfcomm_get_sock_by_channel(int state, u8 channel, bdaddr_t
sk1
=
sk
;
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
);
read_unlock
(
&
rfcomm_sk_list
.
lock
);
return
s
;
return
node
?
sk
:
sk1
;
}
}
static
void
rfcomm_sock_destruct
(
struct
sock
*
sk
)
static
void
rfcomm_sock_destruct
(
struct
sock
*
sk
)
...
@@ -895,7 +888,8 @@ static int rfcomm_sock_shutdown(struct socket *sock, int how)
...
@@ -895,7 +888,8 @@ static int rfcomm_sock_shutdown(struct socket *sock, int how)
BT_DBG
(
"sock %p, sk %p"
,
sock
,
sk
);
BT_DBG
(
"sock %p, sk %p"
,
sock
,
sk
);
if
(
!
sk
)
return
0
;
if
(
!
sk
)
return
0
;
lock_sock
(
sk
);
lock_sock
(
sk
);
if
(
!
sk
->
sk_shutdown
)
{
if
(
!
sk
->
sk_shutdown
)
{
...
@@ -945,6 +939,8 @@ int rfcomm_connect_ind(struct rfcomm_session *s, u8 channel, struct rfcomm_dlc *
...
@@ -945,6 +939,8 @@ int rfcomm_connect_ind(struct rfcomm_session *s, u8 channel, struct rfcomm_dlc *
if
(
!
parent
)
if
(
!
parent
)
return
0
;
return
0
;
bh_lock_sock
(
parent
);
/* Check for backlog size */
/* Check for backlog size */
if
(
sk_acceptq_is_full
(
parent
))
{
if
(
sk_acceptq_is_full
(
parent
))
{
BT_DBG
(
"backlog full %d"
,
parent
->
sk_ack_backlog
);
BT_DBG
(
"backlog full %d"
,
parent
->
sk_ack_backlog
);
...
...
net/bluetooth/rfcomm/tty.c
View file @
c30ae138
...
@@ -431,7 +431,8 @@ static int rfcomm_release_dev(void __user *arg)
...
@@ -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
);
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
;
return
-
ENODEV
;
if
(
dev
->
flags
!=
NOCAP_FLAGS
&&
!
capable
(
CAP_NET_ADMIN
))
{
if
(
dev
->
flags
!=
NOCAP_FLAGS
&&
!
capable
(
CAP_NET_ADMIN
))
{
...
@@ -470,7 +471,8 @@ static int rfcomm_get_dev_list(void __user *arg)
...
@@ -470,7 +471,8 @@ static int rfcomm_get_dev_list(void __user *arg)
size
=
sizeof
(
*
dl
)
+
dev_num
*
sizeof
(
*
di
);
size
=
sizeof
(
*
dl
)
+
dev_num
*
sizeof
(
*
di
);
if
(
!
(
dl
=
kmalloc
(
size
,
GFP_KERNEL
)))
dl
=
kmalloc
(
size
,
GFP_KERNEL
);
if
(
!
dl
)
return
-
ENOMEM
;
return
-
ENOMEM
;
di
=
dl
->
dev_info
;
di
=
dl
->
dev_info
;
...
@@ -513,7 +515,8 @@ static int rfcomm_get_dev_info(void __user *arg)
...
@@ -513,7 +515,8 @@ static int rfcomm_get_dev_info(void __user *arg)
if
(
copy_from_user
(
&
di
,
arg
,
sizeof
(
di
)))
if
(
copy_from_user
(
&
di
,
arg
,
sizeof
(
di
)))
return
-
EFAULT
;
return
-
EFAULT
;
if
(
!
(
dev
=
rfcomm_dev_get
(
di
.
id
)))
dev
=
rfcomm_dev_get
(
di
.
id
);
if
(
!
dev
)
return
-
ENODEV
;
return
-
ENODEV
;
di
.
flags
=
dev
->
flags
;
di
.
flags
=
dev
->
flags
;
...
@@ -561,7 +564,8 @@ static void rfcomm_dev_data_ready(struct rfcomm_dlc *dlc, struct sk_buff *skb)
...
@@ -561,7 +564,8 @@ static void rfcomm_dev_data_ready(struct rfcomm_dlc *dlc, struct sk_buff *skb)
return
;
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
);
skb_queue_tail
(
&
dev
->
pending
,
skb
);
return
;
return
;
}
}
...
@@ -796,7 +800,8 @@ static int rfcomm_tty_write(struct tty_struct *tty, const unsigned char *buf, in
...
@@ -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
);
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
);
kfree_skb
(
skb
);
break
;
break
;
}
}
...
@@ -892,7 +897,7 @@ static void rfcomm_tty_set_termios(struct tty_struct *tty, struct ktermios *old)
...
@@ -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 */
/* Parity on/off and when on, odd/even */
if
(((
old
->
c_cflag
&
PARENB
)
!=
(
new
->
c_cflag
&
PARENB
))
||
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
;
changes
|=
RFCOMM_RPN_PM_PARITY
;
BT_DBG
(
"Parity change detected."
);
BT_DBG
(
"Parity change detected."
);
}
}
...
@@ -937,11 +942,10 @@ static void rfcomm_tty_set_termios(struct tty_struct *tty, struct ktermios *old)
...
@@ -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
/* POSIX does not support 1.5 stop bits and RFCOMM does not
* support 2 stop bits. So a request for 2 stop bits gets
* support 2 stop bits. So a request for 2 stop bits gets
* translated to 1.5 stop bits */
* translated to 1.5 stop bits */
if
(
new
->
c_cflag
&
CSTOPB
)
{
if
(
new
->
c_cflag
&
CSTOPB
)
stop_bits
=
RFCOMM_RPN_STOP_15
;
stop_bits
=
RFCOMM_RPN_STOP_15
;
}
else
{
else
stop_bits
=
RFCOMM_RPN_STOP_1
;
stop_bits
=
RFCOMM_RPN_STOP_1
;
}
/* Handle number of data bits [5-8] */
/* Handle number of data bits [5-8] */
if
((
old
->
c_cflag
&
CSIZE
)
!=
(
new
->
c_cflag
&
CSIZE
))
if
((
old
->
c_cflag
&
CSIZE
)
!=
(
new
->
c_cflag
&
CSIZE
))
...
...
net/bluetooth/sco.c
View file @
c30ae138
...
@@ -44,7 +44,7 @@
...
@@ -44,7 +44,7 @@
#include <net/sock.h>
#include <net/sock.h>
#include <asm/system.h>
#include <asm/system.h>
#include <
asm
/uaccess.h>
#include <
linux
/uaccess.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
#include <net/bluetooth/hci_core.h>
...
@@ -52,7 +52,7 @@
...
@@ -52,7 +52,7 @@
#define VERSION "0.6"
#define VERSION "0.6"
static
int
disable_esco
=
0
;
static
int
disable_esco
;
static
const
struct
proto_ops
sco_sock_ops
;
static
const
struct
proto_ops
sco_sock_ops
;
...
@@ -138,16 +138,17 @@ static inline struct sock *sco_chan_get(struct sco_conn *conn)
...
@@ -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
)
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
;
struct
sock
*
sk
;
if
(
!
(
conn
=
hcon
->
sco_data
)
)
if
(
!
conn
)
return
0
;
return
0
;
BT_DBG
(
"hcon %p conn %p, err %d"
,
hcon
,
conn
,
err
);
BT_DBG
(
"hcon %p conn %p, err %d"
,
hcon
,
conn
,
err
);
/* Kill socket */
/* Kill socket */
if
((
sk
=
sco_chan_get
(
conn
)))
{
sk
=
sco_chan_get
(
conn
);
if
(
sk
)
{
bh_lock_sock
(
sk
);
bh_lock_sock
(
sk
);
sco_sock_clear_timer
(
sk
);
sco_sock_clear_timer
(
sk
);
sco_chan_del
(
sk
,
err
);
sco_chan_del
(
sk
,
err
);
...
@@ -185,7 +186,8 @@ static int sco_connect(struct sock *sk)
...
@@ -185,7 +186,8 @@ static int sco_connect(struct sock *sk)
BT_DBG
(
"%s -> %s"
,
batostr
(
src
),
batostr
(
dst
));
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
;
return
-
EHOSTUNREACH
;
hci_dev_lock_bh
(
hdev
);
hci_dev_lock_bh
(
hdev
);
...
@@ -510,7 +512,8 @@ static int sco_sock_connect(struct socket *sock, struct sockaddr *addr, int alen
...
@@ -510,7 +512,8 @@ static int sco_sock_connect(struct socket *sock, struct sockaddr *addr, int alen
/* Set destination address and psm */
/* Set destination address and psm */
bacpy
(
&
bt_sk
(
sk
)
->
dst
,
&
sa
->
sco_bdaddr
);
bacpy
(
&
bt_sk
(
sk
)
->
dst
,
&
sa
->
sco_bdaddr
);
if
((
err
=
sco_connect
(
sk
)))
err
=
sco_connect
(
sk
);
if
(
err
)
goto
done
;
goto
done
;
err
=
bt_sock_wait_state
(
sk
,
BT_CONNECTED
,
err
=
bt_sock_wait_state
(
sk
,
BT_CONNECTED
,
...
@@ -828,13 +831,14 @@ static void sco_chan_del(struct sock *sk, int err)
...
@@ -828,13 +831,14 @@ static void sco_chan_del(struct sock *sk, int err)
static
void
sco_conn_ready
(
struct
sco_conn
*
conn
)
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
);
BT_DBG
(
"conn %p"
,
conn
);
sco_conn_lock
(
conn
);
sco_conn_lock
(
conn
);
if
(
(
sk
=
conn
->
sk
)
)
{
if
(
sk
)
{
sco_sock_clear_timer
(
sk
);
sco_sock_clear_timer
(
sk
);
bh_lock_sock
(
sk
);
bh_lock_sock
(
sk
);
sk
->
sk_state
=
BT_CONNECTED
;
sk
->
sk_state
=
BT_CONNECTED
;
...
@@ -882,7 +886,7 @@ static int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type)
...
@@ -882,7 +886,7 @@ static int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type)
int
lm
=
0
;
int
lm
=
0
;
if
(
type
!=
SCO_LINK
&&
type
!=
ESCO_LINK
)
if
(
type
!=
SCO_LINK
&&
type
!=
ESCO_LINK
)
return
0
;
return
-
EINVAL
;
BT_DBG
(
"hdev %s, bdaddr %s"
,
hdev
->
name
,
batostr
(
bdaddr
));
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)
...
@@ -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
);
BT_DBG
(
"hcon %p bdaddr %s status %d"
,
hcon
,
batostr
(
&
hcon
->
dst
),
status
);
if
(
hcon
->
type
!=
SCO_LINK
&&
hcon
->
type
!=
ESCO_LINK
)
if
(
hcon
->
type
!=
SCO_LINK
&&
hcon
->
type
!=
ESCO_LINK
)
return
0
;
return
-
EINVAL
;
if
(
!
status
)
{
if
(
!
status
)
{
struct
sco_conn
*
conn
;
struct
sco_conn
*
conn
;
...
@@ -927,7 +931,7 @@ static int sco_disconn_cfm(struct hci_conn *hcon, __u8 reason)
...
@@ -927,7 +931,7 @@ static int sco_disconn_cfm(struct hci_conn *hcon, __u8 reason)
BT_DBG
(
"hcon %p reason %d"
,
hcon
,
reason
);
BT_DBG
(
"hcon %p reason %d"
,
hcon
,
reason
);
if
(
hcon
->
type
!=
SCO_LINK
&&
hcon
->
type
!=
ESCO_LINK
)
if
(
hcon
->
type
!=
SCO_LINK
&&
hcon
->
type
!=
ESCO_LINK
)
return
0
;
return
-
EINVAL
;
sco_conn_del
(
hcon
,
bt_err
(
reason
));
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