Commit d2c74978 authored by Marcel Holtmann's avatar Marcel Holtmann

[Bluetooth] Support raw mode only devices

This patch introduces a quirk flag for turning a device into a raw
mode only device.
Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
parent 8e4a73f4
...@@ -53,7 +53,8 @@ ...@@ -53,7 +53,8 @@
/* HCI device quirks */ /* HCI device quirks */
enum { enum {
HCI_QUIRK_RESET_ON_INIT HCI_QUIRK_RESET_ON_INIT,
HCI_QUIRK_RAW_DEVICE
}; };
/* HCI device flags */ /* HCI device flags */
......
...@@ -457,6 +457,9 @@ int hci_dev_open(__u16 dev) ...@@ -457,6 +457,9 @@ int hci_dev_open(__u16 dev)
goto done; goto done;
} }
if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
set_bit(HCI_RAW, &hdev->flags);
if (hdev->open(hdev)) { if (hdev->open(hdev)) {
ret = -EIO; ret = -EIO;
goto done; goto done;
...@@ -532,9 +535,11 @@ static int hci_dev_do_close(struct hci_dev *hdev) ...@@ -532,9 +535,11 @@ static int hci_dev_do_close(struct hci_dev *hdev)
/* Reset device */ /* Reset device */
skb_queue_purge(&hdev->cmd_q); skb_queue_purge(&hdev->cmd_q);
atomic_set(&hdev->cmd_cnt, 1); atomic_set(&hdev->cmd_cnt, 1);
set_bit(HCI_INIT, &hdev->flags); if (!test_bit(HCI_RAW, &hdev->flags)) {
__hci_request(hdev, hci_reset_req, 0, HZ/4); set_bit(HCI_INIT, &hdev->flags);
clear_bit(HCI_INIT, &hdev->flags); __hci_request(hdev, hci_reset_req, 0, HZ/4);
clear_bit(HCI_INIT, &hdev->flags);
}
/* Kill cmd task */ /* Kill cmd task */
tasklet_kill(&hdev->cmd_task); tasklet_kill(&hdev->cmd_task);
...@@ -604,7 +609,8 @@ int hci_dev_reset(__u16 dev) ...@@ -604,7 +609,8 @@ int hci_dev_reset(__u16 dev)
atomic_set(&hdev->cmd_cnt, 1); atomic_set(&hdev->cmd_cnt, 1);
hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->acl_cnt = 0; hdev->sco_cnt = 0;
ret = __hci_request(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT); if (!test_bit(HCI_RAW, &hdev->flags))
ret = __hci_request(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT);
done: done:
tasklet_enable(&hdev->tx_task); tasklet_enable(&hdev->tx_task);
...@@ -1192,10 +1198,12 @@ static inline void hci_sched_acl(struct hci_dev *hdev) ...@@ -1192,10 +1198,12 @@ static inline void hci_sched_acl(struct hci_dev *hdev)
BT_DBG("%s", hdev->name); BT_DBG("%s", hdev->name);
/* ACL tx timeout must be longer than maximum if (!test_bit(HCI_RAW, &hdev->flags)) {
* link supervision timeout (40.9 seconds) */ /* ACL tx timeout must be longer than maximum
if (!hdev->acl_cnt && (jiffies - hdev->acl_last_tx) > (HZ * 45)) * link supervision timeout (40.9 seconds) */
hci_acl_tx_to(hdev); if (!hdev->acl_cnt && (jiffies - hdev->acl_last_tx) > (HZ * 45))
hci_acl_tx_to(hdev);
}
while (hdev->acl_cnt && (conn = hci_low_sent(hdev, ACL_LINK, &quote))) { while (hdev->acl_cnt && (conn = hci_low_sent(hdev, ACL_LINK, &quote))) {
while (quote-- && (skb = skb_dequeue(&conn->data_q))) { while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
......
...@@ -179,6 +179,9 @@ static inline int hci_sock_bound_ioctl(struct sock *sk, unsigned int cmd, unsign ...@@ -179,6 +179,9 @@ static inline int hci_sock_bound_ioctl(struct sock *sk, unsigned int cmd, unsign
if (!capable(CAP_NET_ADMIN)) if (!capable(CAP_NET_ADMIN))
return -EACCES; return -EACCES;
if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
return -EPERM;
if (arg) if (arg)
set_bit(HCI_RAW, &hdev->flags); set_bit(HCI_RAW, &hdev->flags);
else else
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment