/* Link Control */
 #define OGF_LINK_CTL   0x01 
+
 #define OCF_CREATE_CONN                0x0005
 struct hci_cp_create_conn {
        bdaddr_t bdaddr;
        __u8     role_switch;
 } __attribute__ ((packed));
 
+#define OCF_CREATE_CONN_CANCEL 0x0008
+struct hci_cp_create_conn_cancel {
+       bdaddr_t bdaddr;
+} __attribute__ ((packed));
+
 #define OCF_ACCEPT_CONN_REQ    0x0009
 struct hci_cp_accept_conn_req {
        bdaddr_t bdaddr;
 
        if (atomic_dec_and_test(&conn->refcnt)) {
                unsigned long timeo;
                if (conn->type == ACL_LINK) {
-                       timeo = msecs_to_jiffies(HCI_DISCONN_TIMEOUT);
-                       if (!conn->out)
-                               timeo *= 2;
                        del_timer(&conn->idle_timer);
+                       if (conn->state == BT_CONNECTED) {
+                               timeo = msecs_to_jiffies(HCI_DISCONN_TIMEOUT);
+                               if (!conn->out)
+                                       timeo *= 2;
+                       } else
+                               timeo = msecs_to_jiffies(10);
                } else
                        timeo = msecs_to_jiffies(10);
                mod_timer(&conn->disc_timer, jiffies + timeo);
 
        hci_send_cmd(hdev, OGF_LINK_CTL, OCF_CREATE_CONN, sizeof(cp), &cp);
 }
 
+static void hci_acl_connect_cancel(struct hci_conn *conn)
+{
+       struct hci_cp_create_conn_cancel cp;
+
+       BT_DBG("%p", conn);
+
+       if (conn->hdev->hci_ver < 2)
+               return;
+
+       bacpy(&cp.bdaddr, &conn->dst);
+       hci_send_cmd(conn->hdev, OGF_LINK_CTL,
+                               OCF_CREATE_CONN_CANCEL, sizeof(cp), &cp);
+}
+
 void hci_acl_disconn(struct hci_conn *conn, __u8 reason)
 {
        struct hci_cp_disconnect cp;
 
        cp.handle = __cpu_to_le16(conn->handle);
        cp.reason = reason;
-       hci_send_cmd(conn->hdev, OGF_LINK_CTL, OCF_DISCONNECT, sizeof(cp), &cp);
+       hci_send_cmd(conn->hdev, OGF_LINK_CTL,
+                               OCF_DISCONNECT, sizeof(cp), &cp);
 }
 
 void hci_add_sco(struct hci_conn *conn, __u16 handle)
                return;
 
        hci_dev_lock(hdev);
-       if (conn->state == BT_CONNECTED)
+
+       switch (conn->state) {
+       case BT_CONNECT:
+               hci_acl_connect_cancel(conn);
+               break;
+       case BT_CONNECTED:
                hci_acl_disconn(conn, 0x13);
-       else
+               break;
+       default:
                conn->state = BT_CLOSED;
+               break;
+       }
+
        hci_dev_unlock(hdev);
-       return;
 }
 
 static void hci_conn_idle(unsigned long arg)
 
                if (test_bit(HCI_ENCRYPT, &hdev->flags))
                        conn->link_mode |= HCI_LM_ENCRYPT;
 
+               hci_conn_hold(conn);
+
                /* Get remote features */
                if (conn->type == ACL_LINK) {
                        struct hci_cp_read_remote_features cp;
                        hci_send_cmd(hdev, OGF_LINK_CTL,
                                OCF_CHANGE_CONN_PTYPE, sizeof(cp), &cp);
                }
+
+               hci_conn_put(conn);
        } else
                conn->state = BT_CLOSED;