Commit e3b4ac5d authored by David S. Miller's avatar David S. Miller

Merge http://linux-mh.bkbits.net/bluetooth-2.6

into nuts.davemloft.net:/disk1/BK/net-2.6
parents eae9061b 221ce12d
......@@ -113,12 +113,15 @@ static struct usb_device_id blacklist_ids[] = {
/* ISSC Bluetooth Adapter v3.1 */
{ USB_DEVICE(0x1131, 0x1001), .driver_info = HCI_RESET },
/* RTX Telecom based adapter with buggy SCO support */
{ USB_DEVICE(0x0400, 0x0807), .driver_info = HCI_BROKEN_ISOC },
/* Digianswer devices */
{ USB_DEVICE(0x08fd, 0x0001), .driver_info = HCI_DIGIANSWER },
{ USB_DEVICE(0x08fd, 0x0002), .driver_info = HCI_IGNORE },
/* RTX Telecom based adapter with buggy SCO support */
{ USB_DEVICE(0x0400, 0x0807), .driver_info = HCI_BROKEN_ISOC },
/* CSR BlueCore Bluetooth Sniffer */
{ USB_DEVICE(0x0a12, 0x0002), .driver_info = HCI_SNIFFER },
{ } /* Terminating entry */
};
......@@ -969,6 +972,11 @@ static int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id
if (reset || id->driver_info & HCI_RESET)
set_bit(HCI_QUIRK_RESET_ON_INIT, &hdev->quirks);
if (id->driver_info & HCI_SNIFFER) {
if (le16_to_cpu(udev->descriptor.bcdDevice) > 0x997)
set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);
}
if (hci_register_dev(hdev) < 0) {
BT_ERR("Can't register HCI device");
hci_free_dev(hdev);
......
......@@ -31,7 +31,8 @@
#define HCI_IGNORE 0x01
#define HCI_RESET 0x02
#define HCI_DIGIANSWER 0x04
#define HCI_BROKEN_ISOC 0x08
#define HCI_SNIFFER 0x08
#define HCI_BROKEN_ISOC 0x10
#define HCI_MAX_IFACE_NUM 3
......
......@@ -53,7 +53,8 @@
/* HCI device quirks */
enum {
HCI_QUIRK_RESET_ON_INIT
HCI_QUIRK_RESET_ON_INIT,
HCI_QUIRK_RAW_DEVICE
};
/* HCI device flags */
......@@ -576,6 +577,13 @@ struct hci_ev_rmt_version {
__u16 lmp_subver;
} __attribute__ ((packed));
#define HCI_EV_CLOCK_OFFSET 0x01C
struct hci_ev_clock_offset {
__u8 status;
__u16 handle;
__u16 clock_offset;
} __attribute__ ((packed));
/* Internal events generated by Bluetooth stack */
#define HCI_EV_STACK_INTERNAL 0xFD
struct hci_ev_stack_internal {
......
......@@ -226,7 +226,7 @@ struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src)
list_for_each(p, &hci_dev_list) {
struct hci_dev *d = list_entry(p, struct hci_dev, list);
if (!test_bit(HCI_UP, &d->flags))
if (!test_bit(HCI_UP, &d->flags) || test_bit(HCI_RAW, &d->flags))
continue;
/* Simple routing:
......
......@@ -457,6 +457,9 @@ int hci_dev_open(__u16 dev)
goto done;
}
if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
set_bit(HCI_RAW, &hdev->flags);
if (hdev->open(hdev)) {
ret = -EIO;
goto done;
......@@ -532,9 +535,11 @@ static int hci_dev_do_close(struct hci_dev *hdev)
/* Reset device */
skb_queue_purge(&hdev->cmd_q);
atomic_set(&hdev->cmd_cnt, 1);
if (!test_bit(HCI_RAW, &hdev->flags)) {
set_bit(HCI_INIT, &hdev->flags);
__hci_request(hdev, hci_reset_req, 0, HZ/4);
clear_bit(HCI_INIT, &hdev->flags);
}
/* Kill cmd task */
tasklet_kill(&hdev->cmd_task);
......@@ -604,6 +609,7 @@ int hci_dev_reset(__u16 dev)
atomic_set(&hdev->cmd_cnt, 1);
hdev->acl_cnt = 0; hdev->sco_cnt = 0;
if (!test_bit(HCI_RAW, &hdev->flags))
ret = __hci_request(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT);
done:
......@@ -1192,10 +1198,12 @@ static inline void hci_sched_acl(struct hci_dev *hdev)
BT_DBG("%s", hdev->name);
if (!test_bit(HCI_RAW, &hdev->flags)) {
/* ACL tx timeout must be longer than maximum
* link supervision timeout (40.9 seconds) */
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 (quote-- && (skb = skb_dequeue(&conn->data_q))) {
......
......@@ -818,6 +818,30 @@ static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff
{
}
/* Clock Offset */
static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
struct hci_ev_clock_offset *ev = (struct hci_ev_clock_offset *) skb->data;
struct hci_conn *conn = NULL;
__u16 handle = __le16_to_cpu(ev->handle);
BT_DBG("%s status %d", hdev->name, ev->status);
hci_dev_lock(hdev);
conn = hci_conn_hash_lookup_handle(hdev, handle);
if (conn && !ev->status) {
struct inquiry_entry *ie;
if ((ie = hci_inquiry_cache_lookup(hdev, &conn->dst))) {
ie->data.clock_offset = ev->clock_offset;
ie->timestamp = jiffies;
}
}
hci_dev_unlock(hdev);
}
void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
{
struct hci_event_hdr *hdr = (struct hci_event_hdr *) skb->data;
......@@ -886,6 +910,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
hci_link_key_notify_evt(hdev, skb);
break;
case HCI_EV_CLOCK_OFFSET:
hci_clock_offset_evt(hdev, skb);
break;
case HCI_EV_CMD_STATUS:
cs = (struct hci_ev_cmd_status *) skb->data;
skb_pull(skb, sizeof(cs));
......
......@@ -179,6 +179,9 @@ static inline int hci_sock_bound_ioctl(struct sock *sk, unsigned int cmd, unsign
if (!capable(CAP_NET_ADMIN))
return -EACCES;
if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
return -EPERM;
if (arg)
set_bit(HCI_RAW, &hdev->flags);
else
......
......@@ -770,7 +770,7 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms
return -EOPNOTSUPP;
/* Check outgoing MTU */
if (len > l2cap_pi(sk)->omtu)
if (sk->sk_type != SOCK_RAW && len > l2cap_pi(sk)->omtu)
return -EINVAL;
lock_sock(sk);
......
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