]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - net/bluetooth/hci_core.c
Merge tag 'v2.6.38' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[mv-sheeva.git] / net / bluetooth / hci_core.c
index bc2a052e518b37518eaf9e128ce418d195bd91e1..9c4541bc488ab9b2a74dda2809929f842b9b97e6 100644 (file)
@@ -44,7 +44,7 @@
 #include <net/sock.h>
 
 #include <asm/system.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 #include <asm/unaligned.h>
 
 #include <net/bluetooth/bluetooth.h>
@@ -91,9 +91,16 @@ static void hci_notify(struct hci_dev *hdev, int event)
 
 /* ---- HCI requests ---- */
 
-void hci_req_complete(struct hci_dev *hdev, int result)
+void hci_req_complete(struct hci_dev *hdev, __u16 cmd, int result)
 {
-       BT_DBG("%s result 0x%2.2x", hdev->name, result);
+       BT_DBG("%s command 0x%04x result 0x%2.2x", hdev->name, cmd, result);
+
+       /* If the request has set req_last_cmd (typical for multi-HCI
+        * command requests) check if the completed command matches
+        * this, and if not just return. Single HCI command requests
+        * typically leave req_last_cmd as 0 */
+       if (hdev->req_last_cmd && cmd != hdev->req_last_cmd)
+               return;
 
        if (hdev->req_status == HCI_REQ_PEND) {
                hdev->req_result = result;
@@ -149,7 +156,7 @@ static int __hci_request(struct hci_dev *hdev, void (*req)(struct hci_dev *hdev,
                break;
        }
 
-       hdev->req_status = hdev->req_result = 0;
+       hdev->req_last_cmd = hdev->req_status = hdev->req_result = 0;
 
        BT_DBG("%s end: err %d", hdev->name, err);
 
@@ -252,6 +259,8 @@ static void hci_init_req(struct hci_dev *hdev, unsigned long opt)
        /* Connection accept timeout ~20 secs */
        param = cpu_to_le16(0x7d00);
        hci_send_cmd(hdev, HCI_OP_WRITE_CA_TIMEOUT, 2, &param);
+
+       hdev->req_last_cmd = HCI_OP_WRITE_CA_TIMEOUT;
 }
 
 static void hci_scan_req(struct hci_dev *hdev, unsigned long opt)
@@ -349,20 +358,23 @@ struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, bdaddr_t *b
 void hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data)
 {
        struct inquiry_cache *cache = &hdev->inq_cache;
-       struct inquiry_entry *e;
+       struct inquiry_entry *ie;
 
        BT_DBG("cache %p, %s", cache, batostr(&data->bdaddr));
 
-       if (!(e = hci_inquiry_cache_lookup(hdev, &data->bdaddr))) {
+       ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr);
+       if (!ie) {
                /* Entry not in the cache. Add new one. */
-               if (!(e = kzalloc(sizeof(struct inquiry_entry), GFP_ATOMIC)))
+               ie = kzalloc(sizeof(struct inquiry_entry), GFP_ATOMIC);
+               if (!ie)
                        return;
-               e->next     = cache->list;
-               cache->list = e;
+
+               ie->next = cache->list;
+               cache->list = ie;
        }
 
-       memcpy(&e->data, data, sizeof(*data));
-       e->timestamp = jiffies;
+       memcpy(&ie->data, data, sizeof(*data));
+       ie->timestamp = jiffies;
        cache->timestamp = jiffies;
 }
 
@@ -422,16 +434,20 @@ int hci_inquiry(void __user *arg)
 
        hci_dev_lock_bh(hdev);
        if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX ||
-                                       inquiry_cache_empty(hdev) ||
-                                       ir.flags & IREQ_CACHE_FLUSH) {
+                               inquiry_cache_empty(hdev) ||
+                               ir.flags & IREQ_CACHE_FLUSH) {
                inquiry_cache_flush(hdev);
                do_inquiry = 1;
        }
        hci_dev_unlock_bh(hdev);
 
        timeo = ir.length * msecs_to_jiffies(2000);
-       if (do_inquiry && (err = hci_request(hdev, hci_inq_req, (unsigned long)&ir, timeo)) < 0)
-               goto done;
+
+       if (do_inquiry) {
+               err = hci_request(hdev, hci_inq_req, (unsigned long)&ir, timeo);
+               if (err < 0)
+                       goto done;
+       }
 
        /* for unlimited number of responses we will use buffer with 255 entries */
        max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp;
@@ -439,7 +455,8 @@ int hci_inquiry(void __user *arg)
        /* cache_dump can't sleep. Therefore we allocate temp buffer and then
         * copy it to the user space.
         */
-       if (!(buf = kmalloc(sizeof(struct inquiry_info) * max_rsp, GFP_KERNEL))) {
+       buf = kmalloc(sizeof(struct inquiry_info) *max_rsp, GFP_KERNEL);
+       if (!buf) {
                err = -ENOMEM;
                goto done;
        }
@@ -611,7 +628,8 @@ int hci_dev_close(__u16 dev)
        struct hci_dev *hdev;
        int err;
 
-       if (!(hdev = hci_dev_get(dev)))
+       hdev = hci_dev_get(dev);
+       if (!hdev)
                return -ENODEV;
        err = hci_dev_do_close(hdev);
        hci_dev_put(hdev);
@@ -623,7 +641,8 @@ int hci_dev_reset(__u16 dev)
        struct hci_dev *hdev;
        int ret = 0;
 
-       if (!(hdev = hci_dev_get(dev)))
+       hdev = hci_dev_get(dev);
+       if (!hdev)
                return -ENODEV;
 
        hci_req_lock(hdev);
@@ -663,7 +682,8 @@ int hci_dev_reset_stat(__u16 dev)
        struct hci_dev *hdev;
        int ret = 0;
 
-       if (!(hdev = hci_dev_get(dev)))
+       hdev = hci_dev_get(dev);
+       if (!hdev)
                return -ENODEV;
 
        memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
@@ -682,7 +702,8 @@ int hci_dev_cmd(unsigned int cmd, void __user *arg)
        if (copy_from_user(&dr, arg, sizeof(dr)))
                return -EFAULT;
 
-       if (!(hdev = hci_dev_get(dr.dev_id)))
+       hdev = hci_dev_get(dr.dev_id);
+       if (!hdev)
                return -ENODEV;
 
        switch (cmd) {
@@ -763,7 +784,8 @@ int hci_get_dev_list(void __user *arg)
 
        size = sizeof(*dl) + dev_num * sizeof(*dr);
 
-       if (!(dl = kzalloc(size, GFP_KERNEL)))
+       dl = kzalloc(size, GFP_KERNEL);
+       if (!dl)
                return -ENOMEM;
 
        dr = dl->dev_req;
@@ -797,7 +819,8 @@ int hci_get_dev_info(void __user *arg)
        if (copy_from_user(&di, arg, sizeof(di)))
                return -EFAULT;
 
-       if (!(hdev = hci_dev_get(di.dev_id)))
+       hdev = hci_dev_get(di.dev_id);
+       if (!hdev)
                return -ENODEV;
 
        strcpy(di.name, hdev->name);
@@ -905,7 +928,7 @@ int hci_register_dev(struct hci_dev *hdev)
        hdev->sniff_max_interval = 800;
        hdev->sniff_min_interval = 80;
 
-       tasklet_init(&hdev->cmd_task, hci_cmd_task,(unsigned long) hdev);
+       tasklet_init(&hdev->cmd_task, hci_cmd_task, (unsigned long) hdev);
        tasklet_init(&hdev->rx_task, hci_rx_task, (unsigned long) hdev);
        tasklet_init(&hdev->tx_task, hci_tx_task, (unsigned long) hdev);
 
@@ -946,6 +969,7 @@ int hci_register_dev(struct hci_dev *hdev)
                }
        }
 
+       mgmt_index_added(hdev->id);
        hci_notify(hdev, HCI_DEV_REG);
 
        return id;
@@ -975,6 +999,7 @@ int hci_unregister_dev(struct hci_dev *hdev)
        for (i = 0; i < NUM_REASSEMBLY; i++)
                kfree_skb(hdev->reassembly[i]);
 
+       mgmt_index_removed(hdev->id);
        hci_notify(hdev, HCI_DEV_UNREG);
 
        if (hdev->rfkill) {
@@ -986,6 +1011,10 @@ int hci_unregister_dev(struct hci_dev *hdev)
 
        destroy_workqueue(hdev->workqueue);
 
+       hci_dev_lock_bh(hdev);
+       hci_blacklist_clear(hdev);
+       hci_dev_unlock_bh(hdev);
+
        __hci_dev_put(hdev);
 
        return 0;
@@ -1368,7 +1397,8 @@ void hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags)
        bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
        hci_add_acl_hdr(skb, conn->handle, flags | ACL_START);
 
-       if (!(list = skb_shinfo(skb)->frag_list)) {
+       list = skb_shinfo(skb)->frag_list;
+       if (!list) {
                /* Non fragmented */
                BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
 
@@ -1609,7 +1639,8 @@ static inline void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
                hci_conn_enter_active_mode(conn);
 
                /* Send to upper protocol */
-               if ((hp = hci_proto[HCI_PROTO_L2CAP]) && hp->recv_acldata) {
+               hp = hci_proto[HCI_PROTO_L2CAP];
+               if (hp && hp->recv_acldata) {
                        hp->recv_acldata(conn, skb, flags);
                        return;
                }
@@ -1644,7 +1675,8 @@ static inline void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
                register struct hci_proto *hp;
 
                /* Send to upper protocol */
-               if ((hp = hci_proto[HCI_PROTO_SCO]) && hp->recv_scodata) {
+               hp = hci_proto[HCI_PROTO_SCO];
+               if (hp && hp->recv_scodata) {
                        hp->recv_scodata(conn, skb);
                        return;
                }
@@ -1727,7 +1759,8 @@ static void hci_cmd_task(unsigned long arg)
        if (atomic_read(&hdev->cmd_cnt) && (skb = skb_dequeue(&hdev->cmd_q))) {
                kfree_skb(hdev->sent_cmd);
 
-               if ((hdev->sent_cmd = skb_clone(skb, GFP_ATOMIC))) {
+               hdev->sent_cmd = skb_clone(skb, GFP_ATOMIC);
+               if (hdev->sent_cmd) {
                        atomic_dec(&hdev->cmd_cnt);
                        hci_send_frame(skb);
                        hdev->cmd_last_tx = jiffies;