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
e4c609fe
Commit
e4c609fe
authored
Oct 03, 2002
by
Maksim Krasnyanskiy
Browse files
Options
Browse Files
Download
Plain Diff
Merge
bk://linux-bt.bkbits.net/bt-2.5
into viper.qualcomm.com:/usr/src/bt-2.5
parents
706e5455
fcde38d4
Changes
11
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
411 additions
and
308 deletions
+411
-308
include/net/bluetooth/bluetooth.h
include/net/bluetooth/bluetooth.h
+1
-10
include/net/bluetooth/hci.h
include/net/bluetooth/hci.h
+14
-22
include/net/bluetooth/hci_core.h
include/net/bluetooth/hci_core.h
+6
-7
net/bluetooth/af_bluetooth.c
net/bluetooth/af_bluetooth.c
+9
-6
net/bluetooth/hci_conn.c
net/bluetooth/hci_conn.c
+3
-6
net/bluetooth/hci_core.c
net/bluetooth/hci_core.c
+76
-35
net/bluetooth/hci_event.c
net/bluetooth/hci_event.c
+5
-8
net/bluetooth/hci_sock.c
net/bluetooth/hci_sock.c
+38
-21
net/bluetooth/l2cap.c
net/bluetooth/l2cap.c
+195
-125
net/bluetooth/lib.c
net/bluetooth/lib.c
+1
-1
net/bluetooth/sco.c
net/bluetooth/sco.c
+63
-67
No files found.
include/net/bluetooth/bluetooth.h
View file @
e4c609fe
...
@@ -50,6 +50,7 @@
...
@@ -50,6 +50,7 @@
#define BTPROTO_HCI 1
#define BTPROTO_HCI 1
#define BTPROTO_SCO 2
#define BTPROTO_SCO 2
#define BTPROTO_RFCOMM 3
#define BTPROTO_RFCOMM 3
#define BTPROTO_BNEP 4
#define SOL_HCI 0
#define SOL_HCI 0
#define SOL_L2CAP 6
#define SOL_L2CAP 6
...
@@ -199,14 +200,4 @@ int hci_sock_cleanup(void);
...
@@ -199,14 +200,4 @@ int hci_sock_cleanup(void);
int
bterr
(
__u16
code
);
int
bterr
(
__u16
code
);
#ifndef MODULE_LICENSE
#define MODULE_LICENSE(x)
#endif
#ifndef list_for_each_safe
#define list_for_each_safe(pos, n, head) \
for (pos = (head)->next, n = pos->next; pos != (head); \
pos = n, n = pos->next)
#endif
#endif
/* __BLUETOOTH_H */
#endif
/* __BLUETOOTH_H */
include/net/bluetooth/hci.h
View file @
e4c609fe
...
@@ -113,10 +113,10 @@ enum {
...
@@ -113,10 +113,10 @@ enum {
#define ACL_PTYPE_MASK (~SCO_PTYPE_MASK)
#define ACL_PTYPE_MASK (~SCO_PTYPE_MASK)
/* ACL flags */
/* ACL flags */
#define ACL_CONT 0x0
00
1
#define ACL_CONT 0x01
#define ACL_START 0x0
00
2
#define ACL_START 0x02
#define ACL_ACTIVE_BCAST 0x0
010
#define ACL_ACTIVE_BCAST 0x0
4
#define ACL_PICO_BCAST 0x0
020
#define ACL_PICO_BCAST 0x0
8
/* Baseband links */
/* Baseband links */
#define SCO_LINK 0x00
#define SCO_LINK 0x00
...
@@ -542,7 +542,7 @@ typedef struct {
...
@@ -542,7 +542,7 @@ typedef struct {
bdaddr_t
bdaddr
;
bdaddr_t
bdaddr
;
__u8
role
;
__u8
role
;
}
__attribute__
((
packed
))
evt_role_change
;
}
__attribute__
((
packed
))
evt_role_change
;
#define EVT_ROLE_CHANGE_SIZE
1
#define EVT_ROLE_CHANGE_SIZE
8
#define EVT_PIN_CODE_REQ 0x16
#define EVT_PIN_CODE_REQ 0x16
typedef
struct
{
typedef
struct
{
...
@@ -658,9 +658,15 @@ struct sockaddr_hci {
...
@@ -658,9 +658,15 @@ struct sockaddr_hci {
#define HCI_DEV_NONE 0xffff
#define HCI_DEV_NONE 0xffff
struct
hci_filter
{
struct
hci_filter
{
__u32
type_mask
;
unsigned
long
type_mask
;
__u32
event_mask
[
2
];
unsigned
long
event_mask
[
2
];
__u16
opcode
;
__u16
opcode
;
};
struct
hci_ufilter
{
__u32
type_mask
;
__u32
event_mask
[
2
];
__u16
opcode
;
};
};
#define HCI_FLT_TYPE_BITS 31
#define HCI_FLT_TYPE_BITS 31
...
@@ -668,20 +674,6 @@ struct hci_filter {
...
@@ -668,20 +674,6 @@ struct hci_filter {
#define HCI_FLT_OGF_BITS 63
#define HCI_FLT_OGF_BITS 63
#define HCI_FLT_OCF_BITS 127
#define HCI_FLT_OCF_BITS 127
#if BITS_PER_LONG == 64
static
inline
void
hci_set_bit
(
int
nr
,
void
*
addr
)
{
*
((
__u32
*
)
addr
+
(
nr
>>
5
))
|=
((
__u32
)
1
<<
(
nr
&
31
));
}
static
inline
int
hci_test_bit
(
int
nr
,
void
*
addr
)
{
return
*
((
__u32
*
)
addr
+
(
nr
>>
5
))
&
((
__u32
)
1
<<
(
nr
&
31
));
}
#else
#define hci_set_bit set_bit
#define hci_test_bit test_bit
#endif
/* Ioctl requests structures */
/* Ioctl requests structures */
struct
hci_dev_stats
{
struct
hci_dev_stats
{
__u32
err_rx
;
__u32
err_rx
;
...
...
include/net/bluetooth/hci_core.h
View file @
e4c609fe
...
@@ -149,7 +149,7 @@ struct hci_conn {
...
@@ -149,7 +149,7 @@ struct hci_conn {
extern
struct
hci_proto
*
hci_proto
[];
extern
struct
hci_proto
*
hci_proto
[];
extern
struct
list_head
hdev_list
;
extern
struct
list_head
hdev_list
;
extern
spin
lock_t
hdev_list_lock
;
extern
rw
lock_t
hdev_list_lock
;
/* ----- Inquiry cache ----- */
/* ----- Inquiry cache ----- */
#define INQUIRY_CACHE_AGE_MAX (HZ*30) // 30 seconds
#define INQUIRY_CACHE_AGE_MAX (HZ*30) // 30 seconds
...
@@ -339,8 +339,8 @@ static inline void hci_sched_tx(struct hci_dev *hdev)
...
@@ -339,8 +339,8 @@ static inline void hci_sched_tx(struct hci_dev *hdev)
/* ----- HCI protocols ----- */
/* ----- HCI protocols ----- */
struct
hci_proto
{
struct
hci_proto
{
char
*
name
;
char
*
name
;
__u32
id
;
unsigned
int
id
;
__u32
flags
;
unsigned
long
flags
;
void
*
priv
;
void
*
priv
;
...
@@ -450,12 +450,11 @@ struct hci_pinfo {
...
@@ -450,12 +450,11 @@ struct hci_pinfo {
#define HCI_SFLT_MAX_OGF 4
#define HCI_SFLT_MAX_OGF 4
struct
hci_sec_filter
{
struct
hci_sec_filter
{
__u32
type_mask
;
unsigned
long
type_mask
;
__u32
event_mask
[
2
];
unsigned
long
event_mask
[
2
];
__u32
ocf_mask
[
HCI_SFLT_MAX_OGF
+
1
][
4
];
unsigned
long
ocf_mask
[
HCI_SFLT_MAX_OGF
+
1
][
4
];
};
};
/* ----- HCI requests ----- */
/* ----- HCI requests ----- */
#define HCI_REQ_DONE 0
#define HCI_REQ_DONE 0
#define HCI_REQ_PEND 1
#define HCI_REQ_PEND 1
...
...
net/bluetooth/af_bluetooth.c
View file @
e4c609fe
...
@@ -27,7 +27,7 @@
...
@@ -27,7 +27,7 @@
*
*
* $Id: af_bluetooth.c,v 1.3 2002/04/17 17:37:15 maxk Exp $
* $Id: af_bluetooth.c,v 1.3 2002/04/17 17:37:15 maxk Exp $
*/
*/
#define VERSION "2.
0
"
#define VERSION "2.
2
"
#include <linux/config.h>
#include <linux/config.h>
#include <linux/module.h>
#include <linux/module.h>
...
@@ -57,7 +57,7 @@
...
@@ -57,7 +57,7 @@
#endif
#endif
/* Bluetooth sockets */
/* Bluetooth sockets */
#define BLUEZ_MAX_PROTO
4
#define BLUEZ_MAX_PROTO
5
static
struct
net_proto_family
*
bluez_proto
[
BLUEZ_MAX_PROTO
];
static
struct
net_proto_family
*
bluez_proto
[
BLUEZ_MAX_PROTO
];
static
kmem_cache_t
*
bluez_sock_cache
;
static
kmem_cache_t
*
bluez_sock_cache
;
...
@@ -136,18 +136,18 @@ struct sock *bluez_sock_alloc(struct socket *sock, int proto, int pi_size, int p
...
@@ -136,18 +136,18 @@ struct sock *bluez_sock_alloc(struct socket *sock, int proto, int pi_size, int p
void
bluez_sock_link
(
struct
bluez_sock_list
*
l
,
struct
sock
*
sk
)
void
bluez_sock_link
(
struct
bluez_sock_list
*
l
,
struct
sock
*
sk
)
{
{
write_lock
(
&
l
->
lock
);
write_lock
_bh
(
&
l
->
lock
);
sk
->
next
=
l
->
head
;
sk
->
next
=
l
->
head
;
l
->
head
=
sk
;
l
->
head
=
sk
;
sock_hold
(
sk
);
sock_hold
(
sk
);
write_unlock
(
&
l
->
lock
);
write_unlock
_bh
(
&
l
->
lock
);
}
}
void
bluez_sock_unlink
(
struct
bluez_sock_list
*
l
,
struct
sock
*
sk
)
void
bluez_sock_unlink
(
struct
bluez_sock_list
*
l
,
struct
sock
*
sk
)
{
{
struct
sock
**
skp
;
struct
sock
**
skp
;
write_lock
(
&
l
->
lock
);
write_lock
_bh
(
&
l
->
lock
);
for
(
skp
=
&
l
->
head
;
*
skp
;
skp
=
&
((
*
skp
)
->
next
))
{
for
(
skp
=
&
l
->
head
;
*
skp
;
skp
=
&
((
*
skp
)
->
next
))
{
if
(
*
skp
==
sk
)
{
if
(
*
skp
==
sk
)
{
*
skp
=
sk
->
next
;
*
skp
=
sk
->
next
;
...
@@ -155,7 +155,7 @@ void bluez_sock_unlink(struct bluez_sock_list *l, struct sock *sk)
...
@@ -155,7 +155,7 @@ void bluez_sock_unlink(struct bluez_sock_list *l, struct sock *sk)
break
;
break
;
}
}
}
}
write_unlock
(
&
l
->
lock
);
write_unlock
_bh
(
&
l
->
lock
);
}
}
void
bluez_accept_enqueue
(
struct
sock
*
parent
,
struct
sock
*
sk
)
void
bluez_accept_enqueue
(
struct
sock
*
parent
,
struct
sock
*
sk
)
...
@@ -265,6 +265,9 @@ unsigned int bluez_sock_poll(struct file * file, struct socket *sock, poll_table
...
@@ -265,6 +265,9 @@ unsigned int bluez_sock_poll(struct file * file, struct socket *sock, poll_table
if
(
sk
->
state
==
BT_CLOSED
)
if
(
sk
->
state
==
BT_CLOSED
)
mask
|=
POLLHUP
;
mask
|=
POLLHUP
;
if
(
sk
->
state
==
BT_CONNECT
||
sk
->
state
==
BT_CONNECT2
)
return
mask
;
if
(
sock_writeable
(
sk
))
if
(
sock_writeable
(
sk
))
mask
|=
POLLOUT
|
POLLWRNORM
|
POLLWRBAND
;
mask
|=
POLLOUT
|
POLLWRNORM
|
POLLWRBAND
;
else
else
...
...
net/bluetooth/hci_conn.c
View file @
e4c609fe
...
@@ -73,7 +73,7 @@ void hci_acl_connect(struct hci_conn *conn)
...
@@ -73,7 +73,7 @@ void hci_acl_connect(struct hci_conn *conn)
bacpy
(
&
cp
.
bdaddr
,
&
conn
->
dst
);
bacpy
(
&
cp
.
bdaddr
,
&
conn
->
dst
);
if
((
ie
=
inquiry_cache_lookup
(
hdev
,
&
conn
->
dst
))
&&
if
((
ie
=
inquiry_cache_lookup
(
hdev
,
&
conn
->
dst
))
&&
inquiry_entry_age
(
ie
)
>
INQUIRY_ENTRY_AGE_MAX
)
{
inquiry_entry_age
(
ie
)
<=
INQUIRY_ENTRY_AGE_MAX
)
{
cp
.
pscan_rep_mode
=
ie
->
info
.
pscan_rep_mode
;
cp
.
pscan_rep_mode
=
ie
->
info
.
pscan_rep_mode
;
cp
.
pscan_mode
=
ie
->
info
.
pscan_mode
;
cp
.
pscan_mode
=
ie
->
info
.
pscan_mode
;
cp
.
clock_offset
=
ie
->
info
.
clock_offset
|
__cpu_to_le16
(
0x8000
);
cp
.
clock_offset
=
ie
->
info
.
clock_offset
|
__cpu_to_le16
(
0x8000
);
...
@@ -188,9 +188,6 @@ int hci_conn_del(struct hci_conn *conn)
...
@@ -188,9 +188,6 @@ int hci_conn_del(struct hci_conn *conn)
acl
->
link
=
NULL
;
acl
->
link
=
NULL
;
hci_conn_put
(
acl
);
hci_conn_put
(
acl
);
}
}
/* Unacked frames */
hdev
->
sco_cnt
+=
conn
->
sent
;
}
else
{
}
else
{
struct
hci_conn
*
sco
=
conn
->
link
;
struct
hci_conn
*
sco
=
conn
->
link
;
if
(
sco
)
if
(
sco
)
...
@@ -220,7 +217,7 @@ struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src)
...
@@ -220,7 +217,7 @@ struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src)
BT_DBG
(
"%s -> %s"
,
batostr
(
src
),
batostr
(
dst
));
BT_DBG
(
"%s -> %s"
,
batostr
(
src
),
batostr
(
dst
));
spin
_lock_bh
(
&
hdev_list_lock
);
read
_lock_bh
(
&
hdev_list_lock
);
list_for_each
(
p
,
&
hdev_list
)
{
list_for_each
(
p
,
&
hdev_list
)
{
struct
hci_dev
*
d
;
struct
hci_dev
*
d
;
...
@@ -248,7 +245,7 @@ struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src)
...
@@ -248,7 +245,7 @@ struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src)
if
(
hdev
)
if
(
hdev
)
hci_dev_hold
(
hdev
);
hci_dev_hold
(
hdev
);
spin
_unlock_bh
(
&
hdev_list_lock
);
read
_unlock_bh
(
&
hdev_list_lock
);
return
hdev
;
return
hdev
;
}
}
...
...
net/bluetooth/hci_core.c
View file @
e4c609fe
...
@@ -30,6 +30,7 @@
...
@@ -30,6 +30,7 @@
#include <linux/config.h>
#include <linux/config.h>
#include <linux/module.h>
#include <linux/module.h>
#include <linux/kmod.h>
#include <linux/types.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/errno.h>
...
@@ -66,7 +67,7 @@ rwlock_t hci_task_lock = RW_LOCK_UNLOCKED;
...
@@ -66,7 +67,7 @@ rwlock_t hci_task_lock = RW_LOCK_UNLOCKED;
/* HCI device list */
/* HCI device list */
LIST_HEAD
(
hdev_list
);
LIST_HEAD
(
hdev_list
);
spinlock_t
hdev_list_lock
;
rwlock_t
hdev_list_lock
=
RW_LOCK_UNLOCKED
;
/* HCI protocols */
/* HCI protocols */
#define HCI_MAX_PROTO 2
#define HCI_MAX_PROTO 2
...
@@ -75,7 +76,6 @@ struct hci_proto *hci_proto[HCI_MAX_PROTO];
...
@@ -75,7 +76,6 @@ struct hci_proto *hci_proto[HCI_MAX_PROTO];
/* HCI notifiers list */
/* HCI notifiers list */
static
struct
notifier_block
*
hci_notifier
;
static
struct
notifier_block
*
hci_notifier
;
/* ---- HCI notifications ---- */
/* ---- HCI notifications ---- */
int
hci_register_notifier
(
struct
notifier_block
*
nb
)
int
hci_register_notifier
(
struct
notifier_block
*
nb
)
...
@@ -93,6 +93,32 @@ void hci_notify(struct hci_dev *hdev, int event)
...
@@ -93,6 +93,32 @@ void hci_notify(struct hci_dev *hdev, int event)
notifier_call_chain
(
&
hci_notifier
,
event
,
hdev
);
notifier_call_chain
(
&
hci_notifier
,
event
,
hdev
);
}
}
/* ---- HCI hotplug support ---- */
#ifdef CONFIG_HOTPLUG
static
int
hci_run_hotplug
(
char
*
dev
,
char
*
action
)
{
char
*
argv
[
3
],
*
envp
[
5
],
dstr
[
20
],
astr
[
32
];
sprintf
(
dstr
,
"DEVICE=%s"
,
dev
);
sprintf
(
astr
,
"ACTION=%s"
,
action
);
argv
[
0
]
=
hotplug_path
;
argv
[
1
]
=
"bluetooth"
;
argv
[
2
]
=
NULL
;
envp
[
0
]
=
"HOME=/"
;
envp
[
1
]
=
"PATH=/sbin:/bin:/usr/sbin:/usr/bin"
;
envp
[
2
]
=
dstr
;
envp
[
3
]
=
astr
;
envp
[
4
]
=
NULL
;
return
call_usermodehelper
(
argv
[
0
],
argv
,
envp
);
}
#else
#define hci_run_hotplug(A...)
#endif
/* ---- HCI requests ---- */
/* ---- HCI requests ---- */
...
@@ -270,7 +296,7 @@ struct hci_dev *hci_dev_get(int index)
...
@@ -270,7 +296,7 @@ struct hci_dev *hci_dev_get(int index)
if
(
index
<
0
)
if
(
index
<
0
)
return
NULL
;
return
NULL
;
spin
_lock
(
&
hdev_list_lock
);
read
_lock
(
&
hdev_list_lock
);
list_for_each
(
p
,
&
hdev_list
)
{
list_for_each
(
p
,
&
hdev_list
)
{
hdev
=
list_entry
(
p
,
struct
hci_dev
,
list
);
hdev
=
list_entry
(
p
,
struct
hci_dev
,
list
);
if
(
hdev
->
id
==
index
)
{
if
(
hdev
->
id
==
index
)
{
...
@@ -280,7 +306,7 @@ struct hci_dev *hci_dev_get(int index)
...
@@ -280,7 +306,7 @@ struct hci_dev *hci_dev_get(int index)
}
}
hdev
=
NULL
;
hdev
=
NULL
;
done:
done:
spin
_unlock
(
&
hdev_list_lock
);
read
_unlock
(
&
hdev_list_lock
);
return
hdev
;
return
hdev
;
}
}
...
@@ -699,7 +725,7 @@ int hci_get_dev_list(unsigned long arg)
...
@@ -699,7 +725,7 @@ int hci_get_dev_list(unsigned long arg)
return
-
ENOMEM
;
return
-
ENOMEM
;
dr
=
dl
->
dev_req
;
dr
=
dl
->
dev_req
;
spin
_lock_bh
(
&
hdev_list_lock
);
read
_lock_bh
(
&
hdev_list_lock
);
list_for_each
(
p
,
&
hdev_list
)
{
list_for_each
(
p
,
&
hdev_list
)
{
struct
hci_dev
*
hdev
;
struct
hci_dev
*
hdev
;
hdev
=
list_entry
(
p
,
struct
hci_dev
,
list
);
hdev
=
list_entry
(
p
,
struct
hci_dev
,
list
);
...
@@ -708,7 +734,7 @@ int hci_get_dev_list(unsigned long arg)
...
@@ -708,7 +734,7 @@ int hci_get_dev_list(unsigned long arg)
if
(
++
n
>=
dev_num
)
if
(
++
n
>=
dev_num
)
break
;
break
;
}
}
spin
_unlock_bh
(
&
hdev_list_lock
);
read
_unlock_bh
(
&
hdev_list_lock
);
dl
->
dev_num
=
n
;
dl
->
dev_num
=
n
;
size
=
n
*
sizeof
(
struct
hci_dev_req
)
+
sizeof
(
__u16
);
size
=
n
*
sizeof
(
struct
hci_dev_req
)
+
sizeof
(
__u16
);
...
@@ -768,7 +794,7 @@ int hci_register_dev(struct hci_dev *hdev)
...
@@ -768,7 +794,7 @@ int hci_register_dev(struct hci_dev *hdev)
if
(
!
hdev
->
open
||
!
hdev
->
close
||
!
hdev
->
destruct
)
if
(
!
hdev
->
open
||
!
hdev
->
close
||
!
hdev
->
destruct
)
return
-
EINVAL
;
return
-
EINVAL
;
spin
_lock_bh
(
&
hdev_list_lock
);
write
_lock_bh
(
&
hdev_list_lock
);
/* Find first available device id */
/* Find first available device id */
list_for_each
(
p
,
&
hdev_list
)
{
list_for_each
(
p
,
&
hdev_list
)
{
...
@@ -807,11 +833,12 @@ int hci_register_dev(struct hci_dev *hdev)
...
@@ -807,11 +833,12 @@ int hci_register_dev(struct hci_dev *hdev)
atomic_set
(
&
hdev
->
promisc
,
0
);
atomic_set
(
&
hdev
->
promisc
,
0
);
hci_notify
(
hdev
,
HCI_DEV_REG
);
MOD_INC_USE_COUNT
;
MOD_INC_USE_COUNT
;
spin_unlock_bh
(
&
hdev_list_lock
);
write_unlock_bh
(
&
hdev_list_lock
);
hci_notify
(
hdev
,
HCI_DEV_REG
);
hci_run_hotplug
(
hdev
->
name
,
"register"
);
return
id
;
return
id
;
}
}
...
@@ -821,13 +848,15 @@ int hci_unregister_dev(struct hci_dev *hdev)
...
@@ -821,13 +848,15 @@ int hci_unregister_dev(struct hci_dev *hdev)
{
{
BT_DBG
(
"%p name %s type %d"
,
hdev
,
hdev
->
name
,
hdev
->
type
);
BT_DBG
(
"%p name %s type %d"
,
hdev
,
hdev
->
name
,
hdev
->
type
);
spin
_lock_bh
(
&
hdev_list_lock
);
write
_lock_bh
(
&
hdev_list_lock
);
list_del
(
&
hdev
->
list
);
list_del
(
&
hdev
->
list
);
spin
_unlock_bh
(
&
hdev_list_lock
);
write
_unlock_bh
(
&
hdev_list_lock
);
hci_dev_do_close
(
hdev
);
hci_dev_do_close
(
hdev
);
hci_notify
(
hdev
,
HCI_DEV_UNREG
);
hci_notify
(
hdev
,
HCI_DEV_UNREG
);
hci_run_hotplug
(
hdev
->
name
,
"unregister"
);
hci_dev_put
(
hdev
);
hci_dev_put
(
hdev
);
MOD_DEC_USE_COUNT
;
MOD_DEC_USE_COUNT
;
...
@@ -1103,14 +1132,13 @@ static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int
...
@@ -1103,14 +1132,13 @@ static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int
{
{
struct
conn_hash
*
h
=
&
hdev
->
conn_hash
;
struct
conn_hash
*
h
=
&
hdev
->
conn_hash
;
struct
hci_conn
*
conn
=
NULL
;
struct
hci_conn
*
conn
=
NULL
;
int
num
=
0
,
min
=
0xffff
;
int
num
=
0
,
min
=
~
0
;
struct
list_head
*
p
;
struct
list_head
*
p
;
/* We don't have to lock device here. Connections are always
/* We don't have to lock device here. Connections are always
* added and removed with TX task disabled. */
* added and removed with TX task disabled. */
list_for_each
(
p
,
&
h
->
list
)
{
list_for_each
(
p
,
&
h
->
list
)
{
struct
hci_conn
*
c
;
struct
hci_conn
*
c
;
c
=
list_entry
(
p
,
struct
hci_conn
,
list
);
c
=
list_entry
(
p
,
struct
hci_conn
,
list
);
if
(
c
->
type
!=
type
||
c
->
state
!=
BT_CONNECTED
if
(
c
->
type
!=
type
||
c
->
state
!=
BT_CONNECTED
...
@@ -1118,14 +1146,15 @@ static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int
...
@@ -1118,14 +1146,15 @@ static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int
continue
;
continue
;
num
++
;
num
++
;
if
(
c
->
sent
<
min
||
type
==
SCO_LINK
)
{
if
(
c
->
sent
<
min
)
{
min
=
c
->
sent
;
min
=
c
->
sent
;
conn
=
c
;
conn
=
c
;
}
}
}
}
if
(
conn
)
{
if
(
conn
)
{
int
q
=
hdev
->
acl_cnt
/
num
;
int
cnt
=
(
type
==
ACL_LINK
?
hdev
->
acl_cnt
:
hdev
->
sco_cnt
);
int
q
=
cnt
/
num
;
*
quote
=
q
?
q
:
1
;
*
quote
=
q
?
q
:
1
;
}
else
}
else
*
quote
=
0
;
*
quote
=
0
;
...
@@ -1134,6 +1163,25 @@ static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int
...
@@ -1134,6 +1163,25 @@ static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int
return
conn
;
return
conn
;
}
}
static
inline
void
hci_acl_tx_to
(
struct
hci_dev
*
hdev
)
{
struct
conn_hash
*
h
=
&
hdev
->
conn_hash
;
struct
list_head
*
p
;
struct
hci_conn
*
c
;
BT_ERR
(
"%s ACL tx timeout"
,
hdev
->
name
);
/* Kill stalled connections */
list_for_each
(
p
,
&
h
->
list
)
{
c
=
list_entry
(
p
,
struct
hci_conn
,
list
);
if
(
c
->
type
==
ACL_LINK
&&
c
->
sent
)
{
BT_ERR
(
"%s killing stalled ACL connection %s"
,
hdev
->
name
,
batostr
(
&
c
->
dst
));
hci_acl_disconn
(
c
,
0x13
);
}
}
}
static
inline
void
hci_sched_acl
(
struct
hci_dev
*
hdev
)
static
inline
void
hci_sched_acl
(
struct
hci_dev
*
hdev
)
{
{
struct
hci_conn
*
conn
;
struct
hci_conn
*
conn
;
...
@@ -1142,21 +1190,19 @@ static inline void hci_sched_acl(struct hci_dev *hdev)
...
@@ -1142,21 +1190,19 @@ static inline void hci_sched_acl(struct hci_dev *hdev)
BT_DBG
(
"%s"
,
hdev
->
name
);
BT_DBG
(
"%s"
,
hdev
->
name
);
if
(
!
hdev
->
acl_cnt
&&
(
jiffies
-
hdev
->
acl_last_tx
)
>
HZ
*
5
)
{
/* ACL tx timeout must be longer than maximum
BT_ERR
(
"%s ACL tx timeout"
,
hdev
->
name
);
* link supervision timeout (40.9 seconds) */
hdev
->
acl_cnt
++
;
if
(
!
hdev
->
acl_cnt
&&
(
jiffies
-
hdev
->
acl_last_tx
)
>
(
HZ
*
45
))
}
hci_acl_tx_to
(
hdev
);
while
(
hdev
->
acl_cnt
&&
(
conn
=
hci_low_sent
(
hdev
,
ACL_LINK
,
&
quote
)))
{
while
(
hdev
->
acl_cnt
&&
(
conn
=
hci_low_sent
(
hdev
,
ACL_LINK
,
&
quote
)))
{
while
(
quote
&&
(
skb
=
skb_dequeue
(
&
conn
->
data_q
)))
{
while
(
quote
--
&&
(
skb
=
skb_dequeue
(
&
conn
->
data_q
)))
{
BT_DBG
(
"skb %p len %d"
,
skb
,
skb
->
len
);
BT_DBG
(
"skb %p len %d"
,
skb
,
skb
->
len
);
hci_send_frame
(
skb
);
hci_send_frame
(
skb
);
hdev
->
acl_last_tx
=
jiffies
;
hdev
->
acl_last_tx
=
jiffies
;
conn
->
sent
++
;
hdev
->
acl_cnt
--
;
hdev
->
acl_cnt
--
;
quote
--
;
conn
->
sent
++
;
}
}
}
}
}
}
...
@@ -1170,15 +1216,14 @@ static inline void hci_sched_sco(struct hci_dev *hdev)
...
@@ -1170,15 +1216,14 @@ static inline void hci_sched_sco(struct hci_dev *hdev)
BT_DBG
(
"%s"
,
hdev
->
name
);
BT_DBG
(
"%s"
,
hdev
->
name
);
while
((
conn
=
hci_low_sent
(
hdev
,
SCO_LINK
,
&
quote
)))
{
while
(
hdev
->
sco_cnt
&&
(
conn
=
hci_low_sent
(
hdev
,
SCO_LINK
,
&
quote
)))
{
while
(
quote
&&
(
skb
=
skb_dequeue
(
&
conn
->
data_q
)))
{
while
(
quote
--
&&
(
skb
=
skb_dequeue
(
&
conn
->
data_q
)))
{
BT_DBG
(
"skb %p len %d"
,
skb
,
skb
->
len
);
BT_DBG
(
"skb %p len %d"
,
skb
,
skb
->
len
);
hci_send_frame
(
skb
);
hci_send_frame
(
skb
);
//
conn->sent++;
conn
->
sent
++
;
//hdev->sco_cnt--;
if
(
conn
->
sent
==
~
0
)
quote
--
;
conn
->
sent
=
0
;
}
}
}
}
}
}
...
@@ -1205,7 +1250,6 @@ static void hci_tx_task(unsigned long arg)
...
@@ -1205,7 +1250,6 @@ static void hci_tx_task(unsigned long arg)
read_unlock
(
&
hci_task_lock
);
read_unlock
(
&
hci_task_lock
);
}
}
/* ----- HCI RX task (incomming data proccessing) ----- */
/* ----- HCI RX task (incomming data proccessing) ----- */
/* ACL data packet */
/* ACL data packet */
...
@@ -1367,9 +1411,6 @@ static void hci_cmd_task(unsigned long arg)
...
@@ -1367,9 +1411,6 @@ static void hci_cmd_task(unsigned long arg)
int
hci_core_init
(
void
)
int
hci_core_init
(
void
)
{
{
/* Init locks */
spin_lock_init
(
&
hdev_list_lock
);
return
0
;
return
0
;
}
}
...
...
net/bluetooth/hci_event.c
View file @
e4c609fe
...
@@ -352,15 +352,12 @@ static void hci_cs_link_ctl(struct hci_dev *hdev, __u16 ocf, __u8 status)
...
@@ -352,15 +352,12 @@ static void hci_cs_link_ctl(struct hci_dev *hdev, __u16 ocf, __u8 status)
hci_dev_lock
(
hdev
);
hci_dev_lock
(
hdev
);
acl
=
conn_hash_lookup_handle
(
hdev
,
handle
);
acl
=
conn_hash_lookup_handle
(
hdev
,
handle
);
if
(
!
acl
||
!
(
sco
=
acl
->
link
))
{
if
(
acl
&&
(
sco
=
acl
->
link
))
{
hci_dev_unlock
(
hdev
);
sco
->
state
=
BT_CLOSED
;
break
;
}
sco
->
state
=
BT_CLOSED
;
hci_proto_connect_cfm
(
sco
,
status
);
hci_conn_del
(
sco
);
hci_proto_connect_cfm
(
sco
,
status
);
}
hci_conn_del
(
sco
);
hci_dev_unlock
(
hdev
);
hci_dev_unlock
(
hdev
);
}
}
...
...
net/bluetooth/hci_sock.c
View file @
e4c609fe
...
@@ -86,7 +86,7 @@ static struct bluez_sock_list hci_sk_list = {
...
@@ -86,7 +86,7 @@ static struct bluez_sock_list hci_sk_list = {
/* Send frame to RAW socket */
/* Send frame to RAW socket */
void
hci_send_to_sock
(
struct
hci_dev
*
hdev
,
struct
sk_buff
*
skb
)
void
hci_send_to_sock
(
struct
hci_dev
*
hdev
,
struct
sk_buff
*
skb
)
{
{
struct
sock
*
sk
;
struct
sock
*
sk
;
BT_DBG
(
"hdev %p len %d"
,
hdev
,
skb
->
len
);
BT_DBG
(
"hdev %p len %d"
,
hdev
,
skb
->
len
);
...
@@ -105,13 +105,13 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb)
...
@@ -105,13 +105,13 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb)
/* Apply filter */
/* Apply filter */
flt
=
&
hci_pi
(
sk
)
->
filter
;
flt
=
&
hci_pi
(
sk
)
->
filter
;
if
(
!
hci_
test_bit
((
skb
->
pkt_type
&
HCI_FLT_TYPE_BITS
),
&
flt
->
type_mask
))
if
(
!
test_bit
((
skb
->
pkt_type
&
HCI_FLT_TYPE_BITS
),
&
flt
->
type_mask
))
continue
;
continue
;
if
(
skb
->
pkt_type
==
HCI_EVENT_PKT
)
{
if
(
skb
->
pkt_type
==
HCI_EVENT_PKT
)
{
register
int
evt
=
(
*
(
__u8
*
)
skb
->
data
&
HCI_FLT_EVENT_BITS
);
register
int
evt
=
(
*
(
__u8
*
)
skb
->
data
&
HCI_FLT_EVENT_BITS
);
if
(
!
hci_test_bit
(
evt
,
&
flt
->
event_mask
))
if
(
!
test_bit
(
evt
,
flt
->
event_mask
))
continue
;
continue
;
if
(
flt
->
opcode
&&
((
evt
==
EVT_CMD_COMPLETE
&&
if
(
flt
->
opcode
&&
((
evt
==
EVT_CMD_COMPLETE
&&
...
@@ -249,7 +249,7 @@ static int hci_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long a
...
@@ -249,7 +249,7 @@ static int hci_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long a
err
=
hci_sock_bound_ioctl
(
sk
,
cmd
,
arg
);
err
=
hci_sock_bound_ioctl
(
sk
,
cmd
,
arg
);
release_sock
(
sk
);
release_sock
(
sk
);
return
err
;
return
err
;
}
;
}
}
}
static
int
hci_sock_bind
(
struct
socket
*
sock
,
struct
sockaddr
*
addr
,
int
addr_len
)
static
int
hci_sock_bind
(
struct
socket
*
sock
,
struct
sockaddr
*
addr
,
int
addr_len
)
...
@@ -393,12 +393,12 @@ static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg, int len,
...
@@ -393,12 +393,12 @@ static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg, int len,
err
=
-
EPERM
;
err
=
-
EPERM
;
if
(
skb
->
pkt_type
==
HCI_COMMAND_PKT
)
{
if
(
skb
->
pkt_type
==
HCI_COMMAND_PKT
)
{
__
u16
opcode
=
__le16_to_cpu
(
*
(
__u16
*
)
skb
->
data
);
u16
opcode
=
__le16_to_cpu
(
*
(
__u16
*
)
skb
->
data
);
__
u16
ogf
=
cmd_opcode_ogf
(
opcode
)
-
1
;
u16
ogf
=
cmd_opcode_ogf
(
opcode
)
-
1
;
__
u16
ocf
=
cmd_opcode_ocf
(
opcode
)
&
HCI_FLT_OCF_BITS
;
u16
ocf
=
cmd_opcode_ocf
(
opcode
)
&
HCI_FLT_OCF_BITS
;
if
(
ogf
>
HCI_SFLT_MAX_OGF
||
if
(
ogf
>
HCI_SFLT_MAX_OGF
||
!
hci_test_bit
(
ocf
,
&
hci_sec_filter
.
ocf_mask
[
ogf
]))
!
test_bit
(
ocf
,
hci_sec_filter
.
ocf_mask
[
ogf
]))
goto
drop
;
goto
drop
;
}
else
}
else
goto
drop
;
goto
drop
;
...
@@ -420,8 +420,8 @@ static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg, int len,
...
@@ -420,8 +420,8 @@ static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg, int len,
int
hci_sock_setsockopt
(
struct
socket
*
sock
,
int
level
,
int
optname
,
char
*
optval
,
int
len
)
int
hci_sock_setsockopt
(
struct
socket
*
sock
,
int
level
,
int
optname
,
char
*
optval
,
int
len
)
{
{
struct
hci_ufilter
uf
=
{
.
opcode
=
0
};
struct
sock
*
sk
=
sock
->
sk
;
struct
sock
*
sk
=
sock
->
sk
;
struct
hci_filter
flt
=
{
opcode
:
0
};
int
err
=
0
,
opt
=
0
;
int
err
=
0
,
opt
=
0
;
BT_DBG
(
"sk %p, opt %d"
,
sk
,
optname
);
BT_DBG
(
"sk %p, opt %d"
,
sk
,
optname
);
...
@@ -454,32 +454,40 @@ int hci_sock_setsockopt(struct socket *sock, int level, int optname, char *optva
...
@@ -454,32 +454,40 @@ int hci_sock_setsockopt(struct socket *sock, int level, int optname, char *optva
break
;
break
;
case
HCI_FILTER
:
case
HCI_FILTER
:
len
=
MIN
(
len
,
sizeof
(
struct
hci_filter
));
len
=
MIN
(
len
,
sizeof
(
uf
));
if
(
copy_from_user
(
&
flt
,
optval
,
len
))
{
if
(
copy_from_user
(
&
uf
,
optval
,
len
))
{
err
=
-
EFAULT
;
err
=
-
EFAULT
;
break
;
break
;
}
}
if
(
!
capable
(
CAP_NET_RAW
))
{
if
(
!
capable
(
CAP_NET_RAW
))
{
flt
.
type_mask
&=
hci_sec_filter
.
type_mask
;
uf
.
type_mask
&=
hci_sec_filter
.
type_mask
;
flt
.
event_mask
[
0
]
&=
hci_sec_filter
.
event_mask
[
0
]
;
uf
.
event_mask
[
0
]
&=
*
((
u32
*
)
hci_sec_filter
.
event_mask
+
0
)
;
flt
.
event_mask
[
1
]
&=
hci_sec_filter
.
event_mask
[
1
]
;
uf
.
event_mask
[
1
]
&=
*
((
u32
*
)
hci_sec_filter
.
event_mask
+
1
)
;
}
}
{
struct
hci_filter
*
f
=
&
hci_pi
(
sk
)
->
filter
;
memcpy
(
&
hci_pi
(
sk
)
->
filter
,
&
flt
,
len
);
f
->
type_mask
=
uf
.
type_mask
;
break
;
f
->
opcode
=
uf
.
opcode
;
*
((
u32
*
)
f
->
event_mask
+
0
)
=
uf
.
event_mask
[
0
];
*
((
u32
*
)
f
->
event_mask
+
1
)
=
uf
.
event_mask
[
0
];
}
break
;
default:
default:
err
=
-
ENOPROTOOPT
;
err
=
-
ENOPROTOOPT
;
break
;
break
;
}
;
}
release_sock
(
sk
);
release_sock
(
sk
);
return
err
;
return
err
;
}
}
int
hci_sock_getsockopt
(
struct
socket
*
sock
,
int
level
,
int
optname
,
char
*
optval
,
int
*
optlen
)
int
hci_sock_getsockopt
(
struct
socket
*
sock
,
int
level
,
int
optname
,
char
*
optval
,
int
*
optlen
)
{
{
struct
hci_ufilter
uf
;
struct
sock
*
sk
=
sock
->
sk
;
struct
sock
*
sk
=
sock
->
sk
;
int
len
,
opt
;
int
len
,
opt
;
...
@@ -508,15 +516,24 @@ int hci_sock_getsockopt(struct socket *sock, int level, int optname, char *optva
...
@@ -508,15 +516,24 @@ int hci_sock_getsockopt(struct socket *sock, int level, int optname, char *optva
break
;
break
;
case
HCI_FILTER
:
case
HCI_FILTER
:
len
=
MIN
(
len
,
sizeof
(
struct
hci_filter
));
{
if
(
copy_to_user
(
optval
,
&
hci_pi
(
sk
)
->
filter
,
len
))
struct
hci_filter
*
f
=
&
hci_pi
(
sk
)
->
filter
;
uf
.
type_mask
=
f
->
type_mask
;
uf
.
opcode
=
f
->
opcode
;
uf
.
event_mask
[
0
]
=
*
((
u32
*
)
f
->
event_mask
+
0
);
uf
.
event_mask
[
0
]
=
*
((
u32
*
)
f
->
event_mask
+
1
);
}
len
=
MIN
(
len
,
sizeof
(
uf
));
if
(
copy_to_user
(
optval
,
&
uf
,
len
))
return
-
EFAULT
;
return
-
EFAULT
;
break
;
break
;
default:
default:
return
-
ENOPROTOOPT
;
return
-
ENOPROTOOPT
;
break
;
break
;
}
;
}
return
0
;
return
0
;
}
}
...
...
net/bluetooth/l2cap.c
View file @
e4c609fe
This diff is collapsed.
Click to expand it.
net/bluetooth/lib.c
View file @
e4c609fe
...
@@ -105,7 +105,7 @@ int bterr(__u16 code)
...
@@ -105,7 +105,7 @@ int bterr(__u16 code)
return
EACCES
;
return
EACCES
;
case
0x06
:
case
0x06
:
return
E
INVAL
;
return
E
BADE
;
case
0x07
:
case
0x07
:
return
ENOMEM
;
return
ENOMEM
;
...
...
net/bluetooth/sco.c
View file @
e4c609fe
...
@@ -27,7 +27,7 @@
...
@@ -27,7 +27,7 @@
*
*
* $Id: sco.c,v 1.3 2002/04/17 17:37:16 maxk Exp $
* $Id: sco.c,v 1.3 2002/04/17 17:37:16 maxk Exp $
*/
*/
#define VERSION "0.
2
"
#define VERSION "0.
3
"
#include <linux/config.h>
#include <linux/config.h>
#include <linux/module.h>
#include <linux/module.h>
...
@@ -67,16 +67,15 @@ static struct bluez_sock_list sco_sk_list = {
...
@@ -67,16 +67,15 @@ static struct bluez_sock_list sco_sk_list = {
.
lock
=
RW_LOCK_UNLOCKED
.
lock
=
RW_LOCK_UNLOCKED
};
};
static
inline
int
sco_chan_add
(
struct
sco_conn
*
conn
,
struct
sock
*
sk
,
struct
sock
*
parent
);
static
void
__
sco_chan_add
(
struct
sco_conn
*
conn
,
struct
sock
*
sk
,
struct
sock
*
parent
);
static
void
sco_chan_del
(
struct
sock
*
sk
,
int
err
);
static
void
sco_chan_del
(
struct
sock
*
sk
,
int
err
);
static
inline
struct
sock
*
sco_chan_get
(
struct
sco_conn
*
conn
);
static
int
sco_conn_del
(
struct
hci_conn
*
conn
,
int
err
);
static
int
sco_conn_del
(
struct
hci_conn
*
conn
,
int
err
);
static
void
sco_sock_close
(
struct
sock
*
sk
);
static
void
sco_sock_close
(
struct
sock
*
sk
);
static
void
sco_sock_kill
(
struct
sock
*
sk
);
static
void
sco_sock_kill
(
struct
sock
*
sk
);
/* ----
- SCO timers --
---- */
/* ----
SCO timers
---- */
static
void
sco_sock_timeout
(
unsigned
long
arg
)
static
void
sco_sock_timeout
(
unsigned
long
arg
)
{
{
struct
sock
*
sk
=
(
struct
sock
*
)
arg
;
struct
sock
*
sk
=
(
struct
sock
*
)
arg
;
...
@@ -115,7 +114,7 @@ static void sco_sock_init_timer(struct sock *sk)
...
@@ -115,7 +114,7 @@ static void sco_sock_init_timer(struct sock *sk)
sk
->
timer
.
data
=
(
unsigned
long
)
sk
;
sk
->
timer
.
data
=
(
unsigned
long
)
sk
;
}
}
/* ----
---- SCO connections -----
---- */
/* ----
SCO connections
---- */
static
struct
sco_conn
*
sco_conn_add
(
struct
hci_conn
*
hcon
,
__u8
status
)
static
struct
sco_conn
*
sco_conn_add
(
struct
hci_conn
*
hcon
,
__u8
status
)
{
{
struct
hci_dev
*
hdev
=
hcon
->
hdev
;
struct
hci_dev
*
hdev
=
hcon
->
hdev
;
...
@@ -150,6 +149,15 @@ static struct sco_conn *sco_conn_add(struct hci_conn *hcon, __u8 status)
...
@@ -150,6 +149,15 @@ static struct sco_conn *sco_conn_add(struct hci_conn *hcon, __u8 status)
return
conn
;
return
conn
;
}
}
static
inline
struct
sock
*
sco_chan_get
(
struct
sco_conn
*
conn
)
{
struct
sock
*
sk
=
NULL
;
sco_conn_lock
(
conn
);
sk
=
conn
->
sk
;
sco_conn_unlock
(
conn
);
return
sk
;
}
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
;
...
@@ -176,6 +184,20 @@ static int sco_conn_del(struct hci_conn *hcon, int err)
...
@@ -176,6 +184,20 @@ static int sco_conn_del(struct hci_conn *hcon, int err)
return
0
;
return
0
;
}
}
static
inline
int
sco_chan_add
(
struct
sco_conn
*
conn
,
struct
sock
*
sk
,
struct
sock
*
parent
)
{
int
err
=
0
;
sco_conn_lock
(
conn
);
if
(
conn
->
sk
)
{
err
=
-
EBUSY
;
}
else
{
__sco_chan_add
(
conn
,
sk
,
parent
);
}
sco_conn_unlock
(
conn
);
return
err
;
}
int
sco_connect
(
struct
sock
*
sk
)
int
sco_connect
(
struct
sock
*
sk
)
{
{
bdaddr_t
*
src
=
&
bluez_sk
(
sk
)
->
src
;
bdaddr_t
*
src
=
&
bluez_sk
(
sk
)
->
src
;
...
@@ -462,23 +484,20 @@ static int sco_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_le
...
@@ -462,23 +484,20 @@ static int sco_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_le
goto
done
;
goto
done
;
}
}
write_lock
(
&
sco_sk_list
.
lock
);
write_lock
_bh
(
&
sco_sk_list
.
lock
);
if
(
bacmp
(
src
,
BDADDR_ANY
)
&&
__sco_get_sock_by_addr
(
src
))
{
if
(
bacmp
(
src
,
BDADDR_ANY
)
&&
__sco_get_sock_by_addr
(
src
))
{
err
=
-
EADDRINUSE
;
err
=
-
EADDRINUSE
;
goto
unlock
;
}
else
{
/* Save source address */
bacpy
(
&
bluez_sk
(
sk
)
->
src
,
&
sa
->
sco_bdaddr
);
sk
->
state
=
BT_BOUND
;
}
}
/* Save source address */
write_unlock_bh
(
&
sco_sk_list
.
lock
);
bacpy
(
&
bluez_sk
(
sk
)
->
src
,
&
sa
->
sco_bdaddr
);
sk
->
state
=
BT_BOUND
;
unlock:
write_unlock
(
&
sco_sk_list
.
lock
);
done:
done:
release_sock
(
sk
);
release_sock
(
sk
);
return
err
;
return
err
;
}
}
...
@@ -649,7 +668,7 @@ int sco_sock_setsockopt(struct socket *sock, int level, int optname, char *optva
...
@@ -649,7 +668,7 @@ int sco_sock_setsockopt(struct socket *sock, int level, int optname, char *optva
default:
default:
err
=
-
ENOPROTOOPT
;
err
=
-
ENOPROTOOPT
;
break
;
break
;
}
;
}
release_sock
(
sk
);
release_sock
(
sk
);
return
err
;
return
err
;
...
@@ -703,7 +722,7 @@ int sco_sock_getsockopt(struct socket *sock, int level, int optname, char *optva
...
@@ -703,7 +722,7 @@ int sco_sock_getsockopt(struct socket *sock, int level, int optname, char *optva
default:
default:
err
=
-
ENOPROTOOPT
;
err
=
-
ENOPROTOOPT
;
break
;
break
;
}
;
}
release_sock
(
sk
);
release_sock
(
sk
);
return
err
;
return
err
;
...
@@ -735,29 +754,6 @@ static void __sco_chan_add(struct sco_conn *conn, struct sock *sk, struct sock *
...
@@ -735,29 +754,6 @@ static void __sco_chan_add(struct sco_conn *conn, struct sock *sk, struct sock *
bluez_accept_enqueue
(
parent
,
sk
);
bluez_accept_enqueue
(
parent
,
sk
);
}
}
static
inline
int
sco_chan_add
(
struct
sco_conn
*
conn
,
struct
sock
*
sk
,
struct
sock
*
parent
)
{
int
err
=
0
;
sco_conn_lock
(
conn
);
if
(
conn
->
sk
)
{
err
=
-
EBUSY
;
}
else
{
__sco_chan_add
(
conn
,
sk
,
parent
);
}
sco_conn_unlock
(
conn
);
return
err
;
}
static
inline
struct
sock
*
sco_chan_get
(
struct
sco_conn
*
conn
)
{
struct
sock
*
sk
=
NULL
;
sco_conn_lock
(
conn
);
sk
=
conn
->
sk
;
sco_conn_unlock
(
conn
);
return
sk
;
}
/* Delete channel.
/* Delete channel.
* Must be called on the locked socket. */
* Must be called on the locked socket. */
static
void
sco_chan_del
(
struct
sock
*
sk
,
int
err
)
static
void
sco_chan_del
(
struct
sock
*
sk
,
int
err
)
...
@@ -895,7 +891,7 @@ static int sco_sock_dump(char *buf, struct bluez_sock_list *list)
...
@@ -895,7 +891,7 @@ static int sco_sock_dump(char *buf, struct bluez_sock_list *list)
struct
sock
*
sk
;
struct
sock
*
sk
;
char
*
ptr
=
buf
;
char
*
ptr
=
buf
;
write_lock
(
&
list
->
lock
);
read_lock_bh
(
&
list
->
lock
);
for
(
sk
=
list
->
head
;
sk
;
sk
=
sk
->
next
)
{
for
(
sk
=
list
->
head
;
sk
;
sk
=
sk
->
next
)
{
pi
=
sco_pi
(
sk
);
pi
=
sco_pi
(
sk
);
...
@@ -904,7 +900,7 @@ static int sco_sock_dump(char *buf, struct bluez_sock_list *list)
...
@@ -904,7 +900,7 @@ static int sco_sock_dump(char *buf, struct bluez_sock_list *list)
sk
->
state
);
sk
->
state
);
}
}
write_unlock
(
&
list
->
lock
);
read_unlock_bh
(
&
list
->
lock
);
ptr
+=
sprintf
(
ptr
,
"
\n
"
);
ptr
+=
sprintf
(
ptr
,
"
\n
"
);
...
@@ -936,36 +932,36 @@ static int sco_read_proc(char *buf, char **start, off_t offset, int count, int *
...
@@ -936,36 +932,36 @@ static int sco_read_proc(char *buf, char **start, off_t offset, int count, int *
}
}
static
struct
proto_ops
sco_sock_ops
=
{
static
struct
proto_ops
sco_sock_ops
=
{
.
family
=
PF_BLUETOOTH
,
.
family
=
PF_BLUETOOTH
,
.
release
=
sco_sock_release
,
.
release
=
sco_sock_release
,
.
bind
=
sco_sock_bind
,
.
bind
=
sco_sock_bind
,
.
connect
=
sco_sock_connect
,
.
connect
=
sco_sock_connect
,
.
listen
=
sco_sock_listen
,
.
listen
=
sco_sock_listen
,
.
accept
=
sco_sock_accept
,
.
accept
=
sco_sock_accept
,
.
getname
=
sco_sock_getname
,
.
getname
=
sco_sock_getname
,
.
sendmsg
=
sco_sock_sendmsg
,
.
sendmsg
=
sco_sock_sendmsg
,
.
recvmsg
=
bluez_sock_recvmsg
,
.
recvmsg
=
bluez_sock_recvmsg
,
.
poll
=
bluez_sock_poll
,
.
poll
=
bluez_sock_poll
,
.
socketpair
=
sock_no_socketpair
,
.
ioctl
=
sock_no_ioctl
,
.
ioctl
=
sock_no_ioctl
,
.
mmap
=
sock_no_mmap
,
.
s
hutdown
=
sock_no_shutdown
,
.
s
ocketpair
=
sock_no_socketpair
,
.
s
etsockopt
=
sco_sock_setsockopt
,
.
s
hutdown
=
sock_no_shutdown
,
.
getsockopt
=
sco_sock_g
etsockopt
,
.
setsockopt
=
sco_sock_s
etsockopt
,
.
mmap
=
sock_no_mmap
.
getsockopt
=
sco_sock_getsockopt
};
};
static
struct
net_proto_family
sco_sock_family_ops
=
{
static
struct
net_proto_family
sco_sock_family_ops
=
{
.
family
=
PF_BLUETOOTH
,
.
family
=
PF_BLUETOOTH
,
.
create
=
sco_sock_create
.
create
=
sco_sock_create
};
};
static
struct
hci_proto
sco_hci_proto
=
{
static
struct
hci_proto
sco_hci_proto
=
{
.
name
=
"SCO"
,
.
name
=
"SCO"
,
.
id
=
HCI_PROTO_SCO
,
.
id
=
HCI_PROTO_SCO
,
.
connect_ind
=
sco_connect_ind
,
.
connect_ind
=
sco_connect_ind
,
.
connect_cfm
=
sco_connect_cfm
,
.
connect_cfm
=
sco_connect_cfm
,
.
disconn_ind
=
sco_disconn_ind
,
.
disconn_ind
=
sco_disconn_ind
,
.
recv_scodata
=
sco_recv_scodata
,
.
recv_scodata
=
sco_recv_scodata
};
};
int
__init
sco_init
(
void
)
int
__init
sco_init
(
void
)
...
...
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