Home | History | Annotate | Line # | Download | only in netbt
hci_link.c revision 1.5.2.1
      1  1.5.2.1     yamt /*	$NetBSD: hci_link.c,v 1.5.2.1 2006/10/22 06:07:28 yamt 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.5.2.1     yamt __KERNEL_RCSID(0, "$NetBSD: hci_link.c,v 1.5.2.1 2006/10/22 06:07:28 yamt 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.5   plunky 			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.5.2.1     yamt 		if (err) {
    222      1.1  gdamore 			DPRINTF("error %d sending HCI_CMD_DISCONNECT\n",
    223  1.5.2.1     yamt 			    err);
    224  1.5.2.1     yamt 		}
    225      1.1  gdamore 
    226      1.1  gdamore 		break;
    227      1.1  gdamore 
    228      1.1  gdamore 	default:
    229      1.1  gdamore 		UNKNOWN(link->hl_state);
    230      1.1  gdamore 		break;
    231      1.1  gdamore 	}
    232      1.1  gdamore 
    233      1.1  gdamore out:
    234      1.1  gdamore 	splx(s);
    235      1.1  gdamore }
    236      1.1  gdamore 
    237      1.1  gdamore /*
    238      1.1  gdamore  * Receive ACL Data
    239      1.1  gdamore  *
    240      1.1  gdamore  * we accumulate packet fragments on the hci_link structure
    241      1.1  gdamore  * until a full L2CAP frame is ready, then send it on.
    242      1.1  gdamore  */
    243      1.1  gdamore void
    244      1.1  gdamore hci_acl_recv(struct mbuf *m, struct hci_unit *unit)
    245      1.1  gdamore {
    246      1.1  gdamore 	struct hci_link *link;
    247      1.1  gdamore 	hci_acldata_hdr_t hdr;
    248      1.1  gdamore 	uint16_t handle, want;
    249      1.1  gdamore 	int pb, got;
    250      1.1  gdamore 
    251      1.1  gdamore 	KASSERT(m);
    252      1.1  gdamore 	KASSERT(unit);
    253      1.1  gdamore 
    254      1.1  gdamore 	KASSERT(m->m_pkthdr.len >= sizeof(hdr));
    255      1.1  gdamore 	m_copydata(m, 0, sizeof(hdr), &hdr);
    256      1.1  gdamore 	m_adj(m, sizeof(hdr));
    257      1.1  gdamore 
    258      1.1  gdamore #ifdef DIAGNOSTIC
    259      1.1  gdamore 	if (hdr.type != HCI_ACL_DATA_PKT) {
    260      1.1  gdamore 		printf("%s: bad ACL packet type\n", unit->hci_devname);
    261      1.1  gdamore 		goto bad;
    262      1.1  gdamore 	}
    263      1.1  gdamore 
    264      1.1  gdamore 	if (m->m_pkthdr.len != le16toh(hdr.length)) {
    265      1.5   plunky 		printf("%s: bad ACL packet length (%d != %d)\n",
    266      1.5   plunky 			unit->hci_devname, m->m_pkthdr.len, le16toh(hdr.length));
    267      1.1  gdamore 		goto bad;
    268      1.1  gdamore 	}
    269      1.1  gdamore #endif
    270      1.1  gdamore 
    271      1.1  gdamore 	hdr.length = le16toh(hdr.length);
    272      1.1  gdamore 	hdr.con_handle = le16toh(hdr.con_handle);
    273      1.1  gdamore 	handle = HCI_CON_HANDLE(hdr.con_handle);
    274      1.1  gdamore 	pb = HCI_PB_FLAG(hdr.con_handle);
    275      1.1  gdamore 
    276      1.1  gdamore 	link = hci_link_lookup_handle(unit, handle);
    277      1.1  gdamore 	if (link == NULL) {
    278      1.1  gdamore 		hci_discon_cp cp;
    279      1.1  gdamore 
    280      1.1  gdamore 		DPRINTF("%s: dumping packet for unknown handle #%d\n",
    281      1.1  gdamore 			unit->hci_devname, handle);
    282      1.1  gdamore 
    283      1.1  gdamore 		/*
    284      1.1  gdamore 		 * There is no way to find out what this connection handle is
    285      1.1  gdamore 		 * for, just get rid of it. This may happen, if a USB dongle
    286      1.1  gdamore 		 * is plugged into a self powered hub and does not reset when
    287      1.1  gdamore 		 * the system is shut down.
    288      1.1  gdamore 		 */
    289      1.1  gdamore 		cp.con_handle = htole16(handle);
    290      1.1  gdamore 		cp.reason = 0x13; /* "Remote User Terminated Connection" */
    291      1.1  gdamore 		hci_send_cmd(unit, HCI_CMD_DISCONNECT, &cp, sizeof(cp));
    292      1.1  gdamore 		goto bad;
    293      1.1  gdamore 	}
    294      1.1  gdamore 
    295      1.1  gdamore 	switch (pb) {
    296      1.1  gdamore 	case HCI_PACKET_START:
    297      1.1  gdamore 		if (link->hl_rxp != NULL)
    298      1.1  gdamore 			printf("%s: dropped incomplete ACL packet\n",
    299      1.1  gdamore 				unit->hci_devname);
    300      1.1  gdamore 
    301      1.1  gdamore 		if (m->m_pkthdr.len < sizeof(l2cap_hdr_t)) {
    302      1.1  gdamore 			printf("%s: short ACL packet\n",
    303      1.1  gdamore 				unit->hci_devname);
    304      1.1  gdamore 
    305      1.1  gdamore 			goto bad;
    306      1.1  gdamore 		}
    307      1.1  gdamore 
    308      1.1  gdamore 		link->hl_rxp = m;
    309      1.1  gdamore 		got = m->m_pkthdr.len;
    310      1.1  gdamore 		break;
    311      1.1  gdamore 
    312      1.1  gdamore 	case HCI_PACKET_FRAGMENT:
    313      1.1  gdamore 		if (link->hl_rxp == NULL) {
    314      1.1  gdamore 			printf("%s: unexpected packet fragment\n",
    315      1.1  gdamore 				unit->hci_devname);
    316      1.1  gdamore 
    317      1.1  gdamore 			goto bad;
    318      1.1  gdamore 		}
    319      1.1  gdamore 
    320      1.1  gdamore 		got = m->m_pkthdr.len + link->hl_rxp->m_pkthdr.len;
    321      1.1  gdamore 		m_cat(link->hl_rxp, m);
    322      1.1  gdamore 		m = link->hl_rxp;
    323      1.1  gdamore 		m->m_pkthdr.len = got;
    324      1.1  gdamore 		break;
    325      1.1  gdamore 
    326      1.1  gdamore 	default:
    327      1.1  gdamore 		printf("%s: unknown packet type\n",
    328      1.1  gdamore 			unit->hci_devname);
    329      1.1  gdamore 
    330      1.1  gdamore 		goto bad;
    331      1.1  gdamore 	}
    332      1.1  gdamore 
    333      1.1  gdamore 	m_copydata(m, 0, sizeof(want), &want);
    334      1.1  gdamore 	want = le16toh(want) + sizeof(l2cap_hdr_t) - got;
    335      1.1  gdamore 
    336      1.1  gdamore 	if (want > 0)
    337      1.1  gdamore 		return;
    338      1.1  gdamore 
    339      1.1  gdamore 	link->hl_rxp = NULL;
    340      1.1  gdamore 
    341      1.1  gdamore 	if (want == 0) {
    342      1.1  gdamore 		l2cap_recv_frame(m, link);
    343      1.1  gdamore 		return;
    344      1.1  gdamore 	}
    345      1.1  gdamore 
    346      1.1  gdamore bad:
    347      1.1  gdamore 	m_freem(m);
    348      1.1  gdamore }
    349      1.1  gdamore 
    350      1.1  gdamore /*
    351      1.1  gdamore  * Send ACL data on link
    352      1.1  gdamore  *
    353      1.1  gdamore  * We must fragment packets into chunks of less than unit->hci_max_acl_size and
    354      1.1  gdamore  * prepend a relevant ACL header to each fragment. We keep a PDU structure
    355      1.1  gdamore  * attached to the link, so that completed fragments can be marked off and
    356      1.1  gdamore  * more data requested from above once the PDU is sent.
    357      1.1  gdamore  */
    358      1.1  gdamore int
    359      1.1  gdamore hci_acl_send(struct mbuf *m, struct hci_link *link,
    360      1.1  gdamore 		struct l2cap_channel *chan)
    361      1.1  gdamore {
    362      1.1  gdamore 	struct l2cap_pdu *pdu;
    363      1.1  gdamore 	struct mbuf *n = NULL;
    364      1.1  gdamore 	int plen, mlen, num = 0;
    365      1.1  gdamore 
    366      1.1  gdamore 	KASSERT(link);
    367      1.1  gdamore 	KASSERT(m);
    368      1.1  gdamore 	KASSERT(m->m_flags & M_PKTHDR);
    369      1.1  gdamore 	KASSERT(m->m_pkthdr.len > 0);
    370      1.1  gdamore 
    371      1.1  gdamore 	if (link->hl_state == HCI_LINK_CLOSED) {
    372      1.1  gdamore 		m_freem(m);
    373      1.1  gdamore 		return ENETDOWN;
    374      1.1  gdamore 	}
    375      1.1  gdamore 
    376      1.1  gdamore 	pdu = pool_get(&l2cap_pdu_pool, PR_NOWAIT);
    377      1.1  gdamore 	if (pdu == NULL)
    378      1.1  gdamore 		goto nomem;
    379      1.1  gdamore 
    380      1.1  gdamore 	pdu->lp_chan = chan;
    381      1.1  gdamore 	pdu->lp_pending = 0;
    382      1.1  gdamore 	MBUFQ_INIT(&pdu->lp_data);
    383      1.1  gdamore 
    384      1.1  gdamore 	plen = m->m_pkthdr.len;
    385      1.1  gdamore 	mlen = link->hl_unit->hci_max_acl_size;
    386      1.1  gdamore 
    387      1.1  gdamore 	DPRINTFN(5, "%s: handle #%d, plen = %d, max = %d\n",
    388      1.1  gdamore 		link->hl_unit->hci_devname, link->hl_handle, plen, mlen);
    389      1.1  gdamore 
    390      1.1  gdamore 	while (plen > 0) {
    391      1.1  gdamore 		if (plen > mlen) {
    392      1.1  gdamore 			n = m_split(m, mlen, M_DONTWAIT);
    393      1.1  gdamore 			if (n == NULL)
    394      1.1  gdamore 				goto nomem;
    395      1.1  gdamore 		} else {
    396      1.1  gdamore 			mlen = plen;
    397      1.1  gdamore 		}
    398      1.1  gdamore 
    399      1.1  gdamore 		if (num++ == 0)
    400      1.1  gdamore 			m->m_flags |= M_PROTO1;	/* tag first fragment */
    401      1.1  gdamore 
    402      1.1  gdamore 		DPRINTFN(10, "chunk of %d (plen = %d) bytes\n", mlen, plen);
    403      1.1  gdamore 		MBUFQ_ENQUEUE(&pdu->lp_data, m);
    404      1.1  gdamore 		m = n;
    405      1.1  gdamore 		plen -= mlen;
    406      1.1  gdamore 	}
    407      1.1  gdamore 
    408      1.1  gdamore 	TAILQ_INSERT_TAIL(&link->hl_txq, pdu, lp_next);
    409      1.1  gdamore 	link->hl_txqlen += num;
    410      1.1  gdamore 
    411      1.1  gdamore 	hci_acl_start(link);
    412      1.1  gdamore 
    413      1.1  gdamore 	return 0;
    414      1.1  gdamore 
    415      1.1  gdamore nomem:
    416      1.1  gdamore 	if (m) m_freem(m);
    417      1.1  gdamore 	if (n) m_freem(n);
    418      1.1  gdamore 	if (pdu) {
    419      1.1  gdamore 		MBUFQ_DRAIN(&pdu->lp_data);
    420      1.1  gdamore 		pool_put(&l2cap_pdu_pool, pdu);
    421      1.1  gdamore 	}
    422      1.1  gdamore 
    423      1.1  gdamore 	return ENOMEM;
    424      1.1  gdamore }
    425      1.1  gdamore 
    426      1.1  gdamore /*
    427      1.1  gdamore  * Start sending ACL data on link.
    428      1.1  gdamore  *
    429      1.1  gdamore  *	We may use all the available packet slots. The reason that we add
    430      1.1  gdamore  * the ACL encapsulation here rather than in hci_acl_send() is that L2CAP
    431      1.1  gdamore  * signal packets may be queued before the handle is given to us..
    432      1.1  gdamore  *
    433      1.1  gdamore  * this is called from hci_acl_send() above, and the event processing
    434      1.1  gdamore  * code (for CON_COMPL and NUM_COMPL_PKTS)
    435      1.1  gdamore  */
    436      1.1  gdamore void
    437      1.1  gdamore hci_acl_start(struct hci_link *link)
    438      1.1  gdamore {
    439      1.1  gdamore 	struct hci_unit *unit;
    440      1.1  gdamore 	hci_acldata_hdr_t *hdr;
    441      1.1  gdamore 	struct l2cap_pdu *pdu;
    442      1.1  gdamore 	struct mbuf *m;
    443      1.1  gdamore 	uint16_t handle;
    444      1.1  gdamore 
    445      1.1  gdamore 	KASSERT(link);
    446      1.1  gdamore 
    447      1.1  gdamore 	unit = link->hl_unit;
    448      1.1  gdamore 	KASSERT(unit);
    449      1.1  gdamore 
    450      1.1  gdamore 	/* this is mainly to block ourselves (below) */
    451      1.1  gdamore 	if (link->hl_state != HCI_LINK_OPEN)
    452      1.1  gdamore 		return;
    453      1.1  gdamore 
    454      1.1  gdamore 	if (link->hl_txqlen == 0 || unit->hci_num_acl_pkts == 0)
    455      1.1  gdamore 		return;
    456      1.1  gdamore 
    457      1.1  gdamore 	/* find first PDU with data to send */
    458      1.1  gdamore 	pdu = TAILQ_FIRST(&link->hl_txq);
    459      1.1  gdamore 	for (;;) {
    460      1.1  gdamore 		if (pdu == NULL)
    461      1.1  gdamore 			return;
    462      1.1  gdamore 
    463      1.1  gdamore 		if (MBUFQ_FIRST(&pdu->lp_data) != NULL)
    464      1.1  gdamore 			break;
    465      1.1  gdamore 
    466      1.1  gdamore 		pdu = TAILQ_NEXT(pdu, lp_next);
    467      1.1  gdamore 	}
    468      1.1  gdamore 
    469      1.1  gdamore 	while (unit->hci_num_acl_pkts > 0) {
    470      1.1  gdamore 		MBUFQ_DEQUEUE(&pdu->lp_data, m);
    471      1.1  gdamore 		KASSERT(m != NULL);
    472      1.1  gdamore 
    473      1.1  gdamore 		if (m->m_flags & M_PROTO1)
    474      1.1  gdamore 			handle = HCI_MK_CON_HANDLE(link->hl_handle,
    475      1.1  gdamore 						HCI_PACKET_START, 0);
    476      1.1  gdamore 		else
    477      1.1  gdamore 			handle = HCI_MK_CON_HANDLE(link->hl_handle,
    478      1.1  gdamore 						HCI_PACKET_FRAGMENT, 0);
    479      1.1  gdamore 
    480      1.1  gdamore 		M_PREPEND(m, sizeof(*hdr), M_DONTWAIT);
    481      1.1  gdamore 		if (m == NULL)
    482      1.1  gdamore 			break;
    483      1.1  gdamore 
    484      1.1  gdamore 		hdr = mtod(m, hci_acldata_hdr_t *);
    485      1.1  gdamore 		hdr->type = HCI_ACL_DATA_PKT;
    486      1.1  gdamore 		hdr->con_handle = htole16(handle);
    487      1.1  gdamore 		hdr->length = htole16(m->m_pkthdr.len - sizeof(*hdr));
    488      1.1  gdamore 
    489      1.1  gdamore 		link->hl_txqlen--;
    490      1.1  gdamore 		pdu->lp_pending++;
    491      1.1  gdamore 
    492      1.1  gdamore 		hci_output_acl(unit, m);
    493      1.1  gdamore 
    494      1.1  gdamore 		if (MBUFQ_FIRST(&pdu->lp_data) == NULL) {
    495      1.1  gdamore 			if (pdu->lp_chan) {
    496      1.1  gdamore 				/*
    497      1.1  gdamore 				 * This should enable streaming of PDUs - when
    498      1.1  gdamore 				 * we have placed all the fragments on the acl
    499      1.1  gdamore 				 * output queue, we trigger the L2CAP layer to
    500      1.1  gdamore 				 * send us down one more. Use a false state so
    501      1.1  gdamore 				 * we dont run into ourselves coming back from
    502      1.1  gdamore 				 * the future..
    503      1.1  gdamore 				 */
    504      1.1  gdamore 				link->hl_state = HCI_LINK_BLOCK;
    505      1.1  gdamore 				l2cap_start(pdu->lp_chan);
    506      1.1  gdamore 				link->hl_state = HCI_LINK_OPEN;
    507      1.1  gdamore 			}
    508      1.1  gdamore 
    509      1.1  gdamore 			pdu = TAILQ_NEXT(pdu, lp_next);
    510      1.1  gdamore 			if (pdu == NULL)
    511      1.1  gdamore 				break;
    512      1.1  gdamore 		}
    513      1.1  gdamore 	}
    514      1.1  gdamore 
    515      1.1  gdamore 	/*
    516      1.1  gdamore 	 * We had our turn now, move to the back of the queue to let
    517      1.1  gdamore 	 * other links have a go at the output buffers..
    518      1.1  gdamore 	 */
    519      1.1  gdamore 	if (TAILQ_NEXT(link, hl_next)) {
    520      1.1  gdamore 		TAILQ_REMOVE(&unit->hci_links, link, hl_next);
    521      1.1  gdamore 		TAILQ_INSERT_TAIL(&unit->hci_links, link, hl_next);
    522      1.1  gdamore 	}
    523      1.1  gdamore }
    524      1.1  gdamore 
    525      1.1  gdamore /*
    526      1.1  gdamore  * Confirm ACL packets cleared from Controller buffers. We scan our PDU
    527      1.1  gdamore  * list to clear pending fragments and signal upstream for more data
    528      1.1  gdamore  * when a PDU is complete.
    529      1.1  gdamore  */
    530      1.1  gdamore void
    531      1.1  gdamore hci_acl_complete(struct hci_link *link, int num)
    532      1.1  gdamore {
    533      1.1  gdamore 	struct l2cap_pdu *pdu;
    534      1.1  gdamore 	struct l2cap_channel *chan;
    535      1.1  gdamore 
    536      1.1  gdamore 	DPRINTFN(5, "handle #%d (%d)\n", link->hl_handle, num);
    537      1.1  gdamore 
    538      1.1  gdamore 	while (num > 0) {
    539      1.1  gdamore 		pdu = TAILQ_FIRST(&link->hl_txq);
    540      1.1  gdamore 		if (pdu == NULL) {
    541      1.1  gdamore 			printf("%s: %d packets completed on handle #%x "
    542      1.1  gdamore 				"but none pending!\n",
    543      1.1  gdamore 				link->hl_unit->hci_devname, num,
    544      1.1  gdamore 				link->hl_handle);
    545      1.1  gdamore 			return;
    546      1.1  gdamore 		}
    547      1.1  gdamore 
    548      1.1  gdamore 		if (num >= pdu->lp_pending) {
    549      1.1  gdamore 			num -= pdu->lp_pending;
    550      1.1  gdamore 			pdu->lp_pending = 0;
    551      1.1  gdamore 
    552      1.1  gdamore 			if (MBUFQ_FIRST(&pdu->lp_data) == NULL) {
    553      1.1  gdamore 				TAILQ_REMOVE(&link->hl_txq, pdu, lp_next);
    554      1.1  gdamore 				chan = pdu->lp_chan;
    555      1.1  gdamore 				if (chan != NULL) {
    556      1.1  gdamore 					chan->lc_pending--;
    557      1.1  gdamore 					(*chan->lc_proto->complete)
    558      1.1  gdamore 							(chan->lc_upper, 1);
    559      1.1  gdamore 
    560      1.1  gdamore 					if (chan->lc_pending == 0)
    561      1.1  gdamore 						l2cap_start(chan);
    562      1.1  gdamore 				}
    563      1.1  gdamore 
    564      1.1  gdamore 				pool_put(&l2cap_pdu_pool, pdu);
    565      1.1  gdamore 			}
    566      1.1  gdamore 		} else {
    567      1.1  gdamore 			pdu->lp_pending -= num;
    568      1.1  gdamore 			num = 0;
    569      1.1  gdamore 		}
    570      1.1  gdamore 	}
    571      1.1  gdamore }
    572      1.1  gdamore 
    573      1.1  gdamore /*******************************************************************************
    574      1.1  gdamore  *
    575      1.1  gdamore  *	HCI SCO Connections
    576      1.1  gdamore  */
    577      1.1  gdamore 
    578      1.1  gdamore /*
    579      1.3     tron  * Incoming SCO Connection. We check the list for anybody willing
    580      1.3     tron  * to take it.
    581      1.1  gdamore  */
    582      1.1  gdamore struct hci_link *
    583      1.1  gdamore hci_sco_newconn(struct hci_unit *unit, bdaddr_t *bdaddr)
    584      1.1  gdamore {
    585      1.3     tron 	struct sockaddr_bt laddr, raddr;
    586      1.3     tron 	struct sco_pcb *pcb, *new;
    587      1.3     tron 	struct hci_link *sco, *acl;
    588      1.3     tron 
    589      1.3     tron 	memset(&laddr, 0, sizeof(laddr));
    590      1.3     tron 	laddr.bt_len = sizeof(laddr);
    591      1.3     tron 	laddr.bt_family = AF_BLUETOOTH;
    592      1.3     tron 	bdaddr_copy(&laddr.bt_bdaddr, &unit->hci_bdaddr);
    593      1.3     tron 
    594      1.3     tron 	memset(&raddr, 0, sizeof(raddr));
    595      1.3     tron 	raddr.bt_len = sizeof(raddr);
    596      1.3     tron 	raddr.bt_family = AF_BLUETOOTH;
    597      1.3     tron 	bdaddr_copy(&raddr.bt_bdaddr, bdaddr);
    598      1.3     tron 
    599      1.3     tron 	/*
    600      1.3     tron 	 * There should already be an ACL link up and running before
    601      1.3     tron 	 * the controller sends us SCO connection requests, but you
    602      1.3     tron 	 * never know..
    603      1.3     tron 	 */
    604      1.3     tron 	acl = hci_link_lookup_bdaddr(unit, bdaddr, HCI_LINK_ACL);
    605      1.3     tron 	if (acl == NULL || acl->hl_state != HCI_LINK_OPEN)
    606      1.3     tron 		return NULL;
    607      1.3     tron 
    608      1.3     tron 	LIST_FOREACH(pcb, &sco_pcb, sp_next) {
    609      1.3     tron 		if ((pcb->sp_flags & SP_LISTENING) == 0)
    610      1.3     tron 			continue;
    611      1.3     tron 
    612      1.3     tron 		new = (*pcb->sp_proto->newconn)(pcb->sp_upper, &laddr, &raddr);
    613      1.3     tron 		if (new == NULL)
    614      1.3     tron 			continue;
    615      1.3     tron 
    616      1.3     tron 		/*
    617      1.3     tron 		 * Ok, got new pcb so we can start a new link and fill
    618      1.3     tron 		 * in all the details.
    619      1.3     tron 		 */
    620      1.3     tron 		bdaddr_copy(&new->sp_laddr, &unit->hci_bdaddr);
    621      1.3     tron 		bdaddr_copy(&new->sp_raddr, bdaddr);
    622      1.3     tron 
    623      1.3     tron 		sco = hci_link_alloc(unit);
    624      1.3     tron 		if (sco == NULL) {
    625      1.3     tron 			sco_detach(&new);
    626      1.3     tron 			return NULL;
    627      1.3     tron 		}
    628      1.3     tron 
    629      1.3     tron 		sco->hl_type = HCI_LINK_SCO;
    630      1.3     tron 		bdaddr_copy(&sco->hl_bdaddr, bdaddr);
    631      1.3     tron 
    632      1.3     tron 		sco->hl_link = hci_acl_open(unit, bdaddr);
    633      1.3     tron 		KASSERT(sco->hl_link == acl);
    634      1.3     tron 
    635      1.3     tron 		sco->hl_sco = new;
    636      1.3     tron 		new->sp_link = sco;
    637      1.3     tron 
    638      1.3     tron 		new->sp_mtu = unit->hci_max_sco_size;
    639      1.3     tron 		return sco;
    640      1.3     tron 	}
    641      1.1  gdamore 
    642      1.1  gdamore 	return NULL;
    643      1.1  gdamore }
    644      1.1  gdamore 
    645      1.1  gdamore /*
    646      1.1  gdamore  * receive SCO packet, we only need to strip the header and send
    647      1.1  gdamore  * it to the right handler
    648      1.1  gdamore  */
    649      1.1  gdamore void
    650      1.1  gdamore hci_sco_recv(struct mbuf *m, struct hci_unit *unit)
    651      1.1  gdamore {
    652      1.1  gdamore 	struct hci_link *link;
    653      1.1  gdamore 	hci_scodata_hdr_t hdr;
    654      1.1  gdamore 	uint16_t handle;
    655      1.1  gdamore 
    656      1.1  gdamore 	KASSERT(m);
    657      1.1  gdamore 	KASSERT(unit);
    658      1.1  gdamore 
    659      1.1  gdamore 	KASSERT(m->m_pkthdr.len >= sizeof(hdr));
    660      1.1  gdamore 	m_copydata(m, 0, sizeof(hdr), &hdr);
    661      1.1  gdamore 	m_adj(m, sizeof(hdr));
    662      1.1  gdamore 
    663      1.1  gdamore #ifdef DIAGNOSTIC
    664      1.1  gdamore 	if (hdr.type != HCI_SCO_DATA_PKT) {
    665      1.1  gdamore 		printf("%s: bad SCO packet type\n", unit->hci_devname);
    666      1.1  gdamore 		goto bad;
    667      1.1  gdamore 	}
    668      1.1  gdamore 
    669      1.1  gdamore 	if (m->m_pkthdr.len != hdr.length) {
    670      1.1  gdamore 		printf("%s: bad SCO packet length (%d != %d)\n", unit->hci_devname, m->m_pkthdr.len, hdr.length);
    671      1.1  gdamore 		goto bad;
    672      1.1  gdamore 	}
    673      1.1  gdamore #endif
    674      1.1  gdamore 
    675      1.1  gdamore 	hdr.con_handle = le16toh(hdr.con_handle);
    676      1.1  gdamore 	handle = HCI_CON_HANDLE(hdr.con_handle);
    677      1.1  gdamore 
    678      1.1  gdamore 	link = hci_link_lookup_handle(unit, handle);
    679      1.1  gdamore 	if (link == NULL || link->hl_type == HCI_LINK_ACL) {
    680      1.1  gdamore 		DPRINTF("%s: dumping packet for unknown handle #%d\n",
    681      1.1  gdamore 			unit->hci_devname, handle);
    682      1.1  gdamore 
    683      1.1  gdamore 		goto bad;
    684      1.1  gdamore 	}
    685      1.1  gdamore 
    686      1.1  gdamore 	(*link->hl_sco->sp_proto->input)(link->hl_sco->sp_upper, m);
    687      1.1  gdamore 	return;
    688      1.1  gdamore 
    689      1.1  gdamore bad:
    690      1.1  gdamore 	m_freem(m);
    691      1.1  gdamore }
    692      1.1  gdamore 
    693      1.1  gdamore void
    694  1.5.2.1     yamt hci_sco_start(struct hci_link *link __unused)
    695      1.1  gdamore {
    696      1.1  gdamore }
    697      1.1  gdamore 
    698      1.1  gdamore /*
    699      1.1  gdamore  * SCO packets have completed at the controller, so we can
    700      1.1  gdamore  * signal up to free the buffer space.
    701      1.1  gdamore  */
    702      1.1  gdamore void
    703      1.1  gdamore hci_sco_complete(struct hci_link *link, int num)
    704      1.1  gdamore {
    705      1.1  gdamore 
    706      1.1  gdamore 	DPRINTFN(5, "handle #%d (num=%d)\n", link->hl_handle, num);
    707      1.1  gdamore 	link->hl_sco->sp_pending--;
    708      1.1  gdamore 	(*link->hl_sco->sp_proto->complete)(link->hl_sco->sp_upper, num);
    709      1.1  gdamore }
    710      1.1  gdamore 
    711      1.1  gdamore /*******************************************************************************
    712      1.1  gdamore  *
    713      1.1  gdamore  *	Generic HCI Connection alloc/free/lookup etc
    714      1.1  gdamore  */
    715      1.1  gdamore 
    716      1.1  gdamore struct hci_link *
    717      1.1  gdamore hci_link_alloc(struct hci_unit *unit)
    718      1.1  gdamore {
    719      1.1  gdamore 	struct hci_link *link;
    720      1.1  gdamore 
    721      1.1  gdamore 	KASSERT(unit);
    722      1.1  gdamore 
    723      1.1  gdamore 	link = malloc(sizeof(struct hci_link), M_BLUETOOTH, M_NOWAIT | M_ZERO);
    724      1.1  gdamore 	if (link == NULL)
    725      1.1  gdamore 		return NULL;
    726      1.1  gdamore 
    727      1.1  gdamore 	link->hl_unit = unit;
    728      1.1  gdamore 	link->hl_state = HCI_LINK_CLOSED;
    729      1.1  gdamore 
    730      1.1  gdamore 	/* init ACL portion */
    731      1.1  gdamore 	callout_init(&link->hl_expire);
    732      1.1  gdamore 	callout_setfunc(&link->hl_expire, hci_acl_timeout, link);
    733      1.1  gdamore 
    734      1.1  gdamore 	TAILQ_INIT(&link->hl_txq);	/* outgoing packets */
    735      1.1  gdamore 	TAILQ_INIT(&link->hl_reqs);	/* request queue */
    736      1.1  gdamore 
    737      1.1  gdamore 	link->hl_mtu = L2CAP_MTU_DEFAULT;		/* L2CAP signal mtu */
    738      1.1  gdamore 	link->hl_flush = L2CAP_FLUSH_TIMO_DEFAULT;	/* flush timeout */
    739      1.1  gdamore 
    740      1.1  gdamore 	/* init SCO portion */
    741      1.1  gdamore 	MBUFQ_INIT(&link->hl_data);
    742      1.1  gdamore 
    743      1.1  gdamore 	/* attach to unit */
    744      1.1  gdamore 	TAILQ_INSERT_HEAD(&unit->hci_links, link, hl_next);
    745      1.1  gdamore 	return link;
    746      1.1  gdamore }
    747      1.1  gdamore 
    748      1.1  gdamore void
    749      1.1  gdamore hci_link_free(struct hci_link *link, int err)
    750      1.1  gdamore {
    751      1.1  gdamore 	struct l2cap_req *req;
    752      1.1  gdamore 	struct l2cap_pdu *pdu;
    753      1.4   plunky 	struct l2cap_channel *chan, *next;
    754      1.1  gdamore 
    755      1.1  gdamore 	KASSERT(link);
    756      1.1  gdamore 
    757      1.1  gdamore 	DPRINTF("#%d, type = %d, state = %d, refcnt = %d\n",
    758      1.1  gdamore 		link->hl_handle, link->hl_type,
    759      1.1  gdamore 		link->hl_state, link->hl_refcnt);
    760      1.1  gdamore 
    761      1.1  gdamore 	/* ACL reference count */
    762      1.1  gdamore 	if (link->hl_refcnt > 0) {
    763      1.4   plunky 		next = LIST_FIRST(&l2cap_active_list);
    764      1.4   plunky 		while ((chan = next) != NULL) {
    765      1.4   plunky 			next = LIST_NEXT(chan, lc_ncid);
    766      1.1  gdamore 			if (chan->lc_link == link)
    767      1.1  gdamore 				l2cap_close(chan, err);
    768      1.1  gdamore 		}
    769      1.1  gdamore 	}
    770      1.1  gdamore 	KASSERT(link->hl_refcnt == 0);
    771      1.1  gdamore 
    772      1.1  gdamore 	/* ACL L2CAP requests.. */
    773      1.1  gdamore 	while ((req = TAILQ_FIRST(&link->hl_reqs)) != NULL)
    774      1.1  gdamore 		l2cap_request_free(req);
    775      1.1  gdamore 
    776      1.1  gdamore 	KASSERT(TAILQ_EMPTY(&link->hl_reqs));
    777      1.1  gdamore 
    778      1.1  gdamore 	/* ACL outgoing data queue */
    779      1.1  gdamore 	while ((pdu = TAILQ_FIRST(&link->hl_txq)) != NULL) {
    780      1.1  gdamore 		TAILQ_REMOVE(&link->hl_txq, pdu, lp_next);
    781      1.1  gdamore 		MBUFQ_DRAIN(&pdu->lp_data);
    782      1.1  gdamore 		if (pdu->lp_pending)
    783      1.1  gdamore 			link->hl_unit->hci_num_acl_pkts += pdu->lp_pending;
    784      1.1  gdamore 
    785      1.1  gdamore 		pool_put(&l2cap_pdu_pool, pdu);
    786      1.1  gdamore 	}
    787      1.1  gdamore 
    788      1.1  gdamore 	KASSERT(TAILQ_EMPTY(&link->hl_txq));
    789      1.1  gdamore 
    790      1.1  gdamore 	/* ACL incoming data packet */
    791      1.1  gdamore 	if (link->hl_rxp != NULL) {
    792      1.1  gdamore 		m_freem(link->hl_rxp);
    793      1.1  gdamore 		link->hl_rxp = NULL;
    794      1.1  gdamore 	}
    795      1.1  gdamore 
    796      1.1  gdamore 	/* SCO master ACL link */
    797      1.1  gdamore 	if (link->hl_link != NULL) {
    798      1.1  gdamore 		hci_acl_close(link->hl_link, err);
    799      1.1  gdamore 		link->hl_link = NULL;
    800      1.1  gdamore 	}
    801      1.1  gdamore 
    802      1.1  gdamore 	/* SCO pcb */
    803      1.1  gdamore 	if (link->hl_sco != NULL) {
    804      1.1  gdamore 		struct sco_pcb *pcb;
    805      1.1  gdamore 
    806      1.1  gdamore 		pcb = link->hl_sco;
    807      1.1  gdamore 		pcb->sp_link = NULL;
    808      1.1  gdamore 		link->hl_sco = NULL;
    809      1.1  gdamore 		(*pcb->sp_proto->disconnected)(pcb->sp_upper, err);
    810      1.1  gdamore 	}
    811      1.1  gdamore 
    812      1.1  gdamore 	/* flush any SCO data */
    813      1.1  gdamore 	MBUFQ_DRAIN(&link->hl_data);
    814      1.1  gdamore 
    815      1.1  gdamore 	/*
    816      1.1  gdamore 	 * Halt the callout - if its already running we cannot free the
    817      1.1  gdamore 	 * link structure but the timeout function will call us back in
    818      1.1  gdamore 	 * any case.
    819      1.1  gdamore 	 */
    820      1.1  gdamore 	link->hl_state = HCI_LINK_CLOSED;
    821      1.1  gdamore 	callout_stop(&link->hl_expire);
    822      1.1  gdamore 	if (callout_invoking(&link->hl_expire))
    823      1.1  gdamore 		return;
    824      1.1  gdamore 
    825      1.1  gdamore 	TAILQ_REMOVE(&link->hl_unit->hci_links, link, hl_next);
    826      1.1  gdamore 	free(link, M_BLUETOOTH);
    827      1.1  gdamore }
    828      1.1  gdamore 
    829      1.1  gdamore /*
    830      1.1  gdamore  * Lookup HCI link by address and type. Note that for SCO links there may
    831      1.1  gdamore  * be more than one link per address, so we only return links with no
    832      1.1  gdamore  * handle (ie new links)
    833      1.1  gdamore  */
    834      1.1  gdamore struct hci_link *
    835      1.1  gdamore hci_link_lookup_bdaddr(struct hci_unit *unit, bdaddr_t *bdaddr, uint16_t type)
    836      1.1  gdamore {
    837      1.1  gdamore 	struct hci_link *link;
    838      1.1  gdamore 
    839      1.1  gdamore 	KASSERT(unit);
    840      1.1  gdamore 	KASSERT(bdaddr);
    841      1.1  gdamore 
    842      1.1  gdamore 	TAILQ_FOREACH(link, &unit->hci_links, hl_next) {
    843      1.1  gdamore 		if (link->hl_type != type)
    844      1.1  gdamore 			continue;
    845      1.1  gdamore 
    846      1.1  gdamore 		if (type == HCI_LINK_SCO && link->hl_handle != 0)
    847      1.1  gdamore 			continue;
    848      1.1  gdamore 
    849      1.1  gdamore 		if (bdaddr_same(&link->hl_bdaddr, bdaddr))
    850      1.1  gdamore 			break;
    851      1.1  gdamore 	}
    852      1.1  gdamore 
    853      1.1  gdamore 	return link;
    854      1.1  gdamore }
    855      1.1  gdamore 
    856      1.1  gdamore struct hci_link *
    857      1.1  gdamore hci_link_lookup_handle(struct hci_unit *unit, uint16_t handle)
    858      1.1  gdamore {
    859      1.1  gdamore 	struct hci_link *link;
    860      1.1  gdamore 
    861      1.1  gdamore 	KASSERT(unit);
    862      1.1  gdamore 
    863      1.1  gdamore 	TAILQ_FOREACH(link, &unit->hci_links, hl_next) {
    864      1.1  gdamore 		if (handle == link->hl_handle)
    865      1.1  gdamore 			break;
    866      1.1  gdamore 	}
    867      1.1  gdamore 
    868      1.1  gdamore 	return link;
    869      1.1  gdamore }
    870