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