Commit 323cdc72 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 4f96d0aa cc9d9e46
......@@ -457,6 +457,11 @@ P: Marcel Holtmann
M: marcel@holtmann.org
S: Maintained
BLUETOOTH HCI BPA10X DRIVER
P: Marcel Holtmann
M: marcel@holtmann.org
S: Maintained
BLUETOOTH HCI BFUSB DRIVER
P: Marcel Holtmann
M: marcel@holtmann.org
......
......@@ -35,6 +35,7 @@
#include <linux/ioport.h>
#include <linux/spinlock.h>
#include <linux/moduleparam.h>
#include <linux/wait.h>
#include <linux/skbuff.h>
#include <asm/io.h>
......@@ -289,8 +290,9 @@ static void bluecard_write_wakeup(bluecard_info_t *info)
clear_bit(ready_bit, &(info->tx_state));
if (skb->pkt_type & 0x80) {
DECLARE_WAIT_QUEUE_HEAD(wq);
DEFINE_WAIT(wait);
wait_queue_head_t wait;
unsigned char baud_reg;
switch (skb->pkt_type) {
......@@ -311,8 +313,9 @@ static void bluecard_write_wakeup(bluecard_info_t *info)
}
/* Wait until the command reaches the baseband */
init_waitqueue_head(&wait);
interruptible_sleep_on_timeout(&wait, HZ / 10);
prepare_to_wait(&wq, &wait, TASK_INTERRUPTIBLE);
schedule_timeout(HZ/10);
finish_wait(&wq, &wait);
/* Set baud on baseband */
info->ctrl_reg &= ~0x03;
......@@ -324,8 +327,9 @@ static void bluecard_write_wakeup(bluecard_info_t *info)
outb(info->ctrl_reg, iobase + REG_CONTROL);
/* Wait before the next HCI packet can be send */
interruptible_sleep_on_timeout(&wait, HZ);
prepare_to_wait(&wq, &wait, TASK_INTERRUPTIBLE);
schedule_timeout(HZ);
finish_wait(&wq, &wait);
}
if (len == skb->len) {
......
......@@ -888,7 +888,7 @@ static int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id
isoc_ifnum = 1;
#ifdef CONFIG_BT_HCIUSB_SCO
if (isoc && !(id->driver_info & HCI_BROKEN_ISOC))
if (isoc && !(id->driver_info & (HCI_BROKEN_ISOC | HCI_SNIFFER)))
isoc_iface = usb_ifnum_to_if(udev, isoc_ifnum);
if (isoc_iface) {
......
......@@ -217,7 +217,8 @@ void hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data);
/* ----- HCI Connections ----- */
enum {
HCI_CONN_AUTH_PEND,
HCI_CONN_ENCRYPT_PEND
HCI_CONN_ENCRYPT_PEND,
HCI_CONN_RSWITCH_PEND
};
static inline void hci_conn_hash_init(struct hci_dev *hdev)
......@@ -290,6 +291,7 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *src);
int hci_conn_auth(struct hci_conn *conn);
int hci_conn_encrypt(struct hci_conn *conn);
int hci_conn_change_link_key(struct hci_conn *conn);
int hci_conn_switch_role(struct hci_conn *conn, uint8_t role);
static inline void hci_conn_set_timer(struct hci_conn *conn, unsigned long timeout)
{
......@@ -515,6 +517,8 @@ struct hci_cb {
void (*auth_cfm) (struct hci_conn *conn, __u8 status);
void (*encrypt_cfm) (struct hci_conn *conn, __u8 status, __u8 encrypt);
void (*key_change_cfm) (struct hci_conn *conn, __u8 status);
void (*role_switch_cfm) (struct hci_conn *conn, __u8 status, __u8 role);
};
static inline void hci_auth_cfm(struct hci_conn *conn, __u8 status)
......@@ -547,6 +551,32 @@ static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status, __u8 encr
read_unlock_bh(&hci_cb_list_lock);
}
static inline void hci_key_change_cfm(struct hci_conn *conn, __u8 status)
{
struct list_head *p;
read_lock_bh(&hci_cb_list_lock);
list_for_each(p, &hci_cb_list) {
struct hci_cb *cb = list_entry(p, struct hci_cb, list);
if (cb->key_change_cfm)
cb->key_change_cfm(conn, status);
}
read_unlock_bh(&hci_cb_list_lock);
}
static inline void hci_role_switch_cfm(struct hci_conn *conn, __u8 status, __u8 role)
{
struct list_head *p;
read_lock_bh(&hci_cb_list_lock);
list_for_each(p, &hci_cb_list) {
struct hci_cb *cb = list_entry(p, struct hci_cb, list);
if (cb->role_switch_cfm)
cb->role_switch_cfm(conn, status, role);
}
read_unlock_bh(&hci_cb_list_lock);
}
int hci_register_cb(struct hci_cb *hcb);
int hci_unregister_cb(struct hci_cb *hcb);
......
......@@ -348,6 +348,24 @@ int hci_conn_change_link_key(struct hci_conn *conn)
}
EXPORT_SYMBOL(hci_conn_change_link_key);
/* Switch role */
int hci_conn_switch_role(struct hci_conn *conn, uint8_t role)
{
BT_DBG("conn %p", conn);
if (!role && conn->link_mode & HCI_LM_MASTER)
return 1;
if (!test_and_set_bit(HCI_CONN_RSWITCH_PEND, &conn->pend)) {
struct hci_cp_switch_role cp;
bacpy(&cp.bdaddr, &conn->dst);
cp.role = role;
hci_send_cmd(conn->hdev, OGF_LINK_POLICY, OCF_SWITCH_ROLE, sizeof(cp), &cp);
}
return 0;
}
EXPORT_SYMBOL(hci_conn_switch_role);
/* Drop all connection on the device */
void hci_conn_hash_flush(struct hci_dev *hdev)
{
......
......@@ -718,17 +718,20 @@ static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb
BT_DBG("%s status %d", hdev->name, ev->status);
if (ev->status)
return;
hci_dev_lock(hdev);
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
if (conn) {
if (ev->role)
conn->link_mode &= ~HCI_LM_MASTER;
else
conn->link_mode |= HCI_LM_MASTER;
if (!ev->status) {
if (ev->role)
conn->link_mode &= ~HCI_LM_MASTER;
else
conn->link_mode |= HCI_LM_MASTER;
}
clear_bit(HCI_CONN_RSWITCH_PEND, &conn->pend);
hci_role_switch_cfm(conn, ev->status, ev->role);
}
hci_dev_unlock(hdev);
......@@ -749,6 +752,7 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s
if (conn) {
if (!ev->status)
conn->link_mode |= HCI_LM_AUTH;
clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
hci_auth_cfm(conn, ev->status);
......@@ -790,6 +794,7 @@ static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *
else
conn->link_mode &= ~HCI_LM_ENCRYPT;
}
clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
hci_encrypt_cfm(conn, ev->status, ev->encrypt);
......@@ -801,6 +806,25 @@ static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *
/* Change Connection Link Key Complete */
static inline void hci_change_conn_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
struct hci_ev_change_conn_link_key_complete *ev = (struct hci_ev_change_conn_link_key_complete *) 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) {
if (!ev->status)
conn->link_mode |= HCI_LM_SECURE;
clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
hci_key_change_cfm(conn, ev->status);
}
hci_dev_unlock(hdev);
}
/* Pin Code Request*/
......
......@@ -55,7 +55,7 @@ static ssize_t show_inquiry_cache(struct class_device *cdev, char *buf)
batostr(&bdaddr),
data->pscan_rep_mode, data->pscan_period_mode, data->pscan_mode,
data->dev_class[2], data->dev_class[1], data->dev_class[0],
data->clock_offset, data->rssi, e->timestamp);
__le16_to_cpu(data->clock_offset), data->rssi, e->timestamp);
}
hci_dev_unlock_bh(hdev);
......
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