1 /*	$OpenBSD: aha.c,v 1.51 2003/04/27 11:22:53 ho Exp $	*/
2 /*	$NetBSD: aha.c,v 1.11 1996/05/12 23:51:23 mycroft Exp $	*/
3 
4 #undef AHADIAG
5 
6 /*
7  * Copyright (c) 1994, 1996 Charles M. Hannum.  All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. All advertising materials mentioning features or use of this software
18  *    must display the following acknowledgement:
19  *	This product includes software developed by Charles M. Hannum.
20  * 4. The name of the author may not be used to endorse or promote products
21  *    derived from this software without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  */
34 
35 /*
36  * Originally written by Julian Elischer (julian@tfs.com)
37  * for TRW Financial Systems for use under the MACH(2.5) operating system.
38  *
39  * TRW Financial Systems, in accordance with their agreement with Carnegie
40  * Mellon University, makes this software available to CMU to distribute
41  * or use in any manner that they see fit as long as this message is kept with
42  * the software. For this reason TFS also grants any other persons or
43  * organisations permission to use or modify this software.
44  *
45  * TFS supplies this software to be publicly redistributed
46  * on the understanding that TFS is not responsible for the correct
47  * functioning of this software in any circumstances.
48  */
49 
50 #include <sys/types.h>
51 #include <sys/param.h>
52 #include <sys/systm.h>
53 #include <sys/kernel.h>
54 #include <sys/errno.h>
55 #include <sys/ioctl.h>
56 #include <sys/device.h>
57 #include <sys/malloc.h>
58 #include <sys/buf.h>
59 #include <sys/proc.h>
60 #include <sys/user.h>
61 #include <sys/timeout.h>
62 
63 #include <uvm/uvm.h>
64 #include <uvm/uvm_extern.h>
65 
66 #include <machine/intr.h>
67 #include <machine/bus.h>
68 
69 #include <scsi/scsi_all.h>
70 #include <scsi/scsiconf.h>
71 
72 #include <dev/isa/isavar.h>
73 #include <dev/isa/isadmavar.h>
74 #include <dev/isa/ahareg.h>
75 
76 #ifndef DDB
77 #define Debugger() panic("should call debugger here (aha1542.c)")
78 #endif /* ! DDB */
79 
80 /* XXX fixme:
81  * on i386 at least, xfers to/from user memory
82  * cannot be serviced at interrupt time.
83  */
84 #ifdef i386
85 #define VOLATILE_XS(xs) \
86 	((xs)->datalen > 0 && (xs)->bp == NULL && \
87 	((xs)->flags & SCSI_POLL) == 0)
88 #else
89 #define VOLATILE_XS(xs)        0
90 #endif
91 
92 /*
93  * Mail box defs  etc.
94  * these could be bigger but we need the aha_softc to fit on a single page..
95  */
96 #define AHA_MBX_SIZE	16	/* mail box size */
97 
98 #define	AHA_CCB_MAX	16	/* store up to 32 CCBs at one time */
99 #define	CCB_HASH_SIZE	16	/* hash table size for phystokv */
100 #define	CCB_HASH_SHIFT	9
101 #define	CCB_HASH(x)	((((long)(x))>>CCB_HASH_SHIFT) & (CCB_HASH_SIZE - 1))
102 
103 #define aha_nextmbx(wmb, mbx, mbio) \
104 	if ((wmb) == &(mbx)->mbio[AHA_MBX_SIZE - 1])	\
105 		(wmb) = &(mbx)->mbio[0];		\
106 	else						\
107 		(wmb)++;
108 
109 struct aha_mbx {
110 	struct aha_mbx_out mbo[AHA_MBX_SIZE];
111 	struct aha_mbx_in mbi[AHA_MBX_SIZE];
112 	struct aha_mbx_out *cmbo;	/* Collection Mail Box out */
113 	struct aha_mbx_out *tmbo;	/* Target Mail Box out */
114 	struct aha_mbx_in *tmbi;	/* Target Mail Box in */
115 };
116 
117 struct aha_softc {
118 	struct device sc_dev;
119 	struct isadev sc_id;
120 	void *sc_ih;
121 	bus_dma_tag_t sc_dmat;
122 
123 	int sc_iobase;
124 	int sc_irq, sc_drq;
125 
126 	char sc_model[18],
127 	     sc_firmware[4];
128 
129 	struct aha_mbx *sc_mbx;		/* all the mailboxes */
130 #define	wmbx	(sc->sc_mbx)
131 	struct aha_ccb *sc_ccbhash[CCB_HASH_SIZE];
132 	TAILQ_HEAD(, aha_ccb) sc_free_ccb, sc_waiting_ccb;
133 	int sc_numccbs, sc_mbofull;
134 	int sc_scsi_dev;		/* our scsi id */
135 	struct scsi_link sc_link;
136 };
137 
138 #ifdef AHADEBUG
139 int	aha_debug = 1;
140 #endif /* AHADEBUG */
141 
142 int aha_cmd(int, struct aha_softc *, int, u_char *, int, u_char *);
143 void aha_finish_ccbs(struct aha_softc *);
144 int ahaintr(void *);
145 void aha_reset_ccb(struct aha_softc *, struct aha_ccb *);
146 void aha_free_ccb(struct aha_softc *, struct aha_ccb *);
147 int aha_init_ccb(struct aha_softc *, struct aha_ccb *, int);
148 struct aha_ccb *aha_get_ccb(struct aha_softc *, int);
149 struct aha_ccb *aha_ccb_phys_kv(struct aha_softc *, u_long);
150 void aha_queue_ccb(struct aha_softc *, struct aha_ccb *);
151 void aha_collect_mbo(struct aha_softc *);
152 void aha_start_ccbs(struct aha_softc *);
153 void aha_done(struct aha_softc *, struct aha_ccb *);
154 int aha_find(struct isa_attach_args *, struct aha_softc *, int);
155 void aha_init(struct aha_softc *);
156 void aha_inquire_setup_information(struct aha_softc *);
157 void ahaminphys(struct buf *);
158 int aha_scsi_cmd(struct scsi_xfer *);
159 int aha_poll(struct aha_softc *, struct scsi_xfer *, int);
160 void aha_timeout(void *arg);
161 
162 struct scsi_adapter aha_switch = {
163 	aha_scsi_cmd,
164 	ahaminphys,
165 	0,
166 	0,
167 };
168 
169 /* the below structure is so we have a default dev struct for out link struct */
170 struct scsi_device aha_dev = {
171 	NULL,			/* Use default error handler */
172 	NULL,			/* have a queue, served by this */
173 	NULL,			/* have no async handler */
174 	NULL,			/* Use default 'done' routine */
175 };
176 
177 int	aha_isapnp_probe(struct device *, void *, void *);
178 int	ahaprobe(struct device *, void *, void *);
179 void	ahaattach(struct device *, struct device *, void *);
180 
181 struct cfattach aha_isapnp_ca = {
182 	sizeof(struct aha_softc), aha_isapnp_probe, ahaattach
183 };
184 
185 struct cfattach aha_isa_ca = {
186 	sizeof(struct aha_softc), ahaprobe, ahaattach
187 };
188 
189 struct cfdriver aha_cd = {
190 	NULL, "aha", DV_DULL
191 };
192 
193 #define AHA_RESET_TIMEOUT	2000	/* time to wait for reset (mSec) */
194 #define	AHA_ABORT_TIMEOUT	2000	/* time to wait for abort (mSec) */
195 
196 #include "bha.h"
197 
198 /*
199  * aha_cmd(iobase, sc, icnt, ibuf, ocnt, obuf)
200  *
201  * Activate Adapter command
202  *    icnt:   number of args (outbound bytes including opcode)
203  *    ibuf:   argument buffer
204  *    ocnt:   number of expected returned bytes
205  *    obuf:   result buffer
206  *    wait:   number of seconds to wait for response
207  *
208  * Performs an adapter command through the ports.  Not to be confused with a
209  * scsi command, which is read in via the dma; one of the adapter commands
210  * tells it to read in a scsi command.
211  */
212 int
aha_cmd(iobase,sc,icnt,ibuf,ocnt,obuf)213 aha_cmd(iobase, sc, icnt, ibuf, ocnt, obuf)
214 	int iobase;
215 	struct aha_softc *sc;
216 	int icnt, ocnt;
217 	u_char *ibuf, *obuf;
218 {
219 	const char *name;
220 	register int i;
221 	int wait;
222 	u_char sts;
223 	u_char opcode = ibuf[0];
224 
225 	if (sc != NULL)
226 		name = sc->sc_dev.dv_xname;
227 	else
228 		name = "(aha probe)";
229 
230 	/*
231 	 * Calculate a reasonable timeout for the command.
232 	 */
233 	switch (opcode) {
234 	case AHA_INQUIRE_DEVICES:
235 		wait = 15 * 20000;
236 		break;
237 	default:
238 		wait = 1 * 20000;
239 		break;
240 	}
241 
242 	/*
243 	 * Wait for the adapter to go idle, unless it's one of
244 	 * the commands which don't need this
245 	 */
246 	if (opcode != AHA_MBO_INTR_EN) {
247 		for (i = 20000; i; i--) {	/* 1 sec? */
248 			sts = inb(iobase + AHA_STAT_PORT);
249 			if (sts & AHA_STAT_IDLE)
250 				break;
251 			delay(50);
252 		}
253 		if (!i) {
254 			printf("%s: aha_cmd, host not idle(0x%x)\n",
255 			    name, sts);
256 			return (ENXIO);
257 		}
258 	}
259 	/*
260 	 * Now that it is idle, if we expect output, preflush the
261 	 * queue feeding to us.
262 	 */
263 	if (ocnt) {
264 		while ((inb(iobase + AHA_STAT_PORT)) & AHA_STAT_DF)
265 			inb(iobase + AHA_DATA_PORT);
266 	}
267 	/*
268 	 * Output the command and the number of arguments given
269 	 * for each byte, first check the port is empty.
270 	 */
271 	while (icnt--) {
272 		for (i = wait; i; i--) {
273 			sts = inb(iobase + AHA_STAT_PORT);
274 			if (!(sts & AHA_STAT_CDF))
275 				break;
276 			delay(50);
277 		}
278 		if (!i) {
279 			if (opcode != AHA_INQUIRE_REVISION)
280 				printf("%s: aha_cmd, cmd/data port full\n",
281 				    name);
282 			outb(iobase + AHA_CTRL_PORT, AHA_CTRL_SRST);
283 			return (ENXIO);
284 		}
285 		outb(iobase + AHA_CMD_PORT, *ibuf++);
286 	}
287 	/*
288 	 * If we expect input, loop that many times, each time,
289 	 * looking for the data register to have valid data
290 	 */
291 	while (ocnt--) {
292 		for (i = wait; i; i--) {
293 			sts = inb(iobase + AHA_STAT_PORT);
294 			if (sts & AHA_STAT_DF)
295 				break;
296 			delay(50);
297 		}
298 		if (!i) {
299 			if (opcode != AHA_INQUIRE_REVISION)
300 				printf("%s: aha_cmd, cmd/data port empty %d\n",
301 				    name, ocnt);
302 			outb(iobase + AHA_CTRL_PORT, AHA_CTRL_SRST);
303 			return (ENXIO);
304 		}
305 		*obuf++ = inb(iobase + AHA_DATA_PORT);
306 	}
307 	/*
308 	 * Wait for the board to report a finished instruction.
309 	 * We may get an extra interrupt for the HACC signal, but this is
310 	 * unimportant.
311 	 */
312 	if (opcode != AHA_MBO_INTR_EN) {
313 		for (i = 20000; i; i--) {	/* 1 sec? */
314 			sts = inb(iobase + AHA_INTR_PORT);
315 			/* XXX Need to save this in the interrupt handler? */
316 			if (sts & AHA_INTR_HACC)
317 				break;
318 			delay(50);
319 		}
320 		if (!i) {
321 			printf("%s: aha_cmd, host not finished(0x%x)\n",
322 			    name, sts);
323 			return (ENXIO);
324 		}
325 	}
326 	outb(iobase + AHA_CTRL_PORT, AHA_CTRL_IRST);
327 	return (0);
328 }
329 
330 int
aha_isapnp_probe(parent,match,aux)331 aha_isapnp_probe(parent, match, aux)
332 	struct device *parent;
333 	void *match, *aux;
334 {
335 	return (1);
336 }
337 
338 
339 /*
340  * Check if the device can be found at the port given
341  * and if so, set it up ready for further work
342  * as an argument, takes the isa_device structure from
343  * autoconf.c
344  */
345 int
ahaprobe(parent,match,aux)346 ahaprobe(parent, match, aux)
347 	struct device *parent;
348 	void *match, *aux;
349 {
350 	register struct isa_attach_args *ia = aux;
351 #if NBHA > 0
352 	extern int btports[], nbtports;
353 	int i;
354 
355 	for (i = 0; i < nbtports; i++)
356 		if (btports[i] == ia->ia_iobase)
357 			return (0);
358 #endif
359 
360 	/* See if there is a unit at this location. */
361 	if (aha_find(ia, NULL, 0) != 0)
362 		return (0);
363 
364 	ia->ia_msize = 0;
365 	ia->ia_iosize = 4;
366 	/* IRQ and DRQ set by aha_find(). */
367 	return (1);
368 }
369 
370 /*
371  * Attach all the sub-devices we can find
372  */
373 void
ahaattach(parent,self,aux)374 ahaattach(parent, self, aux)
375 	struct device *parent, *self;
376 	void *aux;
377 {
378 	struct isa_attach_args *ia = aux;
379 	struct aha_softc *sc = (void *)self;
380 	int isapnp = !strcmp(parent->dv_cfdata->cf_driver->cd_name, "isapnp");
381 
382 	if (isapnp) {
383 		ia->ia_iobase = ia->ipa_io[0].base;
384 		isadma_cascade(ia->ia_drq);
385 	}
386 
387 	if (aha_find(ia, sc, isapnp) != 0)
388 		panic("ahaattach: aha_find of %s failed", self->dv_xname);
389 	sc->sc_iobase = ia->ia_iobase;
390 	sc->sc_dmat = ia->ia_dmat;
391 
392 	if (sc->sc_drq != DRQUNK && isapnp == 0)
393 		isadma_cascade(sc->sc_drq);
394 
395 	aha_inquire_setup_information(sc);
396 	aha_init(sc);
397 	TAILQ_INIT(&sc->sc_free_ccb);
398 	TAILQ_INIT(&sc->sc_waiting_ccb);
399 
400 	/*
401 	 * fill in the prototype scsi_link.
402 	 */
403 	sc->sc_link.adapter_softc = sc;
404 	sc->sc_link.adapter_target = sc->sc_scsi_dev;
405 	sc->sc_link.adapter = &aha_switch;
406 	sc->sc_link.device = &aha_dev;
407 	sc->sc_link.openings = 2;
408 
409 	sc->sc_ih = isa_intr_establish(ia->ia_ic, sc->sc_irq, IST_EDGE,
410 	    IPL_BIO, ahaintr, sc, sc->sc_dev.dv_xname);
411 
412 	/*
413 	 * ask the adapter what subunits are present
414 	 */
415 	config_found(self, &sc->sc_link, scsiprint);
416 }
417 
418 void
aha_finish_ccbs(sc)419 aha_finish_ccbs(sc)
420 	struct aha_softc *sc;
421 {
422 	struct aha_mbx_in *wmbi;
423 	struct aha_ccb *ccb;
424 	int i;
425 
426 	wmbi = wmbx->tmbi;
427 
428 	if (wmbi->stat == AHA_MBI_FREE) {
429 		for (i = 0; i < AHA_MBX_SIZE; i++) {
430 			if (wmbi->stat != AHA_MBI_FREE) {
431 				printf("%s: mbi not in round-robin order\n",
432 				    sc->sc_dev.dv_xname);
433 				goto AGAIN;
434 			}
435 			aha_nextmbx(wmbi, wmbx, mbi);
436 		}
437 #ifdef AHADIAGnot
438 		printf("%s: mbi interrupt with no full mailboxes\n",
439 		    sc->sc_dev.dv_xname);
440 #endif
441 		return;
442 	}
443 
444 AGAIN:
445 	do {
446 		ccb = aha_ccb_phys_kv(sc, phystol(wmbi->ccb_addr));
447 		if (!ccb) {
448 			printf("%s: bad mbi ccb pointer; skipping\n",
449 			    sc->sc_dev.dv_xname);
450 			goto next;
451 		}
452 
453 #ifdef AHADEBUG
454 		if (aha_debug) {
455 			u_char *cp = (u_char *)&ccb->scsi_cmd;
456 			printf("op=%x %x %x %x %x %x\n",
457 			    cp[0], cp[1], cp[2], cp[3], cp[4], cp[5]);
458 			printf("stat %x for mbi addr = 0x%08x, ",
459 			    wmbi->stat, wmbi);
460 			printf("ccb addr = 0x%x\n", ccb);
461 		}
462 #endif /* AHADEBUG */
463 
464 		switch (wmbi->stat) {
465 		case AHA_MBI_OK:
466 		case AHA_MBI_ERROR:
467 			if ((ccb->flags & CCB_ABORT) != 0) {
468 				/*
469 				 * If we already started an abort, wait for it
470 				 * to complete before clearing the CCB.  We
471 				 * could instead just clear CCB_SENDING, but
472 				 * what if the mailbox was already received?
473 				 * The worst that happens here is that we clear
474 				 * the CCB a bit later than we need to.  BFD.
475 				 */
476 				goto next;
477 			}
478 			break;
479 
480 		case AHA_MBI_ABORT:
481 		case AHA_MBI_UNKNOWN:
482 			/*
483 			 * Even if the CCB wasn't found, we clear it anyway.
484 			 * See preceeding comment.
485 			 */
486 			break;
487 
488 		default:
489 			printf("%s: bad mbi status %02x; skipping\n",
490 			    sc->sc_dev.dv_xname, wmbi->stat);
491 			goto next;
492 		}
493 
494 		if ((ccb->xs->flags & SCSI_POLL) == 0)
495 			timeout_del(&ccb->xs->stimeout);
496 		bus_dmamap_sync(sc->sc_dmat, ccb->ccb_dmam, 0,
497 		    ccb->ccb_dmam->dm_mapsize, BUS_DMASYNC_POSTREAD);
498 		aha_done(sc, ccb);
499 
500 	next:
501 		wmbi->stat = AHA_MBI_FREE;
502 		aha_nextmbx(wmbi, wmbx, mbi);
503 	} while (wmbi->stat != AHA_MBI_FREE);
504 
505 	wmbx->tmbi = wmbi;
506 }
507 
508 /*
509  * Catch an interrupt from the adaptor
510  */
511 int
ahaintr(arg)512 ahaintr(arg)
513 	void *arg;
514 {
515 	struct aha_softc *sc = arg;
516 	int iobase = sc->sc_iobase;
517 	u_char sts;
518 
519 #ifdef AHADEBUG
520 	if (aha_debug)
521 		printf("%s: ahaintr ", sc->sc_dev.dv_xname);
522 #endif /*AHADEBUG */
523 
524 	/*
525 	 * First acknowlege the interrupt, Then if it's not telling about
526 	 * a completed operation just return.
527 	 */
528 	sts = inb(iobase + AHA_INTR_PORT);
529 	if ((sts & AHA_INTR_ANYINTR) == 0)
530 		return (0);
531 	outb(iobase + AHA_CTRL_PORT, AHA_CTRL_IRST);
532 
533 #ifdef AHADIAG
534 	/* Make sure we clear CCB_SENDING before finishing a CCB. */
535 	aha_collect_mbo(sc);
536 #endif
537 
538 	/* Mail box out empty? */
539 	if (sts & AHA_INTR_MBOA) {
540 		struct aha_toggle toggle;
541 
542 		toggle.cmd.opcode = AHA_MBO_INTR_EN;
543 		toggle.cmd.enable = 0;
544 		aha_cmd(iobase, sc, sizeof(toggle.cmd), (u_char *)&toggle.cmd,
545 		    0, (u_char *)0);
546 		aha_start_ccbs(sc);
547 	}
548 
549 	/* Mail box in full? */
550 	if (sts & AHA_INTR_MBIF)
551 		aha_finish_ccbs(sc);
552 
553 	return (1);
554 }
555 
556 void
aha_reset_ccb(sc,ccb)557 aha_reset_ccb(sc, ccb)
558 	struct aha_softc *sc;
559 	struct aha_ccb *ccb;
560 {
561 
562 	ccb->flags = 0;
563 }
564 
565 /*
566  * A ccb is put onto the free list.
567  */
568 void
aha_free_ccb(sc,ccb)569 aha_free_ccb(sc, ccb)
570 	struct aha_softc *sc;
571 	struct aha_ccb *ccb;
572 {
573 	int s, hashnum;
574 	struct aha_ccb **hashccb;
575 
576 	s = splbio();
577 
578 	if (ccb->ccb_dmam->dm_segs[0].ds_addr != 0)
579 		bus_dmamap_unload(sc->sc_dmat, ccb->ccb_dmam);
580 
581 	/* remove from hash table */
582 
583 	hashnum = CCB_HASH(ccb->ccb_dmam->dm_segs[0].ds_addr);
584 	hashccb = &sc->sc_ccbhash[hashnum];
585 
586 	while (*hashccb) {
587 		if ((*hashccb)->ccb_dmam->dm_segs[0].ds_addr ==
588 		    ccb->ccb_dmam->dm_segs[0].ds_addr) {
589 			*hashccb = (*hashccb)->nexthash;
590 			break;
591 		}
592 		hashccb = &(*hashccb)->nexthash;
593 	}
594 
595 	aha_reset_ccb(sc, ccb);
596 	TAILQ_INSERT_HEAD(&sc->sc_free_ccb, ccb, chain);
597 
598 	/*
599 	 * If there were none, wake anybody waiting for one to come free,
600 	 * starting with queued entries.
601 	 */
602 	if (ccb->chain.tqe_next == 0)
603 		wakeup(&sc->sc_free_ccb);
604 
605 	splx(s);
606 }
607 
608 int
aha_init_ccb(sc,ccb,flags)609 aha_init_ccb(sc, ccb, flags)
610 	struct aha_softc *sc;
611 	struct aha_ccb *ccb;
612 	int flags;
613 {
614 	int error, wait, state = 0;
615 
616 	bzero(ccb, sizeof(struct aha_ccb));
617 	aha_reset_ccb(sc, ccb);
618 
619 	wait = (flags & SCSI_NOSLEEP) ? BUS_DMA_NOWAIT : BUS_DMA_WAITOK;
620 	/* Create a DMA map for the data area.  */
621 	error = bus_dmamap_create(sc->sc_dmat, MAXPHYS, (MAXPHYS / NBPG) + 1,
622 	    MAXPHYS, 0, wait | BUS_DMA_ALLOCNOW, &ccb->dmam);
623 	if (error)
624 		goto fail;
625 	state++;
626 
627 	/* Create a DMA map for the command control block.  */
628 	error = bus_dmamap_create(sc->sc_dmat, CCB_PHYS_SIZE, 1, CCB_PHYS_SIZE,
629 	    0, wait | BUS_DMA_ALLOCNOW, &ccb->ccb_dmam);
630 	if (error)
631 		goto fail;
632 
633 	return (0);
634 
635  fail:
636 	if (state > 0)
637 		bus_dmamap_destroy(sc->sc_dmat, ccb->dmam);
638 	return (error);
639 }
640 
641 /*
642  * Get a free ccb
643  *
644  * If there are none, see if we can allocate a new one.  If so, put it in
645  * the hash table too otherwise either return an error or sleep.
646  */
647 struct aha_ccb *
aha_get_ccb(sc,flags)648 aha_get_ccb(sc, flags)
649 	struct aha_softc *sc;
650 	int flags;
651 {
652 	struct aha_ccb *ccb;
653 	int hashnum, s;
654 
655 	s = splbio();
656 
657 	/*
658 	 * If we can and have to, sleep waiting for one to come free
659 	 * but only if we can't allocate a new one.
660 	 */
661 	for (;;) {
662 		ccb = sc->sc_free_ccb.tqh_first;
663 		if (ccb) {
664 			TAILQ_REMOVE(&sc->sc_free_ccb, ccb, chain);
665 			break;
666 		}
667 		if (sc->sc_numccbs < AHA_CCB_MAX) {
668 			MALLOC(ccb, struct aha_ccb *, sizeof *ccb, M_DEVBUF,
669 			    (flags & SCSI_NOSLEEP) ? M_NOWAIT : M_WAITOK);
670 			if (ccb == NULL) {
671 				printf("%s: can't malloc ccb\n",
672 				    sc->sc_dev.dv_xname);
673 				goto out;
674 			}
675 			if (aha_init_ccb(sc, ccb, flags) == 0) {
676 				sc->sc_numccbs++;
677 				break;
678 			}
679 			FREE(ccb, M_DEVBUF);
680 			ccb = NULL;
681 		}
682 		if (flags & SCSI_NOSLEEP)
683 			goto out;
684 		tsleep(&sc->sc_free_ccb, PRIBIO, "ahaccb", 0);
685 	}
686 
687 	ccb->flags |= CCB_ALLOC;
688 
689 	if (bus_dmamap_load(sc->sc_dmat, ccb->ccb_dmam, ccb, CCB_PHYS_SIZE,
690 	    NULL, BUS_DMA_NOWAIT) != 0) {
691 		aha_free_ccb(sc, ccb);
692 		ccb = NULL;
693 	} else {
694 		hashnum = CCB_HASH(ccb->ccb_dmam->dm_segs[0].ds_addr);
695 		ccb->nexthash = sc->sc_ccbhash[hashnum];
696 		sc->sc_ccbhash[hashnum] = ccb;
697 	}
698 out:
699 	splx(s);
700 	return (ccb);
701 }
702 
703 /*
704  * Given a physical address, find the ccb that it corresponds to.
705  */
706 struct aha_ccb *
aha_ccb_phys_kv(sc,ccb_phys)707 aha_ccb_phys_kv(sc, ccb_phys)
708 	struct aha_softc *sc;
709 	u_long ccb_phys;
710 {
711 	int hashnum = CCB_HASH(ccb_phys);
712 	struct aha_ccb *ccb = sc->sc_ccbhash[hashnum];
713 
714 	while (ccb) {
715 		if (ccb->ccb_dmam->dm_segs[0].ds_addr == ccb_phys)
716 			break;
717 		ccb = ccb->nexthash;
718 	}
719 	return (ccb);
720 }
721 
722 /*
723  * Queue a CCB to be sent to the controller, and send it if possible.
724  */
725 void
aha_queue_ccb(sc,ccb)726 aha_queue_ccb(sc, ccb)
727 	struct aha_softc *sc;
728 	struct aha_ccb *ccb;
729 {
730 
731 	TAILQ_INSERT_TAIL(&sc->sc_waiting_ccb, ccb, chain);
732 	aha_start_ccbs(sc);
733 }
734 
735 /*
736  * Garbage collect mailboxes that are no longer in use.
737  */
738 void
aha_collect_mbo(sc)739 aha_collect_mbo(sc)
740 	struct aha_softc *sc;
741 {
742 	struct aha_mbx_out *wmbo;	/* Mail Box Out pointer */
743 #ifdef AHADIAG
744 	struct aha_ccb *ccb;
745 #endif
746 
747 	wmbo = wmbx->cmbo;
748 
749 	while (sc->sc_mbofull > 0) {
750 		if (wmbo->cmd != AHA_MBO_FREE)
751 			break;
752 
753 #ifdef AHADIAG
754 		ccb = aha_ccb_phys_kv(sc, phystol(wmbo->ccb_addr));
755 		if (!ccb) {
756 			printf("%s: bad mbo ccb pointer; skipping\n",
757 			    sc->sc_dev.dv_xname);
758 		} else
759 			ccb->flags &= ~CCB_SENDING;
760 #endif
761 
762 		--sc->sc_mbofull;
763 		aha_nextmbx(wmbo, wmbx, mbo);
764 	}
765 
766 	wmbx->cmbo = wmbo;
767 }
768 
769 /*
770  * Send as many CCBs as we have empty mailboxes for.
771  */
772 void
aha_start_ccbs(sc)773 aha_start_ccbs(sc)
774 	struct aha_softc *sc;
775 {
776 	int iobase = sc->sc_iobase;
777 	struct aha_mbx_out *wmbo;	/* Mail Box Out pointer */
778 	struct aha_ccb *ccb;
779 
780 	wmbo = wmbx->tmbo;
781 
782 	while ((ccb = sc->sc_waiting_ccb.tqh_first) != NULL) {
783 		if (sc->sc_mbofull >= AHA_MBX_SIZE) {
784 			aha_collect_mbo(sc);
785 			if (sc->sc_mbofull >= AHA_MBX_SIZE) {
786 				struct aha_toggle toggle;
787 
788 				toggle.cmd.opcode = AHA_MBO_INTR_EN;
789 				toggle.cmd.enable = 1;
790 				aha_cmd(iobase, sc, sizeof(toggle.cmd),
791 				    (u_char *)&toggle.cmd, 0, (u_char *)0);
792 				break;
793 			}
794 		}
795 
796 		TAILQ_REMOVE(&sc->sc_waiting_ccb, ccb, chain);
797 #ifdef AHADIAG
798 		ccb->flags |= CCB_SENDING;
799 #endif
800 
801 		/* Link ccb to mbo. */
802 		bus_dmamap_sync(sc->sc_dmat, ccb->ccb_dmam, 0,
803 		    ccb->ccb_dmam->dm_mapsize, BUS_DMASYNC_PREWRITE);
804 		ltophys(ccb->ccb_dmam->dm_segs[0].ds_addr, wmbo->ccb_addr);
805 		if (ccb->flags & CCB_ABORT)
806 			wmbo->cmd = AHA_MBO_ABORT;
807 		else
808 			wmbo->cmd = AHA_MBO_START;
809 
810 		/* Tell the card to poll immediately. */
811 		outb(iobase + AHA_CMD_PORT, AHA_START_SCSI);
812 
813 		if ((ccb->xs->flags & SCSI_POLL) == 0) {
814 			timeout_set(&ccb->xs->stimeout, aha_timeout, ccb);
815 			timeout_add(&ccb->xs->stimeout, (ccb->timeout * hz) / 1000);
816 		}
817 
818 		++sc->sc_mbofull;
819 		aha_nextmbx(wmbo, wmbx, mbo);
820 	}
821 
822 	wmbx->tmbo = wmbo;
823 }
824 
825 /*
826  * We have a ccb which has been processed by the
827  * adaptor, now we look to see how the operation
828  * went. Wake up the owner if waiting
829  */
830 void
aha_done(sc,ccb)831 aha_done(sc, ccb)
832 	struct aha_softc *sc;
833 	struct aha_ccb *ccb;
834 {
835 	struct scsi_sense_data *s1, *s2;
836 	struct scsi_xfer *xs = ccb->xs;
837 
838 	SC_DEBUG(xs->sc_link, SDEV_DB2, ("aha_done\n"));
839 	/*
840 	 * Otherwise, put the results of the operation
841 	 * into the xfer and call whoever started it
842 	 */
843 #ifdef AHADIAG
844 	if (ccb->flags & CCB_SENDING) {
845 		printf("%s: exiting ccb still in transit!\n",
846 		    sc->sc_dev.dv_xname);
847 		Debugger();
848 		return;
849 	}
850 #endif
851 	if ((ccb->flags & CCB_ALLOC) == 0) {
852 		printf("%s: exiting ccb not allocated!\n",
853 		    sc->sc_dev.dv_xname);
854 		Debugger();
855 		return;
856 	}
857 	if (xs->error == XS_NOERROR) {
858 		if (ccb->host_stat != AHA_OK) {
859 			switch (ccb->host_stat) {
860 			case AHA_SEL_TIMEOUT:	/* No response */
861 				xs->error = XS_SELTIMEOUT;
862 				break;
863 			default:	/* Other scsi protocol messes */
864 				printf("%s: host_stat %x\n",
865 				    sc->sc_dev.dv_xname, ccb->host_stat);
866 				xs->error = XS_DRIVER_STUFFUP;
867 				break;
868 			}
869 		} else if (ccb->target_stat != SCSI_OK) {
870 			switch (ccb->target_stat) {
871 			case SCSI_CHECK:
872 				s1 = (struct scsi_sense_data *)
873 				    (((char *)(&ccb->scsi_cmd)) +
874 				    ccb->scsi_cmd_length);
875 				s2 = &xs->sense;
876 				*s2 = *s1;
877 				xs->error = XS_SENSE;
878 				break;
879 			case SCSI_BUSY:
880 				xs->error = XS_BUSY;
881 				break;
882 			default:
883 				printf("%s: target_stat %x\n",
884 				    sc->sc_dev.dv_xname, ccb->target_stat);
885 				xs->error = XS_DRIVER_STUFFUP;
886 				break;
887 			}
888 		} else
889 			xs->resid = 0;
890 	}
891 	xs->flags |= ITSDONE;
892 
893 	if (VOLATILE_XS(xs)) {
894 		wakeup(ccb);
895 		return;
896 	}
897 
898 	if (ccb->dmam->dm_nsegs > 0) {
899 		if (xs->flags & SCSI_DATA_IN)
900 			bus_dmamap_sync(sc->sc_dmat, ccb->dmam, 0,
901 			    ccb->dmam->dm_mapsize, BUS_DMASYNC_POSTREAD);
902 		if (xs->flags & SCSI_DATA_OUT)
903 			bus_dmamap_sync(sc->sc_dmat, ccb->dmam, 0,
904 			    ccb->dmam->dm_mapsize, BUS_DMASYNC_POSTWRITE);
905 		bus_dmamap_unload(sc->sc_dmat, ccb->dmam);
906 	}
907 	aha_free_ccb(sc, ccb);
908 	scsi_done(xs);
909 }
910 
911 /*
912  * Find the board and find its irq/drq
913  */
914 int
aha_find(ia,sc,isapnp)915 aha_find(ia, sc, isapnp)
916 	struct isa_attach_args *ia;
917 	struct aha_softc *sc;
918 	int isapnp;
919 {
920 	int iobase = ia->ia_iobase;
921 	int i;
922 	u_char sts;
923 	struct aha_config config;
924 	int irq, drq;
925 
926 	/*
927 	 * reset board, If it doesn't respond, assume
928 	 * that it's not there.. good for the probe
929 	 */
930 
931 	outb(iobase + AHA_CTRL_PORT, AHA_CTRL_HRST | AHA_CTRL_SRST);
932 
933 	delay(100);
934 	for (i = AHA_RESET_TIMEOUT; i; i--) {
935 		sts = inb(iobase + AHA_STAT_PORT);
936 		if (sts == (AHA_STAT_IDLE | AHA_STAT_INIT))
937 			break;
938 		delay(1000);	/* calibrated in msec */
939 	}
940 	if (!i) {
941 #ifdef AHADEBUG
942 		if (aha_debug)
943 			printf("aha_find: No answer from adaptec board\n");
944 #endif /* AHADEBUG */
945 		return (1);
946 	}
947 
948 	/*
949 	 * setup dma channel from jumpers and save int
950 	 * level
951 	 */
952 	delay(1000);		/* for Bustek 545 */
953 	config.cmd.opcode = AHA_INQUIRE_CONFIG;
954 	aha_cmd(iobase, sc, sizeof(config.cmd), (u_char *)&config.cmd,
955 	    sizeof(config.reply), (u_char *)&config.reply);
956 	switch (config.reply.chan) {
957 	case EISADMA:
958 		drq = DRQUNK;	/* for EISA/VLB/PCI clones */
959 		break;
960 	case CHAN0:
961 		drq = 0;
962 		break;
963 	case CHAN5:
964 		drq = 5;
965 		break;
966 	case CHAN6:
967 		drq = 6;
968 		break;
969 	case CHAN7:
970 		drq = 7;
971 		break;
972 	default:
973 		printf("aha_find: illegal drq setting %x\n",
974 		    config.reply.chan);
975 		return (1);
976 	}
977 	if (isapnp)
978 		irq = ia->ia_irq;
979 
980 	switch (config.reply.intr) {
981 	case INT9:
982 		irq = 9;
983 		break;
984 	case INT10:
985 		irq = 10;
986 		break;
987 	case INT11:
988 		irq = 11;
989 		break;
990 	case INT12:
991 		irq = 12;
992 		break;
993 	case INT14:
994 		irq = 14;
995 		break;
996 	case INT15:
997 		irq = 15;
998 		break;
999 	default:
1000 		printf("aha_find: illegal irq setting %x\n",
1001 		    config.reply.intr);
1002 		return (EIO);
1003 	}
1004 	if (isapnp)
1005 		drq = ia->ia_drq;
1006 
1007 	if (sc != NULL) {
1008 		/* who are we on the scsi bus? */
1009 		sc->sc_scsi_dev = config.reply.scsi_dev;
1010 
1011 		sc->sc_iobase = iobase;
1012 		sc->sc_irq = irq;
1013 		sc->sc_drq = drq;
1014 	} else {
1015 		if (isapnp)
1016 			return (0);
1017 		if (ia->ia_irq == IRQUNK)
1018 			ia->ia_irq = irq;
1019 		else if (ia->ia_irq != irq)
1020 			return (1);
1021 		if (ia->ia_drq == DRQUNK)
1022 			ia->ia_drq = drq;
1023 		else if (ia->ia_drq != drq)
1024 			return (1);
1025 	}
1026 
1027 	return (0);
1028 }
1029 
1030 /*
1031  * Start the board, ready for normal operation
1032  */
1033 void
aha_init(sc)1034 aha_init(sc)
1035 	struct aha_softc *sc;
1036 {
1037 	int iobase = sc->sc_iobase;
1038 	struct aha_devices devices;
1039 	struct aha_setup setup;
1040 	struct aha_mailbox mailbox;
1041 	struct pglist pglist;
1042 	struct vm_page *pg;
1043 	vaddr_t va;
1044 	vsize_t size;
1045 	int i;
1046 
1047 	/*
1048 	 * XXX
1049 	 * If we are a 1542C or later, disable the extended BIOS so that the
1050 	 * mailbox interface is unlocked.
1051 	 * No need to check the extended BIOS flags as some of the
1052 	 * extensions that cause us problems are not flagged in that byte.
1053 	 */
1054 	if (!strncmp(sc->sc_model, "1542C", 5)) {
1055 		struct aha_extbios extbios;
1056 		struct aha_unlock unlock;
1057 
1058 		printf("%s: unlocking mailbox interface\n",
1059 		    sc->sc_dev.dv_xname);
1060 		extbios.cmd.opcode = AHA_EXT_BIOS;
1061 		aha_cmd(iobase, sc, sizeof(extbios.cmd),
1062 		    (u_char *)&extbios.cmd, sizeof(extbios.reply),
1063 		    (u_char *)&extbios.reply);
1064 
1065 #ifdef AHADEBUG
1066 		printf("%s: flags=%02x, mailboxlock=%02x\n",
1067 		    sc->sc_dev.dv_xname,
1068 		    extbios.reply.flags, extbios.reply.mailboxlock);
1069 #endif /* AHADEBUG */
1070 
1071 		unlock.cmd.opcode = AHA_MBX_ENABLE;
1072 		unlock.cmd.junk = 0;
1073 		unlock.cmd.magic = extbios.reply.mailboxlock;
1074 		aha_cmd(iobase, sc, sizeof(unlock.cmd), (u_char *)&unlock.cmd,
1075 		    0, (u_char *)0);
1076 	}
1077 
1078 #if 0
1079 	/*
1080 	 * Change the bus on/off times to not clash with other dma users.
1081 	 */
1082 	aha_cmd(sc, 1, 0, 0, 0, AHA_BUS_ON_TIME_SET, 7);
1083 	aha_cmd(sc, 1, 0, 0, 0, AHA_BUS_OFF_TIME_SET, 4);
1084 #endif
1085 
1086 	/* Inquire Installed Devices (to force synchronous negotiation). */
1087 	devices.cmd.opcode = AHA_INQUIRE_DEVICES;
1088 	aha_cmd(iobase, sc, sizeof(devices.cmd), (u_char *)&devices.cmd,
1089 	    sizeof(devices.reply), (u_char *)&devices.reply);
1090 
1091 	/* Obtain setup information from. */
1092 	setup.cmd.opcode = AHA_INQUIRE_SETUP;
1093 	setup.cmd.len = sizeof(setup.reply);
1094 	aha_cmd(iobase, sc, sizeof(setup.cmd), (u_char *)&setup.cmd,
1095 	    sizeof(setup.reply), (u_char *)&setup.reply);
1096 
1097 	printf("%s: %s, %s\n",
1098 	    sc->sc_dev.dv_xname,
1099 	    setup.reply.sync_neg ? "sync" : "async",
1100 	    setup.reply.parity ? "parity" : "no parity");
1101 
1102 	for (i = 0; i < 8; i++) {
1103 		if (!setup.reply.sync[i].valid ||
1104 		    (!setup.reply.sync[i].offset &&
1105 		    !setup.reply.sync[i].period))
1106 			continue;
1107 		printf("%s targ %d: sync, offset %d, period %dnsec\n",
1108 		    sc->sc_dev.dv_xname, i, setup.reply.sync[i].offset,
1109 		    setup.reply.sync[i].period * 50 + 200);
1110 	}
1111 
1112 	/*
1113 	 * Set up initial mail box for round-robin operation.
1114 	 */
1115 
1116 	/*
1117 	 * XXX - this vm juggling is so wrong. use bus_dma instead!
1118 	 */
1119 	size = round_page(sizeof(struct aha_mbx));
1120 	TAILQ_INIT(&pglist);
1121 	if (uvm_pglistalloc(size, 0, 0xffffff, PAGE_SIZE, 0, &pglist, 1, 0) ||
1122 	    uvm_map(kernel_map, &va, size, NULL, UVM_UNKNOWN_OFFSET, 0,
1123 		UVM_MAPFLAG(UVM_PROT_ALL, UVM_PROT_ALL, UVM_INH_NONE,
1124 			UVM_ADV_RANDOM, 0)))
1125 		panic("aha_init: could not allocate mailbox");
1126 
1127 	wmbx = (struct aha_mbx *)va;
1128 	for (pg = TAILQ_FIRST(&pglist); pg != NULL;
1129 	    pg = TAILQ_NEXT(pg, pageq)) {
1130 		pmap_kenter_pa(va, VM_PAGE_TO_PHYS(pg),
1131 			VM_PROT_READ|VM_PROT_WRITE);
1132 		va += PAGE_SIZE;
1133 	}
1134 	pmap_update(pmap_kernel());
1135 	/*
1136 	 * XXXEND
1137 	 */
1138 
1139 	for (i = 0; i < AHA_MBX_SIZE; i++) {
1140 		wmbx->mbo[i].cmd = AHA_MBO_FREE;
1141 		wmbx->mbi[i].stat = AHA_MBI_FREE;
1142 	}
1143 	wmbx->cmbo = wmbx->tmbo = &wmbx->mbo[0];
1144 	wmbx->tmbi = &wmbx->mbi[0];
1145 	sc->sc_mbofull = 0;
1146 
1147 	/* Initialize mail box. */
1148 	mailbox.cmd.opcode = AHA_MBX_INIT;
1149 	mailbox.cmd.nmbx = AHA_MBX_SIZE;
1150 	ltophys(vtophys(wmbx), mailbox.cmd.addr);
1151 	aha_cmd(iobase, sc, sizeof(mailbox.cmd), (u_char *)&mailbox.cmd,
1152 	    0, (u_char *)0);
1153 }
1154 
1155 void
aha_inquire_setup_information(sc)1156 aha_inquire_setup_information(sc)
1157 	struct aha_softc *sc;
1158 {
1159 	int iobase = sc->sc_iobase;
1160 	struct aha_revision revision;
1161 	u_char sts;
1162 	int i;
1163 	char *p;
1164 
1165 	strlcpy(sc->sc_model, "unknown", sizeof sc->sc_model);
1166 
1167 	/*
1168 	 * Assume we have a board at this stage, do an adapter inquire
1169 	 * to find out what type of controller it is.  If the command
1170 	 * fails, we assume it's either a crusty board or an old 1542
1171 	 * clone, and skip the board-specific stuff.
1172 	 */
1173 	revision.cmd.opcode = AHA_INQUIRE_REVISION;
1174 	if (aha_cmd(iobase, sc, sizeof(revision.cmd), (u_char *)&revision.cmd,
1175 	    sizeof(revision.reply), (u_char *)&revision.reply)) {
1176 		/*
1177 		 * aha_cmd() already started the reset.  It's not clear we
1178 		 * even need to bother here.
1179 		 */
1180 		for (i = AHA_RESET_TIMEOUT; i; i--) {
1181 			sts = inb(iobase + AHA_STAT_PORT);
1182 			if (sts == (AHA_STAT_IDLE | AHA_STAT_INIT))
1183 				break;
1184 			delay(1000);
1185 		}
1186 		if (!i) {
1187 #ifdef AHADEBUG
1188 			printf("aha_init: soft reset failed\n");
1189 #endif /* AHADEBUG */
1190 			return;
1191 		}
1192 #ifdef AHADEBUG
1193 		printf("aha_init: inquire command failed\n");
1194 #endif /* AHADEBUG */
1195 		goto noinquire;
1196 	}
1197 
1198 #ifdef AHADEBUG
1199 	printf("%s: inquire %x, %x, %x, %x\n",
1200 	    sc->sc_dev.dv_xname,
1201 	    revision.reply.boardid, revision.reply.spec_opts,
1202 	    revision.reply.revision_1, revision.reply.revision_2);
1203 #endif /* AHADEBUG */
1204 
1205 	switch (revision.reply.boardid) {
1206 	case 0x31:
1207 		strlcpy(sc->sc_model, "1540", sizeof sc->sc_model);
1208 		break;
1209 	case 0x41:
1210 		strlcpy(sc->sc_model, "1540A/1542A/1542B", sizeof sc->sc_model);
1211 		break;
1212 	case 0x42:
1213 		strlcpy(sc->sc_model, "1640", sizeof sc->sc_model);
1214 		break;
1215 	case 0x43:
1216 	case 0x44:		/* Is this 1542C or -CF? */
1217 		strlcpy(sc->sc_model, "1542C", sizeof sc->sc_model);
1218 		break;
1219 	case 0x45:
1220 		strlcpy(sc->sc_model, "1542CF", sizeof sc->sc_model);
1221 		break;
1222 	case 0x46:
1223 		strlcpy(sc->sc_model, "1542CP", sizeof sc->sc_model);
1224 		break;
1225 	}
1226 
1227 	p = sc->sc_firmware;
1228 	*p++ = revision.reply.revision_1;
1229 	*p++ = '.';
1230 	*p++ = revision.reply.revision_2;
1231 	*p = '\0';
1232 
1233 noinquire:
1234 	printf(": model AHA-%s, firmware %s\n", sc->sc_model, sc->sc_firmware);
1235 }
1236 
1237 void
ahaminphys(bp)1238 ahaminphys(bp)
1239 	struct buf *bp;
1240 {
1241 
1242 	if (bp->b_bcount > ((AHA_NSEG - 1) << PGSHIFT))
1243 		bp->b_bcount = ((AHA_NSEG - 1) << PGSHIFT);
1244 	minphys(bp);
1245 }
1246 
1247 /*
1248  * start a scsi operation given the command and the data address. Also needs
1249  * the unit, target and lu.
1250  */
1251 int
aha_scsi_cmd(xs)1252 aha_scsi_cmd(xs)
1253 	struct scsi_xfer *xs;
1254 {
1255 	struct scsi_link *sc_link = xs->sc_link;
1256 	struct aha_softc *sc = sc_link->adapter_softc;
1257 	struct aha_ccb *ccb;
1258 	struct aha_scat_gath *sg;
1259 	int seg, flags;
1260 #ifdef	TFS
1261 	struct iovec *iovp;
1262 	int datalen;
1263 #endif
1264 	int s;
1265 
1266 	SC_DEBUG(sc_link, SDEV_DB2, ("aha_scsi_cmd\n"));
1267 	/*
1268 	 * get a ccb to use. If the transfer
1269 	 * is from a buf (possibly from interrupt time)
1270 	 * then we can't allow it to sleep
1271 	 */
1272 	flags = xs->flags;
1273 	if ((ccb = aha_get_ccb(sc, flags)) == NULL) {
1274 		xs->error = XS_DRIVER_STUFFUP;
1275 		return (TRY_AGAIN_LATER);
1276 	}
1277 	ccb->xs = xs;
1278 	ccb->timeout = xs->timeout;
1279 
1280 	/*
1281 	 * Put all the arguments for the xfer in the ccb
1282 	 */
1283 	if (flags & SCSI_RESET) {
1284 		ccb->opcode = AHA_RESET_CCB;
1285 		ccb->scsi_cmd_length = 0;
1286 	} else {
1287 		/* can't use S/G if zero length */
1288 		ccb->opcode =
1289 		    (xs->datalen ? AHA_INIT_SCAT_GATH_CCB : AHA_INITIATOR_CCB);
1290 		bcopy(xs->cmd, &ccb->scsi_cmd,
1291 		    ccb->scsi_cmd_length = xs->cmdlen);
1292 	}
1293 
1294 	if (xs->datalen) {
1295 		sg = ccb->scat_gath;
1296 		seg = 0;
1297 #ifdef	TFS
1298 		if (flags & SCSI_DATA_UIO) {
1299 			iovp = ((struct uio *)xs->data)->uio_iov;
1300 			datalen = ((struct uio *)xs->data)->uio_iovcnt;
1301 			xs->datalen = 0;
1302 			while (datalen && seg < AHA_NSEG) {
1303 				ltophys(iovp->iov_base, sg->seg_addr);
1304 				ltophys(iovp->iov_len, sg->seg_len);
1305 				xs->datalen += iovp->iov_len;
1306 				SC_DEBUGN(sc_link, SDEV_DB4, ("UIO(0x%x@0x%x)",
1307 				    iovp->iov_len, iovp->iov_base));
1308 				sg++;
1309 				iovp++;
1310 				seg++;
1311 				datalen--;
1312 			}
1313 		} else
1314 #endif /* TFS */
1315 		{
1316 			/*
1317 			 * Set up the scatter-gather block.
1318 			 */
1319 			if (bus_dmamap_load(sc->sc_dmat, ccb->dmam, xs->data,
1320 			    xs->datalen, NULL, BUS_DMA_NOWAIT) != 0) {
1321 				aha_free_ccb(sc, ccb);
1322 				xs->error = XS_DRIVER_STUFFUP;
1323 				return (TRY_AGAIN_LATER);
1324 			}
1325 			for (seg = 0; seg < ccb->dmam->dm_nsegs; seg++) {
1326 				ltophys(ccb->dmam->dm_segs[seg].ds_addr,
1327 				    sg[seg].seg_addr);
1328 				ltophys(ccb->dmam->dm_segs[seg].ds_len,
1329 				    sg[seg].seg_len);
1330 			}
1331 		}
1332 		if (flags & SCSI_DATA_OUT)
1333 			bus_dmamap_sync(sc->sc_dmat, ccb->dmam, 0,
1334 			    ccb->dmam->dm_mapsize, BUS_DMASYNC_PREWRITE);
1335 		if (flags & SCSI_DATA_IN)
1336 			bus_dmamap_sync(sc->sc_dmat, ccb->dmam, 0,
1337 			    ccb->dmam->dm_mapsize, BUS_DMASYNC_PREREAD);
1338 		ltophys((unsigned)
1339 		    ((struct aha_ccb *)(ccb->ccb_dmam->dm_segs[0].ds_addr))->
1340 		    scat_gath,
1341 		    ccb->data_addr);
1342 		ltophys(ccb->dmam->dm_nsegs * sizeof(struct aha_scat_gath),
1343 		    ccb->data_length);
1344 	} else {		/* No data xfer, use non S/G values */
1345 		ltophys(0, ccb->data_addr);
1346 		ltophys(0, ccb->data_length);
1347 	}
1348 
1349 	ccb->data_out = 0;
1350 	ccb->data_in = 0;
1351 	ccb->target = sc_link->target;
1352 	ccb->lun = sc_link->lun;
1353 	ccb->req_sense_length = sizeof(ccb->scsi_sense);
1354 	ccb->host_stat = 0x00;
1355 	ccb->target_stat = 0x00;
1356 	ccb->link_id = 0;
1357 	ltophys(0, ccb->link_addr);
1358 
1359 	s = splbio();
1360 	aha_queue_ccb(sc, ccb);
1361 
1362 	/*
1363 	 * Usually return SUCCESSFULLY QUEUED
1364 	 */
1365 	SC_DEBUG(sc_link, SDEV_DB3, ("cmd_sent\n"));
1366 
1367 	if (VOLATILE_XS(xs)) {
1368 		while ((ccb->xs->flags & ITSDONE) == 0) {
1369 			tsleep(ccb, PRIBIO, "ahawait", 0);
1370 		}
1371 		if (ccb->dmam->dm_nsegs > 0) {
1372 			if (flags & SCSI_DATA_OUT)
1373 				bus_dmamap_sync(sc->sc_dmat, ccb->dmam, 0,
1374 				    ccb->dmam->dm_mapsize,
1375 				    BUS_DMASYNC_POSTWRITE);
1376 			if (flags & SCSI_DATA_IN)
1377 				bus_dmamap_sync(sc->sc_dmat, ccb->dmam, 0,
1378 				    ccb->dmam->dm_mapsize,
1379 				    BUS_DMASYNC_POSTREAD);
1380 			bus_dmamap_unload(sc->sc_dmat, ccb->dmam);
1381 		}
1382 		aha_free_ccb(sc, ccb);
1383 		scsi_done(xs);
1384 		splx(s);
1385 		return (COMPLETE);
1386 	}
1387 	splx(s);
1388 
1389 	if ((flags & SCSI_POLL) == 0)
1390 		return (SUCCESSFULLY_QUEUED);
1391 
1392 	/*
1393 	 * If we can't use interrupts, poll on completion
1394 	 */
1395 	if (aha_poll(sc, xs, ccb->timeout)) {
1396 		aha_timeout(ccb);
1397 		if (aha_poll(sc, xs, ccb->timeout))
1398 			aha_timeout(ccb);
1399 	}
1400 	return (COMPLETE);
1401 }
1402 
1403 /*
1404  * Poll a particular unit, looking for a particular xs
1405  */
1406 int
aha_poll(sc,xs,count)1407 aha_poll(sc, xs, count)
1408 	struct aha_softc *sc;
1409 	struct scsi_xfer *xs;
1410 	int count;
1411 {
1412 	int iobase = sc->sc_iobase;
1413 
1414 	/* timeouts are in msec, so we loop in 1000 usec cycles */
1415 	while (count) {
1416 		/*
1417 		 * If we had interrupts enabled, would we
1418 		 * have got an interrupt?
1419 		 */
1420 		if (inb(iobase + AHA_INTR_PORT) & AHA_INTR_ANYINTR)
1421 			ahaintr(sc);
1422 		if (xs->flags & ITSDONE)
1423 			return (0);
1424 		delay(1000);	/* only happens in boot so ok */
1425 		count--;
1426 	}
1427 	return (1);
1428 }
1429 
1430 void
aha_timeout(arg)1431 aha_timeout(arg)
1432 	void *arg;
1433 {
1434 	struct aha_ccb *ccb = arg;
1435 	struct scsi_xfer *xs;
1436 	struct scsi_link *sc_link;
1437 	struct aha_softc *sc;
1438 	int s;
1439 
1440 	s = splbio();
1441 	bus_dmamap_sync(sc->sc_dmat, ccb->ccb_dmam, 0,
1442 	    ccb->ccb_dmam->dm_mapsize, BUS_DMASYNC_POSTREAD);
1443 	xs = ccb->xs;
1444 	sc_link = xs->sc_link;
1445 	sc = sc_link->adapter_softc;
1446 
1447 	sc_print_addr(sc_link);
1448 	printf("timed out");
1449 
1450 #ifdef AHADIAG
1451 	/*
1452 	 * If The ccb's mbx is not free, then the board has gone south?
1453 	 */
1454 	aha_collect_mbo(sc);
1455 	if (ccb->flags & CCB_SENDING) {
1456 		printf("%s: not taking commands!\n", sc->sc_dev.dv_xname);
1457 		Debugger();
1458 	}
1459 #endif
1460 
1461 	/*
1462 	 * If it has been through before, then
1463 	 * a previous abort has failed, don't
1464 	 * try abort again
1465 	 */
1466 	if (ccb->flags & CCB_ABORT) {
1467 		/* abort timed out */
1468 		printf(" AGAIN\n");
1469 		/* XXX Must reset! */
1470 	} else {
1471 		/* abort the operation that has timed out */
1472 		printf("\n");
1473 		ccb->xs->error = XS_TIMEOUT;
1474 		ccb->timeout = AHA_ABORT_TIMEOUT;
1475 		ccb->flags |= CCB_ABORT;
1476 		aha_queue_ccb(sc, ccb);
1477 	}
1478 
1479 	splx(s);
1480 }
1481 
1482