aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@intel.com>2015-11-11 01:11:19 -0500
committerMarcel Holtmann <marcel@holtmann.org>2015-11-19 11:50:29 -0500
commit4ebeee2dff9815619be6ff9a845d33716f48468c (patch)
treed8ba8497c1a04a6566f27426ba14bf95c4eb5cb9
parent51d7a94d56f842a6bd752c11de2f80f2cbc4a507 (diff)
Bluetooth: Add HCI status return parameter to hci_req_sync()
In some cases it may be important to get the exact HCI status rather than the converted HCI-to-errno value. Add an optional return parameter to the hci_req_sync() API to allow for this. Since there are no good HCI translation candidates for cancelation and timeout, use the "unknown" status code for those cases. Signed-off-by: Johan Hedberg <johan.hedberg@intel.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
-rw-r--r--include/net/bluetooth/hci.h3
-rw-r--r--net/bluetooth/hci_core.c26
-rw-r--r--net/bluetooth/hci_request.c12
-rw-r--r--net/bluetooth/hci_request.h4
4 files changed, 26 insertions, 19 deletions
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 0205b80cc90b..cc2216727655 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -452,7 +452,8 @@ enum {
452#define HCI_ERROR_REMOTE_POWER_OFF 0x15 452#define HCI_ERROR_REMOTE_POWER_OFF 0x15
453#define HCI_ERROR_LOCAL_HOST_TERM 0x16 453#define HCI_ERROR_LOCAL_HOST_TERM 0x16
454#define HCI_ERROR_PAIRING_NOT_ALLOWED 0x18 454#define HCI_ERROR_PAIRING_NOT_ALLOWED 0x18
455#define HCI_ERROR_INVALID_LL_PARAMS 0x1E 455#define HCI_ERROR_INVALID_LL_PARAMS 0x1e
456#define HCI_ERROR_UNSPECIFIED 0x1f
456#define HCI_ERROR_ADVERTISING_TIMEOUT 0x3c 457#define HCI_ERROR_ADVERTISING_TIMEOUT 0x3c
457 458
458/* Flow control modes */ 459/* Flow control modes */
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 965bc01a0d91..029d7798cffa 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -768,14 +768,14 @@ static int __hci_init(struct hci_dev *hdev)
768{ 768{
769 int err; 769 int err;
770 770
771 err = __hci_req_sync(hdev, hci_init1_req, 0, HCI_INIT_TIMEOUT); 771 err = __hci_req_sync(hdev, hci_init1_req, 0, HCI_INIT_TIMEOUT, NULL);
772 if (err < 0) 772 if (err < 0)
773 return err; 773 return err;
774 774
775 if (hci_dev_test_flag(hdev, HCI_SETUP)) 775 if (hci_dev_test_flag(hdev, HCI_SETUP))
776 hci_debugfs_create_basic(hdev); 776 hci_debugfs_create_basic(hdev);
777 777
778 err = __hci_req_sync(hdev, hci_init2_req, 0, HCI_INIT_TIMEOUT); 778 err = __hci_req_sync(hdev, hci_init2_req, 0, HCI_INIT_TIMEOUT, NULL);
779 if (err < 0) 779 if (err < 0)
780 return err; 780 return err;
781 781
@@ -786,11 +786,11 @@ static int __hci_init(struct hci_dev *hdev)
786 if (hdev->dev_type != HCI_BREDR) 786 if (hdev->dev_type != HCI_BREDR)
787 return 0; 787 return 0;
788 788
789 err = __hci_req_sync(hdev, hci_init3_req, 0, HCI_INIT_TIMEOUT); 789 err = __hci_req_sync(hdev, hci_init3_req, 0, HCI_INIT_TIMEOUT, NULL);
790 if (err < 0) 790 if (err < 0)
791 return err; 791 return err;
792 792
793 err = __hci_req_sync(hdev, hci_init4_req, 0, HCI_INIT_TIMEOUT); 793 err = __hci_req_sync(hdev, hci_init4_req, 0, HCI_INIT_TIMEOUT, NULL);
794 if (err < 0) 794 if (err < 0)
795 return err; 795 return err;
796 796
@@ -846,7 +846,7 @@ static int __hci_unconf_init(struct hci_dev *hdev)
846 if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks)) 846 if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
847 return 0; 847 return 0;
848 848
849 err = __hci_req_sync(hdev, hci_init0_req, 0, HCI_INIT_TIMEOUT); 849 err = __hci_req_sync(hdev, hci_init0_req, 0, HCI_INIT_TIMEOUT, NULL);
850 if (err < 0) 850 if (err < 0)
851 return err; 851 return err;
852 852
@@ -1204,7 +1204,7 @@ int hci_inquiry(void __user *arg)
1204 1204
1205 if (do_inquiry) { 1205 if (do_inquiry) {
1206 err = hci_req_sync(hdev, hci_inq_req, (unsigned long) &ir, 1206 err = hci_req_sync(hdev, hci_inq_req, (unsigned long) &ir,
1207 timeo); 1207 timeo, NULL);
1208 if (err < 0) 1208 if (err < 0)
1209 goto done; 1209 goto done;
1210 1210
@@ -1570,7 +1570,7 @@ int hci_dev_do_close(struct hci_dev *hdev)
1570 if (test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks) && 1570 if (test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks) &&
1571 !auto_off && !hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) { 1571 !auto_off && !hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
1572 set_bit(HCI_INIT, &hdev->flags); 1572 set_bit(HCI_INIT, &hdev->flags);
1573 __hci_req_sync(hdev, hci_reset_req, 0, HCI_CMD_TIMEOUT); 1573 __hci_req_sync(hdev, hci_reset_req, 0, HCI_CMD_TIMEOUT, NULL);
1574 clear_bit(HCI_INIT, &hdev->flags); 1574 clear_bit(HCI_INIT, &hdev->flags);
1575 } 1575 }
1576 1576
@@ -1667,7 +1667,7 @@ static int hci_dev_do_reset(struct hci_dev *hdev)
1667 atomic_set(&hdev->cmd_cnt, 1); 1667 atomic_set(&hdev->cmd_cnt, 1);
1668 hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0; 1668 hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0;
1669 1669
1670 ret = __hci_req_sync(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT); 1670 ret = __hci_req_sync(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT, NULL);
1671 1671
1672 hci_req_sync_unlock(hdev); 1672 hci_req_sync_unlock(hdev);
1673 return ret; 1673 return ret;
@@ -1802,7 +1802,7 @@ int hci_dev_cmd(unsigned int cmd, void __user *arg)
1802 switch (cmd) { 1802 switch (cmd) {
1803 case HCISETAUTH: 1803 case HCISETAUTH:
1804 err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt, 1804 err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
1805 HCI_INIT_TIMEOUT); 1805 HCI_INIT_TIMEOUT, NULL);
1806 break; 1806 break;
1807 1807
1808 case HCISETENCRYPT: 1808 case HCISETENCRYPT:
@@ -1814,18 +1814,18 @@ int hci_dev_cmd(unsigned int cmd, void __user *arg)
1814 if (!test_bit(HCI_AUTH, &hdev->flags)) { 1814 if (!test_bit(HCI_AUTH, &hdev->flags)) {
1815 /* Auth must be enabled first */ 1815 /* Auth must be enabled first */
1816 err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt, 1816 err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
1817 HCI_INIT_TIMEOUT); 1817 HCI_INIT_TIMEOUT, NULL);
1818 if (err) 1818 if (err)
1819 break; 1819 break;
1820 } 1820 }
1821 1821
1822 err = hci_req_sync(hdev, hci_encrypt_req, dr.dev_opt, 1822 err = hci_req_sync(hdev, hci_encrypt_req, dr.dev_opt,
1823 HCI_INIT_TIMEOUT); 1823 HCI_INIT_TIMEOUT, NULL);
1824 break; 1824 break;
1825 1825
1826 case HCISETSCAN: 1826 case HCISETSCAN:
1827 err = hci_req_sync(hdev, hci_scan_req, dr.dev_opt, 1827 err = hci_req_sync(hdev, hci_scan_req, dr.dev_opt,
1828 HCI_INIT_TIMEOUT); 1828 HCI_INIT_TIMEOUT, NULL);
1829 1829
1830 /* Ensure that the connectable and discoverable states 1830 /* Ensure that the connectable and discoverable states
1831 * get correctly modified as this was a non-mgmt change. 1831 * get correctly modified as this was a non-mgmt change.
@@ -1836,7 +1836,7 @@ int hci_dev_cmd(unsigned int cmd, void __user *arg)
1836 1836
1837 case HCISETLINKPOL: 1837 case HCISETLINKPOL:
1838 err = hci_req_sync(hdev, hci_linkpol_req, dr.dev_opt, 1838 err = hci_req_sync(hdev, hci_linkpol_req, dr.dev_opt,
1839 HCI_INIT_TIMEOUT); 1839 HCI_INIT_TIMEOUT, NULL);
1840 break; 1840 break;
1841 1841
1842 case HCISETLINKMODE: 1842 case HCISETLINKMODE:
diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c
index 0adbb59ec2f0..b1d4d5bba7c1 100644
--- a/net/bluetooth/hci_request.c
+++ b/net/bluetooth/hci_request.c
@@ -186,7 +186,7 @@ EXPORT_SYMBOL(__hci_cmd_sync);
186/* Execute request and wait for completion. */ 186/* Execute request and wait for completion. */
187int __hci_req_sync(struct hci_dev *hdev, void (*func)(struct hci_request *req, 187int __hci_req_sync(struct hci_dev *hdev, void (*func)(struct hci_request *req,
188 unsigned long opt), 188 unsigned long opt),
189 unsigned long opt, __u32 timeout) 189 unsigned long opt, u32 timeout, u8 *hci_status)
190{ 190{
191 struct hci_request req; 191 struct hci_request req;
192 DECLARE_WAITQUEUE(wait, current); 192 DECLARE_WAITQUEUE(wait, current);
@@ -231,14 +231,20 @@ int __hci_req_sync(struct hci_dev *hdev, void (*func)(struct hci_request *req,
231 switch (hdev->req_status) { 231 switch (hdev->req_status) {
232 case HCI_REQ_DONE: 232 case HCI_REQ_DONE:
233 err = -bt_to_errno(hdev->req_result); 233 err = -bt_to_errno(hdev->req_result);
234 if (hci_status)
235 *hci_status = hdev->req_result;
234 break; 236 break;
235 237
236 case HCI_REQ_CANCELED: 238 case HCI_REQ_CANCELED:
237 err = -hdev->req_result; 239 err = -hdev->req_result;
240 if (hci_status)
241 *hci_status = HCI_ERROR_UNSPECIFIED;
238 break; 242 break;
239 243
240 default: 244 default:
241 err = -ETIMEDOUT; 245 err = -ETIMEDOUT;
246 if (hci_status)
247 *hci_status = HCI_ERROR_UNSPECIFIED;
242 break; 248 break;
243 } 249 }
244 250
@@ -251,7 +257,7 @@ int __hci_req_sync(struct hci_dev *hdev, void (*func)(struct hci_request *req,
251 257
252int hci_req_sync(struct hci_dev *hdev, void (*req)(struct hci_request *req, 258int hci_req_sync(struct hci_dev *hdev, void (*req)(struct hci_request *req,
253 unsigned long opt), 259 unsigned long opt),
254 unsigned long opt, __u32 timeout) 260 unsigned long opt, u32 timeout, u8 *hci_status)
255{ 261{
256 int ret; 262 int ret;
257 263
@@ -260,7 +266,7 @@ int hci_req_sync(struct hci_dev *hdev, void (*req)(struct hci_request *req,
260 266
261 /* Serialize all requests */ 267 /* Serialize all requests */
262 hci_req_sync_lock(hdev); 268 hci_req_sync_lock(hdev);
263 ret = __hci_req_sync(hdev, req, opt, timeout); 269 ret = __hci_req_sync(hdev, req, opt, timeout, hci_status);
264 hci_req_sync_unlock(hdev); 270 hci_req_sync_unlock(hdev);
265 271
266 return ret; 272 return ret;
diff --git a/net/bluetooth/hci_request.h b/net/bluetooth/hci_request.h
index 983e687fee22..8441d12a62dd 100644
--- a/net/bluetooth/hci_request.h
+++ b/net/bluetooth/hci_request.h
@@ -46,10 +46,10 @@ void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status,
46 46
47int hci_req_sync(struct hci_dev *hdev, void (*req)(struct hci_request *req, 47int hci_req_sync(struct hci_dev *hdev, void (*req)(struct hci_request *req,
48 unsigned long opt), 48 unsigned long opt),
49 unsigned long opt, __u32 timeout); 49 unsigned long opt, u32 timeout, u8 *hci_status);
50int __hci_req_sync(struct hci_dev *hdev, void (*func)(struct hci_request *req, 50int __hci_req_sync(struct hci_dev *hdev, void (*func)(struct hci_request *req,
51 unsigned long opt), 51 unsigned long opt),
52 unsigned long opt, __u32 timeout); 52 unsigned long opt, u32 timeout, u8 *hci_status);
53void hci_req_sync_cancel(struct hci_dev *hdev, int err); 53void hci_req_sync_cancel(struct hci_dev *hdev, int err);
54 54
55struct sk_buff *hci_prepare_cmd(struct hci_dev *hdev, u16 opcode, u32 plen, 55struct sk_buff *hci_prepare_cmd(struct hci_dev *hdev, u16 opcode, u32 plen,