xref: /netbsd-src/sys/dev/pcmcia/bt3c.c (revision 8b0f9554ff8762542c4defc4f70e1eb76fb508fa)
1 /* $NetBSD: bt3c.c,v 1.16 2007/11/28 20:16:11 plunky 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.16 2007/11/28 20:16:11 plunky 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 <sys/cpu.h>
80 #include <sys/bus.h>
81 #include <sys/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 	device_t	sc_dev;
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 	struct bt_stats	sc_stats;		/* HCI stats */
109 
110 	/* hardware interrupt */
111 	void		*sc_intr;		/* cookie */
112 	int		sc_state;		/* receive state */
113 	int		sc_want;		/* how much we want */
114 	struct mbuf	*sc_rxp;		/* incoming packet */
115 	struct mbuf	*sc_txp;		/* outgoing packet */
116 
117 	/* transmit queues */
118 	MBUFQ_HEAD()	sc_cmdq;		/* commands */
119 	MBUFQ_HEAD()	sc_aclq;		/* ACL data */
120 	MBUFQ_HEAD()	sc_scoq;		/* SCO data */
121 };
122 
123 /* sc_state */				/* receiving */
124 #define BT3C_RECV_PKT_TYPE	0		/* packet type */
125 #define BT3C_RECV_ACL_HDR	1		/* acl header */
126 #define BT3C_RECV_SCO_HDR	2		/* sco header */
127 #define BT3C_RECV_EVENT_HDR	3		/* event header */
128 #define BT3C_RECV_ACL_DATA	4		/* acl packet data */
129 #define BT3C_RECV_SCO_DATA	5		/* sco packet data */
130 #define BT3C_RECV_EVENT_DATA	6		/* event packet data */
131 
132 /* sc_flags */
133 #define BT3C_SLEEPING		(1 << 0)	/* but not with the fishes */
134 #define BT3C_XMIT		(1 << 1)	/* transmit active */
135 #define BT3C_ENABLED		(1 << 2)	/* enabled */
136 
137 static int bt3c_match(device_t, struct cfdata *, void *);
138 static void bt3c_attach(device_t, device_t, void *);
139 static int bt3c_detach(device_t, int);
140 static void bt3c_power(int, void *);
141 
142 CFATTACH_DECL_NEW(bt3c, sizeof(struct bt3c_softc),
143     bt3c_match, bt3c_attach, bt3c_detach, NULL);
144 
145 static int bt3c_enable(device_t);
146 static void bt3c_disable(device_t);
147 static void bt3c_output_cmd(device_t, struct mbuf *);
148 static void bt3c_output_acl(device_t, struct mbuf *);
149 static void bt3c_output_sco(device_t, struct mbuf *);
150 static void bt3c_stats(device_t, struct bt_stats *, int);
151 
152 static const struct hci_if bt3c_hci = {
153 	.enable =	bt3c_enable,
154 	.disable =	bt3c_disable,
155 	.output_cmd =	bt3c_output_cmd,
156 	.output_acl =	bt3c_output_acl,
157 	.output_sco =	bt3c_output_sco,
158 	.get_stats =	bt3c_stats,
159 	.ipl =		IPL_TTY,
160 };
161 
162 static void bt3c_start(struct bt3c_softc *);
163 
164 /**************************************************************************
165  *
166  *	Hardware Definitions & IO routines
167  *
168  *	I made up the names for most of these defs since we dont have
169  *	manufacturers recommendations, but I dont like raw numbers..
170  *
171  *	all hardware routines are running at IPL_TTY
172  *
173  */
174 #define BT3C_ISR		0x7001		/* Interrupt Status Register */
175 #define BT3C_ISR_RXRDY			(1<<0)	/* Device has data */
176 #define BT3C_ISR_TXRDY			(1<<1)	/* Finished sending data */
177 #define BT3C_ISR_ANTENNA		(1<<5)	/* Antenna position changed */
178 
179 #define BT3C_CSR		0x7002		/* Card Status Register */
180 #define BT3C_CSR_ANTENNA		(1<<4)	/* Antenna position */
181 
182 #define BT3C_TX_COUNT		0x7005		/* Tx fifo contents */
183 #define BT3C_TX_FIFO		0x7080		/* Transmit Fifo */
184 #define BT3C_RX_COUNT		0x7006		/* Rx fifo contents */
185 #define BT3C_RX_FIFO		0x7480		/* Receive Fifo */
186 #define BT3C_FIFO_SIZE			256
187 
188 /* IO Registers */
189 #define BT3C_IOR_DATA_L		0x00		/* data low byte */
190 #define BT3C_IOR_DATA_H		0x01		/* data high byte */
191 #define BT3C_IOR_ADDR_L		0x02		/* address low byte */
192 #define BT3C_IOR_ADDR_H		0x03		/* address high byte */
193 #define BT3C_IOR_CNTL		0x04		/* control byte */
194 #define BT3C_IOR_CNTL_BOOT		(1<<6)	/* Boot Card */
195 #define BT3C_IOR_CNTL_INTR		(1<<7)	/* Interrupt Requested */
196 #define BT3C_IOR_LEN		0x05
197 
198 static inline uint16_t
199 bt3c_get(struct bt3c_softc *sc)
200 {
201 	uint16_t data;
202 
203 	bus_space_barrier(sc->sc_pcioh.iot, sc->sc_pcioh.ioh,
204 				0, BT3C_IOR_LEN, BUS_SPACE_BARRIER_READ);
205 	data = bus_space_read_1(sc->sc_pcioh.iot, sc->sc_pcioh.ioh,
206 				BT3C_IOR_DATA_L);
207 	data |= bus_space_read_1(sc->sc_pcioh.iot, sc->sc_pcioh.ioh,
208 				BT3C_IOR_DATA_H) << 8;
209 
210 	return data;
211 }
212 
213 static inline void
214 bt3c_put(struct bt3c_softc *sc, uint16_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_DATA_L, data & 0xff);
221 	bus_space_write_1(sc->sc_pcioh.iot, sc->sc_pcioh.ioh,
222 			BT3C_IOR_DATA_H, (data >> 8) & 0xff);
223 }
224 
225 static inline uint8_t
226 bt3c_read_control(struct bt3c_softc *sc)
227 {
228 
229 	bus_space_barrier(sc->sc_pcioh.iot, sc->sc_pcioh.ioh,
230 			0, BT3C_IOR_LEN, BUS_SPACE_BARRIER_READ);
231 	return bus_space_read_1(sc->sc_pcioh.iot, sc->sc_pcioh.ioh,
232 			BT3C_IOR_CNTL);
233 }
234 
235 static inline void
236 bt3c_write_control(struct bt3c_softc *sc, uint8_t data)
237 {
238 
239 	bus_space_barrier(sc->sc_pcioh.iot, sc->sc_pcioh.ioh,
240 			0, BT3C_IOR_LEN, BUS_SPACE_BARRIER_WRITE);
241 	bus_space_write_1(sc->sc_pcioh.iot, sc->sc_pcioh.ioh,
242 			BT3C_IOR_CNTL, data);
243 }
244 
245 static inline void
246 bt3c_set_address(struct bt3c_softc *sc, uint16_t addr)
247 {
248 
249 	bus_space_barrier(sc->sc_pcioh.iot, sc->sc_pcioh.ioh,
250 			0, BT3C_IOR_LEN, BUS_SPACE_BARRIER_WRITE);
251 	bus_space_write_1(sc->sc_pcioh.iot, sc->sc_pcioh.ioh,
252 			BT3C_IOR_ADDR_L, addr & 0xff);
253 	bus_space_write_1(sc->sc_pcioh.iot, sc->sc_pcioh.ioh,
254 			BT3C_IOR_ADDR_H, (addr >> 8) & 0xff);
255 }
256 
257 static inline uint16_t
258 bt3c_read(struct bt3c_softc *sc, uint16_t addr)
259 {
260 
261 	bt3c_set_address(sc, addr);
262 	return bt3c_get(sc);
263 }
264 
265 static inline void
266 bt3c_write(struct bt3c_softc *sc, uint16_t addr, uint16_t data)
267 {
268 
269 	bt3c_set_address(sc, addr);
270 	bt3c_put(sc, data);
271 }
272 
273 /*
274  * receive incoming data from device, store in mbuf chain and
275  * pass on complete packets to bt device
276  */
277 static void
278 bt3c_receive(struct bt3c_softc *sc)
279 {
280 	struct mbuf *m = sc->sc_rxp;
281 	int space = 0;
282 	uint16_t count;
283 	uint8_t b;
284 
285 	/*
286 	 * If we already started a packet, find the
287 	 * trailing end of it.
288 	 */
289 	if (m) {
290 		while (m->m_next)
291 			m = m->m_next;
292 
293 		space = M_TRAILINGSPACE(m);
294 	}
295 
296 	count = bt3c_read(sc, BT3C_RX_COUNT);
297 	bt3c_set_address(sc, BT3C_RX_FIFO);
298 
299 	while (count > 0) {
300 		if (space == 0) {
301 			if (m == NULL) {
302 				/* new packet */
303 				MGETHDR(m, M_DONTWAIT, MT_DATA);
304 				if (m == NULL) {
305 					aprint_error_dev(sc->sc_dev,
306 					    "out of memory\n");
307 					sc->sc_stats.err_rx++;
308 					goto out;	/* (lost sync) */
309 				}
310 
311 				sc->sc_rxp = m;
312 				m->m_pkthdr.len = m->m_len = 0;
313 				space = MHLEN;
314 
315 				sc->sc_state = BT3C_RECV_PKT_TYPE;
316 				sc->sc_want = 1;
317 			} else {
318 				/* extend mbuf */
319 				MGET(m->m_next, M_DONTWAIT, MT_DATA);
320 				if (m->m_next == NULL) {
321 					aprint_error_dev(sc->sc_dev,
322 					    "out of memory\n");
323 					sc->sc_stats.err_rx++;
324 					goto out;	/* (lost sync) */
325 				}
326 
327 				m = m->m_next;
328 				m->m_len = 0;
329 				space = MLEN;
330 
331 				if (sc->sc_want > MINCLSIZE) {
332 					MCLGET(m, M_DONTWAIT);
333 					if (m->m_flags & M_EXT)
334 						space = MCLBYTES;
335 				}
336 			}
337 		}
338 
339 		b = bt3c_get(sc);
340 		mtod(m, uint8_t *)[m->m_len++] = b;
341 		count--;
342 		space--;
343 		sc->sc_rxp->m_pkthdr.len++;
344 		sc->sc_stats.byte_rx++;
345 
346 		sc->sc_want--;
347 		if (sc->sc_want > 0)
348 			continue; /* want more */
349 
350 		switch (sc->sc_state) {
351 		case BT3C_RECV_PKT_TYPE:		/* Got packet type */
352 
353 			switch (b) {
354 			case HCI_ACL_DATA_PKT:
355 				sc->sc_state = BT3C_RECV_ACL_HDR;
356 				sc->sc_want = sizeof(hci_acldata_hdr_t) - 1;
357 				break;
358 
359 			case HCI_SCO_DATA_PKT:
360 				sc->sc_state = BT3C_RECV_SCO_HDR;
361 				sc->sc_want = sizeof(hci_scodata_hdr_t) - 1;
362 				break;
363 
364 			case HCI_EVENT_PKT:
365 				sc->sc_state = BT3C_RECV_EVENT_HDR;
366 				sc->sc_want = sizeof(hci_event_hdr_t) - 1;
367 				break;
368 
369 			default:
370 				aprint_error_dev(sc->sc_dev,
371 				    "Unknown packet type=%#x!\n", b);
372 				sc->sc_stats.err_rx++;
373 				m_freem(sc->sc_rxp);
374 				sc->sc_rxp = NULL;
375 				goto out;	/* (lost sync) */
376 			}
377 
378 			break;
379 
380 		/*
381 		 * we assume (correctly of course :) that the packet headers
382 		 * all fit into a single pkthdr mbuf
383 		 */
384 		case BT3C_RECV_ACL_HDR:		/* Got ACL Header */
385 			sc->sc_state = BT3C_RECV_ACL_DATA;
386 			sc->sc_want = mtod(m, hci_acldata_hdr_t *)->length;
387 			sc->sc_want = le16toh(sc->sc_want);
388 			break;
389 
390 		case BT3C_RECV_SCO_HDR:		/* Got SCO Header */
391 			sc->sc_state = BT3C_RECV_SCO_DATA;
392 			sc->sc_want =  mtod(m, hci_scodata_hdr_t *)->length;
393 			break;
394 
395 		case BT3C_RECV_EVENT_HDR:	/* Got Event Header */
396 			sc->sc_state = BT3C_RECV_EVENT_DATA;
397 			sc->sc_want =  mtod(m, hci_event_hdr_t *)->length;
398 			break;
399 
400 		case BT3C_RECV_ACL_DATA:	/* ACL Packet Complete */
401 			if (!hci_input_acl(sc->sc_unit, sc->sc_rxp))
402 				sc->sc_stats.err_rx++;
403 
404 			sc->sc_stats.acl_rx++;
405 			sc->sc_rxp = m = NULL;
406 			space = 0;
407 			break;
408 
409 		case BT3C_RECV_SCO_DATA:	/* SCO Packet Complete */
410 			if (!hci_input_sco(sc->sc_unit, sc->sc_rxp))
411 				sc->sc_stats.err_rx++;
412 
413 			sc->sc_stats.sco_rx++;
414 			sc->sc_rxp = m = NULL;
415 			space = 0;
416 			break;
417 
418 		case BT3C_RECV_EVENT_DATA:	/* Event Packet Complete */
419 			if (!hci_input_event(sc->sc_unit, sc->sc_rxp))
420 				sc->sc_stats.err_rx++;
421 
422 			sc->sc_stats.evt_rx++;
423 			sc->sc_rxp = m = NULL;
424 			space = 0;
425 			break;
426 
427 		default:
428 			panic("%s: invalid state %d!\n",
429 				device_xname(sc->sc_dev), sc->sc_state);
430 		}
431 	}
432 
433 out:
434 	bt3c_write(sc, BT3C_RX_COUNT, 0x0000);
435 }
436 
437 /*
438  * write data from current packet to Transmit FIFO.
439  * restart when done.
440  */
441 static void
442 bt3c_transmit(struct bt3c_softc *sc)
443 {
444 	struct mbuf *m;
445 	int count, rlen;
446 	uint8_t *rptr;
447 
448 	m = sc->sc_txp;
449 	if (m == NULL) {
450 		sc->sc_flags &= ~BT3C_XMIT;
451 		bt3c_start(sc);
452 		return;
453 	}
454 
455 	count = 0;
456 	rlen = 0;
457 	rptr = mtod(m, uint8_t *);
458 
459 	bt3c_set_address(sc, BT3C_TX_FIFO);
460 
461 	for(;;) {
462 		if (rlen >= m->m_len) {
463 			m = m->m_next;
464 			if (m == NULL) {
465 				m = sc->sc_txp;
466 				sc->sc_txp = NULL;
467 
468 				if (M_GETCTX(m, void *) == NULL)
469 					m_freem(m);
470 				else if (!hci_complete_sco(sc->sc_unit, m))
471 					sc->sc_stats.err_tx++;
472 
473 				break;
474 			}
475 
476 			rlen = 0;
477 			rptr = mtod(m, uint8_t *);
478 			continue;
479 		}
480 
481 		if (count >= BT3C_FIFO_SIZE) {
482 			m_adj(m, rlen);
483 			break;
484 		}
485 
486 		bt3c_put(sc, *rptr++);
487 		rlen++;
488 		count++;
489 	}
490 
491 	bt3c_write(sc, BT3C_TX_COUNT, count);
492 	sc->sc_stats.byte_tx += count;
493 }
494 
495 /*
496  * interrupt routine
497  */
498 static int
499 bt3c_intr(void *arg)
500 {
501 	struct bt3c_softc *sc = arg;
502 	uint16_t control, isr;
503 
504 	control = bt3c_read_control(sc);
505 	if (control & BT3C_IOR_CNTL_INTR) {
506 		isr = bt3c_read(sc, BT3C_ISR);
507 		if ((isr & 0xff) == 0x7f) {
508 			aprint_error_dev(sc->sc_dev, "strange ISR=%04x\n", isr);
509 		} else if ((isr & 0xff) != 0xff) {
510 
511 			if (isr & BT3C_ISR_RXRDY)
512 				bt3c_receive(sc);
513 
514 			if (isr & BT3C_ISR_TXRDY)
515 				bt3c_transmit(sc);
516 
517 #ifdef DIAGNOSTIC
518 			if (isr & BT3C_ISR_ANTENNA) {
519 				if (bt3c_read(sc, BT3C_CSR) & BT3C_CSR_ANTENNA)
520 					aprint_verbose_dev(sc->sc_dev,
521 					    "Antenna Out\n");
522 				else
523 					aprint_verbose_dev(sc->sc_dev,
524 					    "Antenna In\n");
525 			}
526 #endif
527 
528 			bt3c_write(sc, BT3C_ISR, 0x0000);
529 			bt3c_write_control(sc, control);
530 
531 			return 1; /* handled */
532 		}
533 	}
534 
535 	return 0; /* not handled */
536 }
537 
538 /*
539  * load firmware for the device
540  *
541  * The firmware file is a plain ASCII file in the Motorola S-Record format,
542  * with lines in the format:
543  *
544  *	S<Digit><Len><Address><Data1><Data2>...<DataN><Checksum>
545  *
546  * <Digit>:	0	header
547  *		3	data record (4 byte address)
548  *		7	boot record (4 byte address)
549  *
550  * <Len>:	1 byte, and is the number of bytes in the rest of the line
551  * <Address>:	4 byte address (only 2 bytes are valid for bt3c I think)
552  * <Data>:	2 byte data word to be written to the address
553  * <Checksum>:	checksum of all bytes in the line including <Len>
554  *
555  * all bytes are in hexadecimal
556  */
557 static inline int32_t
558 hex(const uint8_t *p, int n)
559 {
560 	uint32_t val = 0;
561 
562 	while (n > 0) {
563 		val <<= 4;
564 
565 		if ('0' <= *p && *p <= '9')
566 			val += (*p - '0');
567 		else if ('a' <= *p && *p <= 'f')
568 			val += (*p - 'a' + 0xa);
569 		else if ('A' <= *p && *p <= 'F')
570 			val += (*p - 'A' + 0xa);
571 		else
572 			return -1;
573 
574 		p++;
575 		n--;
576 	}
577 
578 	return val;
579 }
580 
581 static int
582 bt3c_load_firmware(struct bt3c_softc *sc)
583 {
584 	uint8_t *buf, *line, *next, *p;
585 	int32_t addr, data;
586 	int err, sum, len;
587 	firmware_handle_t fh;
588 	struct cfdata *cf = device_cfdata(sc->sc_dev);
589 	size_t size;
590 
591 	err = firmware_open(cf->cf_name,
592 			    BT3C_FIRMWARE_FILE, &fh);
593 	if (err) {
594 		aprint_error_dev(sc->sc_dev, "Cannot open firmware %s/%s\n",
595 		    cf->cf_name, BT3C_FIRMWARE_FILE);
596 		return err;
597 	}
598 
599 	size = (size_t)firmware_get_size(fh);
600 #ifdef DIAGNOSTIC
601 	if (size > 10 * 1024) {	/* sanity check */
602 		aprint_error_dev(sc->sc_dev, "insane firmware file size!\n");
603 		firmware_close(fh);
604 		return EFBIG;
605 	}
606 #endif
607 
608 	buf = firmware_malloc(size);
609 	KASSERT(buf != NULL);
610 
611 	err = firmware_read(fh, 0, buf, size);
612 	if (err) {
613 		aprint_error_dev(sc->sc_dev, "Firmware read failed (%d)\n", err);
614 		goto out;
615 	}
616 
617 	/* Reset */
618 	bt3c_write(sc, 0x8040, 0x0404);
619 	bt3c_write(sc, 0x8040, 0x0400);
620 	DELAY(1);
621 	bt3c_write(sc, 0x8040, 0x0404);
622 	DELAY(17);
623 
624 	next = buf;
625 	err = EFTYPE;
626 
627 	while (next < buf + size) {
628 		line = next;
629 
630 		while (*next != '\r' && *next != '\n') {
631 			if (next >= buf + size)
632 				goto out;
633 
634 			next++;
635 		}
636 
637 		/* 14 covers address and checksum minimum */
638 		if (next - line < 14)
639 			goto out;
640 
641 		if (line[0] != 'S')
642 			goto out;
643 
644 		/* verify line length */
645 		len = hex(line + 2, 2);
646 		if (len < 0 || next - line != len * 2 + 4)
647 			goto out;
648 
649 		/* checksum the line */
650 		sum = 0;
651 		for (p = line + 2 ; p < next ; p += 2)
652 			sum += hex(p, 2);
653 
654 		if ((sum & 0xff) != 0xff)
655 			goto out;
656 
657 		/* extract relevant data */
658 		switch (line[1]) {
659 		case '0':
660 			/* we ignore the header */
661 			break;
662 
663 		case '3':
664 			/* find number of data words */
665 			len = (len - 5) / 2;
666 			if (len > 15)
667 				goto out;
668 
669 			addr = hex(line + 8, 4);
670 			if (addr < 0)
671 				goto out;
672 
673 			bt3c_set_address(sc, addr);
674 
675 			for (p = line + 12 ; p + 4 < next ; p += 4) {
676 				data = hex(p, 4);
677 				if (data < 0)
678 					goto out;
679 
680 				bt3c_put(sc, data);
681 			}
682 			break;
683 
684 		case '7':
685 			/*
686 			 * for some reason we ignore this record
687 			 * and boot from 0x3000 which happens to
688 			 * be the first record in the file.
689 			 */
690 			break;
691 
692 		default:
693 			goto out;
694 		}
695 
696 		/* skip to start of next line */
697 		while (next < buf + size && (*next == '\r' || *next == '\n'))
698 			next++;
699 	}
700 
701 	err = 0;
702 	DELAY(17);
703 
704 	/* Boot */
705 	bt3c_set_address(sc, 0x3000);
706 	bt3c_write_control(sc, (bt3c_read_control(sc) | BT3C_IOR_CNTL_BOOT));
707 	DELAY(17);
708 
709 	/* Clear Registers */
710 	bt3c_write(sc, BT3C_RX_COUNT, 0x0000);
711 	bt3c_write(sc, BT3C_TX_COUNT, 0x0000);
712 	bt3c_write(sc, BT3C_ISR, 0x0000);
713 	DELAY(1000);
714 
715 out:
716 	firmware_free(buf, size);
717 	firmware_close(fh);
718 	return err;
719 }
720 
721 /**************************************************************************
722  *
723  *  bt device callbacks
724  */
725 
726 /*
727  * start sending on bt3c
728  * should be called at spltty() when BT3C_XMIT is not set
729  */
730 static void
731 bt3c_start(struct bt3c_softc *sc)
732 {
733 	struct mbuf *m;
734 
735 	KASSERT((sc->sc_flags & BT3C_XMIT) == 0);
736 	KASSERT(sc->sc_txp == NULL);
737 
738 	if (MBUFQ_FIRST(&sc->sc_cmdq)) {
739 		MBUFQ_DEQUEUE(&sc->sc_cmdq, m);
740 		sc->sc_stats.cmd_tx++;
741 		goto start;
742 	}
743 
744 	if (MBUFQ_FIRST(&sc->sc_scoq)) {
745 		MBUFQ_DEQUEUE(&sc->sc_scoq, m);
746 		sc->sc_stats.sco_tx++;
747 		goto start;
748 	}
749 
750 	if (MBUFQ_FIRST(&sc->sc_aclq)) {
751 		MBUFQ_DEQUEUE(&sc->sc_aclq, m);
752 		sc->sc_stats.acl_tx++;
753 		goto start;
754 	}
755 
756 	/* Nothing to send */
757 	return;
758 
759 start:
760 	sc->sc_txp = m;
761 	sc->sc_flags |= BT3C_XMIT;
762 	bt3c_transmit(sc);
763 }
764 
765 static void
766 bt3c_output_cmd(device_t self, struct mbuf *m)
767 {
768 	struct bt3c_softc *sc = device_private(self);
769 	int s;
770 
771 	KASSERT(sc->sc_flags & BT3C_ENABLED);
772 
773 	M_SETCTX(m, NULL);
774 
775 	s = spltty();
776 	MBUFQ_ENQUEUE(&sc->sc_cmdq, m);
777 	if ((sc->sc_flags & BT3C_XMIT) == 0)
778 		bt3c_start(sc);
779 
780 	splx(s);
781 }
782 
783 static void
784 bt3c_output_acl(device_t self, struct mbuf *m)
785 {
786 	struct bt3c_softc *sc = device_private(self);
787 	int s;
788 
789 	KASSERT(sc->sc_flags & BT3C_ENABLED);
790 
791 	M_SETCTX(m, NULL);
792 
793 	s = spltty();
794 	MBUFQ_ENQUEUE(&sc->sc_aclq, m);
795 	if ((sc->sc_flags & BT3C_XMIT) == 0)
796 		bt3c_start(sc);
797 
798 	splx(s);
799 }
800 
801 static void
802 bt3c_output_sco(device_t self, struct mbuf *m)
803 {
804 	struct bt3c_softc *sc = device_private(self);
805 	int s;
806 
807 	KASSERT(sc->sc_flags & BT3C_ENABLED);
808 
809 	s = spltty();
810 	MBUFQ_ENQUEUE(&sc->sc_scoq, m);
811 	if ((sc->sc_flags & BT3C_XMIT) == 0)
812 		bt3c_start(sc);
813 
814 	splx(s);
815 }
816 
817 /*
818  * enable device
819  *	turn on card
820  *	load firmware
821  *	establish interrupts
822  */
823 static int
824 bt3c_enable(device_t self)
825 {
826 	struct bt3c_softc *sc = device_private(self);
827 	int err, s;
828 
829 	if (sc->sc_flags & BT3C_ENABLED)
830 		return 0;
831 
832 	s = spltty();
833 
834 	sc->sc_intr = pcmcia_intr_establish(sc->sc_pf, IPL_TTY, bt3c_intr, sc);
835 	if (sc->sc_intr == NULL) {
836 		err = EIO;
837 		goto bad;
838 	}
839 
840 	err = pcmcia_function_enable(sc->sc_pf);
841 	if (err)
842 		goto bad1;
843 
844 	err = bt3c_load_firmware(sc);
845 	if (err)
846 		goto bad2;
847 
848 	sc->sc_flags |= BT3C_ENABLED;
849 	sc->sc_flags &= ~BT3C_XMIT;
850 
851 	splx(s);
852 
853 	return 0;
854 
855 bad2:
856 	pcmcia_function_disable(sc->sc_pf);
857 bad1:
858 	pcmcia_intr_disestablish(sc->sc_pf, sc->sc_intr);
859 	sc->sc_intr = NULL;
860 bad:
861 	splx(s);
862 	return err;
863 }
864 
865 /*
866  * disable device
867  *	shut down card
868  *	disestablish interrupts
869  *	free held packets
870  */
871 static void
872 bt3c_disable(device_t self)
873 {
874 	struct bt3c_softc *sc = device_private(self);
875 	int s;
876 
877 	if ((sc->sc_flags & BT3C_ENABLED) == 0)
878 		return;
879 
880 	s = spltty();
881 
882 	pcmcia_function_disable(sc->sc_pf);
883 
884 	if (sc->sc_intr) {
885 		pcmcia_intr_disestablish(sc->sc_pf, sc->sc_intr);
886 		sc->sc_intr = NULL;
887 	}
888 
889 	if (sc->sc_rxp) {
890 		m_freem(sc->sc_rxp);
891 		sc->sc_rxp = NULL;
892 	}
893 
894 	if (sc->sc_txp) {
895 		m_freem(sc->sc_txp);
896 		sc->sc_txp = NULL;
897 	}
898 
899 	MBUFQ_DRAIN(&sc->sc_cmdq);
900 	MBUFQ_DRAIN(&sc->sc_aclq);
901 	MBUFQ_DRAIN(&sc->sc_scoq);
902 
903 	sc->sc_flags &= ~BT3C_ENABLED;
904 	splx(s);
905 }
906 
907 void
908 bt3c_stats(device_t self, struct bt_stats *dest, int flush)
909 {
910 	struct bt3c_softc *sc = device_private(self);
911 	int s;
912 
913 	s = spltty();
914 	memcpy(dest, &sc->sc_stats, sizeof(struct bt_stats));
915 
916 	if (flush)
917 		memset(&sc->sc_stats, 0, sizeof(struct bt_stats));
918 
919 	splx(s);
920 }
921 
922 /**************************************************************************
923  *
924  *	bt3c PCMCIA autoconfig glue
925  */
926 
927 static int
928 bt3c_match(device_t parent, struct cfdata *match, void *aux)
929 {
930 	struct pcmcia_attach_args *pa = aux;
931 
932 	if (pa->manufacturer == PCMCIA_VENDOR_3COM &&
933 	    pa->product == PCMCIA_PRODUCT_3COM_3CRWB6096)
934 	    return 10;		/* 'com' also claims this, so trump them */
935 
936 	return 0;
937 }
938 
939 static void
940 bt3c_attach(device_t parent, device_t self, void *aux)
941 {
942 	struct bt3c_softc *sc = device_private(self);
943 	struct pcmcia_attach_args *pa = aux;
944 	struct pcmcia_config_entry *cfe;
945 
946 	sc->sc_dev = self;
947 	sc->sc_pf = pa->pf;
948 
949 	MBUFQ_INIT(&sc->sc_cmdq);
950 	MBUFQ_INIT(&sc->sc_aclq);
951 	MBUFQ_INIT(&sc->sc_scoq);
952 
953 	/* Find a PCMCIA config entry we can use */
954 	SIMPLEQ_FOREACH(cfe, &pa->pf->cfe_head, cfe_list) {
955 		if (cfe->num_memspace != 0)
956 			continue;
957 
958 		if (cfe->num_iospace != 1)
959 			continue;
960 
961 		if (pcmcia_io_alloc(pa->pf, cfe->iospace[0].start,
962 				cfe->iospace[0].length, 0, &sc->sc_pcioh) == 0)
963 			break;
964 	}
965 
966 	if (cfe == 0) {
967 		aprint_error("bt3c_attach: cannot allocate io space\n");
968 		goto no_config_entry;
969 	}
970 
971 	/* Initialise it */
972 	pcmcia_function_init(pa->pf, cfe);
973 
974 	/* Map in the io space */
975 	if (pcmcia_io_map(pa->pf, PCMCIA_WIDTH_AUTO,
976 			&sc->sc_pcioh, &sc->sc_iow)) {
977 		aprint_error("bt3c_attach: cannot map io space\n");
978 		goto iomap_failed;
979 	}
980 
981 	/* Attach Bluetooth unit */
982 	sc->sc_unit = hci_attach(&bt3c_hci, self, BTF_POWER_UP_NOOP);
983 
984 	/* establish a power change hook */
985 	sc->sc_powerhook = powerhook_establish(device_xname(sc->sc_dev),
986 	    bt3c_power, sc);
987 	return;
988 
989 iomap_failed:
990 	/* unmap io space */
991 	pcmcia_io_free(pa->pf, &sc->sc_pcioh);
992 
993 no_config_entry:
994 	sc->sc_iow = -1;
995 }
996 
997 static int
998 bt3c_detach(device_t self, int flags)
999 {
1000 	struct bt3c_softc *sc = device_private(self);
1001 	int err = 0;
1002 
1003 	bt3c_disable(self);
1004 
1005 	if (sc->sc_powerhook) {
1006 		powerhook_disestablish(sc->sc_powerhook);
1007 		sc->sc_powerhook = NULL;
1008 	}
1009 
1010 	if (sc->sc_unit) {
1011 		hci_detach(sc->sc_unit);
1012 		sc->sc_unit = NULL;
1013 	}
1014 
1015 	if (sc->sc_iow != -1) {
1016 		pcmcia_io_unmap(sc->sc_pf, sc->sc_iow);
1017 		pcmcia_io_free(sc->sc_pf, &sc->sc_pcioh);
1018 		sc->sc_iow = -1;
1019 	}
1020 
1021 	return err;
1022 }
1023 
1024 static void
1025 bt3c_power(int why, void *arg)
1026 {
1027 	struct bt3c_softc *sc = arg;
1028 
1029 	switch(why) {
1030 	case PWR_SUSPEND:
1031 	case PWR_STANDBY:
1032 		if (sc->sc_flags & BT3C_ENABLED) {
1033 			if (sc->sc_unit) {
1034 				hci_detach(sc->sc_unit);
1035 				sc->sc_unit = NULL;
1036 			}
1037 
1038 			sc->sc_flags |= BT3C_SLEEPING;
1039 			aprint_verbose_dev(sc->sc_dev, "sleeping\n");
1040 		}
1041 		break;
1042 
1043 	case PWR_RESUME:
1044 		if (sc->sc_flags & BT3C_SLEEPING) {
1045 			aprint_verbose_dev(sc->sc_dev, "waking up\n");
1046 			sc->sc_flags &= ~BT3C_SLEEPING;
1047 
1048 			sc->sc_unit = hci_attach(&bt3c_hci, sc->sc_dev,
1049 			    BTF_POWER_UP_NOOP);
1050 		}
1051 		break;
1052 
1053 	case PWR_SOFTSUSPEND:
1054 	case PWR_SOFTSTANDBY:
1055 	case PWR_SOFTRESUME:
1056 		break;
1057 	}
1058 }
1059