diff options
Diffstat (limited to 'net/bluetooth/hci_conn.c')
| -rw-r--r-- | net/bluetooth/hci_conn.c | 42 | 
1 files changed, 19 insertions, 23 deletions
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 4925a02ae7e..6c7f3637972 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -117,7 +117,17 @@ static void hci_acl_create_connection_cancel(struct hci_conn *conn)  	hci_send_cmd(conn->hdev, HCI_OP_CREATE_CONN_CANCEL, sizeof(cp), &cp);  } -void hci_acl_disconn(struct hci_conn *conn, __u8 reason) +static void hci_reject_sco(struct hci_conn *conn) +{ +	struct hci_cp_reject_sync_conn_req cp; + +	cp.reason = HCI_ERROR_REMOTE_USER_TERM; +	bacpy(&cp.bdaddr, &conn->dst); + +	hci_send_cmd(conn->hdev, HCI_OP_REJECT_SYNC_CONN_REQ, sizeof(cp), &cp); +} + +void hci_disconnect(struct hci_conn *conn, __u8 reason)  {  	struct hci_cp_disconnect cp; @@ -253,7 +263,7 @@ static void hci_conn_disconnect(struct hci_conn *conn)  		hci_amp_disconn(conn, reason);  		break;  	default: -		hci_acl_disconn(conn, reason); +		hci_disconnect(conn, reason);  		break;  	}  } @@ -276,6 +286,8 @@ static void hci_conn_timeout(struct work_struct *work)  				hci_acl_create_connection_cancel(conn);  			else if (conn->type == LE_LINK)  				hci_le_create_connection_cancel(conn); +		} else if (conn->type == SCO_LINK || conn->type == ESCO_LINK) { +			hci_reject_sco(conn);  		}  		break;  	case BT_CONFIG: @@ -398,8 +410,6 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)  	if (hdev->notify)  		hdev->notify(hdev, HCI_NOTIFY_CONN_ADD); -	atomic_set(&conn->devref, 0); -  	hci_conn_init_sysfs(conn);  	return conn; @@ -433,7 +443,7 @@ int hci_conn_del(struct hci_conn *conn)  		struct hci_conn *acl = conn->link;  		if (acl) {  			acl->link = NULL; -			hci_conn_put(acl); +			hci_conn_drop(acl);  		}  	} @@ -448,12 +458,11 @@ int hci_conn_del(struct hci_conn *conn)  	skb_queue_purge(&conn->data_q); -	hci_conn_put_device(conn); +	hci_conn_del_sysfs(conn);  	hci_dev_put(hdev); -	if (conn->handle == 0) -		kfree(conn); +	hci_conn_put(conn);  	return 0;  } @@ -565,7 +574,7 @@ static struct hci_conn *hci_connect_sco(struct hci_dev *hdev, int type,  	if (!sco) {  		sco = hci_conn_add(hdev, type, dst);  		if (!sco) { -			hci_conn_put(acl); +			hci_conn_drop(acl);  			return ERR_PTR(-ENOMEM);  		}  	} @@ -835,19 +844,6 @@ void hci_conn_check_pending(struct hci_dev *hdev)  	hci_dev_unlock(hdev);  } -void hci_conn_hold_device(struct hci_conn *conn) -{ -	atomic_inc(&conn->devref); -} -EXPORT_SYMBOL(hci_conn_hold_device); - -void hci_conn_put_device(struct hci_conn *conn) -{ -	if (atomic_dec_and_test(&conn->devref)) -		hci_conn_del_sysfs(conn); -} -EXPORT_SYMBOL(hci_conn_put_device); -  int hci_get_conn_list(void __user *arg)  {  	struct hci_conn *c; @@ -980,7 +976,7 @@ void hci_chan_del(struct hci_chan *chan)  	synchronize_rcu(); -	hci_conn_put(conn); +	hci_conn_drop(conn);  	skb_queue_purge(&chan->data_q);  	kfree(chan);  |