Home | History | Annotate | Line # | Download | only in ic
aic7xxx.c revision 1.58
      1  1.58       mrg /*	$NetBSD: aic7xxx.c,v 1.58 2000/06/28 17:12:53 mrg 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.42      fvdl  * i386/eisa/ahc_eisa.c	27/284X and aic7770 motherboard controllers
      7  1.42      fvdl  * pci/ahc_pci.c	3985, 3980, 3940, 2940, aic7895, aic7890,
      8  1.42      fvdl  *			aic7880, aic7870, aic7860, and aic7850 controllers
      9   1.1   mycroft  *
     10  1.42      fvdl  * Copyright (c) 1994, 1995, 1996, 1997, 1998, 1999, 2000 Justin T. Gibbs.
     11   1.6   mycroft  * All rights reserved.
     12   1.1   mycroft  *
     13   1.6   mycroft  * Redistribution and use in source and binary forms, with or without
     14   1.6   mycroft  * modification, are permitted provided that the following conditions
     15   1.6   mycroft  * are met:
     16   1.6   mycroft  * 1. Redistributions of source code must retain the above copyright
     17  1.42      fvdl  *    notice, this list of conditions, and the following disclaimer,
     18  1.42      fvdl  *    without modification.
     19  1.42      fvdl  * 2. The name of the author may not be used to endorse or promote products
     20   1.6   mycroft  *    derived from this software without specific prior written permission.
     21   1.1   mycroft  *
     22  1.42      fvdl  * Alternatively, this software may be distributed under the terms of the
     23  1.42      fvdl  * the GNU Public License ("GPL").
     24  1.42      fvdl  *
     25   1.6   mycroft  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
     26   1.6   mycroft  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     27   1.6   mycroft  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     28   1.6   mycroft  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
     29   1.6   mycroft  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     30   1.6   mycroft  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     31   1.6   mycroft  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     32   1.6   mycroft  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     33   1.6   mycroft  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     34   1.6   mycroft  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     35   1.6   mycroft  * SUCH DAMAGE.
     36   1.9  explorer  *
     37  1.45      fvdl  * $FreeBSD: src/sys/dev/aic7xxx/aic7xxx.c,v 1.42 2000/03/18 22:28:18 gibbs Exp $
     38   1.1   mycroft  */
     39   1.1   mycroft /*
     40  1.42      fvdl  * A few notes on features of the driver.
     41   1.6   mycroft  *
     42   1.6   mycroft  * SCB paging takes advantage of the fact that devices stay disconnected
     43   1.6   mycroft  * from the bus a relatively long time and that while they're disconnected,
     44  1.42      fvdl  * having the SCBs for these transactions down on the host adapter is of
     45  1.42      fvdl  * little use.  Instead of leaving this idle SCB down on the card we copy
     46  1.42      fvdl  * it back up into kernel memory and reuse the SCB slot on the card to
     47  1.42      fvdl  * schedule another transaction.  This can be a real payoff when doing random
     48  1.42      fvdl  * I/O to tagged queueing devices since there are more transactions active at
     49  1.42      fvdl  * once for the device to sort for optimal seek reduction. The algorithm goes
     50  1.42      fvdl  * like this...
     51   1.6   mycroft  *
     52  1.42      fvdl  * The sequencer maintains two lists of its hardware SCBs.  The first is the
     53  1.42      fvdl  * singly linked free list which tracks all SCBs that are not currently in
     54  1.42      fvdl  * use.  The second is the doubly linked disconnected list which holds the
     55  1.42      fvdl  * SCBs of transactions that are in the disconnected state sorted most
     56  1.42      fvdl  * recently disconnected first.  When the kernel queues a transaction to
     57  1.42      fvdl  * the card, a hardware SCB to "house" this transaction is retrieved from
     58  1.42      fvdl  * either of these two lists.  If the SCB came from the disconnected list,
     59  1.42      fvdl  * a check is made to see if any data transfer or SCB linking (more on linking
     60  1.42      fvdl  * in a bit) information has been changed since it was copied from the host
     61  1.42      fvdl  * and if so, DMAs the SCB back up before it can be used.  Once a hardware
     62  1.42      fvdl  * SCB has been obtained, the SCB is DMAed from the host.  Before any work
     63  1.42      fvdl  * can begin on this SCB, the sequencer must ensure that either the SCB is
     64  1.42      fvdl  * for a tagged transaction or the target is not already working on another
     65  1.42      fvdl  * non-tagged transaction.  If a conflict arises in the non-tagged case, the
     66  1.42      fvdl  * sequencer finds the SCB for the active transactions and sets the SCB_LINKED
     67  1.42      fvdl  * field in that SCB to this next SCB to execute.  To facilitate finding
     68  1.42      fvdl  * active non-tagged SCBs, the last four bytes of up to the first four hardware
     69  1.42      fvdl  * SCBs serve as a storage area for the currently active SCB ID for each
     70  1.42      fvdl  * target.
     71   1.6   mycroft  *
     72  1.42      fvdl  * When a device reconnects, a search is made of the hardware SCBs to find
     73  1.42      fvdl  * the SCB for this transaction.  If the search fails, a hardware SCB is
     74  1.42      fvdl  * pulled from either the free or disconnected SCB list and the proper
     75  1.42      fvdl  * SCB is DMAed from the host.  If the MK_MESSAGE control bit is set
     76  1.42      fvdl  * in the control byte of the SCB while it was disconnected, the sequencer
     77  1.42      fvdl  * will assert ATN and attempt to issue a message to the host.
     78   1.6   mycroft  *
     79  1.42      fvdl  * When a command completes, a check for non-zero status and residuals is
     80  1.42      fvdl  * made.  If either of these conditions exists, the SCB is DMAed back up to
     81  1.42      fvdl  * the host so that it can interpret this information.  Additionally, in the
     82  1.42      fvdl  * case of bad status, the sequencer generates a special interrupt and pauses
     83  1.42      fvdl  * itself.  This allows the host to setup a request sense command if it
     84  1.42      fvdl  * chooses for this target synchronously with the error so that sense
     85  1.42      fvdl  * information isn't lost.
     86   1.6   mycroft  *
     87   1.1   mycroft  */
     88   1.1   mycroft 
     89  1.42      fvdl #include "opt_ddb.h"
     90  1.42      fvdl 
     91   1.1   mycroft #include <sys/param.h>
     92  1.42      fvdl #include <sys/kernel.h>
     93   1.1   mycroft #include <sys/systm.h>
     94   1.1   mycroft #include <sys/device.h>
     95   1.1   mycroft #include <sys/malloc.h>
     96   1.1   mycroft #include <sys/buf.h>
     97   1.1   mycroft #include <sys/proc.h>
     98  1.52      fvdl #include <sys/scsiio.h>
     99   1.1   mycroft 
    100  1.42      fvdl #include <machine/bus.h>
    101  1.42      fvdl #include <machine/intr.h>
    102  1.42      fvdl 
    103  1.25    bouyer #include <dev/scsipi/scsi_all.h>
    104  1.25    bouyer #include <dev/scsipi/scsipi_all.h>
    105  1.25    bouyer #include <dev/scsipi/scsi_message.h>
    106  1.25    bouyer #include <dev/scsipi/scsipi_debug.h>
    107  1.25    bouyer #include <dev/scsipi/scsiconf.h>
    108   1.1   mycroft 
    109  1.58       mrg #include <uvm/uvm_extern.h>
    110   1.1   mycroft 
    111   1.6   mycroft #include <dev/ic/aic7xxxvar.h>
    112  1.42      fvdl #include <dev/microcode/aic7xxx/sequencer.h>
    113  1.42      fvdl #include <dev/microcode/aic7xxx/aic7xxx_reg.h>
    114  1.42      fvdl #include <dev/microcode/aic7xxx/aic7xxx_seq.h>
    115  1.42      fvdl 
    116  1.42      fvdl #define MAX(a,b) (((a) > (b)) ? (a) : (b))
    117  1.42      fvdl #define MIN(a,b) (((a) < (b)) ? (a) : (b))
    118  1.42      fvdl #define ALL_CHANNELS '\0'
    119  1.42      fvdl #define ALL_TARGETS_MASK 0xFFFF
    120  1.42      fvdl #define INITIATOR_WILDCARD	(~0)
    121   1.1   mycroft 
    122  1.42      fvdl #define	SIM_IS_SCSIBUS_B(ahc, sc_link)	\
    123  1.42      fvdl 	((sc_link)->scsipi_scsi.scsibus == (ahc)->sc_link_b.scsipi_scsi.scsibus)
    124  1.42      fvdl #define	SIM_CHANNEL(ahc, sc_link)	\
    125  1.42      fvdl 	(SIM_IS_SCSIBUS_B(ahc, sc_link) ? 'B' : 'A')
    126  1.42      fvdl #define	SIM_SCSI_ID(ahc, sc_link)	\
    127  1.42      fvdl 	(SIM_IS_SCSIBUS_B(ahc, sc_link) ? ahc->our_id_b : ahc->our_id)
    128  1.42      fvdl #define	SCB_IS_SCSIBUS_B(scb)	\
    129  1.42      fvdl 	(((scb)->hscb->tcl & SELBUSB) != 0)
    130  1.42      fvdl #define	SCB_TARGET(scb)	\
    131  1.42      fvdl 	(((scb)->hscb->tcl & TID) >> 4)
    132  1.42      fvdl #define	SCB_CHANNEL(scb) \
    133  1.42      fvdl 	(SCB_IS_SCSIBUS_B(scb) ? 'B' : 'A')
    134  1.42      fvdl #define	SCB_LUN(scb)	\
    135  1.42      fvdl 	((scb)->hscb->tcl & LID)
    136  1.42      fvdl #define SCB_TARGET_OFFSET(scb)		\
    137  1.42      fvdl 	(SCB_TARGET(scb) + (SCB_IS_SCSIBUS_B(scb) ? 8 : 0))
    138  1.42      fvdl #define SCB_TARGET_MASK(scb)		\
    139  1.42      fvdl 	(0x01 << (SCB_TARGET_OFFSET(scb)))
    140  1.42      fvdl #define TCL_CHANNEL(ahc, tcl)		\
    141  1.42      fvdl 	((((ahc)->features & AHC_TWIN) && ((tcl) & SELBUSB)) ? 'B' : 'A')
    142  1.42      fvdl #define TCL_SCSI_ID(ahc, tcl)		\
    143  1.42      fvdl 	(TCL_CHANNEL((ahc), (tcl)) == 'B' ? (ahc)->our_id_b : (ahc)->our_id)
    144  1.42      fvdl #define TCL_TARGET(tcl) (((tcl) & TID) >> TCL_TARGET_SHIFT)
    145  1.42      fvdl #define TCL_LUN(tcl) ((tcl) & LID)
    146  1.42      fvdl 
    147  1.42      fvdl #define XS_TCL(ahc, xs) \
    148  1.42      fvdl 	((((xs)->sc_link->scsipi_scsi.target << 4) & 0xF0) \
    149  1.42      fvdl 	    | (SIM_IS_SCSIBUS_B((ahc), (xs)->sc_link) ? SELBUSB : 0) \
    150  1.42      fvdl 	    | ((xs)->sc_link->scsipi_scsi.lun & 0x07))
    151   1.1   mycroft 
    152  1.42      fvdl char *ahc_chip_names[] =
    153  1.42      fvdl {
    154  1.42      fvdl 	"NONE",
    155  1.42      fvdl 	"aic7770",
    156  1.42      fvdl 	"aic7850",
    157  1.42      fvdl 	"aic7855",
    158  1.42      fvdl 	"aic7859",
    159  1.42      fvdl 	"aic7860",
    160  1.42      fvdl 	"aic7870",
    161  1.42      fvdl 	"aic7880",
    162  1.42      fvdl 	"aic7890/91",
    163  1.42      fvdl 	"aic7892",
    164  1.42      fvdl 	"aic7895",
    165  1.42      fvdl 	"aic7896/97",
    166  1.42      fvdl 	"aic7899"
    167  1.42      fvdl };
    168   1.1   mycroft 
    169  1.42      fvdl typedef enum {
    170  1.42      fvdl 	ROLE_UNKNOWN,
    171  1.42      fvdl 	ROLE_INITIATOR,
    172  1.42      fvdl 	ROLE_TARGET
    173  1.42      fvdl } role_t;
    174  1.42      fvdl 
    175  1.42      fvdl struct ahc_devinfo {
    176  1.42      fvdl 	int	  our_scsiid;
    177  1.42      fvdl 	int	  target_offset;
    178  1.42      fvdl 	u_int16_t target_mask;
    179  1.42      fvdl 	u_int8_t  target;
    180  1.42      fvdl 	u_int8_t  lun;
    181  1.42      fvdl 	char	  channel;
    182  1.42      fvdl 	role_t	  role;		/*
    183  1.42      fvdl 				 * Only guaranteed to be correct if not
    184  1.42      fvdl 				 * in the busfree state.
    185  1.42      fvdl 				 */
    186  1.42      fvdl };
    187  1.28       leo 
    188  1.42      fvdl typedef enum {
    189  1.42      fvdl 	SEARCH_COMPLETE,
    190  1.42      fvdl 	SEARCH_COUNT,
    191  1.42      fvdl 	SEARCH_REMOVE
    192  1.42      fvdl } ahc_search_action;
    193   1.1   mycroft 
    194   1.6   mycroft #ifdef AHC_DEBUG
    195   1.9  explorer static int     ahc_debug = AHC_DEBUG;
    196   1.6   mycroft #endif
    197   1.1   mycroft 
    198  1.42      fvdl static int	ahcinitscbdata(struct ahc_softc *);
    199  1.42      fvdl static void	ahcfiniscbdata(struct ahc_softc *);
    200   1.1   mycroft 
    201  1.42      fvdl #if UNUSED
    202  1.42      fvdl static void	ahc_dump_targcmd(struct target_cmd *);
    203  1.42      fvdl #endif
    204  1.42      fvdl static void	ahc_shutdown(void *arg);
    205  1.42      fvdl static int32_t	ahc_action(struct scsipi_xfer *);
    206  1.52      fvdl static int	ahc_ioctl(struct scsipi_link *, u_long, caddr_t, int,
    207  1.52      fvdl 			  struct proc *);
    208  1.42      fvdl static int	ahc_execute_scb(void *, bus_dma_segment_t *, int);
    209  1.42      fvdl static int	ahc_poll(struct ahc_softc *, int);
    210  1.42      fvdl static int	ahc_setup_data(struct ahc_softc *, struct scsipi_xfer *,
    211  1.42      fvdl 			       struct scb *);
    212  1.42      fvdl static void	ahc_freeze_devq(struct ahc_softc *, struct scsipi_link *);
    213  1.42      fvdl static void	ahcallocscbs(struct ahc_softc *);
    214  1.42      fvdl #if UNUSED
    215  1.42      fvdl static void	ahc_scb_devinfo(struct ahc_softc *, struct ahc_devinfo *,
    216  1.42      fvdl 				struct scb *);
    217  1.42      fvdl #endif
    218  1.42      fvdl static void	ahc_fetch_devinfo(struct ahc_softc *, struct ahc_devinfo *);
    219  1.42      fvdl static void	ahc_compile_devinfo(struct ahc_devinfo *, u_int, u_int, u_int,
    220  1.42      fvdl 				    char, role_t);
    221  1.42      fvdl static u_int	ahc_abort_wscb(struct ahc_softc *, u_int, u_int);
    222  1.42      fvdl static void	ahc_done(struct ahc_softc *, struct scb *);
    223  1.42      fvdl static struct tmode_tstate *
    224  1.42      fvdl 		ahc_alloc_tstate(struct ahc_softc *, u_int, char);
    225  1.42      fvdl #if UNUSED
    226  1.42      fvdl static void	ahc_free_tstate(struct ahc_softc *, u_int, char, int);
    227  1.42      fvdl #endif
    228  1.42      fvdl static void 	ahc_handle_seqint(struct ahc_softc *, u_int);
    229  1.42      fvdl static void	ahc_handle_scsiint(struct ahc_softc *, u_int);
    230  1.42      fvdl static void	ahc_build_transfer_msg(struct ahc_softc *,
    231  1.42      fvdl 				       struct ahc_devinfo *);
    232  1.42      fvdl static void	ahc_setup_initiator_msgout(struct ahc_softc *,
    233  1.42      fvdl 					   struct ahc_devinfo *,
    234  1.42      fvdl 					   struct scb *);
    235  1.42      fvdl static void	ahc_setup_target_msgin(struct ahc_softc *,
    236  1.42      fvdl 				       struct ahc_devinfo *);
    237  1.42      fvdl static void	ahc_clear_msg_state(struct ahc_softc *);
    238  1.42      fvdl static void	ahc_handle_message_phase(struct ahc_softc *,
    239  1.42      fvdl 					 struct scsipi_link *);
    240  1.42      fvdl static int	ahc_sent_msg(struct ahc_softc *, u_int, int);
    241  1.42      fvdl 
    242  1.42      fvdl static int	ahc_parse_msg(struct ahc_softc *, struct scsipi_link *,
    243  1.42      fvdl 			      struct ahc_devinfo *);
    244  1.42      fvdl static void	ahc_handle_ign_wide_residue(struct ahc_softc *,
    245  1.42      fvdl 					    struct ahc_devinfo *);
    246  1.42      fvdl static void	ahc_handle_devreset(struct ahc_softc *, struct ahc_devinfo *,
    247  1.42      fvdl 				    int, char *, int);
    248  1.42      fvdl #ifdef AHC_DUMP_SEQ
    249  1.42      fvdl static void	ahc_dumpseq(struct ahc_softc *);
    250  1.42      fvdl #endif
    251  1.42      fvdl static void	ahc_loadseq(struct ahc_softc *);
    252  1.42      fvdl static int	ahc_check_patch(struct ahc_softc *, struct patch **,
    253  1.42      fvdl 				int, int *);
    254  1.42      fvdl static void	ahc_download_instr(struct ahc_softc *, int, u_int8_t *);
    255  1.42      fvdl static int	ahc_match_scb(struct scb *, int, char, int, u_int, role_t);
    256  1.42      fvdl #if defined(AHC_DEBUG)
    257  1.42      fvdl static void	ahc_print_scb(struct scb *);
    258  1.42      fvdl #endif
    259  1.42      fvdl static int	ahc_search_qinfifo(struct ahc_softc *, int, char, int, u_int,
    260  1.42      fvdl 				   role_t, scb_flag, ahc_search_action);
    261  1.42      fvdl static int	ahc_reset_channel(struct ahc_softc *, char, int);
    262  1.42      fvdl static int	ahc_abort_scbs(struct ahc_softc *, int, char, int, u_int,
    263  1.42      fvdl 			       role_t, int);
    264  1.42      fvdl static int	ahc_search_disc_list(struct ahc_softc *, int,
    265  1.42      fvdl 				     char, int, u_int, int, int, int);
    266  1.42      fvdl static u_int	ahc_rem_scb_from_disc_list(struct ahc_softc *, u_int, u_int);
    267  1.42      fvdl static void	ahc_add_curscb_to_free_list(struct ahc_softc *);
    268  1.42      fvdl static void	ahc_clear_intstat(struct ahc_softc *);
    269  1.42      fvdl static void	ahc_reset_current_bus(struct ahc_softc *);
    270  1.42      fvdl static struct ahc_syncrate *
    271  1.42      fvdl 		ahc_devlimited_syncrate(struct ahc_softc *, u_int *);
    272  1.42      fvdl static struct ahc_syncrate *
    273  1.42      fvdl 		ahc_find_syncrate(struct ahc_softc *, u_int *, u_int);
    274  1.42      fvdl static u_int	ahc_find_period(struct ahc_softc *, u_int, u_int);
    275  1.42      fvdl static void	ahc_validate_offset(struct ahc_softc *, struct ahc_syncrate *,
    276  1.42      fvdl 				    u_int *, int);
    277  1.42      fvdl static void	ahc_update_target_msg_request(struct ahc_softc *,
    278  1.42      fvdl 					      struct ahc_devinfo *,
    279  1.42      fvdl 					      struct ahc_initiator_tinfo *,
    280  1.42      fvdl 					      int, int);
    281  1.42      fvdl static void	ahc_set_syncrate(struct ahc_softc *, struct ahc_devinfo *,
    282  1.42      fvdl 				 struct ahc_syncrate *, u_int, u_int, u_int,
    283  1.42      fvdl 				 int, int);
    284  1.42      fvdl static void	ahc_set_width(struct ahc_softc *, struct ahc_devinfo *,
    285  1.42      fvdl 			      u_int, u_int, int, int);
    286  1.42      fvdl static void	ahc_set_tags(struct ahc_softc *, struct ahc_devinfo *,
    287  1.42      fvdl 			     int);
    288  1.42      fvdl static void	ahc_construct_sdtr(struct ahc_softc *, u_int, u_int);
    289  1.42      fvdl 
    290  1.42      fvdl static void	ahc_construct_wdtr(struct ahc_softc *, u_int);
    291  1.42      fvdl 
    292  1.42      fvdl static void	ahc_calc_residual(struct scb *);
    293  1.42      fvdl 
    294  1.42      fvdl static void	ahc_update_pending_syncrates(struct ahc_softc *);
    295  1.42      fvdl 
    296  1.42      fvdl static void	ahc_set_recoveryscb(struct ahc_softc *, struct scb *);
    297  1.42      fvdl 
    298  1.42      fvdl static void     ahc_timeout (void *);
    299  1.42      fvdl static __inline int  sequencer_paused(struct ahc_softc *);
    300  1.42      fvdl static __inline void pause_sequencer(struct ahc_softc *);
    301  1.42      fvdl static __inline void unpause_sequencer(struct ahc_softc *);
    302  1.42      fvdl static 		void restart_sequencer(struct ahc_softc *);
    303  1.42      fvdl static __inline u_int ahc_index_busy_tcl(struct ahc_softc *, u_int, int);
    304  1.42      fvdl 
    305  1.42      fvdl static __inline void	 ahc_busy_tcl(struct ahc_softc *, struct scb *);
    306  1.42      fvdl static __inline int	ahc_isbusy_tcl(struct ahc_softc *, struct scb *);
    307  1.42      fvdl 
    308  1.42      fvdl static __inline void	   ahc_freeze_ccb(struct scb *);
    309  1.42      fvdl static __inline void	   ahcsetccbstatus(struct scsipi_xfer *, int);
    310  1.42      fvdl static void		   ahc_run_qoutfifo(struct ahc_softc *);
    311  1.42      fvdl 
    312  1.42      fvdl static __inline struct ahc_initiator_tinfo *
    313  1.42      fvdl 			   ahc_fetch_transinfo(struct ahc_softc *,
    314  1.42      fvdl 					       char, u_int, u_int,
    315  1.42      fvdl 					       struct tmode_tstate **);
    316  1.42      fvdl static void	   ahcfreescb(struct ahc_softc *, struct scb *);
    317  1.42      fvdl static __inline	struct scb *ahcgetscb(struct ahc_softc *);
    318  1.42      fvdl 
    319  1.42      fvdl static int ahc_createdmamem(bus_dma_tag_t, int, int, bus_dmamap_t *,
    320  1.42      fvdl 			    caddr_t *, bus_addr_t *, bus_dma_segment_t *,
    321  1.42      fvdl 			    int *, const char *, const char *);
    322  1.42      fvdl static void ahc_freedmamem(bus_dma_tag_t, int, bus_dmamap_t,
    323  1.42      fvdl 			   caddr_t, bus_dma_segment_t *, int);
    324  1.42      fvdl static void ahcminphys(struct buf *);
    325  1.42      fvdl 
    326  1.42      fvdl static __inline struct scsipi_xfer *ahc_first_xs(struct ahc_softc *);
    327  1.42      fvdl static __inline void ahc_swap_hscb(struct hardware_scb *);
    328  1.42      fvdl static __inline void ahc_swap_sg(struct ahc_dma_seg *);
    329  1.45      fvdl static void ahc_check_tags(struct ahc_softc *, struct scsipi_xfer *);
    330  1.51      fvdl static int ahc_istagged_device(struct ahc_softc *, struct scsipi_xfer *, int);
    331   1.1   mycroft 
    332  1.42      fvdl #if defined(AHC_DEBUG) && 0
    333  1.42      fvdl static void ahc_dumptinfo(struct ahc_softc *, struct ahc_initiator_tinfo *);
    334   1.6   mycroft #endif
    335   1.1   mycroft 
    336  1.25    bouyer static struct scsipi_device ahc_dev =
    337   1.6   mycroft {
    338   1.6   mycroft     NULL,                       /* Use default error handler */
    339   1.6   mycroft     NULL,                       /* have a queue, served by this */
    340   1.6   mycroft     NULL,                       /* have no async handler */
    341   1.6   mycroft     NULL,                       /* Use default 'done' routine */
    342   1.6   mycroft };
    343   1.1   mycroft 
    344  1.42      fvdl /*
    345  1.42      fvdl  * Pick the first xs for a non-blocked target.
    346  1.42      fvdl  */
    347  1.42      fvdl static __inline struct scsipi_xfer *
    348  1.42      fvdl ahc_first_xs(struct ahc_softc *ahc)
    349  1.14     gibbs {
    350  1.42      fvdl 	int target;
    351  1.42      fvdl 	struct scsipi_xfer *xs = TAILQ_FIRST(&ahc->sc_q);
    352  1.42      fvdl 
    353  1.42      fvdl 	if (ahc->queue_blocked)
    354  1.42      fvdl 		return NULL;
    355  1.42      fvdl 
    356  1.42      fvdl 	while (xs != NULL) {
    357  1.42      fvdl 		target = xs->sc_link->scsipi_scsi.target;
    358  1.42      fvdl 		if (ahc->devqueue_blocked[target] == 0 &&
    359  1.55      fvdl 		    (ahc_istagged_device(ahc, xs, 0) ||
    360  1.45      fvdl 		     ahc_index_busy_tcl(ahc, XS_TCL(ahc, xs), FALSE) ==
    361  1.45      fvdl 		    SCB_LIST_NULL))
    362  1.42      fvdl 			break;
    363  1.42      fvdl 		xs = TAILQ_NEXT(xs, adapter_q);
    364  1.42      fvdl 	}
    365  1.42      fvdl 
    366  1.42      fvdl 	return xs;
    367  1.42      fvdl }
    368  1.14     gibbs 
    369  1.42      fvdl static __inline void
    370  1.42      fvdl ahc_swap_hscb(struct hardware_scb *hscb)
    371  1.42      fvdl {
    372  1.42      fvdl 	hscb->SG_pointer = htole32(hscb->SG_pointer);
    373  1.42      fvdl 	hscb->data = htole32(hscb->data);
    374  1.42      fvdl 	hscb->datalen = htole32(hscb->datalen);
    375  1.14     gibbs 	/*
    376  1.48   thorpej 	 * No need to swap cmdpointer; it's either 0 or set to
    377  1.42      fvdl 	 * cmdstore_busaddr, which is already swapped.
    378  1.14     gibbs 	 */
    379  1.14     gibbs }
    380   1.1   mycroft 
    381  1.42      fvdl static __inline void
    382  1.42      fvdl ahc_swap_sg(struct ahc_dma_seg *sg)
    383  1.42      fvdl {
    384  1.42      fvdl 	sg->addr = htole32(sg->addr);
    385  1.42      fvdl 	sg->len = htole32(sg->len);
    386  1.14     gibbs }
    387   1.1   mycroft 
    388  1.42      fvdl static void
    389  1.42      fvdl ahcminphys(bp)
    390  1.42      fvdl 	struct buf *bp;
    391  1.42      fvdl {
    392   1.1   mycroft /*
    393  1.42      fvdl  * Even though the card can transfer up to 16megs per command
    394  1.42      fvdl  * we are limited by the number of segments in the dma segment
    395  1.42      fvdl  * list that we can hold.  The worst case is that all pages are
    396  1.42      fvdl  * discontinuous physically, hense the "page per segment" limit
    397  1.42      fvdl  * enforced here.
    398   1.1   mycroft  */
    399  1.42      fvdl 	if (bp->b_bcount > AHC_MAXTRANSFER_SIZE) {
    400  1.42      fvdl 		bp->b_bcount = AHC_MAXTRANSFER_SIZE;
    401  1.42      fvdl 	}
    402  1.42      fvdl 	minphys(bp);
    403  1.14     gibbs }
    404   1.1   mycroft 
    405   1.1   mycroft 
    406  1.42      fvdl static __inline u_int32_t
    407  1.42      fvdl ahc_hscb_busaddr(struct ahc_softc *ahc, u_int index)
    408  1.42      fvdl {
    409  1.42      fvdl 	return (ahc->scb_data->hscb_busaddr
    410  1.42      fvdl 		+ (sizeof(struct hardware_scb) * index));
    411   1.6   mycroft }
    412   1.1   mycroft 
    413  1.42      fvdl #define AHC_BUSRESET_DELAY	25	/* Reset delay in us */
    414   1.1   mycroft 
    415  1.42      fvdl static __inline int
    416  1.42      fvdl sequencer_paused(struct ahc_softc *ahc)
    417  1.42      fvdl {
    418  1.42      fvdl 	return ((ahc_inb(ahc, HCNTRL) & PAUSE) != 0);
    419   1.1   mycroft }
    420   1.1   mycroft 
    421  1.42      fvdl static __inline void
    422  1.42      fvdl pause_sequencer(struct ahc_softc *ahc)
    423  1.42      fvdl {
    424  1.42      fvdl 	ahc_outb(ahc, HCNTRL, ahc->pause);
    425   1.1   mycroft 
    426  1.42      fvdl 	/*
    427  1.42      fvdl 	 * Since the sequencer can disable pausing in a critical section, we
    428  1.42      fvdl 	 * must loop until it actually stops.
    429  1.42      fvdl 	 */
    430  1.42      fvdl 	while (sequencer_paused(ahc) == 0)
    431  1.42      fvdl 		;
    432  1.42      fvdl }
    433   1.1   mycroft 
    434  1.42      fvdl static __inline void
    435  1.42      fvdl unpause_sequencer(struct ahc_softc *ahc)
    436  1.42      fvdl {
    437  1.42      fvdl 	if ((ahc_inb(ahc, INTSTAT) & (SCSIINT | SEQINT | BRKADRINT)) == 0)
    438  1.42      fvdl 		ahc_outb(ahc, HCNTRL, ahc->unpause);
    439  1.42      fvdl }
    440   1.1   mycroft 
    441   1.1   mycroft /*
    442  1.42      fvdl  * Restart the sequencer program from address zero
    443   1.1   mycroft  */
    444  1.42      fvdl static void
    445  1.42      fvdl restart_sequencer(struct ahc_softc *ahc)
    446  1.42      fvdl {
    447  1.42      fvdl 	u_int i;
    448   1.1   mycroft 
    449  1.42      fvdl 	pause_sequencer(ahc);
    450   1.1   mycroft 
    451   1.6   mycroft 	/*
    452  1.42      fvdl 	 * Everytime we restart the sequencer, there
    453  1.42      fvdl 	 * is the possiblitity that we have restarted
    454  1.42      fvdl 	 * within a three instruction window where an
    455  1.42      fvdl 	 * SCB has been marked free but has not made it
    456  1.42      fvdl 	 * onto the free list.  Since SCSI events(bus reset,
    457  1.42      fvdl 	 * unexpected bus free) will always freeze the
    458  1.42      fvdl 	 * sequencer, we cannot close this window.  To
    459  1.42      fvdl 	 * avoid losing an SCB, we reconsitute the free
    460  1.42      fvdl 	 * list every time we restart the sequencer.
    461   1.6   mycroft 	 */
    462  1.42      fvdl 	ahc_outb(ahc, FREE_SCBH, SCB_LIST_NULL);
    463  1.42      fvdl 	for (i = 0; i < ahc->scb_data->maxhscbs; i++) {
    464  1.42      fvdl 
    465  1.42      fvdl 		ahc_outb(ahc, SCBPTR, i);
    466  1.42      fvdl 		if (ahc_inb(ahc, SCB_TAG) == SCB_LIST_NULL)
    467  1.42      fvdl 			ahc_add_curscb_to_free_list(ahc);
    468  1.42      fvdl 	}
    469  1.42      fvdl 	ahc_outb(ahc, SEQCTL, FASTMODE|SEQRESET);
    470  1.42      fvdl 	unpause_sequencer(ahc);
    471  1.42      fvdl }
    472   1.1   mycroft 
    473  1.42      fvdl static __inline u_int
    474  1.42      fvdl ahc_index_busy_tcl(struct ahc_softc *ahc, u_int tcl, int unbusy)
    475  1.42      fvdl {
    476  1.42      fvdl 	u_int scbid;
    477   1.1   mycroft 
    478  1.42      fvdl 	scbid = ahc->untagged_scbs[tcl];
    479  1.42      fvdl 	if (unbusy) {
    480  1.42      fvdl 		ahc->untagged_scbs[tcl] = SCB_LIST_NULL;
    481  1.42      fvdl 		bus_dmamap_sync(ahc->parent_dmat, ahc->shared_data_dmamap,
    482  1.42      fvdl 		    UNTAGGEDSCB_OFFSET * 256, 256, BUS_DMASYNC_PREWRITE);
    483   1.6   mycroft 	}
    484   1.6   mycroft 
    485  1.42      fvdl 	return (scbid);
    486   1.6   mycroft }
    487   1.1   mycroft 
    488  1.42      fvdl static __inline void
    489  1.42      fvdl ahc_busy_tcl(struct ahc_softc *ahc, struct scb *scb)
    490   1.6   mycroft {
    491  1.42      fvdl 	ahc->untagged_scbs[scb->hscb->tcl] = scb->hscb->tag;
    492  1.42      fvdl 	bus_dmamap_sync(ahc->parent_dmat, ahc->shared_data_dmamap,
    493  1.42      fvdl 	    UNTAGGEDSCB_OFFSET * 256, 256, BUS_DMASYNC_PREWRITE);
    494   1.1   mycroft }
    495   1.1   mycroft 
    496  1.42      fvdl static __inline int
    497  1.42      fvdl ahc_isbusy_tcl(struct ahc_softc *ahc, struct scb *scb)
    498  1.42      fvdl {
    499  1.42      fvdl 	return ahc->untagged_scbs[scb->hscb->tcl] != SCB_LIST_NULL;
    500   1.6   mycroft }
    501   1.1   mycroft 
    502  1.42      fvdl static __inline void
    503  1.42      fvdl ahc_freeze_ccb(struct scb *scb)
    504   1.1   mycroft {
    505  1.42      fvdl 	struct scsipi_xfer *xs = scb->xs;
    506  1.42      fvdl 	struct ahc_softc *ahc = (struct ahc_softc *)xs->sc_link->adapter_softc;
    507  1.42      fvdl 	int target;
    508   1.1   mycroft 
    509  1.42      fvdl 	target = xs->sc_link->scsipi_scsi.target;
    510  1.42      fvdl 	if (!(scb->flags & SCB_FREEZE_QUEUE)) {
    511  1.42      fvdl 		ahc->devqueue_blocked[target]++;
    512  1.42      fvdl 		scb->flags |= SCB_FREEZE_QUEUE;
    513  1.14     gibbs 	}
    514   1.1   mycroft }
    515   1.1   mycroft 
    516  1.42      fvdl static __inline void
    517  1.42      fvdl ahcsetccbstatus(struct scsipi_xfer *xs, int status)
    518   1.1   mycroft {
    519  1.42      fvdl 	xs->error = status;
    520  1.42      fvdl }
    521   1.1   mycroft 
    522  1.42      fvdl static __inline struct ahc_initiator_tinfo *
    523  1.42      fvdl ahc_fetch_transinfo(struct ahc_softc *ahc, char channel, u_int our_id,
    524  1.42      fvdl 		    u_int remote_id, struct tmode_tstate **tstate)
    525  1.42      fvdl {
    526  1.18   thorpej 	/*
    527  1.42      fvdl 	 * Transfer data structures are stored from the perspective
    528  1.42      fvdl 	 * of the target role.  Since the parameters for a connection
    529  1.42      fvdl 	 * in the initiator role to a given target are the same as
    530  1.42      fvdl 	 * when the roles are reversed, we pretend we are the target.
    531  1.18   thorpej 	 */
    532  1.42      fvdl 	if (channel == 'B')
    533  1.42      fvdl 		our_id += 8;
    534  1.42      fvdl 	*tstate = ahc->enabled_targets[our_id];
    535  1.42      fvdl 	return (&(*tstate)->transinfo[remote_id]);
    536  1.42      fvdl }
    537  1.18   thorpej 
    538  1.42      fvdl static void
    539  1.42      fvdl ahc_run_qoutfifo(struct ahc_softc *ahc)
    540  1.42      fvdl {
    541  1.42      fvdl 	struct scb *scb;
    542  1.42      fvdl 	u_int  scb_index;
    543  1.32   thorpej 
    544  1.42      fvdl 	bus_dmamap_sync(ahc->parent_dmat, ahc->shared_data_dmamap, 0,
    545  1.42      fvdl 	     256, BUS_DMASYNC_POSTREAD);
    546  1.32   thorpej 
    547  1.42      fvdl 	while (ahc->qoutfifo[ahc->qoutfifonext] != SCB_LIST_NULL) {
    548  1.42      fvdl 		scb_index = ahc->qoutfifo[ahc->qoutfifonext];
    549  1.42      fvdl 		ahc->qoutfifo[ahc->qoutfifonext++] = SCB_LIST_NULL;
    550  1.42      fvdl 
    551  1.42      fvdl 		scb = &ahc->scb_data->scbarray[scb_index];
    552  1.42      fvdl 		if (scb_index >= ahc->scb_data->numscbs
    553  1.42      fvdl 		  || (scb->flags & SCB_ACTIVE) == 0) {
    554  1.42      fvdl 			printf("%s: WARNING no command for scb %d "
    555  1.42      fvdl 			       "(cmdcmplt)\nQOUTPOS = %d\n",
    556  1.42      fvdl 			       ahc_name(ahc), scb_index,
    557  1.42      fvdl 			       ahc->qoutfifonext - 1);
    558  1.42      fvdl 			continue;
    559  1.42      fvdl 		}
    560   1.6   mycroft 
    561   1.6   mycroft 		/*
    562  1.42      fvdl 		 * Save off the residual
    563  1.42      fvdl 		 * if there is one.
    564   1.6   mycroft 		 */
    565  1.42      fvdl 		if (scb->hscb->residual_SG_count != 0)
    566  1.42      fvdl 			ahc_calc_residual(scb);
    567  1.42      fvdl 		else
    568  1.42      fvdl 			scb->xs->resid = 0;
    569  1.42      fvdl #ifdef AHC_DEBUG
    570  1.42      fvdl 		if (ahc_debug & AHC_SHOWSCBS) {
    571  1.42      fvdl 			scsi_print_addr(scb->xs->sc_link);
    572  1.42      fvdl 			printf("run_qoutfifo: SCB %x complete\n",
    573  1.42      fvdl 			    scb->hscb->tag);
    574  1.42      fvdl 		}
    575  1.42      fvdl #endif
    576  1.42      fvdl 		ahc_done(ahc, scb);
    577   1.1   mycroft 	}
    578   1.1   mycroft }
    579   1.1   mycroft 
    580  1.42      fvdl 
    581   1.6   mycroft /*
    582  1.42      fvdl  * An scb (and hence an scb entry on the board) is put onto the
    583  1.42      fvdl  * free list.
    584   1.6   mycroft  */
    585  1.42      fvdl static void
    586  1.42      fvdl ahcfreescb(struct ahc_softc *ahc, struct scb *scb)
    587  1.42      fvdl {
    588  1.42      fvdl 	struct hardware_scb *hscb;
    589  1.42      fvdl 	int opri;
    590  1.42      fvdl 
    591  1.42      fvdl 	hscb = scb->hscb;
    592  1.42      fvdl 
    593  1.42      fvdl #ifdef AHC_DEBUG
    594  1.42      fvdl 	if (ahc_debug & AHC_SHOWSCBALLOC)
    595  1.42      fvdl 		printf("%s: free SCB tag %x\n", ahc_name(ahc), hscb->tag);
    596  1.29       leo #endif
    597  1.28       leo 
    598  1.42      fvdl 	opri = splbio();
    599   1.6   mycroft 
    600  1.42      fvdl 	if ((ahc->flags & AHC_RESOURCE_SHORTAGE) != 0 ||
    601  1.42      fvdl 	    (scb->flags & SCB_RECOVERY_SCB) != 0) {
    602  1.42      fvdl 		ahc->flags &= ~AHC_RESOURCE_SHORTAGE;
    603  1.42      fvdl 		ahc->queue_blocked = 0;
    604  1.42      fvdl 	}
    605   1.6   mycroft 
    606  1.42      fvdl 	/* Clean up for the next user */
    607  1.42      fvdl 	scb->flags = SCB_FREE;
    608  1.42      fvdl 	hscb->control = 0;
    609  1.42      fvdl 	hscb->status = 0;
    610   1.6   mycroft 
    611  1.42      fvdl 	SLIST_INSERT_HEAD(&ahc->scb_data->free_scbs, scb, links);
    612  1.29       leo 
    613  1.42      fvdl 	splx(opri);
    614   1.6   mycroft }
    615   1.6   mycroft 
    616   1.6   mycroft /*
    617  1.42      fvdl  * Get a free scb, either one already assigned to a hardware slot
    618  1.42      fvdl  * on the adapter or one that will require an SCB to be paged out before
    619  1.42      fvdl  * use. If there are none, see if we can allocate a new SCB.  Otherwise
    620  1.42      fvdl  * either return an error or sleep.
    621   1.6   mycroft  */
    622  1.42      fvdl static __inline struct scb *
    623  1.42      fvdl ahcgetscb(struct ahc_softc *ahc)
    624  1.42      fvdl {
    625  1.42      fvdl 	struct scb *scbp;
    626  1.42      fvdl 	int opri;;
    627  1.42      fvdl 
    628  1.42      fvdl 	opri = splbio();
    629  1.42      fvdl 	if ((scbp = SLIST_FIRST(&ahc->scb_data->free_scbs))) {
    630  1.42      fvdl 		SLIST_REMOVE_HEAD(&ahc->scb_data->free_scbs, links);
    631  1.42      fvdl 	} else {
    632  1.42      fvdl 		ahcallocscbs(ahc);
    633  1.42      fvdl 		scbp = SLIST_FIRST(&ahc->scb_data->free_scbs);
    634  1.42      fvdl 		if (scbp != NULL)
    635  1.42      fvdl 			SLIST_REMOVE_HEAD(&ahc->scb_data->free_scbs, links);
    636  1.42      fvdl 	}
    637  1.42      fvdl 
    638  1.42      fvdl 	splx(opri);
    639  1.42      fvdl 
    640  1.42      fvdl #ifdef AHC_DEBUG
    641  1.42      fvdl 	if (ahc_debug & AHC_SHOWSCBALLOC) {
    642  1.42      fvdl 		if (scbp != NULL)
    643  1.42      fvdl 			printf("%s: new SCB, tag %x\n", ahc_name(ahc),
    644  1.42      fvdl 			    scbp->hscb->tag);
    645  1.42      fvdl 		else
    646  1.42      fvdl 			printf("%s: failed to allocate new SCB\n",
    647  1.42      fvdl 			    ahc_name(ahc));
    648  1.42      fvdl 	}
    649  1.42      fvdl #endif
    650  1.42      fvdl 
    651  1.42      fvdl 	return (scbp);
    652  1.42      fvdl }
    653  1.42      fvdl 
    654  1.42      fvdl static int
    655  1.42      fvdl ahc_createdmamem(tag, size, flags, mapp, vaddr, baddr, seg, nseg, myname, what)
    656  1.42      fvdl 	bus_dma_tag_t tag;
    657  1.42      fvdl 	int size;
    658  1.42      fvdl 	int flags;
    659  1.42      fvdl 	bus_dmamap_t *mapp;
    660  1.42      fvdl 	caddr_t *vaddr;
    661  1.42      fvdl 	bus_addr_t *baddr;
    662  1.42      fvdl 	bus_dma_segment_t *seg;
    663  1.42      fvdl 	int *nseg;
    664  1.42      fvdl 	const char *myname, *what;
    665  1.42      fvdl {
    666  1.42      fvdl 	int error, level = 0;
    667  1.42      fvdl 
    668  1.42      fvdl 	if ((error = bus_dmamem_alloc(tag, size, NBPG, 0,
    669  1.42      fvdl 			seg, 1, nseg, BUS_DMA_NOWAIT)) != 0) {
    670  1.42      fvdl 		printf("%s: failed to allocate DMA mem for %s, error = %d\n",
    671  1.42      fvdl 			myname, what, error);
    672  1.42      fvdl 		goto out;
    673  1.42      fvdl 	}
    674  1.42      fvdl 	level++;
    675  1.42      fvdl 
    676  1.42      fvdl 	if ((error = bus_dmamem_map(tag, seg, *nseg, size, vaddr,
    677  1.42      fvdl 			BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) != 0) {
    678  1.42      fvdl 		printf("%s: failed to map DMA mem for %s, error = %d\n",
    679  1.42      fvdl 			myname, what, error);
    680  1.42      fvdl 		goto out;
    681  1.42      fvdl 	}
    682  1.42      fvdl 	level++;
    683  1.42      fvdl 
    684  1.42      fvdl 	if ((error = bus_dmamap_create(tag, size, 1, size, 0,
    685  1.42      fvdl 			BUS_DMA_NOWAIT | flags, mapp)) != 0) {
    686  1.42      fvdl                 printf("%s: failed to create DMA map for %s, error = %d\n",
    687  1.42      fvdl 			myname, what, error);
    688  1.42      fvdl 		goto out;
    689  1.42      fvdl         }
    690  1.42      fvdl 	level++;
    691  1.42      fvdl 
    692  1.42      fvdl 	if ((error = bus_dmamap_load(tag, *mapp, *vaddr, size, NULL,
    693  1.42      fvdl 			BUS_DMA_NOWAIT)) != 0) {
    694  1.42      fvdl                 printf("%s: failed to load DMA map for %s, error = %d\n",
    695  1.42      fvdl 			myname, what, error);
    696  1.42      fvdl 		goto out;
    697  1.42      fvdl         }
    698  1.42      fvdl 
    699  1.42      fvdl 	*baddr = (*mapp)->dm_segs[0].ds_addr;
    700  1.42      fvdl 
    701  1.42      fvdl #ifdef AHC_DEBUG
    702  1.42      fvdl 	printf("%s: dmamem for %s at busaddr %lx virt %lx nseg %d size %d\n",
    703  1.42      fvdl 	    myname, what, (unsigned long)*baddr, (unsigned long)*vaddr,
    704  1.42      fvdl 	    *nseg, size);
    705  1.42      fvdl #endif
    706  1.42      fvdl 
    707  1.42      fvdl 	return 0;
    708  1.42      fvdl out:
    709  1.42      fvdl 	switch (level) {
    710  1.42      fvdl 	case 3:
    711  1.42      fvdl 		bus_dmamap_destroy(tag, *mapp);
    712  1.42      fvdl 		/* FALLTHROUGH */
    713  1.42      fvdl 	case 2:
    714  1.42      fvdl 		bus_dmamem_unmap(tag, *vaddr, size);
    715  1.42      fvdl 		/* FALLTHROUGH */
    716  1.42      fvdl 	case 1:
    717  1.42      fvdl 		bus_dmamem_free(tag, seg, *nseg);
    718  1.42      fvdl 		break;
    719  1.42      fvdl 	default:
    720  1.42      fvdl 		break;
    721  1.42      fvdl 	}
    722  1.42      fvdl 
    723  1.42      fvdl 	return error;
    724  1.42      fvdl }
    725  1.42      fvdl 
    726  1.42      fvdl static void
    727  1.42      fvdl ahc_freedmamem(tag, size, map, vaddr, seg, nseg)
    728  1.42      fvdl 	bus_dma_tag_t tag;
    729  1.42      fvdl 	int size;
    730  1.42      fvdl 	bus_dmamap_t map;
    731  1.42      fvdl 	caddr_t vaddr;
    732  1.42      fvdl 	bus_dma_segment_t *seg;
    733  1.42      fvdl 	int nseg;
    734  1.42      fvdl {
    735  1.42      fvdl 
    736  1.42      fvdl 	bus_dmamap_unload(tag, map);
    737  1.42      fvdl 	bus_dmamap_destroy(tag, map);
    738  1.42      fvdl 	bus_dmamem_unmap(tag, vaddr, size);
    739  1.42      fvdl 	bus_dmamem_free(tag, seg, nseg);
    740  1.42      fvdl }
    741  1.42      fvdl 
    742  1.42      fvdl char *
    743  1.42      fvdl ahc_name(struct ahc_softc *ahc)
    744  1.42      fvdl {
    745  1.42      fvdl 	return (ahc->sc_dev.dv_xname);
    746  1.42      fvdl }
    747  1.42      fvdl 
    748  1.42      fvdl #ifdef AHC_DEBUG
    749  1.42      fvdl static void
    750  1.42      fvdl ahc_print_scb(struct scb *scb)
    751  1.42      fvdl {
    752  1.42      fvdl 	struct hardware_scb *hscb = scb->hscb;
    753  1.42      fvdl 
    754  1.42      fvdl 	printf("scb:%p tag %x control:0x%x tcl:0x%x cmdlen:%d cmdpointer:0x%lx\n",
    755  1.42      fvdl 		scb,
    756  1.42      fvdl 		hscb->tag,
    757  1.42      fvdl 		hscb->control,
    758  1.42      fvdl 		hscb->tcl,
    759  1.42      fvdl 		hscb->cmdlen,
    760  1.42      fvdl 		(unsigned long)le32toh(hscb->cmdpointer));
    761  1.42      fvdl 	printf("        datlen:%u data:0x%lx segs:0x%x segp:0x%lx\n",
    762  1.42      fvdl 		le32toh(hscb->datalen),
    763  1.42      fvdl 		(unsigned long)(le32toh(hscb->data)),
    764  1.42      fvdl 		hscb->SG_count,
    765  1.42      fvdl 		(unsigned long)(le32toh(hscb->SG_pointer)));
    766  1.42      fvdl 	printf("	sg_addr:%lx sg_len:%lu\n",
    767  1.42      fvdl 		(unsigned long)(le32toh(scb->sg_list[0].addr)),
    768  1.50     soren 		(unsigned long)(le32toh(scb->sg_list[0].len)));
    769  1.42      fvdl 	printf("	cdb:%x %x %x %x %x %x %x %x %x %x %x %x\n",
    770  1.42      fvdl 		hscb->cmdstore[0], hscb->cmdstore[1], hscb->cmdstore[2],
    771  1.42      fvdl 		hscb->cmdstore[3], hscb->cmdstore[4], hscb->cmdstore[5],
    772  1.42      fvdl 		hscb->cmdstore[6], hscb->cmdstore[7], hscb->cmdstore[8],
    773  1.42      fvdl 		hscb->cmdstore[9], hscb->cmdstore[10], hscb->cmdstore[11]);
    774  1.42      fvdl }
    775  1.42      fvdl #endif
    776  1.42      fvdl 
    777  1.42      fvdl static struct {
    778  1.42      fvdl         u_int8_t errno;
    779  1.42      fvdl 	char *errmesg;
    780  1.42      fvdl } hard_error[] = {
    781  1.42      fvdl 	{ ILLHADDR,	"Illegal Host Access" },
    782  1.42      fvdl 	{ ILLSADDR,	"Illegal Sequencer Address referrenced" },
    783  1.42      fvdl 	{ ILLOPCODE,	"Illegal Opcode in sequencer program" },
    784  1.42      fvdl 	{ SQPARERR,	"Sequencer Parity Error" },
    785  1.42      fvdl 	{ DPARERR,	"Data-path Parity Error" },
    786  1.42      fvdl 	{ MPARERR,	"Scratch or SCB Memory Parity Error" },
    787  1.42      fvdl 	{ PCIERRSTAT,	"PCI Error detected" },
    788  1.42      fvdl 	{ CIOPARERR,	"CIOBUS Parity Error" },
    789  1.42      fvdl };
    790  1.42      fvdl static const int num_errors = sizeof(hard_error)/sizeof(hard_error[0]);
    791  1.42      fvdl 
    792  1.42      fvdl static struct {
    793  1.42      fvdl         u_int8_t phase;
    794  1.42      fvdl         u_int8_t mesg_out; /* Message response to parity errors */
    795  1.42      fvdl 	char *phasemsg;
    796  1.42      fvdl } phase_table[] = {
    797  1.42      fvdl 	{ P_DATAOUT,	MSG_NOOP,		"in Data-out phase"	},
    798  1.42      fvdl 	{ P_DATAIN,	MSG_INITIATOR_DET_ERR,	"in Data-in phase"	},
    799  1.42      fvdl 	{ P_COMMAND,	MSG_NOOP,		"in Command phase"	},
    800  1.42      fvdl 	{ P_MESGOUT,	MSG_NOOP,		"in Message-out phase"	},
    801  1.42      fvdl 	{ P_STATUS,	MSG_INITIATOR_DET_ERR,	"in Status phase"	},
    802  1.42      fvdl 	{ P_MESGIN,	MSG_PARITY_ERROR,	"in Message-in phase"	},
    803  1.42      fvdl 	{ P_BUSFREE,	MSG_NOOP,		"while idle"		},
    804  1.42      fvdl 	{ 0,		MSG_NOOP,		"in unknown phase"	}
    805  1.42      fvdl };
    806  1.42      fvdl static const int num_phases = (sizeof(phase_table)/sizeof(phase_table[0])) - 1;
    807  1.42      fvdl 
    808  1.42      fvdl /*
    809  1.42      fvdl  * Valid SCSIRATE values.  (p. 3-17)
    810  1.42      fvdl  * Provides a mapping of tranfer periods in ns to the proper value to
    811  1.42      fvdl  * stick in the scsiscfr reg to use that transfer rate.
    812  1.42      fvdl  */
    813  1.42      fvdl #define AHC_SYNCRATE_DT		0
    814  1.42      fvdl #define AHC_SYNCRATE_ULTRA2	1
    815  1.45      fvdl #define AHC_SYNCRATE_ULTRA	3
    816  1.45      fvdl #define AHC_SYNCRATE_FAST	6
    817  1.42      fvdl static struct ahc_syncrate ahc_syncrates[] = {
    818  1.42      fvdl       /* ultra2    fast/ultra  period     rate */
    819  1.42      fvdl 	{ 0x42,      0x000,      9,      "80.0" },
    820  1.42      fvdl 	{ 0x03,      0x000,     10,      "40.0" },
    821  1.42      fvdl 	{ 0x04,      0x000,     11,      "33.0" },
    822  1.42      fvdl 	{ 0x05,      0x100,     12,      "20.0" },
    823  1.42      fvdl 	{ 0x06,      0x110,     15,      "16.0" },
    824  1.42      fvdl 	{ 0x07,      0x120,     18,      "13.4" },
    825  1.42      fvdl 	{ 0x08,      0x000,     25,      "10.0" },
    826  1.42      fvdl 	{ 0x19,      0x010,     31,      "8.0"  },
    827  1.42      fvdl 	{ 0x1a,      0x020,     37,      "6.67" },
    828  1.42      fvdl 	{ 0x1b,      0x030,     43,      "5.7"  },
    829  1.42      fvdl 	{ 0x1c,      0x040,     50,      "5.0"  },
    830  1.42      fvdl 	{ 0x00,      0x050,     56,      "4.4"  },
    831  1.42      fvdl 	{ 0x00,      0x060,     62,      "4.0"  },
    832  1.42      fvdl 	{ 0x00,      0x070,     68,      "3.6"  },
    833  1.42      fvdl 	{ 0x00,      0x000,      0,      NULL   }
    834  1.42      fvdl };
    835  1.42      fvdl 
    836  1.42      fvdl /*
    837  1.42      fvdl  * Allocate a controller structure for a new device and initialize it.
    838  1.42      fvdl  */
    839  1.42      fvdl int
    840  1.42      fvdl ahc_alloc(struct ahc_softc *ahc, bus_space_handle_t sh, bus_space_tag_t st,
    841  1.42      fvdl 	  bus_dma_tag_t parent_dmat, ahc_chip chip, ahc_feature features,
    842  1.42      fvdl 	  ahc_flag flags)
    843  1.42      fvdl {
    844  1.42      fvdl 	struct scb_data *scb_data;
    845  1.42      fvdl 
    846  1.42      fvdl 	scb_data = malloc(sizeof (struct scb_data), M_DEVBUF, M_NOWAIT);
    847  1.42      fvdl 	if (scb_data == NULL) {
    848  1.42      fvdl 		printf("%s: cannot malloc softc!\n", ahc_name(ahc));
    849  1.42      fvdl 		return -1;
    850  1.42      fvdl 	}
    851  1.42      fvdl 	bzero(scb_data, sizeof (struct scb_data));
    852  1.42      fvdl 	LIST_INIT(&ahc->pending_ccbs);
    853  1.42      fvdl 	ahc->tag = st;
    854  1.42      fvdl 	ahc->bsh = sh;
    855  1.42      fvdl 	ahc->parent_dmat = parent_dmat;
    856  1.42      fvdl 	ahc->chip = chip;
    857  1.42      fvdl 	ahc->features = features;
    858  1.42      fvdl 	ahc->flags = flags;
    859  1.42      fvdl 	ahc->scb_data = scb_data;
    860  1.42      fvdl 
    861  1.42      fvdl 	ahc->unpause = (ahc_inb(ahc, HCNTRL) & IRQMS) | INTEN;
    862  1.42      fvdl 	/* The IRQMS bit is only valid on VL and EISA chips */
    863  1.42      fvdl 	if ((ahc->chip & AHC_PCI) != 0)
    864  1.42      fvdl 		ahc->unpause &= ~IRQMS;
    865  1.42      fvdl 	ahc->pause = ahc->unpause | PAUSE;
    866  1.42      fvdl 	return (0);
    867  1.42      fvdl }
    868  1.42      fvdl 
    869  1.42      fvdl void
    870  1.42      fvdl ahc_free(ahc)
    871  1.42      fvdl 	struct ahc_softc *ahc;
    872  1.42      fvdl {
    873  1.42      fvdl 	ahcfiniscbdata(ahc);
    874  1.42      fvdl 	if (ahc->init_level != 0)
    875  1.42      fvdl 		ahc_freedmamem(ahc->parent_dmat, ahc->shared_data_size,
    876  1.42      fvdl 		    ahc->shared_data_dmamap, ahc->qoutfifo,
    877  1.42      fvdl 		    &ahc->shared_data_seg, ahc->shared_data_nseg);
    878  1.42      fvdl 
    879  1.42      fvdl 	if (ahc->scb_data != NULL)
    880  1.42      fvdl 		free(ahc->scb_data, M_DEVBUF);
    881  1.42      fvdl 	if (ahc->bus_data != NULL)
    882  1.42      fvdl 		free(ahc->bus_data, M_DEVBUF);
    883  1.42      fvdl 	return;
    884  1.42      fvdl }
    885  1.42      fvdl 
    886  1.42      fvdl static int
    887  1.42      fvdl ahcinitscbdata(struct ahc_softc *ahc)
    888  1.42      fvdl {
    889  1.42      fvdl 	struct scb_data *scb_data;
    890  1.42      fvdl 	int i;
    891  1.42      fvdl 
    892  1.42      fvdl 	scb_data = ahc->scb_data;
    893  1.42      fvdl 	SLIST_INIT(&scb_data->free_scbs);
    894  1.42      fvdl 	SLIST_INIT(&scb_data->sg_maps);
    895  1.42      fvdl 
    896  1.42      fvdl 	/* Allocate SCB resources */
    897  1.42      fvdl 	scb_data->scbarray =
    898  1.42      fvdl 	    (struct scb *)malloc(sizeof(struct scb) * AHC_SCB_MAX,
    899  1.42      fvdl 				 M_DEVBUF, M_NOWAIT);
    900  1.42      fvdl 	if (scb_data->scbarray == NULL)
    901  1.42      fvdl 		return (ENOMEM);
    902  1.42      fvdl 	bzero(scb_data->scbarray, sizeof(struct scb) * AHC_SCB_MAX);
    903  1.42      fvdl 
    904  1.42      fvdl 	/* Determine the number of hardware SCBs and initialize them */
    905  1.42      fvdl 
    906  1.42      fvdl 	scb_data->maxhscbs = ahc_probe_scbs(ahc);
    907  1.42      fvdl 	/* SCB 0 heads the free list */
    908  1.42      fvdl 	ahc_outb(ahc, FREE_SCBH, 0);
    909  1.42      fvdl 	for (i = 0; i < ahc->scb_data->maxhscbs; i++) {
    910  1.42      fvdl 		ahc_outb(ahc, SCBPTR, i);
    911  1.42      fvdl 
    912  1.42      fvdl 		/* Clear the control byte. */
    913  1.42      fvdl 		ahc_outb(ahc, SCB_CONTROL, 0);
    914  1.42      fvdl 
    915  1.42      fvdl 		/* Set the next pointer */
    916  1.42      fvdl 		ahc_outb(ahc, SCB_NEXT, i+1);
    917  1.42      fvdl 
    918  1.42      fvdl 		/* Make the tag number invalid */
    919  1.42      fvdl 		ahc_outb(ahc, SCB_TAG, SCB_LIST_NULL);
    920  1.42      fvdl 	}
    921  1.42      fvdl 
    922  1.42      fvdl 	/* Make sure that the last SCB terminates the free list */
    923  1.42      fvdl 	ahc_outb(ahc, SCBPTR, i-1);
    924  1.42      fvdl 	ahc_outb(ahc, SCB_NEXT, SCB_LIST_NULL);
    925  1.42      fvdl 
    926  1.42      fvdl 	/* Ensure we clear the 0 SCB's control byte. */
    927  1.42      fvdl 	ahc_outb(ahc, SCBPTR, 0);
    928  1.42      fvdl 	ahc_outb(ahc, SCB_CONTROL, 0);
    929  1.42      fvdl 
    930  1.42      fvdl 	scb_data->maxhscbs = i;
    931  1.42      fvdl 
    932  1.42      fvdl 	if (ahc->scb_data->maxhscbs == 0)
    933  1.42      fvdl 		panic("%s: No SCB space found", ahc_name(ahc));
    934  1.42      fvdl 
    935  1.42      fvdl 	/*
    936  1.42      fvdl 	 * Create our DMA tags.  These tags define the kinds of device
    937  1.42      fvdl 	 * accessable memory allocations and memory mappings we will
    938  1.42      fvdl 	 * need to perform during normal operation.
    939  1.42      fvdl 	 *
    940  1.42      fvdl 	 * Unless we need to further restrict the allocation, we rely
    941  1.42      fvdl 	 * on the restrictions of the parent dmat, hence the common
    942  1.42      fvdl 	 * use of MAXADDR and MAXSIZE.
    943  1.42      fvdl 	 */
    944  1.42      fvdl 
    945  1.42      fvdl 	if (ahc_createdmamem(ahc->parent_dmat,
    946  1.42      fvdl 	    AHC_SCB_MAX * sizeof(struct hardware_scb), ahc->sc_dmaflags,
    947  1.42      fvdl 	    &scb_data->hscb_dmamap,
    948  1.42      fvdl 	    (caddr_t *)&scb_data->hscbs, &scb_data->hscb_busaddr,
    949  1.42      fvdl 	    &scb_data->hscb_seg, &scb_data->hscb_nseg, ahc_name(ahc),
    950  1.42      fvdl 	    "hardware SCB structures") < 0)
    951  1.42      fvdl 		goto error_exit;
    952  1.42      fvdl 
    953  1.42      fvdl 	scb_data->init_level++;
    954  1.42      fvdl 
    955  1.42      fvdl 	if (ahc_createdmamem(ahc->parent_dmat,
    956  1.42      fvdl 	    AHC_SCB_MAX * sizeof(struct scsipi_sense_data), ahc->sc_dmaflags,
    957  1.42      fvdl 	    &scb_data->sense_dmamap, (caddr_t *)&scb_data->sense,
    958  1.42      fvdl 	    &scb_data->sense_busaddr, &scb_data->sense_seg,
    959  1.42      fvdl 	    &scb_data->sense_nseg, ahc_name(ahc), "sense buffers") < 0)
    960  1.42      fvdl 		goto error_exit;
    961  1.42      fvdl 
    962  1.42      fvdl 	scb_data->init_level++;
    963  1.42      fvdl 
    964  1.42      fvdl 	/* Perform initial CCB allocation */
    965  1.42      fvdl 	bzero(scb_data->hscbs, AHC_SCB_MAX * sizeof(struct hardware_scb));
    966  1.42      fvdl 	ahcallocscbs(ahc);
    967  1.42      fvdl 
    968  1.42      fvdl 	if (scb_data->numscbs == 0) {
    969  1.42      fvdl 		printf("%s: ahc_init_scb_data - "
    970  1.42      fvdl 		       "Unable to allocate initial scbs\n",
    971  1.42      fvdl 		       ahc_name(ahc));
    972  1.42      fvdl 		goto error_exit;
    973  1.42      fvdl 	}
    974  1.42      fvdl 
    975  1.42      fvdl 	scb_data->init_level++;
    976  1.42      fvdl 
    977  1.42      fvdl 	/*
    978  1.42      fvdl          * Note that we were successfull
    979  1.42      fvdl          */
    980  1.42      fvdl         return 0;
    981  1.42      fvdl 
    982  1.42      fvdl error_exit:
    983  1.42      fvdl 
    984  1.42      fvdl 	return ENOMEM;
    985  1.42      fvdl }
    986  1.42      fvdl 
    987  1.42      fvdl static void
    988  1.42      fvdl ahcfiniscbdata(struct ahc_softc *ahc)
    989  1.42      fvdl {
    990  1.42      fvdl 	struct scb_data *scb_data;
    991  1.42      fvdl 
    992  1.42      fvdl 	scb_data = ahc->scb_data;
    993  1.42      fvdl 
    994  1.42      fvdl 	switch (scb_data->init_level) {
    995  1.42      fvdl 	default:
    996  1.42      fvdl 	case 3:
    997  1.42      fvdl 	{
    998  1.42      fvdl 		struct sg_map_node *sg_map;
    999  1.42      fvdl 
   1000  1.42      fvdl 		while ((sg_map = SLIST_FIRST(&scb_data->sg_maps))!= NULL) {
   1001  1.42      fvdl 			SLIST_REMOVE_HEAD(&scb_data->sg_maps, links);
   1002  1.42      fvdl 			ahc_freedmamem(ahc->parent_dmat, PAGE_SIZE,
   1003  1.42      fvdl 			    sg_map->sg_dmamap, (caddr_t)sg_map->sg_vaddr,
   1004  1.42      fvdl 			    &sg_map->sg_dmasegs, sg_map->sg_nseg);
   1005  1.42      fvdl 			free(sg_map, M_DEVBUF);
   1006  1.42      fvdl 		}
   1007  1.42      fvdl 	}
   1008  1.42      fvdl 	/*FALLTHROUGH*/
   1009  1.42      fvdl 	case 2:
   1010  1.42      fvdl 		ahc_freedmamem(ahc->parent_dmat,
   1011  1.42      fvdl 		    AHC_SCB_MAX * sizeof(struct scsipi_sense_data),
   1012  1.42      fvdl 		    scb_data->sense_dmamap, (caddr_t)scb_data->sense,
   1013  1.42      fvdl 		    &scb_data->sense_seg, scb_data->sense_nseg);
   1014  1.42      fvdl 	/*FALLTHROUGH*/
   1015  1.42      fvdl 	case 1:
   1016  1.42      fvdl 		ahc_freedmamem(ahc->parent_dmat,
   1017  1.42      fvdl 		    AHC_SCB_MAX * sizeof(struct hardware_scb),
   1018  1.42      fvdl 		    scb_data->hscb_dmamap, (caddr_t)scb_data->hscbs,
   1019  1.42      fvdl 		    &scb_data->hscb_seg, scb_data->hscb_nseg);
   1020  1.42      fvdl 	/*FALLTHROUGH*/
   1021  1.42      fvdl 	}
   1022  1.42      fvdl 	if (scb_data->scbarray != NULL)
   1023  1.42      fvdl 		free(scb_data->scbarray, M_DEVBUF);
   1024  1.42      fvdl }
   1025  1.42      fvdl 
   1026  1.42      fvdl int
   1027  1.42      fvdl ahc_reset(struct ahc_softc *ahc)
   1028  1.42      fvdl {
   1029  1.42      fvdl 	u_int	sblkctl;
   1030  1.42      fvdl 	int	wait;
   1031  1.42      fvdl 
   1032  1.42      fvdl #ifdef AHC_DUMP_SEQ
   1033  1.42      fvdl 	if (ahc->init_level == 0)
   1034  1.42      fvdl 		ahc_dumpseq(ahc);
   1035  1.42      fvdl #endif
   1036  1.42      fvdl 	ahc_outb(ahc, HCNTRL, CHIPRST | ahc->pause);
   1037  1.42      fvdl 	/*
   1038  1.42      fvdl 	 * Ensure that the reset has finished
   1039  1.42      fvdl 	 */
   1040  1.42      fvdl 	wait = 1000;
   1041  1.42      fvdl 	do {
   1042  1.42      fvdl 		DELAY(1000);
   1043  1.42      fvdl 	} while (--wait && !(ahc_inb(ahc, HCNTRL) & CHIPRSTACK));
   1044  1.42      fvdl 
   1045  1.42      fvdl 	if (wait == 0) {
   1046  1.42      fvdl 		printf("%s: WARNING - Failed chip reset!  "
   1047  1.42      fvdl 		       "Trying to initialize anyway.\n", ahc_name(ahc));
   1048  1.42      fvdl 	}
   1049  1.42      fvdl 	ahc_outb(ahc, HCNTRL, ahc->pause);
   1050  1.42      fvdl 
   1051  1.42      fvdl 	/* Determine channel configuration */
   1052  1.42      fvdl 	sblkctl = ahc_inb(ahc, SBLKCTL) & (SELBUSB|SELWIDE);
   1053  1.42      fvdl 	/* No Twin Channel PCI cards */
   1054  1.42      fvdl 	if ((ahc->chip & AHC_PCI) != 0)
   1055  1.42      fvdl 		sblkctl &= ~SELBUSB;
   1056  1.42      fvdl 	switch (sblkctl) {
   1057  1.42      fvdl 	case 0:
   1058  1.42      fvdl 		/* Single Narrow Channel */
   1059  1.42      fvdl 		break;
   1060  1.42      fvdl 	case 2:
   1061  1.42      fvdl 		/* Wide Channel */
   1062  1.42      fvdl 		ahc->features |= AHC_WIDE;
   1063  1.42      fvdl 		break;
   1064  1.42      fvdl 	case 8:
   1065  1.42      fvdl 		/* Twin Channel */
   1066  1.42      fvdl 		ahc->features |= AHC_TWIN;
   1067  1.42      fvdl 		break;
   1068  1.42      fvdl 	default:
   1069  1.42      fvdl 		printf(" Unsupported adapter type.  Ignoring\n");
   1070  1.42      fvdl 		return(-1);
   1071  1.42      fvdl 	}
   1072  1.42      fvdl 
   1073  1.42      fvdl 	return (0);
   1074  1.42      fvdl }
   1075  1.42      fvdl 
   1076  1.42      fvdl /*
   1077  1.42      fvdl  * Called when we have an active connection to a target on the bus,
   1078  1.42      fvdl  * this function finds the nearest syncrate to the input period limited
   1079  1.42      fvdl  * by the capabilities of the bus connectivity of the target.
   1080  1.42      fvdl  */
   1081  1.42      fvdl static struct ahc_syncrate *
   1082  1.42      fvdl ahc_devlimited_syncrate(struct ahc_softc *ahc, u_int *period) {
   1083  1.42      fvdl 	u_int	maxsync;
   1084  1.42      fvdl 
   1085  1.42      fvdl 	if ((ahc->features & AHC_ULTRA2) != 0) {
   1086  1.42      fvdl 		if ((ahc_inb(ahc, SBLKCTL) & ENAB40) != 0
   1087  1.42      fvdl 		 && (ahc_inb(ahc, SSTAT2) & EXP_ACTIVE) == 0) {
   1088  1.42      fvdl 			maxsync = AHC_SYNCRATE_ULTRA2;
   1089  1.42      fvdl 		} else {
   1090  1.42      fvdl 			maxsync = AHC_SYNCRATE_ULTRA;
   1091  1.42      fvdl 		}
   1092  1.42      fvdl 	} else if ((ahc->features & AHC_ULTRA) != 0) {
   1093  1.42      fvdl 		maxsync = AHC_SYNCRATE_ULTRA;
   1094  1.42      fvdl 	} else {
   1095  1.42      fvdl 		maxsync = AHC_SYNCRATE_FAST;
   1096  1.42      fvdl 	}
   1097  1.42      fvdl 	return (ahc_find_syncrate(ahc, period, maxsync));
   1098  1.42      fvdl }
   1099  1.42      fvdl 
   1100  1.42      fvdl /*
   1101  1.42      fvdl  * Look up the valid period to SCSIRATE conversion in our table.
   1102  1.42      fvdl  * Return the period and offset that should be sent to the target
   1103  1.42      fvdl  * if this was the beginning of an SDTR.
   1104  1.42      fvdl  */
   1105  1.42      fvdl static struct ahc_syncrate *
   1106  1.42      fvdl ahc_find_syncrate(struct ahc_softc *ahc, u_int *period, u_int maxsync)
   1107  1.42      fvdl {
   1108  1.42      fvdl 	struct ahc_syncrate *syncrate;
   1109  1.42      fvdl 
   1110  1.42      fvdl 	syncrate = &ahc_syncrates[maxsync];
   1111  1.42      fvdl 	while ((syncrate->rate != NULL)
   1112  1.42      fvdl 	    && ((ahc->features & AHC_ULTRA2) == 0
   1113  1.42      fvdl 	     || (syncrate->sxfr_u2 != 0))) {
   1114  1.42      fvdl 
   1115  1.42      fvdl 		if (*period <= syncrate->period) {
   1116  1.42      fvdl 			/*
   1117  1.42      fvdl 			 * When responding to a target that requests
   1118  1.42      fvdl 			 * sync, the requested rate may fall between
   1119  1.42      fvdl 			 * two rates that we can output, but still be
   1120  1.42      fvdl 			 * a rate that we can receive.  Because of this,
   1121  1.42      fvdl 			 * we want to respond to the target with
   1122  1.42      fvdl 			 * the same rate that it sent to us even
   1123  1.42      fvdl 			 * if the period we use to send data to it
   1124  1.42      fvdl 			 * is lower.  Only lower the response period
   1125  1.42      fvdl 			 * if we must.
   1126  1.42      fvdl 			 */
   1127  1.42      fvdl 			if (syncrate == &ahc_syncrates[maxsync])
   1128  1.42      fvdl 				*period = syncrate->period;
   1129  1.42      fvdl 			break;
   1130  1.42      fvdl 		}
   1131  1.42      fvdl 		syncrate++;
   1132  1.42      fvdl 	}
   1133  1.42      fvdl 
   1134  1.42      fvdl 	if ((*period == 0)
   1135  1.42      fvdl 	 || (syncrate->rate == NULL)
   1136  1.42      fvdl 	 || ((ahc->features & AHC_ULTRA2) != 0
   1137  1.42      fvdl 	  && (syncrate->sxfr_u2 == 0))) {
   1138  1.42      fvdl 		/* Use asynchronous transfers. */
   1139  1.42      fvdl 		*period = 0;
   1140  1.42      fvdl 		syncrate = NULL;
   1141  1.42      fvdl 	}
   1142  1.42      fvdl 	return (syncrate);
   1143  1.42      fvdl }
   1144  1.42      fvdl 
   1145  1.42      fvdl static u_int
   1146  1.42      fvdl ahc_find_period(struct ahc_softc *ahc, u_int scsirate, u_int maxsync)
   1147  1.42      fvdl {
   1148  1.42      fvdl 	struct ahc_syncrate *syncrate;
   1149  1.42      fvdl 
   1150  1.42      fvdl 	if ((ahc->features & AHC_ULTRA2) != 0)
   1151  1.42      fvdl 		scsirate &= SXFR_ULTRA2;
   1152  1.42      fvdl 	else
   1153  1.42      fvdl 		scsirate &= SXFR;
   1154  1.42      fvdl 
   1155  1.42      fvdl 	syncrate = &ahc_syncrates[maxsync];
   1156  1.42      fvdl 	while (syncrate->rate != NULL) {
   1157  1.42      fvdl 
   1158  1.42      fvdl 		if ((ahc->features & AHC_ULTRA2) != 0) {
   1159  1.42      fvdl 			if (syncrate->sxfr_u2 == 0)
   1160  1.42      fvdl 				break;
   1161  1.42      fvdl 			else if (scsirate == (syncrate->sxfr_u2 & SXFR_ULTRA2))
   1162  1.42      fvdl 				return (syncrate->period);
   1163  1.42      fvdl 		} else if (scsirate == (syncrate->sxfr & SXFR)) {
   1164  1.42      fvdl 				return (syncrate->period);
   1165  1.42      fvdl 		}
   1166  1.42      fvdl 		syncrate++;
   1167  1.42      fvdl 	}
   1168  1.42      fvdl 	return (0); /* async */
   1169  1.42      fvdl }
   1170  1.42      fvdl 
   1171  1.42      fvdl static void
   1172  1.42      fvdl ahc_validate_offset(struct ahc_softc *ahc, struct ahc_syncrate *syncrate,
   1173  1.42      fvdl 		    u_int *offset, int wide)
   1174  1.42      fvdl {
   1175  1.42      fvdl 	u_int maxoffset;
   1176  1.42      fvdl 
   1177  1.42      fvdl 	/* Limit offset to what we can do */
   1178  1.42      fvdl 	if (syncrate == NULL) {
   1179  1.42      fvdl 		maxoffset = 0;
   1180  1.42      fvdl 	} else if ((ahc->features & AHC_ULTRA2) != 0) {
   1181  1.42      fvdl 		maxoffset = MAX_OFFSET_ULTRA2;
   1182  1.42      fvdl 	} else {
   1183  1.42      fvdl 		if (wide)
   1184  1.42      fvdl 			maxoffset = MAX_OFFSET_16BIT;
   1185  1.42      fvdl 		else
   1186  1.42      fvdl 			maxoffset = MAX_OFFSET_8BIT;
   1187  1.42      fvdl 	}
   1188  1.42      fvdl 	*offset = MIN(*offset, maxoffset);
   1189  1.42      fvdl }
   1190  1.42      fvdl 
   1191  1.42      fvdl static void
   1192  1.42      fvdl ahc_update_target_msg_request(struct ahc_softc *ahc,
   1193  1.42      fvdl 			      struct ahc_devinfo *devinfo,
   1194  1.42      fvdl 			      struct ahc_initiator_tinfo *tinfo,
   1195  1.42      fvdl 			      int force, int paused)
   1196  1.42      fvdl {
   1197  1.42      fvdl 	u_int targ_msg_req_orig;
   1198  1.42      fvdl 
   1199  1.42      fvdl 	targ_msg_req_orig = ahc->targ_msg_req;
   1200  1.42      fvdl 	if (tinfo->current.period != tinfo->goal.period
   1201  1.42      fvdl 	 || tinfo->current.width != tinfo->goal.width
   1202  1.42      fvdl 	 || tinfo->current.offset != tinfo->goal.offset
   1203  1.42      fvdl 	 || (force
   1204  1.42      fvdl 	  && (tinfo->goal.period != 0
   1205  1.42      fvdl 	   || tinfo->goal.width != MSG_EXT_WDTR_BUS_8_BIT))) {
   1206  1.42      fvdl 		ahc->targ_msg_req |= devinfo->target_mask;
   1207  1.42      fvdl 	} else {
   1208  1.42      fvdl 		ahc->targ_msg_req &= ~devinfo->target_mask;
   1209  1.42      fvdl 	}
   1210  1.42      fvdl 
   1211  1.42      fvdl 	if (ahc->targ_msg_req != targ_msg_req_orig) {
   1212  1.42      fvdl 		/* Update the message request bit for this target */
   1213  1.42      fvdl 		if ((ahc->features & AHC_HS_MAILBOX) != 0) {
   1214  1.42      fvdl 			if (paused) {
   1215  1.42      fvdl 				ahc_outb(ahc, TARGET_MSG_REQUEST,
   1216  1.42      fvdl 					 ahc->targ_msg_req & 0xFF);
   1217  1.42      fvdl 				ahc_outb(ahc, TARGET_MSG_REQUEST + 1,
   1218  1.42      fvdl 					 (ahc->targ_msg_req >> 8) & 0xFF);
   1219  1.42      fvdl 			} else {
   1220  1.42      fvdl 				ahc_outb(ahc, HS_MAILBOX,
   1221  1.42      fvdl 					 0x01 << HOST_MAILBOX_SHIFT);
   1222  1.42      fvdl 			}
   1223  1.42      fvdl 		} else {
   1224  1.42      fvdl 			if (!paused)
   1225  1.42      fvdl 				pause_sequencer(ahc);
   1226  1.42      fvdl 
   1227  1.42      fvdl 			ahc_outb(ahc, TARGET_MSG_REQUEST,
   1228  1.42      fvdl 				 ahc->targ_msg_req & 0xFF);
   1229  1.42      fvdl 			ahc_outb(ahc, TARGET_MSG_REQUEST + 1,
   1230  1.42      fvdl 				 (ahc->targ_msg_req >> 8) & 0xFF);
   1231  1.42      fvdl 
   1232  1.42      fvdl 			if (!paused)
   1233  1.42      fvdl 				unpause_sequencer(ahc);
   1234  1.42      fvdl 		}
   1235  1.42      fvdl 	}
   1236  1.42      fvdl }
   1237  1.42      fvdl 
   1238  1.42      fvdl static void
   1239  1.42      fvdl ahc_set_syncrate(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
   1240  1.42      fvdl 		 struct ahc_syncrate *syncrate,
   1241  1.42      fvdl 		 u_int period, u_int offset, u_int type, int paused, int done)
   1242  1.42      fvdl {
   1243  1.42      fvdl 	struct	ahc_initiator_tinfo *tinfo;
   1244  1.42      fvdl 	struct	tmode_tstate *tstate;
   1245  1.42      fvdl 	u_int	old_period;
   1246  1.42      fvdl 	u_int	old_offset;
   1247  1.42      fvdl 	int	active = (type & AHC_TRANS_ACTIVE) == AHC_TRANS_ACTIVE;
   1248  1.42      fvdl 
   1249  1.42      fvdl 	if (syncrate == NULL) {
   1250  1.42      fvdl 		period = 0;
   1251  1.42      fvdl 		offset = 0;
   1252  1.42      fvdl 	}
   1253  1.42      fvdl 
   1254  1.42      fvdl 	tinfo = ahc_fetch_transinfo(ahc, devinfo->channel, devinfo->our_scsiid,
   1255  1.42      fvdl 				    devinfo->target, &tstate);
   1256  1.42      fvdl 	old_period = tinfo->current.period;
   1257  1.42      fvdl 	old_offset = tinfo->current.offset;
   1258  1.42      fvdl 
   1259  1.42      fvdl 	if ((type & AHC_TRANS_CUR) != 0
   1260  1.42      fvdl 	 && (old_period != period || old_offset != offset)) {
   1261  1.42      fvdl 		u_int	scsirate;
   1262  1.42      fvdl 
   1263  1.42      fvdl 		scsirate = tinfo->scsirate;
   1264  1.42      fvdl 		if ((ahc->features & AHC_ULTRA2) != 0) {
   1265  1.42      fvdl 
   1266  1.42      fvdl 			/* XXX */
   1267  1.42      fvdl 			/* Force single edge until DT is fully implemented */
   1268  1.42      fvdl 			scsirate &= ~(SXFR_ULTRA2|SINGLE_EDGE|ENABLE_CRC);
   1269  1.42      fvdl 			if (syncrate != NULL)
   1270  1.42      fvdl 				scsirate |= syncrate->sxfr_u2|SINGLE_EDGE;
   1271  1.42      fvdl 
   1272  1.42      fvdl 			if (active)
   1273  1.42      fvdl 				ahc_outb(ahc, SCSIOFFSET, offset);
   1274  1.42      fvdl 		} else {
   1275  1.42      fvdl 
   1276  1.42      fvdl 			scsirate &= ~(SXFR|SOFS);
   1277  1.42      fvdl 			/*
   1278  1.42      fvdl 			 * Ensure Ultra mode is set properly for
   1279  1.42      fvdl 			 * this target.
   1280  1.42      fvdl 			 */
   1281  1.42      fvdl 			tstate->ultraenb &= ~devinfo->target_mask;
   1282  1.42      fvdl 			if (syncrate != NULL) {
   1283  1.42      fvdl 				if (syncrate->sxfr & ULTRA_SXFR) {
   1284  1.42      fvdl 					tstate->ultraenb |=
   1285  1.42      fvdl 						devinfo->target_mask;
   1286  1.42      fvdl 				}
   1287  1.42      fvdl 				scsirate |= syncrate->sxfr & SXFR;
   1288  1.42      fvdl 				scsirate |= offset & SOFS;
   1289  1.42      fvdl 			}
   1290  1.42      fvdl 			if (active) {
   1291  1.42      fvdl 				u_int sxfrctl0;
   1292  1.42      fvdl 
   1293  1.42      fvdl 				sxfrctl0 = ahc_inb(ahc, SXFRCTL0);
   1294  1.42      fvdl 				sxfrctl0 &= ~FAST20;
   1295  1.42      fvdl 				if (tstate->ultraenb & devinfo->target_mask)
   1296  1.42      fvdl 					sxfrctl0 |= FAST20;
   1297  1.42      fvdl 				ahc_outb(ahc, SXFRCTL0, sxfrctl0);
   1298  1.42      fvdl 			}
   1299  1.42      fvdl 		}
   1300  1.42      fvdl 		if (active)
   1301  1.42      fvdl 			ahc_outb(ahc, SCSIRATE, scsirate);
   1302  1.42      fvdl 
   1303  1.42      fvdl 		tinfo->scsirate = scsirate;
   1304  1.42      fvdl 		tinfo->current.period = period;
   1305  1.42      fvdl 		tinfo->current.offset = offset;
   1306  1.42      fvdl 
   1307  1.42      fvdl 		/* Update the syncrates in any pending scbs */
   1308  1.42      fvdl 		ahc_update_pending_syncrates(ahc);
   1309  1.42      fvdl 	}
   1310  1.42      fvdl 
   1311  1.42      fvdl 	/*
   1312  1.42      fvdl 	 * Print messages if we're verbose and at the end of a negotiation
   1313  1.42      fvdl 	 * cycle.
   1314  1.42      fvdl 	 */
   1315  1.42      fvdl 	if (done) {
   1316  1.42      fvdl 		if (offset != 0) {
   1317  1.42      fvdl 			printf("%s: target %d synchronous at %sMHz, "
   1318  1.42      fvdl 			       "offset = 0x%x\n", ahc_name(ahc),
   1319  1.42      fvdl 			       devinfo->target, syncrate->rate, offset);
   1320  1.42      fvdl 		} else {
   1321  1.42      fvdl 			printf("%s: target %d using "
   1322  1.42      fvdl 			       "asynchronous transfers\n",
   1323  1.42      fvdl 			       ahc_name(ahc), devinfo->target);
   1324  1.42      fvdl 		}
   1325  1.42      fvdl 	}
   1326  1.42      fvdl 
   1327  1.42      fvdl 	if ((type & AHC_TRANS_GOAL) != 0) {
   1328  1.42      fvdl 		tinfo->goal.period = period;
   1329  1.42      fvdl 		tinfo->goal.offset = offset;
   1330  1.42      fvdl 	}
   1331  1.42      fvdl 
   1332  1.42      fvdl 	if ((type & AHC_TRANS_USER) != 0) {
   1333  1.42      fvdl 		tinfo->user.period = period;
   1334  1.42      fvdl 		tinfo->user.offset = offset;
   1335  1.42      fvdl 	}
   1336  1.42      fvdl 
   1337  1.42      fvdl 	ahc_update_target_msg_request(ahc, devinfo, tinfo,
   1338  1.42      fvdl 				      /*force*/FALSE,
   1339  1.42      fvdl 				      paused);
   1340  1.42      fvdl }
   1341  1.42      fvdl 
   1342  1.42      fvdl static void
   1343  1.42      fvdl ahc_set_width(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
   1344  1.42      fvdl 	      u_int width, u_int type, int paused, int done)
   1345  1.42      fvdl {
   1346  1.42      fvdl 	struct ahc_initiator_tinfo *tinfo;
   1347  1.42      fvdl 	struct tmode_tstate *tstate;
   1348  1.42      fvdl 	u_int  oldwidth;
   1349  1.42      fvdl 	int    active = (type & AHC_TRANS_ACTIVE) == AHC_TRANS_ACTIVE;
   1350  1.42      fvdl 
   1351  1.42      fvdl 	tinfo = ahc_fetch_transinfo(ahc, devinfo->channel, devinfo->our_scsiid,
   1352  1.42      fvdl 				    devinfo->target, &tstate);
   1353  1.42      fvdl 	oldwidth = tinfo->current.width;
   1354  1.42      fvdl 
   1355  1.42      fvdl 	if ((type & AHC_TRANS_CUR) != 0 && oldwidth != width) {
   1356  1.42      fvdl 		u_int	scsirate;
   1357  1.42      fvdl 
   1358  1.42      fvdl 		scsirate =  tinfo->scsirate;
   1359  1.42      fvdl 		scsirate &= ~WIDEXFER;
   1360  1.42      fvdl 		if (width == MSG_EXT_WDTR_BUS_16_BIT)
   1361  1.42      fvdl 			scsirate |= WIDEXFER;
   1362  1.42      fvdl 
   1363  1.42      fvdl 		tinfo->scsirate = scsirate;
   1364  1.42      fvdl 
   1365  1.42      fvdl 		if (active)
   1366  1.42      fvdl 			ahc_outb(ahc, SCSIRATE, scsirate);
   1367  1.42      fvdl 
   1368  1.42      fvdl 		tinfo->current.width = width;
   1369  1.42      fvdl 	}
   1370  1.42      fvdl 
   1371  1.42      fvdl 	if (done) {
   1372  1.42      fvdl 		printf("%s: target %d using %dbit transfers\n",
   1373  1.42      fvdl 		       ahc_name(ahc), devinfo->target,
   1374  1.42      fvdl 		       8 * (0x01 << width));
   1375  1.42      fvdl 	}
   1376  1.42      fvdl 
   1377  1.42      fvdl 	if ((type & AHC_TRANS_GOAL) != 0)
   1378  1.42      fvdl 		tinfo->goal.width = width;
   1379  1.42      fvdl 	if ((type & AHC_TRANS_USER) != 0)
   1380  1.42      fvdl 		tinfo->user.width = width;
   1381  1.42      fvdl 
   1382  1.42      fvdl 	ahc_update_target_msg_request(ahc, devinfo, tinfo,
   1383  1.42      fvdl 				      /*force*/FALSE, paused);
   1384  1.42      fvdl }
   1385  1.42      fvdl 
   1386  1.42      fvdl static void
   1387  1.42      fvdl ahc_set_tags(struct ahc_softc *ahc, struct ahc_devinfo *devinfo, int enable)
   1388  1.42      fvdl {
   1389  1.42      fvdl 	struct ahc_initiator_tinfo *tinfo;
   1390  1.42      fvdl 	struct tmode_tstate *tstate;
   1391  1.42      fvdl 
   1392  1.42      fvdl 	tinfo = ahc_fetch_transinfo(ahc, devinfo->channel, devinfo->our_scsiid,
   1393  1.42      fvdl 				    devinfo->target, &tstate);
   1394  1.42      fvdl 
   1395  1.42      fvdl 	if (enable)
   1396  1.42      fvdl 		tstate->tagenable |= devinfo->target_mask;
   1397  1.49      fvdl 	else {
   1398  1.42      fvdl 		tstate->tagenable &= ~devinfo->target_mask;
   1399  1.49      fvdl 		tstate->tagdisable |= devinfo->target_mask;
   1400  1.49      fvdl 	}
   1401  1.42      fvdl }
   1402  1.42      fvdl 
   1403  1.42      fvdl /*
   1404  1.42      fvdl  * Attach all the sub-devices we can find
   1405  1.42      fvdl  */
   1406  1.42      fvdl int
   1407  1.42      fvdl ahc_attach(struct ahc_softc *ahc)
   1408  1.42      fvdl {
   1409  1.42      fvdl 	TAILQ_INIT(&ahc->sc_q);
   1410  1.42      fvdl 
   1411  1.42      fvdl 	ahc->sc_adapter.scsipi_cmd = ahc_action;
   1412  1.42      fvdl 	ahc->sc_adapter.scsipi_minphys = ahcminphys;
   1413  1.52      fvdl 	ahc->sc_adapter.scsipi_ioctl = ahc_ioctl;
   1414  1.42      fvdl 	ahc->sc_link.type = BUS_SCSI;
   1415  1.42      fvdl 	ahc->sc_link.scsipi_scsi.adapter_target = ahc->our_id;
   1416  1.42      fvdl 	ahc->sc_link.scsipi_scsi.channel = 0;
   1417  1.42      fvdl 	ahc->sc_link.scsipi_scsi.max_target =
   1418  1.42      fvdl 	    (ahc->features & AHC_WIDE) ? 15 : 7;
   1419  1.42      fvdl 	ahc->sc_link.scsipi_scsi.max_lun = 7;
   1420  1.42      fvdl 	ahc->sc_link.adapter_softc = ahc;
   1421  1.42      fvdl 	ahc->sc_link.adapter = &ahc->sc_adapter;
   1422  1.42      fvdl 	ahc->sc_link.openings = 2;
   1423  1.42      fvdl 	ahc->sc_link.device = &ahc_dev;
   1424  1.42      fvdl 
   1425  1.42      fvdl 	if (ahc->features & AHC_TWIN) {
   1426  1.42      fvdl 		ahc->sc_link_b = ahc->sc_link;
   1427  1.42      fvdl 		ahc->sc_link_b.scsipi_scsi.adapter_target = ahc->our_id_b;
   1428  1.42      fvdl 		ahc->sc_link_b.scsipi_scsi.channel = 1;
   1429  1.42      fvdl 	}
   1430  1.42      fvdl 
   1431  1.42      fvdl 	if ((ahc->flags & AHC_CHANNEL_B_PRIMARY) == 0) {
   1432  1.42      fvdl 		ahc->sc_link_b.scsipi_scsi.scsibus = 0xff;
   1433  1.42      fvdl 		config_found((void *)ahc, &ahc->sc_link, scsiprint);
   1434  1.42      fvdl 		if (ahc->features & AHC_TWIN)
   1435  1.42      fvdl 			config_found((void *)ahc, &ahc->sc_link_b, scsiprint);
   1436  1.42      fvdl 	} else {
   1437  1.42      fvdl 		config_found((void *)ahc, &ahc->sc_link_b, scsiprint);
   1438  1.42      fvdl 		config_found((void *)ahc, &ahc->sc_link, scsiprint);
   1439  1.42      fvdl 	}
   1440  1.42      fvdl 	return 1;
   1441  1.42      fvdl }
   1442  1.42      fvdl 
   1443  1.42      fvdl static void
   1444  1.42      fvdl ahc_fetch_devinfo(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
   1445  1.42      fvdl {
   1446  1.42      fvdl 	u_int	saved_tcl;
   1447  1.42      fvdl 	role_t	role;
   1448  1.42      fvdl 	int	our_id;
   1449  1.42      fvdl 
   1450  1.42      fvdl 	if (ahc_inb(ahc, SSTAT0) & TARGET)
   1451  1.42      fvdl 		role = ROLE_TARGET;
   1452  1.42      fvdl 	else
   1453  1.42      fvdl 		role = ROLE_INITIATOR;
   1454  1.42      fvdl 
   1455  1.42      fvdl 	if (role == ROLE_TARGET
   1456  1.42      fvdl 	 && (ahc->features & AHC_MULTI_TID) != 0
   1457  1.42      fvdl 	 && (ahc_inb(ahc, SEQ_FLAGS) & CMDPHASE_PENDING) != 0) {
   1458  1.42      fvdl 		/* We were selected, so pull our id from TARGIDIN */
   1459  1.42      fvdl 		our_id = ahc_inb(ahc, TARGIDIN) & OID;
   1460  1.42      fvdl 	} else if ((ahc->features & AHC_ULTRA2) != 0)
   1461  1.42      fvdl 		our_id = ahc_inb(ahc, SCSIID_ULTRA2) & OID;
   1462  1.42      fvdl 	else
   1463  1.42      fvdl 		our_id = ahc_inb(ahc, SCSIID) & OID;
   1464  1.42      fvdl 
   1465  1.42      fvdl 	saved_tcl = ahc_inb(ahc, SAVED_TCL);
   1466  1.42      fvdl 	ahc_compile_devinfo(devinfo, our_id, TCL_TARGET(saved_tcl),
   1467  1.42      fvdl 			    TCL_LUN(saved_tcl), TCL_CHANNEL(ahc, saved_tcl),
   1468  1.42      fvdl 			    role);
   1469  1.42      fvdl }
   1470  1.42      fvdl 
   1471  1.42      fvdl static void
   1472  1.42      fvdl ahc_compile_devinfo(struct ahc_devinfo *devinfo, u_int our_id, u_int target,
   1473  1.42      fvdl 		    u_int lun, char channel, role_t role)
   1474  1.42      fvdl {
   1475  1.42      fvdl 	devinfo->our_scsiid = our_id;
   1476  1.42      fvdl 	devinfo->target = target;
   1477  1.42      fvdl 	devinfo->lun = lun;
   1478  1.42      fvdl 	devinfo->target_offset = target;
   1479  1.42      fvdl 	devinfo->channel = channel;
   1480  1.42      fvdl 	devinfo->role = role;
   1481  1.42      fvdl 	if (channel == 'B')
   1482  1.42      fvdl 		devinfo->target_offset += 8;
   1483  1.42      fvdl 	devinfo->target_mask = (0x01 << devinfo->target_offset);
   1484  1.42      fvdl }
   1485  1.42      fvdl 
   1486  1.42      fvdl /*
   1487  1.42      fvdl  * Catch an interrupt from the adapter
   1488  1.42      fvdl  */
   1489  1.42      fvdl int
   1490  1.42      fvdl ahc_intr(void *arg)
   1491  1.42      fvdl {
   1492  1.42      fvdl 	struct	ahc_softc *ahc;
   1493  1.42      fvdl 	u_int	intstat;
   1494  1.42      fvdl 
   1495  1.42      fvdl 	ahc = (struct ahc_softc *)arg;
   1496  1.42      fvdl 
   1497  1.42      fvdl 	intstat = ahc_inb(ahc, INTSTAT);
   1498  1.42      fvdl 
   1499  1.42      fvdl 	/*
   1500  1.42      fvdl 	 * Any interrupts to process?
   1501  1.42      fvdl 	 */
   1502  1.42      fvdl 	if ((intstat & INT_PEND) == 0) {
   1503  1.43      fvdl 		if (ahc->bus_intr && ahc->bus_intr(ahc)) {
   1504  1.43      fvdl #ifdef AHC_DEBUG
   1505  1.43      fvdl 			printf("%s: bus intr: CCHADDR %x HADDR %x SEQADDR %x\n",
   1506  1.42      fvdl 			    ahc_name(ahc),
   1507  1.42      fvdl 			    ahc_inb(ahc, CCHADDR) |
   1508  1.42      fvdl 			    (ahc_inb(ahc, CCHADDR+1) << 8)
   1509  1.42      fvdl 			    | (ahc_inb(ahc, CCHADDR+2) << 16)
   1510  1.42      fvdl 			    | (ahc_inb(ahc, CCHADDR+3) << 24),
   1511  1.42      fvdl 			    ahc_inb(ahc, HADDR) | (ahc_inb(ahc, HADDR+1) << 8)
   1512  1.42      fvdl 			    | (ahc_inb(ahc, HADDR+2) << 16)
   1513  1.42      fvdl 			    | (ahc_inb(ahc, HADDR+3) << 24),
   1514  1.42      fvdl 			    ahc_inb(ahc, SEQADDR0) |
   1515  1.42      fvdl 			    (ahc_inb(ahc, SEQADDR1) << 8));
   1516  1.42      fvdl #endif
   1517  1.42      fvdl 			return 1;
   1518  1.42      fvdl 		}
   1519  1.42      fvdl 		return 0;
   1520  1.42      fvdl 	}
   1521  1.42      fvdl 
   1522  1.42      fvdl #ifdef AHC_DEBUG
   1523  1.42      fvdl 	if (ahc_debug & AHC_SHOWINTR) {
   1524  1.42      fvdl 		printf("%s: intstat %x\n", ahc_name(ahc), intstat);
   1525  1.42      fvdl 	}
   1526  1.42      fvdl #endif
   1527  1.42      fvdl 
   1528  1.42      fvdl 	if (intstat & CMDCMPLT) {
   1529  1.42      fvdl 		ahc_outb(ahc, CLRINT, CLRCMDINT);
   1530  1.42      fvdl 		ahc_run_qoutfifo(ahc);
   1531  1.42      fvdl 	}
   1532  1.42      fvdl 	if (intstat & BRKADRINT) {
   1533  1.42      fvdl 		/*
   1534  1.42      fvdl 		 * We upset the sequencer :-(
   1535  1.42      fvdl 		 * Lookup the error message
   1536  1.42      fvdl 		 */
   1537  1.42      fvdl 		int i, error, num_errors;
   1538  1.42      fvdl 
   1539  1.42      fvdl 		error = ahc_inb(ahc, ERROR);
   1540  1.42      fvdl 		num_errors =  sizeof(hard_error)/sizeof(hard_error[0]);
   1541  1.42      fvdl 		for (i = 0; error != 1 && i < num_errors; i++)
   1542  1.42      fvdl 			error >>= 1;
   1543  1.42      fvdl 		panic("%s: brkadrint, %s at seqaddr = 0x%x\n",
   1544  1.42      fvdl 		      ahc_name(ahc), hard_error[i].errmesg,
   1545  1.42      fvdl 		      ahc_inb(ahc, SEQADDR0) |
   1546  1.42      fvdl 		      (ahc_inb(ahc, SEQADDR1) << 8));
   1547  1.42      fvdl 
   1548  1.42      fvdl 		/* Tell everyone that this HBA is no longer availible */
   1549  1.42      fvdl 		ahc_abort_scbs(ahc, AHC_TARGET_WILDCARD, ALL_CHANNELS,
   1550  1.42      fvdl 			       AHC_LUN_WILDCARD, SCB_LIST_NULL, ROLE_UNKNOWN,
   1551  1.42      fvdl 			       XS_DRIVER_STUFFUP);
   1552  1.42      fvdl 	}
   1553  1.42      fvdl 	if (intstat & SEQINT)
   1554  1.42      fvdl 		ahc_handle_seqint(ahc, intstat);
   1555  1.42      fvdl 
   1556  1.42      fvdl 	if (intstat & SCSIINT)
   1557  1.42      fvdl 		ahc_handle_scsiint(ahc, intstat);
   1558  1.42      fvdl 
   1559  1.42      fvdl 	return 1;
   1560  1.42      fvdl }
   1561  1.42      fvdl 
   1562  1.42      fvdl static struct tmode_tstate *
   1563  1.42      fvdl ahc_alloc_tstate(struct ahc_softc *ahc, u_int scsi_id, char channel)
   1564  1.42      fvdl {
   1565  1.42      fvdl 	struct tmode_tstate *master_tstate;
   1566  1.42      fvdl 	struct tmode_tstate *tstate;
   1567  1.42      fvdl 	int i, s;
   1568  1.42      fvdl 
   1569  1.42      fvdl 	master_tstate = ahc->enabled_targets[ahc->our_id];
   1570  1.42      fvdl 	if (channel == 'B') {
   1571  1.42      fvdl 		scsi_id += 8;
   1572  1.42      fvdl 		master_tstate = ahc->enabled_targets[ahc->our_id_b + 8];
   1573  1.42      fvdl 	}
   1574  1.42      fvdl 	if (ahc->enabled_targets[scsi_id] != NULL
   1575  1.42      fvdl 	 && ahc->enabled_targets[scsi_id] != master_tstate)
   1576  1.42      fvdl 		panic("%s: ahc_alloc_tstate - Target already allocated",
   1577  1.42      fvdl 		      ahc_name(ahc));
   1578  1.42      fvdl 	tstate = malloc(sizeof(*tstate), M_DEVBUF, M_NOWAIT);
   1579  1.42      fvdl 	if (tstate == NULL)
   1580  1.42      fvdl 		return (NULL);
   1581  1.42      fvdl 
   1582  1.42      fvdl 	/*
   1583  1.42      fvdl 	 * If we have allocated a master tstate, copy user settings from
   1584  1.42      fvdl 	 * the master tstate (taken from SRAM or the EEPROM) for this
   1585  1.42      fvdl 	 * channel, but reset our current and goal settings to async/narrow
   1586  1.42      fvdl 	 * until an initiator talks to us.
   1587  1.42      fvdl 	 */
   1588  1.42      fvdl 	if (master_tstate != NULL) {
   1589  1.42      fvdl 		bcopy(master_tstate, tstate, sizeof(*tstate));
   1590  1.42      fvdl 		tstate->ultraenb = 0;
   1591  1.42      fvdl 		for (i = 0; i < 16; i++) {
   1592  1.42      fvdl 			bzero(&tstate->transinfo[i].current,
   1593  1.42      fvdl 			      sizeof(tstate->transinfo[i].current));
   1594  1.42      fvdl 			bzero(&tstate->transinfo[i].goal,
   1595  1.42      fvdl 			      sizeof(tstate->transinfo[i].goal));
   1596  1.42      fvdl 		}
   1597  1.42      fvdl 	} else
   1598  1.42      fvdl 		bzero(tstate, sizeof(*tstate));
   1599  1.42      fvdl 	s = splbio();
   1600  1.42      fvdl 	ahc->enabled_targets[scsi_id] = tstate;
   1601  1.42      fvdl 	splx(s);
   1602  1.42      fvdl 	return (tstate);
   1603  1.42      fvdl }
   1604  1.42      fvdl 
   1605  1.42      fvdl #if UNUSED
   1606  1.42      fvdl static void
   1607  1.42      fvdl ahc_free_tstate(struct ahc_softc *ahc, u_int scsi_id, char channel, int force)
   1608  1.42      fvdl {
   1609  1.42      fvdl 	struct tmode_tstate *tstate;
   1610  1.42      fvdl 
   1611  1.42      fvdl 	/* Don't clean up the entry for our initiator role */
   1612  1.42      fvdl 	if ((ahc->flags & AHC_INITIATORMODE) != 0
   1613  1.42      fvdl 	 && ((channel == 'B' && scsi_id == ahc->our_id_b)
   1614  1.42      fvdl 	  || (channel == 'A' && scsi_id == ahc->our_id))
   1615  1.42      fvdl 	 && force == FALSE)
   1616  1.42      fvdl 		return;
   1617  1.42      fvdl 
   1618  1.42      fvdl 	if (channel == 'B')
   1619  1.42      fvdl 		scsi_id += 8;
   1620  1.42      fvdl 	tstate = ahc->enabled_targets[scsi_id];
   1621  1.42      fvdl 	if (tstate != NULL)
   1622  1.42      fvdl 		free(tstate, M_DEVBUF);
   1623  1.42      fvdl 	ahc->enabled_targets[scsi_id] = NULL;
   1624  1.42      fvdl }
   1625  1.42      fvdl #endif
   1626  1.42      fvdl 
   1627  1.42      fvdl static void
   1628  1.42      fvdl ahc_handle_seqint(struct ahc_softc *ahc, u_int intstat)
   1629  1.42      fvdl {
   1630  1.42      fvdl 	struct scb *scb;
   1631  1.42      fvdl 	struct ahc_devinfo devinfo;
   1632  1.42      fvdl 
   1633  1.42      fvdl 	ahc_fetch_devinfo(ahc, &devinfo);
   1634  1.42      fvdl 
   1635  1.42      fvdl 	/*
   1636  1.42      fvdl 	 * Clear the upper byte that holds SEQINT status
   1637  1.42      fvdl 	 * codes and clear the SEQINT bit. We will unpause
   1638  1.42      fvdl 	 * the sequencer, if appropriate, after servicing
   1639  1.42      fvdl 	 * the request.
   1640  1.42      fvdl 	 */
   1641  1.42      fvdl 	ahc_outb(ahc, CLRINT, CLRSEQINT);
   1642  1.42      fvdl 	switch (intstat & SEQINT_MASK) {
   1643  1.42      fvdl 	case NO_MATCH:
   1644  1.42      fvdl 	{
   1645  1.42      fvdl 		/* Ensure we don't leave the selection hardware on */
   1646  1.42      fvdl 		ahc_outb(ahc, SCSISEQ,
   1647  1.42      fvdl 			 ahc_inb(ahc, SCSISEQ) & (ENSELI|ENRSELI|ENAUTOATNP));
   1648  1.42      fvdl 
   1649  1.42      fvdl 		printf("%s:%c:%d: no active SCB for reconnecting "
   1650  1.42      fvdl 		       "target - issuing BUS DEVICE RESET\n",
   1651  1.42      fvdl 		       ahc_name(ahc), devinfo.channel, devinfo.target);
   1652  1.42      fvdl 		printf("SAVED_TCL == 0x%x, ARG_1 == 0x%x, SEQ_FLAGS == 0x%x\n",
   1653  1.42      fvdl 		       ahc_inb(ahc, SAVED_TCL), ahc_inb(ahc, ARG_1),
   1654  1.42      fvdl 		       ahc_inb(ahc, SEQ_FLAGS));
   1655  1.42      fvdl 		ahc->msgout_buf[0] = MSG_BUS_DEV_RESET;
   1656  1.42      fvdl 		ahc->msgout_len = 1;
   1657  1.42      fvdl 		ahc->msgout_index = 0;
   1658  1.42      fvdl 		ahc->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
   1659  1.42      fvdl 		ahc_outb(ahc, MSG_OUT, HOST_MSG);
   1660  1.42      fvdl 		ahc_outb(ahc, SCSISIGO, ahc_inb(ahc, LASTPHASE) | ATNO);
   1661  1.42      fvdl 		break;
   1662  1.42      fvdl 	}
   1663  1.42      fvdl 	case UPDATE_TMSG_REQ:
   1664  1.42      fvdl 		ahc_outb(ahc, TARGET_MSG_REQUEST, ahc->targ_msg_req & 0xFF);
   1665  1.42      fvdl 		ahc_outb(ahc, TARGET_MSG_REQUEST + 1,
   1666  1.42      fvdl 			 (ahc->targ_msg_req >> 8) & 0xFF);
   1667  1.42      fvdl 		ahc_outb(ahc, HS_MAILBOX, 0);
   1668  1.42      fvdl 		break;
   1669  1.42      fvdl 	case SEND_REJECT:
   1670  1.42      fvdl 	{
   1671  1.42      fvdl 		u_int rejbyte = ahc_inb(ahc, ACCUM);
   1672  1.42      fvdl 		printf("%s:%c:%d: Warning - unknown message received from "
   1673  1.42      fvdl 		       "target (0x%x).  Rejecting\n",
   1674  1.42      fvdl 		       ahc_name(ahc), devinfo.channel, devinfo.target, rejbyte);
   1675  1.42      fvdl 		break;
   1676  1.42      fvdl 	}
   1677  1.42      fvdl 	case NO_IDENT:
   1678  1.42      fvdl 	{
   1679  1.42      fvdl 		/*
   1680  1.42      fvdl 		 * The reconnecting target either did not send an identify
   1681  1.42      fvdl 		 * message, or did, but we didn't find and SCB to match and
   1682  1.42      fvdl 		 * before it could respond to our ATN/abort, it hit a dataphase.
   1683  1.42      fvdl 		 * The only safe thing to do is to blow it away with a bus
   1684  1.42      fvdl 		 * reset.
   1685  1.42      fvdl 		 */
   1686  1.42      fvdl 		int found;
   1687  1.42      fvdl 
   1688  1.42      fvdl 		printf("%s:%c:%d: Target did not send an IDENTIFY message. "
   1689  1.42      fvdl 		       "LASTPHASE = 0x%x, SAVED_TCL == 0x%x\n",
   1690  1.42      fvdl 		       ahc_name(ahc), devinfo.channel, devinfo.target,
   1691  1.42      fvdl 		       ahc_inb(ahc, LASTPHASE), ahc_inb(ahc, SAVED_TCL));
   1692  1.42      fvdl 		found = ahc_reset_channel(ahc, devinfo.channel,
   1693  1.42      fvdl 					  /*initiate reset*/TRUE);
   1694  1.42      fvdl 		printf("%s: Issued Channel %c Bus Reset. "
   1695  1.42      fvdl 		       "%d SCBs aborted\n", ahc_name(ahc), devinfo.channel,
   1696  1.42      fvdl 		       found);
   1697  1.42      fvdl 		return;
   1698  1.42      fvdl 	}
   1699  1.42      fvdl 	case BAD_PHASE:
   1700  1.42      fvdl 	{
   1701  1.42      fvdl 		u_int lastphase;
   1702  1.42      fvdl 
   1703  1.42      fvdl 		lastphase = ahc_inb(ahc, LASTPHASE);
   1704  1.42      fvdl 		if (lastphase == P_BUSFREE) {
   1705  1.42      fvdl 			printf("%s:%c:%d: Missed busfree.  Curphase = 0x%x\n",
   1706  1.42      fvdl 			       ahc_name(ahc), devinfo.channel, devinfo.target,
   1707  1.42      fvdl 			       ahc_inb(ahc, SCSISIGI));
   1708  1.42      fvdl 			restart_sequencer(ahc);
   1709  1.42      fvdl 			return;
   1710  1.42      fvdl 		} else {
   1711  1.42      fvdl 			printf("%s:%c:%d: unknown scsi bus phase %x.  "
   1712  1.42      fvdl 			       "Attempting to continue\n",
   1713  1.42      fvdl 			       ahc_name(ahc), devinfo.channel, devinfo.target,
   1714  1.42      fvdl 			       ahc_inb(ahc, SCSISIGI));
   1715  1.42      fvdl 		}
   1716  1.42      fvdl 		break;
   1717  1.42      fvdl 	}
   1718  1.42      fvdl 	case BAD_STATUS:
   1719  1.42      fvdl 	{
   1720  1.42      fvdl 		u_int  scb_index;
   1721  1.42      fvdl 		struct hardware_scb *hscb;
   1722  1.42      fvdl 		struct scsipi_xfer *xs;
   1723  1.42      fvdl 		/*
   1724  1.42      fvdl 		 * The sequencer will notify us when a command
   1725  1.42      fvdl 		 * has an error that would be of interest to
   1726  1.42      fvdl 		 * the kernel.  This allows us to leave the sequencer
   1727  1.42      fvdl 		 * running in the common case of command completes
   1728  1.42      fvdl 		 * without error.  The sequencer will already have
   1729  1.42      fvdl 		 * dma'd the SCB back up to us, so we can reference
   1730  1.42      fvdl 		 * the in kernel copy directly.
   1731  1.42      fvdl 		 */
   1732  1.42      fvdl 		scb_index = ahc_inb(ahc, SCB_TAG);
   1733  1.42      fvdl 		scb = &ahc->scb_data->scbarray[scb_index];
   1734  1.42      fvdl 
   1735  1.42      fvdl 		/* ahc_print_scb(scb); */
   1736  1.42      fvdl 
   1737  1.42      fvdl 		/*
   1738  1.42      fvdl 		 * Set the default return value to 0 (don't
   1739  1.42      fvdl 		 * send sense).  The sense code will change
   1740  1.42      fvdl 		 * this if needed.
   1741  1.42      fvdl 		 */
   1742  1.42      fvdl 		ahc_outb(ahc, RETURN_1, 0);
   1743  1.42      fvdl 		if (!(scb_index < ahc->scb_data->numscbs
   1744  1.42      fvdl 		   && (scb->flags & SCB_ACTIVE) != 0)) {
   1745  1.42      fvdl 			printf("%s:%c:%d: ahc_intr - referenced scb "
   1746  1.42      fvdl 			       "not valid during seqint 0x%x scb(%d)\n",
   1747  1.42      fvdl 			       ahc_name(ahc), devinfo.channel,
   1748  1.42      fvdl 			       devinfo.target, intstat, scb_index);
   1749  1.42      fvdl 			goto unpause;
   1750  1.42      fvdl 		}
   1751  1.42      fvdl 
   1752  1.42      fvdl 		hscb = scb->hscb;
   1753  1.42      fvdl 		xs = scb->xs;
   1754  1.42      fvdl 
   1755  1.42      fvdl 		/* Don't want to clobber the original sense code */
   1756  1.42      fvdl 		if ((scb->flags & SCB_SENSE) != 0) {
   1757  1.42      fvdl 			/*
   1758  1.42      fvdl 			 * Clear the SCB_SENSE Flag and have
   1759  1.42      fvdl 			 * the sequencer do a normal command
   1760  1.42      fvdl 			 * complete.
   1761  1.42      fvdl 			 */
   1762  1.42      fvdl 			scb->flags &= ~SCB_SENSE;
   1763  1.42      fvdl 			ahcsetccbstatus(xs, XS_DRIVER_STUFFUP);
   1764  1.42      fvdl 			break;
   1765  1.42      fvdl 		}
   1766  1.42      fvdl 		/* Freeze the queue unit the client sees the error. */
   1767  1.42      fvdl 		ahc_freeze_devq(ahc, xs->sc_link);
   1768  1.42      fvdl 		ahc_freeze_ccb(scb);
   1769  1.42      fvdl 		xs->status = hscb->status;
   1770  1.42      fvdl 		switch (hscb->status) {
   1771  1.42      fvdl 		case SCSI_STATUS_OK:
   1772  1.42      fvdl 			printf("%s: Interrupted for status of 0???\n",
   1773  1.42      fvdl 			       ahc_name(ahc));
   1774  1.42      fvdl 			break;
   1775  1.42      fvdl 		case SCSI_STATUS_CMD_TERMINATED:
   1776  1.42      fvdl 		case SCSI_STATUS_CHECK_COND:
   1777  1.42      fvdl #if defined(AHC_DEBUG)
   1778  1.42      fvdl 			if (ahc_debug & AHC_SHOWSENSE) {
   1779  1.42      fvdl 				scsi_print_addr(xs->sc_link);
   1780  1.42      fvdl 				printf("Check Status, resid %d datalen %d\n",
   1781  1.42      fvdl 				    xs->resid, xs->datalen);
   1782  1.42      fvdl 			}
   1783  1.42      fvdl #endif
   1784  1.42      fvdl 
   1785  1.42      fvdl 			if (xs->error == XS_NOERROR &&
   1786  1.42      fvdl 			    !(scb->flags & SCB_SENSE)) {
   1787  1.42      fvdl 				struct ahc_dma_seg *sg;
   1788  1.42      fvdl 				struct scsipi_sense *sc;
   1789  1.42      fvdl 				struct ahc_initiator_tinfo *tinfo;
   1790  1.42      fvdl 				struct tmode_tstate *tstate;
   1791  1.42      fvdl 
   1792  1.42      fvdl 				sg = scb->sg_list;
   1793  1.42      fvdl 				sc = (struct scsipi_sense *)(&hscb->cmdstore);
   1794  1.42      fvdl 				/*
   1795  1.42      fvdl 				 * Save off the residual if there is one.
   1796  1.42      fvdl 				 */
   1797  1.42      fvdl 				if (hscb->residual_SG_count != 0)
   1798  1.42      fvdl 					ahc_calc_residual(scb);
   1799  1.42      fvdl 				else
   1800  1.42      fvdl 					xs->resid = 0;
   1801  1.42      fvdl 
   1802  1.42      fvdl #ifdef AHC_DEBUG
   1803  1.42      fvdl 				if (ahc_debug & AHC_SHOWSENSE) {
   1804  1.42      fvdl 					scsi_print_addr(xs->sc_link);
   1805  1.42      fvdl 					printf("Sending Sense\n");
   1806  1.42      fvdl 				}
   1807  1.42      fvdl #endif
   1808  1.42      fvdl 				sg->addr = ahc->scb_data->sense_busaddr +
   1809  1.42      fvdl 				   (hscb->tag*sizeof(struct scsipi_sense_data));
   1810  1.42      fvdl 				sg->len = sizeof (struct scsipi_sense_data);
   1811  1.42      fvdl 
   1812  1.42      fvdl 				sc->opcode = REQUEST_SENSE;
   1813  1.42      fvdl 				sc->byte2 =  SCB_LUN(scb) << 5;
   1814  1.42      fvdl 				sc->unused[0] = 0;
   1815  1.42      fvdl 				sc->unused[1] = 0;
   1816  1.42      fvdl 				sc->length = sg->len;
   1817  1.42      fvdl 				sc->control = 0;
   1818  1.42      fvdl 
   1819  1.42      fvdl 				/*
   1820  1.42      fvdl 				 * Would be nice to preserve DISCENB here,
   1821  1.42      fvdl 				 * but due to the way we page SCBs, we can't.
   1822  1.42      fvdl 				 */
   1823  1.42      fvdl 				hscb->control = 0;
   1824  1.42      fvdl 
   1825  1.42      fvdl 				/*
   1826  1.42      fvdl 				 * This request sense could be because the
   1827  1.42      fvdl 				 * the device lost power or in some other
   1828  1.42      fvdl 				 * way has lost our transfer negotiations.
   1829  1.42      fvdl 				 * Renegotiate if appropriate.  Unit attention
   1830  1.42      fvdl 				 * errors will be reported before any data
   1831  1.42      fvdl 				 * phases occur.
   1832  1.42      fvdl 				 */
   1833  1.42      fvdl 				ahc_calc_residual(scb);
   1834  1.42      fvdl #if defined(AHC_DEBUG)
   1835  1.42      fvdl 				if (ahc_debug & AHC_SHOWSENSE) {
   1836  1.42      fvdl 					scsi_print_addr(xs->sc_link);
   1837  1.42      fvdl 					printf("Sense: datalen %d resid %d"
   1838  1.42      fvdl 					       "chan %d id %d targ %d\n",
   1839  1.42      fvdl 					    xs->datalen, xs->resid,
   1840  1.42      fvdl 					    devinfo.channel, devinfo.our_scsiid,
   1841  1.42      fvdl 					    devinfo.target);
   1842  1.42      fvdl 				}
   1843  1.42      fvdl #endif
   1844  1.42      fvdl 				if (xs->datalen > 0 &&
   1845  1.42      fvdl 				    xs->resid == xs->datalen) {
   1846  1.42      fvdl 					tinfo = ahc_fetch_transinfo(ahc,
   1847  1.42      fvdl 							    devinfo.channel,
   1848  1.42      fvdl 							    devinfo.our_scsiid,
   1849  1.42      fvdl 							    devinfo.target,
   1850  1.42      fvdl 							    &tstate);
   1851  1.42      fvdl 					ahc_update_target_msg_request(ahc,
   1852  1.42      fvdl 							      &devinfo,
   1853  1.42      fvdl 							      tinfo,
   1854  1.42      fvdl 							      /*force*/TRUE,
   1855  1.42      fvdl 							      /*paused*/TRUE);
   1856  1.42      fvdl 				}
   1857  1.42      fvdl 				hscb->status = 0;
   1858  1.42      fvdl 				hscb->SG_count = 1;
   1859  1.42      fvdl 				hscb->SG_pointer = scb->sg_list_phys;
   1860  1.42      fvdl 				hscb->data = sg->addr;
   1861  1.42      fvdl 				hscb->datalen = sg->len;
   1862  1.42      fvdl 				hscb->cmdpointer = hscb->cmdstore_busaddr;
   1863  1.42      fvdl 				hscb->cmdlen = sizeof(*sc);
   1864  1.42      fvdl 				scb->sg_count = hscb->SG_count;
   1865  1.42      fvdl 				ahc_swap_hscb(hscb);
   1866  1.42      fvdl 				ahc_swap_sg(scb->sg_list);
   1867  1.42      fvdl 				scb->flags |= SCB_SENSE;
   1868  1.42      fvdl 				/*
   1869  1.42      fvdl 				 * Ensure the target is busy since this
   1870  1.42      fvdl 				 * will be an untagged request.
   1871  1.42      fvdl 				 */
   1872  1.42      fvdl 				ahc_busy_tcl(ahc, scb);
   1873  1.42      fvdl 				ahc_outb(ahc, RETURN_1, SEND_SENSE);
   1874  1.42      fvdl 
   1875  1.42      fvdl 				/*
   1876  1.42      fvdl 				 * Ensure we have enough time to actually
   1877  1.42      fvdl 				 * retrieve the sense.
   1878  1.42      fvdl 				 */
   1879  1.42      fvdl 				if (!(scb->xs->xs_control & XS_CTL_POLL)) {
   1880  1.44   thorpej 					callout_reset(&scb->xs->xs_callout,
   1881  1.44   thorpej 					    5 * hz, ahc_timeout, scb);
   1882  1.42      fvdl 				}
   1883  1.42      fvdl 			}
   1884  1.42      fvdl 			break;
   1885  1.49      fvdl 		case SCSI_STATUS_QUEUE_FULL:
   1886  1.49      fvdl 			scsi_print_addr(xs->sc_link);
   1887  1.49      fvdl 			printf("queue full\n");
   1888  1.42      fvdl 		case SCSI_STATUS_BUSY:
   1889  1.42      fvdl 			/*
   1890  1.53      fvdl 			 * XXX middle layer doesn't handle XS_BUSY well.
   1891  1.57      fvdl 			 * So, requeue this ourselves internally.
   1892  1.42      fvdl 			 */
   1893  1.53      fvdl 			xs->error = XS_BUSY;
   1894  1.53      fvdl 			scb->flags |= SCB_REQUEUE;
   1895  1.42      fvdl 			break;
   1896  1.42      fvdl 		}
   1897  1.42      fvdl 		break;
   1898  1.42      fvdl 	}
   1899  1.42      fvdl 	case TRACE_POINT:
   1900  1.42      fvdl 	{
   1901  1.42      fvdl 		printf("SSTAT2 = 0x%x DFCNTRL = 0x%x\n", ahc_inb(ahc, SSTAT2),
   1902  1.42      fvdl 		       ahc_inb(ahc, DFCNTRL));
   1903  1.42      fvdl 		printf("SSTAT3 = 0x%x DSTATUS = 0x%x\n", ahc_inb(ahc, SSTAT3),
   1904  1.42      fvdl 		       ahc_inb(ahc, DFSTATUS));
   1905  1.42      fvdl 		printf("SSTAT0 = 0x%x, SCB_DATACNT = 0x%x\n",
   1906  1.42      fvdl 		       ahc_inb(ahc, SSTAT0),
   1907  1.42      fvdl 		       ahc_inb(ahc, SCB_DATACNT));
   1908  1.42      fvdl 		break;
   1909  1.42      fvdl 	}
   1910  1.42      fvdl 	case HOST_MSG_LOOP:
   1911  1.42      fvdl 	{
   1912  1.42      fvdl 		/*
   1913  1.42      fvdl 		 * The sequencer has encountered a message phase
   1914  1.42      fvdl 		 * that requires host assistance for completion.
   1915  1.42      fvdl 		 * While handling the message phase(s), we will be
   1916  1.42      fvdl 		 * notified by the sequencer after each byte is
   1917  1.42      fvdl 		 * transfered so we can track bus phases.
   1918  1.42      fvdl 		 *
   1919  1.42      fvdl 		 * If this is the first time we've seen a HOST_MSG_LOOP,
   1920  1.42      fvdl 		 * initialize the state of the host message loop.
   1921  1.42      fvdl 		 */
   1922  1.42      fvdl 		if (ahc->msg_type == MSG_TYPE_NONE) {
   1923  1.42      fvdl 			u_int bus_phase;
   1924  1.42      fvdl 
   1925  1.42      fvdl 			bus_phase = ahc_inb(ahc, SCSISIGI) & PHASE_MASK;
   1926  1.42      fvdl 			if (bus_phase != P_MESGIN
   1927  1.42      fvdl 			 && bus_phase != P_MESGOUT) {
   1928  1.42      fvdl 				printf("ahc_intr: HOST_MSG_LOOP bad "
   1929  1.42      fvdl 				       "phase 0x%x\n",
   1930  1.42      fvdl 				      bus_phase);
   1931  1.42      fvdl 				/*
   1932  1.42      fvdl 				 * Probably transitioned to bus free before
   1933  1.42      fvdl 				 * we got here.  Just punt the message.
   1934  1.42      fvdl 				 */
   1935  1.42      fvdl 				ahc_clear_intstat(ahc);
   1936  1.42      fvdl 				restart_sequencer(ahc);
   1937  1.42      fvdl 			}
   1938  1.42      fvdl 
   1939  1.42      fvdl 			if (devinfo.role == ROLE_INITIATOR) {
   1940  1.42      fvdl 				struct scb *scb;
   1941  1.42      fvdl 				u_int scb_index;
   1942  1.42      fvdl 
   1943  1.42      fvdl 				scb_index = ahc_inb(ahc, SCB_TAG);
   1944  1.42      fvdl 				scb = &ahc->scb_data->scbarray[scb_index];
   1945  1.42      fvdl 
   1946  1.42      fvdl 				if (bus_phase == P_MESGOUT)
   1947  1.42      fvdl 					ahc_setup_initiator_msgout(ahc,
   1948  1.42      fvdl 								   &devinfo,
   1949  1.42      fvdl 								   scb);
   1950  1.42      fvdl 				else {
   1951  1.42      fvdl 					ahc->msg_type =
   1952  1.42      fvdl 					    MSG_TYPE_INITIATOR_MSGIN;
   1953  1.42      fvdl 					ahc->msgin_index = 0;
   1954  1.42      fvdl 				}
   1955  1.42      fvdl 			} else {
   1956  1.42      fvdl 				if (bus_phase == P_MESGOUT) {
   1957  1.42      fvdl 					ahc->msg_type =
   1958  1.42      fvdl 					    MSG_TYPE_TARGET_MSGOUT;
   1959  1.42      fvdl 					ahc->msgin_index = 0;
   1960  1.42      fvdl 				} else
   1961  1.42      fvdl 					/* XXX Ever executed??? */
   1962  1.42      fvdl 					ahc_setup_target_msgin(ahc, &devinfo);
   1963  1.42      fvdl 			}
   1964  1.42      fvdl 		}
   1965  1.42      fvdl 
   1966  1.42      fvdl 		/* Pass a NULL path so that handlers generate their own */
   1967  1.42      fvdl 		ahc_handle_message_phase(ahc, /*path*/NULL);
   1968  1.42      fvdl 		break;
   1969  1.42      fvdl 	}
   1970  1.42      fvdl 	case PERR_DETECTED:
   1971  1.42      fvdl 	{
   1972  1.42      fvdl 		/*
   1973  1.42      fvdl 		 * If we've cleared the parity error interrupt
   1974  1.42      fvdl 		 * but the sequencer still believes that SCSIPERR
   1975  1.42      fvdl 		 * is true, it must be that the parity error is
   1976  1.42      fvdl 		 * for the currently presented byte on the bus,
   1977  1.42      fvdl 		 * and we are not in a phase (data-in) where we will
   1978  1.42      fvdl 		 * eventually ack this byte.  Ack the byte and
   1979  1.42      fvdl 		 * throw it away in the hope that the target will
   1980  1.42      fvdl 		 * take us to message out to deliver the appropriate
   1981  1.42      fvdl 		 * error message.
   1982  1.42      fvdl 		 */
   1983  1.42      fvdl 		if ((intstat & SCSIINT) == 0
   1984  1.42      fvdl 		 && (ahc_inb(ahc, SSTAT1) & SCSIPERR) != 0) {
   1985  1.42      fvdl 			u_int curphase;
   1986  1.42      fvdl 
   1987  1.42      fvdl 			/*
   1988  1.42      fvdl 			 * The hardware will only let you ack bytes
   1989  1.42      fvdl 			 * if the expected phase in SCSISIGO matches
   1990  1.42      fvdl 			 * the current phase.  Make sure this is
   1991  1.42      fvdl 			 * currently the case.
   1992  1.42      fvdl 			 */
   1993  1.42      fvdl 			curphase = ahc_inb(ahc, SCSISIGI) & PHASE_MASK;
   1994  1.42      fvdl 			ahc_outb(ahc, LASTPHASE, curphase);
   1995  1.42      fvdl 			ahc_outb(ahc, SCSISIGO, curphase);
   1996  1.42      fvdl 			ahc_inb(ahc, SCSIDATL);
   1997  1.42      fvdl 		}
   1998  1.42      fvdl 		break;
   1999  1.42      fvdl 	}
   2000  1.42      fvdl 	case DATA_OVERRUN:
   2001  1.42      fvdl 	{
   2002  1.42      fvdl 		/*
   2003  1.42      fvdl 		 * When the sequencer detects an overrun, it
   2004  1.42      fvdl 		 * places the controller in "BITBUCKET" mode
   2005  1.42      fvdl 		 * and allows the target to complete its transfer.
   2006  1.42      fvdl 		 * Unfortunately, none of the counters get updated
   2007  1.42      fvdl 		 * when the controller is in this mode, so we have
   2008  1.42      fvdl 		 * no way of knowing how large the overrun was.
   2009  1.42      fvdl 		 */
   2010  1.42      fvdl 		u_int scbindex = ahc_inb(ahc, SCB_TAG);
   2011  1.42      fvdl 		u_int lastphase = ahc_inb(ahc, LASTPHASE);
   2012  1.42      fvdl 		int i;
   2013  1.42      fvdl 
   2014  1.42      fvdl 		scb = &ahc->scb_data->scbarray[scbindex];
   2015  1.42      fvdl 		for (i = 0; i < num_phases; i++) {
   2016  1.42      fvdl 			if (lastphase == phase_table[i].phase)
   2017  1.42      fvdl 				break;
   2018  1.42      fvdl 		}
   2019  1.42      fvdl 		scsi_print_addr(scb->xs->sc_link);
   2020  1.42      fvdl 		printf("data overrun detected %s."
   2021  1.42      fvdl 		       "  Tag == 0x%x.\n",
   2022  1.42      fvdl 		       phase_table[i].phasemsg,
   2023  1.42      fvdl   		       scb->hscb->tag);
   2024  1.42      fvdl 		scsi_print_addr(scb->xs->sc_link);
   2025  1.42      fvdl 		printf("%s seen Data Phase.  Length = %d.  NumSGs = %d.\n",
   2026  1.42      fvdl 		       ahc_inb(ahc, SEQ_FLAGS) & DPHASE ? "Have" : "Haven't",
   2027  1.42      fvdl 		       scb->xs->datalen, scb->sg_count);
   2028  1.42      fvdl 		if (scb->sg_count > 0) {
   2029  1.42      fvdl 			for (i = 0; i < scb->sg_count; i++) {
   2030  1.42      fvdl 				printf("sg[%d] - Addr 0x%x : Length %d\n",
   2031  1.42      fvdl 				       i,
   2032  1.42      fvdl 				       le32toh(scb->sg_list[i].addr),
   2033  1.42      fvdl 				       le32toh(scb->sg_list[i].len));
   2034  1.42      fvdl 			}
   2035  1.42      fvdl 		}
   2036  1.42      fvdl 		/*
   2037  1.42      fvdl 		 * Set this and it will take affect when the
   2038  1.42      fvdl 		 * target does a command complete.
   2039  1.42      fvdl 		 */
   2040  1.42      fvdl 		ahc_freeze_devq(ahc, scb->xs->sc_link);
   2041  1.42      fvdl 		ahcsetccbstatus(scb->xs, XS_DRIVER_STUFFUP);
   2042  1.42      fvdl 		ahc_freeze_ccb(scb);
   2043  1.42      fvdl 		break;
   2044  1.42      fvdl 	}
   2045  1.42      fvdl 	case TRACEPOINT:
   2046   1.6   mycroft 	{
   2047  1.42      fvdl 		printf("TRACEPOINT: RETURN_1 = %d\n", ahc_inb(ahc, RETURN_1));
   2048  1.42      fvdl 		printf("TRACEPOINT: RETURN_2 = %d\n", ahc_inb(ahc, RETURN_2));
   2049  1.42      fvdl 		printf("TRACEPOINT: ARG_1    = %d\n", ahc_inb(ahc, ARG_1));
   2050  1.42      fvdl 		printf("TRACEPOINT: ARG_2    = %d\n", ahc_inb(ahc, ARG_2));
   2051  1.42      fvdl 		printf("TRACEPOINT: CCHADDR =  %x\n",
   2052  1.42      fvdl 		    ahc_inb(ahc, CCHADDR) | (ahc_inb(ahc, CCHADDR+1) << 8)
   2053  1.42      fvdl 		    | (ahc_inb(ahc, CCHADDR+2) << 16)
   2054  1.42      fvdl 		    | (ahc_inb(ahc, CCHADDR+3) << 24));
   2055  1.42      fvdl #if 0
   2056  1.42      fvdl 		printf("SSTAT1 == 0x%x\n", ahc_inb(ahc, SSTAT1));
   2057  1.42      fvdl 		printf("SSTAT0 == 0x%x\n", ahc_inb(ahc, SSTAT0));
   2058  1.42      fvdl 		printf(", SCSISIGI == 0x%x\n", ahc_inb(ahc, SCSISIGI));
   2059  1.42      fvdl 		printf("TRACEPOINT: CCHCNT = %d, SG_COUNT = %d\n",
   2060  1.42      fvdl 		       ahc_inb(ahc, CCHCNT), ahc_inb(ahc, SG_COUNT));
   2061  1.42      fvdl 		printf("TRACEPOINT: SCB_TAG = %d\n", ahc_inb(ahc, SCB_TAG));
   2062  1.42      fvdl 		printf("TRACEPOINT1: CCHADDR = %d, CCHCNT = %d, SCBPTR = %d\n",
   2063  1.42      fvdl 		       ahc_inb(ahc, CCHADDR)
   2064  1.42      fvdl 		    | (ahc_inb(ahc, CCHADDR+1) << 8)
   2065  1.42      fvdl 		    | (ahc_inb(ahc, CCHADDR+2) << 16)
   2066  1.42      fvdl 		    | (ahc_inb(ahc, CCHADDR+3) << 24),
   2067  1.42      fvdl 		       ahc_inb(ahc, CCHCNT)
   2068  1.42      fvdl 		    | (ahc_inb(ahc, CCHCNT+1) << 8)
   2069  1.42      fvdl 		    | (ahc_inb(ahc, CCHCNT+2) << 16),
   2070  1.42      fvdl 		       ahc_inb(ahc, SCBPTR));
   2071  1.42      fvdl 		printf("TRACEPOINT: WAITING_SCBH = %d\n", ahc_inb(ahc, WAITING_SCBH));
   2072  1.42      fvdl 		printf("TRACEPOINT: SCB_TAG = %d\n", ahc_inb(ahc, SCB_TAG));
   2073  1.42      fvdl #if DDB > 0
   2074  1.42      fvdl 		cpu_Debugger();
   2075  1.42      fvdl #endif
   2076  1.42      fvdl #endif
   2077  1.42      fvdl 		break;
   2078  1.42      fvdl 	}
   2079  1.42      fvdl #if NOT_YET
   2080  1.42      fvdl 	/* XXX Fill these in later */
   2081  1.42      fvdl 	case MESG_BUFFER_BUSY:
   2082  1.42      fvdl 		break;
   2083  1.42      fvdl 	case MSGIN_PHASEMIS:
   2084  1.42      fvdl 		break;
   2085  1.42      fvdl #endif
   2086  1.42      fvdl 	default:
   2087  1.42      fvdl 		printf("ahc_intr: seqint, "
   2088  1.42      fvdl 		       "intstat == 0x%x, scsisigi = 0x%x\n",
   2089  1.42      fvdl 		       intstat, ahc_inb(ahc, SCSISIGI));
   2090  1.42      fvdl 		break;
   2091   1.6   mycroft 	}
   2092  1.42      fvdl 
   2093  1.42      fvdl unpause:
   2094  1.42      fvdl 	/*
   2095  1.42      fvdl 	 *  The sequencer is paused immediately on
   2096  1.42      fvdl 	 *  a SEQINT, so we should restart it when
   2097  1.42      fvdl 	 *  we're done.
   2098  1.42      fvdl 	 */
   2099  1.42      fvdl 	unpause_sequencer(ahc);
   2100   1.6   mycroft }
   2101   1.6   mycroft 
   2102  1.42      fvdl static void
   2103  1.42      fvdl ahc_handle_scsiint(struct ahc_softc *ahc, u_int intstat)
   2104   1.6   mycroft {
   2105  1.42      fvdl 	u_int	scb_index;
   2106  1.42      fvdl 	u_int	status;
   2107  1.42      fvdl 	struct	scb *scb;
   2108  1.42      fvdl 	char	cur_channel;
   2109  1.42      fvdl 	char	intr_channel;
   2110   1.6   mycroft 
   2111  1.42      fvdl 	if ((ahc->features & AHC_TWIN) != 0
   2112  1.42      fvdl 	 && ((ahc_inb(ahc, SBLKCTL) & SELBUSB) != 0))
   2113  1.42      fvdl 		cur_channel = 'B';
   2114  1.42      fvdl 	else
   2115  1.42      fvdl 		cur_channel = 'A';
   2116  1.42      fvdl 	intr_channel = cur_channel;
   2117   1.1   mycroft 
   2118  1.42      fvdl 	status = ahc_inb(ahc, SSTAT1);
   2119  1.42      fvdl 	if (status == 0) {
   2120  1.42      fvdl 		if ((ahc->features & AHC_TWIN) != 0) {
   2121  1.42      fvdl 			/* Try the other channel */
   2122  1.42      fvdl 		 	ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) ^ SELBUSB);
   2123  1.42      fvdl 			status = ahc_inb(ahc, SSTAT1);
   2124  1.42      fvdl 		 	ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) ^ SELBUSB);
   2125  1.42      fvdl 			intr_channel = (cur_channel == 'A') ? 'B' : 'A';
   2126  1.42      fvdl 		}
   2127  1.42      fvdl 		if (status == 0) {
   2128  1.42      fvdl 			printf("%s: Spurious SCSI interrupt\n", ahc_name(ahc));
   2129  1.42      fvdl 			return;
   2130  1.42      fvdl 		}
   2131  1.42      fvdl 	}
   2132   1.6   mycroft 
   2133  1.42      fvdl 	scb_index = ahc_inb(ahc, SCB_TAG);
   2134  1.42      fvdl 	if (scb_index < ahc->scb_data->numscbs) {
   2135  1.42      fvdl 		scb = &ahc->scb_data->scbarray[scb_index];
   2136  1.42      fvdl 		if ((scb->flags & SCB_ACTIVE) == 0
   2137  1.42      fvdl 		 || (ahc_inb(ahc, SEQ_FLAGS) & IDENTIFY_SEEN) == 0)
   2138  1.42      fvdl 			scb = NULL;
   2139  1.42      fvdl 	} else
   2140  1.42      fvdl 		scb = NULL;
   2141   1.6   mycroft 
   2142  1.42      fvdl 	if ((status & SCSIRSTI) != 0) {
   2143  1.42      fvdl 		printf("%s: Someone reset channel %c\n",
   2144  1.42      fvdl 			ahc_name(ahc), intr_channel);
   2145  1.42      fvdl 		ahc_reset_channel(ahc, intr_channel, /* Initiate Reset */FALSE);
   2146  1.42      fvdl 	} else if ((status & SCSIPERR) != 0) {
   2147  1.42      fvdl 		/*
   2148  1.42      fvdl 		 * Determine the bus phase and queue an appropriate message.
   2149  1.42      fvdl 		 * SCSIPERR is latched true as soon as a parity error
   2150  1.42      fvdl 		 * occurs.  If the sequencer acked the transfer that
   2151  1.42      fvdl 		 * caused the parity error and the currently presented
   2152  1.42      fvdl 		 * transfer on the bus has correct parity, SCSIPERR will
   2153  1.42      fvdl 		 * be cleared by CLRSCSIPERR.  Use this to determine if
   2154  1.42      fvdl 		 * we should look at the last phase the sequencer recorded,
   2155  1.42      fvdl 		 * or the current phase presented on the bus.
   2156  1.42      fvdl 		 */
   2157  1.42      fvdl 		u_int mesg_out;
   2158  1.42      fvdl 		u_int curphase;
   2159  1.42      fvdl 		u_int errorphase;
   2160  1.42      fvdl 		u_int lastphase;
   2161  1.42      fvdl 		int   i;
   2162  1.42      fvdl 
   2163  1.42      fvdl 		lastphase = ahc_inb(ahc, LASTPHASE);
   2164  1.42      fvdl 		curphase = ahc_inb(ahc, SCSISIGI) & PHASE_MASK;
   2165  1.42      fvdl 		ahc_outb(ahc, CLRSINT1, CLRSCSIPERR);
   2166  1.42      fvdl 		/*
   2167  1.42      fvdl 		 * For all phases save DATA, the sequencer won't
   2168  1.42      fvdl 		 * automatically ack a byte that has a parity error
   2169  1.42      fvdl 		 * in it.  So the only way that the current phase
   2170  1.42      fvdl 		 * could be 'data-in' is if the parity error is for
   2171  1.42      fvdl 		 * an already acked byte in the data phase.  During
   2172  1.42      fvdl 		 * synchronous data-in transfers, we may actually
   2173  1.42      fvdl 		 * ack bytes before latching the current phase in
   2174  1.42      fvdl 		 * LASTPHASE, leading to the discrepancy between
   2175  1.42      fvdl 		 * curphase and lastphase.
   2176  1.42      fvdl 		 */
   2177  1.42      fvdl 		if ((ahc_inb(ahc, SSTAT1) & SCSIPERR) != 0
   2178  1.42      fvdl 		 || curphase == P_DATAIN)
   2179  1.42      fvdl 			errorphase = curphase;
   2180  1.42      fvdl 		else
   2181  1.42      fvdl 			errorphase = lastphase;
   2182   1.6   mycroft 
   2183  1.42      fvdl 		for (i = 0; i < num_phases; i++) {
   2184  1.42      fvdl 			if (errorphase == phase_table[i].phase)
   2185  1.42      fvdl 				break;
   2186   1.6   mycroft 		}
   2187  1.42      fvdl 		mesg_out = phase_table[i].mesg_out;
   2188  1.42      fvdl 		if (scb != NULL)
   2189  1.42      fvdl 			scsi_print_addr(scb->xs->sc_link);
   2190  1.42      fvdl 		else
   2191  1.42      fvdl 			printf("%s:%c:%d: ", ahc_name(ahc),
   2192  1.42      fvdl 			       intr_channel,
   2193  1.42      fvdl 			       TCL_TARGET(ahc_inb(ahc, SAVED_TCL)));
   2194  1.42      fvdl 
   2195  1.42      fvdl 		printf("parity error detected %s. "
   2196  1.42      fvdl 		       "SEQADDR(0x%x) SCSIRATE(0x%x)\n",
   2197  1.42      fvdl 		       phase_table[i].phasemsg,
   2198  1.42      fvdl 		       ahc_inb(ahc, SEQADDR0) | (ahc_inb(ahc, SEQADDR1) << 8),
   2199  1.42      fvdl 		       ahc_inb(ahc, SCSIRATE));
   2200   1.6   mycroft 
   2201  1.42      fvdl 		/*
   2202  1.42      fvdl 		 * We've set the hardware to assert ATN if we
   2203  1.42      fvdl 		 * get a parity error on "in" phases, so all we
   2204  1.42      fvdl 		 * need to do is stuff the message buffer with
   2205  1.42      fvdl 		 * the appropriate message.  "In" phases have set
   2206  1.42      fvdl 		 * mesg_out to something other than MSG_NOP.
   2207  1.42      fvdl 		 */
   2208  1.42      fvdl 		if (mesg_out != MSG_NOOP) {
   2209  1.42      fvdl 			if (ahc->msg_type != MSG_TYPE_NONE)
   2210  1.42      fvdl 				ahc->send_msg_perror = TRUE;
   2211  1.42      fvdl 			else
   2212  1.42      fvdl 				ahc_outb(ahc, MSG_OUT, mesg_out);
   2213  1.42      fvdl 		}
   2214  1.42      fvdl 		ahc_outb(ahc, CLRINT, CLRSCSIINT);
   2215  1.42      fvdl 		unpause_sequencer(ahc);
   2216  1.42      fvdl 	} else if ((status & BUSFREE) != 0
   2217  1.42      fvdl 		&& (ahc_inb(ahc, SIMODE1) & ENBUSFREE) != 0) {
   2218  1.42      fvdl 		/*
   2219  1.42      fvdl 		 * First look at what phase we were last in.
   2220  1.42      fvdl 		 * If its message out, chances are pretty good
   2221  1.42      fvdl 		 * that the busfree was in response to one of
   2222  1.42      fvdl 		 * our abort requests.
   2223  1.42      fvdl 		 */
   2224  1.42      fvdl 		u_int lastphase = ahc_inb(ahc, LASTPHASE);
   2225  1.42      fvdl 		u_int saved_tcl = ahc_inb(ahc, SAVED_TCL);
   2226  1.42      fvdl 		u_int target = TCL_TARGET(saved_tcl);
   2227  1.42      fvdl 		u_int initiator_role_id = TCL_SCSI_ID(ahc, saved_tcl);
   2228  1.42      fvdl 		char channel = TCL_CHANNEL(ahc, saved_tcl);
   2229  1.42      fvdl 		int printerror = 1;
   2230  1.42      fvdl 
   2231  1.42      fvdl 		ahc_outb(ahc, SCSISEQ,
   2232  1.42      fvdl 			 ahc_inb(ahc, SCSISEQ) & (ENSELI|ENRSELI|ENAUTOATNP));
   2233  1.42      fvdl 		if (lastphase == P_MESGOUT) {
   2234  1.42      fvdl 			u_int message;
   2235  1.42      fvdl 			u_int tag;
   2236  1.42      fvdl 
   2237  1.42      fvdl 			message = ahc->msgout_buf[ahc->msgout_index - 1];
   2238  1.42      fvdl 			tag = SCB_LIST_NULL;
   2239  1.42      fvdl 			switch (message) {
   2240  1.42      fvdl 			case MSG_ABORT_TAG:
   2241  1.42      fvdl 				tag = scb->hscb->tag;
   2242  1.42      fvdl 				/* FALLTRHOUGH */
   2243  1.42      fvdl 			case MSG_ABORT:
   2244  1.42      fvdl 				scsi_print_addr(scb->xs->sc_link);
   2245  1.42      fvdl 				printf("SCB %x - Abort %s Completed.\n",
   2246  1.42      fvdl 				       scb->hscb->tag, tag == SCB_LIST_NULL ?
   2247  1.42      fvdl 				       "" : "Tag");
   2248  1.42      fvdl 				ahc_abort_scbs(ahc, target, channel,
   2249  1.42      fvdl 					       TCL_LUN(saved_tcl), tag,
   2250  1.42      fvdl 					       ROLE_INITIATOR,
   2251  1.42      fvdl 					       XS_DRIVER_STUFFUP);
   2252  1.42      fvdl 				printerror = 0;
   2253  1.42      fvdl 				break;
   2254  1.42      fvdl 			case MSG_BUS_DEV_RESET:
   2255  1.42      fvdl 			{
   2256  1.42      fvdl 				struct ahc_devinfo devinfo;
   2257   1.6   mycroft 
   2258  1.42      fvdl 				if (scb != NULL &&
   2259  1.42      fvdl 				    (scb->xs->xs_control & XS_CTL_RESET)
   2260  1.42      fvdl 				 && ahc_match_scb(scb, target, channel,
   2261  1.42      fvdl 						  TCL_LUN(saved_tcl),
   2262  1.42      fvdl 						  SCB_LIST_NULL,
   2263  1.42      fvdl 						  ROLE_INITIATOR)) {
   2264  1.42      fvdl 					ahcsetccbstatus(scb->xs, XS_NOERROR);
   2265  1.42      fvdl 				}
   2266  1.42      fvdl 				ahc_compile_devinfo(&devinfo,
   2267  1.42      fvdl 						    initiator_role_id,
   2268  1.42      fvdl 						    target,
   2269  1.42      fvdl 						    TCL_LUN(saved_tcl),
   2270  1.42      fvdl 						    channel,
   2271  1.42      fvdl 						    ROLE_INITIATOR);
   2272  1.42      fvdl 				ahc_handle_devreset(ahc, &devinfo,
   2273  1.42      fvdl 						    XS_RESET,
   2274  1.42      fvdl 						    "Bus Device Reset",
   2275  1.42      fvdl 						    /*verbose_level*/0);
   2276  1.42      fvdl 				printerror = 0;
   2277  1.42      fvdl 				break;
   2278  1.42      fvdl 			}
   2279  1.42      fvdl 			default:
   2280   1.6   mycroft 				break;
   2281  1.42      fvdl 			}
   2282  1.42      fvdl 		}
   2283  1.42      fvdl 		if (printerror != 0) {
   2284  1.42      fvdl 			int i;
   2285   1.6   mycroft 
   2286  1.42      fvdl 			if (scb != NULL) {
   2287  1.42      fvdl 				u_int tag;
   2288   1.6   mycroft 
   2289  1.42      fvdl 				if ((scb->hscb->control & TAG_ENB) != 0)
   2290  1.42      fvdl 					tag = scb->hscb->tag;
   2291  1.42      fvdl 				else
   2292  1.42      fvdl 					tag = SCB_LIST_NULL;
   2293  1.42      fvdl 				ahc_abort_scbs(ahc, target, channel,
   2294  1.42      fvdl 					       SCB_LUN(scb), tag,
   2295  1.42      fvdl 					       ROLE_INITIATOR,
   2296  1.42      fvdl 					       XS_DRIVER_STUFFUP);
   2297  1.42      fvdl 				scsi_print_addr(scb->xs->sc_link);
   2298  1.42      fvdl 			} else {
   2299  1.42      fvdl 				/*
   2300  1.42      fvdl 				 * We had not fully identified this connection,
   2301  1.42      fvdl 				 * so we cannot abort anything.
   2302  1.42      fvdl 				 */
   2303  1.42      fvdl 				printf("%s: ", ahc_name(ahc));
   2304  1.42      fvdl 			}
   2305  1.42      fvdl 			for (i = 0; i < num_phases; i++) {
   2306  1.42      fvdl 				if (lastphase == phase_table[i].phase)
   2307  1.42      fvdl 					break;
   2308  1.42      fvdl 			}
   2309  1.42      fvdl 			printf("Unexpected busfree %s\n"
   2310  1.42      fvdl 			       "SEQADDR == 0x%x\n",
   2311  1.42      fvdl 			       phase_table[i].phasemsg, ahc_inb(ahc, SEQADDR0)
   2312  1.42      fvdl 				| (ahc_inb(ahc, SEQADDR1) << 8));
   2313  1.42      fvdl 		}
   2314  1.42      fvdl 		ahc_clear_msg_state(ahc);
   2315  1.42      fvdl 		ahc_outb(ahc, SIMODE1, ahc_inb(ahc, SIMODE1) & ~ENBUSFREE);
   2316  1.42      fvdl 		ahc_outb(ahc, CLRSINT1, CLRBUSFREE|CLRSCSIPERR);
   2317  1.42      fvdl 		ahc_outb(ahc, CLRINT, CLRSCSIINT);
   2318  1.42      fvdl 		restart_sequencer(ahc);
   2319  1.42      fvdl 	} else if ((status & SELTO) != 0) {
   2320  1.42      fvdl 		u_int scbptr;
   2321   1.6   mycroft 
   2322  1.42      fvdl 		scbptr = ahc_inb(ahc, WAITING_SCBH);
   2323  1.42      fvdl 		ahc_outb(ahc, SCBPTR, scbptr);
   2324  1.42      fvdl 		scb_index = ahc_inb(ahc, SCB_TAG);
   2325  1.42      fvdl 
   2326  1.42      fvdl 		if (scb_index < ahc->scb_data->numscbs) {
   2327  1.42      fvdl 			scb = &ahc->scb_data->scbarray[scb_index];
   2328  1.42      fvdl 			if ((scb->flags & SCB_ACTIVE) == 0)
   2329  1.42      fvdl 				scb = NULL;
   2330  1.42      fvdl 		} else
   2331  1.42      fvdl 			scb = NULL;
   2332   1.6   mycroft 
   2333  1.42      fvdl 		if (scb == NULL) {
   2334  1.42      fvdl 			printf("%s: ahc_intr - referenced scb not "
   2335  1.42      fvdl 			       "valid during SELTO scb(%d, %d)\n",
   2336  1.42      fvdl 			       ahc_name(ahc), scbptr, scb_index);
   2337  1.42      fvdl 		} else {
   2338  1.42      fvdl 			u_int tag;
   2339   1.6   mycroft 
   2340  1.42      fvdl 			tag = SCB_LIST_NULL;
   2341  1.42      fvdl 			if ((scb->hscb->control & MSG_SIMPLE_Q_TAG) != 0)
   2342  1.42      fvdl 				tag = scb->hscb->tag;
   2343   1.6   mycroft 
   2344  1.42      fvdl 			ahc_abort_scbs(ahc, SCB_TARGET(scb), SCB_CHANNEL(scb),
   2345  1.42      fvdl 				       SCB_LUN(scb), tag,
   2346  1.42      fvdl 				       ROLE_INITIATOR, XS_SELTIMEOUT);
   2347  1.42      fvdl 		}
   2348  1.42      fvdl 		/* Stop the selection */
   2349  1.42      fvdl 		ahc_outb(ahc, SCSISEQ, 0);
   2350   1.6   mycroft 
   2351  1.42      fvdl 		/* No more pending messages */
   2352  1.42      fvdl 		ahc_clear_msg_state(ahc);
   2353   1.6   mycroft 
   2354  1.42      fvdl 		/*
   2355  1.42      fvdl 		 * Although the driver does not care about the
   2356  1.42      fvdl 		 * 'Selection in Progress' status bit, the busy
   2357  1.42      fvdl 		 * LED does.  SELINGO is only cleared by a sucessful
   2358  1.42      fvdl 		 * selection, so we must manually clear it to ensure
   2359  1.42      fvdl 		 * the LED turns off just incase no future successful
   2360  1.42      fvdl 		 * selections occur (e.g. no devices on the bus).
   2361  1.42      fvdl 		 */
   2362  1.42      fvdl 		ahc_outb(ahc, CLRSINT0, CLRSELINGO);
   2363   1.6   mycroft 
   2364  1.42      fvdl 		/* Clear interrupt state */
   2365  1.42      fvdl 		ahc_outb(ahc, CLRSINT1, CLRSELTIMEO|CLRBUSFREE|CLRSCSIPERR);
   2366  1.42      fvdl 		ahc_outb(ahc, CLRINT, CLRSCSIINT);
   2367  1.42      fvdl 		restart_sequencer(ahc);
   2368  1.42      fvdl 	} else {
   2369  1.42      fvdl 		scsi_print_addr(scb->xs->sc_link);
   2370  1.42      fvdl 		printf("Unknown SCSIINT. Status = 0x%x\n", status);
   2371  1.42      fvdl 		ahc_outb(ahc, CLRSINT1, status);
   2372  1.42      fvdl 		ahc_outb(ahc, CLRINT, CLRSCSIINT);
   2373  1.42      fvdl 		unpause_sequencer(ahc);
   2374   1.6   mycroft 	}
   2375   1.1   mycroft }
   2376   1.1   mycroft 
   2377  1.42      fvdl static void
   2378  1.42      fvdl ahc_build_transfer_msg(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
   2379   1.1   mycroft {
   2380  1.42      fvdl 	/*
   2381  1.42      fvdl 	 * We need to initiate transfer negotiations.
   2382  1.42      fvdl 	 * If our current and goal settings are identical,
   2383  1.42      fvdl 	 * we want to renegotiate due to a check condition.
   2384  1.42      fvdl 	 */
   2385  1.42      fvdl 	struct	ahc_initiator_tinfo *tinfo;
   2386  1.42      fvdl 	struct	tmode_tstate *tstate;
   2387  1.42      fvdl 	int	dowide;
   2388  1.42      fvdl 	int	dosync;
   2389  1.42      fvdl 
   2390  1.42      fvdl 	tinfo = ahc_fetch_transinfo(ahc, devinfo->channel, devinfo->our_scsiid,
   2391  1.42      fvdl 				    devinfo->target, &tstate);
   2392  1.42      fvdl 	dowide = tinfo->current.width != tinfo->goal.width;
   2393  1.42      fvdl 	dosync = tinfo->current.period != tinfo->goal.period;
   2394  1.42      fvdl 
   2395  1.42      fvdl 	if (!dowide && !dosync) {
   2396  1.42      fvdl 		dowide = tinfo->goal.width != MSG_EXT_WDTR_BUS_8_BIT;
   2397  1.42      fvdl 		dosync = tinfo->goal.period != 0;
   2398  1.42      fvdl 	}
   2399  1.42      fvdl 
   2400  1.42      fvdl 	if (dowide) {
   2401  1.42      fvdl 		ahc_construct_wdtr(ahc, tinfo->goal.width);
   2402  1.42      fvdl 	} else if (dosync) {
   2403  1.42      fvdl 		struct	ahc_syncrate *rate;
   2404  1.42      fvdl 		u_int	period;
   2405  1.42      fvdl 		u_int	offset;
   2406  1.42      fvdl 
   2407  1.42      fvdl 		period = tinfo->goal.period;
   2408  1.42      fvdl 		rate = ahc_devlimited_syncrate(ahc, &period);
   2409  1.42      fvdl 		offset = tinfo->goal.offset;
   2410  1.42      fvdl 		ahc_validate_offset(ahc, rate, &offset,
   2411  1.42      fvdl 				    tinfo->current.width);
   2412  1.42      fvdl 		ahc_construct_sdtr(ahc, period, offset);
   2413  1.42      fvdl 	} else {
   2414  1.42      fvdl 		panic("ahc_intr: AWAITING_MSG for negotiation, "
   2415  1.42      fvdl 		      "but no negotiation needed\n");
   2416  1.42      fvdl 	}
   2417  1.42      fvdl }
   2418   1.1   mycroft 
   2419  1.42      fvdl static void
   2420  1.42      fvdl ahc_setup_initiator_msgout(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
   2421  1.42      fvdl 			   struct scb *scb)
   2422  1.42      fvdl {
   2423  1.42      fvdl 	/*
   2424  1.42      fvdl 	 * To facilitate adding multiple messages together,
   2425  1.42      fvdl 	 * each routine should increment the index and len
   2426  1.42      fvdl 	 * variables instead of setting them explicitly.
   2427  1.42      fvdl 	 */
   2428  1.42      fvdl 	ahc->msgout_index = 0;
   2429  1.42      fvdl 	ahc->msgout_len = 0;
   2430  1.42      fvdl 
   2431  1.42      fvdl 	if ((scb->flags & SCB_DEVICE_RESET) == 0
   2432  1.42      fvdl 	 && ahc_inb(ahc, MSG_OUT) == MSG_IDENTIFYFLAG) {
   2433  1.42      fvdl 		u_int identify_msg;
   2434  1.42      fvdl 
   2435  1.42      fvdl 		identify_msg = MSG_IDENTIFYFLAG | SCB_LUN(scb);
   2436  1.42      fvdl 		if ((scb->hscb->control & DISCENB) != 0)
   2437  1.42      fvdl 			identify_msg |= MSG_IDENTIFY_DISCFLAG;
   2438  1.42      fvdl 		ahc->msgout_buf[ahc->msgout_index++] = identify_msg;
   2439  1.42      fvdl 		ahc->msgout_len++;
   2440  1.42      fvdl 
   2441  1.42      fvdl 		if ((scb->hscb->control & TAG_ENB) != 0) {
   2442  1.42      fvdl 			/* XXX fvdl FreeBSD has tag action passed down */
   2443  1.42      fvdl 			ahc->msgout_buf[ahc->msgout_index++] = MSG_SIMPLE_Q_TAG;
   2444  1.42      fvdl 			ahc->msgout_buf[ahc->msgout_index++] = scb->hscb->tag;
   2445  1.42      fvdl 			ahc->msgout_len += 2;
   2446  1.42      fvdl 		}
   2447  1.42      fvdl 	}
   2448   1.6   mycroft 
   2449  1.42      fvdl 	if (scb->flags & SCB_DEVICE_RESET) {
   2450  1.42      fvdl 		ahc->msgout_buf[ahc->msgout_index++] = MSG_BUS_DEV_RESET;
   2451  1.42      fvdl 		ahc->msgout_len++;
   2452  1.42      fvdl 		scsi_print_addr(scb->xs->sc_link);
   2453  1.42      fvdl 		printf("Bus Device Reset Message Sent\n");
   2454  1.42      fvdl 	} else if (scb->flags & SCB_ABORT) {
   2455  1.42      fvdl 		if ((scb->hscb->control & TAG_ENB) != 0)
   2456  1.42      fvdl 			ahc->msgout_buf[ahc->msgout_index++] = MSG_ABORT_TAG;
   2457  1.42      fvdl 		else
   2458  1.42      fvdl 			ahc->msgout_buf[ahc->msgout_index++] = MSG_ABORT;
   2459  1.42      fvdl 		ahc->msgout_len++;
   2460  1.42      fvdl 		scsi_print_addr(scb->xs->sc_link);
   2461  1.42      fvdl 		printf("Abort Message Sent\n");
   2462  1.42      fvdl 	} else if ((ahc->targ_msg_req & devinfo->target_mask) != 0) {
   2463  1.42      fvdl 		ahc_build_transfer_msg(ahc, devinfo);
   2464  1.42      fvdl 	} else {
   2465  1.42      fvdl 		printf("ahc_intr: AWAITING_MSG for an SCB that "
   2466  1.42      fvdl 		       "does not have a waiting message");
   2467  1.42      fvdl 		panic("SCB = %d, SCB Control = %x, MSG_OUT = %x "
   2468  1.42      fvdl 		      "SCB flags = %x", scb->hscb->tag, scb->hscb->control,
   2469  1.42      fvdl 		      ahc_inb(ahc, MSG_OUT), scb->flags);
   2470  1.42      fvdl 	}
   2471   1.6   mycroft 
   2472  1.42      fvdl 	/*
   2473  1.42      fvdl 	 * Clear the MK_MESSAGE flag from the SCB so we aren't
   2474  1.42      fvdl 	 * asked to send this message again.
   2475  1.42      fvdl 	 */
   2476  1.42      fvdl 	ahc_outb(ahc, SCB_CONTROL, ahc_inb(ahc, SCB_CONTROL) & ~MK_MESSAGE);
   2477  1.42      fvdl 	ahc->msgout_index = 0;
   2478  1.42      fvdl 	ahc->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
   2479   1.1   mycroft }
   2480   1.1   mycroft 
   2481  1.42      fvdl static void
   2482  1.42      fvdl ahc_setup_target_msgin(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
   2483   1.1   mycroft {
   2484  1.42      fvdl 	/*
   2485  1.42      fvdl 	 * To facilitate adding multiple messages together,
   2486  1.42      fvdl 	 * each routine should increment the index and len
   2487  1.42      fvdl 	 * variables instead of setting them explicitly.
   2488  1.42      fvdl 	 */
   2489  1.42      fvdl 	ahc->msgout_index = 0;
   2490  1.42      fvdl 	ahc->msgout_len = 0;
   2491  1.42      fvdl 
   2492  1.42      fvdl 	if ((ahc->targ_msg_req & devinfo->target_mask) != 0)
   2493  1.42      fvdl 		ahc_build_transfer_msg(ahc, devinfo);
   2494  1.42      fvdl 	else
   2495  1.42      fvdl 		panic("ahc_intr: AWAITING target message with no message");
   2496  1.40   thorpej 
   2497  1.42      fvdl 	ahc->msgout_index = 0;
   2498  1.42      fvdl 	ahc->msg_type = MSG_TYPE_TARGET_MSGIN;
   2499  1.42      fvdl }
   2500   1.6   mycroft 
   2501  1.42      fvdl static int
   2502  1.42      fvdl ahc_handle_msg_reject(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
   2503  1.42      fvdl {
   2504   1.1   mycroft 	/*
   2505  1.42      fvdl 	 * What we care about here is if we had an
   2506  1.42      fvdl 	 * outstanding SDTR or WDTR message for this
   2507  1.42      fvdl 	 * target.  If we did, this is a signal that
   2508  1.42      fvdl 	 * the target is refusing negotiation.
   2509   1.1   mycroft 	 */
   2510  1.42      fvdl 	struct scb *scb;
   2511  1.42      fvdl 	u_int scb_index;
   2512  1.42      fvdl 	u_int last_msg;
   2513  1.42      fvdl 	int   response = 0;
   2514  1.42      fvdl 
   2515  1.42      fvdl 	scb_index = ahc_inb(ahc, SCB_TAG);
   2516  1.42      fvdl 	scb = &ahc->scb_data->scbarray[scb_index];
   2517  1.42      fvdl 
   2518  1.42      fvdl 	/* Might be necessary */
   2519  1.42      fvdl 	last_msg = ahc_inb(ahc, LAST_MSG);
   2520  1.42      fvdl 
   2521  1.42      fvdl 	if (ahc_sent_msg(ahc, MSG_EXT_WDTR, /*full*/FALSE)) {
   2522  1.42      fvdl 		struct ahc_initiator_tinfo *tinfo;
   2523  1.42      fvdl 		struct tmode_tstate *tstate;
   2524  1.42      fvdl 
   2525  1.42      fvdl #ifdef AHC_DEBUG_NEG
   2526  1.42      fvdl 		/* note 8bit xfers */
   2527  1.42      fvdl 		printf("%s:%c:%d: refuses WIDE negotiation.  Using "
   2528  1.42      fvdl 		       "8bit transfers\n", ahc_name(ahc),
   2529  1.42      fvdl 		       devinfo->channel, devinfo->target);
   2530  1.42      fvdl #endif
   2531  1.42      fvdl 		ahc_set_width(ahc, devinfo,
   2532  1.42      fvdl 			      MSG_EXT_WDTR_BUS_8_BIT,
   2533  1.42      fvdl 			      AHC_TRANS_ACTIVE|AHC_TRANS_GOAL,
   2534  1.42      fvdl 			      /*paused*/TRUE, /*done*/TRUE);
   2535  1.42      fvdl 		/*
   2536  1.42      fvdl 		 * No need to clear the sync rate.  If the target
   2537  1.42      fvdl 		 * did not accept the command, our syncrate is
   2538  1.42      fvdl 		 * unaffected.  If the target started the negotiation,
   2539  1.42      fvdl 		 * but rejected our response, we already cleared the
   2540  1.42      fvdl 		 * sync rate before sending our WDTR.
   2541  1.42      fvdl 		 */
   2542  1.42      fvdl 		tinfo = ahc_fetch_transinfo(ahc, devinfo->channel,
   2543  1.42      fvdl 					    devinfo->our_scsiid,
   2544  1.42      fvdl 					    devinfo->target, &tstate);
   2545  1.42      fvdl 		if (tinfo->goal.period) {
   2546  1.42      fvdl 			u_int period;
   2547  1.42      fvdl 
   2548  1.42      fvdl 			/* Start the sync negotiation */
   2549  1.42      fvdl 			period = tinfo->goal.period;
   2550  1.42      fvdl 			ahc_devlimited_syncrate(ahc, &period);
   2551  1.42      fvdl 			ahc->msgout_index = 0;
   2552  1.42      fvdl 			ahc->msgout_len = 0;
   2553  1.42      fvdl 			ahc_construct_sdtr(ahc, period, tinfo->goal.offset);
   2554  1.42      fvdl 			ahc->msgout_index = 0;
   2555  1.42      fvdl 			response = 1;
   2556  1.42      fvdl 		}
   2557  1.42      fvdl 	} else if (ahc_sent_msg(ahc, MSG_EXT_SDTR, /*full*/FALSE)) {
   2558  1.42      fvdl 		/* note asynch xfers and clear flag */
   2559  1.42      fvdl 		ahc_set_syncrate(ahc, devinfo, /*syncrate*/NULL, /*period*/0,
   2560  1.42      fvdl 				 /*offset*/0, AHC_TRANS_ACTIVE|AHC_TRANS_GOAL,
   2561  1.42      fvdl 				 /*paused*/TRUE, /*done*/TRUE);
   2562  1.42      fvdl #ifdef AHC_DEBUG_NEG
   2563  1.42      fvdl 		printf("%s:%c:%d: refuses synchronous negotiation. "
   2564  1.42      fvdl 		       "Using asynchronous transfers\n",
   2565  1.42      fvdl 		       ahc_name(ahc),
   2566  1.42      fvdl 		       devinfo->channel, devinfo->target);
   2567  1.42      fvdl #endif
   2568  1.42      fvdl 	} else if ((scb->hscb->control & MSG_SIMPLE_Q_TAG) != 0) {
   2569  1.42      fvdl 		printf("%s:%c:%d: refuses tagged commands.  Performing "
   2570  1.42      fvdl 		       "non-tagged I/O\n", ahc_name(ahc),
   2571  1.42      fvdl 		       devinfo->channel, devinfo->target);
   2572  1.42      fvdl 
   2573  1.42      fvdl 		ahc_set_tags(ahc, devinfo, FALSE);
   2574   1.6   mycroft 
   2575  1.42      fvdl 		/*
   2576  1.42      fvdl 		 * Resend the identify for this CCB as the target
   2577  1.42      fvdl 		 * may believe that the selection is invalid otherwise.
   2578  1.42      fvdl 		 */
   2579  1.42      fvdl 		ahc_outb(ahc, SCB_CONTROL, ahc_inb(ahc, SCB_CONTROL)
   2580  1.42      fvdl 					  & ~MSG_SIMPLE_Q_TAG);
   2581  1.42      fvdl 	 	scb->hscb->control &= ~MSG_SIMPLE_Q_TAG;
   2582  1.42      fvdl 		ahc_outb(ahc, MSG_OUT, MSG_IDENTIFYFLAG);
   2583  1.42      fvdl 		ahc_outb(ahc, SCSISIGO, ahc_inb(ahc, SCSISIGO) | ATNO);
   2584   1.1   mycroft 
   2585  1.42      fvdl 		/*
   2586  1.42      fvdl 		 * Requeue all tagged commands for this target
   2587  1.42      fvdl 		 * currently in our posession so they can be
   2588  1.42      fvdl 		 * converted to untagged commands.
   2589  1.42      fvdl 		 */
   2590  1.42      fvdl 		ahc_search_qinfifo(ahc, SCB_TARGET(scb), SCB_CHANNEL(scb),
   2591  1.42      fvdl 				   SCB_LUN(scb), /*tag*/SCB_LIST_NULL,
   2592  1.42      fvdl 				   ROLE_INITIATOR, SCB_REQUEUE,
   2593  1.42      fvdl 				   SEARCH_COMPLETE);
   2594  1.42      fvdl 	} else {
   2595  1.42      fvdl 		/*
   2596  1.42      fvdl 		 * Otherwise, we ignore it.
   2597  1.42      fvdl 		 */
   2598  1.42      fvdl 		printf("%s:%c:%d: Message reject for %x -- ignored\n",
   2599  1.42      fvdl 		       ahc_name(ahc), devinfo->channel, devinfo->target,
   2600  1.42      fvdl 		       last_msg);
   2601  1.42      fvdl 	}
   2602  1.42      fvdl 	return (response);
   2603  1.42      fvdl }
   2604  1.14     gibbs 
   2605  1.42      fvdl static void
   2606  1.42      fvdl ahc_clear_msg_state(struct ahc_softc *ahc)
   2607  1.42      fvdl {
   2608  1.42      fvdl 	ahc->msgout_len = 0;
   2609  1.42      fvdl 	ahc->msgin_index = 0;
   2610  1.42      fvdl 	ahc->msg_type = MSG_TYPE_NONE;
   2611  1.42      fvdl 	ahc_outb(ahc, MSG_OUT, MSG_NOOP);
   2612  1.42      fvdl }
   2613  1.14     gibbs 
   2614  1.42      fvdl static void
   2615  1.42      fvdl ahc_handle_message_phase(struct ahc_softc *ahc, struct scsipi_link *sc_link)
   2616  1.42      fvdl {
   2617  1.42      fvdl 	struct	ahc_devinfo devinfo;
   2618  1.42      fvdl 	u_int	bus_phase;
   2619  1.42      fvdl 	int	end_session;
   2620  1.42      fvdl 
   2621  1.42      fvdl 	ahc_fetch_devinfo(ahc, &devinfo);
   2622  1.42      fvdl 	end_session = FALSE;
   2623  1.42      fvdl 	bus_phase = ahc_inb(ahc, SCSISIGI) & PHASE_MASK;
   2624  1.42      fvdl 
   2625  1.42      fvdl reswitch:
   2626  1.42      fvdl 	switch (ahc->msg_type) {
   2627  1.42      fvdl 	case MSG_TYPE_INITIATOR_MSGOUT:
   2628  1.42      fvdl 	{
   2629  1.42      fvdl 		int lastbyte;
   2630  1.42      fvdl 		int phasemis;
   2631  1.42      fvdl 		int msgdone;
   2632  1.42      fvdl 
   2633  1.42      fvdl 		if (ahc->msgout_len == 0)
   2634  1.42      fvdl 			panic("REQINIT interrupt with no active message");
   2635  1.42      fvdl 
   2636  1.42      fvdl 		phasemis = bus_phase != P_MESGOUT;
   2637  1.42      fvdl 		if (phasemis) {
   2638  1.42      fvdl 			if (bus_phase == P_MESGIN) {
   2639  1.42      fvdl 				/*
   2640  1.42      fvdl 				 * Change gears and see if
   2641  1.42      fvdl 				 * this messages is of interest to
   2642  1.42      fvdl 				 * us or should be passed back to
   2643  1.42      fvdl 				 * the sequencer.
   2644  1.42      fvdl 				 */
   2645  1.42      fvdl 				ahc_outb(ahc, CLRSINT1, CLRATNO);
   2646  1.42      fvdl 				ahc->send_msg_perror = FALSE;
   2647  1.42      fvdl 				ahc->msg_type = MSG_TYPE_INITIATOR_MSGIN;
   2648  1.42      fvdl 				ahc->msgin_index = 0;
   2649  1.42      fvdl 				goto reswitch;
   2650  1.42      fvdl 			}
   2651  1.42      fvdl 			end_session = TRUE;
   2652  1.42      fvdl 			break;
   2653  1.14     gibbs 		}
   2654  1.42      fvdl 
   2655  1.42      fvdl 		if (ahc->send_msg_perror) {
   2656  1.42      fvdl 			ahc_outb(ahc, CLRSINT1, CLRATNO);
   2657  1.42      fvdl 			ahc_outb(ahc, CLRSINT1, CLRREQINIT);
   2658  1.42      fvdl 			ahc_outb(ahc, SCSIDATL, MSG_PARITY_ERROR);
   2659  1.42      fvdl 			break;
   2660  1.14     gibbs 		}
   2661  1.42      fvdl 
   2662  1.42      fvdl 		msgdone	= ahc->msgout_index == ahc->msgout_len;
   2663  1.42      fvdl 		if (msgdone) {
   2664  1.14     gibbs 			/*
   2665  1.42      fvdl 			 * The target has requested a retry.
   2666  1.42      fvdl 			 * Re-assert ATN, reset our message index to
   2667  1.42      fvdl 			 * 0, and try again.
   2668  1.14     gibbs 			 */
   2669  1.42      fvdl 			ahc->msgout_index = 0;
   2670  1.42      fvdl 			ahc_outb(ahc, SCSISIGO, ahc_inb(ahc, SCSISIGO) | ATNO);
   2671  1.42      fvdl 		}
   2672  1.42      fvdl 
   2673  1.42      fvdl 		lastbyte = ahc->msgout_index == (ahc->msgout_len - 1);
   2674  1.42      fvdl 		if (lastbyte) {
   2675  1.42      fvdl 			/* Last byte is signified by dropping ATN */
   2676  1.42      fvdl 			ahc_outb(ahc, CLRSINT1, CLRATNO);
   2677  1.42      fvdl 		}
   2678  1.42      fvdl 
   2679  1.42      fvdl 		/*
   2680  1.42      fvdl 		 * Clear our interrupt status and present
   2681  1.42      fvdl 		 * the next byte on the bus.
   2682  1.42      fvdl 		 */
   2683  1.42      fvdl 		ahc_outb(ahc, CLRSINT1, CLRREQINIT);
   2684  1.42      fvdl 		ahc_outb(ahc, SCSIDATL, ahc->msgout_buf[ahc->msgout_index++]);
   2685  1.42      fvdl 		break;
   2686  1.42      fvdl 	}
   2687  1.42      fvdl 	case MSG_TYPE_INITIATOR_MSGIN:
   2688  1.42      fvdl 	{
   2689  1.42      fvdl 		int phasemis;
   2690  1.42      fvdl 		int message_done;
   2691  1.42      fvdl 
   2692  1.42      fvdl 		phasemis = bus_phase != P_MESGIN;
   2693  1.42      fvdl 
   2694  1.42      fvdl 		if (phasemis) {
   2695  1.42      fvdl 			ahc->msgin_index = 0;
   2696  1.42      fvdl 			if (bus_phase == P_MESGOUT
   2697  1.42      fvdl 			 && (ahc->send_msg_perror == TRUE
   2698  1.42      fvdl 			  || (ahc->msgout_len != 0
   2699  1.42      fvdl 			   && ahc->msgout_index == 0))) {
   2700  1.42      fvdl 				ahc->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
   2701  1.42      fvdl 				goto reswitch;
   2702  1.14     gibbs 			}
   2703  1.42      fvdl 			end_session = TRUE;
   2704  1.42      fvdl 			break;
   2705  1.42      fvdl 		}
   2706  1.42      fvdl 
   2707  1.42      fvdl 		/* Pull the byte in without acking it */
   2708  1.42      fvdl 		ahc->msgin_buf[ahc->msgin_index] = ahc_inb(ahc, SCSIBUSL);
   2709  1.42      fvdl 
   2710  1.42      fvdl 		message_done = ahc_parse_msg(ahc, sc_link, &devinfo);
   2711  1.42      fvdl 
   2712  1.42      fvdl 		if (message_done) {
   2713  1.42      fvdl 			/*
   2714  1.42      fvdl 			 * Clear our incoming message buffer in case there
   2715  1.42      fvdl 			 * is another message following this one.
   2716  1.42      fvdl 			 */
   2717  1.42      fvdl 			ahc->msgin_index = 0;
   2718  1.42      fvdl 
   2719  1.42      fvdl 			/*
   2720  1.42      fvdl 			 * If this message illicited a response,
   2721  1.42      fvdl 			 * assert ATN so the target takes us to the
   2722  1.42      fvdl 			 * message out phase.
   2723  1.42      fvdl 			 */
   2724  1.42      fvdl 			if (ahc->msgout_len != 0)
   2725  1.42      fvdl 				ahc_outb(ahc, SCSISIGO,
   2726  1.42      fvdl 					 ahc_inb(ahc, SCSISIGO) | ATNO);
   2727  1.42      fvdl 		} else
   2728  1.42      fvdl 			ahc->msgin_index++;
   2729  1.42      fvdl 
   2730  1.42      fvdl 		/* Ack the byte */
   2731  1.42      fvdl 		ahc_outb(ahc, CLRSINT1, CLRREQINIT);
   2732  1.42      fvdl 		ahc_inb(ahc, SCSIDATL);
   2733  1.42      fvdl 		break;
   2734  1.42      fvdl 	}
   2735  1.42      fvdl 	case MSG_TYPE_TARGET_MSGIN:
   2736  1.42      fvdl 	{
   2737  1.42      fvdl 		int msgdone;
   2738  1.42      fvdl 		int msgout_request;
   2739  1.42      fvdl 
   2740  1.42      fvdl 		if (ahc->msgout_len == 0)
   2741  1.42      fvdl 			panic("Target MSGIN with no active message");
   2742  1.42      fvdl 
   2743  1.42      fvdl 		/*
   2744  1.42      fvdl 		 * If we interrupted a mesgout session, the initiator
   2745  1.42      fvdl 		 * will not know this until our first REQ.  So, we
   2746  1.42      fvdl 		 * only honor mesgout requests after we've sent our
   2747  1.42      fvdl 		 * first byte.
   2748  1.42      fvdl 		 */
   2749  1.42      fvdl 		if ((ahc_inb(ahc, SCSISIGI) & ATNI) != 0
   2750  1.42      fvdl 		 && ahc->msgout_index > 0)
   2751  1.42      fvdl 			msgout_request = TRUE;
   2752  1.42      fvdl 		else
   2753  1.42      fvdl 			msgout_request = FALSE;
   2754  1.42      fvdl 
   2755  1.42      fvdl 		if (msgout_request) {
   2756  1.42      fvdl 
   2757  1.42      fvdl 			/*
   2758  1.42      fvdl 			 * Change gears and see if
   2759  1.42      fvdl 			 * this messages is of interest to
   2760  1.42      fvdl 			 * us or should be passed back to
   2761  1.42      fvdl 			 * the sequencer.
   2762  1.42      fvdl 			 */
   2763  1.42      fvdl 			ahc->msg_type = MSG_TYPE_TARGET_MSGOUT;
   2764  1.42      fvdl 			ahc_outb(ahc, SCSISIGO, P_MESGOUT | BSYO);
   2765  1.42      fvdl 			ahc->msgin_index = 0;
   2766  1.42      fvdl 			/* Dummy read to REQ for first byte */
   2767  1.42      fvdl 			ahc_inb(ahc, SCSIDATL);
   2768  1.42      fvdl 			ahc_outb(ahc, SXFRCTL0,
   2769  1.42      fvdl 				 ahc_inb(ahc, SXFRCTL0) | SPIOEN);
   2770  1.42      fvdl 			break;
   2771  1.42      fvdl 		}
   2772  1.42      fvdl 
   2773  1.42      fvdl 		msgdone = ahc->msgout_index == ahc->msgout_len;
   2774  1.42      fvdl 		if (msgdone) {
   2775  1.42      fvdl 			ahc_outb(ahc, SXFRCTL0,
   2776  1.42      fvdl 				 ahc_inb(ahc, SXFRCTL0) & ~SPIOEN);
   2777  1.42      fvdl 			end_session = TRUE;
   2778  1.42      fvdl 			break;
   2779  1.42      fvdl 		}
   2780  1.42      fvdl 
   2781  1.42      fvdl 		/*
   2782  1.42      fvdl 		 * Present the next byte on the bus.
   2783  1.42      fvdl 		 */
   2784  1.42      fvdl 		ahc_outb(ahc, SXFRCTL0, ahc_inb(ahc, SXFRCTL0) | SPIOEN);
   2785  1.42      fvdl 		ahc_outb(ahc, SCSIDATL, ahc->msgout_buf[ahc->msgout_index++]);
   2786  1.42      fvdl 		break;
   2787  1.42      fvdl 	}
   2788  1.42      fvdl 	case MSG_TYPE_TARGET_MSGOUT:
   2789  1.42      fvdl 	{
   2790  1.42      fvdl 		int lastbyte;
   2791  1.42      fvdl 		int msgdone;
   2792  1.42      fvdl 
   2793  1.42      fvdl 		/*
   2794  1.42      fvdl 		 * The initiator signals that this is
   2795  1.42      fvdl 		 * the last byte by dropping ATN.
   2796  1.42      fvdl 		 */
   2797  1.42      fvdl 		lastbyte = (ahc_inb(ahc, SCSISIGI) & ATNI) == 0;
   2798  1.42      fvdl 
   2799  1.42      fvdl 		/*
   2800  1.42      fvdl 		 * Read the latched byte, but turn off SPIOEN first
   2801  1.42      fvdl 		 * so that we don't inadvertantly cause a REQ for the
   2802  1.42      fvdl 		 * next byte.
   2803  1.42      fvdl 		 */
   2804  1.42      fvdl 		ahc_outb(ahc, SXFRCTL0, ahc_inb(ahc, SXFRCTL0) & ~SPIOEN);
   2805  1.42      fvdl 		ahc->msgin_buf[ahc->msgin_index] = ahc_inb(ahc, SCSIDATL);
   2806  1.42      fvdl 		msgdone = ahc_parse_msg(ahc, sc_link, &devinfo);
   2807  1.42      fvdl 		if (msgdone == MSGLOOP_TERMINATED) {
   2808  1.42      fvdl 			/*
   2809  1.42      fvdl 			 * The message is *really* done in that it caused
   2810  1.42      fvdl 			 * us to go to bus free.  The sequencer has already
   2811  1.42      fvdl 			 * been reset at this point, so pull the ejection
   2812  1.42      fvdl 			 * handle.
   2813  1.42      fvdl 			 */
   2814  1.42      fvdl 			return;
   2815  1.42      fvdl 		}
   2816  1.42      fvdl 
   2817  1.42      fvdl 		ahc->msgin_index++;
   2818  1.42      fvdl 
   2819  1.42      fvdl 		/*
   2820  1.42      fvdl 		 * XXX Read spec about initiator dropping ATN too soon
   2821  1.42      fvdl 		 *     and use msgdone to detect it.
   2822  1.42      fvdl 		 */
   2823  1.42      fvdl 		if (msgdone == MSGLOOP_MSGCOMPLETE) {
   2824  1.42      fvdl 			ahc->msgin_index = 0;
   2825   1.9  explorer 
   2826  1.14     gibbs 			/*
   2827  1.42      fvdl 			 * If this message illicited a response, transition
   2828  1.42      fvdl 			 * to the Message in phase and send it.
   2829  1.14     gibbs 			 */
   2830  1.42      fvdl 			if (ahc->msgout_len != 0) {
   2831  1.42      fvdl 				ahc_outb(ahc, SCSISIGO, P_MESGIN | BSYO);
   2832  1.42      fvdl 				ahc_outb(ahc, SXFRCTL0,
   2833  1.42      fvdl 					 ahc_inb(ahc, SXFRCTL0) | SPIOEN);
   2834  1.42      fvdl 				ahc->msg_type = MSG_TYPE_TARGET_MSGIN;
   2835  1.42      fvdl 				ahc->msgin_index = 0;
   2836  1.42      fvdl 				break;
   2837  1.14     gibbs 			}
   2838  1.14     gibbs 		}
   2839  1.14     gibbs 
   2840  1.42      fvdl 		if (lastbyte)
   2841  1.42      fvdl 			end_session = TRUE;
   2842  1.42      fvdl 		else {
   2843  1.42      fvdl 			/* Ask for the next byte. */
   2844  1.42      fvdl 			ahc_outb(ahc, SXFRCTL0,
   2845  1.42      fvdl 				 ahc_inb(ahc, SXFRCTL0) | SPIOEN);
   2846  1.42      fvdl 		}
   2847   1.9  explorer 
   2848  1.42      fvdl 		break;
   2849  1.42      fvdl 	}
   2850  1.42      fvdl 	default:
   2851  1.42      fvdl 		panic("Unknown REQINIT message type");
   2852  1.14     gibbs 	}
   2853  1.14     gibbs 
   2854  1.42      fvdl 	if (end_session) {
   2855  1.42      fvdl 		ahc_clear_msg_state(ahc);
   2856  1.42      fvdl 		ahc_outb(ahc, RETURN_1, EXIT_MSG_LOOP);
   2857  1.42      fvdl 	} else
   2858  1.42      fvdl 		ahc_outb(ahc, RETURN_1, CONT_MSG_LOOP);
   2859  1.14     gibbs }
   2860  1.14     gibbs 
   2861  1.42      fvdl /*
   2862  1.42      fvdl  * See if we sent a particular extended message to the target.
   2863  1.42      fvdl  * If "full" is true, the target saw the full message.
   2864  1.42      fvdl  * If "full" is false, the target saw at least the first
   2865  1.42      fvdl  * byte of the message.
   2866  1.42      fvdl  */
   2867  1.42      fvdl static int
   2868  1.42      fvdl ahc_sent_msg(struct ahc_softc *ahc, u_int msgtype, int full)
   2869  1.14     gibbs {
   2870  1.42      fvdl 	int found;
   2871  1.42      fvdl 	int index;
   2872  1.14     gibbs 
   2873  1.42      fvdl 	found = FALSE;
   2874  1.42      fvdl 	index = 0;
   2875  1.14     gibbs 
   2876  1.42      fvdl 	while (index < ahc->msgout_len) {
   2877  1.42      fvdl 		if (ahc->msgout_buf[index] == MSG_EXTENDED) {
   2878  1.14     gibbs 
   2879  1.42      fvdl 			/* Found a candidate */
   2880  1.42      fvdl 			if (ahc->msgout_buf[index+2] == msgtype) {
   2881  1.42      fvdl 				u_int end_index;
   2882  1.42      fvdl 
   2883  1.42      fvdl 				end_index = index + 1
   2884  1.42      fvdl 					  + ahc->msgout_buf[index + 1];
   2885  1.42      fvdl 				if (full) {
   2886  1.42      fvdl 					if (ahc->msgout_index > end_index)
   2887  1.42      fvdl 						found = TRUE;
   2888  1.42      fvdl 				} else if (ahc->msgout_index > index)
   2889  1.42      fvdl 					found = TRUE;
   2890  1.14     gibbs 			}
   2891  1.42      fvdl 			break;
   2892  1.42      fvdl 		} else if (ahc->msgout_buf[index] >= MSG_SIMPLE_Q_TAG
   2893  1.42      fvdl 			&& ahc->msgout_buf[index] <= MSG_IGN_WIDE_RESIDUE) {
   2894  1.14     gibbs 
   2895  1.42      fvdl 			/* Skip tag type and tag id or residue param*/
   2896  1.42      fvdl 			index += 2;
   2897  1.14     gibbs 		} else {
   2898  1.42      fvdl 			/* Single byte message */
   2899  1.42      fvdl 			index++;
   2900  1.14     gibbs 		}
   2901  1.42      fvdl 	}
   2902  1.42      fvdl 	return (found);
   2903  1.42      fvdl }
   2904  1.42      fvdl 
   2905  1.42      fvdl static int
   2906  1.42      fvdl ahc_parse_msg(struct ahc_softc *ahc, struct scsipi_link *sc_link,
   2907  1.42      fvdl 	      struct ahc_devinfo *devinfo)
   2908  1.42      fvdl {
   2909  1.42      fvdl 	struct	ahc_initiator_tinfo *tinfo;
   2910  1.42      fvdl 	struct	tmode_tstate *tstate;
   2911  1.42      fvdl 	int	reject;
   2912  1.42      fvdl 	int	done;
   2913  1.42      fvdl 	int	response;
   2914  1.42      fvdl 	u_int	targ_scsirate;
   2915  1.42      fvdl 
   2916  1.42      fvdl 	done = MSGLOOP_IN_PROG;
   2917  1.42      fvdl 	response = FALSE;
   2918  1.42      fvdl 	reject = FALSE;
   2919  1.42      fvdl 	tinfo = ahc_fetch_transinfo(ahc, devinfo->channel, devinfo->our_scsiid,
   2920  1.42      fvdl 				    devinfo->target, &tstate);
   2921  1.42      fvdl 	targ_scsirate = tinfo->scsirate;
   2922  1.42      fvdl 
   2923  1.42      fvdl 	/*
   2924  1.42      fvdl 	 * Parse as much of the message as is availible,
   2925  1.42      fvdl 	 * rejecting it if we don't support it.  When
   2926  1.42      fvdl 	 * the entire message is availible and has been
   2927  1.42      fvdl 	 * handled, return MSGLOOP_MSGCOMPLETE, indicating
   2928  1.42      fvdl 	 * that we have parsed an entire message.
   2929  1.42      fvdl 	 *
   2930  1.42      fvdl 	 * In the case of extended messages, we accept the length
   2931  1.42      fvdl 	 * byte outright and perform more checking once we know the
   2932  1.42      fvdl 	 * extended message type.
   2933  1.42      fvdl 	 */
   2934  1.42      fvdl 	switch (ahc->msgin_buf[0]) {
   2935  1.42      fvdl 	case MSG_MESSAGE_REJECT:
   2936  1.42      fvdl 		response = ahc_handle_msg_reject(ahc, devinfo);
   2937  1.42      fvdl 		/* FALLTHROUGH */
   2938  1.42      fvdl 	case MSG_NOOP:
   2939  1.42      fvdl 		done = MSGLOOP_MSGCOMPLETE;
   2940  1.14     gibbs 		break;
   2941  1.42      fvdl 	case MSG_IGN_WIDE_RESIDUE:
   2942  1.14     gibbs 	{
   2943  1.42      fvdl 		/* Wait for the whole message */
   2944  1.42      fvdl 		if (ahc->msgin_index >= 1) {
   2945  1.42      fvdl 			if (ahc->msgin_buf[1] != 1
   2946  1.42      fvdl 			 || tinfo->current.width == MSG_EXT_WDTR_BUS_8_BIT) {
   2947  1.42      fvdl 				reject = TRUE;
   2948  1.42      fvdl 				done = MSGLOOP_MSGCOMPLETE;
   2949  1.42      fvdl 			} else
   2950  1.42      fvdl 				ahc_handle_ign_wide_residue(ahc, devinfo);
   2951  1.42      fvdl 		}
   2952  1.42      fvdl 		break;
   2953  1.14     gibbs 	}
   2954  1.42      fvdl 	case MSG_EXTENDED:
   2955  1.14     gibbs 	{
   2956  1.42      fvdl 		/* Wait for enough of the message to begin validation */
   2957  1.42      fvdl 		if (ahc->msgin_index < 2)
   2958  1.42      fvdl 			break;
   2959  1.42      fvdl 		switch (ahc->msgin_buf[2]) {
   2960  1.14     gibbs 		case MSG_EXT_SDTR:
   2961  1.14     gibbs 		{
   2962  1.42      fvdl 			struct	 ahc_syncrate *syncrate;
   2963  1.42      fvdl 			u_int	 period;
   2964  1.42      fvdl 			u_int	 offset;
   2965  1.42      fvdl 			u_int	 saved_offset;
   2966  1.42      fvdl 
   2967  1.42      fvdl 			if (ahc->msgin_buf[1] != MSG_EXT_SDTR_LEN) {
   2968  1.42      fvdl 				reject = TRUE;
   2969  1.14     gibbs 				break;
   2970  1.14     gibbs 			}
   2971  1.14     gibbs 
   2972  1.14     gibbs 			/*
   2973  1.42      fvdl 			 * Wait until we have both args before validating
   2974  1.42      fvdl 			 * and acting on this message.
   2975  1.42      fvdl 			 *
   2976  1.42      fvdl 			 * Add one to MSG_EXT_SDTR_LEN to account for
   2977  1.42      fvdl 			 * the extended message preamble.
   2978  1.14     gibbs 			 */
   2979  1.42      fvdl 			if (ahc->msgin_index < (MSG_EXT_SDTR_LEN + 1))
   2980  1.42      fvdl 				break;
   2981  1.42      fvdl 
   2982  1.42      fvdl 			period = ahc->msgin_buf[3];
   2983  1.42      fvdl 			saved_offset = offset = ahc->msgin_buf[4];
   2984  1.42      fvdl 			syncrate = ahc_devlimited_syncrate(ahc, &period);
   2985  1.42      fvdl 			ahc_validate_offset(ahc, syncrate, &offset,
   2986  1.42      fvdl 					    targ_scsirate & WIDEXFER);
   2987  1.42      fvdl 			ahc_set_syncrate(ahc, devinfo,
   2988  1.42      fvdl 					 syncrate, period, offset,
   2989  1.42      fvdl 					 AHC_TRANS_ACTIVE|AHC_TRANS_GOAL,
   2990  1.42      fvdl 					 /*paused*/TRUE, /*done*/TRUE);
   2991  1.14     gibbs 
   2992  1.14     gibbs 			/*
   2993  1.14     gibbs 			 * See if we initiated Sync Negotiation
   2994  1.14     gibbs 			 * and didn't have to fall down to async
   2995  1.14     gibbs 			 * transfers.
   2996  1.14     gibbs 			 */
   2997  1.42      fvdl 			if (ahc_sent_msg(ahc, MSG_EXT_SDTR, /*full*/TRUE)) {
   2998  1.42      fvdl 				/* We started it */
   2999  1.42      fvdl 				if (saved_offset != offset) {
   3000  1.42      fvdl 					/* Went too low - force async */
   3001  1.42      fvdl 					reject = TRUE;
   3002  1.42      fvdl 				}
   3003  1.14     gibbs 			} else {
   3004  1.14     gibbs 				/*
   3005  1.14     gibbs 				 * Send our own SDTR in reply
   3006   1.1   mycroft 				 */
   3007  1.42      fvdl 				ahc->msgout_index = 0;
   3008  1.42      fvdl 				ahc->msgout_len = 0;
   3009  1.42      fvdl 				ahc_construct_sdtr(ahc, period, offset);
   3010  1.42      fvdl 				ahc->msgout_index = 0;
   3011  1.42      fvdl 				response = TRUE;
   3012   1.1   mycroft 			}
   3013  1.42      fvdl 			done = MSGLOOP_MSGCOMPLETE;
   3014  1.14     gibbs 			break;
   3015  1.14     gibbs 		}
   3016  1.14     gibbs 		case MSG_EXT_WDTR:
   3017  1.14     gibbs 		{
   3018  1.42      fvdl 			u_int	bus_width;
   3019  1.42      fvdl 			u_int	sending_reply;
   3020   1.1   mycroft 
   3021  1.42      fvdl 			sending_reply = FALSE;
   3022  1.42      fvdl 			if (ahc->msgin_buf[1] != MSG_EXT_WDTR_LEN) {
   3023  1.42      fvdl 				reject = TRUE;
   3024  1.14     gibbs 				break;
   3025  1.14     gibbs 			}
   3026   1.1   mycroft 
   3027  1.42      fvdl 			/*
   3028  1.42      fvdl 			 * Wait until we have our arg before validating
   3029  1.42      fvdl 			 * and acting on this message.
   3030  1.42      fvdl 			 *
   3031  1.42      fvdl 			 * Add one to MSG_EXT_WDTR_LEN to account for
   3032  1.42      fvdl 			 * the extended message preamble.
   3033  1.42      fvdl 			 */
   3034  1.42      fvdl 			if (ahc->msgin_index < (MSG_EXT_WDTR_LEN + 1))
   3035  1.42      fvdl 				break;
   3036   1.1   mycroft 
   3037  1.42      fvdl 			bus_width = ahc->msgin_buf[3];
   3038  1.42      fvdl 			if (ahc_sent_msg(ahc, MSG_EXT_WDTR, /*full*/TRUE)) {
   3039  1.14     gibbs 				/*
   3040  1.14     gibbs 				 * Don't send a WDTR back to the
   3041  1.14     gibbs 				 * target, since we asked first.
   3042  1.14     gibbs 				 */
   3043  1.42      fvdl 				switch (bus_width){
   3044  1.42      fvdl 				default:
   3045   1.6   mycroft 					/*
   3046  1.42      fvdl 					 * How can we do anything greater
   3047  1.42      fvdl 					 * than 16bit transfers on a 16bit
   3048  1.42      fvdl 					 * bus?
   3049   1.6   mycroft 					 */
   3050  1.42      fvdl 					reject = TRUE;
   3051  1.42      fvdl 					printf("%s: target %d requested %dBit "
   3052  1.14     gibbs 					       "transfers.  Rejecting...\n",
   3053  1.42      fvdl 					       ahc_name(ahc), devinfo->target,
   3054  1.42      fvdl 					       8 * (0x01 << bus_width));
   3055  1.42      fvdl 					/* FALLTHROUGH */
   3056  1.42      fvdl 				case MSG_EXT_WDTR_BUS_8_BIT:
   3057  1.42      fvdl 					bus_width = MSG_EXT_WDTR_BUS_8_BIT;
   3058  1.14     gibbs 					break;
   3059  1.42      fvdl 				case MSG_EXT_WDTR_BUS_16_BIT:
   3060  1.14     gibbs 					break;
   3061  1.14     gibbs 				}
   3062  1.14     gibbs 			} else {
   3063  1.14     gibbs 				/*
   3064  1.14     gibbs 				 * Send our own WDTR in reply
   3065  1.14     gibbs 				 */
   3066  1.42      fvdl 				switch (bus_width) {
   3067  1.14     gibbs 				default:
   3068  1.42      fvdl 					if (ahc->features & AHC_WIDE) {
   3069  1.42      fvdl 						/* Respond Wide */
   3070  1.42      fvdl 						bus_width =
   3071  1.42      fvdl 						    MSG_EXT_WDTR_BUS_16_BIT;
   3072  1.42      fvdl 						break;
   3073  1.42      fvdl 					}
   3074  1.42      fvdl 					/* FALLTHROUGH */
   3075  1.42      fvdl 				case MSG_EXT_WDTR_BUS_8_BIT:
   3076  1.42      fvdl 					bus_width = MSG_EXT_WDTR_BUS_8_BIT;
   3077  1.14     gibbs 					break;
   3078   1.1   mycroft 				}
   3079  1.42      fvdl 				ahc->msgout_index = 0;
   3080  1.42      fvdl 				ahc->msgout_len = 0;
   3081  1.42      fvdl 				ahc_construct_wdtr(ahc, bus_width);
   3082  1.42      fvdl 				ahc->msgout_index = 0;
   3083  1.42      fvdl 				response = TRUE;
   3084  1.42      fvdl 				sending_reply = TRUE;
   3085  1.42      fvdl 			}
   3086  1.42      fvdl 			ahc_set_width(ahc, devinfo, bus_width,
   3087  1.42      fvdl 				      AHC_TRANS_ACTIVE|AHC_TRANS_GOAL,
   3088  1.42      fvdl 				      /*paused*/TRUE, /*done*/TRUE);
   3089  1.42      fvdl 
   3090  1.42      fvdl 			/* After a wide message, we are async */
   3091  1.42      fvdl 			ahc_set_syncrate(ahc, devinfo,
   3092  1.42      fvdl 					 /*syncrate*/NULL, /*period*/0,
   3093  1.42      fvdl 					 /*offset*/0, AHC_TRANS_ACTIVE,
   3094  1.42      fvdl 					 /*paused*/TRUE, /*done*/FALSE);
   3095  1.42      fvdl 			if (sending_reply == FALSE && reject == FALSE) {
   3096  1.42      fvdl 
   3097  1.42      fvdl 				if (tinfo->goal.period) {
   3098  1.42      fvdl 					struct	ahc_syncrate *rate;
   3099  1.42      fvdl 					u_int	period;
   3100  1.42      fvdl 					u_int	offset;
   3101  1.42      fvdl 
   3102  1.42      fvdl 					/* Start the sync negotiation */
   3103  1.42      fvdl 					period = tinfo->goal.period;
   3104  1.42      fvdl 					rate = ahc_devlimited_syncrate(ahc,
   3105  1.42      fvdl 								       &period);
   3106  1.42      fvdl 					offset = tinfo->goal.offset;
   3107  1.42      fvdl 					ahc_validate_offset(ahc, rate, &offset,
   3108  1.42      fvdl 							  tinfo->current.width);
   3109  1.42      fvdl 					ahc->msgout_index = 0;
   3110  1.42      fvdl 					ahc->msgout_len = 0;
   3111  1.42      fvdl 					ahc_construct_sdtr(ahc, period, offset);
   3112  1.42      fvdl 					ahc->msgout_index = 0;
   3113  1.42      fvdl 					response = TRUE;
   3114  1.42      fvdl 				}
   3115  1.42      fvdl 			}
   3116  1.42      fvdl 			done = MSGLOOP_MSGCOMPLETE;
   3117  1.14     gibbs 			break;
   3118  1.14     gibbs 		}
   3119  1.14     gibbs 		default:
   3120  1.14     gibbs 			/* Unknown extended message.  Reject it. */
   3121  1.42      fvdl 			reject = TRUE;
   3122  1.42      fvdl 			break;
   3123  1.14     gibbs 		}
   3124  1.42      fvdl 		break;
   3125  1.14     gibbs 	}
   3126  1.42      fvdl 	case MSG_BUS_DEV_RESET:
   3127  1.42      fvdl 		ahc_handle_devreset(ahc, devinfo,
   3128  1.42      fvdl 				    XS_RESET, "Bus Device Reset Received",
   3129  1.42      fvdl 				    /*verbose_level*/0);
   3130  1.42      fvdl 		restart_sequencer(ahc);
   3131  1.42      fvdl 		done = MSGLOOP_TERMINATED;
   3132  1.42      fvdl 		break;
   3133  1.42      fvdl 	case MSG_ABORT_TAG:
   3134  1.42      fvdl 	case MSG_ABORT:
   3135  1.42      fvdl 	case MSG_CLEAR_QUEUE:
   3136  1.42      fvdl 		/* Target mode messages */
   3137  1.42      fvdl 		if (devinfo->role != ROLE_TARGET) {
   3138  1.42      fvdl 			reject = TRUE;
   3139  1.14     gibbs 			break;
   3140  1.14     gibbs 		}
   3141  1.42      fvdl #if AHC_TARGET_MODE
   3142  1.42      fvdl 		ahc_abort_scbs(ahc, devinfo->target, devinfo->channel,
   3143  1.42      fvdl 			       devinfo->lun,
   3144  1.42      fvdl 			       ahc->msgin_buf[0] == MSG_ABORT_TAG
   3145  1.42      fvdl 						  ? SCB_LIST_NULL
   3146  1.42      fvdl 						  : ahc_inb(ahc, INITIATOR_TAG),
   3147  1.42      fvdl 			       ROLE_TARGET, XS_DRIVER_STUFFUP);
   3148  1.42      fvdl 
   3149  1.42      fvdl 		tstate = ahc->enabled_targets[devinfo->our_scsiid];
   3150  1.42      fvdl 		if (tstate != NULL) {
   3151  1.42      fvdl 			struct tmode_lstate* lstate;
   3152  1.42      fvdl 
   3153  1.42      fvdl 			lstate = tstate->enabled_luns[devinfo->lun];
   3154  1.42      fvdl 			if (lstate != NULL) {
   3155  1.42      fvdl 				ahc_queue_lstate_event(ahc, lstate,
   3156  1.42      fvdl 						       devinfo->our_scsiid,
   3157  1.42      fvdl 						       ahc->msgin_buf[0],
   3158  1.42      fvdl 						       /*arg*/0);
   3159  1.42      fvdl 				ahc_send_lstate_events(ahc, lstate);
   3160  1.42      fvdl 			}
   3161  1.42      fvdl 		}
   3162  1.42      fvdl 		done = MSGLOOP_MSGCOMPLETE;
   3163  1.42      fvdl #else
   3164  1.42      fvdl 		panic("ahc: got target mode message");
   3165  1.42      fvdl #endif
   3166  1.42      fvdl 		break;
   3167  1.42      fvdl 	case MSG_TERM_IO_PROC:
   3168  1.42      fvdl 	default:
   3169  1.42      fvdl 		reject = TRUE;
   3170  1.14     gibbs 		break;
   3171  1.14     gibbs 	}
   3172   1.6   mycroft 
   3173  1.42      fvdl 	if (reject) {
   3174  1.14     gibbs 		/*
   3175  1.42      fvdl 		 * Setup to reject the message.
   3176  1.14     gibbs 		 */
   3177  1.42      fvdl 		ahc->msgout_index = 0;
   3178  1.42      fvdl 		ahc->msgout_len = 1;
   3179  1.42      fvdl 		ahc->msgout_buf[0] = MSG_MESSAGE_REJECT;
   3180  1.42      fvdl 		done = MSGLOOP_MSGCOMPLETE;
   3181  1.42      fvdl 		response = TRUE;
   3182  1.42      fvdl 	}
   3183   1.1   mycroft 
   3184  1.42      fvdl 	if (done != MSGLOOP_IN_PROG && !response)
   3185  1.42      fvdl 		/* Clear the outgoing message buffer */
   3186  1.42      fvdl 		ahc->msgout_len = 0;
   3187   1.1   mycroft 
   3188  1.42      fvdl 	return (done);
   3189  1.42      fvdl }
   3190   1.1   mycroft 
   3191  1.42      fvdl static void
   3192  1.42      fvdl ahc_handle_ign_wide_residue(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
   3193  1.42      fvdl {
   3194  1.42      fvdl 	u_int scb_index;
   3195  1.42      fvdl 	struct scb *scb;
   3196  1.22       cgd 
   3197  1.42      fvdl 	scb_index = ahc_inb(ahc, SCB_TAG);
   3198  1.42      fvdl 	scb = &ahc->scb_data->scbarray[scb_index];
   3199  1.42      fvdl 	if ((ahc_inb(ahc, SEQ_FLAGS) & DPHASE) == 0
   3200  1.42      fvdl 	 || !(scb->xs->xs_control & XS_CTL_DATA_IN)) {
   3201  1.42      fvdl 		/*
   3202  1.42      fvdl 		 * Ignore the message if we haven't
   3203  1.42      fvdl 		 * seen an appropriate data phase yet.
   3204  1.42      fvdl 		 */
   3205  1.42      fvdl 	} else {
   3206   1.1   mycroft 		/*
   3207  1.42      fvdl 		 * If the residual occurred on the last
   3208  1.42      fvdl 		 * transfer and the transfer request was
   3209  1.42      fvdl 		 * expected to end on an odd count, do
   3210  1.42      fvdl 		 * nothing.  Otherwise, subtract a byte
   3211  1.42      fvdl 		 * and update the residual count accordingly.
   3212   1.1   mycroft 		 */
   3213  1.42      fvdl 		u_int resid_sgcnt;
   3214   1.6   mycroft 
   3215  1.42      fvdl 		resid_sgcnt = ahc_inb(ahc, SCB_RESID_SGCNT);
   3216  1.42      fvdl 		if (resid_sgcnt == 0
   3217  1.42      fvdl 		 && ahc_inb(ahc, DATA_COUNT_ODD) == 1) {
   3218   1.6   mycroft 			/*
   3219  1.42      fvdl 			 * If the residual occurred on the last
   3220  1.42      fvdl 			 * transfer and the transfer request was
   3221  1.42      fvdl 			 * expected to end on an odd count, do
   3222  1.42      fvdl 			 * nothing.
   3223   1.6   mycroft 			 */
   3224  1.42      fvdl 		} else {
   3225  1.42      fvdl 			u_int data_cnt;
   3226  1.42      fvdl 			u_int32_t data_addr;
   3227  1.42      fvdl 			u_int sg_index;
   3228  1.42      fvdl 
   3229  1.42      fvdl 			data_cnt = (ahc_inb(ahc, SCB_RESID_DCNT + 2) << 16)
   3230  1.42      fvdl 				 | (ahc_inb(ahc, SCB_RESID_DCNT + 1) << 8)
   3231  1.42      fvdl 				 | (ahc_inb(ahc, SCB_RESID_DCNT));
   3232  1.42      fvdl 
   3233  1.42      fvdl 			data_addr = (ahc_inb(ahc, SHADDR + 3) << 24)
   3234  1.42      fvdl 				  | (ahc_inb(ahc, SHADDR + 2) << 16)
   3235  1.42      fvdl 				  | (ahc_inb(ahc, SHADDR + 1) << 8)
   3236  1.42      fvdl 				  | (ahc_inb(ahc, SHADDR));
   3237  1.42      fvdl 
   3238  1.42      fvdl 			data_cnt += 1;
   3239  1.42      fvdl 			data_addr -= 1;
   3240  1.42      fvdl 
   3241  1.42      fvdl 			sg_index = scb->sg_count - resid_sgcnt;
   3242  1.42      fvdl 
   3243  1.42      fvdl 			if (sg_index != 0
   3244  1.42      fvdl 			 && (le32toh(scb->sg_list[sg_index].len) < data_cnt)) {
   3245  1.42      fvdl 				u_int32_t sg_addr;
   3246  1.42      fvdl 
   3247  1.42      fvdl 				sg_index--;
   3248  1.42      fvdl 				data_cnt = 1;
   3249  1.42      fvdl 				data_addr = le32toh(scb->sg_list[sg_index].addr)
   3250  1.42      fvdl 					  + le32toh(scb->sg_list[sg_index].len)
   3251  1.42      fvdl 					  - 1;
   3252  1.42      fvdl 
   3253  1.42      fvdl 				/*
   3254  1.42      fvdl 				 * The physical address base points to the
   3255  1.42      fvdl 				 * second entry as it is always used for
   3256  1.42      fvdl 				 * calculating the "next S/G pointer".
   3257  1.42      fvdl 				 */
   3258  1.42      fvdl 				sg_addr = scb->sg_list_phys
   3259  1.42      fvdl 					+ (sg_index* sizeof(*scb->sg_list));
   3260  1.42      fvdl 				ahc_outb(ahc, SG_NEXT + 3, sg_addr >> 24);
   3261  1.42      fvdl 				ahc_outb(ahc, SG_NEXT + 2, sg_addr >> 16);
   3262  1.42      fvdl 				ahc_outb(ahc, SG_NEXT + 1, sg_addr >> 8);
   3263  1.42      fvdl 				ahc_outb(ahc, SG_NEXT, sg_addr);
   3264   1.6   mycroft 			}
   3265   1.9  explorer 
   3266  1.42      fvdl 			ahc_outb(ahc, SCB_RESID_DCNT + 2, data_cnt >> 16);
   3267  1.42      fvdl 			ahc_outb(ahc, SCB_RESID_DCNT + 1, data_cnt >> 8);
   3268  1.42      fvdl 			ahc_outb(ahc, SCB_RESID_DCNT, data_cnt);
   3269  1.42      fvdl 
   3270  1.42      fvdl 			ahc_outb(ahc, SHADDR + 3, data_addr >> 24);
   3271  1.42      fvdl 			ahc_outb(ahc, SHADDR + 2, data_addr >> 16);
   3272  1.42      fvdl 			ahc_outb(ahc, SHADDR + 1, data_addr >> 8);
   3273  1.42      fvdl 			ahc_outb(ahc, SHADDR, data_addr);
   3274   1.1   mycroft 		}
   3275   1.6   mycroft 	}
   3276  1.42      fvdl }
   3277   1.1   mycroft 
   3278  1.42      fvdl static void
   3279  1.42      fvdl ahc_handle_devreset(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
   3280  1.42      fvdl 		    int status, char *message,
   3281  1.42      fvdl 		    int verbose_level)
   3282  1.42      fvdl {
   3283  1.42      fvdl 	int found;
   3284  1.14     gibbs 
   3285  1.42      fvdl 	found = ahc_abort_scbs(ahc, devinfo->target, devinfo->channel,
   3286  1.42      fvdl 			       AHC_LUN_WILDCARD, SCB_LIST_NULL, devinfo->role,
   3287  1.42      fvdl 			       status);
   3288  1.14     gibbs 
   3289  1.14     gibbs 	/*
   3290  1.42      fvdl 	 * Go back to async/narrow transfers and renegotiate.
   3291  1.42      fvdl 	 * ahc_set_width and ahc_set_syncrate can cope with NULL
   3292  1.42      fvdl 	 * paths.
   3293  1.42      fvdl 	 */
   3294  1.42      fvdl 	ahc_set_width(ahc, devinfo, MSG_EXT_WDTR_BUS_8_BIT,
   3295  1.42      fvdl 		      AHC_TRANS_CUR, /*paused*/TRUE, /*done*/FALSE);
   3296  1.42      fvdl 	ahc_set_syncrate(ahc, devinfo, /*syncrate*/NULL,
   3297  1.42      fvdl 			 /*period*/0, /*offset*/0, AHC_TRANS_CUR,
   3298  1.42      fvdl 			 /*paused*/TRUE, /*done*/FALSE);
   3299  1.42      fvdl 
   3300  1.42      fvdl 	if (message != NULL && (verbose_level <= 0))
   3301  1.42      fvdl 		printf("%s: %s on %c:%d. %d SCBs aborted\n", ahc_name(ahc),
   3302  1.42      fvdl 		       message, devinfo->channel, devinfo->target, found);
   3303   1.1   mycroft }
   3304   1.1   mycroft 
   3305   1.1   mycroft /*
   3306  1.42      fvdl  * We have an scb which has been processed by the
   3307   1.1   mycroft  * adaptor, now we look to see how the operation
   3308   1.1   mycroft  * went.
   3309   1.1   mycroft  */
   3310   1.6   mycroft static void
   3311  1.42      fvdl ahc_done(struct ahc_softc *ahc, struct scb *scb)
   3312   1.1   mycroft {
   3313  1.42      fvdl 	struct scsipi_xfer *xs;
   3314  1.42      fvdl 	struct scsipi_link *sc_link;
   3315  1.42      fvdl 	int requeue = 0;
   3316  1.42      fvdl 	int target;
   3317  1.42      fvdl 
   3318  1.42      fvdl 
   3319  1.42      fvdl 	xs = scb->xs;
   3320  1.42      fvdl 	sc_link = xs->sc_link;
   3321  1.42      fvdl 	LIST_REMOVE(scb, plinks);
   3322  1.42      fvdl 
   3323  1.44   thorpej 	callout_stop(&scb->xs->xs_callout);
   3324  1.42      fvdl 
   3325  1.42      fvdl #ifdef AHC_DEBUG
   3326  1.42      fvdl 	if (ahc_debug & AHC_SHOWCMDS) {
   3327  1.42      fvdl 		scsi_print_addr(sc_link);
   3328  1.42      fvdl 		printf("ahc_done opcode %d tag %x\n", xs->cmdstore.opcode,
   3329  1.42      fvdl 		    scb->hscb->tag);
   3330  1.42      fvdl 	}
   3331  1.42      fvdl #endif
   3332   1.6   mycroft 
   3333  1.42      fvdl 	target = sc_link->scsipi_scsi.target;
   3334  1.28       leo 
   3335  1.28       leo 	if (xs->datalen) {
   3336  1.42      fvdl 		int op;
   3337  1.42      fvdl 
   3338  1.42      fvdl 		if (xs->xs_control & XS_CTL_DATA_IN)
   3339  1.42      fvdl 			op = BUS_DMASYNC_POSTREAD;
   3340  1.42      fvdl 		else
   3341  1.42      fvdl 			op = BUS_DMASYNC_POSTWRITE;
   3342  1.42      fvdl 		bus_dmamap_sync(ahc->parent_dmat, scb->dmamap, 0,
   3343  1.42      fvdl 		    scb->dmamap->dm_mapsize, op);
   3344  1.42      fvdl 		bus_dmamap_unload(ahc->parent_dmat, scb->dmamap);
   3345  1.28       leo 	}
   3346  1.42      fvdl 
   3347  1.28       leo 	/*
   3348  1.42      fvdl 	 * Unbusy this target/channel/lun.
   3349  1.42      fvdl 	 * XXX if we are holding two commands per lun,
   3350  1.42      fvdl 	 *     send the next command.
   3351  1.42      fvdl 	 */
   3352  1.45      fvdl 	if (!(scb->hscb->control & TAG_ENB))
   3353  1.45      fvdl 		ahc_index_busy_tcl(ahc, scb->hscb->tcl, /*unbusy*/TRUE);
   3354  1.42      fvdl 
   3355   1.1   mycroft 	/*
   3356  1.42      fvdl 	 * If the recovery SCB completes, we have to be
   3357  1.42      fvdl 	 * out of our timeout.
   3358   1.1   mycroft 	 */
   3359  1.42      fvdl 	if ((scb->flags & SCB_RECOVERY_SCB) != 0) {
   3360  1.42      fvdl 
   3361  1.42      fvdl 		struct	scb *scbp;
   3362  1.42      fvdl 
   3363  1.42      fvdl 		/*
   3364  1.42      fvdl 		 * We were able to complete the command successfully,
   3365  1.42      fvdl 		 * so reinstate the timeouts for all other pending
   3366  1.42      fvdl 		 * commands.
   3367  1.42      fvdl 		 */
   3368  1.42      fvdl 		scbp = ahc->pending_ccbs.lh_first;
   3369  1.42      fvdl 		while (scbp != NULL) {
   3370  1.42      fvdl 			struct scsipi_xfer *txs = scbp->xs;
   3371  1.42      fvdl 
   3372  1.42      fvdl 			if (!(txs->xs_control & XS_CTL_POLL)) {
   3373  1.44   thorpej 				callout_reset(&scbp->xs->xs_callout,
   3374  1.44   thorpej 				    (scbp->xs->timeout * hz) / 1000,
   3375  1.44   thorpej 				    ahc_timeout, scbp);
   3376  1.42      fvdl 			}
   3377  1.42      fvdl 			scbp = LIST_NEXT(scbp, plinks);
   3378  1.42      fvdl 		}
   3379  1.42      fvdl 
   3380  1.42      fvdl 		/*
   3381  1.42      fvdl 		 * Ensure that we didn't put a second instance of this
   3382  1.42      fvdl 		 * SCB into the QINFIFO.
   3383  1.42      fvdl 		 */
   3384  1.42      fvdl 		ahc_search_qinfifo(ahc, SCB_TARGET(scb), SCB_CHANNEL(scb),
   3385  1.42      fvdl 				   SCB_LUN(scb), scb->hscb->tag,
   3386  1.42      fvdl 				   ROLE_INITIATOR, /*status*/0,
   3387  1.42      fvdl 				   SEARCH_REMOVE);
   3388  1.42      fvdl 		if (xs->error != XS_NOERROR)
   3389  1.42      fvdl 			ahcsetccbstatus(xs, XS_TIMEOUT);
   3390  1.42      fvdl 		scsi_print_addr(xs->sc_link);
   3391  1.42      fvdl 		printf("no longer in timeout, status = %x\n", xs->status);
   3392  1.42      fvdl 	}
   3393  1.42      fvdl 
   3394   1.6   mycroft 	if (xs->error != XS_NOERROR) {
   3395  1.42      fvdl 		/* Don't clobber any existing error state */
   3396  1.42      fvdl 	} else if ((scb->flags & SCB_SENSE) != 0) {
   3397  1.42      fvdl 		/*
   3398  1.42      fvdl 		 * We performed autosense retrieval.
   3399  1.42      fvdl 		 *
   3400  1.42      fvdl 		 * bzero the sense data before having
   3401  1.42      fvdl 		 * the drive fill it.  The SCSI spec mandates
   3402  1.42      fvdl 		 * that any untransfered data should be
   3403  1.42      fvdl 		 * assumed to be zero.  Complete the 'bounce'
   3404  1.42      fvdl 		 * of sense information through buffers accessible
   3405  1.42      fvdl 		 * via bus-space by copying it into the clients
   3406  1.42      fvdl 		 * csio.
   3407  1.42      fvdl 		 */
   3408  1.42      fvdl 		bzero(&xs->sense.scsi_sense, sizeof(xs->sense.scsi_sense));
   3409  1.42      fvdl 		bcopy(&ahc->scb_data->sense[scb->hscb->tag],
   3410  1.42      fvdl 		      &xs->sense.scsi_sense, le32toh(scb->sg_list->len));
   3411   1.6   mycroft 		xs->error = XS_SENSE;
   3412  1.28       leo 	}
   3413  1.42      fvdl 	if (scb->flags & SCB_FREEZE_QUEUE) {
   3414  1.42      fvdl 		ahc->devqueue_blocked[target]--;
   3415  1.42      fvdl 		scb->flags &= ~SCB_FREEZE_QUEUE;
   3416   1.1   mycroft 	}
   3417  1.42      fvdl 
   3418  1.42      fvdl 	requeue = scb->flags & SCB_REQUEUE;
   3419  1.42      fvdl 	ahcfreescb(ahc, scb);
   3420  1.42      fvdl 
   3421  1.42      fvdl 	if (requeue) {
   3422  1.42      fvdl 		/*
   3423  1.42      fvdl 		 * Re-insert at the front of the private queue to
   3424  1.42      fvdl 		 * preserve order.
   3425   1.1   mycroft 		 */
   3426  1.42      fvdl 		int s;
   3427  1.42      fvdl 
   3428  1.42      fvdl 		s = splbio();
   3429  1.42      fvdl 		TAILQ_INSERT_HEAD(&ahc->sc_q, xs, adapter_q);
   3430  1.42      fvdl 		splx(s);
   3431  1.42      fvdl 	} else {
   3432  1.42      fvdl 		xs->xs_status |= XS_STS_DONE;
   3433  1.45      fvdl 		ahc_check_tags(ahc, xs);
   3434  1.42      fvdl 		scsipi_done(xs);
   3435   1.1   mycroft 	}
   3436  1.18   thorpej 
   3437  1.34   thorpej 	if ((xs = TAILQ_FIRST(&ahc->sc_q)) != NULL)
   3438  1.42      fvdl 		ahc_action(xs);
   3439  1.42      fvdl }
   3440  1.42      fvdl 
   3441  1.42      fvdl /*
   3442  1.42      fvdl  * Determine the number of SCBs available on the controller
   3443  1.42      fvdl  */
   3444  1.42      fvdl int
   3445  1.42      fvdl ahc_probe_scbs(struct ahc_softc *ahc) {
   3446  1.42      fvdl 	int i;
   3447  1.42      fvdl 
   3448  1.42      fvdl 	for (i = 0; i < AHC_SCB_MAX; i++) {
   3449  1.42      fvdl 		ahc_outb(ahc, SCBPTR, i);
   3450  1.42      fvdl 		ahc_outb(ahc, SCB_CONTROL, i);
   3451  1.42      fvdl 		if (ahc_inb(ahc, SCB_CONTROL) != i)
   3452  1.42      fvdl 			break;
   3453  1.42      fvdl 		ahc_outb(ahc, SCBPTR, 0);
   3454  1.42      fvdl 		if (ahc_inb(ahc, SCB_CONTROL) != 0)
   3455  1.42      fvdl 			break;
   3456  1.42      fvdl 	}
   3457  1.42      fvdl 	return (i);
   3458   1.1   mycroft }
   3459   1.1   mycroft 
   3460   1.1   mycroft /*
   3461   1.1   mycroft  * Start the board, ready for normal operation
   3462   1.1   mycroft  */
   3463   1.1   mycroft int
   3464  1.42      fvdl ahc_init(struct ahc_softc *ahc)
   3465   1.1   mycroft {
   3466  1.14     gibbs 	int	  max_targ = 15;
   3467  1.42      fvdl 	int	  i;
   3468  1.42      fvdl 	int	  term;
   3469  1.42      fvdl 	u_int	  scsi_conf;
   3470  1.42      fvdl 	u_int	  scsiseq_template;
   3471  1.42      fvdl 	u_int	  ultraenb;
   3472  1.42      fvdl 	u_int	  discenable;
   3473  1.42      fvdl 	u_int	  tagenable;
   3474  1.42      fvdl 	size_t	  driver_data_size;
   3475  1.42      fvdl 	u_int32_t physaddr;
   3476  1.42      fvdl 
   3477  1.42      fvdl #ifdef AHC_PRINT_SRAM
   3478  1.42      fvdl 	printf("Scratch Ram:");
   3479  1.42      fvdl 	for (i = 0x20; i < 0x5f; i++) {
   3480  1.42      fvdl 		if (((i % 8) == 0) && (i != 0)) {
   3481  1.42      fvdl 			printf ("\n              ");
   3482  1.42      fvdl 		}
   3483  1.42      fvdl 		printf (" 0x%x", ahc_inb(ahc, i));
   3484  1.42      fvdl 	}
   3485  1.42      fvdl 	if ((ahc->features & AHC_MORE_SRAM) != 0) {
   3486  1.42      fvdl 		for (i = 0x70; i < 0x7f; i++) {
   3487  1.42      fvdl 			if (((i % 8) == 0) && (i != 0)) {
   3488  1.42      fvdl 				printf ("\n              ");
   3489  1.42      fvdl 			}
   3490  1.42      fvdl 			printf (" 0x%x", ahc_inb(ahc, i));
   3491  1.42      fvdl 		}
   3492  1.42      fvdl 	}
   3493  1.42      fvdl 	printf ("\n");
   3494  1.28       leo #endif
   3495  1.28       leo 
   3496   1.1   mycroft 	/*
   3497   1.6   mycroft 	 * Assume we have a board at this stage and it has been reset.
   3498   1.1   mycroft 	 */
   3499  1.42      fvdl 	if ((ahc->flags & AHC_USEDEFAULTS) != 0)
   3500  1.42      fvdl 		ahc->our_id = ahc->our_id_b = 7;
   3501  1.42      fvdl 
   3502  1.42      fvdl 	/*
   3503  1.42      fvdl 	 * Default to allowing initiator operations.
   3504  1.42      fvdl 	 */
   3505  1.42      fvdl 	ahc->flags |= AHC_INITIATORMODE;
   3506   1.1   mycroft 
   3507  1.42      fvdl 	/*
   3508  1.42      fvdl 	 * DMA tag for our command fifos and other data in system memory
   3509  1.42      fvdl 	 * the card's sequencer must be able to access.  For initiator
   3510  1.42      fvdl 	 * roles, we need to allocate space for the qinfifo, qoutfifo,
   3511  1.42      fvdl 	 * and untagged_scb arrays each of which are composed of 256
   3512  1.42      fvdl 	 * 1 byte elements.  When providing for the target mode role,
   3513  1.42      fvdl 	 * we additionally must provide space for the incoming target
   3514  1.42      fvdl 	 * command fifo.
   3515  1.42      fvdl 	 */
   3516  1.42      fvdl 	driver_data_size = 3 * 256 * sizeof(u_int8_t);
   3517   1.6   mycroft 
   3518  1.42      fvdl 	if (ahc_createdmamem(ahc->parent_dmat, driver_data_size,
   3519  1.42      fvdl 	    ahc->sc_dmaflags,
   3520  1.42      fvdl 	    &ahc->shared_data_dmamap, (caddr_t *)&ahc->qoutfifo,
   3521  1.42      fvdl 	    &ahc->shared_data_busaddr, &ahc->shared_data_seg,
   3522  1.42      fvdl 	    &ahc->shared_data_nseg, ahc_name(ahc), "shared data") < 0)
   3523  1.42      fvdl 		return (ENOMEM);
   3524   1.1   mycroft 
   3525  1.42      fvdl 	ahc->init_level++;
   3526   1.1   mycroft 
   3527  1.42      fvdl 	/* Allocate SCB data now that parent_dmat is initialized */
   3528  1.42      fvdl 	if (ahc->scb_data->maxhscbs == 0)
   3529  1.42      fvdl 		if (ahcinitscbdata(ahc) != 0)
   3530  1.42      fvdl 			return (ENOMEM);
   3531   1.1   mycroft 
   3532  1.42      fvdl 	ahc->qinfifo = &ahc->qoutfifo[256];
   3533  1.42      fvdl 	ahc->untagged_scbs = &ahc->qinfifo[256];
   3534  1.42      fvdl 	/* There are no untagged SCBs active yet. */
   3535  1.42      fvdl 	for (i = 0; i < 256; i++)
   3536  1.42      fvdl 		ahc->untagged_scbs[i] = SCB_LIST_NULL;
   3537   1.6   mycroft 
   3538  1.42      fvdl 	/* All of our queues are empty */
   3539  1.42      fvdl 	for (i = 0; i < 256; i++)
   3540  1.42      fvdl 		ahc->qoutfifo[i] = SCB_LIST_NULL;
   3541   1.6   mycroft 
   3542  1.42      fvdl 	bus_dmamap_sync(ahc->parent_dmat, ahc->shared_data_dmamap, 0,
   3543  1.42      fvdl 	    driver_data_size, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
   3544   1.6   mycroft 
   3545  1.28       leo 	/*
   3546  1.42      fvdl 	 * Allocate a tstate to house information for our
   3547  1.42      fvdl 	 * initiator presence on the bus as well as the user
   3548  1.42      fvdl 	 * data for any target mode initiator.
   3549  1.28       leo 	 */
   3550  1.42      fvdl 	if (ahc_alloc_tstate(ahc, ahc->our_id, 'A') == NULL) {
   3551  1.42      fvdl 		printf("%s: unable to allocate tmode_tstate.  "
   3552  1.42      fvdl 		       "Failing attach\n", ahc_name(ahc));
   3553  1.42      fvdl 		return (-1);
   3554  1.28       leo 	}
   3555  1.42      fvdl 
   3556  1.42      fvdl 	if ((ahc->features & AHC_TWIN) != 0) {
   3557  1.42      fvdl 		if (ahc_alloc_tstate(ahc, ahc->our_id_b, 'B') == NULL) {
   3558  1.42      fvdl 			printf("%s: unable to allocate tmode_tstate.  "
   3559  1.42      fvdl 			       "Failing attach\n", ahc_name(ahc));
   3560  1.42      fvdl 			return (-1);
   3561  1.42      fvdl 		}
   3562  1.42      fvdl  		printf("Twin Channel, A SCSI Id=%d, B SCSI Id=%d, primary %c, ",
   3563  1.42      fvdl 		       ahc->our_id, ahc->our_id_b,
   3564  1.42      fvdl 		       ahc->flags & AHC_CHANNEL_B_PRIMARY? 'B': 'A');
   3565  1.42      fvdl 	} else {
   3566  1.42      fvdl 		if ((ahc->features & AHC_WIDE) != 0) {
   3567  1.42      fvdl 			printf("Wide ");
   3568  1.42      fvdl 		} else {
   3569  1.42      fvdl 			printf("Single ");
   3570  1.42      fvdl 		}
   3571  1.42      fvdl 		printf("Channel %c, SCSI Id=%d, ", ahc->channel, ahc->our_id);
   3572  1.28       leo 	}
   3573  1.42      fvdl 
   3574  1.42      fvdl 	ahc_outb(ahc, SEQ_FLAGS, 0);
   3575  1.42      fvdl 
   3576  1.42      fvdl 	if (ahc->scb_data->maxhscbs < AHC_SCB_MAX) {
   3577  1.42      fvdl 		ahc->flags |= AHC_PAGESCBS;
   3578  1.42      fvdl 		printf("%d/%d SCBs\n", ahc->scb_data->maxhscbs, AHC_SCB_MAX);
   3579  1.42      fvdl 	} else {
   3580  1.42      fvdl 		ahc->flags &= ~AHC_PAGESCBS;
   3581  1.42      fvdl 		printf("%d SCBs\n", ahc->scb_data->maxhscbs);
   3582  1.28       leo 	}
   3583   1.6   mycroft 
   3584   1.6   mycroft #ifdef AHC_DEBUG
   3585  1.42      fvdl 	if (ahc_debug & AHC_SHOWMISC) {
   3586  1.42      fvdl 		printf("%s: hardware scb %d bytes; kernel scb %d bytes; "
   3587   1.6   mycroft 		       "ahc_dma %d bytes\n",
   3588   1.6   mycroft 			ahc_name(ahc),
   3589  1.42      fvdl 		        sizeof(struct hardware_scb),
   3590  1.42      fvdl 			sizeof(struct scb),
   3591   1.6   mycroft 			sizeof(struct ahc_dma_seg));
   3592   1.6   mycroft 	}
   3593   1.6   mycroft #endif /* AHC_DEBUG */
   3594   1.6   mycroft 
   3595   1.6   mycroft 	/* Set the SCSI Id, SXFRCTL0, SXFRCTL1, and SIMODE1, for both channels*/
   3596  1.42      fvdl 	if (ahc->features & AHC_TWIN) {
   3597  1.42      fvdl 
   3598   1.1   mycroft 		/*
   3599   1.1   mycroft 		 * The device is gated to channel B after a chip reset,
   3600   1.1   mycroft 		 * so set those values first
   3601   1.1   mycroft 		 */
   3602  1.42      fvdl 		term = (ahc->flags & AHC_TERM_ENB_B) != 0 ? STPWEN : 0;
   3603  1.42      fvdl 		if ((ahc->features & AHC_ULTRA2) != 0)
   3604  1.42      fvdl 			ahc_outb(ahc, SCSIID_ULTRA2, ahc->our_id_b);
   3605   1.6   mycroft 		else
   3606  1.42      fvdl 			ahc_outb(ahc, SCSIID, ahc->our_id_b);
   3607  1.42      fvdl 		scsi_conf = ahc_inb(ahc, SCSICONF + 1);
   3608  1.42      fvdl 		ahc_outb(ahc, SXFRCTL1, (scsi_conf & (ENSPCHK|STIMESEL))
   3609  1.42      fvdl 					|term|ENSTIMER|ACTNEGEN);
   3610  1.42      fvdl 		ahc_outb(ahc, SIMODE1, ENSELTIMO|ENSCSIRST|ENSCSIPERR);
   3611  1.42      fvdl 		ahc_outb(ahc, SXFRCTL0, DFON|SPIOEN);
   3612  1.42      fvdl 
   3613  1.42      fvdl 		if ((scsi_conf & RESET_SCSI) != 0
   3614  1.42      fvdl 		 && (ahc->flags & AHC_INITIATORMODE) != 0)
   3615  1.42      fvdl 			ahc->flags |= AHC_RESET_BUS_B;
   3616   1.6   mycroft 
   3617   1.1   mycroft 		/* Select Channel A */
   3618  1.42      fvdl 		ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) & ~SELBUSB);
   3619   1.6   mycroft 	}
   3620  1.42      fvdl 	term = (ahc->flags & AHC_TERM_ENB_A) != 0 ? STPWEN : 0;
   3621  1.42      fvdl 	if ((ahc->features & AHC_ULTRA2) != 0)
   3622  1.42      fvdl 		ahc_outb(ahc, SCSIID_ULTRA2, ahc->our_id);
   3623   1.6   mycroft 	else
   3624  1.42      fvdl 		ahc_outb(ahc, SCSIID, ahc->our_id);
   3625  1.42      fvdl 	scsi_conf = ahc_inb(ahc, SCSICONF);
   3626  1.42      fvdl 	ahc_outb(ahc, SXFRCTL1, (scsi_conf & (ENSPCHK|STIMESEL))
   3627  1.42      fvdl 				|term
   3628  1.42      fvdl 				|ENSTIMER|ACTNEGEN);
   3629  1.42      fvdl 	ahc_outb(ahc, SIMODE1, ENSELTIMO|ENSCSIRST|ENSCSIPERR);
   3630  1.42      fvdl 	ahc_outb(ahc, SXFRCTL0, DFON|SPIOEN);
   3631  1.42      fvdl 
   3632  1.42      fvdl 	if ((scsi_conf & RESET_SCSI) != 0
   3633  1.42      fvdl 	 && (ahc->flags & AHC_INITIATORMODE) != 0)
   3634  1.42      fvdl 		ahc->flags |= AHC_RESET_BUS_A;
   3635   1.6   mycroft 
   3636   1.1   mycroft 	/*
   3637   1.1   mycroft 	 * Look at the information that board initialization or
   3638  1.42      fvdl 	 * the board bios has left us.
   3639   1.1   mycroft 	 */
   3640  1.42      fvdl 	ultraenb = 0;
   3641  1.42      fvdl 	tagenable = ALL_TARGETS_MASK;
   3642   1.1   mycroft 
   3643   1.6   mycroft 	/* Grab the disconnection disable table and invert it for our needs */
   3644  1.42      fvdl 	if (ahc->flags & AHC_USEDEFAULTS) {
   3645  1.16  christos 		printf("%s: Host Adapter Bios disabled.  Using default SCSI "
   3646   1.6   mycroft 			"device parameters\n", ahc_name(ahc));
   3647  1.42      fvdl 		ahc->flags |= AHC_EXTENDED_TRANS_A|AHC_EXTENDED_TRANS_B|
   3648  1.42      fvdl 			      AHC_TERM_ENB_A|AHC_TERM_ENB_B;
   3649  1.42      fvdl 		discenable = ALL_TARGETS_MASK;
   3650  1.42      fvdl 		if ((ahc->features & AHC_ULTRA) != 0)
   3651  1.42      fvdl 			ultraenb = ALL_TARGETS_MASK;
   3652  1.42      fvdl 	} else {
   3653  1.42      fvdl 		discenable = ~((ahc_inb(ahc, DISC_DSB + 1) << 8)
   3654  1.42      fvdl 			   | ahc_inb(ahc, DISC_DSB));
   3655  1.42      fvdl 		if ((ahc->features & (AHC_ULTRA|AHC_ULTRA2)) != 0)
   3656  1.42      fvdl 			ultraenb = (ahc_inb(ahc, ULTRA_ENB + 1) << 8)
   3657  1.42      fvdl 				      | ahc_inb(ahc, ULTRA_ENB);
   3658   1.6   mycroft 	}
   3659   1.6   mycroft 
   3660  1.42      fvdl 	if ((ahc->features & (AHC_WIDE|AHC_TWIN)) == 0)
   3661   1.6   mycroft 		max_targ = 7;
   3662   1.6   mycroft 
   3663  1.42      fvdl 	for (i = 0; i <= max_targ; i++) {
   3664  1.42      fvdl 		struct ahc_initiator_tinfo *tinfo;
   3665  1.42      fvdl 		struct tmode_tstate *tstate;
   3666  1.42      fvdl 		u_int our_id;
   3667  1.42      fvdl 		u_int target_id;
   3668  1.42      fvdl 		char channel;
   3669  1.42      fvdl 
   3670  1.42      fvdl 		channel = 'A';
   3671  1.42      fvdl 		our_id = ahc->our_id;
   3672  1.42      fvdl 		target_id = i;
   3673  1.42      fvdl 		if (i > 7 && (ahc->features & AHC_TWIN) != 0) {
   3674  1.42      fvdl 			channel = 'B';
   3675  1.42      fvdl 			our_id = ahc->our_id_b;
   3676  1.42      fvdl 			target_id = i % 8;
   3677  1.42      fvdl 		}
   3678  1.42      fvdl 		tinfo = ahc_fetch_transinfo(ahc, channel, our_id,
   3679  1.42      fvdl 					    target_id, &tstate);
   3680  1.42      fvdl 		/* Default to async narrow across the board */
   3681  1.42      fvdl 		bzero(tinfo, sizeof(*tinfo));
   3682   1.6   mycroft 		if (ahc->flags & AHC_USEDEFAULTS) {
   3683  1.42      fvdl 			if ((ahc->features & AHC_WIDE) != 0)
   3684  1.42      fvdl 				tinfo->user.width = MSG_EXT_WDTR_BUS_16_BIT;
   3685  1.42      fvdl 
   3686  1.42      fvdl 			/*
   3687  1.42      fvdl 			 * These will be truncated when we determine the
   3688  1.42      fvdl 			 * connection type we have with the target.
   3689  1.42      fvdl 			 */
   3690  1.42      fvdl 			tinfo->user.period = ahc_syncrates->period;
   3691  1.42      fvdl 			tinfo->user.offset = ~0;
   3692  1.42      fvdl 		} else {
   3693  1.42      fvdl 			u_int scsirate;
   3694  1.42      fvdl 			u_int16_t mask;
   3695  1.42      fvdl 
   3696   1.6   mycroft 			/* Take the settings leftover in scratch RAM. */
   3697  1.42      fvdl 			scsirate = ahc_inb(ahc, TARG_SCSIRATE + i);
   3698  1.42      fvdl 			mask = (0x01 << i);
   3699  1.42      fvdl 			if ((ahc->features & AHC_ULTRA2) != 0) {
   3700  1.42      fvdl 				u_int offset;
   3701  1.42      fvdl 				u_int maxsync;
   3702   1.6   mycroft 
   3703  1.42      fvdl 				if ((scsirate & SOFS) == 0x0F) {
   3704  1.42      fvdl 					/*
   3705  1.42      fvdl 					 * Haven't negotiated yet,
   3706  1.42      fvdl 					 * so the format is different.
   3707  1.42      fvdl 					 */
   3708  1.42      fvdl 					scsirate = (scsirate & SXFR) >> 4
   3709  1.42      fvdl 						 | (ultraenb & mask)
   3710  1.42      fvdl 						  ? 0x08 : 0x0
   3711  1.42      fvdl 						 | (scsirate & WIDEXFER);
   3712  1.42      fvdl 					offset = MAX_OFFSET_ULTRA2;
   3713  1.42      fvdl 				} else
   3714  1.42      fvdl 					offset = ahc_inb(ahc, TARG_OFFSET + i);
   3715  1.42      fvdl 				maxsync = AHC_SYNCRATE_ULTRA2;
   3716  1.42      fvdl 				if ((ahc->features & AHC_DT) != 0)
   3717  1.42      fvdl 					maxsync = AHC_SYNCRATE_DT;
   3718  1.42      fvdl 				tinfo->user.period =
   3719  1.42      fvdl 				    ahc_find_period(ahc, scsirate, maxsync);
   3720  1.42      fvdl 				if (offset == 0)
   3721  1.42      fvdl 					tinfo->user.period = 0;
   3722  1.42      fvdl 				else
   3723  1.42      fvdl 					tinfo->user.offset = ~0;
   3724  1.42      fvdl 			} else if ((scsirate & SOFS) != 0) {
   3725  1.42      fvdl 				tinfo->user.period =
   3726  1.42      fvdl 				    ahc_find_period(ahc, scsirate,
   3727  1.42      fvdl 						    (ultraenb & mask)
   3728  1.42      fvdl 						   ? AHC_SYNCRATE_ULTRA
   3729  1.42      fvdl 						   : AHC_SYNCRATE_FAST);
   3730  1.42      fvdl 				if (tinfo->user.period != 0)
   3731  1.42      fvdl 					tinfo->user.offset = ~0;
   3732   1.6   mycroft 			}
   3733  1.42      fvdl 			if ((scsirate & WIDEXFER) != 0
   3734  1.42      fvdl 			 && (ahc->features & AHC_WIDE) != 0)
   3735  1.42      fvdl 				tinfo->user.width = MSG_EXT_WDTR_BUS_16_BIT;
   3736  1.42      fvdl 		}
   3737  1.42      fvdl 		tinfo->goal = tinfo->user; /* force negotiation */
   3738  1.42      fvdl 		tstate->ultraenb = ultraenb;
   3739  1.42      fvdl 		tstate->discenable = discenable;
   3740  1.42      fvdl 		tstate->tagenable = 0; /* Wait until the XPT says its okay */
   3741  1.49      fvdl 		tstate->tagdisable = 0;
   3742  1.42      fvdl 	}
   3743  1.42      fvdl 	ahc->user_discenable = discenable;
   3744  1.42      fvdl 	ahc->user_tagenable = tagenable;
   3745  1.42      fvdl 
   3746  1.42      fvdl 	/*
   3747  1.42      fvdl 	 * Tell the sequencer where it can find our arrays in memory.
   3748  1.42      fvdl 	 */
   3749  1.42      fvdl 	physaddr = ahc->scb_data->hscb_busaddr;
   3750  1.42      fvdl 	ahc_outb(ahc, HSCB_ADDR, physaddr & 0xFF);
   3751  1.42      fvdl 	ahc_outb(ahc, HSCB_ADDR + 1, (physaddr >> 8) & 0xFF);
   3752  1.42      fvdl 	ahc_outb(ahc, HSCB_ADDR + 2, (physaddr >> 16) & 0xFF);
   3753  1.42      fvdl 	ahc_outb(ahc, HSCB_ADDR + 3, (physaddr >> 24) & 0xFF);
   3754  1.42      fvdl 
   3755  1.42      fvdl 	physaddr = ahc->shared_data_busaddr;
   3756  1.42      fvdl 	ahc_outb(ahc, SCBID_ADDR, physaddr & 0xFF);
   3757  1.42      fvdl 	ahc_outb(ahc, SCBID_ADDR + 1, (physaddr >> 8) & 0xFF);
   3758  1.42      fvdl 	ahc_outb(ahc, SCBID_ADDR + 2, (physaddr >> 16) & 0xFF);
   3759  1.42      fvdl 	ahc_outb(ahc, SCBID_ADDR + 3, (physaddr >> 24) & 0xFF);
   3760  1.42      fvdl 
   3761  1.42      fvdl 	/* Target mode incomding command fifo */
   3762  1.42      fvdl 	physaddr += 3 * 256 * sizeof(u_int8_t);
   3763  1.42      fvdl 	ahc_outb(ahc, TMODE_CMDADDR, physaddr & 0xFF);
   3764  1.42      fvdl 	ahc_outb(ahc, TMODE_CMDADDR + 1, (physaddr >> 8) & 0xFF);
   3765  1.42      fvdl 	ahc_outb(ahc, TMODE_CMDADDR + 2, (physaddr >> 16) & 0xFF);
   3766  1.42      fvdl 	ahc_outb(ahc, TMODE_CMDADDR + 3, (physaddr >> 24) & 0xFF);
   3767  1.42      fvdl 
   3768  1.42      fvdl 	/*
   3769  1.42      fvdl 	 * Initialize the group code to command length table.
   3770  1.42      fvdl 	 * This overrides the values in TARG_SCSIRATE, so only
   3771  1.42      fvdl 	 * setup the table after we have processed that information.
   3772  1.42      fvdl 	 */
   3773  1.42      fvdl 	ahc_outb(ahc, CMDSIZE_TABLE, 5);
   3774  1.42      fvdl 	ahc_outb(ahc, CMDSIZE_TABLE + 1, 9);
   3775  1.42      fvdl 	ahc_outb(ahc, CMDSIZE_TABLE + 2, 9);
   3776  1.42      fvdl 	ahc_outb(ahc, CMDSIZE_TABLE + 3, 0);
   3777  1.42      fvdl 	ahc_outb(ahc, CMDSIZE_TABLE + 4, 15);
   3778  1.42      fvdl 	ahc_outb(ahc, CMDSIZE_TABLE + 5, 11);
   3779  1.42      fvdl 	ahc_outb(ahc, CMDSIZE_TABLE + 6, 0);
   3780  1.42      fvdl 	ahc_outb(ahc, CMDSIZE_TABLE + 7, 0);
   3781  1.42      fvdl 
   3782  1.42      fvdl 	/* Tell the sequencer of our initial queue positions */
   3783  1.42      fvdl 	ahc_outb(ahc, KERNEL_QINPOS, 0);
   3784  1.42      fvdl 	ahc_outb(ahc, QINPOS, 0);
   3785  1.42      fvdl 	ahc_outb(ahc, QOUTPOS, 0);
   3786   1.9  explorer 
   3787   1.6   mycroft #ifdef AHC_DEBUG
   3788  1.42      fvdl 	if (ahc_debug & AHC_SHOWMISC)
   3789  1.42      fvdl 		printf("DISCENABLE == 0x%x\nULTRAENB == 0x%x\n",
   3790  1.42      fvdl 		       discenable, ultraenb);
   3791   1.6   mycroft #endif
   3792   1.1   mycroft 
   3793  1.42      fvdl 	/* Don't have any special messages to send to targets */
   3794  1.42      fvdl 	ahc_outb(ahc, TARGET_MSG_REQUEST, 0);
   3795  1.42      fvdl 	ahc_outb(ahc, TARGET_MSG_REQUEST + 1, 0);
   3796   1.1   mycroft 
   3797   1.1   mycroft 	/*
   3798  1.42      fvdl 	 * Use the built in queue management registers
   3799  1.42      fvdl 	 * if they are available.
   3800   1.1   mycroft 	 */
   3801  1.42      fvdl 	if ((ahc->features & AHC_QUEUE_REGS) != 0) {
   3802  1.42      fvdl 		ahc_outb(ahc, QOFF_CTLSTA, SCB_QSIZE_256);
   3803  1.42      fvdl 		ahc_outb(ahc, SDSCB_QOFF, 0);
   3804  1.42      fvdl 		ahc_outb(ahc, SNSCB_QOFF, 0);
   3805  1.42      fvdl 		ahc_outb(ahc, HNSCB_QOFF, 0);
   3806  1.42      fvdl 	}
   3807   1.1   mycroft 
   3808   1.6   mycroft 
   3809   1.1   mycroft 	/* We don't have any waiting selections */
   3810  1.42      fvdl 	ahc_outb(ahc, WAITING_SCBH, SCB_LIST_NULL);
   3811   1.6   mycroft 
   3812   1.6   mycroft 	/* Our disconnection list is empty too */
   3813  1.42      fvdl 	ahc_outb(ahc, DISCONNECTED_SCBH, SCB_LIST_NULL);
   3814   1.6   mycroft 
   3815   1.6   mycroft 	/* Message out buffer starts empty */
   3816  1.42      fvdl 	ahc_outb(ahc, MSG_OUT, MSG_NOOP);
   3817  1.42      fvdl 
   3818  1.42      fvdl 	/*
   3819  1.42      fvdl 	 * Setup the allowed SCSI Sequences based on operational mode.
   3820  1.42      fvdl 	 * If we are a target, we'll enalbe select in operations once
   3821  1.42      fvdl 	 * we've had a lun enabled.
   3822  1.42      fvdl 	 */
   3823  1.42      fvdl 	scsiseq_template = ENSELO|ENAUTOATNO|ENAUTOATNP;
   3824  1.42      fvdl 	if ((ahc->flags & AHC_INITIATORMODE) != 0)
   3825  1.42      fvdl 		scsiseq_template |= ENRSELI;
   3826  1.42      fvdl 	ahc_outb(ahc, SCSISEQ_TEMPLATE, scsiseq_template);
   3827   1.6   mycroft 
   3828   1.6   mycroft 	/*
   3829   1.6   mycroft 	 * Load the Sequencer program and Enable the adapter
   3830   1.6   mycroft 	 * in "fast" mode.
   3831   1.6   mycroft          */
   3832  1.42      fvdl #ifdef AHC_DEBUG
   3833  1.42      fvdl 	printf("%s: Downloading Sequencer Program...",
   3834  1.42      fvdl 	       ahc_name(ahc));
   3835  1.13   thorpej #endif
   3836   1.6   mycroft 
   3837   1.6   mycroft 	ahc_loadseq(ahc);
   3838   1.6   mycroft 
   3839  1.42      fvdl 	/* We have to wait until after any system dumps... */
   3840  1.42      fvdl 	shutdownhook_establish(ahc_shutdown, ahc);
   3841   1.6   mycroft 
   3842   1.1   mycroft 	return (0);
   3843   1.1   mycroft }
   3844   1.1   mycroft 
   3845  1.52      fvdl static int
   3846  1.52      fvdl ahc_ioctl(struct scsipi_link *sc_link, u_long cmd, caddr_t addr, int flag,
   3847  1.52      fvdl 	  struct proc *p)
   3848  1.52      fvdl {
   3849  1.52      fvdl 	struct ahc_softc *ahc = sc_link->adapter_softc;
   3850  1.52      fvdl 	char channel;
   3851  1.52      fvdl 	int s, ret = ENOTTY;
   3852  1.52      fvdl 
   3853  1.52      fvdl 	switch (cmd) {
   3854  1.52      fvdl 	case SCBUSIORESET:
   3855  1.52      fvdl 		channel = SIM_CHANNEL(ahc, sc_link);
   3856  1.52      fvdl 		s = splbio();
   3857  1.52      fvdl 		ahc_reset_channel(ahc, channel, TRUE);
   3858  1.52      fvdl 		splx(s);
   3859  1.52      fvdl 		ret = 0;
   3860  1.52      fvdl 		break;
   3861  1.52      fvdl 	default:
   3862  1.52      fvdl 	}
   3863  1.52      fvdl 
   3864  1.52      fvdl 	return ret;
   3865  1.52      fvdl }
   3866  1.52      fvdl 
   3867  1.52      fvdl 
   3868   1.1   mycroft /*
   3869  1.42      fvdl  * XXX fvdl the busy_tcl checks and settings should only be done
   3870  1.42      fvdl  * for the non-tagged queueing case, but we don't do tagged queueing
   3871  1.42      fvdl  * yet, so..
   3872   1.1   mycroft  */
   3873   1.6   mycroft static int32_t
   3874  1.42      fvdl ahc_action(struct scsipi_xfer *xs)
   3875   1.1   mycroft {
   3876  1.42      fvdl 	struct scsipi_xfer *first_xs, *next_xs = NULL;
   3877  1.42      fvdl 	struct ahc_softc *ahc;
   3878  1.42      fvdl 	struct scb *scb;
   3879  1.42      fvdl 	struct hardware_scb *hscb;
   3880  1.42      fvdl 	struct ahc_initiator_tinfo *tinfo;
   3881  1.42      fvdl 	struct tmode_tstate *tstate;
   3882  1.42      fvdl 	u_int target_id;
   3883  1.42      fvdl 	u_int our_id;
   3884  1.42      fvdl 	int s, tcl;
   3885  1.42      fvdl 	u_int16_t mask;
   3886  1.52      fvdl 	char channel;
   3887  1.42      fvdl 	int dontqueue = 0, fromqueue = 0;
   3888  1.42      fvdl 
   3889  1.42      fvdl 	SC_DEBUG(xs->sc_link, SDEV_DB3, ("ahc_action\n"));
   3890  1.18   thorpej 
   3891  1.42      fvdl 	ahc = (struct ahc_softc *)xs->sc_link->adapter_softc;
   3892  1.18   thorpej 
   3893  1.18   thorpej 	/* must protect the queue */
   3894  1.18   thorpej 	s = splbio();
   3895  1.18   thorpej 
   3896  1.34   thorpej 	if (xs == TAILQ_FIRST(&ahc->sc_q)) {
   3897  1.42      fvdl 		/*
   3898  1.42      fvdl 		 * Called from ahc_done. Calling with the first entry in
   3899  1.42      fvdl 		 * the queue is really just a way of seeing where we're
   3900  1.42      fvdl 		 * called from. Now, find the first eligible SCB to send,
   3901  1.42      fvdl 		 * e.g. one which will be accepted immediately.
   3902  1.42      fvdl 		 */
   3903  1.42      fvdl 
   3904  1.42      fvdl 		if (ahc->queue_blocked) {
   3905  1.42      fvdl 			splx(s);
   3906  1.42      fvdl 			return (TRY_AGAIN_LATER);
   3907  1.42      fvdl 		}
   3908  1.42      fvdl 
   3909  1.42      fvdl 		xs = ahc_first_xs(ahc);
   3910  1.42      fvdl 		if (xs == NULL) {
   3911  1.42      fvdl 			splx(s);
   3912  1.42      fvdl 			return (TRY_AGAIN_LATER);
   3913  1.42      fvdl 		}
   3914  1.42      fvdl 
   3915  1.42      fvdl 		next_xs = TAILQ_NEXT(xs, adapter_q);
   3916  1.34   thorpej 		TAILQ_REMOVE(&ahc->sc_q, xs, adapter_q);
   3917  1.18   thorpej 		fromqueue = 1;
   3918  1.18   thorpej 		goto get_scb;
   3919  1.18   thorpej 	}
   3920  1.18   thorpej 
   3921  1.42      fvdl 	/*
   3922  1.42      fvdl 	 * If no new requests are accepted, just insert into the
   3923  1.42      fvdl 	 * private queue to wait for our turn.
   3924  1.42      fvdl 	 */
   3925  1.42      fvdl 	tcl = XS_TCL(ahc, xs);
   3926  1.45      fvdl 
   3927  1.42      fvdl 	if (ahc->queue_blocked ||
   3928  1.42      fvdl 	    ahc->devqueue_blocked[xs->sc_link->scsipi_scsi.target] ||
   3929  1.51      fvdl 	    (!ahc_istagged_device(ahc, xs, 0) &&
   3930  1.45      fvdl 	     ahc_index_busy_tcl(ahc, tcl, FALSE) != SCB_LIST_NULL)) {
   3931  1.42      fvdl 		if (dontqueue) {
   3932  1.42      fvdl 			splx(s);
   3933  1.42      fvdl 			xs->error = XS_DRIVER_STUFFUP;
   3934  1.42      fvdl 			return TRY_AGAIN_LATER;
   3935  1.42      fvdl 		}
   3936  1.42      fvdl 		TAILQ_INSERT_TAIL(&ahc->sc_q, xs, adapter_q);
   3937  1.42      fvdl 		splx(s);
   3938  1.42      fvdl 		return SUCCESSFULLY_QUEUED;
   3939  1.42      fvdl 	}
   3940  1.42      fvdl 
   3941  1.42      fvdl 	first_xs = ahc_first_xs(ahc);
   3942  1.42      fvdl 
   3943  1.21     mikel 	/* determine safety of software queueing */
   3944  1.37   thorpej 	dontqueue = xs->xs_control & XS_CTL_POLL;
   3945  1.18   thorpej 
   3946  1.18   thorpej 	/*
   3947  1.18   thorpej 	 * Handle situations where there's already entries in the
   3948  1.18   thorpej 	 * queue.
   3949  1.18   thorpej 	 */
   3950  1.42      fvdl 	if (first_xs != NULL) {
   3951  1.18   thorpej 		/*
   3952  1.18   thorpej 		 * If we can't queue, we have to abort, since
   3953  1.18   thorpej 		 * we have to preserve order.
   3954  1.18   thorpej 		 */
   3955  1.18   thorpej 		if (dontqueue) {
   3956  1.18   thorpej 			splx(s);
   3957  1.18   thorpej 			xs->error = XS_DRIVER_STUFFUP;
   3958  1.18   thorpej 			return (TRY_AGAIN_LATER);
   3959  1.18   thorpej 		}
   3960  1.18   thorpej 
   3961  1.18   thorpej 		/*
   3962  1.18   thorpej 		 * Swap with the first queue entry.
   3963  1.18   thorpej 		 */
   3964  1.34   thorpej 		TAILQ_INSERT_TAIL(&ahc->sc_q, xs, adapter_q);
   3965  1.42      fvdl 		xs = first_xs;
   3966  1.42      fvdl 		next_xs = TAILQ_NEXT(xs, adapter_q);
   3967  1.34   thorpej 		TAILQ_REMOVE(&ahc->sc_q, xs, adapter_q);
   3968  1.18   thorpej 		fromqueue = 1;
   3969  1.42      fvdl 
   3970  1.18   thorpej 	}
   3971  1.18   thorpej 
   3972  1.42      fvdl get_scb:
   3973  1.42      fvdl 
   3974  1.42      fvdl 	target_id = xs->sc_link->scsipi_scsi.target;
   3975  1.42      fvdl 	our_id = SIM_SCSI_ID(ahc, xs->sc_link);
   3976  1.42      fvdl 
   3977   1.9  explorer 	/*
   3978  1.42      fvdl 	 * get an scb to use.
   3979  1.42      fvdl 	 */
   3980  1.42      fvdl 	if ((scb = ahcgetscb(ahc)) == NULL) {
   3981  1.42      fvdl 
   3982  1.18   thorpej 		if (dontqueue) {
   3983  1.18   thorpej 			splx(s);
   3984  1.18   thorpej 			xs->error = XS_DRIVER_STUFFUP;
   3985  1.18   thorpej 			return (TRY_AGAIN_LATER);
   3986  1.18   thorpej 		}
   3987  1.18   thorpej 
   3988  1.18   thorpej 		/*
   3989  1.42      fvdl 		 * If we were pulled off the queue, put ourselves
   3990  1.42      fvdl 		 * back to where we came from, otherwise tack ourselves
   3991  1.42      fvdl 		 * onto the end.
   3992  1.42      fvdl 		 */
   3993  1.42      fvdl 		if (fromqueue && next_xs != NULL)
   3994  1.42      fvdl 			TAILQ_INSERT_BEFORE(xs, next_xs, adapter_q);
   3995  1.42      fvdl 		else
   3996  1.42      fvdl 			TAILQ_INSERT_TAIL(&ahc->sc_q, xs, adapter_q);
   3997  1.42      fvdl 
   3998  1.42      fvdl 		splx(s);
   3999  1.42      fvdl 		return (SUCCESSFULLY_QUEUED);
   4000  1.42      fvdl 	}
   4001  1.42      fvdl 
   4002  1.42      fvdl 	tcl = XS_TCL(ahc, xs);
   4003  1.42      fvdl 
   4004  1.42      fvdl #ifdef DIAGNOSTIC
   4005  1.51      fvdl 	if (!ahc_istagged_device(ahc, xs, 0) &&
   4006  1.45      fvdl 	    ahc_index_busy_tcl(ahc, tcl, FALSE) != SCB_LIST_NULL)
   4007  1.42      fvdl 		panic("ahc: queuing for busy target");
   4008  1.42      fvdl #endif
   4009  1.42      fvdl 
   4010  1.42      fvdl 	scb->xs = xs;
   4011  1.42      fvdl 	hscb = scb->hscb;
   4012  1.42      fvdl 	hscb->tcl = tcl;
   4013  1.42      fvdl 
   4014  1.51      fvdl 	if (ahc_istagged_device(ahc, xs, 0))
   4015  1.45      fvdl 		scb->hscb->control |= MSG_SIMPLE_Q_TAG;
   4016  1.45      fvdl 	else
   4017  1.45      fvdl 		ahc_busy_tcl(ahc, scb);
   4018  1.42      fvdl 
   4019  1.42      fvdl 	splx(s);
   4020  1.52      fvdl 
   4021  1.52      fvdl 	channel = SIM_CHANNEL(ahc, xs->sc_link);
   4022  1.52      fvdl 	if (ahc->inited_channels[channel - 'A'] == 0) {
   4023  1.54      fvdl 		if ((channel == 'A' && (ahc->flags & AHC_RESET_BUS_A)) ||
   4024  1.54      fvdl 		    (channel == 'B' && (ahc->flags & AHC_RESET_BUS_B))) {
   4025  1.54      fvdl 			s = splbio();
   4026  1.54      fvdl 			ahc_reset_channel(ahc, channel, TRUE);
   4027  1.54      fvdl 			splx(s);
   4028  1.54      fvdl 		}
   4029  1.52      fvdl 		ahc->inited_channels[channel - 'A'] = 1;
   4030  1.52      fvdl 	}
   4031  1.52      fvdl 
   4032  1.42      fvdl 	/*
   4033  1.42      fvdl 	 * Put all the arguments for the xfer in the scb
   4034  1.42      fvdl 	 */
   4035  1.42      fvdl 
   4036  1.42      fvdl 	mask = SCB_TARGET_MASK(scb);
   4037  1.42      fvdl 	tinfo = ahc_fetch_transinfo(ahc, SIM_CHANNEL(ahc, xs->sc_link), our_id,
   4038  1.42      fvdl 				    target_id, &tstate);
   4039  1.42      fvdl 	if (ahc->inited_targets[target_id] == 0) {
   4040  1.42      fvdl 		struct ahc_devinfo devinfo;
   4041  1.42      fvdl 
   4042  1.42      fvdl 		s = splbio();
   4043  1.42      fvdl 		ahc_compile_devinfo(&devinfo, our_id, target_id,
   4044  1.42      fvdl 		    xs->sc_link->scsipi_scsi.lun, SIM_CHANNEL(ahc, xs->sc_link),
   4045  1.42      fvdl 		    ROLE_INITIATOR);
   4046  1.42      fvdl 		ahc_update_target_msg_request(ahc, &devinfo, tinfo, TRUE,
   4047  1.42      fvdl 		    FALSE);
   4048  1.42      fvdl 		ahc->inited_targets[target_id] = 1;
   4049  1.42      fvdl 		splx(s);
   4050  1.42      fvdl 	}
   4051  1.42      fvdl 
   4052  1.42      fvdl 	hscb->scsirate = tinfo->scsirate;
   4053  1.42      fvdl 	hscb->scsioffset = tinfo->current.offset;
   4054  1.42      fvdl 	if ((tstate->ultraenb & mask) != 0)
   4055  1.42      fvdl 		hscb->control |= ULTRAENB;
   4056  1.42      fvdl 
   4057  1.42      fvdl 	if ((tstate->discenable & mask) != 0)
   4058  1.42      fvdl 		hscb->control |= DISCENB;
   4059  1.42      fvdl 
   4060  1.42      fvdl 	if (xs->xs_control & XS_CTL_RESET) {
   4061  1.48   thorpej 		hscb->cmdpointer = 0;
   4062  1.42      fvdl 		scb->flags |= SCB_DEVICE_RESET;
   4063  1.42      fvdl 		hscb->control |= MK_MESSAGE;
   4064  1.42      fvdl 		return ahc_execute_scb(scb, NULL, 0);
   4065  1.42      fvdl 	}
   4066  1.42      fvdl 
   4067  1.42      fvdl 	return ahc_setup_data(ahc, xs, scb);
   4068  1.42      fvdl }
   4069  1.42      fvdl 
   4070  1.42      fvdl static int
   4071  1.42      fvdl ahc_execute_scb(void *arg, bus_dma_segment_t *dm_segs, int nsegments)
   4072  1.42      fvdl {
   4073  1.42      fvdl 	struct	 scb *scb;
   4074  1.42      fvdl 	struct scsipi_xfer *xs;
   4075  1.42      fvdl 	struct	 ahc_softc *ahc;
   4076  1.42      fvdl 	int	 s;
   4077  1.42      fvdl 
   4078  1.42      fvdl 	scb = (struct scb *)arg;
   4079  1.42      fvdl 	xs = scb->xs;
   4080  1.42      fvdl 	ahc = (struct ahc_softc *)xs->sc_link->adapter_softc;
   4081  1.42      fvdl 
   4082  1.42      fvdl 
   4083  1.42      fvdl 	if (nsegments != 0) {
   4084  1.42      fvdl 		struct	  ahc_dma_seg *sg;
   4085  1.42      fvdl 		bus_dma_segment_t *end_seg;
   4086  1.42      fvdl 		int op;
   4087  1.42      fvdl 
   4088  1.42      fvdl 		end_seg = dm_segs + nsegments;
   4089  1.42      fvdl 
   4090  1.42      fvdl 		/* Copy the first SG into the data pointer area */
   4091  1.42      fvdl 		scb->hscb->data = dm_segs->ds_addr;
   4092  1.42      fvdl 		scb->hscb->datalen = dm_segs->ds_len;
   4093  1.42      fvdl 
   4094  1.42      fvdl 		/* Copy the segments into our SG list */
   4095  1.42      fvdl 		sg = scb->sg_list;
   4096  1.42      fvdl 		while (dm_segs < end_seg) {
   4097  1.42      fvdl 			sg->addr = dm_segs->ds_addr;
   4098  1.42      fvdl 			sg->len = dm_segs->ds_len;
   4099  1.42      fvdl 			ahc_swap_sg(sg);
   4100  1.42      fvdl 			sg++;
   4101  1.42      fvdl 			dm_segs++;
   4102  1.42      fvdl 		}
   4103  1.42      fvdl 
   4104  1.42      fvdl 		/* Note where to find the SG entries in bus space */
   4105  1.42      fvdl 		scb->hscb->SG_pointer = scb->sg_list_phys;
   4106  1.42      fvdl 
   4107  1.42      fvdl 		if (xs->xs_control & XS_CTL_DATA_IN)
   4108  1.42      fvdl 			op = BUS_DMASYNC_PREREAD;
   4109  1.34   thorpej 		else
   4110  1.42      fvdl 			op = BUS_DMASYNC_PREWRITE;
   4111  1.42      fvdl 
   4112  1.42      fvdl 		bus_dmamap_sync(ahc->parent_dmat, scb->dmamap, 0,
   4113  1.42      fvdl 		    scb->dmamap->dm_mapsize, op);
   4114  1.18   thorpej 
   4115  1.42      fvdl 	} else {
   4116  1.42      fvdl 		scb->hscb->SG_pointer = 0;
   4117  1.42      fvdl 		scb->hscb->data = 0;
   4118  1.42      fvdl 		scb->hscb->datalen = 0;
   4119   1.9  explorer 	}
   4120  1.42      fvdl 
   4121  1.42      fvdl 	scb->sg_count = scb->hscb->SG_count = nsegments;
   4122  1.18   thorpej 
   4123  1.42      fvdl 	s = splbio();
   4124  1.18   thorpej 
   4125   1.9  explorer 	/*
   4126  1.42      fvdl 	 * Last time we need to check if this SCB needs to
   4127  1.42      fvdl 	 * be aborted.
   4128   1.9  explorer 	 */
   4129  1.42      fvdl 	if (xs->xs_status & XS_STS_DONE) {
   4130  1.51      fvdl 		if (!ahc_istagged_device(ahc, xs, 0))
   4131  1.45      fvdl 			ahc_index_busy_tcl(ahc, scb->hscb->tcl, TRUE);
   4132  1.42      fvdl 		if (nsegments != 0)
   4133  1.42      fvdl 			bus_dmamap_unload(ahc->parent_dmat, scb->dmamap);
   4134  1.42      fvdl 		ahcfreescb(ahc, scb);
   4135  1.42      fvdl 		splx(s);
   4136  1.42      fvdl 		return (COMPLETE);
   4137  1.42      fvdl 	}
   4138   1.6   mycroft 
   4139  1.42      fvdl #ifdef DIAGNOSTIC
   4140  1.42      fvdl 	if (scb->sg_count > 255)
   4141  1.42      fvdl 		panic("ahc bad sg_count");
   4142  1.29       leo #endif
   4143   1.6   mycroft 
   4144  1.42      fvdl 	ahc_swap_hscb(scb->hscb);
   4145  1.42      fvdl 
   4146  1.42      fvdl 	LIST_INSERT_HEAD(&ahc->pending_ccbs, scb, plinks);
   4147   1.6   mycroft 
   4148  1.42      fvdl 	scb->flags |= SCB_ACTIVE;
   4149   1.6   mycroft 
   4150  1.42      fvdl 	if (!(xs->xs_control & XS_CTL_POLL))
   4151  1.44   thorpej 		callout_reset(&scb->xs->xs_callout, (xs->timeout * hz) / 1000,
   4152  1.44   thorpej 		    ahc_timeout, scb);
   4153  1.42      fvdl 
   4154  1.42      fvdl 	if ((scb->flags & SCB_TARGET_IMMEDIATE) != 0) {
   4155  1.42      fvdl #if 0
   4156  1.42      fvdl 		printf("Continueing Immediate Command %d:%d\n",
   4157  1.42      fvdl 		       xs->sc_link->scsipi_scsi.target,
   4158  1.42      fvdl 		       xs->sc_link->scsipi_scsi.lun);
   4159  1.42      fvdl #endif
   4160  1.42      fvdl 		pause_sequencer(ahc);
   4161  1.42      fvdl 		if ((ahc->flags & AHC_PAGESCBS) == 0)
   4162  1.42      fvdl 			ahc_outb(ahc, SCBPTR, scb->hscb->tag);
   4163  1.42      fvdl 		ahc_outb(ahc, SCB_TAG, scb->hscb->tag);
   4164  1.42      fvdl 		ahc_outb(ahc, RETURN_1, CONT_MSG_LOOP);
   4165  1.42      fvdl 		unpause_sequencer(ahc);
   4166  1.42      fvdl 	} else {
   4167   1.6   mycroft 
   4168  1.42      fvdl #if 0
   4169  1.42      fvdl 		printf("tag %x at qpos %u vaddr %p paddr 0x%lx\n",
   4170  1.42      fvdl 		    scb->hscb->tag, ahc->qinfifonext,
   4171  1.42      fvdl 		    &ahc->qinfifo[ahc->qinfifonext],
   4172  1.42      fvdl 		    ahc->shared_data_busaddr + 1024 + ahc->qinfifonext);
   4173  1.28       leo #endif
   4174  1.28       leo 
   4175  1.42      fvdl 		ahc->qinfifo[ahc->qinfifonext++] = scb->hscb->tag;
   4176  1.42      fvdl 
   4177  1.42      fvdl 		bus_dmamap_sync(ahc->parent_dmat, ahc->shared_data_dmamap,
   4178  1.42      fvdl 		    QINFIFO_OFFSET * 256, 256, BUS_DMASYNC_PREWRITE);
   4179  1.42      fvdl 
   4180  1.42      fvdl 		if ((ahc->features & AHC_QUEUE_REGS) != 0) {
   4181  1.42      fvdl 			ahc_outb(ahc, HNSCB_QOFF, ahc->qinfifonext);
   4182  1.42      fvdl 		} else {
   4183  1.42      fvdl 			pause_sequencer(ahc);
   4184  1.42      fvdl 			ahc_outb(ahc, KERNEL_QINPOS, ahc->qinfifonext);
   4185  1.42      fvdl 			unpause_sequencer(ahc);
   4186  1.42      fvdl 		}
   4187  1.42      fvdl 	}
   4188   1.1   mycroft 
   4189   1.6   mycroft #ifdef AHC_DEBUG
   4190  1.42      fvdl 	if (ahc_debug & AHC_SHOWCMDS) {
   4191  1.42      fvdl 		scsi_print_addr(xs->sc_link);
   4192  1.42      fvdl 		printf("opcode %d tag %x len %d flags %x control %x fpos %u"
   4193  1.42      fvdl 		    " rate %x\n",
   4194  1.42      fvdl 		    xs->cmdstore.opcode, scb->hscb->tag, scb->hscb->datalen,
   4195  1.42      fvdl 		    scb->flags, scb->hscb->control, ahc->qinfifonext,
   4196  1.42      fvdl 		    scb->hscb->scsirate);
   4197  1.42      fvdl 	}
   4198   1.1   mycroft #endif
   4199   1.1   mycroft 
   4200  1.42      fvdl 	if (!(xs->xs_control & XS_CTL_POLL)) {
   4201   1.1   mycroft 		splx(s);
   4202   1.1   mycroft 		return (SUCCESSFULLY_QUEUED);
   4203   1.1   mycroft 	}
   4204   1.1   mycroft 	/*
   4205   1.6   mycroft 	 * If we can't use interrupts, poll for completion
   4206   1.1   mycroft 	 */
   4207   1.6   mycroft 	SC_DEBUG(xs->sc_link, SDEV_DB3, ("cmd_poll\n"));
   4208   1.6   mycroft 	do {
   4209   1.6   mycroft 		if (ahc_poll(ahc, xs->timeout)) {
   4210  1.37   thorpej 			if (!(xs->xs_control & XS_CTL_SILENT))
   4211  1.16  christos 				printf("cmd fail\n");
   4212   1.1   mycroft 			ahc_timeout(scb);
   4213   1.6   mycroft 			break;
   4214   1.6   mycroft 		}
   4215  1.37   thorpej 	} while (!(xs->xs_status & XS_STS_DONE));
   4216  1.42      fvdl 	splx(s);
   4217   1.1   mycroft 	return (COMPLETE);
   4218   1.1   mycroft }
   4219   1.1   mycroft 
   4220  1.42      fvdl static int
   4221  1.42      fvdl ahc_poll(struct ahc_softc *ahc, int wait)
   4222  1.42      fvdl {
   4223  1.42      fvdl 	while (--wait) {
   4224  1.42      fvdl 		DELAY(1000);
   4225  1.42      fvdl 		if (ahc_inb(ahc, INTSTAT) & INT_PEND)
   4226  1.42      fvdl 			break;
   4227  1.42      fvdl 	}
   4228  1.42      fvdl 
   4229  1.42      fvdl 	if (wait == 0) {
   4230  1.42      fvdl 		printf("%s: board is not responding\n", ahc_name(ahc));
   4231  1.42      fvdl 		return (EIO);
   4232  1.42      fvdl 	}
   4233  1.42      fvdl 
   4234  1.42      fvdl 	ahc_intr((void *)ahc);
   4235  1.42      fvdl 	return (0);
   4236  1.42      fvdl }
   4237  1.42      fvdl 
   4238  1.42      fvdl static int
   4239  1.42      fvdl ahc_setup_data(struct ahc_softc *ahc, struct scsipi_xfer *xs,
   4240  1.42      fvdl 	       struct scb *scb)
   4241  1.42      fvdl {
   4242  1.42      fvdl 	struct hardware_scb *hscb;
   4243  1.42      fvdl 
   4244  1.42      fvdl 	hscb = scb->hscb;
   4245  1.42      fvdl 	xs->resid = xs->status = 0;
   4246  1.42      fvdl 
   4247  1.42      fvdl 	hscb->cmdlen = xs->cmdlen;
   4248  1.42      fvdl 	memcpy(hscb->cmdstore, xs->cmd, xs->cmdlen);
   4249  1.42      fvdl 	hscb->cmdpointer = hscb->cmdstore_busaddr;
   4250  1.42      fvdl 
   4251  1.42      fvdl 	/* Only use S/G if there is a transfer */
   4252  1.42      fvdl 	if (xs->datalen) {
   4253  1.42      fvdl 		int error;
   4254  1.42      fvdl 
   4255  1.42      fvdl 		error = bus_dmamap_load(ahc->parent_dmat,
   4256  1.42      fvdl 			    scb->dmamap, xs->data,
   4257  1.42      fvdl 			    xs->datalen, NULL,
   4258  1.42      fvdl 			    (xs->xs_control & XS_CTL_NOSLEEP) ?
   4259  1.42      fvdl 			    BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
   4260  1.42      fvdl 		if (error) {
   4261  1.51      fvdl 			if (!ahc_istagged_device(ahc, xs, 0))
   4262  1.45      fvdl 				ahc_index_busy_tcl(ahc, hscb->tcl, TRUE);
   4263  1.42      fvdl 			return (TRY_AGAIN_LATER);	/* XXX fvdl */
   4264  1.42      fvdl 		}
   4265  1.42      fvdl 		error = ahc_execute_scb(scb,
   4266  1.42      fvdl 		    scb->dmamap->dm_segs,
   4267  1.42      fvdl 		    scb->dmamap->dm_nsegs);
   4268  1.42      fvdl 		return error;
   4269  1.42      fvdl 	} else {
   4270  1.42      fvdl 		return ahc_execute_scb(scb, NULL, 0);
   4271  1.42      fvdl 	}
   4272  1.42      fvdl }
   4273  1.42      fvdl 
   4274  1.42      fvdl static void
   4275  1.42      fvdl ahc_freeze_devq(struct ahc_softc *ahc, struct scsipi_link *sc_link)
   4276  1.42      fvdl {
   4277  1.42      fvdl 	int	target;
   4278  1.42      fvdl 	char	channel;
   4279  1.42      fvdl 	int	lun;
   4280  1.42      fvdl 
   4281  1.42      fvdl 	target = sc_link->scsipi_scsi.target;
   4282  1.42      fvdl 	lun = sc_link->scsipi_scsi.lun;
   4283  1.42      fvdl 	channel = sc_link->scsipi_scsi.channel;
   4284  1.42      fvdl 
   4285  1.42      fvdl 	ahc_search_qinfifo(ahc, target, channel, lun,
   4286  1.42      fvdl 			   /*tag*/SCB_LIST_NULL, ROLE_UNKNOWN,
   4287  1.42      fvdl 			   SCB_REQUEUE, SEARCH_COMPLETE);
   4288  1.42      fvdl }
   4289   1.1   mycroft 
   4290   1.6   mycroft static void
   4291  1.42      fvdl ahcallocscbs(struct ahc_softc *ahc)
   4292   1.1   mycroft {
   4293  1.42      fvdl 	struct scb_data *scb_data;
   4294  1.42      fvdl 	struct scb *next_scb;
   4295  1.42      fvdl 	struct sg_map_node *sg_map;
   4296  1.42      fvdl 	bus_addr_t physaddr;
   4297  1.42      fvdl 	struct ahc_dma_seg *segs;
   4298  1.42      fvdl 	int newcount;
   4299  1.42      fvdl 	int i;
   4300  1.42      fvdl 
   4301  1.42      fvdl 	scb_data = ahc->scb_data;
   4302  1.42      fvdl 	if (scb_data->numscbs >= AHC_SCB_MAX)
   4303  1.42      fvdl 		/* Can't allocate any more */
   4304  1.42      fvdl 		return;
   4305  1.42      fvdl 
   4306  1.42      fvdl 	next_scb = &scb_data->scbarray[scb_data->numscbs];
   4307  1.42      fvdl 
   4308  1.42      fvdl 	sg_map = malloc(sizeof(*sg_map), M_DEVBUF, M_NOWAIT);
   4309  1.42      fvdl 
   4310  1.42      fvdl 	if (sg_map == NULL)
   4311  1.42      fvdl 		return;
   4312  1.42      fvdl 
   4313  1.42      fvdl 	if (ahc_createdmamem(ahc->parent_dmat, PAGE_SIZE, ahc->sc_dmaflags,
   4314  1.42      fvdl 	    &sg_map->sg_dmamap,
   4315  1.42      fvdl 	    (caddr_t *)&sg_map->sg_vaddr, &sg_map->sg_physaddr,
   4316  1.42      fvdl 	    &sg_map->sg_dmasegs, &sg_map->sg_nseg, ahc_name(ahc),
   4317  1.42      fvdl 	    "SG space") < 0) {
   4318  1.42      fvdl 		free(sg_map, M_DEVBUF);
   4319  1.42      fvdl 		return;
   4320  1.42      fvdl 	}
   4321   1.1   mycroft 
   4322  1.42      fvdl 	SLIST_INSERT_HEAD(&scb_data->sg_maps, sg_map, links);
   4323  1.42      fvdl 
   4324  1.42      fvdl 	segs = sg_map->sg_vaddr;
   4325  1.42      fvdl 	physaddr = sg_map->sg_physaddr;
   4326   1.1   mycroft 
   4327  1.42      fvdl 	newcount = (PAGE_SIZE / (AHC_NSEG * sizeof(struct ahc_dma_seg)));
   4328  1.42      fvdl 	for (i = 0; scb_data->numscbs < AHC_SCB_MAX && i < newcount; i++) {
   4329  1.42      fvdl 		int error;
   4330   1.9  explorer 
   4331  1.42      fvdl 		next_scb->sg_list = segs;
   4332  1.42      fvdl 		/*
   4333  1.42      fvdl 		 * The sequencer always starts with the second entry.
   4334  1.42      fvdl 		 * The first entry is embedded in the scb.
   4335  1.42      fvdl 		 */
   4336  1.42      fvdl 		next_scb->sg_list_phys = physaddr + sizeof(struct ahc_dma_seg);
   4337  1.42      fvdl 		next_scb->flags = SCB_FREE;
   4338  1.42      fvdl 		error = bus_dmamap_create(ahc->parent_dmat,
   4339  1.42      fvdl 			    AHC_MAXTRANSFER_SIZE, AHC_NSEG, MAXBSIZE, 0,
   4340  1.42      fvdl 			    BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW|ahc->sc_dmaflags,
   4341  1.42      fvdl 			    &next_scb->dmamap);
   4342  1.42      fvdl 		if (error != 0)
   4343  1.42      fvdl 			break;
   4344  1.42      fvdl 		next_scb->hscb = &scb_data->hscbs[scb_data->numscbs];
   4345  1.42      fvdl 		next_scb->hscb->tag = ahc->scb_data->numscbs;
   4346  1.42      fvdl 		next_scb->hscb->cmdstore_busaddr =
   4347  1.42      fvdl 		    ahc_hscb_busaddr(ahc, next_scb->hscb->tag)
   4348  1.42      fvdl 		  + offsetof(struct hardware_scb, cmdstore);
   4349  1.42      fvdl 		next_scb->hscb->cmdstore_busaddr =
   4350  1.42      fvdl 		    htole32(next_scb->hscb->cmdstore_busaddr);
   4351  1.42      fvdl 		SLIST_INSERT_HEAD(&ahc->scb_data->free_scbs, next_scb, links);
   4352  1.42      fvdl 		segs += AHC_NSEG;
   4353  1.42      fvdl 		physaddr += (AHC_NSEG * sizeof(struct ahc_dma_seg));
   4354  1.42      fvdl 		next_scb++;
   4355  1.42      fvdl 		ahc->scb_data->numscbs++;
   4356   1.6   mycroft 	}
   4357  1.42      fvdl #ifdef AHC_DEBUG
   4358  1.42      fvdl 	if (ahc_debug & AHC_SHOWSCBALLOC)
   4359  1.42      fvdl 		printf("%s: allocated %d new SCBs count now %d\n",
   4360  1.42      fvdl 		    ahc_name(ahc), i - 1, ahc->scb_data->numscbs);
   4361  1.42      fvdl #endif
   4362  1.42      fvdl }
   4363  1.42      fvdl 
   4364  1.42      fvdl #ifdef AHC_DUMP_SEQ
   4365  1.42      fvdl static void
   4366  1.42      fvdl ahc_dumpseq(struct ahc_softc* ahc)
   4367  1.42      fvdl {
   4368  1.42      fvdl 	int i;
   4369  1.42      fvdl 	int max_prog;
   4370  1.42      fvdl 
   4371  1.42      fvdl 	if ((ahc->chip & AHC_BUS_MASK) < AHC_PCI)
   4372  1.42      fvdl 		max_prog = 448;
   4373  1.42      fvdl 	else if ((ahc->features & AHC_ULTRA2) != 0)
   4374  1.42      fvdl 		max_prog = 768;
   4375  1.42      fvdl 	else
   4376  1.42      fvdl 		max_prog = 512;
   4377  1.42      fvdl 
   4378  1.42      fvdl 	ahc_outb(ahc, SEQCTL, PERRORDIS|FAILDIS|FASTMODE|LOADRAM);
   4379  1.42      fvdl 	ahc_outb(ahc, SEQADDR0, 0);
   4380  1.42      fvdl 	ahc_outb(ahc, SEQADDR1, 0);
   4381  1.42      fvdl 	for (i = 0; i < max_prog; i++) {
   4382  1.42      fvdl 		u_int8_t ins_bytes[4];
   4383  1.42      fvdl 
   4384  1.42      fvdl 		ahc_insb(ahc, SEQRAM, ins_bytes, 4);
   4385  1.42      fvdl 		printf("0x%08x\n", ins_bytes[0] << 24
   4386  1.42      fvdl 				 | ins_bytes[1] << 16
   4387  1.42      fvdl 				 | ins_bytes[2] << 8
   4388  1.42      fvdl 				 | ins_bytes[3]);
   4389   1.6   mycroft 	}
   4390  1.42      fvdl }
   4391  1.42      fvdl #endif
   4392  1.42      fvdl 
   4393  1.42      fvdl static void
   4394  1.42      fvdl ahc_loadseq(struct ahc_softc *ahc)
   4395  1.42      fvdl {
   4396  1.42      fvdl 	struct patch *cur_patch;
   4397  1.42      fvdl 	int i;
   4398  1.42      fvdl 	int downloaded;
   4399  1.42      fvdl 	int skip_addr;
   4400  1.42      fvdl 	u_int8_t download_consts[4];
   4401  1.42      fvdl 
   4402  1.42      fvdl 	/* Setup downloadable constant table */
   4403  1.42      fvdl #if 0
   4404  1.42      fvdl 	/* No downloaded constants are currently defined. */
   4405  1.42      fvdl 	download_consts[TMODE_NUMCMDS] = ahc->num_targetcmds;
   4406  1.42      fvdl #endif
   4407  1.42      fvdl 
   4408  1.42      fvdl 	cur_patch = patches;
   4409  1.42      fvdl 	downloaded = 0;
   4410  1.42      fvdl 	skip_addr = 0;
   4411  1.42      fvdl 	ahc_outb(ahc, SEQCTL, PERRORDIS|FAILDIS|FASTMODE|LOADRAM);
   4412  1.42      fvdl 	ahc_outb(ahc, SEQADDR0, 0);
   4413  1.42      fvdl 	ahc_outb(ahc, SEQADDR1, 0);
   4414  1.42      fvdl 
   4415  1.42      fvdl 	for (i = 0; i < sizeof(seqprog)/4; i++) {
   4416  1.42      fvdl 		if (ahc_check_patch(ahc, &cur_patch, i, &skip_addr) == 0) {
   4417   1.6   mycroft 			/*
   4418  1.42      fvdl 			 * Don't download this instruction as it
   4419  1.42      fvdl 			 * is in a patch that was removed.
   4420   1.6   mycroft 			 */
   4421  1.42      fvdl                         continue;
   4422  1.42      fvdl 		}
   4423  1.42      fvdl 		ahc_download_instr(ahc, i, download_consts);
   4424  1.42      fvdl 		downloaded++;
   4425   1.6   mycroft 	}
   4426  1.42      fvdl 	ahc_outb(ahc, SEQCTL, PERRORDIS|FAILDIS|FASTMODE);
   4427  1.42      fvdl 	restart_sequencer(ahc);
   4428  1.42      fvdl 
   4429   1.9  explorer #ifdef AHC_DEBUG
   4430  1.42      fvdl 	printf(" %d instructions downloaded\n", downloaded);
   4431   1.9  explorer #endif
   4432   1.1   mycroft }
   4433   1.1   mycroft 
   4434  1.42      fvdl static int
   4435  1.42      fvdl ahc_check_patch(struct ahc_softc *ahc, struct patch **start_patch,
   4436  1.42      fvdl 		int start_instr, int *skip_addr)
   4437  1.42      fvdl {
   4438  1.42      fvdl 	struct	patch *cur_patch;
   4439  1.42      fvdl 	struct	patch *last_patch;
   4440  1.42      fvdl 	int	num_patches;
   4441  1.42      fvdl 
   4442  1.42      fvdl 	num_patches = sizeof(patches)/sizeof(struct patch);
   4443  1.42      fvdl 	last_patch = &patches[num_patches];
   4444  1.42      fvdl 	cur_patch = *start_patch;
   4445  1.42      fvdl 
   4446  1.42      fvdl 	while (cur_patch < last_patch && start_instr == cur_patch->begin) {
   4447  1.42      fvdl 
   4448  1.42      fvdl 		if (cur_patch->patch_func(ahc) == 0) {
   4449  1.42      fvdl 
   4450  1.42      fvdl 			/* Start rejecting code */
   4451  1.42      fvdl 			*skip_addr = start_instr + cur_patch->skip_instr;
   4452  1.42      fvdl 			cur_patch += cur_patch->skip_patch;
   4453  1.42      fvdl 		} else {
   4454  1.42      fvdl 			/* Accepted this patch.  Advance to the next
   4455  1.42      fvdl 			 * one and wait for our intruction pointer to
   4456  1.42      fvdl 			 * hit this point.
   4457  1.42      fvdl 			 */
   4458  1.42      fvdl 			cur_patch++;
   4459  1.28       leo 		}
   4460  1.28       leo 	}
   4461  1.42      fvdl 
   4462  1.42      fvdl 	*start_patch = cur_patch;
   4463  1.42      fvdl 	if (start_instr < *skip_addr)
   4464  1.42      fvdl 		/* Still skipping */
   4465  1.42      fvdl 		return (0);
   4466  1.42      fvdl 
   4467  1.42      fvdl 	return (1);
   4468  1.28       leo }
   4469  1.28       leo 
   4470  1.42      fvdl static void
   4471  1.42      fvdl ahc_download_instr(struct ahc_softc *ahc, int instrptr, u_int8_t *dconsts)
   4472   1.1   mycroft {
   4473  1.42      fvdl 	union	ins_formats instr;
   4474  1.42      fvdl 	struct	ins_format1 *fmt1_ins;
   4475  1.42      fvdl 	struct	ins_format3 *fmt3_ins;
   4476  1.42      fvdl 	u_int	opcode;
   4477  1.42      fvdl 
   4478  1.42      fvdl 	/* Structure copy */
   4479  1.42      fvdl 	instr = *(union ins_formats*)&seqprog[instrptr * 4];
   4480  1.42      fvdl 
   4481  1.42      fvdl 	instr.integer = le32toh(instr.integer);
   4482  1.42      fvdl 
   4483  1.42      fvdl 	fmt1_ins = &instr.format1;
   4484  1.42      fvdl 	fmt3_ins = NULL;
   4485  1.42      fvdl 
   4486  1.42      fvdl 	/* Pull the opcode */
   4487  1.42      fvdl 	opcode = instr.format1.opcode;
   4488  1.42      fvdl 	switch (opcode) {
   4489  1.42      fvdl 	case AIC_OP_JMP:
   4490  1.42      fvdl 	case AIC_OP_JC:
   4491  1.42      fvdl 	case AIC_OP_JNC:
   4492  1.42      fvdl 	case AIC_OP_CALL:
   4493  1.42      fvdl 	case AIC_OP_JNE:
   4494  1.42      fvdl 	case AIC_OP_JNZ:
   4495  1.42      fvdl 	case AIC_OP_JE:
   4496  1.42      fvdl 	case AIC_OP_JZ:
   4497  1.42      fvdl 	{
   4498  1.42      fvdl 		struct patch *cur_patch;
   4499  1.42      fvdl 		int address_offset;
   4500  1.42      fvdl 		u_int address;
   4501  1.42      fvdl 		int skip_addr;
   4502  1.42      fvdl 		int i;
   4503  1.42      fvdl 
   4504  1.42      fvdl 		fmt3_ins = &instr.format3;
   4505  1.42      fvdl 		address_offset = 0;
   4506  1.42      fvdl 		address = fmt3_ins->address;
   4507  1.42      fvdl 		cur_patch = patches;
   4508  1.42      fvdl 		skip_addr = 0;
   4509  1.42      fvdl 
   4510  1.42      fvdl 		for (i = 0; i < address;) {
   4511  1.42      fvdl 
   4512  1.42      fvdl 			ahc_check_patch(ahc, &cur_patch, i, &skip_addr);
   4513  1.42      fvdl 
   4514  1.42      fvdl 			if (skip_addr > i) {
   4515  1.42      fvdl 				int end_addr;
   4516  1.42      fvdl 
   4517  1.42      fvdl 				end_addr = MIN(address, skip_addr);
   4518  1.42      fvdl 				address_offset += end_addr - i;
   4519  1.42      fvdl 				i = skip_addr;
   4520  1.42      fvdl 			} else {
   4521  1.42      fvdl 				i++;
   4522  1.42      fvdl 			}
   4523   1.1   mycroft 		}
   4524  1.42      fvdl 		address -= address_offset;
   4525  1.42      fvdl 		fmt3_ins->address = address;
   4526  1.42      fvdl 		/* FALLTHROUGH */
   4527  1.42      fvdl 	}
   4528  1.42      fvdl 	case AIC_OP_OR:
   4529  1.42      fvdl 	case AIC_OP_AND:
   4530  1.42      fvdl 	case AIC_OP_XOR:
   4531  1.42      fvdl 	case AIC_OP_ADD:
   4532  1.42      fvdl 	case AIC_OP_ADC:
   4533  1.42      fvdl 	case AIC_OP_BMOV:
   4534  1.42      fvdl 		if (fmt1_ins->parity != 0) {
   4535  1.42      fvdl 			fmt1_ins->immediate = dconsts[fmt1_ins->immediate];
   4536  1.42      fvdl 		}
   4537  1.42      fvdl 		fmt1_ins->parity = 0;
   4538  1.42      fvdl 		/* FALLTHROUGH */
   4539  1.42      fvdl 	case AIC_OP_ROL:
   4540  1.42      fvdl 		if ((ahc->features & AHC_ULTRA2) != 0) {
   4541  1.42      fvdl 			int i, count;
   4542  1.42      fvdl 
   4543  1.42      fvdl 			/* Calculate odd parity for the instruction */
   4544  1.42      fvdl 			for (i = 0, count = 0; i < 31; i++) {
   4545  1.42      fvdl 				u_int32_t mask;
   4546  1.42      fvdl 
   4547  1.42      fvdl 				mask = 0x01 << i;
   4548  1.42      fvdl 				if ((instr.integer & mask) != 0)
   4549  1.42      fvdl 					count++;
   4550  1.42      fvdl 			}
   4551  1.42      fvdl 			if ((count & 0x01) == 0)
   4552  1.42      fvdl 				instr.format1.parity = 1;
   4553  1.42      fvdl 		} else {
   4554  1.42      fvdl 			/* Compress the instruction for older sequencers */
   4555  1.42      fvdl 			if (fmt3_ins != NULL) {
   4556  1.42      fvdl 				instr.integer =
   4557  1.42      fvdl 					fmt3_ins->immediate
   4558  1.42      fvdl 				      | (fmt3_ins->source << 8)
   4559  1.42      fvdl 				      | (fmt3_ins->address << 16)
   4560  1.42      fvdl 				      |	(fmt3_ins->opcode << 25);
   4561  1.42      fvdl 			} else {
   4562  1.42      fvdl 				instr.integer =
   4563  1.42      fvdl 					fmt1_ins->immediate
   4564  1.42      fvdl 				      | (fmt1_ins->source << 8)
   4565  1.42      fvdl 				      | (fmt1_ins->destination << 16)
   4566  1.42      fvdl 				      |	(fmt1_ins->ret << 24)
   4567  1.42      fvdl 				      |	(fmt1_ins->opcode << 25);
   4568   1.1   mycroft 			}
   4569   1.1   mycroft 		}
   4570  1.42      fvdl 		instr.integer = htole32(instr.integer);
   4571  1.42      fvdl 		ahc_outsb(ahc, SEQRAM, instr.bytes, 4);
   4572  1.42      fvdl 		break;
   4573  1.42      fvdl 	default:
   4574  1.42      fvdl 		panic("Unknown opcode encountered in seq program");
   4575   1.6   mycroft 		break;
   4576   1.1   mycroft 	}
   4577   1.1   mycroft }
   4578   1.1   mycroft 
   4579  1.42      fvdl static void
   4580  1.42      fvdl ahc_set_recoveryscb(struct ahc_softc *ahc, struct scb *scb)
   4581   1.1   mycroft {
   4582   1.1   mycroft 
   4583  1.42      fvdl 	if ((scb->flags & SCB_RECOVERY_SCB) == 0) {
   4584  1.42      fvdl 		struct scb *scbp;
   4585   1.6   mycroft 
   4586  1.42      fvdl 		scb->flags |= SCB_RECOVERY_SCB;
   4587   1.6   mycroft 
   4588  1.42      fvdl 		/*
   4589  1.42      fvdl 		 * Take all queued, but not sent SCBs out of the equation.
   4590  1.42      fvdl 		 * Also ensure that no new CCBs are queued to us while we
   4591  1.42      fvdl 		 * try to fix this problem.
   4592  1.42      fvdl 		 */
   4593  1.42      fvdl 		ahc->queue_blocked = 1;
   4594   1.1   mycroft 
   4595  1.42      fvdl 		/*
   4596  1.42      fvdl 		 * Go through all of our pending SCBs and remove
   4597  1.42      fvdl 		 * any scheduled timeouts for them.  We will reschedule
   4598  1.42      fvdl 		 * them after we've successfully fixed this problem.
   4599  1.42      fvdl 		 */
   4600  1.42      fvdl 		scbp = ahc->pending_ccbs.lh_first;
   4601  1.42      fvdl 		while (scbp != NULL) {
   4602  1.44   thorpej 			callout_stop(&scbp->xs->xs_callout);
   4603  1.42      fvdl 			scbp = scbp->plinks.le_next;
   4604  1.42      fvdl 		}
   4605   1.6   mycroft 	}
   4606   1.6   mycroft }
   4607   1.6   mycroft 
   4608   1.6   mycroft static void
   4609  1.42      fvdl ahc_timeout(void *arg)
   4610   1.6   mycroft {
   4611  1.42      fvdl 	struct	scb *scb;
   4612  1.42      fvdl 	struct	ahc_softc *ahc;
   4613   1.9  explorer 	int	s, found;
   4614  1.42      fvdl 	u_int	last_phase;
   4615  1.42      fvdl 	int	target;
   4616  1.42      fvdl 	int	lun;
   4617  1.42      fvdl 	int	i;
   4618   1.6   mycroft 	char	channel;
   4619   1.6   mycroft 
   4620  1.42      fvdl 	scb = (struct scb *)arg;
   4621  1.42      fvdl 	ahc = (struct ahc_softc *)scb->xs->sc_link->adapter_softc;
   4622  1.42      fvdl 
   4623   1.6   mycroft 	s = splbio();
   4624   1.6   mycroft 
   4625  1.42      fvdl 	/*
   4626  1.42      fvdl 	 * Ensure that the card doesn't do anything
   4627  1.42      fvdl 	 * behind our back.  Also make sure that we
   4628  1.42      fvdl 	 * didn't "just" miss an interrupt that would
   4629  1.42      fvdl 	 * affect this timeout.
   4630  1.42      fvdl 	 */
   4631  1.42      fvdl 	do {
   4632  1.42      fvdl 		ahc_intr(ahc);
   4633  1.42      fvdl 		pause_sequencer(ahc);
   4634  1.42      fvdl 	} while (ahc_inb(ahc, INTSTAT) & INT_PEND);
   4635  1.42      fvdl 
   4636  1.42      fvdl 	if ((scb->flags & SCB_ACTIVE) == 0) {
   4637   1.6   mycroft 		/* Previous timeout took care of me already */
   4638  1.42      fvdl 		printf("Timedout SCB handled by another timeout\n");
   4639  1.42      fvdl 		unpause_sequencer(ahc);
   4640   1.6   mycroft 		splx(s);
   4641   1.6   mycroft 		return;
   4642   1.6   mycroft 	}
   4643   1.6   mycroft 
   4644  1.42      fvdl 	target = SCB_TARGET(scb);
   4645  1.42      fvdl 	channel = SCB_CHANNEL(scb);
   4646  1.42      fvdl 	lun = SCB_LUN(scb);
   4647   1.6   mycroft 
   4648  1.25    bouyer 	scsi_print_addr(scb->xs->sc_link);
   4649  1.42      fvdl 	printf("SCB %x - timed out ", scb->hscb->tag);
   4650   1.6   mycroft 	/*
   4651   1.6   mycroft 	 * Take a snapshot of the bus state and print out
   4652   1.6   mycroft 	 * some information so we can track down driver bugs.
   4653   1.6   mycroft 	 */
   4654  1.42      fvdl 	last_phase = ahc_inb(ahc, LASTPHASE);
   4655   1.6   mycroft 
   4656  1.42      fvdl 	for (i = 0; i < num_phases; i++) {
   4657  1.42      fvdl 		if (last_phase == phase_table[i].phase)
   4658   1.6   mycroft 			break;
   4659   1.6   mycroft 	}
   4660  1.42      fvdl 	printf("%s", phase_table[i].phasemsg);
   4661   1.6   mycroft 
   4662  1.42      fvdl 	printf(", SEQADDR == 0x%x\n",
   4663  1.42      fvdl 	       ahc_inb(ahc, SEQADDR0) | (ahc_inb(ahc, SEQADDR1) << 8));
   4664  1.42      fvdl 	printf("SCSIRATE == 0x%x\n", ahc_inb(ahc, SCSIRATE));
   4665   1.6   mycroft 
   4666  1.42      fvdl #ifdef AHC_DEBUG
   4667  1.42      fvdl 	ahc_print_scb(scb);
   4668  1.42      fvdl #endif
   4669   1.6   mycroft 
   4670  1.42      fvdl #if 0
   4671  1.42      fvdl 	printf("SSTAT1 == 0x%x\n", ahc_inb(ahc, SSTAT1));
   4672  1.42      fvdl 	printf("SSTAT3 == 0x%x\n", ahc_inb(ahc, SSTAT3));
   4673  1.42      fvdl 	printf("SCSIPHASE == 0x%x\n", ahc_inb(ahc, SCSIPHASE));
   4674  1.42      fvdl 	printf("SCSIOFFSET == 0x%x\n", ahc_inb(ahc, SCSIOFFSET));
   4675  1.42      fvdl 	printf("SEQ_FLAGS == 0x%x\n", ahc_inb(ahc, SEQ_FLAGS));
   4676  1.42      fvdl 	printf("SCB_DATAPTR == 0x%x\n", ahc_inb(ahc, SCB_DATAPTR)
   4677  1.42      fvdl 				      | ahc_inb(ahc, SCB_DATAPTR + 1) << 8
   4678  1.42      fvdl 				      | ahc_inb(ahc, SCB_DATAPTR + 2) << 16
   4679  1.42      fvdl 				      | ahc_inb(ahc, SCB_DATAPTR + 3) << 24);
   4680  1.42      fvdl 	printf("SCB_DATACNT == 0x%x\n", ahc_inb(ahc, SCB_DATACNT)
   4681  1.42      fvdl 				      | ahc_inb(ahc, SCB_DATACNT + 1) << 8
   4682  1.42      fvdl 				      | ahc_inb(ahc, SCB_DATACNT + 2) << 16);
   4683  1.42      fvdl 	printf("SCB_SGCOUNT == 0x%x\n", ahc_inb(ahc, SCB_SGCOUNT));
   4684  1.42      fvdl 	printf("CCSCBCTL == 0x%x\n", ahc_inb(ahc, CCSCBCTL));
   4685  1.42      fvdl 	printf("CCSCBCNT == 0x%x\n", ahc_inb(ahc, CCSCBCNT));
   4686  1.42      fvdl 	printf("DFCNTRL == 0x%x\n", ahc_inb(ahc, DFCNTRL));
   4687  1.42      fvdl 	printf("DFSTATUS == 0x%x\n", ahc_inb(ahc, DFSTATUS));
   4688  1.42      fvdl 	printf("CCHCNT == 0x%x\n", ahc_inb(ahc, CCHCNT));
   4689  1.42      fvdl 	if (scb->sg_count > 0) {
   4690  1.42      fvdl 		for (i = 0; i < scb->sg_count; i++) {
   4691  1.42      fvdl 			printf("sg[%d] - Addr 0x%x : Length %d\n",
   4692  1.42      fvdl 			       i,
   4693  1.42      fvdl 			       le32toh(scb->sg_list[i].addr),
   4694  1.42      fvdl 			       le32toh(scb->sg_list[i].len));
   4695  1.42      fvdl 		}
   4696  1.42      fvdl 	}
   4697  1.42      fvdl #endif
   4698  1.42      fvdl 	if (scb->flags & (SCB_DEVICE_RESET|SCB_ABORT)) {
   4699   1.6   mycroft 		/*
   4700   1.6   mycroft 		 * Been down this road before.
   4701   1.6   mycroft 		 * Do a full bus reset.
   4702   1.6   mycroft 		 */
   4703  1.42      fvdl bus_reset:
   4704  1.42      fvdl 		ahcsetccbstatus(scb->xs, XS_TIMEOUT);
   4705  1.42      fvdl 		found = ahc_reset_channel(ahc, channel, /*Initiate Reset*/TRUE);
   4706  1.42      fvdl 		printf("%s: Issued Channel %c Bus Reset. "
   4707  1.42      fvdl 		       "%d SCBs aborted\n", ahc_name(ahc), channel, found);
   4708  1.42      fvdl 	} else {
   4709   1.6   mycroft 		/*
   4710  1.42      fvdl 		 * If we are a target, transition to bus free and report
   4711  1.42      fvdl 		 * the timeout.
   4712  1.42      fvdl 		 *
   4713  1.42      fvdl 		 * The target/initiator that is holding up the bus may not
   4714   1.6   mycroft 		 * be the same as the one that triggered this timeout
   4715   1.6   mycroft 		 * (different commands have different timeout lengths).
   4716  1.42      fvdl 		 * If the bus is idle and we are actiing as the initiator
   4717  1.42      fvdl 		 * for this request, queue a BDR message to the timed out
   4718  1.42      fvdl 		 * target.  Otherwise, if the timed out transaction is
   4719  1.42      fvdl 		 * active:
   4720  1.42      fvdl 		 *   Initiator transaction:
   4721  1.42      fvdl 		 *	Stuff the message buffer with a BDR message and assert
   4722  1.42      fvdl 		 *	ATN in the hopes that the target will let go of the bus
   4723  1.42      fvdl 		 *	and go to the mesgout phase.  If this fails, we'll
   4724  1.42      fvdl 		 *	get another timeout 2 seconds later which will attempt
   4725  1.42      fvdl 		 *	a bus reset.
   4726   1.6   mycroft 		 *
   4727  1.42      fvdl 		 *   Target transaction:
   4728  1.42      fvdl 		 *	Transition to BUS FREE and report the error.
   4729  1.42      fvdl 		 *	It's good to be the target!
   4730  1.42      fvdl 		 */
   4731  1.42      fvdl 		u_int active_scb_index;
   4732  1.42      fvdl 
   4733  1.42      fvdl 		active_scb_index = ahc_inb(ahc, SCB_TAG);
   4734  1.42      fvdl 
   4735  1.42      fvdl 		if (last_phase != P_BUSFREE
   4736  1.42      fvdl 		  && (active_scb_index < ahc->scb_data->numscbs)) {
   4737  1.42      fvdl 			struct scb *active_scb;
   4738  1.42      fvdl 
   4739  1.42      fvdl 			/*
   4740  1.42      fvdl 			 * If the active SCB is not from our device,
   4741  1.42      fvdl 			 * assume that another device is hogging the bus
   4742  1.42      fvdl 			 * and wait for it's timeout to expire before
   4743  1.42      fvdl 			 * taking additional action.
   4744  1.42      fvdl 			 */
   4745  1.42      fvdl 			active_scb = &ahc->scb_data->scbarray[active_scb_index];
   4746  1.42      fvdl 			if (active_scb->hscb->tcl != scb->hscb->tcl) {
   4747  1.42      fvdl 				u_int	newtimeout;
   4748  1.42      fvdl 
   4749  1.42      fvdl 				scsi_print_addr(scb->xs->sc_link);
   4750  1.42      fvdl 				printf("Other SCB Timeout%s",
   4751  1.42      fvdl 			 	       (scb->flags & SCB_OTHERTCL_TIMEOUT) != 0
   4752  1.42      fvdl 				       ? " again\n" : "\n");
   4753  1.42      fvdl 				scb->flags |= SCB_OTHERTCL_TIMEOUT;
   4754  1.42      fvdl 				newtimeout = MAX(active_scb->xs->timeout,
   4755  1.42      fvdl 						 scb->xs->timeout);
   4756  1.44   thorpej 				callout_reset(&scb->xs->xs_callout,
   4757  1.44   thorpej 				    (newtimeout * hz) / 1000,
   4758  1.44   thorpej 				    ahc_timeout, scb);
   4759  1.42      fvdl 				splx(s);
   4760  1.42      fvdl 				return;
   4761  1.42      fvdl 			}
   4762  1.42      fvdl 
   4763  1.42      fvdl 			/* It's us */
   4764  1.42      fvdl 			if ((scb->hscb->control & TARGET_SCB) != 0) {
   4765  1.42      fvdl 
   4766  1.42      fvdl 				/*
   4767  1.42      fvdl 				 * Send back any queued up transactions
   4768  1.42      fvdl 				 * and properly record the error condition.
   4769  1.42      fvdl 				 */
   4770  1.42      fvdl 				ahc_freeze_devq(ahc, scb->xs->sc_link);
   4771  1.42      fvdl 				ahcsetccbstatus(scb->xs, XS_TIMEOUT);
   4772  1.42      fvdl 				ahc_freeze_ccb(scb);
   4773  1.42      fvdl 				ahc_done(ahc, scb);
   4774  1.42      fvdl 
   4775  1.42      fvdl 				/* Will clear us from the bus */
   4776  1.42      fvdl 				restart_sequencer(ahc);
   4777  1.42      fvdl 				return;
   4778  1.42      fvdl 			}
   4779  1.42      fvdl 
   4780  1.42      fvdl 			ahc_set_recoveryscb(ahc, active_scb);
   4781  1.42      fvdl 			ahc_outb(ahc, MSG_OUT, MSG_BUS_DEV_RESET);
   4782  1.42      fvdl 			ahc_outb(ahc, SCSISIGO, last_phase|ATNO);
   4783  1.42      fvdl 			scsi_print_addr(active_scb->xs->sc_link);
   4784  1.42      fvdl 			printf("BDR message in message buffer\n");
   4785  1.42      fvdl 			active_scb->flags |=  SCB_DEVICE_RESET;
   4786  1.44   thorpej 			callout_reset(&active_scb->xs->xs_callout,
   4787  1.44   thorpej 			    2 * hz, ahc_timeout, active_scb);
   4788  1.42      fvdl 			unpause_sequencer(ahc);
   4789  1.42      fvdl 		} else {
   4790  1.42      fvdl 			int	 disconnected;
   4791  1.42      fvdl 
   4792  1.42      fvdl 			/* XXX Shouldn't panic.  Just punt instead */
   4793  1.42      fvdl 			if ((scb->hscb->control & TARGET_SCB) != 0)
   4794  1.42      fvdl 				panic("Timed-out target SCB but bus idle");
   4795  1.42      fvdl 
   4796  1.42      fvdl 			if (last_phase != P_BUSFREE
   4797  1.42      fvdl 			 && (ahc_inb(ahc, SSTAT0) & TARGET) != 0) {
   4798  1.42      fvdl 				/* XXX What happened to the SCB? */
   4799  1.42      fvdl 				/* Hung target selection.  Goto busfree */
   4800  1.42      fvdl 				printf("%s: Hung target selection\n",
   4801  1.42      fvdl 				       ahc_name(ahc));
   4802  1.42      fvdl 				restart_sequencer(ahc);
   4803  1.42      fvdl 				return;
   4804  1.42      fvdl 			}
   4805  1.42      fvdl 
   4806  1.42      fvdl 			if (ahc_search_qinfifo(ahc, target, channel, lun,
   4807  1.42      fvdl 					       scb->hscb->tag, ROLE_INITIATOR,
   4808  1.42      fvdl 					       /*status*/0, SEARCH_COUNT) > 0) {
   4809  1.42      fvdl 				disconnected = FALSE;
   4810  1.42      fvdl 			} else {
   4811  1.42      fvdl 				disconnected = TRUE;
   4812  1.42      fvdl 			}
   4813  1.42      fvdl 
   4814  1.42      fvdl 			if (disconnected) {
   4815  1.42      fvdl 				u_int active_scb;
   4816   1.1   mycroft 
   4817  1.42      fvdl 				ahc_set_recoveryscb(ahc, scb);
   4818  1.42      fvdl 				/*
   4819  1.42      fvdl 				 * Simply set the MK_MESSAGE control bit.
   4820  1.42      fvdl 				 */
   4821  1.42      fvdl 				scb->hscb->control |= MK_MESSAGE;
   4822  1.42      fvdl 				scb->flags |= SCB_QUEUED_MSG
   4823  1.42      fvdl 					   |  SCB_DEVICE_RESET;
   4824  1.42      fvdl 
   4825  1.42      fvdl 				/*
   4826  1.42      fvdl 				 * Mark the cached copy of this SCB in the
   4827  1.42      fvdl 				 * disconnected list too, so that a reconnect
   4828  1.42      fvdl 				 * at this point causes a BDR or abort.
   4829  1.42      fvdl 				 */
   4830  1.42      fvdl 				active_scb = ahc_inb(ahc, SCBPTR);
   4831  1.42      fvdl 				if (ahc_search_disc_list(ahc, target,
   4832  1.42      fvdl 							 channel, lun,
   4833  1.42      fvdl 							 scb->hscb->tag,
   4834  1.42      fvdl 							 /*stop_on_first*/TRUE,
   4835  1.42      fvdl 							 /*remove*/FALSE,
   4836  1.42      fvdl 							 /*save_state*/FALSE)) {
   4837  1.42      fvdl 					u_int scb_control;
   4838  1.42      fvdl 
   4839  1.42      fvdl 					scb_control = ahc_inb(ahc, SCB_CONTROL);
   4840  1.42      fvdl 					scb_control |= MK_MESSAGE;
   4841  1.42      fvdl 					ahc_outb(ahc, SCB_CONTROL, scb_control);
   4842   1.6   mycroft 				}
   4843  1.42      fvdl 				ahc_outb(ahc, SCBPTR, active_scb);
   4844  1.42      fvdl 				ahc_index_busy_tcl(ahc, scb->hscb->tcl,
   4845  1.42      fvdl 						   /*unbusy*/TRUE);
   4846  1.42      fvdl 
   4847  1.42      fvdl 				/*
   4848  1.42      fvdl 				 * Actually re-queue this SCB in case we can
   4849  1.42      fvdl 				 * select the device before it reconnects.
   4850  1.42      fvdl 				 * Clear out any entries in the QINFIFO first
   4851  1.42      fvdl 				 * so we are the next SCB for this target
   4852  1.42      fvdl 				 * to run.
   4853  1.42      fvdl 				 */
   4854  1.42      fvdl 				ahc_search_qinfifo(ahc, SCB_TARGET(scb),
   4855  1.42      fvdl 						   channel, SCB_LUN(scb),
   4856  1.42      fvdl 						   SCB_LIST_NULL,
   4857  1.42      fvdl 						   ROLE_INITIATOR,
   4858  1.42      fvdl 						   SCB_REQUEUE,
   4859  1.42      fvdl 						   SEARCH_COMPLETE);
   4860  1.25    bouyer 				scsi_print_addr(scb->xs->sc_link);
   4861  1.42      fvdl 				printf("Queuing a BDR SCB\n");
   4862  1.42      fvdl 				ahc->qinfifo[ahc->qinfifonext++] =
   4863  1.42      fvdl 				    scb->hscb->tag;
   4864  1.42      fvdl 
   4865  1.42      fvdl 				bus_dmamap_sync(ahc->parent_dmat,
   4866  1.42      fvdl 				    ahc->shared_data_dmamap,
   4867  1.42      fvdl 				    QINFIFO_OFFSET * 256, 256,
   4868  1.42      fvdl 				    BUS_DMASYNC_PREWRITE);
   4869  1.42      fvdl 
   4870  1.42      fvdl 				if ((ahc->features & AHC_QUEUE_REGS) != 0) {
   4871  1.42      fvdl 					ahc_outb(ahc, HNSCB_QOFF,
   4872  1.42      fvdl 						 ahc->qinfifonext);
   4873  1.42      fvdl 				} else {
   4874  1.42      fvdl 					ahc_outb(ahc, KERNEL_QINPOS,
   4875  1.42      fvdl 						 ahc->qinfifonext);
   4876   1.6   mycroft 				}
   4877  1.44   thorpej 				callout_reset(&scb->xs->xs_callout, 2 * hz,
   4878  1.44   thorpej 				    ahc_timeout, scb);
   4879  1.42      fvdl 				unpause_sequencer(ahc);
   4880  1.42      fvdl 			} else {
   4881  1.42      fvdl 				/* Go "immediatly" to the bus reset */
   4882  1.42      fvdl 				/* This shouldn't happen */
   4883  1.42      fvdl 				ahc_set_recoveryscb(ahc, scb);
   4884  1.42      fvdl 				scsi_print_addr(scb->xs->sc_link);
   4885  1.42      fvdl 				printf("SCB %x: Immediate reset.  "
   4886  1.42      fvdl 					"Flags = 0x%x\n", scb->hscb->tag,
   4887  1.42      fvdl 					scb->flags);
   4888  1.42      fvdl 				goto bus_reset;
   4889   1.6   mycroft 			}
   4890   1.6   mycroft 		}
   4891   1.1   mycroft 	}
   4892   1.6   mycroft 	splx(s);
   4893   1.1   mycroft }
   4894   1.1   mycroft 
   4895   1.6   mycroft static int
   4896  1.42      fvdl ahc_search_qinfifo(struct ahc_softc *ahc, int target, char channel,
   4897  1.42      fvdl 		   int lun, u_int tag, role_t role, scb_flag status,
   4898  1.42      fvdl 		   ahc_search_action action)
   4899  1.42      fvdl {
   4900  1.42      fvdl 	struct	 scb *scbp;
   4901  1.42      fvdl 	u_int8_t qinpos;
   4902  1.42      fvdl 	u_int8_t qintail;
   4903  1.42      fvdl 	int	 found;
   4904   1.1   mycroft 
   4905  1.42      fvdl 	qinpos = ahc_inb(ahc, QINPOS);
   4906  1.42      fvdl 	qintail = ahc->qinfifonext;
   4907  1.42      fvdl 	found = 0;
   4908   1.6   mycroft 
   4909   1.1   mycroft 	/*
   4910  1.42      fvdl 	 * Start with an empty queue.  Entries that are not chosen
   4911  1.42      fvdl 	 * for removal will be re-added to the queue as we go.
   4912   1.1   mycroft 	 */
   4913  1.42      fvdl 	ahc->qinfifonext = qinpos;
   4914  1.42      fvdl 
   4915  1.42      fvdl 	bus_dmamap_sync(ahc->parent_dmat, ahc->shared_data_dmamap,
   4916  1.42      fvdl 	    QINFIFO_OFFSET * 256, 256, BUS_DMASYNC_POSTREAD);
   4917   1.1   mycroft 
   4918  1.42      fvdl 	while (qinpos != qintail) {
   4919  1.42      fvdl 		scbp = &ahc->scb_data->scbarray[ahc->qinfifo[qinpos]];
   4920  1.42      fvdl 		if (ahc_match_scb(scbp, target, channel, lun, tag, role)) {
   4921  1.42      fvdl 			/*
   4922  1.42      fvdl 			 * We found an scb that needs to be removed.
   4923  1.42      fvdl 			 */
   4924  1.42      fvdl 			switch (action) {
   4925  1.42      fvdl 			case SEARCH_COMPLETE:
   4926  1.42      fvdl 				if (!(scbp->xs->xs_status & XS_STS_DONE)) {
   4927  1.42      fvdl 					scbp->flags |= status;
   4928  1.42      fvdl 					scbp->xs->error = XS_NOERROR;
   4929  1.42      fvdl 				}
   4930  1.42      fvdl 				ahc_freeze_ccb(scbp);
   4931  1.42      fvdl 				ahc_done(ahc, scbp);
   4932  1.42      fvdl 				break;
   4933  1.42      fvdl 			case SEARCH_COUNT:
   4934  1.42      fvdl 				ahc->qinfifo[ahc->qinfifonext++] =
   4935  1.42      fvdl 				    scbp->hscb->tag;
   4936  1.42      fvdl 				break;
   4937  1.42      fvdl 			case SEARCH_REMOVE:
   4938  1.42      fvdl 				break;
   4939   1.1   mycroft 			}
   4940  1.42      fvdl 			found++;
   4941  1.42      fvdl 		} else {
   4942  1.42      fvdl 			ahc->qinfifo[ahc->qinfifonext++] = scbp->hscb->tag;
   4943   1.1   mycroft 		}
   4944  1.42      fvdl 		qinpos++;
   4945  1.42      fvdl 	}
   4946  1.42      fvdl 
   4947  1.42      fvdl 	bus_dmamap_sync(ahc->parent_dmat, ahc->shared_data_dmamap,
   4948  1.42      fvdl 	    QINFIFO_OFFSET * 256, 256, BUS_DMASYNC_PREWRITE);
   4949  1.42      fvdl 
   4950  1.42      fvdl 	if ((ahc->features & AHC_QUEUE_REGS) != 0) {
   4951  1.42      fvdl 		ahc_outb(ahc, HNSCB_QOFF, ahc->qinfifonext);
   4952  1.42      fvdl 	} else {
   4953  1.42      fvdl 		ahc_outb(ahc, KERNEL_QINPOS, ahc->qinfifonext);
   4954   1.6   mycroft 	}
   4955   1.1   mycroft 
   4956  1.42      fvdl 	return (found);
   4957  1.42      fvdl }
   4958  1.42      fvdl 
   4959  1.42      fvdl /*
   4960  1.42      fvdl  * Abort all SCBs that match the given description (target/channel/lun/tag),
   4961  1.42      fvdl  * setting their status to the passed in status if the status has not already
   4962  1.42      fvdl  * been modified from CAM_REQ_INPROG.  This routine assumes that the sequencer
   4963  1.42      fvdl  * is paused before it is called.
   4964  1.42      fvdl  */
   4965  1.42      fvdl static int
   4966  1.42      fvdl ahc_abort_scbs(struct ahc_softc *ahc, int target, char channel,
   4967  1.42      fvdl 	       int lun, u_int tag, role_t role, int status)
   4968  1.42      fvdl {
   4969  1.42      fvdl 	struct	scb *scbp;
   4970  1.42      fvdl 	u_int	active_scb;
   4971  1.42      fvdl 	int	i;
   4972  1.42      fvdl 	int	found;
   4973  1.42      fvdl 
   4974  1.42      fvdl 	/* restore this when we're done */
   4975  1.42      fvdl 	active_scb = ahc_inb(ahc, SCBPTR);
   4976  1.42      fvdl 
   4977  1.42      fvdl 	found = ahc_search_qinfifo(ahc, target, channel, lun, SCB_LIST_NULL,
   4978  1.42      fvdl 				   role, SCB_REQUEUE, SEARCH_COMPLETE);
   4979  1.42      fvdl 
   4980   1.6   mycroft 	/*
   4981   1.6   mycroft 	 * Search waiting for selection list.
   4982   1.6   mycroft 	 */
   4983   1.6   mycroft 	{
   4984  1.42      fvdl 		u_int8_t next, prev;
   4985   1.6   mycroft 
   4986  1.42      fvdl 		next = ahc_inb(ahc, WAITING_SCBH);  /* Start at head of list. */
   4987   1.6   mycroft 		prev = SCB_LIST_NULL;
   4988   1.6   mycroft 
   4989   1.6   mycroft 		while (next != SCB_LIST_NULL) {
   4990  1.42      fvdl 			u_int8_t scb_index;
   4991  1.42      fvdl 
   4992  1.42      fvdl 			ahc_outb(ahc, SCBPTR, next);
   4993  1.42      fvdl 			scb_index = ahc_inb(ahc, SCB_TAG);
   4994  1.42      fvdl 			if (scb_index >= ahc->scb_data->numscbs) {
   4995  1.42      fvdl 				panic("Waiting List inconsistency. "
   4996  1.42      fvdl 				      "SCB index == %d, yet numscbs == %d.",
   4997  1.42      fvdl 				      scb_index, ahc->scb_data->numscbs);
   4998   1.6   mycroft 			}
   4999  1.42      fvdl 			scbp = &ahc->scb_data->scbarray[scb_index];
   5000  1.42      fvdl 			if (ahc_match_scb(scbp, target, channel,
   5001  1.42      fvdl 					  lun, SCB_LIST_NULL, role)) {
   5002  1.42      fvdl 
   5003  1.42      fvdl 				next = ahc_abort_wscb(ahc, next, prev);
   5004  1.42      fvdl 			} else {
   5005  1.42      fvdl 
   5006   1.6   mycroft 				prev = next;
   5007  1.42      fvdl 				next = ahc_inb(ahc, SCB_NEXT);
   5008   1.6   mycroft 			}
   5009   1.6   mycroft 		}
   5010   1.1   mycroft 	}
   5011   1.1   mycroft 	/*
   5012  1.42      fvdl 	 * Go through the disconnected list and remove any entries we
   5013  1.42      fvdl 	 * have queued for completion, 0'ing their control byte too.
   5014  1.42      fvdl 	 * We save the active SCB and restore it ourselves, so there
   5015  1.42      fvdl 	 * is no reason for this search to restore it too.
   5016  1.42      fvdl 	 */
   5017  1.42      fvdl 	ahc_search_disc_list(ahc, target, channel, lun, tag,
   5018  1.42      fvdl 			     /*stop_on_first*/FALSE, /*remove*/TRUE,
   5019  1.42      fvdl 			     /*save_state*/FALSE);
   5020  1.42      fvdl 
   5021  1.42      fvdl 	/*
   5022  1.42      fvdl 	 * Go through the hardware SCB array looking for commands that
   5023  1.42      fvdl 	 * were active but not on any list.
   5024  1.42      fvdl 	 */
   5025  1.42      fvdl 	for(i = 0; i < ahc->scb_data->maxhscbs; i++) {
   5026  1.42      fvdl 		u_int scbid;
   5027  1.42      fvdl 
   5028  1.42      fvdl 		ahc_outb(ahc, SCBPTR, i);
   5029  1.42      fvdl 		scbid = ahc_inb(ahc, SCB_TAG);
   5030  1.42      fvdl 		scbp = &ahc->scb_data->scbarray[scbid];
   5031  1.42      fvdl 		if (scbid < ahc->scb_data->numscbs
   5032  1.42      fvdl 		 && ahc_match_scb(scbp, target, channel, lun, tag, role))
   5033  1.42      fvdl 			ahc_add_curscb_to_free_list(ahc);
   5034  1.42      fvdl 	}
   5035  1.42      fvdl 
   5036  1.42      fvdl 	/*
   5037  1.42      fvdl 	 * Go through the pending CCB list and look for
   5038  1.42      fvdl 	 * commands for this target that are still active.
   5039  1.42      fvdl 	 * These are other tagged commands that were
   5040  1.42      fvdl 	 * disconnected when the reset occured.
   5041   1.6   mycroft 	 */
   5042  1.42      fvdl 	{
   5043  1.42      fvdl 		struct scb *scb;
   5044  1.42      fvdl 
   5045  1.42      fvdl 		scb = ahc->pending_ccbs.lh_first;
   5046  1.42      fvdl 		while (scb != NULL) {
   5047  1.42      fvdl 			scbp = scb;
   5048  1.42      fvdl 			scb = scb->plinks.le_next;
   5049  1.42      fvdl 			if (ahc_match_scb(scbp, target, channel,
   5050  1.42      fvdl 					  lun, tag, role)) {
   5051  1.42      fvdl 				if (!(scbp->xs->xs_status & XS_STS_DONE))
   5052  1.42      fvdl 					ahcsetccbstatus(scbp->xs, status);
   5053  1.42      fvdl 				ahc_freeze_ccb(scbp);
   5054  1.42      fvdl 				ahc_done(ahc, scbp);
   5055  1.42      fvdl 				found++;
   5056   1.6   mycroft 			}
   5057   1.6   mycroft 		}
   5058  1.42      fvdl 	}
   5059  1.42      fvdl 	ahc_outb(ahc, SCBPTR, active_scb);
   5060   1.6   mycroft 	return found;
   5061   1.6   mycroft }
   5062   1.6   mycroft 
   5063  1.42      fvdl static int
   5064  1.42      fvdl ahc_search_disc_list(struct ahc_softc *ahc, int target, char channel,
   5065  1.42      fvdl 		     int lun, u_int tag, int stop_on_first, int remove,
   5066  1.42      fvdl 		     int save_state)
   5067  1.42      fvdl {
   5068  1.42      fvdl 	struct	scb *scbp;
   5069  1.42      fvdl 	u_int	next;
   5070  1.42      fvdl 	u_int	prev;
   5071  1.42      fvdl 	u_int	count;
   5072  1.42      fvdl 	u_int	active_scb;
   5073  1.42      fvdl 
   5074  1.42      fvdl 	count = 0;
   5075  1.42      fvdl 	next = ahc_inb(ahc, DISCONNECTED_SCBH);
   5076  1.42      fvdl 	prev = SCB_LIST_NULL;
   5077  1.42      fvdl 
   5078  1.42      fvdl 	if (save_state) {
   5079  1.42      fvdl 		/* restore this when we're done */
   5080  1.42      fvdl 		active_scb = ahc_inb(ahc, SCBPTR);
   5081  1.42      fvdl 	} else
   5082  1.42      fvdl 		/* Silence compiler */
   5083  1.42      fvdl 		active_scb = SCB_LIST_NULL;
   5084  1.42      fvdl 
   5085  1.42      fvdl 	while (next != SCB_LIST_NULL) {
   5086  1.42      fvdl 		u_int scb_index;
   5087  1.42      fvdl 
   5088  1.42      fvdl 		ahc_outb(ahc, SCBPTR, next);
   5089  1.42      fvdl 		scb_index = ahc_inb(ahc, SCB_TAG);
   5090  1.42      fvdl 		if (scb_index >= ahc->scb_data->numscbs) {
   5091  1.42      fvdl 			panic("Disconnected List inconsistency. "
   5092  1.42      fvdl 			      "SCB index == %d, yet numscbs == %d.",
   5093  1.42      fvdl 			      scb_index, ahc->scb_data->numscbs);
   5094  1.42      fvdl 		}
   5095  1.42      fvdl 		scbp = &ahc->scb_data->scbarray[scb_index];
   5096  1.42      fvdl 		if (ahc_match_scb(scbp, target, channel, lun,
   5097  1.42      fvdl 				  tag, ROLE_INITIATOR)) {
   5098  1.42      fvdl 			count++;
   5099  1.42      fvdl 			if (remove) {
   5100  1.42      fvdl 				next =
   5101  1.42      fvdl 				    ahc_rem_scb_from_disc_list(ahc, prev, next);
   5102  1.42      fvdl 			} else {
   5103  1.42      fvdl 				prev = next;
   5104  1.42      fvdl 				next = ahc_inb(ahc, SCB_NEXT);
   5105  1.42      fvdl 			}
   5106  1.42      fvdl 			if (stop_on_first)
   5107  1.42      fvdl 				break;
   5108  1.42      fvdl 		} else {
   5109  1.42      fvdl 			prev = next;
   5110  1.42      fvdl 			next = ahc_inb(ahc, SCB_NEXT);
   5111  1.42      fvdl 		}
   5112  1.42      fvdl 	}
   5113  1.42      fvdl 	if (save_state)
   5114  1.42      fvdl 		ahc_outb(ahc, SCBPTR, active_scb);
   5115  1.42      fvdl 	return (count);
   5116  1.42      fvdl }
   5117  1.42      fvdl 
   5118  1.42      fvdl static u_int
   5119  1.42      fvdl ahc_rem_scb_from_disc_list(struct ahc_softc *ahc, u_int prev, u_int scbptr)
   5120  1.42      fvdl {
   5121  1.42      fvdl 	u_int next;
   5122  1.42      fvdl 
   5123  1.42      fvdl 	ahc_outb(ahc, SCBPTR, scbptr);
   5124  1.42      fvdl 	next = ahc_inb(ahc, SCB_NEXT);
   5125  1.42      fvdl 
   5126  1.42      fvdl 	ahc_outb(ahc, SCB_CONTROL, 0);
   5127  1.42      fvdl 
   5128  1.42      fvdl 	ahc_add_curscb_to_free_list(ahc);
   5129  1.42      fvdl 
   5130  1.42      fvdl 	if (prev != SCB_LIST_NULL) {
   5131  1.42      fvdl 		ahc_outb(ahc, SCBPTR, prev);
   5132  1.42      fvdl 		ahc_outb(ahc, SCB_NEXT, next);
   5133  1.42      fvdl 	} else
   5134  1.42      fvdl 		ahc_outb(ahc, DISCONNECTED_SCBH, next);
   5135  1.42      fvdl 
   5136  1.42      fvdl 	return (next);
   5137  1.42      fvdl }
   5138  1.42      fvdl 
   5139  1.42      fvdl static void
   5140  1.42      fvdl ahc_add_curscb_to_free_list(struct ahc_softc *ahc)
   5141  1.42      fvdl {
   5142  1.42      fvdl 	/* Invalidate the tag so that ahc_find_scb doesn't think it's active */
   5143  1.42      fvdl 	ahc_outb(ahc, SCB_TAG, SCB_LIST_NULL);
   5144  1.42      fvdl 
   5145  1.42      fvdl 	ahc_outb(ahc, SCB_NEXT, ahc_inb(ahc, FREE_SCBH));
   5146  1.42      fvdl 	ahc_outb(ahc, FREE_SCBH, ahc_inb(ahc, SCBPTR));
   5147  1.42      fvdl }
   5148  1.42      fvdl 
   5149   1.6   mycroft /*
   5150   1.6   mycroft  * Manipulate the waiting for selection list and return the
   5151   1.6   mycroft  * scb that follows the one that we remove.
   5152   1.6   mycroft  */
   5153  1.42      fvdl static u_int
   5154  1.42      fvdl ahc_abort_wscb(struct ahc_softc *ahc, u_int scbpos, u_int prev)
   5155   1.6   mycroft {
   5156  1.42      fvdl 	u_int curscb, next;
   5157  1.42      fvdl 
   5158   1.6   mycroft 	/*
   5159   1.6   mycroft 	 * Select the SCB we want to abort and
   5160   1.6   mycroft 	 * pull the next pointer out of it.
   5161   1.6   mycroft 	 */
   5162  1.42      fvdl 	curscb = ahc_inb(ahc, SCBPTR);
   5163  1.42      fvdl 	ahc_outb(ahc, SCBPTR, scbpos);
   5164  1.42      fvdl 	next = ahc_inb(ahc, SCB_NEXT);
   5165   1.6   mycroft 
   5166   1.6   mycroft 	/* Clear the necessary fields */
   5167  1.42      fvdl 	ahc_outb(ahc, SCB_CONTROL, 0);
   5168  1.42      fvdl 
   5169  1.42      fvdl 	ahc_add_curscb_to_free_list(ahc);
   5170   1.6   mycroft 
   5171   1.6   mycroft 	/* update the waiting list */
   5172  1.42      fvdl 	if (prev == SCB_LIST_NULL) {
   5173   1.6   mycroft 		/* First in the list */
   5174  1.42      fvdl 		ahc_outb(ahc, WAITING_SCBH, next);
   5175  1.42      fvdl 
   5176  1.42      fvdl 		/*
   5177  1.42      fvdl 		 * Ensure we aren't attempting to perform
   5178  1.42      fvdl 		 * selection for this entry.
   5179  1.42      fvdl 		 */
   5180  1.42      fvdl 		ahc_outb(ahc, SCSISEQ, (ahc_inb(ahc, SCSISEQ) & ~ENSELO));
   5181  1.42      fvdl 	} else {
   5182   1.1   mycroft 		/*
   5183   1.6   mycroft 		 * Select the scb that pointed to us
   5184   1.6   mycroft 		 * and update its next pointer.
   5185   1.1   mycroft 		 */
   5186  1.42      fvdl 		ahc_outb(ahc, SCBPTR, prev);
   5187  1.42      fvdl 		ahc_outb(ahc, SCB_NEXT, next);
   5188   1.1   mycroft 	}
   5189  1.42      fvdl 
   5190   1.1   mycroft 	/*
   5191  1.42      fvdl 	 * Point us back at the original scb position.
   5192  1.42      fvdl 	 */
   5193  1.42      fvdl 	ahc_outb(ahc, SCBPTR, curscb);
   5194   1.6   mycroft 	return next;
   5195   1.6   mycroft }
   5196   1.6   mycroft 
   5197   1.6   mycroft static void
   5198  1.42      fvdl ahc_clear_intstat(struct ahc_softc *ahc)
   5199  1.42      fvdl {
   5200  1.42      fvdl 	/* Clear any interrupt conditions this may have caused */
   5201  1.42      fvdl 	ahc_outb(ahc, CLRSINT0, CLRSELDO|CLRSELDI|CLRSELINGO);
   5202  1.42      fvdl 	ahc_outb(ahc, CLRSINT1, CLRSELTIMEO|CLRATNO|CLRSCSIRSTI
   5203  1.42      fvdl 				|CLRBUSFREE|CLRSCSIPERR|CLRPHASECHG|
   5204  1.42      fvdl 				CLRREQINIT);
   5205  1.42      fvdl 	ahc_outb(ahc, CLRINT, CLRSCSIINT);
   5206  1.42      fvdl }
   5207  1.42      fvdl 
   5208  1.42      fvdl static void
   5209  1.42      fvdl ahc_reset_current_bus(struct ahc_softc *ahc)
   5210  1.42      fvdl {
   5211  1.42      fvdl 	u_int8_t scsiseq;
   5212  1.42      fvdl 
   5213  1.42      fvdl 	ahc_outb(ahc, SIMODE1, ahc_inb(ahc, SIMODE1) & ~ENSCSIRST);
   5214  1.42      fvdl 	scsiseq = ahc_inb(ahc, SCSISEQ);
   5215  1.42      fvdl 	ahc_outb(ahc, SCSISEQ, scsiseq | SCSIRSTO);
   5216  1.42      fvdl 	DELAY(AHC_BUSRESET_DELAY);
   5217  1.42      fvdl 	/* Turn off the bus reset */
   5218  1.42      fvdl 	ahc_outb(ahc, SCSISEQ, scsiseq & ~SCSIRSTO);
   5219  1.42      fvdl 
   5220  1.42      fvdl 	ahc_clear_intstat(ahc);
   5221  1.42      fvdl 
   5222  1.42      fvdl 	/* Re-enable reset interrupts */
   5223  1.42      fvdl 	ahc_outb(ahc, SIMODE1, ahc_inb(ahc, SIMODE1) | ENSCSIRST);
   5224  1.42      fvdl }
   5225  1.42      fvdl 
   5226  1.42      fvdl static int
   5227  1.42      fvdl ahc_reset_channel(struct ahc_softc *ahc, char channel, int initiate_reset)
   5228   1.6   mycroft {
   5229  1.42      fvdl 	u_int	initiator, target, max_scsiid;
   5230  1.42      fvdl 	u_int	sblkctl;
   5231  1.42      fvdl 	u_int	our_id;
   5232  1.42      fvdl 	int	found;
   5233  1.42      fvdl 	int	restart_needed;
   5234  1.42      fvdl 	char	cur_channel;
   5235  1.42      fvdl 
   5236  1.42      fvdl 	ahc->pending_device = NULL;
   5237  1.42      fvdl 
   5238  1.42      fvdl 	pause_sequencer(ahc);
   5239  1.42      fvdl 
   5240  1.42      fvdl 	/*
   5241  1.42      fvdl 	 * Run our command complete fifos to ensure that we perform
   5242  1.42      fvdl 	 * completion processing on any commands that 'completed'
   5243  1.42      fvdl 	 * before the reset occurred.
   5244  1.42      fvdl 	 */
   5245  1.42      fvdl 	ahc_run_qoutfifo(ahc);
   5246  1.42      fvdl 
   5247  1.42      fvdl 	/*
   5248  1.42      fvdl 	 * Reset the bus if we are initiating this reset
   5249  1.42      fvdl 	 */
   5250  1.42      fvdl 	sblkctl = ahc_inb(ahc, SBLKCTL);
   5251  1.42      fvdl 	cur_channel = 'A';
   5252  1.42      fvdl 	if ((ahc->features & AHC_TWIN) != 0
   5253  1.42      fvdl 	 && ((sblkctl & SELBUSB) != 0))
   5254  1.42      fvdl 	    cur_channel = 'B';
   5255  1.42      fvdl 	if (cur_channel != channel) {
   5256  1.42      fvdl 		/* Case 1: Command for another bus is active
   5257  1.42      fvdl 		 * Stealthily reset the other bus without
   5258  1.42      fvdl 		 * upsetting the current bus.
   5259  1.42      fvdl 		 */
   5260  1.42      fvdl 		ahc_outb(ahc, SBLKCTL, sblkctl ^ SELBUSB);
   5261  1.42      fvdl 		ahc_outb(ahc, SIMODE1, ahc_inb(ahc, SIMODE1) & ~ENBUSFREE);
   5262  1.42      fvdl 		ahc_outb(ahc, SCSISEQ,
   5263  1.42      fvdl 			 ahc_inb(ahc, SCSISEQ) & (ENSELI|ENRSELI|ENAUTOATNP));
   5264  1.42      fvdl 		if (initiate_reset)
   5265  1.42      fvdl 			ahc_reset_current_bus(ahc);
   5266  1.42      fvdl 		ahc_clear_intstat(ahc);
   5267  1.42      fvdl 		ahc_outb(ahc, SBLKCTL, sblkctl);
   5268  1.42      fvdl 		restart_needed = FALSE;
   5269  1.42      fvdl 	} else {
   5270  1.42      fvdl 		/* Case 2: A command from this bus is active or we're idle */
   5271  1.42      fvdl 		ahc_clear_msg_state(ahc);
   5272  1.42      fvdl 		ahc_outb(ahc, SIMODE1, ahc_inb(ahc, SIMODE1) & ~ENBUSFREE);
   5273  1.42      fvdl 		ahc_outb(ahc, SCSISEQ,
   5274  1.42      fvdl 			 ahc_inb(ahc, SCSISEQ) & (ENSELI|ENRSELI|ENAUTOATNP));
   5275  1.42      fvdl 		if (initiate_reset)
   5276  1.42      fvdl 			ahc_reset_current_bus(ahc);
   5277  1.42      fvdl 		ahc_clear_intstat(ahc);
   5278   1.6   mycroft 
   5279  1.42      fvdl 		/*
   5280  1.42      fvdl 		 * Since we are going to restart the sequencer, avoid
   5281  1.42      fvdl 		 * a race in the sequencer that could cause corruption
   5282  1.42      fvdl 		 * of our Q pointers by starting over from index 0.
   5283   1.1   mycroft 		 */
   5284  1.42      fvdl 		ahc->qoutfifonext = 0;
   5285  1.42      fvdl 		if ((ahc->features & AHC_QUEUE_REGS) != 0)
   5286  1.42      fvdl 			ahc_outb(ahc, SDSCB_QOFF, 0);
   5287  1.42      fvdl 		else
   5288  1.42      fvdl 			ahc_outb(ahc, QOUTPOS, 0);
   5289  1.42      fvdl 		restart_needed = TRUE;
   5290  1.42      fvdl 	}
   5291  1.42      fvdl 
   5292  1.42      fvdl 	/*
   5293  1.42      fvdl 	 * Clean up all the state information for the
   5294  1.42      fvdl 	 * pending transactions on this bus.
   5295  1.42      fvdl 	 */
   5296  1.42      fvdl 	found = ahc_abort_scbs(ahc, AHC_TARGET_WILDCARD, channel,
   5297  1.42      fvdl 			       AHC_LUN_WILDCARD, SCB_LIST_NULL,
   5298  1.42      fvdl 			       ROLE_UNKNOWN, XS_RESET);
   5299  1.42      fvdl 	if (channel == 'B') {
   5300  1.42      fvdl 		our_id = ahc->our_id_b;
   5301  1.42      fvdl 	} else {
   5302  1.42      fvdl 		our_id = ahc->our_id;
   5303   1.6   mycroft 	}
   5304  1.42      fvdl 
   5305  1.42      fvdl 	max_scsiid = (ahc->features & AHC_WIDE) ? 15 : 7;
   5306  1.42      fvdl 
   5307  1.42      fvdl 	/*
   5308  1.42      fvdl 	 * Revert to async/narrow transfers until we renegotiate.
   5309  1.42      fvdl 	 */
   5310  1.42      fvdl 	for (target = 0; target <= max_scsiid; target++) {
   5311  1.42      fvdl 
   5312  1.42      fvdl 		if (ahc->enabled_targets[target] == NULL)
   5313  1.42      fvdl 			continue;
   5314  1.42      fvdl 		for (initiator = 0; initiator <= max_scsiid; initiator++) {
   5315  1.42      fvdl 			struct ahc_devinfo devinfo;
   5316  1.42      fvdl 
   5317  1.42      fvdl 			ahc_compile_devinfo(&devinfo, target, initiator,
   5318  1.42      fvdl 					    AHC_LUN_WILDCARD,
   5319  1.42      fvdl 					    channel, ROLE_UNKNOWN);
   5320  1.42      fvdl 			ahc_set_width(ahc, &devinfo,
   5321  1.42      fvdl 				      MSG_EXT_WDTR_BUS_8_BIT,
   5322  1.42      fvdl 				      AHC_TRANS_CUR, /*paused*/TRUE, FALSE);
   5323  1.42      fvdl 			ahc_set_syncrate(ahc, &devinfo,
   5324  1.42      fvdl 					 /*syncrate*/NULL, /*period*/0,
   5325  1.42      fvdl 					 /*offset*/0, AHC_TRANS_CUR,
   5326  1.42      fvdl 					 /*paused*/TRUE, FALSE);
   5327  1.42      fvdl 		}
   5328  1.42      fvdl 	}
   5329  1.42      fvdl 
   5330  1.42      fvdl 	if (restart_needed)
   5331  1.42      fvdl 		restart_sequencer(ahc);
   5332  1.42      fvdl 	else
   5333  1.42      fvdl 		unpause_sequencer(ahc);
   5334  1.42      fvdl 	return found;
   5335  1.42      fvdl }
   5336  1.42      fvdl 
   5337  1.42      fvdl static int
   5338  1.42      fvdl ahc_match_scb(struct scb *scb, int target, char channel,
   5339  1.42      fvdl 	      int lun, u_int tag, role_t role)
   5340  1.42      fvdl {
   5341  1.42      fvdl 	int targ = SCB_TARGET(scb);
   5342  1.42      fvdl 	char chan = SCB_CHANNEL(scb);
   5343  1.42      fvdl 	int slun = SCB_LUN(scb);
   5344  1.42      fvdl 	int match;
   5345  1.42      fvdl 
   5346  1.42      fvdl 	match = ((chan == channel) || (channel == ALL_CHANNELS));
   5347  1.42      fvdl 	if (match != 0)
   5348  1.42      fvdl 		match = ((targ == target) || (target == AHC_TARGET_WILDCARD));
   5349  1.42      fvdl 	if (match != 0)
   5350  1.42      fvdl 		match = ((lun == slun) || (lun == AHC_LUN_WILDCARD));
   5351  1.42      fvdl 
   5352  1.42      fvdl 	return match;
   5353   1.6   mycroft }
   5354   1.6   mycroft 
   5355   1.6   mycroft static void
   5356  1.42      fvdl ahc_construct_sdtr(struct ahc_softc *ahc, u_int period, u_int offset)
   5357   1.6   mycroft {
   5358  1.42      fvdl 	ahc->msgout_buf[ahc->msgout_index++] = MSG_EXTENDED;
   5359  1.42      fvdl 	ahc->msgout_buf[ahc->msgout_index++] = MSG_EXT_SDTR_LEN;
   5360  1.42      fvdl 	ahc->msgout_buf[ahc->msgout_index++] = MSG_EXT_SDTR;
   5361  1.42      fvdl 	ahc->msgout_buf[ahc->msgout_index++] = period;
   5362  1.42      fvdl 	ahc->msgout_buf[ahc->msgout_index++] = offset;
   5363  1.42      fvdl 	ahc->msgout_len += 5;
   5364  1.42      fvdl }
   5365   1.1   mycroft 
   5366  1.42      fvdl static void
   5367  1.42      fvdl ahc_construct_wdtr(struct ahc_softc *ahc, u_int bus_width)
   5368  1.42      fvdl {
   5369  1.42      fvdl 	ahc->msgout_buf[ahc->msgout_index++] = MSG_EXTENDED;
   5370  1.42      fvdl 	ahc->msgout_buf[ahc->msgout_index++] = MSG_EXT_WDTR_LEN;
   5371  1.42      fvdl 	ahc->msgout_buf[ahc->msgout_index++] = MSG_EXT_WDTR;
   5372  1.42      fvdl 	ahc->msgout_buf[ahc->msgout_index++] = bus_width;
   5373  1.42      fvdl 	ahc->msgout_len += 4;
   5374   1.1   mycroft }
   5375   1.1   mycroft 
   5376   1.6   mycroft static void
   5377  1.42      fvdl ahc_calc_residual(struct scb *scb)
   5378   1.1   mycroft {
   5379  1.42      fvdl 	struct	hardware_scb *hscb;
   5380   1.1   mycroft 
   5381  1.42      fvdl 	hscb = scb->hscb;
   5382   1.6   mycroft 
   5383   1.6   mycroft 	/*
   5384  1.42      fvdl 	 * If the disconnected flag is still set, this is bogus
   5385  1.42      fvdl 	 * residual information left over from a sequencer
   5386  1.42      fvdl 	 * pagin/pageout, so ignore this case.
   5387   1.6   mycroft 	 */
   5388  1.42      fvdl 	if ((scb->hscb->control & DISCONNECTED) == 0) {
   5389  1.42      fvdl 		u_int32_t resid;
   5390  1.42      fvdl 		int	  resid_sgs;
   5391  1.42      fvdl 		int	  sg;
   5392  1.42      fvdl 
   5393  1.42      fvdl 		/*
   5394  1.42      fvdl 		 * Remainder of the SG where the transfer
   5395  1.42      fvdl 		 * stopped.
   5396  1.42      fvdl 		 */
   5397  1.42      fvdl 		resid = (hscb->residual_data_count[2] << 16)
   5398  1.42      fvdl 		      |	(hscb->residual_data_count[1] <<8)
   5399  1.42      fvdl 		      |	(hscb->residual_data_count[0]);
   5400   1.1   mycroft 
   5401   1.6   mycroft 		/*
   5402  1.42      fvdl 		 * Add up the contents of all residual
   5403  1.42      fvdl 		 * SG segments that are after the SG where
   5404  1.42      fvdl 		 * the transfer stopped.
   5405   1.6   mycroft 		 */
   5406  1.42      fvdl 		resid_sgs = scb->hscb->residual_SG_count - 1/*current*/;
   5407  1.42      fvdl 		sg = scb->sg_count - resid_sgs;
   5408  1.42      fvdl 		while (resid_sgs > 0) {
   5409  1.42      fvdl 
   5410  1.42      fvdl 			resid += le32toh(scb->sg_list[sg].len);
   5411  1.42      fvdl 			sg++;
   5412  1.42      fvdl 			resid_sgs--;
   5413   1.6   mycroft 		}
   5414  1.42      fvdl 		scb->xs->resid = resid;
   5415  1.42      fvdl 	}
   5416  1.42      fvdl 
   5417  1.42      fvdl 	/*
   5418  1.42      fvdl 	 * Clean out the residual information in this SCB for its
   5419  1.42      fvdl 	 * next consumer.
   5420  1.42      fvdl 	 */
   5421  1.42      fvdl 	hscb->residual_SG_count = 0;
   5422  1.42      fvdl 
   5423  1.42      fvdl #ifdef AHC_DEBUG
   5424  1.42      fvdl 	if (ahc_debug & AHC_SHOWMISC) {
   5425  1.42      fvdl 		scsi_print_addr(scb->xs->sc_link);
   5426  1.42      fvdl 		printf("Handled Residual of %ld bytes\n" ,(long)scb->xs->resid);
   5427  1.42      fvdl 	}
   5428  1.42      fvdl #endif
   5429  1.42      fvdl }
   5430  1.42      fvdl 
   5431  1.42      fvdl static void
   5432  1.42      fvdl ahc_update_pending_syncrates(struct ahc_softc *ahc)
   5433  1.42      fvdl {
   5434  1.42      fvdl 	struct	scb *scb;
   5435  1.42      fvdl 	int	pending_ccb_count;
   5436  1.42      fvdl 	int	i;
   5437  1.42      fvdl 	u_int	saved_scbptr;
   5438  1.42      fvdl 
   5439  1.42      fvdl 	/*
   5440  1.42      fvdl 	 * Traverse the pending SCB list and ensure that all of the
   5441  1.42      fvdl 	 * SCBs there have the proper settings.
   5442  1.42      fvdl 	 */
   5443  1.42      fvdl 	scb = LIST_FIRST(&ahc->pending_ccbs);
   5444  1.42      fvdl 	pending_ccb_count = 0;
   5445  1.42      fvdl 	while (scb != NULL) {
   5446  1.42      fvdl 		struct ahc_devinfo devinfo;
   5447  1.42      fvdl 		struct scsipi_xfer *xs;
   5448  1.42      fvdl 		struct scb *pending_scb;
   5449  1.42      fvdl 		struct hardware_scb *pending_hscb;
   5450  1.42      fvdl 		struct ahc_initiator_tinfo *tinfo;
   5451  1.42      fvdl 		struct tmode_tstate *tstate;
   5452  1.42      fvdl 		u_int  our_id, remote_id;
   5453  1.42      fvdl 
   5454  1.42      fvdl 		xs = scb->xs;
   5455  1.42      fvdl 		pending_scb = scb;
   5456  1.42      fvdl 		pending_hscb = pending_scb->hscb;
   5457  1.42      fvdl 		our_id = SCB_IS_SCSIBUS_B(pending_scb)
   5458  1.42      fvdl 		       ? ahc->our_id_b : ahc->our_id;
   5459  1.42      fvdl 		remote_id = xs->sc_link->scsipi_scsi.target;
   5460  1.42      fvdl 		ahc_compile_devinfo(&devinfo, our_id, remote_id,
   5461  1.42      fvdl 				    SCB_LUN(pending_scb),
   5462  1.42      fvdl 				    SCB_CHANNEL(pending_scb),
   5463  1.42      fvdl 				    ROLE_UNKNOWN);
   5464  1.42      fvdl 		tinfo = ahc_fetch_transinfo(ahc, devinfo.channel,
   5465  1.42      fvdl 					    our_id, remote_id, &tstate);
   5466  1.42      fvdl 		pending_hscb->control &= ~ULTRAENB;
   5467  1.42      fvdl 		if ((tstate->ultraenb & devinfo.target_mask) != 0)
   5468  1.42      fvdl 			pending_hscb->control |= ULTRAENB;
   5469  1.42      fvdl 		pending_hscb->scsirate = tinfo->scsirate;
   5470  1.42      fvdl 		pending_hscb->scsioffset = tinfo->current.offset;
   5471  1.42      fvdl 		pending_ccb_count++;
   5472  1.42      fvdl 		scb = LIST_NEXT(scb, plinks);
   5473  1.42      fvdl 	}
   5474  1.42      fvdl 
   5475  1.42      fvdl 	if (pending_ccb_count == 0)
   5476  1.42      fvdl 		return;
   5477  1.42      fvdl 
   5478  1.42      fvdl 	saved_scbptr = ahc_inb(ahc, SCBPTR);
   5479  1.42      fvdl 	/* Ensure that the hscbs down on the card match the new information */
   5480  1.42      fvdl 	for (i = 0; i < ahc->scb_data->maxhscbs; i++) {
   5481  1.42      fvdl 		u_int scb_tag;
   5482  1.42      fvdl 
   5483  1.42      fvdl 		ahc_outb(ahc, SCBPTR, i);
   5484  1.42      fvdl 		scb_tag = ahc_inb(ahc, SCB_TAG);
   5485  1.42      fvdl 		if (scb_tag != SCB_LIST_NULL) {
   5486  1.42      fvdl 			struct	ahc_devinfo devinfo;
   5487  1.42      fvdl 			struct	scb *pending_scb;
   5488  1.42      fvdl 			struct scsipi_xfer *xs;
   5489  1.42      fvdl 			struct	hardware_scb *pending_hscb;
   5490  1.42      fvdl 			struct	ahc_initiator_tinfo *tinfo;
   5491  1.42      fvdl 			struct	tmode_tstate *tstate;
   5492  1.42      fvdl 			u_int	our_id, remote_id;
   5493  1.42      fvdl 			u_int	control;
   5494  1.42      fvdl 
   5495  1.42      fvdl 			pending_scb = &ahc->scb_data->scbarray[scb_tag];
   5496  1.42      fvdl 			if (pending_scb->flags == SCB_FREE)
   5497  1.42      fvdl 				continue;
   5498  1.42      fvdl 			pending_hscb = pending_scb->hscb;
   5499  1.42      fvdl 			xs = pending_scb->xs;
   5500  1.42      fvdl 			our_id = SCB_IS_SCSIBUS_B(pending_scb)
   5501  1.42      fvdl 			       ? ahc->our_id_b : ahc->our_id;
   5502  1.42      fvdl 			remote_id = xs->sc_link->scsipi_scsi.target;
   5503  1.42      fvdl 			ahc_compile_devinfo(&devinfo, our_id, remote_id,
   5504  1.42      fvdl 					    SCB_LUN(pending_scb),
   5505  1.42      fvdl 					    SCB_CHANNEL(pending_scb),
   5506  1.42      fvdl 					    ROLE_UNKNOWN);
   5507  1.42      fvdl 			tinfo = ahc_fetch_transinfo(ahc, devinfo.channel,
   5508  1.42      fvdl 						    our_id, remote_id, &tstate);
   5509  1.42      fvdl 			control = ahc_inb(ahc, SCB_CONTROL);
   5510  1.42      fvdl 			control &= ~ULTRAENB;
   5511  1.42      fvdl 			if ((tstate->ultraenb & devinfo.target_mask) != 0)
   5512  1.42      fvdl 				control |= ULTRAENB;
   5513  1.42      fvdl 			ahc_outb(ahc, SCB_CONTROL, control);
   5514  1.42      fvdl 			ahc_outb(ahc, SCB_SCSIRATE, tinfo->scsirate);
   5515  1.42      fvdl 			ahc_outb(ahc, SCB_SCSIOFFSET, tinfo->current.offset);
   5516   1.6   mycroft 		}
   5517   1.1   mycroft 	}
   5518  1.42      fvdl 	ahc_outb(ahc, SCBPTR, saved_scbptr);
   5519   1.6   mycroft }
   5520   1.1   mycroft 
   5521  1.42      fvdl #if UNUSED
   5522  1.42      fvdl static void
   5523  1.42      fvdl ahc_dump_targcmd(struct target_cmd *cmd)
   5524   1.6   mycroft {
   5525  1.42      fvdl 	u_int8_t *byte;
   5526  1.42      fvdl 	u_int8_t *last_byte;
   5527   1.6   mycroft 	int i;
   5528  1.42      fvdl 
   5529  1.42      fvdl 	byte = &cmd->initiator_channel;
   5530  1.42      fvdl 	/* Debugging info for received commands */
   5531  1.42      fvdl 	last_byte = &cmd[1].initiator_channel;
   5532  1.42      fvdl 
   5533  1.42      fvdl 	i = 0;
   5534  1.42      fvdl 	while (byte < last_byte) {
   5535  1.42      fvdl 		if (i == 0)
   5536  1.42      fvdl 			printf("\t");
   5537  1.42      fvdl 		printf("%#x", *byte++);
   5538  1.42      fvdl 		i++;
   5539  1.42      fvdl 		if (i == 8) {
   5540  1.42      fvdl 			printf("\n");
   5541  1.42      fvdl 			i = 0;
   5542  1.42      fvdl 		} else {
   5543  1.42      fvdl 			printf(", ");
   5544  1.42      fvdl 		}
   5545   1.1   mycroft 	}
   5546   1.6   mycroft }
   5547  1.42      fvdl #endif
   5548  1.42      fvdl 
   5549  1.42      fvdl static void
   5550  1.42      fvdl ahc_shutdown(void *arg)
   5551   1.6   mycroft {
   5552  1.42      fvdl 	struct	ahc_softc *ahc;
   5553  1.42      fvdl 	int	i;
   5554  1.42      fvdl 	u_int	sxfrctl1_a, sxfrctl1_b;
   5555  1.42      fvdl 
   5556  1.42      fvdl 	ahc = (struct ahc_softc *)arg;
   5557  1.42      fvdl 
   5558  1.42      fvdl 	pause_sequencer(ahc);
   5559  1.42      fvdl 
   5560  1.42      fvdl 	/*
   5561  1.42      fvdl 	 * Preserve the value of the SXFRCTL1 register for all channels.
   5562  1.42      fvdl 	 * It contains settings that affect termination and we don't want
   5563  1.42      fvdl 	 * to disturb the integrity of the bus during shutdown in case
   5564  1.42      fvdl 	 * we are in a multi-initiator setup.
   5565  1.42      fvdl 	 */
   5566  1.42      fvdl 	sxfrctl1_b = 0;
   5567  1.42      fvdl 	if ((ahc->features & AHC_TWIN) != 0) {
   5568  1.42      fvdl 		u_int sblkctl;
   5569  1.42      fvdl 
   5570  1.42      fvdl 		sblkctl = ahc_inb(ahc, SBLKCTL);
   5571  1.42      fvdl 		ahc_outb(ahc, SBLKCTL, sblkctl | SELBUSB);
   5572  1.42      fvdl 		sxfrctl1_b = ahc_inb(ahc, SXFRCTL1);
   5573  1.42      fvdl 		ahc_outb(ahc, SBLKCTL, sblkctl & ~SELBUSB);
   5574  1.42      fvdl 	}
   5575  1.42      fvdl 
   5576  1.42      fvdl 	sxfrctl1_a = ahc_inb(ahc, SXFRCTL1);
   5577  1.42      fvdl 
   5578  1.42      fvdl 	/* This will reset most registers to 0, but not all */
   5579  1.42      fvdl 	ahc_reset(ahc);
   5580   1.1   mycroft 
   5581  1.42      fvdl 	if ((ahc->features & AHC_TWIN) != 0) {
   5582  1.42      fvdl 		u_int sblkctl;
   5583  1.42      fvdl 
   5584  1.42      fvdl 		sblkctl = ahc_inb(ahc, SBLKCTL);
   5585  1.42      fvdl 		ahc_outb(ahc, SBLKCTL, sblkctl | SELBUSB);
   5586  1.42      fvdl 		ahc_outb(ahc, SXFRCTL1, sxfrctl1_b);
   5587  1.42      fvdl 		ahc_outb(ahc, SBLKCTL, sblkctl & ~SELBUSB);
   5588  1.42      fvdl 	}
   5589  1.42      fvdl 	ahc_outb(ahc, SXFRCTL1, sxfrctl1_a);
   5590  1.14     gibbs 
   5591  1.42      fvdl 	ahc_outb(ahc, SCSISEQ, 0);
   5592  1.42      fvdl 	ahc_outb(ahc, SXFRCTL0, 0);
   5593  1.42      fvdl 	ahc_outb(ahc, DSPCISTATUS, 0);
   5594  1.14     gibbs 
   5595  1.42      fvdl 	for (i = TARG_SCSIRATE; i < HA_274_BIOSCTRL; i++)
   5596  1.42      fvdl 		ahc_outb(ahc, i, 0);
   5597  1.14     gibbs }
   5598  1.14     gibbs 
   5599  1.42      fvdl #if defined(AHC_DEBUG) && 0
   5600  1.14     gibbs static void
   5601  1.42      fvdl ahc_dumptinfo(struct ahc_softc *ahc, struct ahc_initiator_tinfo *tinfo)
   5602  1.14     gibbs {
   5603  1.42      fvdl 	printf("%s: tinfo: rate %u\n", ahc_name(ahc), tinfo->scsirate);
   5604  1.42      fvdl 
   5605  1.42      fvdl 	printf("\tcurrent:\n");
   5606  1.42      fvdl 	printf("\t\twidth %u period %u offset %u flags %x\n",
   5607  1.42      fvdl 	    tinfo->current.width, tinfo->current.period,
   5608  1.42      fvdl 	    tinfo->current.offset, tinfo->current.ppr_flags);
   5609  1.42      fvdl 
   5610  1.42      fvdl 	printf("\tgoal:\n");
   5611  1.42      fvdl 	printf("\t\twidth %u period %u offset %u flags %x\n",
   5612  1.42      fvdl 	    tinfo->goal.width, tinfo->goal.period,
   5613  1.42      fvdl 	    tinfo->goal.offset, tinfo->goal.ppr_flags);
   5614  1.42      fvdl 
   5615  1.42      fvdl 	printf("\tuser:\n");
   5616  1.42      fvdl 	printf("\t\twidth %u period %u offset %u flags %x\n",
   5617  1.42      fvdl 	    tinfo->user.width, tinfo->user.period,
   5618  1.42      fvdl 	    tinfo->user.offset, tinfo->user.ppr_flags);
   5619   1.1   mycroft }
   5620  1.42      fvdl #endif
   5621  1.45      fvdl 
   5622  1.45      fvdl static void
   5623  1.45      fvdl ahc_check_tags(struct ahc_softc *ahc, struct scsipi_xfer *xs)
   5624  1.45      fvdl {
   5625  1.45      fvdl 	struct scsipi_inquiry_data *inq;
   5626  1.45      fvdl 	struct ahc_devinfo devinfo;
   5627  1.49      fvdl 	struct tmode_tstate *tstate;
   5628  1.45      fvdl 	int target_id, our_id;
   5629  1.49      fvdl 	char channel;
   5630  1.45      fvdl 
   5631  1.45      fvdl 	if (xs->cmd->opcode != INQUIRY || xs->error != XS_NOERROR)
   5632  1.45      fvdl 		return;
   5633  1.45      fvdl 
   5634  1.49      fvdl 	if (xs->sc_link->quirks & SDEV_NOTAG)
   5635  1.49      fvdl 		return;
   5636  1.49      fvdl 
   5637  1.45      fvdl 	target_id = xs->sc_link->scsipi_scsi.target;
   5638  1.45      fvdl 	our_id = SIM_SCSI_ID(ahc, xs->sc_link);
   5639  1.49      fvdl 	channel = SIM_CHANNEL(ahc, xs->sc_link);
   5640  1.49      fvdl 
   5641  1.49      fvdl 	(void)ahc_fetch_transinfo(ahc, channel, our_id, target_id, &tstate);
   5642  1.49      fvdl 	ahc_compile_devinfo(&devinfo, our_id, target_id,
   5643  1.49      fvdl 	    xs->sc_link->scsipi_scsi.lun, channel, ROLE_INITIATOR);
   5644  1.49      fvdl 
   5645  1.49      fvdl 	if (tstate->tagdisable & devinfo.target_mask)
   5646  1.49      fvdl 		return;
   5647  1.45      fvdl 
   5648  1.45      fvdl 	/*
   5649  1.45      fvdl 	 * Sneak a look at the results of the SCSI Inquiry
   5650  1.45      fvdl 	 * command and see if we can do Tagged queing.  This
   5651  1.45      fvdl 	 * should really be done by the higher level drivers.
   5652  1.45      fvdl 	 */
   5653  1.45      fvdl 	inq = (struct scsipi_inquiry_data *)xs->data;
   5654  1.51      fvdl 	if ((inq->flags3 & SID_CmdQue) && !(ahc_istagged_device(ahc, xs, 1))) {
   5655  1.45      fvdl 	        printf("%s: target %d using tagged queuing\n",
   5656  1.45      fvdl 			ahc_name(ahc), xs->sc_link->scsipi_scsi.target);
   5657  1.45      fvdl 
   5658  1.45      fvdl 		ahc_set_tags(ahc, &devinfo, TRUE);
   5659  1.45      fvdl 
   5660  1.45      fvdl 		if (ahc->scb_data->maxhscbs >= 16 ||
   5661  1.45      fvdl 		    (ahc->flags & AHC_PAGESCBS)) {
   5662  1.46      fvdl 			/* Default to 16 tags */
   5663  1.49      fvdl 			xs->sc_link->openings = 16;
   5664  1.45      fvdl 		} else {
   5665  1.45      fvdl 			/*
   5666  1.45      fvdl 			 * Default to 4 tags on whimpy
   5667  1.45      fvdl 			 * cards that don't have much SCB
   5668  1.45      fvdl 			 * space and can't page.  This prevents
   5669  1.45      fvdl 			 * a single device from hogging all
   5670  1.45      fvdl 			 * slots.  We should really have a better
   5671  1.45      fvdl 			 * way of providing fairness.
   5672  1.45      fvdl 			 */
   5673  1.49      fvdl 			xs->sc_link->openings = 4;
   5674  1.45      fvdl 		}
   5675  1.45      fvdl 	}
   5676  1.45      fvdl }
   5677  1.45      fvdl 
   5678  1.45      fvdl static int
   5679  1.51      fvdl ahc_istagged_device(struct ahc_softc *ahc, struct scsipi_xfer *xs,
   5680  1.51      fvdl 		    int nocmdcheck)
   5681  1.45      fvdl {
   5682  1.45      fvdl 	char channel;
   5683  1.45      fvdl 	u_int our_id, target;
   5684  1.45      fvdl 	struct tmode_tstate *tstate;
   5685  1.45      fvdl 	struct ahc_devinfo devinfo;
   5686  1.49      fvdl 
   5687  1.49      fvdl 	if (xs->sc_link->quirks & SDEV_NOTAG)
   5688  1.51      fvdl 		return 0;
   5689  1.51      fvdl 
   5690  1.51      fvdl 	/*
   5691  1.51      fvdl 	 * XXX never do these commands with tags. Should really be
   5692  1.51      fvdl 	 * in a higher layer.
   5693  1.51      fvdl 	 */
   5694  1.51      fvdl 	if (!nocmdcheck && (xs->cmd->opcode == INQUIRY ||
   5695  1.51      fvdl 	     xs->cmd->opcode == TEST_UNIT_READY ||
   5696  1.51      fvdl 	     xs->cmd->opcode == REQUEST_SENSE))
   5697  1.49      fvdl 		return 0;
   5698  1.45      fvdl 
   5699  1.45      fvdl 	channel = SIM_CHANNEL(ahc, xs->sc_link);
   5700  1.45      fvdl 	our_id = SIM_SCSI_ID(ahc, xs->sc_link);
   5701  1.45      fvdl 	target = xs->sc_link->scsipi_scsi.target;
   5702  1.45      fvdl 	(void)ahc_fetch_transinfo(ahc, channel, our_id, target, &tstate);
   5703  1.45      fvdl 
   5704  1.45      fvdl 	ahc_compile_devinfo(&devinfo, our_id, target,
   5705  1.45      fvdl 	    xs->sc_link->scsipi_scsi.lun, channel, ROLE_INITIATOR);
   5706  1.45      fvdl 
   5707  1.45      fvdl 	return (tstate->tagenable & devinfo.target_mask);
   5708  1.45      fvdl }
   5709