Home | History | Annotate | Line # | Download | only in ic
aic7xxx.c revision 1.9
      1  1.9  explorer /*	$NetBSD: aic7xxx.c,v 1.9 1996/07/10 22:50:44 explorer Exp $	*/
      2  1.8   thorpej 
      3  1.1   mycroft /*
      4  1.1   mycroft  * Generic driver for the aic7xxx based adaptec SCSI controllers
      5  1.1   mycroft  * Product specific probe and attach routines can be found in:
      6  1.6   mycroft  * i386/eisa/aic7770.c	27/284X and aic7770 motherboard controllers
      7  1.9  explorer  * pci/aic7870.c	3940, 2940, aic7880, aic7870 and aic7850 controllers
      8  1.1   mycroft  *
      9  1.6   mycroft  * Copyright (c) 1994, 1995, 1996 Justin T. Gibbs.
     10  1.6   mycroft  * All rights reserved.
     11  1.1   mycroft  *
     12  1.6   mycroft  * Redistribution and use in source and binary forms, with or without
     13  1.6   mycroft  * modification, are permitted provided that the following conditions
     14  1.6   mycroft  * are met:
     15  1.6   mycroft  * 1. Redistributions of source code must retain the above copyright
     16  1.6   mycroft  *    notice immediately at the beginning of the file, without modification,
     17  1.6   mycroft  *    this list of conditions, and the following disclaimer.
     18  1.6   mycroft  * 2. Redistributions in binary form must reproduce the above copyright
     19  1.6   mycroft  *    notice, this list of conditions and the following disclaimer in the
     20  1.6   mycroft  *    documentation and/or other materials provided with the distribution.
     21  1.6   mycroft  * 3. The name of the author may not be used to endorse or promote products
     22  1.6   mycroft  *    derived from this software without specific prior written permission.
     23  1.1   mycroft  *
     24  1.6   mycroft  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
     25  1.6   mycroft  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     26  1.6   mycroft  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     27  1.6   mycroft  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
     28  1.6   mycroft  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     29  1.6   mycroft  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     30  1.6   mycroft  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     31  1.6   mycroft  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     32  1.6   mycroft  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     33  1.6   mycroft  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     34  1.6   mycroft  * SUCH DAMAGE.
     35  1.9  explorer  *
     36  1.9  explorer  * from Id: aic7xxx.c,v 1.75 1996/06/23 20:02:37 gibbs Exp
     37  1.1   mycroft  */
     38  1.1   mycroft /*
     39  1.1   mycroft  * TODO:
     40  1.1   mycroft  *	Implement Target Mode
     41  1.6   mycroft  *
     42  1.6   mycroft  * A few notes on how SCB paging works...
     43  1.6   mycroft  *
     44  1.6   mycroft  * SCB paging takes advantage of the fact that devices stay disconnected
     45  1.6   mycroft  * from the bus a relatively long time and that while they're disconnected,
     46  1.6   mycroft  * having the SCBs for that device down on the host adapter is of little use.
     47  1.6   mycroft  * Instead we copy the SCB back up into kernel memory and reuse the SCB slot
     48  1.6   mycroft  * on the card to schedule another transaction.  This can be a real payoff
     49  1.6   mycroft  * when doing random I/O to tagged queueing devices since there are more
     50  1.6   mycroft  * transactions active at once for the device to sort for optimal seek
     51  1.6   mycroft  * reduction. The algorithm goes like this...
     52  1.6   mycroft  *
     53  1.6   mycroft  * At the sequencer level:
     54  1.6   mycroft  * 1) Disconnected SCBs are threaded onto a doubly linked list, headed by
     55  1.6   mycroft  *    DISCONNECTED_SCBH using the SCB_NEXT and SCB_PREV fields.  The most
     56  1.6   mycroft  *    recently disconnected device is always at the head.
     57  1.6   mycroft  *
     58  1.6   mycroft  * 2) The SCB has an added field SCB_TAG that corresponds to the kernel
     59  1.6   mycroft  *    SCB number (ie 0-254).
     60  1.6   mycroft  *
     61  1.6   mycroft  * 3) When a command is queued, the hardware index of the SCB it was downloaded
     62  1.6   mycroft  *    into is placed into the QINFIFO for easy indexing by the sequencer.
     63  1.6   mycroft  *
     64  1.6   mycroft  * 4) The tag field is used as the tag for tagged-queueing, for determining
     65  1.6   mycroft  *    the related kernel SCB, and is the value put into the QOUTFIFO
     66  1.6   mycroft  *    so the kernel doesn't have to upload the SCB to determine the kernel SCB
     67  1.6   mycroft  *    that completed on command completes.
     68  1.6   mycroft  *
     69  1.6   mycroft  * 5) When a reconnect occurs, the sequencer must scan the SCB array (even
     70  1.6   mycroft  *    in the tag case) looking for the appropriate SCB and if it can't find
     71  1.6   mycroft  *    it, it interrupts the kernel so it can page the SCB in.
     72  1.6   mycroft  *
     73  1.6   mycroft  * 6) If the sequencer is successful in finding the SCB, it removes it from
     74  1.6   mycroft  *    the doubly linked list of disconnected SCBS.
     75  1.6   mycroft  *
     76  1.6   mycroft  * At the kernel level:
     77  1.6   mycroft  * 1) There are four queues that a kernel SCB may reside on:
     78  1.6   mycroft  *	free_scbs - SCBs that are not in use and have a hardware slot assigned
     79  1.6   mycroft  *		    to them.
     80  1.6   mycroft  *      page_scbs - SCBs that are not in use and need to have a hardware slot
     81  1.6   mycroft  *		    assigned to them (i.e. they will most likely cause a page
     82  1.6   mycroft  *		    out event).
     83  1.6   mycroft  *	waiting_scbs - SCBs that are active, don't have an assigned hardware
     84  1.6   mycroft  *		    slot assigned to them and are waiting for either a
     85  1.6   mycroft  *		    disconnection or a command complete to free up a slot.
     86  1.6   mycroft  *	assigned_scbs - SCBs that were in the waiting_scbs queue, but were
     87  1.6   mycroft  *		    assigned a slot by ahc_free_scb.
     88  1.6   mycroft  *
     89  1.6   mycroft  * 2) When a new request comes in, an SCB is allocated from the free_scbs or
     90  1.6   mycroft  *    page_scbs queue with preference to SCBs on the free_scbs queue.
     91  1.6   mycroft  *
     92  1.6   mycroft  * 3) If there are no free slots (we retrieved the SCB off of the page_scbs
     93  1.6   mycroft  *    queue), the SCB is inserted onto the tail of the waiting_scbs list and
     94  1.6   mycroft  *    we attempt to run this queue down.
     95  1.6   mycroft  *
     96  1.6   mycroft  * 4) ahc_run_waiing_queues() looks at both the assigned_scbs and waiting_scbs
     97  1.6   mycroft  *    queues.  In the case of the assigned_scbs, the commands are immediately
     98  1.6   mycroft  *    downloaded and started.  For waiting_scbs, we page in all that we can
     99  1.6   mycroft  *    ensuring we don't create a resource deadlock (see comments in
    100  1.6   mycroft  *    ahc_run_waing_queues()).
    101  1.6   mycroft  *
    102  1.6   mycroft  * 5) After we handle a bunch of command completes, we also try running the
    103  1.6   mycroft  *    queues since many SCBs may have disconnected since the last command
    104  1.6   mycroft  *    was started and we have at least one free slot on the card.
    105  1.6   mycroft  *
    106  1.6   mycroft  * 6) ahc_free_scb looks at the waiting_scbs queue for a transaction
    107  1.6   mycroft  *    requiring a slot and moves it to the assigned_scbs queue if it
    108  1.6   mycroft  *    finds one.  Otherwise it puts the current SCB onto the free_scbs
    109  1.6   mycroft  *    queue for later use.
    110  1.6   mycroft  *
    111  1.6   mycroft  * 7) The driver handles page-in requests from the sequencer in response to
    112  1.6   mycroft  *    the NO_MATCH sequencer interrupt.  For tagged commands, the approprite
    113  1.6   mycroft  *    SCB is easily found since the tag is a direct index into our kernel SCB
    114  1.6   mycroft  *    array.  For non-tagged commands, we keep a separate array of 16 pointers
    115  1.6   mycroft  *    that point to the single possible SCB that was paged out for that target.
    116  1.1   mycroft  */
    117  1.1   mycroft 
    118  1.1   mycroft #include <sys/param.h>
    119  1.1   mycroft #include <sys/systm.h>
    120  1.6   mycroft #if defined(__NetBSD__)
    121  1.1   mycroft #include <sys/device.h>
    122  1.6   mycroft #include <machine/bus.h>
    123  1.6   mycroft #include <machine/intr.h>
    124  1.6   mycroft #endif /* defined(__NetBSD__) */
    125  1.6   mycroft 
    126  1.1   mycroft #include <sys/malloc.h>
    127  1.1   mycroft #include <sys/buf.h>
    128  1.1   mycroft #include <sys/proc.h>
    129  1.1   mycroft 
    130  1.1   mycroft #include <scsi/scsi_all.h>
    131  1.6   mycroft #if defined(__NetBSD__)
    132  1.1   mycroft #include <scsi/scsi_debug.h>
    133  1.6   mycroft #endif
    134  1.1   mycroft #include <scsi/scsiconf.h>
    135  1.1   mycroft 
    136  1.6   mycroft #if defined(__FreeBSD__)
    137  1.6   mycroft #include <machine/clock.h>
    138  1.5   mycroft #endif
    139  1.1   mycroft 
    140  1.6   mycroft #include <vm/vm.h>
    141  1.6   mycroft #include <vm/vm_param.h>
    142  1.6   mycroft #include <vm/pmap.h>
    143  1.1   mycroft 
    144  1.6   mycroft #if defined(__FreeBSD__)
    145  1.6   mycroft #include <i386/scsi/aic7xxx.h>
    146  1.1   mycroft 
    147  1.6   mycroft #include <dev/aic7xxx/aic7xxx_reg.h>
    148  1.6   mycroft #endif /* defined(__FreeBSD__) */
    149  1.1   mycroft 
    150  1.6   mycroft #if defined(__NetBSD__)
    151  1.6   mycroft #include <dev/ic/aic7xxxreg.h>
    152  1.6   mycroft #include <dev/ic/aic7xxxvar.h>
    153  1.1   mycroft 
    154  1.6   mycroft #define bootverbose	1
    155  1.1   mycroft 
    156  1.6   mycroft #define DEBUGTARG	DEBUGTARGET
    157  1.6   mycroft #if DEBUGTARG < 0	/* Negative numbrs for disabling cause warnings */
    158  1.6   mycroft #undef DEBUGTARG
    159  1.6   mycroft #define DEBUGTARG	9
    160  1.6   mycroft #endif
    161  1.6   mycroft #endif /* defined(__NetBSD__) */
    162  1.1   mycroft 
    163  1.6   mycroft #include <sys/kernel.h>
    164  1.6   mycroft #define KVTOPHYS(x)   vtophys(x)
    165  1.1   mycroft 
    166  1.6   mycroft #define MIN(a,b) ((a < b) ? a : b)
    167  1.6   mycroft #define ALL_TARGETS -1
    168  1.1   mycroft 
    169  1.6   mycroft #if defined(__FreeBSD__)
    170  1.6   mycroft u_long ahc_unit = 0;
    171  1.6   mycroft #endif
    172  1.1   mycroft 
    173  1.6   mycroft #ifdef AHC_DEBUG
    174  1.9  explorer static int     ahc_debug = AHC_DEBUG;
    175  1.6   mycroft #endif
    176  1.1   mycroft 
    177  1.6   mycroft #ifdef AHC_BROKEN_CACHE
    178  1.6   mycroft int ahc_broken_cache = 1;
    179  1.1   mycroft 
    180  1.1   mycroft /*
    181  1.6   mycroft  * "wbinvd" cause writing back whole cache (both CPU internal & external)
    182  1.6   mycroft  * to memory, so that the instruction takes a lot of time.
    183  1.6   mycroft  * This makes machine slow.
    184  1.1   mycroft  */
    185  1.6   mycroft #define	INVALIDATE_CACHE()	__asm __volatile("wbinvd")
    186  1.6   mycroft #endif
    187  1.1   mycroft 
    188  1.6   mycroft /**** bit definitions for SCSIDEF ****/
    189  1.6   mycroft #define	HSCSIID		0x07		/* our SCSI ID */
    190  1.6   mycroft #define HWSCSIID	0x0f		/* our SCSI ID if Wide Bus */
    191  1.1   mycroft 
    192  1.6   mycroft static void	 ahcminphys __P((struct buf *bp));
    193  1.6   mycroft static int32_t	 ahc_scsi_cmd __P((struct scsi_xfer *xs));
    194  1.1   mycroft 
    195  1.6   mycroft static struct scsi_adapter ahc_switch =
    196  1.6   mycroft {
    197  1.6   mycroft         ahc_scsi_cmd,
    198  1.6   mycroft         ahcminphys,
    199  1.6   mycroft         0,
    200  1.6   mycroft         0,
    201  1.6   mycroft #if defined(__FreeBSD__)
    202  1.6   mycroft         0,
    203  1.6   mycroft         "ahc",
    204  1.6   mycroft         { 0, 0 }
    205  1.6   mycroft #endif
    206  1.6   mycroft };
    207  1.1   mycroft 
    208  1.6   mycroft /* the below structure is so we have a default dev struct for our link struct */
    209  1.6   mycroft static struct scsi_device ahc_dev =
    210  1.6   mycroft {
    211  1.6   mycroft     NULL,                       /* Use default error handler */
    212  1.6   mycroft     NULL,                       /* have a queue, served by this */
    213  1.6   mycroft     NULL,                       /* have no async handler */
    214  1.6   mycroft     NULL,                       /* Use default 'done' routine */
    215  1.6   mycroft #if defined(__FreeBSD__)
    216  1.6   mycroft     "ahc",
    217  1.6   mycroft     0,
    218  1.6   mycroft     { 0, 0 }
    219  1.6   mycroft #endif
    220  1.6   mycroft };
    221  1.1   mycroft 
    222  1.1   mycroft /*
    223  1.6   mycroft  * Since the sequencer can disable pausing in a critical section, we
    224  1.6   mycroft  * must loop until it actually stops.
    225  1.6   mycroft  * XXX Should add a timeout in here??
    226  1.1   mycroft  */
    227  1.6   mycroft #define PAUSE_SEQUENCER(ahc)					\
    228  1.6   mycroft 	AHC_OUTB(ahc, HCNTRL, ahc->pause);			\
    229  1.6   mycroft 								\
    230  1.6   mycroft 	while ((AHC_INB(ahc, HCNTRL) & PAUSE) == 0)		\
    231  1.6   mycroft 		;
    232  1.1   mycroft 
    233  1.6   mycroft #define UNPAUSE_SEQUENCER(ahc)					\
    234  1.6   mycroft 	AHC_OUTB(ahc, HCNTRL, ahc->unpause )
    235  1.1   mycroft 
    236  1.1   mycroft /*
    237  1.6   mycroft  * Restart the sequencer program from address zero
    238  1.1   mycroft  */
    239  1.6   mycroft #define RESTART_SEQUENCER(ahc)						\
    240  1.6   mycroft 	do {								\
    241  1.6   mycroft 		AHC_OUTB(ahc, SEQCTL, SEQRESET|FASTMODE);		\
    242  1.9  explorer 	} while((AHC_INB(ahc, SEQADDR0) != 0)				\
    243  1.9  explorer 		|| (AHC_INB(ahc, SEQADDR1) != 0));			\
    244  1.6   mycroft 									\
    245  1.6   mycroft 	UNPAUSE_SEQUENCER(ahc);
    246  1.1   mycroft 
    247  1.6   mycroft #if defined(__NetBSD__)
    248  1.1   mycroft /*
    249  1.6   mycroft  * Is device which is pointed by sc_link connected on second scsi bus ?
    250  1.1   mycroft  */
    251  1.6   mycroft #define	IS_SCSIBUS_B(ahc, sc_link)	\
    252  1.6   mycroft 	((sc_link)->scsibus == (ahc)->sc_link_b.scsibus)
    253  1.1   mycroft 
    254  1.1   mycroft /*
    255  1.6   mycroft  * convert FreeBSD's SCSI symbols to NetBSD's
    256  1.6   mycroft  */
    257  1.6   mycroft #define	SCSI_NOMASK	SCSI_POLL
    258  1.6   mycroft #define	opennings	openings
    259  1.6   mycroft #endif
    260  1.6   mycroft 
    261  1.6   mycroft static u_char	ahc_abort_wscb __P((struct ahc_data *ahc, struct scb *scbp,
    262  1.6   mycroft 				    u_char prev,
    263  1.6   mycroft 				    u_char timedout_scb, u_int32_t xs_error));
    264  1.6   mycroft static void	ahc_add_waiting_scb __P((struct ahc_data *ahc,
    265  1.6   mycroft 					 struct scb *scb));
    266  1.6   mycroft static void	ahc_done __P((struct ahc_data *ahc, struct scb *scbp));
    267  1.6   mycroft static void	ahc_free_scb __P((struct ahc_data *ahc, struct scb *scb,
    268  1.6   mycroft 				  int flags));
    269  1.6   mycroft static inline void ahc_send_scb __P((struct ahc_data *ahc, struct scb *scb));
    270  1.6   mycroft static inline void ahc_fetch_scb __P((struct ahc_data *ahc, struct scb *scb));
    271  1.6   mycroft static inline void ahc_page_scb __P((struct ahc_data *ahc, struct scb *out_scb,
    272  1.6   mycroft 				struct scb *in_scb));
    273  1.6   mycroft static inline void ahc_run_waiting_queues __P((struct ahc_data *ahc));
    274  1.6   mycroft static struct scb *
    275  1.6   mycroft 		ahc_get_scb __P((struct ahc_data *ahc, int flags));
    276  1.6   mycroft static void	ahc_loadseq __P((struct ahc_data *ahc));
    277  1.6   mycroft static int	ahc_match_scb __P((struct scb *scb, int target, char channel));
    278  1.6   mycroft static int	ahc_poll __P((struct ahc_data *ahc, int wait));
    279  1.6   mycroft #ifdef AHC_DEBUG
    280  1.6   mycroft static void	ahc_print_scb __P((struct scb *scb));
    281  1.6   mycroft #endif
    282  1.6   mycroft static int	ahc_reset_channel __P((struct ahc_data *ahc, char channel,
    283  1.6   mycroft 				       u_char timedout_scb, u_int32_t xs_error,
    284  1.6   mycroft 				       u_char initiate_reset));
    285  1.6   mycroft static int	ahc_reset_device __P((struct ahc_data *ahc, int target,
    286  1.6   mycroft 				      char channel, u_char timedout_scb,
    287  1.6   mycroft 				      u_int32_t xs_error));
    288  1.6   mycroft static void	ahc_reset_current_bus __P((struct ahc_data *ahc));
    289  1.6   mycroft static void	ahc_run_done_queue __P((struct ahc_data *ahc));
    290  1.6   mycroft static void	ahc_scsirate __P((struct ahc_data* ahc, u_char *scsirate,
    291  1.9  explorer 				  int period, int offset, char channel,
    292  1.9  explorer 				  int target));
    293  1.6   mycroft #if defined(__FreeBSD__)
    294  1.6   mycroft static timeout_t
    295  1.6   mycroft 		ahc_timeout;
    296  1.6   mycroft #elif defined(__NetBSD__)
    297  1.6   mycroft static void	ahc_timeout __P((void *));
    298  1.6   mycroft #endif
    299  1.6   mycroft static void	ahc_busy_target __P((struct ahc_data *ahc,
    300  1.6   mycroft 				     int target, char channel));
    301  1.6   mycroft static void	ahc_unbusy_target __P((struct ahc_data *ahc,
    302  1.6   mycroft 				       int target, char channel));
    303  1.1   mycroft 
    304  1.6   mycroft #if defined(__FreeBSD__)
    305  1.1   mycroft 
    306  1.6   mycroft char *ahc_name(ahc)
    307  1.6   mycroft 	struct ahc_data *ahc;
    308  1.6   mycroft {
    309  1.6   mycroft 	static char name[10];
    310  1.1   mycroft 
    311  1.6   mycroft 	sprintf(name, "ahc%d", ahc->unit);
    312  1.6   mycroft 	return (name);
    313  1.6   mycroft }
    314  1.1   mycroft 
    315  1.6   mycroft #elif defined(__NetBSD__)
    316  1.6   mycroft struct cfdriver ahc_cd = {
    317  1.6   mycroft 	NULL, "ahc", DV_DULL
    318  1.6   mycroft };
    319  1.6   mycroft #endif
    320  1.1   mycroft 
    321  1.1   mycroft #ifdef  AHC_DEBUG
    322  1.6   mycroft static void
    323  1.1   mycroft ahc_print_scb(scb)
    324  1.6   mycroft         struct scb *scb;
    325  1.1   mycroft {
    326  1.6   mycroft         printf("scb:%p control:0x%x tcl:0x%x cmdlen:%d cmdpointer:0x%lx\n"
    327  1.6   mycroft 	    ,scb
    328  1.6   mycroft 	    ,scb->control
    329  1.6   mycroft 	    ,scb->tcl
    330  1.6   mycroft 	    ,scb->cmdlen
    331  1.6   mycroft 	    ,scb->cmdpointer );
    332  1.6   mycroft         printf("        datlen:%d data:0x%lx segs:0x%x segp:0x%lx\n"
    333  1.6   mycroft 	    ,scb->datalen
    334  1.6   mycroft 	    ,scb->data
    335  1.6   mycroft 	    ,scb->SG_segment_count
    336  1.6   mycroft 	    ,scb->SG_list_pointer);
    337  1.6   mycroft 	printf("	sg_addr:%lx sg_len:%ld\n"
    338  1.6   mycroft 	    ,scb->ahc_dma[0].addr
    339  1.6   mycroft 	    ,scb->ahc_dma[0].len);
    340  1.1   mycroft }
    341  1.1   mycroft 
    342  1.1   mycroft #endif
    343  1.1   mycroft 
    344  1.1   mycroft static struct {
    345  1.6   mycroft         u_char errno;
    346  1.1   mycroft 	char *errmesg;
    347  1.1   mycroft } hard_error[] = {
    348  1.1   mycroft 	{ ILLHADDR,  "Illegal Host Access" },
    349  1.1   mycroft 	{ ILLSADDR,  "Illegal Sequencer Address referrenced" },
    350  1.1   mycroft 	{ ILLOPCODE, "Illegal Opcode in sequencer program" },
    351  1.1   mycroft 	{ PARERR,    "Sequencer Ram Parity Error" }
    352  1.1   mycroft };
    353  1.1   mycroft 
    354  1.1   mycroft 
    355  1.1   mycroft /*
    356  1.1   mycroft  * Valid SCSIRATE values.  (p. 3-17)
    357  1.1   mycroft  * Provides a mapping of tranfer periods in ns to the proper value to
    358  1.1   mycroft  * stick in the scsiscfr reg to use that transfer rate.
    359  1.1   mycroft  */
    360  1.1   mycroft static struct {
    361  1.6   mycroft 	short sxfr;
    362  1.6   mycroft 	/* Rates in Ultra mode have bit 8 of sxfr set */
    363  1.6   mycroft #define		ULTRA_SXFR 0x100
    364  1.6   mycroft 	short period; /* in ns */
    365  1.1   mycroft 	char *rate;
    366  1.1   mycroft } ahc_syncrates[] = {
    367  1.6   mycroft 	{ 0x100,  50, "20.0"  },
    368  1.6   mycroft 	{ 0x110,  62, "16.0"  },
    369  1.6   mycroft 	{ 0x120,  75, "13.4"  },
    370  1.6   mycroft 	{ 0x000, 100, "10.0"  },
    371  1.6   mycroft 	{ 0x010, 125,  "8.0"  },
    372  1.6   mycroft 	{ 0x020, 150,  "6.67" },
    373  1.6   mycroft 	{ 0x030, 175,  "5.7"  },
    374  1.6   mycroft 	{ 0x040, 200,  "5.0"  },
    375  1.6   mycroft 	{ 0x050, 225,  "4.4"  },
    376  1.6   mycroft 	{ 0x060, 250,  "4.0"  },
    377  1.6   mycroft 	{ 0x070, 275,  "3.6"  }
    378  1.1   mycroft };
    379  1.1   mycroft 
    380  1.1   mycroft static int ahc_num_syncrates =
    381  1.1   mycroft 	sizeof(ahc_syncrates) / sizeof(ahc_syncrates[0]);
    382  1.1   mycroft 
    383  1.1   mycroft /*
    384  1.6   mycroft  * Allocate a controller structures for a new device and initialize it.
    385  1.6   mycroft  * ahc_reset should be called before now since we assume that the card
    386  1.6   mycroft  * is paused.
    387  1.6   mycroft  *
    388  1.1   mycroft  */
    389  1.6   mycroft #if defined(__FreeBSD__)
    390  1.6   mycroft struct ahc_data *
    391  1.6   mycroft ahc_alloc(unit, iobase, type, flags)
    392  1.6   mycroft 	int unit;
    393  1.6   mycroft 	u_long iobase;
    394  1.6   mycroft #elif defined(__NetBSD__)
    395  1.6   mycroft void
    396  1.6   mycroft ahc_construct(ahc, bc, ioh, type, flags)
    397  1.6   mycroft 	struct  ahc_data *ahc;
    398  1.6   mycroft 	bus_chipset_tag_t bc;
    399  1.6   mycroft 	bus_io_handle_t ioh;
    400  1.6   mycroft #endif
    401  1.6   mycroft 	ahc_type type;
    402  1.6   mycroft 	ahc_flag flags;
    403  1.6   mycroft {
    404  1.1   mycroft 
    405  1.6   mycroft 	/*
    406  1.6   mycroft 	 * find unit and check we have that many defined
    407  1.6   mycroft 	 */
    408  1.1   mycroft 
    409  1.6   mycroft #if defined(__FreeBSD__)
    410  1.6   mycroft 	struct  ahc_data *ahc;
    411  1.1   mycroft 
    412  1.1   mycroft 	/*
    413  1.6   mycroft 	 * Allocate a storage area for us
    414  1.1   mycroft 	 */
    415  1.1   mycroft 
    416  1.6   mycroft 	ahc = malloc(sizeof(struct ahc_data), M_TEMP, M_NOWAIT);
    417  1.6   mycroft 	if (!ahc) {
    418  1.6   mycroft 		printf("ahc%d: cannot malloc!\n", unit);
    419  1.6   mycroft 		return NULL;
    420  1.6   mycroft 	}
    421  1.6   mycroft 	bzero(ahc, sizeof(struct ahc_data));
    422  1.6   mycroft #endif
    423  1.9  explorer 	STAILQ_INIT(&ahc->free_scbs);
    424  1.9  explorer 	STAILQ_INIT(&ahc->page_scbs);
    425  1.9  explorer 	STAILQ_INIT(&ahc->waiting_scbs);
    426  1.9  explorer 	STAILQ_INIT(&ahc->assigned_scbs);
    427  1.6   mycroft #if defined(__FreeBSD__)
    428  1.6   mycroft 	ahc->unit = unit;
    429  1.9  explorer #endif
    430  1.9  explorer #if defined(__FreeBSD__)
    431  1.6   mycroft 	ahc->baseport = iobase;
    432  1.6   mycroft #elif defined(__NetBSD__)
    433  1.6   mycroft 	ahc->sc_bc = bc;
    434  1.6   mycroft 	ahc->sc_ioh = ioh;
    435  1.6   mycroft #endif
    436  1.6   mycroft 	ahc->type = type;
    437  1.6   mycroft 	ahc->flags = flags;
    438  1.6   mycroft 	ahc->unpause = (AHC_INB(ahc, HCNTRL) & IRQMS) | INTEN;
    439  1.6   mycroft 	ahc->pause = ahc->unpause | PAUSE;
    440  1.6   mycroft 
    441  1.6   mycroft #if defined(__FreeBSD__)
    442  1.6   mycroft 	return (ahc);
    443  1.6   mycroft #endif
    444  1.6   mycroft }
    445  1.1   mycroft 
    446  1.6   mycroft void
    447  1.6   mycroft ahc_free(ahc)
    448  1.6   mycroft 	struct ahc_data *ahc;
    449  1.6   mycroft {
    450  1.6   mycroft #if defined(__FreeBSD__)
    451  1.6   mycroft 	free(ahc, M_DEVBUF);
    452  1.6   mycroft 	return;
    453  1.6   mycroft #endif
    454  1.1   mycroft }
    455  1.1   mycroft 
    456  1.6   mycroft void
    457  1.6   mycroft #if defined(__FreeBSD__)
    458  1.6   mycroft ahc_reset(iobase)
    459  1.6   mycroft 	u_long iobase;
    460  1.6   mycroft #elif defined(__NetBSD__)
    461  1.6   mycroft ahc_reset(devname, bc, ioh)
    462  1.6   mycroft 	char *devname;
    463  1.6   mycroft 	bus_chipset_tag_t bc;
    464  1.6   mycroft 	bus_io_handle_t ioh;
    465  1.6   mycroft #endif
    466  1.6   mycroft {
    467  1.6   mycroft         u_char hcntrl;
    468  1.6   mycroft 	int wait;
    469  1.6   mycroft 
    470  1.6   mycroft 	/* Retain the IRQ type accross the chip reset */
    471  1.6   mycroft #if defined(__FreeBSD__)
    472  1.6   mycroft 	hcntrl = (inb(HCNTRL + iobase) & IRQMS) | INTEN;
    473  1.6   mycroft 
    474  1.6   mycroft 	outb(HCNTRL + iobase, CHIPRST | PAUSE);
    475  1.6   mycroft #elif defined(__NetBSD__)
    476  1.6   mycroft 	hcntrl = (bus_io_read_1(bc, ioh, HCNTRL) & IRQMS) | INTEN;
    477  1.6   mycroft 
    478  1.6   mycroft 	bus_io_write_1(bc, ioh, HCNTRL, CHIPRST | PAUSE);
    479  1.6   mycroft #endif
    480  1.6   mycroft 	/*
    481  1.6   mycroft 	 * Ensure that the reset has finished
    482  1.6   mycroft 	 */
    483  1.6   mycroft 	wait = 1000;
    484  1.6   mycroft #if defined(__FreeBSD__)
    485  1.6   mycroft 	while (--wait && !(inb(HCNTRL + iobase) & CHIPRSTACK))
    486  1.6   mycroft #elif defined(__NetBSD__)
    487  1.6   mycroft 	while (--wait && !(bus_io_read_1(bc, ioh, HCNTRL) & CHIPRSTACK))
    488  1.6   mycroft #endif
    489  1.6   mycroft 		DELAY(1000);
    490  1.6   mycroft 	if(wait == 0) {
    491  1.6   mycroft #if defined(__FreeBSD__)
    492  1.6   mycroft 		printf("ahc at 0x%lx: WARNING - Failed chip reset!  "
    493  1.6   mycroft 		       "Trying to initialize anyway.\n", iobase);
    494  1.6   mycroft #elif defined(__NetBSD__)
    495  1.6   mycroft 		printf("%s: WARNING - Failed chip reset!  "
    496  1.6   mycroft 		       "Trying to initialize anyway.\n", devname);
    497  1.6   mycroft #endif
    498  1.6   mycroft 	}
    499  1.6   mycroft #if defined(__FreeBSD__)
    500  1.6   mycroft 	outb(HCNTRL + iobase, hcntrl | PAUSE);
    501  1.6   mycroft #elif defined(__NetBSD__)
    502  1.6   mycroft 	bus_io_write_1(bc, ioh, HCNTRL, hcntrl | PAUSE);
    503  1.6   mycroft #endif
    504  1.6   mycroft }
    505  1.1   mycroft 
    506  1.1   mycroft /*
    507  1.1   mycroft  * Look up the valid period to SCSIRATE conversion in our table.
    508  1.1   mycroft  */
    509  1.6   mycroft static void
    510  1.9  explorer ahc_scsirate(ahc, scsirate, period, offset, channel, target )
    511  1.6   mycroft 	struct	ahc_data *ahc;
    512  1.6   mycroft 	u_char	*scsirate;
    513  1.6   mycroft 	short	period;
    514  1.6   mycroft 	u_char	offset;
    515  1.9  explorer 	char	channel;
    516  1.6   mycroft 	int	target;
    517  1.1   mycroft {
    518  1.1   mycroft 	int i;
    519  1.1   mycroft 
    520  1.1   mycroft 	for (i = 0; i < ahc_num_syncrates; i++) {
    521  1.9  explorer 		u_char ultra_enb;
    522  1.9  explorer 		u_char sxfrctl0;
    523  1.9  explorer 		u_long ultra_enb_addr;
    524  1.6   mycroft 
    525  1.1   mycroft 		if ((ahc_syncrates[i].period - period) >= 0) {
    526  1.6   mycroft 			/*
    527  1.6   mycroft 			 * Watch out for Ultra speeds when ultra is not
    528  1.6   mycroft 			 * enabled and vice-versa.
    529  1.6   mycroft 			 */
    530  1.9  explorer 			if(!(ahc->type & AHC_ULTRA)
    531  1.9  explorer 			 && (ahc_syncrates[i].sxfr & ULTRA_SXFR)) {
    532  1.9  explorer 				/*
    533  1.9  explorer 				 * This should only happen if the
    534  1.9  explorer 				 * drive is the first to negotiate
    535  1.9  explorer 				 * and chooses a high rate.  We'll
    536  1.9  explorer 				 * just move down the table util
    537  1.9  explorer 				 * we hit a non ultra speed.
    538  1.9  explorer 				 */
    539  1.9  explorer 				continue;
    540  1.9  explorer 			}
    541  1.9  explorer 			*scsirate = (ahc_syncrates[i].sxfr) | (offset & 0x0f);
    542  1.9  explorer 
    543  1.9  explorer 			/*
    544  1.9  explorer 			 * Ensure Ultra mode is set properly for
    545  1.9  explorer 			 * this target.
    546  1.9  explorer 			 */
    547  1.9  explorer 			ultra_enb_addr = ULTRA_ENB;
    548  1.9  explorer 			if(channel == 'B' || target > 7)
    549  1.9  explorer 				ultra_enb_addr++;
    550  1.9  explorer 			ultra_enb = AHC_INB(ahc, ultra_enb_addr);
    551  1.9  explorer 			sxfrctl0 = AHC_INB(ahc, SXFRCTL0);
    552  1.9  explorer 			if (ahc_syncrates[i].sxfr & ULTRA_SXFR) {
    553  1.9  explorer 				ultra_enb |= 0x01 << (target & 0x07);
    554  1.9  explorer 				sxfrctl0 |= ULTRAEN;
    555  1.6   mycroft 			}
    556  1.6   mycroft 			else {
    557  1.9  explorer 				ultra_enb &= ~(0x01 << (target & 0x07));
    558  1.9  explorer 				sxfrctl0 &= ~ULTRAEN;
    559  1.6   mycroft 			}
    560  1.9  explorer 			AHC_OUTB(ahc, ultra_enb_addr, ultra_enb);
    561  1.9  explorer 			AHC_OUTB(ahc, SXFRCTL0, sxfrctl0);
    562  1.9  explorer 
    563  1.6   mycroft 			if(bootverbose) {
    564  1.6   mycroft 				printf("%s: target %d synchronous at %sMHz,"
    565  1.6   mycroft 				       " offset = 0x%x\n",
    566  1.6   mycroft 				        ahc_name(ahc), target,
    567  1.6   mycroft 					ahc_syncrates[i].rate, offset );
    568  1.6   mycroft 			}
    569  1.6   mycroft 			return;
    570  1.1   mycroft 		}
    571  1.1   mycroft 	}
    572  1.1   mycroft 	/* Default to asyncronous transfers.  Also reject this SDTR request. */
    573  1.6   mycroft 	*scsirate = 0;
    574  1.6   mycroft 	if(bootverbose) {
    575  1.6   mycroft 		printf("%s: target %d using asyncronous transfers\n",
    576  1.6   mycroft 			ahc_name(ahc), target );
    577  1.6   mycroft 	}
    578  1.1   mycroft }
    579  1.1   mycroft 
    580  1.6   mycroft #if defined(__NetBSD__)
    581  1.4   mycroft int
    582  1.4   mycroft ahcprint(aux, name)
    583  1.4   mycroft 	void *aux;
    584  1.4   mycroft 	char *name;
    585  1.1   mycroft {
    586  1.1   mycroft 
    587  1.4   mycroft 	if (name != NULL)
    588  1.4   mycroft 		printf("%s: scsibus ", name);
    589  1.4   mycroft 	return UNCONF;
    590  1.1   mycroft }
    591  1.6   mycroft #endif
    592  1.1   mycroft 
    593  1.1   mycroft /*
    594  1.1   mycroft  * Attach all the sub-devices we can find
    595  1.1   mycroft  */
    596  1.1   mycroft int
    597  1.6   mycroft ahc_attach(ahc)
    598  1.6   mycroft 	struct ahc_data *ahc;
    599  1.1   mycroft {
    600  1.6   mycroft 	struct scsibus_data *scbus;
    601  1.1   mycroft 
    602  1.6   mycroft #ifdef AHC_BROKEN_CACHE
    603  1.6   mycroft 	if (cpu_class == CPUCLASS_386)	/* doesn't have "wbinvd" instruction */
    604  1.6   mycroft 		ahc_broken_cache = 0;
    605  1.6   mycroft #endif
    606  1.1   mycroft 	/*
    607  1.6   mycroft 	 * fill in the prototype scsi_links.
    608  1.1   mycroft 	 */
    609  1.6   mycroft #if defined(__FreeBSD__)
    610  1.6   mycroft 	ahc->sc_link.adapter_unit = ahc->unit;
    611  1.6   mycroft 	ahc->sc_link.adapter_targ = ahc->our_id;
    612  1.6   mycroft 	ahc->sc_link.fordriver = 0;
    613  1.6   mycroft #elif defined(__NetBSD__)
    614  1.6   mycroft 	ahc->sc_link.adapter_target = ahc->our_id;
    615  1.6   mycroft #endif
    616  1.1   mycroft 	ahc->sc_link.adapter_softc = ahc;
    617  1.1   mycroft 	ahc->sc_link.adapter = &ahc_switch;
    618  1.6   mycroft 	ahc->sc_link.opennings = 2;
    619  1.1   mycroft 	ahc->sc_link.device = &ahc_dev;
    620  1.1   mycroft 	ahc->sc_link.flags = DEBUGLEVEL;
    621  1.6   mycroft 
    622  1.6   mycroft 	if(ahc->type & AHC_TWIN) {
    623  1.6   mycroft 		/* Configure the second scsi bus */
    624  1.6   mycroft 		ahc->sc_link_b = ahc->sc_link;
    625  1.6   mycroft #if defined(__FreeBSD__)
    626  1.6   mycroft 		ahc->sc_link_b.adapter_targ = ahc->our_id_b;
    627  1.6   mycroft 		ahc->sc_link_b.adapter_bus = 1;
    628  1.6   mycroft 		ahc->sc_link_b.fordriver = (void *)SELBUSB;
    629  1.6   mycroft #elif defined(__NetBSD__)
    630  1.6   mycroft 		ahc->sc_link_b.adapter_target = ahc->our_id_b;
    631  1.6   mycroft #endif
    632  1.6   mycroft 	}
    633  1.6   mycroft 
    634  1.6   mycroft 
    635  1.6   mycroft #if defined(__FreeBSD__)
    636  1.6   mycroft 	/*
    637  1.6   mycroft 	 * Prepare the scsibus_data area for the upperlevel
    638  1.6   mycroft 	 * scsi code.
    639  1.6   mycroft 	 */
    640  1.6   mycroft 	scbus = scsi_alloc_bus();
    641  1.6   mycroft 	if(!scbus)
    642  1.6   mycroft 		return 0;
    643  1.6   mycroft 	scbus->adapter_link = (ahc->flags & AHC_CHANNEL_B_PRIMARY) ?
    644  1.6   mycroft 				&ahc->sc_link_b : &ahc->sc_link;
    645  1.6   mycroft 	if(ahc->type & AHC_WIDE)
    646  1.6   mycroft 		scbus->maxtarg = 15;
    647  1.6   mycroft 
    648  1.6   mycroft 	/*
    649  1.6   mycroft 	 * ask the adapter what subunits are present
    650  1.6   mycroft 	 */
    651  1.6   mycroft 	if(bootverbose)
    652  1.6   mycroft 		printf("ahc%d: Probing channel %c\n", ahc->unit,
    653  1.6   mycroft 			(ahc->flags & AHC_CHANNEL_B_PRIMARY) ? 'B' : 'A');
    654  1.6   mycroft 	scsi_attachdevs(scbus);
    655  1.6   mycroft 	scbus = NULL;	/* Upper-level SCSI code owns this now */
    656  1.6   mycroft 
    657  1.6   mycroft 	if(ahc->type & AHC_TWIN) {
    658  1.6   mycroft 		scbus =  scsi_alloc_bus();
    659  1.6   mycroft 		if(!scbus)
    660  1.6   mycroft 			return 0;
    661  1.6   mycroft 		scbus->adapter_link = (ahc->flags & AHC_CHANNEL_B_PRIMARY) ?
    662  1.6   mycroft 					&ahc->sc_link : &ahc->sc_link_b;
    663  1.6   mycroft 		if(ahc->type & AHC_WIDE)
    664  1.6   mycroft 			scbus->maxtarg = 15;
    665  1.6   mycroft 		if(bootverbose)
    666  1.6   mycroft 			printf("ahc%d: Probing Channel %c\n", ahc->unit,
    667  1.6   mycroft 			       (ahc->flags & AHC_CHANNEL_B_PRIMARY) ? 'A': 'B');
    668  1.6   mycroft 		scsi_attachdevs(scbus);
    669  1.6   mycroft 		scbus = NULL;	/* Upper-level SCSI code owns this now */
    670  1.6   mycroft 	}
    671  1.6   mycroft #elif defined(__NetBSD__)
    672  1.6   mycroft 	/*
    673  1.6   mycroft 	 * XXX - Update MI SCSI code
    674  1.6   mycroft 	 *
    675  1.6   mycroft 	 * if(ahc->type & AHC_WIDE)
    676  1.6   mycroft 	 *	max target of both channel A and B = 15;
    677  1.6   mycroft 	 */
    678  1.1   mycroft 
    679  1.1   mycroft 	/*
    680  1.1   mycroft 	 * ask the adapter what subunits are present
    681  1.1   mycroft 	 */
    682  1.6   mycroft 	if ((ahc->flags & AHC_CHANNEL_B_PRIMARY) == 0) {
    683  1.6   mycroft 		/* make IS_SCSIBUS_B() == false, while probing channel A */
    684  1.6   mycroft 		ahc->sc_link_b.scsibus = 0xff;
    685  1.6   mycroft 
    686  1.6   mycroft 		if (ahc->type & AHC_TWIN)
    687  1.6   mycroft 			printf("%s: Probing channel A\n", ahc_name(ahc));
    688  1.6   mycroft 		config_found((void *)ahc, &ahc->sc_link, ahcprint);
    689  1.6   mycroft 		if (ahc->type & AHC_TWIN) {
    690  1.6   mycroft 			printf("%s: Probing channel B\n", ahc_name(ahc));
    691  1.6   mycroft 			config_found((void *)ahc, &ahc->sc_link_b, ahcprint);
    692  1.6   mycroft 		}
    693  1.6   mycroft 	} else {
    694  1.6   mycroft 		/*
    695  1.6   mycroft 		 * if implementation of IS_SCSIBUS_B() is changed to use
    696  1.6   mycroft 		 * ahc->sc_link.scsibus, then "ahc->sc_link.scsibus = 0xff;"
    697  1.6   mycroft 		 * is needed, here.
    698  1.6   mycroft 		 */
    699  1.6   mycroft 
    700  1.6   mycroft 		/* assert(ahc->type & AHC_TWIN); */
    701  1.6   mycroft 		printf("%s: Probing channel B\n", ahc_name(ahc));
    702  1.1   mycroft 		config_found((void *)ahc, &ahc->sc_link_b, ahcprint);
    703  1.6   mycroft 		printf("%s: Probing channel A\n", ahc_name(ahc));
    704  1.6   mycroft 		config_found((void *)ahc, &ahc->sc_link, ahcprint);
    705  1.1   mycroft 	}
    706  1.6   mycroft #endif
    707  1.1   mycroft 	return 1;
    708  1.1   mycroft }
    709  1.1   mycroft 
    710  1.6   mycroft /*
    711  1.6   mycroft  * Send an SCB down to the card via PIO.
    712  1.6   mycroft  * We assume that the proper SCB is already selected in SCBPTR.
    713  1.6   mycroft  */
    714  1.6   mycroft static inline void
    715  1.1   mycroft ahc_send_scb(ahc, scb)
    716  1.6   mycroft         struct	ahc_data *ahc;
    717  1.6   mycroft         struct	scb *scb;
    718  1.1   mycroft {
    719  1.6   mycroft 	AHC_OUTB(ahc, SCBCNT, SCBAUTO);
    720  1.6   mycroft 	if( ahc->type == AHC_284 )
    721  1.6   mycroft 		/* Can only do 8bit PIO */
    722  1.6   mycroft 		AHC_OUTSB(ahc, SCBARRAY, scb, SCB_PIO_TRANSFER_SIZE);
    723  1.6   mycroft 	else
    724  1.6   mycroft 		AHC_OUTSL(ahc, SCBARRAY, scb,
    725  1.6   mycroft 		      (SCB_PIO_TRANSFER_SIZE + 3) / 4);
    726  1.6   mycroft 	AHC_OUTB(ahc, SCBCNT, 0);
    727  1.6   mycroft }
    728  1.6   mycroft 
    729  1.6   mycroft /*
    730  1.6   mycroft  * Retrieve an SCB from the card via PIO.
    731  1.6   mycroft  * We assume that the proper SCB is already selected in SCBPTR.
    732  1.6   mycroft  */
    733  1.6   mycroft static inline void
    734  1.6   mycroft ahc_fetch_scb(ahc, scb)
    735  1.6   mycroft 	struct	ahc_data *ahc;
    736  1.6   mycroft 	struct	scb *scb;
    737  1.6   mycroft {
    738  1.6   mycroft 	AHC_OUTB(ahc, SCBCNT, 0x80);	/* SCBAUTO */
    739  1.6   mycroft 
    740  1.6   mycroft 	/* Can only do 8bit PIO for reads */
    741  1.6   mycroft 	AHC_INSB(ahc, SCBARRAY, scb, SCB_PIO_TRANSFER_SIZE);
    742  1.6   mycroft 
    743  1.6   mycroft 	AHC_OUTB(ahc, SCBCNT, 0);
    744  1.6   mycroft }
    745  1.6   mycroft 
    746  1.6   mycroft /*
    747  1.6   mycroft  * Swap in_scbp for out_scbp down in the cards SCB array.
    748  1.6   mycroft  * We assume that the SCB for out_scbp is already selected in SCBPTR.
    749  1.6   mycroft  */
    750  1.6   mycroft static inline void
    751  1.6   mycroft ahc_page_scb(ahc, out_scbp, in_scbp)
    752  1.6   mycroft 	struct ahc_data *ahc;
    753  1.6   mycroft 	struct scb *out_scbp;
    754  1.6   mycroft 	struct scb *in_scbp;
    755  1.6   mycroft {
    756  1.6   mycroft 	/* Page-out */
    757  1.6   mycroft 	ahc_fetch_scb(ahc, out_scbp);
    758  1.6   mycroft 	out_scbp->flags |= SCB_PAGED_OUT;
    759  1.6   mycroft 	if(!(out_scbp->control & TAG_ENB))
    760  1.6   mycroft 	{
    761  1.6   mycroft 		/* Stick in non-tagged array */
    762  1.6   mycroft 		int index =  (out_scbp->tcl >> 4)
    763  1.6   mycroft 			   | (out_scbp->tcl & SELBUSB);
    764  1.6   mycroft 		ahc->pagedout_ntscbs[index] = out_scbp;
    765  1.6   mycroft 	}
    766  1.6   mycroft 
    767  1.6   mycroft 	/* Page-in */
    768  1.6   mycroft 	in_scbp->position = out_scbp->position;
    769  1.6   mycroft 	out_scbp->position = SCB_LIST_NULL;
    770  1.6   mycroft 	ahc_send_scb(ahc, in_scbp);
    771  1.6   mycroft 	in_scbp->flags &= ~SCB_PAGED_OUT;
    772  1.6   mycroft }
    773  1.6   mycroft 
    774  1.6   mycroft static inline void
    775  1.6   mycroft ahc_run_waiting_queues(ahc)
    776  1.6   mycroft 	struct ahc_data *ahc;
    777  1.6   mycroft {
    778  1.6   mycroft 	struct scb* scb;
    779  1.6   mycroft 	u_char cur_scb;
    780  1.6   mycroft 
    781  1.9  explorer 	if(!(ahc->assigned_scbs.stqh_first || ahc->waiting_scbs.stqh_first))
    782  1.6   mycroft 		return;
    783  1.1   mycroft 
    784  1.1   mycroft 	PAUSE_SEQUENCER(ahc);
    785  1.6   mycroft 	cur_scb = AHC_INB(ahc, SCBPTR);
    786  1.6   mycroft 
    787  1.6   mycroft 	/*
    788  1.6   mycroft 	 * First handle SCBs that are waiting but have been
    789  1.6   mycroft 	 * assigned a slot.
    790  1.6   mycroft 	 */
    791  1.9  explorer 	while((scb = ahc->assigned_scbs.stqh_first) != NULL) {
    792  1.9  explorer 		STAILQ_REMOVE_HEAD(&ahc->assigned_scbs, links);
    793  1.6   mycroft 		AHC_OUTB(ahc, SCBPTR, scb->position);
    794  1.6   mycroft 		ahc_send_scb(ahc, scb);
    795  1.6   mycroft 
    796  1.6   mycroft 		/* Mark this as an active command */
    797  1.9  explorer 		scb->flags ^= SCB_ASSIGNEDQ|SCB_ACTIVE;
    798  1.6   mycroft 
    799  1.6   mycroft 		AHC_OUTB(ahc, QINFIFO, scb->position);
    800  1.6   mycroft 		if (!(scb->xs->flags & SCSI_NOMASK)) {
    801  1.6   mycroft 			timeout(ahc_timeout, (caddr_t)scb,
    802  1.6   mycroft 				(scb->xs->timeout * hz) / 1000);
    803  1.6   mycroft 		}
    804  1.6   mycroft 		SC_DEBUG(scb->xs->sc_link, SDEV_DB3, ("cmd_sent\n"));
    805  1.6   mycroft 	}
    806  1.6   mycroft 	/* Now deal with SCBs that require paging */
    807  1.9  explorer 	if((scb = ahc->waiting_scbs.stqh_first) != NULL) {
    808  1.6   mycroft 		u_char disc_scb = AHC_INB(ahc, DISCONNECTED_SCBH);
    809  1.6   mycroft 		u_char active = AHC_INB(ahc, FLAGS) & (SELECTED|IDENTIFY_SEEN);
    810  1.6   mycroft 		int count = 0;
    811  1.6   mycroft 
    812  1.6   mycroft 		do {
    813  1.6   mycroft 			u_char next_scb;
    814  1.6   mycroft 
    815  1.6   mycroft 			/* Attempt to page this SCB in */
    816  1.6   mycroft 			if(disc_scb == SCB_LIST_NULL)
    817  1.6   mycroft 				break;
    818  1.6   mycroft 
    819  1.6   mycroft 			/*
    820  1.9  explorer 			 * Check the next SCB on in the list.
    821  1.6   mycroft 			 */
    822  1.6   mycroft 			AHC_OUTB(ahc, SCBPTR, disc_scb);
    823  1.6   mycroft 			next_scb = AHC_INB(ahc, SCB_NEXT);
    824  1.6   mycroft 
    825  1.6   mycroft 			/*
    826  1.6   mycroft 			 * We have to be careful about when we allow
    827  1.6   mycroft 			 * an SCB to be paged out.  There must always
    828  1.6   mycroft 			 * be at least one slot availible for a
    829  1.6   mycroft 			 * reconnecting target in case it references
    830  1.6   mycroft 			 * an SCB that has been paged out.  Our
    831  1.6   mycroft 			 * heuristic is that either the disconnected
    832  1.6   mycroft 			 * list has at least two entries in it or
    833  1.6   mycroft 			 * there is one entry and the sequencer is
    834  1.6   mycroft 			 * activily working on an SCB which implies that
    835  1.6   mycroft 			 * it will either complete or disconnect before
    836  1.6   mycroft 			 * another reconnection can occur.
    837  1.6   mycroft 			 */
    838  1.6   mycroft 			if((next_scb != SCB_LIST_NULL) || active)
    839  1.6   mycroft 			{
    840  1.6   mycroft 				u_char out_scbi;
    841  1.6   mycroft 				struct scb* out_scbp;
    842  1.6   mycroft 
    843  1.9  explorer 				STAILQ_REMOVE_HEAD(&ahc->waiting_scbs, links);
    844  1.6   mycroft 
    845  1.6   mycroft 				/*
    846  1.6   mycroft 				 * Find the in-core SCB for the one
    847  1.6   mycroft 				 * we're paging out.
    848  1.6   mycroft 				 */
    849  1.6   mycroft 				out_scbi = AHC_INB(ahc, SCB_TAG);
    850  1.6   mycroft 				out_scbp = ahc->scbarray[out_scbi];
    851  1.6   mycroft 
    852  1.6   mycroft 				/* Do the page out */
    853  1.6   mycroft 				ahc_page_scb(ahc, out_scbp, scb);
    854  1.6   mycroft 
    855  1.6   mycroft 				/* Mark this as an active command */
    856  1.9  explorer 				scb->flags ^= SCB_WAITINGQ|SCB_ACTIVE;
    857  1.6   mycroft 
    858  1.6   mycroft 				/* Queue the command */
    859  1.6   mycroft 				AHC_OUTB(ahc, QINFIFO, scb->position);
    860  1.6   mycroft 				if (!(scb->xs->flags & SCSI_NOMASK)) {
    861  1.6   mycroft 					timeout(ahc_timeout, (caddr_t)scb,
    862  1.6   mycroft 						(scb->xs->timeout * hz) / 1000);
    863  1.6   mycroft 				}
    864  1.6   mycroft 				SC_DEBUG(scb->xs->sc_link, SDEV_DB3,
    865  1.6   mycroft 					("cmd_paged-in\n"));
    866  1.6   mycroft 				count++;
    867  1.6   mycroft 
    868  1.6   mycroft 				/* Advance to the next disconnected SCB */
    869  1.6   mycroft 				disc_scb = next_scb;
    870  1.6   mycroft 			}
    871  1.6   mycroft 			else
    872  1.6   mycroft 				break;
    873  1.9  explorer 		} while((scb = ahc->waiting_scbs.stqh_first) != NULL);
    874  1.6   mycroft 
    875  1.6   mycroft 		if(count) {
    876  1.6   mycroft 			/*
    877  1.6   mycroft 			 * Update the head of the disconnected list.
    878  1.6   mycroft 			 */
    879  1.6   mycroft 			AHC_OUTB(ahc, DISCONNECTED_SCBH, disc_scb);
    880  1.6   mycroft 			if(disc_scb != SCB_LIST_NULL) {
    881  1.6   mycroft 				AHC_OUTB(ahc, SCBPTR, disc_scb);
    882  1.6   mycroft 				AHC_OUTB(ahc, SCB_PREV, SCB_LIST_NULL);
    883  1.6   mycroft 			}
    884  1.6   mycroft 		}
    885  1.6   mycroft 	}
    886  1.6   mycroft 	/* Restore old position */
    887  1.6   mycroft 	AHC_OUTB(ahc, SCBPTR, cur_scb);
    888  1.1   mycroft 	UNPAUSE_SEQUENCER(ahc);
    889  1.1   mycroft }
    890  1.1   mycroft 
    891  1.6   mycroft /*
    892  1.6   mycroft  * Add this SCB to the head of the "waiting for selection" list.
    893  1.6   mycroft  */
    894  1.6   mycroft static
    895  1.6   mycroft void ahc_add_waiting_scb(ahc, scb)
    896  1.6   mycroft 	struct ahc_data *ahc;
    897  1.6   mycroft 	struct scb *scb;
    898  1.1   mycroft {
    899  1.6   mycroft 	u_char next;
    900  1.6   mycroft 	u_char curscb;
    901  1.1   mycroft 
    902  1.6   mycroft 	curscb = AHC_INB(ahc, SCBPTR);
    903  1.6   mycroft 	next = AHC_INB(ahc, WAITING_SCBH);
    904  1.6   mycroft 
    905  1.6   mycroft 	AHC_OUTB(ahc, SCBPTR, scb->position);
    906  1.6   mycroft 	AHC_OUTB(ahc, SCB_NEXT, next);
    907  1.6   mycroft 	AHC_OUTB(ahc, WAITING_SCBH, scb->position);
    908  1.6   mycroft 
    909  1.6   mycroft 	AHC_OUTB(ahc, SCBPTR, curscb);
    910  1.1   mycroft }
    911  1.1   mycroft 
    912  1.1   mycroft /*
    913  1.6   mycroft  * Catch an interrupt from the adapter
    914  1.1   mycroft  */
    915  1.6   mycroft #if defined(__FreeBSD__)
    916  1.6   mycroft void
    917  1.6   mycroft #elif defined (__NetBSD__)
    918  1.1   mycroft int
    919  1.6   mycroft #endif
    920  1.6   mycroft ahc_intr(arg)
    921  1.6   mycroft         void *arg;
    922  1.1   mycroft {
    923  1.6   mycroft 	int     intstat;
    924  1.6   mycroft 	u_char	status;
    925  1.9  explorer 	struct	scb *scb;
    926  1.9  explorer 	struct	scsi_xfer *xs;
    927  1.9  explorer 	struct	ahc_data *ahc = (struct ahc_data *)arg;
    928  1.6   mycroft 
    929  1.9  explorer 	intstat = AHC_INB(ahc, INTSTAT);
    930  1.1   mycroft 	/*
    931  1.1   mycroft 	 * Is this interrupt for me? or for
    932  1.1   mycroft 	 * someone who is sharing my interrupt
    933  1.1   mycroft 	 */
    934  1.6   mycroft 	if (!(intstat & INT_PEND))
    935  1.6   mycroft #if defined(__FreeBSD__)
    936  1.6   mycroft 		return;
    937  1.6   mycroft #elif defined(__NetBSD__)
    938  1.1   mycroft 		return 0;
    939  1.6   mycroft #endif
    940  1.6   mycroft 
    941  1.6   mycroft         if (intstat & BRKADRINT) {
    942  1.1   mycroft 		/* We upset the sequencer :-( */
    943  1.1   mycroft 
    944  1.1   mycroft 		/* Lookup the error message */
    945  1.6   mycroft 		int i, error = AHC_INB(ahc, ERROR);
    946  1.1   mycroft 		int num_errors =  sizeof(hard_error)/sizeof(hard_error[0]);
    947  1.6   mycroft 		for(i = 0; error != 1 && i < num_errors; i++)
    948  1.1   mycroft 			error >>= 1;
    949  1.6   mycroft                 panic("%s: brkadrint, %s at seqaddr = 0x%x\n",
    950  1.6   mycroft 		      ahc_name(ahc), hard_error[i].errmesg,
    951  1.6   mycroft 		      (AHC_INB(ahc, SEQADDR1) << 8) |
    952  1.6   mycroft 		      AHC_INB(ahc, SEQADDR0));
    953  1.6   mycroft         }
    954  1.6   mycroft         if (intstat & SEQINT) {
    955  1.6   mycroft 		u_short targ_mask;
    956  1.6   mycroft 		u_char target = (AHC_INB(ahc, SCSIID) >> 4) & 0x0f;
    957  1.6   mycroft 		u_char scratch_offset = target;
    958  1.6   mycroft 		char channel =
    959  1.6   mycroft 			AHC_INB(ahc, SBLKCTL) & SELBUSB ? 'B': 'A';
    960  1.6   mycroft 
    961  1.6   mycroft 		if (channel == 'B')
    962  1.6   mycroft 			scratch_offset += 8;
    963  1.6   mycroft 		targ_mask = (0x01 << scratch_offset);
    964  1.6   mycroft 
    965  1.6   mycroft                 switch (intstat & SEQINT_MASK) {
    966  1.6   mycroft                     case NO_MATCH:
    967  1.6   mycroft 			if(ahc->flags & AHC_PAGESCBS) {
    968  1.6   mycroft 				/* SCB Page-in request */
    969  1.6   mycroft 				u_char tag;
    970  1.6   mycroft 				u_char next;
    971  1.6   mycroft 				u_char disc_scb;
    972  1.6   mycroft 				struct scb *outscb;
    973  1.6   mycroft 				u_char arg_1 = AHC_INB(ahc, ARG_1);
    974  1.9  explorer 
    975  1.9  explorer 				/*
    976  1.9  explorer 				 * We should succeed, so set this now.
    977  1.9  explorer 				 * If we don't, and one of the methods
    978  1.9  explorer 				 * we use to aquire an SCB calls ahc_done,
    979  1.9  explorer 				 * we may wind up in our start routine
    980  1.9  explorer 				 * and unpause the adapter without giving
    981  1.9  explorer 				 * it the correct return value, which will
    982  1.9  explorer 				 * cause a hang.
    983  1.9  explorer 				 */
    984  1.9  explorer 				AHC_OUTB(ahc, RETURN_1, SCB_PAGEDIN);
    985  1.9  explorer 
    986  1.6   mycroft 				if(arg_1 == SCB_LIST_NULL) {
    987  1.6   mycroft 					/* Non-tagged command */
    988  1.6   mycroft 					int index = target |
    989  1.6   mycroft 						(channel == 'B' ? SELBUSB : 0);
    990  1.6   mycroft 					scb = ahc->pagedout_ntscbs[index];
    991  1.6   mycroft 				}
    992  1.6   mycroft 				else
    993  1.6   mycroft 					scb = ahc->scbarray[arg_1];
    994  1.1   mycroft 
    995  1.9  explorer 				if(!(scb->flags & SCB_PAGED_OUT))
    996  1.9  explorer 					panic("%s: Request to page in a"
    997  1.9  explorer 					      "non paged out SCB.",
    998  1.9  explorer 					      ahc_name(ahc));
    999  1.1   mycroft 				/*
   1000  1.6   mycroft 				 * Now to pick the SCB to page out.
   1001  1.6   mycroft 				 * Either take a free SCB, an assigned SCB,
   1002  1.6   mycroft 				 * an SCB that just completed, the first
   1003  1.6   mycroft 				 * one on the disconnected SCB list, or
   1004  1.6   mycroft 				 * as a last resort a queued SCB.
   1005  1.1   mycroft 				 */
   1006  1.9  explorer 				if(ahc->free_scbs.stqh_first) {
   1007  1.9  explorer 					outscb = ahc->free_scbs.stqh_first;
   1008  1.9  explorer 					STAILQ_REMOVE_HEAD(&ahc->free_scbs,
   1009  1.9  explorer 							   links);
   1010  1.6   mycroft 					scb->position = outscb->position;
   1011  1.6   mycroft 					outscb->position = SCB_LIST_NULL;
   1012  1.9  explorer 					STAILQ_INSERT_HEAD(&ahc->page_scbs,
   1013  1.9  explorer 							   outscb, links);
   1014  1.6   mycroft 					AHC_OUTB(ahc, SCBPTR, scb->position);
   1015  1.6   mycroft 					ahc_send_scb(ahc, scb);
   1016  1.6   mycroft 					scb->flags &= ~SCB_PAGED_OUT;
   1017  1.6   mycroft 					goto pagein_done;
   1018  1.6   mycroft 				}
   1019  1.9  explorer 				if(ahc->assigned_scbs.stqh_first) {
   1020  1.9  explorer 					outscb = ahc->assigned_scbs.stqh_first;
   1021  1.9  explorer 					STAILQ_REMOVE_HEAD(&ahc->assigned_scbs,
   1022  1.9  explorer 							   links);
   1023  1.9  explorer 					outscb->flags ^= SCB_ASSIGNEDQ
   1024  1.9  explorer 							|SCB_WAITINGQ;
   1025  1.6   mycroft 					scb->position = outscb->position;
   1026  1.6   mycroft 					outscb->position = SCB_LIST_NULL;
   1027  1.9  explorer 					STAILQ_INSERT_HEAD(&ahc->waiting_scbs,
   1028  1.9  explorer 							   outscb, links);
   1029  1.6   mycroft 					AHC_OUTB(ahc, SCBPTR, scb->position);
   1030  1.6   mycroft 					ahc_send_scb(ahc, scb);
   1031  1.6   mycroft 					scb->flags &= ~SCB_PAGED_OUT;
   1032  1.6   mycroft 					goto pagein_done;
   1033  1.6   mycroft 				}
   1034  1.6   mycroft 				if(intstat & CMDCMPLT) {
   1035  1.6   mycroft 					int   scb_index;
   1036  1.6   mycroft 
   1037  1.6   mycroft 					AHC_OUTB(ahc, CLRINT, CLRCMDINT);
   1038  1.6   mycroft 					scb_index = AHC_INB(ahc, QOUTFIFO);
   1039  1.6   mycroft 					if(!(AHC_INB(ahc, QOUTCNT) & ahc->qcntmask))
   1040  1.6   mycroft 						intstat &= ~CMDCMPLT;
   1041  1.6   mycroft 
   1042  1.6   mycroft 					outscb = ahc->scbarray[scb_index];
   1043  1.6   mycroft 					if (!outscb || !(outscb->flags & SCB_ACTIVE)) {
   1044  1.6   mycroft 						printf("%s: WARNING "
   1045  1.6   mycroft 						       "no command for scb %d (cmdcmplt)\n",
   1046  1.6   mycroft 							ahc_name(ahc),
   1047  1.6   mycroft 						        scb_index);
   1048  1.6   mycroft 						/* Fall through in hopes of finding another SCB */
   1049  1.6   mycroft 					}
   1050  1.6   mycroft 					else {
   1051  1.6   mycroft 						scb->position = outscb->position;
   1052  1.6   mycroft 						outscb->position = SCB_LIST_NULL;
   1053  1.6   mycroft 						AHC_OUTB(ahc, SCBPTR, scb->position);
   1054  1.6   mycroft 						ahc_send_scb(ahc, scb);
   1055  1.6   mycroft 						scb->flags &= ~SCB_PAGED_OUT;
   1056  1.6   mycroft 						untimeout(ahc_timeout, (caddr_t)outscb);
   1057  1.6   mycroft 						ahc_done(ahc, outscb);
   1058  1.6   mycroft 						goto pagein_done;
   1059  1.6   mycroft 					}
   1060  1.6   mycroft 				}
   1061  1.6   mycroft 				disc_scb = AHC_INB(ahc, DISCONNECTED_SCBH);
   1062  1.6   mycroft 				if(disc_scb != SCB_LIST_NULL) {
   1063  1.6   mycroft 					AHC_OUTB(ahc, SCBPTR, disc_scb);
   1064  1.6   mycroft 					tag = AHC_INB(ahc, SCB_TAG);
   1065  1.6   mycroft 					outscb = ahc->scbarray[tag];
   1066  1.6   mycroft 					next = AHC_INB(ahc, SCB_NEXT);
   1067  1.6   mycroft 					if(next != SCB_LIST_NULL) {
   1068  1.6   mycroft 						AHC_OUTB(ahc, SCBPTR, next);
   1069  1.6   mycroft 						AHC_OUTB(ahc, SCB_PREV,
   1070  1.6   mycroft 						     SCB_LIST_NULL);
   1071  1.6   mycroft 						AHC_OUTB(ahc, SCBPTR, disc_scb);
   1072  1.6   mycroft 					}
   1073  1.6   mycroft 					AHC_OUTB(ahc, DISCONNECTED_SCBH, next);
   1074  1.6   mycroft 					ahc_page_scb(ahc, outscb, scb);
   1075  1.6   mycroft 				}
   1076  1.6   mycroft 				else if(AHC_INB(ahc, QINCNT) & ahc->qcntmask) {
   1077  1.6   mycroft 					/* Pull one of our queued commands as a last resort */
   1078  1.6   mycroft 					disc_scb = AHC_INB(ahc, QINFIFO);
   1079  1.6   mycroft 					AHC_OUTB(ahc, SCBPTR, disc_scb);
   1080  1.6   mycroft 					tag = AHC_INB(ahc, SCB_TAG);
   1081  1.6   mycroft 					outscb = ahc->scbarray[tag];
   1082  1.6   mycroft 					if((outscb->control & 0x23) != TAG_ENB) {
   1083  1.6   mycroft 						/*
   1084  1.6   mycroft 						 * This is not a simple tagged command
   1085  1.6   mycroft 						 * so its position in the queue
   1086  1.6   mycroft 						 * matters.  Take the command at the
   1087  1.6   mycroft 						 * end of the queue instead.
   1088  1.6   mycroft 						 */
   1089  1.6   mycroft 						int i;
   1090  1.9  explorer 						u_char saved_queue[AHC_SCB_MAX];
   1091  1.9  explorer 						u_char queued = AHC_INB(ahc, QINCNT) & ahc->qcntmask;
   1092  1.6   mycroft 
   1093  1.6   mycroft 						/* Count the command we removed already */
   1094  1.6   mycroft 						saved_queue[0] = disc_scb;
   1095  1.6   mycroft 						queued++;
   1096  1.6   mycroft 
   1097  1.6   mycroft 						/* Empty the input queue */
   1098  1.6   mycroft 						for (i = 1; i < queued; i++)
   1099  1.6   mycroft 							saved_queue[i] = AHC_INB(ahc, QINFIFO);
   1100  1.6   mycroft 
   1101  1.6   mycroft 						/* Put everyone back put the last entry */
   1102  1.6   mycroft 						queued--;
   1103  1.6   mycroft 						for (i = 0; i < queued; i++)
   1104  1.6   mycroft 							AHC_OUTB(ahc, QINFIFO, saved_queue[i]);
   1105  1.6   mycroft 
   1106  1.6   mycroft 						AHC_OUTB(ahc, SCBPTR, saved_queue[queued]);
   1107  1.6   mycroft 						tag = AHC_INB(ahc, SCB_TAG);
   1108  1.6   mycroft 						outscb = ahc->scbarray[tag];
   1109  1.6   mycroft 					}
   1110  1.6   mycroft 					untimeout(ahc_timeout, (caddr_t)outscb);
   1111  1.6   mycroft 					scb->position = outscb->position;
   1112  1.6   mycroft 					outscb->position = SCB_LIST_NULL;
   1113  1.9  explorer 					STAILQ_INSERT_HEAD(&ahc->waiting_scbs,
   1114  1.6   mycroft 							   outscb, links);
   1115  1.9  explorer 					outscb->flags |= SCB_WAITINGQ;
   1116  1.6   mycroft 					ahc_send_scb(ahc, scb);
   1117  1.6   mycroft 					scb->flags &= ~SCB_PAGED_OUT;
   1118  1.6   mycroft 				}
   1119  1.9  explorer 				else {
   1120  1.6   mycroft 					panic("Page-in request with no candidates");
   1121  1.9  explorer 					AHC_OUTB(ahc, RETURN_1, 0);
   1122  1.9  explorer 				}
   1123  1.6   mycroft pagein_done:
   1124  1.6   mycroft 			}
   1125  1.6   mycroft 			else {
   1126  1.6   mycroft 				printf("%s:%c:%d: no active SCB for "
   1127  1.6   mycroft 				       "reconnecting target - "
   1128  1.6   mycroft 				       "issuing ABORT\n",
   1129  1.6   mycroft 				       ahc_name(ahc), channel, target);
   1130  1.6   mycroft 				printf("SAVED_TCL == 0x%x\n",
   1131  1.6   mycroft 					AHC_INB(ahc, SAVED_TCL));
   1132  1.6   mycroft 				ahc_unbusy_target(ahc, target, channel);
   1133  1.6   mycroft 				AHC_OUTB(ahc, SCB_CONTROL, 0);
   1134  1.6   mycroft 				AHC_OUTB(ahc, CLRSINT1, CLRSELTIMEO);
   1135  1.6   mycroft 				AHC_OUTB(ahc, RETURN_1, 0);
   1136  1.6   mycroft 			}
   1137  1.6   mycroft 			break;
   1138  1.9  explorer                     case SEND_REJECT:
   1139  1.9  explorer 			{
   1140  1.9  explorer 				u_char rejbyte = AHC_INB(ahc, REJBYTE);
   1141  1.9  explorer 				if(( rejbyte & 0xf0) == 0x20) {
   1142  1.9  explorer 					/* Tagged Message */
   1143  1.9  explorer 					printf("\n%s:%c:%d: Tagged message "
   1144  1.9  explorer 						"received without identify. "
   1145  1.9  explorer 						"Disabling tagged commands "
   1146  1.9  explorer 						"for this target.\n",
   1147  1.9  explorer 						ahc_name(ahc),
   1148  1.9  explorer 					        channel, target);
   1149  1.9  explorer 					ahc->tagenable &= ~targ_mask;
   1150  1.9  explorer 				}
   1151  1.9  explorer 				else
   1152  1.9  explorer 					printf("%s:%c:%d: Warning - "
   1153  1.9  explorer 					       "unknown message recieved from "
   1154  1.9  explorer 					       "target (0x%x - 0x%x).  Rejecting\n",
   1155  1.9  explorer 						ahc_name(ahc), channel, target,
   1156  1.9  explorer 						rejbyte,
   1157  1.9  explorer 					        AHC_INB(ahc, REJBYTE_EXT));
   1158  1.9  explorer 				break;
   1159  1.9  explorer 			}
   1160  1.9  explorer                     case NO_IDENT:
   1161  1.9  explorer                         panic("%s:%c:%d: Target did not send an IDENTIFY "
   1162  1.9  explorer 			      "message. SAVED_TCL == 0x%x\n",
   1163  1.9  explorer                               ahc_name(ahc), channel, target,
   1164  1.9  explorer 			      AHC_INB(ahc, SAVED_TCL));
   1165  1.9  explorer 			break;
   1166  1.9  explorer                     case BAD_PHASE:
   1167  1.9  explorer                         printf("%s:%c:%d: unknown scsi bus phase.  "
   1168  1.9  explorer 			      "Attempting to continue\n",
   1169  1.9  explorer 			      ahc_name(ahc), channel, target);
   1170  1.9  explorer                         break;
   1171  1.6   mycroft                     case SDTR_MSG:
   1172  1.6   mycroft 			{
   1173  1.6   mycroft 				short period;
   1174  1.6   mycroft 				u_char offset, rate;
   1175  1.6   mycroft 				u_char targ_scratch;
   1176  1.6   mycroft 				u_char maxoffset;
   1177  1.6   mycroft 	                        /*
   1178  1.6   mycroft 				 * Help the sequencer to translate the
   1179  1.6   mycroft 				 * negotiated transfer rate.  Transfer is
   1180  1.6   mycroft 				 * 1/4 the period in ns as is returned by
   1181  1.6   mycroft 				 * the sync negotiation message.  So, we must
   1182  1.6   mycroft 				 * multiply by four
   1183  1.1   mycroft 				 */
   1184  1.6   mycroft 	                        period = AHC_INB(ahc, ARG_1) << 2;
   1185  1.6   mycroft 				offset = AHC_INB(ahc, ACCUM);
   1186  1.6   mycroft 				targ_scratch = AHC_INB(ahc, TARG_SCRATCH
   1187  1.6   mycroft 						   + scratch_offset);
   1188  1.6   mycroft 				if(targ_scratch & WIDEXFER)
   1189  1.6   mycroft 					maxoffset = 0x08;
   1190  1.6   mycroft 				else
   1191  1.6   mycroft 					maxoffset = 0x0f;
   1192  1.9  explorer 				ahc_scsirate(ahc, &rate, period,
   1193  1.9  explorer 					     MIN(offset, maxoffset),
   1194  1.9  explorer 					     channel, target);
   1195  1.6   mycroft 				/* Preserve the WideXfer flag */
   1196  1.6   mycroft 				targ_scratch = rate | (targ_scratch & WIDEXFER);
   1197  1.6   mycroft 				AHC_OUTB(ahc, TARG_SCRATCH + scratch_offset,
   1198  1.6   mycroft 				     targ_scratch);
   1199  1.6   mycroft 				AHC_OUTB(ahc, SCSIRATE, targ_scratch);
   1200  1.6   mycroft 				if( (targ_scratch & 0x0f) == 0 )
   1201  1.6   mycroft 				{
   1202  1.6   mycroft 					/*
   1203  1.6   mycroft 					 * The requested rate was so low
   1204  1.6   mycroft 					 * that asyncronous transfers are
   1205  1.6   mycroft 					 * faster (not to mention the
   1206  1.6   mycroft 					 * controller won't support them),
   1207  1.6   mycroft 					 * so we issue a message reject to
   1208  1.6   mycroft 					 * ensure we go to asyncronous
   1209  1.6   mycroft 					 * transfers.
   1210  1.6   mycroft 					 */
   1211  1.6   mycroft 					AHC_OUTB(ahc, RETURN_1, SEND_REJ);
   1212  1.6   mycroft 				}
   1213  1.6   mycroft 				/* See if we initiated Sync Negotiation */
   1214  1.6   mycroft 				else if(ahc->sdtrpending & targ_mask)
   1215  1.6   mycroft 				{
   1216  1.6   mycroft 					/*
   1217  1.6   mycroft 					 * Don't send an SDTR back to
   1218  1.6   mycroft 					 * the target
   1219  1.6   mycroft 					 */
   1220  1.6   mycroft 					AHC_OUTB(ahc, RETURN_1, 0);
   1221  1.6   mycroft 				}
   1222  1.6   mycroft 				else{
   1223  1.6   mycroft 					/*
   1224  1.6   mycroft 					 * Send our own SDTR in reply
   1225  1.6   mycroft 					 */
   1226  1.6   mycroft #ifdef AHC_DEBUG
   1227  1.6   mycroft 					if(ahc_debug & AHC_SHOWMISC)
   1228  1.6   mycroft 						printf("Sending SDTR!!\n");
   1229  1.6   mycroft #endif
   1230  1.6   mycroft 					AHC_OUTB(ahc, RETURN_1, SEND_SDTR);
   1231  1.6   mycroft 				}
   1232  1.1   mycroft 				/*
   1233  1.6   mycroft 				 * Negate the flags
   1234  1.1   mycroft 				 */
   1235  1.6   mycroft 				ahc->needsdtr &= ~targ_mask;
   1236  1.6   mycroft 				ahc->sdtrpending &= ~targ_mask;
   1237  1.6   mycroft 	                        break;
   1238  1.1   mycroft 			}
   1239  1.6   mycroft                     case WDTR_MSG:
   1240  1.6   mycroft 			{
   1241  1.6   mycroft 				u_char scratch, bus_width;
   1242  1.1   mycroft 
   1243  1.6   mycroft 				bus_width = AHC_INB(ahc, ARG_1);
   1244  1.1   mycroft 
   1245  1.6   mycroft 				scratch = AHC_INB(ahc, TARG_SCRATCH
   1246  1.6   mycroft 					      + scratch_offset);
   1247  1.1   mycroft 
   1248  1.6   mycroft 				if(ahc->wdtrpending & targ_mask)
   1249  1.6   mycroft 				{
   1250  1.6   mycroft 					/*
   1251  1.6   mycroft 					 * Don't send a WDTR back to the
   1252  1.6   mycroft 					 * target, since we asked first.
   1253  1.6   mycroft 					 */
   1254  1.6   mycroft 					AHC_OUTB(ahc, RETURN_1, 0);
   1255  1.6   mycroft 					switch(bus_width)
   1256  1.6   mycroft 					{
   1257  1.6   mycroft 						case BUS_8_BIT:
   1258  1.6   mycroft 						    scratch &= 0x7f;
   1259  1.6   mycroft 						    break;
   1260  1.6   mycroft 						case BUS_16_BIT:
   1261  1.6   mycroft 						    if(bootverbose)
   1262  1.6   mycroft 		        				printf("%s: target "
   1263  1.6   mycroft 							       "%d using 16Bit "
   1264  1.6   mycroft 							       "transfers\n",
   1265  1.6   mycroft 							       ahc_name(ahc),
   1266  1.6   mycroft 							       target);
   1267  1.6   mycroft 						    scratch |= 0x80;
   1268  1.6   mycroft 						    break;
   1269  1.6   mycroft 						case BUS_32_BIT:
   1270  1.6   mycroft 						    /*
   1271  1.6   mycroft 						     * How can we do 32bit
   1272  1.6   mycroft 						     * transfers on a 16bit
   1273  1.6   mycroft 						     * bus?
   1274  1.6   mycroft 						     */
   1275  1.6   mycroft 						    AHC_OUTB(ahc, RETURN_1,
   1276  1.6   mycroft 							 SEND_REJ);
   1277  1.6   mycroft 		        			    printf("%s: target "
   1278  1.6   mycroft 						           "%d requested 32Bit "
   1279  1.6   mycroft 						           "transfers.  "
   1280  1.6   mycroft 							   "Rejecting...\n",
   1281  1.6   mycroft 							   ahc_name(ahc),
   1282  1.6   mycroft 							   target);
   1283  1.6   mycroft 						    break;
   1284  1.6   mycroft 						default:
   1285  1.6   mycroft 						    break;
   1286  1.6   mycroft 					}
   1287  1.6   mycroft 				}
   1288  1.6   mycroft 				else {
   1289  1.6   mycroft 					/*
   1290  1.6   mycroft 					 * Send our own WDTR in reply
   1291  1.6   mycroft 					 */
   1292  1.6   mycroft 					switch(bus_width)
   1293  1.6   mycroft 					{
   1294  1.6   mycroft 						case BUS_8_BIT:
   1295  1.6   mycroft 							scratch &= 0x7f;
   1296  1.6   mycroft 							break;
   1297  1.6   mycroft 						case BUS_32_BIT:
   1298  1.6   mycroft 						case BUS_16_BIT:
   1299  1.6   mycroft 						    if(ahc->type & AHC_WIDE) {
   1300  1.6   mycroft 							/* Negotiate 16_BITS */
   1301  1.6   mycroft 							bus_width = BUS_16_BIT;
   1302  1.6   mycroft 							if(bootverbose)
   1303  1.6   mycroft 							    printf("%s: "
   1304  1.6   mycroft 								"target %d "
   1305  1.6   mycroft 								"using 16Bit "
   1306  1.6   mycroft 							        "transfers\n",
   1307  1.6   mycroft 								ahc_name(ahc),
   1308  1.6   mycroft 								target);
   1309  1.6   mycroft 						 	scratch |= 0x80;
   1310  1.6   mycroft 						    }
   1311  1.6   mycroft 						    else
   1312  1.6   mycroft 							bus_width = BUS_8_BIT;
   1313  1.6   mycroft 						    break;
   1314  1.6   mycroft 						default:
   1315  1.6   mycroft 						    break;
   1316  1.6   mycroft 					}
   1317  1.6   mycroft 					AHC_OUTB(ahc, RETURN_1,
   1318  1.6   mycroft 						bus_width | SEND_WDTR);
   1319  1.1   mycroft 				}
   1320  1.6   mycroft 				ahc->needwdtr &= ~targ_mask;
   1321  1.6   mycroft 				ahc->wdtrpending &= ~targ_mask;
   1322  1.6   mycroft 				AHC_OUTB(ahc, TARG_SCRATCH + scratch_offset,
   1323  1.6   mycroft 				     scratch);
   1324  1.6   mycroft 				AHC_OUTB(ahc, SCSIRATE, scratch);
   1325  1.6   mycroft 	                        break;
   1326  1.6   mycroft 			}
   1327  1.6   mycroft 		    case REJECT_MSG:
   1328  1.6   mycroft 			{
   1329  1.1   mycroft 				/*
   1330  1.6   mycroft 				 * What we care about here is if we had an
   1331  1.6   mycroft 				 * outstanding SDTR or WDTR message for this
   1332  1.6   mycroft 				 * target.  If we did, this is a signal that
   1333  1.6   mycroft 				 * the target is refusing negotiation.
   1334  1.1   mycroft 				 */
   1335  1.1   mycroft 
   1336  1.6   mycroft 				u_char targ_scratch;
   1337  1.6   mycroft 
   1338  1.6   mycroft 				targ_scratch = AHC_INB(ahc, TARG_SCRATCH
   1339  1.6   mycroft 						   + scratch_offset);
   1340  1.1   mycroft 
   1341  1.6   mycroft 				if(ahc->wdtrpending & targ_mask){
   1342  1.6   mycroft 					/* note 8bit xfers and clear flag */
   1343  1.6   mycroft 					targ_scratch &= 0x7f;
   1344  1.6   mycroft 					ahc->needwdtr &= ~targ_mask;
   1345  1.6   mycroft 					ahc->wdtrpending &= ~targ_mask;
   1346  1.6   mycroft         				printf("%s:%c:%d: refuses "
   1347  1.6   mycroft 					       "WIDE negotiation.  Using "
   1348  1.6   mycroft 					       "8bit transfers\n",
   1349  1.6   mycroft 						ahc_name(ahc),
   1350  1.6   mycroft 					        channel, target);
   1351  1.6   mycroft 				}
   1352  1.6   mycroft 				else if(ahc->sdtrpending & targ_mask){
   1353  1.6   mycroft 					/* note asynch xfers and clear flag */
   1354  1.6   mycroft 					targ_scratch &= 0xf0;
   1355  1.6   mycroft 					ahc->needsdtr &= ~targ_mask;
   1356  1.6   mycroft 					ahc->sdtrpending &= ~targ_mask;
   1357  1.6   mycroft         				printf("%s:%c:%d: refuses "
   1358  1.6   mycroft 					       "syncronous negotiation.  Using "
   1359  1.6   mycroft 					       "asyncronous transfers\n",
   1360  1.6   mycroft 						ahc_name(ahc),
   1361  1.6   mycroft 					        channel, target);
   1362  1.6   mycroft 				}
   1363  1.6   mycroft 				else {
   1364  1.6   mycroft 					/*
   1365  1.6   mycroft 					 * Otherwise, we ignore it.
   1366  1.6   mycroft 					 */
   1367  1.1   mycroft #ifdef AHC_DEBUG
   1368  1.6   mycroft 					if(ahc_debug & AHC_SHOWMISC)
   1369  1.6   mycroft 						printf("%s:%c:%d: Message "
   1370  1.6   mycroft 						       "reject -- ignored\n",
   1371  1.6   mycroft 							ahc_name(ahc),
   1372  1.6   mycroft 						        channel, target);
   1373  1.1   mycroft #endif
   1374  1.6   mycroft 					break;
   1375  1.6   mycroft 				}
   1376  1.6   mycroft 				AHC_OUTB(ahc, TARG_SCRATCH + scratch_offset,
   1377  1.6   mycroft 				     targ_scratch);
   1378  1.6   mycroft 				AHC_OUTB(ahc, SCSIRATE, targ_scratch);
   1379  1.1   mycroft 				break;
   1380  1.1   mycroft 			}
   1381  1.6   mycroft                     case BAD_STATUS:
   1382  1.6   mycroft 			{
   1383  1.6   mycroft 			  int	scb_index;
   1384  1.6   mycroft 
   1385  1.6   mycroft 			  /* The sequencer will notify us when a command
   1386  1.6   mycroft 			   * has an error that would be of interest to
   1387  1.6   mycroft 			   * the kernel.  This allows us to leave the sequencer
   1388  1.6   mycroft 			   * running in the common case of command completes
   1389  1.6   mycroft 			   * without error.
   1390  1.6   mycroft 			   */
   1391  1.6   mycroft 
   1392  1.6   mycroft   			  scb_index = AHC_INB(ahc, SCB_TAG);
   1393  1.6   mycroft 			  scb = ahc->scbarray[scb_index];
   1394  1.6   mycroft 
   1395  1.6   mycroft 			  /*
   1396  1.6   mycroft 			   * Set the default return value to 0 (don't
   1397  1.6   mycroft 			   * send sense).  The sense code will change
   1398  1.6   mycroft 			   * this if needed and this reduces code
   1399  1.6   mycroft 			   * duplication.
   1400  1.6   mycroft 			   */
   1401  1.6   mycroft 			  AHC_OUTB(ahc, RETURN_1, 0);
   1402  1.6   mycroft 		 	  if (!(scb && (scb->flags & SCB_ACTIVE))) {
   1403  1.6   mycroft 				printf("%s:%c:%d: ahc_intr - referenced scb "
   1404  1.6   mycroft 				       "not valid during seqint 0x%x scb(%d)\n",
   1405  1.6   mycroft 				       ahc_name(ahc),
   1406  1.6   mycroft 				       channel, target, intstat,
   1407  1.6   mycroft 				       scb_index);
   1408  1.6   mycroft 			      goto clear;
   1409  1.6   mycroft 			  }
   1410  1.1   mycroft 
   1411  1.6   mycroft 			  xs = scb->xs;
   1412  1.1   mycroft 
   1413  1.6   mycroft 			  scb->status = AHC_INB(ahc, SCB_TARGET_STATUS);
   1414  1.1   mycroft 
   1415  1.6   mycroft #ifdef AHC_DEBUG
   1416  1.6   mycroft 			  if((ahc_debug & AHC_SHOWSCBS)
   1417  1.6   mycroft 			    && xs->sc_link->target == DEBUGTARG)
   1418  1.1   mycroft 				ahc_print_scb(scb);
   1419  1.1   mycroft #endif
   1420  1.6   mycroft 			  xs->status = scb->status;
   1421  1.6   mycroft 			  switch(scb->status){
   1422  1.6   mycroft 			    case SCSI_OK:
   1423  1.6   mycroft 				printf("%s: Interrupted for staus of"
   1424  1.6   mycroft 					" 0???\n", ahc_name(ahc));
   1425  1.1   mycroft 				break;
   1426  1.6   mycroft 			    case SCSI_CHECK:
   1427  1.1   mycroft #ifdef AHC_DEBUG
   1428  1.6   mycroft 				if(ahc_debug & AHC_SHOWSENSE)
   1429  1.6   mycroft 				{
   1430  1.6   mycroft 					sc_print_addr(xs->sc_link);
   1431  1.6   mycroft 					printf("requests Check Status\n");
   1432  1.6   mycroft 				}
   1433  1.1   mycroft #endif
   1434  1.1   mycroft 
   1435  1.6   mycroft 				if((xs->error == XS_NOERROR) &&
   1436  1.6   mycroft 				    !(scb->flags & SCB_SENSE)) {
   1437  1.1   mycroft 					struct ahc_dma_seg *sg = scb->ahc_dma;
   1438  1.1   mycroft 					struct scsi_sense *sc = &(scb->sense_cmd);
   1439  1.1   mycroft #ifdef AHC_DEBUG
   1440  1.6   mycroft 					if(ahc_debug & AHC_SHOWSENSE)
   1441  1.6   mycroft 					{
   1442  1.6   mycroft 						sc_print_addr(xs->sc_link);
   1443  1.6   mycroft 						printf("Sending Sense\n");
   1444  1.6   mycroft 					}
   1445  1.1   mycroft #endif
   1446  1.6   mycroft #if defined(__FreeBSD__)
   1447  1.6   mycroft 					sc->op_code = REQUEST_SENSE;
   1448  1.6   mycroft #elif defined(__NetBSD__)
   1449  1.1   mycroft 					sc->opcode = REQUEST_SENSE;
   1450  1.6   mycroft #endif
   1451  1.1   mycroft 					sc->byte2 =  xs->sc_link->lun << 5;
   1452  1.1   mycroft 					sc->length = sizeof(struct scsi_sense_data);
   1453  1.1   mycroft 					sc->control = 0;
   1454  1.1   mycroft 
   1455  1.6   mycroft 					sg->addr = KVTOPHYS(&xs->sense);
   1456  1.6   mycroft 					sg->len = sizeof(struct scsi_sense_data);
   1457  1.1   mycroft 
   1458  1.6   mycroft 					scb->control &= DISCENB;
   1459  1.6   mycroft 					scb->status = 0;
   1460  1.1   mycroft 					scb->SG_segment_count = 1;
   1461  1.6   mycroft 					scb->SG_list_pointer = KVTOPHYS(sg);
   1462  1.6   mycroft 			                scb->data = sg->addr;
   1463  1.6   mycroft 					scb->datalen = sg->len;
   1464  1.6   mycroft #ifdef AHC_BROKEN_CACHE
   1465  1.6   mycroft 					if (ahc_broken_cache)
   1466  1.6   mycroft 						INVALIDATE_CACHE();
   1467  1.6   mycroft #endif
   1468  1.6   mycroft 					scb->cmdpointer = KVTOPHYS(sc);
   1469  1.1   mycroft 					scb->cmdlen = sizeof(*sc);
   1470  1.1   mycroft 
   1471  1.6   mycroft 					scb->flags |= SCB_SENSE;
   1472  1.6   mycroft 					ahc_send_scb(ahc, scb);
   1473  1.6   mycroft 					/*
   1474  1.6   mycroft 					 * Ensure that the target is "BUSY"
   1475  1.6   mycroft 					 * so we don't get overlapping
   1476  1.6   mycroft 					 * commands if we happen to be doing
   1477  1.6   mycroft 					 * tagged I/O.
   1478  1.6   mycroft 					 */
   1479  1.6   mycroft 					ahc_busy_target(ahc, target, channel);
   1480  1.1   mycroft 
   1481  1.1   mycroft 					/*
   1482  1.6   mycroft 					 * Make us the next command to run
   1483  1.1   mycroft 					 */
   1484  1.6   mycroft 					ahc_add_waiting_scb(ahc, scb);
   1485  1.6   mycroft 					AHC_OUTB(ahc, RETURN_1, SEND_SENSE);
   1486  1.1   mycroft 					break;
   1487  1.1   mycroft 				}
   1488  1.1   mycroft 				/*
   1489  1.6   mycroft 				 * Clear the SCB_SENSE Flag and have
   1490  1.6   mycroft 				 * the sequencer do a normal command
   1491  1.1   mycroft 				 * complete with either a "DRIVER_STUFFUP"
   1492  1.1   mycroft 				 * error or whatever other error condition
   1493  1.1   mycroft 				 * we already had.
   1494  1.1   mycroft 				 */
   1495  1.6   mycroft 				scb->flags &= ~SCB_SENSE;
   1496  1.6   mycroft 				if(xs->error == XS_NOERROR)
   1497  1.1   mycroft 					xs->error = XS_DRIVER_STUFFUP;
   1498  1.1   mycroft 				break;
   1499  1.6   mycroft 			    case SCSI_BUSY:
   1500  1.6   mycroft 				xs->error = XS_BUSY;
   1501  1.1   mycroft 				sc_print_addr(xs->sc_link);
   1502  1.1   mycroft 				printf("Target Busy\n");
   1503  1.1   mycroft 				break;
   1504  1.6   mycroft 			    case SCSI_QUEUE_FULL:
   1505  1.1   mycroft 				/*
   1506  1.9  explorer 				 * The upper level SCSI code will someday
   1507  1.1   mycroft 				 * handle this properly.
   1508  1.1   mycroft 				 */
   1509  1.1   mycroft 				sc_print_addr(xs->sc_link);
   1510  1.1   mycroft 				printf("Queue Full\n");
   1511  1.9  explorer 				scb->flags |= SCB_ASSIGNEDQ;
   1512  1.9  explorer 				STAILQ_INSERT_TAIL(&ahc->assigned_scbs,
   1513  1.6   mycroft 						   scb, links);
   1514  1.1   mycroft 				break;
   1515  1.6   mycroft 			    default:
   1516  1.1   mycroft 				sc_print_addr(xs->sc_link);
   1517  1.1   mycroft 				printf("unexpected targ_status: %x\n",
   1518  1.6   mycroft 					scb->status);
   1519  1.1   mycroft 				xs->error = XS_DRIVER_STUFFUP;
   1520  1.1   mycroft 				break;
   1521  1.1   mycroft 			}
   1522  1.1   mycroft 			break;
   1523  1.6   mycroft 		  }
   1524  1.6   mycroft 		  case RESIDUAL:
   1525  1.6   mycroft 		  {
   1526  1.6   mycroft 			int   scb_index;
   1527  1.6   mycroft 			scb_index = AHC_INB(ahc, SCB_TAG);
   1528  1.1   mycroft 			scb = ahc->scbarray[scb_index];
   1529  1.6   mycroft 			xs = scb->xs;
   1530  1.1   mycroft 			/*
   1531  1.1   mycroft 			 * Don't clobber valid resid info with
   1532  1.1   mycroft 			 * a resid coming from a check sense
   1533  1.1   mycroft 			 * operation.
   1534  1.1   mycroft 			 */
   1535  1.6   mycroft 			if(!(scb->flags & SCB_SENSE)) {
   1536  1.6   mycroft 				int resid_sgs;
   1537  1.6   mycroft 
   1538  1.6   mycroft 				/*
   1539  1.6   mycroft 				 * Remainder of the SG where the transfer
   1540  1.6   mycroft 				 * stopped.
   1541  1.6   mycroft 				 */
   1542  1.6   mycroft 				xs->resid =
   1543  1.6   mycroft 					(AHC_INB(ahc, SCB_RESID_DCNT2)<<16) |
   1544  1.6   mycroft 					(AHC_INB(ahc, SCB_RESID_DCNT1)<<8)  |
   1545  1.6   mycroft 					 AHC_INB(ahc, SCB_RESID_DCNT0);
   1546  1.6   mycroft 
   1547  1.6   mycroft 				/*
   1548  1.6   mycroft 				 * Add up the contents of all residual
   1549  1.6   mycroft 				 * SG segments that are after the SG where
   1550  1.6   mycroft 				 * the transfer stopped.
   1551  1.6   mycroft 				 */
   1552  1.6   mycroft 				resid_sgs = AHC_INB(ahc, SCB_RESID_SGCNT) - 1;
   1553  1.6   mycroft 				while(resid_sgs > 0) {
   1554  1.6   mycroft 					int sg;
   1555  1.6   mycroft 
   1556  1.6   mycroft 					sg = scb->SG_segment_count - resid_sgs;
   1557  1.6   mycroft 					xs->resid += scb->ahc_dma[sg].len;
   1558  1.6   mycroft 					resid_sgs--;
   1559  1.6   mycroft 				}
   1560  1.6   mycroft 
   1561  1.6   mycroft #if defined(__FreeBSD__)
   1562  1.6   mycroft 				xs->flags |= SCSI_RESID_VALID;
   1563  1.6   mycroft #elif defined(__NetBSD__)
   1564  1.6   mycroft 				/* XXX - Update to do this right */
   1565  1.6   mycroft #endif
   1566  1.6   mycroft #ifdef AHC_DEBUG
   1567  1.6   mycroft 				if(ahc_debug & AHC_SHOWMISC) {
   1568  1.6   mycroft 					sc_print_addr(xs->sc_link);
   1569  1.6   mycroft 					printf("Handled Residual of %ld bytes\n"
   1570  1.6   mycroft 						,xs->resid);
   1571  1.6   mycroft 				}
   1572  1.1   mycroft #endif
   1573  1.6   mycroft 			}
   1574  1.1   mycroft 			break;
   1575  1.6   mycroft 		  }
   1576  1.6   mycroft 		  case ABORT_TAG:
   1577  1.6   mycroft 		  {
   1578  1.6   mycroft 			int   scb_index;
   1579  1.6   mycroft 			scb_index = AHC_INB(ahc, SCB_TAG);
   1580  1.1   mycroft 			scb = ahc->scbarray[scb_index];
   1581  1.6   mycroft 			xs = scb->xs;
   1582  1.1   mycroft 			/*
   1583  1.1   mycroft 			 * We didn't recieve a valid tag back from
   1584  1.1   mycroft 			 * the target on a reconnect.
   1585  1.1   mycroft 			 */
   1586  1.1   mycroft 			sc_print_addr(xs->sc_link);
   1587  1.6   mycroft 			printf("invalid tag recieved -- sending ABORT_TAG\n");
   1588  1.6   mycroft 			xs->error = XS_DRIVER_STUFFUP;
   1589  1.6   mycroft 			untimeout(ahc_timeout, (caddr_t)scb);
   1590  1.1   mycroft 			ahc_done(ahc, scb);
   1591  1.1   mycroft 			break;
   1592  1.6   mycroft 		  }
   1593  1.6   mycroft 		  case AWAITING_MSG:
   1594  1.6   mycroft 		  {
   1595  1.6   mycroft 			int   scb_index;
   1596  1.6   mycroft 			scb_index = AHC_INB(ahc, SCB_TAG);
   1597  1.6   mycroft 			scb = ahc->scbarray[scb_index];
   1598  1.6   mycroft 			/*
   1599  1.6   mycroft 			 * This SCB had a zero length command, informing
   1600  1.6   mycroft 			 * the sequencer that we wanted to send a special
   1601  1.6   mycroft 			 * message to this target.  We only do this for
   1602  1.6   mycroft 			 * BUS_DEVICE_RESET messages currently.
   1603  1.6   mycroft 			 */
   1604  1.6   mycroft 			if(scb->flags & SCB_DEVICE_RESET)
   1605  1.6   mycroft 			{
   1606  1.6   mycroft 				AHC_OUTB(ahc, MSG0,
   1607  1.6   mycroft 					MSG_BUS_DEVICE_RESET);
   1608  1.6   mycroft 				AHC_OUTB(ahc, MSG_LEN, 1);
   1609  1.6   mycroft 				printf("Bus Device Reset Message Sent\n");
   1610  1.6   mycroft 			}
   1611  1.6   mycroft 			else
   1612  1.6   mycroft 				panic("ahc_intr: AWAITING_MSG for an SCB that "
   1613  1.6   mycroft 					"does not have a waiting message");
   1614  1.6   mycroft 			break;
   1615  1.6   mycroft 		  }
   1616  1.6   mycroft 		  case IMMEDDONE:
   1617  1.6   mycroft 		  {
   1618  1.6   mycroft 			/*
   1619  1.6   mycroft 			 * Take care of device reset messages
   1620  1.6   mycroft 			 */
   1621  1.6   mycroft 			u_char scbindex = AHC_INB(ahc, SCB_TAG);
   1622  1.6   mycroft 			scb = ahc->scbarray[scbindex];
   1623  1.6   mycroft 			if(scb->flags & SCB_DEVICE_RESET) {
   1624  1.6   mycroft 				u_char targ_scratch;
   1625  1.6   mycroft 				int found;
   1626  1.6   mycroft 				/*
   1627  1.6   mycroft 				 * Go back to async/narrow transfers and
   1628  1.6   mycroft 				 * renegotiate.
   1629  1.6   mycroft 				 */
   1630  1.6   mycroft 				ahc_unbusy_target(ahc, target, channel);
   1631  1.6   mycroft 				ahc->needsdtr |= ahc->needsdtr_orig & targ_mask;
   1632  1.6   mycroft 				ahc->needwdtr |= ahc->needwdtr_orig & targ_mask;
   1633  1.6   mycroft 				ahc->sdtrpending &= ~targ_mask;
   1634  1.6   mycroft 				ahc->wdtrpending &= ~targ_mask;
   1635  1.6   mycroft 				targ_scratch = AHC_INB(ahc, TARG_SCRATCH
   1636  1.6   mycroft 							+ scratch_offset);
   1637  1.6   mycroft 				targ_scratch &= SXFR;
   1638  1.6   mycroft 				AHC_OUTB(ahc, TARG_SCRATCH + scratch_offset,
   1639  1.6   mycroft 					targ_scratch);
   1640  1.6   mycroft 				found = ahc_reset_device(ahc, target,
   1641  1.6   mycroft 						channel, SCB_LIST_NULL,
   1642  1.6   mycroft 						XS_NOERROR);
   1643  1.6   mycroft 				sc_print_addr(scb->xs->sc_link);
   1644  1.6   mycroft 				printf("Bus Device Reset delivered. "
   1645  1.6   mycroft 					"%d SCBs aborted\n", found);
   1646  1.6   mycroft 				ahc->in_timeout = FALSE;
   1647  1.6   mycroft 				ahc_run_done_queue(ahc);
   1648  1.6   mycroft 			}
   1649  1.6   mycroft 			else
   1650  1.6   mycroft 				panic("ahc_intr: Immediate complete for "
   1651  1.6   mycroft 				      "unknown operation.");
   1652  1.6   mycroft 			break;
   1653  1.6   mycroft 		  }
   1654  1.9  explorer 		  case DATA_OVERRUN:
   1655  1.9  explorer 		  {
   1656  1.9  explorer 			/*
   1657  1.9  explorer 			 * When the sequencer detects an overrun, it
   1658  1.9  explorer 			 * sets STCNT to 0x00ffffff and allows the
   1659  1.9  explorer 			 * target to complete its transfer in
   1660  1.9  explorer 			 * BITBUCKET mode.
   1661  1.9  explorer 			 */
   1662  1.9  explorer 			u_char scbindex = AHC_INB(ahc, SCB_TAG);
   1663  1.9  explorer 			u_int32_t overrun;
   1664  1.9  explorer 			scb = ahc->scbarray[scbindex];
   1665  1.9  explorer 			overrun = AHC_INB(ahc, STCNT0)
   1666  1.9  explorer 				| (AHC_INB(ahc, STCNT1) << 8)
   1667  1.9  explorer 				| (AHC_INB(ahc, STCNT2) << 16);
   1668  1.9  explorer 			overrun = 0x00ffffff - overrun;
   1669  1.9  explorer 			sc_print_addr(scb->xs->sc_link);
   1670  1.9  explorer 			printf("data overrun of %d bytes detected."
   1671  1.9  explorer 			       "  Forcing a retry.\n", overrun);
   1672  1.9  explorer 			/*
   1673  1.9  explorer 			 * Set this and it will take affect when the
   1674  1.9  explorer 			 * target does a command complete.
   1675  1.9  explorer 			 */
   1676  1.9  explorer 			scb->xs->error = XS_DRIVER_STUFFUP;
   1677  1.9  explorer 			break;
   1678  1.9  explorer 		  }
   1679  1.6   mycroft #if NOT_YET
   1680  1.6   mycroft 		  /* XXX Fill these in later */
   1681  1.6   mycroft 		  case MESG_BUFFER_BUSY:
   1682  1.6   mycroft 			break;
   1683  1.6   mycroft 		  case MSGIN_PHASEMIS:
   1684  1.6   mycroft 			break;
   1685  1.6   mycroft #endif
   1686  1.6   mycroft 		  default:
   1687  1.6   mycroft 			printf("ahc_intr: seqint, "
   1688  1.6   mycroft 			       "intstat == 0x%x, scsisigi = 0x%x\n",
   1689  1.6   mycroft 			       intstat, AHC_INB(ahc, SCSISIGI));
   1690  1.1   mycroft 			break;
   1691  1.1   mycroft 		}
   1692  1.6   mycroft clear:
   1693  1.1   mycroft 		/*
   1694  1.1   mycroft 		 * Clear the upper byte that holds SEQINT status
   1695  1.1   mycroft 		 * codes and clear the SEQINT bit.
   1696  1.1   mycroft 		 */
   1697  1.6   mycroft 		AHC_OUTB(ahc, CLRINT, CLRSEQINT);
   1698  1.1   mycroft 
   1699  1.1   mycroft 		/*
   1700  1.1   mycroft 		 *  The sequencer is paused immediately on
   1701  1.1   mycroft 		 *  a SEQINT, so we should restart it when
   1702  1.1   mycroft 		 *  we leave this section.
   1703  1.1   mycroft 		 */
   1704  1.1   mycroft 		UNPAUSE_SEQUENCER(ahc);
   1705  1.6   mycroft 	   }
   1706  1.6   mycroft 
   1707  1.6   mycroft 
   1708  1.6   mycroft 	   if (intstat & SCSIINT) {
   1709  1.6   mycroft 
   1710  1.6   mycroft 		int scb_index = AHC_INB(ahc, SCB_TAG);
   1711  1.6   mycroft 		status = AHC_INB(ahc, SSTAT1);
   1712  1.1   mycroft 		scb = ahc->scbarray[scb_index];
   1713  1.1   mycroft 
   1714  1.6   mycroft 		if (status & SCSIRSTI) {
   1715  1.6   mycroft 			char channel;
   1716  1.6   mycroft 			channel = AHC_INB(ahc, SBLKCTL);
   1717  1.6   mycroft 			channel = channel & SELBUSB ? 'B' : 'A';
   1718  1.6   mycroft 			printf("%s: Someone reset channel %c\n",
   1719  1.6   mycroft 				ahc_name(ahc), channel);
   1720  1.6   mycroft 			ahc_reset_channel(ahc,
   1721  1.6   mycroft 					  channel,
   1722  1.6   mycroft 					  SCB_LIST_NULL,
   1723  1.6   mycroft 					  XS_BUSY,
   1724  1.6   mycroft 					  /* Initiate Reset */FALSE);
   1725  1.6   mycroft 			scb = NULL;
   1726  1.6   mycroft 		}
   1727  1.6   mycroft 		else if (!(scb && (scb->flags & SCB_ACTIVE))){
   1728  1.6   mycroft 			printf("%s: ahc_intr - referenced scb not "
   1729  1.1   mycroft 			       "valid during scsiint 0x%x scb(%d)\n",
   1730  1.6   mycroft 				ahc_name(ahc), status, scb_index);
   1731  1.6   mycroft 			AHC_OUTB(ahc, CLRSINT1, status);
   1732  1.1   mycroft 			UNPAUSE_SEQUENCER(ahc);
   1733  1.6   mycroft 			AHC_OUTB(ahc, CLRINT, CLRSCSIINT);
   1734  1.1   mycroft 			scb = NULL;
   1735  1.1   mycroft 		}
   1736  1.6   mycroft 		else if (status & SCSIPERR) {
   1737  1.6   mycroft 			/*
   1738  1.6   mycroft 			 * Determine the bus phase and
   1739  1.6   mycroft 			 * queue an appropriate message
   1740  1.6   mycroft 			 */
   1741  1.6   mycroft 			char	*phase;
   1742  1.6   mycroft 			u_char	mesg_out = MSG_NOP;
   1743  1.6   mycroft 			u_char	lastphase = AHC_INB(ahc, LASTPHASE);
   1744  1.1   mycroft 
   1745  1.9  explorer 			xs = scb->xs;
   1746  1.6   mycroft 			sc_print_addr(xs->sc_link);
   1747  1.6   mycroft 
   1748  1.6   mycroft 			switch(lastphase) {
   1749  1.6   mycroft 				case P_DATAOUT:
   1750  1.6   mycroft 					phase = "Data-Out";
   1751  1.6   mycroft 					break;
   1752  1.6   mycroft 				case P_DATAIN:
   1753  1.6   mycroft 					phase = "Data-In";
   1754  1.6   mycroft 					mesg_out = MSG_INITIATOR_DET_ERROR;
   1755  1.6   mycroft 					break;
   1756  1.6   mycroft 				case P_COMMAND:
   1757  1.6   mycroft 					phase = "Command";
   1758  1.6   mycroft 					break;
   1759  1.6   mycroft 				case P_MESGOUT:
   1760  1.6   mycroft 					phase = "Message-Out";
   1761  1.6   mycroft 					break;
   1762  1.6   mycroft 				case P_STATUS:
   1763  1.6   mycroft 					phase = "Status";
   1764  1.6   mycroft 					mesg_out = MSG_INITIATOR_DET_ERROR;
   1765  1.6   mycroft 					break;
   1766  1.6   mycroft 				case P_MESGIN:
   1767  1.6   mycroft 					phase = "Message-In";
   1768  1.6   mycroft 					mesg_out = MSG_MSG_PARITY_ERROR;
   1769  1.6   mycroft 					break;
   1770  1.6   mycroft 				default:
   1771  1.6   mycroft 					phase = "unknown";
   1772  1.6   mycroft 					break;
   1773  1.6   mycroft 			}
   1774  1.6   mycroft                         printf("parity error during %s phase.\n", phase);
   1775  1.1   mycroft 
   1776  1.6   mycroft 			/*
   1777  1.9  explorer 			 * We've set the hardware to assert ATN if we
   1778  1.9  explorer 			 * get a parity error on "in" phases, so all we
   1779  1.6   mycroft 			 * need to do is stuff the message buffer with
   1780  1.9  explorer 			 * the appropriate message.  "In" phases have set
   1781  1.6   mycroft 			 * mesg_out to something other than MSG_NOP.
   1782  1.6   mycroft 			 */
   1783  1.6   mycroft 			if(mesg_out != MSG_NOP) {
   1784  1.6   mycroft 				AHC_OUTB(ahc, MSG0, mesg_out);
   1785  1.6   mycroft 				AHC_OUTB(ahc, MSG_LEN, 1);
   1786  1.6   mycroft 			}
   1787  1.6   mycroft 			else
   1788  1.6   mycroft 				/*
   1789  1.6   mycroft 				 * Should we allow the target to make
   1790  1.6   mycroft 				 * this decision for us?
   1791  1.6   mycroft 				 */
   1792  1.6   mycroft 				xs->error = XS_DRIVER_STUFFUP;
   1793  1.6   mycroft 		}
   1794  1.6   mycroft 		else if (status & SELTO) {
   1795  1.1   mycroft 			u_char waiting;
   1796  1.1   mycroft 			u_char flags;
   1797  1.9  explorer 
   1798  1.9  explorer 			xs = scb->xs;
   1799  1.9  explorer 			xs->error = XS_SELTIMEOUT;
   1800  1.1   mycroft 			/*
   1801  1.1   mycroft 			 * Clear any pending messages for the timed out
   1802  1.1   mycroft 			 * target, and mark the target as free
   1803  1.1   mycroft 			 */
   1804  1.6   mycroft 			flags = AHC_INB(ahc, FLAGS);
   1805  1.6   mycroft 			AHC_OUTB(ahc, MSG_LEN, 0);
   1806  1.6   mycroft 			ahc_unbusy_target(ahc, xs->sc_link->target,
   1807  1.6   mycroft #if defined(__FreeBSD__)
   1808  1.6   mycroft 			 	((long)xs->sc_link->fordriver & SELBUSB)
   1809  1.6   mycroft #elif defined(__NetBSD__)
   1810  1.6   mycroft 				IS_SCSIBUS_B(ahc, xs->sc_link)
   1811  1.6   mycroft #endif
   1812  1.6   mycroft 				 	? 'B' : 'A');
   1813  1.9  explorer 			/* Stop the selection */
   1814  1.9  explorer 			AHC_OUTB(ahc, SCSISEQ, 0);
   1815  1.1   mycroft 
   1816  1.6   mycroft 			AHC_OUTB(ahc, SCB_CONTROL, 0);
   1817  1.1   mycroft 
   1818  1.6   mycroft 			AHC_OUTB(ahc, CLRSINT1, CLRSELTIMEO);
   1819  1.1   mycroft 
   1820  1.6   mycroft 			AHC_OUTB(ahc, CLRINT, CLRSCSIINT);
   1821  1.1   mycroft 
   1822  1.1   mycroft 			/* Shift the waiting for selection queue forward */
   1823  1.6   mycroft 			waiting = AHC_INB(ahc, WAITING_SCBH);
   1824  1.6   mycroft 			AHC_OUTB(ahc, SCBPTR, waiting);
   1825  1.6   mycroft 			waiting = AHC_INB(ahc, SCB_NEXT);
   1826  1.6   mycroft 			AHC_OUTB(ahc, WAITING_SCBH, waiting);
   1827  1.1   mycroft 
   1828  1.1   mycroft 			RESTART_SEQUENCER(ahc);
   1829  1.6   mycroft 		}
   1830  1.6   mycroft 		else if (!(status & BUSFREE)) {
   1831  1.9  explorer 		      sc_print_addr(scb->xs->sc_link);
   1832  1.6   mycroft 		      printf("Unknown SCSIINT. Status = 0x%x\n", status);
   1833  1.6   mycroft 		      AHC_OUTB(ahc, CLRSINT1, status);
   1834  1.6   mycroft 		      UNPAUSE_SEQUENCER(ahc);
   1835  1.6   mycroft 		      AHC_OUTB(ahc, CLRINT, CLRSCSIINT);
   1836  1.6   mycroft 		      scb = NULL;
   1837  1.6   mycroft 		}
   1838  1.6   mycroft 		if(scb != NULL) {
   1839  1.6   mycroft 		    /* We want to process the command */
   1840  1.6   mycroft 		    untimeout(ahc_timeout, (caddr_t)scb);
   1841  1.6   mycroft 		    ahc_done(ahc, scb);
   1842  1.1   mycroft 		}
   1843  1.6   mycroft 	}
   1844  1.6   mycroft 	if (intstat & CMDCMPLT) {
   1845  1.6   mycroft 		int   scb_index;
   1846  1.1   mycroft 
   1847  1.6   mycroft 		do {
   1848  1.6   mycroft 			scb_index = AHC_INB(ahc, QOUTFIFO);
   1849  1.6   mycroft 			scb = ahc->scbarray[scb_index];
   1850  1.6   mycroft 			if (!scb || !(scb->flags & SCB_ACTIVE)) {
   1851  1.6   mycroft 				printf("%s: WARNING "
   1852  1.6   mycroft 				       "no command for scb %d (cmdcmplt)\n"
   1853  1.6   mycroft 				       "QOUTCNT == %d\n",
   1854  1.6   mycroft 					ahc_name(ahc), scb_index,
   1855  1.6   mycroft 					AHC_INB(ahc, QOUTCNT));
   1856  1.6   mycroft 				AHC_OUTB(ahc, CLRINT, CLRCMDINT);
   1857  1.6   mycroft 				continue;
   1858  1.6   mycroft 			}
   1859  1.6   mycroft 			AHC_OUTB(ahc, CLRINT, CLRCMDINT);
   1860  1.6   mycroft 			untimeout(ahc_timeout, (caddr_t)scb);
   1861  1.6   mycroft 			ahc_done(ahc, scb);
   1862  1.1   mycroft 
   1863  1.6   mycroft 		} while (AHC_INB(ahc, QOUTCNT) & ahc->qcntmask);
   1864  1.1   mycroft 
   1865  1.6   mycroft 		ahc_run_waiting_queues(ahc);
   1866  1.6   mycroft 	}
   1867  1.6   mycroft #if defined(__NetBSD__)
   1868  1.6   mycroft 	return 1;
   1869  1.1   mycroft #endif
   1870  1.1   mycroft }
   1871  1.1   mycroft 
   1872  1.1   mycroft /*
   1873  1.1   mycroft  * We have a scb which has been processed by the
   1874  1.1   mycroft  * adaptor, now we look to see how the operation
   1875  1.1   mycroft  * went.
   1876  1.1   mycroft  */
   1877  1.6   mycroft static void
   1878  1.1   mycroft ahc_done(ahc, scb)
   1879  1.6   mycroft 	struct ahc_data *ahc;
   1880  1.6   mycroft 	struct scb *scb;
   1881  1.1   mycroft {
   1882  1.1   mycroft 	struct scsi_xfer *xs = scb->xs;
   1883  1.6   mycroft 
   1884  1.6   mycroft 	SC_DEBUG(xs->sc_link, SDEV_DB2, ("ahc_done\n"));
   1885  1.1   mycroft 	/*
   1886  1.1   mycroft 	 * Put the results of the operation
   1887  1.1   mycroft 	 * into the xfer and call whoever started it
   1888  1.1   mycroft 	 */
   1889  1.6   mycroft #if defined(__NetBSD__)
   1890  1.6   mycroft 	if (xs->error != XS_NOERROR) {
   1891  1.6   mycroft 		/* Don't override the error value. */
   1892  1.6   mycroft 	} else if (scb->flags & SCB_ABORTED) {
   1893  1.6   mycroft 		xs->error = XS_DRIVER_STUFFUP;
   1894  1.6   mycroft 	} else
   1895  1.6   mycroft #endif
   1896  1.6   mycroft 	if(scb->flags & SCB_SENSE)
   1897  1.6   mycroft 		xs->error = XS_SENSE;
   1898  1.6   mycroft 	if(scb->flags & SCB_SENTORDEREDTAG)
   1899  1.6   mycroft 		ahc->in_timeout = FALSE;
   1900  1.6   mycroft #if defined(__FreeBSD__)
   1901  1.6   mycroft 	if ((xs->flags & SCSI_ERR_OK) && !(xs->error == XS_SENSE)) {
   1902  1.6   mycroft 		/* All went correctly  OR errors expected */
   1903  1.6   mycroft 		xs->error = XS_NOERROR;
   1904  1.1   mycroft 	}
   1905  1.6   mycroft #elif defined(__NetBSD__)
   1906  1.6   mycroft 	/*
   1907  1.6   mycroft 	 * Since NetBSD doesn't have error ignoring operation mode
   1908  1.6   mycroft 	 * (SCSI_ERR_OK in FreeBSD), we don't have to care this case.
   1909  1.6   mycroft 	 */
   1910  1.6   mycroft #endif
   1911  1.1   mycroft 	xs->flags |= ITSDONE;
   1912  1.1   mycroft #ifdef AHC_TAGENABLE
   1913  1.6   mycroft 	if(xs->cmd->opcode == INQUIRY && xs->error == XS_NOERROR)
   1914  1.6   mycroft 	{
   1915  1.1   mycroft 		struct scsi_inquiry_data *inq_data;
   1916  1.1   mycroft 		u_short mask = 0x01 << (xs->sc_link->target |
   1917  1.6   mycroft 				(scb->tcl & 0x08));
   1918  1.1   mycroft 		/*
   1919  1.1   mycroft 		 * Sneak a look at the results of the SCSI Inquiry
   1920  1.6   mycroft 		 * command and see if we can do Tagged queing.  This
   1921  1.1   mycroft 		 * should really be done by the higher level drivers.
   1922  1.1   mycroft 		 */
   1923  1.1   mycroft 		inq_data = (struct scsi_inquiry_data *)xs->data;
   1924  1.6   mycroft 		if((inq_data->flags & SID_CmdQue) && !(ahc->tagenable & mask))
   1925  1.6   mycroft 		{
   1926  1.6   mycroft 		        printf("%s: target %d Tagged Queuing Device\n",
   1927  1.6   mycroft 				ahc_name(ahc), xs->sc_link->target);
   1928  1.1   mycroft 			ahc->tagenable |= mask;
   1929  1.6   mycroft 			if(ahc->maxhscbs >= 16 || (ahc->flags & AHC_PAGESCBS)) {
   1930  1.6   mycroft 				/* Default to 8 tags */
   1931  1.6   mycroft 				xs->sc_link->opennings += 6;
   1932  1.6   mycroft 			}
   1933  1.6   mycroft 			else
   1934  1.6   mycroft 			{
   1935  1.6   mycroft 				/*
   1936  1.6   mycroft 				 * Default to 4 tags on whimpy
   1937  1.6   mycroft 				 * cards that don't have much SCB
   1938  1.6   mycroft 				 * space and can't page.  This prevents
   1939  1.6   mycroft 				 * a single device from hogging all
   1940  1.6   mycroft 				 * slots.  We should really have a better
   1941  1.6   mycroft 				 * way of providing fairness.
   1942  1.6   mycroft 				 */
   1943  1.6   mycroft 				xs->sc_link->opennings += 2;
   1944  1.6   mycroft 			}
   1945  1.1   mycroft 		}
   1946  1.1   mycroft 	}
   1947  1.1   mycroft #endif
   1948  1.1   mycroft 	ahc_free_scb(ahc, scb, xs->flags);
   1949  1.1   mycroft 	scsi_done(xs);
   1950  1.1   mycroft }
   1951  1.1   mycroft 
   1952  1.1   mycroft /*
   1953  1.1   mycroft  * Start the board, ready for normal operation
   1954  1.1   mycroft  */
   1955  1.1   mycroft int
   1956  1.1   mycroft ahc_init(ahc)
   1957  1.6   mycroft 	struct  ahc_data *ahc;
   1958  1.1   mycroft {
   1959  1.6   mycroft 	u_char	scsi_conf, sblkctl, i;
   1960  1.9  explorer 	u_short	ultraenable = 0;
   1961  1.6   mycroft 	int     max_targ = 15;
   1962  1.1   mycroft 	/*
   1963  1.6   mycroft 	 * Assume we have a board at this stage and it has been reset.
   1964  1.1   mycroft 	 */
   1965  1.1   mycroft 
   1966  1.6   mycroft 	/* Handle the SCBPAGING option */
   1967  1.6   mycroft #ifndef AHC_SCBPAGING_ENABLE
   1968  1.6   mycroft 	ahc->flags &= ~AHC_PAGESCBS;
   1969  1.6   mycroft #endif
   1970  1.6   mycroft 
   1971  1.6   mycroft 	/* Determine channel configuration and who we are on the scsi bus. */
   1972  1.6   mycroft 	switch ( (sblkctl = AHC_INB(ahc, SBLKCTL) & 0x0a) ) {
   1973  1.6   mycroft 	    case 0:
   1974  1.6   mycroft 		ahc->our_id = (AHC_INB(ahc, SCSICONF) & HSCSIID);
   1975  1.6   mycroft 		ahc->flags &= ~AHC_CHANNEL_B_PRIMARY;
   1976  1.6   mycroft 		if(ahc->type == AHC_394)
   1977  1.6   mycroft 			printf("Channel %c, SCSI Id=%d, ",
   1978  1.6   mycroft 				ahc->flags & AHC_CHNLB ? 'B' : 'A',
   1979  1.6   mycroft 				ahc->our_id);
   1980  1.6   mycroft 		else
   1981  1.6   mycroft 			printf("Single Channel, SCSI Id=%d, ", ahc->our_id);
   1982  1.6   mycroft 		AHC_OUTB(ahc, FLAGS, SINGLE_BUS | (ahc->flags & AHC_PAGESCBS));
   1983  1.1   mycroft 		break;
   1984  1.6   mycroft 	    case 2:
   1985  1.6   mycroft 		ahc->our_id = (AHC_INB(ahc, SCSICONF + 1) & HWSCSIID);
   1986  1.6   mycroft 		ahc->flags &= ~AHC_CHANNEL_B_PRIMARY;
   1987  1.6   mycroft 		if(ahc->type == AHC_394)
   1988  1.6   mycroft 			printf("Wide Channel %c, SCSI Id=%d, ",
   1989  1.6   mycroft 				ahc->flags & AHC_CHNLB ? 'B' : 'A',
   1990  1.6   mycroft 				ahc->our_id);
   1991  1.1   mycroft 		else
   1992  1.6   mycroft 			printf("Wide Channel, SCSI Id=%d, ", ahc->our_id);
   1993  1.1   mycroft 		ahc->type |= AHC_WIDE;
   1994  1.6   mycroft 		AHC_OUTB(ahc, FLAGS, WIDE_BUS | (ahc->flags & AHC_PAGESCBS));
   1995  1.1   mycroft 		break;
   1996  1.6   mycroft 	    case 8:
   1997  1.6   mycroft 		ahc->our_id = (AHC_INB(ahc, SCSICONF) & HSCSIID);
   1998  1.6   mycroft 		ahc->our_id_b = (AHC_INB(ahc, SCSICONF + 1) & HSCSIID);
   1999  1.1   mycroft 		printf("Twin Channel, A SCSI Id=%d, B SCSI Id=%d, ",
   2000  1.6   mycroft 			ahc->our_id, ahc->our_id_b);
   2001  1.1   mycroft 		ahc->type |= AHC_TWIN;
   2002  1.6   mycroft 		AHC_OUTB(ahc, FLAGS, TWIN_BUS | (ahc->flags & AHC_PAGESCBS));
   2003  1.1   mycroft 		break;
   2004  1.6   mycroft 	    default:
   2005  1.6   mycroft 		printf(" Unsupported adapter type.  Ignoring\n");
   2006  1.1   mycroft 		return(-1);
   2007  1.1   mycroft 	}
   2008  1.1   mycroft 
   2009  1.6   mycroft 	/* Determine the number of SCBs */
   2010  1.1   mycroft 
   2011  1.6   mycroft 	{
   2012  1.6   mycroft 		AHC_OUTB(ahc, SCBPTR, 0);
   2013  1.6   mycroft 		AHC_OUTB(ahc, SCB_CONTROL, 0);
   2014  1.6   mycroft 		for(i = 1; i < AHC_SCB_MAX; i++) {
   2015  1.6   mycroft 			AHC_OUTB(ahc, SCBPTR, i);
   2016  1.6   mycroft 			AHC_OUTB(ahc, SCB_CONTROL, i);
   2017  1.6   mycroft 			if(AHC_INB(ahc, SCB_CONTROL) != i)
   2018  1.6   mycroft 				break;
   2019  1.6   mycroft 			AHC_OUTB(ahc, SCBPTR, 0);
   2020  1.6   mycroft 			if(AHC_INB(ahc, SCB_CONTROL) != 0)
   2021  1.6   mycroft 				break;
   2022  1.6   mycroft 			/* Clear the control byte. */
   2023  1.6   mycroft 			AHC_OUTB(ahc, SCBPTR, i);
   2024  1.6   mycroft 			AHC_OUTB(ahc, SCB_CONTROL, 0);
   2025  1.1   mycroft 
   2026  1.6   mycroft 			ahc->qcntmask |= i;     /* Update the count mask. */
   2027  1.1   mycroft 		}
   2028  1.6   mycroft 
   2029  1.6   mycroft 		/* Ensure we clear the 0 SCB's control byte. */
   2030  1.6   mycroft 		AHC_OUTB(ahc, SCBPTR, 0);
   2031  1.6   mycroft 		AHC_OUTB(ahc, SCB_CONTROL, 0);
   2032  1.6   mycroft 
   2033  1.6   mycroft 		ahc->qcntmask |= i;
   2034  1.6   mycroft 		ahc->maxhscbs = i;
   2035  1.6   mycroft 	}
   2036  1.6   mycroft 
   2037  1.6   mycroft 	if((ahc->maxhscbs < AHC_SCB_MAX) && (ahc->flags & AHC_PAGESCBS))
   2038  1.6   mycroft 		ahc->maxscbs = AHC_SCB_MAX;
   2039  1.6   mycroft 	else {
   2040  1.6   mycroft 		ahc->maxscbs = ahc->maxhscbs;
   2041  1.6   mycroft 		ahc->flags &= ~AHC_PAGESCBS;
   2042  1.1   mycroft 	}
   2043  1.6   mycroft 
   2044  1.6   mycroft 	printf("%d SCBs\n", ahc->maxhscbs);
   2045  1.6   mycroft 
   2046  1.6   mycroft #ifdef AHC_DEBUG
   2047  1.6   mycroft 	if(ahc_debug & AHC_SHOWMISC) {
   2048  1.6   mycroft 		struct scb	test;
   2049  1.6   mycroft 		printf("%s: hardware scb %ld bytes; kernel scb; "
   2050  1.6   mycroft 		       "ahc_dma %d bytes\n",
   2051  1.6   mycroft 			ahc_name(ahc),
   2052  1.6   mycroft 		        (u_long)&(test.next) - (u_long)(&test),
   2053  1.6   mycroft 			sizeof(test),
   2054  1.6   mycroft 			sizeof(struct ahc_dma_seg));
   2055  1.6   mycroft 	}
   2056  1.6   mycroft #endif /* AHC_DEBUG */
   2057  1.6   mycroft 
   2058  1.6   mycroft 	/* Set the SCSI Id, SXFRCTL0, SXFRCTL1, and SIMODE1, for both channels*/
   2059  1.6   mycroft 	if(ahc->type & AHC_TWIN)
   2060  1.6   mycroft 	{
   2061  1.1   mycroft 		/*
   2062  1.1   mycroft 		 * The device is gated to channel B after a chip reset,
   2063  1.1   mycroft 		 * so set those values first
   2064  1.1   mycroft 		 */
   2065  1.6   mycroft 		AHC_OUTB(ahc, SCSIID, ahc->our_id_b);
   2066  1.6   mycroft 		scsi_conf = AHC_INB(ahc, SCSICONF + 1);
   2067  1.6   mycroft 		AHC_OUTB(ahc, SXFRCTL1, (scsi_conf & (ENSPCHK|STIMESEL))
   2068  1.6   mycroft 					| ENSTIMER|ACTNEGEN|STPWEN);
   2069  1.6   mycroft 		AHC_OUTB(ahc, SIMODE1, ENSELTIMO|ENSCSIRST|ENSCSIPERR);
   2070  1.6   mycroft 		if(ahc->type & AHC_ULTRA)
   2071  1.6   mycroft 			AHC_OUTB(ahc, SXFRCTL0, DFON|SPIOEN|ULTRAEN);
   2072  1.6   mycroft 		else
   2073  1.6   mycroft 			AHC_OUTB(ahc, SXFRCTL0, DFON|SPIOEN);
   2074  1.6   mycroft 
   2075  1.6   mycroft 		if(scsi_conf & RESET_SCSI) {
   2076  1.6   mycroft 			/* Reset the bus */
   2077  1.6   mycroft 			if(bootverbose)
   2078  1.6   mycroft 				printf("%s: Reseting Channel B\n",
   2079  1.6   mycroft 				       ahc_name(ahc));
   2080  1.6   mycroft 			AHC_OUTB(ahc, SCSISEQ, SCSIRSTO);
   2081  1.6   mycroft 			DELAY(1000);
   2082  1.6   mycroft 			AHC_OUTB(ahc, SCSISEQ, 0);
   2083  1.6   mycroft 
   2084  1.6   mycroft 			/* Ensure we don't get a RSTI interrupt from this */
   2085  1.6   mycroft 			AHC_OUTB(ahc, CLRSINT1, CLRSCSIRSTI);
   2086  1.6   mycroft 			AHC_OUTB(ahc, CLRINT, CLRSCSIINT);
   2087  1.6   mycroft 		}
   2088  1.6   mycroft 
   2089  1.1   mycroft 		/* Select Channel A */
   2090  1.6   mycroft 		AHC_OUTB(ahc, SBLKCTL, 0);
   2091  1.6   mycroft 	}
   2092  1.6   mycroft 	AHC_OUTB(ahc, SCSIID, ahc->our_id);
   2093  1.6   mycroft 	scsi_conf = AHC_INB(ahc, SCSICONF);
   2094  1.6   mycroft 	AHC_OUTB(ahc, SXFRCTL1, (scsi_conf & (ENSPCHK|STIMESEL))
   2095  1.6   mycroft 				| ENSTIMER|ACTNEGEN|STPWEN);
   2096  1.6   mycroft 	AHC_OUTB(ahc, SIMODE1, ENSELTIMO|ENSCSIRST|ENSCSIPERR);
   2097  1.6   mycroft 	if(ahc->type & AHC_ULTRA)
   2098  1.6   mycroft 		AHC_OUTB(ahc, SXFRCTL0, DFON|SPIOEN|ULTRAEN);
   2099  1.6   mycroft 	else
   2100  1.6   mycroft 		AHC_OUTB(ahc, SXFRCTL0, DFON|SPIOEN);
   2101  1.6   mycroft 
   2102  1.6   mycroft 	if(scsi_conf & RESET_SCSI) {
   2103  1.6   mycroft 		/* Reset the bus */
   2104  1.6   mycroft 		if(bootverbose)
   2105  1.6   mycroft 			printf("%s: Reseting Channel A\n", ahc_name(ahc));
   2106  1.6   mycroft 
   2107  1.6   mycroft 		AHC_OUTB(ahc, SCSISEQ, SCSIRSTO);
   2108  1.6   mycroft 		DELAY(1000);
   2109  1.6   mycroft 		AHC_OUTB(ahc, SCSISEQ, 0);
   2110  1.6   mycroft 
   2111  1.6   mycroft 		/* Ensure we don't get a RSTI interrupt from this */
   2112  1.6   mycroft 		AHC_OUTB(ahc, CLRSINT1, CLRSCSIRSTI);
   2113  1.6   mycroft 		AHC_OUTB(ahc, CLRINT, CLRSCSIINT);
   2114  1.1   mycroft 	}
   2115  1.6   mycroft 
   2116  1.1   mycroft 	/*
   2117  1.1   mycroft 	 * Look at the information that board initialization or
   2118  1.1   mycroft 	 * the board bios has left us.  In the lower four bits of each
   2119  1.1   mycroft 	 * target's scratch space any value other than 0 indicates
   2120  1.1   mycroft 	 * that we should initiate syncronous transfers.  If it's zero,
   2121  1.1   mycroft 	 * the user or the BIOS has decided to disable syncronous
   2122  1.6   mycroft 	 * negotiation to that target so we don't activate the needsdtr
   2123  1.1   mycroft 	 * flag.
   2124  1.1   mycroft 	 */
   2125  1.1   mycroft 	ahc->needsdtr_orig = 0;
   2126  1.1   mycroft 	ahc->needwdtr_orig = 0;
   2127  1.1   mycroft 
   2128  1.6   mycroft 	/* Grab the disconnection disable table and invert it for our needs */
   2129  1.6   mycroft 	if(ahc->flags & AHC_USEDEFAULTS) {
   2130  1.6   mycroft 		printf("%s: Host Adapter Bios disabled.  Using default SCSI "
   2131  1.6   mycroft 			"device parameters\n", ahc_name(ahc));
   2132  1.6   mycroft 		ahc->discenable = 0xff;
   2133  1.6   mycroft 	}
   2134  1.6   mycroft 	else
   2135  1.6   mycroft 		ahc->discenable = ~((AHC_INB(ahc, DISC_DSB + 1) << 8)
   2136  1.6   mycroft 				   | AHC_INB(ahc, DISC_DSB));
   2137  1.6   mycroft 
   2138  1.6   mycroft 	if(!(ahc->type & (AHC_WIDE|AHC_TWIN)))
   2139  1.6   mycroft 		max_targ = 7;
   2140  1.6   mycroft 
   2141  1.6   mycroft 	for(i = 0; i <= max_targ; i++){
   2142  1.6   mycroft 		u_char target_settings;
   2143  1.6   mycroft 		if (ahc->flags & AHC_USEDEFAULTS) {
   2144  1.6   mycroft 			target_settings = 0; /* 10MHz */
   2145  1.1   mycroft 			ahc->needsdtr_orig |= (0x01 << i);
   2146  1.6   mycroft 			ahc->needwdtr_orig |= (0x01 << i);
   2147  1.1   mycroft 		}
   2148  1.6   mycroft 		else {
   2149  1.6   mycroft 			/* Take the settings leftover in scratch RAM. */
   2150  1.6   mycroft 			target_settings = AHC_INB(ahc, TARG_SCRATCH + i);
   2151  1.6   mycroft 
   2152  1.6   mycroft 			if(target_settings & 0x0f){
   2153  1.6   mycroft 				ahc->needsdtr_orig |= (0x01 << i);
   2154  1.6   mycroft 				/*Default to a asyncronous transfers(0 offset)*/
   2155  1.6   mycroft 				target_settings &= 0xf0;
   2156  1.6   mycroft 			}
   2157  1.6   mycroft 			if(target_settings & 0x80){
   2158  1.6   mycroft 				ahc->needwdtr_orig |= (0x01 << i);
   2159  1.6   mycroft 				/*
   2160  1.6   mycroft 				 * We'll set the Wide flag when we
   2161  1.6   mycroft 				 * are successful with Wide negotiation.
   2162  1.6   mycroft 				 * Turn it off for now so we aren't
   2163  1.6   mycroft 				 * confused.
   2164  1.6   mycroft 				 */
   2165  1.6   mycroft 				target_settings &= 0x7f;
   2166  1.6   mycroft 			}
   2167  1.9  explorer 			if(ahc->type & AHC_ULTRA) {
   2168  1.9  explorer 				/*
   2169  1.9  explorer 				 * Enable Ultra for any target that
   2170  1.9  explorer 				 * has a valid ultra syncrate setting.
   2171  1.9  explorer 				 */
   2172  1.9  explorer 				u_char rate = target_settings & 0x70;
   2173  1.9  explorer 				if(rate == 0x00 || rate == 0x10 ||
   2174  1.9  explorer 				   rate == 0x20 || rate == 0x40) {
   2175  1.9  explorer 					if(rate == 0x40) {
   2176  1.9  explorer 						/* Treat 10MHz specially */
   2177  1.9  explorer 						target_settings &= ~0x70;
   2178  1.9  explorer 					}
   2179  1.9  explorer 					else
   2180  1.9  explorer 						ultraenable |= (0x01 << i);
   2181  1.9  explorer 				}
   2182  1.9  explorer 			}
   2183  1.1   mycroft 		}
   2184  1.6   mycroft 		AHC_OUTB(ahc, TARG_SCRATCH+i,target_settings);
   2185  1.1   mycroft 	}
   2186  1.1   mycroft 	/*
   2187  1.1   mycroft 	 * If we are not a WIDE device, forget WDTR.  This
   2188  1.1   mycroft 	 * makes the driver work on some cards that don't
   2189  1.1   mycroft 	 * leave these fields cleared when the BIOS is not
   2190  1.1   mycroft 	 * installed.
   2191  1.1   mycroft 	 */
   2192  1.6   mycroft 	if(!(ahc->type & AHC_WIDE))
   2193  1.1   mycroft 		ahc->needwdtr_orig = 0;
   2194  1.1   mycroft 	ahc->needsdtr = ahc->needsdtr_orig;
   2195  1.1   mycroft 	ahc->needwdtr = ahc->needwdtr_orig;
   2196  1.1   mycroft 	ahc->sdtrpending = 0;
   2197  1.1   mycroft 	ahc->wdtrpending = 0;
   2198  1.1   mycroft 	ahc->tagenable = 0;
   2199  1.6   mycroft 	ahc->orderedtag = 0;
   2200  1.6   mycroft 
   2201  1.9  explorer 	AHC_OUTB(ahc, ULTRA_ENB, ultraenable & 0xff);
   2202  1.9  explorer 	AHC_OUTB(ahc, ULTRA_ENB + 1, (ultraenable >> 8) & 0xff);
   2203  1.9  explorer 
   2204  1.6   mycroft #ifdef AHC_DEBUG
   2205  1.6   mycroft 	/* How did we do? */
   2206  1.6   mycroft 	if(ahc_debug & AHC_SHOWMISC)
   2207  1.6   mycroft 		printf("NEEDSDTR == 0x%x\nNEEDWDTR == 0x%x\n"
   2208  1.6   mycroft 			"DISCENABLE == 0x%x\n", ahc->needsdtr,
   2209  1.6   mycroft 			ahc->needwdtr, ahc->discenable);
   2210  1.6   mycroft #endif
   2211  1.1   mycroft 	/*
   2212  1.6   mycroft 	 * Set the number of availible SCBs
   2213  1.1   mycroft 	 */
   2214  1.6   mycroft 	AHC_OUTB(ahc, SCBCOUNT, ahc->maxhscbs);
   2215  1.1   mycroft 
   2216  1.6   mycroft 	/*
   2217  1.6   mycroft 	 * 2's compliment of maximum tag value
   2218  1.6   mycroft 	 */
   2219  1.6   mycroft 	i = ahc->maxscbs;
   2220  1.6   mycroft 	AHC_OUTB(ahc, COMP_SCBCOUNT, -i & 0xff);
   2221  1.1   mycroft 
   2222  1.1   mycroft 	/*
   2223  1.6   mycroft 	 * QCount mask to deal with broken aic7850s that
   2224  1.6   mycroft 	 * sporatically get garbage in the upper bits of
   2225  1.6   mycroft 	 * their QCount registers.
   2226  1.1   mycroft 	 */
   2227  1.6   mycroft 	AHC_OUTB(ahc, QCNTMASK, ahc->qcntmask);
   2228  1.1   mycroft 
   2229  1.1   mycroft 	/* We don't have any busy targets right now */
   2230  1.6   mycroft 	AHC_OUTB(ahc, ACTIVE_A, 0);
   2231  1.6   mycroft 	AHC_OUTB(ahc, ACTIVE_B, 0);
   2232  1.6   mycroft 
   2233  1.1   mycroft 	/* We don't have any waiting selections */
   2234  1.6   mycroft 	AHC_OUTB(ahc, WAITING_SCBH, SCB_LIST_NULL);
   2235  1.6   mycroft 
   2236  1.6   mycroft 	/* Our disconnection list is empty too */
   2237  1.6   mycroft 	AHC_OUTB(ahc, DISCONNECTED_SCBH, SCB_LIST_NULL);
   2238  1.6   mycroft 
   2239  1.6   mycroft 	/* Message out buffer starts empty */
   2240  1.6   mycroft 	AHC_OUTB(ahc, MSG_LEN, 0x00);
   2241  1.6   mycroft 
   2242  1.6   mycroft 	/*
   2243  1.6   mycroft 	 * Load the Sequencer program and Enable the adapter
   2244  1.6   mycroft 	 * in "fast" mode.
   2245  1.6   mycroft          */
   2246  1.6   mycroft 	if(bootverbose)
   2247  1.6   mycroft 		printf("%s: Downloading Sequencer Program...",
   2248  1.6   mycroft 		       ahc_name(ahc));
   2249  1.6   mycroft 
   2250  1.6   mycroft 	ahc_loadseq(ahc);
   2251  1.6   mycroft 
   2252  1.6   mycroft 	if(bootverbose)
   2253  1.6   mycroft 		printf("Done\n");
   2254  1.6   mycroft 
   2255  1.6   mycroft 	AHC_OUTB(ahc, SEQCTL, FASTMODE);
   2256  1.6   mycroft 
   2257  1.6   mycroft 	UNPAUSE_SEQUENCER(ahc);
   2258  1.6   mycroft 
   2259  1.1   mycroft 	/*
   2260  1.6   mycroft 	 * Note that we are going and return (to probe)
   2261  1.1   mycroft 	 */
   2262  1.6   mycroft 	ahc->flags |= AHC_INIT;
   2263  1.1   mycroft 	return (0);
   2264  1.1   mycroft }
   2265  1.1   mycroft 
   2266  1.6   mycroft static void
   2267  1.1   mycroft ahcminphys(bp)
   2268  1.6   mycroft         struct buf *bp;
   2269  1.1   mycroft {
   2270  1.6   mycroft /*
   2271  1.6   mycroft  * Even though the card can transfer up to 16megs per command
   2272  1.6   mycroft  * we are limited by the number of segments in the dma segment
   2273  1.6   mycroft  * list that we can hold.  The worst case is that all pages are
   2274  1.6   mycroft  * discontinuous physically, hense the "page per segment" limit
   2275  1.6   mycroft  * enforced here.
   2276  1.6   mycroft  */
   2277  1.9  explorer         if (bp->b_bcount > ((AHC_NSEG - 1) * PAGE_SIZE)) {
   2278  1.9  explorer                 bp->b_bcount = ((AHC_NSEG - 1) * PAGE_SIZE);
   2279  1.6   mycroft         }
   2280  1.6   mycroft #if defined(__NetBSD__)
   2281  1.1   mycroft 	minphys(bp);
   2282  1.6   mycroft #endif
   2283  1.1   mycroft }
   2284  1.1   mycroft 
   2285  1.1   mycroft /*
   2286  1.1   mycroft  * start a scsi operation given the command and
   2287  1.1   mycroft  * the data address, target, and lun all of which
   2288  1.1   mycroft  * are stored in the scsi_xfer struct
   2289  1.1   mycroft  */
   2290  1.6   mycroft static int32_t
   2291  1.1   mycroft ahc_scsi_cmd(xs)
   2292  1.6   mycroft         struct scsi_xfer *xs;
   2293  1.1   mycroft {
   2294  1.9  explorer 	struct	scb *scb;
   2295  1.9  explorer 	struct	ahc_dma_seg *sg;
   2296  1.9  explorer 	int	seg;		/* scatter gather seg being worked on */
   2297  1.9  explorer 	int	thiskv;
   2298  1.9  explorer 	physaddr thisphys, nextphys;
   2299  1.9  explorer 	int	bytes_this_seg, bytes_this_page, datalen, flags;
   2300  1.9  explorer 	struct	ahc_data *ahc;
   2301  1.6   mycroft 	u_short	mask;
   2302  1.9  explorer 	int	s;
   2303  1.6   mycroft 
   2304  1.6   mycroft 	ahc = (struct ahc_data *)xs->sc_link->adapter_softc;
   2305  1.9  explorer 	mask = (0x01 << (xs->sc_link->target
   2306  1.6   mycroft #if defined(__FreeBSD__)
   2307  1.6   mycroft 				| ((u_long)xs->sc_link->fordriver & 0x08)));
   2308  1.6   mycroft #elif defined(__NetBSD__)
   2309  1.6   mycroft 			| (IS_SCSIBUS_B(ahc, xs->sc_link) ? SELBUSB : 0) ));
   2310  1.6   mycroft #endif
   2311  1.9  explorer 	SC_DEBUG(xs->sc_link, SDEV_DB2, ("ahc_scsi_cmd\n"));
   2312  1.9  explorer 	/*
   2313  1.9  explorer 	 * get an scb to use. If the transfer
   2314  1.9  explorer 	 * is from a buf (possibly from interrupt time)
   2315  1.9  explorer 	 * then we can't allow it to sleep
   2316  1.9  explorer 	 */
   2317  1.9  explorer 	flags = xs->flags;
   2318  1.9  explorer 	if (flags & ITSDONE) {
   2319  1.9  explorer 		printf("%s: Already done?", ahc_name(ahc));
   2320  1.9  explorer 		xs->flags &= ~ITSDONE;
   2321  1.9  explorer 	}
   2322  1.9  explorer 	if (!(flags & INUSE)) {
   2323  1.9  explorer 		printf("%s: Not in use?", ahc_name(ahc));
   2324  1.9  explorer 		xs->flags |= INUSE;
   2325  1.9  explorer 	}
   2326  1.9  explorer 	if (!(scb = ahc_get_scb(ahc, flags))) {
   2327  1.9  explorer 		xs->error = XS_DRIVER_STUFFUP;
   2328  1.9  explorer 		return (TRY_AGAIN_LATER);
   2329  1.9  explorer 	}
   2330  1.9  explorer 	SC_DEBUG(xs->sc_link, SDEV_DB3, ("start scb(%p)\n", scb));
   2331  1.9  explorer 	scb->xs = xs;
   2332  1.9  explorer 	if (flags & SCSI_RESET)
   2333  1.6   mycroft 		scb->flags |= SCB_DEVICE_RESET|SCB_IMMED;
   2334  1.9  explorer 	/*
   2335  1.9  explorer 	 * Put all the arguments for the xfer in the scb
   2336  1.9  explorer 	 */
   2337  1.6   mycroft 
   2338  1.6   mycroft 	if(ahc->tagenable & mask) {
   2339  1.6   mycroft 		scb->control |= TAG_ENB;
   2340  1.6   mycroft 		if(ahc->orderedtag & mask) {
   2341  1.6   mycroft 			printf("Ordered Tag sent\n");
   2342  1.6   mycroft 			scb->control |= 0x02;
   2343  1.6   mycroft 			ahc->orderedtag &= ~mask;
   2344  1.6   mycroft 		}
   2345  1.6   mycroft 	}
   2346  1.6   mycroft 	if(ahc->discenable & mask)
   2347  1.6   mycroft 		scb->control |= DISCENB;
   2348  1.6   mycroft 	if((ahc->needwdtr & mask) && !(ahc->wdtrpending & mask))
   2349  1.6   mycroft 	{
   2350  1.6   mycroft 		scb->control |= NEEDWDTR;
   2351  1.1   mycroft 		ahc->wdtrpending |= mask;
   2352  1.1   mycroft 	}
   2353  1.6   mycroft 	else if((ahc->needsdtr & mask) && !(ahc->sdtrpending & mask))
   2354  1.6   mycroft 	{
   2355  1.6   mycroft 		scb->control |= NEEDSDTR;
   2356  1.1   mycroft 		ahc->sdtrpending |= mask;
   2357  1.1   mycroft 	}
   2358  1.6   mycroft 	scb->tcl = ((xs->sc_link->target << 4) & 0xF0) |
   2359  1.6   mycroft #if defined(__FreeBSD__)
   2360  1.6   mycroft 				  ((u_long)xs->sc_link->fordriver & 0x08) |
   2361  1.6   mycroft #elif defined(__NetBSD__)
   2362  1.6   mycroft 				  (IS_SCSIBUS_B(ahc,xs->sc_link)? SELBUSB : 0)|
   2363  1.6   mycroft #endif
   2364  1.6   mycroft 				  (xs->sc_link->lun & 0x07);
   2365  1.1   mycroft 	scb->cmdlen = xs->cmdlen;
   2366  1.6   mycroft 	scb->cmdpointer = KVTOPHYS(xs->cmd);
   2367  1.1   mycroft 	xs->resid = 0;
   2368  1.6   mycroft 	xs->status = 0;
   2369  1.6   mycroft 	if (xs->datalen) {      /* should use S/G only if not zero length */
   2370  1.6   mycroft 		scb->SG_list_pointer = KVTOPHYS(scb->ahc_dma);
   2371  1.1   mycroft 		sg = scb->ahc_dma;
   2372  1.1   mycroft 		seg = 0;
   2373  1.6   mycroft 		/*
   2374  1.6   mycroft 		 * Set up the scatter gather block
   2375  1.6   mycroft 		 */
   2376  1.6   mycroft 		SC_DEBUG(xs->sc_link, SDEV_DB4,
   2377  1.6   mycroft 			 ("%ld @%p:- ", xs->datalen, xs->data));
   2378  1.6   mycroft 		datalen = xs->datalen;
   2379  1.6   mycroft 		thiskv = (int) xs->data;
   2380  1.6   mycroft 		thisphys = KVTOPHYS(thiskv);
   2381  1.6   mycroft 
   2382  1.6   mycroft 		while ((datalen) && (seg < AHC_NSEG)) {
   2383  1.6   mycroft 			bytes_this_seg = 0;
   2384  1.6   mycroft 
   2385  1.6   mycroft 			/* put in the base address */
   2386  1.6   mycroft 			sg->addr = thisphys;
   2387  1.6   mycroft 
   2388  1.6   mycroft 			SC_DEBUGN(xs->sc_link, SDEV_DB4, ("0x%lx", thisphys));
   2389  1.6   mycroft 
   2390  1.6   mycroft 			/* do it at least once */
   2391  1.6   mycroft 			nextphys = thisphys;
   2392  1.6   mycroft 			while ((datalen) && (thisphys == nextphys)) {
   2393  1.1   mycroft 				/*
   2394  1.6   mycroft 				 * This page is contiguous (physically)
   2395  1.6   mycroft 				 * with the the last, just extend the
   2396  1.6   mycroft 				 * length
   2397  1.1   mycroft 				 */
   2398  1.6   mycroft 				/* how far to the end of the page */
   2399  1.9  explorer 				nextphys = (thisphys & (~(PAGE_SIZE- 1)))
   2400  1.9  explorer 					   + PAGE_SIZE;
   2401  1.6   mycroft 				bytes_this_page = nextphys - thisphys;
   2402  1.6   mycroft 				/**** or the data ****/
   2403  1.6   mycroft 				bytes_this_page = min(bytes_this_page ,datalen);
   2404  1.6   mycroft 				bytes_this_seg += bytes_this_page;
   2405  1.6   mycroft 				datalen -= bytes_this_page;
   2406  1.6   mycroft 
   2407  1.6   mycroft 				/* get more ready for the next page */
   2408  1.9  explorer 				thiskv = (thiskv & (~(PAGE_SIZE - 1)))
   2409  1.9  explorer 					 + PAGE_SIZE;
   2410  1.6   mycroft 				if (datalen)
   2411  1.6   mycroft 					thisphys = KVTOPHYS(thiskv);
   2412  1.1   mycroft 			}
   2413  1.6   mycroft 			/*
   2414  1.6   mycroft 			 * next page isn't contiguous, finish the seg
   2415  1.6   mycroft 			 */
   2416  1.6   mycroft 			SC_DEBUGN(xs->sc_link, SDEV_DB4,
   2417  1.6   mycroft 					("(0x%x)", bytes_this_seg));
   2418  1.6   mycroft 			sg->len = bytes_this_seg;
   2419  1.6   mycroft 			sg++;
   2420  1.6   mycroft 			seg++;
   2421  1.1   mycroft 		}
   2422  1.1   mycroft 		scb->SG_segment_count = seg;
   2423  1.6   mycroft 
   2424  1.6   mycroft 		/* Copy the first SG into the data pointer area */
   2425  1.6   mycroft 		scb->data = scb->ahc_dma->addr;
   2426  1.6   mycroft 		scb->datalen = scb->ahc_dma->len;
   2427  1.6   mycroft 		SC_DEBUGN(xs->sc_link, SDEV_DB4, ("\n"));
   2428  1.6   mycroft 		if (datalen) {
   2429  1.6   mycroft 			/* there's still data, must have run out of segs! */
   2430  1.6   mycroft 			printf("%s: ahc_scsi_cmd: more than %d DMA segs\n",
   2431  1.6   mycroft 				ahc_name(ahc), AHC_NSEG);
   2432  1.1   mycroft 			xs->error = XS_DRIVER_STUFFUP;
   2433  1.1   mycroft 			ahc_free_scb(ahc, scb, flags);
   2434  1.1   mycroft 			return (COMPLETE);
   2435  1.1   mycroft 		}
   2436  1.6   mycroft #ifdef AHC_BROKEN_CACHE
   2437  1.6   mycroft 		if (ahc_broken_cache)
   2438  1.6   mycroft 			INVALIDATE_CACHE();
   2439  1.6   mycroft #endif
   2440  1.6   mycroft 	}
   2441  1.6   mycroft 	else {
   2442  1.6   mycroft 		/*
   2443  1.6   mycroft 		 * No data xfer, use non S/G values
   2444  1.6   mycroft 	 	 */
   2445  1.1   mycroft 		scb->SG_segment_count = 0;
   2446  1.6   mycroft 		scb->SG_list_pointer = 0;
   2447  1.6   mycroft 		scb->data = 0;
   2448  1.6   mycroft 		scb->datalen = 0;
   2449  1.1   mycroft 	}
   2450  1.1   mycroft 
   2451  1.6   mycroft #ifdef AHC_DEBUG
   2452  1.6   mycroft 	if((ahc_debug & AHC_SHOWSCBS) && (xs->sc_link->target == DEBUGTARG))
   2453  1.1   mycroft 		ahc_print_scb(scb);
   2454  1.1   mycroft #endif
   2455  1.1   mycroft 	s = splbio();
   2456  1.1   mycroft 
   2457  1.6   mycroft 	if( scb->position != SCB_LIST_NULL )
   2458  1.6   mycroft 	{
   2459  1.6   mycroft 		/* We already have a valid slot */
   2460  1.6   mycroft 		u_char curscb;
   2461  1.1   mycroft 
   2462  1.6   mycroft 		PAUSE_SEQUENCER(ahc);
   2463  1.6   mycroft 		curscb = AHC_INB(ahc, SCBPTR);
   2464  1.6   mycroft 		AHC_OUTB(ahc, SCBPTR, scb->position);
   2465  1.6   mycroft 		ahc_send_scb(ahc, scb);
   2466  1.6   mycroft 		AHC_OUTB(ahc, SCBPTR, curscb);
   2467  1.6   mycroft 		AHC_OUTB(ahc, QINFIFO, scb->position);
   2468  1.6   mycroft 		UNPAUSE_SEQUENCER(ahc);
   2469  1.9  explorer 		scb->flags |= SCB_ACTIVE;
   2470  1.6   mycroft 		if (!(flags & SCSI_NOMASK)) {
   2471  1.6   mycroft 			timeout(ahc_timeout, (caddr_t)scb,
   2472  1.6   mycroft 				(xs->timeout * hz) / 1000);
   2473  1.6   mycroft 		}
   2474  1.6   mycroft 		SC_DEBUG(xs->sc_link, SDEV_DB3, ("cmd_sent\n"));
   2475  1.6   mycroft 	}
   2476  1.6   mycroft 	else {
   2477  1.9  explorer 		scb->flags |= SCB_WAITINGQ;
   2478  1.9  explorer 		STAILQ_INSERT_TAIL(&ahc->waiting_scbs, scb, links);
   2479  1.6   mycroft 		ahc_run_waiting_queues(ahc);
   2480  1.6   mycroft 	}
   2481  1.6   mycroft 	if (!(flags & SCSI_NOMASK)) {
   2482  1.1   mycroft 		splx(s);
   2483  1.1   mycroft 		return (SUCCESSFULLY_QUEUED);
   2484  1.1   mycroft 	}
   2485  1.1   mycroft 	/*
   2486  1.6   mycroft 	 * If we can't use interrupts, poll for completion
   2487  1.1   mycroft 	 */
   2488  1.6   mycroft 	SC_DEBUG(xs->sc_link, SDEV_DB3, ("cmd_poll\n"));
   2489  1.6   mycroft 	do {
   2490  1.6   mycroft 		if (ahc_poll(ahc, xs->timeout)) {
   2491  1.6   mycroft 			if (!(xs->flags & SCSI_SILENT))
   2492  1.6   mycroft 				printf("cmd fail\n");
   2493  1.1   mycroft 			ahc_timeout(scb);
   2494  1.6   mycroft 			break;
   2495  1.6   mycroft 		}
   2496  1.6   mycroft 	} while (!(xs->flags & ITSDONE));  /* a non command complete intr */
   2497  1.6   mycroft 	splx(s);
   2498  1.1   mycroft 	return (COMPLETE);
   2499  1.1   mycroft }
   2500  1.1   mycroft 
   2501  1.1   mycroft 
   2502  1.1   mycroft /*
   2503  1.1   mycroft  * A scb (and hence an scb entry on the board is put onto the
   2504  1.1   mycroft  * free list.
   2505  1.1   mycroft  */
   2506  1.6   mycroft static void
   2507  1.1   mycroft ahc_free_scb(ahc, scb, flags)
   2508  1.6   mycroft         struct	ahc_data *ahc;
   2509  1.6   mycroft         int     flags;
   2510  1.6   mycroft         struct  scb *scb;
   2511  1.1   mycroft {
   2512  1.6   mycroft 	struct scb *wscb;
   2513  1.6   mycroft 	unsigned int opri;
   2514  1.1   mycroft 
   2515  1.6   mycroft 	opri = splbio();
   2516  1.1   mycroft 
   2517  1.9  explorer 	/* Clean up for the next user */
   2518  1.1   mycroft 	scb->flags = SCB_FREE;
   2519  1.9  explorer 	scb->control = 0;
   2520  1.9  explorer 	scb->status = 0;
   2521  1.9  explorer 
   2522  1.6   mycroft 	if(scb->position == SCB_LIST_NULL) {
   2523  1.9  explorer 		STAILQ_INSERT_HEAD(&ahc->page_scbs, scb, links);
   2524  1.9  explorer 		if(!scb->links.stqe_next && !ahc->free_scbs.stqh_first)
   2525  1.6   mycroft 			/*
   2526  1.6   mycroft 			 * If there were no SCBs availible, wake anybody waiting
   2527  1.6   mycroft 			 * for one to come free.
   2528  1.6   mycroft 			 */
   2529  1.6   mycroft 			wakeup((caddr_t)&ahc->free_scbs);
   2530  1.6   mycroft 	}
   2531  1.6   mycroft 	/*
   2532  1.6   mycroft 	 * If there are any SCBS on the waiting queue,
   2533  1.6   mycroft 	 * assign the slot of this "freed" SCB to the first
   2534  1.6   mycroft 	 * one.  We'll run the waiting queues after all command
   2535  1.6   mycroft 	 * completes for a particular interrupt are completed
   2536  1.6   mycroft 	 * or when we start another command.
   2537  1.6   mycroft 	 */
   2538  1.9  explorer 	else if((wscb = ahc->waiting_scbs.stqh_first) != NULL) {
   2539  1.9  explorer 		STAILQ_REMOVE_HEAD(&ahc->waiting_scbs, links);
   2540  1.6   mycroft 		wscb->position = scb->position;
   2541  1.9  explorer 		STAILQ_INSERT_HEAD(&ahc->assigned_scbs, wscb, links);
   2542  1.9  explorer 		wscb->flags ^= SCB_WAITINGQ|SCB_ASSIGNEDQ;
   2543  1.6   mycroft 
   2544  1.6   mycroft 		/*
   2545  1.6   mycroft 		 * The "freed" SCB will need to be assigned a slot
   2546  1.6   mycroft 		 * before being used, so put it in the page_scbs
   2547  1.6   mycroft 		 * queue.
   2548  1.6   mycroft 		 */
   2549  1.6   mycroft 		scb->position = SCB_LIST_NULL;
   2550  1.9  explorer 		STAILQ_INSERT_HEAD(&ahc->page_scbs, scb, links);
   2551  1.9  explorer 		if(!scb->links.stqe_next && !ahc->free_scbs.stqh_first)
   2552  1.6   mycroft 			/*
   2553  1.6   mycroft 			 * If there were no SCBs availible, wake anybody waiting
   2554  1.6   mycroft 			 * for one to come free.
   2555  1.6   mycroft 			 */
   2556  1.6   mycroft 			wakeup((caddr_t)&ahc->free_scbs);
   2557  1.6   mycroft 	}
   2558  1.6   mycroft 	else {
   2559  1.9  explorer 		STAILQ_INSERT_HEAD(&ahc->free_scbs, scb, links);
   2560  1.9  explorer 		if(!scb->links.stqe_next && !ahc->page_scbs.stqh_first)
   2561  1.6   mycroft 			/*
   2562  1.6   mycroft 			 * If there were no SCBs availible, wake anybody waiting
   2563  1.6   mycroft 			 * for one to come free.
   2564  1.6   mycroft 			 */
   2565  1.6   mycroft 			wakeup((caddr_t)&ahc->free_scbs);
   2566  1.6   mycroft 	}
   2567  1.9  explorer #ifdef AHC_DEBUG
   2568  1.9  explorer 	ahc->activescbs--;
   2569  1.9  explorer #endif
   2570  1.6   mycroft 	splx(opri);
   2571  1.1   mycroft }
   2572  1.1   mycroft 
   2573  1.1   mycroft /*
   2574  1.6   mycroft  * Get a free scb, either one already assigned to a hardware slot
   2575  1.6   mycroft  * on the adapter or one that will require an SCB to be paged out before
   2576  1.6   mycroft  * use. If there are none, see if we can allocate a new SCB.  Otherwise
   2577  1.6   mycroft  * either return an error or sleep.
   2578  1.1   mycroft  */
   2579  1.6   mycroft static struct scb *
   2580  1.1   mycroft ahc_get_scb(ahc, flags)
   2581  1.6   mycroft         struct	ahc_data *ahc;
   2582  1.6   mycroft         int	flags;
   2583  1.1   mycroft {
   2584  1.6   mycroft 	unsigned opri;
   2585  1.6   mycroft 	struct scb *scbp;
   2586  1.1   mycroft 
   2587  1.6   mycroft 	opri = splbio();
   2588  1.1   mycroft 	/*
   2589  1.1   mycroft 	 * If we can and have to, sleep waiting for one to come free
   2590  1.1   mycroft 	 * but only if we can't allocate a new one.
   2591  1.1   mycroft 	 */
   2592  1.6   mycroft 	while (1) {
   2593  1.9  explorer 		if((scbp = ahc->free_scbs.stqh_first)) {
   2594  1.9  explorer 			STAILQ_REMOVE_HEAD(&ahc->free_scbs, links);
   2595  1.6   mycroft 		}
   2596  1.9  explorer 		else if((scbp = ahc->page_scbs.stqh_first)) {
   2597  1.9  explorer 			STAILQ_REMOVE_HEAD(&ahc->page_scbs, links);
   2598  1.6   mycroft 		}
   2599  1.9  explorer 		else if(ahc->numscbs < ahc->maxscbs) {
   2600  1.6   mycroft 			scbp = (struct scb *) malloc(sizeof(struct scb),
   2601  1.6   mycroft 				M_TEMP, M_NOWAIT);
   2602  1.6   mycroft 			if (scbp) {
   2603  1.6   mycroft 				bzero(scbp, sizeof(struct scb));
   2604  1.6   mycroft 				scbp->tag = ahc->numscbs;
   2605  1.6   mycroft 				if( ahc->numscbs < ahc->maxhscbs )
   2606  1.6   mycroft 					scbp->position = ahc->numscbs;
   2607  1.6   mycroft 				else
   2608  1.6   mycroft 					scbp->position = SCB_LIST_NULL;
   2609  1.6   mycroft 				ahc->numscbs++;
   2610  1.6   mycroft 				/*
   2611  1.6   mycroft 				 * Place in the scbarray
   2612  1.6   mycroft 				 * Never is removed.
   2613  1.6   mycroft 				 */
   2614  1.6   mycroft 				ahc->scbarray[scbp->tag] = scbp;
   2615  1.6   mycroft 			}
   2616  1.6   mycroft 			else {
   2617  1.6   mycroft 				printf("%s: Can't malloc SCB\n",
   2618  1.6   mycroft 				       ahc_name(ahc));
   2619  1.6   mycroft 			}
   2620  1.1   mycroft 		}
   2621  1.6   mycroft 		else {
   2622  1.6   mycroft 			if (!(flags & SCSI_NOSLEEP)) {
   2623  1.6   mycroft 				tsleep((caddr_t)&ahc->free_scbs, PRIBIO,
   2624  1.6   mycroft 					"ahcscb", 0);
   2625  1.6   mycroft 				continue;
   2626  1.1   mycroft 			}
   2627  1.1   mycroft 		}
   2628  1.6   mycroft 		break;
   2629  1.1   mycroft 	}
   2630  1.1   mycroft 
   2631  1.9  explorer #ifdef AHC_DEBUG
   2632  1.6   mycroft 	if (scbp) {
   2633  1.6   mycroft 		ahc->activescbs++;
   2634  1.6   mycroft 		if((ahc_debug & AHC_SHOWSCBCNT)
   2635  1.6   mycroft 		  && (ahc->activescbs == ahc->maxhscbs))
   2636  1.6   mycroft 			printf("%s: Max SCBs active\n", ahc_name(ahc));
   2637  1.9  explorer 	}
   2638  1.1   mycroft #endif
   2639  1.6   mycroft 
   2640  1.6   mycroft 	splx(opri);
   2641  1.1   mycroft 
   2642  1.6   mycroft 	return (scbp);
   2643  1.1   mycroft }
   2644  1.1   mycroft 
   2645  1.6   mycroft static void ahc_loadseq(ahc)
   2646  1.6   mycroft 	struct ahc_data *ahc;
   2647  1.1   mycroft {
   2648  1.9  explorer         static u_char seqprog[] = {
   2649  1.1   mycroft #               include "aic7xxx_seq.h"
   2650  1.1   mycroft 	};
   2651  1.1   mycroft 
   2652  1.6   mycroft 	AHC_OUTB(ahc, SEQCTL, PERRORDIS|SEQRESET|LOADRAM);
   2653  1.6   mycroft 
   2654  1.6   mycroft 	AHC_OUTSB(ahc, SEQRAM, seqprog, sizeof(seqprog));
   2655  1.6   mycroft 
   2656  1.6   mycroft 	do {
   2657  1.6   mycroft 		AHC_OUTB(ahc, SEQCTL, SEQRESET|FASTMODE);
   2658  1.9  explorer 	} while((AHC_INB(ahc, SEQADDR0) != 0)
   2659  1.9  explorer 		|| (AHC_INB(ahc, SEQADDR1) != 0));
   2660  1.1   mycroft }
   2661  1.1   mycroft 
   2662  1.1   mycroft /*
   2663  1.6   mycroft  * Function to poll for command completion when
   2664  1.6   mycroft  * interrupts are disabled (crash dumps)
   2665  1.1   mycroft  */
   2666  1.6   mycroft static int
   2667  1.6   mycroft ahc_poll(ahc, wait)
   2668  1.6   mycroft 	struct	ahc_data *ahc;
   2669  1.6   mycroft 	int	wait; /* in msec */
   2670  1.6   mycroft {
   2671  1.6   mycroft 	while (--wait) {
   2672  1.6   mycroft 		DELAY(1000);
   2673  1.6   mycroft 		if (AHC_INB(ahc, INTSTAT) & INT_PEND)
   2674  1.6   mycroft 			break;
   2675  1.6   mycroft 	} if (wait == 0) {
   2676  1.9  explorer 		printf("%s: board is not responding\n", ahc_name(ahc));
   2677  1.6   mycroft 		return (EIO);
   2678  1.6   mycroft 	}
   2679  1.6   mycroft 	ahc_intr((void *)ahc);
   2680  1.6   mycroft 	return (0);
   2681  1.6   mycroft }
   2682  1.6   mycroft 
   2683  1.6   mycroft static void
   2684  1.6   mycroft ahc_timeout(arg)
   2685  1.6   mycroft 	void	*arg;
   2686  1.6   mycroft {
   2687  1.6   mycroft 	struct	scb *scb = (struct scb *)arg;
   2688  1.6   mycroft 	struct	ahc_data *ahc;
   2689  1.9  explorer 	int	s, found;
   2690  1.6   mycroft 	u_char	bus_state;
   2691  1.6   mycroft 	char	channel;
   2692  1.6   mycroft 
   2693  1.6   mycroft 	s = splbio();
   2694  1.6   mycroft 
   2695  1.6   mycroft 	if (!(scb->flags & SCB_ACTIVE)) {
   2696  1.6   mycroft 		/* Previous timeout took care of me already */
   2697  1.6   mycroft 		splx(s);
   2698  1.6   mycroft 		return;
   2699  1.6   mycroft 	}
   2700  1.6   mycroft 
   2701  1.6   mycroft 	ahc = (struct ahc_data *)scb->xs->sc_link->adapter_softc;
   2702  1.6   mycroft 
   2703  1.6   mycroft 	if (ahc->in_timeout) {
   2704  1.6   mycroft 		/*
   2705  1.6   mycroft 		 * Some other SCB has started a recovery operation
   2706  1.6   mycroft 		 * and is still working on cleaning things up.
   2707  1.6   mycroft 		 */
   2708  1.6   mycroft 		if (scb->flags & SCB_TIMEDOUT) {
   2709  1.6   mycroft 			/*
   2710  1.6   mycroft 			 * This SCB has been here before and is not the
   2711  1.6   mycroft 			 * recovery SCB. Cut our losses and panic.  Its
   2712  1.6   mycroft 			 * better to do this than trash a filesystem.
   2713  1.6   mycroft 			 */
   2714  1.6   mycroft 			panic("%s: Timed-out command times out "
   2715  1.6   mycroft 				"again\n", ahc_name(ahc));
   2716  1.6   mycroft 		}
   2717  1.6   mycroft 		else if (!(scb->flags & SCB_ABORTED))
   2718  1.6   mycroft 		{
   2719  1.6   mycroft 			/*
   2720  1.6   mycroft 			 * This is not the SCB that started this timeout
   2721  1.6   mycroft 			 * processing.  Give this scb another lifetime so
   2722  1.6   mycroft 			 * that it can continue once we deal with the
   2723  1.6   mycroft 			 * timeout.
   2724  1.6   mycroft 			 */
   2725  1.6   mycroft 			scb->flags |= SCB_TIMEDOUT;
   2726  1.6   mycroft 			timeout(ahc_timeout, (caddr_t)scb,
   2727  1.6   mycroft 				(scb->xs->timeout * hz) / 1000);
   2728  1.6   mycroft 			splx(s);
   2729  1.6   mycroft 			return;
   2730  1.6   mycroft 		}
   2731  1.6   mycroft 	}
   2732  1.6   mycroft 	ahc->in_timeout = TRUE;
   2733  1.6   mycroft 
   2734  1.6   mycroft 	/*
   2735  1.6   mycroft 	 * Ensure that the card doesn't do anything
   2736  1.6   mycroft 	 * behind our back.
   2737  1.6   mycroft 	 */
   2738  1.6   mycroft 	PAUSE_SEQUENCER(ahc);
   2739  1.6   mycroft 
   2740  1.6   mycroft 	sc_print_addr(scb->xs->sc_link);
   2741  1.6   mycroft 	printf("timed out ");
   2742  1.6   mycroft 	/*
   2743  1.6   mycroft 	 * Take a snapshot of the bus state and print out
   2744  1.6   mycroft 	 * some information so we can track down driver bugs.
   2745  1.6   mycroft 	 */
   2746  1.6   mycroft 	bus_state = AHC_INB(ahc, LASTPHASE);
   2747  1.6   mycroft 
   2748  1.6   mycroft 	switch(bus_state & PHASE_MASK)
   2749  1.6   mycroft 	{
   2750  1.6   mycroft 		case P_DATAOUT:
   2751  1.6   mycroft 			printf("in dataout phase");
   2752  1.6   mycroft 			break;
   2753  1.6   mycroft 		case P_DATAIN:
   2754  1.6   mycroft 			printf("in datain phase");
   2755  1.6   mycroft 			break;
   2756  1.6   mycroft 		case P_COMMAND:
   2757  1.6   mycroft 			printf("in command phase");
   2758  1.6   mycroft 			break;
   2759  1.6   mycroft 		case P_MESGOUT:
   2760  1.6   mycroft 			printf("in message out phase");
   2761  1.6   mycroft 			break;
   2762  1.6   mycroft 		case P_STATUS:
   2763  1.6   mycroft 			printf("in status phase");
   2764  1.6   mycroft 			break;
   2765  1.6   mycroft 		case P_MESGIN:
   2766  1.6   mycroft 			printf("in message in phase");
   2767  1.6   mycroft 			break;
   2768  1.6   mycroft 		default:
   2769  1.6   mycroft 			printf("while idle, LASTPHASE == 0x%x",
   2770  1.6   mycroft 				bus_state);
   2771  1.6   mycroft 			/*
   2772  1.6   mycroft 			 * We aren't in a valid phase, so assume we're
   2773  1.6   mycroft 			 * idle.
   2774  1.6   mycroft 			 */
   2775  1.6   mycroft 			bus_state = 0;
   2776  1.6   mycroft 			break;
   2777  1.6   mycroft 	}
   2778  1.6   mycroft 
   2779  1.6   mycroft 	printf(", SCSISIGI == 0x%x\n", AHC_INB(ahc, SCSISIGI));
   2780  1.6   mycroft 
   2781  1.6   mycroft 	/* Decide our course of action */
   2782  1.6   mycroft 
   2783  1.6   mycroft 	if(scb->flags & SCB_ABORTED)
   2784  1.6   mycroft 	{
   2785  1.6   mycroft 		/*
   2786  1.6   mycroft 		 * Been down this road before.
   2787  1.6   mycroft 		 * Do a full bus reset.
   2788  1.6   mycroft 		 */
   2789  1.6   mycroft 		char channel = (scb->tcl & SELBUSB)
   2790  1.6   mycroft 			   ? 'B': 'A';
   2791  1.6   mycroft 		found = ahc_reset_channel(ahc, channel, scb->tag,
   2792  1.6   mycroft 					  XS_TIMEOUT, /*Initiate Reset*/TRUE);
   2793  1.6   mycroft 		printf("%s: Issued Channel %c Bus Reset #1. "
   2794  1.6   mycroft 		       "%d SCBs aborted\n", ahc_name(ahc), channel, found);
   2795  1.6   mycroft 		ahc->in_timeout = FALSE;
   2796  1.6   mycroft 	}
   2797  1.6   mycroft 	else if(scb->control & TAG_ENB) {
   2798  1.6   mycroft 		/*
   2799  1.6   mycroft 		 * We could be starving this command
   2800  1.6   mycroft 		 * try sending an ordered tag command
   2801  1.6   mycroft 		 * to the target we come from.
   2802  1.6   mycroft 		 */
   2803  1.6   mycroft 		scb->flags |= SCB_ABORTED|SCB_SENTORDEREDTAG;
   2804  1.6   mycroft 		ahc->orderedtag |= 0xFF;
   2805  1.6   mycroft 		timeout(ahc_timeout, (caddr_t)scb, (5 * hz));
   2806  1.6   mycroft 		UNPAUSE_SEQUENCER(ahc);
   2807  1.6   mycroft 		printf("Ordered Tag queued\n");
   2808  1.6   mycroft 		goto done;
   2809  1.6   mycroft 	}
   2810  1.6   mycroft 	else {
   2811  1.6   mycroft 		/*
   2812  1.6   mycroft 		 * Send a Bus Device Reset Message:
   2813  1.6   mycroft 		 * The target that is holding up the bus may not
   2814  1.6   mycroft 		 * be the same as the one that triggered this timeout
   2815  1.6   mycroft 		 * (different commands have different timeout lengths).
   2816  1.6   mycroft 		 * It is also impossible to get a message to a target
   2817  1.6   mycroft 		 * if we are in a "frozen" data transfer phase.  Our
   2818  1.6   mycroft 		 * strategy here is to queue a bus device reset message
   2819  1.6   mycroft 		 * to the timed out target if it is disconnected.
   2820  1.6   mycroft 		 * Otherwise, if we have an active target we stuff the
   2821  1.6   mycroft 		 * message buffer with a bus device reset message and
   2822  1.6   mycroft 		 * assert ATN in the hopes that the target will let go
   2823  1.6   mycroft 		 * of the bus and finally disconnect.  If this fails,
   2824  1.6   mycroft 		 * we'll get another timeout 2 seconds later which will
   2825  1.6   mycroft 		 * cause a bus reset.
   2826  1.6   mycroft 		 *
   2827  1.6   mycroft 		 * XXX If the SCB is paged out, we simply reset the
   2828  1.6   mycroft 		 *     bus.  We should probably queue a new command
   2829  1.6   mycroft 		 *     instead.
   2830  1.6   mycroft 		 */
   2831  1.6   mycroft 
   2832  1.6   mycroft 		/* Test to see if scb is disconnected */
   2833  1.6   mycroft 		if( !(scb->flags & SCB_PAGED_OUT ) ){
   2834  1.6   mycroft 			u_char active_scb;
   2835  1.6   mycroft 			struct scb *active_scbp;
   2836  1.6   mycroft 
   2837  1.6   mycroft 			active_scb = AHC_INB(ahc, SCBPTR);
   2838  1.6   mycroft 			active_scbp = ahc->scbarray[AHC_INB(ahc, SCB_TAG)];
   2839  1.6   mycroft 			AHC_OUTB(ahc, SCBPTR, scb->position);
   2840  1.1   mycroft 
   2841  1.6   mycroft 			if(AHC_INB(ahc, SCB_CONTROL) & DISCONNECTED) {
   2842  1.6   mycroft 				if(ahc->flags & AHC_PAGESCBS) {
   2843  1.6   mycroft 					/*
   2844  1.6   mycroft 					 * Pull this SCB out of the
   2845  1.6   mycroft 					 * disconnected list.
   2846  1.6   mycroft 					 */
   2847  1.6   mycroft 					u_char prev = AHC_INB(ahc, SCB_PREV);
   2848  1.6   mycroft 					u_char next = AHC_INB(ahc, SCB_NEXT);
   2849  1.6   mycroft 					if(prev == SCB_LIST_NULL) {
   2850  1.6   mycroft 						/* At the head */
   2851  1.6   mycroft 						AHC_OUTB(ahc, DISCONNECTED_SCBH,
   2852  1.6   mycroft 						     next );
   2853  1.6   mycroft 					}
   2854  1.6   mycroft 					else {
   2855  1.6   mycroft 						AHC_OUTB(ahc, SCBPTR, prev);
   2856  1.6   mycroft 						AHC_OUTB(ahc, SCB_NEXT, next);
   2857  1.6   mycroft 						if(next != SCB_LIST_NULL) {
   2858  1.6   mycroft 							AHC_OUTB(ahc, SCBPTR,
   2859  1.6   mycroft 							     next);
   2860  1.6   mycroft 							AHC_OUTB(ahc, SCB_PREV,
   2861  1.6   mycroft 							     prev);
   2862  1.6   mycroft 						}
   2863  1.6   mycroft 						AHC_OUTB(ahc, SCBPTR,
   2864  1.6   mycroft 						     scb->position);
   2865  1.6   mycroft 					}
   2866  1.6   mycroft 				}
   2867  1.6   mycroft 				scb->flags |= SCB_DEVICE_RESET|SCB_ABORTED;
   2868  1.6   mycroft 				scb->control &= DISCENB;
   2869  1.6   mycroft 				scb->cmdlen = 0;
   2870  1.6   mycroft 				scb->SG_segment_count = 0;
   2871  1.6   mycroft 				scb->SG_list_pointer = 0;
   2872  1.6   mycroft 				scb->data = 0;
   2873  1.6   mycroft 				scb->datalen = 0;
   2874  1.6   mycroft 				ahc_send_scb(ahc, scb);
   2875  1.6   mycroft 				ahc_add_waiting_scb(ahc, scb);
   2876  1.6   mycroft 				timeout(ahc_timeout, (caddr_t)scb, (2 * hz));
   2877  1.6   mycroft 				sc_print_addr(scb->xs->sc_link);
   2878  1.6   mycroft 				printf("BUS DEVICE RESET message queued.\n");
   2879  1.6   mycroft 				AHC_OUTB(ahc, SCBPTR, active_scb);
   2880  1.6   mycroft 				UNPAUSE_SEQUENCER(ahc);
   2881  1.6   mycroft 				goto done;
   2882  1.6   mycroft 			}
   2883  1.6   mycroft 			/* Is the active SCB really active? */
   2884  1.6   mycroft 			else if((active_scbp->flags & SCB_ACTIVE) && bus_state){
   2885  1.6   mycroft 				AHC_OUTB(ahc, MSG_LEN, 1);
   2886  1.6   mycroft 				AHC_OUTB(ahc, MSG0, MSG_BUS_DEVICE_RESET);
   2887  1.6   mycroft 				AHC_OUTB(ahc, SCSISIGO, bus_state|ATNO);
   2888  1.6   mycroft 				sc_print_addr(active_scbp->xs->sc_link);
   2889  1.6   mycroft 				printf("asserted ATN - device reset in "
   2890  1.6   mycroft 				       "message buffer\n");
   2891  1.6   mycroft 				active_scbp->flags |=   SCB_DEVICE_RESET
   2892  1.6   mycroft 						      | SCB_ABORTED;
   2893  1.6   mycroft 				if(active_scbp != scb) {
   2894  1.6   mycroft 					untimeout(ahc_timeout,
   2895  1.6   mycroft 						  (caddr_t)active_scbp);
   2896  1.6   mycroft 					/* Give scb a new lease on life */
   2897  1.6   mycroft 					timeout(ahc_timeout, (caddr_t)scb,
   2898  1.6   mycroft 						(scb->xs->timeout * hz) / 1000);
   2899  1.6   mycroft 				}
   2900  1.6   mycroft 				timeout(ahc_timeout, (caddr_t)active_scbp,
   2901  1.6   mycroft 					(2 * hz));
   2902  1.6   mycroft 				AHC_OUTB(ahc, SCBPTR, active_scb);
   2903  1.6   mycroft 				UNPAUSE_SEQUENCER(ahc);
   2904  1.6   mycroft 				goto done;
   2905  1.6   mycroft 			}
   2906  1.6   mycroft 		}
   2907  1.1   mycroft 		/*
   2908  1.6   mycroft 		 * No active target or a paged out SCB.
   2909  1.6   mycroft 		 * Try reseting the bus.
   2910  1.1   mycroft 		 */
   2911  1.6   mycroft 		channel = (scb->tcl & SELBUSB) ? 'B': 'A';
   2912  1.6   mycroft 		found = ahc_reset_channel(ahc, channel, scb->tag,
   2913  1.6   mycroft 					  XS_TIMEOUT,
   2914  1.6   mycroft 					  /*Initiate Reset*/TRUE);
   2915  1.6   mycroft 		printf("%s: Issued Channel %c Bus Reset #2. "
   2916  1.6   mycroft 			"%d SCBs aborted\n", ahc_name(ahc), channel,
   2917  1.6   mycroft 			found);
   2918  1.6   mycroft 		ahc->in_timeout = FALSE;
   2919  1.1   mycroft 	}
   2920  1.6   mycroft done:
   2921  1.6   mycroft 	splx(s);
   2922  1.1   mycroft }
   2923  1.1   mycroft 
   2924  1.6   mycroft 
   2925  1.6   mycroft /*
   2926  1.6   mycroft  * The device at the given target/channel has been reset.  Abort
   2927  1.6   mycroft  * all active and queued scbs for that target/channel.
   2928  1.6   mycroft  */
   2929  1.6   mycroft static int
   2930  1.6   mycroft ahc_reset_device(ahc, target, channel, timedout_scb, xs_error)
   2931  1.6   mycroft 	struct ahc_data *ahc;
   2932  1.6   mycroft 	int target;
   2933  1.6   mycroft 	char channel;
   2934  1.6   mycroft 	u_char timedout_scb;
   2935  1.6   mycroft 	u_int32_t xs_error;
   2936  1.1   mycroft {
   2937  1.6   mycroft         struct scb *scbp;
   2938  1.6   mycroft 	u_char active_scb;
   2939  1.6   mycroft 	int i = 0;
   2940  1.1   mycroft 	int found = 0;
   2941  1.1   mycroft 
   2942  1.6   mycroft 	/* restore this when we're done */
   2943  1.6   mycroft 	active_scb = AHC_INB(ahc, SCBPTR);
   2944  1.6   mycroft 
   2945  1.1   mycroft 	/*
   2946  1.6   mycroft 	 * Search the QINFIFO.
   2947  1.1   mycroft 	 */
   2948  1.1   mycroft 	{
   2949  1.9  explorer 		u_char saved_queue[AHC_SCB_MAX];
   2950  1.9  explorer 		u_char queued = AHC_INB(ahc, QINCNT) & ahc->qcntmask;
   2951  1.1   mycroft 
   2952  1.1   mycroft 		for (i = 0; i < (queued - found); i++) {
   2953  1.6   mycroft 			saved_queue[i] = AHC_INB(ahc, QINFIFO);
   2954  1.6   mycroft 			AHC_OUTB(ahc, SCBPTR, saved_queue[i]);
   2955  1.6   mycroft 			scbp = ahc->scbarray[AHC_INB(ahc, SCB_TAG)];
   2956  1.6   mycroft 			if (ahc_match_scb (scbp, target, channel)){
   2957  1.6   mycroft 				/*
   2958  1.6   mycroft 				 * We found an scb that needs to be aborted.
   2959  1.6   mycroft 				 */
   2960  1.6   mycroft 				scbp->flags = SCB_ABORTED|SCB_QUEUED_FOR_DONE;
   2961  1.6   mycroft 				scbp->xs->error |= xs_error;
   2962  1.6   mycroft 				if(scbp->position != timedout_scb)
   2963  1.6   mycroft 					untimeout(ahc_timeout, (caddr_t)scbp);
   2964  1.6   mycroft 				AHC_OUTB(ahc, SCB_CONTROL, 0);
   2965  1.1   mycroft 				i--;
   2966  1.6   mycroft 				found++;
   2967  1.1   mycroft 			}
   2968  1.1   mycroft 		}
   2969  1.6   mycroft 		/* Now put the saved scbs back. */
   2970  1.6   mycroft 		for (queued = 0; queued < i; queued++) {
   2971  1.6   mycroft 			AHC_OUTB(ahc, QINFIFO, saved_queue[queued]);
   2972  1.6   mycroft 		}
   2973  1.6   mycroft 	}
   2974  1.1   mycroft 
   2975  1.6   mycroft 	/*
   2976  1.6   mycroft 	 * Search waiting for selection list.
   2977  1.6   mycroft 	 */
   2978  1.6   mycroft 	{
   2979  1.6   mycroft 		u_char next, prev;
   2980  1.6   mycroft 
   2981  1.6   mycroft 		next = AHC_INB(ahc, WAITING_SCBH);  /* Start at head of list. */
   2982  1.6   mycroft 		prev = SCB_LIST_NULL;
   2983  1.6   mycroft 
   2984  1.6   mycroft 		while (next != SCB_LIST_NULL) {
   2985  1.6   mycroft 			AHC_OUTB(ahc, SCBPTR, next);
   2986  1.6   mycroft 			scbp = ahc->scbarray[AHC_INB(ahc, SCB_TAG)];
   2987  1.6   mycroft 			/*
   2988  1.6   mycroft 			 * Select the SCB.
   2989  1.6   mycroft 			 */
   2990  1.6   mycroft 			if (ahc_match_scb(scbp, target, channel)) {
   2991  1.6   mycroft 				next = ahc_abort_wscb(ahc, scbp, prev,
   2992  1.6   mycroft 						timedout_scb, xs_error);
   2993  1.6   mycroft 				found++;
   2994  1.6   mycroft 			}
   2995  1.6   mycroft 			else {
   2996  1.6   mycroft 				prev = next;
   2997  1.6   mycroft 				next = AHC_INB(ahc, SCB_NEXT);
   2998  1.6   mycroft 			}
   2999  1.6   mycroft 		}
   3000  1.1   mycroft 	}
   3001  1.1   mycroft 	/*
   3002  1.6   mycroft 	 * Go through the entire SCB array now and look for
   3003  1.6   mycroft 	 * commands for this target that are active.  These
   3004  1.6   mycroft 	 * are other (most likely tagged) commands that
   3005  1.6   mycroft 	 * were disconnected when the reset occured.
   3006  1.6   mycroft 	 */
   3007  1.6   mycroft 	for(i = 0; i < ahc->numscbs; i++) {
   3008  1.6   mycroft 		scbp = ahc->scbarray[i];
   3009  1.6   mycroft 		if((scbp->flags & SCB_ACTIVE)
   3010  1.6   mycroft 		  && ahc_match_scb(scbp, target, channel)) {
   3011  1.6   mycroft 			/* Ensure the target is "free" */
   3012  1.6   mycroft 			ahc_unbusy_target(ahc, target, channel);
   3013  1.6   mycroft 			if( !(scbp->flags & SCB_PAGED_OUT) )
   3014  1.6   mycroft 			{
   3015  1.6   mycroft 				AHC_OUTB(ahc, SCBPTR, scbp->position);
   3016  1.6   mycroft 				AHC_OUTB(ahc, SCB_CONTROL, 0);
   3017  1.6   mycroft 			}
   3018  1.6   mycroft 			scbp->flags = SCB_ABORTED|SCB_QUEUED_FOR_DONE;
   3019  1.6   mycroft 			scbp->xs->error |= xs_error;
   3020  1.6   mycroft 			if(scbp->tag != timedout_scb)
   3021  1.6   mycroft 				untimeout(ahc_timeout, (caddr_t)scbp);
   3022  1.6   mycroft 			found++;
   3023  1.6   mycroft 		}
   3024  1.6   mycroft 	}
   3025  1.6   mycroft 	AHC_OUTB(ahc, SCBPTR, active_scb);
   3026  1.6   mycroft 	return found;
   3027  1.6   mycroft }
   3028  1.6   mycroft 
   3029  1.6   mycroft /*
   3030  1.6   mycroft  * Manipulate the waiting for selection list and return the
   3031  1.6   mycroft  * scb that follows the one that we remove.
   3032  1.6   mycroft  */
   3033  1.6   mycroft static u_char
   3034  1.6   mycroft ahc_abort_wscb (ahc, scbp, prev, timedout_scb, xs_error)
   3035  1.6   mycroft 	struct ahc_data *ahc;
   3036  1.6   mycroft         struct scb *scbp;
   3037  1.6   mycroft 	u_char prev;
   3038  1.6   mycroft 	u_char timedout_scb;
   3039  1.6   mycroft 	u_int32_t xs_error;
   3040  1.6   mycroft {
   3041  1.6   mycroft 	u_char curscbp, next;
   3042  1.6   mycroft 	int target = ((scbp->tcl >> 4) & 0x0f);
   3043  1.6   mycroft 	char channel = (scbp->tcl & SELBUSB) ? 'B' : 'A';
   3044  1.6   mycroft 	/*
   3045  1.6   mycroft 	 * Select the SCB we want to abort and
   3046  1.6   mycroft 	 * pull the next pointer out of it.
   3047  1.6   mycroft 	 */
   3048  1.6   mycroft 	curscbp = AHC_INB(ahc, SCBPTR);
   3049  1.6   mycroft 	AHC_OUTB(ahc, SCBPTR, scbp->position);
   3050  1.6   mycroft 	next = AHC_INB(ahc, SCB_NEXT);
   3051  1.6   mycroft 
   3052  1.6   mycroft 	/* Clear the necessary fields */
   3053  1.6   mycroft 	AHC_OUTB(ahc, SCB_CONTROL, 0);
   3054  1.6   mycroft 	AHC_OUTB(ahc, SCB_NEXT, SCB_LIST_NULL);
   3055  1.6   mycroft 	ahc_unbusy_target(ahc, target, channel);
   3056  1.6   mycroft 
   3057  1.6   mycroft 	/* update the waiting list */
   3058  1.6   mycroft 	if( prev == SCB_LIST_NULL )
   3059  1.6   mycroft 		/* First in the list */
   3060  1.6   mycroft 		AHC_OUTB(ahc, WAITING_SCBH, next);
   3061  1.6   mycroft 	else {
   3062  1.1   mycroft 		/*
   3063  1.6   mycroft 		 * Select the scb that pointed to us
   3064  1.6   mycroft 		 * and update its next pointer.
   3065  1.1   mycroft 		 */
   3066  1.6   mycroft 		AHC_OUTB(ahc, SCBPTR, prev);
   3067  1.6   mycroft 		AHC_OUTB(ahc, SCB_NEXT, next);
   3068  1.1   mycroft 	}
   3069  1.1   mycroft 	/*
   3070  1.6   mycroft 	 * Point us back at the original scb position
   3071  1.6   mycroft 	 * and inform the SCSI system that the command
   3072  1.6   mycroft 	 * has been aborted.
   3073  1.6   mycroft 	 */
   3074  1.6   mycroft 	AHC_OUTB(ahc, SCBPTR, curscbp);
   3075  1.6   mycroft 	scbp->flags = SCB_ABORTED|SCB_QUEUED_FOR_DONE;
   3076  1.6   mycroft 	scbp->xs->error |= xs_error;
   3077  1.6   mycroft 	if(scbp->tag != timedout_scb)
   3078  1.6   mycroft 		untimeout(ahc_timeout, (caddr_t)scbp);
   3079  1.6   mycroft 	return next;
   3080  1.6   mycroft }
   3081  1.6   mycroft 
   3082  1.6   mycroft static void
   3083  1.6   mycroft ahc_busy_target(ahc, target, channel)
   3084  1.6   mycroft 	struct ahc_data *ahc;
   3085  1.6   mycroft 	u_char target;
   3086  1.6   mycroft 	char   channel;
   3087  1.6   mycroft {
   3088  1.6   mycroft 	u_char active;
   3089  1.6   mycroft 	u_long active_port = ACTIVE_A;
   3090  1.6   mycroft 
   3091  1.6   mycroft 	if(target > 0x07 || channel == 'B') {
   3092  1.6   mycroft 		/*
   3093  1.6   mycroft 		 * targets on the Second channel or
   3094  1.6   mycroft 		 * above id 7 store info in byte two
   3095  1.6   mycroft 		 * of HA_ACTIVE
   3096  1.1   mycroft 		 */
   3097  1.6   mycroft 		active_port++;
   3098  1.6   mycroft 	}
   3099  1.6   mycroft 	active = AHC_INB(ahc, active_port);
   3100  1.6   mycroft 	active |= (0x01 << (target & 0x07));
   3101  1.6   mycroft 	AHC_OUTB(ahc, active_port, active);
   3102  1.6   mycroft }
   3103  1.6   mycroft 
   3104  1.6   mycroft static void
   3105  1.6   mycroft ahc_unbusy_target(ahc, target, channel)
   3106  1.6   mycroft 	struct ahc_data *ahc;
   3107  1.6   mycroft 	u_char target;
   3108  1.6   mycroft 	char   channel;
   3109  1.6   mycroft {
   3110  1.6   mycroft 	u_char active;
   3111  1.6   mycroft 	u_long active_port = ACTIVE_A;
   3112  1.1   mycroft 
   3113  1.6   mycroft 	if(target > 0x07 || channel == 'B') {
   3114  1.6   mycroft 		/*
   3115  1.6   mycroft 		 * targets on the Second channel or
   3116  1.6   mycroft 		 * above id 7 store info in byte two
   3117  1.6   mycroft 		 * of HA_ACTIVE
   3118  1.6   mycroft 		 */
   3119  1.6   mycroft 		active_port++;
   3120  1.1   mycroft 	}
   3121  1.6   mycroft 	active = AHC_INB(ahc, active_port);
   3122  1.6   mycroft 	active &= ~(0x01 << (target & 0x07));
   3123  1.6   mycroft 	AHC_OUTB(ahc, active_port, active);
   3124  1.1   mycroft }
   3125  1.1   mycroft 
   3126  1.6   mycroft static void
   3127  1.6   mycroft ahc_reset_current_bus(ahc)
   3128  1.6   mycroft 	struct ahc_data *ahc;
   3129  1.1   mycroft {
   3130  1.6   mycroft 	AHC_OUTB(ahc, SCSISEQ, SCSIRSTO);
   3131  1.6   mycroft 	DELAY(1000);
   3132  1.6   mycroft 	AHC_OUTB(ahc, SCSISEQ, 0);
   3133  1.6   mycroft }
   3134  1.1   mycroft 
   3135  1.6   mycroft static int
   3136  1.6   mycroft ahc_reset_channel(ahc, channel, timedout_scb, xs_error, initiate_reset)
   3137  1.6   mycroft 	struct ahc_data *ahc;
   3138  1.6   mycroft 	char   channel;
   3139  1.6   mycroft 	u_char timedout_scb;
   3140  1.6   mycroft 	u_int32_t xs_error;
   3141  1.6   mycroft 	u_char initiate_reset;
   3142  1.6   mycroft {
   3143  1.6   mycroft 	u_char sblkctl;
   3144  1.6   mycroft 	char cur_channel;
   3145  1.6   mycroft 	u_long offset, offset_max;
   3146  1.6   mycroft 	int found;
   3147  1.6   mycroft 
   3148  1.6   mycroft 	/*
   3149  1.6   mycroft 	 * Clean up all the state information for the
   3150  1.6   mycroft 	 * pending transactions on this bus.
   3151  1.6   mycroft 	 */
   3152  1.6   mycroft 	found = ahc_reset_device(ahc, ALL_TARGETS, channel,
   3153  1.6   mycroft 				 timedout_scb, xs_error);
   3154  1.6   mycroft 	if(channel == 'B'){
   3155  1.6   mycroft 		ahc->needsdtr |= (ahc->needsdtr_orig & 0xff00);
   3156  1.6   mycroft 		ahc->sdtrpending &= 0x00ff;
   3157  1.6   mycroft 		AHC_OUTB(ahc, ACTIVE_B, 0);
   3158  1.6   mycroft 		offset = TARG_SCRATCH + 8;
   3159  1.6   mycroft 		offset_max = TARG_SCRATCH + 16;
   3160  1.6   mycroft 	}
   3161  1.6   mycroft 	else if (ahc->type & AHC_WIDE){
   3162  1.6   mycroft 		ahc->needsdtr = ahc->needsdtr_orig;
   3163  1.6   mycroft 		ahc->needwdtr = ahc->needwdtr_orig;
   3164  1.6   mycroft 		ahc->sdtrpending = 0;
   3165  1.6   mycroft 		ahc->wdtrpending = 0;
   3166  1.6   mycroft 		AHC_OUTB(ahc, ACTIVE_A, 0);
   3167  1.6   mycroft 		AHC_OUTB(ahc, ACTIVE_B, 0);
   3168  1.6   mycroft 		offset = TARG_SCRATCH;
   3169  1.6   mycroft 		offset_max = TARG_SCRATCH + 16;
   3170  1.6   mycroft 	}
   3171  1.6   mycroft 	else{
   3172  1.6   mycroft 		ahc->needsdtr |= (ahc->needsdtr_orig & 0x00ff);
   3173  1.6   mycroft 		ahc->sdtrpending &= 0xff00;
   3174  1.6   mycroft 		AHC_OUTB(ahc, ACTIVE_A, 0);
   3175  1.6   mycroft 		offset = TARG_SCRATCH;
   3176  1.6   mycroft 		offset_max = TARG_SCRATCH + 8;
   3177  1.6   mycroft 	}
   3178  1.6   mycroft 	for(;offset < offset_max;offset++) {
   3179  1.6   mycroft 		/*
   3180  1.6   mycroft 		 * Revert to async/narrow transfers
   3181  1.6   mycroft 		 * until we renegotiate.
   3182  1.6   mycroft 		 */
   3183  1.6   mycroft 		u_char targ_scratch;
   3184  1.1   mycroft 
   3185  1.6   mycroft 		targ_scratch = AHC_INB(ahc, offset);
   3186  1.6   mycroft 		targ_scratch &= SXFR;
   3187  1.6   mycroft 		AHC_OUTB(ahc, offset, targ_scratch);
   3188  1.6   mycroft 	}
   3189  1.1   mycroft 
   3190  1.6   mycroft 	/*
   3191  1.6   mycroft 	 * Reset the bus if we are initiating this reset and
   3192  1.6   mycroft 	 * restart/unpause the sequencer
   3193  1.6   mycroft 	 */
   3194  1.6   mycroft 	/* Case 1: Command for another bus is active */
   3195  1.6   mycroft 	sblkctl = AHC_INB(ahc, SBLKCTL);
   3196  1.6   mycroft 	cur_channel = (sblkctl & SELBUSB) ? 'B' : 'A';
   3197  1.6   mycroft 	if(cur_channel != channel)
   3198  1.6   mycroft 	{
   3199  1.6   mycroft 		/*
   3200  1.6   mycroft 		 * Stealthily reset the other bus
   3201  1.6   mycroft 		 * without upsetting the current bus
   3202  1.6   mycroft 		 */
   3203  1.6   mycroft 		AHC_OUTB(ahc, SBLKCTL, sblkctl ^ SELBUSB);
   3204  1.6   mycroft 		if( initiate_reset )
   3205  1.6   mycroft 		{
   3206  1.6   mycroft 			ahc_reset_current_bus(ahc);
   3207  1.6   mycroft 		}
   3208  1.6   mycroft 		AHC_OUTB(ahc, CLRSINT1, CLRSCSIRSTI|CLRSELTIMEO);
   3209  1.6   mycroft 		AHC_OUTB(ahc, CLRINT, CLRSCSIINT);
   3210  1.6   mycroft 		AHC_OUTB(ahc, SBLKCTL, sblkctl);
   3211  1.6   mycroft 		UNPAUSE_SEQUENCER(ahc);
   3212  1.6   mycroft 	}
   3213  1.6   mycroft 	/* Case 2: A command from this bus is active or we're idle */
   3214  1.6   mycroft 	else {
   3215  1.6   mycroft 		if( initiate_reset )
   3216  1.6   mycroft 		{
   3217  1.6   mycroft 			ahc_reset_current_bus(ahc);
   3218  1.6   mycroft 		}
   3219  1.6   mycroft 		AHC_OUTB(ahc, CLRSINT1, CLRSCSIRSTI|CLRSELTIMEO);
   3220  1.6   mycroft 		AHC_OUTB(ahc, CLRINT, CLRSCSIINT);
   3221  1.6   mycroft 		RESTART_SEQUENCER(ahc);
   3222  1.1   mycroft 	}
   3223  1.6   mycroft 	ahc_run_done_queue(ahc);
   3224  1.6   mycroft 	return found;
   3225  1.6   mycroft }
   3226  1.1   mycroft 
   3227  1.6   mycroft void
   3228  1.6   mycroft ahc_run_done_queue(ahc)
   3229  1.6   mycroft 	struct ahc_data *ahc;
   3230  1.6   mycroft {
   3231  1.6   mycroft 	int i;
   3232  1.6   mycroft 	struct scb *scbp;
   3233  1.6   mycroft 
   3234  1.6   mycroft 	for(i = 0; i < ahc->numscbs; i++) {
   3235  1.6   mycroft 		scbp = ahc->scbarray[i];
   3236  1.6   mycroft 		if(scbp->flags & SCB_QUEUED_FOR_DONE)
   3237  1.6   mycroft 			ahc_done(ahc, scbp);
   3238  1.1   mycroft 	}
   3239  1.6   mycroft }
   3240  1.6   mycroft 
   3241  1.6   mycroft static int
   3242  1.6   mycroft ahc_match_scb (scb, target, channel)
   3243  1.6   mycroft         struct scb *scb;
   3244  1.6   mycroft         int target;
   3245  1.6   mycroft 	char channel;
   3246  1.6   mycroft {
   3247  1.6   mycroft 	int targ = (scb->tcl >> 4) & 0x0f;
   3248  1.6   mycroft 	char chan = (scb->tcl & SELBUSB) ? 'B' : 'A';
   3249  1.1   mycroft 
   3250  1.6   mycroft 	if (target == ALL_TARGETS)
   3251  1.6   mycroft 		return (chan == channel);
   3252  1.6   mycroft 	else
   3253  1.6   mycroft 		return ((chan == channel) && (targ == target));
   3254  1.1   mycroft }
   3255