xref: /openbsd-src/sys/dev/ic/adv.c (revision 43003dfe3ad45d1698bed8a37f2b0f5b14f20d4f)
1 /*	$OpenBSD: adv.c,v 1.26 2009/09/04 04:57:14 miod Exp $	*/
2 /*	$NetBSD: adv.c,v 1.6 1998/10/28 20:39:45 dante Exp $	*/
3 
4 /*
5  * Generic driver for the Advanced Systems Inc. Narrow SCSI controllers
6  *
7  * Copyright (c) 1998 The NetBSD Foundation, Inc.
8  * All rights reserved.
9  *
10  * Author: Baldassare Dante Profeta <dante@mclink.it>
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  *
21  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
22  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
25  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 #include <sys/types.h>
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/kernel.h>
38 #include <sys/errno.h>
39 #include <sys/ioctl.h>
40 #include <sys/device.h>
41 #include <sys/malloc.h>
42 #include <sys/buf.h>
43 #include <sys/proc.h>
44 #include <sys/user.h>
45 
46 #include <machine/bus.h>
47 #include <machine/intr.h>
48 
49 #include <scsi/scsi_all.h>
50 #include <scsi/scsiconf.h>
51 
52 #include <dev/ic/adv.h>
53 #include <dev/ic/advlib.h>
54 
55 /* #define ASC_DEBUG */
56 
57 /******************************************************************************/
58 
59 
60 static int adv_alloc_ccbs(ASC_SOFTC *);
61 static int adv_create_ccbs(ASC_SOFTC *, ADV_CCB *, int);
62 static void adv_free_ccb(ASC_SOFTC *, ADV_CCB *);
63 static void adv_reset_ccb(ADV_CCB *);
64 static int adv_init_ccb(ASC_SOFTC *, ADV_CCB *);
65 static ADV_CCB *adv_get_ccb(ASC_SOFTC *, int);
66 static void adv_queue_ccb(ASC_SOFTC *, ADV_CCB *);
67 static void adv_start_ccbs(ASC_SOFTC *);
68 
69 static u_int8_t *adv_alloc_overrunbuf(char *dvname, bus_dma_tag_t);
70 
71 static int adv_scsi_cmd(struct scsi_xfer *);
72 static void advminphys(struct buf *, struct scsi_link *);
73 static void adv_narrow_isr_callback(ASC_SOFTC *, ASC_QDONE_INFO *);
74 
75 static int adv_poll(ASC_SOFTC *, struct scsi_xfer *, int);
76 static void adv_timeout(void *);
77 static void adv_watchdog(void *);
78 
79 
80 /******************************************************************************/
81 
82 
83 struct cfdriver adv_cd = {
84 	NULL, "adv", DV_DULL
85 };
86 
87 
88 struct scsi_adapter adv_switch =
89 {
90 	adv_scsi_cmd,		/* called to start/enqueue a SCSI command */
91 	advminphys,		/* to limit the transfer to max device can do */
92 	0,			/* IT SEEMS IT IS NOT USED YET */
93 	0,			/* as above... */
94 };
95 
96 
97 /* the below structure is so we have a default dev struct for out link struct */
98 struct scsi_device adv_dev =
99 {
100 	NULL,			/* Use default error handler */
101 	NULL,			/* have a queue, served by this */
102 	NULL,			/* have no async handler */
103 	NULL,			/* Use default 'done' routine */
104 };
105 
106 
107 #define ADV_ABORT_TIMEOUT       2000	/* time to wait for abort (mSec) */
108 #define ADV_WATCH_TIMEOUT       1000	/* time to wait for watchdog (mSec) */
109 
110 
111 /******************************************************************************/
112 /*                             Control Blocks routines                        */
113 /******************************************************************************/
114 
115 
116 static int
117 adv_alloc_ccbs(sc)
118 	ASC_SOFTC      *sc;
119 {
120 	bus_dma_segment_t seg;
121 	int             error, rseg;
122 
123 	/*
124          * Allocate the control blocks.
125          */
126 	if ((error = bus_dmamem_alloc(sc->sc_dmat, sizeof(struct adv_control),
127 			   NBPG, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) {
128 		printf("%s: unable to allocate control structures,"
129 		       " error = %d\n", sc->sc_dev.dv_xname, error);
130 		return (error);
131 	}
132 	if ((error = bus_dmamem_map(sc->sc_dmat, &seg, rseg,
133 		   sizeof(struct adv_control), (caddr_t *) & sc->sc_control,
134 				 BUS_DMA_NOWAIT | BUS_DMA_COHERENT)) != 0) {
135 		printf("%s: unable to map control structures, error = %d\n",
136 		       sc->sc_dev.dv_xname, error);
137 		return (error);
138 	}
139 	/*
140          * Create and load the DMA map used for the control blocks.
141          */
142 	if ((error = bus_dmamap_create(sc->sc_dmat, sizeof(struct adv_control),
143 			   1, sizeof(struct adv_control), 0, BUS_DMA_NOWAIT,
144 				       &sc->sc_dmamap_control)) != 0) {
145 		printf("%s: unable to create control DMA map, error = %d\n",
146 		       sc->sc_dev.dv_xname, error);
147 		return (error);
148 	}
149 	if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap_control,
150 			   sc->sc_control, sizeof(struct adv_control), NULL,
151 				     BUS_DMA_NOWAIT)) != 0) {
152 		printf("%s: unable to load control DMA map, error = %d\n",
153 		       sc->sc_dev.dv_xname, error);
154 		return (error);
155 	}
156 	return (0);
157 }
158 
159 
160 /*
161  * Create a set of ccbs and add them to the free list.  Called once
162  * by adv_init().  We return the number of CCBs successfully created.
163  */
164 static int
165 adv_create_ccbs(sc, ccbstore, count)
166 	ASC_SOFTC      *sc;
167 	ADV_CCB        *ccbstore;
168 	int             count;
169 {
170 	ADV_CCB        *ccb;
171 	int             i, error;
172 
173 	bzero(ccbstore, sizeof(ADV_CCB) * count);
174 	for (i = 0; i < count; i++) {
175 		ccb = &ccbstore[i];
176 		if ((error = adv_init_ccb(sc, ccb)) != 0) {
177 			printf("%s: unable to initialize ccb, error = %d\n",
178 			       sc->sc_dev.dv_xname, error);
179 			return (i);
180 		}
181 		TAILQ_INSERT_TAIL(&sc->sc_free_ccb, ccb, chain);
182 	}
183 
184 	return (i);
185 }
186 
187 
188 /*
189  * A ccb is put onto the free list.
190  */
191 static void
192 adv_free_ccb(sc, ccb)
193 	ASC_SOFTC      *sc;
194 	ADV_CCB        *ccb;
195 {
196 	int             s;
197 
198 	s = splbio();
199 
200 	adv_reset_ccb(ccb);
201 	TAILQ_INSERT_HEAD(&sc->sc_free_ccb, ccb, chain);
202 
203 	/*
204          * If there were none, wake anybody waiting for one to come free,
205          * starting with queued entries.
206          */
207 	if (TAILQ_NEXT(ccb, chain) == NULL)
208 		wakeup(&sc->sc_free_ccb);
209 
210 	splx(s);
211 }
212 
213 
214 static void
215 adv_reset_ccb(ccb)
216 	ADV_CCB        *ccb;
217 {
218 
219 	ccb->flags = 0;
220 }
221 
222 
223 static int
224 adv_init_ccb(sc, ccb)
225 	ASC_SOFTC      *sc;
226 	ADV_CCB        *ccb;
227 {
228 	int             error;
229 
230 	/*
231          * Create the DMA map for this CCB.
232          */
233 	error = bus_dmamap_create(sc->sc_dmat,
234 				  (ASC_MAX_SG_LIST - 1) * PAGE_SIZE,
235 			 ASC_MAX_SG_LIST, (ASC_MAX_SG_LIST - 1) * PAGE_SIZE,
236 		   0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &ccb->dmamap_xfer);
237 	if (error) {
238 		printf("%s: unable to create DMA map, error = %d\n",
239 		       sc->sc_dev.dv_xname, error);
240 		return (error);
241 	}
242 	adv_reset_ccb(ccb);
243 	return (0);
244 }
245 
246 
247 /*
248  * Get a free ccb
249  *
250  * If there are none, see if we can allocate a new one
251  */
252 static ADV_CCB *
253 adv_get_ccb(sc, flags)
254 	ASC_SOFTC      *sc;
255 	int             flags;
256 {
257 	ADV_CCB        *ccb = 0;
258 	int             s;
259 
260 	s = splbio();
261 
262 	/*
263          * If we can and have to, sleep waiting for one to come free
264          * but only if we can't allocate a new one.
265          */
266 	for (;;) {
267 		ccb = TAILQ_FIRST(&sc->sc_free_ccb);
268 		if (ccb) {
269 			TAILQ_REMOVE(&sc->sc_free_ccb, ccb, chain);
270 			break;
271 		}
272 		if ((flags & SCSI_NOSLEEP) != 0)
273 			goto out;
274 
275 		tsleep(&sc->sc_free_ccb, PRIBIO, "advccb", 0);
276 	}
277 
278 	ccb->flags |= CCB_ALLOC;
279 
280 out:
281 	splx(s);
282 	return (ccb);
283 }
284 
285 
286 /*
287  * Queue a CCB to be sent to the controller, and send it if possible.
288  */
289 static void
290 adv_queue_ccb(sc, ccb)
291 	ASC_SOFTC      *sc;
292 	ADV_CCB        *ccb;
293 {
294 
295 	timeout_set(&ccb->xs->stimeout, adv_timeout, ccb);
296 	TAILQ_INSERT_TAIL(&sc->sc_waiting_ccb, ccb, chain);
297 
298 	adv_start_ccbs(sc);
299 }
300 
301 
302 static void
303 adv_start_ccbs(sc)
304 	ASC_SOFTC      *sc;
305 {
306 	ADV_CCB        *ccb;
307 	struct scsi_xfer *xs;
308 
309 	while ((ccb = TAILQ_FIRST(&sc->sc_waiting_ccb)) != NULL) {
310 
311 		xs = ccb->xs;
312 		if (ccb->flags & CCB_WATCHDOG)
313 			timeout_del(&xs->stimeout);
314 
315 		if (AscExeScsiQueue(sc, &ccb->scsiq) == ASC_BUSY) {
316 			ccb->flags |= CCB_WATCHDOG;
317 			timeout_set(&xs->stimeout, adv_watchdog, ccb);
318 			timeout_add_msec(&xs->stimeout, ADV_WATCH_TIMEOUT);
319 			break;
320 		}
321 		TAILQ_REMOVE(&sc->sc_waiting_ccb, ccb, chain);
322 
323 		if ((ccb->xs->flags & SCSI_POLL) == 0) {
324 			timeout_set(&xs->stimeout, adv_timeout, ccb);
325 			timeout_add_msec(&xs->stimeout, ccb->timeout);
326 		}
327 	}
328 }
329 
330 
331 /******************************************************************************/
332 /*                      DMA able memory allocation routines                   */
333 /******************************************************************************/
334 
335 
336 /*
337  * Allocate a DMA able memory for overrun_buffer.
338  * This memory can be safely shared among all the AdvanSys boards.
339  */
340 u_int8_t       *
341 adv_alloc_overrunbuf(dvname, dmat)
342 	char           *dvname;
343 	bus_dma_tag_t   dmat;
344 {
345 	static u_int8_t *overrunbuf = NULL;
346 
347 	bus_dmamap_t    ovrbuf_dmamap;
348 	bus_dma_segment_t seg;
349 	int             rseg, error;
350 
351 
352 	/*
353          * if an overrun buffer has been already allocated don't allocate it
354          * again. Instead return the address of the allocated buffer.
355          */
356 	if (overrunbuf)
357 		return (overrunbuf);
358 
359 
360 	if ((error = bus_dmamem_alloc(dmat, ASC_OVERRUN_BSIZE,
361 			   NBPG, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) {
362 		printf("%s: unable to allocate overrun buffer, error = %d\n",
363 		       dvname, error);
364 		return (0);
365 	}
366 	if ((error = bus_dmamem_map(dmat, &seg, rseg, ASC_OVERRUN_BSIZE,
367 	(caddr_t *) & overrunbuf, BUS_DMA_NOWAIT | BUS_DMA_COHERENT)) != 0) {
368 		printf("%s: unable to map overrun buffer, error = %d\n",
369 		       dvname, error);
370 
371 		bus_dmamem_free(dmat, &seg, 1);
372 		return (0);
373 	}
374 	if ((error = bus_dmamap_create(dmat, ASC_OVERRUN_BSIZE, 1,
375 	      ASC_OVERRUN_BSIZE, 0, BUS_DMA_NOWAIT, &ovrbuf_dmamap)) != 0) {
376 		printf("%s: unable to create overrun buffer DMA map,"
377 		       " error = %d\n", dvname, error);
378 
379 		bus_dmamem_unmap(dmat, overrunbuf, ASC_OVERRUN_BSIZE);
380 		bus_dmamem_free(dmat, &seg, 1);
381 		return (0);
382 	}
383 	if ((error = bus_dmamap_load(dmat, ovrbuf_dmamap, overrunbuf,
384 			   ASC_OVERRUN_BSIZE, NULL, BUS_DMA_NOWAIT)) != 0) {
385 		printf("%s: unable to load overrun buffer DMA map,"
386 		       " error = %d\n", dvname, error);
387 
388 		bus_dmamap_destroy(dmat, ovrbuf_dmamap);
389 		bus_dmamem_unmap(dmat, overrunbuf, ASC_OVERRUN_BSIZE);
390 		bus_dmamem_free(dmat, &seg, 1);
391 		return (0);
392 	}
393 	return (overrunbuf);
394 }
395 
396 
397 /******************************************************************************/
398 /*                         SCSI layer interfacing routines                    */
399 /******************************************************************************/
400 
401 
402 int
403 adv_init(sc)
404 	ASC_SOFTC      *sc;
405 {
406 	int             warn;
407 
408 	if (!AscFindSignature(sc->sc_iot, sc->sc_ioh))
409 		panic("adv_init: adv_find_signature failed");
410 
411 	/*
412          * Read the board configuration
413          */
414 	AscInitASC_SOFTC(sc);
415 	warn = AscInitFromEEP(sc);
416 	if (warn) {
417 		printf("%s -get: ", sc->sc_dev.dv_xname);
418 		switch (warn) {
419 		case -1:
420 			printf("Chip is not halted\n");
421 			break;
422 
423 		case -2:
424 			printf("Couldn't get MicroCode Start"
425 			       " address\n");
426 			break;
427 
428 		case ASC_WARN_IO_PORT_ROTATE:
429 			printf("I/O port address modified\n");
430 			break;
431 
432 		case ASC_WARN_AUTO_CONFIG:
433 			printf("I/O port increment switch enabled\n");
434 			break;
435 
436 		case ASC_WARN_EEPROM_CHKSUM:
437 			printf("EEPROM checksum error\n");
438 			break;
439 
440 		case ASC_WARN_IRQ_MODIFIED:
441 			printf("IRQ modified\n");
442 			break;
443 
444 		case ASC_WARN_CMD_QNG_CONFLICT:
445 			printf("tag queuing enabled w/o disconnects\n");
446 			break;
447 
448 		default:
449 			printf("unknown warning %d\n", warn);
450 		}
451 	}
452 	if (sc->scsi_reset_wait > ASC_MAX_SCSI_RESET_WAIT)
453 		sc->scsi_reset_wait = ASC_MAX_SCSI_RESET_WAIT;
454 
455 	/*
456          * Modify the board configuration
457          */
458 	warn = AscInitFromASC_SOFTC(sc);
459 	if (warn) {
460 		printf("%s -set: ", sc->sc_dev.dv_xname);
461 		switch (warn) {
462 		case ASC_WARN_CMD_QNG_CONFLICT:
463 			printf("tag queuing enabled w/o disconnects\n");
464 			break;
465 
466 		case ASC_WARN_AUTO_CONFIG:
467 			printf("I/O port increment switch enabled\n");
468 			break;
469 
470 		default:
471 			printf("unknown warning %d\n", warn);
472 		}
473 	}
474 	sc->isr_callback = (ulong) adv_narrow_isr_callback;
475 
476 	if (!(sc->overrun_buf = adv_alloc_overrunbuf(sc->sc_dev.dv_xname,
477 						     sc->sc_dmat))) {
478 		return (1);
479 	}
480 
481 	return (0);
482 }
483 
484 
485 void
486 adv_attach(sc)
487 	ASC_SOFTC      *sc;
488 {
489 	struct scsibus_attach_args	saa;
490 	int				i, error;
491 
492 	/*
493          * Initialize board RISC chip and enable interrupts.
494          */
495 	switch (AscInitDriver(sc)) {
496 	case 0:
497 		/* AllOK */
498 		break;
499 
500 	case 1:
501 		panic("%s: bad signature", sc->sc_dev.dv_xname);
502 		break;
503 
504 	case 2:
505 		panic("%s: unable to load MicroCode",
506 		      sc->sc_dev.dv_xname);
507 		break;
508 
509 	case 3:
510 		panic("%s: unable to initialize MicroCode",
511 		      sc->sc_dev.dv_xname);
512 		break;
513 
514 	default:
515 		panic("%s: unable to initialize board RISC chip",
516 		      sc->sc_dev.dv_xname);
517 	}
518 
519 
520 	/*
521          * fill in the prototype scsi_link.
522          */
523 	sc->sc_link.adapter_softc = sc;
524 	sc->sc_link.adapter_target = sc->chip_scsi_id;
525 	sc->sc_link.adapter = &adv_switch;
526 	sc->sc_link.device = &adv_dev;
527 	sc->sc_link.openings = 4;
528 	sc->sc_link.adapter_buswidth = 7;
529 
530 
531 	TAILQ_INIT(&sc->sc_free_ccb);
532 	TAILQ_INIT(&sc->sc_waiting_ccb);
533 
534 
535 	/*
536          * Allocate the Control Blocks.
537          */
538 	error = adv_alloc_ccbs(sc);
539 	if (error)
540 		return; /* (error) */ ;
541 
542 	/*
543          * Create and initialize the Control Blocks.
544          */
545 	i = adv_create_ccbs(sc, sc->sc_control->ccbs, ADV_MAX_CCB);
546 	if (i == 0) {
547 		printf("%s: unable to create control blocks\n",
548 		       sc->sc_dev.dv_xname);
549 		return; /* (ENOMEM) */ ;
550 	} else if (i != ADV_MAX_CCB) {
551 		printf("%s: WARNING: only %d of %d control blocks created\n",
552 		       sc->sc_dev.dv_xname, i, ADV_MAX_CCB);
553 	}
554 
555 	bzero(&saa, sizeof(saa));
556 	saa.saa_sc_link = &sc->sc_link;
557 	config_found(&sc->sc_dev, &saa, scsiprint);
558 }
559 
560 
561 static void
562 advminphys(struct buf *bp, struct scsi_link *sl)
563 {
564 	if (bp->b_bcount > ((ASC_MAX_SG_LIST - 1) * PAGE_SIZE))
565 		bp->b_bcount = ((ASC_MAX_SG_LIST - 1) * PAGE_SIZE);
566 	minphys(bp);
567 }
568 
569 
570 /*
571  * start a scsi operation given the command and the data address.  Also needs
572  * the unit, target and lu.
573  */
574 static int
575 adv_scsi_cmd(xs)
576 	struct scsi_xfer *xs;
577 {
578 	struct scsi_link *sc_link = xs->sc_link;
579 	ASC_SOFTC      *sc = sc_link->adapter_softc;
580 	bus_dma_tag_t   dmat = sc->sc_dmat;
581 	ADV_CCB        *ccb;
582 	int             s, flags, error, nsegs;
583 
584 	s = splbio();		/* protect the queue */
585 
586 	/*
587          * get a ccb to use. If the transfer
588          * is from a buf (possibly from interrupt time)
589          * then we can't allow it to sleep
590          */
591 
592 	flags = xs->flags;
593 	if ((ccb = adv_get_ccb(sc, flags)) == NULL) {
594 		splx(s);
595 		return (NO_CCB);
596 	}
597 	splx(s);		/* done playing with the queue */
598 
599 	ccb->xs = xs;
600 	ccb->timeout = xs->timeout;
601 
602 	/*
603          * Build up the request
604          */
605 	memset(&ccb->scsiq, 0, sizeof(ASC_SCSI_Q));
606 
607 	ccb->scsiq.q2.ccb_ptr = (ulong) ccb;
608 
609 	ccb->scsiq.cdbptr = &xs->cmd->opcode;
610 	ccb->scsiq.q2.cdb_len = xs->cmdlen;
611 	ccb->scsiq.q1.target_id = ASC_TID_TO_TARGET_ID(sc_link->target);
612 	ccb->scsiq.q1.target_lun = sc_link->lun;
613 	ccb->scsiq.q2.target_ix = ASC_TIDLUN_TO_IX(sc_link->target,
614 						   sc_link->lun);
615 	ccb->scsiq.q1.sense_addr = sc->sc_dmamap_control->dm_segs[0].ds_addr +
616 		ADV_CCB_OFF(ccb) + offsetof(struct adv_ccb, scsi_sense);
617 	ccb->scsiq.q1.sense_len = sizeof(struct scsi_sense_data);
618 
619 	/*
620          * If  there  are  any  outstanding  requests  for  the  current target,
621          * then  every  255th request  send an  ORDERED request.  This heuristic
622          * tries  to  retain  the  benefit  of request  sorting while preventing
623          * request starvation. 255 is the max number of tags or pending commands
624          * a device may have outstanding.
625          */
626 	sc->reqcnt[sc_link->target]++;
627 	if ((sc->reqcnt[sc_link->target] > 0) &&
628 	    (sc->reqcnt[sc_link->target] % 255) == 0) {
629 		ccb->scsiq.q2.tag_code = M2_QTAG_MSG_ORDERED;
630 	} else {
631 		ccb->scsiq.q2.tag_code = M2_QTAG_MSG_SIMPLE;
632 	}
633 
634 
635 	if (xs->datalen) {
636 		/*
637                  * Map the DMA transfer.
638                  */
639 		error = bus_dmamap_load(dmat,
640 		      ccb->dmamap_xfer, xs->data, xs->datalen, NULL,
641 					(flags & SCSI_NOSLEEP) ? BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
642 
643 		if (error) {
644 			if (error == EFBIG) {
645 				printf("%s: adv_scsi_cmd, more than %d dma"
646 				       " segments\n",
647 				       sc->sc_dev.dv_xname, ASC_MAX_SG_LIST);
648 			} else {
649 				printf("%s: adv_scsi_cmd, error %d loading"
650 				       " dma map\n",
651 				       sc->sc_dev.dv_xname, error);
652 			}
653 
654 			xs->error = XS_DRIVER_STUFFUP;
655 			adv_free_ccb(sc, ccb);
656 			xs->flags |= ITSDONE;
657 			s = splbio();
658 			scsi_done(xs);
659 			splx(s);
660 			return (COMPLETE);
661 		}
662 		bus_dmamap_sync(dmat, ccb->dmamap_xfer,
663 		    0, ccb->dmamap_xfer->dm_mapsize,
664 		    ((flags & SCSI_DATA_IN) ? BUS_DMASYNC_PREREAD :
665 			BUS_DMASYNC_PREWRITE));
666 
667 
668 		memset(&ccb->sghead, 0, sizeof(ASC_SG_HEAD));
669 
670 		for (nsegs = 0; nsegs < ccb->dmamap_xfer->dm_nsegs; nsegs++) {
671 
672 			ccb->sghead.sg_list[nsegs].addr =
673 				ccb->dmamap_xfer->dm_segs[nsegs].ds_addr;
674 			ccb->sghead.sg_list[nsegs].bytes =
675 				ccb->dmamap_xfer->dm_segs[nsegs].ds_len;
676 		}
677 
678 		ccb->sghead.entry_cnt = ccb->scsiq.q1.sg_queue_cnt =
679 			ccb->dmamap_xfer->dm_nsegs;
680 
681 		ccb->scsiq.q1.cntl |= ASC_QC_SG_HEAD;
682 		ccb->scsiq.sg_head = &ccb->sghead;
683 		ccb->scsiq.q1.data_addr = 0;
684 		ccb->scsiq.q1.data_cnt = 0;
685 	} else {
686 		/*
687                  * No data xfer, use non S/G values.
688                  */
689 		ccb->scsiq.q1.data_addr = 0;
690 		ccb->scsiq.q1.data_cnt = 0;
691 	}
692 
693 #ifdef ASC_DEBUG
694 	printf("id = %d, lun = %d, cmd = %d, ccb = 0x%lX \n",
695 			sc_link->scsipi_scsi.target,
696 			sc_link->scsipi_scsi.lun, xs->cmd->opcode,
697 			(unsigned long)ccb);
698 #endif
699 	/*
700          * Usually return SUCCESSFULLY QUEUED
701          */
702 	if ((flags & SCSI_POLL) == 0)
703 		return (SUCCESSFULLY_QUEUED);
704 
705 	/*
706          * If we can't use interrupts, poll on completion
707          */
708 	if (adv_poll(sc, xs, ccb->timeout)) {
709 		adv_timeout(ccb);
710 		if (adv_poll(sc, xs, ccb->timeout))
711 			adv_timeout(ccb);
712 	}
713 
714 	return (COMPLETE);
715 }
716 
717 
718 int
719 adv_intr(arg)
720 	void           *arg;
721 {
722 	ASC_SOFTC      *sc = arg;
723 
724 #ifdef ASC_DEBUG
725 	int int_pend = FALSE;
726 
727 	if(ASC_IS_INT_PENDING(sc->sc_iot, sc->sc_ioh))
728 	{
729 		int_pend = TRUE;
730 		printf("ISR - ");
731 	}
732 #endif
733 	AscISR(sc);
734 #ifdef ASC_DEBUG
735 	if(int_pend)
736 		printf("\n");
737 #endif
738 
739 	return (1);
740 }
741 
742 
743 /*
744  * Poll a particular unit, looking for a particular xs
745  */
746 static int
747 adv_poll(sc, xs, count)
748 	ASC_SOFTC      *sc;
749 	struct scsi_xfer *xs;
750 	int             count;
751 {
752 	int s;
753 
754 	/* timeouts are in msec, so we loop in 1000 usec cycles */
755 	while (count) {
756 		s = splbio();
757 		adv_intr(sc);
758 		splx(s);
759 		if (xs->flags & ITSDONE)
760 			return (0);
761 		delay(1000);	/* only happens in boot so ok */
762 		count--;
763 	}
764 	return (1);
765 }
766 
767 
768 static void
769 adv_timeout(arg)
770 	void           *arg;
771 {
772 	ADV_CCB        *ccb = arg;
773 	struct scsi_xfer *xs = ccb->xs;
774 	struct scsi_link *sc_link = xs->sc_link;
775 	ASC_SOFTC      *sc = sc_link->adapter_softc;
776 	int             s;
777 
778 	sc_print_addr(sc_link);
779 	printf("timed out");
780 
781 	s = splbio();
782 
783 	/*
784          * If it has been through before, then a previous abort has failed,
785          * don't try abort again, reset the bus instead.
786          */
787 	if (ccb->flags & CCB_ABORT) {
788 		/* abort timed out */
789 		printf(" AGAIN. Resetting Bus\n");
790 		/* Lets try resetting the bus! */
791 		if (AscResetBus(sc) == ASC_ERROR) {
792 			ccb->timeout = sc->scsi_reset_wait;
793 			adv_queue_ccb(sc, ccb);
794 		}
795 	} else {
796 		/* abort the operation that has timed out */
797 		printf("\n");
798 		AscAbortCCB(sc, (u_int32_t) ccb);
799 		ccb->xs->error = XS_TIMEOUT;
800 		ccb->timeout = ADV_ABORT_TIMEOUT;
801 		ccb->flags |= CCB_ABORT;
802 		adv_queue_ccb(sc, ccb);
803 	}
804 
805 	splx(s);
806 }
807 
808 
809 static void
810 adv_watchdog(arg)
811 	void           *arg;
812 {
813 	ADV_CCB        *ccb = arg;
814 	struct scsi_xfer *xs = ccb->xs;
815 	struct scsi_link *sc_link = xs->sc_link;
816 	ASC_SOFTC      *sc = sc_link->adapter_softc;
817 	int             s;
818 
819 	s = splbio();
820 
821 	ccb->flags &= ~CCB_WATCHDOG;
822 	adv_start_ccbs(sc);
823 
824 	splx(s);
825 }
826 
827 
828 /******************************************************************************/
829 /*                  NARROW and WIDE boards Interrupt callbacks                */
830 /******************************************************************************/
831 
832 
833 /*
834  * adv_narrow_isr_callback() - Second Level Interrupt Handler called by AscISR()
835  *
836  * Interrupt callback function for the Narrow SCSI Asc Library.
837  */
838 static void
839 adv_narrow_isr_callback(sc, qdonep)
840 	ASC_SOFTC      *sc;
841 	ASC_QDONE_INFO *qdonep;
842 {
843 	bus_dma_tag_t   dmat = sc->sc_dmat;
844 	ADV_CCB        *ccb = (ADV_CCB *) qdonep->d2.ccb_ptr;
845 	struct scsi_xfer *xs = ccb->xs;
846 	struct scsi_sense_data *s1, *s2;
847 
848 
849 #ifdef ASC_DEBUG
850 	printf(" - ccb=0x%lx, id=%d, lun=%d, cmd=%d, ",
851 			(unsigned long)ccb,
852 			xs->sc_link->scsipi_scsi.target,
853 			xs->sc_link->scsipi_scsi.lun, xs->cmd->opcode);
854 #endif
855 	timeout_del(&xs->stimeout);
856 
857 	/*
858          * If we were a data transfer, unload the map that described
859          * the data buffer.
860          */
861 	if (xs->datalen) {
862 		bus_dmamap_sync(dmat, ccb->dmamap_xfer,
863 		    0, ccb->dmamap_xfer->dm_mapsize,
864 		    ((xs->flags & SCSI_DATA_IN) ? BUS_DMASYNC_POSTREAD :
865 			BUS_DMASYNC_POSTWRITE));
866 		bus_dmamap_unload(dmat, ccb->dmamap_xfer);
867 	}
868 	if ((ccb->flags & CCB_ALLOC) == 0) {
869 		panic("%s: exiting ccb not allocated!\n", sc->sc_dev.dv_xname);
870 		return;
871 	}
872 	/*
873          * 'qdonep' contains the command's ending status.
874          */
875 #ifdef ASC_DEBUG
876 	printf("d_s=%d, h_s=%d", qdonep->d3.done_stat, qdonep->d3.host_stat);
877 #endif
878 	switch (qdonep->d3.done_stat) {
879 	case ASC_QD_NO_ERROR:
880 		switch (qdonep->d3.host_stat) {
881 		case ASC_QHSTA_NO_ERROR:
882 			xs->error = XS_NOERROR;
883 			xs->resid = 0;
884 			break;
885 
886 		default:
887 			/* QHSTA error occurred */
888 			xs->error = XS_DRIVER_STUFFUP;
889 			break;
890 		}
891 
892 		/*
893                  * If an INQUIRY command completed successfully, then call
894                  * the AscInquiryHandling() function to patch bugged boards.
895                  */
896 		if ((xs->cmd->opcode == SCSICMD_Inquiry) &&
897 		    (xs->sc_link->lun == 0) &&
898 		    (xs->datalen - qdonep->remain_bytes) >= 8) {
899 			AscInquiryHandling(sc,
900 				      xs->sc_link->target & 0x7,
901 					   (ASC_SCSI_INQUIRY *) xs->data);
902 		}
903 		break;
904 
905 	case ASC_QD_WITH_ERROR:
906 		switch (qdonep->d3.host_stat) {
907 		case ASC_QHSTA_NO_ERROR:
908 			if (qdonep->d3.scsi_stat == SS_CHK_CONDITION) {
909 				s1 = &ccb->scsi_sense;
910 				s2 = &xs->sense;
911 				*s2 = *s1;
912 				xs->error = XS_SENSE;
913 			} else {
914 				xs->error = XS_DRIVER_STUFFUP;
915 			}
916 			break;
917 
918 		default:
919 			/* QHSTA error occurred */
920 			xs->error = XS_DRIVER_STUFFUP;
921 			break;
922 		}
923 		break;
924 
925 	case ASC_QD_ABORTED_BY_HOST:
926 	default:
927 		xs->error = XS_DRIVER_STUFFUP;
928 		break;
929 	}
930 
931 
932 	adv_free_ccb(sc, ccb);
933 	xs->flags |= ITSDONE;
934 	scsi_done(xs);
935 }
936