int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr)
 {
        struct bdaddr_list *entry;
-       int err;
 
        if (bacmp(bdaddr, BDADDR_ANY) == 0)
                return -EBADF;
 
-       hci_dev_lock_bh(hdev);
-
-       if (hci_blacklist_lookup(hdev, bdaddr)) {
-               err = -EEXIST;
-               goto err;
-       }
+       if (hci_blacklist_lookup(hdev, bdaddr))
+               return -EEXIST;
 
        entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL);
-       if (!entry) {
-               err = -ENOMEM;
-               goto err;
-       }
+       if (!entry)
+               return -ENOMEM;
 
        bacpy(&entry->bdaddr, bdaddr);
 
        list_add(&entry->list, &hdev->blacklist);
 
-       err = 0;
-
-err:
-       hci_dev_unlock_bh(hdev);
-       return err;
+       return mgmt_device_blocked(hdev->id, bdaddr);
 }
 
 int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr)
 {
        struct bdaddr_list *entry;
-       int err = 0;
-
-       hci_dev_lock_bh(hdev);
 
        if (bacmp(bdaddr, BDADDR_ANY) == 0) {
-               hci_blacklist_clear(hdev);
-               goto done;
+               return hci_blacklist_clear(hdev);
        }
 
        entry = hci_blacklist_lookup(hdev, bdaddr);
        if (!entry) {
-               err = -ENOENT;
-               goto done;
+               return -ENOENT;
        }
 
        list_del(&entry->list);
        kfree(entry);
 
-done:
-       hci_dev_unlock_bh(hdev);
-       return err;
+       return mgmt_device_unblocked(hdev->id, bdaddr);
 }
 
 static void hci_clear_adv_cache(unsigned long arg)
 
 static int hci_sock_blacklist_add(struct hci_dev *hdev, void __user *arg)
 {
        bdaddr_t bdaddr;
+       int err;
 
        if (copy_from_user(&bdaddr, arg, sizeof(bdaddr)))
                return -EFAULT;
 
-       return hci_blacklist_add(hdev, &bdaddr);
+       hci_dev_lock_bh(hdev);
+
+       err = hci_blacklist_add(hdev, &bdaddr);
+
+       hci_dev_unlock_bh(hdev);
+
+       return err;
 }
 
 static int hci_sock_blacklist_del(struct hci_dev *hdev, void __user *arg)
 {
        bdaddr_t bdaddr;
+       int err;
 
        if (copy_from_user(&bdaddr, arg, sizeof(bdaddr)))
                return -EFAULT;
 
-       return hci_blacklist_del(hdev, &bdaddr);
+       hci_dev_lock_bh(hdev);
+
+       err = hci_blacklist_del(hdev, &bdaddr);
+
+       hci_dev_unlock_bh(hdev);
+
+       return err;
 }
 
 /* Ioctls that require bound socket */
 
                                                                u16 len)
 {
        struct hci_dev *hdev;
-       struct mgmt_cp_block_device *cp;
+       struct pending_cmd *cmd;
+       struct mgmt_cp_block_device *cp = (void *) data;
        int err;
 
        BT_DBG("hci%u", index);
 
-       cp = (void *) data;
-
        if (len != sizeof(*cp))
                return cmd_status(sk, index, MGMT_OP_BLOCK_DEVICE,
                                                        EINVAL);
                return cmd_status(sk, index, MGMT_OP_BLOCK_DEVICE,
                                                        ENODEV);
 
+       hci_dev_lock_bh(hdev);
+
+       cmd = mgmt_pending_add(sk, MGMT_OP_BLOCK_DEVICE, index, NULL, 0);
+       if (!cmd) {
+               err = -ENOMEM;
+               goto failed;
+       }
+
        err = hci_blacklist_add(hdev, &cp->bdaddr);
 
        if (err < 0)
        else
                err = cmd_complete(sk, index, MGMT_OP_BLOCK_DEVICE,
                                                        NULL, 0);
+
+       mgmt_pending_remove(cmd);
+
+failed:
+       hci_dev_unlock_bh(hdev);
        hci_dev_put(hdev);
 
        return err;
                                                                u16 len)
 {
        struct hci_dev *hdev;
-       struct mgmt_cp_unblock_device *cp;
+       struct pending_cmd *cmd;
+       struct mgmt_cp_unblock_device *cp = (void *) data;
        int err;
 
        BT_DBG("hci%u", index);
 
-       cp = (void *) data;
-
        if (len != sizeof(*cp))
                return cmd_status(sk, index, MGMT_OP_UNBLOCK_DEVICE,
                                                                EINVAL);
                return cmd_status(sk, index, MGMT_OP_UNBLOCK_DEVICE,
                                                                ENODEV);
 
+       hci_dev_lock_bh(hdev);
+
+       cmd = mgmt_pending_add(sk, MGMT_OP_UNBLOCK_DEVICE, index, NULL, 0);
+       if (!cmd) {
+               err = -ENOMEM;
+               goto failed;
+       }
+
        err = hci_blacklist_del(hdev, &cp->bdaddr);
 
        if (err < 0)
        else
                err = cmd_complete(sk, index, MGMT_OP_UNBLOCK_DEVICE,
                                                                NULL, 0);
+
+       mgmt_pending_remove(cmd);
+
+failed:
+       hci_dev_unlock_bh(hdev);
        hci_dev_put(hdev);
 
        return err;
        return mgmt_event(MGMT_EV_DISCOVERING, index, &discovering,
                                                sizeof(discovering), NULL);
 }
+
+int mgmt_device_blocked(u16 index, bdaddr_t *bdaddr)
+{
+       struct pending_cmd *cmd;
+       struct mgmt_ev_device_blocked ev;
+
+       cmd = mgmt_pending_find(MGMT_OP_BLOCK_DEVICE, index);
+
+       bacpy(&ev.bdaddr, bdaddr);
+
+       return mgmt_event(MGMT_EV_DEVICE_BLOCKED, index, &ev, sizeof(ev),
+                                               cmd ? cmd->sk : NULL);
+}
+
+int mgmt_device_unblocked(u16 index, bdaddr_t *bdaddr)
+{
+       struct pending_cmd *cmd;
+       struct mgmt_ev_device_unblocked ev;
+
+       cmd = mgmt_pending_find(MGMT_OP_UNBLOCK_DEVICE, index);
+
+       bacpy(&ev.bdaddr, bdaddr);
+
+       return mgmt_event(MGMT_EV_DEVICE_UNBLOCKED, index, &ev, sizeof(ev),
+                                               cmd ? cmd->sk : NULL);
+}