aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2006-10-15 17:30:56 +0200
committerDavid S. Miller <davem@sunset.davemloft.net>2006-10-15 23:14:30 -0700
commit4c67bc74f016b0d360b8573e18969c0ff7926974 (patch)
treed5eec3da59b642f48e7fcc2034b6d90b5fa54e01 /net
parente9c4bec63eac001651d6d30239dd4175cc3698ef (diff)
downloadkernel_samsung_tuna-4c67bc74f016b0d360b8573e18969c0ff7926974.zip
kernel_samsung_tuna-4c67bc74f016b0d360b8573e18969c0ff7926974.tar.gz
kernel_samsung_tuna-4c67bc74f016b0d360b8573e18969c0ff7926974.tar.bz2
[Bluetooth] Support concurrent connect requests
Most Bluetooth chips don't support concurrent connect requests, because this would involve a multiple baseband page with only one radio. In the case an upper layer like L2CAP requests a concurrent connect these chips return the error "Command Disallowed" for the second request. If this happens it the responsibility of the Bluetooth core to queue the request and try again after the previous connect attempt has been completed. Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net')
-rw-r--r--net/bluetooth/af_bluetooth.c2
-rw-r--r--net/bluetooth/hci_conn.c6
-rw-r--r--net/bluetooth/hci_event.c15
3 files changed, 16 insertions, 7 deletions
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
index 305a099..a91fee4 100644
--- a/net/bluetooth/af_bluetooth.c
+++ b/net/bluetooth/af_bluetooth.c
@@ -48,7 +48,7 @@
#define BT_DBG(D...)
#endif
-#define VERSION "2.10"
+#define VERSION "2.11"
/* Bluetooth sockets */
#define BT_MAX_PROTO 8
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 90e3a28..6cd5711 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -51,7 +51,7 @@
#define BT_DBG(D...)
#endif
-static void hci_acl_connect(struct hci_conn *conn)
+void hci_acl_connect(struct hci_conn *conn)
{
struct hci_dev *hdev = conn->hdev;
struct inquiry_entry *ie;
@@ -63,6 +63,8 @@ static void hci_acl_connect(struct hci_conn *conn)
conn->out = 1;
conn->link_mode = HCI_LM_MASTER;
+ conn->attempt++;
+
memset(&cp, 0, sizeof(cp));
bacpy(&cp.bdaddr, &conn->dst);
cp.pscan_rep_mode = 0x02;
@@ -80,7 +82,7 @@ static void hci_acl_connect(struct hci_conn *conn)
cp.role_switch = 0x01;
else
cp.role_switch = 0x00;
-
+
hci_send_cmd(hdev, OGF_LINK_CTL, OCF_CREATE_CONN, sizeof(cp), &cp);
}
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index d43d0c8..65f0948 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -414,9 +414,12 @@ static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
if (status) {
if (conn && conn->state == BT_CONNECT) {
- conn->state = BT_CLOSED;
- hci_proto_connect_cfm(conn, status);
- hci_conn_del(conn);
+ if (status != 0x0c || conn->attempt > 2) {
+ conn->state = BT_CLOSED;
+ hci_proto_connect_cfm(conn, status);
+ hci_conn_del(conn);
+ } else
+ conn->state = BT_CONNECT2;
}
} else {
if (!conn) {
@@ -728,7 +731,7 @@ static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *sk
static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
struct hci_ev_conn_complete *ev = (struct hci_ev_conn_complete *) skb->data;
- struct hci_conn *conn;
+ struct hci_conn *conn, *pend;
BT_DBG("%s", hdev->name);
@@ -801,6 +804,10 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s
if (ev->status)
hci_conn_del(conn);
+ pend = hci_conn_hash_lookup_state(hdev, ACL_LINK, BT_CONNECT2);
+ if (pend)
+ hci_acl_connect(pend);
+
hci_dev_unlock(hdev);
}