Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/padovan/bluetooth-next

Conflicts:
	net/bluetooth/l2cap_sock.c
	net/bluetooth/mgmt.c
This commit is contained in:
John W. Linville
2011-11-09 14:54:33 -05:00
27 changed files with 2302 additions and 983 deletions

View File

@@ -374,6 +374,8 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
skb_queue_head_init(&conn->data_q);
hci_chan_hash_init(conn);
setup_timer(&conn->disc_timer, hci_conn_timeout, (unsigned long)conn);
setup_timer(&conn->idle_timer, hci_conn_idle, (unsigned long)conn);
setup_timer(&conn->auto_accept_timer, hci_conn_auto_accept,
@@ -432,6 +434,8 @@ int hci_conn_del(struct hci_conn *conn)
tasklet_disable(&hdev->tx_task);
hci_chan_hash_flush(conn);
hci_conn_hash_del(hdev, conn);
if (hdev->notify)
hdev->notify(hdev, HCI_NOTIFY_CONN_DEL);
@@ -453,16 +457,13 @@ int hci_conn_del(struct hci_conn *conn)
struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src)
{
int use_src = bacmp(src, BDADDR_ANY);
struct hci_dev *hdev = NULL;
struct list_head *p;
struct hci_dev *hdev = NULL, *d;
BT_DBG("%s -> %s", batostr(src), batostr(dst));
read_lock_bh(&hci_dev_list_lock);
list_for_each(p, &hci_dev_list) {
struct hci_dev *d = list_entry(p, struct hci_dev, list);
list_for_each_entry(d, &hci_dev_list, list) {
if (!test_bit(HCI_UP, &d->flags) || test_bit(HCI_RAW, &d->flags))
continue;
@@ -819,7 +820,7 @@ void hci_conn_hash_flush(struct hci_dev *hdev)
c->state = BT_CLOSED;
hci_proto_disconn_cfm(c, 0x16);
hci_proto_disconn_cfm(c, HCI_ERROR_LOCAL_HOST_TERM);
hci_conn_del(c);
}
}
@@ -855,10 +856,10 @@ EXPORT_SYMBOL(hci_conn_put_device);
int hci_get_conn_list(void __user *arg)
{
register struct hci_conn *c;
struct hci_conn_list_req req, *cl;
struct hci_conn_info *ci;
struct hci_dev *hdev;
struct list_head *p;
int n = 0, size, err;
if (copy_from_user(&req, arg, sizeof(req)))
@@ -882,10 +883,7 @@ int hci_get_conn_list(void __user *arg)
ci = cl->conn_info;
hci_dev_lock_bh(hdev);
list_for_each(p, &hdev->conn_hash.list) {
register struct hci_conn *c;
c = list_entry(p, struct hci_conn, list);
list_for_each_entry(c, &hdev->conn_hash.list, list) {
bacpy(&(ci + n)->bdaddr, &c->dst);
(ci + n)->handle = c->handle;
(ci + n)->type = c->type;
@@ -956,3 +954,52 @@ int hci_get_auth_info(struct hci_dev *hdev, void __user *arg)
return copy_to_user(arg, &req, sizeof(req)) ? -EFAULT : 0;
}
struct hci_chan *hci_chan_create(struct hci_conn *conn)
{
struct hci_dev *hdev = conn->hdev;
struct hci_chan *chan;
BT_DBG("%s conn %p", hdev->name, conn);
chan = kzalloc(sizeof(struct hci_chan), GFP_ATOMIC);
if (!chan)
return NULL;
chan->conn = conn;
skb_queue_head_init(&chan->data_q);
tasklet_disable(&hdev->tx_task);
hci_chan_hash_add(conn, chan);
tasklet_enable(&hdev->tx_task);
return chan;
}
int hci_chan_del(struct hci_chan *chan)
{
struct hci_conn *conn = chan->conn;
struct hci_dev *hdev = conn->hdev;
BT_DBG("%s conn %p chan %p", hdev->name, conn, chan);
tasklet_disable(&hdev->tx_task);
hci_chan_hash_del(conn, chan);
tasklet_enable(&hdev->tx_task);
skb_queue_purge(&chan->data_q);
kfree(chan);
return 0;
}
void hci_chan_hash_flush(struct hci_conn *conn)
{
struct hci_chan_hash *h = &conn->chan_hash;
struct hci_chan *chan, *tmp;
BT_DBG("conn %p", conn);
list_for_each_entry_safe(chan, tmp, &h->list, list)
hci_chan_del(chan);
}