1/*	$NetBSD: btl.c,v 1.23 2009/11/27 03:23:04 rmind Exp $	*/
2/*	NetBSD: bt.c,v 1.10 1996/05/12 23:51:54 mycroft Exp 	*/
3
4#undef BTDIAG
5#define integrate
6
7#define notyet /* XXX - #undef this, if this driver does actually work */
8
9/*
10 * Copyright (c) 1994, 1996 Charles M. Hannum.  All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 *    notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 *    notice, this list of conditions and the following disclaimer in the
19 *    documentation and/or other materials provided with the distribution.
20 * 3. All advertising materials mentioning features or use of this software
21 *    must display the following acknowledgement:
22 *	This product includes software developed by Charles M. Hannum.
23 * 4. The name of the author may not be used to endorse or promote products
24 *    derived from this software without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
27 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
28 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
29 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
30 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
31 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 */
37
38/*
39 * Originally written by Julian Elischer (julian@tfs.com)
40 * for TRW Financial Systems for use under the MACH(2.5) operating system.
41 *
42 * TRW Financial Systems, in accordance with their agreement with Carnegie
43 * Mellon University, makes this software available to CMU to distribute
44 * or use in any manner that they see fit as long as this message is kept with
45 * the software. For this reason TFS also grants any other persons or
46 * organisations permission to use or modify this software.
47 *
48 * TFS supplies this software to be publicly redistributed
49 * on the understanding that TFS is not responsible for the correct
50 * functioning of this software in any circumstances.
51 */
52
53#include <sys/cdefs.h>
54__KERNEL_RCSID(0, "$NetBSD: btl.c,v 1.23 2009/11/27 03:23:04 rmind Exp $");
55
56#include <sys/types.h>
57#include <sys/param.h>
58#include <sys/systm.h>
59#include <sys/kernel.h>
60#include <sys/errno.h>
61#include <sys/malloc.h>
62#include <sys/ioctl.h>
63#include <sys/device.h>
64#include <sys/buf.h>
65#include <sys/proc.h>
66
67#include <machine/intr.h>
68#include <machine/pio.h>
69
70#include <arc/dti/desktech.h>
71
72#include <dev/scsipi/scsi_all.h>
73#include <dev/scsipi/scsipi_all.h>
74#include <dev/scsipi/scsiconf.h>
75
76#include <dev/isa/isavar.h>
77#include <arc/dti/btlreg.h>
78#include <arc/dti/btlvar.h>
79
80#ifndef DDB
81#define Debugger() panic("should call debugger here (bt742a.c)")
82#endif /* ! DDB */
83
84/*
85 * Mail box defs  etc.
86 * these could be bigger but we need the bt_softc to fit on a single page..
87 */
88#define BT_MBX_SIZE	32	/* mail box size  (MAX 255 MBxs) */
89				/* don't need that many really */
90#define BT_CCB_MAX	32	/* store up to 32 CCBs at one time */
91#define	CCB_HASH_SIZE	32	/* hash table size for phystokv */
92#define	CCB_HASH_SHIFT	9
93#define CCB_HASH(x)	((((long)(x))>>CCB_HASH_SHIFT) & (CCB_HASH_SIZE - 1))
94
95#define bt_nextmbx(wmb, mbx, mbio) \
96	if ((wmb) == &(mbx)->mbio[BT_MBX_SIZE - 1])	\
97		(wmb) = &(mbx)->mbio[0];		\
98	else						\
99		(wmb)++;
100
101struct bt_mbx {
102	struct bt_mbx_out mbo[BT_MBX_SIZE];
103	struct bt_mbx_in mbi[BT_MBX_SIZE];
104	struct bt_mbx_out *cmbo;	/* Collection Mail Box out */
105	struct bt_mbx_out *tmbo;	/* Target Mail Box out */
106	struct bt_mbx_in *tmbi;		/* Target Mail Box in */
107};
108
109#define KVTOPHYS(x)	(*btl_conf->bc_kvtophys)((int)(x))
110#define PHYSTOKV(x)	(*btl_conf->bc_phystokv)((int)(x))
111
112struct bt_softc {
113	device_t sc_dev;
114	void *sc_ih;
115
116	int sc_iobase;
117	int sc_irq, sc_drq;
118
119	char sc_model[7],
120	     sc_firmware[6];
121
122	struct bt_mbx *sc_mbx;		/* all our mailboxes */
123#define	wmbx	(sc->sc_mbx)
124	struct bt_ccb *sc_ccbhash[CCB_HASH_SIZE];
125	TAILQ_HEAD(, bt_ccb) sc_free_ccb, sc_waiting_ccb;
126	TAILQ_HEAD(, bt_buf) sc_free_buf;
127	int sc_numccbs, sc_mbofull;
128	int sc_numbufs;
129	int sc_scsi_dev;		/* adapters scsi id */
130	struct scsipi_link sc_link;	/* prototype for devs */
131	struct scsipi_adapter sc_adapter;
132};
133
134#ifdef BTDEBUG
135int     bt_debug = 0;
136#endif /* BTDEBUG */
137
138int bt_cmd(int, struct bt_softc *, int, u_char *, int, u_char *);
139integrate void bt_finish_ccbs(struct bt_softc *);
140int btintr(void *);
141integrate void bt_reset_ccb(struct bt_softc *, struct bt_ccb *);
142void bt_free_ccb(struct bt_softc *, struct bt_ccb *);
143integrate void bt_init_ccb(struct bt_softc *, struct bt_ccb *);
144struct bt_ccb *bt_get_ccb(struct bt_softc *, int);
145struct bt_ccb *bt_ccb_phys_kv(struct bt_softc *, u_long);
146void bt_queue_ccb(struct bt_softc *, struct bt_ccb *);
147void bt_collect_mbo(struct bt_softc *);
148void bt_start_ccbs(struct bt_softc *);
149void bt_done(struct bt_softc *, struct bt_ccb *);
150int bt_find(struct isa_attach_args *, struct bt_softc *);
151void bt_init(struct bt_softc *);
152void bt_inquire_setup_information(struct bt_softc *);
153void btminphys(struct buf *);
154int bt_scsi_cmd(struct scsipi_xfer *);
155int bt_poll(struct bt_softc *, struct scsipi_xfer *, int);
156void bt_timeout(void *arg);
157void bt_free_buf(struct bt_softc *, struct bt_buf *);
158struct bt_buf * bt_get_buf(struct bt_softc *, int);
159
160/* the below structure is so we have a default dev struct for out link struct */
161struct scsipi_device bt_dev = {
162	NULL,			/* Use default error handler */
163	NULL,			/* have a queue, served by this */
164	NULL,			/* have no async handler */
165	NULL,			/* Use default 'done' routine */
166};
167
168static int	btprobe(device_t, cfdata_t, void *);
169static void	btattach(device_t, device_t, void *);
170
171CFATTACH_DECL_NEW(btl, sizeof(struct bt_softc),
172    btprobe, btattach, NULL, NULL);
173
174#define BT_RESET_TIMEOUT	2000	/* time to wait for reset (mSec) */
175#define	BT_ABORT_TIMEOUT	2000	/* time to wait for abort (mSec) */
176
177struct btl_config *btl_conf = NULL;
178
179/*
180 * bt_cmd(iobase, sc, icnt, ibuf, ocnt, obuf)
181 *
182 * Activate Adapter command
183 *    icnt:   number of args (outbound bytes including opcode)
184 *    ibuf:   argument buffer
185 *    ocnt:   number of expected returned bytes
186 *    obuf:   result buffer
187 *    wait:   number of seconds to wait for response
188 *
189 * Performs an adapter command through the ports.  Not to be confused with a
190 * scsi command, which is read in via the DMA; one of the adapter commands
191 * tells it to read in a scsi command.
192 */
193int
194bt_cmd(int iobase, struct bt_softc *sc, int icnt, int ocnt, u_char *ibuf,
195    u_char *obuf)
196{
197	const char *name;
198	int i;
199	int wait;
200	u_char sts;
201	u_char opcode = ibuf[0];
202
203	if (sc != NULL)
204		name = device_xname(sc->sc_dev);
205	else
206		name = "(bt probe)";
207
208	/*
209	 * Calculate a reasonable timeout for the command.
210	 */
211	switch (opcode) {
212	case BT_INQUIRE_DEVICES:
213		wait = 15 * 20000;
214		break;
215	default:
216		wait = 1 * 20000;
217		break;
218	}
219
220	/*
221	 * Wait for the adapter to go idle, unless it's one of
222	 * the commands which don't need this
223	 */
224	if (opcode != BT_MBO_INTR_EN) {
225		for (i = 20000; i; i--) {	/* 1 sec? */
226			sts = isa_inb(iobase + BT_STAT_PORT);
227			if (sts & BT_STAT_IDLE)
228				break;
229			delay(50);
230		}
231		if (!i) {
232			printf("%s: bt_cmd, host not idle(0x%x)\n",
233			    name, sts);
234			return ENXIO;
235		}
236	}
237	/*
238	 * Now that it is idle, if we expect output, preflush the
239	 * queue feeding to us.
240	 */
241	if (ocnt) {
242		while ((isa_inb(iobase + BT_STAT_PORT)) & BT_STAT_DF)
243			isa_inb(iobase + BT_DATA_PORT);
244	}
245	/*
246	 * Output the command and the number of arguments given
247	 * for each byte, first check the port is empty.
248	 */
249	while (icnt--) {
250		for (i = wait; i; i--) {
251			sts = isa_inb(iobase + BT_STAT_PORT);
252			if (!(sts & BT_STAT_CDF))
253				break;
254			delay(50);
255		}
256		if (!i) {
257			if (opcode != BT_INQUIRE_REVISION &&
258			    opcode != BT_INQUIRE_REVISION_3)
259				printf("%s: bt_cmd, cmd/data port full\n", name);
260			isa_outb(iobase + BT_CTRL_PORT, BT_CTRL_SRST);
261			return ENXIO;
262		}
263		isa_outb(iobase + BT_CMD_PORT, *ibuf++);
264	}
265	/*
266	 * If we expect input, loop that many times, each time,
267	 * looking for the data register to have valid data
268	 */
269	while (ocnt--) {
270		for (i = wait; i; i--) {
271			sts = isa_inb(iobase + BT_STAT_PORT);
272			if (sts & BT_STAT_DF)
273				break;
274			delay(50);
275		}
276		if (!i) {
277			if (opcode != BT_INQUIRE_REVISION &&
278			    opcode != BT_INQUIRE_REVISION_3)
279				printf("%s: bt_cmd, cmd/data port empty %d\n",
280				    name, ocnt);
281			isa_outb(iobase + BT_CTRL_PORT, BT_CTRL_SRST);
282			return ENXIO;
283		}
284		*obuf++ = isa_inb(iobase + BT_DATA_PORT);
285	}
286	/*
287	 * Wait for the board to report a finished instruction.
288	 * We may get an extra interrupt for the HACC signal, but this is
289	 * unimportant.
290	 */
291	if (opcode != BT_MBO_INTR_EN) {
292		for (i = 20000; i; i--) {	/* 1 sec? */
293			sts = isa_inb(iobase + BT_INTR_PORT);
294			/* XXX Need to save this in the interrupt handler? */
295			if (sts & BT_INTR_HACC)
296				break;
297			delay(50);
298		}
299		if (!i) {
300			printf("%s: bt_cmd, host not finished(0x%x)\n",
301			    name, sts);
302			return ENXIO;
303		}
304	}
305	isa_outb(iobase + BT_CTRL_PORT, BT_CTRL_IRST);
306	return 0;
307}
308
309/*
310 * Check if the device can be found at the port given
311 * and if so, set it up ready for further work
312 * as an argument, takes the isa_device structure from
313 * autoconf.c
314 */
315static int
316btprobe(device_t parent, cfdata_t cf, void *aux)
317{
318	struct isa_attach_args *ia = aux;
319
320#ifdef NEWCONFIG
321	if (ia->ia_iobase == IOBASEUNK)
322		return 0;
323#endif
324
325	if (btl_conf == NULL)
326		return (0);
327
328	/* See if there is a unit at this location. */
329	if (bt_find(ia, NULL) != 0)
330		return 0;
331
332	ia->ia_msize = 0;
333	ia->ia_iosize = 4;
334	/* IRQ and DRQ set by bt_find(). */
335	return 1;
336}
337
338/*
339 * Attach all the sub-devices we can find
340 */
341static void
342btattach(device_t parent, device_t self, void *aux)
343{
344	struct isa_attach_args *ia = aux;
345	struct bt_softc *sc = device_private(self);
346	struct bt_ccb *ccb;
347	struct bt_buf *buf;
348	u_int bouncearea;
349	u_int bouncebase;
350	u_int bouncesize;
351
352	sc->sc_dev = self;
353
354	if (bt_find(ia, sc) != 0)
355		panic("btattach: bt_find of %s failed", self->dv_xname);
356	sc->sc_iobase = ia->ia_iobase;
357
358	/*
359	 * create mbox area
360	 */
361	(*btl_conf->bc_bouncemem)(&bouncebase, &bouncesize);
362	bouncearea = bouncebase + sizeof(struct bt_mbx);
363	sc->sc_mbx = (struct bt_mbx *)bouncebase;
364
365	bt_inquire_setup_information(sc);
366	bt_init(sc);
367	TAILQ_INIT(&sc->sc_free_ccb);
368	TAILQ_INIT(&sc->sc_free_buf);
369	TAILQ_INIT(&sc->sc_waiting_ccb);
370
371	/*
372	 * fill up with ccb's
373	 */
374	while (sc->sc_numccbs < BT_CCB_MAX) {
375		ccb = (struct bt_ccb *)bouncearea;
376		bouncearea +=  sizeof(struct bt_ccb);
377		bt_init_ccb(sc, ccb);
378		TAILQ_INSERT_HEAD(&sc->sc_free_ccb, ccb, chain);
379		sc->sc_numccbs++;
380	}
381	/*
382	 * fill up with bufs's
383	 */
384	while ((bouncearea + sizeof(struct bt_buf)) < bouncebase + bouncesize) {
385		buf = (struct bt_buf *)bouncearea;
386		bouncearea +=  sizeof(struct bt_buf);
387		TAILQ_INSERT_HEAD(&sc->sc_free_buf, buf, chain);
388		sc->sc_numbufs++;
389	}
390	/*
391	 * Fill in the adapter.
392	 */
393	sc->sc_adapter.scsipi_cmd = bt_scsi_cmd;
394	sc->sc_adapter.scsipi_minphys = btminphys;
395	/*
396	 * fill in the prototype scsipi_link.
397	 */
398	sc->sc_link.scsipi_scsi.channel = SCSI_CHANNEL_ONLY_ONE;
399	sc->sc_link.adapter_softc = sc;
400	sc->sc_link.scsipi_scsi.adapter_target = sc->sc_scsi_dev;
401	sc->sc_link.adapter = &sc->sc_adapter;
402	sc->sc_link.device = &bt_dev;
403	sc->sc_link.openings = 1;
404	sc->sc_link.scsipi_scsi.max_target = 7;
405	sc->sc_link.scsipi_scsi.max_lun = 7;
406	sc->sc_link.type = BUS_SCSI;
407
408	sc->sc_ih = isa_intr_establish(ia->ia_ic, sc->sc_irq, IST_EDGE,
409	    IPL_BIO, btintr, sc);
410
411	/*
412	 * ask the adapter what subunits are present
413	 */
414	config_found(self, &sc->sc_link, scsiprint);
415}
416
417integrate void
418bt_finish_ccbs(struct bt_softc *sc)
419{
420	struct bt_mbx_in *wmbi;
421	struct bt_ccb *ccb;
422	int i;
423
424	wmbi = wmbx->tmbi;
425
426	if (wmbi->stat == BT_MBI_FREE) {
427		for (i = 0; i < BT_MBX_SIZE; i++) {
428			if (wmbi->stat != BT_MBI_FREE) {
429				printf("%s: mbi not in round-robin order\n",
430				    device_xname(sc->sc_dev));
431				goto AGAIN;
432			}
433			bt_nextmbx(wmbi, wmbx, mbi);
434		}
435#ifdef BTDIAGnot
436		printf("%s: mbi interrupt with no full mailboxes\n",
437		    device_xname(sc->sc_dev));
438#endif
439		return;
440	}
441
442AGAIN:
443	do {
444		ccb = bt_ccb_phys_kv(sc, phystol(wmbi->ccb_addr));
445		if (!ccb) {
446			printf("%s: bad mbi ccb pointer; skipping\n",
447			    device_xname(sc->sc_dev));
448			goto next;
449		}
450
451#ifdef BTDEBUG
452		if (bt_debug) {
453			u_char *cp = (u_char *) &ccb->scsi_cmd;
454			printf("op=%x %x %x %x %x %x\n",
455			    cp[0], cp[1], cp[2], cp[3], cp[4], cp[5]);
456			printf("stat %x for mbi addr = 0x%08x, ",
457			    wmbi->stat, wmbi);
458			printf("ccb addr = 0x%x\n", ccb);
459		}
460#endif /* BTDEBUG */
461
462		switch (wmbi->stat) {
463		case BT_MBI_OK:
464		case BT_MBI_ERROR:
465			if ((ccb->flags & CCB_ABORT) != 0) {
466				/*
467				 * If we already started an abort, wait for it
468				 * to complete before clearing the CCB.  We
469				 * could instead just clear CCB_SENDING, but
470				 * what if the mailbox was already received?
471				 * The worst that happens here is that we clear
472				 * the CCB a bit later than we need to.  BFD.
473				 */
474				goto next;
475			}
476			break;
477
478		case BT_MBI_ABORT:
479		case BT_MBI_UNKNOWN:
480			/*
481			 * Even if the CCB wasn't found, we clear it anyway.
482			 * See preceding comment.
483			 */
484			break;
485
486		default:
487			printf("%s: bad mbi status %02x; skipping\n",
488			    device_xname(sc->sc_dev), wmbi->stat);
489			goto next;
490		}
491
492		callout_stop(&ccb->xs->xs_callout);
493		bt_done(sc, ccb);
494
495	next:
496		wmbi->stat = BT_MBI_FREE;
497		bt_nextmbx(wmbi, wmbx, mbi);
498	} while (wmbi->stat != BT_MBI_FREE);
499
500	wmbx->tmbi = wmbi;
501}
502
503/*
504 * Catch an interrupt from the adaptor
505 */
506int
507btintr(void *arg)
508{
509	struct bt_softc *sc = arg;
510	int iobase = sc->sc_iobase;
511	u_char sts;
512
513#ifdef BTDEBUG
514	printf("%s: btintr ", device_xname(sc->sc_dev));
515#endif /* BTDEBUG */
516
517	/*
518	 * First acknowlege the interrupt, Then if it's not telling about
519	 * a completed operation just return.
520	 */
521	sts = isa_inb(iobase + BT_INTR_PORT);
522	if ((sts & BT_INTR_ANYINTR) == 0)
523		return 0;
524	isa_outb(iobase + BT_CTRL_PORT, BT_CTRL_IRST);
525
526#ifdef BTDIAG
527	/* Make sure we clear CCB_SENDING before finishing a CCB. */
528	bt_collect_mbo(sc);
529#endif
530
531	/* Mail box out empty? */
532	if (sts & BT_INTR_MBOA) {
533		struct bt_toggle toggle;
534
535		toggle.cmd.opcode = BT_MBO_INTR_EN;
536		toggle.cmd.enable = 0;
537		bt_cmd(iobase, sc, sizeof(toggle.cmd), (u_char *)&toggle.cmd, 0,
538		    (u_char *)0);
539		bt_start_ccbs(sc);
540	}
541
542	/* Mail box in full? */
543	if (sts & BT_INTR_MBIF)
544		bt_finish_ccbs(sc);
545
546	return 1;
547}
548
549integrate void
550bt_reset_ccb(struct bt_softc *sc, struct bt_ccb *ccb)
551{
552
553	ccb->flags = 0;
554}
555
556/*
557 * A ccb is put onto the free list.
558 */
559void
560bt_free_ccb(struct bt_softc *sc, struct bt_ccb *ccb)
561{
562	int s;
563
564	s = splbio();
565
566	bt_reset_ccb(sc, ccb);
567	TAILQ_INSERT_HEAD(&sc->sc_free_ccb, ccb, chain);
568
569	/*
570	 * If there were none, wake anybody waiting for one to come free,
571	 * starting with queued entries.
572	 */
573	if (ccb->chain.tqe_next == 0)
574		wakeup(&sc->sc_free_ccb);
575
576	splx(s);
577}
578
579/*
580 * A buf is put onto the free list.
581 */
582void
583bt_free_buf(struct bt_softc *sc, struct bt_buf *buf)
584{
585	int s;
586
587	s = splbio();
588
589	TAILQ_INSERT_HEAD(&sc->sc_free_buf, buf, chain);
590	sc->sc_numbufs++;
591
592	/*
593	 * If there were none, wake anybody waiting for one to come free,
594	 * starting with queued entries.
595	 */
596	if (buf->chain.tqe_next == 0)
597		wakeup(&sc->sc_free_buf);
598
599	splx(s);
600}
601
602integrate void
603bt_init_ccb(struct bt_softc *sc, struct bt_ccb *ccb)
604{
605	int hashnum;
606
607	memset(ccb, 0, sizeof(struct bt_ccb));
608	/*
609	 * put in the phystokv hash table
610	 * Never gets taken out.
611	 */
612	ccb->hashkey = KVTOPHYS(ccb);
613	hashnum = CCB_HASH(ccb->hashkey);
614	ccb->nexthash = sc->sc_ccbhash[hashnum];
615	sc->sc_ccbhash[hashnum] = ccb;
616	bt_reset_ccb(sc, ccb);
617}
618
619/*
620 * Get a free ccb
621 *
622 * If there are none, either return an error or sleep.
623 */
624struct bt_ccb *
625bt_get_ccb(struct bt_softc *sc, int nosleep)
626{
627	struct bt_ccb *ccb;
628	int s;
629
630	s = splbio();
631
632	/*
633	 * If we can and have to, sleep waiting for one to come free.
634	 */
635	for (;;) {
636		ccb = sc->sc_free_ccb.tqh_first;
637		if (ccb) {
638			TAILQ_REMOVE(&sc->sc_free_ccb, ccb, chain);
639			break;
640		}
641		if (nosleep)
642			goto out;
643		tsleep(&sc->sc_free_ccb, PRIBIO, "btccb", 0);
644	}
645
646	ccb->flags |= CCB_ALLOC;
647
648out:
649	splx(s);
650	return ccb;
651}
652
653/*
654 * Get a free buf
655 *
656 * If there are none, either return an error or sleep.
657 */
658struct bt_buf *
659bt_get_buf(struct bt_softc *sc, int nosleep)
660{
661	struct bt_buf *buf;
662	int s;
663
664	s = splbio();
665
666	/*
667	 * If we can and have to, sleep waiting for one to come free.
668	 */
669	for (;;) {
670		buf = sc->sc_free_buf.tqh_first;
671		if (buf) {
672			TAILQ_REMOVE(&sc->sc_free_buf, buf, chain);
673			sc->sc_numbufs--;
674			break;
675		}
676		if (nosleep)
677			goto out;
678		tsleep(&sc->sc_free_buf, PRIBIO, "btbuf", 0);
679	}
680
681out:
682	splx(s);
683	return buf;
684}
685
686/*
687 * Given a physical address, find the ccb that it corresponds to.
688 */
689struct bt_ccb *
690bt_ccb_phys_kv(struct bt_softc *sc, u_long ccb_phys)
691{
692	int hashnum = CCB_HASH(ccb_phys);
693	struct bt_ccb *ccb = sc->sc_ccbhash[hashnum];
694
695	while (ccb) {
696		if (ccb->hashkey == ccb_phys)
697			break;
698		ccb = ccb->nexthash;
699	}
700	return ccb;
701}
702
703/*
704 * Queue a CCB to be sent to the controller, and send it if possible.
705 */
706void
707bt_queue_ccb(struct bt_softc *sc, struct bt_ccb *ccb)
708{
709
710	TAILQ_INSERT_TAIL(&sc->sc_waiting_ccb, ccb, chain);
711	bt_start_ccbs(sc);
712}
713
714/*
715 * Garbage collect mailboxes that are no longer in use.
716 */
717void
718bt_collect_mbo(struct bt_softc *sc)
719{
720	struct bt_mbx_out *wmbo;	/* Mail Box Out pointer */
721
722	wmbo = wmbx->cmbo;
723
724	while (sc->sc_mbofull > 0) {
725		if (wmbo->cmd != BT_MBO_FREE)
726			break;
727
728#ifdef BTDIAG
729		ccb = bt_ccb_phys_kv(sc, phystol(wmbo->ccb_addr));
730		ccb->flags &= ~CCB_SENDING;
731#endif
732
733		--sc->sc_mbofull;
734		bt_nextmbx(wmbo, wmbx, mbo);
735	}
736
737	wmbx->cmbo = wmbo;
738}
739
740/*
741 * Send as many CCBs as we have empty mailboxes for.
742 */
743void
744bt_start_ccbs(struct bt_softc *sc)
745{
746	int iobase = sc->sc_iobase;
747	struct bt_mbx_out *wmbo;	/* Mail Box Out pointer */
748	struct bt_ccb *ccb;
749
750	wmbo = wmbx->tmbo;
751
752	while ((ccb = sc->sc_waiting_ccb.tqh_first) != NULL) {
753		if (sc->sc_mbofull >= BT_MBX_SIZE) {
754			bt_collect_mbo(sc);
755			if (sc->sc_mbofull >= BT_MBX_SIZE) {
756				struct bt_toggle toggle;
757
758				toggle.cmd.opcode = BT_MBO_INTR_EN;
759				toggle.cmd.enable = 1;
760				bt_cmd(iobase, sc, sizeof(toggle.cmd),
761				    (u_char *)&toggle.cmd, 0, (u_char *)0);
762				break;
763			}
764		}
765
766		TAILQ_REMOVE(&sc->sc_waiting_ccb, ccb, chain);
767#ifdef BTDIAG
768		ccb->flags |= CCB_SENDING;
769#endif
770
771		/* Link ccb to mbo. */
772		ltophys(KVTOPHYS(ccb), wmbo->ccb_addr);
773		if (ccb->flags & CCB_ABORT)
774			wmbo->cmd = BT_MBO_ABORT;
775		else
776			wmbo->cmd = BT_MBO_START;
777
778		/* Tell the card to poll immediately. */
779		isa_outb(iobase + BT_CMD_PORT, BT_START_SCSI);
780
781		if ((ccb->xs->xs_control & XS_CTL_POLL) == 0)
782			callout_reset(&ccb->xs->xs_callout,
783			    mstohz(ccb->timeout), bt_timeout, ccb);
784
785		++sc->sc_mbofull;
786		bt_nextmbx(wmbo, wmbx, mbo);
787	}
788
789	wmbx->tmbo = wmbo;
790}
791
792/*
793 * We have a ccb which has been processed by the
794 * adaptor, now we look to see how the operation
795 * went. Wake up the owner if waiting
796 */
797void
798bt_done(struct bt_softc *sc, struct bt_ccb *ccb)
799{
800	struct scsi_sense_data *s1, *s2;
801	struct scsipi_xfer *xs = ccb->xs;
802
803	u_long thiskv, thisbounce;
804	int bytes_this_page, datalen;
805	struct bt_scat_gath *sg;
806	int seg;
807
808	SC_DEBUG(xs->sc_link, SDEV_DB2, ("bt_done\n"));
809	/*
810	 * Otherwise, put the results of the operation
811	 * into the xfer and call whoever started it
812	 */
813#ifdef BTDIAG
814	if (ccb->flags & CCB_SENDING) {
815		printf("%s: exiting ccb still in transit!\n",
816		    device_xname(sc->sc_dev));
817		Debugger();
818		return;
819	}
820#endif
821	if ((ccb->flags & CCB_ALLOC) == 0) {
822		printf("%s: exiting ccb not allocated!\n",
823		    device_xname(sc->sc_dev));
824		Debugger();
825		return;
826	}
827	if (xs->error == XS_NOERROR) {
828		if (ccb->host_stat != BT_OK) {
829			switch (ccb->host_stat) {
830			case BT_SEL_TIMEOUT:	/* No response */
831				xs->error = XS_SELTIMEOUT;
832				break;
833			default:	/* Other scsi protocol messes */
834				printf("%s: host_stat %x\n",
835				    device_xname(sc->sc_dev), ccb->host_stat);
836				xs->error = XS_DRIVER_STUFFUP;
837				break;
838			}
839		} else if (ccb->target_stat != SCSI_OK) {
840			switch (ccb->target_stat) {
841			case SCSI_CHECK:
842				s1 = &ccb->scsi_sense;
843				s2 = &xs->sense.scsi_sense;
844				*s2 = *s1;
845				xs->error = XS_SENSE;
846				break;
847			case SCSI_BUSY:
848				xs->error = XS_BUSY;
849				break;
850			default:
851				printf("%s: target_stat %x\n",
852				    device_xname(sc->sc_dev), ccb->target_stat);
853				xs->error = XS_DRIVER_STUFFUP;
854				break;
855			}
856		} else
857			xs->resid = 0;
858	}
859
860	if((datalen = xs->datalen) != 0) {
861		thiskv = (int)xs->data;
862		sg = ccb->scat_gath;
863		seg = phystol(ccb->data_length) / sizeof(struct bt_scat_gath);
864
865		while (seg) {
866			thisbounce = PHYSTOKV(phystol(sg->seg_addr));
867			bytes_this_page = phystol(sg->seg_len);
868			if(xs->xs_control & XS_CTL_DATA_IN) {
869				memcpy((void *)thiskv, (void *)thisbounce, bytes_this_page);
870			}
871			bt_free_buf(sc, (struct bt_buf *)thisbounce);
872			thiskv += bytes_this_page;
873			datalen -= bytes_this_page;
874
875			sg++;
876			seg--;
877		}
878	}
879
880	bt_free_ccb(sc, ccb);
881	xs->xs_status |= XS_STS_DONE;
882	scsipi_done(xs);
883}
884
885/*
886 * Find the board and find it's irq/drq
887 */
888int
889bt_find(struct isa_attach_args *ia, struct bt_softc *sc)
890{
891	int iobase = ia->ia_iobase;
892	int i;
893	u_char sts;
894	struct bt_extended_inquire inquire;
895	struct bt_config config;
896	int irq, drq;
897
898#ifndef notyet
899	/* Check something is at the ports we need to access */
900	sts = isa_inb(iobase + BHA_STAT_PORT);
901	if (sts == 0xFF)
902		return (0);
903#endif
904
905	/*
906	 * reset board, If it doesn't respond, assume
907	 * that it's not there.. good for the probe
908	 */
909
910	isa_outb(iobase + BT_CTRL_PORT, BT_CTRL_HRST | BT_CTRL_SRST);
911
912	delay(100);
913	for (i = BT_RESET_TIMEOUT; i; i--) {
914		sts = isa_inb(iobase + BT_STAT_PORT);
915		if (sts == (BT_STAT_IDLE | BT_STAT_INIT))
916			break;
917		delay(1000);
918	}
919	if (!i) {
920#ifdef BTDEBUG
921		if (bt_debug)
922			printf("bt_find: No answer from buslogic board\n");
923#endif /* BTDEBUG */
924		return 1;
925	}
926
927#ifndef notyet
928	/*
929	 * The BusLogic cards implement an Adaptec 1542 (aha)-compatible
930	 * interface. The native bha interface is not compatible with
931	 * an aha. 1542. We need to ensure that we never match an
932	 * Adaptec 1542. We must also avoid sending Adaptec-compatible
933	 * commands to a real bha, lest it go into 1542 emulation mode.
934	 * (On an indirect bus like ISA, we should always probe for BusLogic
935	 * interfaces before Adaptec interfaces).
936	 */
937
938	/*
939	 * Make sure we don't match an AHA-1542A or AHA-1542B, by checking
940	 * for an extended-geometry register.  The 1542[AB] don't have one.
941	 */
942	sts = isa_inb(iobase +  BT_EXTGEOM_PORT);
943	if (sts == 0xFF)
944		return (0);
945#endif /* notyet */
946
947	/*
948	 * Check that we actually know how to use this board.
949	 */
950	delay(1000);
951	memset(&inquire, 0, sizeof inquire);
952	inquire.cmd.opcode = BT_INQUIRE_EXTENDED;
953	inquire.cmd.len = sizeof(inquire.reply);
954	i = bt_cmd(iobase, sc, sizeof(inquire.cmd), (u_char *)&inquire.cmd,
955	    sizeof(inquire.reply), (u_char *)&inquire.reply);
956
957#ifndef notyet
958	/*
959	 * Some 1542Cs (CP, perhaps not CF, may depend on firmware rev)
960	 * have the extended-geometry register and also respond to
961	 * BHA_INQUIRE_EXTENDED.  Make sure we never match such cards,
962	 * by checking the size of the reply is what a BusLogic card returns.
963	 */
964	if (i) { /* XXX - this doesn't really check the size. ??? see bha.c */
965#ifdef BTDEBUG
966		printf("bt_find: board returned %d instead of %d to %s\n",
967		       i, sizeof(inquire.reply), "INQUIRE_EXTENDED");
968#endif
969		return (0);
970	}
971
972	/* OK, we know we've found a buslogic adaptor. */
973#endif /* notyet */
974
975	switch (inquire.reply.bus_type) {
976	case BT_BUS_TYPE_24BIT:
977	case BT_BUS_TYPE_32BIT:
978		break;
979	case BT_BUS_TYPE_MCA:
980		/* We don't grok MicroChannel (yet). */
981		return 1;
982	default:
983		printf("bt_find: illegal bus type %c\n", inquire.reply.bus_type);
984		return 1;
985	}
986
987	/*
988	 * Assume we have a board at this stage setup DMA channel from
989	 * jumpers and save int level
990	 */
991	delay(1000);
992	config.cmd.opcode = BT_INQUIRE_CONFIG;
993	bt_cmd(iobase, sc, sizeof(config.cmd), (u_char *)&config.cmd,
994	    sizeof(config.reply), (u_char *)&config.reply);
995	switch (config.reply.chan) {
996	case EISADMA:
997		drq = DRQUNK;
998		break;
999	case CHAN0:
1000		drq = 0;
1001		break;
1002	case CHAN5:
1003		drq = 5;
1004		break;
1005	case CHAN6:
1006		drq = 6;
1007		break;
1008	case CHAN7:
1009		drq = 7;
1010		break;
1011	default:
1012		printf("bt_find: illegal drq setting %x\n", config.reply.chan);
1013		return 1;
1014	}
1015
1016	switch (config.reply.intr) {
1017	case INT9:
1018		irq = 9;
1019		break;
1020	case INT10:
1021		irq = 10;
1022		break;
1023	case INT11:
1024		irq = 11;
1025		break;
1026	case INT12:
1027		irq = 12;
1028		break;
1029	case INT14:
1030		irq = 14;
1031		break;
1032	case INT15:
1033		irq = 15;
1034		break;
1035	default:
1036		printf("bt_find: illegal irq setting %x\n", config.reply.intr);
1037		return 1;
1038	}
1039
1040	if (sc != NULL) {
1041		/* who are we on the scsi bus? */
1042		sc->sc_scsi_dev = config.reply.scsi_dev;
1043
1044		sc->sc_iobase = iobase;
1045		sc->sc_irq = irq;
1046		sc->sc_drq = drq;
1047	} else {
1048		if (ia->ia_irq == IRQUNK)
1049			ia->ia_irq = irq;
1050		else if (ia->ia_irq != irq)
1051			return 1;
1052		if (ia->ia_drq == DRQUNK)
1053			ia->ia_drq = drq;
1054		else if (ia->ia_drq != drq)
1055			return 1;
1056	}
1057
1058	return 0;
1059}
1060
1061/*
1062 * Start the board, ready for normal operation
1063 */
1064void
1065bt_init(struct bt_softc *sc)
1066{
1067	int iobase = sc->sc_iobase;
1068	struct bt_devices devices;
1069	struct bt_setup setup;
1070	struct bt_mailbox mailbox;
1071	struct bt_period period;
1072	int i;
1073
1074	/* Enable round-robin scheme - appeared at firmware rev. 3.31. */
1075	if (strcmp(sc->sc_firmware, "3.31") >= 0) {
1076		struct bt_toggle toggle;
1077
1078		toggle.cmd.opcode = BT_ROUND_ROBIN;
1079		toggle.cmd.enable = 1;
1080		bt_cmd(iobase, sc, sizeof(toggle.cmd), (u_char *)&toggle.cmd,
1081		    0, (u_char *)0);
1082	}
1083
1084	/* Inquire Installed Devices (to force synchronous negotiation). */
1085	devices.cmd.opcode = BT_INQUIRE_DEVICES;
1086	bt_cmd(iobase, sc, sizeof(devices.cmd), (u_char *)&devices.cmd,
1087	    sizeof(devices.reply), (u_char *)&devices.reply);
1088
1089	/* Obtain setup information from. */
1090	setup.cmd.opcode = BT_INQUIRE_SETUP;
1091	setup.cmd.len = sizeof(setup.reply);
1092	bt_cmd(iobase, sc, sizeof(setup.cmd), (u_char *)&setup.cmd,
1093	    sizeof(setup.reply), (u_char *)&setup.reply);
1094
1095	printf("%s: %s, %s\n",
1096	    device_xname(sc->sc_dev),
1097	    setup.reply.sync_neg ? "sync" : "async",
1098	    setup.reply.parity ? "parity" : "no parity");
1099
1100	for (i = 0; i < 8; i++)
1101		period.reply.period[i] = setup.reply.sync[i].period * 5 + 20;
1102
1103	if (sc->sc_firmware[0] >= '3') {
1104		period.cmd.opcode = BT_INQUIRE_PERIOD;
1105		period.cmd.len = sizeof(period.reply);
1106		bt_cmd(iobase, sc, sizeof(period.cmd), (u_char *)&period.cmd,
1107		    sizeof(period.reply), (u_char *)&period.reply);
1108	}
1109
1110	for (i = 0; i < 8; i++) {
1111		if (!setup.reply.sync[i].valid ||
1112		    (!setup.reply.sync[i].offset && !setup.reply.sync[i].period))
1113			continue;
1114		printf("%s targ %d: sync, offset %d, period %dnsec\n",
1115		    device_xname(sc->sc_dev), i,
1116		    setup.reply.sync[i].offset, period.reply.period[i] * 10);
1117	}
1118
1119	/*
1120	 * Set up initial mail box for round-robin operation.
1121	 */
1122	for (i = 0; i < BT_MBX_SIZE; i++) {
1123		wmbx->mbo[i].cmd = BT_MBO_FREE;
1124		wmbx->mbi[i].stat = BT_MBI_FREE;
1125	}
1126	wmbx->cmbo = wmbx->tmbo = &wmbx->mbo[0];
1127	wmbx->tmbi = &wmbx->mbi[0];
1128	sc->sc_mbofull = 0;
1129
1130	/* Initialize mail box. */
1131	mailbox.cmd.opcode = BT_MBX_INIT_EXTENDED;
1132	mailbox.cmd.nmbx = BT_MBX_SIZE;
1133	ltophys(KVTOPHYS(wmbx), mailbox.cmd.addr);
1134	bt_cmd(iobase, sc, sizeof(mailbox.cmd), (u_char *)&mailbox.cmd,
1135	    0, (u_char *)0);
1136}
1137
1138void
1139bt_inquire_setup_information(struct bt_softc *sc)
1140{
1141	int iobase = sc->sc_iobase;
1142	struct bt_model model;
1143	struct bt_revision revision;
1144	struct bt_digit digit;
1145	char *p;
1146
1147	/*
1148	 * Get the firmware revision.
1149	 */
1150	p = sc->sc_firmware;
1151	revision.cmd.opcode = BT_INQUIRE_REVISION;
1152	bt_cmd(iobase, sc, sizeof(revision.cmd), (u_char *)&revision.cmd,
1153	    sizeof(revision.reply), (u_char *)&revision.reply);
1154	*p++ = revision.reply.firm_revision;
1155	*p++ = '.';
1156	*p++ = revision.reply.firm_version;
1157	digit.cmd.opcode = BT_INQUIRE_REVISION_3;
1158	bt_cmd(iobase, sc, sizeof(digit.cmd), (u_char *)&digit.cmd,
1159	    sizeof(digit.reply), (u_char *)&digit.reply);
1160	*p++ = digit.reply.digit;
1161	if (revision.reply.firm_revision >= '3' ||
1162	    (revision.reply.firm_revision == '3' && revision.reply.firm_version >= '3')) {
1163		digit.cmd.opcode = BT_INQUIRE_REVISION_4;
1164		bt_cmd(iobase, sc, sizeof(digit.cmd), (u_char *)&digit.cmd,
1165		    sizeof(digit.reply), (u_char *)&digit.reply);
1166		*p++ = digit.reply.digit;
1167	}
1168	while (p > sc->sc_firmware && (p[-1] == ' ' || p[-1] == '\0'))
1169		p--;
1170	*p = '\0';
1171
1172	/*
1173	 * Get the model number.
1174	 */
1175	if (revision.reply.firm_revision >= '3') {
1176		p = sc->sc_model;
1177		model.cmd.opcode = BT_INQUIRE_MODEL;
1178		model.cmd.len = sizeof(model.reply);
1179		bt_cmd(iobase, sc, sizeof(model.cmd), (u_char *)&model.cmd,
1180		    sizeof(model.reply), (u_char *)&model.reply);
1181		*p++ = model.reply.id[0];
1182		*p++ = model.reply.id[1];
1183		*p++ = model.reply.id[2];
1184		*p++ = model.reply.id[3];
1185		while (p > sc->sc_model && (p[-1] == ' ' || p[-1] == '\0'))
1186			p--;
1187		*p++ = model.reply.version[0];
1188		*p++ = model.reply.version[1];
1189		while (p > sc->sc_model && (p[-1] == ' ' || p[-1] == '\0'))
1190			p--;
1191		*p = '\0';
1192	} else
1193		strcpy(sc->sc_model, "542B");
1194
1195	printf(": model BT-%s, firmware %s\n", sc->sc_model, sc->sc_firmware);
1196}
1197
1198void
1199btminphys(struct buf *bp)
1200{
1201
1202	if (bp->b_bcount > ((BT_NSEG - 1) << PGSHIFT))
1203		bp->b_bcount = ((BT_NSEG - 1) << PGSHIFT);
1204	minphys(bp);
1205}
1206
1207/*
1208 * start a scsi operation given the command and the data address.  Also needs
1209 * the unit, target and lu.
1210 */
1211int
1212bt_scsi_cmd(struct scsipi_xfer *xs)
1213{
1214	struct scsipi_link *sc_link = xs->sc_link;
1215	struct bt_softc *sc = sc_link->adapter_softc;
1216	struct bt_ccb *ccb;
1217	struct bt_scat_gath *sg;
1218	int seg;		/* scatter gather seg being worked on */
1219	u_long thiskv, thisbounce;
1220	int bytes_this_page, datalen, control;
1221	int s;
1222
1223	SC_DEBUG(sc_link, SDEV_DB2, ("bt_scsi_cmd\n"));
1224	/*
1225	 * get a ccb to use. If the transfer
1226	 * is from a buf (possibly from interrupt time)
1227	 * then we can't allow it to sleep
1228	 */
1229	control = xs->xs_control;
1230	if ((ccb = bt_get_ccb(sc, control & XS_CTL_NOSLEEP)) == NULL) {
1231		xs->error = XS_DRIVER_STUFFUP;
1232		return TRY_AGAIN_LATER;
1233	}
1234	ccb->xs = xs;
1235	ccb->timeout = xs->timeout;
1236
1237	/*
1238	 * Put all the arguments for the xfer in the ccb
1239	 */
1240	if (control & XS_CTL_RESET) {
1241		ccb->opcode = BT_RESET_CCB;
1242		ccb->scsi_cmd_length = 0;
1243	} else {
1244		/* can't use S/G if zero length */
1245		if (xs->cmdlen > sizeof(ccb->scsi_cmd)) {
1246			printf("%s: cmdlen %d too large for CCB\n",
1247			    device_xname(sc->sc_dev), xs->cmdlen);
1248			xs->error = XS_DRIVER_STUFFUP;
1249			bt_free_ccb(sc, ccb);
1250			return COMPLETE;
1251		}
1252		ccb->opcode = (xs->datalen ? BT_INIT_SCAT_GATH_CCB
1253					   : BT_INITIATOR_CCB);
1254		memcpy(&ccb->scsi_cmd, xs->cmd,
1255		    ccb->scsi_cmd_length = xs->cmdlen);
1256	}
1257
1258	if (xs->datalen) {
1259		sg = ccb->scat_gath;
1260		seg = 0;
1261		/*
1262		 * Set up the scatter-gather block.
1263		 */
1264		SC_DEBUG(sc_link, SDEV_DB4,
1265		    ("%d @0x%x:- ", xs->datalen, xs->data));
1266
1267		datalen = xs->datalen;
1268		thiskv = (int)xs->data;
1269
1270		while (datalen && seg < BT_NSEG) {
1271
1272			/* put in the base address of a buf */
1273			thisbounce = (u_long)
1274				bt_get_buf(sc, control & XS_CTL_NOSLEEP);
1275			if(thisbounce == 0)
1276				break;
1277			ltophys(KVTOPHYS(thisbounce), sg->seg_addr);
1278			bytes_this_page = min(sizeof(struct bt_buf), datalen);
1279			if (control & XS_CTL_DATA_OUT) {
1280				memcpy((void *)thisbounce, (void *)thiskv, bytes_this_page);
1281			}
1282			thiskv += bytes_this_page;
1283			datalen -= bytes_this_page;
1284
1285			ltophys(bytes_this_page, sg->seg_len);
1286			sg++;
1287			seg++;
1288		}
1289		SC_DEBUGN(sc_link, SDEV_DB4, ("\n"));
1290		if (datalen) {
1291			printf("%s: bt_scsi_cmd, out of bufs %d of %d left.\n",
1292			    device_xname(sc->sc_dev), datalen, xs->datalen);
1293			goto badbuf;
1294		}
1295		ltophys(KVTOPHYS(ccb->scat_gath), ccb->data_addr);
1296		ltophys(seg * sizeof(struct bt_scat_gath), ccb->data_length);
1297	} else {		/* No data xfer, use non S/G values */
1298		ltophys(0, ccb->data_addr);
1299		ltophys(0, ccb->data_length);
1300	}
1301
1302	ccb->data_out = 0;
1303	ccb->data_in = 0;
1304	ccb->target = sc_link->scsipi_scsi.target;
1305	ccb->lun = sc_link->scsipi_scsi.lun;
1306	ltophys(KVTOPHYS(&ccb->scsi_sense), ccb->sense_ptr);
1307	ccb->req_sense_length = sizeof(ccb->scsi_sense);
1308	ccb->host_stat = 0x00;
1309	ccb->target_stat = 0x00;
1310	ccb->link_id = 0;
1311	ltophys(0, ccb->link_addr);
1312
1313	s = splbio();
1314	bt_queue_ccb(sc, ccb);
1315	splx(s);
1316
1317	/*
1318	 * Usually return SUCCESSFULLY QUEUED
1319	 */
1320	SC_DEBUG(sc_link, SDEV_DB3, ("cmd_sent\n"));
1321	if ((control & XS_CTL_POLL) == 0)
1322		return SUCCESSFULLY_QUEUED;
1323
1324	/*
1325	 * If we can't use interrupts, poll on completion
1326	 */
1327	if (bt_poll(sc, xs, ccb->timeout)) {
1328		bt_timeout(ccb);
1329		if (bt_poll(sc, xs, ccb->timeout))
1330			bt_timeout(ccb);
1331	}
1332	return COMPLETE;
1333
1334badbuf:
1335	sg = ccb->scat_gath;
1336	while (seg) {
1337		thisbounce = PHYSTOKV(phystol(sg->seg_addr));
1338		bt_free_buf(sc, (struct bt_buf *)thisbounce);
1339		sg++;
1340		seg--;
1341	}
1342	xs->error = XS_DRIVER_STUFFUP;
1343	bt_free_ccb(sc, ccb);
1344	return TRY_AGAIN_LATER;
1345}
1346
1347/*
1348 * Poll a particular unit, looking for a particular xs
1349 */
1350int
1351bt_poll(struct bt_softc *sc, struct scsipi_xfer *xs, int count)
1352{
1353	int iobase = sc->sc_iobase;
1354
1355	/* timeouts are in msec, so we loop in 1000 usec cycles */
1356	while (count) {
1357		/*
1358		 * If we had interrupts enabled, would we
1359		 * have got an interrupt?
1360		 */
1361		if (isa_inb(iobase + BT_INTR_PORT) & BT_INTR_ANYINTR)
1362			btintr(sc);
1363		if (xs->xs_status & XS_STS_DONE)
1364			return 0;
1365		delay(1000);	/* only happens in boot so ok */
1366		count--;
1367	}
1368	return 1;
1369}
1370
1371void
1372bt_timeout(void *arg)
1373{
1374	struct bt_ccb *ccb = arg;
1375	struct scsipi_xfer *xs = ccb->xs;
1376	struct scsipi_link *sc_link = xs->sc_link;
1377	struct bt_softc *sc = sc_link->adapter_softc;
1378	int s;
1379
1380	scsi_print_addr(sc_link);
1381	printf("timed out");
1382
1383	s = splbio();
1384
1385#ifdef BTDIAG
1386	/*
1387	 * If the ccb's mbx is not free, then the board has gone Far East?
1388	 */
1389	bt_collect_mbo(sc);
1390	if (ccb->flags & CCB_SENDING) {
1391		printf("%s: not taking commands!\n", device_xname(sc->sc_dev));
1392		Debugger();
1393	}
1394#endif
1395
1396	/*
1397	 * If it has been through before, then
1398	 * a previous abort has failed, don't
1399	 * try abort again
1400	 */
1401	if (ccb->flags & CCB_ABORT) {
1402		/* abort timed out */
1403		printf(" AGAIN\n");
1404		/* XXX Must reset! */
1405	} else {
1406		/* abort the operation that has timed out */
1407		printf("\n");
1408		ccb->xs->error = XS_TIMEOUT;
1409		ccb->timeout = BT_ABORT_TIMEOUT;
1410		ccb->flags |= CCB_ABORT;
1411		bt_queue_ccb(sc, ccb);
1412	}
1413
1414	splx(s);
1415}
1416