Commit 5bf89211 authored by David S. Miller's avatar David S. Miller

Merge branch 'for-upstream' of...

Merge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next

Johan Hedberg says:

====================
pull request: bluetooth-next 2015-10-28

Here are a some more Bluetooth patches for 4.4 which collected up during
the past week. The most important ones are from Kuba Pawlak for fixing
locking issues with SCO sockets. There's also a fix from Alexander Aring
for 6lowpan, a memleak fix from Julia Lawall for the btmrvl driver and
some cleanup patches from Marcel.

Please let me know if there are any issues pulling. Thanks.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents b7b0b1d2 324e786e
...@@ -516,14 +516,17 @@ static int btmrvl_check_device_tree(struct btmrvl_private *priv) ...@@ -516,14 +516,17 @@ static int btmrvl_check_device_tree(struct btmrvl_private *priv)
ret = of_property_read_u8_array(dt_node, "btmrvl,cal-data", ret = of_property_read_u8_array(dt_node, "btmrvl,cal-data",
cal_data + BT_CAL_HDR_LEN, cal_data + BT_CAL_HDR_LEN,
BT_CAL_DATA_SIZE); BT_CAL_DATA_SIZE);
if (ret) if (ret) {
of_node_put(dt_node);
return ret; return ret;
}
BT_DBG("Use cal data from device tree"); BT_DBG("Use cal data from device tree");
ret = btmrvl_download_cal_data(priv, cal_data, ret = btmrvl_download_cal_data(priv, cal_data,
BT_CAL_DATA_SIZE); BT_CAL_DATA_SIZE);
if (ret) { if (ret) {
BT_ERR("Fail to download calibrate data"); BT_ERR("Fail to download calibrate data");
of_node_put(dt_node);
return ret; return ret;
} }
} }
......
...@@ -296,22 +296,22 @@ typedef void (*hci_req_complete_t)(struct hci_dev *hdev, u8 status, u16 opcode); ...@@ -296,22 +296,22 @@ typedef void (*hci_req_complete_t)(struct hci_dev *hdev, u8 status, u16 opcode);
typedef void (*hci_req_complete_skb_t)(struct hci_dev *hdev, u8 status, typedef void (*hci_req_complete_skb_t)(struct hci_dev *hdev, u8 status,
u16 opcode, struct sk_buff *skb); u16 opcode, struct sk_buff *skb);
struct req_ctrl { struct hci_ctrl {
bool start; __u16 opcode;
u8 event; bool req_start;
hci_req_complete_t complete; u8 req_event;
hci_req_complete_skb_t complete_skb; hci_req_complete_t req_complete;
hci_req_complete_skb_t req_complete_skb;
}; };
struct bt_skb_cb { struct bt_skb_cb {
__u8 pkt_type; __u8 pkt_type;
__u8 force_active; __u8 force_active;
__u16 opcode;
__u16 expect; __u16 expect;
__u8 incoming:1; __u8 incoming:1;
union { union {
struct l2cap_ctrl l2cap; struct l2cap_ctrl l2cap;
struct req_ctrl req; struct hci_ctrl hci;
}; };
}; };
#define bt_cb(skb) ((struct bt_skb_cb *)((skb)->cb)) #define bt_cb(skb) ((struct bt_skb_cb *)((skb)->cb))
......
...@@ -263,7 +263,7 @@ static int give_skb_to_upper(struct sk_buff *skb, struct net_device *dev) ...@@ -263,7 +263,7 @@ static int give_skb_to_upper(struct sk_buff *skb, struct net_device *dev)
if (!skb_cp) if (!skb_cp)
return NET_RX_DROP; return NET_RX_DROP;
return netif_rx(skb_cp); return netif_rx_ni(skb_cp);
} }
static int iphc_decompress(struct sk_buff *skb, struct net_device *netdev, static int iphc_decompress(struct sk_buff *skb, struct net_device *netdev,
......
...@@ -221,7 +221,7 @@ int bt_sock_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, ...@@ -221,7 +221,7 @@ int bt_sock_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
BT_DBG("sock %p sk %p len %zu", sock, sk, len); BT_DBG("sock %p sk %p len %zu", sock, sk, len);
if (flags & (MSG_OOB)) if (flags & MSG_OOB)
return -EOPNOTSUPP; return -EOPNOTSUPP;
skb = skb_recv_datagram(sk, flags, noblock, &err); skb = skb_recv_datagram(sk, flags, noblock, &err);
......
...@@ -65,13 +65,6 @@ static DEFINE_IDA(hci_index_ida); ...@@ -65,13 +65,6 @@ static DEFINE_IDA(hci_index_ida);
#define hci_req_lock(d) mutex_lock(&d->req_lock) #define hci_req_lock(d) mutex_lock(&d->req_lock)
#define hci_req_unlock(d) mutex_unlock(&d->req_lock) #define hci_req_unlock(d) mutex_unlock(&d->req_lock)
/* ---- HCI notifications ---- */
static void hci_notify(struct hci_dev *hdev, int event)
{
hci_sock_dev_event(hdev, event);
}
/* ---- HCI debugfs entries ---- */ /* ---- HCI debugfs entries ---- */
static ssize_t dut_mode_read(struct file *file, char __user *user_buf, static ssize_t dut_mode_read(struct file *file, char __user *user_buf,
...@@ -1455,7 +1448,7 @@ static int hci_dev_do_open(struct hci_dev *hdev) ...@@ -1455,7 +1448,7 @@ static int hci_dev_do_open(struct hci_dev *hdev)
} }
set_bit(HCI_RUNNING, &hdev->flags); set_bit(HCI_RUNNING, &hdev->flags);
hci_notify(hdev, HCI_DEV_OPEN); hci_sock_dev_event(hdev, HCI_DEV_OPEN);
atomic_set(&hdev->cmd_cnt, 1); atomic_set(&hdev->cmd_cnt, 1);
set_bit(HCI_INIT, &hdev->flags); set_bit(HCI_INIT, &hdev->flags);
...@@ -1524,7 +1517,7 @@ static int hci_dev_do_open(struct hci_dev *hdev) ...@@ -1524,7 +1517,7 @@ static int hci_dev_do_open(struct hci_dev *hdev)
hci_dev_hold(hdev); hci_dev_hold(hdev);
hci_dev_set_flag(hdev, HCI_RPA_EXPIRED); hci_dev_set_flag(hdev, HCI_RPA_EXPIRED);
set_bit(HCI_UP, &hdev->flags); set_bit(HCI_UP, &hdev->flags);
hci_notify(hdev, HCI_DEV_UP); hci_sock_dev_event(hdev, HCI_DEV_UP);
if (!hci_dev_test_flag(hdev, HCI_SETUP) && if (!hci_dev_test_flag(hdev, HCI_SETUP) &&
!hci_dev_test_flag(hdev, HCI_CONFIG) && !hci_dev_test_flag(hdev, HCI_CONFIG) &&
!hci_dev_test_flag(hdev, HCI_UNCONFIGURED) && !hci_dev_test_flag(hdev, HCI_UNCONFIGURED) &&
...@@ -1552,7 +1545,7 @@ static int hci_dev_do_open(struct hci_dev *hdev) ...@@ -1552,7 +1545,7 @@ static int hci_dev_do_open(struct hci_dev *hdev)
} }
clear_bit(HCI_RUNNING, &hdev->flags); clear_bit(HCI_RUNNING, &hdev->flags);
hci_notify(hdev, HCI_DEV_CLOSE); hci_sock_dev_event(hdev, HCI_DEV_CLOSE);
hdev->close(hdev); hdev->close(hdev);
hdev->flags &= BIT(HCI_RAW); hdev->flags &= BIT(HCI_RAW);
...@@ -1708,7 +1701,7 @@ int hci_dev_do_close(struct hci_dev *hdev) ...@@ -1708,7 +1701,7 @@ int hci_dev_do_close(struct hci_dev *hdev)
smp_unregister(hdev); smp_unregister(hdev);
hci_notify(hdev, HCI_DEV_DOWN); hci_sock_dev_event(hdev, HCI_DEV_DOWN);
if (hdev->flush) if (hdev->flush)
hdev->flush(hdev); hdev->flush(hdev);
...@@ -1739,7 +1732,7 @@ int hci_dev_do_close(struct hci_dev *hdev) ...@@ -1739,7 +1732,7 @@ int hci_dev_do_close(struct hci_dev *hdev)
} }
clear_bit(HCI_RUNNING, &hdev->flags); clear_bit(HCI_RUNNING, &hdev->flags);
hci_notify(hdev, HCI_DEV_CLOSE); hci_sock_dev_event(hdev, HCI_DEV_CLOSE);
/* After this point our queues are empty /* After this point our queues are empty
* and no tasks are scheduled. */ * and no tasks are scheduled. */
...@@ -3414,7 +3407,7 @@ int hci_register_dev(struct hci_dev *hdev) ...@@ -3414,7 +3407,7 @@ int hci_register_dev(struct hci_dev *hdev)
if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks)) if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
hci_dev_set_flag(hdev, HCI_UNCONFIGURED); hci_dev_set_flag(hdev, HCI_UNCONFIGURED);
hci_notify(hdev, HCI_DEV_REG); hci_sock_dev_event(hdev, HCI_DEV_REG);
hci_dev_hold(hdev); hci_dev_hold(hdev);
queue_work(hdev->req_workqueue, &hdev->power_on); queue_work(hdev->req_workqueue, &hdev->power_on);
...@@ -3462,7 +3455,7 @@ void hci_unregister_dev(struct hci_dev *hdev) ...@@ -3462,7 +3455,7 @@ void hci_unregister_dev(struct hci_dev *hdev)
* pending list */ * pending list */
BUG_ON(!list_empty(&hdev->mgmt_pending)); BUG_ON(!list_empty(&hdev->mgmt_pending));
hci_notify(hdev, HCI_DEV_UNREG); hci_sock_dev_event(hdev, HCI_DEV_UNREG);
if (hdev->rfkill) { if (hdev->rfkill) {
rfkill_unregister(hdev->rfkill); rfkill_unregister(hdev->rfkill);
...@@ -3499,7 +3492,7 @@ EXPORT_SYMBOL(hci_unregister_dev); ...@@ -3499,7 +3492,7 @@ EXPORT_SYMBOL(hci_unregister_dev);
/* Suspend HCI device */ /* Suspend HCI device */
int hci_suspend_dev(struct hci_dev *hdev) int hci_suspend_dev(struct hci_dev *hdev)
{ {
hci_notify(hdev, HCI_DEV_SUSPEND); hci_sock_dev_event(hdev, HCI_DEV_SUSPEND);
return 0; return 0;
} }
EXPORT_SYMBOL(hci_suspend_dev); EXPORT_SYMBOL(hci_suspend_dev);
...@@ -3507,7 +3500,7 @@ EXPORT_SYMBOL(hci_suspend_dev); ...@@ -3507,7 +3500,7 @@ EXPORT_SYMBOL(hci_suspend_dev);
/* Resume HCI device */ /* Resume HCI device */
int hci_resume_dev(struct hci_dev *hdev) int hci_resume_dev(struct hci_dev *hdev)
{ {
hci_notify(hdev, HCI_DEV_RESUME); hci_sock_dev_event(hdev, HCI_DEV_RESUME);
return 0; return 0;
} }
EXPORT_SYMBOL(hci_resume_dev); EXPORT_SYMBOL(hci_resume_dev);
...@@ -3650,7 +3643,7 @@ int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, ...@@ -3650,7 +3643,7 @@ int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen,
/* Stand-alone HCI commands must be flagged as /* Stand-alone HCI commands must be flagged as
* single-command requests. * single-command requests.
*/ */
bt_cb(skb)->req.start = true; bt_cb(skb)->hci.req_start = true;
skb_queue_tail(&hdev->cmd_q, skb); skb_queue_tail(&hdev->cmd_q, skb);
queue_work(hdev->workqueue, &hdev->cmd_work); queue_work(hdev->workqueue, &hdev->cmd_work);
...@@ -4347,7 +4340,7 @@ static bool hci_req_is_complete(struct hci_dev *hdev) ...@@ -4347,7 +4340,7 @@ static bool hci_req_is_complete(struct hci_dev *hdev)
if (!skb) if (!skb)
return true; return true;
return bt_cb(skb)->req.start; return bt_cb(skb)->hci.req_start;
} }
static void hci_resend_last(struct hci_dev *hdev) static void hci_resend_last(struct hci_dev *hdev)
...@@ -4407,26 +4400,26 @@ void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status, ...@@ -4407,26 +4400,26 @@ void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status,
* callback would be found in hdev->sent_cmd instead of the * callback would be found in hdev->sent_cmd instead of the
* command queue (hdev->cmd_q). * command queue (hdev->cmd_q).
*/ */
if (bt_cb(hdev->sent_cmd)->req.complete) { if (bt_cb(hdev->sent_cmd)->hci.req_complete) {
*req_complete = bt_cb(hdev->sent_cmd)->req.complete; *req_complete = bt_cb(hdev->sent_cmd)->hci.req_complete;
return; return;
} }
if (bt_cb(hdev->sent_cmd)->req.complete_skb) { if (bt_cb(hdev->sent_cmd)->hci.req_complete_skb) {
*req_complete_skb = bt_cb(hdev->sent_cmd)->req.complete_skb; *req_complete_skb = bt_cb(hdev->sent_cmd)->hci.req_complete_skb;
return; return;
} }
/* Remove all pending commands belonging to this request */ /* Remove all pending commands belonging to this request */
spin_lock_irqsave(&hdev->cmd_q.lock, flags); spin_lock_irqsave(&hdev->cmd_q.lock, flags);
while ((skb = __skb_dequeue(&hdev->cmd_q))) { while ((skb = __skb_dequeue(&hdev->cmd_q))) {
if (bt_cb(skb)->req.start) { if (bt_cb(skb)->hci.req_start) {
__skb_queue_head(&hdev->cmd_q, skb); __skb_queue_head(&hdev->cmd_q, skb);
break; break;
} }
*req_complete = bt_cb(skb)->req.complete; *req_complete = bt_cb(skb)->hci.req_complete;
*req_complete_skb = bt_cb(skb)->req.complete_skb; *req_complete_skb = bt_cb(skb)->hci.req_complete_skb;
kfree_skb(skb); kfree_skb(skb);
} }
spin_unlock_irqrestore(&hdev->cmd_q.lock, flags); spin_unlock_irqrestore(&hdev->cmd_q.lock, flags);
......
...@@ -3138,7 +3138,7 @@ static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb, ...@@ -3138,7 +3138,7 @@ static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb,
* complete event). * complete event).
*/ */
if (ev->status || if (ev->status ||
(hdev->sent_cmd && !bt_cb(hdev->sent_cmd)->req.event)) (hdev->sent_cmd && !bt_cb(hdev->sent_cmd)->hci.req_event))
hci_req_cmd_complete(hdev, *opcode, ev->status, req_complete, hci_req_cmd_complete(hdev, *opcode, ev->status, req_complete,
req_complete_skb); req_complete_skb);
...@@ -5209,7 +5209,7 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) ...@@ -5209,7 +5209,7 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
u8 status = 0, event = hdr->evt, req_evt = 0; u8 status = 0, event = hdr->evt, req_evt = 0;
u16 opcode = HCI_OP_NOP; u16 opcode = HCI_OP_NOP;
if (hdev->sent_cmd && bt_cb(hdev->sent_cmd)->req.event == event) { if (hdev->sent_cmd && bt_cb(hdev->sent_cmd)->hci.req_event == event) {
struct hci_command_hdr *cmd_hdr = (void *) hdev->sent_cmd->data; struct hci_command_hdr *cmd_hdr = (void *) hdev->sent_cmd->data;
opcode = __le16_to_cpu(cmd_hdr->opcode); opcode = __le16_to_cpu(cmd_hdr->opcode);
hci_req_cmd_complete(hdev, opcode, status, &req_complete, hci_req_cmd_complete(hdev, opcode, status, &req_complete,
......
...@@ -56,8 +56,8 @@ static int req_run(struct hci_request *req, hci_req_complete_t complete, ...@@ -56,8 +56,8 @@ static int req_run(struct hci_request *req, hci_req_complete_t complete,
return -ENODATA; return -ENODATA;
skb = skb_peek_tail(&req->cmd_q); skb = skb_peek_tail(&req->cmd_q);
bt_cb(skb)->req.complete = complete; bt_cb(skb)->hci.req_complete = complete;
bt_cb(skb)->req.complete_skb = complete_skb; bt_cb(skb)->hci.req_complete_skb = complete_skb;
spin_lock_irqsave(&hdev->cmd_q.lock, flags); spin_lock_irqsave(&hdev->cmd_q.lock, flags);
skb_queue_splice_tail(&req->cmd_q, &hdev->cmd_q); skb_queue_splice_tail(&req->cmd_q, &hdev->cmd_q);
...@@ -99,7 +99,7 @@ struct sk_buff *hci_prepare_cmd(struct hci_dev *hdev, u16 opcode, u32 plen, ...@@ -99,7 +99,7 @@ struct sk_buff *hci_prepare_cmd(struct hci_dev *hdev, u16 opcode, u32 plen,
BT_DBG("skb len %d", skb->len); BT_DBG("skb len %d", skb->len);
bt_cb(skb)->pkt_type = HCI_COMMAND_PKT; bt_cb(skb)->pkt_type = HCI_COMMAND_PKT;
bt_cb(skb)->opcode = opcode; bt_cb(skb)->hci.opcode = opcode;
return skb; return skb;
} }
...@@ -128,9 +128,9 @@ void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen, ...@@ -128,9 +128,9 @@ void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen,
} }
if (skb_queue_empty(&req->cmd_q)) if (skb_queue_empty(&req->cmd_q))
bt_cb(skb)->req.start = true; bt_cb(skb)->hci.req_start = true;
bt_cb(skb)->req.event = event; bt_cb(skb)->hci.req_event = event;
skb_queue_tail(&req->cmd_q, skb); skb_queue_tail(&req->cmd_q, skb);
} }
......
...@@ -1001,7 +1001,7 @@ static int hci_sock_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, ...@@ -1001,7 +1001,7 @@ static int hci_sock_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
BT_DBG("sock %p, sk %p", sock, sk); BT_DBG("sock %p, sk %p", sock, sk);
if (flags & (MSG_OOB)) if (flags & MSG_OOB)
return -EOPNOTSUPP; return -EOPNOTSUPP;
if (sk->sk_state == BT_CLOSED) if (sk->sk_state == BT_CLOSED)
...@@ -1249,7 +1249,7 @@ static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg, ...@@ -1249,7 +1249,7 @@ static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg,
/* Stand-alone HCI commands must be flagged as /* Stand-alone HCI commands must be flagged as
* single-command requests. * single-command requests.
*/ */
bt_cb(skb)->req.start = true; bt_cb(skb)->hci.req_start = true;
skb_queue_tail(&hdev->cmd_q, skb); skb_queue_tail(&hdev->cmd_q, skb);
queue_work(hdev->workqueue, &hdev->cmd_work); queue_work(hdev->workqueue, &hdev->cmd_work);
......
...@@ -74,7 +74,7 @@ struct sco_pinfo { ...@@ -74,7 +74,7 @@ struct sco_pinfo {
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;
BT_DBG("sock %p state %d", sk, sk->sk_state); BT_DBG("sock %p state %d", sk, sk->sk_state);
...@@ -170,18 +170,21 @@ static void sco_conn_del(struct hci_conn *hcon, int err) ...@@ -170,18 +170,21 @@ static void sco_conn_del(struct hci_conn *hcon, int err)
sco_conn_unlock(conn); sco_conn_unlock(conn);
if (sk) { if (sk) {
sock_hold(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);
bh_unlock_sock(sk); bh_unlock_sock(sk);
sco_sock_kill(sk); sco_sock_kill(sk);
sock_put(sk);
} }
hcon->sco_data = NULL; hcon->sco_data = NULL;
kfree(conn); kfree(conn);
} }
static void __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)
{ {
BT_DBG("conn %p", conn); BT_DBG("conn %p", conn);
...@@ -414,8 +417,10 @@ static void __sco_sock_close(struct sock *sk) ...@@ -414,8 +417,10 @@ static void __sco_sock_close(struct sock *sk)
if (sco_pi(sk)->conn->hcon) { if (sco_pi(sk)->conn->hcon) {
sk->sk_state = BT_DISCONN; sk->sk_state = BT_DISCONN;
sco_sock_set_timer(sk, SCO_DISCONN_TIMEOUT); sco_sock_set_timer(sk, SCO_DISCONN_TIMEOUT);
sco_conn_lock(sco_pi(sk)->conn);
hci_conn_drop(sco_pi(sk)->conn->hcon); hci_conn_drop(sco_pi(sk)->conn->hcon);
sco_pi(sk)->conn->hcon = NULL; sco_pi(sk)->conn->hcon = NULL;
sco_conn_unlock(sco_pi(sk)->conn);
} else } else
sco_chan_del(sk, ECONNRESET); sco_chan_del(sk, ECONNRESET);
break; break;
...@@ -459,7 +464,8 @@ static struct proto sco_proto = { ...@@ -459,7 +464,8 @@ static struct proto sco_proto = {
.obj_size = sizeof(struct sco_pinfo) .obj_size = sizeof(struct sco_pinfo)
}; };
static struct sock *sco_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio, int kern) static struct sock *sco_sock_alloc(struct net *net, struct socket *sock,
int proto, gfp_t prio, int kern)
{ {
struct sock *sk; struct sock *sk;
...@@ -508,7 +514,8 @@ static int sco_sock_create(struct net *net, struct socket *sock, int protocol, ...@@ -508,7 +514,8 @@ 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 addr_len) static int sco_sock_bind(struct socket *sock, struct sockaddr *addr,
int addr_len)
{ {
struct sockaddr_sco *sa = (struct sockaddr_sco *) addr; struct sockaddr_sco *sa = (struct sockaddr_sco *) addr;
struct sock *sk = sock->sk; struct sock *sk = sock->sk;
...@@ -615,7 +622,8 @@ static int sco_sock_listen(struct socket *sock, int backlog) ...@@ -615,7 +622,8 @@ static int sco_sock_listen(struct socket *sock, int backlog)
return err; return err;
} }
static int sco_sock_accept(struct socket *sock, struct socket *newsock, int flags) static int sco_sock_accept(struct socket *sock, struct socket *newsock,
int flags)
{ {
DEFINE_WAIT_FUNC(wait, woken_wake_function); DEFINE_WAIT_FUNC(wait, woken_wake_function);
struct sock *sk = sock->sk, *ch; struct sock *sk = sock->sk, *ch;
...@@ -669,7 +677,8 @@ static int sco_sock_accept(struct socket *sock, struct socket *newsock, int flag ...@@ -669,7 +677,8 @@ static int sco_sock_accept(struct socket *sock, struct socket *newsock, int flag
return err; return err;
} }
static int sco_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer) static int sco_sock_getname(struct socket *sock, struct sockaddr *addr,
int *len, int peer)
{ {
struct sockaddr_sco *sa = (struct sockaddr_sco *) addr; struct sockaddr_sco *sa = (struct sockaddr_sco *) addr;
struct sock *sk = sock->sk; struct sock *sk = sock->sk;
...@@ -779,7 +788,8 @@ static int sco_sock_recvmsg(struct socket *sock, struct msghdr *msg, ...@@ -779,7 +788,8 @@ static int sco_sock_recvmsg(struct socket *sock, struct msghdr *msg,
return bt_sock_recvmsg(sock, msg, len, flags); return bt_sock_recvmsg(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 len, err = 0; int len, err = 0;
...@@ -819,7 +829,7 @@ static int sco_sock_setsockopt(struct socket *sock, int level, int optname, char ...@@ -819,7 +829,7 @@ static int sco_sock_setsockopt(struct socket *sock, int level, int optname, char
voice.setting = sco_pi(sk)->setting; voice.setting = sco_pi(sk)->setting;
len = min_t(unsigned int, sizeof(voice), optlen); len = min_t(unsigned int, sizeof(voice), optlen);
if (copy_from_user((char *) &voice, optval, len)) { if (copy_from_user((char *)&voice, optval, len)) {
err = -EFAULT; err = -EFAULT;
break; break;
} }
...@@ -843,7 +853,8 @@ static int sco_sock_setsockopt(struct socket *sock, int level, int optname, char ...@@ -843,7 +853,8 @@ static int sco_sock_setsockopt(struct socket *sock, int level, int optname, char
return err; return err;
} }
static int sco_sock_getsockopt_old(struct socket *sock, int optname, char __user *optval, int __user *optlen) static int sco_sock_getsockopt_old(struct socket *sock, int optname,
char __user *optval, int __user *optlen)
{ {
struct sock *sk = sock->sk; struct sock *sk = sock->sk;
struct sco_options opts; struct sco_options opts;
...@@ -903,7 +914,8 @@ static int sco_sock_getsockopt_old(struct socket *sock, int optname, char __user ...@@ -903,7 +914,8 @@ static int sco_sock_getsockopt_old(struct socket *sock, int optname, char __user
return err; return err;
} }
static int sco_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen) static int sco_sock_getsockopt(struct socket *sock, int level, int optname,
char __user *optval, int __user *optlen)
{ {
struct sock *sk = sock->sk; struct sock *sk = sock->sk;
int len, err = 0; int len, err = 0;
...@@ -928,7 +940,7 @@ static int sco_sock_getsockopt(struct socket *sock, int level, int optname, char ...@@ -928,7 +940,7 @@ static int sco_sock_getsockopt(struct socket *sock, int level, int optname, char
} }
if (put_user(test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags), if (put_user(test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags),
(u32 __user *) optval)) (u32 __user *)optval))
err = -EFAULT; err = -EFAULT;
break; break;
...@@ -961,7 +973,9 @@ static int sco_sock_shutdown(struct socket *sock, int how) ...@@ -961,7 +973,9 @@ static int sco_sock_shutdown(struct socket *sock, int how)
if (!sk) if (!sk)
return 0; return 0;
sock_hold(sk);
lock_sock(sk); lock_sock(sk);
if (!sk->sk_shutdown) { if (!sk->sk_shutdown) {
sk->sk_shutdown = SHUTDOWN_MASK; sk->sk_shutdown = SHUTDOWN_MASK;
sco_sock_clear_timer(sk); sco_sock_clear_timer(sk);
...@@ -972,7 +986,10 @@ static int sco_sock_shutdown(struct socket *sock, int how) ...@@ -972,7 +986,10 @@ static int sco_sock_shutdown(struct socket *sock, int how)
err = bt_sock_wait_state(sk, BT_CLOSED, err = bt_sock_wait_state(sk, BT_CLOSED,
sk->sk_lingertime); sk->sk_lingertime);
} }
release_sock(sk); release_sock(sk);
sock_put(sk);
return err; return err;
} }
...@@ -1016,6 +1033,11 @@ static void sco_conn_ready(struct sco_conn *conn) ...@@ -1016,6 +1033,11 @@ static void sco_conn_ready(struct sco_conn *conn)
} else { } else {
sco_conn_lock(conn); sco_conn_lock(conn);
if (!conn->hcon) {
sco_conn_unlock(conn);
return;
}
parent = sco_get_sock_listen(&conn->hcon->src); parent = sco_get_sock_listen(&conn->hcon->src);
if (!parent) { if (!parent) {
sco_conn_unlock(conn); sco_conn_unlock(conn);
......
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