Commit 06ef5c4b authored by John W. Linville's avatar John W. Linville

Merge branch 'for-upstream' of...

Merge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next
parents 55cec505 0b27a4b9
...@@ -376,7 +376,7 @@ extern int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt); ...@@ -376,7 +376,7 @@ extern int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt);
extern int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, extern int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb,
u16 flags); u16 flags);
extern int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr); extern int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags);
extern void sco_connect_cfm(struct hci_conn *hcon, __u8 status); extern void sco_connect_cfm(struct hci_conn *hcon, __u8 status);
extern void sco_disconn_cfm(struct hci_conn *hcon, __u8 reason); extern void sco_disconn_cfm(struct hci_conn *hcon, __u8 reason);
extern int sco_recv_scodata(struct hci_conn *hcon, struct sk_buff *skb); extern int sco_recv_scodata(struct hci_conn *hcon, struct sk_buff *skb);
...@@ -577,6 +577,7 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst); ...@@ -577,6 +577,7 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst);
int hci_conn_del(struct hci_conn *conn); int hci_conn_del(struct hci_conn *conn);
void hci_conn_hash_flush(struct hci_dev *hdev); void hci_conn_hash_flush(struct hci_dev *hdev);
void hci_conn_check_pending(struct hci_dev *hdev); void hci_conn_check_pending(struct hci_dev *hdev);
void hci_conn_accept(struct hci_conn *conn, int mask);
struct hci_chan *hci_chan_create(struct hci_conn *conn); struct hci_chan *hci_chan_create(struct hci_conn *conn);
void hci_chan_del(struct hci_chan *chan); void hci_chan_del(struct hci_chan *chan);
...@@ -766,7 +767,7 @@ void hci_conn_del_sysfs(struct hci_conn *conn); ...@@ -766,7 +767,7 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
#define lmp_sniffsubr_capable(dev) ((dev)->features[5] & LMP_SNIFF_SUBR) #define lmp_sniffsubr_capable(dev) ((dev)->features[5] & LMP_SNIFF_SUBR)
#define lmp_pause_enc_capable(dev) ((dev)->features[5] & LMP_PAUSE_ENC) #define lmp_pause_enc_capable(dev) ((dev)->features[5] & LMP_PAUSE_ENC)
#define lmp_ext_inq_capable(dev) ((dev)->features[6] & LMP_EXT_INQ) #define lmp_ext_inq_capable(dev) ((dev)->features[6] & LMP_EXT_INQ)
#define lmp_le_br_capable(dev) ((dev)->features[6] & LMP_SIMUL_LE_BR) #define lmp_le_br_capable(dev) !!((dev)->features[6] & LMP_SIMUL_LE_BR)
#define lmp_ssp_capable(dev) ((dev)->features[6] & LMP_SIMPLE_PAIR) #define lmp_ssp_capable(dev) ((dev)->features[6] & LMP_SIMPLE_PAIR)
#define lmp_no_flush_capable(dev) ((dev)->features[6] & LMP_NO_FLUSH) #define lmp_no_flush_capable(dev) ((dev)->features[6] & LMP_NO_FLUSH)
#define lmp_lsto_capable(dev) ((dev)->features[7] & LMP_LSTO) #define lmp_lsto_capable(dev) ((dev)->features[7] & LMP_LSTO)
...@@ -775,12 +776,30 @@ void hci_conn_del_sysfs(struct hci_conn *conn); ...@@ -775,12 +776,30 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
/* ----- Extended LMP capabilities ----- */ /* ----- Extended LMP capabilities ----- */
#define lmp_host_ssp_capable(dev) ((dev)->host_features[0] & LMP_HOST_SSP) #define lmp_host_ssp_capable(dev) ((dev)->host_features[0] & LMP_HOST_SSP)
#define lmp_host_le_capable(dev) ((dev)->host_features[0] & LMP_HOST_LE) #define lmp_host_le_capable(dev) !!((dev)->host_features[0] & LMP_HOST_LE)
#define lmp_host_le_br_capable(dev) ((dev)->host_features[0] & LMP_HOST_LE_BREDR) #define lmp_host_le_br_capable(dev) !!((dev)->host_features[0] & LMP_HOST_LE_BREDR)
/* returns true if at least one AMP active */
static inline bool hci_amp_capable(void)
{
struct hci_dev *hdev;
bool ret = false;
read_lock(&hci_dev_list_lock);
list_for_each_entry(hdev, &hci_dev_list, list)
if (hdev->amp_type == HCI_AMP &&
test_bit(HCI_UP, &hdev->flags))
ret = true;
read_unlock(&hci_dev_list_lock);
return ret;
}
/* ----- HCI protocols ----- */ /* ----- HCI protocols ----- */
#define HCI_PROTO_DEFER 0x01
static inline int hci_proto_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, static inline int hci_proto_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr,
__u8 type) __u8 type, __u8 *flags)
{ {
switch (type) { switch (type) {
case ACL_LINK: case ACL_LINK:
...@@ -788,7 +807,7 @@ static inline int hci_proto_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, ...@@ -788,7 +807,7 @@ static inline int hci_proto_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr,
case SCO_LINK: case SCO_LINK:
case ESCO_LINK: case ESCO_LINK:
return sco_connect_ind(hdev, bdaddr); return sco_connect_ind(hdev, bdaddr, flags);
default: default:
BT_ERR("unknown link type %d", type); BT_ERR("unknown link type %d", type);
......
...@@ -611,7 +611,7 @@ enum { ...@@ -611,7 +611,7 @@ enum {
CONF_MTU_DONE, CONF_MTU_DONE,
CONF_MODE_DONE, CONF_MODE_DONE,
CONF_CONNECT_PEND, CONF_CONNECT_PEND,
CONF_NO_FCS_RECV, CONF_RECV_NO_FCS,
CONF_STATE2_DEVICE, CONF_STATE2_DEVICE,
CONF_EWS_RECV, CONF_EWS_RECV,
CONF_LOC_CONF_PEND, CONF_LOC_CONF_PEND,
......
...@@ -861,6 +861,9 @@ static int hci_dev_do_close(struct hci_dev *hdev) ...@@ -861,6 +861,9 @@ static int hci_dev_do_close(struct hci_dev *hdev)
/* Clear flags */ /* Clear flags */
hdev->flags = 0; hdev->flags = 0;
/* Controller radio is available but is currently powered down */
hdev->amp_status = 0;
memset(hdev->eir, 0, sizeof(hdev->eir)); memset(hdev->eir, 0, sizeof(hdev->eir));
memset(hdev->dev_class, 0, sizeof(hdev->dev_class)); memset(hdev->dev_class, 0, sizeof(hdev->dev_class));
...@@ -1854,6 +1857,8 @@ void hci_unregister_dev(struct hci_dev *hdev) ...@@ -1854,6 +1857,8 @@ void hci_unregister_dev(struct hci_dev *hdev)
for (i = 0; i < NUM_REASSEMBLY; i++) for (i = 0; i < NUM_REASSEMBLY; i++)
kfree_skb(hdev->reassembly[i]); kfree_skb(hdev->reassembly[i]);
cancel_work_sync(&hdev->power_on);
if (!test_bit(HCI_INIT, &hdev->flags) && if (!test_bit(HCI_INIT, &hdev->flags) &&
!test_bit(HCI_SETUP, &hdev->dev_flags)) { !test_bit(HCI_SETUP, &hdev->dev_flags)) {
hci_dev_lock(hdev); hci_dev_lock(hdev);
......
...@@ -794,10 +794,10 @@ static void hci_set_le_support(struct hci_dev *hdev) ...@@ -794,10 +794,10 @@ static void hci_set_le_support(struct hci_dev *hdev)
if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) { if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) {
cp.le = 1; cp.le = 1;
cp.simul = !!lmp_le_br_capable(hdev); cp.simul = lmp_le_br_capable(hdev);
} }
if (cp.le != !!lmp_host_le_capable(hdev)) if (cp.le != lmp_host_le_capable(hdev))
hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp), hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp),
&cp); &cp);
} }
...@@ -2047,15 +2047,53 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) ...@@ -2047,15 +2047,53 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
hci_conn_check_pending(hdev); hci_conn_check_pending(hdev);
} }
void hci_conn_accept(struct hci_conn *conn, int mask)
{
struct hci_dev *hdev = conn->hdev;
BT_DBG("conn %p", conn);
conn->state = BT_CONFIG;
if (!lmp_esco_capable(hdev)) {
struct hci_cp_accept_conn_req cp;
bacpy(&cp.bdaddr, &conn->dst);
if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
cp.role = 0x00; /* Become master */
else
cp.role = 0x01; /* Remain slave */
hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp), &cp);
} else /* lmp_esco_capable(hdev)) */ {
struct hci_cp_accept_sync_conn_req cp;
bacpy(&cp.bdaddr, &conn->dst);
cp.pkt_type = cpu_to_le16(conn->pkt_type);
cp.tx_bandwidth = __constant_cpu_to_le32(0x00001f40);
cp.rx_bandwidth = __constant_cpu_to_le32(0x00001f40);
cp.max_latency = __constant_cpu_to_le16(0xffff);
cp.content_format = cpu_to_le16(hdev->voice_setting);
cp.retrans_effort = 0xff;
hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
sizeof(cp), &cp);
}
}
static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb) static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
{ {
struct hci_ev_conn_request *ev = (void *) skb->data; struct hci_ev_conn_request *ev = (void *) skb->data;
int mask = hdev->link_mode; int mask = hdev->link_mode;
__u8 flags = 0;
BT_DBG("%s bdaddr %pMR type 0x%x", hdev->name, &ev->bdaddr, BT_DBG("%s bdaddr %pMR type 0x%x", hdev->name, &ev->bdaddr,
ev->link_type); ev->link_type);
mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type); mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type,
&flags);
if ((mask & HCI_LM_ACCEPT) && if ((mask & HCI_LM_ACCEPT) &&
!hci_blacklist_lookup(hdev, &ev->bdaddr)) { !hci_blacklist_lookup(hdev, &ev->bdaddr)) {
...@@ -2081,12 +2119,13 @@ static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb) ...@@ -2081,12 +2119,13 @@ static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
} }
memcpy(conn->dev_class, ev->dev_class, 3); memcpy(conn->dev_class, ev->dev_class, 3);
conn->state = BT_CONNECT;
hci_dev_unlock(hdev); hci_dev_unlock(hdev);
if (ev->link_type == ACL_LINK || !lmp_esco_capable(hdev)) { if (ev->link_type == ACL_LINK ||
(!(flags & HCI_PROTO_DEFER) && !lmp_esco_capable(hdev))) {
struct hci_cp_accept_conn_req cp; struct hci_cp_accept_conn_req cp;
conn->state = BT_CONNECT;
bacpy(&cp.bdaddr, &ev->bdaddr); bacpy(&cp.bdaddr, &ev->bdaddr);
...@@ -2097,8 +2136,9 @@ static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb) ...@@ -2097,8 +2136,9 @@ static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp), hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp),
&cp); &cp);
} else { } else if (!(flags & HCI_PROTO_DEFER)) {
struct hci_cp_accept_sync_conn_req cp; struct hci_cp_accept_sync_conn_req cp;
conn->state = BT_CONNECT;
bacpy(&cp.bdaddr, &ev->bdaddr); bacpy(&cp.bdaddr, &ev->bdaddr);
cp.pkt_type = cpu_to_le16(conn->pkt_type); cp.pkt_type = cpu_to_le16(conn->pkt_type);
...@@ -2111,6 +2151,10 @@ static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb) ...@@ -2111,6 +2151,10 @@ static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ, hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
sizeof(cp), &cp); sizeof(cp), &cp);
} else {
conn->state = BT_CONNECT2;
hci_proto_connect_cfm(conn, 0);
hci_conn_put(conn);
} }
} else { } else {
/* Connection rejected */ /* Connection rejected */
......
This diff is collapsed.
...@@ -1226,7 +1226,7 @@ static int set_le(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) ...@@ -1226,7 +1226,7 @@ static int set_le(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
} }
val = !!cp->val; val = !!cp->val;
enabled = !!lmp_host_le_capable(hdev); enabled = lmp_host_le_capable(hdev);
if (!hdev_is_powered(hdev) || val == enabled) { if (!hdev_is_powered(hdev) || val == enabled) {
bool changed = false; bool changed = false;
...@@ -1262,7 +1262,7 @@ static int set_le(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) ...@@ -1262,7 +1262,7 @@ static int set_le(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
if (val) { if (val) {
hci_cp.le = val; hci_cp.le = val;
hci_cp.simul = !!lmp_le_br_capable(hdev); hci_cp.simul = lmp_le_br_capable(hdev);
} }
err = hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(hci_cp), err = hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(hci_cp),
...@@ -2926,13 +2926,13 @@ int mgmt_powered(struct hci_dev *hdev, u8 powered) ...@@ -2926,13 +2926,13 @@ int mgmt_powered(struct hci_dev *hdev, u8 powered)
struct hci_cp_write_le_host_supported cp; struct hci_cp_write_le_host_supported cp;
cp.le = 1; cp.le = 1;
cp.simul = !!lmp_le_br_capable(hdev); cp.simul = lmp_le_br_capable(hdev);
/* Check first if we already have the right /* Check first if we already have the right
* host state (host features set) * host state (host features set)
*/ */
if (cp.le != !!lmp_host_le_capable(hdev) || if (cp.le != lmp_host_le_capable(hdev) ||
cp.simul != !!lmp_host_le_br_capable(hdev)) cp.simul != lmp_host_le_br_capable(hdev))
hci_send_cmd(hdev, hci_send_cmd(hdev,
HCI_OP_WRITE_LE_HOST_SUPPORTED, HCI_OP_WRITE_LE_HOST_SUPPORTED,
sizeof(cp), &cp); sizeof(cp), &cp);
......
...@@ -467,7 +467,7 @@ static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int f ...@@ -467,7 +467,7 @@ static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int f
long timeo; long timeo;
int err = 0; int err = 0;
lock_sock(sk); lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
if (sk->sk_type != SOCK_STREAM) { if (sk->sk_type != SOCK_STREAM) {
err = -EINVAL; err = -EINVAL;
...@@ -504,7 +504,7 @@ static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int f ...@@ -504,7 +504,7 @@ static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int f
release_sock(sk); release_sock(sk);
timeo = schedule_timeout(timeo); timeo = schedule_timeout(timeo);
lock_sock(sk); lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
} }
__set_current_state(TASK_RUNNING); __set_current_state(TASK_RUNNING);
remove_wait_queue(sk_sleep(sk), &wait); remove_wait_queue(sk_sleep(sk), &wait);
......
...@@ -131,15 +131,6 @@ static int sco_conn_del(struct hci_conn *hcon, int err) ...@@ -131,15 +131,6 @@ static int sco_conn_del(struct hci_conn *hcon, int err)
sco_sock_clear_timer(sk); sco_sock_clear_timer(sk);
sco_chan_del(sk, err); sco_chan_del(sk, err);
bh_unlock_sock(sk); bh_unlock_sock(sk);
sco_conn_lock(conn);
conn->sk = NULL;
sco_pi(sk)->conn = NULL;
sco_conn_unlock(conn);
if (conn->hcon)
hci_conn_put(conn->hcon);
sco_sock_kill(sk); sco_sock_kill(sk);
} }
...@@ -397,6 +388,7 @@ static void sco_sock_init(struct sock *sk, struct sock *parent) ...@@ -397,6 +388,7 @@ static void sco_sock_init(struct sock *sk, struct sock *parent)
if (parent) { if (parent) {
sk->sk_type = parent->sk_type; sk->sk_type = parent->sk_type;
bt_sk(sk)->flags = bt_sk(parent)->flags;
security_sk_clone(parent, sk); security_sk_clone(parent, sk);
} }
} }
...@@ -662,16 +654,57 @@ static int sco_sock_sendmsg(struct kiocb *iocb, struct socket *sock, ...@@ -662,16 +654,57 @@ static int sco_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
return err; return err;
} }
static int sco_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
struct msghdr *msg, size_t len, int flags)
{
struct sock *sk = sock->sk;
struct sco_pinfo *pi = sco_pi(sk);
lock_sock(sk);
if (sk->sk_state == BT_CONNECT2 &&
test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
hci_conn_accept(pi->conn->hcon, 0);
sk->sk_state = BT_CONFIG;
release_sock(sk);
return 0;
}
release_sock(sk);
return bt_sock_recvmsg(iocb, sock, msg, len, flags);
}
static int sco_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen) static int sco_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
{ {
struct sock *sk = sock->sk; struct sock *sk = sock->sk;
int err = 0; int err = 0;
u32 opt;
BT_DBG("sk %p", sk); BT_DBG("sk %p", sk);
lock_sock(sk); lock_sock(sk);
switch (optname) { switch (optname) {
case BT_DEFER_SETUP:
if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
err = -EINVAL;
break;
}
if (get_user(opt, (u32 __user *) optval)) {
err = -EFAULT;
break;
}
if (opt)
set_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags);
else
clear_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags);
break;
default: default:
err = -ENOPROTOOPT; err = -ENOPROTOOPT;
break; break;
...@@ -753,6 +786,19 @@ static int sco_sock_getsockopt(struct socket *sock, int level, int optname, char ...@@ -753,6 +786,19 @@ static int sco_sock_getsockopt(struct socket *sock, int level, int optname, char
lock_sock(sk); lock_sock(sk);
switch (optname) { switch (optname) {
case BT_DEFER_SETUP:
if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
err = -EINVAL;
break;
}
if (put_user(test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags),
(u32 __user *) optval))
err = -EFAULT;
break;
default: default:
err = -ENOPROTOOPT; err = -ENOPROTOOPT;
break; break;
...@@ -830,6 +876,16 @@ static void sco_chan_del(struct sock *sk, int err) ...@@ -830,6 +876,16 @@ static void sco_chan_del(struct sock *sk, int err)
BT_DBG("sk %p, conn %p, err %d", sk, conn, err); BT_DBG("sk %p, conn %p, err %d", sk, conn, err);
if (conn) {
sco_conn_lock(conn);
conn->sk = NULL;
sco_pi(sk)->conn = NULL;
sco_conn_unlock(conn);
if (conn->hcon)
hci_conn_put(conn->hcon);
}
sk->sk_state = BT_CLOSED; sk->sk_state = BT_CLOSED;
sk->sk_err = err; sk->sk_err = err;
sk->sk_state_change(sk); sk->sk_state_change(sk);
...@@ -874,7 +930,10 @@ static void sco_conn_ready(struct sco_conn *conn) ...@@ -874,7 +930,10 @@ static void sco_conn_ready(struct sco_conn *conn)
hci_conn_hold(conn->hcon); hci_conn_hold(conn->hcon);
__sco_chan_add(conn, sk, parent); __sco_chan_add(conn, sk, parent);
sk->sk_state = BT_CONNECTED; if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(parent)->flags))
sk->sk_state = BT_CONNECT2;
else
sk->sk_state = BT_CONNECTED;
/* Wake up parent */ /* Wake up parent */
parent->sk_data_ready(parent, 1); parent->sk_data_ready(parent, 1);
...@@ -887,7 +946,7 @@ static void sco_conn_ready(struct sco_conn *conn) ...@@ -887,7 +946,7 @@ static void sco_conn_ready(struct sco_conn *conn)
} }
/* ----- SCO interface with lower layer (HCI) ----- */ /* ----- SCO interface with lower layer (HCI) ----- */
int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr) int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags)
{ {
struct sock *sk; struct sock *sk;
struct hlist_node *node; struct hlist_node *node;
...@@ -904,6 +963,9 @@ int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr) ...@@ -904,6 +963,9 @@ int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr) || if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr) ||
!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) { !bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
lm |= HCI_LM_ACCEPT; lm |= HCI_LM_ACCEPT;
if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags))
*flags |= HCI_PROTO_DEFER;
break; break;
} }
} }
...@@ -992,7 +1054,7 @@ static const struct proto_ops sco_sock_ops = { ...@@ -992,7 +1054,7 @@ static const struct proto_ops sco_sock_ops = {
.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 = bt_sock_recvmsg, .recvmsg = sco_sock_recvmsg,
.poll = bt_sock_poll, .poll = bt_sock_poll,
.ioctl = bt_sock_ioctl, .ioctl = bt_sock_ioctl,
.mmap = sock_no_mmap, .mmap = sock_no_mmap,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment