mirror of
https://github.com/torvalds/linux.git
synced 2024-11-27 22:51:35 +00:00
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: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
5bf8921116
@ -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",
|
||||
cal_data + BT_CAL_HDR_LEN,
|
||||
BT_CAL_DATA_SIZE);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
of_node_put(dt_node);
|
||||
return ret;
|
||||
}
|
||||
|
||||
BT_DBG("Use cal data from device tree");
|
||||
ret = btmrvl_download_cal_data(priv, cal_data,
|
||||
BT_CAL_DATA_SIZE);
|
||||
if (ret) {
|
||||
BT_ERR("Fail to download calibrate data");
|
||||
of_node_put(dt_node);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
u16 opcode, struct sk_buff *skb);
|
||||
|
||||
struct req_ctrl {
|
||||
bool start;
|
||||
u8 event;
|
||||
hci_req_complete_t complete;
|
||||
hci_req_complete_skb_t complete_skb;
|
||||
struct hci_ctrl {
|
||||
__u16 opcode;
|
||||
bool req_start;
|
||||
u8 req_event;
|
||||
hci_req_complete_t req_complete;
|
||||
hci_req_complete_skb_t req_complete_skb;
|
||||
};
|
||||
|
||||
struct bt_skb_cb {
|
||||
__u8 pkt_type;
|
||||
__u8 force_active;
|
||||
__u16 opcode;
|
||||
__u16 expect;
|
||||
__u8 incoming:1;
|
||||
union {
|
||||
struct l2cap_ctrl l2cap;
|
||||
struct req_ctrl req;
|
||||
struct hci_ctrl hci;
|
||||
};
|
||||
};
|
||||
#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)
|
||||
if (!skb_cp)
|
||||
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,
|
||||
|
@ -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);
|
||||
|
||||
if (flags & (MSG_OOB))
|
||||
if (flags & MSG_OOB)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
skb = skb_recv_datagram(sk, flags, noblock, &err);
|
||||
|
@ -65,13 +65,6 @@ static DEFINE_IDA(hci_index_ida);
|
||||
#define hci_req_lock(d) mutex_lock(&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 ---- */
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
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);
|
||||
set_bit(HCI_INIT, &hdev->flags);
|
||||
@ -1524,7 +1517,7 @@ static int hci_dev_do_open(struct hci_dev *hdev)
|
||||
hci_dev_hold(hdev);
|
||||
hci_dev_set_flag(hdev, HCI_RPA_EXPIRED);
|
||||
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) &&
|
||||
!hci_dev_test_flag(hdev, HCI_CONFIG) &&
|
||||
!hci_dev_test_flag(hdev, HCI_UNCONFIGURED) &&
|
||||
@ -1552,7 +1545,7 @@ static int hci_dev_do_open(struct hci_dev *hdev)
|
||||
}
|
||||
|
||||
clear_bit(HCI_RUNNING, &hdev->flags);
|
||||
hci_notify(hdev, HCI_DEV_CLOSE);
|
||||
hci_sock_dev_event(hdev, HCI_DEV_CLOSE);
|
||||
|
||||
hdev->close(hdev);
|
||||
hdev->flags &= BIT(HCI_RAW);
|
||||
@ -1708,7 +1701,7 @@ int hci_dev_do_close(struct hci_dev *hdev)
|
||||
|
||||
smp_unregister(hdev);
|
||||
|
||||
hci_notify(hdev, HCI_DEV_DOWN);
|
||||
hci_sock_dev_event(hdev, HCI_DEV_DOWN);
|
||||
|
||||
if (hdev->flush)
|
||||
hdev->flush(hdev);
|
||||
@ -1739,7 +1732,7 @@ int hci_dev_do_close(struct hci_dev *hdev)
|
||||
}
|
||||
|
||||
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
|
||||
* and no tasks are scheduled. */
|
||||
@ -3414,7 +3407,7 @@ int hci_register_dev(struct hci_dev *hdev)
|
||||
if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
|
||||
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);
|
||||
|
||||
queue_work(hdev->req_workqueue, &hdev->power_on);
|
||||
@ -3462,7 +3455,7 @@ void hci_unregister_dev(struct hci_dev *hdev)
|
||||
* pending list */
|
||||
BUG_ON(!list_empty(&hdev->mgmt_pending));
|
||||
|
||||
hci_notify(hdev, HCI_DEV_UNREG);
|
||||
hci_sock_dev_event(hdev, HCI_DEV_UNREG);
|
||||
|
||||
if (hdev->rfkill) {
|
||||
rfkill_unregister(hdev->rfkill);
|
||||
@ -3499,7 +3492,7 @@ EXPORT_SYMBOL(hci_unregister_dev);
|
||||
/* Suspend HCI device */
|
||||
int hci_suspend_dev(struct hci_dev *hdev)
|
||||
{
|
||||
hci_notify(hdev, HCI_DEV_SUSPEND);
|
||||
hci_sock_dev_event(hdev, HCI_DEV_SUSPEND);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(hci_suspend_dev);
|
||||
@ -3507,7 +3500,7 @@ EXPORT_SYMBOL(hci_suspend_dev);
|
||||
/* Resume HCI device */
|
||||
int hci_resume_dev(struct hci_dev *hdev)
|
||||
{
|
||||
hci_notify(hdev, HCI_DEV_RESUME);
|
||||
hci_sock_dev_event(hdev, HCI_DEV_RESUME);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(hci_resume_dev);
|
||||
@ -3650,7 +3643,7 @@ int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen,
|
||||
/* Stand-alone HCI commands must be flagged as
|
||||
* single-command requests.
|
||||
*/
|
||||
bt_cb(skb)->req.start = true;
|
||||
bt_cb(skb)->hci.req_start = true;
|
||||
|
||||
skb_queue_tail(&hdev->cmd_q, skb);
|
||||
queue_work(hdev->workqueue, &hdev->cmd_work);
|
||||
@ -4347,7 +4340,7 @@ static bool hci_req_is_complete(struct hci_dev *hdev)
|
||||
if (!skb)
|
||||
return true;
|
||||
|
||||
return bt_cb(skb)->req.start;
|
||||
return bt_cb(skb)->hci.req_start;
|
||||
}
|
||||
|
||||
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,
|
||||
* callback would be found in hdev->sent_cmd instead of the
|
||||
* command queue (hdev->cmd_q).
|
||||
*/
|
||||
if (bt_cb(hdev->sent_cmd)->req.complete) {
|
||||
*req_complete = bt_cb(hdev->sent_cmd)->req.complete;
|
||||
if (bt_cb(hdev->sent_cmd)->hci.req_complete) {
|
||||
*req_complete = bt_cb(hdev->sent_cmd)->hci.req_complete;
|
||||
return;
|
||||
}
|
||||
|
||||
if (bt_cb(hdev->sent_cmd)->req.complete_skb) {
|
||||
*req_complete_skb = 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)->hci.req_complete_skb;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Remove all pending commands belonging to this request */
|
||||
spin_lock_irqsave(&hdev->cmd_q.lock, flags);
|
||||
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);
|
||||
break;
|
||||
}
|
||||
|
||||
*req_complete = bt_cb(skb)->req.complete;
|
||||
*req_complete_skb = bt_cb(skb)->req.complete_skb;
|
||||
*req_complete = bt_cb(skb)->hci.req_complete;
|
||||
*req_complete_skb = bt_cb(skb)->hci.req_complete_skb;
|
||||
kfree_skb(skb);
|
||||
}
|
||||
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,
|
||||
* complete event).
|
||||
*/
|
||||
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,
|
||||
req_complete_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;
|
||||
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;
|
||||
opcode = __le16_to_cpu(cmd_hdr->opcode);
|
||||
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,
|
||||
return -ENODATA;
|
||||
|
||||
skb = skb_peek_tail(&req->cmd_q);
|
||||
bt_cb(skb)->req.complete = complete;
|
||||
bt_cb(skb)->req.complete_skb = complete_skb;
|
||||
bt_cb(skb)->hci.req_complete = complete;
|
||||
bt_cb(skb)->hci.req_complete_skb = complete_skb;
|
||||
|
||||
spin_lock_irqsave(&hdev->cmd_q.lock, flags);
|
||||
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,
|
||||
BT_DBG("skb len %d", skb->len);
|
||||
|
||||
bt_cb(skb)->pkt_type = HCI_COMMAND_PKT;
|
||||
bt_cb(skb)->opcode = opcode;
|
||||
bt_cb(skb)->hci.opcode = opcode;
|
||||
|
||||
return skb;
|
||||
}
|
||||
@ -128,9 +128,9 @@ void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen,
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
if (flags & (MSG_OOB))
|
||||
if (flags & MSG_OOB)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (sk->sk_state == BT_CLOSED)
|
||||
@ -1249,7 +1249,7 @@ static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg,
|
||||
/* Stand-alone HCI commands must be flagged as
|
||||
* single-command requests.
|
||||
*/
|
||||
bt_cb(skb)->req.start = true;
|
||||
bt_cb(skb)->hci.req_start = true;
|
||||
|
||||
skb_queue_tail(&hdev->cmd_q, skb);
|
||||
queue_work(hdev->workqueue, &hdev->cmd_work);
|
||||
|
@ -74,7 +74,7 @@ struct sco_pinfo {
|
||||
|
||||
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);
|
||||
|
||||
@ -170,18 +170,21 @@ static void sco_conn_del(struct hci_conn *hcon, int err)
|
||||
sco_conn_unlock(conn);
|
||||
|
||||
if (sk) {
|
||||
sock_hold(sk);
|
||||
bh_lock_sock(sk);
|
||||
sco_sock_clear_timer(sk);
|
||||
sco_chan_del(sk, err);
|
||||
bh_unlock_sock(sk);
|
||||
sco_sock_kill(sk);
|
||||
sock_put(sk);
|
||||
}
|
||||
|
||||
hcon->sco_data = NULL;
|
||||
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);
|
||||
|
||||
@ -414,8 +417,10 @@ static void __sco_sock_close(struct sock *sk)
|
||||
if (sco_pi(sk)->conn->hcon) {
|
||||
sk->sk_state = BT_DISCONN;
|
||||
sco_sock_set_timer(sk, SCO_DISCONN_TIMEOUT);
|
||||
sco_conn_lock(sco_pi(sk)->conn);
|
||||
hci_conn_drop(sco_pi(sk)->conn->hcon);
|
||||
sco_pi(sk)->conn->hcon = NULL;
|
||||
sco_conn_unlock(sco_pi(sk)->conn);
|
||||
} else
|
||||
sco_chan_del(sk, ECONNRESET);
|
||||
break;
|
||||
@ -459,7 +464,8 @@ static struct proto sco_proto = {
|
||||
.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;
|
||||
|
||||
@ -508,7 +514,8 @@ static int sco_sock_create(struct net *net, struct socket *sock, int protocol,
|
||||
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 sock *sk = sock->sk;
|
||||
@ -615,7 +622,8 @@ done:
|
||||
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);
|
||||
struct sock *sk = sock->sk, *ch;
|
||||
@ -669,7 +677,8 @@ done:
|
||||
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 sock *sk = sock->sk;
|
||||
@ -779,7 +788,8 @@ static int sco_sock_recvmsg(struct socket *sock, struct msghdr *msg,
|
||||
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;
|
||||
int len, err = 0;
|
||||
@ -819,7 +829,7 @@ static int sco_sock_setsockopt(struct socket *sock, int level, int optname, char
|
||||
voice.setting = sco_pi(sk)->setting;
|
||||
|
||||
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;
|
||||
break;
|
||||
}
|
||||
@ -843,7 +853,8 @@ static int sco_sock_setsockopt(struct socket *sock, int level, int optname, char
|
||||
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 sco_options opts;
|
||||
@ -903,7 +914,8 @@ static int sco_sock_getsockopt_old(struct socket *sock, int optname, char __user
|
||||
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;
|
||||
int len, err = 0;
|
||||
@ -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),
|
||||
(u32 __user *) optval))
|
||||
(u32 __user *)optval))
|
||||
err = -EFAULT;
|
||||
|
||||
break;
|
||||
@ -961,7 +973,9 @@ static int sco_sock_shutdown(struct socket *sock, int how)
|
||||
if (!sk)
|
||||
return 0;
|
||||
|
||||
sock_hold(sk);
|
||||
lock_sock(sk);
|
||||
|
||||
if (!sk->sk_shutdown) {
|
||||
sk->sk_shutdown = SHUTDOWN_MASK;
|
||||
sco_sock_clear_timer(sk);
|
||||
@ -972,7 +986,10 @@ static int sco_sock_shutdown(struct socket *sock, int how)
|
||||
err = bt_sock_wait_state(sk, BT_CLOSED,
|
||||
sk->sk_lingertime);
|
||||
}
|
||||
|
||||
release_sock(sk);
|
||||
sock_put(sk);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -1016,6 +1033,11 @@ static void sco_conn_ready(struct sco_conn *conn)
|
||||
} else {
|
||||
sco_conn_lock(conn);
|
||||
|
||||
if (!conn->hcon) {
|
||||
sco_conn_unlock(conn);
|
||||
return;
|
||||
}
|
||||
|
||||
parent = sco_get_sock_listen(&conn->hcon->src);
|
||||
if (!parent) {
|
||||
sco_conn_unlock(conn);
|
||||
|
Loading…
Reference in New Issue
Block a user