Home | History | Annotate | Line # | Download | only in sdmmc
sbt.c revision 1.2.28.2
      1  1.2.28.2     tls /*	$NetBSD: sbt.c,v 1.2.28.2 2014/08/20 00:03:50 tls 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.2.28.2     tls __KERNEL_RCSID(0, "$NetBSD: sbt.c,v 1.2.28.2 2014/08/20 00:03:50 tls 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.1  nonaka 		printf("%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.1  nonaka 	sc->sc_buf = malloc(SBT_PKT_BUFSIZ, M_DEVBUF, M_NOWAIT | M_CANFAIL);
    186       1.1  nonaka 	if (sc->sc_buf == NULL) {
    187       1.1  nonaka 		printf("%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.1  nonaka 		printf("%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.2.28.2     tls 	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.2.28.1     tls 	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.2.28.2     tls 		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.1  nonaka 		m_free(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.1  nonaka 			m_free(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