diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h index 10eb9b3..2ee2520 100644 --- a/include/net/bluetooth/bluetooth.h +++ b/include/net/bluetooth/bluetooth.h @@ -265,6 +265,7 @@ typedef void (*hci_req_complete_t)(struct hci_dev *hdev, u8 status); struct hci_req_ctrl { bool start; + bool ignore_status; u8 event; hci_req_complete_t complete; }; diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 7cb6d36..f1d7500 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -1084,7 +1084,7 @@ int hci_req_run(struct hci_request *req, hci_req_complete_t complete); void hci_req_add(struct hci_request *req, u16 opcode, u32 plen, const void *param); void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen, - const void *param, u8 event); + const void *param, u8 event, bool ignore_status); void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status); struct sk_buff *__hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen, diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index d817c93..c3d5056 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -145,7 +145,7 @@ struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen, hci_req_init(&req, hdev); - hci_req_add_ev(&req, opcode, plen, param, event); + hci_req_add_ev(&req, opcode, plen, param, event, false); hdev->req_status = HCI_REQ_PEND; @@ -367,7 +367,8 @@ static void bredr_setup(struct hci_request *req) bacpy(&cp.bdaddr, BDADDR_ANY); cp.delete_all = 0x01; - hci_req_add(req, HCI_OP_DELETE_STORED_LINK_KEY, sizeof(cp), &cp); + hci_req_add_ev(req, HCI_OP_DELETE_STORED_LINK_KEY, sizeof(cp), &cp, + 0, true); /* Read page scan parameters */ if (req->hdev->hci_ver > BLUETOOTH_VER_1_1) { @@ -2669,7 +2670,7 @@ int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, /* Queue a command to an asynchronous HCI request */ void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen, - const void *param, u8 event) + const void *param, u8 event, bool ignore_status) { struct hci_dev *hdev = req->hdev; struct sk_buff *skb; @@ -2694,6 +2695,7 @@ void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen, bt_cb(skb)->req.start = true; bt_cb(skb)->req.event = event; + bt_cb(skb)->req.ignore_status = ignore_status; skb_queue_tail(&req->cmd_q, skb); } @@ -2701,7 +2703,7 @@ void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen, void hci_req_add(struct hci_request *req, u16 opcode, u32 plen, const void *param) { - hci_req_add_ev(req, opcode, plen, param, 0); + hci_req_add_ev(req, opcode, plen, param, 0, false); } /* Get data from the previously sent command */ @@ -3425,6 +3427,10 @@ void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status) return; } + /* Check for commands whose failures aren't critical */ + if (bt_cb(hdev->sent_cmd)->req.ignore_status) + status = 0; + /* If the command succeeded and there's still more commands in * this request the request is not yet complete. */