projects
/
GitHub
/
mt8127
/
android_kernel_alcatel_ttab.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Merge tag 'v3.10.55' into update
[GitHub/mt8127/android_kernel_alcatel_ttab.git]
/
net
/
bluetooth
/
sco.c
diff --git
a/net/bluetooth/sco.c
b/net/bluetooth/sco.c
index e7bd4eea575cff782401430147c9cdcc1a1ad6b0..de9c955b247acb7ccf1b4efc0a67dd9819502643 100644
(file)
--- a/
net/bluetooth/sco.c
+++ b/
net/bluetooth/sco.c
@@
-158,6
+158,7
@@
static int sco_connect(struct sock *sk)
{
bdaddr_t *src = &bt_sk(sk)->src;
bdaddr_t *dst = &bt_sk(sk)->dst;
{
bdaddr_t *src = &bt_sk(sk)->src;
bdaddr_t *dst = &bt_sk(sk)->dst;
+ __u16 pkt_type = sco_pi(sk)->pkt_type;
struct sco_conn *conn;
struct hci_conn *hcon;
struct hci_dev *hdev;
struct sco_conn *conn;
struct hci_conn *hcon;
struct hci_dev *hdev;
@@
-173,11
+174,13
@@
static int sco_connect(struct sock *sk)
if (lmp_esco_capable(hdev) && !disable_esco)
type = ESCO_LINK;
if (lmp_esco_capable(hdev) && !disable_esco)
type = ESCO_LINK;
- else
+ else
{
type = SCO_LINK;
type = SCO_LINK;
+ pkt_type &= SCO_ESCO_MASK;
+ }
- hcon = hci_connect(hdev, type,
dst, BDADDR_BREDR, BT_SECURITY_LOW
,
- HCI_AT_NO_BONDING);
+ hcon = hci_connect(hdev, type,
pkt_type, dst, BDADDR_BREDR
,
+
BT_SECURITY_LOW,
HCI_AT_NO_BONDING);
if (IS_ERR(hcon)) {
err = PTR_ERR(hcon);
goto done;
if (IS_ERR(hcon)) {
err = PTR_ERR(hcon);
goto done;
@@
-445,17
+448,21
@@
static int sco_sock_create(struct net *net, struct socket *sock, int protocol,
return 0;
}
return 0;
}
-static int sco_sock_bind(struct socket *sock, struct sockaddr *addr, int a
ddr_
len)
+static int sco_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
{
{
- struct sockaddr_sco
*sa = (struct sockaddr_sco *) addr
;
+ struct sockaddr_sco
sa
;
struct sock *sk = sock->sk;
struct sock *sk = sock->sk;
- int err = 0;
+ int
len,
err = 0;
- BT_DBG("sk %p %pMR", sk, &sa
->
sco_bdaddr);
+ BT_DBG("sk %p %pMR", sk, &sa
.
sco_bdaddr);
if (!addr || addr->sa_family != AF_BLUETOOTH)
return -EINVAL;
if (!addr || addr->sa_family != AF_BLUETOOTH)
return -EINVAL;
+ memset(&sa, 0, sizeof(sa));
+ len = min_t(unsigned int, sizeof(sa), alen);
+ memcpy(&sa, addr, len);
+
lock_sock(sk);
if (sk->sk_state != BT_OPEN) {
lock_sock(sk);
if (sk->sk_state != BT_OPEN) {
@@
-468,7
+475,8
@@
static int sco_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_le
goto done;
}
goto done;
}
- bacpy(&bt_sk(sk)->src, &sa->sco_bdaddr);
+ bacpy(&bt_sk(sk)->src, &sa.sco_bdaddr);
+ sco_pi(sk)->pkt_type = sa.sco_pkt_type;
sk->sk_state = BT_BOUND;
sk->sk_state = BT_BOUND;
@@
-479,26
+487,34
@@
done:
static int sco_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
{
static int sco_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
{
- struct sockaddr_sco *sa = (struct sockaddr_sco *) addr;
struct sock *sk = sock->sk;
struct sock *sk = sock->sk;
- int err;
+ struct sockaddr_sco sa;
+ int len, err;
BT_DBG("sk %p", sk);
BT_DBG("sk %p", sk);
- if (alen < sizeof(struct sockaddr_sco) ||
- addr->sa_family != AF_BLUETOOTH)
+ if (!addr || addr->sa_family != AF_BLUETOOTH)
return -EINVAL;
return -EINVAL;
- if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND)
- return -EBADFD;
-
- if (sk->sk_type != SOCK_SEQPACKET)
- return -EINVAL;
+ memset(&sa, 0, sizeof(sa));
+ len = min_t(unsigned int, sizeof(sa), alen);
+ memcpy(&sa, addr, len);
lock_sock(sk);
lock_sock(sk);
+ if (sk->sk_type != SOCK_SEQPACKET) {
+ err = -EINVAL;
+ goto done;
+ }
+
+ if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND) {
+ err = -EBADFD;
+ goto done;
+ }
+
/* 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);
+ sco_pi(sk)->pkt_type = sa.sco_pkt_type;
err = sco_connect(sk);
if (err)
err = sco_connect(sk);
if (err)
@@
-622,6
+638,7
@@
static int sco_sock_getname(struct socket *sock, struct sockaddr *addr, int *len
bacpy(&sa->sco_bdaddr, &bt_sk(sk)->dst);
else
bacpy(&sa->sco_bdaddr, &bt_sk(sk)->src);
bacpy(&sa->sco_bdaddr, &bt_sk(sk)->dst);
else
bacpy(&sa->sco_bdaddr, &bt_sk(sk)->src);
+ sa->sco_pkt_type = sco_pi(sk)->pkt_type;
return 0;
}
return 0;
}
@@
-700,7
+717,6
@@
static int sco_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
sco_conn_defer_accept(pi->conn->hcon, 0);
sk->sk_state = BT_CONFIG;
test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
sco_conn_defer_accept(pi->conn->hcon, 0);
sk->sk_state = BT_CONFIG;
- msg->msg_namelen = 0;
release_sock(sk);
return 0;
release_sock(sk);
return 0;
@@
-859,7
+875,8
@@
static int sco_sock_shutdown(struct socket *sock, int how)
sco_sock_clear_timer(sk);
__sco_sock_close(sk);
sco_sock_clear_timer(sk);
__sco_sock_close(sk);
- if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime)
+ if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime &&
+ !(current->flags & PF_EXITING))
err = bt_sock_wait_state(sk, BT_CLOSED,
sk->sk_lingertime);
}
err = bt_sock_wait_state(sk, BT_CLOSED,
sk->sk_lingertime);
}
@@
-879,7
+896,8
@@
static int sco_sock_release(struct socket *sock)
sco_sock_close(sk);
sco_sock_close(sk);
- if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime) {
+ if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime &&
+ !(current->flags & PF_EXITING)) {
lock_sock(sk);
err = bt_sock_wait_state(sk, BT_CLOSED, sk->sk_lingertime);
release_sock(sk);
lock_sock(sk);
err = bt_sock_wait_state(sk, BT_CLOSED, sk->sk_lingertime);
release_sock(sk);