Home | History | Annotate | Line # | Download | only in netbt
hci_link.c revision 1.3.2.1
      1  1.3.2.1      riz /*	$NetBSD: hci_link.c,v 1.3.2.1 2006/09/14 21:16:31 riz Exp $	*/
      2      1.1  gdamore 
      3      1.1  gdamore /*-
      4      1.1  gdamore  * Copyright (c) 2005 Iain Hibbert.
      5      1.1  gdamore  * Copyright (c) 2006 Itronix Inc.
      6      1.1  gdamore  * All rights reserved.
      7      1.1  gdamore  *
      8      1.1  gdamore  * Redistribution and use in source and binary forms, with or without
      9      1.1  gdamore  * modification, are permitted provided that the following conditions
     10      1.1  gdamore  * are met:
     11      1.1  gdamore  * 1. Redistributions of source code must retain the above copyright
     12      1.1  gdamore  *    notice, this list of conditions and the following disclaimer.
     13      1.1  gdamore  * 2. Redistributions in binary form must reproduce the above copyright
     14      1.1  gdamore  *    notice, this list of conditions and the following disclaimer in the
     15      1.1  gdamore  *    documentation and/or other materials provided with the distribution.
     16      1.1  gdamore  * 3. The name of Itronix Inc. may not be used to endorse
     17      1.1  gdamore  *    or promote products derived from this software without specific
     18      1.1  gdamore  *    prior written permission.
     19      1.1  gdamore  *
     20      1.1  gdamore  * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND
     21      1.1  gdamore  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     22      1.1  gdamore  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     23      1.1  gdamore  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
     24      1.1  gdamore  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     25      1.1  gdamore  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     26      1.1  gdamore  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
     27      1.1  gdamore  * ON ANY THEORY OF LIABILITY, WHETHER IN
     28      1.1  gdamore  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     29      1.1  gdamore  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     30      1.1  gdamore  * POSSIBILITY OF SUCH DAMAGE.
     31      1.1  gdamore  */
     32      1.1  gdamore 
     33      1.1  gdamore #include <sys/cdefs.h>
     34  1.3.2.1      riz __KERNEL_RCSID(0, "$NetBSD: hci_link.c,v 1.3.2.1 2006/09/14 21:16:31 riz Exp $");
     35      1.1  gdamore 
     36      1.1  gdamore #include <sys/param.h>
     37      1.1  gdamore #include <sys/kernel.h>
     38      1.1  gdamore #include <sys/malloc.h>
     39      1.1  gdamore #include <sys/mbuf.h>
     40      1.1  gdamore #include <sys/proc.h>
     41      1.1  gdamore #include <sys/queue.h>
     42      1.1  gdamore #include <sys/systm.h>
     43      1.1  gdamore 
     44      1.1  gdamore #include <netbt/bluetooth.h>
     45      1.1  gdamore #include <netbt/hci.h>
     46      1.2     tron #include <netbt/l2cap.h>
     47      1.1  gdamore #include <netbt/sco.h>
     48      1.1  gdamore 
     49      1.1  gdamore /*******************************************************************************
     50      1.1  gdamore  *
     51      1.1  gdamore  *	HCI ACL Connections
     52      1.1  gdamore  */
     53      1.1  gdamore 
     54      1.1  gdamore /*
     55      1.1  gdamore  * Automatically expire unused ACL connections after this number of
     56      1.1  gdamore  * seconds (if zero, do not expire unused connections) [sysctl]
     57      1.1  gdamore  */
     58      1.1  gdamore int hci_acl_expiry = 10;	/* seconds */
     59      1.1  gdamore 
     60      1.1  gdamore /*
     61      1.1  gdamore  * hci_acl_open(unit, bdaddr)
     62      1.1  gdamore  *
     63      1.1  gdamore  * open ACL connection to remote bdaddr. Only one ACL connection is permitted
     64      1.1  gdamore  * between any two Bluetooth devices, so we look for an existing one before
     65      1.1  gdamore  * trying to start a new one.
     66      1.1  gdamore  */
     67      1.1  gdamore struct hci_link *
     68      1.1  gdamore hci_acl_open(struct hci_unit *unit, bdaddr_t *bdaddr)
     69      1.1  gdamore {
     70      1.1  gdamore 	struct hci_link *link;
     71      1.2     tron 	struct hci_memo *memo;
     72      1.1  gdamore 	hci_create_con_cp cp;
     73      1.1  gdamore 	int err;
     74      1.1  gdamore 
     75      1.1  gdamore 	KASSERT(unit);
     76      1.1  gdamore 	KASSERT(bdaddr);
     77      1.1  gdamore 
     78      1.1  gdamore 	link = hci_link_lookup_bdaddr(unit, bdaddr, HCI_LINK_ACL);
     79      1.1  gdamore 	if (link == NULL) {
     80      1.1  gdamore 		link = hci_link_alloc(unit);
     81      1.1  gdamore 		if (link == NULL)
     82      1.1  gdamore 			return NULL;
     83      1.1  gdamore 
     84      1.1  gdamore 		link->hl_type = HCI_LINK_ACL;
     85      1.1  gdamore 		bdaddr_copy(&link->hl_bdaddr, bdaddr);
     86      1.1  gdamore 	}
     87      1.1  gdamore 
     88      1.1  gdamore 	switch(link->hl_state) {
     89      1.1  gdamore 	case HCI_LINK_CLOSED:
     90      1.1  gdamore 		/*
     91      1.1  gdamore 		 * open connection to remote device
     92      1.1  gdamore 		 */
     93      1.1  gdamore 		memset(&cp, 0, sizeof(cp));
     94      1.1  gdamore 		bdaddr_copy(&cp.bdaddr, bdaddr);
     95      1.1  gdamore 		cp.pkt_type = htole16(unit->hci_packet_type);
     96      1.2     tron 
     97      1.2     tron 		memo = hci_memo_find(unit, bdaddr);
     98      1.2     tron 		if (memo != NULL) {
     99      1.2     tron 			cp.page_scan_rep_mode = memo->response.page_scan_rep_mode;
    100      1.2     tron 			cp.page_scan_mode = memo->response.page_scan_mode;
    101  1.3.2.1      riz 			cp.clock_offset = htole16(memo->response.clock_offset);
    102      1.2     tron 		}
    103      1.2     tron 
    104      1.1  gdamore 		if (unit->hci_link_policy & HCI_LINK_POLICY_ENABLE_ROLE_SWITCH)
    105      1.1  gdamore 			cp.accept_role_switch = 1;
    106      1.1  gdamore 
    107      1.1  gdamore 		err = hci_send_cmd(unit, HCI_CMD_CREATE_CON, &cp, sizeof(cp));
    108      1.1  gdamore 		if (err) {
    109      1.1  gdamore 			hci_link_free(link, err);
    110      1.1  gdamore 			return NULL;
    111      1.1  gdamore 		}
    112      1.1  gdamore 
    113      1.1  gdamore 		link->hl_state = HCI_LINK_WAIT_CONNECT;
    114      1.1  gdamore 		break;
    115      1.1  gdamore 
    116      1.1  gdamore 	case HCI_LINK_WAIT_CONNECT:
    117      1.1  gdamore 		/*
    118      1.1  gdamore 		 * somebody else already trying to connect, we just
    119      1.1  gdamore 		 * sit on the bench with them..
    120      1.1  gdamore 		 */
    121      1.1  gdamore 		break;
    122      1.1  gdamore 
    123      1.1  gdamore 	case HCI_LINK_OPEN:
    124      1.1  gdamore 		/*
    125      1.1  gdamore 		 * If already open, halt any expiry timeouts. We dont need
    126      1.1  gdamore 		 * to care about already invoking timeouts since refcnt >0
    127      1.1  gdamore 		 * will keep the link alive.
    128      1.1  gdamore 		 */
    129      1.1  gdamore 		callout_stop(&link->hl_expire);
    130      1.1  gdamore 		break;
    131      1.1  gdamore 
    132      1.1  gdamore 	default:
    133      1.1  gdamore 		UNKNOWN(link->hl_state);
    134      1.1  gdamore 		return NULL;
    135      1.1  gdamore 	}
    136      1.1  gdamore 
    137      1.1  gdamore 	/* open */
    138      1.1  gdamore 	link->hl_refcnt++;
    139      1.1  gdamore 
    140      1.1  gdamore 	return link;
    141      1.1  gdamore }
    142      1.1  gdamore 
    143      1.1  gdamore /*
    144      1.1  gdamore  * Close ACL connection. When there are no more references to this link,
    145      1.1  gdamore  * we can either close it down or schedule a delayed closedown.
    146      1.1  gdamore  */
    147      1.1  gdamore void
    148      1.1  gdamore hci_acl_close(struct hci_link *link, int err)
    149      1.1  gdamore {
    150      1.1  gdamore 
    151      1.1  gdamore 	KASSERT(link);
    152      1.1  gdamore 
    153      1.1  gdamore 	if (--link->hl_refcnt == 0) {
    154      1.1  gdamore 		if (link->hl_state == HCI_LINK_CLOSED)
    155      1.1  gdamore 			hci_link_free(link, err);
    156      1.1  gdamore 		else if (hci_acl_expiry > 0)
    157      1.1  gdamore 			callout_schedule(&link->hl_expire, hci_acl_expiry * hz);
    158      1.1  gdamore 	}
    159      1.1  gdamore }
    160      1.1  gdamore 
    161      1.1  gdamore /*
    162      1.3     tron  * Incoming ACL connection.
    163      1.3     tron  *
    164      1.3     tron  * For now, we accept all connections but it would be better to check
    165      1.3     tron  * the L2CAP listen list and only accept when there is a listener
    166      1.3     tron  * available.
    167      1.3     tron  *
    168      1.3     tron  * There should not be a link to the same bdaddr already, we check
    169      1.3     tron  * anyway though its left unhandled for now.
    170      1.1  gdamore  */
    171      1.1  gdamore struct hci_link *
    172      1.1  gdamore hci_acl_newconn(struct hci_unit *unit, bdaddr_t *bdaddr)
    173      1.1  gdamore {
    174      1.1  gdamore 	struct hci_link *link;
    175      1.1  gdamore 
    176      1.3     tron 	link = hci_link_lookup_bdaddr(unit, bdaddr, HCI_LINK_ACL);
    177      1.3     tron 	if (link != NULL)
    178      1.3     tron 		return NULL;
    179      1.3     tron 
    180      1.1  gdamore 	link = hci_link_alloc(unit);
    181      1.1  gdamore 	if (link != NULL) {
    182      1.1  gdamore 		link->hl_state = HCI_LINK_WAIT_CONNECT;
    183      1.1  gdamore 		link->hl_type = HCI_LINK_ACL;
    184      1.1  gdamore 		bdaddr_copy(&link->hl_bdaddr, bdaddr);
    185      1.1  gdamore 
    186      1.1  gdamore 		if (hci_acl_expiry > 0)
    187      1.1  gdamore 			callout_schedule(&link->hl_expire, hci_acl_expiry * hz);
    188      1.1  gdamore 	}
    189      1.1  gdamore 
    190      1.1  gdamore 	return link;
    191      1.1  gdamore }
    192      1.1  gdamore 
    193      1.1  gdamore void
    194      1.1  gdamore hci_acl_timeout(void *arg)
    195      1.1  gdamore {
    196      1.1  gdamore 	struct hci_link *link = arg;
    197      1.1  gdamore 	hci_discon_cp cp;
    198      1.1  gdamore 	int s, err;
    199      1.1  gdamore 
    200      1.1  gdamore 	s = splsoftnet();
    201      1.1  gdamore 	callout_ack(&link->hl_expire);
    202      1.1  gdamore 
    203      1.1  gdamore 	if (link->hl_refcnt > 0)
    204      1.1  gdamore 		goto out;
    205      1.1  gdamore 
    206      1.1  gdamore 	DPRINTF("link #%d expired\n", link->hl_handle);
    207      1.1  gdamore 
    208      1.1  gdamore 	switch (link->hl_state) {
    209      1.1  gdamore 	case HCI_LINK_CLOSED:
    210      1.1  gdamore 	case HCI_LINK_WAIT_CONNECT:
    211      1.1  gdamore 		hci_link_free(link, ECONNRESET);
    212      1.1  gdamore 		break;
    213      1.1  gdamore 
    214      1.1  gdamore 	case HCI_LINK_OPEN:
    215      1.1  gdamore 		cp.con_handle = htole16(link->hl_handle);
    216      1.1  gdamore 		cp.reason = 0x13; /* "Remote User Terminated Connection" */
    217      1.1  gdamore 
    218      1.1  gdamore 		err = hci_send_cmd(link->hl_unit, HCI_CMD_DISCONNECT,
    219      1.1  gdamore 					&cp, sizeof(cp));
    220      1.1  gdamore 
    221      1.1  gdamore 		if (err)
    222      1.1  gdamore 			DPRINTF("error %d sending HCI_CMD_DISCONNECT\n",
    223      1.1  gdamore 					err);
    224      1.1  gdamore 
    225      1.1  gdamore 		break;
    226      1.1  gdamore 
    227      1.1  gdamore 	default:
    228      1.1  gdamore 		UNKNOWN(link->hl_state);
    229      1.1  gdamore 		break;
    230      1.1  gdamore 	}
    231      1.1  gdamore 
    232      1.1  gdamore out:
    233      1.1  gdamore 	splx(s);
    234      1.1  gdamore }
    235      1.1  gdamore 
    236      1.1  gdamore /*
    237      1.1  gdamore  * Receive ACL Data
    238      1.1  gdamore  *
    239      1.1  gdamore  * we accumulate packet fragments on the hci_link structure
    240      1.1  gdamore  * until a full L2CAP frame is ready, then send it on.
    241      1.1  gdamore  */
    242      1.1  gdamore void
    243      1.1  gdamore hci_acl_recv(struct mbuf *m, struct hci_unit *unit)
    244      1.1  gdamore {
    245      1.1  gdamore 	struct hci_link *link;
    246      1.1  gdamore 	hci_acldata_hdr_t hdr;
    247      1.1  gdamore 	uint16_t handle, want;
    248      1.1  gdamore 	int pb, got;
    249      1.1  gdamore 
    250      1.1  gdamore 	KASSERT(m);
    251      1.1  gdamore 	KASSERT(unit);
    252      1.1  gdamore 
    253      1.1  gdamore 	KASSERT(m->m_pkthdr.len >= sizeof(hdr));
    254      1.1  gdamore 	m_copydata(m, 0, sizeof(hdr), &hdr);
    255      1.1  gdamore 	m_adj(m, sizeof(hdr));
    256      1.1  gdamore 
    257      1.1  gdamore #ifdef DIAGNOSTIC
    258      1.1  gdamore 	if (hdr.type != HCI_ACL_DATA_PKT) {
    259      1.1  gdamore 		printf("%s: bad ACL packet type\n", unit->hci_devname);
    260      1.1  gdamore 		goto bad;
    261      1.1  gdamore 	}
    262      1.1  gdamore 
    263      1.1  gdamore 	if (m->m_pkthdr.len != le16toh(hdr.length)) {
    264  1.3.2.1      riz 		printf("%s: bad ACL packet length (%d != %d)\n",
    265  1.3.2.1      riz 			unit->hci_devname, m->m_pkthdr.len, le16toh(hdr.length));
    266      1.1  gdamore 		goto bad;
    267      1.1  gdamore 	}
    268      1.1  gdamore #endif
    269      1.1  gdamore 
    270      1.1  gdamore 	hdr.length = le16toh(hdr.length);
    271      1.1  gdamore 	hdr.con_handle = le16toh(hdr.con_handle);
    272      1.1  gdamore 	handle = HCI_CON_HANDLE(hdr.con_handle);
    273      1.1  gdamore 	pb = HCI_PB_FLAG(hdr.con_handle);
    274      1.1  gdamore 
    275      1.1  gdamore 	link = hci_link_lookup_handle(unit, handle);
    276      1.1  gdamore 	if (link == NULL) {
    277      1.1  gdamore 		hci_discon_cp cp;
    278      1.1  gdamore 
    279      1.1  gdamore 		DPRINTF("%s: dumping packet for unknown handle #%d\n",
    280      1.1  gdamore 			unit->hci_devname, handle);
    281      1.1  gdamore 
    282      1.1  gdamore 		/*
    283      1.1  gdamore 		 * There is no way to find out what this connection handle is
    284      1.1  gdamore 		 * for, just get rid of it. This may happen, if a USB dongle
    285      1.1  gdamore 		 * is plugged into a self powered hub and does not reset when
    286      1.1  gdamore 		 * the system is shut down.
    287      1.1  gdamore 		 */
    288      1.1  gdamore 		cp.con_handle = htole16(handle);
    289      1.1  gdamore 		cp.reason = 0x13; /* "Remote User Terminated Connection" */
    290      1.1  gdamore 		hci_send_cmd(unit, HCI_CMD_DISCONNECT, &cp, sizeof(cp));
    291      1.1  gdamore 		goto bad;
    292      1.1  gdamore 	}
    293      1.1  gdamore 
    294      1.1  gdamore 	switch (pb) {
    295      1.1  gdamore 	case HCI_PACKET_START:
    296      1.1  gdamore 		if (link->hl_rxp != NULL)
    297      1.1  gdamore 			printf("%s: dropped incomplete ACL packet\n",
    298      1.1  gdamore 				unit->hci_devname);
    299      1.1  gdamore 
    300      1.1  gdamore 		if (m->m_pkthdr.len < sizeof(l2cap_hdr_t)) {
    301      1.1  gdamore 			printf("%s: short ACL packet\n",
    302      1.1  gdamore 				unit->hci_devname);
    303      1.1  gdamore 
    304      1.1  gdamore 			goto bad;
    305      1.1  gdamore 		}
    306      1.1  gdamore 
    307      1.1  gdamore 		link->hl_rxp = m;
    308      1.1  gdamore 		got = m->m_pkthdr.len;
    309      1.1  gdamore 		break;
    310      1.1  gdamore 
    311      1.1  gdamore 	case HCI_PACKET_FRAGMENT:
    312      1.1  gdamore 		if (link->hl_rxp == NULL) {
    313      1.1  gdamore 			printf("%s: unexpected packet fragment\n",
    314      1.1  gdamore 				unit->hci_devname);
    315      1.1  gdamore 
    316      1.1  gdamore 			goto bad;
    317      1.1  gdamore 		}
    318      1.1  gdamore 
    319      1.1  gdamore 		got = m->m_pkthdr.len + link->hl_rxp->m_pkthdr.len;
    320      1.1  gdamore 		m_cat(link->hl_rxp, m);
    321      1.1  gdamore 		m = link->hl_rxp;
    322      1.1  gdamore 		m->m_pkthdr.len = got;
    323      1.1  gdamore 		break;
    324      1.1  gdamore 
    325      1.1  gdamore 	default:
    326      1.1  gdamore 		printf("%s: unknown packet type\n",
    327      1.1  gdamore 			unit->hci_devname);
    328      1.1  gdamore 
    329      1.1  gdamore 		goto bad;
    330      1.1  gdamore 	}
    331      1.1  gdamore 
    332      1.1  gdamore 	m_copydata(m, 0, sizeof(want), &want);
    333      1.1  gdamore 	want = le16toh(want) + sizeof(l2cap_hdr_t) - got;
    334      1.1  gdamore 
    335      1.1  gdamore 	if (want > 0)
    336      1.1  gdamore 		return;
    337      1.1  gdamore 
    338      1.1  gdamore 	link->hl_rxp = NULL;
    339      1.1  gdamore 
    340      1.1  gdamore 	if (want == 0) {
    341      1.1  gdamore 		l2cap_recv_frame(m, link);
    342      1.1  gdamore 		return;
    343      1.1  gdamore 	}
    344      1.1  gdamore 
    345      1.1  gdamore bad:
    346      1.1  gdamore 	m_freem(m);
    347      1.1  gdamore }
    348      1.1  gdamore 
    349      1.1  gdamore /*
    350      1.1  gdamore  * Send ACL data on link
    351      1.1  gdamore  *
    352      1.1  gdamore  * We must fragment packets into chunks of less than unit->hci_max_acl_size and
    353      1.1  gdamore  * prepend a relevant ACL header to each fragment. We keep a PDU structure
    354      1.1  gdamore  * attached to the link, so that completed fragments can be marked off and
    355      1.1  gdamore  * more data requested from above once the PDU is sent.
    356      1.1  gdamore  */
    357      1.1  gdamore int
    358      1.1  gdamore hci_acl_send(struct mbuf *m, struct hci_link *link,
    359      1.1  gdamore 		struct l2cap_channel *chan)
    360      1.1  gdamore {
    361      1.1  gdamore 	struct l2cap_pdu *pdu;
    362      1.1  gdamore 	struct mbuf *n = NULL;
    363      1.1  gdamore 	int plen, mlen, num = 0;
    364      1.1  gdamore 
    365      1.1  gdamore 	KASSERT(link);
    366      1.1  gdamore 	KASSERT(m);
    367      1.1  gdamore 	KASSERT(m->m_flags & M_PKTHDR);
    368      1.1  gdamore 	KASSERT(m->m_pkthdr.len > 0);
    369      1.1  gdamore 
    370      1.1  gdamore 	if (link->hl_state == HCI_LINK_CLOSED) {
    371      1.1  gdamore 		m_freem(m);
    372      1.1  gdamore 		return ENETDOWN;
    373      1.1  gdamore 	}
    374      1.1  gdamore 
    375      1.1  gdamore 	pdu = pool_get(&l2cap_pdu_pool, PR_NOWAIT);
    376      1.1  gdamore 	if (pdu == NULL)
    377      1.1  gdamore 		goto nomem;
    378      1.1  gdamore 
    379      1.1  gdamore 	pdu->lp_chan = chan;
    380      1.1  gdamore 	pdu->lp_pending = 0;
    381      1.1  gdamore 	MBUFQ_INIT(&pdu->lp_data);
    382      1.1  gdamore 
    383      1.1  gdamore 	plen = m->m_pkthdr.len;
    384      1.1  gdamore 	mlen = link->hl_unit->hci_max_acl_size;
    385      1.1  gdamore 
    386      1.1  gdamore 	DPRINTFN(5, "%s: handle #%d, plen = %d, max = %d\n",
    387      1.1  gdamore 		link->hl_unit->hci_devname, link->hl_handle, plen, mlen);
    388      1.1  gdamore 
    389      1.1  gdamore 	while (plen > 0) {
    390      1.1  gdamore 		if (plen > mlen) {
    391      1.1  gdamore 			n = m_split(m, mlen, M_DONTWAIT);
    392      1.1  gdamore 			if (n == NULL)
    393      1.1  gdamore 				goto nomem;
    394      1.1  gdamore 		} else {
    395      1.1  gdamore 			mlen = plen;
    396      1.1  gdamore 		}
    397      1.1  gdamore 
    398      1.1  gdamore 		if (num++ == 0)
    399      1.1  gdamore 			m->m_flags |= M_PROTO1;	/* tag first fragment */
    400      1.1  gdamore 
    401      1.1  gdamore 		DPRINTFN(10, "chunk of %d (plen = %d) bytes\n", mlen, plen);
    402      1.1  gdamore 		MBUFQ_ENQUEUE(&pdu->lp_data, m);
    403      1.1  gdamore 		m = n;
    404      1.1  gdamore 		plen -= mlen;
    405      1.1  gdamore 	}
    406      1.1  gdamore 
    407      1.1  gdamore 	TAILQ_INSERT_TAIL(&link->hl_txq, pdu, lp_next);
    408      1.1  gdamore 	link->hl_txqlen += num;
    409      1.1  gdamore 
    410      1.1  gdamore 	hci_acl_start(link);
    411      1.1  gdamore 
    412      1.1  gdamore 	return 0;
    413      1.1  gdamore 
    414      1.1  gdamore nomem:
    415      1.1  gdamore 	if (m) m_freem(m);
    416      1.1  gdamore 	if (n) m_freem(n);
    417      1.1  gdamore 	if (pdu) {
    418      1.1  gdamore 		MBUFQ_DRAIN(&pdu->lp_data);
    419      1.1  gdamore 		pool_put(&l2cap_pdu_pool, pdu);
    420      1.1  gdamore 	}
    421      1.1  gdamore 
    422      1.1  gdamore 	return ENOMEM;
    423      1.1  gdamore }
    424      1.1  gdamore 
    425      1.1  gdamore /*
    426      1.1  gdamore  * Start sending ACL data on link.
    427      1.1  gdamore  *
    428      1.1  gdamore  *	We may use all the available packet slots. The reason that we add
    429      1.1  gdamore  * the ACL encapsulation here rather than in hci_acl_send() is that L2CAP
    430      1.1  gdamore  * signal packets may be queued before the handle is given to us..
    431      1.1  gdamore  *
    432      1.1  gdamore  * this is called from hci_acl_send() above, and the event processing
    433      1.1  gdamore  * code (for CON_COMPL and NUM_COMPL_PKTS)
    434      1.1  gdamore  */
    435      1.1  gdamore void
    436      1.1  gdamore hci_acl_start(struct hci_link *link)
    437      1.1  gdamore {
    438      1.1  gdamore 	struct hci_unit *unit;
    439      1.1  gdamore 	hci_acldata_hdr_t *hdr;
    440      1.1  gdamore 	struct l2cap_pdu *pdu;
    441      1.1  gdamore 	struct mbuf *m;
    442      1.1  gdamore 	uint16_t handle;
    443      1.1  gdamore 
    444      1.1  gdamore 	KASSERT(link);
    445      1.1  gdamore 
    446      1.1  gdamore 	unit = link->hl_unit;
    447      1.1  gdamore 	KASSERT(unit);
    448      1.1  gdamore 
    449      1.1  gdamore 	/* this is mainly to block ourselves (below) */
    450      1.1  gdamore 	if (link->hl_state != HCI_LINK_OPEN)
    451      1.1  gdamore 		return;
    452      1.1  gdamore 
    453      1.1  gdamore 	if (link->hl_txqlen == 0 || unit->hci_num_acl_pkts == 0)
    454      1.1  gdamore 		return;
    455      1.1  gdamore 
    456      1.1  gdamore 	/* find first PDU with data to send */
    457      1.1  gdamore 	pdu = TAILQ_FIRST(&link->hl_txq);
    458      1.1  gdamore 	for (;;) {
    459      1.1  gdamore 		if (pdu == NULL)
    460      1.1  gdamore 			return;
    461      1.1  gdamore 
    462      1.1  gdamore 		if (MBUFQ_FIRST(&pdu->lp_data) != NULL)
    463      1.1  gdamore 			break;
    464      1.1  gdamore 
    465      1.1  gdamore 		pdu = TAILQ_NEXT(pdu, lp_next);
    466      1.1  gdamore 	}
    467      1.1  gdamore 
    468      1.1  gdamore 	while (unit->hci_num_acl_pkts > 0) {
    469      1.1  gdamore 		MBUFQ_DEQUEUE(&pdu->lp_data, m);
    470      1.1  gdamore 		KASSERT(m != NULL);
    471      1.1  gdamore 
    472      1.1  gdamore 		if (m->m_flags & M_PROTO1)
    473      1.1  gdamore 			handle = HCI_MK_CON_HANDLE(link->hl_handle,
    474      1.1  gdamore 						HCI_PACKET_START, 0);
    475      1.1  gdamore 		else
    476      1.1  gdamore 			handle = HCI_MK_CON_HANDLE(link->hl_handle,
    477      1.1  gdamore 						HCI_PACKET_FRAGMENT, 0);
    478      1.1  gdamore 
    479      1.1  gdamore 		M_PREPEND(m, sizeof(*hdr), M_DONTWAIT);
    480      1.1  gdamore 		if (m == NULL)
    481      1.1  gdamore 			break;
    482      1.1  gdamore 
    483      1.1  gdamore 		hdr = mtod(m, hci_acldata_hdr_t *);
    484      1.1  gdamore 		hdr->type = HCI_ACL_DATA_PKT;
    485      1.1  gdamore 		hdr->con_handle = htole16(handle);
    486      1.1  gdamore 		hdr->length = htole16(m->m_pkthdr.len - sizeof(*hdr));
    487      1.1  gdamore 
    488      1.1  gdamore 		link->hl_txqlen--;
    489      1.1  gdamore 		pdu->lp_pending++;
    490      1.1  gdamore 
    491      1.1  gdamore 		hci_output_acl(unit, m);
    492      1.1  gdamore 
    493      1.1  gdamore 		if (MBUFQ_FIRST(&pdu->lp_data) == NULL) {
    494      1.1  gdamore 			if (pdu->lp_chan) {
    495      1.1  gdamore 				/*
    496      1.1  gdamore 				 * This should enable streaming of PDUs - when
    497      1.1  gdamore 				 * we have placed all the fragments on the acl
    498      1.1  gdamore 				 * output queue, we trigger the L2CAP layer to
    499      1.1  gdamore 				 * send us down one more. Use a false state so
    500      1.1  gdamore 				 * we dont run into ourselves coming back from
    501      1.1  gdamore 				 * the future..
    502      1.1  gdamore 				 */
    503      1.1  gdamore 				link->hl_state = HCI_LINK_BLOCK;
    504      1.1  gdamore 				l2cap_start(pdu->lp_chan);
    505      1.1  gdamore 				link->hl_state = HCI_LINK_OPEN;
    506      1.1  gdamore 			}
    507      1.1  gdamore 
    508      1.1  gdamore 			pdu = TAILQ_NEXT(pdu, lp_next);
    509      1.1  gdamore 			if (pdu == NULL)
    510      1.1  gdamore 				break;
    511      1.1  gdamore 		}
    512      1.1  gdamore 	}
    513      1.1  gdamore 
    514      1.1  gdamore 	/*
    515      1.1  gdamore 	 * We had our turn now, move to the back of the queue to let
    516      1.1  gdamore 	 * other links have a go at the output buffers..
    517      1.1  gdamore 	 */
    518      1.1  gdamore 	if (TAILQ_NEXT(link, hl_next)) {
    519      1.1  gdamore 		TAILQ_REMOVE(&unit->hci_links, link, hl_next);
    520      1.1  gdamore 		TAILQ_INSERT_TAIL(&unit->hci_links, link, hl_next);
    521      1.1  gdamore 	}
    522      1.1  gdamore }
    523      1.1  gdamore 
    524      1.1  gdamore /*
    525      1.1  gdamore  * Confirm ACL packets cleared from Controller buffers. We scan our PDU
    526      1.1  gdamore  * list to clear pending fragments and signal upstream for more data
    527      1.1  gdamore  * when a PDU is complete.
    528      1.1  gdamore  */
    529      1.1  gdamore void
    530      1.1  gdamore hci_acl_complete(struct hci_link *link, int num)
    531      1.1  gdamore {
    532      1.1  gdamore 	struct l2cap_pdu *pdu;
    533      1.1  gdamore 	struct l2cap_channel *chan;
    534      1.1  gdamore 
    535      1.1  gdamore 	DPRINTFN(5, "handle #%d (%d)\n", link->hl_handle, num);
    536      1.1  gdamore 
    537      1.1  gdamore 	while (num > 0) {
    538      1.1  gdamore 		pdu = TAILQ_FIRST(&link->hl_txq);
    539      1.1  gdamore 		if (pdu == NULL) {
    540      1.1  gdamore 			printf("%s: %d packets completed on handle #%x "
    541      1.1  gdamore 				"but none pending!\n",
    542      1.1  gdamore 				link->hl_unit->hci_devname, num,
    543      1.1  gdamore 				link->hl_handle);
    544      1.1  gdamore 			return;
    545      1.1  gdamore 		}
    546      1.1  gdamore 
    547      1.1  gdamore 		if (num >= pdu->lp_pending) {
    548      1.1  gdamore 			num -= pdu->lp_pending;
    549      1.1  gdamore 			pdu->lp_pending = 0;
    550      1.1  gdamore 
    551      1.1  gdamore 			if (MBUFQ_FIRST(&pdu->lp_data) == NULL) {
    552      1.1  gdamore 				TAILQ_REMOVE(&link->hl_txq, pdu, lp_next);
    553      1.1  gdamore 				chan = pdu->lp_chan;
    554      1.1  gdamore 				if (chan != NULL) {
    555      1.1  gdamore 					chan->lc_pending--;
    556      1.1  gdamore 					(*chan->lc_proto->complete)
    557      1.1  gdamore 							(chan->lc_upper, 1);
    558      1.1  gdamore 
    559      1.1  gdamore 					if (chan->lc_pending == 0)
    560      1.1  gdamore 						l2cap_start(chan);
    561      1.1  gdamore 				}
    562      1.1  gdamore 
    563      1.1  gdamore 				pool_put(&l2cap_pdu_pool, pdu);
    564      1.1  gdamore 			}
    565      1.1  gdamore 		} else {
    566      1.1  gdamore 			pdu->lp_pending -= num;
    567      1.1  gdamore 			num = 0;
    568      1.1  gdamore 		}
    569      1.1  gdamore 	}
    570      1.1  gdamore }
    571      1.1  gdamore 
    572      1.1  gdamore /*******************************************************************************
    573      1.1  gdamore  *
    574      1.1  gdamore  *	HCI SCO Connections
    575      1.1  gdamore  */
    576      1.1  gdamore 
    577      1.1  gdamore /*
    578      1.3     tron  * Incoming SCO Connection. We check the list for anybody willing
    579      1.3     tron  * to take it.
    580      1.1  gdamore  */
    581      1.1  gdamore struct hci_link *
    582      1.1  gdamore hci_sco_newconn(struct hci_unit *unit, bdaddr_t *bdaddr)
    583      1.1  gdamore {
    584      1.3     tron 	struct sockaddr_bt laddr, raddr;
    585      1.3     tron 	struct sco_pcb *pcb, *new;
    586      1.3     tron 	struct hci_link *sco, *acl;
    587      1.3     tron 
    588      1.3     tron 	memset(&laddr, 0, sizeof(laddr));
    589      1.3     tron 	laddr.bt_len = sizeof(laddr);
    590      1.3     tron 	laddr.bt_family = AF_BLUETOOTH;
    591      1.3     tron 	bdaddr_copy(&laddr.bt_bdaddr, &unit->hci_bdaddr);
    592      1.3     tron 
    593      1.3     tron 	memset(&raddr, 0, sizeof(raddr));
    594      1.3     tron 	raddr.bt_len = sizeof(raddr);
    595      1.3     tron 	raddr.bt_family = AF_BLUETOOTH;
    596      1.3     tron 	bdaddr_copy(&raddr.bt_bdaddr, bdaddr);
    597      1.3     tron 
    598      1.3     tron 	/*
    599      1.3     tron 	 * There should already be an ACL link up and running before
    600      1.3     tron 	 * the controller sends us SCO connection requests, but you
    601      1.3     tron 	 * never know..
    602      1.3     tron 	 */
    603      1.3     tron 	acl = hci_link_lookup_bdaddr(unit, bdaddr, HCI_LINK_ACL);
    604      1.3     tron 	if (acl == NULL || acl->hl_state != HCI_LINK_OPEN)
    605      1.3     tron 		return NULL;
    606      1.3     tron 
    607      1.3     tron 	LIST_FOREACH(pcb, &sco_pcb, sp_next) {
    608      1.3     tron 		if ((pcb->sp_flags & SP_LISTENING) == 0)
    609      1.3     tron 			continue;
    610      1.3     tron 
    611      1.3     tron 		new = (*pcb->sp_proto->newconn)(pcb->sp_upper, &laddr, &raddr);
    612      1.3     tron 		if (new == NULL)
    613      1.3     tron 			continue;
    614      1.3     tron 
    615      1.3     tron 		/*
    616      1.3     tron 		 * Ok, got new pcb so we can start a new link and fill
    617      1.3     tron 		 * in all the details.
    618      1.3     tron 		 */
    619      1.3     tron 		bdaddr_copy(&new->sp_laddr, &unit->hci_bdaddr);
    620      1.3     tron 		bdaddr_copy(&new->sp_raddr, bdaddr);
    621      1.3     tron 
    622      1.3     tron 		sco = hci_link_alloc(unit);
    623      1.3     tron 		if (sco == NULL) {
    624      1.3     tron 			sco_detach(&new);
    625      1.3     tron 			return NULL;
    626      1.3     tron 		}
    627      1.3     tron 
    628      1.3     tron 		sco->hl_type = HCI_LINK_SCO;
    629      1.3     tron 		bdaddr_copy(&sco->hl_bdaddr, bdaddr);
    630      1.3     tron 
    631      1.3     tron 		sco->hl_link = hci_acl_open(unit, bdaddr);
    632      1.3     tron 		KASSERT(sco->hl_link == acl);
    633      1.3     tron 
    634      1.3     tron 		sco->hl_sco = new;
    635      1.3     tron 		new->sp_link = sco;
    636      1.3     tron 
    637      1.3     tron 		new->sp_mtu = unit->hci_max_sco_size;
    638      1.3     tron 		return sco;
    639      1.3     tron 	}
    640      1.1  gdamore 
    641      1.1  gdamore 	return NULL;
    642      1.1  gdamore }
    643      1.1  gdamore 
    644      1.1  gdamore /*
    645      1.1  gdamore  * receive SCO packet, we only need to strip the header and send
    646      1.1  gdamore  * it to the right handler
    647      1.1  gdamore  */
    648      1.1  gdamore void
    649      1.1  gdamore hci_sco_recv(struct mbuf *m, struct hci_unit *unit)
    650      1.1  gdamore {
    651      1.1  gdamore 	struct hci_link *link;
    652      1.1  gdamore 	hci_scodata_hdr_t hdr;
    653      1.1  gdamore 	uint16_t handle;
    654      1.1  gdamore 
    655      1.1  gdamore 	KASSERT(m);
    656      1.1  gdamore 	KASSERT(unit);
    657      1.1  gdamore 
    658      1.1  gdamore 	KASSERT(m->m_pkthdr.len >= sizeof(hdr));
    659      1.1  gdamore 	m_copydata(m, 0, sizeof(hdr), &hdr);
    660      1.1  gdamore 	m_adj(m, sizeof(hdr));
    661      1.1  gdamore 
    662      1.1  gdamore #ifdef DIAGNOSTIC
    663      1.1  gdamore 	if (hdr.type != HCI_SCO_DATA_PKT) {
    664      1.1  gdamore 		printf("%s: bad SCO packet type\n", unit->hci_devname);
    665      1.1  gdamore 		goto bad;
    666      1.1  gdamore 	}
    667      1.1  gdamore 
    668      1.1  gdamore 	if (m->m_pkthdr.len != hdr.length) {
    669      1.1  gdamore 		printf("%s: bad SCO packet length (%d != %d)\n", unit->hci_devname, m->m_pkthdr.len, hdr.length);
    670      1.1  gdamore 		goto bad;
    671      1.1  gdamore 	}
    672      1.1  gdamore #endif
    673      1.1  gdamore 
    674      1.1  gdamore 	hdr.con_handle = le16toh(hdr.con_handle);
    675      1.1  gdamore 	handle = HCI_CON_HANDLE(hdr.con_handle);
    676      1.1  gdamore 
    677      1.1  gdamore 	link = hci_link_lookup_handle(unit, handle);
    678      1.1  gdamore 	if (link == NULL || link->hl_type == HCI_LINK_ACL) {
    679      1.1  gdamore 		DPRINTF("%s: dumping packet for unknown handle #%d\n",
    680      1.1  gdamore 			unit->hci_devname, handle);
    681      1.1  gdamore 
    682      1.1  gdamore 		goto bad;
    683      1.1  gdamore 	}
    684      1.1  gdamore 
    685      1.1  gdamore 	(*link->hl_sco->sp_proto->input)(link->hl_sco->sp_upper, m);
    686      1.1  gdamore 	return;
    687      1.1  gdamore 
    688      1.1  gdamore bad:
    689      1.1  gdamore 	m_freem(m);
    690      1.1  gdamore }
    691      1.1  gdamore 
    692      1.1  gdamore void
    693      1.1  gdamore hci_sco_start(struct hci_link *link)
    694      1.1  gdamore {
    695      1.1  gdamore }
    696      1.1  gdamore 
    697      1.1  gdamore /*
    698      1.1  gdamore  * SCO packets have completed at the controller, so we can
    699      1.1  gdamore  * signal up to free the buffer space.
    700      1.1  gdamore  */
    701      1.1  gdamore void
    702      1.1  gdamore hci_sco_complete(struct hci_link *link, int num)
    703      1.1  gdamore {
    704      1.1  gdamore 
    705      1.1  gdamore 	DPRINTFN(5, "handle #%d (num=%d)\n", link->hl_handle, num);
    706      1.1  gdamore 	link->hl_sco->sp_pending--;
    707      1.1  gdamore 	(*link->hl_sco->sp_proto->complete)(link->hl_sco->sp_upper, num);
    708      1.1  gdamore }
    709      1.1  gdamore 
    710      1.1  gdamore /*******************************************************************************
    711      1.1  gdamore  *
    712      1.1  gdamore  *	Generic HCI Connection alloc/free/lookup etc
    713      1.1  gdamore  */
    714      1.1  gdamore 
    715      1.1  gdamore struct hci_link *
    716      1.1  gdamore hci_link_alloc(struct hci_unit *unit)
    717      1.1  gdamore {
    718      1.1  gdamore 	struct hci_link *link;
    719      1.1  gdamore 
    720      1.1  gdamore 	KASSERT(unit);
    721      1.1  gdamore 
    722      1.1  gdamore 	link = malloc(sizeof(struct hci_link), M_BLUETOOTH, M_NOWAIT | M_ZERO);
    723      1.1  gdamore 	if (link == NULL)
    724      1.1  gdamore 		return NULL;
    725      1.1  gdamore 
    726      1.1  gdamore 	link->hl_unit = unit;
    727      1.1  gdamore 	link->hl_state = HCI_LINK_CLOSED;
    728      1.1  gdamore 
    729      1.1  gdamore 	/* init ACL portion */
    730      1.1  gdamore 	callout_init(&link->hl_expire);
    731      1.1  gdamore 	callout_setfunc(&link->hl_expire, hci_acl_timeout, link);
    732      1.1  gdamore 
    733      1.1  gdamore 	TAILQ_INIT(&link->hl_txq);	/* outgoing packets */
    734      1.1  gdamore 	TAILQ_INIT(&link->hl_reqs);	/* request queue */
    735      1.1  gdamore 
    736      1.1  gdamore 	link->hl_mtu = L2CAP_MTU_DEFAULT;		/* L2CAP signal mtu */
    737      1.1  gdamore 	link->hl_flush = L2CAP_FLUSH_TIMO_DEFAULT;	/* flush timeout */
    738      1.1  gdamore 
    739      1.1  gdamore 	/* init SCO portion */
    740      1.1  gdamore 	MBUFQ_INIT(&link->hl_data);
    741      1.1  gdamore 
    742      1.1  gdamore 	/* attach to unit */
    743      1.1  gdamore 	TAILQ_INSERT_HEAD(&unit->hci_links, link, hl_next);
    744      1.1  gdamore 	return link;
    745      1.1  gdamore }
    746      1.1  gdamore 
    747      1.1  gdamore void
    748      1.1  gdamore hci_link_free(struct hci_link *link, int err)
    749      1.1  gdamore {
    750      1.1  gdamore 	struct l2cap_req *req;
    751      1.1  gdamore 	struct l2cap_pdu *pdu;
    752  1.3.2.1      riz 	struct l2cap_channel *chan, *next;
    753      1.1  gdamore 
    754      1.1  gdamore 	KASSERT(link);
    755      1.1  gdamore 
    756      1.1  gdamore 	DPRINTF("#%d, type = %d, state = %d, refcnt = %d\n",
    757      1.1  gdamore 		link->hl_handle, link->hl_type,
    758      1.1  gdamore 		link->hl_state, link->hl_refcnt);
    759      1.1  gdamore 
    760      1.1  gdamore 	/* ACL reference count */
    761      1.1  gdamore 	if (link->hl_refcnt > 0) {
    762  1.3.2.1      riz 		next = LIST_FIRST(&l2cap_active_list);
    763  1.3.2.1      riz 		while ((chan = next) != NULL) {
    764  1.3.2.1      riz 			next = LIST_NEXT(chan, lc_ncid);
    765      1.1  gdamore 			if (chan->lc_link == link)
    766      1.1  gdamore 				l2cap_close(chan, err);
    767      1.1  gdamore 		}
    768      1.1  gdamore 	}
    769      1.1  gdamore 	KASSERT(link->hl_refcnt == 0);
    770      1.1  gdamore 
    771      1.1  gdamore 	/* ACL L2CAP requests.. */
    772      1.1  gdamore 	while ((req = TAILQ_FIRST(&link->hl_reqs)) != NULL)
    773      1.1  gdamore 		l2cap_request_free(req);
    774      1.1  gdamore 
    775      1.1  gdamore 	KASSERT(TAILQ_EMPTY(&link->hl_reqs));
    776      1.1  gdamore 
    777      1.1  gdamore 	/* ACL outgoing data queue */
    778      1.1  gdamore 	while ((pdu = TAILQ_FIRST(&link->hl_txq)) != NULL) {
    779      1.1  gdamore 		TAILQ_REMOVE(&link->hl_txq, pdu, lp_next);
    780      1.1  gdamore 		MBUFQ_DRAIN(&pdu->lp_data);
    781      1.1  gdamore 		if (pdu->lp_pending)
    782      1.1  gdamore 			link->hl_unit->hci_num_acl_pkts += pdu->lp_pending;
    783      1.1  gdamore 
    784      1.1  gdamore 		pool_put(&l2cap_pdu_pool, pdu);
    785      1.1  gdamore 	}
    786      1.1  gdamore 
    787      1.1  gdamore 	KASSERT(TAILQ_EMPTY(&link->hl_txq));
    788      1.1  gdamore 
    789      1.1  gdamore 	/* ACL incoming data packet */
    790      1.1  gdamore 	if (link->hl_rxp != NULL) {
    791      1.1  gdamore 		m_freem(link->hl_rxp);
    792      1.1  gdamore 		link->hl_rxp = NULL;
    793      1.1  gdamore 	}
    794      1.1  gdamore 
    795      1.1  gdamore 	/* SCO master ACL link */
    796      1.1  gdamore 	if (link->hl_link != NULL) {
    797      1.1  gdamore 		hci_acl_close(link->hl_link, err);
    798      1.1  gdamore 		link->hl_link = NULL;
    799      1.1  gdamore 	}
    800      1.1  gdamore 
    801      1.1  gdamore 	/* SCO pcb */
    802      1.1  gdamore 	if (link->hl_sco != NULL) {
    803      1.1  gdamore 		struct sco_pcb *pcb;
    804      1.1  gdamore 
    805      1.1  gdamore 		pcb = link->hl_sco;
    806      1.1  gdamore 		pcb->sp_link = NULL;
    807      1.1  gdamore 		link->hl_sco = NULL;
    808      1.1  gdamore 		(*pcb->sp_proto->disconnected)(pcb->sp_upper, err);
    809      1.1  gdamore 	}
    810      1.1  gdamore 
    811      1.1  gdamore 	/* flush any SCO data */
    812      1.1  gdamore 	MBUFQ_DRAIN(&link->hl_data);
    813      1.1  gdamore 
    814      1.1  gdamore 	/*
    815      1.1  gdamore 	 * Halt the callout - if its already running we cannot free the
    816      1.1  gdamore 	 * link structure but the timeout function will call us back in
    817      1.1  gdamore 	 * any case.
    818      1.1  gdamore 	 */
    819      1.1  gdamore 	link->hl_state = HCI_LINK_CLOSED;
    820      1.1  gdamore 	callout_stop(&link->hl_expire);
    821      1.1  gdamore 	if (callout_invoking(&link->hl_expire))
    822      1.1  gdamore 		return;
    823      1.1  gdamore 
    824      1.1  gdamore 	TAILQ_REMOVE(&link->hl_unit->hci_links, link, hl_next);
    825      1.1  gdamore 	free(link, M_BLUETOOTH);
    826      1.1  gdamore }
    827      1.1  gdamore 
    828      1.1  gdamore /*
    829      1.1  gdamore  * Lookup HCI link by address and type. Note that for SCO links there may
    830      1.1  gdamore  * be more than one link per address, so we only return links with no
    831      1.1  gdamore  * handle (ie new links)
    832      1.1  gdamore  */
    833      1.1  gdamore struct hci_link *
    834      1.1  gdamore hci_link_lookup_bdaddr(struct hci_unit *unit, bdaddr_t *bdaddr, uint16_t type)
    835      1.1  gdamore {
    836      1.1  gdamore 	struct hci_link *link;
    837      1.1  gdamore 
    838      1.1  gdamore 	KASSERT(unit);
    839      1.1  gdamore 	KASSERT(bdaddr);
    840      1.1  gdamore 
    841      1.1  gdamore 	TAILQ_FOREACH(link, &unit->hci_links, hl_next) {
    842      1.1  gdamore 		if (link->hl_type != type)
    843      1.1  gdamore 			continue;
    844      1.1  gdamore 
    845      1.1  gdamore 		if (type == HCI_LINK_SCO && link->hl_handle != 0)
    846      1.1  gdamore 			continue;
    847      1.1  gdamore 
    848      1.1  gdamore 		if (bdaddr_same(&link->hl_bdaddr, bdaddr))
    849      1.1  gdamore 			break;
    850      1.1  gdamore 	}
    851      1.1  gdamore 
    852      1.1  gdamore 	return link;
    853      1.1  gdamore }
    854      1.1  gdamore 
    855      1.1  gdamore struct hci_link *
    856      1.1  gdamore hci_link_lookup_handle(struct hci_unit *unit, uint16_t handle)
    857      1.1  gdamore {
    858      1.1  gdamore 	struct hci_link *link;
    859      1.1  gdamore 
    860      1.1  gdamore 	KASSERT(unit);
    861      1.1  gdamore 
    862      1.1  gdamore 	TAILQ_FOREACH(link, &unit->hci_links, hl_next) {
    863      1.1  gdamore 		if (handle == link->hl_handle)
    864      1.1  gdamore 			break;
    865      1.1  gdamore 	}
    866      1.1  gdamore 
    867      1.1  gdamore 	return link;
    868      1.1  gdamore }
    869