1 /*	$OpenBSD: dpt.c,v 1.9 2003/10/21 18:58:49 jmc Exp $	*/
2 /*	$NetBSD: dpt.c,v 1.12 1999/10/23 16:26:33 ad Exp $	*/
3 
4 /*-
5  * Copyright (c) 1997, 1998, 1999 The NetBSD Foundation, Inc.
6  * All rights reserved.
7  *
8  * This code is derived from software contributed to The NetBSD Foundation
9  * by Andy Doran, Charles M. Hannum and by Jason R. Thorpe of the Numerical
10  * Aerospace Simulation Facility, NASA Ames Research Center.
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 the NetBSD
23  *	Foundation, Inc. and its contributors.
24  * 4. Neither the name of The NetBSD Foundation nor the names of its
25  *    contributors may be used to endorse or promote products derived
26  *    from this software without specific prior written permission.
27  *
28  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
29  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
31  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
32  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
33  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
36  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38  * POSSIBILITY OF SUCH DAMAGE.
39  */
40 
41 /*
42  * Portions of this code fall under the following copyright:
43  *
44  * Originally written by Julian Elischer (julian@tfs.com)
45  * for TRW Financial Systems for use under the MACH(2.5) operating system.
46  *
47  * TRW Financial Systems, in accordance with their agreement with Carnegie
48  * Mellon University, makes this software available to CMU to distribute
49  * or use in any manner that they see fit as long as this message is kept with
50  * the software. For this reason TFS also grants any other persons or
51  * organisations permission to use or modify this software.
52  *
53  * TFS supplies this software to be publicly redistributed
54  * on the understanding that TFS is not responsible for the correct
55  * functioning of this software in any circumstances.
56  */
57 
58 /*
59  * Driver for DPT EATA SCSI adapters.
60  *
61  * TODO:
62  *
63  * o Need a front-end for (newer) ISA boards.
64  * o Handle older firmware better.
65  * o Find a bunch of different firmware EEPROMs and try them out.
66  * o Test with a bunch of different boards.
67  * o dpt_readcfg() should not be using CP_PIO_GETCFG.
68  * o An interface to userland applications.
69  * o Some sysctls or a utility (eg dptctl(8)) to control parameters.
70  */
71 
72 #include <sys/cdefs.h>
73 #ifdef __NetBSD__
74 __KERNEL_RCSID(0, "$NetBSD: dpt.c,v 1.12 1999/10/23 16:26:33 ad Exp $");
75 #endif /* __NetBSD__ */
76 
77 #include <sys/param.h>
78 #include <sys/systm.h>
79 #include <sys/kernel.h>
80 #include <sys/device.h>
81 #include <sys/queue.h>
82 #include <sys/proc.h>
83 #include <sys/buf.h>
84 
85 #include <machine/endian.h>
86 #ifdef __NetBSD__
87 #include <machine/bswap.h>
88 #endif /* __NetBSD__ */
89 #include <machine/bus.h>
90 
91 #ifdef __NetBSD__
92 #include <dev/scsipi/scsi_all.h>
93 #include <dev/scsipi/scsipi_all.h>
94 #include <dev/scsipi/scsiconf.h>
95 #endif /* __NetBSD__ */
96 #ifdef __OpenBSD__
97 #include <scsi/scsi_all.h>
98 #include <scsi/scsiconf.h>
99 #endif /* __OpenBSD__ */
100 
101 #include <dev/ic/dptreg.h>
102 #include <dev/ic/dptvar.h>
103 
104 #ifdef __OpenBSD__
105 static void dpt_enqueue(struct dpt_softc *, struct scsi_xfer *, int);
106 static struct scsi_xfer *dpt_dequeue(struct dpt_softc *);
107 
108 struct cfdriver dpt_cd = {
109 	NULL, "dpt", DV_DULL
110 };
111 #endif /* __OpenBSD__ */
112 
113 /* A default for our link struct */
114 #ifdef __NetBSD__
115 static struct scsipi_device dpt_dev = {
116 #endif /* __NetBSD__ */
117 #ifdef __OpenBSD__
118 static struct scsi_device dpt_dev = {
119 #endif /* __OpenBSD__ */
120 	NULL,			/* Use default error handler */
121 	NULL,			/* have a queue, served by this */
122 	NULL,			/* have no async handler */
123 	NULL,			/* Use default 'done' routine */
124 };
125 
126 #ifndef offsetof
127 #define offsetof(type, member) (int)((&((type *)0)->member))
128 #endif /* offsetof */
129 
130 static char *dpt_cname[] = {
131 	"PM3334", "SmartRAID IV",
132 	"PM3332", "SmartRAID IV",
133 	"PM2144", "SmartCache IV",
134 	"PM2044", "SmartCache IV",
135 	"PM2142", "SmartCache IV",
136 	"PM2042", "SmartCache IV",
137 	"PM2041", "SmartCache IV",
138 	"PM3224", "SmartRAID III",
139 	"PM3222", "SmartRAID III",
140 	"PM3021", "SmartRAID III",
141 	"PM2124", "SmartCache III",
142 	"PM2024", "SmartCache III",
143 	"PM2122", "SmartCache III",
144 	"PM2022", "SmartCache III",
145 	"PM2021", "SmartCache III",
146 	"SK2012", "SmartCache Plus",
147 	"SK2011", "SmartCache Plus",
148 	NULL,     "unknown adapter, please report using sendbug(1)",
149 };
150 
151 /*
152  * Handle an interrupt from the HBA.
153  */
154 int
155 dpt_intr(xxx_sc)
156 	void *xxx_sc;
157 {
158 	struct dpt_softc *sc;
159 	struct dpt_ccb *ccb;
160 	struct eata_sp *sp;
161 	static int moretimo;
162 	int more;
163 
164 	sc = xxx_sc;
165 	sp = sc->sc_statpack;
166 
167 	if (!sp) {
168 #ifdef DEBUG
169 		printf("%s: premature intr (st:%02x aux:%02x)\n",
170 			sc->sc_dv.dv_xname, dpt_inb(sc, HA_STATUS),
171 			dpt_inb(sc, HA_AUX_STATUS));
172 #else /* DEBUG */
173 		(void) dpt_inb(sc, HA_STATUS);
174 #endif /* DEBUG */
175 		return (0);
176 	}
177 
178 	more = 0;
179 
180 #ifdef DEBUG
181 	if ((dpt_inb(sc, HA_AUX_STATUS) & HA_AUX_INTR) == 0)
182 		printf("%s: spurious intr\n", sc->sc_dv.dv_xname);
183 #endif
184 
185 	/* Don't get stalled by HA_ST_MORE */
186 	if (moretimo < DPT_MORE_TIMEOUT / 100)
187 		moretimo = 0;
188 
189 	for (;;) {
190 		/*
191 		 * HBA might have interrupted while we were dealing with the
192 		 * last completed command, since we ACK before we deal; keep
193 		 * polling. If no interrupt is signalled, but the HBA has
194 		 * indicated that more data will be available soon, hang
195 		 * around.
196 		 */
197 		if ((dpt_inb(sc, HA_AUX_STATUS) & HA_AUX_INTR) == 0) {
198 			if (more != 0 && moretimo++ < DPT_MORE_TIMEOUT / 100) {
199 				DELAY(10);
200 				continue;
201 			}
202 			break;
203 		}
204 
205 		bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_ccb, sc->sc_spoff,
206 		    sizeof(struct eata_sp), BUS_DMASYNC_POSTREAD);
207 
208 		if (!sp) {
209 			more = dpt_inb(sc, HA_STATUS) & HA_ST_MORE;
210 
211 			/* Don't get stalled by HA_ST_MORE */
212 			if (moretimo < DPT_MORE_TIMEOUT / 100)
213 				moretimo = 0;
214 			continue;
215 		}
216 
217 		/* Might have looped before HBA can reset HBA_AUX_INTR */
218 		if (sp->sp_ccbid == -1) {
219 			DELAY(50);
220 #ifdef DIAGNOSTIC
221 			printf("%s: slow reset of HA_AUX_STATUS?",
222 			    sc->sc_dv.dv_xname);
223 #endif
224 			if ((dpt_inb(sc, HA_AUX_STATUS) & HA_AUX_INTR) == 0)
225 				return (0);
226 #ifdef DIAGNOSTIC
227 			printf("%s: was a slow reset of HA_AUX_STATUS",
228 			    sc->sc_dv.dv_xname);
229 #endif
230 			/* Re-sync DMA map */
231 			bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_ccb,
232 			    sc->sc_spoff, sizeof(struct eata_sp),
233 			    BUS_DMASYNC_POSTREAD);
234 		}
235 
236 		/* Make sure CCB ID from status packet is realistic */
237 		if (sp->sp_ccbid >= 0 && sp->sp_ccbid < sc->sc_nccbs) {
238 			/* Sync up DMA map and cache cmd status */
239 			ccb = sc->sc_ccbs + sp->sp_ccbid;
240 
241 			bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_ccb,
242 			    CCB_OFF(sc, ccb), sizeof(struct dpt_ccb),
243 			    BUS_DMASYNC_POSTWRITE);
244 
245 			ccb->ccb_hba_status = sp->sp_hba_status & 0x7F;
246 			ccb->ccb_scsi_status = sp->sp_scsi_status;
247 
248 			/*
249 			 * Ack the interrupt and process the CCB. If this
250 			 * is a private CCB it's up to dpt_poll() to notice.
251 			 */
252 			sp->sp_ccbid = -1;
253 			ccb->ccb_flg |= CCB_INTR;
254 			more = dpt_inb(sc, HA_STATUS) & HA_ST_MORE;
255 			if ((ccb->ccb_flg & CCB_PRIVATE) == 0)
256 				dpt_done_ccb(sc, ccb);
257 		} else {
258 			printf("%s: bogus status (returned CCB id %d)\n",
259 			    sc->sc_dv.dv_xname, sp->sp_ccbid);
260 
261 			/* Ack the interrupt */
262 			sp->sp_ccbid = -1;
263 			more = dpt_inb(sc, HA_STATUS) & HA_ST_MORE;
264 		}
265 
266 		/* Don't get stalled by HA_ST_MORE */
267 		if (moretimo < DPT_MORE_TIMEOUT / 100)
268 			moretimo = 0;
269 	}
270 
271 	return (0);
272 }
273 
274 /*
275  * Initialize and attach the HBA. This is the entry point from bus
276  * specific probe-and-attach code.
277  */
278 void
279 dpt_init(sc, intrstr)
280 	struct dpt_softc *sc;
281 	const char *intrstr;
282 {
283 	struct eata_inquiry_data *ei;
284 	int i, j, error, rseg, mapsize;
285 	bus_dma_segment_t seg;
286 	struct eata_cfg *ec;
287 	char model[16];
288 
289 	ec = &sc->sc_ec;
290 
291 	/* Allocate the CCB/status packet/scratch DMA map and load */
292 	sc->sc_nccbs = min(betoh16(*(int16_t *)ec->ec_queuedepth),
293 			   DPT_MAX_CCBS);
294 	sc->sc_spoff = sc->sc_nccbs * sizeof(struct dpt_ccb);
295 	sc->sc_scroff = sc->sc_spoff + sizeof(struct eata_sp);
296 	sc->sc_scrlen = 256; /* XXX */
297 	mapsize = sc->sc_nccbs * sizeof(struct dpt_ccb) + sc->sc_scrlen +
298 	    sizeof(struct eata_sp);
299 
300 	if ((error = bus_dmamem_alloc(sc->sc_dmat, mapsize, NBPG, 0,
301 	    &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) {
302 		printf("%s: unable to allocate CCBs, error = %d\n",
303 		    sc->sc_dv.dv_xname, error);
304 		return;
305 	}
306 
307 	if ((error = bus_dmamem_map(sc->sc_dmat, &seg, rseg, mapsize,
308 	    (caddr_t *)&sc->sc_ccbs, BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) != 0) {
309 		printf("%s: unable to map CCBs, error = %d\n",
310 		    sc->sc_dv.dv_xname, error);
311 		return;
312 	}
313 
314 	if ((error = bus_dmamap_create(sc->sc_dmat, mapsize, mapsize, 1, 0,
315 	    BUS_DMA_NOWAIT, &sc->sc_dmamap_ccb)) != 0) {
316 		printf("%s: unable to create CCB DMA map, error = %d\n",
317 		    sc->sc_dv.dv_xname, error);
318 		return;
319 	}
320 
321 	if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap_ccb,
322 	    sc->sc_ccbs, mapsize, NULL, BUS_DMA_NOWAIT)) != 0) {
323 		printf("%s: unable to load CCB DMA map, error = %d\n",
324 		    sc->sc_dv.dv_xname, error);
325 		return;
326 	}
327 
328 	sc->sc_statpack = (struct eata_sp *)((caddr_t)sc->sc_ccbs +
329 	    sc->sc_spoff);
330 	sc->sc_sppa = sc->sc_dmamap_ccb->dm_segs[0].ds_addr + sc->sc_spoff;
331 	sc->sc_scr = (caddr_t)sc->sc_ccbs + sc->sc_scroff;
332 	sc->sc_scrpa = sc->sc_dmamap_ccb->dm_segs[0].ds_addr + sc->sc_scroff;
333 	sc->sc_statpack->sp_ccbid = -1;
334 
335 	/* Initialize the CCBs */
336 	TAILQ_INIT(&sc->sc_free_ccb);
337 	i = dpt_create_ccbs(sc, sc->sc_ccbs, sc->sc_nccbs);
338 
339 	if (i == 0) {
340 		printf("%s: unable to create CCBs\n", sc->sc_dv.dv_xname);
341 		return;
342 	} else if (i != sc->sc_nccbs) {
343 		printf("%s: %d/%d CCBs created!\n", sc->sc_dv.dv_xname, i,
344 		    sc->sc_nccbs);
345 		sc->sc_nccbs = i;
346 	}
347 
348 	/* Set shutdownhook before we start any device activity */
349 	sc->sc_sdh = shutdownhook_establish(dpt_shutdown, sc);
350 
351 	/* Get the page 0 inquiry data from the HBA */
352 	dpt_hba_inquire(sc, &ei);
353 
354 	/*
355 	 * dpt0 at pci0 dev 12 function 0: DPT SmartRAID III (PM3224A/9X-R)
356 	 * dpt0: interrupting at irq 10
357 	 * dpt0: 64 queued commands, 1 channel(s), adapter on ID(s) 7
358 	 */
359 	for (i = 0; ei->ei_vendor[i] != ' ' && i < 8; i++)
360 		;
361 	ei->ei_vendor[i] = '\0';
362 
363 	for (i = 0; ei->ei_model[i] != ' ' && i < 7; i++)
364 		model[i] = ei->ei_model[i];
365 	for (j = 0; ei->ei_suffix[j] != ' ' && j < 7; j++)
366 		model[i++] = ei->ei_suffix[j];
367 	model[i] = '\0';
368 
369 	/* Find the canonical name for the board */
370 	for (i = 0; dpt_cname[i] != NULL; i += 2)
371 		if (memcmp(ei->ei_model, dpt_cname[i], 6) == 0)
372 			break;
373 
374 	printf("%s %s (%s)\n", ei->ei_vendor, dpt_cname[i + 1], model);
375 
376 	if (intrstr != NULL)
377 		printf("%s: interrupting at %s\n", sc->sc_dv.dv_xname, intrstr);
378 
379 	printf("%s: %d queued commands, %d channel(s), adapter on ID(s)",
380 	    sc->sc_dv.dv_xname, sc->sc_nccbs, ec->ec_maxchannel + 1);
381 
382 	for (i = 0; i <= ec->ec_maxchannel; i++)
383 		printf(" %d", ec->ec_hba[3 - i]);
384 	printf("\n");
385 
386 	/* Reset the SCSI bus */
387 	if (dpt_cmd(sc, NULL, 0, CP_IMMEDIATE, CPI_BUS_RESET))
388 		panic("%s: dpt_cmd failed", sc->sc_dv.dv_xname);
389         DELAY(20000);
390 
391 	/* Fill in the adapter, each link and attach in turn */
392 #ifdef __NetBSD__
393 	sc->sc_adapter.scsipi_cmd = dpt_scsi_cmd;
394 	sc->sc_adapter.scsipi_minphys = dpt_minphys;
395 #endif /* __NetBSD__ */
396 #ifdef __OpenBSD__
397 	sc->sc_adapter.scsi_cmd = dpt_scsi_cmd;
398 	sc->sc_adapter.scsi_minphys = dpt_minphys;
399 #endif /* __OpenBSD__ */
400 
401 	for (i = 0; i <= ec->ec_maxchannel; i++) {
402 #ifdef __NetBSD__
403 		struct scsipi_link *link;
404 #endif /* __NetBSD__ */
405 #ifdef __OpenBSD__
406 		struct scsi_link *link;
407 #endif /* __OpenBSD__ */
408 		sc->sc_hbaid[i] = ec->ec_hba[3 - i];
409 		link = &sc->sc_link[i];
410 #ifdef __NetBSD__
411 		link->scsipi_scsi.scsibus = i;
412 		link->scsipi_scsi.adapter_target = sc->sc_hbaid[i];
413 		link->scsipi_scsi.max_lun = ec->ec_maxlun;
414 		link->scsipi_scsi.max_target = ec->ec_maxtarget;
415 		link->type = BUS_SCSI;
416 #endif /* __NetBSD__ */
417 #ifdef __OpenBSD__
418 		link->scsibus = i;
419 		link->adapter_target = sc->sc_hbaid[i];
420 		link->luns = ec->ec_maxlun + 1;
421 		link->adapter_buswidth = ec->ec_maxtarget + 1;
422 #endif /* __OpenBSD__ */
423 		link->device = &dpt_dev;
424 		link->adapter = &sc->sc_adapter;
425 		link->adapter_softc = sc;
426 		link->openings = sc->sc_nccbs;
427 		config_found(&sc->sc_dv, link, scsiprint);
428 	}
429 }
430 
431 /*
432  * Our 'shutdownhook' to cleanly shut down the HBA. The HBA must flush
433  * all data from it's cache and mark array groups as clean.
434  */
435 void
436 dpt_shutdown(xxx_sc)
437 	void *xxx_sc;
438 {
439 	struct dpt_softc *sc;
440 
441 	sc = xxx_sc;
442 	printf("shutting down %s...", sc->sc_dv.dv_xname);
443 	dpt_cmd(sc, NULL, 0, CP_IMMEDIATE, CPI_POWEROFF_WARN);
444 	DELAY(5000*1000);
445 	printf(" done\n");
446 }
447 
448 /*
449  * Send an EATA command to the HBA.
450  */
451 int
452 dpt_cmd(sc, cp, addr, eatacmd, icmd)
453 	struct dpt_softc *sc;
454 	struct eata_cp *cp;
455 	u_int32_t addr;
456 	int eatacmd, icmd;
457 {
458 	int i;
459 
460 	for (i = 20000; i; i--) {
461 		if ((dpt_inb(sc, HA_AUX_STATUS) & HA_AUX_BUSY) == 0)
462 			break;
463 		DELAY(50);
464 	}
465 
466 	/* Not the most graceful way to handle this */
467 	if (i == 0) {
468 		printf("%s: HBA timeout on EATA command issue; aborting\n",
469 		    sc->sc_dv.dv_xname);
470 		return (-1);
471 	}
472 
473 	if (cp == NULL)
474 		addr = 0;
475 
476 	dpt_outb(sc, HA_DMA_BASE + 0, (u_int32_t)addr);
477 	dpt_outb(sc, HA_DMA_BASE + 1, (u_int32_t)addr >> 8);
478 	dpt_outb(sc, HA_DMA_BASE + 2, (u_int32_t)addr >> 16);
479 	dpt_outb(sc, HA_DMA_BASE + 3, (u_int32_t)addr >> 24);
480 
481 	if (eatacmd == CP_IMMEDIATE) {
482 		if (cp == NULL) {
483 			/* XXX should really pass meaningful values */
484 			dpt_outb(sc, HA_ICMD_CODE2, 0);
485 			dpt_outb(sc, HA_ICMD_CODE1, 0);
486 		}
487 		dpt_outb(sc, HA_ICMD, icmd);
488 	}
489 
490         dpt_outb(sc, HA_COMMAND, eatacmd);
491         return (0);
492 }
493 
494 /*
495  * Wait for the HBA to reach an arbitrary state.
496  */
497 int
498 dpt_wait(sc, mask, state, ms)
499         struct dpt_softc *sc;
500         u_int8_t mask, state;
501         int ms;
502 {
503 
504         for (ms *= 10; ms; ms--) {
505                 if ((dpt_inb(sc, HA_STATUS) & mask) == state)
506                 	return (0);
507                 DELAY(100);
508         }
509         return (-1);
510 }
511 
512 /*
513  * Wait for the specified CCB to finish. This is used when we may not be
514  * able to sleep and/or interrupts are disabled (eg autoconfiguration).
515  * The timeout value from the CCB is used. This should only be used for
516  * CCB_PRIVATE requests; otherwise the CCB will get recycled before we get
517  * a look at it.
518  */
519 int
520 dpt_poll(sc, ccb)
521         struct dpt_softc *sc;
522         struct dpt_ccb *ccb;
523 {
524 	int i;
525 
526 #ifdef DEBUG
527 	if ((ccb->ccb_flg & CCB_PRIVATE) == 0)
528 		panic("dpt_poll: called for non-CCB_PRIVATE request");
529 #endif
530 
531  	if ((ccb->ccb_flg & CCB_INTR) != 0)
532         	return (0);
533 
534         for (i = ccb->ccb_timeout * 20; i; i--) {
535                 if ((dpt_inb(sc, HA_AUX_STATUS) & HA_AUX_INTR) != 0)
536                 	dpt_intr(sc);
537                 if ((ccb->ccb_flg & CCB_INTR) != 0)
538                 	return (0);
539                 DELAY(50);
540         }
541         return (-1);
542 }
543 
544 /*
545  * Read the EATA configuration from the HBA and perform some sanity checks.
546  */
547 int
548 dpt_readcfg(sc)
549 	struct dpt_softc *sc;
550 {
551 	struct eata_cfg *ec;
552 	int i, j, stat;
553 	u_int16_t *p;
554 
555 	ec = &sc->sc_ec;
556 
557 	/* Older firmware may puke if we talk to it too soon after reset */
558 	dpt_outb(sc, HA_COMMAND, CP_RESET);
559         DELAY(750000);
560 
561 	for (i = 1000; i; i--) {
562 		if ((dpt_inb(sc, HA_STATUS) & HA_ST_READY) != 0)
563 			break;
564 		DELAY(2000);
565 	}
566 
567 	if (i == 0) {
568 		printf("%s: HBA not ready after reset: %02x\n",
569 		    sc->sc_dv.dv_xname, dpt_inb(sc, HA_STATUS));
570 		return (-1);
571 	}
572 
573 	while((((stat = dpt_inb(sc, HA_STATUS))
574             != (HA_ST_READY|HA_ST_SEEK_COMPLETE))
575             && (stat != (HA_ST_READY|HA_ST_SEEK_COMPLETE|HA_ST_ERROR))
576             && (stat != (HA_ST_READY|HA_ST_SEEK_COMPLETE|HA_ST_ERROR|HA_ST_DRQ)))
577             || (dpt_wait(sc, HA_ST_BUSY, 0, 2000))) {
578         	/* RAID drives still spinning up? */
579                 if((dpt_inb(sc, HA_ERROR) != 'D')
580                     || (dpt_inb(sc, HA_ERROR + 1) != 'P')
581                     || (dpt_inb(sc, HA_ERROR + 2) != 'T')) {
582                     	printf("%s: HBA not ready\n", sc->sc_dv.dv_xname);
583                         return (-1);
584 		}
585         }
586 
587 	/*
588 	 * Issue the read-config command and wait for the data to appear.
589 	 * XXX we shouldn't be doing this with PIO, but it makes it a lot
590 	 * easier as no DMA setup is required.
591 	 */
592 	dpt_outb(sc, HA_COMMAND, CP_PIO_GETCFG);
593 	memset(ec, 0, sizeof(*ec));
594 	i = ((int)&((struct eata_cfg *)0)->ec_cfglen +
595 	    sizeof(ec->ec_cfglen)) >> 1;
596 	p = (u_int16_t *)ec;
597 
598 	if (dpt_wait(sc, 0xFF, HA_ST_DATA_RDY, 2000)) {
599 		printf("%s: cfg data didn't appear (status:%02x)\n",
600 		    sc->sc_dv.dv_xname, dpt_inb(sc, HA_STATUS));
601   		return (-1);
602   	}
603 
604 	/* Begin reading */
605  	while (i--)
606 		*p++ = dpt_inw(sc, HA_DATA);
607 
608         if ((i = ec->ec_cfglen) > (sizeof(struct eata_cfg)
609             - (int)(&(((struct eata_cfg *)0L)->ec_cfglen))
610             - sizeof(ec->ec_cfglen)))
611                 i = sizeof(struct eata_cfg)
612                   - (int)(&(((struct eata_cfg *)0L)->ec_cfglen))
613                   - sizeof(ec->ec_cfglen);
614 
615         j = i + (int)(&(((struct eata_cfg *)0L)->ec_cfglen)) +
616             sizeof(ec->ec_cfglen);
617         i >>= 1;
618 
619 	while (i--)
620                 *p++ = dpt_inw(sc, HA_DATA);
621 
622         /* Flush until we have read 512 bytes. */
623         i = (512 - j + 1) >> 1;
624 	while (i--)
625  		dpt_inw(sc, HA_DATA);
626 
627         /* Defaults for older Firmware */
628 	if (p <= (u_short *)&ec->ec_hba[DPT_MAX_CHANNELS - 1])
629 		ec->ec_hba[DPT_MAX_CHANNELS - 1] = 7;
630 
631         if ((dpt_inb(sc, HA_STATUS) & HA_ST_ERROR) != 0) {
632         	printf("%s: HBA error\n", sc->sc_dv.dv_xname);
633         	return (-1);
634         }
635 
636         if (!ec->ec_hbavalid) {
637                 printf("%s: ec_hba field invalid\n", sc->sc_dv.dv_xname);
638 		return (-1);
639 	}
640 
641 	if (memcmp(ec->ec_eatasig, "EATA", 4) != 0) {
642 	        printf("%s: EATA signature mismatch\n", sc->sc_dv.dv_xname);
643 		return (-1);
644 	}
645 
646 	if (!ec->ec_dmasupported) {
647 	        printf("%s: DMA not supported\n", sc->sc_dv.dv_xname);
648 		return (-1);
649 	}
650 
651 	return (0);
652 }
653 
654 /*
655  * Adjust the size of each I/O before it passes to the SCSI layer.
656  */
657 void
658 dpt_minphys(bp)
659 	struct buf *bp;
660 {
661 
662 	if (bp->b_bcount > DPT_MAX_XFER)
663 		bp->b_bcount = DPT_MAX_XFER;
664 	minphys(bp);
665 }
666 
667 /*
668  * Put a CCB onto the freelist.
669  */
670 void
671 dpt_free_ccb(sc, ccb)
672 	struct dpt_softc *sc;
673 	struct dpt_ccb *ccb;
674 {
675 	int s;
676 
677 	s = splbio();
678 	ccb->ccb_flg = 0;
679 	TAILQ_INSERT_HEAD(&sc->sc_free_ccb, ccb, ccb_chain);
680 
681 	/* Wake anybody waiting for a free ccb */
682 	if (ccb->ccb_chain.tqe_next == 0)
683 		wakeup(&sc->sc_free_ccb);
684 	splx(s);
685 }
686 
687 /*
688  * Initialize the specified CCB.
689  */
690 int
691 dpt_init_ccb(sc, ccb)
692 	struct dpt_softc *sc;
693 	struct dpt_ccb *ccb;
694 {
695 	int error;
696 
697 	/* Create the DMA map for this CCB's data */
698 	error = bus_dmamap_create(sc->sc_dmat, DPT_MAX_XFER, DPT_SG_SIZE,
699 	    DPT_MAX_XFER, 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
700 	    &ccb->ccb_dmamap_xfer);
701 
702 	if (error) {
703 		printf("%s: can't create ccb dmamap (%d)\n",
704 		   sc->sc_dv.dv_xname, error);
705 		return (error);
706 	}
707 
708 	ccb->ccb_flg = 0;
709 	ccb->ccb_ccbpa = sc->sc_dmamap_ccb->dm_segs[0].ds_addr +
710 	    CCB_OFF(sc, ccb);
711 	return (0);
712 }
713 
714 /*
715  * Create a set of CCBs and add them to the free list.
716  */
717 int
718 dpt_create_ccbs(sc, ccbstore, count)
719 	struct dpt_softc *sc;
720 	struct dpt_ccb *ccbstore;
721 	int count;
722 {
723 	struct dpt_ccb *ccb;
724 	int i, error;
725 
726 	memset(ccbstore, 0, sizeof(struct dpt_ccb) * count);
727 
728 	for (i = 0, ccb = ccbstore; i < count; i++, ccb++) {
729 		if ((error = dpt_init_ccb(sc, ccb)) != 0) {
730 			printf("%s: unable to init ccb, error = %d\n",
731 			    sc->sc_dv.dv_xname, error);
732 			break;
733 		}
734 		ccb->ccb_id = i;
735 		TAILQ_INSERT_TAIL(&sc->sc_free_ccb, ccb, ccb_chain);
736 	}
737 
738 	return (i);
739 }
740 
741 /*
742  * Get a free ccb. If there are none, see if we can allocate a new one. If
743  * none are available right now and we are permitted to sleep, then wait
744  * until one becomes free, otherwise return an error.
745  */
746 struct dpt_ccb *
747 dpt_alloc_ccb(sc, flg)
748 	struct dpt_softc *sc;
749 	int flg;
750 {
751 	struct dpt_ccb *ccb;
752 	int s;
753 
754 	s = splbio();
755 
756 	for (;;) {
757 		ccb = TAILQ_FIRST(&sc->sc_free_ccb);
758 		if (ccb) {
759 			TAILQ_REMOVE(&sc->sc_free_ccb, ccb, ccb_chain);
760 			break;
761 		}
762 #ifdef __NetBSD__
763 		if ((flg & XS_CTL_NOSLEEP) != 0) {
764 #endif /* __NetBSD__ */
765 #ifdef __OpenBSD__
766 		if ((flg & SCSI_NOSLEEP) != 0) {
767 #endif /* __OpenBSD__ */
768 			splx(s);
769 			return (NULL);
770 		}
771 		tsleep(&sc->sc_free_ccb, PRIBIO, "dptccb", 0);
772 	}
773 
774 	ccb->ccb_flg |= CCB_ALLOC;
775 	splx(s);
776 	return (ccb);
777 }
778 
779 /*
780  * We have a CCB which has been processed by the HBA, now we look to see how
781  * the operation went. CCBs marked with CCB_PRIVATE are not automatically
782  * passed here by dpt_intr().
783  */
784 void
785 dpt_done_ccb(sc, ccb)
786 	struct dpt_softc *sc;
787 	struct dpt_ccb *ccb;
788 {
789 #ifdef __NetBSD__
790 	struct scsipi_sense_data *s1, *s2;
791 	struct scsipi_xfer *xs;
792 #endif /* __NetBSD__ */
793 #ifdef __OpenBSD__
794 	struct scsi_sense_data *s1, *s2;
795 	struct scsi_xfer *xs;
796 #endif /* __OpenBSD__ */
797 	bus_dma_tag_t dmat;
798 
799 	dmat = sc->sc_dmat;
800 	xs = ccb->ccb_xs;
801 
802 	SC_DEBUG(xs->sc_link, SDEV_DB2, ("dpt_done_ccb\n"));
803 
804 	/*
805 	 * If we were a data transfer, unload the map that described the
806 	 * data buffer.
807 	 */
808 	if (xs->datalen) {
809 		bus_dmamap_sync(dmat, ccb->ccb_dmamap_xfer, 0,
810 		    ccb->ccb_dmamap_xfer->dm_mapsize,
811 		    (xs->flags & SCSI_DATA_IN) ? BUS_DMASYNC_POSTREAD :
812 		    BUS_DMASYNC_POSTWRITE);
813 		bus_dmamap_unload(dmat, ccb->ccb_dmamap_xfer);
814 	}
815 
816 	/*
817 	 * Otherwise, put the results of the operation into the xfer and
818 	 * call whoever started it.
819 	 */
820 #ifdef DIAGNOSTIC
821 	if ((ccb->ccb_flg & CCB_ALLOC) == 0) {
822 		panic("%s: done ccb not allocated!", sc->sc_dv.dv_xname);
823 		return;
824 	}
825 #endif
826 
827 	if (xs->error == XS_NOERROR) {
828 		if (ccb->ccb_hba_status != HA_NO_ERROR) {
829 			switch (ccb->ccb_hba_status) {
830 			case HA_ERROR_SEL_TO:
831 				xs->error = XS_SELTIMEOUT;
832 				break;
833 			case HA_ERROR_RESET:
834 				xs->error = XS_RESET;
835 				break;
836 			default:	/* Other scsi protocol messes */
837 				printf("%s: HBA status %x\n",
838 				    sc->sc_dv.dv_xname, ccb->ccb_hba_status);
839 				xs->error = XS_DRIVER_STUFFUP;
840 			}
841 		} else if (ccb->ccb_scsi_status != SCSI_OK) {
842 			switch (ccb->ccb_scsi_status) {
843 			case SCSI_CHECK:
844 				s1 = &ccb->ccb_sense;
845 #ifdef __NetBSD__
846 				s2 = &xs->sense.scsi_sense;
847 #endif /* __NetBSD__ */
848 #ifdef __OpenBSD__
849 				s2 = &xs->sense;
850 #endif /* __OpenBSD__ */
851 				*s2 = *s1;
852 				xs->error = XS_SENSE;
853 				break;
854 			case SCSI_BUSY:
855 				xs->error = XS_BUSY;
856 				break;
857 			default:
858 				printf("%s: SCSI status %x\n",
859 				    sc->sc_dv.dv_xname, ccb->ccb_scsi_status);
860 				xs->error = XS_DRIVER_STUFFUP;
861 			}
862 		} else
863 			xs->resid = 0;
864 
865 		xs->status = ccb->ccb_scsi_status;
866 	}
867 
868 	/* Free up the CCB and mark the command as done */
869 	dpt_free_ccb(sc, ccb);
870 #ifdef __NetBSD__
871 	xs->xs_status |= XS_STS_DONE;
872 	scsipi_done(xs);
873 #endif /* __NetBSD__ */
874 #ifdef __OpenBSD__
875 	xs->flags |= ITSDONE;
876 	scsi_done(xs);
877 #endif /* __OpenBSD__ */
878 
879 	/*
880 	 * If there are entries in the software queue, try to run the first
881 	 * one. We should be more or less guaranteed to succeed, since we
882 	 * just freed an CCB. NOTE: dpt_scsi_cmd() relies on our calling it
883 	 * with the first entry in the queue.
884 	 */
885 #ifdef __NetBSD__
886 	if ((xs = TAILQ_FIRST(&sc->sc_queue)) != NULL)
887 #endif /* __NetBSD__ */
888 #ifdef __OpenBSD__
889 	if ((xs = sc->sc_queue.lh_first) != NULL)
890 #endif /* __OpenBSD__ */
891 		dpt_scsi_cmd(xs);
892 }
893 
894 #ifdef __OpenBSD__
895 /*
896  * Insert a scsi_xfer into the software queue.  We overload xs->free_list
897  * to avoid having to allocate additional resources (since we're used
898  * only during resource shortages anyhow.
899  */
900 static void
901 dpt_enqueue(sc, xs, infront)
902 	struct dpt_softc *sc;
903 	struct scsi_xfer *xs;
904 	int             infront;
905 {
906 
907 	if (infront || sc->sc_queue.lh_first == NULL) {
908 		if (sc->sc_queue.lh_first == NULL)
909 			sc->sc_queuelast = xs;
910 		LIST_INSERT_HEAD(&sc->sc_queue, xs, free_list);
911 		return;
912 	}
913 	LIST_INSERT_AFTER(sc->sc_queuelast, xs, free_list);
914 	sc->sc_queuelast = xs;
915 }
916 
917 /*
918  * Pull a scsi_xfer off the front of the software queue.
919  */
920 static struct scsi_xfer *
921 dpt_dequeue(sc)
922 	struct dpt_softc *sc;
923 {
924 	struct scsi_xfer *xs;
925 
926 	xs = sc->sc_queue.lh_first;
927 	LIST_REMOVE(xs, free_list);
928 
929 	if (sc->sc_queue.lh_first == NULL)
930 		sc->sc_queuelast = NULL;
931 
932 	return (xs);
933 }
934 #endif /* __OpenBSD__ */
935 
936 /*
937  * Start a SCSI command.
938  */
939 int
940 dpt_scsi_cmd(xs)
941 #ifdef __NetBSD__
942 	struct scsipi_xfer *xs;
943 #endif /* __NetBSD__ */
944 #ifdef __OpenBSD__
945 	struct scsi_xfer *xs;
946 #endif /* __OpenBSD__ */
947 {
948 	int error, i, flags, s, fromqueue, dontqueue;
949 #ifdef __NetBSD__
950 	struct scsipi_link *sc_link;
951 #endif /* __NetBSD__ */
952 #ifdef __OpenBSD__
953 	struct scsi_link *sc_link;
954 #endif /* __OpenBSD__ */
955 	struct dpt_softc *sc;
956 	struct dpt_ccb *ccb;
957 	struct eata_sg *sg;
958 	struct eata_cp *cp;
959 	bus_dma_tag_t dmat;
960 	bus_dmamap_t xfer;
961 
962 	sc_link = xs->sc_link;
963 #ifdef __NetBSD__
964 	flags = xs->xs_control;
965 #endif /* __NetBSD__ */
966 #ifdef __OpenBSD__
967 	flags = xs->flags;
968 #endif /* __OpenBSD__ */
969 	sc = sc_link->adapter_softc;
970 	dmat = sc->sc_dmat;
971 	fromqueue = 0;
972 	dontqueue = 0;
973 
974 	SC_DEBUG(sc_link, SDEV_DB2, ("dpt_scsi_cmd\n"));
975 
976 	/* Protect the queue */
977 	s = splbio();
978 
979 	/*
980 	 * If we're running the queue from dpt_done_ccb(), we've been called
981 	 * with the first queue entry as our argument.
982 	 */
983 #ifdef __NetBSD__
984 	if (xs == TAILQ_FIRST(&sc->sc_queue)) {
985 		TAILQ_REMOVE(&sc->sc_queue, xs, adapter_q);
986 #endif /* __NetBSD__ */
987 #ifdef __OpenBSD__
988 	if (xs == sc->sc_queue.lh_first) {
989 		xs = dpt_dequeue(sc);
990 #endif /* __OpenBSD__ */
991 		fromqueue = 1;
992 	} else {
993 		/* Cmds must be no more than 12 bytes for us */
994 		if (xs->cmdlen > 12) {
995 			splx(s);
996 			xs->error = XS_DRIVER_STUFFUP;
997 			return (COMPLETE);
998 		}
999 
1000 		/* XXX we can't reset devices just yet */
1001 #ifdef __NetBSD__
1002 		if ((flags & XS_CTL_RESET) != 0) {
1003 #endif /* __NetBSD__ */
1004 #ifdef __OpenBSD__
1005 		if ((xs->flags & SCSI_RESET) != 0) {
1006 #endif /* __OpenBSD__ */
1007 			splx(s);
1008 			xs->error = XS_DRIVER_STUFFUP;
1009 			return (COMPLETE);
1010 		}
1011 
1012 		/* Polled requests can't be queued for later */
1013 #ifdef __NetBSD__
1014 		dontqueue = flags & XS_CTL_POLL;
1015 #endif /* __NetBSD__ */
1016 #ifdef __OpenBSD__
1017 		dontqueue = xs->flags & SCSI_POLL;
1018 #endif /* __OpenBSD__ */
1019 
1020 		/* If there are jobs in the queue, run them first */
1021 #ifdef __NetBSD__
1022 		if (TAILQ_FIRST(&sc->sc_queue) != NULL) {
1023 #endif /* __NetBSD__ */
1024 #ifdef __OpenBSD__
1025 		if (sc->sc_queue.lh_first != NULL) {
1026 #endif /* __OpenBSD__ */
1027 			/*
1028 			 * If we can't queue we abort, since we must
1029 			 * preserve the queue order.
1030 			 */
1031 			if (dontqueue) {
1032 				splx(s);
1033 				xs->error = XS_DRIVER_STUFFUP;
1034 				return (TRY_AGAIN_LATER);
1035 			}
1036 
1037 			/* Swap with the first queue entry. */
1038 #ifdef __NetBSD__
1039 			TAILQ_INSERT_TAIL(&sc->sc_queue, xs, adapter_q);
1040 			xs = TAILQ_FIRST(&sc->sc_queue);
1041 			TAILQ_REMOVE(&sc->sc_queue, xs, adapter_q);
1042 #endif /* __NetBSD__ */
1043 #ifdef __OpenBSD__
1044 			dpt_enqueue(sc, xs, 0);
1045 			xs = dpt_dequeue(sc);
1046 #endif /* __OpenBSD__ */
1047 			fromqueue = 1;
1048 		}
1049 	}
1050 
1051 	/* Get a CCB */
1052 #ifdef __NetBSD__
1053 	if ((ccb = dpt_alloc_ccb(sc, flags)) == NULL) {
1054 #endif /* __NetBSD__ */
1055 #ifdef __OpenBSD__
1056 	if ((ccb = dpt_alloc_ccb(sc, xs->flags)) == NULL) {
1057 #endif /* __OpenBSD__ */
1058 		/* If we can't queue, we lose */
1059 		if (dontqueue) {
1060 			splx(s);
1061 			xs->error = XS_DRIVER_STUFFUP;
1062 			return (TRY_AGAIN_LATER);
1063 		}
1064 
1065 		/*
1066 		 * Stuff request into the queue, in front if we came off
1067 		 * it in the first place.
1068 		 */
1069 #ifdef __NetBSD__
1070 		if (fromqueue)
1071 			TAILQ_INSERT_HEAD(&sc->sc_queue, xs, adapter_q);
1072 		else
1073 			TAILQ_INSERT_TAIL(&sc->sc_queue, xs, adapter_q);
1074 #endif /* __NetBSD__ */
1075 #ifdef __OpenBSD__
1076 		dpt_enqueue(sc, xs, fromqueue);
1077 #endif /* __OpenBSD__ */
1078 		splx(s);
1079 		return (SUCCESSFULLY_QUEUED);
1080 	}
1081 
1082 	splx(s);
1083 
1084 	ccb->ccb_xs = xs;
1085 	ccb->ccb_timeout = xs->timeout;
1086 
1087 	cp = &ccb->ccb_eata_cp;
1088 #ifdef __NetBSD__
1089 	memcpy(&cp->cp_scsi_cmd, xs->cmd, xs->cmdlen);
1090 #endif /* __NetBSD__ */
1091 #ifdef __OpenBSD__
1092 	bcopy(xs->cmd, &cp->cp_scsi_cmd, xs->cmdlen);
1093 #endif /* __OpenBSD__ */
1094 	cp->cp_ccbid = ccb->ccb_id;
1095 #ifdef __NetBSD__
1096 	cp->cp_id = sc_link->scsipi_scsi.target;
1097 	cp->cp_lun = sc_link->scsipi_scsi.lun;
1098 	cp->cp_channel = sc_link->scsipi_scsi.channel;
1099 #endif /* __NetBSD__ */
1100 #ifdef __OpenBSD__
1101 	cp->cp_id = sc_link->target;
1102 	cp->cp_lun = sc_link->lun;
1103 	cp->cp_channel = sc_link->scsibus;
1104 #endif /* __OpenBSD__ */
1105 	cp->cp_senselen = sizeof(ccb->ccb_sense);
1106 	cp->cp_stataddr = htobe32(sc->sc_sppa);
1107 	cp->cp_dispri = 1;
1108 	cp->cp_identify = 1;
1109 	cp->cp_autosense = 1;
1110 #ifdef __NetBSD__
1111 	cp->cp_datain = ((flags & XS_CTL_DATA_IN) != 0);
1112 	cp->cp_dataout = ((flags & XS_CTL_DATA_OUT) != 0);
1113 	cp->cp_interpret = (sc->sc_hbaid[sc_link->scsipi_scsi.channel] ==
1114 	    sc_link->scsipi_scsi.target);
1115 #endif /* __NetBSD__ */
1116 #ifdef __OpenBSD__
1117 	cp->cp_datain = ((xs->flags & SCSI_DATA_IN) != 0);
1118 	cp->cp_dataout = ((xs->flags & SCSI_DATA_OUT) != 0);
1119 	cp->cp_interpret = (sc->sc_hbaid[sc_link->scsibus] == sc_link->target);
1120 #endif /* __OpenBSD__ */
1121 
1122 	/* Synchronous xfers musn't write-back through the cache */
1123 	if (xs->bp != NULL && (xs->bp->b_flags & (B_ASYNC | B_READ)) == 0)
1124 		cp->cp_nocache = 1;
1125 	else
1126 		cp->cp_nocache = 0;
1127 
1128 	cp->cp_senseaddr = htobe32(sc->sc_dmamap_ccb->dm_segs[0].ds_addr +
1129 	    CCB_OFF(sc, ccb) + offsetof(struct dpt_ccb, ccb_sense));
1130 
1131 	if (xs->datalen) {
1132 		xfer = ccb->ccb_dmamap_xfer;
1133 #ifdef	TFS
1134 #ifdef __NetBSD__
1135 		if ((flags & XS_CTL_DATA_UIO) != 0) {
1136 			error = bus_dmamap_load_uio(dmat, xfer,
1137 			    (struct uio *)xs->data, (flags & XS_CTL_NOSLEEP) ?
1138 			    BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
1139 #endif /* __NetBSD__ */
1140 #ifdef __OpenBSD__
1141 		if ((xs->flags & SCSI_DATA_UIO) != 0) {
1142 			error = bus_dmamap_load_uio(dmat, xfer,
1143 			    (xs->flags & SCSI_NOSLEEP) ?
1144 			    BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
1145 #endif /* __OpenBSD__ */
1146 		} else
1147 #endif /*TFS */
1148 		{
1149 #ifdef __NetBSD__
1150 			error = bus_dmamap_load(dmat, xfer, xs->data,
1151 			    xs->datalen, NULL, (flags & XS_CTL_NOSLEEP) ?
1152 			    BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
1153 #endif /* __NetBSD__ */
1154 #ifdef __OpenBSD__
1155 			error = bus_dmamap_load(dmat, xfer, xs->data,
1156 			    xs->datalen, NULL, (xs->flags & SCSI_NOSLEEP) ?
1157 			    BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
1158 #endif /* __OpenBSD__ */
1159 		}
1160 
1161 		if (error) {
1162 			printf("%s: dpt_scsi_cmd: ", sc->sc_dv.dv_xname);
1163 			if (error == EFBIG)
1164 				printf("more than %d dma segs\n", DPT_SG_SIZE);
1165 			else
1166 				printf("error %d loading dma map\n", error);
1167 
1168 			xs->error = XS_DRIVER_STUFFUP;
1169 			dpt_free_ccb(sc, ccb);
1170 			return (COMPLETE);
1171 		}
1172 
1173 		bus_dmamap_sync(dmat, xfer, 0, xfer->dm_mapsize,
1174 		    (flags & SCSI_DATA_IN) ? BUS_DMASYNC_PREREAD :
1175 		    BUS_DMASYNC_PREWRITE);
1176 
1177 		/* Don't bother using scatter/gather for just 1 segment */
1178 		if (xfer->dm_nsegs == 1) {
1179 			cp->cp_dataaddr = htobe32(xfer->dm_segs[0].ds_addr);
1180 			cp->cp_datalen = htobe32(xfer->dm_segs[0].ds_len);
1181 			cp->cp_scatter = 0;
1182 		} else {
1183 			/*
1184 			 * Load the hardware scatter/gather map with the
1185 			 * contents of the DMA map.
1186 			 */
1187 			sg = ccb->ccb_sg;
1188 			for (i = 0; i < xfer->dm_nsegs; i++, sg++) {
1189 				sg->sg_addr =
1190 				  htobe32(xfer->dm_segs[i].ds_addr);
1191 				sg->sg_len =
1192 				  htobe32(xfer->dm_segs[i].ds_len);
1193 			}
1194 			cp->cp_dataaddr = htobe32(CCB_OFF(sc, ccb) +
1195 			    sc->sc_dmamap_ccb->dm_segs[0].ds_addr +
1196 			    offsetof(struct dpt_ccb, ccb_sg));
1197 			cp->cp_datalen = htobe32(i * sizeof(struct eata_sg));
1198 			cp->cp_scatter = 1;
1199 		}
1200 	} else {
1201 		cp->cp_dataaddr = 0;
1202 		cp->cp_datalen = 0;
1203 		cp->cp_scatter = 0;
1204 	}
1205 
1206 	/* Sync up CCB and status packet */
1207 	bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_ccb, CCB_OFF(sc, ccb),
1208 	    sizeof(struct dpt_ccb), BUS_DMASYNC_PREWRITE);
1209 	bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_ccb, sc->sc_spoff,
1210 	    sizeof(struct eata_sp), BUS_DMASYNC_PREREAD);
1211 
1212 	/*
1213 	 * Start the command. If we are polling on completion, mark it
1214 	 * private so that dpt_intr/dpt_done_ccb don't recycle the CCB
1215 	 * without us noticing.
1216 	 */
1217 	if (dontqueue != 0)
1218 		ccb->ccb_flg |= CCB_PRIVATE;
1219 
1220 	if (dpt_cmd(sc, &ccb->ccb_eata_cp, ccb->ccb_ccbpa, CP_DMA_CMD, 0)) {
1221 		printf("%s: dpt_cmd failed\n", sc->sc_dv.dv_xname);
1222 		xs->error = XS_DRIVER_STUFFUP;
1223 		dpt_free_ccb(sc, ccb);
1224 		return (TRY_AGAIN_LATER);
1225 	}
1226 
1227 	if (dontqueue == 0)
1228 		return (SUCCESSFULLY_QUEUED);
1229 
1230 	/* Don't wait longer than this single command wants to wait */
1231 	if (dpt_poll(sc, ccb)) {
1232 		dpt_timeout(ccb);
1233 		/* Wait for abort to complete */
1234 		if (dpt_poll(sc, ccb))
1235 			dpt_timeout(ccb);
1236 	}
1237 
1238 	dpt_done_ccb(sc, ccb);
1239 	return (COMPLETE);
1240 }
1241 
1242 /*
1243  * Specified CCB has timed out, abort it.
1244  */
1245 void
1246 dpt_timeout(arg)
1247 	void *arg;
1248 {
1249 #ifdef __NetBSD__
1250 	struct scsipi_link *sc_link;
1251 	struct scsipi_xfer *xs;
1252 #endif /* __NetBSD__ */
1253 #ifdef __OpenBSD__
1254 	struct scsi_link *sc_link;
1255 	struct scsi_xfer *xs;
1256 #endif /* __OpenBSD__ */
1257 	struct dpt_softc *sc;
1258  	struct dpt_ccb *ccb;
1259 	int s;
1260 
1261 	ccb = arg;
1262 	xs = ccb->ccb_xs;
1263 	sc_link = xs->sc_link;
1264 	sc  = sc_link->adapter_softc;
1265 
1266 #ifdef __NetBSD__
1267 	scsi_print_addr(sc_link);
1268 #endif /* __NetBSD__ */
1269 #ifdef __OpenBSD__
1270 	sc_print_addr(sc_link);
1271 #endif /* __OpenBSD__ */
1272 	printf("timed out (status:%02x aux status:%02x)",
1273 	    dpt_inb(sc, HA_STATUS), dpt_inb(sc, HA_AUX_STATUS));
1274 
1275 	s = splbio();
1276 
1277 	if ((ccb->ccb_flg & CCB_ABORT) != 0) {
1278 		/* Abort timed out, reset the HBA */
1279 		printf(" AGAIN, resetting HBA\n");
1280 		dpt_outb(sc, HA_COMMAND, CP_RESET);
1281 		DELAY(750000);
1282 	} else {
1283 		/* Abort the operation that has timed out */
1284 		printf("\n");
1285 		ccb->ccb_xs->error = XS_TIMEOUT;
1286 		ccb->ccb_timeout = DPT_ABORT_TIMEOUT;
1287 		ccb->ccb_flg |= CCB_ABORT;
1288 		/* Start the abort */
1289 		if (dpt_cmd(sc, &ccb->ccb_eata_cp, ccb->ccb_ccbpa,
1290 		    CP_IMMEDIATE, CPI_SPEC_ABORT))
1291 		    printf("%s: dpt_cmd failed\n", sc->sc_dv.dv_xname);
1292 	}
1293 
1294 	splx(s);
1295 }
1296 
1297 #ifdef DEBUG
1298 /*
1299  * Dump the contents of an EATA status packet.
1300  */
1301 void
1302 dpt_dump_sp(sp)
1303 	struct eata_sp *sp;
1304 {
1305 	int i;
1306 
1307 	printf("\thba_status\t%02x\n", sp->sp_hba_status);
1308 	printf("\tscsi_status\t%02x\n", sp->sp_scsi_status);
1309 	printf("\tinv_residue\t%d\n", sp->sp_inv_residue);
1310 	printf("\tccbid\t\t%d\n", sp->sp_ccbid);
1311 	printf("\tid_message\t%d\n", sp->sp_id_message);
1312 	printf("\tque_message\t%d\n", sp->sp_que_message);
1313 	printf("\ttag_message\t%d\n", sp->sp_tag_message);
1314 	printf("\tmessages\t");
1315 
1316 	for (i = 0; i < 9; i++)
1317 		printf("%d ", sp->sp_messages[i]);
1318 
1319 	printf("\n");
1320 }
1321 #endif	/* DEBUG */
1322 
1323 /*
1324  * Get inquiry data from the adapter.
1325  */
1326 void
1327 dpt_hba_inquire(sc, ei)
1328 	struct dpt_softc *sc;
1329 	struct eata_inquiry_data **ei;
1330 {
1331 	struct dpt_ccb *ccb;
1332 	struct eata_cp *cp;
1333 	bus_dma_tag_t dmat;
1334 
1335 	*ei = (struct eata_inquiry_data *)sc->sc_scr;
1336 	dmat = sc->sc_dmat;
1337 
1338 	/* Get a CCB and mark as private */
1339 	if ((ccb = dpt_alloc_ccb(sc, 0)) == NULL)
1340 		panic("%s: no CCB for inquiry", sc->sc_dv.dv_xname);
1341 
1342 	ccb->ccb_flg |= CCB_PRIVATE;
1343 	ccb->ccb_timeout = 200;
1344 
1345 	/* Put all the arguments into the CCB */
1346 	cp = &ccb->ccb_eata_cp;
1347 	cp->cp_ccbid = ccb->ccb_id;
1348 	cp->cp_id = sc->sc_hbaid[0];
1349 	cp->cp_lun = 0;
1350 	cp->cp_channel = 0;
1351 	cp->cp_senselen = sizeof(ccb->ccb_sense);
1352 	cp->cp_stataddr = htobe32(sc->sc_sppa);
1353 	cp->cp_dispri = 1;
1354 	cp->cp_identify = 1;
1355 	cp->cp_autosense = 0;
1356 	cp->cp_interpret = 1;
1357 	cp->cp_nocache = 0;
1358 	cp->cp_datain = 1;
1359 	cp->cp_dataout = 0;
1360 	cp->cp_senseaddr = 0;
1361 	cp->cp_dataaddr = htobe32(sc->sc_scrpa);
1362 	cp->cp_datalen = htobe32(sizeof(struct eata_inquiry_data));
1363 	cp->cp_scatter = 0;
1364 
1365 	/* Put together the SCSI inquiry command */
1366 	memset(&cp->cp_scsi_cmd, 0, 12);	/* XXX */
1367 	cp->cp_scsi_cmd = INQUIRY;
1368 	cp->cp_len = sizeof(struct eata_inquiry_data);
1369 
1370 	/* Sync up CCB, status packet and scratch area */
1371 	bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_ccb, CCB_OFF(sc, ccb),
1372 	    sizeof(struct dpt_ccb), BUS_DMASYNC_PREWRITE);
1373 	bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_ccb, sc->sc_spoff,
1374 	    sizeof(struct eata_sp), BUS_DMASYNC_PREREAD);
1375 	bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_ccb, sc->sc_scroff,
1376 	    sizeof(struct eata_inquiry_data), BUS_DMASYNC_PREREAD);
1377 
1378 	/* Start the command and poll on completion */
1379 	if (dpt_cmd(sc, &ccb->ccb_eata_cp, ccb->ccb_ccbpa, CP_DMA_CMD, 0))
1380 		panic("%s: dpt_cmd failed", sc->sc_dv.dv_xname);
1381 
1382 	if (dpt_poll(sc, ccb))
1383 		panic("%s: inquiry timed out", sc->sc_dv.dv_xname);
1384 
1385 	if (ccb->ccb_hba_status != HA_NO_ERROR ||
1386 	    ccb->ccb_scsi_status != SCSI_OK)
1387 	    	panic("%s: inquiry failed (hba:%02x scsi:%02x",
1388 	    	    sc->sc_dv.dv_xname, ccb->ccb_hba_status,
1389 	    	    ccb->ccb_scsi_status);
1390 
1391 	/* Sync up the DMA map and free CCB, returning */
1392 	bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_ccb, sc->sc_scroff,
1393 	    sizeof(struct eata_inquiry_data), BUS_DMASYNC_POSTREAD);
1394 	dpt_free_ccb(sc, ccb);
1395 }
1396