xref: /netbsd-src/sys/dev/pcmcia/bt3c.c (revision fad4c9f71477ae11cea2ee75ec82151ac770a534)
1 /* $NetBSD: bt3c.c,v 1.1 2006/06/19 15:44:45 gdamore Exp $ */
2 
3 /*-
4  * Copyright (c) 2005 Iain D. Hibbert,
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. The name of the author may not be used to endorse or promote products
16  *    derived from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 /*
31  * Driver for the 3Com Bluetooth PC Card 3CRWB6096, written with reference to
32  *  FreeBSD and BlueZ drivers for same, with credit for those going to:
33  *
34  *		Maksim Yevmenkin <m_evmenkin@yahoo.com>		(FreeBSD)
35  *		Marcel Holtmann <marcel@holtmann.org>		(BlueZ)
36  *		Jose Orlando Pereira <jop@di.uminho.pt>		(BlueZ)
37  *		David Hinds <dahinds@users.sourceforge.net>	(Original Code)
38  */
39 
40 /*
41  * The CIS info from my card:
42  *
43  *	pcmcia1: CIS tuple chain:
44  *	CISTPL_DEVICE type=null speed=null
45  *	 01 03 00 00 ff
46  *	CISTPL_VERS_1
47  *	 15 24 05 00 33 43 4f 4d 00 33 43 52 57 42 36 30
48  *	 2d 41 00 42 6c 75 65 74 6f 6f 74 68 20 50 43 20
49  *	 43 61 72 64 00 ff
50  *	CISTPL_MANFID
51  *	 20 04 01 01 40 00
52  *	CISTPL_FUNCID
53  *	 21 02 02 01
54  *	CISTPL_CONFIG
55  *	 1a 06 05 30 20 03 17 00
56  *	CISTPL_CFTABLE_ENTRY
57  *	 1b 09 f0 41 18 a0 40 07 30 ff ff
58  *	unhandled CISTPL 80
59  *	 80 0a 02 01 40 00 2d 00 00 00 00 ff
60  *	CISTPL_NO_LINK
61  *	 14 00
62  *	CISTPL_END
63  *	 ff
64  *	pcmcia1: CIS version PC Card Standard 5.0
65  *	pcmcia1: CIS info: 3COM, 3CRWB60-A, Bluetooth PC Card
66  *	pcmcia1: Manufacturer code 0x101, product 0x40
67  *	pcmcia1: function 0: serial port, ccr addr 320 mask 17
68  *	pcmcia1: function 0, config table entry 48: I/O card; irq mask ffff; iomask 0, iospace 0-7; rdybsy_active io8 irqlevel
69  */
70 
71 #include <sys/cdefs.h>
72 __KERNEL_RCSID(0, "$NetBSD: bt3c.c,v 1.1 2006/06/19 15:44:45 gdamore Exp $");
73 
74 #include <sys/param.h>
75 #include <sys/device.h>
76 #include <sys/mbuf.h>
77 #include <sys/systm.h>
78 
79 #include <machine/cpu.h>
80 #include <machine/bus.h>
81 #include <machine/intr.h>
82 
83 #include <dev/pcmcia/pcmciareg.h>
84 #include <dev/pcmcia/pcmciavar.h>
85 #include <dev/pcmcia/pcmciadevs.h>
86 
87 #include <netbt/bluetooth.h>
88 #include <netbt/hci.h>
89 
90 #include <dev/firmload.h>
91 #define BT3C_FIRMWARE_FILE	"BT3CPCC.bin"
92 
93 /**************************************************************************
94  *
95  *	bt3c autoconfig glue
96  */
97 
98 struct bt3c_softc {
99 	struct device	sc_dev;			/* required */
100 
101 	struct pcmcia_function *sc_pf;		/* our PCMCIA function */
102 	struct pcmcia_io_handle sc_pcioh;	/* PCMCIA i/o space info */
103 	int		sc_iow;			/* our i/o window */
104 	void		*sc_powerhook;		/* power hook descriptor */
105 	int		sc_flags;		/* flags */
106 
107 	struct hci_unit sc_unit;		/* Bluetooth HCI Unit */
108 
109 	/* hardware interrupt */
110 	void		*sc_intr;		/* cookie */
111 	int		sc_state;		/* receive state */
112 	int		sc_want;		/* how much we want */
113 	struct mbuf	*sc_rxp;		/* incoming packet */
114 	struct mbuf	*sc_txp;		/* outgoing packet */
115 };
116 
117 /* sc_state */				/* receiving */
118 #define BT3C_RECV_PKT_TYPE	0		/* packet type */
119 #define BT3C_RECV_ACL_HDR	1		/* acl header */
120 #define BT3C_RECV_SCO_HDR	2		/* sco header */
121 #define BT3C_RECV_EVENT_HDR	3		/* event header */
122 #define BT3C_RECV_ACL_DATA	4		/* acl packet data */
123 #define BT3C_RECV_SCO_DATA	5		/* sco packet data */
124 #define BT3C_RECV_EVENT_DATA	6		/* event packet data */
125 
126 /* sc_flags */
127 #define BT3C_SLEEPING		(1 << 0)	/* but not with the fishes */
128 
129 static int bt3c_match(struct device *, struct cfdata *, void *);
130 static void bt3c_attach(struct device *, struct device *, void *);
131 static int bt3c_detach(struct device *, int);
132 static int bt3c_activate(struct device *, enum devact);
133 static void bt3c_power(int, void *);
134 
135 CFATTACH_DECL(bt3c, sizeof(struct bt3c_softc),
136     bt3c_match, bt3c_attach, bt3c_detach, bt3c_activate);
137 
138 static void bt3c_start(struct hci_unit *);
139 static int bt3c_enable(struct hci_unit *);
140 static void bt3c_disable(struct hci_unit *);
141 
142 /**************************************************************************
143  *
144  *	Hardware Definitions & IO routines
145  *
146  *	I made up the names for most of these defs since we dont have
147  *	manufacturers recommendations, but I dont like raw numbers..
148  *
149  *	all hardware routines are running at IPL_TTY
150  *
151  */
152 #define BT3C_ISR		0x7001		/* Interrupt Status Register */
153 #define BT3C_ISR_RXRDY			(1<<0)	/* Device has data */
154 #define BT3C_ISR_TXRDY			(1<<1)	/* Finished sending data */
155 #define BT3C_ISR_ANTENNA		(1<<5)	/* Antenna position changed */
156 
157 #define BT3C_CSR		0x7002		/* Card Status Register */
158 #define BT3C_CSR_ANTENNA		(1<<4)	/* Antenna position */
159 
160 #define BT3C_TX_COUNT		0x7005		/* Tx fifo contents */
161 #define BT3C_TX_FIFO		0x7080		/* Transmit Fifo */
162 #define BT3C_RX_COUNT		0x7006		/* Rx fifo contents */
163 #define BT3C_RX_FIFO		0x7480		/* Receive Fifo */
164 #define BT3C_FIFO_SIZE			256
165 
166 /* IO Registers */
167 #define BT3C_IOR_DATA_L		0x00		/* data low byte */
168 #define BT3C_IOR_DATA_H		0x01		/* data high byte */
169 #define BT3C_IOR_ADDR_L		0x02		/* address low byte */
170 #define BT3C_IOR_ADDR_H		0x03		/* address high byte */
171 #define BT3C_IOR_CNTL		0x04		/* control byte */
172 #define BT3C_IOR_CNTL_BOOT		(1<<6)	/* Boot Card */
173 #define BT3C_IOR_CNTL_INTR		(1<<7)	/* Interrupt Requested */
174 #define BT3C_IOR_LEN		0x05
175 
176 static inline uint16_t
177 bt3c_get(struct bt3c_softc *sc)
178 {
179 	uint16_t data;
180 
181 	bus_space_barrier(sc->sc_pcioh.iot, sc->sc_pcioh.ioh,
182 				0, BT3C_IOR_LEN, BUS_SPACE_BARRIER_READ);
183 	data = bus_space_read_1(sc->sc_pcioh.iot, sc->sc_pcioh.ioh,
184 				BT3C_IOR_DATA_L);
185 	data |= bus_space_read_1(sc->sc_pcioh.iot, sc->sc_pcioh.ioh,
186 				BT3C_IOR_DATA_H) << 8;
187 
188 	return data;
189 }
190 
191 static inline void
192 bt3c_put(struct bt3c_softc *sc, uint16_t data)
193 {
194 
195 	bus_space_barrier(sc->sc_pcioh.iot, sc->sc_pcioh.ioh,
196 			0, BT3C_IOR_LEN, BUS_SPACE_BARRIER_WRITE);
197 	bus_space_write_1(sc->sc_pcioh.iot, sc->sc_pcioh.ioh,
198 			BT3C_IOR_DATA_L, data & 0xff);
199 	bus_space_write_1(sc->sc_pcioh.iot, sc->sc_pcioh.ioh,
200 			BT3C_IOR_DATA_H, (data >> 8) & 0xff);
201 }
202 
203 static inline uint8_t
204 bt3c_read_control(struct bt3c_softc *sc)
205 {
206 
207 	bus_space_barrier(sc->sc_pcioh.iot, sc->sc_pcioh.ioh,
208 			0, BT3C_IOR_LEN, BUS_SPACE_BARRIER_READ);
209 	return bus_space_read_1(sc->sc_pcioh.iot, sc->sc_pcioh.ioh,
210 			BT3C_IOR_CNTL);
211 }
212 
213 static inline void
214 bt3c_write_control(struct bt3c_softc *sc, uint8_t data)
215 {
216 
217 	bus_space_barrier(sc->sc_pcioh.iot, sc->sc_pcioh.ioh,
218 			0, BT3C_IOR_LEN, BUS_SPACE_BARRIER_WRITE);
219 	bus_space_write_1(sc->sc_pcioh.iot, sc->sc_pcioh.ioh,
220 			BT3C_IOR_CNTL, data);
221 }
222 
223 static inline void
224 bt3c_set_address(struct bt3c_softc *sc, uint16_t addr)
225 {
226 
227 	bus_space_barrier(sc->sc_pcioh.iot, sc->sc_pcioh.ioh,
228 			0, BT3C_IOR_LEN, BUS_SPACE_BARRIER_WRITE);
229 	bus_space_write_1(sc->sc_pcioh.iot, sc->sc_pcioh.ioh,
230 			BT3C_IOR_ADDR_L, addr & 0xff);
231 	bus_space_write_1(sc->sc_pcioh.iot, sc->sc_pcioh.ioh,
232 			BT3C_IOR_ADDR_H, (addr >> 8) & 0xff);
233 }
234 
235 static inline uint16_t
236 bt3c_read(struct bt3c_softc *sc, uint16_t addr)
237 {
238 
239 	bt3c_set_address(sc, addr);
240 	return bt3c_get(sc);
241 }
242 
243 static inline void
244 bt3c_write(struct bt3c_softc *sc, uint16_t addr, uint16_t data)
245 {
246 
247 	bt3c_set_address(sc, addr);
248 	bt3c_put(sc, data);
249 }
250 
251 /*
252  * receive incoming data from device, store in mbuf chain and
253  * pass on complete packets to bt device
254  */
255 static void
256 bt3c_receive(struct bt3c_softc *sc)
257 {
258 	struct mbuf *m = sc->sc_rxp;
259 	int space = 0;
260 	uint16_t count;
261 	uint8_t b;
262 
263 	/*
264 	 * If we already started a packet, find the
265 	 * trailing end of it.
266 	 */
267 	if (m) {
268 		while (m->m_next)
269 			m = m->m_next;
270 
271 		space = M_TRAILINGSPACE(m);
272 	}
273 
274 	count = bt3c_read(sc, BT3C_RX_COUNT);
275 	bt3c_set_address(sc, BT3C_RX_FIFO);
276 
277 	while (count > 0) {
278 		if (space == 0) {
279 			if (m == NULL) {
280 				/* new packet */
281 				MGETHDR(m, M_DONTWAIT, MT_DATA);
282 				if (m == NULL) {
283 					printf("%s: out of memory\n",
284 						sc->sc_dev.dv_xname);
285 					++sc->sc_unit.hci_stats.err_rx;
286 					goto out;	/* (lost sync) */
287 				}
288 
289 				sc->sc_rxp = m;
290 				m->m_pkthdr.len = m->m_len = 0;
291 				space = MHLEN;
292 
293 				sc->sc_state = BT3C_RECV_PKT_TYPE;
294 				sc->sc_want = 1;
295 			} else {
296 				/* extend mbuf */
297 				MGET(m->m_next, M_DONTWAIT, MT_DATA);
298 				if (m->m_next == NULL) {
299 					printf("%s: out of memory\n",
300 						sc->sc_dev.dv_xname);
301 					++sc->sc_unit.hci_stats.err_rx;
302 					goto out;	/* (lost sync) */
303 				}
304 
305 				m = m->m_next;
306 				m->m_len = 0;
307 				space = MLEN;
308 
309 				if (sc->sc_want > MINCLSIZE) {
310 					MCLGET(m, M_DONTWAIT);
311 					if (m->m_flags & M_EXT)
312 						space = MCLBYTES;
313 				}
314 			}
315 		}
316 
317 		b = bt3c_get(sc);
318 		mtod(m, uint8_t *)[m->m_len++] = b;
319 		count--;
320 		space--;
321 		sc->sc_rxp->m_pkthdr.len++;
322 		sc->sc_unit.hci_stats.byte_rx++;
323 
324 		sc->sc_want--;
325 		if (sc->sc_want > 0)
326 			continue; /* want more */
327 
328 		switch (sc->sc_state) {
329 		case BT3C_RECV_PKT_TYPE:		/* Got packet type */
330 
331 			switch (b) {
332 			case HCI_ACL_DATA_PKT:
333 				sc->sc_state = BT3C_RECV_ACL_HDR;
334 				sc->sc_want = sizeof(hci_acldata_hdr_t) - 1;
335 				break;
336 
337 			case HCI_SCO_DATA_PKT:
338 				sc->sc_state = BT3C_RECV_SCO_HDR;
339 				sc->sc_want = sizeof(hci_scodata_hdr_t) - 1;
340 				break;
341 
342 			case HCI_EVENT_PKT:
343 				sc->sc_state = BT3C_RECV_EVENT_HDR;
344 				sc->sc_want = sizeof(hci_event_hdr_t) - 1;
345 				break;
346 
347 			default:
348 				printf("%s: Unknown packet type=%#x!\n",
349 					sc->sc_dev.dv_xname, b);
350 				++sc->sc_unit.hci_stats.err_rx;
351 				m_freem(sc->sc_rxp);
352 				sc->sc_rxp = NULL;
353 				goto out;	/* (lost sync) */
354 			}
355 
356 			break;
357 
358 		/*
359 		 * we assume (correctly of course :) that the packet headers
360 		 * all fit into a single pkthdr mbuf
361 		 */
362 		case BT3C_RECV_ACL_HDR:		/* Got ACL Header */
363 			sc->sc_state = BT3C_RECV_ACL_DATA;
364 			sc->sc_want = mtod(m, hci_acldata_hdr_t *)->length;
365 			sc->sc_want = le16toh(sc->sc_want);
366 			break;
367 
368 		case BT3C_RECV_SCO_HDR:		/* Got SCO Header */
369 			sc->sc_state = BT3C_RECV_SCO_DATA;
370 			sc->sc_want =  mtod(m, hci_scodata_hdr_t *)->length;
371 			break;
372 
373 		case BT3C_RECV_EVENT_HDR:	/* Got Event Header */
374 			sc->sc_state = BT3C_RECV_EVENT_DATA;
375 			sc->sc_want =  mtod(m, hci_event_hdr_t *)->length;
376 			break;
377 
378 		case BT3C_RECV_ACL_DATA:	/* ACL Packet Complete */
379 			hci_input_acl(&sc->sc_unit, sc->sc_rxp);
380 			sc->sc_unit.hci_stats.acl_rx++;
381 			sc->sc_rxp = m = NULL;
382 			space = 0;
383 			break;
384 
385 		case BT3C_RECV_SCO_DATA:	/* SCO Packet Complete */
386 			hci_input_sco(&sc->sc_unit, sc->sc_rxp);
387 			sc->sc_unit.hci_stats.sco_rx++;
388 			sc->sc_rxp = m = NULL;
389 			space = 0;
390 			break;
391 
392 		case BT3C_RECV_EVENT_DATA:	/* Event Packet Complete */
393 			sc->sc_unit.hci_stats.evt_rx++;
394 			hci_input_event(&sc->sc_unit, sc->sc_rxp);
395 			sc->sc_rxp = m = NULL;
396 			space = 0;
397 			break;
398 
399 		default:
400 			panic("%s: invalid state %d!\n",
401 				sc->sc_dev.dv_xname, sc->sc_state);
402 		}
403 	}
404 
405 out:
406 	bt3c_write(sc, BT3C_RX_COUNT, 0x0000);
407 }
408 
409 /*
410  * write data from current packet to Transmit FIFO.
411  * restart when done.
412  */
413 static void
414 bt3c_transmit(struct bt3c_softc *sc)
415 {
416 	struct mbuf *m;
417 	int count, rlen;
418 	uint8_t *rptr;
419 
420 	m = sc->sc_txp;
421 	if (m == NULL) {
422 		sc->sc_unit.hci_flags &= ~BTF_XMIT;
423 		bt3c_start(&sc->sc_unit);
424 		return;
425 	}
426 
427 	count = 0;
428 	rlen = 0;
429 	rptr = mtod(m, uint8_t *);
430 
431 	bt3c_set_address(sc, BT3C_TX_FIFO);
432 
433 	for(;;) {
434 		if (rlen >= m->m_len) {
435 			m = m->m_next;
436 			if (m == NULL) {
437 				m = sc->sc_txp;
438 				sc->sc_txp = NULL;
439 
440 				if (M_GETCTX(m, void *) == NULL)
441 					m_freem(m);
442 				else
443 					hci_complete_sco(&sc->sc_unit, m);
444 
445 				break;
446 			}
447 
448 			rlen = 0;
449 			rptr = mtod(m, uint8_t *);
450 			continue;
451 		}
452 
453 		if (count >= BT3C_FIFO_SIZE) {
454 			m_adj(m, rlen);
455 			break;
456 		}
457 
458 		bt3c_put(sc, *rptr++);
459 		rlen++;
460 		count++;
461 	}
462 
463 	bt3c_write(sc, BT3C_TX_COUNT, count);
464 	sc->sc_unit.hci_stats.byte_tx += count;
465 }
466 
467 /*
468  * interrupt routine
469  */
470 static int
471 bt3c_intr(void *arg)
472 {
473 	struct bt3c_softc *sc = arg;
474 	uint16_t control, isr;
475 
476 	control = bt3c_read_control(sc);
477 	if (control & BT3C_IOR_CNTL_INTR) {
478 		isr = bt3c_read(sc, BT3C_ISR);
479 		if ((isr & 0xff) == 0x7f) {
480 			printf("%s: bt3c_intr got strange ISR=%04x\n",
481 				sc->sc_dev.dv_xname, isr);
482 		} else if ((isr & 0xff) != 0xff) {
483 
484 			if (isr & BT3C_ISR_RXRDY)
485 				bt3c_receive(sc);
486 
487 			if (isr & BT3C_ISR_TXRDY)
488 				bt3c_transmit(sc);
489 
490 #ifdef DIAGNOSTIC
491 			if (isr & BT3C_ISR_ANTENNA) {
492 				if (bt3c_read(sc, BT3C_CSR) & BT3C_CSR_ANTENNA)
493 					printf("%s: Antenna Out\n",
494 						sc->sc_dev.dv_xname);
495 				else
496 					printf("%s: Antenna In\n",
497 						sc->sc_dev.dv_xname);
498 			}
499 #endif
500 
501 			bt3c_write(sc, BT3C_ISR, 0x0000);
502 			bt3c_write_control(sc, control);
503 
504 			return 1; /* handled */
505 		}
506 	}
507 
508 	return 0; /* not handled */
509 }
510 
511 /*
512  * load firmware for the device
513  *
514  * The firmware file is a plain ASCII file containing lines in the format:
515  *
516  *	S<Digit><Len><Address><Data1><Data2>...<DataN><Checksum>
517  *
518  * <Digit>:	0	start ?
519  *		3	data line
520  *		7	finish ?
521  *
522  * <Len>:	1 byte, and is the number of bytes in the rest of the line
523  * <Address>:	4 byte address (only 2 bytes are valid for bt3c I think)
524  * <Data>:	2 byte data word to be written to the address
525  * <Checksum>:	checksum of all bytes in the line including <Len>
526  *
527  * all bytes are in hexadecimal
528  */
529 static inline int32_t
530 hex(const uint8_t *p, int n)
531 {
532 	uint32_t val = 0;
533 
534 	while (n > 0) {
535 		val <<= 4;
536 
537 		if ('0' <= *p && *p <= '9')
538 			val += (*p - '0');
539 		else if ('a' <= *p && *p <= 'f')
540 			val += (*p - 'a' + 0xa);
541 		else if ('A' <= *p && *p <= 'F')
542 			val += (*p - 'A' + 0xa);
543 		else
544 			return -1;
545 
546 		p++;
547 		n--;
548 	}
549 
550 	return val;
551 }
552 
553 static int
554 bt3c_load_firmware(struct bt3c_softc *sc)
555 {
556 	uint8_t *buf, *line, *next, *p;
557 	int32_t addr, data;
558 	int err, sum, len;
559 	firmware_handle_t fh;
560 	size_t size;
561 
562 	err = firmware_open(sc->sc_dev.dv_cfdata->cf_name,
563 			    BT3C_FIRMWARE_FILE, &fh);
564 	if (err) {
565 		printf("%s: Cannot open firmware %s/%s\n", sc->sc_dev.dv_xname,
566 		    sc->sc_dev.dv_cfdata->cf_name, BT3C_FIRMWARE_FILE);
567 		return err;
568 	}
569 
570 	size = (size_t)firmware_get_size(fh);
571 #ifdef DIAGNOSTIC
572 	if (size < 0 || size > 10 * 1024) {	/* sanity check */
573 		printf("%s: firmware file seems WAY too big!\n",
574 			sc->sc_dev.dv_xname);
575 		return EFBIG;
576 	}
577 #endif
578 
579 	buf = firmware_malloc(size);
580 	KASSERT(buf != NULL);
581 
582 	err = firmware_read(fh, 0, buf, size);
583 	if (err) {
584 		printf("%s: Firmware read failed (%d)\n",
585 				sc->sc_dev.dv_xname, err);
586 		goto out;
587 	}
588 
589 	/* Reset */
590 	bt3c_write(sc, 0x8040, 0x0404);
591 	bt3c_write(sc, 0x8040, 0x0400);
592 	DELAY(1);
593 	bt3c_write(sc, 0x8040, 0x0404);
594 	DELAY(17);
595 
596 	next = buf;
597 	err = EFTYPE;
598 
599 	while (next < buf + size) {
600 		line = next;
601 
602 		while (*next != '\r' && *next != '\n') {
603 			if (next >= buf + size)
604 				goto out;
605 
606 			next++;
607 		}
608 
609 		/* 14 covers address and checksum minimum */
610 		if (next - line < 14)
611 			goto out;
612 
613 		if (line[0] != 'S')
614 			goto out;
615 
616 		/* verify line length */
617 		len = hex(line + 2, 2);
618 		if (len < 0 || next - line != len * 2 + 4)
619 			goto out;
620 
621 		/* checksum the line */
622 		sum = 0;
623 		for (p = line + 2 ; p < next ; p += 2)
624 			sum += hex(p, 2);
625 
626 		if ((sum & 0xff) != 0xff)
627 			goto out;
628 
629 		/* extract relevant data */
630 		switch (line[1]) {
631 		case '0':
632 			/* I dont know what this is */
633 			break;
634 
635 		case '3':
636 			/* find number of data words */
637 			len = (len - 5) / 2;
638 			if (len > 15)
639 				goto out;
640 
641 			addr = hex(line + 8, 4);
642 			if (addr < 0)
643 				goto out;
644 
645 			bt3c_set_address(sc, addr);
646 
647 			for (p = line + 12 ; p + 4 < next ; p += 4) {
648 				data = hex(p, 4);
649 				if (data < 0)
650 					goto out;
651 
652 				bt3c_put(sc, data);
653 			}
654 			break;
655 
656 		case '7':
657 			/* I dont know what this is */
658 			break;
659 
660 		default:
661 			goto out;
662 		}
663 
664 		/* skip to start of next line */
665 		while (next < buf + size && (*next == '\r' || *next == '\n'))
666 			next++;
667 	}
668 
669 	err = 0;
670 	DELAY(17);
671 
672 	/* Boot */
673 	bt3c_set_address(sc, 0x3000);
674 	bt3c_write_control(sc, (bt3c_read_control(sc) | BT3C_IOR_CNTL_BOOT));
675 	DELAY(17);
676 
677 	/* Clear Registers */
678 	bt3c_write(sc, BT3C_RX_COUNT, 0x0000);
679 	bt3c_write(sc, BT3C_TX_COUNT, 0x0000);
680 	bt3c_write(sc, BT3C_ISR, 0x0000);
681 	DELAY(1000);
682 
683 out:
684 	firmware_free(buf, size);
685 	firmware_close(fh);
686 	return err;
687 }
688 
689 /**************************************************************************
690  *
691  *  bt device callbacks (all called at IPL_TTY)
692  */
693 
694 /*
695  * start sending on bt3c
696  * this should be called only when BTF_XMIT is not set, and
697  * we only send cmd packets that are clear to send
698  */
699 static void
700 bt3c_start(struct hci_unit *unit)
701 {
702 	struct bt3c_softc *sc = unit->hci_softc;
703 	struct mbuf *m;
704 
705 	KASSERT((unit->hci_flags & BTF_XMIT) == 0);
706 	KASSERT(sc->sc_txp == NULL);
707 
708 	if (MBUFQ_FIRST(&unit->hci_cmdq)) {
709 		MBUFQ_DEQUEUE(&unit->hci_cmdq, m);
710 		unit->hci_stats.cmd_tx++;
711 		M_SETCTX(m, NULL);
712 		goto start;
713 	}
714 
715 	if (MBUFQ_FIRST(&unit->hci_scotxq)) {
716 		MBUFQ_DEQUEUE(&unit->hci_scotxq, m);
717 		unit->hci_stats.sco_tx++;
718 		goto start;
719 	}
720 
721 	if (MBUFQ_FIRST(&unit->hci_acltxq)) {
722 		MBUFQ_DEQUEUE(&unit->hci_acltxq, m);
723 		unit->hci_stats.acl_tx++;
724 		M_SETCTX(m, NULL);
725 		goto start;
726 	}
727 
728 	/* Nothing to send */
729 	return;
730 
731 start:
732 	sc->sc_txp = m;
733 	unit->hci_flags |= BTF_XMIT;
734 	bt3c_transmit(sc);
735 }
736 
737 /*
738  * enable device
739  *	turn on card
740  *	load firmware
741  *	establish interrupts
742  */
743 static int
744 bt3c_enable(struct hci_unit *unit)
745 {
746 	struct bt3c_softc *sc = unit->hci_softc;
747 	int err;
748 
749 	if (unit->hci_flags & BTF_RUNNING)
750 		return 0;
751 
752 	sc->sc_intr = pcmcia_intr_establish(sc->sc_pf, IPL_TTY, bt3c_intr, sc);
753 	if (sc->sc_intr == NULL) {
754 		err = EIO;
755 		goto bad;
756 	}
757 
758 	err = pcmcia_function_enable(sc->sc_pf);
759 	if (err)
760 		goto bad1;
761 
762 	err = bt3c_load_firmware(sc);
763 	if (err)
764 		goto bad2;
765 
766 	unit->hci_flags |= BTF_RUNNING;
767 	unit->hci_flags &= ~BTF_XMIT;
768 
769 	/*
770 	 * 3Com card will send a Command_Status packet when its
771 	 * ready to receive commands
772 	 */
773 	unit->hci_num_cmd_pkts = 0;
774 
775 	return 0;
776 
777 bad2:
778 	pcmcia_function_disable(sc->sc_pf);
779 bad1:
780 	pcmcia_intr_disestablish(sc->sc_pf, sc->sc_intr);
781 	sc->sc_intr = NULL;
782 bad:
783 	return err;
784 }
785 
786 /*
787  * disable device
788  *	shut down card
789  *	disestablish interrupts
790  *	free held packets
791  */
792 static void
793 bt3c_disable(struct hci_unit *unit)
794 {
795 	struct bt3c_softc *sc = unit->hci_softc;
796 
797 	if ((unit->hci_flags & BTF_RUNNING) == 0)
798 		return;
799 
800 	pcmcia_function_disable(sc->sc_pf);
801 
802 	if (sc->sc_intr) {
803 		pcmcia_intr_disestablish(sc->sc_pf, sc->sc_intr);
804 		sc->sc_intr = NULL;
805 	}
806 
807 	if (sc->sc_rxp) {
808 		m_freem(sc->sc_rxp);
809 		sc->sc_rxp = NULL;
810 	}
811 
812 	if (sc->sc_txp) {
813 		m_freem(sc->sc_txp);
814 		sc->sc_txp = NULL;
815 	}
816 
817 	unit->hci_flags &= ~BTF_RUNNING;
818 }
819 
820 /**************************************************************************
821  *
822  *	bt3c PCMCIA autoconfig glue
823  */
824 
825 static int
826 bt3c_match(struct device *parent, struct cfdata *match, void *aux)
827 {
828 	struct pcmcia_attach_args *pa = aux;
829 
830 	if (pa->manufacturer == PCMCIA_VENDOR_3COM &&
831 	    pa->product == PCMCIA_PRODUCT_3COM_3CRWB6096)
832 	    return 10;		/* 'com' also claims this, so trump them */
833 
834 	return 0;
835 }
836 
837 static void
838 bt3c_attach(struct device *parent, struct device *self, void *aux)
839 {
840 	struct bt3c_softc *sc = (struct bt3c_softc *)self;
841 	struct pcmcia_attach_args *pa = aux;
842 	struct pcmcia_config_entry *cfe;
843 
844 	sc->sc_pf = pa->pf;
845 
846 	/* Find a PCMCIA config entry we can use */
847 	SIMPLEQ_FOREACH(cfe, &pa->pf->cfe_head, cfe_list) {
848 		if (cfe->num_memspace != 0)
849 			continue;
850 
851 		if (cfe->num_iospace != 1)
852 			continue;
853 
854 		if (pcmcia_io_alloc(pa->pf, cfe->iospace[0].start,
855 				cfe->iospace[0].length, 0, &sc->sc_pcioh) == 0)
856 			break;
857 	}
858 
859 	if (cfe == 0) {
860 		aprint_error("bt3c_attach: cannot allocate io space\n");
861 		goto no_config_entry;
862 	}
863 
864 	/* Initialise it */
865 	pcmcia_function_init(pa->pf, cfe);
866 
867 	/* Map in the io space */
868 	if (pcmcia_io_map(pa->pf, PCMCIA_WIDTH_AUTO,
869 			&sc->sc_pcioh, &sc->sc_iow)) {
870 		aprint_error("bt3c_attach: cannot map io space\n");
871 		goto iomap_failed;
872 	}
873 
874 	/* Attach Bluetooth unit */
875 	sc->sc_unit.hci_softc = sc;
876 	sc->sc_unit.hci_devname = sc->sc_dev.dv_xname;
877 	sc->sc_unit.hci_enable = bt3c_enable;
878 	sc->sc_unit.hci_disable = bt3c_disable;
879 	sc->sc_unit.hci_start_cmd = bt3c_start;
880 	sc->sc_unit.hci_start_acl = bt3c_start;
881 	sc->sc_unit.hci_start_sco = bt3c_start;
882 	sc->sc_unit.hci_ipl = IPL_TTY;
883 	hci_attach(&sc->sc_unit);
884 
885 	/* establish a power change hook */
886 	sc->sc_powerhook = powerhook_establish(bt3c_power, sc);
887 	return;
888 
889 iomap_failed:
890 	/* unmap io space */
891 	pcmcia_io_free(pa->pf, &sc->sc_pcioh);
892 
893 no_config_entry:
894 	sc->sc_iow = -1;
895 }
896 
897 static int
898 bt3c_detach(struct device *self, int flags)
899 {
900 	struct bt3c_softc *sc = (struct bt3c_softc *)self;
901 	int err = 0;
902 
903 	bt3c_disable(&sc->sc_unit);
904 
905 	if (sc->sc_powerhook) {
906 		powerhook_disestablish(sc->sc_powerhook);
907 		sc->sc_powerhook = NULL;
908 	}
909 
910 	hci_detach(&sc->sc_unit);
911 
912 	if (sc->sc_iow != -1) {
913 		pcmcia_io_unmap(sc->sc_pf, sc->sc_iow);
914 		pcmcia_io_free(sc->sc_pf, &sc->sc_pcioh);
915 		sc->sc_iow = -1;
916 	}
917 
918 	return err;
919 }
920 
921 static int
922 bt3c_activate(struct device *self, enum devact act)
923 {
924 	// struct bt3c_softc *sc = (struct bt3c_softc *)self;
925 	int err = 0;
926 
927 	switch(act) {
928 	case DVACT_ACTIVATE:
929 		err = EOPNOTSUPP;
930 		break;
931 
932 	case DVACT_DEACTIVATE:
933 		// could notify unit somehow?
934 		break;
935 	}
936 
937 	return err;
938 }
939 
940 static void
941 bt3c_power(int why, void *arg)
942 {
943 	struct bt3c_softc *sc = arg;
944 
945 	switch(why) {
946 	case PWR_SUSPEND:
947 	case PWR_STANDBY:
948 		if (sc->sc_unit.hci_flags & BTF_RUNNING) {
949 			printf_nolog("%s: sleeping\n", sc->sc_dev.dv_xname);
950 			bt3c_disable(&sc->sc_unit);
951 			sc->sc_flags |= BT3C_SLEEPING;
952 		}
953 		break;
954 
955 	case PWR_RESUME:
956 		if (sc->sc_flags & BT3C_SLEEPING) {
957 			printf_nolog("%s: waking up\n", sc->sc_dev.dv_xname);
958 			bt3c_enable(&sc->sc_unit);
959 			sc->sc_flags &= ~BT3C_SLEEPING;
960 		}
961 		break;
962 
963 	case PWR_SOFTSUSPEND:
964 	case PWR_SOFTSTANDBY:
965 	case PWR_SOFTRESUME:
966 		break;
967 	}
968 }
969