Home | History | Annotate | Line # | Download | only in sdmmc
sbt.c revision 1.6.2.1
      1  1.6.2.1  christos /*	$NetBSD: sbt.c,v 1.6.2.1 2019/06/10 22:07:32 christos Exp $	*/
      2      1.1    nonaka /*	$OpenBSD: sbt.c,v 1.9 2007/06/19 07:59:57 uwe Exp $	*/
      3      1.1    nonaka 
      4      1.1    nonaka /*
      5      1.1    nonaka  * Copyright (c) 2007 Uwe Stuehler <uwe (at) openbsd.org>
      6      1.1    nonaka  *
      7      1.1    nonaka  * Permission to use, copy, modify, and distribute this software for any
      8      1.1    nonaka  * purpose with or without fee is hereby granted, provided that the above
      9      1.1    nonaka  * copyright notice and this permission notice appear in all copies.
     10      1.1    nonaka  *
     11      1.1    nonaka  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
     12      1.1    nonaka  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     13      1.1    nonaka  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     14      1.1    nonaka  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     15      1.1    nonaka  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
     16      1.1    nonaka  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
     17      1.1    nonaka  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     18      1.1    nonaka  */
     19      1.1    nonaka 
     20      1.1    nonaka /* Driver for Type-A/B SDIO Bluetooth cards */
     21      1.1    nonaka 
     22      1.1    nonaka #include <sys/cdefs.h>
     23  1.6.2.1  christos __KERNEL_RCSID(0, "$NetBSD: sbt.c,v 1.6.2.1 2019/06/10 22:07:32 christos Exp $");
     24      1.1    nonaka 
     25      1.1    nonaka #include <sys/param.h>
     26      1.1    nonaka #include <sys/device.h>
     27      1.1    nonaka #include <sys/malloc.h>
     28      1.1    nonaka #include <sys/mbuf.h>
     29      1.1    nonaka #include <sys/proc.h>
     30      1.1    nonaka #include <sys/queue.h>
     31      1.1    nonaka #include <sys/socket.h>
     32      1.1    nonaka #include <sys/systm.h>
     33      1.1    nonaka 
     34      1.1    nonaka #include <netbt/hci.h>
     35      1.1    nonaka 
     36      1.1    nonaka #include <dev/sdmmc/sdmmcdevs.h>
     37      1.1    nonaka #include <dev/sdmmc/sdmmcvar.h>
     38      1.1    nonaka 
     39      1.1    nonaka #define CSR_READ_1(sc, reg)       sdmmc_io_read_1((sc)->sc_sf, (reg))
     40      1.1    nonaka #define CSR_WRITE_1(sc, reg, val) sdmmc_io_write_1((sc)->sc_sf, (reg), (val))
     41      1.1    nonaka 
     42      1.1    nonaka #define SBT_REG_DAT	0x00		/* receiver/transmitter data */
     43      1.1    nonaka #define SBT_REG_RPC	0x10		/* read packet control */
     44      1.1    nonaka #define  RPC_PCRRT	(1<<0)		/* packet read retry */
     45      1.1    nonaka #define SBT_REG_WPC	0x11		/* write packet control */
     46      1.1    nonaka #define  WPC_PCWRT	(1<<0)		/* packet write retry */
     47      1.1    nonaka #define SBT_REG_RC	0x12		/* retry control status/set */
     48      1.1    nonaka #define SBT_REG_ISTAT	0x13		/* interrupt status */
     49      1.1    nonaka #define  ISTAT_INTRD	(1<<0)		/* packet available for read */
     50      1.1    nonaka #define SBT_REG_ICLR	0x13		/* interrupt clear */
     51      1.1    nonaka #define SBT_REG_IENA	0x14		/* interrupt enable */
     52      1.1    nonaka #define SBT_REG_BTMODE	0x20		/* SDIO Bluetooth card mode */
     53      1.1    nonaka #define  BTMODE_TYPEB	(1<<0)		/* 1=Type-B, 0=Type-A */
     54      1.1    nonaka 
     55      1.1    nonaka #define SBT_PKT_BUFSIZ	65540
     56      1.1    nonaka #define SBT_RXTRY_MAX	5
     57      1.1    nonaka 
     58      1.1    nonaka struct sbt_softc {
     59      1.1    nonaka 	device_t sc_dev;		/* base device */
     60      1.1    nonaka 	int sc_flags;
     61      1.1    nonaka 	struct hci_unit *sc_unit;	/* Bluetooth HCI Unit */
     62      1.1    nonaka 	struct bt_stats sc_stats;
     63      1.1    nonaka 	struct sdmmc_function *sc_sf;	/* SDIO function */
     64      1.1    nonaka 	int sc_dying;			/* shutdown in progress */
     65      1.1    nonaka 	void *sc_ih;
     66      1.1    nonaka 	u_char *sc_buf;
     67      1.1    nonaka 	int sc_rxtry;
     68      1.1    nonaka 
     69      1.1    nonaka 	/* transmit queues */
     70      1.1    nonaka 	MBUFQ_HEAD() sc_cmdq;
     71      1.1    nonaka 	MBUFQ_HEAD() sc_aclq;
     72      1.1    nonaka 	MBUFQ_HEAD() sc_scoq;
     73      1.1    nonaka };
     74      1.1    nonaka 
     75      1.1    nonaka /* sc_flags */
     76      1.1    nonaka #define SBT_XMIT	(1 << 0)	/* transmit is active */
     77      1.1    nonaka #define SBT_ENABLED	(1 << 1)	/* device is enabled */
     78      1.1    nonaka 
     79      1.2    cegger static int	sbt_match(device_t, cfdata_t, void *);
     80      1.1    nonaka static void	sbt_attach(device_t, device_t, void *);
     81      1.1    nonaka static int	sbt_detach(device_t, int);
     82      1.1    nonaka 
     83      1.1    nonaka CFATTACH_DECL_NEW(sbt, sizeof(struct sbt_softc),
     84      1.1    nonaka     sbt_match, sbt_attach, sbt_detach, NULL);
     85      1.1    nonaka 
     86      1.1    nonaka static int	sbt_write_packet(struct sbt_softc *, u_char *, size_t);
     87      1.1    nonaka static int	sbt_read_packet(struct sbt_softc *, u_char *, size_t *);
     88      1.1    nonaka static void	sbt_start(struct sbt_softc *);
     89      1.1    nonaka 
     90      1.1    nonaka static int	sbt_intr(void *);
     91      1.1    nonaka 
     92      1.1    nonaka static int	sbt_enable(device_t);
     93      1.1    nonaka static void	sbt_disable(device_t);
     94      1.1    nonaka static void	sbt_start_cmd(device_t, struct mbuf *);
     95      1.1    nonaka static void	sbt_start_acl(device_t, struct mbuf *);
     96      1.1    nonaka static void	sbt_start_sco(device_t, struct mbuf *);
     97      1.1    nonaka static void	sbt_stats(device_t, struct bt_stats *, int);
     98      1.1    nonaka 
     99      1.1    nonaka #undef DPRINTF	/* avoid redefine by bluetooth.h */
    100      1.1    nonaka #ifdef SBT_DEBUG
    101      1.1    nonaka int sbt_debug = 1;
    102      1.1    nonaka #define DPRINTF(s)	printf s
    103      1.1    nonaka #define DNPRINTF(n, s)	do { if ((n) <= sbt_debug) printf s; } while (0)
    104      1.1    nonaka #else
    105      1.1    nonaka #define DPRINTF(s)	do {} while (0)
    106      1.1    nonaka #define DNPRINTF(n, s)	do {} while (0)
    107      1.1    nonaka #endif
    108      1.1    nonaka 
    109      1.1    nonaka #define DEVNAME(sc)	device_xname((sc)->sc_dev)
    110      1.1    nonaka 
    111      1.1    nonaka 
    112      1.1    nonaka /*
    113      1.1    nonaka  * Autoconf glue
    114      1.1    nonaka  */
    115      1.1    nonaka 
    116      1.1    nonaka static const struct sbt_product {
    117      1.1    nonaka 	uint16_t	sp_vendor;
    118      1.1    nonaka 	uint16_t	sp_product;
    119      1.1    nonaka 	const char	*sp_cisinfo[4];
    120      1.1    nonaka } sbt_products[] = {
    121      1.1    nonaka 	{
    122      1.1    nonaka 		SDMMC_VENDOR_SOCKETCOM,
    123      1.1    nonaka 		SDMMC_PRODUCT_SOCKETCOM_BTCARD,
    124      1.1    nonaka 		SDMMC_CIS_SOCKETCOM_BTCARD
    125      1.1    nonaka 	},
    126      1.1    nonaka };
    127      1.1    nonaka 
    128      1.1    nonaka static const struct hci_if sbt_hci = {
    129      1.1    nonaka 	.enable = sbt_enable,
    130      1.1    nonaka 	.disable = sbt_disable,
    131      1.1    nonaka 	.output_cmd = sbt_start_cmd,
    132      1.1    nonaka 	.output_acl = sbt_start_acl,
    133      1.1    nonaka 	.output_sco = sbt_start_sco,
    134      1.1    nonaka 	.get_stats = sbt_stats,
    135      1.1    nonaka 	.ipl = IPL_TTY,			/* XXX */
    136      1.1    nonaka };
    137      1.1    nonaka 
    138      1.1    nonaka 
    139      1.1    nonaka static int
    140      1.2    cegger sbt_match(device_t parent, cfdata_t match, void *aux)
    141      1.1    nonaka {
    142      1.1    nonaka 	struct sdmmc_attach_args *sa = aux;
    143      1.1    nonaka 	const struct sbt_product *sp;
    144      1.1    nonaka 	struct sdmmc_function *sf;
    145      1.1    nonaka 	int i;
    146      1.1    nonaka 
    147      1.1    nonaka 	if (sa->sf == NULL)
    148      1.1    nonaka 		return 0;	/* not SDIO */
    149      1.1    nonaka 
    150      1.1    nonaka 	sf = sa->sf->sc->sc_fn0;
    151      1.1    nonaka 	sp = &sbt_products[0];
    152      1.1    nonaka 
    153      1.1    nonaka 	for (i = 0; i < sizeof(sbt_products) / sizeof(sbt_products[0]);
    154      1.1    nonaka 	     i++, sp = &sbt_products[i])
    155      1.1    nonaka 		if (sp->sp_vendor == sf->cis.manufacturer &&
    156      1.1    nonaka 		    sp->sp_product == sf->cis.product)
    157      1.1    nonaka 			return 1;
    158      1.1    nonaka 	return 0;
    159      1.1    nonaka }
    160      1.1    nonaka 
    161      1.1    nonaka static void
    162      1.1    nonaka sbt_attach(device_t parent, device_t self, void *aux)
    163      1.1    nonaka {
    164      1.1    nonaka 	struct sbt_softc *sc = device_private(self);
    165      1.1    nonaka 	struct sdmmc_attach_args *sa = aux;
    166      1.1    nonaka 
    167      1.1    nonaka 	aprint_normal("\n");
    168      1.1    nonaka 	aprint_naive("\n");
    169      1.1    nonaka 
    170      1.1    nonaka 	sc->sc_dev = self;
    171      1.1    nonaka 	sc->sc_sf = sa->sf;
    172      1.1    nonaka 	MBUFQ_INIT(&sc->sc_cmdq);
    173      1.1    nonaka 	MBUFQ_INIT(&sc->sc_aclq);
    174      1.1    nonaka 	MBUFQ_INIT(&sc->sc_scoq);
    175      1.1    nonaka 
    176      1.1    nonaka 	(void)sdmmc_io_function_disable(sc->sc_sf);
    177      1.1    nonaka 	if (sdmmc_io_function_enable(sc->sc_sf)) {
    178      1.5   msaitoh 		aprint_error("%s: function not ready\n", DEVNAME(sc));
    179      1.1    nonaka 		return;
    180      1.1    nonaka 	}
    181      1.1    nonaka 
    182      1.1    nonaka 	/* It may be Type-B, but we use it only in Type-A mode. */
    183      1.1    nonaka 	printf("%s: SDIO Bluetooth Type-A\n", DEVNAME(sc));
    184      1.1    nonaka 
    185  1.6.2.1  christos 	sc->sc_buf = malloc(SBT_PKT_BUFSIZ, M_DEVBUF, M_NOWAIT);
    186      1.1    nonaka 	if (sc->sc_buf == NULL) {
    187      1.5   msaitoh 		aprint_error("%s: can't allocate cmd buffer\n", DEVNAME(sc));
    188      1.1    nonaka 		return;
    189      1.1    nonaka 	}
    190      1.1    nonaka 
    191      1.1    nonaka 	/* Enable the HCI packet transport read interrupt. */
    192      1.1    nonaka 	CSR_WRITE_1(sc, SBT_REG_IENA, ISTAT_INTRD);
    193      1.1    nonaka 
    194      1.1    nonaka 	/* Enable the card interrupt for this function. */
    195      1.1    nonaka 	sc->sc_ih = sdmmc_intr_establish(parent, sbt_intr, sc, DEVNAME(sc));
    196      1.1    nonaka 	if (sc->sc_ih == NULL) {
    197      1.5   msaitoh 		aprint_error("%s: can't establish interrupt\n", DEVNAME(sc));
    198      1.1    nonaka 		return;
    199      1.1    nonaka 	}
    200      1.1    nonaka 	sdmmc_intr_enable(sc->sc_sf);
    201      1.1    nonaka 
    202      1.1    nonaka 	/*
    203      1.1    nonaka 	 * Attach Bluetooth unit (machine-independent HCI).
    204      1.1    nonaka 	 */
    205      1.4     rmind 	sc->sc_unit = hci_attach_pcb(&sbt_hci, self, 0);
    206      1.1    nonaka }
    207      1.1    nonaka 
    208      1.1    nonaka static int
    209      1.1    nonaka sbt_detach(device_t self, int flags)
    210      1.1    nonaka {
    211      1.3       chs 	struct sbt_softc *sc = device_private(self);
    212      1.1    nonaka 
    213      1.1    nonaka 	sc->sc_dying = 1;
    214      1.1    nonaka 
    215      1.1    nonaka 	if (sc->sc_unit) {
    216      1.4     rmind 		hci_detach_pcb(sc->sc_unit);
    217      1.1    nonaka 		sc->sc_unit = NULL;
    218      1.1    nonaka 	}
    219      1.1    nonaka 
    220      1.1    nonaka 	if (sc->sc_ih != NULL)
    221      1.1    nonaka 		sdmmc_intr_disestablish(sc->sc_ih);
    222      1.1    nonaka 
    223      1.1    nonaka 	return 0;
    224      1.1    nonaka }
    225      1.1    nonaka 
    226      1.1    nonaka 
    227      1.1    nonaka /*
    228      1.1    nonaka  * Bluetooth HCI packet transport
    229      1.1    nonaka  */
    230      1.1    nonaka 
    231      1.1    nonaka static int
    232      1.1    nonaka sbt_write_packet(struct sbt_softc *sc, u_char *buf, size_t len)
    233      1.1    nonaka {
    234      1.1    nonaka 	u_char hdr[3];
    235      1.1    nonaka 	size_t pktlen;
    236      1.1    nonaka 	int error = EIO;
    237      1.1    nonaka 	int retry = 3;
    238      1.1    nonaka 
    239      1.1    nonaka again:
    240      1.1    nonaka 	if (retry-- == 0) {
    241      1.1    nonaka 		DPRINTF(("%s: sbt_write_cmd: giving up\n", DEVNAME(sc)));
    242      1.1    nonaka 		return error;
    243      1.1    nonaka 	}
    244      1.1    nonaka 
    245      1.1    nonaka 	/* Restart the current packet. */
    246      1.1    nonaka 	sdmmc_io_write_1(sc->sc_sf, SBT_REG_WPC, WPC_PCWRT);
    247      1.1    nonaka 
    248      1.1    nonaka 	/* Write the packet length. */
    249      1.1    nonaka 	pktlen = len + 3;
    250      1.1    nonaka 	hdr[0] = pktlen & 0xff;
    251      1.1    nonaka 	hdr[1] = (pktlen >> 8) & 0xff;
    252      1.1    nonaka 	hdr[2] = (pktlen >> 16) & 0xff;
    253      1.1    nonaka 	error = sdmmc_io_write_multi_1(sc->sc_sf, SBT_REG_DAT, hdr, 3);
    254      1.1    nonaka 	if (error) {
    255      1.1    nonaka 		DPRINTF(("%s: sbt_write_packet: failed to send length\n",
    256      1.1    nonaka 		    DEVNAME(sc)));
    257      1.1    nonaka 		goto again;
    258      1.1    nonaka 	}
    259      1.1    nonaka 
    260      1.1    nonaka 	error = sdmmc_io_write_multi_1(sc->sc_sf, SBT_REG_DAT, buf, len);
    261      1.1    nonaka 	if (error) {
    262      1.1    nonaka 		DPRINTF(("%s: sbt_write_packet: failed to send packet data\n",
    263      1.1    nonaka 		    DEVNAME(sc)));
    264      1.1    nonaka 		goto again;
    265      1.1    nonaka 	}
    266      1.1    nonaka 	return 0;
    267      1.1    nonaka }
    268      1.1    nonaka 
    269      1.1    nonaka static int
    270      1.1    nonaka sbt_read_packet(struct sbt_softc *sc, u_char *buf, size_t *lenp)
    271      1.1    nonaka {
    272      1.1    nonaka 	u_char hdr[3];
    273      1.1    nonaka 	size_t len;
    274      1.1    nonaka 	int error;
    275      1.1    nonaka 
    276      1.1    nonaka 	error = sdmmc_io_read_multi_1(sc->sc_sf, SBT_REG_DAT, hdr, 3);
    277      1.1    nonaka 	if (error) {
    278      1.1    nonaka 		DPRINTF(("%s: sbt_read_packet: failed to read length\n",
    279      1.1    nonaka 		    DEVNAME(sc)));
    280      1.1    nonaka 		goto out;
    281      1.1    nonaka 	}
    282      1.1    nonaka 	len = (hdr[0] | (hdr[1] << 8) | (hdr[2] << 16)) - 3;
    283      1.1    nonaka 	if (len > *lenp) {
    284      1.1    nonaka 		DPRINTF(("%s: sbt_read_packet: len %u > %u\n",
    285      1.1    nonaka 		    DEVNAME(sc), len, *lenp));
    286      1.1    nonaka 		error = ENOBUFS;
    287      1.1    nonaka 		goto out;
    288      1.1    nonaka 	}
    289      1.1    nonaka 
    290      1.1    nonaka 	DNPRINTF(2,("%s: sbt_read_packet: reading len %u bytes\n",
    291      1.1    nonaka 	    DEVNAME(sc), len));
    292      1.1    nonaka 	error = sdmmc_io_read_multi_1(sc->sc_sf, SBT_REG_DAT, buf, len);
    293      1.1    nonaka 	if (error) {
    294      1.1    nonaka 		DPRINTF(("%s: sbt_read_packet: failed to read packet data\n",
    295      1.1    nonaka 		    DEVNAME(sc)));
    296      1.1    nonaka 		goto out;
    297      1.1    nonaka 	}
    298      1.1    nonaka 
    299      1.1    nonaka out:
    300      1.1    nonaka 	if (error) {
    301      1.1    nonaka 		if (sc->sc_rxtry >= SBT_RXTRY_MAX) {
    302      1.1    nonaka 			/* Drop and request the next packet. */
    303      1.1    nonaka 			sc->sc_rxtry = 0;
    304      1.1    nonaka 			CSR_WRITE_1(sc, SBT_REG_RPC, 0);
    305      1.1    nonaka 		} else {
    306      1.1    nonaka 			/* Request the current packet again. */
    307      1.1    nonaka 			sc->sc_rxtry++;
    308      1.1    nonaka 			CSR_WRITE_1(sc, SBT_REG_RPC, RPC_PCRRT);
    309      1.1    nonaka 		}
    310      1.1    nonaka 		return error;
    311      1.1    nonaka 	}
    312      1.1    nonaka 
    313      1.1    nonaka 	/* acknowledge read packet */
    314      1.1    nonaka 	CSR_WRITE_1(sc, SBT_REG_RPC, 0);
    315      1.1    nonaka 
    316      1.1    nonaka 	*lenp = len;
    317      1.1    nonaka 	return 0;
    318      1.1    nonaka }
    319      1.1    nonaka 
    320      1.1    nonaka /*
    321      1.1    nonaka  * Interrupt handling
    322      1.1    nonaka  */
    323      1.1    nonaka 
    324      1.1    nonaka static int
    325      1.1    nonaka sbt_intr(void *arg)
    326      1.1    nonaka {
    327      1.1    nonaka 	struct sbt_softc *sc = arg;
    328      1.1    nonaka 	struct mbuf *m = NULL;
    329      1.1    nonaka 	u_int8_t status;
    330      1.1    nonaka 	size_t len;
    331      1.1    nonaka 	int s;
    332      1.1    nonaka 
    333      1.1    nonaka 	s = splsdmmc();
    334      1.1    nonaka 
    335      1.1    nonaka 	status = CSR_READ_1(sc, SBT_REG_ISTAT);
    336      1.1    nonaka 	CSR_WRITE_1(sc, SBT_REG_ICLR, status);
    337      1.1    nonaka 
    338      1.1    nonaka 	if ((status & ISTAT_INTRD) == 0)
    339      1.1    nonaka 		return 0;	/* shared SDIO card interrupt? */
    340      1.1    nonaka 
    341      1.1    nonaka 	len = SBT_PKT_BUFSIZ;
    342      1.1    nonaka 	if (sbt_read_packet(sc, sc->sc_buf, &len) != 0 || len == 0) {
    343      1.1    nonaka 		DPRINTF(("%s: sbt_intr: read failed\n", DEVNAME(sc)));
    344      1.1    nonaka 		goto eoi;
    345      1.1    nonaka 	}
    346      1.1    nonaka 
    347      1.1    nonaka 	MGETHDR(m, M_DONTWAIT, MT_DATA);
    348      1.1    nonaka 	if (m == NULL) {
    349      1.1    nonaka 		DPRINTF(("%s: sbt_intr: MGETHDR failed\n", DEVNAME(sc)));
    350      1.1    nonaka 		goto eoi;
    351      1.1    nonaka 	}
    352      1.1    nonaka 
    353      1.1    nonaka 	m->m_pkthdr.len = m->m_len = MHLEN;
    354      1.1    nonaka 	m_copyback(m, 0, len, sc->sc_buf);
    355      1.1    nonaka 	if (m->m_pkthdr.len == MAX(MHLEN, len)) {
    356      1.1    nonaka 		m->m_pkthdr.len = len;
    357      1.1    nonaka 		m->m_len = MIN(MHLEN, m->m_pkthdr.len);
    358      1.1    nonaka 	} else {
    359      1.1    nonaka 		DPRINTF(("%s: sbt_intr: m_copyback failed\n", DEVNAME(sc)));
    360      1.6      maxv 		m_freem(m);
    361      1.1    nonaka 		m = NULL;
    362      1.1    nonaka 	}
    363      1.1    nonaka 
    364      1.1    nonaka eoi:
    365      1.1    nonaka 	if (m != NULL) {
    366      1.1    nonaka 		switch (sc->sc_buf[0]) {
    367      1.1    nonaka 		case HCI_ACL_DATA_PKT:
    368      1.1    nonaka 			DNPRINTF(1,("%s: recv ACL packet (%d bytes)\n",
    369      1.1    nonaka 			    DEVNAME(sc), m->m_pkthdr.len));
    370      1.1    nonaka 			hci_input_acl(sc->sc_unit, m);
    371      1.1    nonaka 			break;
    372      1.1    nonaka 		case HCI_SCO_DATA_PKT:
    373      1.1    nonaka 			DNPRINTF(1,("%s: recv SCO packet (%d bytes)\n",
    374      1.1    nonaka 			    DEVNAME(sc), m->m_pkthdr.len));
    375      1.1    nonaka 			hci_input_sco(sc->sc_unit, m);
    376      1.1    nonaka 			break;
    377      1.1    nonaka 		case HCI_EVENT_PKT:
    378      1.1    nonaka 			DNPRINTF(1,("%s: recv EVENT packet (%d bytes)\n",
    379      1.1    nonaka 			    DEVNAME(sc), m->m_pkthdr.len));
    380      1.1    nonaka 			hci_input_event(sc->sc_unit, m);
    381      1.1    nonaka 			break;
    382      1.1    nonaka 		default:
    383      1.1    nonaka 			DPRINTF(("%s: recv 0x%x packet (%d bytes)\n",
    384      1.1    nonaka 			    DEVNAME(sc), sc->sc_buf[0], m->m_pkthdr.len));
    385      1.1    nonaka 			sc->sc_stats.err_rx++;
    386      1.6      maxv 			m_freem(m);
    387      1.1    nonaka 			break;
    388      1.1    nonaka 		}
    389      1.1    nonaka 	} else
    390      1.1    nonaka 		sc->sc_stats.err_rx++;
    391      1.1    nonaka 
    392      1.1    nonaka 	splx(s);
    393      1.1    nonaka 
    394      1.1    nonaka 	/* Claim this interrupt. */
    395      1.1    nonaka 	return 1;
    396      1.1    nonaka }
    397      1.1    nonaka 
    398      1.1    nonaka 
    399      1.1    nonaka /*
    400      1.1    nonaka  * Bluetooth HCI unit functions
    401      1.1    nonaka  */
    402      1.1    nonaka 
    403      1.1    nonaka static int
    404      1.1    nonaka sbt_enable(device_t self)
    405      1.1    nonaka {
    406      1.1    nonaka 	struct sbt_softc *sc = device_private(self);
    407      1.1    nonaka 	int s;
    408      1.1    nonaka 
    409      1.1    nonaka 	if (sc->sc_flags & SBT_ENABLED)
    410      1.1    nonaka 		return 0;
    411      1.1    nonaka 
    412      1.1    nonaka 	s = spltty();
    413      1.1    nonaka 
    414      1.1    nonaka 	sc->sc_flags |= SBT_ENABLED;
    415      1.1    nonaka 	sc->sc_flags &= ~SBT_XMIT;
    416      1.1    nonaka 
    417      1.1    nonaka 	splx(s);
    418      1.1    nonaka 
    419      1.1    nonaka 	return 0;
    420      1.1    nonaka }
    421      1.1    nonaka 
    422      1.1    nonaka static void
    423      1.1    nonaka sbt_disable(device_t self)
    424      1.1    nonaka {
    425      1.1    nonaka 	struct sbt_softc *sc = device_private(self);
    426      1.1    nonaka 	int s;
    427      1.1    nonaka 
    428      1.1    nonaka 	if (!(sc->sc_flags & SBT_ENABLED))
    429      1.1    nonaka 		return;
    430      1.1    nonaka 
    431      1.1    nonaka 	s = spltty();
    432      1.1    nonaka 
    433      1.1    nonaka #ifdef notyet			/* XXX */
    434      1.1    nonaka 	if (sc->sc_rxp) {
    435      1.1    nonaka 		m_freem(sc->sc_rxp);
    436      1.1    nonaka 		sc->sc_rxp = NULL;
    437      1.1    nonaka 	}
    438      1.1    nonaka 
    439      1.1    nonaka 	if (sc->sc_txp) {
    440      1.1    nonaka 		m_freem(sc->sc_txp);
    441      1.1    nonaka 		sc->sc_txp = NULL;
    442      1.1    nonaka 	}
    443      1.1    nonaka #endif
    444      1.1    nonaka 
    445      1.1    nonaka 	MBUFQ_DRAIN(&sc->sc_cmdq);
    446      1.1    nonaka 	MBUFQ_DRAIN(&sc->sc_aclq);
    447      1.1    nonaka 	MBUFQ_DRAIN(&sc->sc_scoq);
    448      1.1    nonaka 
    449      1.1    nonaka 	sc->sc_flags &= ~SBT_ENABLED;
    450      1.1    nonaka 
    451      1.1    nonaka 	splx(s);
    452      1.1    nonaka }
    453      1.1    nonaka 
    454      1.1    nonaka static void
    455      1.1    nonaka sbt_start(struct sbt_softc *sc)
    456      1.1    nonaka {
    457      1.1    nonaka 	struct mbuf *m;
    458      1.1    nonaka 	int len;
    459      1.1    nonaka #ifdef SBT_DEBUG
    460      1.1    nonaka 	const char *what;
    461      1.1    nonaka #endif
    462      1.1    nonaka 
    463      1.1    nonaka 	KASSERT((sc->sc_flags & SBT_XMIT) == 0);
    464      1.1    nonaka 
    465      1.1    nonaka 	if (sc->sc_dying)
    466      1.1    nonaka 		return;
    467      1.1    nonaka 
    468      1.1    nonaka 	if (MBUFQ_FIRST(&sc->sc_cmdq)) {
    469      1.1    nonaka 		MBUFQ_DEQUEUE(&sc->sc_cmdq, m);
    470      1.1    nonaka 		sc->sc_stats.cmd_tx++;
    471      1.1    nonaka #ifdef SBT_DEBUG
    472      1.1    nonaka 		what = "CMD";
    473      1.1    nonaka #endif
    474      1.1    nonaka 		goto start;
    475      1.1    nonaka 	}
    476      1.1    nonaka 
    477      1.1    nonaka 	if (MBUFQ_FIRST(&sc->sc_scoq)) {
    478      1.1    nonaka 		MBUFQ_DEQUEUE(&sc->sc_scoq, m);
    479      1.1    nonaka 		sc->sc_stats.sco_tx++;
    480      1.1    nonaka #ifdef SBT_DEBUG
    481      1.1    nonaka 		what = "SCO";
    482      1.1    nonaka #endif
    483      1.1    nonaka 		goto start;
    484      1.1    nonaka 	}
    485      1.1    nonaka 
    486      1.1    nonaka 	if (MBUFQ_FIRST(&sc->sc_aclq)) {
    487      1.1    nonaka 		MBUFQ_DEQUEUE(&sc->sc_aclq, m);
    488      1.1    nonaka 		sc->sc_stats.acl_tx++;
    489      1.1    nonaka #ifdef SBT_DEBUG
    490      1.1    nonaka 		what = "ACL";
    491      1.1    nonaka #endif
    492      1.1    nonaka 		goto start;
    493      1.1    nonaka 	}
    494      1.1    nonaka 
    495      1.1    nonaka 	/* Nothing to send */
    496      1.1    nonaka 	return;
    497      1.1    nonaka 
    498      1.1    nonaka start:
    499      1.1    nonaka 	DNPRINTF(1,("%s: xmit %s packet (%d bytes)\n", DEVNAME(sc),
    500      1.1    nonaka 	    what, m->m_pkthdr.len));
    501      1.1    nonaka 
    502      1.1    nonaka 	sc->sc_flags |= SBT_XMIT;
    503      1.1    nonaka 
    504      1.1    nonaka 	len = m->m_pkthdr.len;
    505      1.1    nonaka 	m_copydata(m, 0, len, sc->sc_buf);
    506      1.1    nonaka 	m_freem(m);
    507      1.1    nonaka 
    508      1.1    nonaka 	if (sbt_write_packet(sc, sc->sc_buf, len))
    509      1.1    nonaka 		DPRINTF(("%s: sbt_write_packet failed\n", DEVNAME(sc)));
    510      1.1    nonaka 
    511      1.1    nonaka 	sc->sc_flags &= ~SBT_XMIT;
    512      1.1    nonaka }
    513      1.1    nonaka 
    514      1.1    nonaka static void
    515      1.1    nonaka sbt_start_cmd(device_t self, struct mbuf *m)
    516      1.1    nonaka {
    517      1.1    nonaka 	struct sbt_softc *sc = device_private(self);
    518      1.1    nonaka 	int s;
    519      1.1    nonaka 
    520      1.1    nonaka 	KASSERT(sc->sc_flags & SBT_ENABLED);
    521      1.1    nonaka 
    522      1.1    nonaka 	M_SETCTX(m, NULL);
    523      1.1    nonaka 
    524      1.1    nonaka 	s = spltty();
    525      1.1    nonaka 
    526      1.1    nonaka 	MBUFQ_ENQUEUE(&sc->sc_cmdq, m);
    527      1.1    nonaka 	if ((sc->sc_flags & SBT_XMIT) == 0)
    528      1.1    nonaka 		sbt_start(sc);
    529      1.1    nonaka 
    530      1.1    nonaka 	splx(s);
    531      1.1    nonaka }
    532      1.1    nonaka 
    533      1.1    nonaka static void
    534      1.1    nonaka sbt_start_acl(device_t self, struct mbuf *m)
    535      1.1    nonaka {
    536      1.1    nonaka 	struct sbt_softc *sc = device_private(self);
    537      1.1    nonaka 	int s;
    538      1.1    nonaka 
    539      1.1    nonaka 	KASSERT(sc->sc_flags & SBT_ENABLED);
    540      1.1    nonaka 
    541      1.1    nonaka 	M_SETCTX(m, NULL);
    542      1.1    nonaka 
    543      1.1    nonaka 	s = spltty();
    544      1.1    nonaka 
    545      1.1    nonaka 	MBUFQ_ENQUEUE(&sc->sc_aclq, m);
    546      1.1    nonaka 	if ((sc->sc_flags & SBT_XMIT) == 0)
    547      1.1    nonaka 		sbt_start(sc);
    548      1.1    nonaka 
    549      1.1    nonaka 	splx(s);
    550      1.1    nonaka }
    551      1.1    nonaka 
    552      1.1    nonaka static void
    553      1.1    nonaka sbt_start_sco(device_t self, struct mbuf *m)
    554      1.1    nonaka {
    555      1.1    nonaka 	struct sbt_softc *sc = device_private(self);
    556      1.1    nonaka 	int s;
    557      1.1    nonaka 
    558      1.1    nonaka 	KASSERT(sc->sc_flags & SBT_ENABLED);
    559      1.1    nonaka 
    560      1.1    nonaka 	s = spltty();
    561      1.1    nonaka 
    562      1.1    nonaka 	MBUFQ_ENQUEUE(&sc->sc_scoq, m);
    563      1.1    nonaka 	if ((sc->sc_flags & SBT_XMIT) == 0)
    564      1.1    nonaka 		sbt_start(sc);
    565      1.1    nonaka 
    566      1.1    nonaka 	splx(s);
    567      1.1    nonaka }
    568      1.1    nonaka 
    569      1.1    nonaka static void
    570      1.1    nonaka sbt_stats(device_t self, struct bt_stats *dest, int flush)
    571      1.1    nonaka {
    572      1.1    nonaka 	struct sbt_softc *sc = device_private(self);
    573      1.1    nonaka 	int s;
    574      1.1    nonaka 
    575      1.1    nonaka 	s = spltty();
    576      1.1    nonaka 
    577      1.1    nonaka 	memcpy(dest, &sc->sc_stats, sizeof(struct bt_stats));
    578      1.1    nonaka 
    579      1.1    nonaka 	if (flush)
    580      1.1    nonaka 		memset(&sc->sc_stats, 0, sizeof(struct bt_stats));
    581      1.1    nonaka 
    582      1.1    nonaka 	splx(s);
    583      1.1    nonaka }
    584