Bluetooth: Add error return value to hci_req_sync callback
In some circumstances it may be useful to abort the request through
checks done in the request callback. To make the feature possible this
patch changes the return value of the request callback from void to
int and aborts the request if a non-zero value is returned.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c
index 4588fe2..ecfa410 100644
--- a/net/bluetooth/hci_request.c
+++ b/net/bluetooth/hci_request.c
@@ -184,8 +184,8 @@
EXPORT_SYMBOL(__hci_cmd_sync);
/* Execute request and wait for completion. */
-int __hci_req_sync(struct hci_dev *hdev, void (*func)(struct hci_request *req,
- unsigned long opt),
+int __hci_req_sync(struct hci_dev *hdev, int (*func)(struct hci_request *req,
+ unsigned long opt),
unsigned long opt, u32 timeout, u8 *hci_status)
{
struct hci_request req;
@@ -198,7 +198,12 @@
hdev->req_status = HCI_REQ_PEND;
- func(&req, opt);
+ err = func(&req, opt);
+ if (err) {
+ if (hci_status)
+ *hci_status = HCI_ERROR_UNSPECIFIED;
+ return err;
+ }
add_wait_queue(&hdev->req_wait_q, &wait);
set_current_state(TASK_INTERRUPTIBLE);
@@ -255,8 +260,8 @@
return err;
}
-int hci_req_sync(struct hci_dev *hdev, void (*req)(struct hci_request *req,
- unsigned long opt),
+int hci_req_sync(struct hci_dev *hdev, int (*req)(struct hci_request *req,
+ unsigned long opt),
unsigned long opt, u32 timeout, u8 *hci_status)
{
int ret;
@@ -830,11 +835,12 @@
return 0;
}
-static void update_bg_scan(struct hci_request *req, unsigned long opt)
+static int update_bg_scan(struct hci_request *req, unsigned long opt)
{
hci_dev_lock(req->hdev);
__hci_update_background_scan(req);
hci_dev_unlock(req->hdev);
+ return 0;
}
static void bg_scan_update(struct work_struct *work)
@@ -932,9 +938,10 @@
}
}
-static void le_scan_disable(struct hci_request *req, unsigned long opt)
+static int le_scan_disable(struct hci_request *req, unsigned long opt)
{
hci_req_add_le_scan_disable(req);
+ return 0;
}
static void le_scan_disable_work(struct work_struct *work)
@@ -1000,14 +1007,14 @@
hci_dev_unlock(hdev);
}
-static void le_scan_restart(struct hci_request *req, unsigned long opt)
+static int le_scan_restart(struct hci_request *req, unsigned long opt)
{
struct hci_dev *hdev = req->hdev;
struct hci_cp_le_set_scan_enable cp;
/* If controller is not scanning we are done. */
if (!hci_dev_test_flag(hdev, HCI_LE_SCAN))
- return;
+ return 0;
hci_req_add_le_scan_disable(req);
@@ -1015,6 +1022,8 @@
cp.enable = LE_SCAN_ENABLE;
cp.filter_dup = LE_SCAN_FILTER_DUP_ENABLE;
hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
+
+ return 0;
}
static void le_scan_restart_work(struct work_struct *work)