Home | History | Annotate | Line # | Download | only in ic
aic7xxx.c revision 1.123
      1  1.123  christos /*	$NetBSD: aic7xxx.c,v 1.123 2006/11/16 01:32:50 christos Exp $	*/
      2  1.100      fvdl 
      3    1.1   mycroft /*
      4   1.96      fvdl  * Core routines and tables shareable across OS platforms.
      5    1.1   mycroft  *
      6   1.96      fvdl  * Copyright (c) 1994-2002 Justin T. Gibbs.
      7   1.96      fvdl  * Copyright (c) 2000-2002 Adaptec Inc.
      8    1.6   mycroft  * All rights reserved.
      9    1.1   mycroft  *
     10    1.6   mycroft  * Redistribution and use in source and binary forms, with or without
     11    1.6   mycroft  * modification, are permitted provided that the following conditions
     12    1.6   mycroft  * are met:
     13    1.6   mycroft  * 1. Redistributions of source code must retain the above copyright
     14   1.42      fvdl  *    notice, this list of conditions, and the following disclaimer,
     15   1.42      fvdl  *    without modification.
     16   1.96      fvdl  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
     17   1.96      fvdl  *    substantially similar to the "NO WARRANTY" disclaimer below
     18   1.96      fvdl  *    ("Disclaimer") and any redistribution must be conditioned upon
     19   1.96      fvdl  *    including a substantially similar Disclaimer requirement for further
     20   1.96      fvdl  *    binary redistribution.
     21   1.96      fvdl  * 3. Neither the names of the above-listed copyright holders nor the names
     22   1.96      fvdl  *    of any contributors may be used to endorse or promote products derived
     23   1.96      fvdl  *    from this software without specific prior written permission.
     24    1.1   mycroft  *
     25   1.42      fvdl  * Alternatively, this software may be distributed under the terms of the
     26   1.96      fvdl  * GNU General Public License ("GPL") version 2 as published by the Free
     27   1.96      fvdl  * Software Foundation.
     28   1.42      fvdl  *
     29   1.96      fvdl  * NO WARRANTY
     30   1.96      fvdl  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     31   1.96      fvdl  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     32   1.96      fvdl  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
     33   1.96      fvdl  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     34   1.96      fvdl  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     35    1.6   mycroft  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     36    1.6   mycroft  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     37   1.96      fvdl  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     38   1.96      fvdl  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
     39   1.96      fvdl  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     40   1.96      fvdl  * POSSIBILITY OF SUCH DAMAGES.
     41   1.96      fvdl  *
     42  1.123  christos  * $Id: aic7xxx.c,v 1.123 2006/11/16 01:32:50 christos Exp $
     43    1.9  explorer  *
     44   1.96      fvdl  * //depot/aic7xxx/aic7xxx/aic7xxx.c#112 $
     45   1.96      fvdl  *
     46   1.96      fvdl  * $FreeBSD: /repoman/r/ncvs/src/sys/dev/aic7xxx/aic7xxx.c,v 1.88 2003/01/20 20:44:55 gibbs Exp $
     47    1.1   mycroft  */
     48    1.1   mycroft /*
     49   1.96      fvdl  * Ported from FreeBSD by Pascal Renauld, Network Storage Solutions, Inc. - April 2003
     50    1.1   mycroft  */
     51  1.106     lukem 
     52  1.106     lukem #include <sys/cdefs.h>
     53  1.123  christos __KERNEL_RCSID(0, "$NetBSD: aic7xxx.c,v 1.123 2006/11/16 01:32:50 christos Exp $");
     54   1.83     lukem 
     55   1.96      fvdl #include <dev/ic/aic7xxx_osm.h>
     56   1.96      fvdl #include <dev/ic/aic7xxx_inline.h>
     57   1.96      fvdl #include <dev/ic/aic7xxx_cam.h>
     58    1.1   mycroft 
     59   1.96      fvdl /****************************** Softc Data ************************************/
     60   1.96      fvdl struct ahc_softc_tailq ahc_tailq = TAILQ_HEAD_INITIALIZER(ahc_tailq);
     61   1.42      fvdl 
     62   1.96      fvdl /***************************** Lookup Tables **********************************/
     63  1.114  christos const char *ahc_chip_names[] =
     64   1.42      fvdl {
     65   1.42      fvdl 	"NONE",
     66   1.42      fvdl 	"aic7770",
     67   1.42      fvdl 	"aic7850",
     68   1.42      fvdl 	"aic7855",
     69   1.42      fvdl 	"aic7859",
     70   1.42      fvdl 	"aic7860",
     71   1.42      fvdl 	"aic7870",
     72   1.42      fvdl 	"aic7880",
     73   1.96      fvdl 	"aic7895",
     74   1.96      fvdl 	"aic7895C",
     75   1.42      fvdl 	"aic7890/91",
     76   1.96      fvdl 	"aic7896/97",
     77   1.42      fvdl 	"aic7892",
     78   1.42      fvdl 	"aic7899"
     79   1.42      fvdl };
     80    1.1   mycroft 
     81   1.96      fvdl /*
     82   1.96      fvdl  * Hardware error codes.
     83   1.96      fvdl  */
     84   1.96      fvdl struct ahc_hard_error_entry {
     85  1.119   tsutsui 	uint8_t errno;
     86  1.114  christos 	const char *errmesg;
     87   1.42      fvdl };
     88   1.28       leo 
     89   1.96      fvdl static struct ahc_hard_error_entry ahc_hard_errors[] = {
     90   1.96      fvdl 	{ ILLHADDR,	"Illegal Host Access" },
     91   1.96      fvdl 	{ ILLSADDR,	"Illegal Sequencer Address referrenced" },
     92   1.96      fvdl 	{ ILLOPCODE,	"Illegal Opcode in sequencer program" },
     93   1.96      fvdl 	{ SQPARERR,	"Sequencer Parity Error" },
     94   1.96      fvdl 	{ DPARERR,	"Data-path Parity Error" },
     95   1.96      fvdl 	{ MPARERR,	"Scratch or SCB Memory Parity Error" },
     96   1.96      fvdl 	{ PCIERRSTAT,	"PCI Error detected" },
     97   1.96      fvdl 	{ CIOPARERR,	"CIOBUS Parity Error" },
     98   1.96      fvdl };
     99   1.96      fvdl static const u_int num_errors = NUM_ELEMENTS(ahc_hard_errors);
    100    1.1   mycroft 
    101   1.96      fvdl static struct ahc_phase_table_entry ahc_phase_table[] =
    102   1.42      fvdl {
    103   1.96      fvdl 	{ P_DATAOUT,	MSG_NOOP,		"in Data-out phase"	},
    104   1.96      fvdl 	{ P_DATAIN,	MSG_INITIATOR_DET_ERR,	"in Data-in phase"	},
    105   1.96      fvdl 	{ P_DATAOUT_DT,	MSG_NOOP,		"in DT Data-out phase"	},
    106   1.96      fvdl 	{ P_DATAIN_DT,	MSG_INITIATOR_DET_ERR,	"in DT Data-in phase"	},
    107   1.96      fvdl 	{ P_COMMAND,	MSG_NOOP,		"in Command phase"	},
    108   1.96      fvdl 	{ P_MESGOUT,	MSG_NOOP,		"in Message-out phase"	},
    109   1.96      fvdl 	{ P_STATUS,	MSG_INITIATOR_DET_ERR,	"in Status phase"	},
    110   1.96      fvdl 	{ P_MESGIN,	MSG_PARITY_ERROR,	"in Message-in phase"	},
    111   1.96      fvdl 	{ P_BUSFREE,	MSG_NOOP,		"while idle"		},
    112   1.96      fvdl 	{ 0,		MSG_NOOP,		"in unknown phase"	}
    113   1.96      fvdl };
    114    1.1   mycroft 
    115    1.1   mycroft /*
    116   1.96      fvdl  * In most cases we only wish to itterate over real phases, so
    117   1.96      fvdl  * exclude the last element from the count.
    118    1.1   mycroft  */
    119   1.96      fvdl static const u_int num_phases = NUM_ELEMENTS(ahc_phase_table) - 1;
    120    1.1   mycroft 
    121   1.96      fvdl /*
    122   1.96      fvdl  * Valid SCSIRATE values.  (p. 3-17)
    123  1.108       wiz  * Provides a mapping of transfer periods in ns to the proper value to
    124   1.96      fvdl  * stick in the scsixfer reg.
    125   1.96      fvdl  */
    126   1.96      fvdl static struct ahc_syncrate ahc_syncrates[] =
    127   1.42      fvdl {
    128   1.96      fvdl       /* ultra2    fast/ultra  period     rate */
    129   1.96      fvdl 	{ 0x42,      0x000,      9,      "80.0" },
    130   1.96      fvdl 	{ 0x03,      0x000,     10,      "40.0" },
    131   1.96      fvdl 	{ 0x04,      0x000,     11,      "33.0" },
    132   1.96      fvdl 	{ 0x05,      0x100,     12,      "20.0" },
    133   1.96      fvdl 	{ 0x06,      0x110,     15,      "16.0" },
    134   1.96      fvdl 	{ 0x07,      0x120,     18,      "13.4" },
    135   1.96      fvdl 	{ 0x08,      0x000,     25,      "10.0" },
    136   1.96      fvdl 	{ 0x19,      0x010,     31,      "8.0"  },
    137   1.96      fvdl 	{ 0x1a,      0x020,     37,      "6.67" },
    138   1.96      fvdl 	{ 0x1b,      0x030,     43,      "5.7"  },
    139   1.96      fvdl 	{ 0x1c,      0x040,     50,      "5.0"  },
    140   1.96      fvdl 	{ 0x00,      0x050,     56,      "4.4"  },
    141   1.96      fvdl 	{ 0x00,      0x060,     62,      "4.0"  },
    142   1.96      fvdl 	{ 0x00,      0x070,     68,      "3.6"  },
    143   1.96      fvdl 	{ 0x00,      0x000,      0,      NULL   }
    144   1.96      fvdl };
    145    1.1   mycroft 
    146   1.96      fvdl /* Our Sequencer Program */
    147   1.96      fvdl #include <dev/microcode/aic7xxx/aic7xxx_seq.h>
    148    1.1   mycroft 
    149   1.96      fvdl /**************************** Function Declarations ***************************/
    150   1.96      fvdl static void		ahc_force_renegotiation(struct ahc_softc *ahc);
    151   1.96      fvdl static struct ahc_tmode_tstate*
    152   1.96      fvdl 			ahc_alloc_tstate(struct ahc_softc *ahc,
    153   1.96      fvdl 					 u_int scsi_id, char channel);
    154   1.96      fvdl #ifdef AHC_TARGET_MODE
    155   1.96      fvdl static void		ahc_free_tstate(struct ahc_softc *ahc,
    156   1.96      fvdl 					u_int scsi_id, char channel, int force);
    157   1.96      fvdl #endif
    158   1.96      fvdl static struct ahc_syncrate*
    159   1.96      fvdl 			ahc_devlimited_syncrate(struct ahc_softc *ahc,
    160   1.96      fvdl 					        struct ahc_initiator_tinfo *,
    161   1.96      fvdl 						u_int *period,
    162   1.96      fvdl 						u_int *ppr_options,
    163   1.96      fvdl 						role_t role);
    164   1.96      fvdl static void		ahc_update_pending_scbs(struct ahc_softc *ahc);
    165   1.96      fvdl static void		ahc_fetch_devinfo(struct ahc_softc *ahc,
    166   1.96      fvdl 					  struct ahc_devinfo *devinfo);
    167   1.96      fvdl static void		ahc_scb_devinfo(struct ahc_softc *ahc,
    168   1.96      fvdl 					struct ahc_devinfo *devinfo,
    169   1.96      fvdl 					struct scb *scb);
    170   1.96      fvdl static void		ahc_assert_atn(struct ahc_softc *ahc);
    171   1.96      fvdl static void		ahc_setup_initiator_msgout(struct ahc_softc *ahc,
    172   1.96      fvdl 						   struct ahc_devinfo *devinfo,
    173   1.96      fvdl 						   struct scb *scb);
    174   1.96      fvdl static void		ahc_build_transfer_msg(struct ahc_softc *ahc,
    175   1.96      fvdl 					       struct ahc_devinfo *devinfo);
    176   1.96      fvdl static void		ahc_construct_sdtr(struct ahc_softc *ahc,
    177   1.96      fvdl 					   struct ahc_devinfo *devinfo,
    178   1.96      fvdl 					   u_int period, u_int offset);
    179   1.96      fvdl static void		ahc_construct_wdtr(struct ahc_softc *ahc,
    180   1.96      fvdl 					   struct ahc_devinfo *devinfo,
    181   1.96      fvdl 					   u_int bus_width);
    182   1.96      fvdl static void		ahc_construct_ppr(struct ahc_softc *ahc,
    183   1.96      fvdl 					  struct ahc_devinfo *devinfo,
    184   1.96      fvdl 					  u_int period, u_int offset,
    185   1.96      fvdl 					  u_int bus_width, u_int ppr_options);
    186   1.96      fvdl static void		ahc_clear_msg_state(struct ahc_softc *ahc);
    187   1.96      fvdl static void		ahc_handle_proto_violation(struct ahc_softc *ahc);
    188   1.96      fvdl static void		ahc_handle_message_phase(struct ahc_softc *ahc);
    189   1.96      fvdl typedef enum {
    190   1.96      fvdl 	AHCMSG_1B,
    191   1.96      fvdl 	AHCMSG_2B,
    192   1.96      fvdl 	AHCMSG_EXT
    193   1.96      fvdl } ahc_msgtype;
    194   1.96      fvdl static int		ahc_sent_msg(struct ahc_softc *ahc, ahc_msgtype type,
    195   1.96      fvdl 				     u_int msgval, int full);
    196   1.96      fvdl static int		ahc_parse_msg(struct ahc_softc *ahc,
    197   1.96      fvdl 				      struct ahc_devinfo *devinfo);
    198   1.96      fvdl static int		ahc_handle_msg_reject(struct ahc_softc *ahc,
    199   1.96      fvdl 					      struct ahc_devinfo *devinfo);
    200   1.96      fvdl static void		ahc_handle_ign_wide_residue(struct ahc_softc *ahc,
    201   1.96      fvdl 						struct ahc_devinfo *devinfo);
    202   1.96      fvdl static void		ahc_reinitialize_dataptrs(struct ahc_softc *ahc);
    203   1.96      fvdl static void		ahc_handle_devreset(struct ahc_softc *ahc,
    204   1.96      fvdl 					    struct ahc_devinfo *devinfo,
    205  1.114  christos 					    cam_status status,
    206  1.114  christos 					    const char *message,
    207   1.96      fvdl 					    int verbose_level);
    208   1.96      fvdl #if AHC_TARGET_MODE
    209   1.96      fvdl static void		ahc_setup_target_msgin(struct ahc_softc *ahc,
    210   1.96      fvdl 					       struct ahc_devinfo *devinfo,
    211   1.96      fvdl 					       struct scb *scb);
    212   1.96      fvdl #endif
    213   1.96      fvdl 
    214  1.112     perry //static bus_dmamap_callback_t	ahc_dmamap_cb;
    215   1.96      fvdl static void			ahc_build_free_scb_list(struct ahc_softc *ahc);
    216   1.96      fvdl static int			ahc_init_scbdata(struct ahc_softc *ahc);
    217   1.96      fvdl static void			ahc_fini_scbdata(struct ahc_softc *ahc);
    218   1.96      fvdl static void		ahc_qinfifo_requeue(struct ahc_softc *ahc,
    219   1.96      fvdl 					    struct scb *prev_scb,
    220   1.96      fvdl 					    struct scb *scb);
    221   1.96      fvdl static int		ahc_qinfifo_count(struct ahc_softc *ahc);
    222   1.96      fvdl static u_int		ahc_rem_scb_from_disc_list(struct ahc_softc *ahc,
    223   1.96      fvdl 						   u_int prev, u_int scbptr);
    224   1.96      fvdl static void		ahc_add_curscb_to_free_list(struct ahc_softc *ahc);
    225   1.96      fvdl static u_int		ahc_rem_wscb(struct ahc_softc *ahc,
    226   1.96      fvdl 				     u_int scbpos, u_int prev);
    227   1.96      fvdl static void		ahc_reset_current_bus(struct ahc_softc *ahc);
    228   1.96      fvdl #ifdef AHC_DUMP_SEQ
    229   1.96      fvdl static void		ahc_dumpseq(struct ahc_softc *ahc);
    230   1.96      fvdl #endif
    231   1.96      fvdl static void		ahc_loadseq(struct ahc_softc *ahc);
    232   1.96      fvdl static int		ahc_check_patch(struct ahc_softc *ahc,
    233   1.96      fvdl 					struct patch **start_patch,
    234   1.96      fvdl 					u_int start_instr, u_int *skip_addr);
    235   1.96      fvdl static void		ahc_download_instr(struct ahc_softc *ahc,
    236   1.96      fvdl 					   u_int instrptr, uint8_t *dconsts);
    237   1.96      fvdl #ifdef AHC_TARGET_MODE
    238   1.96      fvdl static void		ahc_queue_lstate_event(struct ahc_softc *ahc,
    239   1.96      fvdl 					       struct ahc_tmode_lstate *lstate,
    240   1.96      fvdl 					       u_int initiator_id,
    241   1.96      fvdl 					       u_int event_type,
    242   1.96      fvdl 					       u_int event_arg);
    243   1.96      fvdl static void		ahc_update_scsiid(struct ahc_softc *ahc,
    244   1.96      fvdl 					  u_int targid_mask);
    245   1.96      fvdl static int		ahc_handle_target_cmd(struct ahc_softc *ahc,
    246   1.96      fvdl 					      struct target_cmd *cmd);
    247   1.96      fvdl #endif
    248   1.96      fvdl 
    249   1.96      fvdl /************************** Added for porting to NetBSD ***********************/
    250   1.96      fvdl static int ahc_createdmamem(bus_dma_tag_t tag,
    251   1.96      fvdl 			    int size,
    252   1.96      fvdl 			    int flags,
    253   1.96      fvdl 			    bus_dmamap_t *mapp,
    254   1.96      fvdl 			    caddr_t *vaddr,
    255   1.96      fvdl 			    bus_addr_t *baddr,
    256   1.96      fvdl 			    bus_dma_segment_t *seg,
    257   1.96      fvdl 			    int *nseg,
    258   1.96      fvdl 			    const char *myname, const char *what);
    259   1.96      fvdl static void ahc_freedmamem(bus_dma_tag_t tag,
    260   1.96      fvdl 			   int size,
    261   1.96      fvdl 			   bus_dmamap_t map,
    262   1.96      fvdl 			   caddr_t vaddr,
    263   1.96      fvdl 			   bus_dma_segment_t *seg,
    264   1.96      fvdl 			   int nseg);
    265    1.1   mycroft 
    266   1.96      fvdl /************************* Sequencer Execution Control ************************/
    267    1.1   mycroft /*
    268   1.42      fvdl  * Restart the sequencer program from address zero
    269    1.1   mycroft  */
    270   1.96      fvdl void
    271   1.96      fvdl ahc_restart(struct ahc_softc *ahc)
    272   1.42      fvdl {
    273    1.1   mycroft 
    274   1.96      fvdl 	ahc_pause(ahc);
    275   1.96      fvdl 
    276   1.96      fvdl 	/* No more pending messages. */
    277   1.96      fvdl 	ahc_clear_msg_state(ahc);
    278   1.96      fvdl 
    279   1.96      fvdl 	ahc_outb(ahc, SCSISIGO, 0);		/* De-assert BSY */
    280   1.96      fvdl 	ahc_outb(ahc, MSG_OUT, MSG_NOOP);	/* No message to send */
    281   1.96      fvdl 	ahc_outb(ahc, SXFRCTL1, ahc_inb(ahc, SXFRCTL1) & ~BITBUCKET);
    282   1.96      fvdl 	ahc_outb(ahc, LASTPHASE, P_BUSFREE);
    283   1.96      fvdl 	ahc_outb(ahc, SAVED_SCSIID, 0xFF);
    284   1.96      fvdl 	ahc_outb(ahc, SAVED_LUN, 0xFF);
    285    1.1   mycroft 
    286    1.6   mycroft 	/*
    287   1.96      fvdl 	 * Ensure that the sequencer's idea of TQINPOS
    288   1.96      fvdl 	 * matches our own.  The sequencer increments TQINPOS
    289   1.96      fvdl 	 * only after it sees a DMA complete and a reset could
    290   1.96      fvdl 	 * occur before the increment leaving the kernel to believe
    291   1.96      fvdl 	 * the command arrived but the sequencer to not.
    292    1.6   mycroft 	 */
    293   1.96      fvdl 	ahc_outb(ahc, TQINPOS, ahc->tqinfifonext);
    294    1.1   mycroft 
    295   1.96      fvdl 	/* Always allow reselection */
    296   1.96      fvdl 	ahc_outb(ahc, SCSISEQ,
    297   1.96      fvdl 		 ahc_inb(ahc, SCSISEQ_TEMPLATE) & (ENSELI|ENRSELI|ENAUTOATNP));
    298   1.96      fvdl 	if ((ahc->features & AHC_CMD_CHAN) != 0) {
    299   1.96      fvdl 		/* Ensure that no DMA operations are in progress */
    300   1.96      fvdl 		ahc_outb(ahc, CCSCBCNT, 0);
    301   1.96      fvdl 		ahc_outb(ahc, CCSGCTL, 0);
    302   1.96      fvdl 		ahc_outb(ahc, CCSCBCTL, 0);
    303   1.14     gibbs 	}
    304   1.18   thorpej 	/*
    305   1.96      fvdl 	 * If we were in the process of DMA'ing SCB data into
    306   1.96      fvdl 	 * an SCB, replace that SCB on the free list.  This prevents
    307   1.96      fvdl 	 * an SCB leak.
    308   1.18   thorpej 	 */
    309   1.96      fvdl 	if ((ahc_inb(ahc, SEQ_FLAGS2) & SCB_DMA) != 0) {
    310   1.96      fvdl 		ahc_add_curscb_to_free_list(ahc);
    311   1.96      fvdl 		ahc_outb(ahc, SEQ_FLAGS2,
    312   1.96      fvdl 			 ahc_inb(ahc, SEQ_FLAGS2) & ~SCB_DMA);
    313   1.96      fvdl 	}
    314   1.96      fvdl 	ahc_outb(ahc, MWI_RESIDUAL, 0);
    315   1.96      fvdl 	ahc_outb(ahc, SEQCTL, FASTMODE);
    316   1.96      fvdl 	ahc_outb(ahc, SEQADDR0, 0);
    317   1.96      fvdl 	ahc_outb(ahc, SEQADDR1, 0);
    318   1.96      fvdl 	ahc_unpause(ahc);
    319   1.42      fvdl }
    320   1.18   thorpej 
    321   1.96      fvdl /************************* Input/Output Queues ********************************/
    322   1.96      fvdl void
    323   1.42      fvdl ahc_run_qoutfifo(struct ahc_softc *ahc)
    324   1.42      fvdl {
    325   1.42      fvdl 	struct scb *scb;
    326   1.42      fvdl 	u_int  scb_index;
    327   1.32   thorpej 
    328   1.96      fvdl 	ahc_sync_qoutfifo(ahc, BUS_DMASYNC_POSTREAD);
    329   1.96      fvdl 	while (ahc->qoutfifo[ahc->qoutfifonext] != SCB_LIST_NULL) {
    330   1.32   thorpej 
    331   1.42      fvdl 		scb_index = ahc->qoutfifo[ahc->qoutfifonext];
    332   1.96      fvdl 		if ((ahc->qoutfifonext & 0x03) == 0x03) {
    333   1.96      fvdl 			u_int modnext;
    334   1.96      fvdl 
    335   1.96      fvdl 			/*
    336   1.96      fvdl 			 * Clear 32bits of QOUTFIFO at a time
    337   1.96      fvdl 			 * so that we don't clobber an incoming
    338   1.96      fvdl 			 * byte DMA to the array on architectures
    339   1.96      fvdl 			 * that only support 32bit load and store
    340   1.96      fvdl 			 * operations.
    341   1.96      fvdl 			 */
    342   1.96      fvdl 			modnext = ahc->qoutfifonext & ~0x3;
    343   1.96      fvdl 			*((uint32_t *)(&ahc->qoutfifo[modnext])) = 0xFFFFFFFFUL;
    344   1.96      fvdl 			ahc_dmamap_sync(ahc, ahc->parent_dmat /*shared_data_dmat*/,
    345   1.96      fvdl 					ahc->shared_data_dmamap,
    346   1.96      fvdl 					/*offset*/modnext, /*len*/4,
    347   1.96      fvdl 					BUS_DMASYNC_PREREAD);
    348   1.96      fvdl 		}
    349   1.96      fvdl 		ahc->qoutfifonext++;
    350   1.42      fvdl 
    351   1.96      fvdl 		scb = ahc_lookup_scb(ahc, scb_index);
    352   1.96      fvdl 		if (scb == NULL) {
    353   1.42      fvdl 			printf("%s: WARNING no command for scb %d "
    354   1.42      fvdl 			       "(cmdcmplt)\nQOUTPOS = %d\n",
    355   1.42      fvdl 			       ahc_name(ahc), scb_index,
    356   1.96      fvdl 			       (ahc->qoutfifonext - 1) & 0xFF);
    357   1.42      fvdl 			continue;
    358   1.42      fvdl 		}
    359    1.6   mycroft 
    360    1.6   mycroft 		/*
    361   1.42      fvdl 		 * Save off the residual
    362   1.42      fvdl 		 * if there is one.
    363    1.6   mycroft 		 */
    364   1.96      fvdl 		ahc_update_residual(ahc, scb);
    365   1.42      fvdl 		ahc_done(ahc, scb);
    366    1.1   mycroft 	}
    367    1.1   mycroft }
    368    1.1   mycroft 
    369   1.96      fvdl void
    370   1.96      fvdl ahc_run_untagged_queues(struct ahc_softc *ahc)
    371   1.59        pk {
    372   1.96      fvdl 	int i;
    373   1.42      fvdl 
    374   1.96      fvdl 	for (i = 0; i < 16; i++)
    375   1.96      fvdl 		ahc_run_untagged_queue(ahc, &ahc->untagged_queues[i]);
    376   1.96      fvdl }
    377   1.42      fvdl 
    378   1.96      fvdl void
    379   1.96      fvdl ahc_run_untagged_queue(struct ahc_softc *ahc, struct scb_tailq *queue)
    380   1.96      fvdl {
    381   1.96      fvdl 	struct scb *scb;
    382   1.28       leo 
    383   1.96      fvdl 	if (ahc->untagged_queue_lock != 0)
    384   1.96      fvdl 		return;
    385    1.6   mycroft 
    386   1.96      fvdl 	if ((scb = TAILQ_FIRST(queue)) != NULL
    387   1.96      fvdl 	    && (scb->flags & SCB_ACTIVE) == 0) {
    388   1.96      fvdl 		scb->flags |= SCB_ACTIVE;
    389   1.96      fvdl 		ahc_queue_scb(ahc, scb);
    390   1.42      fvdl 	}
    391   1.96      fvdl }
    392    1.6   mycroft 
    393   1.96      fvdl /************************* Interrupt Handling *********************************/
    394   1.96      fvdl void
    395   1.96      fvdl ahc_handle_brkadrint(struct ahc_softc *ahc)
    396   1.96      fvdl {
    397   1.96      fvdl 	/*
    398   1.96      fvdl 	 * We upset the sequencer :-(
    399   1.96      fvdl 	 * Lookup the error message
    400   1.96      fvdl 	 */
    401   1.96      fvdl 	int i;
    402   1.96      fvdl 	int error;
    403    1.6   mycroft 
    404   1.96      fvdl 	error = ahc_inb(ahc, ERROR);
    405   1.96      fvdl 	for (i = 0; error != 1 && i < num_errors; i++)
    406   1.96      fvdl 		error >>= 1;
    407   1.96      fvdl 	printf("%s: brkadrint, %s at seqaddr = 0x%x\n",
    408   1.96      fvdl 	       ahc_name(ahc), ahc_hard_errors[i].errmesg,
    409   1.96      fvdl 	       ahc_inb(ahc, SEQADDR0) |
    410   1.96      fvdl 	       (ahc_inb(ahc, SEQADDR1) << 8));
    411   1.96      fvdl 
    412   1.96      fvdl 	ahc_dump_card_state(ahc);
    413   1.96      fvdl 
    414  1.108       wiz 	/* Tell everyone that this HBA is no longer available */
    415   1.96      fvdl 	ahc_abort_scbs(ahc, CAM_TARGET_WILDCARD, ALL_CHANNELS,
    416   1.96      fvdl 		       CAM_LUN_WILDCARD, SCB_LIST_NULL, ROLE_UNKNOWN,
    417   1.96      fvdl 		       CAM_NO_HBA);
    418   1.29       leo 
    419   1.96      fvdl 	/* Disable all interrupt sources by resetting the controller */
    420   1.96      fvdl 	ahc_shutdown(ahc);
    421    1.6   mycroft }
    422    1.6   mycroft 
    423   1.96      fvdl void
    424   1.96      fvdl ahc_handle_seqint(struct ahc_softc *ahc, u_int intstat)
    425   1.42      fvdl {
    426   1.96      fvdl 	struct scb *scb;
    427   1.96      fvdl 	struct ahc_devinfo devinfo;
    428  1.112     perry 
    429   1.96      fvdl 	ahc_fetch_devinfo(ahc, &devinfo);
    430   1.96      fvdl 
    431   1.96      fvdl 	/*
    432   1.96      fvdl 	 * Clear the upper byte that holds SEQINT status
    433   1.96      fvdl 	 * codes and clear the SEQINT bit. We will unpause
    434   1.96      fvdl 	 * the sequencer, if appropriate, after servicing
    435   1.96      fvdl 	 * the request.
    436   1.96      fvdl 	 */
    437   1.96      fvdl 	ahc_outb(ahc, CLRINT, CLRSEQINT);
    438   1.96      fvdl 	switch (intstat & SEQINT_MASK) {
    439   1.96      fvdl 	case BAD_STATUS:
    440   1.96      fvdl 	{
    441   1.96      fvdl 		u_int  scb_index;
    442   1.96      fvdl 		struct hardware_scb *hscb;
    443   1.42      fvdl 
    444   1.96      fvdl 		/*
    445   1.96      fvdl 		 * Set the default return value to 0 (don't
    446   1.96      fvdl 		 * send sense).  The sense code will change
    447   1.96      fvdl 		 * this if needed.
    448   1.96      fvdl 		 */
    449   1.96      fvdl 		ahc_outb(ahc, RETURN_1, 0);
    450   1.96      fvdl 
    451   1.96      fvdl 		/*
    452   1.96      fvdl 		 * The sequencer will notify us when a command
    453   1.96      fvdl 		 * has an error that would be of interest to
    454   1.96      fvdl 		 * the kernel.  This allows us to leave the sequencer
    455   1.96      fvdl 		 * running in the common case of command completes
    456   1.96      fvdl 		 * without error.  The sequencer will already have
    457  1.105       wiz 		 * DMA'd the SCB back up to us, so we can reference
    458   1.96      fvdl 		 * the in kernel copy directly.
    459   1.96      fvdl 		 */
    460   1.96      fvdl 		scb_index = ahc_inb(ahc, SCB_TAG);
    461   1.96      fvdl 		scb = ahc_lookup_scb(ahc, scb_index);
    462   1.96      fvdl 		if (scb == NULL) {
    463   1.96      fvdl 			ahc_print_devinfo(ahc, &devinfo);
    464   1.96      fvdl 			printf("ahc_intr - referenced scb "
    465   1.96      fvdl 			       "not valid during seqint 0x%x scb(%d)\n",
    466   1.96      fvdl 			       intstat, scb_index);
    467   1.96      fvdl 			ahc_dump_card_state(ahc);
    468   1.96      fvdl 			panic("for safety");
    469   1.96      fvdl 			goto unpause;
    470   1.96      fvdl 		}
    471   1.42      fvdl 
    472  1.112     perry 		hscb = scb->hscb;
    473   1.42      fvdl 
    474   1.96      fvdl 		/* Don't want to clobber the original sense code */
    475   1.96      fvdl 		if ((scb->flags & SCB_SENSE) != 0) {
    476   1.96      fvdl 			/*
    477   1.96      fvdl 			 * Clear the SCB_SENSE Flag and have
    478   1.96      fvdl 			 * the sequencer do a normal command
    479   1.96      fvdl 			 * complete.
    480   1.96      fvdl 			 */
    481   1.96      fvdl 			scb->flags &= ~SCB_SENSE;
    482   1.96      fvdl 			break;
    483   1.96      fvdl 		}
    484   1.96      fvdl 		/* Freeze the queue until the client sees the error. */
    485   1.96      fvdl 		ahc_freeze_devq(ahc, scb);
    486   1.96      fvdl 		ahc_freeze_scb(scb);
    487   1.96      fvdl 		ahc_set_scsi_status(scb, hscb->shared_data.status.scsi_status);
    488   1.96      fvdl 		switch (hscb->shared_data.status.scsi_status) {
    489   1.96      fvdl 		case SCSI_STATUS_OK:
    490  1.101      fvdl 			printf("%s: Interrupted for status of 0 (?)\n",
    491   1.96      fvdl 			       ahc_name(ahc));
    492   1.96      fvdl 			break;
    493   1.96      fvdl 		case SCSI_STATUS_CMD_TERMINATED:
    494   1.96      fvdl 		case SCSI_STATUS_CHECK_COND:
    495   1.96      fvdl 		{
    496   1.96      fvdl 			struct ahc_dma_seg *sg;
    497  1.111   thorpej 			struct scsi_request_sense *sc;
    498   1.96      fvdl 			struct ahc_initiator_tinfo *targ_info;
    499   1.96      fvdl 			struct ahc_tmode_tstate *tstate;
    500   1.96      fvdl 			struct ahc_transinfo *tinfo;
    501  1.116   tsutsui 			uint32_t len;
    502   1.42      fvdl #ifdef AHC_DEBUG
    503   1.96      fvdl 			if (ahc_debug & AHC_SHOW_SENSE) {
    504   1.96      fvdl 				ahc_print_path(ahc, scb);
    505   1.96      fvdl 				printf("SCB %d: requests Check Status\n",
    506   1.96      fvdl 				       scb->hscb->tag);
    507   1.96      fvdl 			}
    508   1.42      fvdl #endif
    509   1.42      fvdl 
    510   1.96      fvdl 			if (ahc_perform_autosense(scb) == 0)
    511   1.96      fvdl 				break;
    512   1.42      fvdl 
    513   1.96      fvdl 			targ_info = ahc_fetch_transinfo(ahc,
    514   1.96      fvdl 							devinfo.channel,
    515   1.96      fvdl 							devinfo.our_scsiid,
    516   1.96      fvdl 							devinfo.target,
    517   1.96      fvdl 							&tstate);
    518   1.96      fvdl 			tinfo = &targ_info->curr;
    519   1.96      fvdl 			sg = scb->sg_list;
    520  1.112     perry 			sc = (struct scsi_request_sense *)(&hscb->shared_data.cdb);
    521   1.96      fvdl 			/*
    522   1.96      fvdl 			 * Save off the residual if there is one.
    523   1.96      fvdl 			 */
    524   1.96      fvdl 			ahc_update_residual(ahc, scb);
    525   1.96      fvdl #ifdef AHC_DEBUG
    526   1.96      fvdl 			if (ahc_debug & AHC_SHOW_SENSE) {
    527   1.96      fvdl 				ahc_print_path(ahc, scb);
    528   1.96      fvdl 				printf("Sending Sense\n");
    529   1.96      fvdl 			}
    530   1.96      fvdl #endif
    531  1.116   tsutsui 			sg->addr = ahc_htole32(ahc_get_sense_bufaddr(ahc, scb));
    532  1.116   tsutsui 			len = ahc_get_sense_bufsize(ahc, scb);
    533  1.116   tsutsui 			sg->len = ahc_htole32(len | AHC_DMA_LAST_SEG);
    534   1.96      fvdl 
    535  1.111   thorpej 			memset(sc, 0, sizeof(*sc));
    536  1.111   thorpej 			sc->opcode = SCSI_REQUEST_SENSE;
    537   1.96      fvdl 			if (tinfo->protocol_version <= SCSI_REV_2
    538   1.96      fvdl 			    && SCB_GET_LUN(scb) < 8)
    539   1.96      fvdl 				sc->byte2 = SCB_GET_LUN(scb) << 5;
    540  1.116   tsutsui 			sc->length = len;
    541   1.42      fvdl 
    542   1.96      fvdl 			/*
    543   1.96      fvdl 			 * We can't allow the target to disconnect.
    544   1.96      fvdl 			 * This will be an untagged transaction and
    545   1.96      fvdl 			 * having the target disconnect will make this
    546  1.108       wiz 			 * transaction indistinguishable from outstanding
    547   1.96      fvdl 			 * tagged transactions.
    548   1.96      fvdl 			 */
    549   1.96      fvdl 			hscb->control = 0;
    550   1.42      fvdl 
    551   1.96      fvdl 			/*
    552   1.96      fvdl 			 * This request sense could be because the
    553   1.96      fvdl 			 * the device lost power or in some other
    554   1.96      fvdl 			 * way has lost our transfer negotiations.
    555   1.96      fvdl 			 * Renegotiate if appropriate.  Unit attention
    556   1.96      fvdl 			 * errors will be reported before any data
    557   1.96      fvdl 			 * phases occur.
    558   1.96      fvdl 			 */
    559  1.112     perry 			if (ahc_get_residual(scb)
    560   1.96      fvdl 			    == ahc_get_transfer_length(scb)) {
    561   1.96      fvdl 				ahc_update_neg_request(ahc, &devinfo,
    562   1.96      fvdl 						       tstate, targ_info,
    563   1.96      fvdl 						       AHC_NEG_IF_NON_ASYNC);
    564   1.96      fvdl 			}
    565   1.96      fvdl 			if (tstate->auto_negotiate & devinfo.target_mask) {
    566   1.96      fvdl 				hscb->control |= MK_MESSAGE;
    567   1.96      fvdl 				scb->flags &= ~SCB_NEGOTIATE;
    568   1.96      fvdl 				scb->flags |= SCB_AUTO_NEGOTIATE;
    569   1.96      fvdl 			}
    570   1.96      fvdl 			hscb->cdb_len = sizeof(*sc);
    571  1.112     perry 			hscb->dataptr = sg->addr;
    572   1.96      fvdl 			hscb->datacnt = sg->len;
    573  1.116   tsutsui 			hscb->sgptr =
    574  1.116   tsutsui 			    ahc_htole32(scb->sg_list_phys | SG_FULL_RESID);
    575   1.96      fvdl 			scb->sg_count = 1;
    576   1.96      fvdl 			scb->flags |= SCB_SENSE;
    577   1.96      fvdl 			ahc_qinfifo_requeue_tail(ahc, scb);
    578   1.96      fvdl 			ahc_outb(ahc, RETURN_1, SEND_SENSE);
    579   1.96      fvdl 			/*
    580   1.96      fvdl 			 * Ensure we have enough time to actually
    581   1.96      fvdl 			 * retrieve the sense.
    582   1.96      fvdl 			 */
    583   1.96      fvdl 			ahc_scb_timer_reset(scb, 5 * 1000000);
    584   1.96      fvdl 			break;
    585   1.96      fvdl 		}
    586   1.96      fvdl 		default:
    587   1.96      fvdl 			break;
    588   1.96      fvdl 		}
    589   1.96      fvdl 		break;
    590   1.96      fvdl 	}
    591   1.96      fvdl 	case NO_MATCH:
    592   1.96      fvdl 	{
    593   1.96      fvdl 		/* Ensure we don't leave the selection hardware on */
    594   1.96      fvdl 		ahc_outb(ahc, SCSISEQ,
    595   1.96      fvdl 			 ahc_inb(ahc, SCSISEQ) & (ENSELI|ENRSELI|ENAUTOATNP));
    596   1.96      fvdl 
    597   1.96      fvdl 		printf("%s:%c:%d: no active SCB for reconnecting "
    598   1.96      fvdl 		       "target - issuing BUS DEVICE RESET\n",
    599   1.96      fvdl 		       ahc_name(ahc), devinfo.channel, devinfo.target);
    600   1.96      fvdl 		printf("SAVED_SCSIID == 0x%x, SAVED_LUN == 0x%x, "
    601   1.96      fvdl 		       "ARG_1 == 0x%x ACCUM = 0x%x\n",
    602   1.96      fvdl 		       ahc_inb(ahc, SAVED_SCSIID), ahc_inb(ahc, SAVED_LUN),
    603   1.96      fvdl 		       ahc_inb(ahc, ARG_1), ahc_inb(ahc, ACCUM));
    604   1.96      fvdl 		printf("SEQ_FLAGS == 0x%x, SCBPTR == 0x%x, BTT == 0x%x, "
    605   1.96      fvdl 		       "SINDEX == 0x%x\n",
    606   1.96      fvdl 		       ahc_inb(ahc, SEQ_FLAGS), ahc_inb(ahc, SCBPTR),
    607   1.96      fvdl 		       ahc_index_busy_tcl(ahc,
    608   1.96      fvdl 			    BUILD_TCL(ahc_inb(ahc, SAVED_SCSIID),
    609   1.96      fvdl 				      ahc_inb(ahc, SAVED_LUN))),
    610   1.96      fvdl 		       ahc_inb(ahc, SINDEX));
    611   1.96      fvdl 		printf("SCSIID == 0x%x, SCB_SCSIID == 0x%x, SCB_LUN == 0x%x, "
    612   1.96      fvdl 		       "SCB_TAG == 0x%x, SCB_CONTROL == 0x%x\n",
    613   1.96      fvdl 		       ahc_inb(ahc, SCSIID), ahc_inb(ahc, SCB_SCSIID),
    614   1.96      fvdl 		       ahc_inb(ahc, SCB_LUN), ahc_inb(ahc, SCB_TAG),
    615   1.96      fvdl 		       ahc_inb(ahc, SCB_CONTROL));
    616   1.96      fvdl 		printf("SCSIBUSL == 0x%x, SCSISIGI == 0x%x\n",
    617   1.96      fvdl 		       ahc_inb(ahc, SCSIBUSL), ahc_inb(ahc, SCSISIGI));
    618   1.96      fvdl 		printf("SXFRCTL0 == 0x%x\n", ahc_inb(ahc, SXFRCTL0));
    619   1.96      fvdl 		printf("SEQCTL == 0x%x\n", ahc_inb(ahc, SEQCTL));
    620   1.96      fvdl 		ahc_dump_card_state(ahc);
    621   1.96      fvdl 		ahc->msgout_buf[0] = MSG_BUS_DEV_RESET;
    622   1.96      fvdl 		ahc->msgout_len = 1;
    623   1.96      fvdl 		ahc->msgout_index = 0;
    624   1.96      fvdl 		ahc->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
    625   1.96      fvdl 		ahc_outb(ahc, MSG_OUT, HOST_MSG);
    626   1.96      fvdl 		ahc_assert_atn(ahc);
    627   1.96      fvdl 		break;
    628   1.96      fvdl 	}
    629  1.112     perry 	case SEND_REJECT:
    630   1.96      fvdl 	{
    631   1.96      fvdl 		u_int rejbyte = ahc_inb(ahc, ACCUM);
    632   1.96      fvdl 		printf("%s:%c:%d: Warning - unknown message received from "
    633  1.112     perry 		       "target (0x%x).  Rejecting\n",
    634   1.96      fvdl 		       ahc_name(ahc), devinfo.channel, devinfo.target, rejbyte);
    635  1.112     perry 		break;
    636   1.96      fvdl 	}
    637   1.96      fvdl 	case PROTO_VIOLATION:
    638   1.96      fvdl 	{
    639   1.96      fvdl 		ahc_handle_proto_violation(ahc);
    640   1.96      fvdl 		break;
    641   1.96      fvdl 	}
    642   1.96      fvdl 	case IGN_WIDE_RES:
    643   1.96      fvdl 		ahc_handle_ign_wide_residue(ahc, &devinfo);
    644   1.96      fvdl 		break;
    645   1.96      fvdl 	case PDATA_REINIT:
    646   1.96      fvdl 		ahc_reinitialize_dataptrs(ahc);
    647   1.96      fvdl 		break;
    648   1.96      fvdl 	case BAD_PHASE:
    649   1.96      fvdl 	{
    650   1.96      fvdl 		u_int lastphase;
    651   1.96      fvdl 
    652   1.96      fvdl 		lastphase = ahc_inb(ahc, LASTPHASE);
    653   1.96      fvdl 		printf("%s:%c:%d: unknown scsi bus phase %x, "
    654   1.96      fvdl 		       "lastphase = 0x%x.  Attempting to continue\n",
    655   1.96      fvdl 		       ahc_name(ahc), devinfo.channel, devinfo.target,
    656   1.96      fvdl 		       lastphase, ahc_inb(ahc, SCSISIGI));
    657   1.96      fvdl 		break;
    658   1.96      fvdl 	}
    659   1.96      fvdl 	case MISSED_BUSFREE:
    660   1.96      fvdl 	{
    661   1.96      fvdl 		u_int lastphase;
    662   1.96      fvdl 
    663   1.96      fvdl 		lastphase = ahc_inb(ahc, LASTPHASE);
    664   1.96      fvdl 		printf("%s:%c:%d: Missed busfree. "
    665   1.96      fvdl 		       "Lastphase = 0x%x, Curphase = 0x%x\n",
    666   1.96      fvdl 		       ahc_name(ahc), devinfo.channel, devinfo.target,
    667   1.96      fvdl 		       lastphase, ahc_inb(ahc, SCSISIGI));
    668   1.96      fvdl 		ahc_restart(ahc);
    669   1.96      fvdl 		return;
    670   1.96      fvdl 	}
    671   1.96      fvdl 	case HOST_MSG_LOOP:
    672   1.96      fvdl 	{
    673   1.96      fvdl 		/*
    674   1.96      fvdl 		 * The sequencer has encountered a message phase
    675   1.96      fvdl 		 * that requires host assistance for completion.
    676   1.96      fvdl 		 * While handling the message phase(s), we will be
    677   1.96      fvdl 		 * notified by the sequencer after each byte is
    678  1.108       wiz 		 * transferred so we can track bus phase changes.
    679   1.96      fvdl 		 *
    680   1.96      fvdl 		 * If this is the first time we've seen a HOST_MSG_LOOP
    681   1.96      fvdl 		 * interrupt, initialize the state of the host message
    682   1.96      fvdl 		 * loop.
    683   1.96      fvdl 		 */
    684   1.96      fvdl 		if (ahc->msg_type == MSG_TYPE_NONE) {
    685  1.114  christos 			struct scb *scb1;
    686   1.96      fvdl 			u_int scb_index;
    687   1.96      fvdl 			u_int bus_phase;
    688   1.96      fvdl 
    689   1.96      fvdl 			bus_phase = ahc_inb(ahc, SCSISIGI) & PHASE_MASK;
    690   1.96      fvdl 			if (bus_phase != P_MESGIN
    691   1.96      fvdl 			 && bus_phase != P_MESGOUT) {
    692   1.96      fvdl 				printf("ahc_intr: HOST_MSG_LOOP bad "
    693   1.96      fvdl 				       "phase 0x%x\n",
    694   1.96      fvdl 				      bus_phase);
    695   1.96      fvdl 				/*
    696   1.96      fvdl 				 * Probably transitioned to bus free before
    697   1.96      fvdl 				 * we got here.  Just punt the message.
    698   1.96      fvdl 				 */
    699   1.96      fvdl 				ahc_clear_intstat(ahc);
    700   1.96      fvdl 				ahc_restart(ahc);
    701   1.96      fvdl 				return;
    702   1.96      fvdl 			}
    703   1.96      fvdl 
    704   1.96      fvdl 			scb_index = ahc_inb(ahc, SCB_TAG);
    705  1.114  christos 			scb1 = ahc_lookup_scb(ahc, scb_index);
    706   1.96      fvdl 			if (devinfo.role == ROLE_INITIATOR) {
    707  1.114  christos 				if (scb1 == NULL)
    708   1.96      fvdl 					panic("HOST_MSG_LOOP with "
    709   1.96      fvdl 					      "invalid SCB %x\n", scb_index);
    710   1.96      fvdl 
    711   1.96      fvdl 				if (bus_phase == P_MESGOUT)
    712   1.96      fvdl 					ahc_setup_initiator_msgout(ahc,
    713   1.96      fvdl 								   &devinfo,
    714  1.114  christos 								   scb1);
    715   1.96      fvdl 				else {
    716   1.96      fvdl 					ahc->msg_type =
    717   1.96      fvdl 					    MSG_TYPE_INITIATOR_MSGIN;
    718   1.96      fvdl 					ahc->msgin_index = 0;
    719   1.96      fvdl 				}
    720   1.96      fvdl 			}
    721   1.96      fvdl #if AHC_TARGET_MODE
    722   1.96      fvdl 			else {
    723   1.96      fvdl 				if (bus_phase == P_MESGOUT) {
    724   1.96      fvdl 					ahc->msg_type =
    725   1.96      fvdl 					    MSG_TYPE_TARGET_MSGOUT;
    726   1.96      fvdl 					ahc->msgin_index = 0;
    727   1.96      fvdl 				}
    728  1.112     perry 				else
    729   1.96      fvdl 					ahc_setup_target_msgin(ahc,
    730   1.96      fvdl 							       &devinfo,
    731  1.114  christos 							       scb1);
    732   1.96      fvdl 			}
    733   1.96      fvdl #endif
    734   1.96      fvdl 		}
    735   1.96      fvdl 
    736   1.96      fvdl 		ahc_handle_message_phase(ahc);
    737   1.96      fvdl 		break;
    738   1.96      fvdl 	}
    739   1.96      fvdl 	case PERR_DETECTED:
    740   1.96      fvdl 	{
    741   1.96      fvdl 		/*
    742   1.96      fvdl 		 * If we've cleared the parity error interrupt
    743   1.96      fvdl 		 * but the sequencer still believes that SCSIPERR
    744   1.96      fvdl 		 * is true, it must be that the parity error is
    745   1.96      fvdl 		 * for the currently presented byte on the bus,
    746   1.96      fvdl 		 * and we are not in a phase (data-in) where we will
    747   1.96      fvdl 		 * eventually ack this byte.  Ack the byte and
    748   1.96      fvdl 		 * throw it away in the hope that the target will
    749   1.96      fvdl 		 * take us to message out to deliver the appropriate
    750   1.96      fvdl 		 * error message.
    751   1.96      fvdl 		 */
    752   1.96      fvdl 		if ((intstat & SCSIINT) == 0
    753   1.96      fvdl 		 && (ahc_inb(ahc, SSTAT1) & SCSIPERR) != 0) {
    754   1.96      fvdl 
    755   1.96      fvdl 			if ((ahc->features & AHC_DT) == 0) {
    756   1.96      fvdl 				u_int curphase;
    757   1.96      fvdl 
    758   1.96      fvdl 				/*
    759   1.96      fvdl 				 * The hardware will only let you ack bytes
    760   1.96      fvdl 				 * if the expected phase in SCSISIGO matches
    761   1.96      fvdl 				 * the current phase.  Make sure this is
    762   1.96      fvdl 				 * currently the case.
    763   1.96      fvdl 				 */
    764   1.96      fvdl 				curphase = ahc_inb(ahc, SCSISIGI) & PHASE_MASK;
    765   1.96      fvdl 				ahc_outb(ahc, LASTPHASE, curphase);
    766   1.96      fvdl 				ahc_outb(ahc, SCSISIGO, curphase);
    767   1.96      fvdl 			}
    768   1.96      fvdl 			if ((ahc_inb(ahc, SCSISIGI) & (CDI|MSGI)) == 0) {
    769   1.96      fvdl 				int wait;
    770   1.96      fvdl 
    771   1.96      fvdl 				/*
    772   1.96      fvdl 				 * In a data phase.  Faster to bitbucket
    773   1.96      fvdl 				 * the data than to individually ack each
    774   1.96      fvdl 				 * byte.  This is also the only strategy
    775   1.96      fvdl 				 * that will work with AUTOACK enabled.
    776   1.96      fvdl 				 */
    777   1.96      fvdl 				ahc_outb(ahc, SXFRCTL1,
    778   1.96      fvdl 					 ahc_inb(ahc, SXFRCTL1) | BITBUCKET);
    779   1.96      fvdl 				wait = 5000;
    780   1.96      fvdl 				while (--wait != 0) {
    781   1.96      fvdl 					if ((ahc_inb(ahc, SCSISIGI)
    782   1.96      fvdl 					  & (CDI|MSGI)) != 0)
    783   1.96      fvdl 						break;
    784   1.96      fvdl 					ahc_delay(100);
    785   1.96      fvdl 				}
    786   1.96      fvdl 				ahc_outb(ahc, SXFRCTL1,
    787   1.96      fvdl 					 ahc_inb(ahc, SXFRCTL1) & ~BITBUCKET);
    788   1.96      fvdl 				if (wait == 0) {
    789  1.114  christos 					struct	scb *scb1;
    790   1.96      fvdl 					u_int	scb_index;
    791   1.96      fvdl 
    792   1.96      fvdl 					ahc_print_devinfo(ahc, &devinfo);
    793   1.96      fvdl 					printf("Unable to clear parity error.  "
    794   1.96      fvdl 					       "Resetting bus.\n");
    795   1.96      fvdl 					scb_index = ahc_inb(ahc, SCB_TAG);
    796  1.114  christos 					scb1 = ahc_lookup_scb(ahc, scb_index);
    797  1.114  christos 					if (scb1 != NULL)
    798  1.114  christos 						ahc_set_transaction_status(scb1,
    799   1.96      fvdl 						    CAM_UNCOR_PARITY);
    800  1.112     perry 					ahc_reset_channel(ahc, devinfo.channel,
    801   1.96      fvdl 							  /*init reset*/TRUE);
    802   1.96      fvdl 				}
    803   1.96      fvdl 			} else {
    804  1.121  christos 				(void)ahc_inb(ahc, SCSIDATL);
    805   1.96      fvdl 			}
    806   1.96      fvdl 		}
    807   1.96      fvdl 		break;
    808   1.96      fvdl 	}
    809   1.96      fvdl 	case DATA_OVERRUN:
    810   1.96      fvdl 	{
    811   1.96      fvdl 		/*
    812   1.96      fvdl 		 * When the sequencer detects an overrun, it
    813   1.96      fvdl 		 * places the controller in "BITBUCKET" mode
    814   1.96      fvdl 		 * and allows the target to complete its transfer.
    815   1.96      fvdl 		 * Unfortunately, none of the counters get updated
    816   1.96      fvdl 		 * when the controller is in this mode, so we have
    817   1.96      fvdl 		 * no way of knowing how large the overrun was.
    818   1.96      fvdl 		 */
    819   1.96      fvdl 		u_int scbindex = ahc_inb(ahc, SCB_TAG);
    820   1.96      fvdl 		u_int lastphase = ahc_inb(ahc, LASTPHASE);
    821   1.96      fvdl 		u_int i;
    822   1.96      fvdl 
    823   1.96      fvdl 		scb = ahc_lookup_scb(ahc, scbindex);
    824   1.96      fvdl 		for (i = 0; i < num_phases; i++) {
    825   1.96      fvdl 			if (lastphase == ahc_phase_table[i].phase)
    826   1.96      fvdl 				break;
    827   1.96      fvdl 		}
    828   1.96      fvdl 		ahc_print_path(ahc, scb);
    829   1.96      fvdl 		printf("data overrun detected %s."
    830   1.96      fvdl 		       "  Tag == 0x%x.\n",
    831   1.96      fvdl 		       ahc_phase_table[i].phasemsg,
    832  1.119   tsutsui 		       scb->hscb->tag);
    833   1.96      fvdl 		ahc_print_path(ahc, scb);
    834   1.96      fvdl 		printf("%s seen Data Phase.  Length = %ld.  NumSGs = %d.\n",
    835   1.96      fvdl 		       ahc_inb(ahc, SEQ_FLAGS) & DPHASE ? "Have" : "Haven't",
    836   1.96      fvdl 		       ahc_get_transfer_length(scb), scb->sg_count);
    837   1.96      fvdl 		if (scb->sg_count > 0) {
    838   1.96      fvdl 			for (i = 0; i < scb->sg_count; i++) {
    839   1.96      fvdl 
    840   1.96      fvdl 				printf("sg[%d] - Addr 0x%x%x : Length %d\n",
    841   1.96      fvdl 				       i,
    842   1.96      fvdl 				       (ahc_le32toh(scb->sg_list[i].len) >> 24
    843   1.96      fvdl 				        & SG_HIGH_ADDR_BITS),
    844   1.96      fvdl 				       ahc_le32toh(scb->sg_list[i].addr),
    845   1.96      fvdl 				       ahc_le32toh(scb->sg_list[i].len)
    846   1.96      fvdl 				       & AHC_SG_LEN_MASK);
    847   1.96      fvdl 			}
    848   1.96      fvdl 		}
    849   1.96      fvdl 		/*
    850   1.96      fvdl 		 * Set this and it will take effect when the
    851   1.96      fvdl 		 * target does a command complete.
    852   1.96      fvdl 		 */
    853   1.96      fvdl 		ahc_freeze_devq(ahc, scb);
    854   1.96      fvdl 		if ((scb->flags & SCB_SENSE) == 0) {
    855   1.96      fvdl 			ahc_set_transaction_status(scb, CAM_DATA_RUN_ERR);
    856   1.96      fvdl 		} else {
    857   1.96      fvdl 			scb->flags &= ~SCB_SENSE;
    858   1.96      fvdl 			ahc_set_transaction_status(scb, CAM_AUTOSENSE_FAIL);
    859   1.96      fvdl 		}
    860   1.96      fvdl 		ahc_freeze_scb(scb);
    861   1.96      fvdl 
    862   1.96      fvdl 		if ((ahc->features & AHC_ULTRA2) != 0) {
    863   1.96      fvdl 			/*
    864   1.96      fvdl 			 * Clear the channel in case we return
    865   1.96      fvdl 			 * to data phase later.
    866   1.96      fvdl 			 */
    867   1.96      fvdl 			ahc_outb(ahc, SXFRCTL0,
    868   1.96      fvdl 				 ahc_inb(ahc, SXFRCTL0) | CLRSTCNT|CLRCHN);
    869   1.96      fvdl 			ahc_outb(ahc, SXFRCTL0,
    870   1.96      fvdl 				 ahc_inb(ahc, SXFRCTL0) | CLRSTCNT|CLRCHN);
    871   1.96      fvdl 		}
    872   1.96      fvdl 		if ((ahc->flags & AHC_39BIT_ADDRESSING) != 0) {
    873   1.96      fvdl 			u_int dscommand1;
    874   1.96      fvdl 
    875   1.96      fvdl 			/* Ensure HHADDR is 0 for future DMA operations. */
    876   1.96      fvdl 			dscommand1 = ahc_inb(ahc, DSCOMMAND1);
    877   1.96      fvdl 			ahc_outb(ahc, DSCOMMAND1, dscommand1 | HADDLDSEL0);
    878   1.96      fvdl 			ahc_outb(ahc, HADDR, 0);
    879   1.96      fvdl 			ahc_outb(ahc, DSCOMMAND1, dscommand1);
    880   1.96      fvdl 		}
    881   1.96      fvdl 		break;
    882   1.96      fvdl 	}
    883   1.96      fvdl 	case MKMSG_FAILED:
    884   1.96      fvdl 	{
    885   1.96      fvdl 		u_int scbindex;
    886   1.96      fvdl 
    887   1.96      fvdl 		printf("%s:%c:%d:%d: Attempt to issue message failed\n",
    888   1.96      fvdl 		       ahc_name(ahc), devinfo.channel, devinfo.target,
    889   1.96      fvdl 		       devinfo.lun);
    890   1.96      fvdl 		scbindex = ahc_inb(ahc, SCB_TAG);
    891   1.96      fvdl 		scb = ahc_lookup_scb(ahc, scbindex);
    892   1.96      fvdl 		if (scb != NULL
    893   1.96      fvdl 		 && (scb->flags & SCB_RECOVERY_SCB) != 0)
    894   1.96      fvdl 			/*
    895   1.96      fvdl 			 * Ensure that we didn't put a second instance of this
    896   1.96      fvdl 			 * SCB into the QINFIFO.
    897   1.96      fvdl 			 */
    898   1.96      fvdl 			ahc_search_qinfifo(ahc, SCB_GET_TARGET(ahc, scb),
    899   1.96      fvdl 					   SCB_GET_CHANNEL(ahc, scb),
    900   1.96      fvdl 					   SCB_GET_LUN(scb), scb->hscb->tag,
    901   1.96      fvdl 					   ROLE_INITIATOR, /*status*/0,
    902   1.96      fvdl 					   SEARCH_REMOVE);
    903   1.96      fvdl 		break;
    904   1.96      fvdl 	}
    905   1.96      fvdl 	case NO_FREE_SCB:
    906   1.96      fvdl 	{
    907   1.96      fvdl 		printf("%s: No free or disconnected SCBs\n", ahc_name(ahc));
    908   1.96      fvdl 		ahc_dump_card_state(ahc);
    909   1.96      fvdl 		panic("for safety");
    910   1.96      fvdl 		break;
    911   1.96      fvdl 	}
    912   1.96      fvdl 	case SCB_MISMATCH:
    913   1.96      fvdl 	{
    914   1.96      fvdl 		u_int scbptr;
    915   1.96      fvdl 
    916   1.96      fvdl 		scbptr = ahc_inb(ahc, SCBPTR);
    917   1.96      fvdl 		printf("Bogus TAG after DMA.  SCBPTR %d, tag %d, our tag %d\n",
    918   1.96      fvdl 		       scbptr, ahc_inb(ahc, ARG_1),
    919   1.96      fvdl 		       ahc->scb_data->hscbs[scbptr].tag);
    920   1.96      fvdl 		ahc_dump_card_state(ahc);
    921   1.96      fvdl 		panic("for saftey");
    922   1.96      fvdl 		break;
    923   1.96      fvdl 	}
    924   1.96      fvdl 	case OUT_OF_RANGE:
    925   1.96      fvdl 	{
    926   1.96      fvdl 		printf("%s: BTT calculation out of range\n", ahc_name(ahc));
    927   1.96      fvdl 		printf("SAVED_SCSIID == 0x%x, SAVED_LUN == 0x%x, "
    928   1.96      fvdl 		       "ARG_1 == 0x%x ACCUM = 0x%x\n",
    929   1.96      fvdl 		       ahc_inb(ahc, SAVED_SCSIID), ahc_inb(ahc, SAVED_LUN),
    930   1.96      fvdl 		       ahc_inb(ahc, ARG_1), ahc_inb(ahc, ACCUM));
    931   1.96      fvdl 		printf("SEQ_FLAGS == 0x%x, SCBPTR == 0x%x, BTT == 0x%x, "
    932   1.96      fvdl 		       "SINDEX == 0x%x\n, A == 0x%x\n",
    933   1.96      fvdl 		       ahc_inb(ahc, SEQ_FLAGS), ahc_inb(ahc, SCBPTR),
    934   1.96      fvdl 		       ahc_index_busy_tcl(ahc,
    935   1.96      fvdl 			    BUILD_TCL(ahc_inb(ahc, SAVED_SCSIID),
    936   1.96      fvdl 				      ahc_inb(ahc, SAVED_LUN))),
    937   1.96      fvdl 		       ahc_inb(ahc, SINDEX),
    938   1.96      fvdl 		       ahc_inb(ahc, ACCUM));
    939   1.96      fvdl 		printf("SCSIID == 0x%x, SCB_SCSIID == 0x%x, SCB_LUN == 0x%x, "
    940   1.96      fvdl 		       "SCB_TAG == 0x%x, SCB_CONTROL == 0x%x\n",
    941   1.96      fvdl 		       ahc_inb(ahc, SCSIID), ahc_inb(ahc, SCB_SCSIID),
    942   1.96      fvdl 		       ahc_inb(ahc, SCB_LUN), ahc_inb(ahc, SCB_TAG),
    943   1.96      fvdl 		       ahc_inb(ahc, SCB_CONTROL));
    944   1.96      fvdl 		printf("SCSIBUSL == 0x%x, SCSISIGI == 0x%x\n",
    945   1.96      fvdl 		       ahc_inb(ahc, SCSIBUSL), ahc_inb(ahc, SCSISIGI));
    946   1.96      fvdl 		ahc_dump_card_state(ahc);
    947   1.96      fvdl 		panic("for safety");
    948   1.96      fvdl 		break;
    949   1.96      fvdl 	}
    950   1.96      fvdl 	default:
    951   1.96      fvdl 		printf("ahc_intr: seqint, "
    952   1.96      fvdl 		       "intstat == 0x%x, scsisigi = 0x%x\n",
    953   1.96      fvdl 		       intstat, ahc_inb(ahc, SCSISIGI));
    954   1.96      fvdl 		break;
    955   1.96      fvdl 	}
    956   1.96      fvdl unpause:
    957   1.96      fvdl 	/*
    958   1.96      fvdl 	 *  The sequencer is paused immediately on
    959   1.96      fvdl 	 *  a SEQINT, so we should restart it when
    960   1.96      fvdl 	 *  we're done.
    961   1.96      fvdl 	 */
    962   1.96      fvdl 	ahc_unpause(ahc);
    963   1.96      fvdl }
    964   1.96      fvdl 
    965   1.96      fvdl void
    966  1.123  christos ahc_handle_scsiint(struct ahc_softc *ahc, u_int intstat)
    967   1.96      fvdl {
    968   1.96      fvdl 	u_int	scb_index;
    969   1.96      fvdl 	u_int	status0;
    970   1.96      fvdl 	u_int	status;
    971   1.96      fvdl 	struct	scb *scb;
    972   1.96      fvdl 	char	cur_channel;
    973   1.96      fvdl 	char	intr_channel;
    974   1.96      fvdl 
    975   1.96      fvdl 	if ((ahc->features & AHC_TWIN) != 0
    976   1.96      fvdl 	    && ((ahc_inb(ahc, SBLKCTL) & SELBUSB) != 0))
    977   1.96      fvdl 		cur_channel = 'B';
    978   1.96      fvdl 	else
    979   1.96      fvdl 		cur_channel = 'A';
    980   1.96      fvdl 	intr_channel = cur_channel;
    981   1.96      fvdl 
    982   1.96      fvdl 	if ((ahc->features & AHC_ULTRA2) != 0)
    983   1.96      fvdl 		status0 = ahc_inb(ahc, SSTAT0) & IOERR;
    984   1.96      fvdl 	else
    985   1.96      fvdl 		status0 = 0;
    986   1.96      fvdl 	status = ahc_inb(ahc, SSTAT1) & (SELTO|SCSIRSTI|BUSFREE|SCSIPERR);
    987   1.96      fvdl 	if (status == 0 && status0 == 0) {
    988   1.96      fvdl 		if ((ahc->features & AHC_TWIN) != 0) {
    989   1.96      fvdl 			/* Try the other channel */
    990   1.96      fvdl 		 	ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) ^ SELBUSB);
    991   1.96      fvdl 			status = ahc_inb(ahc, SSTAT1)
    992   1.96      fvdl 			       & (SELTO|SCSIRSTI|BUSFREE|SCSIPERR);
    993   1.96      fvdl 			intr_channel = (cur_channel == 'A') ? 'B' : 'A';
    994   1.96      fvdl 		}
    995   1.96      fvdl 		if (status == 0) {
    996   1.96      fvdl 			printf("%s: Spurious SCSI interrupt\n", ahc_name(ahc));
    997   1.96      fvdl 			ahc_outb(ahc, CLRINT, CLRSCSIINT);
    998   1.96      fvdl 			ahc_unpause(ahc);
    999   1.96      fvdl 			return;
   1000   1.96      fvdl 		}
   1001   1.96      fvdl 	}
   1002   1.96      fvdl 
   1003   1.96      fvdl 	/* Make sure the sequencer is in a safe location. */
   1004   1.96      fvdl 	ahc_clear_critical_section(ahc);
   1005   1.96      fvdl 
   1006   1.96      fvdl 	scb_index = ahc_inb(ahc, SCB_TAG);
   1007   1.96      fvdl 	scb = ahc_lookup_scb(ahc, scb_index);
   1008   1.96      fvdl 	if (scb != NULL
   1009   1.96      fvdl 	 && (ahc_inb(ahc, SEQ_FLAGS) & NOT_IDENTIFIED) != 0)
   1010   1.96      fvdl 		scb = NULL;
   1011   1.96      fvdl 
   1012   1.96      fvdl 	if ((ahc->features & AHC_ULTRA2) != 0
   1013   1.96      fvdl 	 && (status0 & IOERR) != 0) {
   1014   1.96      fvdl 		int now_lvd;
   1015   1.96      fvdl 
   1016   1.96      fvdl 		now_lvd = ahc_inb(ahc, SBLKCTL) & ENAB40;
   1017   1.96      fvdl 		printf("%s: Transceiver State Has Changed to %s mode\n",
   1018   1.96      fvdl 		       ahc_name(ahc), now_lvd ? "LVD" : "SE");
   1019   1.96      fvdl 		ahc_outb(ahc, CLRSINT0, CLRIOERR);
   1020   1.96      fvdl 		/*
   1021   1.96      fvdl 		 * When transitioning to SE mode, the reset line
   1022   1.96      fvdl 		 * glitches, triggering an arbitration bug in some
   1023   1.96      fvdl 		 * Ultra2 controllers.  This bug is cleared when we
   1024   1.96      fvdl 		 * assert the reset line.  Since a reset glitch has
   1025   1.96      fvdl 		 * already occurred with this transition and a
   1026   1.96      fvdl 		 * transceiver state change is handled just like
   1027   1.96      fvdl 		 * a bus reset anyway, asserting the reset line
   1028   1.96      fvdl 		 * ourselves is safe.
   1029   1.96      fvdl 		 */
   1030   1.96      fvdl 		ahc_reset_channel(ahc, intr_channel,
   1031   1.96      fvdl 				 /*Initiate Reset*/now_lvd == 0);
   1032   1.96      fvdl 	} else if ((status & SCSIRSTI) != 0) {
   1033   1.96      fvdl 		printf("%s: Someone reset channel %c\n",
   1034   1.96      fvdl 			ahc_name(ahc), intr_channel);
   1035   1.96      fvdl 		if (intr_channel != cur_channel)
   1036   1.96      fvdl 		 	ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) ^ SELBUSB);
   1037   1.96      fvdl 		ahc_reset_channel(ahc, intr_channel, /*Initiate Reset*/FALSE);
   1038   1.96      fvdl 	} else if ((status & SCSIPERR) != 0) {
   1039   1.96      fvdl 		/*
   1040   1.96      fvdl 		 * Determine the bus phase and queue an appropriate message.
   1041   1.96      fvdl 		 * SCSIPERR is latched true as soon as a parity error
   1042   1.96      fvdl 		 * occurs.  If the sequencer acked the transfer that
   1043   1.96      fvdl 		 * caused the parity error and the currently presented
   1044   1.96      fvdl 		 * transfer on the bus has correct parity, SCSIPERR will
   1045   1.96      fvdl 		 * be cleared by CLRSCSIPERR.  Use this to determine if
   1046   1.96      fvdl 		 * we should look at the last phase the sequencer recorded,
   1047   1.96      fvdl 		 * or the current phase presented on the bus.
   1048   1.96      fvdl 		 */
   1049   1.96      fvdl 		u_int mesg_out;
   1050   1.96      fvdl 		u_int curphase;
   1051   1.96      fvdl 		u_int errorphase;
   1052   1.96      fvdl 		u_int lastphase;
   1053   1.96      fvdl 		u_int scsirate;
   1054   1.96      fvdl 		u_int i;
   1055   1.96      fvdl 		u_int sstat2;
   1056   1.96      fvdl 		int   silent;
   1057   1.96      fvdl 
   1058   1.96      fvdl 		lastphase = ahc_inb(ahc, LASTPHASE);
   1059   1.96      fvdl 		curphase = ahc_inb(ahc, SCSISIGI) & PHASE_MASK;
   1060   1.96      fvdl 		sstat2 = ahc_inb(ahc, SSTAT2);
   1061   1.96      fvdl 		ahc_outb(ahc, CLRSINT1, CLRSCSIPERR);
   1062   1.96      fvdl 		/*
   1063   1.96      fvdl 		 * For all phases save DATA, the sequencer won't
   1064   1.96      fvdl 		 * automatically ack a byte that has a parity error
   1065   1.96      fvdl 		 * in it.  So the only way that the current phase
   1066   1.96      fvdl 		 * could be 'data-in' is if the parity error is for
   1067   1.96      fvdl 		 * an already acked byte in the data phase.  During
   1068   1.96      fvdl 		 * synchronous data-in transfers, we may actually
   1069   1.96      fvdl 		 * ack bytes before latching the current phase in
   1070   1.96      fvdl 		 * LASTPHASE, leading to the discrepancy between
   1071   1.96      fvdl 		 * curphase and lastphase.
   1072   1.96      fvdl 		 */
   1073   1.96      fvdl 		if ((ahc_inb(ahc, SSTAT1) & SCSIPERR) != 0
   1074   1.96      fvdl 		 || curphase == P_DATAIN || curphase == P_DATAIN_DT)
   1075   1.96      fvdl 			errorphase = curphase;
   1076   1.96      fvdl 		else
   1077   1.96      fvdl 			errorphase = lastphase;
   1078   1.96      fvdl 
   1079   1.96      fvdl 		for (i = 0; i < num_phases; i++) {
   1080   1.96      fvdl 			if (errorphase == ahc_phase_table[i].phase)
   1081   1.96      fvdl 				break;
   1082   1.96      fvdl 		}
   1083   1.96      fvdl 		mesg_out = ahc_phase_table[i].mesg_out;
   1084   1.96      fvdl 		silent = FALSE;
   1085   1.96      fvdl 		if (scb != NULL) {
   1086   1.96      fvdl 			if (SCB_IS_SILENT(scb))
   1087   1.96      fvdl 				silent = TRUE;
   1088   1.96      fvdl 			else
   1089   1.96      fvdl 				ahc_print_path(ahc, scb);
   1090   1.96      fvdl 			scb->flags |= SCB_TRANSMISSION_ERROR;
   1091   1.96      fvdl 		} else
   1092   1.96      fvdl 			printf("%s:%c:%d: ", ahc_name(ahc), intr_channel,
   1093   1.96      fvdl 			       SCSIID_TARGET(ahc, ahc_inb(ahc, SAVED_SCSIID)));
   1094   1.96      fvdl 		scsirate = ahc_inb(ahc, SCSIRATE);
   1095   1.96      fvdl 		if (silent == FALSE) {
   1096   1.96      fvdl 			printf("parity error detected %s. "
   1097   1.96      fvdl 			       "SEQADDR(0x%x) SCSIRATE(0x%x)\n",
   1098   1.96      fvdl 			       ahc_phase_table[i].phasemsg,
   1099   1.96      fvdl 			       ahc_inw(ahc, SEQADDR0),
   1100   1.96      fvdl 			       scsirate);
   1101   1.96      fvdl 			if ((ahc->features & AHC_DT) != 0) {
   1102   1.96      fvdl 				if ((sstat2 & CRCVALERR) != 0)
   1103   1.96      fvdl 					printf("\tCRC Value Mismatch\n");
   1104   1.96      fvdl 				if ((sstat2 & CRCENDERR) != 0)
   1105   1.96      fvdl 					printf("\tNo terminal CRC packet "
   1106   1.96      fvdl 					       "recevied\n");
   1107   1.96      fvdl 				if ((sstat2 & CRCREQERR) != 0)
   1108   1.96      fvdl 					printf("\tIllegal CRC packet "
   1109   1.96      fvdl 					       "request\n");
   1110   1.96      fvdl 				if ((sstat2 & DUAL_EDGE_ERR) != 0)
   1111   1.96      fvdl 					printf("\tUnexpected %sDT Data Phase\n",
   1112   1.96      fvdl 					       (scsirate & SINGLE_EDGE)
   1113   1.96      fvdl 					     ? "" : "non-");
   1114   1.96      fvdl 			}
   1115   1.96      fvdl 		}
   1116   1.96      fvdl 
   1117   1.96      fvdl 		if ((ahc->features & AHC_DT) != 0
   1118   1.96      fvdl 		 && (sstat2 & DUAL_EDGE_ERR) != 0) {
   1119   1.96      fvdl 			/*
   1120   1.96      fvdl 			 * This error applies regardless of
   1121   1.96      fvdl 			 * data direction, so ignore the value
   1122   1.96      fvdl 			 * in the phase table.
   1123   1.96      fvdl 			 */
   1124   1.96      fvdl 			mesg_out = MSG_INITIATOR_DET_ERR;
   1125   1.96      fvdl 		}
   1126   1.96      fvdl 
   1127   1.96      fvdl 		/*
   1128  1.112     perry 		 * We've set the hardware to assert ATN if we
   1129  1.112     perry 		 * get a parity error on "in" phases, so all we
   1130   1.96      fvdl 		 * need to do is stuff the message buffer with
   1131   1.96      fvdl 		 * the appropriate message.  "In" phases have set
   1132   1.96      fvdl 		 * mesg_out to something other than MSG_NOP.
   1133   1.96      fvdl 		 */
   1134   1.96      fvdl 		if (mesg_out != MSG_NOOP) {
   1135   1.96      fvdl 			if (ahc->msg_type != MSG_TYPE_NONE)
   1136   1.96      fvdl 				ahc->send_msg_perror = TRUE;
   1137   1.96      fvdl 			else
   1138   1.96      fvdl 				ahc_outb(ahc, MSG_OUT, mesg_out);
   1139   1.96      fvdl 		}
   1140   1.96      fvdl 		/*
   1141   1.96      fvdl 		 * Force a renegotiation with this target just in
   1142   1.96      fvdl 		 * case we are out of sync for some external reason
   1143   1.96      fvdl 		 * unknown (or unreported) by the target.
   1144   1.96      fvdl 		 */
   1145   1.96      fvdl 		ahc_force_renegotiation(ahc);
   1146   1.96      fvdl 		ahc_outb(ahc, CLRINT, CLRSCSIINT);
   1147   1.96      fvdl 		ahc_unpause(ahc);
   1148   1.96      fvdl 	} else if ((status & SELTO) != 0) {
   1149   1.96      fvdl 		u_int	scbptr;
   1150   1.96      fvdl 
   1151   1.96      fvdl 		/* Stop the selection */
   1152   1.96      fvdl 		ahc_outb(ahc, SCSISEQ, 0);
   1153   1.96      fvdl 
   1154   1.96      fvdl 		/* No more pending messages */
   1155   1.96      fvdl 		ahc_clear_msg_state(ahc);
   1156   1.96      fvdl 
   1157   1.96      fvdl 		/* Clear interrupt state */
   1158   1.96      fvdl 		ahc_outb(ahc, SIMODE1, ahc_inb(ahc, SIMODE1) & ~ENBUSFREE);
   1159   1.96      fvdl 		ahc_outb(ahc, CLRSINT1, CLRSELTIMEO|CLRBUSFREE|CLRSCSIPERR);
   1160   1.96      fvdl 
   1161   1.96      fvdl 		/*
   1162   1.96      fvdl 		 * Although the driver does not care about the
   1163   1.96      fvdl 		 * 'Selection in Progress' status bit, the busy
   1164   1.96      fvdl 		 * LED does.  SELINGO is only cleared by a sucessfull
   1165   1.96      fvdl 		 * selection, so we must manually clear it to insure
   1166   1.96      fvdl 		 * the LED turns off just incase no future successful
   1167   1.96      fvdl 		 * selections occur (e.g. no devices on the bus).
   1168   1.96      fvdl 		 */
   1169   1.96      fvdl 		ahc_outb(ahc, CLRSINT0, CLRSELINGO);
   1170   1.96      fvdl 
   1171   1.96      fvdl 		scbptr = ahc_inb(ahc, WAITING_SCBH);
   1172   1.96      fvdl 		ahc_outb(ahc, SCBPTR, scbptr);
   1173   1.96      fvdl 		scb_index = ahc_inb(ahc, SCB_TAG);
   1174   1.96      fvdl 
   1175   1.96      fvdl 		scb = ahc_lookup_scb(ahc, scb_index);
   1176   1.96      fvdl 		if (scb == NULL) {
   1177   1.96      fvdl 			printf("%s: ahc_intr - referenced scb not "
   1178   1.96      fvdl 			       "valid during SELTO scb(%d, %d)\n",
   1179   1.96      fvdl 			       ahc_name(ahc), scbptr, scb_index);
   1180   1.96      fvdl 			ahc_dump_card_state(ahc);
   1181   1.96      fvdl 		} else {
   1182   1.96      fvdl #ifdef AHC_DEBUG
   1183   1.96      fvdl 			if ((ahc_debug & AHC_SHOW_SELTO) != 0) {
   1184   1.96      fvdl 				ahc_print_path(ahc, scb);
   1185   1.96      fvdl 				printf("Saw Selection Timeout for SCB 0x%x\n",
   1186   1.96      fvdl 				       scb_index);
   1187   1.96      fvdl 			}
   1188   1.96      fvdl #endif
   1189   1.96      fvdl 			/*
   1190   1.96      fvdl 			 * Force a renegotiation with this target just in
   1191   1.96      fvdl 			 * case the cable was pulled and will later be
   1192   1.96      fvdl 			 * re-attached.  The target may forget its negotiation
   1193   1.96      fvdl 			 * settings with us should it attempt to reselect
   1194   1.96      fvdl 			 * during the interruption.  The target will not issue
   1195   1.96      fvdl 			 * a unit attention in this case, so we must always
   1196   1.96      fvdl 			 * renegotiate.
   1197   1.96      fvdl 			 */
   1198   1.96      fvdl 			ahc_force_renegotiation(ahc);
   1199   1.96      fvdl 			ahc_set_transaction_status(scb, CAM_SEL_TIMEOUT);
   1200   1.96      fvdl 			ahc_freeze_devq(ahc, scb);
   1201   1.96      fvdl 		}
   1202   1.96      fvdl 		ahc_outb(ahc, CLRINT, CLRSCSIINT);
   1203   1.96      fvdl 		ahc_restart(ahc);
   1204   1.96      fvdl 	} else if ((status & BUSFREE) != 0
   1205   1.96      fvdl 		&& (ahc_inb(ahc, SIMODE1) & ENBUSFREE) != 0) {
   1206   1.96      fvdl 		u_int lastphase;
   1207   1.96      fvdl 		u_int saved_scsiid;
   1208   1.96      fvdl 		u_int saved_lun;
   1209   1.96      fvdl 		u_int target;
   1210   1.96      fvdl 		u_int initiator_role_id;
   1211   1.96      fvdl 		char channel;
   1212   1.96      fvdl 		int printerror;
   1213   1.96      fvdl 
   1214   1.96      fvdl 		/*
   1215   1.96      fvdl 		 * Clear our selection hardware as soon as possible.
   1216   1.96      fvdl 		 * We may have an entry in the waiting Q for this target,
   1217   1.96      fvdl 		 * that is affected by this busfree and we don't want to
   1218   1.96      fvdl 		 * go about selecting the target while we handle the event.
   1219   1.96      fvdl 		 */
   1220   1.96      fvdl 		ahc_outb(ahc, SCSISEQ,
   1221   1.96      fvdl 			 ahc_inb(ahc, SCSISEQ) & (ENSELI|ENRSELI|ENAUTOATNP));
   1222   1.96      fvdl 
   1223   1.96      fvdl 		/*
   1224   1.96      fvdl 		 * Disable busfree interrupts and clear the busfree
   1225   1.96      fvdl 		 * interrupt status.  We do this here so that several
   1226   1.96      fvdl 		 * bus transactions occur prior to clearing the SCSIINT
   1227   1.96      fvdl 		 * latch.  It can take a bit for the clearing to take effect.
   1228   1.96      fvdl 		 */
   1229   1.96      fvdl 		ahc_outb(ahc, SIMODE1, ahc_inb(ahc, SIMODE1) & ~ENBUSFREE);
   1230   1.96      fvdl 		ahc_outb(ahc, CLRSINT1, CLRBUSFREE|CLRSCSIPERR);
   1231   1.96      fvdl 
   1232   1.96      fvdl 		/*
   1233   1.96      fvdl 		 * Look at what phase we were last in.
   1234   1.96      fvdl 		 * If its message out, chances are pretty good
   1235   1.96      fvdl 		 * that the busfree was in response to one of
   1236   1.96      fvdl 		 * our abort requests.
   1237   1.96      fvdl 		 */
   1238   1.96      fvdl 		lastphase = ahc_inb(ahc, LASTPHASE);
   1239   1.96      fvdl 		saved_scsiid = ahc_inb(ahc, SAVED_SCSIID);
   1240   1.96      fvdl 		saved_lun = ahc_inb(ahc, SAVED_LUN);
   1241   1.96      fvdl 		target = SCSIID_TARGET(ahc, saved_scsiid);
   1242   1.96      fvdl 		initiator_role_id = SCSIID_OUR_ID(saved_scsiid);
   1243   1.96      fvdl 		channel = SCSIID_CHANNEL(ahc, saved_scsiid);
   1244   1.96      fvdl 		printerror = 1;
   1245   1.96      fvdl 
   1246   1.96      fvdl 		if (lastphase == P_MESGOUT) {
   1247   1.96      fvdl 			struct ahc_devinfo devinfo;
   1248   1.96      fvdl 			u_int tag;
   1249   1.96      fvdl 
   1250   1.96      fvdl 			ahc_fetch_devinfo(ahc, &devinfo);
   1251   1.96      fvdl 			tag = SCB_LIST_NULL;
   1252   1.96      fvdl 			if (ahc_sent_msg(ahc, AHCMSG_1B, MSG_ABORT_TAG, TRUE)
   1253   1.96      fvdl 			    || ahc_sent_msg(ahc, AHCMSG_1B, MSG_ABORT, TRUE)) {
   1254   1.96      fvdl 				if (ahc->msgout_buf[ahc->msgout_index - 1]
   1255   1.96      fvdl 				    == MSG_ABORT_TAG)
   1256   1.96      fvdl 				tag = scb->hscb->tag;
   1257   1.96      fvdl 				ahc_print_path(ahc, scb);
   1258   1.96      fvdl 				printf("SCB %d - Abort%s Completed.\n",
   1259   1.96      fvdl 				       scb->hscb->tag, tag == SCB_LIST_NULL ?
   1260   1.96      fvdl 				       "" : " Tag");
   1261   1.96      fvdl 				ahc_abort_scbs(ahc, target, channel,
   1262   1.96      fvdl 					       saved_lun, tag,
   1263   1.96      fvdl 					       ROLE_INITIATOR,
   1264   1.96      fvdl 					       CAM_REQ_ABORTED);
   1265   1.96      fvdl 				printerror = 0;
   1266   1.96      fvdl 			} else if (ahc_sent_msg(ahc, AHCMSG_1B,
   1267   1.96      fvdl 						MSG_BUS_DEV_RESET, TRUE)) {
   1268   1.96      fvdl #ifdef __FreeBSD__
   1269   1.96      fvdl 				/*
   1270   1.96      fvdl 				 * Don't mark the user's request for this BDR
   1271   1.96      fvdl 				 * as completing with CAM_BDR_SENT.  CAM3
   1272   1.96      fvdl 				 * specifies CAM_REQ_CMP.
   1273   1.96      fvdl 				 */
   1274   1.96      fvdl 				if (scb != NULL
   1275   1.96      fvdl 				 && scb->io_ctx->ccb_h.func_code== XPT_RESET_DEV
   1276   1.96      fvdl 				 && ahc_match_scb(ahc, scb, target, channel,
   1277   1.96      fvdl 						  CAM_LUN_WILDCARD,
   1278   1.96      fvdl 						  SCB_LIST_NULL,
   1279   1.96      fvdl 						  ROLE_INITIATOR)) {
   1280   1.96      fvdl 					ahc_set_transaction_status(scb, CAM_REQ_CMP);
   1281   1.96      fvdl 				}
   1282   1.96      fvdl #endif
   1283   1.96      fvdl 				ahc_compile_devinfo(&devinfo,
   1284   1.96      fvdl 						    initiator_role_id,
   1285   1.96      fvdl 						    target,
   1286   1.96      fvdl 						    CAM_LUN_WILDCARD,
   1287   1.96      fvdl 						    channel,
   1288   1.96      fvdl 						    ROLE_INITIATOR);
   1289   1.96      fvdl 				ahc_handle_devreset(ahc, &devinfo,
   1290   1.96      fvdl 						    CAM_BDR_SENT,
   1291   1.96      fvdl 						    "Bus Device Reset",
   1292   1.96      fvdl 						    /*verbose_level*/0);
   1293   1.96      fvdl 				printerror = 0;
   1294   1.96      fvdl 			} else if (ahc_sent_msg(ahc, AHCMSG_EXT,
   1295   1.96      fvdl 						MSG_EXT_PPR, FALSE)) {
   1296   1.96      fvdl 				struct ahc_initiator_tinfo *tinfo;
   1297   1.96      fvdl 				struct ahc_tmode_tstate *tstate;
   1298   1.96      fvdl 
   1299   1.96      fvdl 				/*
   1300   1.96      fvdl 				 * PPR Rejected.  Try non-ppr negotiation
   1301   1.96      fvdl 				 * and retry command.
   1302   1.96      fvdl 				 */
   1303   1.96      fvdl 				tinfo = ahc_fetch_transinfo(ahc,
   1304   1.96      fvdl 							    devinfo.channel,
   1305   1.96      fvdl 							    devinfo.our_scsiid,
   1306   1.96      fvdl 							    devinfo.target,
   1307   1.96      fvdl 							    &tstate);
   1308   1.96      fvdl 				tinfo->curr.transport_version = 2;
   1309   1.96      fvdl 				tinfo->goal.transport_version = 2;
   1310   1.96      fvdl 				tinfo->goal.ppr_options = 0;
   1311   1.96      fvdl 				ahc_qinfifo_requeue_tail(ahc, scb);
   1312   1.96      fvdl 				printerror = 0;
   1313   1.96      fvdl 			} else if (ahc_sent_msg(ahc, AHCMSG_EXT,
   1314   1.96      fvdl 						MSG_EXT_WDTR, FALSE)
   1315   1.96      fvdl 				|| ahc_sent_msg(ahc, AHCMSG_EXT,
   1316   1.96      fvdl 						MSG_EXT_SDTR, FALSE)) {
   1317   1.96      fvdl 				/*
   1318   1.96      fvdl 				 * Negotiation Rejected.  Go-async and
   1319   1.96      fvdl 				 * retry command.
   1320   1.96      fvdl 				 */
   1321   1.96      fvdl 				ahc_set_width(ahc, &devinfo,
   1322   1.96      fvdl 					      MSG_EXT_WDTR_BUS_8_BIT,
   1323   1.96      fvdl 					      AHC_TRANS_CUR|AHC_TRANS_GOAL,
   1324   1.96      fvdl 					      /*paused*/TRUE);
   1325   1.96      fvdl 				ahc_set_syncrate(ahc, &devinfo,
   1326   1.96      fvdl 						/*syncrate*/NULL,
   1327   1.96      fvdl 						/*period*/0, /*offset*/0,
   1328   1.96      fvdl 						/*ppr_options*/0,
   1329   1.96      fvdl 						AHC_TRANS_CUR|AHC_TRANS_GOAL,
   1330   1.96      fvdl 						/*paused*/TRUE);
   1331   1.96      fvdl 				ahc_qinfifo_requeue_tail(ahc, scb);
   1332   1.96      fvdl 				printerror = 0;
   1333   1.96      fvdl 			}
   1334   1.96      fvdl 		}
   1335   1.96      fvdl 		if (printerror != 0) {
   1336   1.96      fvdl 			u_int i;
   1337   1.96      fvdl 
   1338   1.96      fvdl 			if (scb != NULL) {
   1339   1.96      fvdl 				u_int tag;
   1340   1.96      fvdl 
   1341   1.96      fvdl 				if ((scb->hscb->control & TAG_ENB) != 0)
   1342   1.96      fvdl 					tag = scb->hscb->tag;
   1343   1.96      fvdl 				else
   1344   1.96      fvdl 					tag = SCB_LIST_NULL;
   1345   1.96      fvdl 				ahc_print_path(ahc, scb);
   1346   1.96      fvdl 				ahc_abort_scbs(ahc, target, channel,
   1347   1.96      fvdl 					       SCB_GET_LUN(scb), tag,
   1348   1.96      fvdl 					       ROLE_INITIATOR,
   1349   1.96      fvdl 					       CAM_UNEXP_BUSFREE);
   1350   1.96      fvdl 			} else {
   1351   1.96      fvdl 				/*
   1352   1.96      fvdl 				 * We had not fully identified this connection,
   1353   1.96      fvdl 				 * so we cannot abort anything.
   1354   1.96      fvdl 				 */
   1355   1.96      fvdl 				printf("%s: ", ahc_name(ahc));
   1356   1.96      fvdl 			}
   1357   1.96      fvdl 			for (i = 0; i < num_phases; i++) {
   1358   1.96      fvdl 				if (lastphase == ahc_phase_table[i].phase)
   1359   1.96      fvdl 					break;
   1360   1.96      fvdl 			}
   1361   1.96      fvdl 			/*
   1362   1.96      fvdl 			 * Renegotiate with this device at the
   1363  1.108       wiz 			 * next opportunity just in case this busfree
   1364   1.96      fvdl 			 * is due to a negotiation mismatch with the
   1365   1.96      fvdl 			 * device.
   1366   1.96      fvdl 			 */
   1367   1.96      fvdl 			ahc_force_renegotiation(ahc);
   1368   1.96      fvdl 			printf("Unexpected busfree %s\n"
   1369   1.96      fvdl 			       "SEQADDR == 0x%x\n",
   1370   1.96      fvdl 			       ahc_phase_table[i].phasemsg,
   1371   1.96      fvdl 			       ahc_inb(ahc, SEQADDR0)
   1372   1.96      fvdl 				| (ahc_inb(ahc, SEQADDR1) << 8));
   1373   1.96      fvdl 		}
   1374   1.96      fvdl 		ahc_outb(ahc, CLRINT, CLRSCSIINT);
   1375   1.96      fvdl 		ahc_restart(ahc);
   1376   1.96      fvdl 	} else {
   1377   1.96      fvdl 		printf("%s: Missing case in ahc_handle_scsiint. status = %x\n",
   1378   1.96      fvdl 		       ahc_name(ahc), status);
   1379   1.96      fvdl 		ahc_outb(ahc, CLRINT, CLRSCSIINT);
   1380   1.96      fvdl 	}
   1381   1.96      fvdl }
   1382   1.96      fvdl 
   1383   1.96      fvdl /*
   1384   1.96      fvdl  * Force renegotiation to occur the next time we initiate
   1385   1.96      fvdl  * a command to the current device.
   1386   1.96      fvdl  */
   1387   1.96      fvdl static void
   1388   1.96      fvdl ahc_force_renegotiation(struct ahc_softc *ahc)
   1389   1.96      fvdl {
   1390   1.96      fvdl 	struct	ahc_devinfo devinfo;
   1391   1.96      fvdl 	struct	ahc_initiator_tinfo *targ_info;
   1392   1.96      fvdl 	struct	ahc_tmode_tstate *tstate;
   1393   1.96      fvdl 
   1394   1.96      fvdl 	ahc_fetch_devinfo(ahc, &devinfo);
   1395   1.96      fvdl 	targ_info = ahc_fetch_transinfo(ahc,
   1396   1.96      fvdl 					devinfo.channel,
   1397   1.96      fvdl 					devinfo.our_scsiid,
   1398   1.96      fvdl 					devinfo.target,
   1399   1.96      fvdl 					&tstate);
   1400   1.96      fvdl 	ahc_update_neg_request(ahc, &devinfo, tstate,
   1401   1.96      fvdl 			       targ_info, AHC_NEG_IF_NON_ASYNC);
   1402   1.96      fvdl }
   1403   1.96      fvdl 
   1404   1.96      fvdl #define AHC_MAX_STEPS 2000
   1405   1.96      fvdl void
   1406   1.96      fvdl ahc_clear_critical_section(struct ahc_softc *ahc)
   1407   1.96      fvdl {
   1408   1.96      fvdl 	int	stepping;
   1409   1.96      fvdl 	int	steps;
   1410   1.96      fvdl 	u_int	simode0;
   1411   1.96      fvdl 	u_int	simode1;
   1412   1.96      fvdl 
   1413   1.96      fvdl 	if (ahc->num_critical_sections == 0)
   1414   1.96      fvdl 		return;
   1415   1.96      fvdl 
   1416   1.96      fvdl 	stepping = FALSE;
   1417   1.96      fvdl 	steps = 0;
   1418   1.96      fvdl 	simode0 = 0;
   1419   1.96      fvdl 	simode1 = 0;
   1420   1.96      fvdl 	for (;;) {
   1421   1.96      fvdl 		struct	cs *cs;
   1422   1.96      fvdl 		u_int	seqaddr;
   1423   1.96      fvdl 		u_int	i;
   1424   1.96      fvdl 
   1425   1.96      fvdl 		seqaddr = ahc_inb(ahc, SEQADDR0)
   1426   1.96      fvdl 			| (ahc_inb(ahc, SEQADDR1) << 8);
   1427   1.96      fvdl 
   1428   1.96      fvdl 		/*
   1429  1.112     perry 		 * Seqaddr represents the next instruction to execute,
   1430   1.96      fvdl 		 * so we are really executing the instruction just
   1431   1.96      fvdl 		 * before it.
   1432   1.96      fvdl 		 */
   1433   1.96      fvdl 		if (seqaddr != 0)
   1434   1.96      fvdl 			seqaddr -= 1;
   1435   1.96      fvdl 		cs = ahc->critical_sections;
   1436   1.96      fvdl 		for (i = 0; i < ahc->num_critical_sections; i++, cs++) {
   1437  1.112     perry 
   1438   1.96      fvdl 			if (cs->begin < seqaddr && cs->end >= seqaddr)
   1439   1.96      fvdl 				break;
   1440   1.96      fvdl 		}
   1441   1.96      fvdl 
   1442   1.96      fvdl 		if (i == ahc->num_critical_sections)
   1443   1.96      fvdl 			break;
   1444   1.96      fvdl 
   1445   1.96      fvdl 		if (steps > AHC_MAX_STEPS) {
   1446   1.96      fvdl 			printf("%s: Infinite loop in critical section\n",
   1447   1.96      fvdl 			       ahc_name(ahc));
   1448   1.96      fvdl 			ahc_dump_card_state(ahc);
   1449   1.96      fvdl 			panic("critical section loop");
   1450   1.96      fvdl 		}
   1451   1.96      fvdl 
   1452   1.96      fvdl 		steps++;
   1453   1.96      fvdl 		if (stepping == FALSE) {
   1454   1.96      fvdl 
   1455   1.96      fvdl 			/*
   1456   1.96      fvdl 			 * Disable all interrupt sources so that the
   1457   1.96      fvdl 			 * sequencer will not be stuck by a pausing
   1458   1.96      fvdl 			 * interrupt condition while we attempt to
   1459   1.96      fvdl 			 * leave a critical section.
   1460   1.96      fvdl 			 */
   1461   1.96      fvdl 			simode0 = ahc_inb(ahc, SIMODE0);
   1462   1.96      fvdl 			ahc_outb(ahc, SIMODE0, 0);
   1463   1.96      fvdl 			simode1 = ahc_inb(ahc, SIMODE1);
   1464   1.96      fvdl 			if ((ahc->features & AHC_DT) != 0)
   1465   1.96      fvdl 				/*
   1466   1.96      fvdl 				 * On DT class controllers, we
   1467   1.96      fvdl 				 * use the enhanced busfree logic.
   1468   1.96      fvdl 				 * Unfortunately we cannot re-enable
   1469   1.96      fvdl 				 * busfree detection within the
   1470   1.96      fvdl 				 * current connection, so we must
   1471   1.96      fvdl 				 * leave it on while single stepping.
   1472   1.96      fvdl 				 */
   1473   1.96      fvdl 				ahc_outb(ahc, SIMODE1, ENBUSFREE);
   1474   1.96      fvdl 			else
   1475   1.96      fvdl 				ahc_outb(ahc, SIMODE1, 0);
   1476   1.96      fvdl 			ahc_outb(ahc, CLRINT, CLRSCSIINT);
   1477   1.96      fvdl 			ahc_outb(ahc, SEQCTL, ahc_inb(ahc, SEQCTL) | STEP);
   1478   1.96      fvdl 			stepping = TRUE;
   1479   1.96      fvdl 		}
   1480   1.96      fvdl 		if ((ahc->features & AHC_DT) != 0) {
   1481   1.96      fvdl 			ahc_outb(ahc, CLRSINT1, CLRBUSFREE);
   1482   1.96      fvdl 			ahc_outb(ahc, CLRINT, CLRSCSIINT);
   1483   1.96      fvdl 		}
   1484   1.96      fvdl 		ahc_outb(ahc, HCNTRL, ahc->unpause);
   1485   1.96      fvdl 		while (!ahc_is_paused(ahc))
   1486   1.96      fvdl 			ahc_delay(200);
   1487   1.96      fvdl 	}
   1488   1.96      fvdl 	if (stepping) {
   1489   1.96      fvdl 		ahc_outb(ahc, SIMODE0, simode0);
   1490   1.96      fvdl 		ahc_outb(ahc, SIMODE1, simode1);
   1491   1.96      fvdl 		ahc_outb(ahc, SEQCTL, ahc_inb(ahc, SEQCTL) & ~STEP);
   1492   1.96      fvdl 	}
   1493   1.96      fvdl }
   1494   1.96      fvdl 
   1495   1.96      fvdl /*
   1496   1.96      fvdl  * Clear any pending interrupt status.
   1497   1.96      fvdl  */
   1498   1.96      fvdl void
   1499   1.96      fvdl ahc_clear_intstat(struct ahc_softc *ahc)
   1500   1.96      fvdl {
   1501   1.96      fvdl 	/* Clear any interrupt conditions this may have caused */
   1502   1.96      fvdl 	ahc_outb(ahc, CLRSINT1, CLRSELTIMEO|CLRATNO|CLRSCSIRSTI
   1503   1.96      fvdl 				|CLRBUSFREE|CLRSCSIPERR|CLRPHASECHG|
   1504   1.96      fvdl 				CLRREQINIT);
   1505   1.96      fvdl 	ahc_flush_device_writes(ahc);
   1506   1.96      fvdl 	ahc_outb(ahc, CLRSINT0, CLRSELDO|CLRSELDI|CLRSELINGO);
   1507   1.96      fvdl  	ahc_flush_device_writes(ahc);
   1508   1.96      fvdl 	ahc_outb(ahc, CLRINT, CLRSCSIINT);
   1509   1.96      fvdl 	ahc_flush_device_writes(ahc);
   1510   1.96      fvdl }
   1511   1.96      fvdl 
   1512   1.96      fvdl /**************************** Debugging Routines ******************************/
   1513   1.96      fvdl #ifdef AHC_DEBUG
   1514   1.96      fvdl uint32_t ahc_debug = 0; /* AHC_SHOW_MISC|AHC_SHOW_SENSE|AHC_DEBUG_OPTS;*/
   1515   1.96      fvdl #endif
   1516   1.96      fvdl 
   1517   1.96      fvdl void
   1518   1.96      fvdl ahc_print_scb(struct scb *scb)
   1519   1.96      fvdl {
   1520   1.96      fvdl 	int i;
   1521   1.96      fvdl 
   1522   1.96      fvdl 	struct hardware_scb *hscb = scb->hscb;
   1523   1.96      fvdl 
   1524   1.96      fvdl 	printf("scb:%p control:0x%x scsiid:0x%x lun:%d cdb_len:%d\n",
   1525   1.96      fvdl 	       (void *)scb,
   1526   1.96      fvdl 	       hscb->control,
   1527   1.96      fvdl 	       hscb->scsiid,
   1528   1.96      fvdl 	       hscb->lun,
   1529   1.96      fvdl 	       hscb->cdb_len);
   1530   1.96      fvdl 	printf("Shared Data: ");
   1531   1.96      fvdl 	for (i = 0; i < sizeof(hscb->shared_data.cdb); i++)
   1532   1.96      fvdl 		printf("%#02x", hscb->shared_data.cdb[i]);
   1533   1.96      fvdl 	printf("        dataptr:%#x datacnt:%#x sgptr:%#x tag:%#x\n",
   1534   1.96      fvdl 		ahc_le32toh(hscb->dataptr),
   1535   1.96      fvdl 		ahc_le32toh(hscb->datacnt),
   1536   1.96      fvdl 		ahc_le32toh(hscb->sgptr),
   1537   1.96      fvdl 		hscb->tag);
   1538   1.96      fvdl 	if (scb->sg_count > 0) {
   1539   1.96      fvdl 		for (i = 0; i < scb->sg_count; i++) {
   1540   1.96      fvdl 			printf("sg[%d] - Addr 0x%x%x : Length %d\n",
   1541   1.96      fvdl 			       i,
   1542   1.96      fvdl 			       (ahc_le32toh(scb->sg_list[i].len) >> 24
   1543   1.96      fvdl 			        & SG_HIGH_ADDR_BITS),
   1544   1.96      fvdl 			       ahc_le32toh(scb->sg_list[i].addr),
   1545   1.96      fvdl 			       ahc_le32toh(scb->sg_list[i].len));
   1546   1.96      fvdl 		}
   1547   1.96      fvdl 	}
   1548   1.96      fvdl }
   1549   1.96      fvdl 
   1550   1.96      fvdl /************************* Transfer Negotiation *******************************/
   1551   1.96      fvdl /*
   1552   1.96      fvdl  * Allocate per target mode instance (ID we respond to as a target)
   1553   1.96      fvdl  * transfer negotiation data structures.
   1554   1.96      fvdl  */
   1555   1.96      fvdl static struct ahc_tmode_tstate *
   1556   1.96      fvdl ahc_alloc_tstate(struct ahc_softc *ahc, u_int scsi_id, char channel)
   1557   1.96      fvdl {
   1558   1.96      fvdl 	struct ahc_tmode_tstate *master_tstate;
   1559   1.96      fvdl 	struct ahc_tmode_tstate *tstate;
   1560   1.96      fvdl 	int i;
   1561   1.96      fvdl 
   1562   1.96      fvdl 	master_tstate = ahc->enabled_targets[ahc->our_id];
   1563   1.96      fvdl 	if (channel == 'B') {
   1564   1.96      fvdl 		scsi_id += 8;
   1565   1.96      fvdl 		master_tstate = ahc->enabled_targets[ahc->our_id_b + 8];
   1566   1.96      fvdl 	}
   1567   1.96      fvdl 	if (ahc->enabled_targets[scsi_id] != NULL
   1568   1.96      fvdl 	    && ahc->enabled_targets[scsi_id] != master_tstate)
   1569   1.96      fvdl 		panic("%s: ahc_alloc_tstate - Target already allocated",
   1570   1.96      fvdl 		      ahc_name(ahc));
   1571   1.96      fvdl 	tstate = (struct ahc_tmode_tstate*)malloc(sizeof(*tstate),
   1572   1.96      fvdl 						   M_DEVBUF, M_NOWAIT);
   1573   1.96      fvdl 	if (tstate == NULL)
   1574   1.96      fvdl 		return (NULL);
   1575   1.96      fvdl 
   1576   1.96      fvdl 	/*
   1577   1.96      fvdl 	 * If we have allocated a master tstate, copy user settings from
   1578   1.96      fvdl 	 * the master tstate (taken from SRAM or the EEPROM) for this
   1579   1.96      fvdl 	 * channel, but reset our current and goal settings to async/narrow
   1580   1.96      fvdl 	 * until an initiator talks to us.
   1581   1.96      fvdl 	 */
   1582   1.96      fvdl 	if (master_tstate != NULL) {
   1583   1.96      fvdl 		memcpy(tstate, master_tstate, sizeof(*tstate));
   1584   1.96      fvdl 		memset(tstate->enabled_luns, 0, sizeof(tstate->enabled_luns));
   1585   1.96      fvdl 		tstate->ultraenb = 0;
   1586   1.96      fvdl 		for (i = 0; i < AHC_NUM_TARGETS; i++) {
   1587   1.96      fvdl 			memset(&tstate->transinfo[i].curr, 0,
   1588   1.96      fvdl 			      sizeof(tstate->transinfo[i].curr));
   1589   1.96      fvdl 			memset(&tstate->transinfo[i].goal, 0,
   1590   1.96      fvdl 			      sizeof(tstate->transinfo[i].goal));
   1591   1.96      fvdl 		}
   1592   1.96      fvdl 	} else
   1593   1.96      fvdl 		memset(tstate, 0, sizeof(*tstate));
   1594   1.96      fvdl 	ahc->enabled_targets[scsi_id] = tstate;
   1595   1.96      fvdl 	return (tstate);
   1596   1.96      fvdl }
   1597   1.96      fvdl 
   1598   1.96      fvdl #ifdef AHC_TARGET_MODE
   1599   1.96      fvdl /*
   1600   1.96      fvdl  * Free per target mode instance (ID we respond to as a target)
   1601   1.96      fvdl  * transfer negotiation data structures.
   1602   1.96      fvdl  */
   1603   1.96      fvdl static void
   1604   1.96      fvdl ahc_free_tstate(struct ahc_softc *ahc, u_int scsi_id, char channel, int force)
   1605   1.96      fvdl {
   1606   1.96      fvdl 	struct ahc_tmode_tstate *tstate;
   1607   1.96      fvdl 
   1608   1.96      fvdl 	/*
   1609   1.96      fvdl 	 * Don't clean up our "master" tstate.
   1610   1.96      fvdl 	 * It has our default user settings.
   1611   1.96      fvdl 	 */
   1612   1.96      fvdl 	if (((channel == 'B' && scsi_id == ahc->our_id_b)
   1613   1.96      fvdl 	  || (channel == 'A' && scsi_id == ahc->our_id))
   1614   1.96      fvdl 	 && force == FALSE)
   1615   1.96      fvdl 		return;
   1616   1.96      fvdl 
   1617   1.96      fvdl 	if (channel == 'B')
   1618   1.96      fvdl 		scsi_id += 8;
   1619   1.96      fvdl 	tstate = ahc->enabled_targets[scsi_id];
   1620   1.96      fvdl 	if (tstate != NULL)
   1621   1.96      fvdl 		free(tstate, M_DEVBUF);
   1622   1.96      fvdl 	ahc->enabled_targets[scsi_id] = NULL;
   1623   1.96      fvdl }
   1624   1.96      fvdl #endif
   1625   1.96      fvdl 
   1626   1.96      fvdl /*
   1627   1.96      fvdl  * Called when we have an active connection to a target on the bus,
   1628   1.96      fvdl  * this function finds the nearest syncrate to the input period limited
   1629   1.96      fvdl  * by the capabilities of the bus connectivity of and sync settings for
   1630   1.96      fvdl  * the target.
   1631   1.96      fvdl  */
   1632   1.96      fvdl struct ahc_syncrate *
   1633   1.96      fvdl ahc_devlimited_syncrate(struct ahc_softc *ahc,
   1634   1.96      fvdl 			struct ahc_initiator_tinfo *tinfo,
   1635   1.96      fvdl 			u_int *period, u_int *ppr_options, role_t role)
   1636   1.96      fvdl {
   1637   1.96      fvdl 	struct	ahc_transinfo *transinfo;
   1638   1.96      fvdl 	u_int	maxsync;
   1639   1.96      fvdl 
   1640   1.96      fvdl 	if ((ahc->features & AHC_ULTRA2) != 0) {
   1641   1.96      fvdl 		if ((ahc_inb(ahc, SBLKCTL) & ENAB40) != 0
   1642   1.96      fvdl 		 && (ahc_inb(ahc, SSTAT2) & EXP_ACTIVE) == 0) {
   1643   1.96      fvdl 			maxsync = AHC_SYNCRATE_DT;
   1644   1.96      fvdl 		} else {
   1645   1.96      fvdl 			maxsync = AHC_SYNCRATE_ULTRA;
   1646   1.96      fvdl 			/* Can't do DT on an SE bus */
   1647   1.96      fvdl 			*ppr_options &= ~MSG_EXT_PPR_DT_REQ;
   1648   1.96      fvdl 		}
   1649   1.96      fvdl 	} else if ((ahc->features & AHC_ULTRA) != 0) {
   1650   1.96      fvdl 		maxsync = AHC_SYNCRATE_ULTRA;
   1651   1.96      fvdl 	} else {
   1652   1.96      fvdl 		maxsync = AHC_SYNCRATE_FAST;
   1653   1.96      fvdl 	}
   1654   1.96      fvdl 	/*
   1655   1.96      fvdl 	 * Never allow a value higher than our current goal
   1656   1.96      fvdl 	 * period otherwise we may allow a target initiated
   1657   1.96      fvdl 	 * negotiation to go above the limit as set by the
   1658   1.96      fvdl 	 * user.  In the case of an initiator initiated
   1659   1.96      fvdl 	 * sync negotiation, we limit based on the user
   1660   1.96      fvdl 	 * setting.  This allows the system to still accept
   1661   1.96      fvdl 	 * incoming negotiations even if target initiated
   1662   1.96      fvdl 	 * negotiation is not performed.
   1663   1.96      fvdl 	 */
   1664   1.96      fvdl 	if (role == ROLE_TARGET)
   1665   1.96      fvdl 		transinfo = &tinfo->user;
   1666  1.112     perry 	else
   1667   1.96      fvdl 		transinfo = &tinfo->goal;
   1668   1.96      fvdl 	*ppr_options &= transinfo->ppr_options;
   1669   1.96      fvdl 	if (transinfo->width == MSG_EXT_WDTR_BUS_8_BIT) {
   1670   1.96      fvdl 		maxsync = MAX(maxsync, AHC_SYNCRATE_ULTRA2);
   1671   1.96      fvdl 		*ppr_options &= ~MSG_EXT_PPR_DT_REQ;
   1672   1.96      fvdl 	}
   1673   1.96      fvdl 	if (transinfo->period == 0) {
   1674   1.96      fvdl 		*period = 0;
   1675   1.96      fvdl 		*ppr_options = 0;
   1676   1.96      fvdl 		return (NULL);
   1677   1.96      fvdl 	}
   1678   1.96      fvdl 	*period = MAX(*period, transinfo->period);
   1679   1.96      fvdl 	return (ahc_find_syncrate(ahc, period, ppr_options, maxsync));
   1680   1.96      fvdl }
   1681   1.96      fvdl 
   1682   1.96      fvdl /*
   1683   1.96      fvdl  * Look up the valid period to SCSIRATE conversion in our table.
   1684   1.96      fvdl  * Return the period and offset that should be sent to the target
   1685   1.96      fvdl  * if this was the beginning of an SDTR.
   1686   1.96      fvdl  */
   1687   1.96      fvdl struct ahc_syncrate *
   1688   1.96      fvdl ahc_find_syncrate(struct ahc_softc *ahc, u_int *period,
   1689   1.96      fvdl 		  u_int *ppr_options, u_int maxsync)
   1690   1.96      fvdl {
   1691   1.96      fvdl 	struct ahc_syncrate *syncrate;
   1692   1.96      fvdl 
   1693   1.96      fvdl 	if ((ahc->features & AHC_DT) == 0)
   1694   1.96      fvdl 		*ppr_options &= ~MSG_EXT_PPR_DT_REQ;
   1695   1.96      fvdl 
   1696   1.96      fvdl 	/* Skip all DT only entries if DT is not available */
   1697   1.96      fvdl 	if ((*ppr_options & MSG_EXT_PPR_DT_REQ) == 0
   1698   1.96      fvdl 	 && maxsync < AHC_SYNCRATE_ULTRA2)
   1699   1.96      fvdl 		maxsync = AHC_SYNCRATE_ULTRA2;
   1700  1.112     perry 
   1701   1.96      fvdl 	for (syncrate = &ahc_syncrates[maxsync];
   1702   1.96      fvdl 	     syncrate->rate != NULL;
   1703   1.96      fvdl 	     syncrate++) {
   1704   1.96      fvdl 
   1705   1.96      fvdl 		/*
   1706   1.96      fvdl 		 * The Ultra2 table doesn't go as low
   1707   1.96      fvdl 		 * as for the Fast/Ultra cards.
   1708   1.96      fvdl 		 */
   1709   1.96      fvdl 		if ((ahc->features & AHC_ULTRA2) != 0
   1710   1.96      fvdl 		 && (syncrate->sxfr_u2 == 0))
   1711   1.96      fvdl 			break;
   1712   1.96      fvdl 
   1713   1.96      fvdl 		if (*period <= syncrate->period) {
   1714   1.96      fvdl 			/*
   1715   1.96      fvdl 			 * When responding to a target that requests
   1716   1.96      fvdl 			 * sync, the requested rate may fall between
   1717   1.96      fvdl 			 * two rates that we can output, but still be
   1718   1.96      fvdl 			 * a rate that we can receive.  Because of this,
   1719   1.96      fvdl 			 * we want to respond to the target with
   1720   1.96      fvdl 			 * the same rate that it sent to us even
   1721   1.96      fvdl 			 * if the period we use to send data to it
   1722   1.96      fvdl 			 * is lower.  Only lower the response period
   1723   1.96      fvdl 			 * if we must.
   1724   1.96      fvdl 			 */
   1725   1.96      fvdl 			if (syncrate == &ahc_syncrates[maxsync])
   1726   1.96      fvdl 				*period = syncrate->period;
   1727   1.96      fvdl 
   1728   1.96      fvdl 			/*
   1729   1.96      fvdl 			 * At some speeds, we only support
   1730   1.96      fvdl 			 * ST transfers.
   1731   1.96      fvdl 			 */
   1732   1.96      fvdl 		 	if ((syncrate->sxfr_u2 & ST_SXFR) != 0)
   1733   1.96      fvdl 				*ppr_options &= ~MSG_EXT_PPR_DT_REQ;
   1734   1.96      fvdl 			break;
   1735   1.96      fvdl 		}
   1736   1.96      fvdl 	}
   1737   1.96      fvdl 
   1738   1.96      fvdl 	if ((*period == 0)
   1739   1.96      fvdl 	 || (syncrate->rate == NULL)
   1740   1.96      fvdl 	 || ((ahc->features & AHC_ULTRA2) != 0
   1741   1.96      fvdl 	  && (syncrate->sxfr_u2 == 0))) {
   1742   1.96      fvdl 		/* Use asynchronous transfers. */
   1743   1.96      fvdl 		*period = 0;
   1744   1.96      fvdl 		syncrate = NULL;
   1745   1.96      fvdl 		*ppr_options &= ~MSG_EXT_PPR_DT_REQ;
   1746   1.96      fvdl 	}
   1747   1.96      fvdl 	return (syncrate);
   1748   1.96      fvdl }
   1749   1.96      fvdl 
   1750   1.96      fvdl /*
   1751   1.96      fvdl  * Convert from an entry in our syncrate table to the SCSI equivalent
   1752   1.96      fvdl  * sync "period" factor.
   1753   1.96      fvdl  */
   1754   1.96      fvdl u_int
   1755   1.96      fvdl ahc_find_period(struct ahc_softc *ahc, u_int scsirate, u_int maxsync)
   1756   1.96      fvdl {
   1757   1.96      fvdl 	struct ahc_syncrate *syncrate;
   1758   1.96      fvdl 
   1759   1.96      fvdl 	if ((ahc->features & AHC_ULTRA2) != 0)
   1760   1.96      fvdl 		scsirate &= SXFR_ULTRA2;
   1761   1.96      fvdl 	else
   1762   1.96      fvdl 		scsirate &= SXFR;
   1763   1.96      fvdl 
   1764   1.96      fvdl 	syncrate = &ahc_syncrates[maxsync];
   1765   1.96      fvdl 	while (syncrate->rate != NULL) {
   1766   1.96      fvdl 
   1767   1.96      fvdl 		if ((ahc->features & AHC_ULTRA2) != 0) {
   1768   1.96      fvdl 			if (syncrate->sxfr_u2 == 0)
   1769   1.96      fvdl 				break;
   1770   1.96      fvdl 			else if (scsirate == (syncrate->sxfr_u2 & SXFR_ULTRA2))
   1771   1.96      fvdl 				return (syncrate->period);
   1772   1.96      fvdl 		} else if (scsirate == (syncrate->sxfr & SXFR)) {
   1773   1.96      fvdl 				return (syncrate->period);
   1774   1.96      fvdl 		}
   1775   1.96      fvdl 		syncrate++;
   1776   1.96      fvdl 	}
   1777   1.96      fvdl 	return (0); /* async */
   1778   1.96      fvdl }
   1779   1.96      fvdl 
   1780   1.96      fvdl /*
   1781   1.96      fvdl  * Truncate the given synchronous offset to a value the
   1782   1.96      fvdl  * current adapter type and syncrate are capable of.
   1783   1.96      fvdl  */
   1784   1.96      fvdl void
   1785   1.96      fvdl ahc_validate_offset(struct ahc_softc *ahc,
   1786   1.96      fvdl 		    struct ahc_initiator_tinfo *tinfo,
   1787   1.96      fvdl 		    struct ahc_syncrate *syncrate,
   1788   1.96      fvdl 		    u_int *offset, int wide, role_t role)
   1789   1.96      fvdl {
   1790   1.96      fvdl 	u_int maxoffset;
   1791   1.96      fvdl 
   1792   1.96      fvdl 	/* Limit offset to what we can do */
   1793   1.96      fvdl 	if (syncrate == NULL) {
   1794   1.96      fvdl 		maxoffset = 0;
   1795   1.96      fvdl 	} else if ((ahc->features & AHC_ULTRA2) != 0) {
   1796   1.96      fvdl 		maxoffset = MAX_OFFSET_ULTRA2;
   1797   1.96      fvdl 	} else {
   1798   1.96      fvdl 		if (wide)
   1799   1.96      fvdl 			maxoffset = MAX_OFFSET_16BIT;
   1800   1.96      fvdl 		else
   1801   1.96      fvdl 			maxoffset = MAX_OFFSET_8BIT;
   1802   1.96      fvdl 	}
   1803   1.96      fvdl 	*offset = MIN(*offset, maxoffset);
   1804   1.96      fvdl 	if (tinfo != NULL) {
   1805   1.96      fvdl 		if (role == ROLE_TARGET)
   1806   1.96      fvdl 			*offset = MIN(*offset, tinfo->user.offset);
   1807   1.96      fvdl 		else
   1808   1.96      fvdl 			*offset = MIN(*offset, tinfo->goal.offset);
   1809   1.96      fvdl 	}
   1810   1.96      fvdl }
   1811   1.96      fvdl 
   1812   1.96      fvdl /*
   1813   1.96      fvdl  * Truncate the given transfer width parameter to a value the
   1814   1.96      fvdl  * current adapter type is capable of.
   1815   1.96      fvdl  */
   1816   1.96      fvdl void
   1817   1.96      fvdl ahc_validate_width(struct ahc_softc *ahc, struct ahc_initiator_tinfo *tinfo,
   1818   1.96      fvdl 		   u_int *bus_width, role_t role)
   1819   1.96      fvdl {
   1820   1.96      fvdl 	switch (*bus_width) {
   1821   1.96      fvdl 	default:
   1822   1.96      fvdl 		if (ahc->features & AHC_WIDE) {
   1823   1.96      fvdl 			/* Respond Wide */
   1824   1.96      fvdl 			*bus_width = MSG_EXT_WDTR_BUS_16_BIT;
   1825   1.96      fvdl 			break;
   1826   1.96      fvdl 		}
   1827   1.96      fvdl 		/* FALLTHROUGH */
   1828   1.96      fvdl 	case MSG_EXT_WDTR_BUS_8_BIT:
   1829   1.96      fvdl 		*bus_width = MSG_EXT_WDTR_BUS_8_BIT;
   1830   1.96      fvdl 		break;
   1831   1.96      fvdl 	}
   1832   1.96      fvdl 	if (tinfo != NULL) {
   1833   1.96      fvdl 		if (role == ROLE_TARGET)
   1834   1.96      fvdl 			*bus_width = MIN(tinfo->user.width, *bus_width);
   1835   1.96      fvdl 		else
   1836   1.96      fvdl 			*bus_width = MIN(tinfo->goal.width, *bus_width);
   1837   1.96      fvdl 	}
   1838   1.96      fvdl }
   1839   1.96      fvdl 
   1840   1.96      fvdl /*
   1841   1.96      fvdl  * Update the bitmask of targets for which the controller should
   1842  1.108       wiz  * negotiate with at the next convenient opportunity.  This currently
   1843   1.96      fvdl  * means the next time we send the initial identify messages for
   1844   1.96      fvdl  * a new transaction.
   1845   1.96      fvdl  */
   1846   1.96      fvdl int
   1847   1.96      fvdl ahc_update_neg_request(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
   1848   1.96      fvdl 		       struct ahc_tmode_tstate *tstate,
   1849   1.96      fvdl 		       struct ahc_initiator_tinfo *tinfo, ahc_neg_type neg_type)
   1850   1.96      fvdl {
   1851   1.96      fvdl 	u_int auto_negotiate_orig;
   1852   1.96      fvdl 
   1853   1.96      fvdl 	auto_negotiate_orig = tstate->auto_negotiate;
   1854   1.96      fvdl 	if (neg_type == AHC_NEG_ALWAYS) {
   1855   1.96      fvdl 		/*
   1856   1.96      fvdl 		 * Force our "current" settings to be
   1857   1.96      fvdl 		 * unknown so that unless a bus reset
   1858   1.96      fvdl 		 * occurs the need to renegotiate is
   1859   1.96      fvdl 		 * recorded persistently.
   1860   1.96      fvdl 		 */
   1861   1.96      fvdl 		if ((ahc->features & AHC_WIDE) != 0)
   1862   1.96      fvdl 			tinfo->curr.width = AHC_WIDTH_UNKNOWN;
   1863   1.96      fvdl 		tinfo->curr.period = AHC_PERIOD_UNKNOWN;
   1864   1.96      fvdl 		tinfo->curr.offset = AHC_OFFSET_UNKNOWN;
   1865   1.96      fvdl 	}
   1866   1.96      fvdl 	if (tinfo->curr.period != tinfo->goal.period
   1867   1.96      fvdl 	 || tinfo->curr.width != tinfo->goal.width
   1868   1.96      fvdl 	 || tinfo->curr.offset != tinfo->goal.offset
   1869   1.96      fvdl 	 || tinfo->curr.ppr_options != tinfo->goal.ppr_options
   1870   1.96      fvdl 	 || (neg_type == AHC_NEG_IF_NON_ASYNC
   1871   1.96      fvdl 	  && (tinfo->goal.offset != 0
   1872   1.96      fvdl 	   || tinfo->goal.width != MSG_EXT_WDTR_BUS_8_BIT
   1873   1.96      fvdl 	   || tinfo->goal.ppr_options != 0)))
   1874   1.96      fvdl 		tstate->auto_negotiate |= devinfo->target_mask;
   1875   1.96      fvdl 	else
   1876   1.96      fvdl 		tstate->auto_negotiate &= ~devinfo->target_mask;
   1877   1.96      fvdl 
   1878   1.96      fvdl 	return (auto_negotiate_orig != tstate->auto_negotiate);
   1879   1.96      fvdl }
   1880   1.96      fvdl 
   1881   1.96      fvdl /*
   1882   1.96      fvdl  * Update the user/goal/curr tables of synchronous negotiation
   1883   1.96      fvdl  * parameters as well as, in the case of a current or active update,
   1884   1.96      fvdl  * any data structures on the host controller.  In the case of an
   1885   1.96      fvdl  * active update, the specified target is currently talking to us on
   1886   1.96      fvdl  * the bus, so the transfer parameter update must take effect
   1887   1.96      fvdl  * immediately.
   1888   1.96      fvdl  */
   1889   1.96      fvdl void
   1890   1.96      fvdl ahc_set_syncrate(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
   1891  1.122  christos     struct ahc_syncrate *syncrate, u_int period,
   1892  1.123  christos     u_int offset, u_int ppr_options, u_int type, int paused)
   1893   1.96      fvdl {
   1894   1.96      fvdl 	struct	ahc_initiator_tinfo *tinfo;
   1895   1.96      fvdl 	struct	ahc_tmode_tstate *tstate;
   1896   1.96      fvdl 	u_int	old_period;
   1897   1.96      fvdl 	u_int	old_offset;
   1898   1.96      fvdl 	u_int	old_ppr;
   1899   1.96      fvdl 	int	active;
   1900   1.96      fvdl 	int	update_needed;
   1901   1.96      fvdl 
   1902   1.96      fvdl 	active = (type & AHC_TRANS_ACTIVE) == AHC_TRANS_ACTIVE;
   1903   1.96      fvdl 	update_needed = 0;
   1904   1.96      fvdl 
   1905   1.96      fvdl 	if (syncrate == NULL) {
   1906   1.96      fvdl 		period = 0;
   1907   1.96      fvdl 		offset = 0;
   1908   1.96      fvdl 	}
   1909   1.96      fvdl 
   1910   1.96      fvdl 	tinfo = ahc_fetch_transinfo(ahc, devinfo->channel, devinfo->our_scsiid,
   1911   1.96      fvdl 				    devinfo->target, &tstate);
   1912   1.96      fvdl 
   1913   1.96      fvdl 	if ((type & AHC_TRANS_USER) != 0) {
   1914   1.96      fvdl 		tinfo->user.period = period;
   1915   1.96      fvdl 		tinfo->user.offset = offset;
   1916   1.96      fvdl 		tinfo->user.ppr_options = ppr_options;
   1917   1.96      fvdl 	}
   1918   1.96      fvdl 
   1919   1.96      fvdl 	if ((type & AHC_TRANS_GOAL) != 0) {
   1920   1.96      fvdl 		tinfo->goal.period = period;
   1921   1.96      fvdl 		tinfo->goal.offset = offset;
   1922   1.96      fvdl 		tinfo->goal.ppr_options = ppr_options;
   1923   1.96      fvdl 	}
   1924   1.96      fvdl 
   1925   1.96      fvdl 	old_period = tinfo->curr.period;
   1926   1.96      fvdl 	old_offset = tinfo->curr.offset;
   1927   1.96      fvdl 	old_ppr	   = tinfo->curr.ppr_options;
   1928   1.96      fvdl 
   1929   1.96      fvdl 	if ((type & AHC_TRANS_CUR) != 0
   1930   1.96      fvdl 	 && (old_period != period
   1931   1.96      fvdl 	  || old_offset != offset
   1932   1.96      fvdl 	  || old_ppr != ppr_options)) {
   1933   1.96      fvdl 		u_int	scsirate;
   1934   1.96      fvdl 
   1935   1.96      fvdl 		update_needed++;
   1936   1.96      fvdl 		scsirate = tinfo->scsirate;
   1937   1.96      fvdl 		if ((ahc->features & AHC_ULTRA2) != 0) {
   1938   1.96      fvdl 
   1939   1.96      fvdl 			scsirate &= ~(SXFR_ULTRA2|SINGLE_EDGE|ENABLE_CRC);
   1940   1.96      fvdl 			if (syncrate != NULL) {
   1941   1.96      fvdl 				scsirate |= syncrate->sxfr_u2;
   1942   1.96      fvdl 				if ((ppr_options & MSG_EXT_PPR_DT_REQ) != 0)
   1943   1.96      fvdl 					scsirate |= ENABLE_CRC;
   1944   1.96      fvdl 				else
   1945   1.96      fvdl 					scsirate |= SINGLE_EDGE;
   1946   1.96      fvdl 			}
   1947   1.96      fvdl 		} else {
   1948   1.96      fvdl 
   1949   1.96      fvdl 			scsirate &= ~(SXFR|SOFS);
   1950   1.96      fvdl 			/*
   1951   1.96      fvdl 			 * Ensure Ultra mode is set properly for
   1952   1.96      fvdl 			 * this target.
   1953   1.96      fvdl 			 */
   1954   1.96      fvdl 			tstate->ultraenb &= ~devinfo->target_mask;
   1955   1.96      fvdl 			if (syncrate != NULL) {
   1956   1.96      fvdl 				if (syncrate->sxfr & ULTRA_SXFR) {
   1957   1.96      fvdl 					tstate->ultraenb |=
   1958   1.96      fvdl 						devinfo->target_mask;
   1959   1.96      fvdl 				}
   1960   1.96      fvdl 				scsirate |= syncrate->sxfr & SXFR;
   1961   1.96      fvdl 				scsirate |= offset & SOFS;
   1962   1.96      fvdl 			}
   1963   1.96      fvdl 			if (active) {
   1964   1.96      fvdl 				u_int sxfrctl0;
   1965   1.96      fvdl 
   1966   1.96      fvdl 				sxfrctl0 = ahc_inb(ahc, SXFRCTL0);
   1967   1.96      fvdl 				sxfrctl0 &= ~FAST20;
   1968   1.96      fvdl 				if (tstate->ultraenb & devinfo->target_mask)
   1969   1.96      fvdl 					sxfrctl0 |= FAST20;
   1970   1.96      fvdl 				ahc_outb(ahc, SXFRCTL0, sxfrctl0);
   1971   1.96      fvdl 			}
   1972   1.96      fvdl 		}
   1973   1.96      fvdl 		if (active) {
   1974   1.96      fvdl 			ahc_outb(ahc, SCSIRATE, scsirate);
   1975   1.96      fvdl 			if ((ahc->features & AHC_ULTRA2) != 0)
   1976   1.96      fvdl 				ahc_outb(ahc, SCSIOFFSET, offset);
   1977   1.96      fvdl 		}
   1978   1.96      fvdl 
   1979   1.96      fvdl 		tinfo->scsirate = scsirate;
   1980   1.96      fvdl 		tinfo->curr.period = period;
   1981   1.96      fvdl 		tinfo->curr.offset = offset;
   1982   1.96      fvdl 		tinfo->curr.ppr_options = ppr_options;
   1983   1.96      fvdl 
   1984   1.96      fvdl 		ahc_send_async(ahc, devinfo->channel, devinfo->target,
   1985   1.96      fvdl 		  CAM_LUN_WILDCARD, AC_TRANSFER_NEG, NULL);
   1986   1.96      fvdl 		if (bootverbose) {
   1987   1.96      fvdl 			if (offset != 0) {
   1988   1.96      fvdl 				printf("%s: target %d synchronous at %sMHz%s, "
   1989   1.96      fvdl 				       "offset = 0x%x\n", ahc_name(ahc),
   1990   1.96      fvdl 				       devinfo->target, syncrate->rate,
   1991   1.96      fvdl 				       (ppr_options & MSG_EXT_PPR_DT_REQ)
   1992   1.96      fvdl 				       ? " DT" : "", offset);
   1993   1.96      fvdl 			} else {
   1994   1.96      fvdl 				printf("%s: target %d using "
   1995   1.96      fvdl 				       "asynchronous transfers\n",
   1996   1.96      fvdl 				       ahc_name(ahc), devinfo->target);
   1997   1.96      fvdl 			}
   1998   1.96      fvdl 		}
   1999   1.96      fvdl 	}
   2000   1.96      fvdl 
   2001   1.96      fvdl 	update_needed += ahc_update_neg_request(ahc, devinfo, tstate,
   2002   1.96      fvdl 						tinfo, AHC_NEG_TO_GOAL);
   2003   1.96      fvdl 
   2004   1.96      fvdl 	if (update_needed)
   2005   1.96      fvdl 		ahc_update_pending_scbs(ahc);
   2006   1.96      fvdl }
   2007   1.96      fvdl 
   2008   1.96      fvdl /*
   2009   1.96      fvdl  * Update the user/goal/curr tables of wide negotiation
   2010   1.96      fvdl  * parameters as well as, in the case of a current or active update,
   2011   1.96      fvdl  * any data structures on the host controller.  In the case of an
   2012   1.96      fvdl  * active update, the specified target is currently talking to us on
   2013   1.96      fvdl  * the bus, so the transfer parameter update must take effect
   2014   1.96      fvdl  * immediately.
   2015   1.96      fvdl  */
   2016   1.96      fvdl void
   2017   1.96      fvdl ahc_set_width(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
   2018  1.123  christos     u_int width, u_int type, int paused)
   2019   1.96      fvdl {
   2020   1.96      fvdl 	struct	ahc_initiator_tinfo *tinfo;
   2021   1.96      fvdl 	struct	ahc_tmode_tstate *tstate;
   2022   1.96      fvdl 	u_int	oldwidth;
   2023   1.96      fvdl 	int	active;
   2024   1.96      fvdl 	int	update_needed;
   2025   1.96      fvdl 
   2026   1.96      fvdl 	active = (type & AHC_TRANS_ACTIVE) == AHC_TRANS_ACTIVE;
   2027   1.96      fvdl 	update_needed = 0;
   2028   1.96      fvdl 	tinfo = ahc_fetch_transinfo(ahc, devinfo->channel, devinfo->our_scsiid,
   2029   1.96      fvdl 				    devinfo->target, &tstate);
   2030   1.96      fvdl 
   2031   1.96      fvdl 	if ((type & AHC_TRANS_USER) != 0)
   2032   1.96      fvdl 		tinfo->user.width = width;
   2033   1.96      fvdl 
   2034   1.96      fvdl 	if ((type & AHC_TRANS_GOAL) != 0)
   2035   1.96      fvdl 		tinfo->goal.width = width;
   2036   1.96      fvdl 
   2037   1.96      fvdl 	oldwidth = tinfo->curr.width;
   2038   1.96      fvdl 	if ((type & AHC_TRANS_CUR) != 0 && oldwidth != width) {
   2039   1.96      fvdl 		u_int	scsirate;
   2040   1.96      fvdl 
   2041   1.96      fvdl 		update_needed++;
   2042   1.96      fvdl 		scsirate =  tinfo->scsirate;
   2043   1.96      fvdl 		scsirate &= ~WIDEXFER;
   2044   1.96      fvdl 		if (width == MSG_EXT_WDTR_BUS_16_BIT)
   2045   1.96      fvdl 			scsirate |= WIDEXFER;
   2046   1.96      fvdl 
   2047   1.96      fvdl 		tinfo->scsirate = scsirate;
   2048   1.96      fvdl 
   2049   1.96      fvdl 		if (active)
   2050   1.96      fvdl 			ahc_outb(ahc, SCSIRATE, scsirate);
   2051   1.96      fvdl 
   2052   1.96      fvdl 		tinfo->curr.width = width;
   2053   1.96      fvdl 
   2054   1.96      fvdl 		ahc_send_async(ahc, devinfo->channel, devinfo->target,
   2055   1.96      fvdl 			       CAM_LUN_WILDCARD, AC_TRANSFER_NEG, NULL);
   2056   1.96      fvdl 		if (bootverbose) {
   2057   1.96      fvdl 			printf("%s: target %d using %dbit transfers\n",
   2058   1.96      fvdl 			       ahc_name(ahc), devinfo->target,
   2059   1.96      fvdl 			       8 * (0x01 << width));
   2060   1.96      fvdl 		}
   2061   1.96      fvdl 	}
   2062   1.96      fvdl 
   2063   1.96      fvdl 	update_needed += ahc_update_neg_request(ahc, devinfo, tstate,
   2064   1.96      fvdl 						tinfo, AHC_NEG_TO_GOAL);
   2065   1.96      fvdl 	if (update_needed)
   2066   1.96      fvdl 		ahc_update_pending_scbs(ahc);
   2067   1.96      fvdl }
   2068   1.96      fvdl 
   2069   1.96      fvdl /*
   2070   1.96      fvdl  * Update the current state of tagged queuing for a given target.
   2071   1.96      fvdl  */
   2072   1.96      fvdl void
   2073   1.96      fvdl ahc_set_tags(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
   2074   1.96      fvdl 	     ahc_queue_alg alg)
   2075   1.96      fvdl {
   2076   1.96      fvdl  	ahc_platform_set_tags(ahc, devinfo, alg);
   2077   1.96      fvdl }
   2078   1.96      fvdl 
   2079   1.96      fvdl /*
   2080   1.96      fvdl  * When the transfer settings for a connection change, update any
   2081   1.96      fvdl  * in-transit SCBs to contain the new data so the hardware will
   2082   1.96      fvdl  * be set correctly during future (re)selections.
   2083   1.96      fvdl  */
   2084   1.96      fvdl static void
   2085   1.96      fvdl ahc_update_pending_scbs(struct ahc_softc *ahc)
   2086   1.96      fvdl {
   2087   1.96      fvdl 	struct	scb *pending_scb;
   2088   1.96      fvdl 	int	pending_scb_count;
   2089   1.96      fvdl 	int	i;
   2090   1.96      fvdl 	int	paused;
   2091   1.96      fvdl 	u_int	saved_scbptr;
   2092   1.96      fvdl 
   2093   1.96      fvdl 	/*
   2094   1.96      fvdl 	 * Traverse the pending SCB list and ensure that all of the
   2095   1.96      fvdl 	 * SCBs there have the proper settings.
   2096   1.96      fvdl 	 */
   2097   1.96      fvdl 	pending_scb_count = 0;
   2098   1.96      fvdl 	LIST_FOREACH(pending_scb, &ahc->pending_scbs, pending_links) {
   2099   1.96      fvdl 		struct ahc_devinfo devinfo;
   2100   1.96      fvdl 		struct hardware_scb *pending_hscb;
   2101   1.96      fvdl 		struct ahc_initiator_tinfo *tinfo;
   2102   1.96      fvdl 		struct ahc_tmode_tstate *tstate;
   2103   1.96      fvdl 
   2104   1.96      fvdl 		ahc_scb_devinfo(ahc, &devinfo, pending_scb);
   2105   1.96      fvdl 		tinfo = ahc_fetch_transinfo(ahc, devinfo.channel,
   2106   1.96      fvdl 					    devinfo.our_scsiid,
   2107   1.96      fvdl 					    devinfo.target, &tstate);
   2108   1.96      fvdl 		pending_hscb = pending_scb->hscb;
   2109   1.96      fvdl 		pending_hscb->control &= ~ULTRAENB;
   2110   1.96      fvdl 		if ((tstate->ultraenb & devinfo.target_mask) != 0)
   2111   1.96      fvdl 			pending_hscb->control |= ULTRAENB;
   2112   1.96      fvdl 		pending_hscb->scsirate = tinfo->scsirate;
   2113   1.96      fvdl 		pending_hscb->scsioffset = tinfo->curr.offset;
   2114   1.96      fvdl 		if ((tstate->auto_negotiate & devinfo.target_mask) == 0
   2115   1.96      fvdl 		 && (pending_scb->flags & SCB_AUTO_NEGOTIATE) != 0) {
   2116   1.96      fvdl 			pending_scb->flags &= ~SCB_AUTO_NEGOTIATE;
   2117   1.96      fvdl 			pending_hscb->control &= ~MK_MESSAGE;
   2118   1.96      fvdl 		}
   2119   1.96      fvdl 		ahc_sync_scb(ahc, pending_scb,
   2120   1.96      fvdl 			     BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
   2121   1.96      fvdl 		pending_scb_count++;
   2122   1.96      fvdl 	}
   2123   1.96      fvdl 
   2124   1.96      fvdl 	if (pending_scb_count == 0)
   2125   1.96      fvdl 		return;
   2126   1.96      fvdl 
   2127   1.96      fvdl 	if (ahc_is_paused(ahc)) {
   2128   1.96      fvdl 		paused = 1;
   2129   1.96      fvdl 	} else {
   2130   1.96      fvdl 		paused = 0;
   2131   1.96      fvdl 		ahc_pause(ahc);
   2132   1.96      fvdl 	}
   2133   1.96      fvdl 
   2134   1.96      fvdl 	saved_scbptr = ahc_inb(ahc, SCBPTR);
   2135   1.96      fvdl 	/* Ensure that the hscbs down on the card match the new information */
   2136   1.96      fvdl 	for (i = 0; i < ahc->scb_data->maxhscbs; i++) {
   2137   1.96      fvdl 		struct	hardware_scb *pending_hscb;
   2138   1.96      fvdl 		u_int	control;
   2139   1.96      fvdl 		u_int	scb_tag;
   2140   1.96      fvdl 
   2141   1.96      fvdl 		ahc_outb(ahc, SCBPTR, i);
   2142   1.96      fvdl 		scb_tag = ahc_inb(ahc, SCB_TAG);
   2143   1.96      fvdl 		pending_scb = ahc_lookup_scb(ahc, scb_tag);
   2144   1.96      fvdl 		if (pending_scb == NULL)
   2145   1.96      fvdl 			continue;
   2146   1.96      fvdl 
   2147   1.96      fvdl 		pending_hscb = pending_scb->hscb;
   2148   1.96      fvdl 		control = ahc_inb(ahc, SCB_CONTROL);
   2149   1.96      fvdl 		control &= ~(ULTRAENB|MK_MESSAGE);
   2150   1.96      fvdl 		control |= pending_hscb->control & (ULTRAENB|MK_MESSAGE);
   2151   1.96      fvdl 		ahc_outb(ahc, SCB_CONTROL, control);
   2152   1.96      fvdl 		ahc_outb(ahc, SCB_SCSIRATE, pending_hscb->scsirate);
   2153   1.96      fvdl 		ahc_outb(ahc, SCB_SCSIOFFSET, pending_hscb->scsioffset);
   2154   1.96      fvdl 	}
   2155   1.96      fvdl 	ahc_outb(ahc, SCBPTR, saved_scbptr);
   2156   1.96      fvdl 
   2157   1.96      fvdl 	if (paused == 0)
   2158   1.96      fvdl 		ahc_unpause(ahc);
   2159   1.96      fvdl }
   2160   1.96      fvdl 
   2161   1.96      fvdl /**************************** Pathing Information *****************************/
   2162   1.96      fvdl static void
   2163   1.96      fvdl ahc_fetch_devinfo(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
   2164   1.96      fvdl {
   2165   1.96      fvdl 	u_int	saved_scsiid;
   2166   1.96      fvdl 	role_t	role;
   2167   1.96      fvdl 	int	our_id;
   2168   1.96      fvdl 
   2169   1.96      fvdl 	if (ahc_inb(ahc, SSTAT0) & TARGET)
   2170   1.96      fvdl 		role = ROLE_TARGET;
   2171   1.96      fvdl 	else
   2172   1.96      fvdl 		role = ROLE_INITIATOR;
   2173   1.96      fvdl 
   2174   1.96      fvdl 	if (role == ROLE_TARGET
   2175   1.96      fvdl 	 && (ahc->features & AHC_MULTI_TID) != 0
   2176   1.96      fvdl 	 && (ahc_inb(ahc, SEQ_FLAGS)
   2177   1.96      fvdl  	   & (CMDPHASE_PENDING|TARG_CMD_PENDING|NO_DISCONNECT)) != 0) {
   2178   1.96      fvdl 		/* We were selected, so pull our id from TARGIDIN */
   2179   1.96      fvdl 		our_id = ahc_inb(ahc, TARGIDIN) & OID;
   2180   1.96      fvdl 	} else if ((ahc->features & AHC_ULTRA2) != 0)
   2181   1.96      fvdl 		our_id = ahc_inb(ahc, SCSIID_ULTRA2) & OID;
   2182   1.96      fvdl 	else
   2183   1.96      fvdl 		our_id = ahc_inb(ahc, SCSIID) & OID;
   2184   1.96      fvdl 
   2185   1.96      fvdl 	saved_scsiid = ahc_inb(ahc, SAVED_SCSIID);
   2186   1.96      fvdl 	ahc_compile_devinfo(devinfo,
   2187   1.96      fvdl 			    our_id,
   2188   1.96      fvdl 			    SCSIID_TARGET(ahc, saved_scsiid),
   2189   1.96      fvdl 			    ahc_inb(ahc, SAVED_LUN),
   2190   1.96      fvdl 			    SCSIID_CHANNEL(ahc, saved_scsiid),
   2191   1.96      fvdl 			    role);
   2192   1.96      fvdl }
   2193   1.96      fvdl 
   2194   1.96      fvdl struct ahc_phase_table_entry*
   2195   1.96      fvdl ahc_lookup_phase_entry(int phase)
   2196   1.96      fvdl {
   2197   1.96      fvdl 	struct ahc_phase_table_entry *entry;
   2198   1.96      fvdl 	struct ahc_phase_table_entry *last_entry;
   2199   1.96      fvdl 
   2200   1.96      fvdl 	/*
   2201   1.96      fvdl 	 * num_phases doesn't include the default entry which
   2202   1.96      fvdl 	 * will be returned if the phase doesn't match.
   2203   1.96      fvdl 	 */
   2204   1.96      fvdl 	last_entry = &ahc_phase_table[num_phases];
   2205   1.96      fvdl 	for (entry = ahc_phase_table; entry < last_entry; entry++) {
   2206   1.96      fvdl 		if (phase == entry->phase)
   2207   1.96      fvdl 			break;
   2208   1.96      fvdl 	}
   2209   1.96      fvdl 	return (entry);
   2210   1.96      fvdl }
   2211   1.96      fvdl 
   2212   1.96      fvdl void
   2213   1.96      fvdl ahc_compile_devinfo(struct ahc_devinfo *devinfo, u_int our_id, u_int target,
   2214   1.96      fvdl 		    u_int lun, char channel, role_t role)
   2215   1.96      fvdl {
   2216   1.96      fvdl 	devinfo->our_scsiid = our_id;
   2217   1.96      fvdl 	devinfo->target = target;
   2218   1.96      fvdl 	devinfo->lun = lun;
   2219   1.96      fvdl 	devinfo->target_offset = target;
   2220   1.96      fvdl 	devinfo->channel = channel;
   2221   1.96      fvdl 	devinfo->role = role;
   2222   1.96      fvdl 	if (channel == 'B')
   2223   1.96      fvdl 		devinfo->target_offset += 8;
   2224   1.96      fvdl 	devinfo->target_mask = (0x01 << devinfo->target_offset);
   2225   1.96      fvdl }
   2226   1.96      fvdl 
   2227   1.96      fvdl void
   2228   1.96      fvdl ahc_print_devinfo(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
   2229   1.96      fvdl {
   2230   1.96      fvdl 	printf("%s:%c:%d:%d: ", ahc_name(ahc), devinfo->channel,
   2231   1.96      fvdl 	       devinfo->target, devinfo->lun);
   2232   1.96      fvdl }
   2233   1.96      fvdl 
   2234   1.96      fvdl static void
   2235   1.96      fvdl ahc_scb_devinfo(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
   2236   1.96      fvdl 		struct scb *scb)
   2237   1.96      fvdl {
   2238   1.96      fvdl 	role_t	role;
   2239   1.96      fvdl 	int	our_id;
   2240   1.96      fvdl 
   2241   1.96      fvdl 	our_id = SCSIID_OUR_ID(scb->hscb->scsiid);
   2242   1.96      fvdl 	role = ROLE_INITIATOR;
   2243   1.96      fvdl 	if ((scb->flags & SCB_TARGET_SCB) != 0)
   2244   1.96      fvdl 		role = ROLE_TARGET;
   2245   1.96      fvdl 	ahc_compile_devinfo(devinfo, our_id, SCB_GET_TARGET(ahc, scb),
   2246   1.96      fvdl 			    SCB_GET_LUN(scb), SCB_GET_CHANNEL(ahc, scb), role);
   2247   1.96      fvdl }
   2248   1.96      fvdl 
   2249   1.96      fvdl 
   2250   1.96      fvdl /************************ Message Phase Processing ****************************/
   2251   1.96      fvdl static void
   2252   1.96      fvdl ahc_assert_atn(struct ahc_softc *ahc)
   2253   1.96      fvdl {
   2254   1.96      fvdl 	u_int scsisigo;
   2255   1.96      fvdl 
   2256   1.96      fvdl 	scsisigo = ATNO;
   2257   1.96      fvdl 	if ((ahc->features & AHC_DT) == 0)
   2258   1.96      fvdl 		scsisigo |= ahc_inb(ahc, SCSISIGI);
   2259   1.96      fvdl 	ahc_outb(ahc, SCSISIGO, scsisigo);
   2260   1.96      fvdl }
   2261   1.96      fvdl 
   2262   1.96      fvdl /*
   2263   1.96      fvdl  * When an initiator transaction with the MK_MESSAGE flag either reconnects
   2264   1.96      fvdl  * or enters the initial message out phase, we are interrupted.  Fill our
   2265  1.108       wiz  * outgoing message buffer with the appropriate message and begin handing
   2266   1.96      fvdl  * the message phase(s) manually.
   2267   1.96      fvdl  */
   2268   1.96      fvdl static void
   2269   1.96      fvdl ahc_setup_initiator_msgout(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
   2270   1.96      fvdl 			   struct scb *scb)
   2271   1.96      fvdl {
   2272   1.96      fvdl 	/*
   2273   1.96      fvdl 	 * To facilitate adding multiple messages together,
   2274   1.96      fvdl 	 * each routine should increment the index and len
   2275   1.96      fvdl 	 * variables instead of setting them explicitly.
   2276   1.96      fvdl 	 */
   2277   1.96      fvdl 	ahc->msgout_index = 0;
   2278   1.96      fvdl 	ahc->msgout_len = 0;
   2279   1.96      fvdl 
   2280   1.96      fvdl 	if ((scb->flags & SCB_DEVICE_RESET) == 0
   2281   1.96      fvdl 	 && ahc_inb(ahc, MSG_OUT) == MSG_IDENTIFYFLAG) {
   2282   1.96      fvdl 		u_int identify_msg;
   2283   1.96      fvdl 
   2284   1.96      fvdl 		identify_msg = MSG_IDENTIFYFLAG | SCB_GET_LUN(scb);
   2285   1.96      fvdl 		if ((scb->hscb->control & DISCENB) != 0)
   2286   1.96      fvdl 			identify_msg |= MSG_IDENTIFY_DISCFLAG;
   2287   1.96      fvdl 		ahc->msgout_buf[ahc->msgout_index++] = identify_msg;
   2288   1.96      fvdl 		ahc->msgout_len++;
   2289   1.96      fvdl 
   2290   1.96      fvdl 		if ((scb->hscb->control & TAG_ENB) != 0) {
   2291   1.96      fvdl 			ahc->msgout_buf[ahc->msgout_index++] =
   2292   1.96      fvdl 			    scb->hscb->control & (TAG_ENB|SCB_TAG_TYPE);
   2293   1.96      fvdl 			ahc->msgout_buf[ahc->msgout_index++] = scb->hscb->tag;
   2294   1.96      fvdl 			ahc->msgout_len += 2;
   2295   1.96      fvdl 		}
   2296   1.96      fvdl 	}
   2297   1.96      fvdl 
   2298   1.96      fvdl 	if (scb->flags & SCB_DEVICE_RESET) {
   2299   1.96      fvdl 		ahc->msgout_buf[ahc->msgout_index++] = MSG_BUS_DEV_RESET;
   2300   1.96      fvdl 		ahc->msgout_len++;
   2301   1.96      fvdl 		ahc_print_path(ahc, scb);
   2302   1.96      fvdl 		printf("Bus Device Reset Message Sent\n");
   2303   1.96      fvdl 		/*
   2304   1.96      fvdl 		 * Clear our selection hardware in advance of
   2305   1.96      fvdl 		 * the busfree.  We may have an entry in the waiting
   2306   1.96      fvdl 		 * Q for this target, and we don't want to go about
   2307   1.96      fvdl 		 * selecting while we handle the busfree and blow it
   2308   1.96      fvdl 		 * away.
   2309   1.96      fvdl 		 */
   2310   1.96      fvdl 		ahc_outb(ahc, SCSISEQ, (ahc_inb(ahc, SCSISEQ) & ~ENSELO));
   2311   1.96      fvdl 	} else if ((scb->flags & SCB_ABORT) != 0) {
   2312   1.96      fvdl 		if ((scb->hscb->control & TAG_ENB) != 0)
   2313   1.96      fvdl 			ahc->msgout_buf[ahc->msgout_index++] = MSG_ABORT_TAG;
   2314   1.96      fvdl 		else
   2315   1.96      fvdl 			ahc->msgout_buf[ahc->msgout_index++] = MSG_ABORT;
   2316   1.96      fvdl 		ahc->msgout_len++;
   2317   1.96      fvdl 		ahc_print_path(ahc, scb);
   2318   1.96      fvdl 		printf("Abort%s Message Sent\n",
   2319   1.96      fvdl 		       (scb->hscb->control & TAG_ENB) != 0 ? " Tag" : "");
   2320   1.96      fvdl 		/*
   2321   1.96      fvdl 		 * Clear our selection hardware in advance of
   2322   1.96      fvdl 		 * the busfree.  We may have an entry in the waiting
   2323   1.96      fvdl 		 * Q for this target, and we don't want to go about
   2324   1.96      fvdl 		 * selecting while we handle the busfree and blow it
   2325   1.96      fvdl 		 * away.
   2326   1.96      fvdl 		 */
   2327   1.96      fvdl 		ahc_outb(ahc, SCSISEQ, (ahc_inb(ahc, SCSISEQ) & ~ENSELO));
   2328   1.96      fvdl 	} else if ((scb->flags & (SCB_AUTO_NEGOTIATE|SCB_NEGOTIATE)) != 0) {
   2329   1.96      fvdl 		ahc_build_transfer_msg(ahc, devinfo);
   2330   1.96      fvdl 	} else {
   2331   1.96      fvdl 		printf("ahc_intr: AWAITING_MSG for an SCB that "
   2332   1.96      fvdl 		       "does not have a waiting message\n");
   2333   1.96      fvdl 		printf("SCSIID = %x, target_mask = %x\n", scb->hscb->scsiid,
   2334   1.96      fvdl 		       devinfo->target_mask);
   2335   1.96      fvdl 		panic("SCB = %d, SCB Control = %x, MSG_OUT = %x "
   2336   1.96      fvdl 		      "SCB flags = %x", scb->hscb->tag, scb->hscb->control,
   2337   1.96      fvdl 		      ahc_inb(ahc, MSG_OUT), scb->flags);
   2338   1.96      fvdl 	}
   2339   1.96      fvdl 
   2340   1.96      fvdl 	/*
   2341   1.96      fvdl 	 * Clear the MK_MESSAGE flag from the SCB so we aren't
   2342   1.96      fvdl 	 * asked to send this message again.
   2343   1.96      fvdl 	 */
   2344   1.96      fvdl 	ahc_outb(ahc, SCB_CONTROL, ahc_inb(ahc, SCB_CONTROL) & ~MK_MESSAGE);
   2345   1.96      fvdl 	scb->hscb->control &= ~MK_MESSAGE;
   2346   1.96      fvdl 	ahc->msgout_index = 0;
   2347   1.96      fvdl 	ahc->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
   2348   1.96      fvdl }
   2349   1.96      fvdl 
   2350   1.96      fvdl /*
   2351   1.96      fvdl  * Build an appropriate transfer negotiation message for the
   2352   1.96      fvdl  * currently active target.
   2353   1.96      fvdl  */
   2354   1.96      fvdl static void
   2355   1.96      fvdl ahc_build_transfer_msg(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
   2356   1.96      fvdl {
   2357   1.96      fvdl 	/*
   2358   1.96      fvdl 	 * We need to initiate transfer negotiations.
   2359   1.96      fvdl 	 * If our current and goal settings are identical,
   2360   1.96      fvdl 	 * we want to renegotiate due to a check condition.
   2361   1.96      fvdl 	 */
   2362   1.96      fvdl 	struct	ahc_initiator_tinfo *tinfo;
   2363   1.96      fvdl 	struct	ahc_tmode_tstate *tstate;
   2364   1.96      fvdl 	struct	ahc_syncrate *rate;
   2365   1.96      fvdl 	int	dowide;
   2366   1.96      fvdl 	int	dosync;
   2367   1.96      fvdl 	int	doppr;
   2368   1.96      fvdl 	u_int	period;
   2369   1.96      fvdl 	u_int	ppr_options;
   2370   1.96      fvdl 	u_int	offset;
   2371   1.96      fvdl 
   2372   1.96      fvdl 	tinfo = ahc_fetch_transinfo(ahc, devinfo->channel, devinfo->our_scsiid,
   2373   1.96      fvdl 				    devinfo->target, &tstate);
   2374   1.96      fvdl 	/*
   2375   1.96      fvdl 	 * Filter our period based on the current connection.
   2376   1.96      fvdl 	 * If we can't perform DT transfers on this segment (not in LVD
   2377   1.96      fvdl 	 * mode for instance), then our decision to issue a PPR message
   2378   1.96      fvdl 	 * may change.
   2379   1.96      fvdl 	 */
   2380   1.96      fvdl 	period = tinfo->goal.period;
   2381   1.96      fvdl 	ppr_options = tinfo->goal.ppr_options;
   2382   1.96      fvdl 	/* Target initiated PPR is not allowed in the SCSI spec */
   2383   1.96      fvdl 	if (devinfo->role == ROLE_TARGET)
   2384   1.96      fvdl 		ppr_options = 0;
   2385   1.96      fvdl 	rate = ahc_devlimited_syncrate(ahc, tinfo, &period,
   2386   1.96      fvdl 				       &ppr_options, devinfo->role);
   2387   1.96      fvdl 	dowide = tinfo->curr.width != tinfo->goal.width;
   2388   1.96      fvdl 	dosync = tinfo->curr.period != period;
   2389   1.96      fvdl 	/*
   2390   1.96      fvdl 	 * Only use PPR if we have options that need it, even if the device
   2391   1.96      fvdl 	 * claims to support it.  There might be an expander in the way
   2392   1.96      fvdl 	 * that doesn't.
   2393   1.96      fvdl 	 */
   2394   1.96      fvdl 	doppr = ppr_options != 0;
   2395   1.96      fvdl 
   2396   1.96      fvdl 	if (!dowide && !dosync && !doppr) {
   2397   1.96      fvdl 		dowide = tinfo->goal.width != MSG_EXT_WDTR_BUS_8_BIT;
   2398   1.96      fvdl 		dosync = tinfo->goal.offset != 0;
   2399   1.96      fvdl 	}
   2400   1.96      fvdl 
   2401   1.96      fvdl 	if (!dowide && !dosync && !doppr) {
   2402   1.96      fvdl 		/*
   2403   1.96      fvdl 		 * Force async with a WDTR message if we have a wide bus,
   2404   1.96      fvdl 		 * or just issue an SDTR with a 0 offset.
   2405   1.96      fvdl 		 */
   2406   1.96      fvdl 		if ((ahc->features & AHC_WIDE) != 0)
   2407   1.96      fvdl 			dowide = 1;
   2408   1.96      fvdl 		else
   2409   1.96      fvdl 			dosync = 1;
   2410   1.96      fvdl 
   2411   1.96      fvdl 		if (bootverbose) {
   2412   1.96      fvdl 			ahc_print_devinfo(ahc, devinfo);
   2413   1.96      fvdl 			printf("Ensuring async\n");
   2414   1.96      fvdl 		}
   2415   1.96      fvdl 	}
   2416   1.96      fvdl 
   2417   1.96      fvdl 	/* Target initiated PPR is not allowed in the SCSI spec */
   2418   1.96      fvdl 	if (devinfo->role == ROLE_TARGET)
   2419   1.96      fvdl 		doppr = 0;
   2420   1.96      fvdl 
   2421   1.96      fvdl 	/*
   2422   1.96      fvdl 	 * Both the PPR message and SDTR message require the
   2423   1.96      fvdl 	 * goal syncrate to be limited to what the target device
   2424   1.96      fvdl 	 * is capable of handling (based on whether an LVD->SE
   2425   1.96      fvdl 	 * expander is on the bus), so combine these two cases.
   2426   1.96      fvdl 	 * Regardless, guarantee that if we are using WDTR and SDTR
   2427   1.96      fvdl 	 * messages that WDTR comes first.
   2428   1.96      fvdl 	 */
   2429   1.96      fvdl 	if (doppr || (dosync && !dowide)) {
   2430   1.96      fvdl 
   2431   1.96      fvdl 		offset = tinfo->goal.offset;
   2432   1.96      fvdl 		ahc_validate_offset(ahc, tinfo, rate, &offset,
   2433   1.96      fvdl 				    doppr ? tinfo->goal.width
   2434   1.96      fvdl 					  : tinfo->curr.width,
   2435   1.96      fvdl 				    devinfo->role);
   2436   1.96      fvdl 		if (doppr) {
   2437   1.96      fvdl 			ahc_construct_ppr(ahc, devinfo, period, offset,
   2438   1.96      fvdl 					  tinfo->goal.width, ppr_options);
   2439   1.96      fvdl 		} else {
   2440   1.96      fvdl 			ahc_construct_sdtr(ahc, devinfo, period, offset);
   2441   1.96      fvdl 		}
   2442   1.96      fvdl 	} else {
   2443   1.96      fvdl 		ahc_construct_wdtr(ahc, devinfo, tinfo->goal.width);
   2444   1.96      fvdl 	}
   2445   1.96      fvdl }
   2446   1.96      fvdl 
   2447   1.96      fvdl /*
   2448   1.96      fvdl  * Build a synchronous negotiation message in our message
   2449   1.96      fvdl  * buffer based on the input parameters.
   2450   1.96      fvdl  */
   2451   1.96      fvdl static void
   2452   1.96      fvdl ahc_construct_sdtr(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
   2453   1.96      fvdl 		   u_int period, u_int offset)
   2454   1.96      fvdl {
   2455   1.96      fvdl 	if (offset == 0)
   2456   1.96      fvdl 		period = AHC_ASYNC_XFER_PERIOD;
   2457   1.96      fvdl 	ahc->msgout_buf[ahc->msgout_index++] = MSG_EXTENDED;
   2458   1.96      fvdl 	ahc->msgout_buf[ahc->msgout_index++] = MSG_EXT_SDTR_LEN;
   2459   1.96      fvdl 	ahc->msgout_buf[ahc->msgout_index++] = MSG_EXT_SDTR;
   2460   1.96      fvdl 	ahc->msgout_buf[ahc->msgout_index++] = period;
   2461   1.96      fvdl 	ahc->msgout_buf[ahc->msgout_index++] = offset;
   2462   1.96      fvdl 	ahc->msgout_len += 5;
   2463   1.96      fvdl 	if (bootverbose) {
   2464   1.96      fvdl 		printf("(%s:%c:%d:%d): Sending SDTR period %x, offset %x\n",
   2465   1.96      fvdl 		       ahc_name(ahc), devinfo->channel, devinfo->target,
   2466   1.96      fvdl 		       devinfo->lun, period, offset);
   2467   1.96      fvdl 	}
   2468   1.96      fvdl }
   2469   1.96      fvdl 
   2470   1.96      fvdl /*
   2471   1.96      fvdl  * Build a wide negotiation message in our message
   2472   1.96      fvdl  * buffer based on the input parameters.
   2473   1.96      fvdl  */
   2474   1.96      fvdl static void
   2475   1.96      fvdl ahc_construct_wdtr(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
   2476   1.96      fvdl 		   u_int bus_width)
   2477   1.96      fvdl {
   2478   1.96      fvdl 	ahc->msgout_buf[ahc->msgout_index++] = MSG_EXTENDED;
   2479   1.96      fvdl 	ahc->msgout_buf[ahc->msgout_index++] = MSG_EXT_WDTR_LEN;
   2480   1.96      fvdl 	ahc->msgout_buf[ahc->msgout_index++] = MSG_EXT_WDTR;
   2481   1.96      fvdl 	ahc->msgout_buf[ahc->msgout_index++] = bus_width;
   2482   1.96      fvdl 	ahc->msgout_len += 4;
   2483   1.96      fvdl 	if (bootverbose) {
   2484   1.96      fvdl 		printf("(%s:%c:%d:%d): Sending WDTR %x\n",
   2485   1.96      fvdl 		       ahc_name(ahc), devinfo->channel, devinfo->target,
   2486   1.96      fvdl 		       devinfo->lun, bus_width);
   2487   1.96      fvdl 	}
   2488   1.96      fvdl }
   2489   1.96      fvdl 
   2490   1.96      fvdl /*
   2491   1.96      fvdl  * Build a parallel protocol request message in our message
   2492   1.96      fvdl  * buffer based on the input parameters.
   2493   1.96      fvdl  */
   2494   1.96      fvdl static void
   2495   1.96      fvdl ahc_construct_ppr(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
   2496   1.96      fvdl 		  u_int period, u_int offset, u_int bus_width,
   2497   1.96      fvdl 		  u_int ppr_options)
   2498   1.96      fvdl {
   2499   1.96      fvdl 	if (offset == 0)
   2500   1.96      fvdl 		period = AHC_ASYNC_XFER_PERIOD;
   2501   1.96      fvdl 	ahc->msgout_buf[ahc->msgout_index++] = MSG_EXTENDED;
   2502   1.96      fvdl 	ahc->msgout_buf[ahc->msgout_index++] = MSG_EXT_PPR_LEN;
   2503   1.96      fvdl 	ahc->msgout_buf[ahc->msgout_index++] = MSG_EXT_PPR;
   2504   1.96      fvdl 	ahc->msgout_buf[ahc->msgout_index++] = period;
   2505   1.96      fvdl 	ahc->msgout_buf[ahc->msgout_index++] = 0;
   2506   1.96      fvdl 	ahc->msgout_buf[ahc->msgout_index++] = offset;
   2507   1.96      fvdl 	ahc->msgout_buf[ahc->msgout_index++] = bus_width;
   2508   1.96      fvdl 	ahc->msgout_buf[ahc->msgout_index++] = ppr_options;
   2509   1.96      fvdl 	ahc->msgout_len += 8;
   2510   1.96      fvdl 	if (bootverbose) {
   2511   1.96      fvdl 		printf("(%s:%c:%d:%d): Sending PPR bus_width %x, period %x, "
   2512   1.96      fvdl 		       "offset %x, ppr_options %x\n", ahc_name(ahc),
   2513   1.96      fvdl 		       devinfo->channel, devinfo->target, devinfo->lun,
   2514   1.96      fvdl 		       bus_width, period, offset, ppr_options);
   2515   1.96      fvdl 	}
   2516   1.96      fvdl }
   2517   1.96      fvdl 
   2518   1.96      fvdl /*
   2519   1.96      fvdl  * Clear any active message state.
   2520   1.96      fvdl  */
   2521   1.96      fvdl static void
   2522   1.96      fvdl ahc_clear_msg_state(struct ahc_softc *ahc)
   2523   1.96      fvdl {
   2524   1.96      fvdl 	ahc->msgout_len = 0;
   2525   1.96      fvdl 	ahc->msgin_index = 0;
   2526   1.96      fvdl 	ahc->msg_type = MSG_TYPE_NONE;
   2527   1.96      fvdl 	if ((ahc_inb(ahc, SCSISIGI) & ATNI) != 0) {
   2528   1.96      fvdl 		/*
   2529   1.96      fvdl 		 * The target didn't care to respond to our
   2530   1.96      fvdl 		 * message request, so clear ATN.
   2531   1.96      fvdl 		 */
   2532   1.96      fvdl 		ahc_outb(ahc, CLRSINT1, CLRATNO);
   2533   1.96      fvdl 	}
   2534   1.96      fvdl 	ahc_outb(ahc, MSG_OUT, MSG_NOOP);
   2535   1.96      fvdl 	ahc_outb(ahc, SEQ_FLAGS2,
   2536   1.96      fvdl 		 ahc_inb(ahc, SEQ_FLAGS2) & ~TARGET_MSG_PENDING);
   2537   1.96      fvdl }
   2538   1.96      fvdl 
   2539   1.96      fvdl static void
   2540   1.96      fvdl ahc_handle_proto_violation(struct ahc_softc *ahc)
   2541   1.96      fvdl {
   2542   1.96      fvdl 	struct	ahc_devinfo devinfo;
   2543   1.96      fvdl 	struct	scb *scb;
   2544   1.96      fvdl 	u_int	scbid;
   2545   1.96      fvdl 	u_int	seq_flags;
   2546   1.96      fvdl 	u_int	curphase;
   2547   1.96      fvdl 	u_int	lastphase;
   2548   1.96      fvdl 	int	found;
   2549   1.96      fvdl 
   2550   1.96      fvdl 	ahc_fetch_devinfo(ahc, &devinfo);
   2551   1.96      fvdl 	scbid = ahc_inb(ahc, SCB_TAG);
   2552   1.96      fvdl 	scb = ahc_lookup_scb(ahc, scbid);
   2553   1.96      fvdl 	seq_flags = ahc_inb(ahc, SEQ_FLAGS);
   2554   1.96      fvdl 	curphase = ahc_inb(ahc, SCSISIGI) & PHASE_MASK;
   2555   1.96      fvdl 	lastphase = ahc_inb(ahc, LASTPHASE);
   2556   1.96      fvdl 	if ((seq_flags & NOT_IDENTIFIED) != 0) {
   2557   1.96      fvdl 
   2558   1.96      fvdl 		/*
   2559   1.96      fvdl 		 * The reconnecting target either did not send an
   2560   1.96      fvdl 		 * identify message, or did, but we didn't find an SCB
   2561   1.96      fvdl 		 * to match.
   2562   1.96      fvdl 		 */
   2563   1.96      fvdl 		ahc_print_devinfo(ahc, &devinfo);
   2564   1.96      fvdl 		printf("Target did not send an IDENTIFY message. "
   2565   1.96      fvdl 		       "LASTPHASE = 0x%x.\n", lastphase);
   2566   1.96      fvdl 		scb = NULL;
   2567   1.96      fvdl 	} else if (scb == NULL) {
   2568   1.96      fvdl 		/*
   2569   1.96      fvdl 		 * We don't seem to have an SCB active for this
   2570   1.96      fvdl 		 * transaction.  Print an error and reset the bus.
   2571   1.96      fvdl 		 */
   2572   1.96      fvdl 		ahc_print_devinfo(ahc, &devinfo);
   2573   1.96      fvdl 		printf("No SCB found during protocol violation\n");
   2574   1.96      fvdl 		goto proto_violation_reset;
   2575   1.96      fvdl 	} else {
   2576   1.96      fvdl 		ahc_set_transaction_status(scb, CAM_SEQUENCE_FAIL);
   2577   1.96      fvdl 		if ((seq_flags & NO_CDB_SENT) != 0) {
   2578   1.96      fvdl 			ahc_print_path(ahc, scb);
   2579   1.96      fvdl 			printf("No or incomplete CDB sent to device.\n");
   2580   1.96      fvdl 		} else if ((ahc_inb(ahc, SCB_CONTROL) & STATUS_RCVD) == 0) {
   2581   1.96      fvdl 			/*
   2582   1.96      fvdl 			 * The target never bothered to provide status to
   2583   1.96      fvdl 			 * us prior to completing the command.  Since we don't
   2584   1.96      fvdl 			 * know the disposition of this command, we must attempt
   2585   1.96      fvdl 			 * to abort it.  Assert ATN and prepare to send an abort
   2586   1.96      fvdl 			 * message.
   2587   1.96      fvdl 			 */
   2588   1.96      fvdl 			ahc_print_path(ahc, scb);
   2589   1.96      fvdl 			printf("Completed command without status.\n");
   2590   1.96      fvdl 		} else {
   2591   1.96      fvdl 			ahc_print_path(ahc, scb);
   2592   1.96      fvdl 			printf("Unknown protocol violation.\n");
   2593   1.96      fvdl 			ahc_dump_card_state(ahc);
   2594   1.96      fvdl 		}
   2595   1.96      fvdl 	}
   2596   1.96      fvdl 	if ((lastphase & ~P_DATAIN_DT) == 0
   2597   1.96      fvdl 	 || lastphase == P_COMMAND) {
   2598   1.96      fvdl proto_violation_reset:
   2599   1.96      fvdl 		/*
   2600   1.96      fvdl 		 * Target either went directly to data/command
   2601   1.96      fvdl 		 * phase or didn't respond to our ATN.
   2602   1.96      fvdl 		 * The only safe thing to do is to blow
   2603   1.96      fvdl 		 * it away with a bus reset.
   2604   1.96      fvdl 		 */
   2605   1.96      fvdl 		found = ahc_reset_channel(ahc, 'A', TRUE);
   2606   1.96      fvdl 		printf("%s: Issued Channel %c Bus Reset. "
   2607   1.96      fvdl 		       "%d SCBs aborted\n", ahc_name(ahc), 'A', found);
   2608   1.96      fvdl 	} else {
   2609   1.96      fvdl 		/*
   2610   1.96      fvdl 		 * Leave the selection hardware off in case
   2611   1.96      fvdl 		 * this abort attempt will affect yet to
   2612   1.96      fvdl 		 * be sent commands.
   2613   1.96      fvdl 		 */
   2614   1.96      fvdl 		ahc_outb(ahc, SCSISEQ,
   2615   1.96      fvdl 			 ahc_inb(ahc, SCSISEQ) & ~ENSELO);
   2616   1.96      fvdl 		ahc_assert_atn(ahc);
   2617   1.96      fvdl 		ahc_outb(ahc, MSG_OUT, HOST_MSG);
   2618   1.96      fvdl 		if (scb == NULL) {
   2619   1.96      fvdl 			ahc_print_devinfo(ahc, &devinfo);
   2620   1.96      fvdl 			ahc->msgout_buf[0] = MSG_ABORT_TASK;
   2621   1.96      fvdl 			ahc->msgout_len = 1;
   2622   1.96      fvdl 			ahc->msgout_index = 0;
   2623   1.96      fvdl 			ahc->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
   2624   1.96      fvdl 		} else {
   2625   1.96      fvdl 			ahc_print_path(ahc, scb);
   2626   1.96      fvdl 			scb->flags |= SCB_ABORT;
   2627   1.96      fvdl 		}
   2628   1.96      fvdl 		printf("Protocol violation %s.  Attempting to abort.\n",
   2629   1.96      fvdl 		       ahc_lookup_phase_entry(curphase)->phasemsg);
   2630   1.96      fvdl 	}
   2631   1.96      fvdl }
   2632   1.96      fvdl 
   2633   1.96      fvdl /*
   2634   1.96      fvdl  * Manual message loop handler.
   2635   1.96      fvdl  */
   2636   1.96      fvdl static void
   2637   1.96      fvdl ahc_handle_message_phase(struct ahc_softc *ahc)
   2638  1.112     perry {
   2639   1.96      fvdl 	struct	ahc_devinfo devinfo;
   2640   1.96      fvdl 	u_int	bus_phase;
   2641   1.96      fvdl 	int	end_session;
   2642   1.96      fvdl 
   2643   1.96      fvdl 	ahc_fetch_devinfo(ahc, &devinfo);
   2644   1.96      fvdl 	end_session = FALSE;
   2645   1.96      fvdl 	bus_phase = ahc_inb(ahc, SCSISIGI) & PHASE_MASK;
   2646   1.96      fvdl 
   2647   1.96      fvdl reswitch:
   2648   1.96      fvdl 	switch (ahc->msg_type) {
   2649   1.96      fvdl 	case MSG_TYPE_INITIATOR_MSGOUT:
   2650   1.96      fvdl 	{
   2651   1.96      fvdl 		int lastbyte;
   2652   1.96      fvdl 		int phasemis;
   2653   1.96      fvdl 		int msgdone;
   2654   1.96      fvdl 
   2655   1.96      fvdl 		if (ahc->msgout_len == 0)
   2656   1.96      fvdl 			panic("HOST_MSG_LOOP interrupt with no active message");
   2657   1.96      fvdl 
   2658   1.96      fvdl #ifdef AHC_DEBUG
   2659   1.96      fvdl 		if ((ahc_debug & AHC_SHOW_MESSAGES) != 0) {
   2660   1.96      fvdl 			ahc_print_devinfo(ahc, &devinfo);
   2661   1.96      fvdl 			printf("INITIATOR_MSG_OUT");
   2662   1.96      fvdl 		}
   2663   1.96      fvdl #endif
   2664   1.96      fvdl 		phasemis = bus_phase != P_MESGOUT;
   2665   1.96      fvdl 		if (phasemis) {
   2666   1.96      fvdl #ifdef AHC_DEBUG
   2667   1.96      fvdl 			if ((ahc_debug & AHC_SHOW_MESSAGES) != 0) {
   2668   1.96      fvdl 				printf(" PHASEMIS %s\n",
   2669   1.96      fvdl 				       ahc_lookup_phase_entry(bus_phase)
   2670   1.96      fvdl 							     ->phasemsg);
   2671   1.96      fvdl 			}
   2672   1.96      fvdl #endif
   2673   1.96      fvdl 			if (bus_phase == P_MESGIN) {
   2674   1.96      fvdl 				/*
   2675   1.96      fvdl 				 * Change gears and see if
   2676   1.96      fvdl 				 * this messages is of interest to
   2677   1.96      fvdl 				 * us or should be passed back to
   2678   1.96      fvdl 				 * the sequencer.
   2679   1.96      fvdl 				 */
   2680   1.96      fvdl 				ahc_outb(ahc, CLRSINT1, CLRATNO);
   2681   1.96      fvdl 				ahc->send_msg_perror = FALSE;
   2682   1.96      fvdl 				ahc->msg_type = MSG_TYPE_INITIATOR_MSGIN;
   2683   1.96      fvdl 				ahc->msgin_index = 0;
   2684   1.96      fvdl 				goto reswitch;
   2685   1.96      fvdl 			}
   2686   1.96      fvdl 			end_session = TRUE;
   2687   1.96      fvdl 			break;
   2688   1.96      fvdl 		}
   2689   1.96      fvdl 
   2690   1.96      fvdl 		if (ahc->send_msg_perror) {
   2691   1.96      fvdl 			ahc_outb(ahc, CLRSINT1, CLRATNO);
   2692   1.96      fvdl 			ahc_outb(ahc, CLRSINT1, CLRREQINIT);
   2693   1.96      fvdl #ifdef AHC_DEBUG
   2694   1.96      fvdl 			if ((ahc_debug & AHC_SHOW_MESSAGES) != 0)
   2695   1.96      fvdl 				printf(" byte 0x%x\n", ahc->send_msg_perror);
   2696   1.96      fvdl #endif
   2697   1.96      fvdl 			ahc_outb(ahc, SCSIDATL, MSG_PARITY_ERROR);
   2698   1.96      fvdl 			break;
   2699   1.96      fvdl 		}
   2700   1.96      fvdl 
   2701   1.96      fvdl 		msgdone	= ahc->msgout_index == ahc->msgout_len;
   2702   1.96      fvdl 		if (msgdone) {
   2703   1.96      fvdl 			/*
   2704   1.96      fvdl 			 * The target has requested a retry.
   2705   1.96      fvdl 			 * Re-assert ATN, reset our message index to
   2706   1.96      fvdl 			 * 0, and try again.
   2707   1.96      fvdl 			 */
   2708   1.96      fvdl 			ahc->msgout_index = 0;
   2709   1.96      fvdl 			ahc_assert_atn(ahc);
   2710   1.96      fvdl 		}
   2711   1.96      fvdl 
   2712   1.96      fvdl 		lastbyte = ahc->msgout_index == (ahc->msgout_len - 1);
   2713   1.96      fvdl 		if (lastbyte) {
   2714   1.96      fvdl 			/* Last byte is signified by dropping ATN */
   2715   1.96      fvdl 			ahc_outb(ahc, CLRSINT1, CLRATNO);
   2716   1.96      fvdl 		}
   2717   1.96      fvdl 
   2718   1.96      fvdl 		/*
   2719   1.96      fvdl 		 * Clear our interrupt status and present
   2720   1.96      fvdl 		 * the next byte on the bus.
   2721   1.96      fvdl 		 */
   2722   1.96      fvdl 		ahc_outb(ahc, CLRSINT1, CLRREQINIT);
   2723   1.96      fvdl #ifdef AHC_DEBUG
   2724   1.96      fvdl 		if ((ahc_debug & AHC_SHOW_MESSAGES) != 0)
   2725   1.96      fvdl 			printf(" byte 0x%x\n",
   2726   1.96      fvdl 			       ahc->msgout_buf[ahc->msgout_index]);
   2727   1.96      fvdl #endif
   2728   1.96      fvdl 		ahc_outb(ahc, SCSIDATL, ahc->msgout_buf[ahc->msgout_index++]);
   2729   1.96      fvdl 		break;
   2730   1.42      fvdl 	}
   2731   1.96      fvdl 	case MSG_TYPE_INITIATOR_MSGIN:
   2732   1.96      fvdl 	{
   2733   1.96      fvdl 		int phasemis;
   2734   1.96      fvdl 		int message_done;
   2735   1.96      fvdl 
   2736   1.96      fvdl #ifdef AHC_DEBUG
   2737   1.96      fvdl 		if ((ahc_debug & AHC_SHOW_MESSAGES) != 0) {
   2738   1.96      fvdl 			ahc_print_devinfo(ahc, &devinfo);
   2739   1.96      fvdl 			printf("INITIATOR_MSG_IN");
   2740   1.96      fvdl 		}
   2741   1.96      fvdl #endif
   2742   1.96      fvdl 		phasemis = bus_phase != P_MESGIN;
   2743   1.96      fvdl 		if (phasemis) {
   2744   1.96      fvdl #ifdef AHC_DEBUG
   2745   1.96      fvdl 			if ((ahc_debug & AHC_SHOW_MESSAGES) != 0) {
   2746   1.96      fvdl 				printf(" PHASEMIS %s\n",
   2747   1.96      fvdl 				       ahc_lookup_phase_entry(bus_phase)
   2748   1.96      fvdl 							     ->phasemsg);
   2749   1.96      fvdl 			}
   2750   1.96      fvdl #endif
   2751   1.96      fvdl 			ahc->msgin_index = 0;
   2752   1.96      fvdl 			if (bus_phase == P_MESGOUT
   2753   1.96      fvdl 			 && (ahc->send_msg_perror == TRUE
   2754   1.96      fvdl 			  || (ahc->msgout_len != 0
   2755   1.96      fvdl 			   && ahc->msgout_index == 0))) {
   2756   1.96      fvdl 				ahc->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
   2757   1.96      fvdl 				goto reswitch;
   2758   1.96      fvdl 			}
   2759   1.96      fvdl 			end_session = TRUE;
   2760   1.96      fvdl 			break;
   2761   1.96      fvdl 		}
   2762   1.42      fvdl 
   2763   1.96      fvdl 		/* Pull the byte in without acking it */
   2764   1.96      fvdl 		ahc->msgin_buf[ahc->msgin_index] = ahc_inb(ahc, SCSIBUSL);
   2765   1.96      fvdl #ifdef AHC_DEBUG
   2766   1.96      fvdl 		if ((ahc_debug & AHC_SHOW_MESSAGES) != 0)
   2767   1.96      fvdl 			printf(" byte 0x%x\n",
   2768   1.96      fvdl 			       ahc->msgin_buf[ahc->msgin_index]);
   2769   1.96      fvdl #endif
   2770   1.42      fvdl 
   2771   1.96      fvdl 		message_done = ahc_parse_msg(ahc, &devinfo);
   2772   1.42      fvdl 
   2773   1.96      fvdl 		if (message_done) {
   2774   1.96      fvdl 			/*
   2775   1.96      fvdl 			 * Clear our incoming message buffer in case there
   2776   1.96      fvdl 			 * is another message following this one.
   2777   1.96      fvdl 			 */
   2778   1.96      fvdl 			ahc->msgin_index = 0;
   2779   1.42      fvdl 
   2780   1.96      fvdl 			/*
   2781   1.96      fvdl 			 * If this message illicited a response,
   2782   1.96      fvdl 			 * assert ATN so the target takes us to the
   2783   1.96      fvdl 			 * message out phase.
   2784   1.96      fvdl 			 */
   2785   1.96      fvdl 			if (ahc->msgout_len != 0) {
   2786   1.42      fvdl #ifdef AHC_DEBUG
   2787   1.96      fvdl 				if ((ahc_debug & AHC_SHOW_MESSAGES) != 0) {
   2788   1.96      fvdl 					ahc_print_devinfo(ahc, &devinfo);
   2789   1.96      fvdl 					printf("Asserting ATN for response\n");
   2790   1.96      fvdl 				}
   2791   1.42      fvdl #endif
   2792   1.96      fvdl 				ahc_assert_atn(ahc);
   2793   1.96      fvdl 			}
   2794  1.112     perry 		} else
   2795   1.96      fvdl 			ahc->msgin_index++;
   2796   1.42      fvdl 
   2797   1.96      fvdl 		if (message_done == MSGLOOP_TERMINATED) {
   2798   1.96      fvdl 			end_session = TRUE;
   2799   1.96      fvdl 		} else {
   2800   1.96      fvdl 			/* Ack the byte */
   2801   1.96      fvdl 			ahc_outb(ahc, CLRSINT1, CLRREQINIT);
   2802  1.121  christos 			(void)ahc_inb(ahc, SCSIDATL);
   2803   1.96      fvdl 		}
   2804   1.42      fvdl 		break;
   2805   1.42      fvdl 	}
   2806   1.96      fvdl 	case MSG_TYPE_TARGET_MSGIN:
   2807   1.96      fvdl 	{
   2808   1.96      fvdl 		int msgdone;
   2809   1.96      fvdl 		int msgout_request;
   2810   1.42      fvdl 
   2811   1.96      fvdl 		if (ahc->msgout_len == 0)
   2812   1.96      fvdl 			panic("Target MSGIN with no active message");
   2813   1.42      fvdl 
   2814   1.96      fvdl 		/*
   2815   1.96      fvdl 		 * If we interrupted a mesgout session, the initiator
   2816   1.96      fvdl 		 * will not know this until our first REQ.  So, we
   2817   1.96      fvdl 		 * only honor mesgout requests after we've sent our
   2818   1.96      fvdl 		 * first byte.
   2819   1.96      fvdl 		 */
   2820   1.96      fvdl 		if ((ahc_inb(ahc, SCSISIGI) & ATNI) != 0
   2821   1.96      fvdl 		 && ahc->msgout_index > 0)
   2822   1.96      fvdl 			msgout_request = TRUE;
   2823   1.96      fvdl 		else
   2824   1.96      fvdl 			msgout_request = FALSE;
   2825   1.42      fvdl 
   2826   1.96      fvdl 		if (msgout_request) {
   2827   1.42      fvdl 
   2828   1.96      fvdl 			/*
   2829   1.96      fvdl 			 * Change gears and see if
   2830   1.96      fvdl 			 * this messages is of interest to
   2831   1.96      fvdl 			 * us or should be passed back to
   2832   1.96      fvdl 			 * the sequencer.
   2833   1.96      fvdl 			 */
   2834   1.96      fvdl 			ahc->msg_type = MSG_TYPE_TARGET_MSGOUT;
   2835   1.96      fvdl 			ahc_outb(ahc, SCSISIGO, P_MESGOUT | BSYO);
   2836   1.96      fvdl 			ahc->msgin_index = 0;
   2837   1.96      fvdl 			/* Dummy read to REQ for first byte */
   2838  1.121  christos 			(void)ahc_inb(ahc, SCSIDATL);
   2839   1.96      fvdl 			ahc_outb(ahc, SXFRCTL0,
   2840   1.96      fvdl 				 ahc_inb(ahc, SXFRCTL0) | SPIOEN);
   2841   1.96      fvdl 			break;
   2842   1.96      fvdl 		}
   2843   1.42      fvdl 
   2844   1.96      fvdl 		msgdone = ahc->msgout_index == ahc->msgout_len;
   2845   1.96      fvdl 		if (msgdone) {
   2846   1.96      fvdl 			ahc_outb(ahc, SXFRCTL0,
   2847   1.96      fvdl 				 ahc_inb(ahc, SXFRCTL0) & ~SPIOEN);
   2848   1.96      fvdl 			end_session = TRUE;
   2849   1.96      fvdl 			break;
   2850   1.96      fvdl 		}
   2851   1.42      fvdl 
   2852   1.96      fvdl 		/*
   2853   1.96      fvdl 		 * Present the next byte on the bus.
   2854   1.96      fvdl 		 */
   2855   1.96      fvdl 		ahc_outb(ahc, SXFRCTL0, ahc_inb(ahc, SXFRCTL0) | SPIOEN);
   2856   1.96      fvdl 		ahc_outb(ahc, SCSIDATL, ahc->msgout_buf[ahc->msgout_index++]);
   2857   1.96      fvdl 		break;
   2858   1.96      fvdl 	}
   2859   1.96      fvdl 	case MSG_TYPE_TARGET_MSGOUT:
   2860   1.96      fvdl 	{
   2861   1.96      fvdl 		int lastbyte;
   2862   1.96      fvdl 		int msgdone;
   2863   1.42      fvdl 
   2864   1.96      fvdl 		/*
   2865   1.96      fvdl 		 * The initiator signals that this is
   2866   1.96      fvdl 		 * the last byte by dropping ATN.
   2867   1.96      fvdl 		 */
   2868   1.96      fvdl 		lastbyte = (ahc_inb(ahc, SCSISIGI) & ATNI) == 0;
   2869   1.42      fvdl 
   2870   1.96      fvdl 		/*
   2871   1.96      fvdl 		 * Read the latched byte, but turn off SPIOEN first
   2872   1.96      fvdl 		 * so that we don't inadvertently cause a REQ for the
   2873   1.96      fvdl 		 * next byte.
   2874   1.96      fvdl 		 */
   2875   1.96      fvdl 		ahc_outb(ahc, SXFRCTL0, ahc_inb(ahc, SXFRCTL0) & ~SPIOEN);
   2876   1.96      fvdl 		ahc->msgin_buf[ahc->msgin_index] = ahc_inb(ahc, SCSIDATL);
   2877   1.96      fvdl 		msgdone = ahc_parse_msg(ahc, &devinfo);
   2878   1.96      fvdl 		if (msgdone == MSGLOOP_TERMINATED) {
   2879   1.96      fvdl 			/*
   2880   1.96      fvdl 			 * The message is *really* done in that it caused
   2881   1.96      fvdl 			 * us to go to bus free.  The sequencer has already
   2882   1.96      fvdl 			 * been reset at this point, so pull the ejection
   2883   1.96      fvdl 			 * handle.
   2884   1.96      fvdl 			 */
   2885   1.96      fvdl 			return;
   2886   1.96      fvdl 		}
   2887  1.112     perry 
   2888   1.96      fvdl 		ahc->msgin_index++;
   2889   1.42      fvdl 
   2890   1.96      fvdl 		/*
   2891   1.96      fvdl 		 * XXX Read spec about initiator dropping ATN too soon
   2892   1.96      fvdl 		 *     and use msgdone to detect it.
   2893   1.96      fvdl 		 */
   2894   1.96      fvdl 		if (msgdone == MSGLOOP_MSGCOMPLETE) {
   2895   1.96      fvdl 			ahc->msgin_index = 0;
   2896   1.42      fvdl 
   2897   1.96      fvdl 			/*
   2898   1.96      fvdl 			 * If this message illicited a response, transition
   2899   1.96      fvdl 			 * to the Message in phase and send it.
   2900   1.96      fvdl 			 */
   2901   1.96      fvdl 			if (ahc->msgout_len != 0) {
   2902   1.96      fvdl 				ahc_outb(ahc, SCSISIGO, P_MESGIN | BSYO);
   2903   1.96      fvdl 				ahc_outb(ahc, SXFRCTL0,
   2904   1.96      fvdl 					 ahc_inb(ahc, SXFRCTL0) | SPIOEN);
   2905   1.96      fvdl 				ahc->msg_type = MSG_TYPE_TARGET_MSGIN;
   2906   1.96      fvdl 				ahc->msgin_index = 0;
   2907   1.96      fvdl 				break;
   2908   1.96      fvdl 			}
   2909   1.96      fvdl 		}
   2910   1.42      fvdl 
   2911   1.96      fvdl 		if (lastbyte)
   2912   1.96      fvdl 			end_session = TRUE;
   2913   1.96      fvdl 		else {
   2914   1.96      fvdl 			/* Ask for the next byte. */
   2915   1.96      fvdl 			ahc_outb(ahc, SXFRCTL0,
   2916   1.96      fvdl 				 ahc_inb(ahc, SXFRCTL0) | SPIOEN);
   2917   1.96      fvdl 		}
   2918   1.42      fvdl 
   2919   1.96      fvdl 		break;
   2920   1.96      fvdl 	}
   2921   1.96      fvdl 	default:
   2922   1.96      fvdl 		panic("Unknown REQINIT message type");
   2923   1.96      fvdl 	}
   2924   1.42      fvdl 
   2925   1.96      fvdl 	if (end_session) {
   2926   1.96      fvdl 		ahc_clear_msg_state(ahc);
   2927   1.96      fvdl 		ahc_outb(ahc, RETURN_1, EXIT_MSG_LOOP);
   2928   1.96      fvdl 	} else
   2929   1.96      fvdl 		ahc_outb(ahc, RETURN_1, CONT_MSG_LOOP);
   2930   1.42      fvdl }
   2931   1.42      fvdl 
   2932   1.96      fvdl /*
   2933   1.96      fvdl  * See if we sent a particular extended message to the target.
   2934   1.96      fvdl  * If "full" is true, return true only if the target saw the full
   2935   1.96      fvdl  * message.  If "full" is false, return true if the target saw at
   2936   1.96      fvdl  * least the first byte of the message.
   2937   1.96      fvdl  */
   2938   1.42      fvdl static int
   2939   1.96      fvdl ahc_sent_msg(struct ahc_softc *ahc, ahc_msgtype type, u_int msgval, int full)
   2940   1.42      fvdl {
   2941   1.96      fvdl 	int found;
   2942   1.96      fvdl 	u_int index;
   2943   1.42      fvdl 
   2944   1.96      fvdl 	found = FALSE;
   2945   1.96      fvdl 	index = 0;
   2946   1.42      fvdl 
   2947   1.96      fvdl 	while (index < ahc->msgout_len) {
   2948   1.96      fvdl 		if (ahc->msgout_buf[index] == MSG_EXTENDED) {
   2949   1.96      fvdl 			u_int end_index;
   2950   1.42      fvdl 
   2951   1.96      fvdl 			end_index = index + 1 + ahc->msgout_buf[index + 1];
   2952   1.96      fvdl 			if (ahc->msgout_buf[index+2] == msgval
   2953   1.96      fvdl 			 && type == AHCMSG_EXT) {
   2954   1.42      fvdl 
   2955   1.96      fvdl 				if (full) {
   2956   1.96      fvdl 					if (ahc->msgout_index > end_index)
   2957   1.96      fvdl 						found = TRUE;
   2958   1.96      fvdl 				} else if (ahc->msgout_index > index)
   2959   1.96      fvdl 					found = TRUE;
   2960   1.96      fvdl 			}
   2961   1.96      fvdl 			index = end_index;
   2962   1.96      fvdl 		} else if (ahc->msgout_buf[index] >= MSG_SIMPLE_TASK
   2963   1.96      fvdl 			&& ahc->msgout_buf[index] <= MSG_IGN_WIDE_RESIDUE) {
   2964   1.42      fvdl 
   2965   1.96      fvdl 			/* Skip tag type and tag id or residue param*/
   2966   1.96      fvdl 			index += 2;
   2967   1.96      fvdl 		} else {
   2968   1.96      fvdl 			/* Single byte message */
   2969   1.96      fvdl 			if (type == AHCMSG_1B
   2970   1.96      fvdl 			 && ahc->msgout_buf[index] == msgval
   2971   1.96      fvdl 			 && ahc->msgout_index > index)
   2972   1.96      fvdl 				found = TRUE;
   2973   1.96      fvdl 			index++;
   2974   1.96      fvdl 		}
   2975   1.42      fvdl 
   2976   1.96      fvdl 		if (found)
   2977   1.96      fvdl 			break;
   2978   1.42      fvdl 	}
   2979   1.96      fvdl 	return (found);
   2980   1.96      fvdl }
   2981   1.42      fvdl 
   2982   1.96      fvdl /*
   2983   1.96      fvdl  * Wait for a complete incoming message, parse it, and respond accordingly.
   2984   1.96      fvdl  */
   2985   1.96      fvdl static int
   2986   1.96      fvdl ahc_parse_msg(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
   2987   1.96      fvdl {
   2988   1.96      fvdl 	struct	ahc_initiator_tinfo *tinfo;
   2989   1.96      fvdl 	struct	ahc_tmode_tstate *tstate;
   2990   1.96      fvdl 	int	reject;
   2991   1.96      fvdl 	int	done;
   2992   1.96      fvdl 	int	response;
   2993   1.96      fvdl 	u_int	targ_scsirate;
   2994   1.42      fvdl 
   2995   1.96      fvdl 	done = MSGLOOP_IN_PROG;
   2996   1.96      fvdl 	response = FALSE;
   2997   1.96      fvdl 	reject = FALSE;
   2998   1.96      fvdl 	tinfo = ahc_fetch_transinfo(ahc, devinfo->channel, devinfo->our_scsiid,
   2999   1.96      fvdl 				    devinfo->target, &tstate);
   3000   1.96      fvdl 	targ_scsirate = tinfo->scsirate;
   3001   1.42      fvdl 
   3002   1.42      fvdl 	/*
   3003  1.108       wiz 	 * Parse as much of the message as is available,
   3004   1.96      fvdl 	 * rejecting it if we don't support it.  When
   3005  1.108       wiz 	 * the entire message is available and has been
   3006   1.96      fvdl 	 * handled, return MSGLOOP_MSGCOMPLETE, indicating
   3007   1.96      fvdl 	 * that we have parsed an entire message.
   3008   1.42      fvdl 	 *
   3009   1.96      fvdl 	 * In the case of extended messages, we accept the length
   3010   1.96      fvdl 	 * byte outright and perform more checking once we know the
   3011   1.96      fvdl 	 * extended message type.
   3012   1.42      fvdl 	 */
   3013   1.96      fvdl 	switch (ahc->msgin_buf[0]) {
   3014   1.96      fvdl 	case MSG_DISCONNECT:
   3015   1.96      fvdl 	case MSG_SAVEDATAPOINTER:
   3016   1.96      fvdl 	case MSG_CMDCOMPLETE:
   3017   1.96      fvdl 	case MSG_RESTOREPOINTERS:
   3018   1.96      fvdl 	case MSG_IGN_WIDE_RESIDUE:
   3019   1.96      fvdl 		/*
   3020   1.96      fvdl 		 * End our message loop as these are messages
   3021   1.96      fvdl 		 * the sequencer handles on its own.
   3022   1.96      fvdl 		 */
   3023   1.96      fvdl 		done = MSGLOOP_TERMINATED;
   3024   1.96      fvdl 		break;
   3025   1.96      fvdl 	case MSG_MESSAGE_REJECT:
   3026   1.96      fvdl 		response = ahc_handle_msg_reject(ahc, devinfo);
   3027   1.96      fvdl 		/* FALLTHROUGH */
   3028   1.96      fvdl 	case MSG_NOOP:
   3029   1.96      fvdl 		done = MSGLOOP_MSGCOMPLETE;
   3030   1.96      fvdl 		break;
   3031   1.96      fvdl 	case MSG_EXTENDED:
   3032   1.96      fvdl 	{
   3033   1.96      fvdl 		/* Wait for enough of the message to begin validation */
   3034   1.96      fvdl 		if (ahc->msgin_index < 2)
   3035   1.96      fvdl 			break;
   3036   1.96      fvdl 		switch (ahc->msgin_buf[2]) {
   3037   1.96      fvdl 		case MSG_EXT_SDTR:
   3038   1.96      fvdl 		{
   3039   1.96      fvdl 			struct	 ahc_syncrate *syncrate;
   3040   1.96      fvdl 			u_int	 period;
   3041   1.96      fvdl 			u_int	 ppr_options;
   3042   1.96      fvdl 			u_int	 offset;
   3043   1.96      fvdl 			u_int	 saved_offset;
   3044  1.112     perry 
   3045   1.96      fvdl 			if (ahc->msgin_buf[1] != MSG_EXT_SDTR_LEN) {
   3046   1.96      fvdl 				reject = TRUE;
   3047   1.96      fvdl 				break;
   3048   1.96      fvdl 			}
   3049   1.42      fvdl 
   3050   1.96      fvdl 			/*
   3051   1.96      fvdl 			 * Wait until we have both args before validating
   3052   1.96      fvdl 			 * and acting on this message.
   3053   1.96      fvdl 			 *
   3054   1.96      fvdl 			 * Add one to MSG_EXT_SDTR_LEN to account for
   3055   1.96      fvdl 			 * the extended message preamble.
   3056   1.96      fvdl 			 */
   3057   1.96      fvdl 			if (ahc->msgin_index < (MSG_EXT_SDTR_LEN + 1))
   3058   1.96      fvdl 				break;
   3059   1.42      fvdl 
   3060   1.96      fvdl 			period = ahc->msgin_buf[3];
   3061   1.96      fvdl 			ppr_options = 0;
   3062   1.96      fvdl 			saved_offset = offset = ahc->msgin_buf[4];
   3063   1.96      fvdl 			syncrate = ahc_devlimited_syncrate(ahc, tinfo, &period,
   3064   1.96      fvdl 							   &ppr_options,
   3065   1.96      fvdl 							   devinfo->role);
   3066   1.96      fvdl 			ahc_validate_offset(ahc, tinfo, syncrate, &offset,
   3067   1.96      fvdl 					    targ_scsirate & WIDEXFER,
   3068   1.96      fvdl 					    devinfo->role);
   3069   1.96      fvdl 			if (bootverbose) {
   3070   1.96      fvdl 				printf("(%s:%c:%d:%d): Received "
   3071   1.96      fvdl 				       "SDTR period %x, offset %x\n\t"
   3072   1.96      fvdl 				       "Filtered to period %x, offset %x\n",
   3073   1.96      fvdl 				       ahc_name(ahc), devinfo->channel,
   3074   1.96      fvdl 				       devinfo->target, devinfo->lun,
   3075   1.96      fvdl 				       ahc->msgin_buf[3], saved_offset,
   3076   1.96      fvdl 				       period, offset);
   3077   1.96      fvdl 			}
   3078  1.112     perry 			ahc_set_syncrate(ahc, devinfo,
   3079   1.96      fvdl 					 syncrate, period,
   3080   1.96      fvdl 					 offset, ppr_options,
   3081   1.96      fvdl 					 AHC_TRANS_ACTIVE|AHC_TRANS_GOAL,
   3082   1.96      fvdl 					 /*paused*/TRUE);
   3083   1.42      fvdl 
   3084   1.96      fvdl 			/*
   3085   1.96      fvdl 			 * See if we initiated Sync Negotiation
   3086   1.96      fvdl 			 * and didn't have to fall down to async
   3087   1.96      fvdl 			 * transfers.
   3088   1.96      fvdl 			 */
   3089   1.96      fvdl 			if (ahc_sent_msg(ahc, AHCMSG_EXT, MSG_EXT_SDTR, TRUE)) {
   3090   1.96      fvdl 				/* We started it */
   3091   1.96      fvdl 				if (saved_offset != offset) {
   3092   1.96      fvdl 					/* Went too low - force async */
   3093   1.96      fvdl 					reject = TRUE;
   3094   1.96      fvdl 				}
   3095   1.96      fvdl 			} else {
   3096   1.96      fvdl 				/*
   3097   1.96      fvdl 				 * Send our own SDTR in reply
   3098   1.96      fvdl 				 */
   3099   1.96      fvdl 				if (bootverbose
   3100   1.96      fvdl 				 && devinfo->role == ROLE_INITIATOR) {
   3101   1.96      fvdl 					printf("(%s:%c:%d:%d): Target "
   3102   1.96      fvdl 					       "Initiated SDTR\n",
   3103   1.96      fvdl 					       ahc_name(ahc), devinfo->channel,
   3104   1.96      fvdl 					       devinfo->target, devinfo->lun);
   3105   1.96      fvdl 				}
   3106   1.96      fvdl 				ahc->msgout_index = 0;
   3107   1.96      fvdl 				ahc->msgout_len = 0;
   3108   1.96      fvdl 				ahc_construct_sdtr(ahc, devinfo,
   3109   1.96      fvdl 						   period, offset);
   3110   1.96      fvdl 				ahc->msgout_index = 0;
   3111   1.96      fvdl 				response = TRUE;
   3112   1.96      fvdl 			}
   3113   1.96      fvdl 			done = MSGLOOP_MSGCOMPLETE;
   3114   1.96      fvdl 			break;
   3115   1.96      fvdl 		}
   3116   1.96      fvdl 		case MSG_EXT_WDTR:
   3117   1.96      fvdl 		{
   3118   1.96      fvdl 			u_int bus_width;
   3119   1.96      fvdl 			u_int saved_width;
   3120   1.96      fvdl 			u_int sending_reply;
   3121   1.42      fvdl 
   3122   1.96      fvdl 			sending_reply = FALSE;
   3123   1.96      fvdl 			if (ahc->msgin_buf[1] != MSG_EXT_WDTR_LEN) {
   3124   1.96      fvdl 				reject = TRUE;
   3125   1.96      fvdl 				break;
   3126   1.96      fvdl 			}
   3127   1.42      fvdl 
   3128   1.96      fvdl 			/*
   3129   1.96      fvdl 			 * Wait until we have our arg before validating
   3130   1.96      fvdl 			 * and acting on this message.
   3131   1.96      fvdl 			 *
   3132   1.96      fvdl 			 * Add one to MSG_EXT_WDTR_LEN to account for
   3133   1.96      fvdl 			 * the extended message preamble.
   3134   1.96      fvdl 			 */
   3135   1.96      fvdl 			if (ahc->msgin_index < (MSG_EXT_WDTR_LEN + 1))
   3136   1.96      fvdl 				break;
   3137   1.42      fvdl 
   3138   1.96      fvdl 			bus_width = ahc->msgin_buf[3];
   3139   1.96      fvdl 			saved_width = bus_width;
   3140   1.96      fvdl 			ahc_validate_width(ahc, tinfo, &bus_width,
   3141   1.96      fvdl 					   devinfo->role);
   3142   1.96      fvdl 			if (bootverbose) {
   3143   1.96      fvdl 				printf("(%s:%c:%d:%d): Received WDTR "
   3144   1.96      fvdl 				       "%x filtered to %x\n",
   3145   1.96      fvdl 				       ahc_name(ahc), devinfo->channel,
   3146   1.96      fvdl 				       devinfo->target, devinfo->lun,
   3147   1.96      fvdl 				       saved_width, bus_width);
   3148   1.96      fvdl 			}
   3149   1.42      fvdl 
   3150   1.96      fvdl 			if (ahc_sent_msg(ahc, AHCMSG_EXT, MSG_EXT_WDTR, TRUE)) {
   3151   1.96      fvdl 				/*
   3152   1.96      fvdl 				 * Don't send a WDTR back to the
   3153   1.96      fvdl 				 * target, since we asked first.
   3154   1.96      fvdl 				 * If the width went higher than our
   3155   1.96      fvdl 				 * request, reject it.
   3156   1.96      fvdl 				 */
   3157   1.96      fvdl 				if (saved_width > bus_width) {
   3158   1.96      fvdl 					reject = TRUE;
   3159   1.96      fvdl 					printf("(%s:%c:%d:%d): requested %dBit "
   3160   1.96      fvdl 					       "transfers.  Rejecting...\n",
   3161   1.96      fvdl 					       ahc_name(ahc), devinfo->channel,
   3162   1.96      fvdl 					       devinfo->target, devinfo->lun,
   3163   1.96      fvdl 					       8 * (0x01 << bus_width));
   3164   1.96      fvdl 					bus_width = 0;
   3165   1.96      fvdl 				}
   3166   1.96      fvdl 			} else {
   3167   1.96      fvdl 				/*
   3168   1.96      fvdl 				 * Send our own WDTR in reply
   3169   1.96      fvdl 				 */
   3170   1.96      fvdl 				if (bootverbose
   3171   1.96      fvdl 				 && devinfo->role == ROLE_INITIATOR) {
   3172   1.96      fvdl 					printf("(%s:%c:%d:%d): Target "
   3173   1.96      fvdl 					       "Initiated WDTR\n",
   3174   1.96      fvdl 					       ahc_name(ahc), devinfo->channel,
   3175   1.96      fvdl 					       devinfo->target, devinfo->lun);
   3176   1.96      fvdl 				}
   3177   1.96      fvdl 				ahc->msgout_index = 0;
   3178   1.96      fvdl 				ahc->msgout_len = 0;
   3179   1.96      fvdl 				ahc_construct_wdtr(ahc, devinfo, bus_width);
   3180   1.96      fvdl 				ahc->msgout_index = 0;
   3181   1.96      fvdl 				response = TRUE;
   3182   1.96      fvdl 				sending_reply = TRUE;
   3183   1.96      fvdl 			}
   3184   1.96      fvdl 			ahc_set_width(ahc, devinfo, bus_width,
   3185   1.96      fvdl 				      AHC_TRANS_ACTIVE|AHC_TRANS_GOAL,
   3186   1.96      fvdl 				      /*paused*/TRUE);
   3187   1.96      fvdl 			/* After a wide message, we are async */
   3188   1.96      fvdl 			ahc_set_syncrate(ahc, devinfo,
   3189   1.96      fvdl 					 /*syncrate*/NULL, /*period*/0,
   3190   1.96      fvdl 					 /*offset*/0, /*ppr_options*/0,
   3191   1.96      fvdl 					 AHC_TRANS_ACTIVE, /*paused*/TRUE);
   3192   1.96      fvdl 			if (sending_reply == FALSE && reject == FALSE) {
   3193   1.42      fvdl 
   3194   1.96      fvdl 				if (tinfo->goal.offset) {
   3195   1.96      fvdl 					ahc->msgout_index = 0;
   3196   1.96      fvdl 					ahc->msgout_len = 0;
   3197   1.96      fvdl 					ahc_build_transfer_msg(ahc, devinfo);
   3198   1.96      fvdl 					ahc->msgout_index = 0;
   3199   1.96      fvdl 					response = TRUE;
   3200   1.96      fvdl 				}
   3201   1.96      fvdl 			}
   3202   1.96      fvdl 			done = MSGLOOP_MSGCOMPLETE;
   3203   1.96      fvdl 			break;
   3204   1.96      fvdl 		}
   3205   1.96      fvdl 		case MSG_EXT_PPR:
   3206   1.96      fvdl 		{
   3207   1.96      fvdl 			struct	ahc_syncrate *syncrate;
   3208   1.96      fvdl 			u_int	period;
   3209   1.96      fvdl 			u_int	offset;
   3210   1.96      fvdl 			u_int	bus_width;
   3211   1.96      fvdl 			u_int	ppr_options;
   3212   1.96      fvdl 			u_int	saved_width;
   3213   1.96      fvdl 			u_int	saved_offset;
   3214   1.96      fvdl 			u_int	saved_ppr_options;
   3215   1.42      fvdl 
   3216   1.96      fvdl 			if (ahc->msgin_buf[1] != MSG_EXT_PPR_LEN) {
   3217   1.96      fvdl 				reject = TRUE;
   3218   1.96      fvdl 				break;
   3219   1.96      fvdl 			}
   3220   1.42      fvdl 
   3221   1.96      fvdl 			/*
   3222   1.96      fvdl 			 * Wait until we have all args before validating
   3223   1.96      fvdl 			 * and acting on this message.
   3224   1.96      fvdl 			 *
   3225   1.96      fvdl 			 * Add one to MSG_EXT_PPR_LEN to account for
   3226   1.96      fvdl 			 * the extended message preamble.
   3227   1.96      fvdl 			 */
   3228   1.96      fvdl 			if (ahc->msgin_index < (MSG_EXT_PPR_LEN + 1))
   3229   1.96      fvdl 				break;
   3230   1.42      fvdl 
   3231   1.96      fvdl 			period = ahc->msgin_buf[3];
   3232   1.96      fvdl 			offset = ahc->msgin_buf[5];
   3233   1.96      fvdl 			bus_width = ahc->msgin_buf[6];
   3234   1.96      fvdl 			saved_width = bus_width;
   3235   1.96      fvdl 			ppr_options = ahc->msgin_buf[7];
   3236   1.96      fvdl 			/*
   3237   1.96      fvdl 			 * According to the spec, a DT only
   3238   1.96      fvdl 			 * period factor with no DT option
   3239   1.96      fvdl 			 * set implies async.
   3240   1.96      fvdl 			 */
   3241   1.96      fvdl 			if ((ppr_options & MSG_EXT_PPR_DT_REQ) == 0
   3242   1.96      fvdl 			 && period == 9)
   3243   1.96      fvdl 				offset = 0;
   3244   1.96      fvdl 			saved_ppr_options = ppr_options;
   3245   1.96      fvdl 			saved_offset = offset;
   3246   1.42      fvdl 
   3247   1.96      fvdl 			/*
   3248   1.96      fvdl 			 * Mask out any options we don't support
   3249   1.96      fvdl 			 * on any controller.  Transfer options are
   3250   1.96      fvdl 			 * only available if we are negotiating wide.
   3251   1.96      fvdl 			 */
   3252   1.96      fvdl 			ppr_options &= MSG_EXT_PPR_DT_REQ;
   3253   1.96      fvdl 			if (bus_width == 0)
   3254   1.96      fvdl 				ppr_options = 0;
   3255   1.96      fvdl 
   3256   1.96      fvdl 			ahc_validate_width(ahc, tinfo, &bus_width,
   3257   1.96      fvdl 					   devinfo->role);
   3258   1.96      fvdl 			syncrate = ahc_devlimited_syncrate(ahc, tinfo, &period,
   3259   1.96      fvdl 							   &ppr_options,
   3260   1.96      fvdl 							   devinfo->role);
   3261   1.96      fvdl 			ahc_validate_offset(ahc, tinfo, syncrate,
   3262   1.96      fvdl 					    &offset, bus_width,
   3263   1.96      fvdl 					    devinfo->role);
   3264   1.42      fvdl 
   3265   1.96      fvdl 			if (ahc_sent_msg(ahc, AHCMSG_EXT, MSG_EXT_PPR, TRUE)) {
   3266   1.96      fvdl 				/*
   3267   1.96      fvdl 				 * If we are unable to do any of the
   3268   1.96      fvdl 				 * requested options (we went too low),
   3269   1.96      fvdl 				 * then we'll have to reject the message.
   3270   1.96      fvdl 				 */
   3271   1.96      fvdl 				if (saved_width > bus_width
   3272   1.96      fvdl 				 || saved_offset != offset
   3273   1.96      fvdl 				 || saved_ppr_options != ppr_options) {
   3274   1.96      fvdl 					reject = TRUE;
   3275   1.96      fvdl 					period = 0;
   3276   1.96      fvdl 					offset = 0;
   3277   1.96      fvdl 					bus_width = 0;
   3278   1.96      fvdl 					ppr_options = 0;
   3279   1.96      fvdl 					syncrate = NULL;
   3280   1.96      fvdl 				}
   3281   1.96      fvdl 			} else {
   3282   1.96      fvdl 				if (devinfo->role != ROLE_TARGET)
   3283   1.96      fvdl 					printf("(%s:%c:%d:%d): Target "
   3284   1.96      fvdl 					       "Initiated PPR\n",
   3285   1.96      fvdl 					       ahc_name(ahc), devinfo->channel,
   3286   1.96      fvdl 					       devinfo->target, devinfo->lun);
   3287   1.96      fvdl 				else
   3288   1.96      fvdl 					printf("(%s:%c:%d:%d): Initiator "
   3289   1.96      fvdl 					       "Initiated PPR\n",
   3290   1.96      fvdl 					       ahc_name(ahc), devinfo->channel,
   3291   1.96      fvdl 					       devinfo->target, devinfo->lun);
   3292   1.96      fvdl 				ahc->msgout_index = 0;
   3293   1.96      fvdl 				ahc->msgout_len = 0;
   3294   1.96      fvdl 				ahc_construct_ppr(ahc, devinfo, period, offset,
   3295   1.96      fvdl 						  bus_width, ppr_options);
   3296   1.96      fvdl 				ahc->msgout_index = 0;
   3297   1.96      fvdl 				response = TRUE;
   3298   1.96      fvdl 			}
   3299   1.96      fvdl 			if (bootverbose) {
   3300   1.96      fvdl 				printf("(%s:%c:%d:%d): Received PPR width %x, "
   3301   1.96      fvdl 				       "period %x, offset %x,options %x\n"
   3302   1.96      fvdl 				       "\tFiltered to width %x, period %x, "
   3303   1.96      fvdl 				       "offset %x, options %x\n",
   3304   1.96      fvdl 				       ahc_name(ahc), devinfo->channel,
   3305   1.96      fvdl 				       devinfo->target, devinfo->lun,
   3306   1.96      fvdl 				       saved_width, ahc->msgin_buf[3],
   3307   1.96      fvdl 				       saved_offset, saved_ppr_options,
   3308   1.96      fvdl 				       bus_width, period, offset, ppr_options);
   3309   1.96      fvdl 			}
   3310   1.96      fvdl 			ahc_set_width(ahc, devinfo, bus_width,
   3311   1.96      fvdl 				      AHC_TRANS_ACTIVE|AHC_TRANS_GOAL,
   3312   1.96      fvdl 				      /*paused*/TRUE);
   3313   1.96      fvdl 			ahc_set_syncrate(ahc, devinfo,
   3314   1.96      fvdl 					 syncrate, period,
   3315   1.96      fvdl 					 offset, ppr_options,
   3316   1.96      fvdl 					 AHC_TRANS_ACTIVE|AHC_TRANS_GOAL,
   3317   1.96      fvdl 					 /*paused*/TRUE);
   3318   1.96      fvdl 			done = MSGLOOP_MSGCOMPLETE;
   3319   1.96      fvdl 			break;
   3320   1.96      fvdl 		}
   3321   1.96      fvdl 		default:
   3322   1.96      fvdl 			/* Unknown extended message.  Reject it. */
   3323   1.96      fvdl 			reject = TRUE;
   3324   1.96      fvdl 			break;
   3325   1.96      fvdl 		}
   3326   1.96      fvdl 		break;
   3327   1.96      fvdl 	}
   3328   1.96      fvdl #ifdef AHC_TARGET_MODE
   3329   1.96      fvdl 	case MSG_BUS_DEV_RESET:
   3330   1.96      fvdl 		ahc_handle_devreset(ahc, devinfo,
   3331   1.96      fvdl 				    CAM_BDR_SENT,
   3332   1.96      fvdl 				    "Bus Device Reset Received",
   3333   1.96      fvdl 				    /*verbose_level*/0);
   3334   1.96      fvdl 		ahc_restart(ahc);
   3335   1.96      fvdl 		done = MSGLOOP_TERMINATED;
   3336   1.96      fvdl 		break;
   3337   1.96      fvdl 	case MSG_ABORT_TAG:
   3338   1.96      fvdl 	case MSG_ABORT:
   3339   1.96      fvdl 	case MSG_CLEAR_QUEUE:
   3340   1.42      fvdl 	{
   3341   1.96      fvdl 		int tag;
   3342   1.42      fvdl 
   3343   1.96      fvdl 		/* Target mode messages */
   3344   1.96      fvdl 		if (devinfo->role != ROLE_TARGET) {
   3345   1.96      fvdl 			reject = TRUE;
   3346   1.96      fvdl 			break;
   3347   1.42      fvdl 		}
   3348   1.96      fvdl 		tag = SCB_LIST_NULL;
   3349   1.96      fvdl 		if (ahc->msgin_buf[0] == MSG_ABORT_TAG)
   3350   1.96      fvdl 			tag = ahc_inb(ahc, INITIATOR_TAG);
   3351   1.96      fvdl 		ahc_abort_scbs(ahc, devinfo->target, devinfo->channel,
   3352   1.96      fvdl 			       devinfo->lun, tag, ROLE_TARGET,
   3353   1.96      fvdl 			       CAM_REQ_ABORTED);
   3354   1.42      fvdl 
   3355   1.96      fvdl 		tstate = ahc->enabled_targets[devinfo->our_scsiid];
   3356   1.96      fvdl 		if (tstate != NULL) {
   3357   1.96      fvdl 			struct ahc_tmode_lstate* lstate;
   3358   1.42      fvdl 
   3359   1.96      fvdl 			lstate = tstate->enabled_luns[devinfo->lun];
   3360   1.96      fvdl 			if (lstate != NULL) {
   3361   1.96      fvdl 				ahc_queue_lstate_event(ahc, lstate,
   3362   1.96      fvdl 						       devinfo->our_scsiid,
   3363   1.96      fvdl 						       ahc->msgin_buf[0],
   3364   1.96      fvdl 						       /*arg*/tag);
   3365   1.96      fvdl 				ahc_send_lstate_events(ahc, lstate);
   3366   1.96      fvdl 			}
   3367   1.96      fvdl 		}
   3368   1.96      fvdl 		ahc_restart(ahc);
   3369   1.96      fvdl 		done = MSGLOOP_TERMINATED;
   3370   1.42      fvdl 		break;
   3371   1.96      fvdl 	}
   3372   1.96      fvdl #endif
   3373   1.96      fvdl 	case MSG_TERM_IO_PROC:
   3374   1.96      fvdl 	default:
   3375   1.96      fvdl 		reject = TRUE;
   3376   1.42      fvdl 		break;
   3377   1.42      fvdl 	}
   3378   1.42      fvdl 
   3379   1.96      fvdl 	if (reject) {
   3380   1.96      fvdl 		/*
   3381   1.96      fvdl 		 * Setup to reject the message.
   3382   1.96      fvdl 		 */
   3383   1.96      fvdl 		ahc->msgout_index = 0;
   3384   1.96      fvdl 		ahc->msgout_len = 1;
   3385   1.96      fvdl 		ahc->msgout_buf[0] = MSG_MESSAGE_REJECT;
   3386   1.96      fvdl 		done = MSGLOOP_MSGCOMPLETE;
   3387   1.96      fvdl 		response = TRUE;
   3388   1.96      fvdl 	}
   3389   1.42      fvdl 
   3390   1.96      fvdl 	if (done != MSGLOOP_IN_PROG && !response)
   3391   1.96      fvdl 		/* Clear the outgoing message buffer */
   3392   1.96      fvdl 		ahc->msgout_len = 0;
   3393   1.42      fvdl 
   3394   1.96      fvdl 	return (done);
   3395   1.42      fvdl }
   3396   1.42      fvdl 
   3397   1.42      fvdl /*
   3398   1.96      fvdl  * Process a message reject message.
   3399   1.42      fvdl  */
   3400   1.96      fvdl static int
   3401   1.96      fvdl ahc_handle_msg_reject(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
   3402   1.42      fvdl {
   3403   1.96      fvdl 	/*
   3404   1.96      fvdl 	 * What we care about here is if we had an
   3405   1.96      fvdl 	 * outstanding SDTR or WDTR message for this
   3406   1.96      fvdl 	 * target.  If we did, this is a signal that
   3407   1.96      fvdl 	 * the target is refusing negotiation.
   3408   1.96      fvdl 	 */
   3409   1.96      fvdl 	struct scb *scb;
   3410   1.96      fvdl 	struct ahc_initiator_tinfo *tinfo;
   3411   1.96      fvdl 	struct ahc_tmode_tstate *tstate;
   3412   1.96      fvdl 	u_int scb_index;
   3413   1.96      fvdl 	u_int last_msg;
   3414   1.96      fvdl 	int   response = 0;
   3415   1.42      fvdl 
   3416   1.96      fvdl 	scb_index = ahc_inb(ahc, SCB_TAG);
   3417   1.96      fvdl 	scb = ahc_lookup_scb(ahc, scb_index);
   3418   1.96      fvdl 	tinfo = ahc_fetch_transinfo(ahc, devinfo->channel,
   3419   1.96      fvdl 				    devinfo->our_scsiid,
   3420   1.96      fvdl 				    devinfo->target, &tstate);
   3421   1.96      fvdl 	/* Might be necessary */
   3422   1.96      fvdl 	last_msg = ahc_inb(ahc, LAST_MSG);
   3423   1.42      fvdl 
   3424   1.96      fvdl 	if (ahc_sent_msg(ahc, AHCMSG_EXT, MSG_EXT_PPR, /*full*/FALSE)) {
   3425   1.96      fvdl 		/*
   3426   1.96      fvdl 		 * Target does not support the PPR message.
   3427   1.96      fvdl 		 * Attempt to negotiate SPI-2 style.
   3428   1.96      fvdl 		 */
   3429   1.96      fvdl 		if (bootverbose) {
   3430   1.96      fvdl 			printf("(%s:%c:%d:%d): PPR Rejected. "
   3431   1.96      fvdl 			       "Trying WDTR/SDTR\n",
   3432   1.96      fvdl 			       ahc_name(ahc), devinfo->channel,
   3433   1.96      fvdl 			       devinfo->target, devinfo->lun);
   3434   1.96      fvdl 		}
   3435   1.96      fvdl 		tinfo->goal.ppr_options = 0;
   3436   1.96      fvdl 		tinfo->curr.transport_version = 2;
   3437   1.96      fvdl 		tinfo->goal.transport_version = 2;
   3438   1.96      fvdl 		ahc->msgout_index = 0;
   3439   1.96      fvdl 		ahc->msgout_len = 0;
   3440   1.96      fvdl 		ahc_build_transfer_msg(ahc, devinfo);
   3441   1.96      fvdl 		ahc->msgout_index = 0;
   3442   1.96      fvdl 		response = 1;
   3443   1.96      fvdl 	} else if (ahc_sent_msg(ahc, AHCMSG_EXT, MSG_EXT_WDTR, /*full*/FALSE)) {
   3444   1.42      fvdl 
   3445   1.96      fvdl 		/* note 8bit xfers */
   3446   1.96      fvdl 		if (bootverbose)
   3447   1.96      fvdl 			printf("(%s:%c:%d:%d): refuses WIDE negotiation. Using "
   3448   1.96      fvdl 			       "8bit transfers\n", ahc_name(ahc),
   3449   1.96      fvdl 			       devinfo->channel, devinfo->target, devinfo->lun);
   3450   1.96      fvdl 		ahc_set_width(ahc, devinfo, MSG_EXT_WDTR_BUS_8_BIT,
   3451   1.96      fvdl 			      AHC_TRANS_ACTIVE|AHC_TRANS_GOAL,
   3452   1.96      fvdl 			      /*paused*/TRUE);
   3453   1.96      fvdl 		/*
   3454   1.96      fvdl 		 * No need to clear the sync rate.  If the target
   3455   1.96      fvdl 		 * did not accept the command, our syncrate is
   3456   1.96      fvdl 		 * unaffected.  If the target started the negotiation,
   3457   1.96      fvdl 		 * but rejected our response, we already cleared the
   3458   1.96      fvdl 		 * sync rate before sending our WDTR.
   3459   1.96      fvdl 		 */
   3460   1.96      fvdl 		if (tinfo->goal.offset != tinfo->curr.offset) {
   3461   1.42      fvdl 
   3462   1.96      fvdl 			/* Start the sync negotiation */
   3463   1.96      fvdl 			ahc->msgout_index = 0;
   3464   1.96      fvdl 			ahc->msgout_len = 0;
   3465   1.96      fvdl 			ahc_build_transfer_msg(ahc, devinfo);
   3466   1.96      fvdl 			ahc->msgout_index = 0;
   3467   1.96      fvdl 			response = 1;
   3468   1.96      fvdl 		}
   3469   1.96      fvdl 	} else if (ahc_sent_msg(ahc, AHCMSG_EXT, MSG_EXT_SDTR, /*full*/FALSE)) {
   3470   1.96      fvdl 		/* note asynch xfers and clear flag */
   3471   1.96      fvdl 		ahc_set_syncrate(ahc, devinfo, /*syncrate*/NULL, /*period*/0,
   3472   1.96      fvdl 				 /*offset*/0, /*ppr_options*/0,
   3473   1.96      fvdl 				 AHC_TRANS_ACTIVE|AHC_TRANS_GOAL,
   3474   1.96      fvdl 				 /*paused*/TRUE);
   3475   1.96      fvdl 		if (bootverbose)
   3476   1.96      fvdl 			printf("(%s:%c:%d:%d): refuses synchronous negotiation."
   3477   1.96      fvdl 			       " Using asynchronous transfers\n",
   3478   1.96      fvdl 			       ahc_name(ahc), devinfo->channel,
   3479   1.96      fvdl 			       devinfo->target, devinfo->lun);
   3480   1.96      fvdl 	} else if ((scb->hscb->control & MSG_SIMPLE_TASK) != 0) {
   3481   1.96      fvdl 		int tag_type;
   3482   1.96      fvdl 		int mask;
   3483   1.96      fvdl 
   3484   1.96      fvdl 		tag_type = (scb->hscb->control & MSG_SIMPLE_TASK);
   3485   1.96      fvdl 
   3486   1.96      fvdl 		if (tag_type == MSG_SIMPLE_TASK) {
   3487   1.96      fvdl 			if (bootverbose)
   3488   1.96      fvdl 				printf("(%s:%c:%d:%d): refuses tagged commands."
   3489   1.96      fvdl 				       " Performing non-tagged I/O\n",
   3490   1.96      fvdl 					ahc_name(ahc), devinfo->channel,
   3491   1.96      fvdl 					devinfo->target, devinfo->lun);
   3492   1.96      fvdl 			ahc_set_tags(ahc, devinfo, AHC_QUEUE_NONE);
   3493   1.96      fvdl 			mask = ~0x23;
   3494   1.96      fvdl 		} else {
   3495   1.96      fvdl 			if (bootverbose)
   3496   1.96      fvdl 				printf("(%s:%c:%d:%d): refuses %s tagged "
   3497   1.96      fvdl 				       "commands. Performing simple queue "
   3498   1.96      fvdl 				       "tagged I/O only\n",
   3499   1.96      fvdl 				       ahc_name(ahc), devinfo->channel,
   3500   1.96      fvdl 				       devinfo->target, devinfo->lun,
   3501   1.96      fvdl 				       tag_type == MSG_ORDERED_TASK
   3502   1.96      fvdl 				         ? "ordered" : "head of queue");
   3503   1.96      fvdl 			ahc_set_tags(ahc, devinfo, AHC_QUEUE_BASIC);
   3504   1.96      fvdl 			mask = ~0x03;
   3505   1.96      fvdl 		}
   3506   1.42      fvdl 
   3507   1.96      fvdl 		/*
   3508   1.96      fvdl 		 * Resend the identify for this CCB as the target
   3509   1.96      fvdl 		 * may believe that the selection is invalid otherwise.
   3510   1.96      fvdl 		 */
   3511   1.96      fvdl 		ahc_outb(ahc, SCB_CONTROL,
   3512   1.96      fvdl 			 ahc_inb(ahc, SCB_CONTROL) & mask);
   3513   1.96      fvdl 	 	scb->hscb->control &= mask;
   3514   1.96      fvdl 		ahc_set_transaction_tag(scb, /*enabled*/FALSE,
   3515   1.96      fvdl 					/*type*/MSG_SIMPLE_TASK);
   3516   1.96      fvdl 		ahc_outb(ahc, MSG_OUT, MSG_IDENTIFYFLAG);
   3517   1.96      fvdl 		ahc_assert_atn(ahc);
   3518   1.42      fvdl 
   3519   1.96      fvdl 		/*
   3520   1.96      fvdl 		 * This transaction is now at the head of
   3521   1.96      fvdl 		 * the untagged queue for this target.
   3522   1.96      fvdl 		 */
   3523   1.96      fvdl 		if ((ahc->flags & AHC_SCB_BTT) == 0) {
   3524   1.96      fvdl 			struct scb_tailq *untagged_q;
   3525   1.42      fvdl 
   3526   1.96      fvdl 			untagged_q =
   3527   1.96      fvdl 			    &(ahc->untagged_queues[devinfo->target_offset]);
   3528   1.96      fvdl 			TAILQ_INSERT_HEAD(untagged_q, scb, links.tqe);
   3529   1.96      fvdl 			scb->flags |= SCB_UNTAGGEDQ;
   3530   1.42      fvdl 		}
   3531   1.96      fvdl 		ahc_busy_tcl(ahc, BUILD_TCL(scb->hscb->scsiid, devinfo->lun),
   3532   1.96      fvdl 			     scb->hscb->tag);
   3533   1.96      fvdl 
   3534   1.96      fvdl 		/*
   3535   1.96      fvdl 		 * Requeue all tagged commands for this target
   3536  1.108       wiz 		 * currently in our possession so they can be
   3537   1.96      fvdl 		 * converted to untagged commands.
   3538   1.96      fvdl 		 */
   3539   1.96      fvdl 		ahc_search_qinfifo(ahc, SCB_GET_TARGET(ahc, scb),
   3540   1.96      fvdl 				   SCB_GET_CHANNEL(ahc, scb),
   3541   1.96      fvdl 				   SCB_GET_LUN(scb), /*tag*/SCB_LIST_NULL,
   3542   1.96      fvdl 				   ROLE_INITIATOR, CAM_REQUEUE_REQ,
   3543   1.96      fvdl 				   SEARCH_COMPLETE);
   3544   1.96      fvdl 	} else {
   3545   1.96      fvdl 		/*
   3546   1.96      fvdl 		 * Otherwise, we ignore it.
   3547   1.96      fvdl 		 */
   3548   1.96      fvdl 		if (bootverbose)
   3549   1.96      fvdl 			printf("%s:%c:%d: Message reject for %x -- ignored\n",
   3550   1.96      fvdl 			       ahc_name(ahc), devinfo->channel, devinfo->target,
   3551   1.96      fvdl 			       last_msg);
   3552   1.42      fvdl 	}
   3553   1.96      fvdl 	return (response);
   3554   1.42      fvdl }
   3555   1.42      fvdl 
   3556   1.96      fvdl /*
   3557   1.96      fvdl  * Process an ingnore wide residue message.
   3558   1.96      fvdl  */
   3559   1.42      fvdl static void
   3560  1.122  christos ahc_handle_ign_wide_residue(struct ahc_softc *ahc,
   3561  1.123  christos     struct ahc_devinfo *devinfo)
   3562   1.42      fvdl {
   3563   1.96      fvdl 	u_int scb_index;
   3564   1.96      fvdl 	struct scb *scb;
   3565   1.42      fvdl 
   3566   1.96      fvdl 	scb_index = ahc_inb(ahc, SCB_TAG);
   3567   1.96      fvdl 	scb = ahc_lookup_scb(ahc, scb_index);
   3568   1.96      fvdl 	/*
   3569   1.96      fvdl 	 * XXX Actually check data direction in the sequencer?
   3570   1.96      fvdl 	 * Perhaps add datadir to some spare bits in the hscb?
   3571   1.96      fvdl 	 */
   3572   1.96      fvdl 	if ((ahc_inb(ahc, SEQ_FLAGS) & DPHASE) == 0
   3573   1.96      fvdl 	 || ahc_get_transfer_dir(scb) != CAM_DIR_IN) {
   3574   1.96      fvdl 		/*
   3575   1.96      fvdl 		 * Ignore the message if we haven't
   3576   1.96      fvdl 		 * seen an appropriate data phase yet.
   3577   1.96      fvdl 		 */
   3578   1.42      fvdl 	} else {
   3579   1.96      fvdl 		/*
   3580   1.96      fvdl 		 * If the residual occurred on the last
   3581   1.96      fvdl 		 * transfer and the transfer request was
   3582   1.96      fvdl 		 * expected to end on an odd count, do
   3583   1.96      fvdl 		 * nothing.  Otherwise, subtract a byte
   3584   1.96      fvdl 		 * and update the residual count accordingly.
   3585   1.96      fvdl 		 */
   3586   1.96      fvdl 		uint32_t sgptr;
   3587   1.42      fvdl 
   3588   1.96      fvdl 		sgptr = ahc_inb(ahc, SCB_RESIDUAL_SGPTR);
   3589   1.96      fvdl 		if ((sgptr & SG_LIST_NULL) != 0
   3590   1.96      fvdl 		 && ahc_inb(ahc, DATA_COUNT_ODD) == 1) {
   3591   1.96      fvdl 			/*
   3592   1.96      fvdl 			 * If the residual occurred on the last
   3593   1.96      fvdl 			 * transfer and the transfer request was
   3594   1.96      fvdl 			 * expected to end on an odd count, do
   3595   1.96      fvdl 			 * nothing.
   3596   1.96      fvdl 			 */
   3597   1.42      fvdl 		} else {
   3598   1.96      fvdl 			struct ahc_dma_seg *sg;
   3599   1.96      fvdl 			uint32_t data_cnt;
   3600   1.96      fvdl 			uint32_t data_addr;
   3601   1.96      fvdl 			uint32_t sglen;
   3602   1.96      fvdl 
   3603   1.96      fvdl 			/* Pull in the rest of the sgptr */
   3604   1.96      fvdl 			sgptr |= (ahc_inb(ahc, SCB_RESIDUAL_SGPTR + 3) << 24)
   3605   1.96      fvdl 			      | (ahc_inb(ahc, SCB_RESIDUAL_SGPTR + 2) << 16)
   3606   1.96      fvdl 			      | (ahc_inb(ahc, SCB_RESIDUAL_SGPTR + 1) << 8);
   3607   1.96      fvdl 			sgptr &= SG_PTR_MASK;
   3608   1.96      fvdl 			data_cnt = (ahc_inb(ahc, SCB_RESIDUAL_DATACNT+3) << 24)
   3609   1.96      fvdl 				 | (ahc_inb(ahc, SCB_RESIDUAL_DATACNT+2) << 16)
   3610   1.96      fvdl 				 | (ahc_inb(ahc, SCB_RESIDUAL_DATACNT+1) << 8)
   3611   1.96      fvdl 				 | (ahc_inb(ahc, SCB_RESIDUAL_DATACNT));
   3612   1.42      fvdl 
   3613   1.96      fvdl 			data_addr = (ahc_inb(ahc, SHADDR + 3) << 24)
   3614   1.96      fvdl 				  | (ahc_inb(ahc, SHADDR + 2) << 16)
   3615   1.96      fvdl 				  | (ahc_inb(ahc, SHADDR + 1) << 8)
   3616   1.96      fvdl 				  | (ahc_inb(ahc, SHADDR));
   3617   1.42      fvdl 
   3618   1.96      fvdl 			data_cnt += 1;
   3619   1.96      fvdl 			data_addr -= 1;
   3620   1.42      fvdl 
   3621   1.96      fvdl 			sg = ahc_sg_bus_to_virt(scb, sgptr);
   3622   1.42      fvdl 			/*
   3623   1.96      fvdl 			 * The residual sg ptr points to the next S/G
   3624   1.96      fvdl 			 * to load so we must go back one.
   3625   1.42      fvdl 			 */
   3626   1.96      fvdl 			sg--;
   3627   1.96      fvdl 			sglen = ahc_le32toh(sg->len) & AHC_SG_LEN_MASK;
   3628   1.96      fvdl 			if (sg != scb->sg_list
   3629   1.96      fvdl 			 && sglen < (data_cnt & AHC_SG_LEN_MASK)) {
   3630   1.96      fvdl 
   3631   1.96      fvdl 				sg--;
   3632   1.96      fvdl 				sglen = ahc_le32toh(sg->len);
   3633   1.96      fvdl 				/*
   3634   1.96      fvdl 				 * Preserve High Address and SG_LIST bits
   3635   1.96      fvdl 				 * while setting the count to 1.
   3636   1.96      fvdl 				 */
   3637   1.96      fvdl 				data_cnt = 1 | (sglen & (~AHC_SG_LEN_MASK));
   3638   1.96      fvdl 				data_addr = ahc_le32toh(sg->addr)
   3639   1.96      fvdl 					  + (sglen & AHC_SG_LEN_MASK) - 1;
   3640   1.96      fvdl 
   3641   1.96      fvdl 				/*
   3642   1.96      fvdl 				 * Increment sg so it points to the
   3643   1.96      fvdl 				 * "next" sg.
   3644   1.96      fvdl 				 */
   3645   1.96      fvdl 				sg++;
   3646   1.96      fvdl 				sgptr = ahc_sg_virt_to_bus(scb, sg);
   3647   1.96      fvdl 				ahc_outb(ahc, SCB_RESIDUAL_SGPTR + 3,
   3648   1.96      fvdl 					 sgptr >> 24);
   3649   1.96      fvdl 				ahc_outb(ahc, SCB_RESIDUAL_SGPTR + 2,
   3650   1.96      fvdl 					 sgptr >> 16);
   3651   1.96      fvdl 				ahc_outb(ahc, SCB_RESIDUAL_SGPTR + 1,
   3652   1.96      fvdl 					 sgptr >> 8);
   3653   1.96      fvdl 				ahc_outb(ahc, SCB_RESIDUAL_SGPTR, sgptr);
   3654   1.42      fvdl 			}
   3655   1.42      fvdl 
   3656   1.96      fvdl 			ahc_outb(ahc, SCB_RESIDUAL_DATACNT + 3, data_cnt >> 24);
   3657   1.96      fvdl 			ahc_outb(ahc, SCB_RESIDUAL_DATACNT + 2, data_cnt >> 16);
   3658   1.96      fvdl 			ahc_outb(ahc, SCB_RESIDUAL_DATACNT + 1, data_cnt >> 8);
   3659   1.96      fvdl 			ahc_outb(ahc, SCB_RESIDUAL_DATACNT, data_cnt);
   3660   1.42      fvdl 		}
   3661   1.96      fvdl 	}
   3662   1.96      fvdl }
   3663   1.42      fvdl 
   3664   1.42      fvdl 
   3665   1.96      fvdl /*
   3666   1.96      fvdl  * Reinitialize the data pointers for the active transfer
   3667   1.96      fvdl  * based on its current residual.
   3668   1.96      fvdl  */
   3669   1.96      fvdl static void
   3670   1.96      fvdl ahc_reinitialize_dataptrs(struct ahc_softc *ahc)
   3671   1.96      fvdl {
   3672   1.96      fvdl 	struct	 scb *scb;
   3673   1.96      fvdl 	struct	 ahc_dma_seg *sg;
   3674   1.96      fvdl 	u_int	 scb_index;
   3675   1.96      fvdl 	uint32_t sgptr;
   3676   1.96      fvdl 	uint32_t resid;
   3677   1.96      fvdl 	uint32_t dataptr;
   3678   1.42      fvdl 
   3679   1.96      fvdl 	scb_index = ahc_inb(ahc, SCB_TAG);
   3680   1.96      fvdl 	scb = ahc_lookup_scb(ahc, scb_index);
   3681   1.96      fvdl 	sgptr = (ahc_inb(ahc, SCB_RESIDUAL_SGPTR + 3) << 24)
   3682   1.96      fvdl 	      | (ahc_inb(ahc, SCB_RESIDUAL_SGPTR + 2) << 16)
   3683   1.96      fvdl 	      | (ahc_inb(ahc, SCB_RESIDUAL_SGPTR + 1) << 8)
   3684   1.96      fvdl 	      |	ahc_inb(ahc, SCB_RESIDUAL_SGPTR);
   3685   1.96      fvdl 
   3686   1.96      fvdl 	sgptr &= SG_PTR_MASK;
   3687   1.96      fvdl 	sg = ahc_sg_bus_to_virt(scb, sgptr);
   3688   1.96      fvdl 
   3689   1.96      fvdl 	/* The residual sg_ptr always points to the next sg */
   3690   1.96      fvdl 	sg--;
   3691   1.96      fvdl 
   3692   1.96      fvdl 	resid = (ahc_inb(ahc, SCB_RESIDUAL_DATACNT + 2) << 16)
   3693   1.96      fvdl 	      | (ahc_inb(ahc, SCB_RESIDUAL_DATACNT + 1) << 8)
   3694   1.96      fvdl 	      | ahc_inb(ahc, SCB_RESIDUAL_DATACNT);
   3695   1.96      fvdl 
   3696   1.96      fvdl 	dataptr = ahc_le32toh(sg->addr)
   3697   1.96      fvdl 		+ (ahc_le32toh(sg->len) & AHC_SG_LEN_MASK)
   3698   1.96      fvdl 		- resid;
   3699   1.96      fvdl 	if ((ahc->flags & AHC_39BIT_ADDRESSING) != 0) {
   3700   1.96      fvdl 		u_int dscommand1;
   3701   1.96      fvdl 
   3702   1.96      fvdl 		dscommand1 = ahc_inb(ahc, DSCOMMAND1);
   3703   1.96      fvdl 		ahc_outb(ahc, DSCOMMAND1, dscommand1 | HADDLDSEL0);
   3704   1.96      fvdl 		ahc_outb(ahc, HADDR,
   3705   1.96      fvdl 			 (ahc_le32toh(sg->len) >> 24) & SG_HIGH_ADDR_BITS);
   3706   1.96      fvdl 		ahc_outb(ahc, DSCOMMAND1, dscommand1);
   3707   1.96      fvdl 	}
   3708   1.96      fvdl 	ahc_outb(ahc, HADDR + 3, dataptr >> 24);
   3709   1.96      fvdl 	ahc_outb(ahc, HADDR + 2, dataptr >> 16);
   3710   1.96      fvdl 	ahc_outb(ahc, HADDR + 1, dataptr >> 8);
   3711   1.96      fvdl 	ahc_outb(ahc, HADDR, dataptr);
   3712   1.96      fvdl 	ahc_outb(ahc, HCNT + 2, resid >> 16);
   3713   1.96      fvdl 	ahc_outb(ahc, HCNT + 1, resid >> 8);
   3714   1.96      fvdl 	ahc_outb(ahc, HCNT, resid);
   3715   1.96      fvdl 	if ((ahc->features & AHC_ULTRA2) == 0) {
   3716   1.96      fvdl 		ahc_outb(ahc, STCNT + 2, resid >> 16);
   3717   1.96      fvdl 		ahc_outb(ahc, STCNT + 1, resid >> 8);
   3718   1.96      fvdl 		ahc_outb(ahc, STCNT, resid);
   3719   1.42      fvdl 	}
   3720   1.42      fvdl }
   3721   1.42      fvdl 
   3722   1.96      fvdl /*
   3723   1.96      fvdl  * Handle the effects of issuing a bus device reset message.
   3724   1.96      fvdl  */
   3725   1.42      fvdl static void
   3726   1.96      fvdl ahc_handle_devreset(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
   3727  1.114  christos 		    cam_status status, const char *message, int verbose_level)
   3728   1.42      fvdl {
   3729   1.96      fvdl #ifdef AHC_TARGET_MODE
   3730   1.96      fvdl 	struct ahc_tmode_tstate* tstate;
   3731   1.96      fvdl 	u_int lun;
   3732   1.96      fvdl #endif
   3733   1.96      fvdl 	int found;
   3734   1.42      fvdl 
   3735   1.96      fvdl 	found = ahc_abort_scbs(ahc, devinfo->target, devinfo->channel,
   3736   1.96      fvdl 			       CAM_LUN_WILDCARD, SCB_LIST_NULL, devinfo->role,
   3737   1.96      fvdl 			       status);
   3738   1.42      fvdl 
   3739   1.96      fvdl #ifdef AHC_TARGET_MODE
   3740   1.96      fvdl 	/*
   3741   1.96      fvdl 	 * Send an immediate notify ccb to all target mord peripheral
   3742   1.96      fvdl 	 * drivers affected by this action.
   3743   1.96      fvdl 	 */
   3744   1.96      fvdl 	tstate = ahc->enabled_targets[devinfo->our_scsiid];
   3745   1.96      fvdl 	if (tstate != NULL) {
   3746   1.96      fvdl 		for (lun = 0; lun < AHC_NUM_LUNS; lun++) {
   3747   1.96      fvdl 			struct ahc_tmode_lstate* lstate;
   3748   1.42      fvdl 
   3749   1.96      fvdl 			lstate = tstate->enabled_luns[lun];
   3750   1.96      fvdl 			if (lstate == NULL)
   3751   1.96      fvdl 				continue;
   3752   1.42      fvdl 
   3753   1.96      fvdl 			ahc_queue_lstate_event(ahc, lstate, devinfo->our_scsiid,
   3754   1.96      fvdl 					       MSG_BUS_DEV_RESET, /*arg*/0);
   3755   1.96      fvdl 			ahc_send_lstate_events(ahc, lstate);
   3756   1.96      fvdl 		}
   3757   1.42      fvdl 	}
   3758   1.96      fvdl #endif
   3759   1.42      fvdl 
   3760   1.96      fvdl 	/*
   3761   1.96      fvdl 	 * Go back to async/narrow transfers and renegotiate.
   3762   1.96      fvdl 	 */
   3763   1.96      fvdl 	ahc_set_width(ahc, devinfo, MSG_EXT_WDTR_BUS_8_BIT,
   3764   1.96      fvdl 		      AHC_TRANS_CUR, /*paused*/TRUE);
   3765   1.96      fvdl 	ahc_set_syncrate(ahc, devinfo, /*syncrate*/NULL,
   3766   1.96      fvdl 			 /*period*/0, /*offset*/0, /*ppr_options*/0,
   3767   1.96      fvdl 			 AHC_TRANS_CUR, /*paused*/TRUE);
   3768  1.112     perry 
   3769   1.96      fvdl 	ahc_send_async(ahc, devinfo->channel, devinfo->target,
   3770   1.96      fvdl 	  CAM_LUN_WILDCARD, AC_SENT_BDR, NULL);
   3771   1.42      fvdl 
   3772   1.96      fvdl 	if (message != NULL
   3773   1.96      fvdl 	 && (verbose_level <= bootverbose))
   3774   1.96      fvdl 		printf("%s: %s on %c:%d. %d SCBs aborted\n", ahc_name(ahc),
   3775   1.96      fvdl 		       message, devinfo->channel, devinfo->target, found);
   3776   1.42      fvdl }
   3777   1.42      fvdl 
   3778   1.96      fvdl #ifdef AHC_TARGET_MODE
   3779   1.42      fvdl static void
   3780   1.96      fvdl ahc_setup_target_msgin(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
   3781   1.96      fvdl 		       struct scb *scb)
   3782   1.42      fvdl {
   3783   1.42      fvdl 
   3784  1.112     perry 	/*
   3785   1.96      fvdl 	 * To facilitate adding multiple messages together,
   3786   1.96      fvdl 	 * each routine should increment the index and len
   3787   1.96      fvdl 	 * variables instead of setting them explicitly.
   3788  1.112     perry 	 */
   3789   1.96      fvdl 	ahc->msgout_index = 0;
   3790   1.96      fvdl 	ahc->msgout_len = 0;
   3791   1.96      fvdl 
   3792   1.96      fvdl 	if (scb != NULL && (scb->flags & SCB_AUTO_NEGOTIATE) != 0)
   3793   1.96      fvdl 		ahc_build_transfer_msg(ahc, devinfo);
   3794   1.96      fvdl 	else
   3795   1.96      fvdl 		panic("ahc_intr: AWAITING target message with no message");
   3796   1.96      fvdl 
   3797   1.96      fvdl 	ahc->msgout_index = 0;
   3798   1.96      fvdl 	ahc->msg_type = MSG_TYPE_TARGET_MSGIN;
   3799   1.96      fvdl }
   3800   1.96      fvdl #endif
   3801   1.96      fvdl 
   3802   1.96      fvdl int
   3803   1.96      fvdl ahc_softc_init(struct ahc_softc *ahc)
   3804   1.96      fvdl {
   3805   1.42      fvdl 
   3806   1.96      fvdl 	/* The IRQMS bit is only valid on VL and EISA chips */
   3807   1.96      fvdl 	if ((ahc->chip & AHC_PCI) == 0)
   3808   1.96      fvdl 		ahc->unpause = ahc_inb(ahc, HCNTRL) & IRQMS;
   3809   1.96      fvdl 	else
   3810   1.96      fvdl 		ahc->unpause = 0;
   3811  1.112     perry 	ahc->pause = ahc->unpause | PAUSE;
   3812   1.96      fvdl 	/* XXX The shared scb data stuff should be deprecated */
   3813   1.96      fvdl 	if (ahc->scb_data == NULL) {
   3814   1.96      fvdl 		ahc->scb_data = malloc(sizeof(*ahc->scb_data),
   3815   1.96      fvdl 				       M_DEVBUF, M_NOWAIT);
   3816   1.96      fvdl 		if (ahc->scb_data == NULL)
   3817   1.96      fvdl 			return (ENOMEM);
   3818   1.96      fvdl 		memset(ahc->scb_data, 0, sizeof(*ahc->scb_data));
   3819   1.49      fvdl 	}
   3820   1.96      fvdl 
   3821   1.96      fvdl 	return (0);
   3822   1.42      fvdl }
   3823   1.42      fvdl 
   3824   1.96      fvdl void
   3825   1.96      fvdl ahc_softc_insert(struct ahc_softc *ahc)
   3826   1.71    bouyer {
   3827   1.96      fvdl 	struct ahc_softc *list_ahc;
   3828   1.71    bouyer 
   3829   1.96      fvdl #if AHC_PCI_CONFIG > 0
   3830   1.96      fvdl 	/*
   3831   1.96      fvdl 	 * Second Function PCI devices need to inherit some
   3832   1.96      fvdl 	 * settings from function 0.
   3833   1.96      fvdl 	 */
   3834   1.96      fvdl 	if ((ahc->chip & AHC_BUS_MASK) == AHC_PCI
   3835   1.96      fvdl 	 && (ahc->features & AHC_MULTI_FUNC) != 0) {
   3836   1.96      fvdl 		TAILQ_FOREACH(list_ahc, &ahc_tailq, links) {
   3837   1.96      fvdl 			ahc_dev_softc_t list_pci;
   3838   1.96      fvdl 			ahc_dev_softc_t pci;
   3839   1.96      fvdl 
   3840   1.96      fvdl 			list_pci = list_ahc->dev_softc;
   3841   1.96      fvdl 			pci = ahc->dev_softc;
   3842   1.96      fvdl 			if (ahc_get_pci_slot(list_pci) == ahc_get_pci_slot(pci)
   3843   1.96      fvdl 			 && ahc_get_pci_bus(list_pci) == ahc_get_pci_bus(pci)) {
   3844   1.96      fvdl 				struct ahc_softc *master;
   3845   1.96      fvdl 				struct ahc_softc *slave;
   3846   1.96      fvdl 
   3847   1.96      fvdl 				if (ahc_get_pci_function(list_pci) == 0) {
   3848   1.96      fvdl 					master = list_ahc;
   3849   1.96      fvdl 					slave = ahc;
   3850   1.96      fvdl 				} else {
   3851   1.96      fvdl 					master = ahc;
   3852   1.96      fvdl 					slave = list_ahc;
   3853   1.96      fvdl 				}
   3854  1.112     perry 				slave->flags &= ~AHC_BIOS_ENABLED;
   3855   1.96      fvdl 				slave->flags |=
   3856   1.96      fvdl 				    master->flags & AHC_BIOS_ENABLED;
   3857  1.112     perry 				slave->flags &= ~AHC_PRIMARY_CHANNEL;
   3858   1.96      fvdl 				slave->flags |=
   3859   1.96      fvdl 				    master->flags & AHC_PRIMARY_CHANNEL;
   3860   1.96      fvdl 				break;
   3861   1.96      fvdl 			}
   3862   1.96      fvdl 		}
   3863   1.96      fvdl 	}
   3864   1.96      fvdl #endif
   3865   1.71    bouyer 
   3866   1.96      fvdl 	/*
   3867   1.96      fvdl 	 * Insertion sort into our list of softcs.
   3868   1.96      fvdl 	 */
   3869   1.96      fvdl 	list_ahc = TAILQ_FIRST(&ahc_tailq);
   3870   1.96      fvdl 	while (list_ahc != NULL
   3871   1.96      fvdl 	    && ahc_softc_comp(list_ahc, ahc) <= 0)
   3872   1.96      fvdl 		list_ahc = TAILQ_NEXT(list_ahc, links);
   3873   1.96      fvdl 	if (list_ahc != NULL)
   3874   1.96      fvdl 		TAILQ_INSERT_BEFORE(list_ahc, ahc, links);
   3875   1.96      fvdl 	else
   3876   1.96      fvdl 		TAILQ_INSERT_TAIL(&ahc_tailq, ahc, links);
   3877   1.96      fvdl 	ahc->init_level++;
   3878   1.71    bouyer }
   3879   1.71    bouyer 
   3880   1.42      fvdl /*
   3881   1.96      fvdl  * Verify that the passed in softc pointer is for a
   3882   1.96      fvdl  * controller that is still configured.
   3883   1.42      fvdl  */
   3884   1.96      fvdl struct ahc_softc *
   3885   1.96      fvdl ahc_find_softc(struct ahc_softc *ahc)
   3886   1.42      fvdl {
   3887   1.96      fvdl 	struct ahc_softc *list_ahc;
   3888   1.42      fvdl 
   3889   1.96      fvdl 	TAILQ_FOREACH(list_ahc, &ahc_tailq, links) {
   3890   1.96      fvdl 		if (list_ahc == ahc)
   3891   1.96      fvdl 			return (ahc);
   3892   1.42      fvdl 	}
   3893   1.96      fvdl 	return (NULL);
   3894   1.86    ichiro }
   3895   1.86    ichiro 
   3896   1.96      fvdl void
   3897   1.96      fvdl ahc_set_unit(struct ahc_softc *ahc, int unit)
   3898   1.86    ichiro {
   3899   1.96      fvdl 	ahc->unit = unit;
   3900   1.96      fvdl }
   3901   1.86    ichiro 
   3902   1.96      fvdl void
   3903   1.96      fvdl ahc_set_name(struct ahc_softc *ahc, char *name)
   3904   1.96      fvdl {
   3905   1.96      fvdl 	if (ahc->name != NULL)
   3906   1.96      fvdl 		free(ahc->name, M_DEVBUF);
   3907   1.96      fvdl 	ahc->name = name;
   3908   1.86    ichiro }
   3909   1.86    ichiro 
   3910   1.96      fvdl void
   3911   1.96      fvdl ahc_free(struct ahc_softc *ahc)
   3912   1.86    ichiro {
   3913   1.96      fvdl 	int i;
   3914   1.86    ichiro 
   3915   1.96      fvdl 	ahc_fini_scbdata(ahc);
   3916   1.96      fvdl 	switch (ahc->init_level) {
   3917   1.96      fvdl 	default:
   3918   1.96      fvdl 	case 2:
   3919   1.96      fvdl 		ahc_shutdown(ahc);
   3920  1.104      fvdl 		/* TAILQ_REMOVE(&ahc_tailq, ahc, links); XXX */
   3921   1.96      fvdl 		/* FALLTHROUGH */
   3922   1.96      fvdl 	case 1:
   3923   1.96      fvdl 		bus_dmamap_unload(ahc->parent_dmat, ahc->shared_data_dmamap);
   3924   1.96      fvdl 		bus_dmamap_destroy(ahc->parent_dmat, ahc->shared_data_dmamap);
   3925   1.96      fvdl 		bus_dmamem_unmap(ahc->parent_dmat, (caddr_t)ahc->qoutfifo, ahc->shared_data_size);
   3926   1.96      fvdl 		bus_dmamem_free(ahc->parent_dmat, &ahc->shared_data_seg, ahc->shared_data_nseg);
   3927   1.86    ichiro 		break;
   3928   1.96      fvdl 	case 0:
   3929   1.86    ichiro 		break;
   3930   1.86    ichiro 	}
   3931   1.86    ichiro 
   3932   1.96      fvdl 	ahc_platform_free(ahc);
   3933   1.96      fvdl 	for (i = 0; i < AHC_NUM_TARGETS; i++) {
   3934   1.96      fvdl 		struct ahc_tmode_tstate *tstate;
   3935   1.96      fvdl 
   3936   1.96      fvdl 		tstate = ahc->enabled_targets[i];
   3937   1.96      fvdl 		if (tstate != NULL) {
   3938   1.96      fvdl #if AHC_TARGET_MODE
   3939   1.96      fvdl 			int j;
   3940   1.96      fvdl 
   3941   1.96      fvdl 			for (j = 0; j < AHC_NUM_LUNS; j++) {
   3942   1.96      fvdl 				struct ahc_tmode_lstate *lstate;
   3943   1.96      fvdl 
   3944   1.96      fvdl 				lstate = tstate->enabled_luns[j];
   3945   1.96      fvdl 				if (lstate != NULL) {
   3946   1.96      fvdl 					  /*xpt_free_path(lstate->path);*/
   3947   1.96      fvdl 					free(lstate, M_DEVBUF);
   3948   1.96      fvdl 				}
   3949   1.96      fvdl 			}
   3950   1.96      fvdl #endif
   3951   1.96      fvdl 			free(tstate, M_DEVBUF);
   3952   1.96      fvdl 		}
   3953   1.96      fvdl 	}
   3954   1.96      fvdl #if AHC_TARGET_MODE
   3955   1.96      fvdl 	if (ahc->black_hole != NULL) {
   3956   1.96      fvdl 	  /*xpt_free_path(ahc->black_hole->path);*/
   3957   1.96      fvdl 		free(ahc->black_hole, M_DEVBUF);
   3958   1.96      fvdl 	}
   3959   1.96      fvdl #endif
   3960  1.104      fvdl #ifndef __NetBSD__
   3961   1.96      fvdl 	if (ahc->name != NULL)
   3962   1.96      fvdl 		free(ahc->name, M_DEVBUF);
   3963  1.104      fvdl #endif
   3964   1.96      fvdl 	if (ahc->seep_config != NULL)
   3965   1.96      fvdl 		free(ahc->seep_config, M_DEVBUF);
   3966  1.115    bouyer #if !defined(__FreeBSD__) && !defined(__NetBSD__)
   3967   1.96      fvdl 	free(ahc, M_DEVBUF);
   3968   1.96      fvdl #endif
   3969   1.96      fvdl 	return;
   3970   1.42      fvdl }
   3971   1.42      fvdl 
   3972   1.96      fvdl void
   3973   1.96      fvdl ahc_shutdown(void *arg)
   3974   1.42      fvdl {
   3975   1.96      fvdl 	struct	ahc_softc *ahc;
   3976   1.96      fvdl 	int	i;
   3977   1.42      fvdl 
   3978   1.96      fvdl 	ahc = (struct ahc_softc *)arg;
   3979   1.42      fvdl 
   3980   1.96      fvdl 	/* This will reset most registers to 0, but not all */
   3981   1.96      fvdl 	ahc_reset(ahc);
   3982   1.96      fvdl 	ahc_outb(ahc, SCSISEQ, 0);
   3983   1.96      fvdl 	ahc_outb(ahc, SXFRCTL0, 0);
   3984   1.96      fvdl 	ahc_outb(ahc, DSPCISTATUS, 0);
   3985   1.42      fvdl 
   3986   1.96      fvdl 	for (i = TARG_SCSIRATE; i < SCSICONF; i++)
   3987   1.96      fvdl 		ahc_outb(ahc, i, 0);
   3988   1.42      fvdl }
   3989   1.42      fvdl 
   3990   1.42      fvdl /*
   3991   1.96      fvdl  * Reset the controller and record some information about it
   3992   1.96      fvdl  * that is only available just after a reset.
   3993   1.42      fvdl  */
   3994   1.42      fvdl int
   3995   1.96      fvdl ahc_reset(struct ahc_softc *ahc)
   3996   1.42      fvdl {
   3997   1.96      fvdl 	u_int	sblkctl;
   3998   1.96      fvdl 	u_int	sxfrctl1_a, sxfrctl1_b;
   3999   1.96      fvdl 	int	wait;
   4000  1.112     perry 
   4001   1.96      fvdl 	/*
   4002   1.96      fvdl 	 * Preserve the value of the SXFRCTL1 register for all channels.
   4003   1.96      fvdl 	 * It contains settings that affect termination and we don't want
   4004   1.96      fvdl 	 * to disturb the integrity of the bus.
   4005   1.96      fvdl 	 */
   4006   1.96      fvdl 	ahc_pause(ahc);
   4007   1.96      fvdl 	if ((ahc_inb(ahc, HCNTRL) & CHIPRST) != 0) {
   4008   1.96      fvdl 		/*
   4009   1.96      fvdl 		 * The chip has not been initialized since
   4010   1.96      fvdl 		 * PCI/EISA/VLB bus reset.  Don't trust
   4011   1.96      fvdl 		 * "left over BIOS data".
   4012   1.96      fvdl 		 */
   4013   1.96      fvdl 		ahc->flags |= AHC_NO_BIOS_INIT;
   4014   1.96      fvdl 	}
   4015   1.96      fvdl 	sxfrctl1_b = 0;
   4016   1.96      fvdl 	if ((ahc->chip & AHC_CHIPID_MASK) == AHC_AIC7770) {
   4017  1.114  christos 		u_int sblkctl1;
   4018   1.42      fvdl 
   4019   1.96      fvdl 		/*
   4020   1.96      fvdl 		 * Save channel B's settings in case this chip
   4021   1.96      fvdl 		 * is setup for TWIN channel operation.
   4022   1.96      fvdl 		 */
   4023  1.114  christos 		sblkctl1 = ahc_inb(ahc, SBLKCTL);
   4024  1.114  christos 		ahc_outb(ahc, SBLKCTL, sblkctl1 | SELBUSB);
   4025   1.96      fvdl 		sxfrctl1_b = ahc_inb(ahc, SXFRCTL1);
   4026  1.114  christos 		ahc_outb(ahc, SBLKCTL, sblkctl1 & ~SELBUSB);
   4027   1.96      fvdl 	}
   4028   1.96      fvdl 	sxfrctl1_a = ahc_inb(ahc, SXFRCTL1);
   4029   1.42      fvdl 
   4030   1.96      fvdl 	ahc_outb(ahc, HCNTRL, CHIPRST | ahc->pause);
   4031   1.42      fvdl 
   4032   1.42      fvdl 	/*
   4033   1.96      fvdl 	 * Ensure that the reset has finished.  We delay 1000us
   4034   1.96      fvdl 	 * prior to reading the register to make sure the chip
   4035   1.96      fvdl 	 * has sufficiently completed its reset to handle register
   4036   1.96      fvdl 	 * accesses.
   4037   1.42      fvdl 	 */
   4038   1.96      fvdl 	wait = 1000;
   4039   1.96      fvdl 	do {
   4040   1.96      fvdl 		ahc_delay(1000);
   4041   1.96      fvdl 	} while (--wait && !(ahc_inb(ahc, HCNTRL) & CHIPRSTACK));
   4042   1.42      fvdl 
   4043   1.96      fvdl 	if (wait == 0) {
   4044   1.96      fvdl 		printf("%s: WARNING - Failed chip reset!  "
   4045   1.96      fvdl 		       "Trying to initialize anyway.\n", ahc_name(ahc));
   4046   1.42      fvdl 	}
   4047   1.96      fvdl 	ahc_outb(ahc, HCNTRL, ahc->pause);
   4048   1.42      fvdl 
   4049   1.96      fvdl 	/* Determine channel configuration */
   4050   1.96      fvdl 	sblkctl = ahc_inb(ahc, SBLKCTL) & (SELBUSB|SELWIDE);
   4051   1.96      fvdl 	/* No Twin Channel PCI cards */
   4052   1.96      fvdl 	if ((ahc->chip & AHC_PCI) != 0)
   4053   1.96      fvdl 		sblkctl &= ~SELBUSB;
   4054   1.96      fvdl 	switch (sblkctl) {
   4055   1.96      fvdl 	case 0:
   4056   1.96      fvdl 		/* Single Narrow Channel */
   4057   1.96      fvdl 		break;
   4058   1.96      fvdl 	case 2:
   4059   1.96      fvdl 		/* Wide Channel */
   4060   1.96      fvdl 		ahc->features |= AHC_WIDE;
   4061   1.96      fvdl 		break;
   4062   1.96      fvdl 	case 8:
   4063   1.96      fvdl 		/* Twin Channel */
   4064   1.96      fvdl 		ahc->features |= AHC_TWIN;
   4065   1.96      fvdl 		break;
   4066   1.96      fvdl 	default:
   4067   1.96      fvdl 		printf(" Unsupported adapter type (0x%x).  Ignoring\n", sblkctl);
   4068   1.96      fvdl 		return(-1);
   4069   1.42      fvdl 	}
   4070   1.42      fvdl 
   4071   1.96      fvdl 	/*
   4072   1.96      fvdl 	 * Reload sxfrctl1.
   4073   1.96      fvdl 	 *
   4074   1.96      fvdl 	 * We must always initialize STPWEN to 1 before we
   4075   1.96      fvdl 	 * restore the saved values.  STPWEN is initialized
   4076   1.96      fvdl 	 * to a tri-state condition which can only be cleared
   4077   1.96      fvdl 	 * by turning it on.
   4078   1.96      fvdl 	 */
   4079   1.96      fvdl 	if ((ahc->features & AHC_TWIN) != 0) {
   4080  1.114  christos 		u_int sblkctl1;
   4081   1.42      fvdl 
   4082  1.114  christos 		sblkctl1 = ahc_inb(ahc, SBLKCTL);
   4083  1.114  christos 		ahc_outb(ahc, SBLKCTL, sblkctl1 | SELBUSB);
   4084   1.96      fvdl 		ahc_outb(ahc, SXFRCTL1, sxfrctl1_b);
   4085  1.114  christos 		ahc_outb(ahc, SBLKCTL, sblkctl1 & ~SELBUSB);
   4086   1.42      fvdl 	}
   4087   1.96      fvdl 	ahc_outb(ahc, SXFRCTL1, sxfrctl1_a);
   4088   1.42      fvdl 
   4089   1.96      fvdl #ifdef AHC_DUMP_SEQ
   4090   1.96      fvdl 	if (ahc->init_level == 0)
   4091   1.96      fvdl 		ahc_dumpseq(ahc);
   4092   1.96      fvdl #endif
   4093   1.42      fvdl 
   4094   1.96      fvdl 	return (0);
   4095   1.42      fvdl }
   4096   1.42      fvdl 
   4097   1.96      fvdl /*
   4098   1.96      fvdl  * Determine the number of SCBs available on the controller
   4099   1.96      fvdl  */
   4100   1.96      fvdl int
   4101   1.96      fvdl ahc_probe_scbs(struct ahc_softc *ahc) {
   4102   1.96      fvdl 	int i;
   4103   1.96      fvdl 
   4104   1.96      fvdl 	for (i = 0; i < AHC_SCB_MAX; i++) {
   4105   1.42      fvdl 
   4106   1.96      fvdl 		ahc_outb(ahc, SCBPTR, i);
   4107   1.96      fvdl 		ahc_outb(ahc, SCB_BASE, i);
   4108   1.96      fvdl 		if (ahc_inb(ahc, SCB_BASE) != i)
   4109   1.96      fvdl 			break;
   4110   1.96      fvdl 		ahc_outb(ahc, SCBPTR, 0);
   4111   1.96      fvdl 		if (ahc_inb(ahc, SCB_BASE) != 0)
   4112   1.96      fvdl 			break;
   4113   1.42      fvdl 	}
   4114   1.96      fvdl 	return (i);
   4115   1.42      fvdl }
   4116   1.42      fvdl 
   4117   1.96      fvdl #if 0
   4118   1.42      fvdl static void
   4119  1.112     perry ahc_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error)
   4120   1.42      fvdl {
   4121   1.96      fvdl 	bus_addr_t *baddr;
   4122   1.42      fvdl 
   4123   1.96      fvdl 	baddr = (bus_addr_t *)arg;
   4124   1.96      fvdl 	*baddr = segs->ds_addr;
   4125   1.42      fvdl }
   4126   1.42      fvdl #endif
   4127   1.42      fvdl 
   4128   1.42      fvdl static void
   4129   1.96      fvdl ahc_build_free_scb_list(struct ahc_softc *ahc)
   4130   1.42      fvdl {
   4131   1.96      fvdl 	int scbsize;
   4132   1.96      fvdl 	int i;
   4133   1.59        pk 
   4134   1.96      fvdl 	scbsize = 32;
   4135   1.96      fvdl 	if ((ahc->flags & AHC_LSCBS_ENABLED) != 0)
   4136   1.96      fvdl 		scbsize = 64;
   4137   1.42      fvdl 
   4138   1.96      fvdl 	for (i = 0; i < ahc->scb_data->maxhscbs; i++) {
   4139   1.96      fvdl 		int j;
   4140   1.42      fvdl 
   4141   1.96      fvdl 		ahc_outb(ahc, SCBPTR, i);
   4142   1.42      fvdl 
   4143   1.42      fvdl 		/*
   4144   1.96      fvdl 		 * Touch all SCB bytes to avoid parity errors
   4145   1.96      fvdl 		 * should one of our debugging routines read
   4146   1.96      fvdl 		 * an otherwise uninitiatlized byte.
   4147   1.42      fvdl 		 */
   4148   1.96      fvdl 		for (j = 0; j < scbsize; j++)
   4149   1.96      fvdl 			ahc_outb(ahc, SCB_BASE+j, 0xFF);
   4150   1.42      fvdl 
   4151   1.96      fvdl 		/* Clear the control byte. */
   4152   1.96      fvdl 		ahc_outb(ahc, SCB_CONTROL, 0);
   4153   1.42      fvdl 
   4154   1.96      fvdl 		/* Set the next pointer */
   4155   1.96      fvdl 		if ((ahc->flags & AHC_PAGESCBS) != 0)
   4156   1.96      fvdl 			ahc_outb(ahc, SCB_NEXT, i+1);
   4157  1.112     perry 		else
   4158   1.96      fvdl 			ahc_outb(ahc, SCB_NEXT, SCB_LIST_NULL);
   4159   1.42      fvdl 
   4160   1.96      fvdl 		/* Make the tag number, SCSIID, and lun invalid */
   4161   1.96      fvdl 		ahc_outb(ahc, SCB_TAG, SCB_LIST_NULL);
   4162   1.96      fvdl 		ahc_outb(ahc, SCB_SCSIID, 0xFF);
   4163   1.96      fvdl 		ahc_outb(ahc, SCB_LUN, 0xFF);
   4164   1.96      fvdl 	}
   4165   1.42      fvdl 
   4166   1.96      fvdl 	/* Make sure that the last SCB terminates the free list */
   4167   1.96      fvdl 	ahc_outb(ahc, SCBPTR, i-1);
   4168   1.96      fvdl 	ahc_outb(ahc, SCB_NEXT, SCB_LIST_NULL);
   4169   1.96      fvdl }
   4170   1.42      fvdl 
   4171   1.96      fvdl static int
   4172   1.96      fvdl ahc_init_scbdata(struct ahc_softc *ahc)
   4173   1.96      fvdl {
   4174   1.96      fvdl 	struct scb_data *scb_data;
   4175   1.42      fvdl 
   4176   1.96      fvdl 	scb_data = ahc->scb_data;
   4177   1.96      fvdl 	SLIST_INIT(&scb_data->free_scbs);
   4178   1.96      fvdl 	SLIST_INIT(&scb_data->sg_maps);
   4179   1.42      fvdl 
   4180   1.96      fvdl 	/* Allocate SCB resources */
   4181   1.96      fvdl 	scb_data->scbarray =
   4182   1.96      fvdl 	    (struct scb *)malloc(sizeof(struct scb) * AHC_SCB_MAX_ALLOC,
   4183   1.96      fvdl 				 M_DEVBUF, M_NOWAIT);
   4184   1.96      fvdl 	if (scb_data->scbarray == NULL)
   4185   1.96      fvdl 		return (ENOMEM);
   4186   1.96      fvdl 	memset(scb_data->scbarray, 0, sizeof(struct scb) * AHC_SCB_MAX_ALLOC);
   4187   1.42      fvdl 
   4188   1.96      fvdl 	/* Determine the number of hardware SCBs and initialize them */
   4189   1.42      fvdl 
   4190   1.96      fvdl 	scb_data->maxhscbs = ahc_probe_scbs(ahc);
   4191   1.96      fvdl 	if ((ahc->flags & AHC_PAGESCBS) != 0) {
   4192   1.96      fvdl 		/* SCB 0 heads the free list */
   4193   1.96      fvdl 		ahc_outb(ahc, FREE_SCBH, 0);
   4194   1.96      fvdl 	} else {
   4195   1.96      fvdl 		ahc_outb(ahc, FREE_SCBH, SCB_LIST_NULL);
   4196   1.42      fvdl 	}
   4197   1.42      fvdl 
   4198   1.96      fvdl 	if (ahc->scb_data->maxhscbs == 0) {
   4199   1.96      fvdl 		printf("%s: No SCB space found\n", ahc_name(ahc));
   4200   1.96      fvdl 		return (ENXIO);
   4201   1.42      fvdl 	}
   4202   1.42      fvdl 
   4203   1.96      fvdl 	ahc_build_free_scb_list(ahc);
   4204   1.59        pk 
   4205   1.42      fvdl 	/*
   4206   1.96      fvdl 	 * Create our DMA tags.  These tags define the kinds of device
   4207   1.96      fvdl 	 * accessible memory allocations and memory mappings we will
   4208   1.96      fvdl 	 * need to perform during normal operation.
   4209   1.96      fvdl 	 *
   4210   1.96      fvdl 	 * Unless we need to further restrict the allocation, we rely
   4211   1.96      fvdl 	 * on the restrictions of the parent dmat, hence the common
   4212   1.96      fvdl 	 * use of MAXADDR and MAXSIZE.
   4213   1.42      fvdl 	 */
   4214    1.6   mycroft 
   4215   1.96      fvdl 	if (ahc_createdmamem(ahc->parent_dmat,
   4216  1.107      fvdl 	     AHC_SCB_MAX * sizeof(struct hardware_scb), ahc->sc_dmaflags,
   4217  1.107      fvdl 	     &scb_data->hscb_dmamap,
   4218  1.107      fvdl 	     (caddr_t *)&scb_data->hscbs, &scb_data->hscb_busaddr,
   4219  1.107      fvdl 	     &scb_data->hscb_seg, &scb_data->hscb_nseg, ahc_name(ahc),
   4220  1.107      fvdl 	     "hardware SCB structures") < 0)
   4221   1.96      fvdl 		goto error_exit;
   4222   1.96      fvdl 
   4223   1.96      fvdl 	scb_data->init_level++;
   4224   1.96      fvdl 
   4225   1.96      fvdl 	if (ahc_createdmamem(ahc->parent_dmat,
   4226  1.111   thorpej 	     AHC_SCB_MAX * sizeof(struct scsi_sense_data), ahc->sc_dmaflags,
   4227  1.107      fvdl 	     &scb_data->sense_dmamap, (caddr_t *)&scb_data->sense,
   4228  1.107      fvdl 	     &scb_data->sense_busaddr, &scb_data->sense_seg,
   4229  1.107      fvdl 	     &scb_data->sense_nseg, ahc_name(ahc), "sense buffers") < 0)
   4230   1.96      fvdl 		goto error_exit;
   4231   1.96      fvdl 
   4232   1.96      fvdl 	scb_data->init_level++;
   4233    1.6   mycroft 
   4234   1.96      fvdl 	/* Perform initial CCB allocation */
   4235   1.96      fvdl 	memset(scb_data->hscbs, 0,
   4236   1.96      fvdl 	       AHC_SCB_MAX_ALLOC * sizeof(struct hardware_scb));
   4237   1.96      fvdl 	ahc_alloc_scbs(ahc);
   4238  1.104      fvdl 	scb_data->init_level++;
   4239    1.1   mycroft 
   4240   1.96      fvdl 	if (scb_data->numscbs == 0) {
   4241   1.96      fvdl 		printf("%s: ahc_init_scbdata - "
   4242   1.96      fvdl 		       "Unable to allocate initial scbs\n",
   4243   1.96      fvdl 		       ahc_name(ahc));
   4244   1.96      fvdl 		goto error_exit;
   4245   1.42      fvdl 	}
   4246    1.6   mycroft 
   4247   1.96      fvdl 	/*
   4248   1.96      fvdl 	 * Tell the sequencer which SCB will be the next one it receives.
   4249   1.96      fvdl 	 */
   4250   1.96      fvdl 	ahc->next_queued_scb = ahc_get_scb(ahc);
   4251   1.96      fvdl 	ahc_outb(ahc, NEXT_QUEUED_SCB, ahc->next_queued_scb->hscb->tag);
   4252   1.96      fvdl 
   4253   1.96      fvdl 	/*
   4254   1.96      fvdl 	 * Note that we were successfull
   4255   1.96      fvdl 	 */
   4256  1.112     perry 	return (0);
   4257    1.6   mycroft 
   4258   1.96      fvdl error_exit:
   4259   1.42      fvdl 
   4260   1.96      fvdl 	return (ENOMEM);
   4261   1.96      fvdl }
   4262    1.6   mycroft 
   4263   1.96      fvdl static void
   4264   1.96      fvdl ahc_fini_scbdata(struct ahc_softc *ahc)
   4265   1.96      fvdl {
   4266   1.96      fvdl 	struct scb_data *scb_data;
   4267    1.6   mycroft 
   4268   1.96      fvdl 	scb_data = ahc->scb_data;
   4269   1.96      fvdl 	if (scb_data == NULL)
   4270   1.96      fvdl 		return;
   4271   1.42      fvdl 
   4272   1.96      fvdl 	switch (scb_data->init_level) {
   4273   1.96      fvdl 	default:
   4274  1.104      fvdl 	case 5:
   4275   1.96      fvdl 	{
   4276   1.96      fvdl 		struct sg_map_node *sg_map;
   4277   1.42      fvdl 
   4278   1.96      fvdl 		while ((sg_map = SLIST_FIRST(&scb_data->sg_maps))!= NULL) {
   4279   1.96      fvdl 			SLIST_REMOVE_HEAD(&scb_data->sg_maps, links);
   4280   1.96      fvdl 			ahc_freedmamem(ahc->parent_dmat, PAGE_SIZE,
   4281   1.96      fvdl 			    sg_map->sg_dmamap, (caddr_t)sg_map->sg_vaddr,
   4282   1.96      fvdl 			    &sg_map->sg_dmasegs, sg_map->sg_nseg);
   4283   1.96      fvdl 			free(sg_map, M_DEVBUF);
   4284   1.96      fvdl 		}
   4285   1.96      fvdl 	}
   4286   1.96      fvdl 	/*FALLTHROUGH*/
   4287  1.104      fvdl 	case 4:
   4288   1.96      fvdl 		ahc_freedmamem(ahc->parent_dmat,
   4289  1.111   thorpej 		    AHC_SCB_MAX * sizeof(struct scsi_sense_data),
   4290   1.96      fvdl 		    scb_data->sense_dmamap, (caddr_t)scb_data->sense,
   4291   1.96      fvdl 		    &scb_data->sense_seg, scb_data->sense_nseg);
   4292   1.96      fvdl 	/*FALLTHROUGH*/
   4293  1.104      fvdl 	case 3:
   4294   1.96      fvdl 		ahc_freedmamem(ahc->parent_dmat,
   4295   1.96      fvdl 		    AHC_SCB_MAX * sizeof(struct hardware_scb),
   4296   1.96      fvdl 		    scb_data->hscb_dmamap, (caddr_t)scb_data->hscbs,
   4297   1.96      fvdl 		    &scb_data->hscb_seg, scb_data->hscb_nseg);
   4298   1.96      fvdl 	/*FALLTHROUGH*/
   4299  1.104      fvdl 	case 2:
   4300  1.104      fvdl 	case 1:
   4301  1.104      fvdl 	case 0:
   4302  1.104      fvdl 		break;
   4303   1.96      fvdl 	}
   4304   1.96      fvdl 	if (scb_data->scbarray != NULL)
   4305   1.96      fvdl 		free(scb_data->scbarray, M_DEVBUF);
   4306   1.96      fvdl }
   4307    1.6   mycroft 
   4308  1.117    bouyer int
   4309   1.96      fvdl ahc_alloc_scbs(struct ahc_softc *ahc)
   4310   1.96      fvdl {
   4311   1.96      fvdl 	struct scb_data *scb_data;
   4312   1.96      fvdl 	struct scb *next_scb;
   4313   1.96      fvdl 	struct sg_map_node *sg_map;
   4314   1.96      fvdl 	bus_addr_t physaddr;
   4315   1.96      fvdl 	struct ahc_dma_seg *segs;
   4316   1.96      fvdl 	int newcount;
   4317   1.96      fvdl 	int i;
   4318    1.6   mycroft 
   4319   1.96      fvdl 	scb_data = ahc->scb_data;
   4320   1.96      fvdl 	if (scb_data->numscbs >= AHC_SCB_MAX_ALLOC)
   4321   1.96      fvdl 		/* Can't allocate any more */
   4322  1.117    bouyer 		return (0);
   4323    1.6   mycroft 
   4324   1.96      fvdl 	next_scb = &scb_data->scbarray[scb_data->numscbs];
   4325    1.6   mycroft 
   4326  1.117    bouyer 	sg_map = malloc(sizeof(*sg_map), M_DEVBUF, M_WAITOK);
   4327   1.42      fvdl 
   4328   1.96      fvdl 	if (sg_map == NULL)
   4329  1.117    bouyer 		return (0);
   4330    1.6   mycroft 
   4331   1.96      fvdl 	/* Allocate S/G space for the next batch of SCBS */
   4332   1.96      fvdl 	if (ahc_createdmamem(ahc->parent_dmat, PAGE_SIZE, ahc->sc_dmaflags,
   4333   1.96      fvdl 			     &sg_map->sg_dmamap,
   4334   1.96      fvdl 			     (caddr_t *)&sg_map->sg_vaddr, &sg_map->sg_physaddr,
   4335   1.96      fvdl 			     &sg_map->sg_dmasegs, &sg_map->sg_nseg, ahc_name(ahc),
   4336   1.96      fvdl 			     "SG space") < 0) {
   4337   1.96      fvdl 		free(sg_map, M_DEVBUF);
   4338  1.117    bouyer 		return (0);
   4339   1.96      fvdl 	}
   4340    1.6   mycroft 
   4341   1.96      fvdl 	SLIST_INSERT_HEAD(&scb_data->sg_maps, sg_map, links);
   4342    1.6   mycroft 
   4343   1.96      fvdl 	segs = sg_map->sg_vaddr;
   4344   1.96      fvdl 	physaddr = sg_map->sg_physaddr;
   4345    1.6   mycroft 
   4346   1.96      fvdl 	newcount = (PAGE_SIZE / (AHC_NSEG * sizeof(struct ahc_dma_seg)));
   4347   1.96      fvdl 	newcount = MIN(newcount, (AHC_SCB_MAX_ALLOC - scb_data->numscbs));
   4348   1.96      fvdl 	for (i = 0; i < newcount; i++) {
   4349   1.96      fvdl 		struct scb_platform_data *pdata;
   4350   1.96      fvdl 		int error;
   4351    1.6   mycroft 
   4352   1.96      fvdl 		pdata = (struct scb_platform_data *)malloc(sizeof(*pdata),
   4353  1.117    bouyer 							   M_DEVBUF, M_WAITOK);
   4354   1.96      fvdl 		if (pdata == NULL)
   4355   1.96      fvdl 			break;
   4356   1.96      fvdl 		next_scb->platform_data = pdata;
   4357   1.96      fvdl 		next_scb->sg_map = sg_map;
   4358   1.96      fvdl 		next_scb->sg_list = segs;
   4359   1.42      fvdl 		/*
   4360   1.96      fvdl 		 * The sequencer always starts with the second entry.
   4361   1.96      fvdl 		 * The first entry is embedded in the scb.
   4362   1.42      fvdl 		 */
   4363   1.96      fvdl 		next_scb->sg_list_phys = physaddr + sizeof(struct ahc_dma_seg);
   4364   1.96      fvdl 		next_scb->ahc_softc = ahc;
   4365   1.96      fvdl 		next_scb->flags = SCB_FREE;
   4366   1.96      fvdl 
   4367  1.112     perry 		error = bus_dmamap_create(ahc->parent_dmat,
   4368  1.107      fvdl 			  AHC_MAXTRANSFER_SIZE, AHC_NSEG, MAXPHYS, 0,
   4369  1.117    bouyer 			  BUS_DMA_WAITOK|BUS_DMA_ALLOCNOW|ahc->sc_dmaflags,
   4370  1.107      fvdl 			  &next_scb->dmamap);
   4371   1.96      fvdl 		if (error != 0)
   4372   1.96      fvdl 			break;
   4373    1.6   mycroft 
   4374   1.96      fvdl 		next_scb->hscb = &scb_data->hscbs[scb_data->numscbs];
   4375   1.96      fvdl 		next_scb->hscb->tag = ahc->scb_data->numscbs;
   4376   1.96      fvdl 		SLIST_INSERT_HEAD(&ahc->scb_data->free_scbs,
   4377   1.96      fvdl 				  next_scb, links.sle);
   4378   1.96      fvdl 		segs += AHC_NSEG;
   4379   1.96      fvdl 		physaddr += (AHC_NSEG * sizeof(struct ahc_dma_seg));
   4380   1.96      fvdl 		next_scb++;
   4381   1.96      fvdl 		ahc->scb_data->numscbs++;
   4382    1.6   mycroft 	}
   4383  1.117    bouyer 	return (newcount);
   4384    1.1   mycroft }
   4385    1.1   mycroft 
   4386   1.96      fvdl void
   4387  1.114  christos ahc_controller_info(struct ahc_softc *ahc, char *tbuf, size_t l)
   4388    1.1   mycroft {
   4389   1.96      fvdl 	int len;
   4390  1.110    itojun 	char *ep;
   4391   1.42      fvdl 
   4392  1.114  christos 	ep = tbuf + l;
   4393  1.110    itojun 
   4394  1.114  christos 	len = snprintf(tbuf, ep - tbuf, "%s: ",
   4395  1.110    itojun 	    ahc_chip_names[ahc->chip & AHC_CHIPID_MASK]);
   4396  1.114  christos 	tbuf += len;
   4397   1.96      fvdl 	if ((ahc->features & AHC_TWIN) != 0)
   4398  1.114  christos  		len = snprintf(tbuf, ep - tbuf, "Twin Channel, A SCSI Id=%d, "
   4399   1.96      fvdl 			      "B SCSI Id=%d, primary %c, ",
   4400   1.96      fvdl 			      ahc->our_id, ahc->our_id_b,
   4401   1.96      fvdl 			      (ahc->flags & AHC_PRIMARY_CHANNEL) + 'A');
   4402   1.96      fvdl 	else {
   4403   1.96      fvdl 		const char *speed;
   4404   1.96      fvdl 		const char *type;
   4405   1.96      fvdl 
   4406   1.96      fvdl 		speed = "";
   4407   1.96      fvdl 		if ((ahc->features & AHC_ULTRA) != 0) {
   4408   1.96      fvdl 			speed = "Ultra ";
   4409   1.96      fvdl 		} else if ((ahc->features & AHC_DT) != 0) {
   4410   1.96      fvdl 			speed = "Ultra160 ";
   4411   1.96      fvdl 		} else if ((ahc->features & AHC_ULTRA2) != 0) {
   4412   1.96      fvdl 			speed = "Ultra2 ";
   4413   1.96      fvdl 		}
   4414   1.96      fvdl 		if ((ahc->features & AHC_WIDE) != 0) {
   4415   1.96      fvdl 			type = "Wide";
   4416   1.96      fvdl 		} else {
   4417   1.96      fvdl 			type = "Single";
   4418   1.96      fvdl 		}
   4419  1.114  christos 		len = snprintf(tbuf, ep - tbuf, "%s%s Channel %c, SCSI Id=%d, ",
   4420   1.96      fvdl 			      speed, type, ahc->channel, ahc->our_id);
   4421   1.42      fvdl 	}
   4422  1.114  christos 	tbuf += len;
   4423   1.42      fvdl 
   4424   1.96      fvdl 	if ((ahc->flags & AHC_PAGESCBS) != 0)
   4425  1.114  christos 		snprintf(tbuf, ep - tbuf, "%d/%d SCBs",
   4426   1.96      fvdl 			ahc->scb_data->maxhscbs, AHC_MAX_QUEUE);
   4427   1.96      fvdl 	else
   4428  1.114  christos 		snprintf(tbuf, ep - tbuf, "%d SCBs", ahc->scb_data->maxhscbs);
   4429   1.42      fvdl }
   4430    1.1   mycroft 
   4431   1.96      fvdl /*
   4432   1.96      fvdl  * Start the board, ready for normal operation
   4433   1.96      fvdl  */
   4434   1.96      fvdl int
   4435   1.96      fvdl ahc_init(struct ahc_softc *ahc)
   4436   1.42      fvdl {
   4437   1.96      fvdl 	int	 max_targ;
   4438   1.96      fvdl 	int	 i;
   4439   1.96      fvdl 	int	 term;
   4440   1.96      fvdl 	u_int	 scsi_conf;
   4441   1.96      fvdl 	u_int	 scsiseq_template;
   4442   1.96      fvdl 	u_int	 ultraenb;
   4443   1.96      fvdl 	u_int	 discenable;
   4444   1.96      fvdl 	u_int	 tagenable;
   4445   1.96      fvdl 	size_t	 driver_data_size;
   4446   1.96      fvdl 	uint32_t physaddr;
   4447   1.42      fvdl 
   4448   1.96      fvdl #ifdef AHC_DEBUG
   4449   1.96      fvdl 	if ((ahc_debug & AHC_DEBUG_SEQUENCER) != 0)
   4450   1.96      fvdl 		ahc->flags |= AHC_SEQUENCER_DEBUG;
   4451   1.96      fvdl #endif
   4452   1.42      fvdl 
   4453   1.96      fvdl #ifdef AHC_PRINT_SRAM
   4454   1.96      fvdl 	printf("Scratch Ram:");
   4455   1.96      fvdl 	for (i = 0x20; i < 0x5f; i++) {
   4456   1.96      fvdl 		if (((i % 8) == 0) && (i != 0)) {
   4457   1.96      fvdl 			printf ("\n              ");
   4458   1.42      fvdl 		}
   4459   1.96      fvdl 		printf (" 0x%x", ahc_inb(ahc, i));
   4460   1.42      fvdl 	}
   4461   1.96      fvdl 	if ((ahc->features & AHC_MORE_SRAM) != 0) {
   4462   1.96      fvdl 		for (i = 0x70; i < 0x7f; i++) {
   4463   1.96      fvdl 			if (((i % 8) == 0) && (i != 0)) {
   4464   1.96      fvdl 				printf ("\n              ");
   4465   1.96      fvdl 			}
   4466   1.96      fvdl 			printf (" 0x%x", ahc_inb(ahc, i));
   4467   1.96      fvdl 		}
   4468   1.42      fvdl 	}
   4469   1.96      fvdl 	printf ("\n");
   4470   1.96      fvdl 	/*
   4471   1.96      fvdl 	 * Reading uninitialized scratch ram may
   4472   1.96      fvdl 	 * generate parity errors.
   4473   1.96      fvdl 	 */
   4474   1.96      fvdl 	ahc_outb(ahc, CLRINT, CLRPARERR);
   4475   1.96      fvdl 	ahc_outb(ahc, CLRINT, CLRBRKADRINT);
   4476   1.96      fvdl #endif
   4477   1.96      fvdl 	max_targ = 15;
   4478    1.6   mycroft 
   4479   1.42      fvdl 	/*
   4480   1.96      fvdl 	 * Assume we have a board at this stage and it has been reset.
   4481   1.42      fvdl 	 */
   4482   1.96      fvdl 	if ((ahc->flags & AHC_USEDEFAULTS) != 0)
   4483   1.96      fvdl 		ahc->our_id = ahc->our_id_b = 7;
   4484  1.112     perry 
   4485   1.59        pk 	/*
   4486   1.96      fvdl 	 * Default to allowing initiator operations.
   4487   1.59        pk 	 */
   4488   1.96      fvdl 	ahc->flags |= AHC_INITIATORROLE;
   4489    1.6   mycroft 
   4490    1.1   mycroft 	/*
   4491   1.96      fvdl 	 * Only allow target mode features if this unit has them enabled.
   4492    1.1   mycroft 	 */
   4493   1.96      fvdl 	//if ((AHC_TMODE_ENABLE & (0x1 << ahc->unit)) == 0)
   4494   1.96      fvdl 		ahc->features &= ~AHC_TARGETMODE;
   4495   1.42      fvdl 
   4496   1.96      fvdl 	/*
   4497   1.96      fvdl 	 * DMA tag for our command fifos and other data in system memory
   4498   1.96      fvdl 	 * the card's sequencer must be able to access.  For initiator
   4499   1.96      fvdl 	 * roles, we need to allocate space for the qinfifo and qoutfifo.
   4500  1.112     perry 	 * The qinfifo and qoutfifo are composed of 256 1 byte elements.
   4501   1.96      fvdl 	 * When providing for the target mode role, we must additionally
   4502   1.96      fvdl 	 * provide space for the incoming target command fifo and an extra
   4503  1.105       wiz 	 * byte to deal with a DMA bug in some chip versions.
   4504   1.96      fvdl 	 */
   4505   1.96      fvdl 	driver_data_size = 2 * 256 * sizeof(uint8_t);
   4506   1.96      fvdl 	if ((ahc->features & AHC_TARGETMODE) != 0)
   4507   1.96      fvdl 		driver_data_size += AHC_TMODE_CMDS * sizeof(struct target_cmd)
   4508   1.96      fvdl 				 + /*DMA WideOdd Bug Buffer*/1;
   4509   1.42      fvdl 
   4510   1.96      fvdl 	if (ahc_createdmamem(ahc->parent_dmat, driver_data_size,
   4511   1.96      fvdl 			     ahc->sc_dmaflags,
   4512   1.96      fvdl 			     &ahc->shared_data_dmamap, (caddr_t *)&ahc->qoutfifo,
   4513   1.96      fvdl 			     &ahc->shared_data_busaddr, &ahc->shared_data_seg,
   4514   1.96      fvdl 			     &ahc->shared_data_nseg, ahc_name(ahc), "shared data") < 0)
   4515   1.96      fvdl 		return (ENOMEM);
   4516    1.6   mycroft 
   4517   1.96      fvdl 	ahc->init_level++;
   4518    1.1   mycroft 
   4519   1.96      fvdl 	if ((ahc->features & AHC_TARGETMODE) != 0) {
   4520   1.96      fvdl 		ahc->targetcmds = (struct target_cmd *)ahc->qoutfifo;
   4521   1.96      fvdl 		ahc->qoutfifo = (uint8_t *)&ahc->targetcmds[AHC_TMODE_CMDS];
   4522   1.96      fvdl 		ahc->dma_bug_buf = ahc->shared_data_busaddr
   4523   1.96      fvdl 				 + driver_data_size - 1;
   4524   1.96      fvdl 		/* All target command blocks start out invalid. */
   4525   1.96      fvdl 		for (i = 0; i < AHC_TMODE_CMDS; i++)
   4526   1.96      fvdl 			ahc->targetcmds[i].cmd_valid = 0;
   4527   1.96      fvdl 		ahc_sync_tqinfifo(ahc, BUS_DMASYNC_PREREAD);
   4528   1.96      fvdl 		ahc->tqinfifonext = 1;
   4529   1.96      fvdl 		ahc_outb(ahc, KERNEL_TQINPOS, ahc->tqinfifonext - 1);
   4530   1.96      fvdl 		ahc_outb(ahc, TQINPOS, ahc->tqinfifonext);
   4531   1.96      fvdl 		ahc->qoutfifo = (uint8_t *)&ahc->targetcmds[256];
   4532   1.42      fvdl 	}
   4533   1.96      fvdl 	ahc->qinfifo = &ahc->qoutfifo[256];
   4534   1.14     gibbs 
   4535   1.96      fvdl 	ahc->init_level++;
   4536   1.14     gibbs 
   4537   1.96      fvdl 	/* Allocate SCB data now that buffer_dmat is initialized */
   4538   1.96      fvdl 	if (ahc->scb_data->maxhscbs == 0)
   4539   1.96      fvdl 		if (ahc_init_scbdata(ahc) != 0)
   4540   1.96      fvdl 		  return (ENOMEM);
   4541   1.42      fvdl 
   4542   1.96      fvdl 	if (bootverbose)
   4543   1.96      fvdl 		printf("%s: found %d SCBs\n", ahc_name(ahc),
   4544   1.96      fvdl 		    ahc->scb_data->maxhscbs);
   4545   1.42      fvdl 
   4546   1.96      fvdl 	/*
   4547   1.96      fvdl 	 * Allocate a tstate to house information for our
   4548   1.96      fvdl 	 * initiator presence on the bus as well as the user
   4549   1.96      fvdl 	 * data for any target mode initiator.
   4550   1.96      fvdl 	 */
   4551   1.96      fvdl 	if (ahc_alloc_tstate(ahc, ahc->our_id, 'A') == NULL) {
   4552   1.96      fvdl 		printf("%s: unable to allocate ahc_tmode_tstate.  "
   4553   1.96      fvdl 		       "Failing attach\n", ahc_name(ahc));
   4554   1.96      fvdl 		return (ENOMEM);
   4555   1.96      fvdl 	}
   4556   1.42      fvdl 
   4557   1.96      fvdl 	if ((ahc->features & AHC_TWIN) != 0) {
   4558   1.96      fvdl 		if (ahc_alloc_tstate(ahc, ahc->our_id_b, 'B') == NULL) {
   4559   1.96      fvdl 			printf("%s: unable to allocate ahc_tmode_tstate.  "
   4560   1.96      fvdl 			       "Failing attach\n", ahc_name(ahc));
   4561   1.96      fvdl 			return (ENOMEM);
   4562   1.96      fvdl 		}
   4563   1.96      fvdl 	}
   4564   1.42      fvdl 
   4565   1.96      fvdl 	ahc_outb(ahc, SEQ_FLAGS, 0);
   4566   1.96      fvdl 	ahc_outb(ahc, SEQ_FLAGS2, 0);
   4567   1.42      fvdl 
   4568   1.96      fvdl 	if (ahc->scb_data->maxhscbs < AHC_SCB_MAX_ALLOC) {
   4569   1.96      fvdl 		ahc->flags |= AHC_PAGESCBS;
   4570   1.96      fvdl 	} else {
   4571   1.96      fvdl 		ahc->flags &= ~AHC_PAGESCBS;
   4572   1.96      fvdl 	}
   4573   1.42      fvdl 
   4574   1.96      fvdl #ifdef AHC_DEBUG
   4575   1.96      fvdl 	if (ahc_debug & AHC_SHOW_MISC) {
   4576   1.97     bjh21 		printf("%s: hardware scb %lu bytes; kernel scb %lu bytes; "
   4577   1.97     bjh21 		       "ahc_dma %lu bytes\n",
   4578   1.96      fvdl 			ahc_name(ahc),
   4579   1.97     bjh21 			(u_long)sizeof(struct hardware_scb),
   4580   1.97     bjh21 			(u_long)sizeof(struct scb),
   4581   1.97     bjh21 			(u_long)sizeof(struct ahc_dma_seg));
   4582   1.96      fvdl 	}
   4583   1.96      fvdl #endif /* AHC_DEBUG */
   4584   1.42      fvdl 
   4585   1.96      fvdl 	/* Set the SCSI Id, SXFRCTL0, SXFRCTL1, and SIMODE1, for both channels*/
   4586   1.96      fvdl 	if (ahc->features & AHC_TWIN) {
   4587   1.42      fvdl 
   4588   1.42      fvdl 		/*
   4589   1.96      fvdl 		 * The device is gated to channel B after a chip reset,
   4590   1.96      fvdl 		 * so set those values first
   4591   1.42      fvdl 		 */
   4592   1.96      fvdl 		ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) | SELBUSB);
   4593   1.96      fvdl 		term = (ahc->flags & AHC_TERM_ENB_B) != 0 ? STPWEN : 0;
   4594   1.96      fvdl 		ahc_outb(ahc, SCSIID, ahc->our_id_b);
   4595   1.96      fvdl 		scsi_conf = ahc_inb(ahc, SCSICONF + 1);
   4596   1.96      fvdl 		ahc_outb(ahc, SXFRCTL1, (scsi_conf & (ENSPCHK|STIMESEL))
   4597   1.96      fvdl 					|term|ahc->seltime_b|ENSTIMER|ACTNEGEN);
   4598   1.96      fvdl 		if ((ahc->features & AHC_ULTRA2) != 0)
   4599   1.96      fvdl 			ahc_outb(ahc, SIMODE0, ahc_inb(ahc, SIMODE0)|ENIOERR);
   4600   1.96      fvdl 		ahc_outb(ahc, SIMODE1, ENSELTIMO|ENSCSIRST|ENSCSIPERR);
   4601   1.96      fvdl 		ahc_outb(ahc, SXFRCTL0, DFON|SPIOEN);
   4602   1.96      fvdl 
   4603   1.96      fvdl 		if ((scsi_conf & RESET_SCSI) != 0
   4604   1.96      fvdl 		 && (ahc->flags & AHC_INITIATORROLE) != 0)
   4605   1.96      fvdl 			ahc->flags |= AHC_RESET_BUS_B;
   4606   1.96      fvdl 
   4607   1.96      fvdl 		/* Select Channel A */
   4608   1.96      fvdl 		ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) & ~SELBUSB);
   4609   1.42      fvdl 	}
   4610   1.42      fvdl 
   4611   1.96      fvdl 	term = (ahc->flags & AHC_TERM_ENB_A) != 0 ? STPWEN : 0;
   4612   1.96      fvdl 	if ((ahc->features & AHC_ULTRA2) != 0)
   4613   1.96      fvdl 		ahc_outb(ahc, SCSIID_ULTRA2, ahc->our_id);
   4614   1.96      fvdl 	else
   4615   1.96      fvdl 		ahc_outb(ahc, SCSIID, ahc->our_id);
   4616   1.96      fvdl 	scsi_conf = ahc_inb(ahc, SCSICONF);
   4617   1.96      fvdl 	ahc_outb(ahc, SXFRCTL1, (scsi_conf & (ENSPCHK|STIMESEL))
   4618   1.96      fvdl 				|term|ahc->seltime
   4619   1.96      fvdl 				|ENSTIMER|ACTNEGEN);
   4620   1.96      fvdl 	if ((ahc->features & AHC_ULTRA2) != 0)
   4621   1.96      fvdl 		ahc_outb(ahc, SIMODE0, ahc_inb(ahc, SIMODE0)|ENIOERR);
   4622   1.96      fvdl 	ahc_outb(ahc, SIMODE1, ENSELTIMO|ENSCSIRST|ENSCSIPERR);
   4623   1.96      fvdl 	ahc_outb(ahc, SXFRCTL0, DFON|SPIOEN);
   4624   1.96      fvdl 
   4625   1.96      fvdl 	if ((scsi_conf & RESET_SCSI) != 0
   4626   1.96      fvdl 	 && (ahc->flags & AHC_INITIATORROLE) != 0)
   4627   1.96      fvdl 		ahc->flags |= AHC_RESET_BUS_A;
   4628   1.96      fvdl 
   4629   1.96      fvdl 	/*
   4630   1.96      fvdl 	 * Look at the information that board initialization or
   4631   1.96      fvdl 	 * the board bios has left us.
   4632   1.96      fvdl 	 */
   4633  1.112     perry 	ultraenb = 0;
   4634   1.96      fvdl 	tagenable = ALL_TARGETS_MASK;
   4635   1.42      fvdl 
   4636   1.96      fvdl 	/* Grab the disconnection disable table and invert it for our needs */
   4637   1.96      fvdl 	if ((ahc->flags & AHC_USEDEFAULTS) != 0) {
   4638  1.120   tsutsui 		printf("%s: Host Adapter BIOS disabled. Using default SCSI "
   4639  1.120   tsutsui 			"host and target device parameters\n", ahc_name(ahc));
   4640   1.96      fvdl 		ahc->flags |= AHC_EXTENDED_TRANS_A|AHC_EXTENDED_TRANS_B|
   4641   1.96      fvdl 			      AHC_TERM_ENB_A|AHC_TERM_ENB_B;
   4642   1.96      fvdl 		discenable = ALL_TARGETS_MASK;
   4643   1.96      fvdl 		if ((ahc->features & AHC_ULTRA) != 0)
   4644   1.96      fvdl 			ultraenb = ALL_TARGETS_MASK;
   4645  1.120   tsutsui 	} else if ((ahc->flags & AHC_USETARGETDEFAULTS) != 0) {
   4646  1.120   tsutsui 		printf("%s: Host Adapter has no SEEPROM. Using default SCSI"
   4647  1.120   tsutsui 		    " target parameters\n", ahc_name(ahc));
   4648  1.120   tsutsui 		ahc->flags |= AHC_EXTENDED_TRANS_A|AHC_EXTENDED_TRANS_B;
   4649  1.120   tsutsui 		discenable = ALL_TARGETS_MASK;
   4650  1.120   tsutsui 		if ((ahc->features & AHC_ULTRA) != 0)
   4651  1.120   tsutsui 			ultraenb = ALL_TARGETS_MASK;
   4652   1.96      fvdl 	} else {
   4653   1.96      fvdl 		discenable = ~((ahc_inb(ahc, DISC_DSB + 1) << 8)
   4654   1.96      fvdl 			   | ahc_inb(ahc, DISC_DSB));
   4655   1.96      fvdl 		if ((ahc->features & (AHC_ULTRA|AHC_ULTRA2)) != 0)
   4656   1.96      fvdl 			ultraenb = (ahc_inb(ahc, ULTRA_ENB + 1) << 8)
   4657   1.96      fvdl 				      | ahc_inb(ahc, ULTRA_ENB);
   4658   1.96      fvdl 	}
   4659   1.42      fvdl 
   4660   1.96      fvdl 	if ((ahc->features & (AHC_WIDE|AHC_TWIN)) == 0)
   4661   1.96      fvdl 		max_targ = 7;
   4662   1.42      fvdl 
   4663   1.96      fvdl 	for (i = 0; i <= max_targ; i++) {
   4664   1.96      fvdl 		struct ahc_initiator_tinfo *tinfo;
   4665   1.96      fvdl 		struct ahc_tmode_tstate *tstate;
   4666   1.96      fvdl 		u_int our_id;
   4667   1.96      fvdl 		u_int target_id;
   4668   1.96      fvdl 		char channel;
   4669   1.42      fvdl 
   4670   1.96      fvdl 		channel = 'A';
   4671   1.96      fvdl 		our_id = ahc->our_id;
   4672   1.96      fvdl 		target_id = i;
   4673   1.96      fvdl 		if (i > 7 && (ahc->features & AHC_TWIN) != 0) {
   4674   1.96      fvdl 			channel = 'B';
   4675   1.96      fvdl 			our_id = ahc->our_id_b;
   4676   1.96      fvdl 			target_id = i % 8;
   4677   1.96      fvdl 		}
   4678   1.96      fvdl 		tinfo = ahc_fetch_transinfo(ahc, channel, our_id,
   4679   1.96      fvdl 					    target_id, &tstate);
   4680   1.96      fvdl 		/* Default to async narrow across the board */
   4681   1.96      fvdl 		memset(tinfo, 0, sizeof(*tinfo));
   4682  1.120   tsutsui 		if (ahc->flags & (AHC_USEDEFAULTS | AHC_USETARGETDEFAULTS)) {
   4683   1.96      fvdl 			if ((ahc->features & AHC_WIDE) != 0)
   4684   1.96      fvdl 				tinfo->user.width = MSG_EXT_WDTR_BUS_16_BIT;
   4685   1.42      fvdl 
   4686   1.42      fvdl 			/*
   4687   1.96      fvdl 			 * These will be truncated when we determine the
   4688   1.96      fvdl 			 * connection type we have with the target.
   4689   1.42      fvdl 			 */
   4690   1.96      fvdl 			tinfo->user.period = ahc_syncrates->period;
   4691   1.96      fvdl 			tinfo->user.offset = ~0;
   4692   1.96      fvdl 		} else {
   4693   1.96      fvdl 			u_int scsirate;
   4694   1.96      fvdl 			uint16_t mask;
   4695   1.42      fvdl 
   4696   1.96      fvdl 			/* Take the settings leftover in scratch RAM. */
   4697   1.96      fvdl 			scsirate = ahc_inb(ahc, TARG_SCSIRATE + i);
   4698   1.96      fvdl 			mask = (0x01 << i);
   4699   1.96      fvdl 			if ((ahc->features & AHC_ULTRA2) != 0) {
   4700   1.96      fvdl 				u_int offset;
   4701   1.96      fvdl 				u_int maxsync;
   4702   1.42      fvdl 
   4703   1.96      fvdl 				if ((scsirate & SOFS) == 0x0F) {
   4704   1.96      fvdl 					/*
   4705   1.96      fvdl 					 * Haven't negotiated yet,
   4706   1.96      fvdl 					 * so the format is different.
   4707   1.96      fvdl 					 */
   4708   1.96      fvdl 					scsirate = (scsirate & SXFR) >> 4
   4709   1.96      fvdl 						 | (ultraenb & mask)
   4710   1.96      fvdl 						  ? 0x08 : 0x0
   4711   1.96      fvdl 						 | (scsirate & WIDEXFER);
   4712   1.96      fvdl 					offset = MAX_OFFSET_ULTRA2;
   4713   1.96      fvdl 				} else
   4714   1.96      fvdl 					offset = ahc_inb(ahc, TARG_OFFSET + i);
   4715   1.96      fvdl 				if ((scsirate & ~WIDEXFER) == 0 && offset != 0)
   4716   1.96      fvdl 					/* Set to the lowest sync rate, 5MHz */
   4717   1.96      fvdl 					scsirate |= 0x1c;
   4718   1.96      fvdl 				maxsync = AHC_SYNCRATE_ULTRA2;
   4719   1.96      fvdl 				if ((ahc->features & AHC_DT) != 0)
   4720   1.96      fvdl 					maxsync = AHC_SYNCRATE_DT;
   4721   1.96      fvdl 				tinfo->user.period =
   4722   1.96      fvdl 				    ahc_find_period(ahc, scsirate, maxsync);
   4723   1.96      fvdl 				if (offset == 0)
   4724   1.96      fvdl 					tinfo->user.period = 0;
   4725   1.96      fvdl 				else
   4726   1.96      fvdl 					tinfo->user.offset = ~0;
   4727   1.96      fvdl 				if ((scsirate & SXFR_ULTRA2) <= 8/*10MHz*/
   4728   1.96      fvdl 				 && (ahc->features & AHC_DT) != 0)
   4729   1.96      fvdl 					tinfo->user.ppr_options =
   4730   1.96      fvdl 					    MSG_EXT_PPR_DT_REQ;
   4731   1.96      fvdl 			} else if ((scsirate & SOFS) != 0) {
   4732   1.96      fvdl 				if ((scsirate & SXFR) == 0x40
   4733   1.96      fvdl 				 && (ultraenb & mask) != 0) {
   4734   1.96      fvdl 					/* Treat 10MHz as a non-ultra speed */
   4735   1.96      fvdl 					scsirate &= ~SXFR;
   4736   1.96      fvdl 				 	ultraenb &= ~mask;
   4737   1.96      fvdl 				}
   4738  1.112     perry 				tinfo->user.period =
   4739   1.96      fvdl 				    ahc_find_period(ahc, scsirate,
   4740   1.96      fvdl 						    (ultraenb & mask)
   4741   1.96      fvdl 						   ? AHC_SYNCRATE_ULTRA
   4742   1.96      fvdl 						   : AHC_SYNCRATE_FAST);
   4743   1.96      fvdl 				if (tinfo->user.period != 0)
   4744   1.96      fvdl 					tinfo->user.offset = ~0;
   4745   1.96      fvdl 			}
   4746   1.96      fvdl 			if (tinfo->user.period == 0)
   4747   1.96      fvdl 				tinfo->user.offset = 0;
   4748   1.96      fvdl 			if ((scsirate & WIDEXFER) != 0
   4749   1.96      fvdl 			 && (ahc->features & AHC_WIDE) != 0)
   4750   1.96      fvdl 				tinfo->user.width = MSG_EXT_WDTR_BUS_16_BIT;
   4751   1.96      fvdl 			tinfo->user.protocol_version = 4;
   4752   1.96      fvdl 			if ((ahc->features & AHC_DT) != 0)
   4753   1.96      fvdl 				tinfo->user.transport_version = 3;
   4754   1.96      fvdl 			else
   4755   1.96      fvdl 				tinfo->user.transport_version = 2;
   4756   1.96      fvdl 			tinfo->goal.protocol_version = 2;
   4757   1.96      fvdl 			tinfo->goal.transport_version = 2;
   4758   1.96      fvdl 			tinfo->curr.protocol_version = 2;
   4759   1.96      fvdl 			tinfo->curr.transport_version = 2;
   4760   1.42      fvdl 		}
   4761   1.96      fvdl 		tstate->ultraenb = 0;
   4762   1.96      fvdl 		tstate->discenable = discenable;
   4763   1.42      fvdl 	}
   4764   1.96      fvdl 	ahc->user_discenable = discenable;
   4765   1.96      fvdl 	ahc->user_tagenable = tagenable;
   4766   1.42      fvdl 
   4767   1.96      fvdl 	/* There are no untagged SCBs active yet. */
   4768   1.96      fvdl 	for (i = 0; i < 16; i++) {
   4769   1.96      fvdl 		ahc_unbusy_tcl(ahc, BUILD_TCL(i << 4, 0));
   4770   1.96      fvdl 		if ((ahc->flags & AHC_SCB_BTT) != 0) {
   4771   1.96      fvdl 			int lun;
   4772   1.42      fvdl 
   4773   1.42      fvdl 			/*
   4774   1.96      fvdl 			 * The SCB based BTT allows an entry per
   4775   1.96      fvdl 			 * target and lun pair.
   4776   1.42      fvdl 			 */
   4777   1.96      fvdl 			for (lun = 1; lun < AHC_NUM_LUNS; lun++)
   4778   1.96      fvdl 				ahc_unbusy_tcl(ahc, BUILD_TCL(i << 4, lun));
   4779   1.42      fvdl 		}
   4780   1.96      fvdl 	}
   4781   1.59        pk 
   4782   1.96      fvdl 	/* All of our queues are empty */
   4783   1.96      fvdl 	for (i = 0; i < 256; i++)
   4784   1.96      fvdl 		ahc->qoutfifo[i] = SCB_LIST_NULL;
   4785   1.42      fvdl 
   4786   1.96      fvdl 	ahc_sync_qoutfifo(ahc, BUS_DMASYNC_PREREAD);
   4787    1.9  explorer 
   4788   1.96      fvdl 	for (i = 0; i < 256; i++)
   4789   1.96      fvdl 		ahc->qinfifo[i] = SCB_LIST_NULL;
   4790    1.9  explorer 
   4791   1.96      fvdl 	if ((ahc->features & AHC_MULTI_TID) != 0) {
   4792   1.96      fvdl 		ahc_outb(ahc, TARGID, 0);
   4793   1.96      fvdl 		ahc_outb(ahc, TARGID + 1, 0);
   4794   1.14     gibbs 	}
   4795   1.14     gibbs 
   4796   1.96      fvdl 	/*
   4797   1.96      fvdl 	 * Tell the sequencer where it can find our arrays in memory.
   4798   1.96      fvdl 	 */
   4799   1.96      fvdl 	physaddr = ahc->scb_data->hscb_busaddr;
   4800   1.96      fvdl 	ahc_outb(ahc, HSCB_ADDR, physaddr & 0xFF);
   4801   1.96      fvdl 	ahc_outb(ahc, HSCB_ADDR + 1, (physaddr >> 8) & 0xFF);
   4802   1.96      fvdl 	ahc_outb(ahc, HSCB_ADDR + 2, (physaddr >> 16) & 0xFF);
   4803   1.96      fvdl 	ahc_outb(ahc, HSCB_ADDR + 3, (physaddr >> 24) & 0xFF);
   4804   1.14     gibbs 
   4805   1.96      fvdl 	physaddr = ahc->shared_data_busaddr;
   4806   1.96      fvdl 	ahc_outb(ahc, SHARED_DATA_ADDR, physaddr & 0xFF);
   4807   1.96      fvdl 	ahc_outb(ahc, SHARED_DATA_ADDR + 1, (physaddr >> 8) & 0xFF);
   4808   1.96      fvdl 	ahc_outb(ahc, SHARED_DATA_ADDR + 2, (physaddr >> 16) & 0xFF);
   4809   1.96      fvdl 	ahc_outb(ahc, SHARED_DATA_ADDR + 3, (physaddr >> 24) & 0xFF);
   4810   1.14     gibbs 
   4811   1.96      fvdl 	/*
   4812   1.96      fvdl 	 * Initialize the group code to command length table.
   4813   1.96      fvdl 	 * This overrides the values in TARG_SCSIRATE, so only
   4814   1.96      fvdl 	 * setup the table after we have processed that information.
   4815   1.96      fvdl 	 */
   4816   1.96      fvdl 	ahc_outb(ahc, CMDSIZE_TABLE, 5);
   4817   1.96      fvdl 	ahc_outb(ahc, CMDSIZE_TABLE + 1, 9);
   4818   1.96      fvdl 	ahc_outb(ahc, CMDSIZE_TABLE + 2, 9);
   4819   1.96      fvdl 	ahc_outb(ahc, CMDSIZE_TABLE + 3, 0);
   4820   1.96      fvdl 	ahc_outb(ahc, CMDSIZE_TABLE + 4, 15);
   4821   1.96      fvdl 	ahc_outb(ahc, CMDSIZE_TABLE + 5, 11);
   4822   1.96      fvdl 	ahc_outb(ahc, CMDSIZE_TABLE + 6, 0);
   4823   1.96      fvdl 	ahc_outb(ahc, CMDSIZE_TABLE + 7, 0);
   4824  1.112     perry 
   4825   1.96      fvdl 	/* Tell the sequencer of our initial queue positions */
   4826   1.96      fvdl 	ahc_outb(ahc, KERNEL_QINPOS, 0);
   4827   1.96      fvdl 	ahc_outb(ahc, QINPOS, 0);
   4828   1.96      fvdl 	ahc_outb(ahc, QOUTPOS, 0);
   4829   1.14     gibbs 
   4830   1.96      fvdl 	/*
   4831   1.96      fvdl 	 * Use the built in queue management registers
   4832   1.96      fvdl 	 * if they are available.
   4833   1.96      fvdl 	 */
   4834   1.96      fvdl 	if ((ahc->features & AHC_QUEUE_REGS) != 0) {
   4835   1.96      fvdl 		ahc_outb(ahc, QOFF_CTLSTA, SCB_QSIZE_256);
   4836   1.96      fvdl 		ahc_outb(ahc, SDSCB_QOFF, 0);
   4837   1.96      fvdl 		ahc_outb(ahc, SNSCB_QOFF, 0);
   4838   1.96      fvdl 		ahc_outb(ahc, HNSCB_QOFF, 0);
   4839   1.96      fvdl 	}
   4840   1.14     gibbs 
   4841   1.42      fvdl 
   4842   1.96      fvdl 	/* We don't have any waiting selections */
   4843   1.96      fvdl 	ahc_outb(ahc, WAITING_SCBH, SCB_LIST_NULL);
   4844   1.14     gibbs 
   4845   1.96      fvdl 	/* Our disconnection list is empty too */
   4846   1.96      fvdl 	ahc_outb(ahc, DISCONNECTED_SCBH, SCB_LIST_NULL);
   4847   1.42      fvdl 
   4848   1.96      fvdl 	/* Message out buffer starts empty */
   4849   1.96      fvdl 	ahc_outb(ahc, MSG_OUT, MSG_NOOP);
   4850   1.42      fvdl 
   4851   1.42      fvdl 	/*
   4852   1.96      fvdl 	 * Setup the allowed SCSI Sequences based on operational mode.
   4853  1.118       wiz 	 * If we are a target, we'll enable select in operations once
   4854   1.96      fvdl 	 * we've had a lun enabled.
   4855   1.42      fvdl 	 */
   4856   1.96      fvdl 	scsiseq_template = ENSELO|ENAUTOATNO|ENAUTOATNP;
   4857   1.96      fvdl 	if ((ahc->flags & AHC_INITIATORROLE) != 0)
   4858   1.96      fvdl 		scsiseq_template |= ENRSELI;
   4859   1.96      fvdl 	ahc_outb(ahc, SCSISEQ_TEMPLATE, scsiseq_template);
   4860   1.42      fvdl 
   4861   1.96      fvdl 	/*
   4862   1.96      fvdl 	 * Load the Sequencer program and Enable the adapter
   4863   1.96      fvdl 	 * in "fast" mode.
   4864   1.96      fvdl 	 */
   4865   1.96      fvdl 	if (bootverbose)
   4866   1.96      fvdl 		printf("%s: Downloading Sequencer Program...",
   4867   1.96      fvdl 		       ahc_name(ahc));
   4868   1.14     gibbs 
   4869   1.96      fvdl 	ahc_loadseq(ahc);
   4870   1.42      fvdl 
   4871   1.96      fvdl 	if ((ahc->features & AHC_ULTRA2) != 0) {
   4872   1.96      fvdl 		int wait;
   4873   1.14     gibbs 
   4874   1.96      fvdl 		/*
   4875   1.96      fvdl 		 * Wait for up to 500ms for our transceivers
   4876   1.96      fvdl 		 * to settle.  If the adapter does not have
   4877  1.108       wiz 		 * a cable attached, the transceivers may
   4878   1.96      fvdl 		 * never settle, so don't complain if we
   4879   1.96      fvdl 		 * fail here.
   4880   1.96      fvdl 		 */
   4881   1.96      fvdl 		ahc_pause(ahc);
   4882   1.96      fvdl 		for (wait = 5000;
   4883   1.96      fvdl 		     (ahc_inb(ahc, SBLKCTL) & (ENAB40|ENAB20)) == 0 && wait;
   4884   1.96      fvdl 		     wait--)
   4885   1.96      fvdl 			ahc_delay(100);
   4886   1.96      fvdl 		ahc_unpause(ahc);
   4887   1.96      fvdl 	}
   4888    1.1   mycroft 
   4889   1.96      fvdl 	/* We have to wait until after any system dumps... */
   4890   1.96      fvdl 	ahc->shutdown_hook = shutdownhook_establish(ahc_shutdown, ahc);
   4891    1.1   mycroft 
   4892   1.96      fvdl 	return (0);
   4893   1.96      fvdl }
   4894    1.1   mycroft 
   4895   1.96      fvdl void
   4896   1.96      fvdl ahc_intr_enable(struct ahc_softc *ahc, int enable)
   4897   1.96      fvdl {
   4898   1.96      fvdl 	u_int hcntrl;
   4899   1.42      fvdl 
   4900   1.96      fvdl 	hcntrl = ahc_inb(ahc, HCNTRL);
   4901   1.96      fvdl 	hcntrl &= ~INTEN;
   4902   1.96      fvdl 	ahc->pause &= ~INTEN;
   4903   1.96      fvdl 	ahc->unpause &= ~INTEN;
   4904   1.96      fvdl 	if (enable) {
   4905   1.96      fvdl 		hcntrl |= INTEN;
   4906   1.96      fvdl 		ahc->pause |= INTEN;
   4907   1.96      fvdl 		ahc->unpause |= INTEN;
   4908   1.96      fvdl 	}
   4909   1.96      fvdl 	ahc_outb(ahc, HCNTRL, hcntrl);
   4910   1.96      fvdl }
   4911   1.42      fvdl 
   4912   1.96      fvdl /*
   4913   1.96      fvdl  * Ensure that the card is paused in a location
   4914   1.96      fvdl  * outside of all critical sections and that all
   4915   1.96      fvdl  * pending work is completed prior to returning.
   4916   1.96      fvdl  * This routine should only be called from outside
   4917   1.96      fvdl  * an interrupt context.
   4918   1.96      fvdl  */
   4919   1.96      fvdl void
   4920   1.96      fvdl ahc_pause_and_flushwork(struct ahc_softc *ahc)
   4921   1.96      fvdl {
   4922   1.96      fvdl 	int intstat;
   4923   1.96      fvdl 	int maxloops;
   4924   1.96      fvdl 	int paused;
   4925   1.96      fvdl 
   4926   1.96      fvdl 	maxloops = 1000;
   4927   1.96      fvdl 	ahc->flags |= AHC_ALL_INTERRUPTS;
   4928   1.96      fvdl 	intstat = 0;
   4929   1.96      fvdl 	paused = FALSE;
   4930   1.96      fvdl 	do {
   4931   1.96      fvdl 		if (paused)
   4932   1.96      fvdl 			ahc_unpause(ahc);
   4933   1.96      fvdl 		ahc_intr(ahc);
   4934   1.96      fvdl 		ahc_pause(ahc);
   4935   1.96      fvdl 		paused = TRUE;
   4936   1.96      fvdl 		ahc_outb(ahc, SCSISEQ, ahc_inb(ahc, SCSISEQ) & ~ENSELO);
   4937   1.96      fvdl 		ahc_clear_critical_section(ahc);
   4938   1.96      fvdl 		if (intstat == 0xFF && (ahc->features & AHC_REMOVABLE) != 0)
   4939   1.42      fvdl 			break;
   4940   1.96      fvdl 	} while (--maxloops
   4941   1.96      fvdl 	      && (((intstat = ahc_inb(ahc, INTSTAT)) & INT_PEND) != 0
   4942   1.96      fvdl 	       || (ahc_inb(ahc, SSTAT0) & (SELDO|SELINGO))));
   4943   1.96      fvdl 	if (maxloops == 0) {
   4944   1.96      fvdl 		printf("Infinite interrupt loop, INTSTAT = %x",
   4945   1.96      fvdl 		       ahc_inb(ahc, INTSTAT));
   4946   1.14     gibbs 	}
   4947   1.96      fvdl 	ahc_platform_flushwork(ahc);
   4948   1.96      fvdl 	ahc->flags &= ~AHC_ALL_INTERRUPTS;
   4949   1.96      fvdl }
   4950   1.96      fvdl 
   4951   1.96      fvdl int
   4952   1.96      fvdl ahc_suspend(struct ahc_softc *ahc)
   4953   1.96      fvdl {
   4954   1.96      fvdl 	uint8_t *ptr;
   4955   1.96      fvdl 	int	 i;
   4956   1.96      fvdl 
   4957   1.96      fvdl 	ahc_pause_and_flushwork(ahc);
   4958   1.42      fvdl 
   4959   1.96      fvdl 	if (LIST_FIRST(&ahc->pending_scbs) != NULL)
   4960   1.96      fvdl 		return (EBUSY);
   4961   1.42      fvdl 
   4962   1.96      fvdl #if AHC_TARGET_MODE
   4963   1.96      fvdl 	/*
   4964   1.96      fvdl 	 * XXX What about ATIOs that have not yet been serviced?
   4965   1.96      fvdl 	 * Perhaps we should just refuse to be suspended if we
   4966   1.96      fvdl 	 * are acting in a target role.
   4967   1.96      fvdl 	 */
   4968   1.96      fvdl 	if (ahc->pending_device != NULL)
   4969   1.96      fvdl 		return (EBUSY);
   4970   1.42      fvdl #endif
   4971   1.96      fvdl 
   4972   1.96      fvdl 	/* Save volatile registers */
   4973   1.96      fvdl 	if ((ahc->features & AHC_TWIN) != 0) {
   4974   1.96      fvdl 		ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) | SELBUSB);
   4975   1.96      fvdl 		ahc->suspend_state.channel[1].scsiseq = ahc_inb(ahc, SCSISEQ);
   4976   1.96      fvdl 		ahc->suspend_state.channel[1].sxfrctl0 = ahc_inb(ahc, SXFRCTL0);
   4977   1.96      fvdl 		ahc->suspend_state.channel[1].sxfrctl1 = ahc_inb(ahc, SXFRCTL1);
   4978   1.96      fvdl 		ahc->suspend_state.channel[1].simode0 = ahc_inb(ahc, SIMODE0);
   4979   1.96      fvdl 		ahc->suspend_state.channel[1].simode1 = ahc_inb(ahc, SIMODE1);
   4980   1.96      fvdl 		ahc->suspend_state.channel[1].seltimer = ahc_inb(ahc, SELTIMER);
   4981   1.96      fvdl 		ahc->suspend_state.channel[1].seqctl = ahc_inb(ahc, SEQCTL);
   4982   1.96      fvdl 		ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) & ~SELBUSB);
   4983   1.96      fvdl 	}
   4984   1.96      fvdl 	ahc->suspend_state.channel[0].scsiseq = ahc_inb(ahc, SCSISEQ);
   4985   1.96      fvdl 	ahc->suspend_state.channel[0].sxfrctl0 = ahc_inb(ahc, SXFRCTL0);
   4986   1.96      fvdl 	ahc->suspend_state.channel[0].sxfrctl1 = ahc_inb(ahc, SXFRCTL1);
   4987   1.96      fvdl 	ahc->suspend_state.channel[0].simode0 = ahc_inb(ahc, SIMODE0);
   4988   1.96      fvdl 	ahc->suspend_state.channel[0].simode1 = ahc_inb(ahc, SIMODE1);
   4989   1.96      fvdl 	ahc->suspend_state.channel[0].seltimer = ahc_inb(ahc, SELTIMER);
   4990   1.96      fvdl 	ahc->suspend_state.channel[0].seqctl = ahc_inb(ahc, SEQCTL);
   4991   1.96      fvdl 
   4992   1.96      fvdl 	if ((ahc->chip & AHC_PCI) != 0) {
   4993   1.96      fvdl 		ahc->suspend_state.dscommand0 = ahc_inb(ahc, DSCOMMAND0);
   4994   1.96      fvdl 		ahc->suspend_state.dspcistatus = ahc_inb(ahc, DSPCISTATUS);
   4995   1.96      fvdl 	}
   4996   1.96      fvdl 
   4997   1.96      fvdl 	if ((ahc->features & AHC_DT) != 0) {
   4998   1.96      fvdl 		u_int sfunct;
   4999   1.96      fvdl 
   5000   1.96      fvdl 		sfunct = ahc_inb(ahc, SFUNCT) & ~ALT_MODE;
   5001   1.96      fvdl 		ahc_outb(ahc, SFUNCT, sfunct | ALT_MODE);
   5002   1.96      fvdl 		ahc->suspend_state.optionmode = ahc_inb(ahc, OPTIONMODE);
   5003   1.96      fvdl 		ahc_outb(ahc, SFUNCT, sfunct);
   5004   1.96      fvdl 		ahc->suspend_state.crccontrol1 = ahc_inb(ahc, CRCCONTROL1);
   5005   1.14     gibbs 	}
   5006    1.6   mycroft 
   5007   1.96      fvdl 	if ((ahc->features & AHC_MULTI_FUNC) != 0)
   5008   1.96      fvdl 		ahc->suspend_state.scbbaddr = ahc_inb(ahc, SCBBADDR);
   5009   1.96      fvdl 
   5010   1.96      fvdl 	if ((ahc->features & AHC_ULTRA2) != 0)
   5011   1.96      fvdl 		ahc->suspend_state.dff_thrsh = ahc_inb(ahc, DFF_THRSH);
   5012   1.96      fvdl 
   5013   1.96      fvdl 	ptr = ahc->suspend_state.scratch_ram;
   5014   1.96      fvdl 	for (i = 0; i < 64; i++)
   5015   1.96      fvdl 		*ptr++ = ahc_inb(ahc, SRAM_BASE + i);
   5016   1.96      fvdl 
   5017   1.96      fvdl 	if ((ahc->features & AHC_MORE_SRAM) != 0) {
   5018   1.96      fvdl 		for (i = 0; i < 16; i++)
   5019   1.96      fvdl 			*ptr++ = ahc_inb(ahc, TARG_OFFSET + i);
   5020   1.42      fvdl 	}
   5021    1.1   mycroft 
   5022   1.96      fvdl 	ptr = ahc->suspend_state.btt;
   5023   1.96      fvdl 	if ((ahc->flags & AHC_SCB_BTT) != 0) {
   5024   1.96      fvdl 		for (i = 0;i < AHC_NUM_TARGETS; i++) {
   5025   1.96      fvdl 			int j;
   5026   1.96      fvdl 
   5027   1.96      fvdl 			for (j = 0;j < AHC_NUM_LUNS; j++) {
   5028   1.96      fvdl 				u_int tcl;
   5029    1.1   mycroft 
   5030   1.96      fvdl 				tcl = BUILD_TCL(i << 4, j);
   5031   1.96      fvdl 				*ptr = ahc_index_busy_tcl(ahc, tcl);
   5032   1.96      fvdl 			}
   5033   1.96      fvdl 		}
   5034   1.96      fvdl 	}
   5035   1.96      fvdl 	ahc_shutdown(ahc);
   5036   1.96      fvdl 	return (0);
   5037   1.42      fvdl }
   5038    1.1   mycroft 
   5039   1.96      fvdl int
   5040   1.96      fvdl ahc_resume(struct ahc_softc *ahc)
   5041   1.42      fvdl {
   5042   1.96      fvdl 	uint8_t *ptr;
   5043   1.96      fvdl 	int	 i;
   5044   1.96      fvdl 
   5045   1.96      fvdl 	ahc_reset(ahc);
   5046   1.96      fvdl 
   5047   1.96      fvdl 	ahc_build_free_scb_list(ahc);
   5048   1.96      fvdl 
   5049   1.96      fvdl 	/* Restore volatile registers */
   5050   1.96      fvdl 	if ((ahc->features & AHC_TWIN) != 0) {
   5051   1.96      fvdl 		ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) | SELBUSB);
   5052   1.96      fvdl 		ahc_outb(ahc, SCSIID, ahc->our_id);
   5053   1.96      fvdl 		ahc_outb(ahc, SCSISEQ, ahc->suspend_state.channel[1].scsiseq);
   5054   1.96      fvdl 		ahc_outb(ahc, SXFRCTL0, ahc->suspend_state.channel[1].sxfrctl0);
   5055   1.96      fvdl 		ahc_outb(ahc, SXFRCTL1, ahc->suspend_state.channel[1].sxfrctl1);
   5056   1.96      fvdl 		ahc_outb(ahc, SIMODE0, ahc->suspend_state.channel[1].simode0);
   5057   1.96      fvdl 		ahc_outb(ahc, SIMODE1, ahc->suspend_state.channel[1].simode1);
   5058   1.96      fvdl 		ahc_outb(ahc, SELTIMER, ahc->suspend_state.channel[1].seltimer);
   5059   1.96      fvdl 		ahc_outb(ahc, SEQCTL, ahc->suspend_state.channel[1].seqctl);
   5060   1.96      fvdl 		ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) & ~SELBUSB);
   5061   1.96      fvdl 	}
   5062   1.96      fvdl 	ahc_outb(ahc, SCSISEQ, ahc->suspend_state.channel[0].scsiseq);
   5063   1.96      fvdl 	ahc_outb(ahc, SXFRCTL0, ahc->suspend_state.channel[0].sxfrctl0);
   5064   1.96      fvdl 	ahc_outb(ahc, SXFRCTL1, ahc->suspend_state.channel[0].sxfrctl1);
   5065   1.96      fvdl 	ahc_outb(ahc, SIMODE0, ahc->suspend_state.channel[0].simode0);
   5066   1.96      fvdl 	ahc_outb(ahc, SIMODE1, ahc->suspend_state.channel[0].simode1);
   5067   1.96      fvdl 	ahc_outb(ahc, SELTIMER, ahc->suspend_state.channel[0].seltimer);
   5068   1.96      fvdl 	ahc_outb(ahc, SEQCTL, ahc->suspend_state.channel[0].seqctl);
   5069   1.96      fvdl 	if ((ahc->features & AHC_ULTRA2) != 0)
   5070   1.96      fvdl 		ahc_outb(ahc, SCSIID_ULTRA2, ahc->our_id);
   5071   1.96      fvdl 	else
   5072   1.96      fvdl 		ahc_outb(ahc, SCSIID, ahc->our_id);
   5073   1.22       cgd 
   5074   1.96      fvdl 	if ((ahc->chip & AHC_PCI) != 0) {
   5075   1.96      fvdl 		ahc_outb(ahc, DSCOMMAND0, ahc->suspend_state.dscommand0);
   5076   1.96      fvdl 		ahc_outb(ahc, DSPCISTATUS, ahc->suspend_state.dspcistatus);
   5077   1.96      fvdl 	}
   5078    1.6   mycroft 
   5079   1.96      fvdl 	if ((ahc->features & AHC_DT) != 0) {
   5080   1.96      fvdl 		u_int sfunct;
   5081   1.42      fvdl 
   5082   1.96      fvdl 		sfunct = ahc_inb(ahc, SFUNCT) & ~ALT_MODE;
   5083   1.96      fvdl 		ahc_outb(ahc, SFUNCT, sfunct | ALT_MODE);
   5084   1.96      fvdl 		ahc_outb(ahc, OPTIONMODE, ahc->suspend_state.optionmode);
   5085   1.96      fvdl 		ahc_outb(ahc, SFUNCT, sfunct);
   5086   1.96      fvdl 		ahc_outb(ahc, CRCCONTROL1, ahc->suspend_state.crccontrol1);
   5087   1.96      fvdl 	}
   5088   1.42      fvdl 
   5089   1.96      fvdl 	if ((ahc->features & AHC_MULTI_FUNC) != 0)
   5090   1.96      fvdl 		ahc_outb(ahc, SCBBADDR, ahc->suspend_state.scbbaddr);
   5091   1.42      fvdl 
   5092   1.96      fvdl 	if ((ahc->features & AHC_ULTRA2) != 0)
   5093   1.96      fvdl 		ahc_outb(ahc, DFF_THRSH, ahc->suspend_state.dff_thrsh);
   5094   1.42      fvdl 
   5095   1.96      fvdl 	ptr = ahc->suspend_state.scratch_ram;
   5096   1.96      fvdl 	for (i = 0; i < 64; i++)
   5097   1.96      fvdl 		ahc_outb(ahc, SRAM_BASE + i, *ptr++);
   5098   1.59        pk 
   5099   1.96      fvdl 	if ((ahc->features & AHC_MORE_SRAM) != 0) {
   5100   1.96      fvdl 		for (i = 0; i < 16; i++)
   5101   1.96      fvdl 			ahc_outb(ahc, TARG_OFFSET + i, *ptr++);
   5102    1.6   mycroft 	}
   5103   1.14     gibbs 
   5104   1.96      fvdl 	ptr = ahc->suspend_state.btt;
   5105   1.96      fvdl 	if ((ahc->flags & AHC_SCB_BTT) != 0) {
   5106   1.96      fvdl 		for (i = 0;i < AHC_NUM_TARGETS; i++) {
   5107   1.96      fvdl 			int j;
   5108   1.14     gibbs 
   5109   1.96      fvdl 			for (j = 0;j < AHC_NUM_LUNS; j++) {
   5110   1.96      fvdl 				u_int tcl;
   5111   1.59        pk 
   5112   1.96      fvdl 				tcl = BUILD_TCL(i << 4, j);
   5113   1.96      fvdl 				ahc_busy_tcl(ahc, tcl, *ptr);
   5114   1.96      fvdl 			}
   5115   1.96      fvdl 		}
   5116   1.96      fvdl 	}
   5117   1.96      fvdl 	return (0);
   5118    1.1   mycroft }
   5119    1.1   mycroft 
   5120   1.96      fvdl /************************** Busy Target Table *********************************/
   5121    1.1   mycroft /*
   5122   1.96      fvdl  * Return the untagged transaction id for a given target/channel lun.
   5123   1.96      fvdl  * Optionally, clear the entry.
   5124    1.1   mycroft  */
   5125   1.96      fvdl u_int
   5126   1.96      fvdl ahc_index_busy_tcl(struct ahc_softc *ahc, u_int tcl)
   5127    1.1   mycroft {
   5128   1.96      fvdl 	u_int scbid;
   5129   1.96      fvdl 	u_int target_offset;
   5130   1.96      fvdl 
   5131   1.96      fvdl 	if ((ahc->flags & AHC_SCB_BTT) != 0) {
   5132   1.96      fvdl 		u_int saved_scbptr;
   5133  1.112     perry 
   5134   1.96      fvdl 		saved_scbptr = ahc_inb(ahc, SCBPTR);
   5135   1.96      fvdl 		ahc_outb(ahc, SCBPTR, TCL_LUN(tcl));
   5136   1.96      fvdl 		scbid = ahc_inb(ahc, SCB_64_BTT + TCL_TARGET_OFFSET(tcl));
   5137   1.96      fvdl 		ahc_outb(ahc, SCBPTR, saved_scbptr);
   5138   1.96      fvdl 	} else {
   5139   1.96      fvdl 		target_offset = TCL_TARGET_OFFSET(tcl);
   5140   1.96      fvdl 		scbid = ahc_inb(ahc, BUSY_TARGETS + target_offset);
   5141   1.96      fvdl 	}
   5142   1.96      fvdl 
   5143   1.96      fvdl 	return (scbid);
   5144   1.96      fvdl }
   5145   1.59        pk 
   5146   1.96      fvdl void
   5147   1.96      fvdl ahc_unbusy_tcl(struct ahc_softc *ahc, u_int tcl)
   5148   1.96      fvdl {
   5149   1.96      fvdl 	u_int target_offset;
   5150   1.42      fvdl 
   5151   1.96      fvdl 	if ((ahc->flags & AHC_SCB_BTT) != 0) {
   5152   1.96      fvdl 		u_int saved_scbptr;
   5153  1.112     perry 
   5154   1.96      fvdl 		saved_scbptr = ahc_inb(ahc, SCBPTR);
   5155   1.96      fvdl 		ahc_outb(ahc, SCBPTR, TCL_LUN(tcl));
   5156   1.96      fvdl 		ahc_outb(ahc, SCB_64_BTT+TCL_TARGET_OFFSET(tcl), SCB_LIST_NULL);
   5157   1.96      fvdl 		ahc_outb(ahc, SCBPTR, saved_scbptr);
   5158   1.96      fvdl 	} else {
   5159   1.96      fvdl 		target_offset = TCL_TARGET_OFFSET(tcl);
   5160   1.96      fvdl 		ahc_outb(ahc, BUSY_TARGETS + target_offset, SCB_LIST_NULL);
   5161   1.96      fvdl 	}
   5162   1.96      fvdl }
   5163   1.42      fvdl 
   5164   1.96      fvdl void
   5165   1.96      fvdl ahc_busy_tcl(struct ahc_softc *ahc, u_int tcl, u_int scbid)
   5166   1.96      fvdl {
   5167   1.96      fvdl 	u_int target_offset;
   5168   1.42      fvdl 
   5169   1.96      fvdl 	if ((ahc->flags & AHC_SCB_BTT) != 0) {
   5170   1.96      fvdl 		u_int saved_scbptr;
   5171  1.112     perry 
   5172   1.96      fvdl 		saved_scbptr = ahc_inb(ahc, SCBPTR);
   5173   1.96      fvdl 		ahc_outb(ahc, SCBPTR, TCL_LUN(tcl));
   5174   1.96      fvdl 		ahc_outb(ahc, SCB_64_BTT + TCL_TARGET_OFFSET(tcl), scbid);
   5175   1.96      fvdl 		ahc_outb(ahc, SCBPTR, saved_scbptr);
   5176   1.96      fvdl 	} else {
   5177   1.96      fvdl 		target_offset = TCL_TARGET_OFFSET(tcl);
   5178   1.96      fvdl 		ahc_outb(ahc, BUSY_TARGETS + target_offset, scbid);
   5179   1.42      fvdl 	}
   5180   1.96      fvdl }
   5181    1.6   mycroft 
   5182   1.96      fvdl /************************** SCB and SCB queue management **********************/
   5183   1.96      fvdl int
   5184   1.96      fvdl ahc_match_scb(struct ahc_softc *ahc, struct scb *scb, int target,
   5185  1.123  christos     char channel, int lun, u_int tag, role_t role)
   5186   1.96      fvdl {
   5187   1.96      fvdl 	int targ = SCB_GET_TARGET(ahc, scb);
   5188   1.96      fvdl 	char chan = SCB_GET_CHANNEL(ahc, scb);
   5189   1.96      fvdl 	int slun = SCB_GET_LUN(scb);
   5190   1.96      fvdl 	int match;
   5191   1.28       leo 
   5192   1.96      fvdl 	match = ((chan == channel) || (channel == ALL_CHANNELS));
   5193   1.96      fvdl 	if (match != 0)
   5194   1.96      fvdl 		match = ((targ == target) || (target == CAM_TARGET_WILDCARD));
   5195   1.96      fvdl 	if (match != 0)
   5196   1.96      fvdl 		match = ((lun == slun) || (lun == CAM_LUN_WILDCARD));
   5197   1.96      fvdl 	if (match != 0) {
   5198   1.96      fvdl #if 0
   5199   1.96      fvdl #if AHC_TARGET_MODE
   5200   1.96      fvdl 		int group;
   5201   1.42      fvdl 
   5202   1.96      fvdl 		group = XPT_FC_GROUP(scb->io_ctx->ccb_h.func_code);
   5203   1.96      fvdl 		if (role == ROLE_INITIATOR) {
   5204   1.96      fvdl 			match = (group != XPT_FC_GROUP_TMODE)
   5205   1.96      fvdl 			      && ((tag == scb->hscb->tag)
   5206   1.96      fvdl 			       || (tag == SCB_LIST_NULL));
   5207   1.96      fvdl 		} else if (role == ROLE_TARGET) {
   5208   1.96      fvdl 			match = (group == XPT_FC_GROUP_TMODE)
   5209   1.96      fvdl 			      && ((tag == scb->io_ctx->csio.tag_id)
   5210   1.96      fvdl 			       || (tag == SCB_LIST_NULL));
   5211   1.96      fvdl 		}
   5212   1.96      fvdl #else /* !AHC_TARGET_MODE */
   5213   1.96      fvdl 		match = ((tag == scb->hscb->tag) || (tag == SCB_LIST_NULL));
   5214   1.96      fvdl #endif /* AHC_TARGET_MODE */
   5215   1.96      fvdl #endif
   5216   1.28       leo 	}
   5217   1.42      fvdl 
   5218   1.96      fvdl 	return match;
   5219   1.96      fvdl }
   5220   1.96      fvdl 
   5221   1.96      fvdl void
   5222   1.96      fvdl ahc_freeze_devq(struct ahc_softc *ahc, struct scb *scb)
   5223   1.96      fvdl {
   5224   1.96      fvdl 	int	target;
   5225   1.96      fvdl 	char	channel;
   5226   1.96      fvdl 	int	lun;
   5227   1.42      fvdl 
   5228   1.96      fvdl 	target = SCB_GET_TARGET(ahc, scb);
   5229   1.96      fvdl 	lun = SCB_GET_LUN(scb);
   5230   1.96      fvdl 	channel = SCB_GET_CHANNEL(ahc, scb);
   5231  1.112     perry 
   5232   1.96      fvdl 	ahc_search_qinfifo(ahc, target, channel, lun,
   5233   1.96      fvdl 			   /*tag*/SCB_LIST_NULL, ROLE_UNKNOWN,
   5234   1.96      fvdl 			   CAM_REQUEUE_REQ, SEARCH_COMPLETE);
   5235   1.42      fvdl 
   5236   1.96      fvdl 	ahc_platform_freeze_devq(ahc, scb);
   5237   1.96      fvdl }
   5238   1.42      fvdl 
   5239   1.96      fvdl void
   5240   1.96      fvdl ahc_qinfifo_requeue_tail(struct ahc_softc *ahc, struct scb *scb)
   5241   1.96      fvdl {
   5242   1.96      fvdl 	struct scb *prev_scb;
   5243   1.42      fvdl 
   5244   1.96      fvdl 	prev_scb = NULL;
   5245   1.96      fvdl 	if (ahc_qinfifo_count(ahc) != 0) {
   5246   1.96      fvdl 		u_int prev_tag;
   5247   1.96      fvdl 		uint8_t prev_pos;
   5248   1.42      fvdl 
   5249   1.96      fvdl 		prev_pos = ahc->qinfifonext - 1;
   5250   1.96      fvdl 		prev_tag = ahc->qinfifo[prev_pos];
   5251   1.96      fvdl 		prev_scb = ahc_lookup_scb(ahc, prev_tag);
   5252   1.42      fvdl 	}
   5253   1.96      fvdl 	ahc_qinfifo_requeue(ahc, prev_scb, scb);
   5254   1.96      fvdl 	if ((ahc->features & AHC_QUEUE_REGS) != 0) {
   5255   1.96      fvdl 		ahc_outb(ahc, HNSCB_QOFF, ahc->qinfifonext);
   5256   1.96      fvdl 	} else {
   5257   1.96      fvdl 		ahc_outb(ahc, KERNEL_QINPOS, ahc->qinfifonext);
   5258    1.1   mycroft 	}
   5259   1.96      fvdl }
   5260   1.42      fvdl 
   5261   1.96      fvdl static void
   5262   1.96      fvdl ahc_qinfifo_requeue(struct ahc_softc *ahc, struct scb *prev_scb,
   5263   1.96      fvdl 		    struct scb *scb)
   5264   1.96      fvdl {
   5265   1.96      fvdl 	if (prev_scb == NULL) {
   5266   1.96      fvdl 		ahc_outb(ahc, NEXT_QUEUED_SCB, scb->hscb->tag);
   5267   1.96      fvdl 	} else {
   5268   1.96      fvdl 		prev_scb->hscb->next = scb->hscb->tag;
   5269  1.112     perry 		ahc_sync_scb(ahc, prev_scb,
   5270   1.96      fvdl 			     BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
   5271   1.96      fvdl 	}
   5272   1.96      fvdl 	ahc->qinfifo[ahc->qinfifonext++] = scb->hscb->tag;
   5273   1.96      fvdl 	scb->hscb->next = ahc->next_queued_scb->hscb->tag;
   5274   1.96      fvdl 	ahc_sync_scb(ahc, scb, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
   5275   1.42      fvdl }
   5276   1.42      fvdl 
   5277   1.96      fvdl static int
   5278   1.96      fvdl ahc_qinfifo_count(struct ahc_softc *ahc)
   5279   1.96      fvdl {
   5280   1.96      fvdl 	uint8_t qinpos;
   5281   1.96      fvdl 	uint8_t diff;
   5282   1.42      fvdl 
   5283   1.96      fvdl 	if ((ahc->features & AHC_QUEUE_REGS) != 0) {
   5284   1.96      fvdl 		qinpos = ahc_inb(ahc, SNSCB_QOFF);
   5285   1.96      fvdl 		ahc_outb(ahc, SNSCB_QOFF, qinpos);
   5286   1.96      fvdl 	} else
   5287   1.96      fvdl 		qinpos = ahc_inb(ahc, QINPOS);
   5288   1.96      fvdl 	diff = ahc->qinfifonext - qinpos;
   5289   1.96      fvdl 	return (diff);
   5290    1.1   mycroft }
   5291    1.1   mycroft 
   5292    1.1   mycroft int
   5293   1.96      fvdl ahc_search_qinfifo(struct ahc_softc *ahc, int target, char channel,
   5294   1.96      fvdl 		   int lun, u_int tag, role_t role, uint32_t status,
   5295   1.96      fvdl 		   ahc_search_action action)
   5296    1.1   mycroft {
   5297   1.96      fvdl 	struct	scb *scb;
   5298   1.96      fvdl 	struct	scb *prev_scb;
   5299   1.96      fvdl 	uint8_t qinstart;
   5300   1.96      fvdl 	uint8_t qinpos;
   5301   1.96      fvdl 	uint8_t qintail;
   5302   1.96      fvdl 	uint8_t next;
   5303   1.96      fvdl 	uint8_t prev;
   5304   1.96      fvdl 	uint8_t curscbptr;
   5305   1.96      fvdl 	int	found;
   5306   1.96      fvdl 	int	have_qregs;
   5307   1.96      fvdl 
   5308   1.96      fvdl 	qintail = ahc->qinfifonext;
   5309   1.96      fvdl 	have_qregs = (ahc->features & AHC_QUEUE_REGS) != 0;
   5310   1.96      fvdl 	if (have_qregs) {
   5311   1.96      fvdl 		qinstart = ahc_inb(ahc, SNSCB_QOFF);
   5312   1.96      fvdl 		ahc_outb(ahc, SNSCB_QOFF, qinstart);
   5313   1.96      fvdl 	} else
   5314   1.96      fvdl 		qinstart = ahc_inb(ahc, QINPOS);
   5315   1.96      fvdl 	qinpos = qinstart;
   5316   1.96      fvdl 	found = 0;
   5317   1.96      fvdl 	prev_scb = NULL;
   5318   1.42      fvdl 
   5319   1.96      fvdl 	if (action == SEARCH_COMPLETE) {
   5320   1.96      fvdl 		/*
   5321   1.96      fvdl 		 * Don't attempt to run any queued untagged transactions
   5322   1.96      fvdl 		 * until we are done with the abort process.
   5323   1.96      fvdl 		 */
   5324   1.96      fvdl 		ahc_freeze_untagged_queues(ahc);
   5325   1.42      fvdl 	}
   5326   1.28       leo 
   5327    1.1   mycroft 	/*
   5328   1.96      fvdl 	 * Start with an empty queue.  Entries that are not chosen
   5329   1.96      fvdl 	 * for removal will be re-added to the queue as we go.
   5330    1.1   mycroft 	 */
   5331   1.96      fvdl 	ahc->qinfifonext = qinpos;
   5332   1.96      fvdl 	ahc_outb(ahc, NEXT_QUEUED_SCB, ahc->next_queued_scb->hscb->tag);
   5333   1.59        pk 
   5334   1.96      fvdl 	while (qinpos != qintail) {
   5335   1.96      fvdl 		scb = ahc_lookup_scb(ahc, ahc->qinfifo[qinpos]);
   5336   1.96      fvdl 		if (scb == NULL) {
   5337   1.96      fvdl 			printf("qinpos = %d, SCB index = %d\n",
   5338   1.96      fvdl 				qinpos, ahc->qinfifo[qinpos]);
   5339   1.96      fvdl 			panic("Loop 1\n");
   5340   1.96      fvdl 		}
   5341    1.1   mycroft 
   5342   1.96      fvdl 		if (ahc_match_scb(ahc, scb, target, channel, lun, tag, role)) {
   5343   1.96      fvdl 			/*
   5344   1.96      fvdl 			 * We found an scb that needs to be acted on.
   5345   1.96      fvdl 			 */
   5346   1.96      fvdl 			found++;
   5347   1.96      fvdl 			switch (action) {
   5348   1.96      fvdl 			case SEARCH_COMPLETE:
   5349   1.96      fvdl 			{
   5350   1.96      fvdl 				cam_status ostat;
   5351   1.96      fvdl 				cam_status cstat;
   5352    1.6   mycroft 
   5353   1.96      fvdl 				ostat = ahc_get_transaction_status(scb);
   5354   1.96      fvdl 				if (ostat == CAM_REQ_INPROG)
   5355   1.96      fvdl 					ahc_set_transaction_status(scb, status);
   5356   1.96      fvdl 				cstat = ahc_get_transaction_status(scb);
   5357   1.96      fvdl 				if (cstat != CAM_REQ_CMP)
   5358   1.96      fvdl 					ahc_freeze_scb(scb);
   5359   1.96      fvdl 				if ((scb->flags & SCB_ACTIVE) == 0)
   5360   1.96      fvdl 					printf("Inactive SCB in qinfifo\n");
   5361   1.96      fvdl 				ahc_done(ahc, scb);
   5362    1.1   mycroft 
   5363   1.96      fvdl 				/* FALLTHROUGH */
   5364   1.96      fvdl 			}
   5365   1.96      fvdl 			case SEARCH_REMOVE:
   5366   1.96      fvdl 				break;
   5367   1.96      fvdl 			case SEARCH_COUNT:
   5368   1.96      fvdl 				ahc_qinfifo_requeue(ahc, prev_scb, scb);
   5369   1.96      fvdl 				prev_scb = scb;
   5370   1.96      fvdl 				break;
   5371   1.96      fvdl 			}
   5372   1.96      fvdl 		} else {
   5373   1.96      fvdl 			ahc_qinfifo_requeue(ahc, prev_scb, scb);
   5374   1.96      fvdl 			prev_scb = scb;
   5375   1.96      fvdl 		}
   5376   1.96      fvdl 		qinpos++;
   5377   1.96      fvdl 	}
   5378    1.1   mycroft 
   5379   1.96      fvdl 	if ((ahc->features & AHC_QUEUE_REGS) != 0) {
   5380   1.96      fvdl 		ahc_outb(ahc, HNSCB_QOFF, ahc->qinfifonext);
   5381   1.96      fvdl 	} else {
   5382   1.96      fvdl 		ahc_outb(ahc, KERNEL_QINPOS, ahc->qinfifonext);
   5383   1.96      fvdl 	}
   5384    1.1   mycroft 
   5385   1.96      fvdl 	if (action != SEARCH_COUNT
   5386   1.96      fvdl 	 && (found != 0)
   5387   1.96      fvdl 	 && (qinstart != ahc->qinfifonext)) {
   5388   1.96      fvdl 		/*
   5389  1.105       wiz 		 * The sequencer may be in the process of DMA'ing
   5390   1.96      fvdl 		 * down the SCB at the beginning of the queue.
   5391   1.96      fvdl 		 * This could be problematic if either the first,
   5392   1.96      fvdl 		 * or the second SCB is removed from the queue
   5393   1.96      fvdl 		 * (the first SCB includes a pointer to the "next"
   5394  1.105       wiz 		 * SCB to DMA). If we have removed any entries, swap
   5395   1.96      fvdl 		 * the first element in the queue with the next HSCB
   5396   1.96      fvdl 		 * so the sequencer will notice that NEXT_QUEUED_SCB
   5397  1.105       wiz 		 * has changed during its DMA attempt and will retry
   5398   1.96      fvdl 		 * the DMA.
   5399   1.96      fvdl 		 */
   5400   1.96      fvdl 		scb = ahc_lookup_scb(ahc, ahc->qinfifo[qinstart]);
   5401    1.6   mycroft 
   5402   1.96      fvdl 		if (scb == NULL) {
   5403   1.96      fvdl 			printf("found = %d, qinstart = %d, qinfifionext = %d\n",
   5404   1.96      fvdl 				found, qinstart, ahc->qinfifonext);
   5405   1.96      fvdl 			panic("First/Second Qinfifo fixup\n");
   5406   1.96      fvdl 		}
   5407   1.96      fvdl 		/*
   5408   1.96      fvdl 		 * ahc_swap_with_next_hscb forces our next pointer to
   5409   1.96      fvdl 		 * point to the reserved SCB for future commands.  Save
   5410   1.96      fvdl 		 * and restore our original next pointer to maintain
   5411   1.96      fvdl 		 * queue integrity.
   5412   1.96      fvdl 		 */
   5413   1.96      fvdl 		next = scb->hscb->next;
   5414   1.96      fvdl 		ahc->scb_data->scbindex[scb->hscb->tag] = NULL;
   5415   1.96      fvdl 		ahc_swap_with_next_hscb(ahc, scb);
   5416   1.96      fvdl 		scb->hscb->next = next;
   5417   1.96      fvdl 		ahc->qinfifo[qinstart] = scb->hscb->tag;
   5418   1.96      fvdl 
   5419   1.96      fvdl 		/* Tell the card about the new head of the qinfifo. */
   5420   1.96      fvdl 		ahc_outb(ahc, NEXT_QUEUED_SCB, scb->hscb->tag);
   5421   1.96      fvdl 
   5422   1.96      fvdl 		/* Fixup the tail "next" pointer. */
   5423   1.96      fvdl 		qintail = ahc->qinfifonext - 1;
   5424   1.96      fvdl 		scb = ahc_lookup_scb(ahc, ahc->qinfifo[qintail]);
   5425   1.96      fvdl 		scb->hscb->next = ahc->next_queued_scb->hscb->tag;
   5426   1.96      fvdl 	}
   5427    1.6   mycroft 
   5428   1.28       leo 	/*
   5429   1.96      fvdl 	 * Search waiting for selection list.
   5430   1.28       leo 	 */
   5431   1.96      fvdl 	curscbptr = ahc_inb(ahc, SCBPTR);
   5432   1.96      fvdl 	next = ahc_inb(ahc, WAITING_SCBH);  /* Start at head of list. */
   5433   1.96      fvdl 	prev = SCB_LIST_NULL;
   5434   1.96      fvdl 
   5435   1.96      fvdl 	while (next != SCB_LIST_NULL) {
   5436   1.96      fvdl 		uint8_t scb_index;
   5437   1.42      fvdl 
   5438   1.96      fvdl 		ahc_outb(ahc, SCBPTR, next);
   5439   1.96      fvdl 		scb_index = ahc_inb(ahc, SCB_TAG);
   5440   1.96      fvdl 		if (scb_index >= ahc->scb_data->numscbs) {
   5441   1.96      fvdl 			printf("Waiting List inconsistency. "
   5442   1.96      fvdl 			       "SCB index == %d, yet numscbs == %d.",
   5443   1.96      fvdl 			       scb_index, ahc->scb_data->numscbs);
   5444   1.96      fvdl 			ahc_dump_card_state(ahc);
   5445   1.96      fvdl 			panic("for safety");
   5446   1.96      fvdl 		}
   5447   1.96      fvdl 		scb = ahc_lookup_scb(ahc, scb_index);
   5448   1.96      fvdl 		if (scb == NULL) {
   5449   1.96      fvdl 			printf("scb_index = %d, next = %d\n",
   5450   1.96      fvdl 				scb_index, next);
   5451   1.96      fvdl 			panic("Waiting List traversal\n");
   5452   1.42      fvdl 		}
   5453   1.96      fvdl 		if (ahc_match_scb(ahc, scb, target, channel,
   5454   1.96      fvdl 				  lun, SCB_LIST_NULL, role)) {
   5455   1.96      fvdl 			/*
   5456   1.96      fvdl 			 * We found an scb that needs to be acted on.
   5457   1.96      fvdl 			 */
   5458   1.96      fvdl 			found++;
   5459   1.96      fvdl 			switch (action) {
   5460   1.96      fvdl 			case SEARCH_COMPLETE:
   5461   1.96      fvdl 			{
   5462   1.96      fvdl 				cam_status ostat;
   5463   1.96      fvdl 				cam_status cstat;
   5464   1.96      fvdl 
   5465   1.96      fvdl 				ostat = ahc_get_transaction_status(scb);
   5466   1.96      fvdl 				if (ostat == CAM_REQ_INPROG)
   5467   1.96      fvdl 					ahc_set_transaction_status(scb, status);
   5468   1.96      fvdl 				cstat = ahc_get_transaction_status(scb);
   5469   1.96      fvdl 				if (cstat != CAM_REQ_CMP)
   5470   1.96      fvdl 					ahc_freeze_scb(scb);
   5471   1.96      fvdl 				if ((scb->flags & SCB_ACTIVE) == 0)
   5472   1.96      fvdl 					printf("Inactive SCB in Waiting List\n");
   5473   1.96      fvdl 				ahc_done(ahc, scb);
   5474   1.96      fvdl 				/* FALLTHROUGH */
   5475   1.96      fvdl 			}
   5476   1.96      fvdl 			case SEARCH_REMOVE:
   5477   1.96      fvdl 				next = ahc_rem_wscb(ahc, next, prev);
   5478   1.96      fvdl 				break;
   5479   1.96      fvdl 			case SEARCH_COUNT:
   5480   1.96      fvdl 				prev = next;
   5481   1.96      fvdl 				next = ahc_inb(ahc, SCB_NEXT);
   5482   1.96      fvdl 				break;
   5483   1.96      fvdl 			}
   5484   1.42      fvdl 		} else {
   5485  1.112     perry 
   5486   1.96      fvdl 			prev = next;
   5487   1.96      fvdl 			next = ahc_inb(ahc, SCB_NEXT);
   5488   1.42      fvdl 		}
   5489   1.28       leo 	}
   5490   1.96      fvdl 	ahc_outb(ahc, SCBPTR, curscbptr);
   5491   1.42      fvdl 
   5492   1.96      fvdl 	found += ahc_search_untagged_queues(ahc, /*ahc_io_ctx_t*/NULL, target,
   5493   1.96      fvdl 					    channel, lun, status, action);
   5494   1.42      fvdl 
   5495   1.96      fvdl 	if (action == SEARCH_COMPLETE)
   5496   1.96      fvdl 		ahc_release_untagged_queues(ahc);
   5497   1.96      fvdl 	return (found);
   5498   1.96      fvdl }
   5499    1.6   mycroft 
   5500   1.96      fvdl int
   5501  1.122  christos ahc_search_untagged_queues(struct ahc_softc *ahc,
   5502  1.123  christos     struct scsipi_xfer *xs, int target, char channel, int lun,
   5503  1.122  christos     uint32_t status, ahc_search_action action)
   5504   1.96      fvdl {
   5505   1.96      fvdl 	struct	scb *scb;
   5506   1.96      fvdl 	int	maxtarget;
   5507   1.96      fvdl 	int	found;
   5508   1.96      fvdl 	int	i;
   5509   1.42      fvdl 
   5510   1.96      fvdl 	if (action == SEARCH_COMPLETE) {
   5511    1.1   mycroft 		/*
   5512   1.96      fvdl 		 * Don't attempt to run any queued untagged transactions
   5513   1.96      fvdl 		 * until we are done with the abort process.
   5514    1.1   mycroft 		 */
   5515   1.96      fvdl 		ahc_freeze_untagged_queues(ahc);
   5516    1.6   mycroft 	}
   5517   1.42      fvdl 
   5518   1.96      fvdl 	found = 0;
   5519   1.96      fvdl 	i = 0;
   5520   1.96      fvdl 	if ((ahc->flags & AHC_SCB_BTT) == 0) {
   5521    1.6   mycroft 
   5522   1.96      fvdl 		maxtarget = 16;
   5523   1.96      fvdl 		if (target != CAM_TARGET_WILDCARD) {
   5524    1.1   mycroft 
   5525   1.96      fvdl 			i = target;
   5526   1.96      fvdl 			if (channel == 'B')
   5527   1.96      fvdl 				i += 8;
   5528   1.96      fvdl 			maxtarget = i + 1;
   5529   1.96      fvdl 		}
   5530   1.42      fvdl 	} else {
   5531   1.96      fvdl 		maxtarget = 0;
   5532    1.6   mycroft 	}
   5533    1.6   mycroft 
   5534   1.96      fvdl 	for (; i < maxtarget; i++) {
   5535   1.96      fvdl 		struct scb_tailq *untagged_q;
   5536   1.96      fvdl 		struct scb *next_scb;
   5537    1.6   mycroft 
   5538   1.96      fvdl 		untagged_q = &(ahc->untagged_queues[i]);
   5539   1.96      fvdl 		next_scb = TAILQ_FIRST(untagged_q);
   5540   1.96      fvdl 		while (next_scb != NULL) {
   5541   1.42      fvdl 
   5542   1.96      fvdl 			scb = next_scb;
   5543   1.96      fvdl 			next_scb = TAILQ_NEXT(scb, links.tqe);
   5544   1.42      fvdl 
   5545   1.42      fvdl 			/*
   5546   1.96      fvdl 			 * The head of the list may be the currently
   5547   1.96      fvdl 			 * active untagged command for a device.
   5548   1.96      fvdl 			 * We're only searching for commands that
   5549   1.96      fvdl 			 * have not been started.  A transaction
   5550   1.96      fvdl 			 * marked active but still in the qinfifo
   5551   1.96      fvdl 			 * is removed by the qinfifo scanning code
   5552   1.96      fvdl 			 * above.
   5553   1.42      fvdl 			 */
   5554   1.96      fvdl 			if ((scb->flags & SCB_ACTIVE) != 0)
   5555   1.96      fvdl 				continue;
   5556   1.96      fvdl 
   5557   1.96      fvdl 			if (ahc_match_scb(ahc, scb, target, channel, lun,
   5558   1.96      fvdl 					  SCB_LIST_NULL, ROLE_INITIATOR) == 0
   5559   1.96      fvdl 			    /*|| (ctx != NULL && ctx != scb->io_ctx)*/)
   5560   1.96      fvdl 				continue;
   5561   1.42      fvdl 
   5562   1.96      fvdl 			/*
   5563   1.96      fvdl 			 * We found an scb that needs to be acted on.
   5564   1.96      fvdl 			 */
   5565   1.96      fvdl 			found++;
   5566   1.96      fvdl 			switch (action) {
   5567   1.96      fvdl 			case SEARCH_COMPLETE:
   5568   1.96      fvdl 			{
   5569   1.96      fvdl 				cam_status ostat;
   5570   1.96      fvdl 				cam_status cstat;
   5571    1.6   mycroft 
   5572   1.96      fvdl 				ostat = ahc_get_transaction_status(scb);
   5573   1.96      fvdl 				if (ostat == CAM_REQ_INPROG)
   5574   1.96      fvdl 					ahc_set_transaction_status(scb, status);
   5575   1.96      fvdl 				cstat = ahc_get_transaction_status(scb);
   5576   1.96      fvdl 				if (cstat != CAM_REQ_CMP)
   5577   1.96      fvdl 					ahc_freeze_scb(scb);
   5578   1.96      fvdl 				if ((scb->flags & SCB_ACTIVE) == 0)
   5579   1.96      fvdl 					printf("Inactive SCB in untaggedQ\n");
   5580   1.96      fvdl 				ahc_done(ahc, scb);
   5581   1.96      fvdl 				break;
   5582   1.96      fvdl 			}
   5583   1.96      fvdl 			case SEARCH_REMOVE:
   5584   1.96      fvdl 				scb->flags &= ~SCB_UNTAGGEDQ;
   5585   1.96      fvdl 				TAILQ_REMOVE(untagged_q, scb, links.tqe);
   5586   1.96      fvdl 				break;
   5587   1.96      fvdl 			case SEARCH_COUNT:
   5588   1.96      fvdl 				break;
   5589    1.6   mycroft 			}
   5590   1.42      fvdl 		}
   5591   1.42      fvdl 	}
   5592   1.42      fvdl 
   5593   1.96      fvdl 	if (action == SEARCH_COMPLETE)
   5594   1.96      fvdl 		ahc_release_untagged_queues(ahc);
   5595   1.96      fvdl 	return (found);
   5596   1.96      fvdl }
   5597   1.42      fvdl 
   5598   1.96      fvdl int
   5599   1.96      fvdl ahc_search_disc_list(struct ahc_softc *ahc, int target, char channel,
   5600   1.96      fvdl 		     int lun, u_int tag, int stop_on_first, int remove,
   5601   1.96      fvdl 		     int save_state)
   5602   1.96      fvdl {
   5603   1.96      fvdl 	struct	scb *scbp;
   5604   1.96      fvdl 	u_int	next;
   5605   1.96      fvdl 	u_int	prev;
   5606   1.96      fvdl 	u_int	count;
   5607   1.96      fvdl 	u_int	active_scb;
   5608   1.42      fvdl 
   5609   1.96      fvdl 	count = 0;
   5610   1.96      fvdl 	next = ahc_inb(ahc, DISCONNECTED_SCBH);
   5611   1.96      fvdl 	prev = SCB_LIST_NULL;
   5612   1.59        pk 
   5613   1.96      fvdl 	if (save_state) {
   5614   1.96      fvdl 		/* restore this when we're done */
   5615   1.96      fvdl 		active_scb = ahc_inb(ahc, SCBPTR);
   5616   1.96      fvdl 	} else
   5617   1.96      fvdl 		/* Silence compiler */
   5618   1.96      fvdl 		active_scb = SCB_LIST_NULL;
   5619    1.9  explorer 
   5620   1.96      fvdl 	while (next != SCB_LIST_NULL) {
   5621   1.96      fvdl 		u_int scb_index;
   5622    1.1   mycroft 
   5623   1.96      fvdl 		ahc_outb(ahc, SCBPTR, next);
   5624   1.96      fvdl 		scb_index = ahc_inb(ahc, SCB_TAG);
   5625   1.96      fvdl 		if (scb_index >= ahc->scb_data->numscbs) {
   5626   1.96      fvdl 			printf("Disconnected List inconsistency. "
   5627   1.96      fvdl 			       "SCB index == %d, yet numscbs == %d.",
   5628   1.96      fvdl 			       scb_index, ahc->scb_data->numscbs);
   5629   1.96      fvdl 			ahc_dump_card_state(ahc);
   5630   1.96      fvdl 			panic("for safety");
   5631   1.96      fvdl 		}
   5632    1.1   mycroft 
   5633   1.96      fvdl 		if (next == prev) {
   5634   1.96      fvdl 			panic("Disconnected List Loop. "
   5635   1.96      fvdl 			      "cur SCBPTR == %x, prev SCBPTR == %x.",
   5636   1.96      fvdl 			      next, prev);
   5637   1.96      fvdl 		}
   5638   1.96      fvdl 		scbp = ahc_lookup_scb(ahc, scb_index);
   5639   1.96      fvdl 		if (ahc_match_scb(ahc, scbp, target, channel, lun,
   5640   1.96      fvdl 				  tag, ROLE_INITIATOR)) {
   5641   1.96      fvdl 			count++;
   5642   1.96      fvdl 			if (remove) {
   5643   1.96      fvdl 				next =
   5644   1.96      fvdl 				    ahc_rem_scb_from_disc_list(ahc, prev, next);
   5645   1.96      fvdl 			} else {
   5646   1.96      fvdl 				prev = next;
   5647   1.96      fvdl 				next = ahc_inb(ahc, SCB_NEXT);
   5648   1.96      fvdl 			}
   5649   1.96      fvdl 			if (stop_on_first)
   5650   1.96      fvdl 				break;
   5651   1.96      fvdl 		} else {
   5652   1.96      fvdl 			prev = next;
   5653   1.96      fvdl 			next = ahc_inb(ahc, SCB_NEXT);
   5654   1.96      fvdl 		}
   5655   1.42      fvdl 	}
   5656   1.96      fvdl 	if (save_state)
   5657   1.96      fvdl 		ahc_outb(ahc, SCBPTR, active_scb);
   5658   1.96      fvdl 	return (count);
   5659   1.96      fvdl }
   5660    1.1   mycroft 
   5661   1.96      fvdl /*
   5662   1.96      fvdl  * Remove an SCB from the on chip list of disconnected transactions.
   5663   1.96      fvdl  * This is empty/unused if we are not performing SCB paging.
   5664   1.96      fvdl  */
   5665   1.96      fvdl static u_int
   5666   1.96      fvdl ahc_rem_scb_from_disc_list(struct ahc_softc *ahc, u_int prev, u_int scbptr)
   5667   1.96      fvdl {
   5668   1.96      fvdl 	u_int next;
   5669   1.96      fvdl 
   5670   1.96      fvdl 	ahc_outb(ahc, SCBPTR, scbptr);
   5671   1.96      fvdl 	next = ahc_inb(ahc, SCB_NEXT);
   5672   1.96      fvdl 
   5673   1.96      fvdl 	ahc_outb(ahc, SCB_CONTROL, 0);
   5674    1.6   mycroft 
   5675   1.96      fvdl 	ahc_add_curscb_to_free_list(ahc);
   5676    1.6   mycroft 
   5677   1.96      fvdl 	if (prev != SCB_LIST_NULL) {
   5678   1.96      fvdl 		ahc_outb(ahc, SCBPTR, prev);
   5679   1.96      fvdl 		ahc_outb(ahc, SCB_NEXT, next);
   5680   1.96      fvdl 	} else
   5681   1.96      fvdl 		ahc_outb(ahc, DISCONNECTED_SCBH, next);
   5682    1.6   mycroft 
   5683   1.96      fvdl 	return (next);
   5684   1.96      fvdl }
   5685   1.42      fvdl 
   5686   1.96      fvdl /*
   5687   1.96      fvdl  * Add the SCB as selected by SCBPTR onto the on chip list of
   5688   1.96      fvdl  * free hardware SCBs.  This list is empty/unused if we are not
   5689   1.96      fvdl  * performing SCB paging.
   5690   1.96      fvdl  */
   5691   1.96      fvdl static void
   5692   1.96      fvdl ahc_add_curscb_to_free_list(struct ahc_softc *ahc)
   5693   1.96      fvdl {
   5694   1.42      fvdl 	/*
   5695   1.96      fvdl 	 * Invalidate the tag so that our abort
   5696   1.96      fvdl 	 * routines don't think it's active.
   5697   1.42      fvdl 	 */
   5698   1.96      fvdl 	ahc_outb(ahc, SCB_TAG, SCB_LIST_NULL);
   5699   1.96      fvdl 
   5700   1.96      fvdl 	if ((ahc->flags & AHC_PAGESCBS) != 0) {
   5701   1.96      fvdl 		ahc_outb(ahc, SCB_NEXT, ahc_inb(ahc, FREE_SCBH));
   5702   1.96      fvdl 		ahc_outb(ahc, FREE_SCBH, ahc_inb(ahc, SCBPTR));
   5703   1.96      fvdl 	}
   5704   1.96      fvdl }
   5705   1.96      fvdl 
   5706   1.96      fvdl /*
   5707   1.96      fvdl  * Manipulate the waiting for selection list and return the
   5708   1.96      fvdl  * scb that follows the one that we remove.
   5709   1.96      fvdl  */
   5710   1.96      fvdl static u_int
   5711   1.96      fvdl ahc_rem_wscb(struct ahc_softc *ahc, u_int scbpos, u_int prev)
   5712  1.112     perry {
   5713   1.96      fvdl 	u_int curscb, next;
   5714    1.6   mycroft 
   5715    1.6   mycroft 	/*
   5716   1.96      fvdl 	 * Select the SCB we want to abort and
   5717   1.96      fvdl 	 * pull the next pointer out of it.
   5718   1.96      fvdl 	 */
   5719   1.96      fvdl 	curscb = ahc_inb(ahc, SCBPTR);
   5720   1.96      fvdl 	ahc_outb(ahc, SCBPTR, scbpos);
   5721   1.96      fvdl 	next = ahc_inb(ahc, SCB_NEXT);
   5722    1.6   mycroft 
   5723   1.96      fvdl 	/* Clear the necessary fields */
   5724   1.96      fvdl 	ahc_outb(ahc, SCB_CONTROL, 0);
   5725    1.6   mycroft 
   5726   1.96      fvdl 	ahc_add_curscb_to_free_list(ahc);
   5727    1.1   mycroft 
   5728   1.96      fvdl 	/* update the waiting list */
   5729   1.96      fvdl 	if (prev == SCB_LIST_NULL) {
   5730   1.96      fvdl 		/* First in the list */
   5731  1.112     perry 		ahc_outb(ahc, WAITING_SCBH, next);
   5732   1.52      fvdl 
   5733   1.96      fvdl 		/*
   5734   1.96      fvdl 		 * Ensure we aren't attempting to perform
   5735   1.96      fvdl 		 * selection for this entry.
   5736   1.96      fvdl 		 */
   5737   1.96      fvdl 		ahc_outb(ahc, SCSISEQ, (ahc_inb(ahc, SCSISEQ) & ~ENSELO));
   5738   1.96      fvdl 	} else {
   5739   1.96      fvdl 		/*
   5740  1.112     perry 		 * Select the scb that pointed to us
   5741   1.96      fvdl 		 * and update its next pointer.
   5742   1.96      fvdl 		 */
   5743   1.96      fvdl 		ahc_outb(ahc, SCBPTR, prev);
   5744   1.96      fvdl 		ahc_outb(ahc, SCB_NEXT, next);
   5745   1.52      fvdl 	}
   5746   1.52      fvdl 
   5747   1.96      fvdl 	/*
   5748   1.96      fvdl 	 * Point us back at the original scb position.
   5749   1.96      fvdl 	 */
   5750   1.96      fvdl 	ahc_outb(ahc, SCBPTR, curscb);
   5751   1.96      fvdl 	return next;
   5752   1.52      fvdl }
   5753   1.52      fvdl 
   5754   1.96      fvdl /******************************** Error Handling ******************************/
   5755    1.1   mycroft /*
   5756   1.96      fvdl  * Abort all SCBs that match the given description (target/channel/lun/tag),
   5757   1.96      fvdl  * setting their status to the passed in status if the status has not already
   5758   1.96      fvdl  * been modified from CAM_REQ_INPROG.  This routine assumes that the sequencer
   5759   1.96      fvdl  * is paused before it is called.
   5760    1.1   mycroft  */
   5761   1.96      fvdl int
   5762   1.96      fvdl ahc_abort_scbs(struct ahc_softc *ahc, int target, char channel,
   5763   1.96      fvdl 	       int lun, u_int tag, role_t role, uint32_t status)
   5764    1.1   mycroft {
   5765   1.96      fvdl 	struct	scb *scbp;
   5766   1.96      fvdl 	struct	scb *scbp_next;
   5767   1.96      fvdl 	u_int	active_scb;
   5768   1.96      fvdl 	int	i, j;
   5769   1.96      fvdl 	int	maxtarget;
   5770   1.96      fvdl 	int	minlun;
   5771   1.96      fvdl 	int	maxlun;
   5772   1.42      fvdl 
   5773   1.96      fvdl 	int	found;
   5774   1.18   thorpej 
   5775   1.96      fvdl 	/*
   5776   1.96      fvdl 	 * Don't attempt to run any queued untagged transactions
   5777   1.96      fvdl 	 * until we are done with the abort process.
   5778   1.96      fvdl 	 */
   5779   1.96      fvdl 	ahc_freeze_untagged_queues(ahc);
   5780   1.18   thorpej 
   5781   1.96      fvdl 	/* restore this when we're done */
   5782   1.96      fvdl 	active_scb = ahc_inb(ahc, SCBPTR);
   5783   1.18   thorpej 
   5784   1.96      fvdl 	found = ahc_search_qinfifo(ahc, target, channel, lun, SCB_LIST_NULL,
   5785   1.96      fvdl 				   role, CAM_REQUEUE_REQ, SEARCH_COMPLETE);
   5786   1.42      fvdl 
   5787   1.96      fvdl 	/*
   5788   1.96      fvdl 	 * Clean out the busy target table for any untagged commands.
   5789   1.96      fvdl 	 */
   5790   1.96      fvdl 	i = 0;
   5791   1.96      fvdl 	maxtarget = 16;
   5792   1.96      fvdl 	if (target != CAM_TARGET_WILDCARD) {
   5793   1.96      fvdl 		i = target;
   5794   1.96      fvdl 		if (channel == 'B')
   5795   1.96      fvdl 			i += 8;
   5796   1.96      fvdl 		maxtarget = i + 1;
   5797   1.96      fvdl 	}
   5798   1.96      fvdl 
   5799   1.96      fvdl 	if (lun == CAM_LUN_WILDCARD) {
   5800   1.96      fvdl 
   5801   1.96      fvdl 		/*
   5802   1.96      fvdl 		 * Unless we are using an SCB based
   5803   1.96      fvdl 		 * busy targets table, there is only
   5804   1.96      fvdl 		 * one table entry for all luns of
   5805   1.96      fvdl 		 * a target.
   5806   1.96      fvdl 		 */
   5807   1.96      fvdl 		minlun = 0;
   5808   1.96      fvdl 		maxlun = 1;
   5809   1.96      fvdl 		if ((ahc->flags & AHC_SCB_BTT) != 0)
   5810   1.96      fvdl 			maxlun = AHC_NUM_LUNS;
   5811   1.96      fvdl 	} else {
   5812   1.96      fvdl 		minlun = lun;
   5813   1.96      fvdl 		maxlun = lun + 1;
   5814   1.96      fvdl 	}
   5815   1.42      fvdl 
   5816   1.96      fvdl 	if (role != ROLE_TARGET) {
   5817   1.96      fvdl 		for (;i < maxtarget; i++) {
   5818   1.96      fvdl 			for (j = minlun;j < maxlun; j++) {
   5819   1.96      fvdl 				u_int scbid;
   5820   1.96      fvdl 				u_int tcl;
   5821   1.96      fvdl 
   5822   1.96      fvdl 				tcl = BUILD_TCL(i << 4, j);
   5823   1.96      fvdl 				scbid = ahc_index_busy_tcl(ahc, tcl);
   5824   1.96      fvdl 				scbp = ahc_lookup_scb(ahc, scbid);
   5825   1.96      fvdl 				if (scbp == NULL
   5826   1.96      fvdl 				 || ahc_match_scb(ahc, scbp, target, channel,
   5827   1.96      fvdl 						  lun, tag, role) == 0)
   5828   1.96      fvdl 					continue;
   5829   1.96      fvdl 				ahc_unbusy_tcl(ahc, BUILD_TCL(i << 4, j));
   5830   1.70    bouyer 			}
   5831   1.18   thorpej 		}
   5832   1.18   thorpej 
   5833   1.18   thorpej 		/*
   5834   1.96      fvdl 		 * Go through the disconnected list and remove any entries we
   5835   1.96      fvdl 		 * have queued for completion, 0'ing their control byte too.
   5836   1.96      fvdl 		 * We save the active SCB and restore it ourselves, so there
   5837   1.96      fvdl 		 * is no reason for this search to restore it too.
   5838   1.96      fvdl 		 */
   5839   1.96      fvdl 		ahc_search_disc_list(ahc, target, channel, lun, tag,
   5840   1.96      fvdl 				     /*stop_on_first*/FALSE, /*remove*/TRUE,
   5841   1.96      fvdl 				     /*save_state*/FALSE);
   5842   1.96      fvdl 	}
   5843   1.42      fvdl 
   5844   1.96      fvdl 	/*
   5845   1.96      fvdl 	 * Go through the hardware SCB array looking for commands that
   5846   1.96      fvdl 	 * were active but not on any list.  In some cases, these remnants
   5847   1.96      fvdl 	 * might not still have mappings in the scbindex array (e.g. unexpected
   5848   1.96      fvdl 	 * bus free with the same scb queued for an abort).  Don't hold this
   5849   1.96      fvdl 	 * against them.
   5850   1.96      fvdl 	 */
   5851   1.96      fvdl 	for (i = 0; i < ahc->scb_data->maxhscbs; i++) {
   5852   1.96      fvdl 		u_int scbid;
   5853   1.42      fvdl 
   5854   1.96      fvdl 		ahc_outb(ahc, SCBPTR, i);
   5855   1.96      fvdl 		scbid = ahc_inb(ahc, SCB_TAG);
   5856   1.96      fvdl 		scbp = ahc_lookup_scb(ahc, scbid);
   5857   1.96      fvdl 		if ((scbp == NULL && scbid != SCB_LIST_NULL)
   5858   1.96      fvdl 		 || (scbp != NULL
   5859   1.96      fvdl 		  && ahc_match_scb(ahc, scbp, target, channel, lun, tag, role)))
   5860   1.96      fvdl 			ahc_add_curscb_to_free_list(ahc);
   5861   1.96      fvdl 	}
   5862   1.42      fvdl 
   5863   1.96      fvdl 	/*
   5864   1.96      fvdl 	 * Go through the pending CCB list and look for
   5865   1.96      fvdl 	 * commands for this target that are still active.
   5866   1.96      fvdl 	 * These are other tagged commands that were
   5867   1.96      fvdl 	 * disconnected when the reset occurred.
   5868   1.96      fvdl 	 */
   5869   1.96      fvdl 	scbp_next = LIST_FIRST(&ahc->pending_scbs);
   5870   1.96      fvdl 	while (scbp_next != NULL) {
   5871   1.96      fvdl 		scbp = scbp_next;
   5872   1.96      fvdl 		scbp_next = LIST_NEXT(scbp, pending_links);
   5873   1.96      fvdl 		if (ahc_match_scb(ahc, scbp, target, channel, lun, tag, role)) {
   5874   1.96      fvdl 			cam_status ostat;
   5875   1.96      fvdl 
   5876   1.96      fvdl 			ostat = ahc_get_transaction_status(scbp);
   5877   1.96      fvdl 			if (ostat == CAM_REQ_INPROG)
   5878   1.96      fvdl 				ahc_set_transaction_status(scbp, status);
   5879   1.96      fvdl 			if (ahc_get_transaction_status(scbp) != CAM_REQ_CMP)
   5880   1.96      fvdl 				ahc_freeze_scb(scbp);
   5881   1.96      fvdl 			if ((scbp->flags & SCB_ACTIVE) == 0)
   5882   1.96      fvdl 				printf("Inactive SCB on pending list\n");
   5883   1.96      fvdl 			ahc_done(ahc, scbp);
   5884   1.96      fvdl 			found++;
   5885   1.70    bouyer 		}
   5886   1.42      fvdl 	}
   5887   1.96      fvdl 	ahc_outb(ahc, SCBPTR, active_scb);
   5888   1.96      fvdl 	ahc_platform_abort_scbs(ahc, target, channel, lun, tag, role, status);
   5889   1.96      fvdl 	ahc_release_untagged_queues(ahc);
   5890   1.96      fvdl 	return found;
   5891   1.42      fvdl }
   5892   1.42      fvdl 
   5893   1.70    bouyer static void
   5894   1.96      fvdl ahc_reset_current_bus(struct ahc_softc *ahc)
   5895   1.42      fvdl {
   5896   1.96      fvdl 	uint8_t scsiseq;
   5897   1.96      fvdl 
   5898   1.96      fvdl 	ahc_outb(ahc, SIMODE1, ahc_inb(ahc, SIMODE1) & ~ENSCSIRST);
   5899   1.96      fvdl 	scsiseq = ahc_inb(ahc, SCSISEQ);
   5900   1.96      fvdl 	ahc_outb(ahc, SCSISEQ, scsiseq | SCSIRSTO);
   5901   1.96      fvdl 	ahc_flush_device_writes(ahc);
   5902   1.96      fvdl 	ahc_delay(AHC_BUSRESET_DELAY);
   5903   1.96      fvdl 	/* Turn off the bus reset */
   5904   1.96      fvdl 	ahc_outb(ahc, SCSISEQ, scsiseq & ~SCSIRSTO);
   5905   1.42      fvdl 
   5906   1.96      fvdl 	ahc_clear_intstat(ahc);
   5907   1.42      fvdl 
   5908   1.96      fvdl 	/* Re-enable reset interrupts */
   5909   1.96      fvdl 	ahc_outb(ahc, SIMODE1, ahc_inb(ahc, SIMODE1) | ENSCSIRST);
   5910   1.96      fvdl }
   5911   1.42      fvdl 
   5912   1.96      fvdl int
   5913   1.96      fvdl ahc_reset_channel(struct ahc_softc *ahc, char channel, int initiate_reset)
   5914   1.96      fvdl {
   5915  1.114  christos 	struct	ahc_devinfo dinfo;
   5916   1.96      fvdl 	u_int	initiator, target, max_scsiid;
   5917   1.96      fvdl 	u_int	sblkctl;
   5918   1.96      fvdl 	u_int	scsiseq;
   5919   1.96      fvdl 	u_int	simode1;
   5920   1.96      fvdl 	int	found;
   5921   1.96      fvdl 	int	restart_needed;
   5922   1.96      fvdl 	char	cur_channel;
   5923   1.18   thorpej 
   5924   1.96      fvdl 	ahc->pending_device = NULL;
   5925   1.59        pk 
   5926  1.114  christos 	ahc_compile_devinfo(&dinfo,
   5927   1.96      fvdl 			    CAM_TARGET_WILDCARD,
   5928   1.96      fvdl 			    CAM_TARGET_WILDCARD,
   5929   1.96      fvdl 			    CAM_LUN_WILDCARD,
   5930   1.96      fvdl 			    channel, ROLE_UNKNOWN);
   5931   1.96      fvdl 	ahc_pause(ahc);
   5932   1.18   thorpej 
   5933   1.96      fvdl 	/* Make sure the sequencer is in a safe location. */
   5934   1.96      fvdl 	ahc_clear_critical_section(ahc);
   5935   1.18   thorpej 
   5936    1.9  explorer 	/*
   5937   1.96      fvdl 	 * Run our command complete fifos to ensure that we perform
   5938   1.96      fvdl 	 * completion processing on any commands that 'completed'
   5939   1.96      fvdl 	 * before the reset occurred.
   5940   1.96      fvdl 	 */
   5941   1.96      fvdl 	ahc_run_qoutfifo(ahc);
   5942   1.96      fvdl #if AHC_TARGET_MODE
   5943   1.96      fvdl 	/*
   5944   1.96      fvdl 	 * XXX - In Twin mode, the tqinfifo may have commands
   5945   1.96      fvdl 	 *	 for an unaffected channel in it.  However, if
   5946   1.96      fvdl 	 *	 we have run out of ATIO resources to drain that
   5947   1.96      fvdl 	 *	 queue, we may not get them all out here.  Further,
   5948   1.96      fvdl 	 *	 the blocked transactions for the reset channel
   5949   1.96      fvdl 	 *	 should just be killed off, irrespecitve of whether
   5950   1.96      fvdl 	 *	 we are blocked on ATIO resources.  Write a routine
   5951   1.96      fvdl 	 *	 to compact the tqinfifo appropriately.
   5952    1.9  explorer 	 */
   5953   1.96      fvdl 	if ((ahc->flags & AHC_TARGETROLE) != 0) {
   5954   1.96      fvdl 		ahc_run_tqinfifo(ahc, /*paused*/TRUE);
   5955   1.42      fvdl 	}
   5956   1.96      fvdl #endif
   5957    1.6   mycroft 
   5958   1.96      fvdl 	/*
   5959   1.96      fvdl 	 * Reset the bus if we are initiating this reset
   5960   1.96      fvdl 	 */
   5961   1.96      fvdl 	sblkctl = ahc_inb(ahc, SBLKCTL);
   5962   1.96      fvdl 	cur_channel = 'A';
   5963   1.96      fvdl 	if ((ahc->features & AHC_TWIN) != 0
   5964   1.96      fvdl 	 && ((sblkctl & SELBUSB) != 0))
   5965   1.96      fvdl 	    cur_channel = 'B';
   5966   1.96      fvdl 	scsiseq = ahc_inb(ahc, SCSISEQ_TEMPLATE);
   5967   1.96      fvdl 	if (cur_channel != channel) {
   5968   1.96      fvdl 		/* Case 1: Command for another bus is active
   5969   1.96      fvdl 		 * Stealthily reset the other bus without
   5970   1.96      fvdl 		 * upsetting the current bus.
   5971   1.96      fvdl 		 */
   5972   1.96      fvdl 		ahc_outb(ahc, SBLKCTL, sblkctl ^ SELBUSB);
   5973   1.96      fvdl 		simode1 = ahc_inb(ahc, SIMODE1) & ~(ENBUSFREE|ENSCSIRST);
   5974   1.96      fvdl #if AHC_TARGET_MODE
   5975   1.96      fvdl 		/*
   5976   1.96      fvdl 		 * Bus resets clear ENSELI, so we cannot
   5977   1.96      fvdl 		 * defer re-enabling bus reset interrupts
   5978   1.96      fvdl 		 * if we are in target mode.
   5979   1.96      fvdl 		 */
   5980   1.96      fvdl 		if ((ahc->flags & AHC_TARGETROLE) != 0)
   5981   1.96      fvdl 			simode1 |= ENSCSIRST;
   5982   1.96      fvdl #endif
   5983   1.96      fvdl 		ahc_outb(ahc, SIMODE1, simode1);
   5984   1.96      fvdl 		if (initiate_reset)
   5985   1.96      fvdl 			ahc_reset_current_bus(ahc);
   5986   1.96      fvdl 		ahc_clear_intstat(ahc);
   5987   1.96      fvdl 		ahc_outb(ahc, SCSISEQ, scsiseq & (ENSELI|ENRSELI|ENAUTOATNP));
   5988   1.96      fvdl 		ahc_outb(ahc, SBLKCTL, sblkctl);
   5989   1.96      fvdl 		restart_needed = FALSE;
   5990   1.96      fvdl 	} else {
   5991   1.96      fvdl 		/* Case 2: A command from this bus is active or we're idle */
   5992   1.96      fvdl 		simode1 = ahc_inb(ahc, SIMODE1) & ~(ENBUSFREE|ENSCSIRST);
   5993   1.96      fvdl #if AHC_TARGET_MODE
   5994   1.96      fvdl 		/*
   5995   1.96      fvdl 		 * Bus resets clear ENSELI, so we cannot
   5996   1.96      fvdl 		 * defer re-enabling bus reset interrupts
   5997   1.96      fvdl 		 * if we are in target mode.
   5998   1.96      fvdl 		 */
   5999   1.96      fvdl 		if ((ahc->flags & AHC_TARGETROLE) != 0)
   6000   1.96      fvdl 			simode1 |= ENSCSIRST;
   6001   1.29       leo #endif
   6002   1.96      fvdl 		ahc_outb(ahc, SIMODE1, simode1);
   6003   1.96      fvdl 		if (initiate_reset)
   6004   1.96      fvdl 			ahc_reset_current_bus(ahc);
   6005   1.96      fvdl 		ahc_clear_intstat(ahc);
   6006   1.96      fvdl 		ahc_outb(ahc, SCSISEQ, scsiseq & (ENSELI|ENRSELI|ENAUTOATNP));
   6007   1.96      fvdl 		restart_needed = TRUE;
   6008   1.96      fvdl 	}
   6009    1.6   mycroft 
   6010   1.96      fvdl 	/*
   6011   1.96      fvdl 	 * Clean up all the state information for the
   6012   1.96      fvdl 	 * pending transactions on this bus.
   6013   1.96      fvdl 	 */
   6014   1.96      fvdl 	found = ahc_abort_scbs(ahc, CAM_TARGET_WILDCARD, channel,
   6015   1.96      fvdl 			       CAM_LUN_WILDCARD, SCB_LIST_NULL,
   6016   1.96      fvdl 			       ROLE_UNKNOWN, CAM_SCSI_BUS_RESET);
   6017   1.59        pk 
   6018   1.96      fvdl 	max_scsiid = (ahc->features & AHC_WIDE) ? 15 : 7;
   6019    1.6   mycroft 
   6020   1.96      fvdl #ifdef AHC_TARGET_MODE
   6021   1.96      fvdl 	/*
   6022   1.96      fvdl 	 * Send an immediate notify ccb to all target more peripheral
   6023   1.96      fvdl 	 * drivers affected by this action.
   6024   1.96      fvdl 	 */
   6025   1.96      fvdl 	for (target = 0; target <= max_scsiid; target++) {
   6026   1.96      fvdl 		struct ahc_tmode_tstate* tstate;
   6027   1.96      fvdl 		u_int lun;
   6028    1.6   mycroft 
   6029   1.96      fvdl 		tstate = ahc->enabled_targets[target];
   6030   1.96      fvdl 		if (tstate == NULL)
   6031   1.96      fvdl 			continue;
   6032   1.96      fvdl 		for (lun = 0; lun < AHC_NUM_LUNS; lun++) {
   6033   1.96      fvdl 			struct ahc_tmode_lstate* lstate;
   6034   1.42      fvdl 
   6035   1.96      fvdl 			lstate = tstate->enabled_luns[lun];
   6036   1.96      fvdl 			if (lstate == NULL)
   6037   1.96      fvdl 				continue;
   6038    1.6   mycroft 
   6039   1.96      fvdl 			ahc_queue_lstate_event(ahc, lstate, CAM_TARGET_WILDCARD,
   6040   1.96      fvdl 					       EVENT_TYPE_BUS_RESET, /*arg*/0);
   6041   1.96      fvdl 			ahc_send_lstate_events(ahc, lstate);
   6042   1.42      fvdl 		}
   6043   1.42      fvdl 	}
   6044    1.1   mycroft #endif
   6045    1.1   mycroft 	/*
   6046   1.96      fvdl 	 * Revert to async/narrow transfers until we renegotiate.
   6047    1.1   mycroft 	 */
   6048   1.96      fvdl 	for (target = 0; target <= max_scsiid; target++) {
   6049    1.1   mycroft 
   6050   1.96      fvdl 		if (ahc->enabled_targets[target] == NULL)
   6051   1.96      fvdl 			continue;
   6052   1.96      fvdl 		for (initiator = 0; initiator <= max_scsiid; initiator++) {
   6053   1.96      fvdl 			struct ahc_devinfo devinfo;
   6054   1.42      fvdl 
   6055   1.96      fvdl 			ahc_compile_devinfo(&devinfo, target, initiator,
   6056   1.96      fvdl 					    CAM_LUN_WILDCARD,
   6057   1.96      fvdl 					    channel, ROLE_UNKNOWN);
   6058   1.96      fvdl 			ahc_set_width(ahc, &devinfo, MSG_EXT_WDTR_BUS_8_BIT,
   6059   1.96      fvdl 				      AHC_TRANS_CUR, /*paused*/TRUE);
   6060   1.96      fvdl 			ahc_set_syncrate(ahc, &devinfo, /*syncrate*/NULL,
   6061   1.96      fvdl 					 /*period*/0, /*offset*/0,
   6062   1.96      fvdl 					 /*ppr_options*/0, AHC_TRANS_CUR,
   6063   1.96      fvdl 					 /*paused*/TRUE);
   6064   1.96      fvdl 		}
   6065   1.42      fvdl 	}
   6066   1.59        pk 
   6067   1.96      fvdl 	if (restart_needed)
   6068   1.96      fvdl 		ahc_restart(ahc);
   6069   1.96      fvdl 	else
   6070   1.96      fvdl 		ahc_unpause(ahc);
   6071   1.96      fvdl 	return found;
   6072   1.42      fvdl }
   6073   1.42      fvdl 
   6074   1.96      fvdl 
   6075   1.96      fvdl /***************************** Residual Processing ****************************/
   6076   1.96      fvdl /*
   6077   1.96      fvdl  * Calculate the residual for a just completed SCB.
   6078   1.96      fvdl  */
   6079   1.96      fvdl void
   6080  1.123  christos ahc_calc_residual(struct ahc_softc *ahc, struct scb *scb)
   6081   1.42      fvdl {
   6082   1.42      fvdl 	struct hardware_scb *hscb;
   6083   1.96      fvdl 	struct status_pkt *spkt;
   6084   1.96      fvdl 	uint32_t sgptr;
   6085   1.96      fvdl 	uint32_t resid_sgptr;
   6086   1.96      fvdl 	uint32_t resid;
   6087   1.96      fvdl 
   6088   1.96      fvdl 	/*
   6089   1.96      fvdl 	 * 5 cases.
   6090   1.96      fvdl 	 * 1) No residual.
   6091   1.96      fvdl 	 *    SG_RESID_VALID clear in sgptr.
   6092   1.96      fvdl 	 * 2) Transferless command
   6093   1.96      fvdl 	 * 3) Never performed any transfers.
   6094   1.96      fvdl 	 *    sgptr has SG_FULL_RESID set.
   6095   1.96      fvdl 	 * 4) No residual but target did not
   6096   1.96      fvdl 	 *    save data pointers after the
   6097   1.96      fvdl 	 *    last transfer, so sgptr was
   6098   1.96      fvdl 	 *    never updated.
   6099   1.96      fvdl 	 * 5) We have a partial residual.
   6100   1.96      fvdl 	 *    Use residual_sgptr to determine
   6101   1.96      fvdl 	 *    where we are.
   6102   1.96      fvdl 	 */
   6103   1.59        pk 
   6104   1.42      fvdl 	hscb = scb->hscb;
   6105   1.96      fvdl 	sgptr = ahc_le32toh(hscb->sgptr);
   6106   1.96      fvdl 	if ((sgptr & SG_RESID_VALID) == 0)
   6107   1.96      fvdl 		/* Case 1 */
   6108   1.96      fvdl 		return;
   6109   1.96      fvdl 	sgptr &= ~SG_RESID_VALID;
   6110   1.59        pk 
   6111   1.96      fvdl 	if ((sgptr & SG_LIST_NULL) != 0)
   6112   1.96      fvdl 		/* Case 2 */
   6113   1.96      fvdl 		return;
   6114   1.42      fvdl 
   6115   1.96      fvdl 	spkt = &hscb->shared_data.status;
   6116   1.96      fvdl 	resid_sgptr = ahc_le32toh(spkt->residual_sg_ptr);
   6117   1.96      fvdl 	if ((sgptr & SG_FULL_RESID) != 0) {
   6118   1.96      fvdl 		/* Case 3 */
   6119   1.96      fvdl 		resid = ahc_get_transfer_length(scb);
   6120   1.96      fvdl 	} else if ((resid_sgptr & SG_LIST_NULL) != 0) {
   6121   1.96      fvdl 		/* Case 4 */
   6122   1.96      fvdl 		return;
   6123   1.96      fvdl 	} else if ((resid_sgptr & ~SG_PTR_MASK) != 0) {
   6124   1.96      fvdl 		panic("Bogus resid sgptr value 0x%x\n", resid_sgptr);
   6125   1.42      fvdl 	} else {
   6126   1.96      fvdl 		struct ahc_dma_seg *sg;
   6127   1.42      fvdl 
   6128   1.96      fvdl 		/*
   6129   1.96      fvdl 		 * Remainder of the SG where the transfer
   6130  1.112     perry 		 * stopped.
   6131   1.96      fvdl 		 */
   6132   1.96      fvdl 		resid = ahc_le32toh(spkt->residual_datacnt) & AHC_SG_LEN_MASK;
   6133   1.96      fvdl 		sg = ahc_sg_bus_to_virt(scb, resid_sgptr & SG_PTR_MASK);
   6134   1.42      fvdl 
   6135   1.96      fvdl 		/* The residual sg_ptr always points to the next sg */
   6136   1.96      fvdl 		sg--;
   6137   1.42      fvdl 
   6138   1.96      fvdl 		/*
   6139   1.96      fvdl 		 * Add up the contents of all residual
   6140   1.96      fvdl 		 * SG segments that are after the SG where
   6141   1.96      fvdl 		 * the transfer stopped.
   6142   1.96      fvdl 		 */
   6143   1.96      fvdl 		while ((ahc_le32toh(sg->len) & AHC_DMA_LAST_SEG) == 0) {
   6144   1.96      fvdl 			sg++;
   6145   1.96      fvdl 			resid += ahc_le32toh(sg->len) & AHC_SG_LEN_MASK;
   6146   1.96      fvdl 		}
   6147   1.96      fvdl 	}
   6148   1.96      fvdl 	if ((scb->flags & SCB_SENSE) == 0)
   6149   1.96      fvdl 		ahc_set_residual(scb, resid);
   6150   1.96      fvdl 	else
   6151   1.96      fvdl 		ahc_set_sense_residual(scb, resid);
   6152   1.42      fvdl 
   6153   1.96      fvdl #ifdef AHC_DEBUG
   6154   1.96      fvdl 	if ((ahc_debug & AHC_SHOW_MISC) != 0) {
   6155   1.96      fvdl 		ahc_print_path(ahc, scb);
   6156   1.96      fvdl 		printf("Handled %sResidual of %d bytes\n",
   6157   1.96      fvdl 		       (scb->flags & SCB_SENSE) ? "Sense " : "", resid);
   6158   1.42      fvdl 	}
   6159   1.96      fvdl #endif
   6160   1.96      fvdl }
   6161   1.96      fvdl 
   6162   1.96      fvdl /******************************* Target Mode **********************************/
   6163   1.96      fvdl #ifdef AHC_TARGET_MODE
   6164   1.96      fvdl /*
   6165   1.96      fvdl  * Add a target mode event to this lun's queue
   6166   1.96      fvdl  */
   6167   1.96      fvdl static void
   6168   1.96      fvdl ahc_queue_lstate_event(struct ahc_softc *ahc, struct ahc_tmode_lstate *lstate,
   6169   1.96      fvdl 		       u_int initiator_id, u_int event_type, u_int event_arg)
   6170   1.96      fvdl {
   6171   1.96      fvdl 	struct ahc_tmode_event *event;
   6172   1.96      fvdl 	int pending;
   6173    1.1   mycroft 
   6174   1.96      fvdl 	xpt_freeze_devq(lstate->path, /*count*/1);
   6175   1.96      fvdl 	if (lstate->event_w_idx >= lstate->event_r_idx)
   6176   1.96      fvdl 		pending = lstate->event_w_idx - lstate->event_r_idx;
   6177   1.96      fvdl 	else
   6178   1.96      fvdl 		pending = AHC_TMODE_EVENT_BUFFER_SIZE + 1
   6179   1.96      fvdl 			- (lstate->event_r_idx - lstate->event_w_idx);
   6180   1.42      fvdl 
   6181   1.96      fvdl 	if (event_type == EVENT_TYPE_BUS_RESET
   6182   1.96      fvdl 	 || event_type == MSG_BUS_DEV_RESET) {
   6183   1.96      fvdl 		/*
   6184   1.96      fvdl 		 * Any earlier events are irrelevant, so reset our buffer.
   6185   1.96      fvdl 		 * This has the effect of allowing us to deal with reset
   6186   1.96      fvdl 		 * floods (an external device holding down the reset line)
   6187   1.96      fvdl 		 * without losing the event that is really interesting.
   6188   1.96      fvdl 		 */
   6189   1.96      fvdl 		lstate->event_r_idx = 0;
   6190   1.96      fvdl 		lstate->event_w_idx = 0;
   6191   1.96      fvdl 		xpt_release_devq(lstate->path, pending, /*runqueue*/FALSE);
   6192   1.96      fvdl 	}
   6193   1.96      fvdl 
   6194   1.96      fvdl 	if (pending == AHC_TMODE_EVENT_BUFFER_SIZE) {
   6195   1.96      fvdl 		xpt_print_path(lstate->path);
   6196   1.96      fvdl 		printf("immediate event %x:%x lost\n",
   6197   1.96      fvdl 		       lstate->event_buffer[lstate->event_r_idx].event_type,
   6198   1.96      fvdl 		       lstate->event_buffer[lstate->event_r_idx].event_arg);
   6199   1.96      fvdl 		lstate->event_r_idx++;
   6200   1.96      fvdl 		if (lstate->event_r_idx == AHC_TMODE_EVENT_BUFFER_SIZE)
   6201   1.96      fvdl 			lstate->event_r_idx = 0;
   6202   1.96      fvdl 		xpt_release_devq(lstate->path, /*count*/1, /*runqueue*/FALSE);
   6203   1.96      fvdl 	}
   6204   1.96      fvdl 
   6205   1.96      fvdl 	event = &lstate->event_buffer[lstate->event_w_idx];
   6206   1.96      fvdl 	event->initiator_id = initiator_id;
   6207   1.96      fvdl 	event->event_type = event_type;
   6208   1.96      fvdl 	event->event_arg = event_arg;
   6209   1.96      fvdl 	lstate->event_w_idx++;
   6210   1.96      fvdl 	if (lstate->event_w_idx == AHC_TMODE_EVENT_BUFFER_SIZE)
   6211   1.96      fvdl 		lstate->event_w_idx = 0;
   6212   1.96      fvdl }
   6213    1.1   mycroft 
   6214   1.96      fvdl /*
   6215   1.96      fvdl  * Send any target mode events queued up waiting
   6216   1.96      fvdl  * for immediate notify resources.
   6217   1.96      fvdl  */
   6218   1.96      fvdl void
   6219   1.96      fvdl ahc_send_lstate_events(struct ahc_softc *ahc, struct ahc_tmode_lstate *lstate)
   6220   1.96      fvdl {
   6221   1.96      fvdl 	struct ccb_hdr *ccbh;
   6222   1.96      fvdl 	struct ccb_immed_notify *inot;
   6223    1.9  explorer 
   6224   1.96      fvdl 	while (lstate->event_r_idx != lstate->event_w_idx
   6225   1.96      fvdl 	    && (ccbh = SLIST_FIRST(&lstate->immed_notifies)) != NULL) {
   6226   1.96      fvdl 		struct ahc_tmode_event *event;
   6227   1.96      fvdl 
   6228   1.96      fvdl 		event = &lstate->event_buffer[lstate->event_r_idx];
   6229   1.96      fvdl 		SLIST_REMOVE_HEAD(&lstate->immed_notifies, sim_links.sle);
   6230   1.96      fvdl 		inot = (struct ccb_immed_notify *)ccbh;
   6231   1.96      fvdl 		switch (event->event_type) {
   6232   1.96      fvdl 		case EVENT_TYPE_BUS_RESET:
   6233   1.96      fvdl 			ccbh->status = CAM_SCSI_BUS_RESET|CAM_DEV_QFRZN;
   6234   1.96      fvdl 			break;
   6235   1.96      fvdl 		default:
   6236   1.96      fvdl 			ccbh->status = CAM_MESSAGE_RECV|CAM_DEV_QFRZN;
   6237   1.96      fvdl 			inot->message_args[0] = event->event_type;
   6238   1.96      fvdl 			inot->message_args[1] = event->event_arg;
   6239   1.42      fvdl 			break;
   6240   1.96      fvdl 		}
   6241   1.96      fvdl 		inot->initiator_id = event->initiator_id;
   6242   1.96      fvdl 		inot->sense_len = 0;
   6243   1.96      fvdl 		xpt_done((union ccb *)inot);
   6244   1.96      fvdl 		lstate->event_r_idx++;
   6245   1.96      fvdl 		if (lstate->event_r_idx == AHC_TMODE_EVENT_BUFFER_SIZE)
   6246   1.96      fvdl 			lstate->event_r_idx = 0;
   6247    1.6   mycroft 	}
   6248   1.96      fvdl }
   6249   1.42      fvdl #endif
   6250   1.96      fvdl 
   6251   1.96      fvdl /******************** Sequencer Program Patching/Download *********************/
   6252   1.42      fvdl 
   6253   1.42      fvdl #ifdef AHC_DUMP_SEQ
   6254   1.96      fvdl void
   6255   1.42      fvdl ahc_dumpseq(struct ahc_softc* ahc)
   6256   1.42      fvdl {
   6257   1.42      fvdl 	int i;
   6258   1.42      fvdl 	int max_prog;
   6259   1.42      fvdl 
   6260   1.42      fvdl 	if ((ahc->chip & AHC_BUS_MASK) < AHC_PCI)
   6261   1.42      fvdl 		max_prog = 448;
   6262   1.42      fvdl 	else if ((ahc->features & AHC_ULTRA2) != 0)
   6263   1.42      fvdl 		max_prog = 768;
   6264   1.42      fvdl 	else
   6265   1.42      fvdl 		max_prog = 512;
   6266   1.42      fvdl 
   6267   1.42      fvdl 	ahc_outb(ahc, SEQCTL, PERRORDIS|FAILDIS|FASTMODE|LOADRAM);
   6268   1.42      fvdl 	ahc_outb(ahc, SEQADDR0, 0);
   6269   1.42      fvdl 	ahc_outb(ahc, SEQADDR1, 0);
   6270   1.42      fvdl 	for (i = 0; i < max_prog; i++) {
   6271   1.96      fvdl 		uint8_t ins_bytes[4];
   6272   1.42      fvdl 
   6273   1.42      fvdl 		ahc_insb(ahc, SEQRAM, ins_bytes, 4);
   6274   1.42      fvdl 		printf("0x%08x\n", ins_bytes[0] << 24
   6275   1.42      fvdl 				 | ins_bytes[1] << 16
   6276   1.42      fvdl 				 | ins_bytes[2] << 8
   6277   1.42      fvdl 				 | ins_bytes[3]);
   6278    1.6   mycroft 	}
   6279   1.42      fvdl }
   6280   1.42      fvdl #endif
   6281   1.42      fvdl 
   6282   1.42      fvdl static void
   6283   1.42      fvdl ahc_loadseq(struct ahc_softc *ahc)
   6284   1.42      fvdl {
   6285   1.96      fvdl 	struct	cs cs_table[num_critical_sections];
   6286   1.96      fvdl 	u_int	begin_set[num_critical_sections];
   6287   1.96      fvdl 	u_int	end_set[num_critical_sections];
   6288   1.96      fvdl 	struct	patch *cur_patch;
   6289   1.96      fvdl 	u_int	cs_count;
   6290   1.96      fvdl 	u_int	cur_cs;
   6291   1.96      fvdl 	u_int	i;
   6292   1.96      fvdl 	int	downloaded;
   6293   1.96      fvdl 	u_int	skip_addr;
   6294   1.96      fvdl 	u_int	sg_prefetch_cnt;
   6295   1.96      fvdl 	uint8_t	download_consts[7];
   6296   1.96      fvdl 
   6297   1.96      fvdl 	/*
   6298   1.96      fvdl 	 * Start out with 0 critical sections
   6299   1.96      fvdl 	 * that apply to this firmware load.
   6300   1.96      fvdl 	 */
   6301   1.96      fvdl 	cs_count = 0;
   6302   1.96      fvdl 	cur_cs = 0;
   6303   1.96      fvdl 	memset(begin_set, 0, sizeof(begin_set));
   6304   1.96      fvdl 	memset(end_set, 0, sizeof(end_set));
   6305   1.42      fvdl 
   6306   1.42      fvdl 	/* Setup downloadable constant table */
   6307   1.96      fvdl 	download_consts[QOUTFIFO_OFFSET] = 0;
   6308   1.96      fvdl 	if (ahc->targetcmds != NULL)
   6309   1.96      fvdl 		download_consts[QOUTFIFO_OFFSET] += 32;
   6310   1.96      fvdl 	download_consts[QINFIFO_OFFSET] = download_consts[QOUTFIFO_OFFSET] + 1;
   6311   1.96      fvdl 	download_consts[CACHESIZE_MASK] = ahc->pci_cachesize - 1;
   6312   1.96      fvdl 	download_consts[INVERTED_CACHESIZE_MASK] = ~(ahc->pci_cachesize - 1);
   6313   1.96      fvdl 	sg_prefetch_cnt = ahc->pci_cachesize;
   6314   1.96      fvdl 	if (sg_prefetch_cnt < (2 * sizeof(struct ahc_dma_seg)))
   6315   1.96      fvdl 		sg_prefetch_cnt = 2 * sizeof(struct ahc_dma_seg);
   6316   1.96      fvdl 	download_consts[SG_PREFETCH_CNT] = sg_prefetch_cnt;
   6317   1.96      fvdl 	download_consts[SG_PREFETCH_ALIGN_MASK] = ~(sg_prefetch_cnt - 1);
   6318   1.96      fvdl 	download_consts[SG_PREFETCH_ADDR_MASK] = (sg_prefetch_cnt - 1);
   6319   1.42      fvdl 
   6320   1.42      fvdl 	cur_patch = patches;
   6321   1.42      fvdl 	downloaded = 0;
   6322   1.42      fvdl 	skip_addr = 0;
   6323   1.42      fvdl 	ahc_outb(ahc, SEQCTL, PERRORDIS|FAILDIS|FASTMODE|LOADRAM);
   6324   1.42      fvdl 	ahc_outb(ahc, SEQADDR0, 0);
   6325   1.42      fvdl 	ahc_outb(ahc, SEQADDR1, 0);
   6326   1.42      fvdl 
   6327   1.42      fvdl 	for (i = 0; i < sizeof(seqprog)/4; i++) {
   6328   1.42      fvdl 		if (ahc_check_patch(ahc, &cur_patch, i, &skip_addr) == 0) {
   6329    1.6   mycroft 			/*
   6330   1.42      fvdl 			 * Don't download this instruction as it
   6331   1.42      fvdl 			 * is in a patch that was removed.
   6332    1.6   mycroft 			 */
   6333   1.96      fvdl 			continue;
   6334   1.96      fvdl 		}
   6335   1.96      fvdl 		/*
   6336   1.96      fvdl 		 * Move through the CS table until we find a CS
   6337   1.96      fvdl 		 * that might apply to this instruction.
   6338   1.96      fvdl 		 */
   6339   1.96      fvdl 		for (; cur_cs < num_critical_sections; cur_cs++) {
   6340   1.96      fvdl 			if (critical_sections[cur_cs].end <= i) {
   6341   1.96      fvdl 				if (begin_set[cs_count] == TRUE
   6342   1.96      fvdl 				 && end_set[cs_count] == FALSE) {
   6343   1.96      fvdl 					cs_table[cs_count].end = downloaded;
   6344   1.96      fvdl 				 	end_set[cs_count] = TRUE;
   6345   1.96      fvdl 					cs_count++;
   6346   1.96      fvdl 				}
   6347   1.96      fvdl 				continue;
   6348   1.96      fvdl 			}
   6349   1.96      fvdl 			if (critical_sections[cur_cs].begin <= i
   6350   1.96      fvdl 			 && begin_set[cs_count] == FALSE) {
   6351   1.96      fvdl 				cs_table[cs_count].begin = downloaded;
   6352   1.96      fvdl 				begin_set[cs_count] = TRUE;
   6353   1.96      fvdl 			}
   6354   1.96      fvdl 			break;
   6355   1.42      fvdl 		}
   6356   1.42      fvdl 		ahc_download_instr(ahc, i, download_consts);
   6357   1.42      fvdl 		downloaded++;
   6358    1.6   mycroft 	}
   6359   1.96      fvdl 
   6360   1.96      fvdl 	ahc->num_critical_sections = cs_count;
   6361   1.96      fvdl 	if (cs_count != 0) {
   6362   1.96      fvdl 
   6363   1.96      fvdl 		cs_count *= sizeof(struct cs);
   6364   1.96      fvdl 		ahc->critical_sections = malloc(cs_count, M_DEVBUF, M_NOWAIT);
   6365   1.96      fvdl 		if (ahc->critical_sections == NULL)
   6366   1.96      fvdl 			panic("ahc_loadseq: Could not malloc");
   6367   1.96      fvdl 		memcpy(ahc->critical_sections, cs_table, cs_count);
   6368   1.96      fvdl 	}
   6369   1.42      fvdl 	ahc_outb(ahc, SEQCTL, PERRORDIS|FAILDIS|FASTMODE);
   6370   1.96      fvdl 	ahc_restart(ahc);
   6371   1.42      fvdl 
   6372   1.96      fvdl 	if (bootverbose) {
   6373   1.96      fvdl 		printf(" %d instructions downloaded\n", downloaded);
   6374   1.96      fvdl 		printf("%s: Features 0x%x, Bugs 0x%x, Flags 0x%x\n",
   6375   1.96      fvdl 		       ahc_name(ahc), ahc->features, ahc->bugs, ahc->flags);
   6376   1.96      fvdl 	}
   6377    1.1   mycroft }
   6378    1.1   mycroft 
   6379   1.42      fvdl static int
   6380   1.96      fvdl ahc_check_patch(struct ahc_softc *ahc, struct patch **start_patch,
   6381   1.96      fvdl 		u_int start_instr, u_int *skip_addr)
   6382   1.42      fvdl {
   6383   1.96      fvdl 	struct	patch *cur_patch;
   6384   1.96      fvdl 	struct	patch *last_patch;
   6385   1.96      fvdl 	u_int	num_patches;
   6386   1.42      fvdl 
   6387   1.42      fvdl 	num_patches = sizeof(patches)/sizeof(struct patch);
   6388   1.42      fvdl 	last_patch = &patches[num_patches];
   6389   1.42      fvdl 	cur_patch = *start_patch;
   6390   1.42      fvdl 
   6391   1.42      fvdl 	while (cur_patch < last_patch && start_instr == cur_patch->begin) {
   6392   1.42      fvdl 
   6393   1.42      fvdl 		if (cur_patch->patch_func(ahc) == 0) {
   6394   1.42      fvdl 
   6395   1.42      fvdl 			/* Start rejecting code */
   6396   1.42      fvdl 			*skip_addr = start_instr + cur_patch->skip_instr;
   6397   1.42      fvdl 			cur_patch += cur_patch->skip_patch;
   6398   1.42      fvdl 		} else {
   6399   1.42      fvdl 			/* Accepted this patch.  Advance to the next
   6400   1.42      fvdl 			 * one and wait for our intruction pointer to
   6401   1.42      fvdl 			 * hit this point.
   6402   1.42      fvdl 			 */
   6403   1.42      fvdl 			cur_patch++;
   6404   1.28       leo 		}
   6405   1.28       leo 	}
   6406   1.42      fvdl 
   6407   1.42      fvdl 	*start_patch = cur_patch;
   6408   1.42      fvdl 	if (start_instr < *skip_addr)
   6409   1.42      fvdl 		/* Still skipping */
   6410   1.42      fvdl 		return (0);
   6411   1.42      fvdl 
   6412   1.42      fvdl 	return (1);
   6413   1.28       leo }
   6414   1.28       leo 
   6415   1.42      fvdl static void
   6416   1.96      fvdl ahc_download_instr(struct ahc_softc *ahc, u_int instrptr, uint8_t *dconsts)
   6417    1.1   mycroft {
   6418   1.42      fvdl 	union	ins_formats instr;
   6419   1.42      fvdl 	struct	ins_format1 *fmt1_ins;
   6420   1.42      fvdl 	struct	ins_format3 *fmt3_ins;
   6421   1.42      fvdl 	u_int	opcode;
   6422   1.42      fvdl 
   6423   1.96      fvdl 	/*
   6424   1.96      fvdl 	 * The firmware is always compiled into a little endian format.
   6425   1.96      fvdl 	 */
   6426   1.96      fvdl 	instr.integer = ahc_le32toh(*(uint32_t*)&seqprog[instrptr * 4]);
   6427   1.42      fvdl 
   6428   1.42      fvdl 	fmt1_ins = &instr.format1;
   6429   1.42      fvdl 	fmt3_ins = NULL;
   6430   1.42      fvdl 
   6431   1.42      fvdl 	/* Pull the opcode */
   6432   1.42      fvdl 	opcode = instr.format1.opcode;
   6433   1.42      fvdl 	switch (opcode) {
   6434   1.42      fvdl 	case AIC_OP_JMP:
   6435   1.42      fvdl 	case AIC_OP_JC:
   6436   1.42      fvdl 	case AIC_OP_JNC:
   6437   1.42      fvdl 	case AIC_OP_CALL:
   6438   1.42      fvdl 	case AIC_OP_JNE:
   6439   1.42      fvdl 	case AIC_OP_JNZ:
   6440   1.42      fvdl 	case AIC_OP_JE:
   6441   1.42      fvdl 	case AIC_OP_JZ:
   6442   1.42      fvdl 	{
   6443   1.96      fvdl 		struct patch *cur_patch;
   6444   1.42      fvdl 		int address_offset;
   6445   1.42      fvdl 		u_int address;
   6446   1.96      fvdl 		u_int skip_addr;
   6447   1.96      fvdl 		u_int i;
   6448   1.42      fvdl 
   6449   1.42      fvdl 		fmt3_ins = &instr.format3;
   6450   1.42      fvdl 		address_offset = 0;
   6451   1.42      fvdl 		address = fmt3_ins->address;
   6452   1.42      fvdl 		cur_patch = patches;
   6453   1.42      fvdl 		skip_addr = 0;
   6454   1.42      fvdl 		for (i = 0; i < address;) {
   6455   1.42      fvdl 			ahc_check_patch(ahc, &cur_patch, i, &skip_addr);
   6456   1.42      fvdl 
   6457   1.42      fvdl 			if (skip_addr > i) {
   6458   1.42      fvdl 				int end_addr;
   6459   1.42      fvdl 
   6460   1.42      fvdl 				end_addr = MIN(address, skip_addr);
   6461   1.42      fvdl 				address_offset += end_addr - i;
   6462   1.42      fvdl 				i = skip_addr;
   6463   1.42      fvdl 			} else {
   6464   1.42      fvdl 				i++;
   6465   1.42      fvdl 			}
   6466    1.1   mycroft 		}
   6467   1.42      fvdl 		address -= address_offset;
   6468   1.42      fvdl 		fmt3_ins->address = address;
   6469   1.42      fvdl 		/* FALLTHROUGH */
   6470   1.42      fvdl 	}
   6471   1.42      fvdl 	case AIC_OP_OR:
   6472   1.42      fvdl 	case AIC_OP_AND:
   6473   1.42      fvdl 	case AIC_OP_XOR:
   6474   1.42      fvdl 	case AIC_OP_ADD:
   6475   1.42      fvdl 	case AIC_OP_ADC:
   6476   1.42      fvdl 	case AIC_OP_BMOV:
   6477   1.42      fvdl 		if (fmt1_ins->parity != 0) {
   6478   1.42      fvdl 			fmt1_ins->immediate = dconsts[fmt1_ins->immediate];
   6479   1.42      fvdl 		}
   6480   1.42      fvdl 		fmt1_ins->parity = 0;
   6481   1.96      fvdl 		if ((ahc->features & AHC_CMD_CHAN) == 0
   6482   1.96      fvdl 		 && opcode == AIC_OP_BMOV) {
   6483   1.96      fvdl 			/*
   6484   1.96      fvdl 			 * Block move was added at the same time
   6485   1.96      fvdl 			 * as the command channel.  Verify that
   6486   1.96      fvdl 			 * this is only a move of a single element
   6487   1.96      fvdl 			 * and convert the BMOV to a MOV
   6488   1.96      fvdl 			 * (AND with an immediate of FF).
   6489   1.96      fvdl 			 */
   6490   1.96      fvdl 			if (fmt1_ins->immediate != 1)
   6491   1.96      fvdl 				panic("%s: BMOV not supported\n",
   6492   1.96      fvdl 				      ahc_name(ahc));
   6493   1.96      fvdl 			fmt1_ins->opcode = AIC_OP_AND;
   6494   1.96      fvdl 			fmt1_ins->immediate = 0xff;
   6495   1.96      fvdl 		}
   6496   1.42      fvdl 		/* FALLTHROUGH */
   6497   1.42      fvdl 	case AIC_OP_ROL:
   6498   1.42      fvdl 		if ((ahc->features & AHC_ULTRA2) != 0) {
   6499   1.42      fvdl 			int i, count;
   6500   1.42      fvdl 
   6501   1.42      fvdl 			/* Calculate odd parity for the instruction */
   6502   1.42      fvdl 			for (i = 0, count = 0; i < 31; i++) {
   6503   1.96      fvdl 				uint32_t mask;
   6504   1.42      fvdl 
   6505   1.42      fvdl 				mask = 0x01 << i;
   6506   1.42      fvdl 				if ((instr.integer & mask) != 0)
   6507   1.42      fvdl 					count++;
   6508   1.42      fvdl 			}
   6509   1.42      fvdl 			if ((count & 0x01) == 0)
   6510   1.42      fvdl 				instr.format1.parity = 1;
   6511   1.42      fvdl 		} else {
   6512   1.42      fvdl 			/* Compress the instruction for older sequencers */
   6513   1.42      fvdl 			if (fmt3_ins != NULL) {
   6514   1.42      fvdl 				instr.integer =
   6515   1.42      fvdl 					fmt3_ins->immediate
   6516   1.42      fvdl 				      | (fmt3_ins->source << 8)
   6517   1.42      fvdl 				      | (fmt3_ins->address << 16)
   6518   1.42      fvdl 				      |	(fmt3_ins->opcode << 25);
   6519   1.42      fvdl 			} else {
   6520   1.42      fvdl 				instr.integer =
   6521   1.42      fvdl 					fmt1_ins->immediate
   6522   1.42      fvdl 				      | (fmt1_ins->source << 8)
   6523   1.42      fvdl 				      | (fmt1_ins->destination << 16)
   6524   1.42      fvdl 				      |	(fmt1_ins->ret << 24)
   6525   1.42      fvdl 				      |	(fmt1_ins->opcode << 25);
   6526    1.1   mycroft 			}
   6527    1.1   mycroft 		}
   6528  1.109       wiz 		/* The sequencer is a little endian CPU */
   6529   1.96      fvdl 		instr.integer = ahc_htole32(instr.integer);
   6530   1.42      fvdl 		ahc_outsb(ahc, SEQRAM, instr.bytes, 4);
   6531   1.42      fvdl 		break;
   6532   1.42      fvdl 	default:
   6533   1.42      fvdl 		panic("Unknown opcode encountered in seq program");
   6534    1.6   mycroft 		break;
   6535    1.1   mycroft 	}
   6536    1.1   mycroft }
   6537    1.1   mycroft 
   6538   1.96      fvdl int
   6539   1.96      fvdl ahc_print_register(ahc_reg_parse_entry_t *table, u_int num_entries,
   6540  1.123  christos     const char *name, u_int address, u_int value,
   6541  1.122  christos     u_int *cur_column, u_int wrap_point)
   6542   1.96      fvdl {
   6543   1.96      fvdl 	int	printed;
   6544   1.96      fvdl 	u_int	printed_mask;
   6545   1.98      fvdl 	char    line[1024];
   6546   1.96      fvdl 
   6547   1.99      fvdl 	line[0] = 0;
   6548   1.96      fvdl 
   6549   1.96      fvdl 	if (cur_column != NULL && *cur_column >= wrap_point) {
   6550   1.96      fvdl 		printf("\n");
   6551   1.96      fvdl 		*cur_column = 0;
   6552   1.96      fvdl 	}
   6553   1.99      fvdl 	printed = snprintf(line, sizeof(line), "%s[0x%x]", name, value);
   6554   1.96      fvdl 	if (table == NULL) {
   6555   1.99      fvdl 		printed += snprintf(&line[printed], (sizeof line) - printed,
   6556   1.99      fvdl 		    " ");
   6557   1.98      fvdl 		printf("%s", line);
   6558   1.98      fvdl 		if (cur_column != NULL)
   6559   1.98      fvdl 			*cur_column += printed;
   6560   1.96      fvdl 		return (printed);
   6561   1.96      fvdl 	}
   6562   1.96      fvdl 	printed_mask = 0;
   6563   1.96      fvdl 	while (printed_mask != 0xFF) {
   6564   1.96      fvdl 		int entry;
   6565   1.96      fvdl 
   6566   1.96      fvdl 		for (entry = 0; entry < num_entries; entry++) {
   6567   1.96      fvdl 			if (((value & table[entry].mask)
   6568   1.96      fvdl 			  != table[entry].value)
   6569   1.96      fvdl 			 || ((printed_mask & table[entry].mask)
   6570   1.96      fvdl 			  == table[entry].mask))
   6571   1.96      fvdl 				continue;
   6572   1.98      fvdl 			printed += snprintf(&line[printed],
   6573  1.112     perry 			    (sizeof line) - printed, "%s%s",
   6574   1.96      fvdl 				printed_mask == 0 ? ":(" : "|",
   6575   1.96      fvdl 				table[entry].name);
   6576   1.96      fvdl 			printed_mask |= table[entry].mask;
   6577  1.112     perry 
   6578   1.96      fvdl 			break;
   6579   1.42      fvdl 		}
   6580   1.96      fvdl 		if (entry >= num_entries)
   6581   1.96      fvdl 			break;
   6582    1.6   mycroft 	}
   6583   1.96      fvdl 	if (printed_mask != 0)
   6584   1.98      fvdl 		printed += snprintf(&line[printed],
   6585   1.98      fvdl 		    (sizeof line) - printed, ") ");
   6586   1.96      fvdl 	else
   6587   1.98      fvdl 		printed += snprintf(&line[printed],
   6588   1.98      fvdl 		    (sizeof line) - printed, " ");
   6589   1.96      fvdl 	if (cur_column != NULL)
   6590   1.96      fvdl 		*cur_column += printed;
   6591   1.98      fvdl 	printf("%s", line);
   6592   1.96      fvdl 
   6593   1.96      fvdl 	return (printed);
   6594    1.6   mycroft }
   6595    1.6   mycroft 
   6596   1.96      fvdl void
   6597   1.96      fvdl ahc_dump_card_state(struct ahc_softc *ahc)
   6598    1.6   mycroft {
   6599   1.42      fvdl 	struct	scb *scb;
   6600   1.96      fvdl 	struct	scb_tailq *untagged_q;
   6601   1.96      fvdl 	u_int	cur_col;
   6602   1.96      fvdl 	int	paused;
   6603   1.42      fvdl 	int	target;
   6604   1.96      fvdl 	int	maxtarget;
   6605   1.42      fvdl 	int	i;
   6606   1.96      fvdl 	uint8_t last_phase;
   6607   1.96      fvdl 	uint8_t qinpos;
   6608   1.96      fvdl 	uint8_t qintail;
   6609   1.96      fvdl 	uint8_t qoutpos;
   6610   1.96      fvdl 	uint8_t scb_index;
   6611   1.96      fvdl 	uint8_t saved_scbptr;
   6612    1.6   mycroft 
   6613   1.96      fvdl 	if (ahc_is_paused(ahc)) {
   6614   1.96      fvdl 		paused = 1;
   6615   1.96      fvdl 	} else {
   6616   1.96      fvdl 		paused = 0;
   6617   1.96      fvdl 		ahc_pause(ahc);
   6618    1.6   mycroft 	}
   6619    1.6   mycroft 
   6620   1.96      fvdl 	saved_scbptr = ahc_inb(ahc, SCBPTR);
   6621   1.42      fvdl 	last_phase = ahc_inb(ahc, LASTPHASE);
   6622   1.96      fvdl 	printf(">>>>>>>>>>>>>>>>>> Dump Card State Begins <<<<<<<<<<<<<<<<<\n"
   6623   1.96      fvdl 	       "%s: Dumping Card State %s, at SEQADDR 0x%x\n",
   6624   1.96      fvdl 	       ahc_name(ahc), ahc_lookup_phase_entry(last_phase)->phasemsg,
   6625   1.42      fvdl 	       ahc_inb(ahc, SEQADDR0) | (ahc_inb(ahc, SEQADDR1) << 8));
   6626   1.96      fvdl 	if (paused)
   6627   1.96      fvdl 		printf("Card was paused\n");
   6628   1.96      fvdl 	printf("ACCUM = 0x%x, SINDEX = 0x%x, DINDEX = 0x%x, ARG_2 = 0x%x\n",
   6629   1.96      fvdl 	       ahc_inb(ahc, ACCUM), ahc_inb(ahc, SINDEX), ahc_inb(ahc, DINDEX),
   6630   1.96      fvdl 	       ahc_inb(ahc, ARG_2));
   6631   1.96      fvdl 	printf("HCNT = 0x%x SCBPTR = 0x%x\n", ahc_inb(ahc, HCNT),
   6632   1.96      fvdl 	       ahc_inb(ahc, SCBPTR));
   6633   1.96      fvdl 	cur_col = 0;
   6634   1.96      fvdl 	if ((ahc->features & AHC_DT) != 0)
   6635   1.96      fvdl 		ahc_scsiphase_print(ahc_inb(ahc, SCSIPHASE), &cur_col, 50);
   6636   1.96      fvdl 	ahc_scsisigi_print(ahc_inb(ahc, SCSISIGI), &cur_col, 50);
   6637   1.96      fvdl 	ahc_error_print(ahc_inb(ahc, ERROR), &cur_col, 50);
   6638   1.96      fvdl 	ahc_scsibusl_print(ahc_inb(ahc, SCSIBUSL), &cur_col, 50);
   6639   1.96      fvdl 	ahc_lastphase_print(ahc_inb(ahc, LASTPHASE), &cur_col, 50);
   6640   1.96      fvdl 	ahc_scsiseq_print(ahc_inb(ahc, SCSISEQ), &cur_col, 50);
   6641   1.96      fvdl 	ahc_sblkctl_print(ahc_inb(ahc, SBLKCTL), &cur_col, 50);
   6642   1.96      fvdl 	ahc_scsirate_print(ahc_inb(ahc, SCSIRATE), &cur_col, 50);
   6643   1.96      fvdl 	ahc_seqctl_print(ahc_inb(ahc, SEQCTL), &cur_col, 50);
   6644   1.96      fvdl 	ahc_seq_flags_print(ahc_inb(ahc, SEQ_FLAGS), &cur_col, 50);
   6645   1.96      fvdl 	ahc_sstat0_print(ahc_inb(ahc, SSTAT0), &cur_col, 50);
   6646   1.96      fvdl 	ahc_sstat1_print(ahc_inb(ahc, SSTAT1), &cur_col, 50);
   6647   1.96      fvdl 	ahc_sstat2_print(ahc_inb(ahc, SSTAT2), &cur_col, 50);
   6648   1.96      fvdl 	ahc_sstat3_print(ahc_inb(ahc, SSTAT3), &cur_col, 50);
   6649   1.96      fvdl 	ahc_simode0_print(ahc_inb(ahc, SIMODE0), &cur_col, 50);
   6650   1.96      fvdl 	ahc_simode1_print(ahc_inb(ahc, SIMODE1), &cur_col, 50);
   6651   1.96      fvdl 	ahc_sxfrctl0_print(ahc_inb(ahc, SXFRCTL0), &cur_col, 50);
   6652   1.96      fvdl 	ahc_dfcntrl_print(ahc_inb(ahc, DFCNTRL), &cur_col, 50);
   6653   1.96      fvdl 	ahc_dfstatus_print(ahc_inb(ahc, DFSTATUS), &cur_col, 50);
   6654   1.96      fvdl 	if (cur_col != 0)
   6655   1.96      fvdl 		printf("\n");
   6656   1.96      fvdl 	printf("STACK:");
   6657   1.96      fvdl 	for (i = 0; i < STACK_SIZE; i++)
   6658   1.96      fvdl 	       printf(" 0x%x", ahc_inb(ahc, STACK)|(ahc_inb(ahc, STACK) << 8));
   6659   1.96      fvdl 	printf("\nSCB count = %d\n", ahc->scb_data->numscbs);
   6660   1.96      fvdl 	printf("Kernel NEXTQSCB = %d\n", ahc->next_queued_scb->hscb->tag);
   6661   1.96      fvdl 	printf("Card NEXTQSCB = %d\n", ahc_inb(ahc, NEXT_QUEUED_SCB));
   6662   1.96      fvdl 	/* QINFIFO */
   6663   1.96      fvdl 	printf("QINFIFO entries: ");
   6664   1.96      fvdl 	if ((ahc->features & AHC_QUEUE_REGS) != 0) {
   6665   1.96      fvdl 		qinpos = ahc_inb(ahc, SNSCB_QOFF);
   6666   1.96      fvdl 		ahc_outb(ahc, SNSCB_QOFF, qinpos);
   6667   1.96      fvdl 	} else
   6668   1.96      fvdl 		qinpos = ahc_inb(ahc, QINPOS);
   6669   1.42      fvdl 	qintail = ahc->qinfifonext;
   6670   1.42      fvdl 	while (qinpos != qintail) {
   6671   1.96      fvdl 		printf("%d ", ahc->qinfifo[qinpos]);
   6672   1.42      fvdl 		qinpos++;
   6673   1.42      fvdl 	}
   6674   1.96      fvdl 	printf("\n");
   6675   1.42      fvdl 
   6676   1.96      fvdl 	printf("Waiting Queue entries: ");
   6677   1.96      fvdl 	scb_index = ahc_inb(ahc, WAITING_SCBH);
   6678   1.96      fvdl 	i = 0;
   6679   1.96      fvdl 	while (scb_index != SCB_LIST_NULL && i++ < 256) {
   6680   1.96      fvdl 		ahc_outb(ahc, SCBPTR, scb_index);
   6681   1.96      fvdl 		printf("%d:%d ", scb_index, ahc_inb(ahc, SCB_TAG));
   6682   1.96      fvdl 		scb_index = ahc_inb(ahc, SCB_NEXT);
   6683    1.6   mycroft 	}
   6684   1.96      fvdl 	printf("\n");
   6685    1.1   mycroft 
   6686   1.96      fvdl 	printf("Disconnected Queue entries: ");
   6687   1.96      fvdl 	scb_index = ahc_inb(ahc, DISCONNECTED_SCBH);
   6688   1.96      fvdl 	i = 0;
   6689   1.96      fvdl 	while (scb_index != SCB_LIST_NULL && i++ < 256) {
   6690   1.96      fvdl 		ahc_outb(ahc, SCBPTR, scb_index);
   6691   1.96      fvdl 		printf("%d:%d ", scb_index, ahc_inb(ahc, SCB_TAG));
   6692   1.96      fvdl 		scb_index = ahc_inb(ahc, SCB_NEXT);
   6693   1.96      fvdl 	}
   6694   1.96      fvdl 	printf("\n");
   6695  1.112     perry 
   6696   1.96      fvdl 	ahc_sync_qoutfifo(ahc, BUS_DMASYNC_POSTREAD);
   6697   1.96      fvdl 	printf("QOUTFIFO entries: ");
   6698   1.96      fvdl 	qoutpos = ahc->qoutfifonext;
   6699   1.96      fvdl 	i = 0;
   6700   1.96      fvdl 	while (ahc->qoutfifo[qoutpos] != SCB_LIST_NULL && i++ < 256) {
   6701   1.96      fvdl 		printf("%d ", ahc->qoutfifo[qoutpos]);
   6702   1.96      fvdl 		qoutpos++;
   6703    1.1   mycroft 	}
   6704   1.96      fvdl 	printf("\n");
   6705   1.42      fvdl 
   6706   1.96      fvdl 	printf("Sequencer Free SCB List: ");
   6707   1.96      fvdl 	scb_index = ahc_inb(ahc, FREE_SCBH);
   6708   1.96      fvdl 	i = 0;
   6709   1.96      fvdl 	while (scb_index != SCB_LIST_NULL && i++ < 256) {
   6710   1.96      fvdl 		ahc_outb(ahc, SCBPTR, scb_index);
   6711   1.96      fvdl 		printf("%d ", scb_index);
   6712   1.96      fvdl 		scb_index = ahc_inb(ahc, SCB_NEXT);
   6713   1.96      fvdl 	}
   6714   1.96      fvdl 	printf("\n");
   6715   1.42      fvdl 
   6716   1.96      fvdl 	printf("Sequencer SCB Info: ");
   6717   1.96      fvdl 	for (i = 0; i < ahc->scb_data->maxhscbs; i++) {
   6718   1.42      fvdl 		ahc_outb(ahc, SCBPTR, i);
   6719   1.96      fvdl 		/*cur_col =*/ printf("\n%3d ", i);
   6720   1.96      fvdl 
   6721   1.96      fvdl 		ahc_scb_control_print(ahc_inb(ahc, SCB_CONTROL), &cur_col, 60);
   6722   1.96      fvdl 		ahc_scb_scsiid_print(ahc_inb(ahc, SCB_SCSIID), &cur_col, 60);
   6723   1.96      fvdl 		ahc_scb_lun_print(ahc_inb(ahc, SCB_LUN), &cur_col, 60);
   6724   1.96      fvdl 		ahc_scb_tag_print(ahc_inb(ahc, SCB_TAG), &cur_col, 60);
   6725   1.42      fvdl 	}
   6726   1.96      fvdl 	printf("\n");
   6727   1.42      fvdl 
   6728   1.96      fvdl 	printf("Pending list: ");
   6729   1.96      fvdl 	i = 0;
   6730   1.96      fvdl 	LIST_FOREACH(scb, &ahc->pending_scbs, pending_links) {
   6731   1.96      fvdl 		if (i++ > 256)
   6732   1.96      fvdl 			break;
   6733   1.96      fvdl 		/*cur_col =*/ printf("\n%3d ", scb->hscb->tag);
   6734   1.96      fvdl 		ahc_scb_control_print(scb->hscb->control, &cur_col, 60);
   6735   1.96      fvdl 		ahc_scb_scsiid_print(scb->hscb->scsiid, &cur_col, 60);
   6736   1.96      fvdl 		ahc_scb_lun_print(scb->hscb->lun, &cur_col, 60);
   6737   1.96      fvdl 		if ((ahc->flags & AHC_PAGESCBS) == 0) {
   6738   1.96      fvdl 			ahc_outb(ahc, SCBPTR, scb->hscb->tag);
   6739   1.96      fvdl 			printf("(");
   6740   1.96      fvdl 			ahc_scb_control_print(ahc_inb(ahc, SCB_CONTROL),
   6741   1.96      fvdl 					      &cur_col, 60);
   6742   1.96      fvdl 			ahc_scb_tag_print(ahc_inb(ahc, SCB_TAG), &cur_col, 60);
   6743   1.96      fvdl 			printf(")");
   6744    1.6   mycroft 		}
   6745   1.42      fvdl 	}
   6746   1.96      fvdl 	printf("\n");
   6747    1.6   mycroft 
   6748   1.96      fvdl 	printf("Kernel Free SCB list: ");
   6749   1.96      fvdl 	i = 0;
   6750   1.96      fvdl 	SLIST_FOREACH(scb, &ahc->scb_data->free_scbs, links.sle) {
   6751   1.96      fvdl 		if (i++ > 256)
   6752   1.96      fvdl 			break;
   6753   1.96      fvdl 		printf("%d ", scb->hscb->tag);
   6754   1.96      fvdl 	}
   6755   1.96      fvdl 	printf("\n");
   6756   1.42      fvdl 
   6757   1.96      fvdl 	maxtarget = (ahc->features & (AHC_WIDE|AHC_TWIN)) ? 15 : 7;
   6758   1.96      fvdl 	for (target = 0; target <= maxtarget; target++) {
   6759   1.96      fvdl 		untagged_q = &ahc->untagged_queues[target];
   6760   1.96      fvdl 		if (TAILQ_FIRST(untagged_q) == NULL)
   6761   1.96      fvdl 			continue;
   6762   1.96      fvdl 		printf("Untagged Q(%d): ", target);
   6763   1.96      fvdl 		i = 0;
   6764   1.96      fvdl 		TAILQ_FOREACH(scb, untagged_q, links.tqe) {
   6765   1.96      fvdl 			if (i++ > 256)
   6766   1.42      fvdl 				break;
   6767   1.96      fvdl 			printf("%d ", scb->hscb->tag);
   6768   1.42      fvdl 		}
   6769   1.96      fvdl 		printf("\n");
   6770   1.42      fvdl 	}
   6771   1.96      fvdl 
   6772   1.96      fvdl 	ahc_platform_dump_card_state(ahc);
   6773   1.96      fvdl 	printf("\n<<<<<<<<<<<<<<<<< Dump Card State Ends >>>>>>>>>>>>>>>>>>\n");
   6774   1.96      fvdl 	ahc_outb(ahc, SCBPTR, saved_scbptr);
   6775   1.96      fvdl 	if (paused == 0)
   6776   1.96      fvdl 		ahc_unpause(ahc);
   6777   1.42      fvdl }
   6778   1.42      fvdl 
   6779   1.96      fvdl /************************* Target Mode ****************************************/
   6780   1.96      fvdl #ifdef AHC_TARGET_MODE
   6781   1.96      fvdl cam_status
   6782   1.96      fvdl ahc_find_tmode_devs(struct ahc_softc *ahc, struct cam_sim *sim, union ccb *ccb,
   6783   1.96      fvdl 		    struct ahc_tmode_tstate **tstate,
   6784   1.96      fvdl 		    struct ahc_tmode_lstate **lstate,
   6785   1.96      fvdl 		    int notfound_failure)
   6786   1.42      fvdl {
   6787   1.42      fvdl 
   6788   1.96      fvdl 	if ((ahc->features & AHC_TARGETMODE) == 0)
   6789   1.96      fvdl 		return (CAM_REQ_INVALID);
   6790   1.42      fvdl 
   6791   1.96      fvdl 	/*
   6792   1.96      fvdl 	 * Handle the 'black hole' device that sucks up
   6793   1.96      fvdl 	 * requests to unattached luns on enabled targets.
   6794   1.96      fvdl 	 */
   6795   1.96      fvdl 	if (ccb->ccb_h.target_id == CAM_TARGET_WILDCARD
   6796   1.96      fvdl 	 && ccb->ccb_h.target_lun == CAM_LUN_WILDCARD) {
   6797   1.96      fvdl 		*tstate = NULL;
   6798   1.96      fvdl 		*lstate = ahc->black_hole;
   6799   1.96      fvdl 	} else {
   6800   1.96      fvdl 		u_int max_id;
   6801   1.42      fvdl 
   6802   1.96      fvdl 		max_id = (ahc->features & AHC_WIDE) ? 15 : 7;
   6803   1.96      fvdl 		if (ccb->ccb_h.target_id > max_id)
   6804   1.96      fvdl 			return (CAM_TID_INVALID);
   6805   1.42      fvdl 
   6806   1.96      fvdl 		if (ccb->ccb_h.target_lun >= AHC_NUM_LUNS)
   6807   1.96      fvdl 			return (CAM_LUN_INVALID);
   6808   1.42      fvdl 
   6809   1.96      fvdl 		*tstate = ahc->enabled_targets[ccb->ccb_h.target_id];
   6810   1.96      fvdl 		*lstate = NULL;
   6811   1.96      fvdl 		if (*tstate != NULL)
   6812   1.96      fvdl 			*lstate =
   6813   1.96      fvdl 			    (*tstate)->enabled_luns[ccb->ccb_h.target_lun];
   6814   1.96      fvdl 	}
   6815   1.42      fvdl 
   6816   1.96      fvdl 	if (notfound_failure != 0 && *lstate == NULL)
   6817   1.96      fvdl 		return (CAM_PATH_INVALID);
   6818   1.42      fvdl 
   6819   1.96      fvdl 	return (CAM_REQ_CMP);
   6820   1.42      fvdl }
   6821   1.42      fvdl 
   6822   1.96      fvdl void
   6823   1.96      fvdl ahc_handle_en_lun(struct ahc_softc *ahc, struct cam_sim *sim, union ccb *ccb)
   6824   1.59        pk {
   6825   1.96      fvdl 	struct	   ahc_tmode_tstate *tstate;
   6826   1.96      fvdl 	struct	   ahc_tmode_lstate *lstate;
   6827   1.96      fvdl 	struct	   ccb_en_lun *cel;
   6828   1.96      fvdl 	cam_status status;
   6829   1.96      fvdl 	u_int	   target;
   6830   1.96      fvdl 	u_int	   lun;
   6831   1.96      fvdl 	u_int	   target_mask;
   6832   1.96      fvdl 	u_int	   our_id;
   6833   1.96      fvdl 	u_long	   s;
   6834   1.96      fvdl 	char	   channel;
   6835    1.6   mycroft 
   6836   1.96      fvdl 	status = ahc_find_tmode_devs(ahc, sim, ccb, &tstate, &lstate,
   6837   1.96      fvdl 				     /*notfound_failure*/FALSE);
   6838   1.42      fvdl 
   6839   1.96      fvdl 	if (status != CAM_REQ_CMP) {
   6840   1.96      fvdl 		ccb->ccb_h.status = status;
   6841   1.96      fvdl 		return;
   6842   1.96      fvdl 	}
   6843    1.6   mycroft 
   6844   1.96      fvdl 	if (cam_sim_bus(sim) == 0)
   6845   1.96      fvdl 		our_id = ahc->our_id;
   6846   1.96      fvdl 	else
   6847   1.96      fvdl 		our_id = ahc->our_id_b;
   6848   1.42      fvdl 
   6849   1.96      fvdl 	if (ccb->ccb_h.target_id != our_id) {
   6850   1.42      fvdl 		/*
   6851   1.96      fvdl 		 * our_id represents our initiator ID, or
   6852   1.96      fvdl 		 * the ID of the first target to have an
   6853   1.96      fvdl 		 * enabled lun in target mode.  There are
   6854   1.96      fvdl 		 * two cases that may preclude enabling a
   6855   1.96      fvdl 		 * target id other than our_id.
   6856   1.96      fvdl 		 *
   6857   1.96      fvdl 		 *   o our_id is for an active initiator role.
   6858   1.96      fvdl 		 *     Since the hardware does not support
   6859   1.96      fvdl 		 *     reselections to the initiator role at
   6860   1.96      fvdl 		 *     anything other than our_id, and our_id
   6861   1.96      fvdl 		 *     is used by the hardware to indicate the
   6862   1.96      fvdl 		 *     ID to use for both select-out and
   6863   1.96      fvdl 		 *     reselect-out operations, the only target
   6864   1.96      fvdl 		 *     ID we can support in this mode is our_id.
   6865   1.96      fvdl 		 *
   6866   1.96      fvdl 		 *   o The MULTARGID feature is not available and
   6867   1.96      fvdl 		 *     a previous target mode ID has been enabled.
   6868   1.42      fvdl 		 */
   6869   1.96      fvdl 		if ((ahc->features & AHC_MULTIROLE) != 0) {
   6870   1.96      fvdl 
   6871   1.96      fvdl 			if ((ahc->features & AHC_MULTI_TID) != 0
   6872   1.96      fvdl 		   	 && (ahc->flags & AHC_INITIATORROLE) != 0) {
   6873   1.96      fvdl 				/*
   6874   1.96      fvdl 				 * Only allow additional targets if
   6875   1.96      fvdl 				 * the initiator role is disabled.
   6876   1.96      fvdl 				 * The hardware cannot handle a re-select-in
   6877   1.96      fvdl 				 * on the initiator id during a re-select-out
   6878   1.96      fvdl 				 * on a different target id.
   6879   1.96      fvdl 				 */
   6880   1.96      fvdl 				status = CAM_TID_INVALID;
   6881   1.96      fvdl 			} else if ((ahc->flags & AHC_INITIATORROLE) != 0
   6882   1.96      fvdl 				|| ahc->enabled_luns > 0) {
   6883   1.96      fvdl 				/*
   6884   1.96      fvdl 				 * Only allow our target id to change
   6885   1.96      fvdl 				 * if the initiator role is not configured
   6886   1.96      fvdl 				 * and there are no enabled luns which
   6887   1.96      fvdl 				 * are attached to the currently registered
   6888   1.96      fvdl 				 * scsi id.
   6889   1.96      fvdl 				 */
   6890   1.96      fvdl 				status = CAM_TID_INVALID;
   6891   1.96      fvdl 			}
   6892   1.96      fvdl 		} else if ((ahc->features & AHC_MULTI_TID) == 0
   6893   1.96      fvdl 			&& ahc->enabled_luns > 0) {
   6894   1.96      fvdl 
   6895   1.96      fvdl 			status = CAM_TID_INVALID;
   6896   1.96      fvdl 		}
   6897   1.96      fvdl 	}
   6898   1.96      fvdl 
   6899   1.96      fvdl 	if (status != CAM_REQ_CMP) {
   6900   1.96      fvdl 		ccb->ccb_h.status = status;
   6901   1.96      fvdl 		return;
   6902    1.1   mycroft 	}
   6903   1.42      fvdl 
   6904    1.1   mycroft 	/*
   6905   1.96      fvdl 	 * We now have an id that is valid.
   6906   1.96      fvdl 	 * If we aren't in target mode, switch modes.
   6907   1.42      fvdl 	 */
   6908   1.96      fvdl 	if ((ahc->flags & AHC_TARGETROLE) == 0
   6909   1.96      fvdl 	 && ccb->ccb_h.target_id != CAM_TARGET_WILDCARD) {
   6910   1.96      fvdl 		u_long	s;
   6911   1.96      fvdl 
   6912   1.96      fvdl 		printf("Configuring Target Mode\n");
   6913   1.96      fvdl 		ahc_lock(ahc, &s);
   6914   1.96      fvdl 		if (LIST_FIRST(&ahc->pending_scbs) != NULL) {
   6915   1.96      fvdl 			ccb->ccb_h.status = CAM_BUSY;
   6916   1.96      fvdl 			ahc_unlock(ahc, &s);
   6917   1.96      fvdl 			return;
   6918   1.96      fvdl 		}
   6919   1.96      fvdl 		ahc->flags |= AHC_TARGETROLE;
   6920   1.96      fvdl 		if ((ahc->features & AHC_MULTIROLE) == 0)
   6921   1.96      fvdl 			ahc->flags &= ~AHC_INITIATORROLE;
   6922   1.96      fvdl 		ahc_pause(ahc);
   6923   1.96      fvdl 		ahc_loadseq(ahc);
   6924   1.96      fvdl 		ahc_unlock(ahc, &s);
   6925   1.96      fvdl 	}
   6926   1.96      fvdl 	cel = &ccb->cel;
   6927   1.96      fvdl 	target = ccb->ccb_h.target_id;
   6928   1.96      fvdl 	lun = ccb->ccb_h.target_lun;
   6929   1.96      fvdl 	channel = SIM_CHANNEL(ahc, sim);
   6930   1.96      fvdl 	target_mask = 0x01 << target;
   6931   1.96      fvdl 	if (channel == 'B')
   6932   1.96      fvdl 		target_mask <<= 8;
   6933   1.42      fvdl 
   6934   1.96      fvdl 	if (cel->enable != 0) {
   6935   1.96      fvdl 		u_int scsiseq;
   6936   1.42      fvdl 
   6937   1.96      fvdl 		/* Are we already enabled?? */
   6938   1.96      fvdl 		if (lstate != NULL) {
   6939   1.96      fvdl 			xpt_print_path(ccb->ccb_h.path);
   6940   1.96      fvdl 			printf("Lun already enabled\n");
   6941   1.96      fvdl 			ccb->ccb_h.status = CAM_LUN_ALRDY_ENA;
   6942   1.96      fvdl 			return;
   6943   1.96      fvdl 		}
   6944   1.42      fvdl 
   6945   1.96      fvdl 		if (cel->grp6_len != 0
   6946   1.96      fvdl 		 || cel->grp7_len != 0) {
   6947   1.96      fvdl 			/*
   6948   1.96      fvdl 			 * Don't (yet?) support vendor
   6949   1.96      fvdl 			 * specific commands.
   6950   1.96      fvdl 			 */
   6951   1.96      fvdl 			ccb->ccb_h.status = CAM_REQ_INVALID;
   6952   1.96      fvdl 			printf("Non-zero Group Codes\n");
   6953   1.96      fvdl 			return;
   6954   1.96      fvdl 		}
   6955   1.42      fvdl 
   6956   1.96      fvdl 		/*
   6957   1.96      fvdl 		 * Seems to be okay.
   6958   1.96      fvdl 		 * Setup our data structures.
   6959   1.96      fvdl 		 */
   6960   1.96      fvdl 		if (target != CAM_TARGET_WILDCARD && tstate == NULL) {
   6961   1.96      fvdl 			tstate = ahc_alloc_tstate(ahc, target, channel);
   6962   1.96      fvdl 			if (tstate == NULL) {
   6963   1.96      fvdl 				xpt_print_path(ccb->ccb_h.path);
   6964   1.96      fvdl 				printf("Couldn't allocate tstate\n");
   6965   1.96      fvdl 				ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
   6966   1.96      fvdl 				return;
   6967   1.96      fvdl 			}
   6968   1.96      fvdl 		}
   6969   1.96      fvdl 		lstate = malloc(sizeof(*lstate), M_DEVBUF, M_NOWAIT);
   6970   1.96      fvdl 		if (lstate == NULL) {
   6971   1.96      fvdl 			xpt_print_path(ccb->ccb_h.path);
   6972   1.96      fvdl 			printf("Couldn't allocate lstate\n");
   6973   1.96      fvdl 			ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
   6974   1.96      fvdl 			return;
   6975   1.96      fvdl 		}
   6976   1.96      fvdl 		memset(lstate, 0, sizeof(*lstate));
   6977   1.96      fvdl 		status = xpt_create_path(&lstate->path, /*periph*/NULL,
   6978   1.96      fvdl 					 xpt_path_path_id(ccb->ccb_h.path),
   6979   1.96      fvdl 					 xpt_path_target_id(ccb->ccb_h.path),
   6980   1.96      fvdl 					 xpt_path_lun_id(ccb->ccb_h.path));
   6981   1.96      fvdl 		if (status != CAM_REQ_CMP) {
   6982   1.96      fvdl 			free(lstate, M_DEVBUF);
   6983   1.96      fvdl 			xpt_print_path(ccb->ccb_h.path);
   6984   1.96      fvdl 			printf("Couldn't allocate path\n");
   6985   1.96      fvdl 			ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
   6986   1.96      fvdl 			return;
   6987   1.96      fvdl 		}
   6988   1.96      fvdl 		SLIST_INIT(&lstate->accept_tios);
   6989   1.96      fvdl 		SLIST_INIT(&lstate->immed_notifies);
   6990   1.96      fvdl 		ahc_lock(ahc, &s);
   6991   1.96      fvdl 		ahc_pause(ahc);
   6992   1.96      fvdl 		if (target != CAM_TARGET_WILDCARD) {
   6993   1.96      fvdl 			tstate->enabled_luns[lun] = lstate;
   6994   1.96      fvdl 			ahc->enabled_luns++;
   6995   1.96      fvdl 
   6996   1.96      fvdl 			if ((ahc->features & AHC_MULTI_TID) != 0) {
   6997   1.96      fvdl 				u_int targid_mask;
   6998   1.96      fvdl 
   6999   1.96      fvdl 				targid_mask = ahc_inb(ahc, TARGID)
   7000   1.96      fvdl 					    | (ahc_inb(ahc, TARGID + 1) << 8);
   7001   1.96      fvdl 
   7002   1.96      fvdl 				targid_mask |= target_mask;
   7003   1.96      fvdl 				ahc_outb(ahc, TARGID, targid_mask);
   7004   1.96      fvdl 				ahc_outb(ahc, TARGID+1, (targid_mask >> 8));
   7005  1.112     perry 
   7006   1.96      fvdl 				ahc_update_scsiid(ahc, targid_mask);
   7007   1.96      fvdl 			} else {
   7008   1.96      fvdl 				u_int our_id;
   7009   1.96      fvdl 				char  channel;
   7010   1.42      fvdl 
   7011   1.96      fvdl 				channel = SIM_CHANNEL(ahc, sim);
   7012   1.96      fvdl 				our_id = SIM_SCSI_ID(ahc, sim);
   7013   1.42      fvdl 
   7014   1.96      fvdl 				/*
   7015   1.96      fvdl 				 * This can only happen if selections
   7016   1.96      fvdl 				 * are not enabled
   7017   1.96      fvdl 				 */
   7018   1.96      fvdl 				if (target != our_id) {
   7019   1.96      fvdl 					u_int sblkctl;
   7020   1.96      fvdl 					char  cur_channel;
   7021   1.96      fvdl 					int   swap;
   7022   1.96      fvdl 
   7023   1.96      fvdl 					sblkctl = ahc_inb(ahc, SBLKCTL);
   7024   1.96      fvdl 					cur_channel = (sblkctl & SELBUSB)
   7025   1.96      fvdl 						    ? 'B' : 'A';
   7026   1.96      fvdl 					if ((ahc->features & AHC_TWIN) == 0)
   7027   1.96      fvdl 						cur_channel = 'A';
   7028   1.96      fvdl 					swap = cur_channel != channel;
   7029   1.96      fvdl 					if (channel == 'A')
   7030   1.96      fvdl 						ahc->our_id = target;
   7031   1.96      fvdl 					else
   7032   1.96      fvdl 						ahc->our_id_b = target;
   7033   1.96      fvdl 
   7034   1.96      fvdl 					if (swap)
   7035   1.96      fvdl 						ahc_outb(ahc, SBLKCTL,
   7036   1.96      fvdl 							 sblkctl ^ SELBUSB);
   7037   1.42      fvdl 
   7038   1.96      fvdl 					ahc_outb(ahc, SCSIID, target);
   7039   1.42      fvdl 
   7040   1.96      fvdl 					if (swap)
   7041   1.96      fvdl 						ahc_outb(ahc, SBLKCTL, sblkctl);
   7042   1.96      fvdl 				}
   7043   1.96      fvdl 			}
   7044   1.96      fvdl 		} else
   7045   1.96      fvdl 			ahc->black_hole = lstate;
   7046   1.96      fvdl 		/* Allow select-in operations */
   7047   1.96      fvdl 		if (ahc->black_hole != NULL && ahc->enabled_luns > 0) {
   7048   1.96      fvdl 			scsiseq = ahc_inb(ahc, SCSISEQ_TEMPLATE);
   7049   1.96      fvdl 			scsiseq |= ENSELI;
   7050   1.96      fvdl 			ahc_outb(ahc, SCSISEQ_TEMPLATE, scsiseq);
   7051   1.96      fvdl 			scsiseq = ahc_inb(ahc, SCSISEQ);
   7052   1.96      fvdl 			scsiseq |= ENSELI;
   7053   1.96      fvdl 			ahc_outb(ahc, SCSISEQ, scsiseq);
   7054   1.96      fvdl 		}
   7055   1.96      fvdl 		ahc_unpause(ahc);
   7056   1.96      fvdl 		ahc_unlock(ahc, &s);
   7057   1.96      fvdl 		ccb->ccb_h.status = CAM_REQ_CMP;
   7058   1.96      fvdl 		xpt_print_path(ccb->ccb_h.path);
   7059   1.96      fvdl 		printf("Lun now enabled for target mode\n");
   7060   1.42      fvdl 	} else {
   7061   1.96      fvdl 		struct scb *scb;
   7062   1.96      fvdl 		int i, empty;
   7063    1.6   mycroft 
   7064   1.96      fvdl 		if (lstate == NULL) {
   7065   1.96      fvdl 			ccb->ccb_h.status = CAM_LUN_INVALID;
   7066   1.96      fvdl 			return;
   7067   1.96      fvdl 		}
   7068   1.42      fvdl 
   7069   1.96      fvdl 		ahc_lock(ahc, &s);
   7070  1.112     perry 
   7071   1.96      fvdl 		ccb->ccb_h.status = CAM_REQ_CMP;
   7072   1.96      fvdl 		LIST_FOREACH(scb, &ahc->pending_scbs, pending_links) {
   7073   1.96      fvdl 			struct ccb_hdr *ccbh;
   7074   1.96      fvdl 
   7075   1.96      fvdl 			ccbh = &scb->io_ctx->ccb_h;
   7076   1.96      fvdl 			if (ccbh->func_code == XPT_CONT_TARGET_IO
   7077   1.96      fvdl 			 && !xpt_path_comp(ccbh->path, ccb->ccb_h.path)){
   7078   1.96      fvdl 				printf("CTIO pending\n");
   7079   1.96      fvdl 				ccb->ccb_h.status = CAM_REQ_INVALID;
   7080   1.96      fvdl 				ahc_unlock(ahc, &s);
   7081   1.96      fvdl 				return;
   7082   1.96      fvdl 			}
   7083   1.96      fvdl 		}
   7084   1.42      fvdl 
   7085   1.96      fvdl 		if (SLIST_FIRST(&lstate->accept_tios) != NULL) {
   7086   1.96      fvdl 			printf("ATIOs pending\n");
   7087   1.96      fvdl 			ccb->ccb_h.status = CAM_REQ_INVALID;
   7088   1.96      fvdl 		}
   7089   1.42      fvdl 
   7090   1.96      fvdl 		if (SLIST_FIRST(&lstate->immed_notifies) != NULL) {
   7091   1.96      fvdl 			printf("INOTs pending\n");
   7092   1.96      fvdl 			ccb->ccb_h.status = CAM_REQ_INVALID;
   7093   1.96      fvdl 		}
   7094   1.42      fvdl 
   7095   1.96      fvdl 		if (ccb->ccb_h.status != CAM_REQ_CMP) {
   7096   1.96      fvdl 			ahc_unlock(ahc, &s);
   7097   1.96      fvdl 			return;
   7098   1.42      fvdl 		}
   7099   1.42      fvdl 
   7100   1.96      fvdl 		xpt_print_path(ccb->ccb_h.path);
   7101   1.96      fvdl 		printf("Target mode disabled\n");
   7102   1.96      fvdl 		xpt_free_path(lstate->path);
   7103   1.96      fvdl 		free(lstate, M_DEVBUF);
   7104   1.96      fvdl 
   7105   1.96      fvdl 		ahc_pause(ahc);
   7106   1.96      fvdl 		/* Can we clean up the target too? */
   7107   1.96      fvdl 		if (target != CAM_TARGET_WILDCARD) {
   7108   1.96      fvdl 			tstate->enabled_luns[lun] = NULL;
   7109   1.96      fvdl 			ahc->enabled_luns--;
   7110   1.96      fvdl 			for (empty = 1, i = 0; i < 8; i++)
   7111   1.96      fvdl 				if (tstate->enabled_luns[i] != NULL) {
   7112   1.96      fvdl 					empty = 0;
   7113   1.96      fvdl 					break;
   7114   1.96      fvdl 				}
   7115   1.42      fvdl 
   7116   1.96      fvdl 			if (empty) {
   7117   1.96      fvdl 				ahc_free_tstate(ahc, target, channel,
   7118   1.96      fvdl 						/*force*/FALSE);
   7119   1.96      fvdl 				if (ahc->features & AHC_MULTI_TID) {
   7120   1.96      fvdl 					u_int targid_mask;
   7121   1.96      fvdl 
   7122   1.96      fvdl 					targid_mask = ahc_inb(ahc, TARGID)
   7123   1.96      fvdl 						    | (ahc_inb(ahc, TARGID + 1)
   7124   1.96      fvdl 						       << 8);
   7125   1.96      fvdl 
   7126   1.96      fvdl 					targid_mask &= ~target_mask;
   7127   1.96      fvdl 					ahc_outb(ahc, TARGID, targid_mask);
   7128   1.96      fvdl 					ahc_outb(ahc, TARGID+1,
   7129   1.96      fvdl 					 	 (targid_mask >> 8));
   7130   1.96      fvdl 					ahc_update_scsiid(ahc, targid_mask);
   7131   1.96      fvdl 				}
   7132   1.96      fvdl 			}
   7133   1.96      fvdl 		} else {
   7134   1.42      fvdl 
   7135   1.96      fvdl 			ahc->black_hole = NULL;
   7136   1.42      fvdl 
   7137   1.96      fvdl 			/*
   7138   1.96      fvdl 			 * We can't allow selections without
   7139   1.96      fvdl 			 * our black hole device.
   7140   1.96      fvdl 			 */
   7141   1.96      fvdl 			empty = TRUE;
   7142   1.96      fvdl 		}
   7143   1.96      fvdl 		if (ahc->enabled_luns == 0) {
   7144   1.96      fvdl 			/* Disallow select-in */
   7145   1.96      fvdl 			u_int scsiseq;
   7146   1.96      fvdl 
   7147   1.96      fvdl 			scsiseq = ahc_inb(ahc, SCSISEQ_TEMPLATE);
   7148   1.96      fvdl 			scsiseq &= ~ENSELI;
   7149   1.96      fvdl 			ahc_outb(ahc, SCSISEQ_TEMPLATE, scsiseq);
   7150   1.96      fvdl 			scsiseq = ahc_inb(ahc, SCSISEQ);
   7151   1.96      fvdl 			scsiseq &= ~ENSELI;
   7152   1.96      fvdl 			ahc_outb(ahc, SCSISEQ, scsiseq);
   7153   1.96      fvdl 
   7154   1.96      fvdl 			if ((ahc->features & AHC_MULTIROLE) == 0) {
   7155   1.96      fvdl 				printf("Configuring Initiator Mode\n");
   7156   1.96      fvdl 				ahc->flags &= ~AHC_TARGETROLE;
   7157   1.96      fvdl 				ahc->flags |= AHC_INITIATORROLE;
   7158   1.96      fvdl 				ahc_pause(ahc);
   7159   1.96      fvdl 				ahc_loadseq(ahc);
   7160   1.96      fvdl 			}
   7161   1.96      fvdl 		}
   7162   1.96      fvdl 		ahc_unpause(ahc);
   7163   1.96      fvdl 		ahc_unlock(ahc, &s);
   7164   1.96      fvdl 	}
   7165    1.6   mycroft }
   7166    1.6   mycroft 
   7167    1.6   mycroft static void
   7168   1.96      fvdl ahc_update_scsiid(struct ahc_softc *ahc, u_int targid_mask)
   7169    1.6   mycroft {
   7170   1.96      fvdl 	u_int scsiid_mask;
   7171   1.96      fvdl 	u_int scsiid;
   7172   1.96      fvdl 
   7173   1.96      fvdl 	if ((ahc->features & AHC_MULTI_TID) == 0)
   7174   1.96      fvdl 		panic("ahc_update_scsiid called on non-multitid unit\n");
   7175   1.96      fvdl 
   7176   1.96      fvdl 	/*
   7177   1.96      fvdl 	 * Since we will rely on the TARGID mask
   7178   1.96      fvdl 	 * for selection enables, ensure that OID
   7179   1.96      fvdl 	 * in SCSIID is not set to some other ID
   7180   1.96      fvdl 	 * that we don't want to allow selections on.
   7181   1.96      fvdl 	 */
   7182   1.96      fvdl 	if ((ahc->features & AHC_ULTRA2) != 0)
   7183   1.96      fvdl 		scsiid = ahc_inb(ahc, SCSIID_ULTRA2);
   7184   1.96      fvdl 	else
   7185   1.96      fvdl 		scsiid = ahc_inb(ahc, SCSIID);
   7186   1.96      fvdl 	scsiid_mask = 0x1 << (scsiid & OID);
   7187   1.96      fvdl 	if ((targid_mask & scsiid_mask) == 0) {
   7188   1.96      fvdl 		u_int our_id;
   7189    1.1   mycroft 
   7190   1.96      fvdl 		/* ffs counts from 1 */
   7191   1.96      fvdl 		our_id = ffs(targid_mask);
   7192   1.96      fvdl 		if (our_id == 0)
   7193   1.96      fvdl 			our_id = ahc->our_id;
   7194   1.96      fvdl 		else
   7195   1.96      fvdl 			our_id--;
   7196   1.96      fvdl 		scsiid &= TID;
   7197   1.96      fvdl 		scsiid |= our_id;
   7198   1.96      fvdl 	}
   7199   1.96      fvdl 	if ((ahc->features & AHC_ULTRA2) != 0)
   7200   1.96      fvdl 		ahc_outb(ahc, SCSIID_ULTRA2, scsiid);
   7201   1.96      fvdl 	else
   7202   1.96      fvdl 		ahc_outb(ahc, SCSIID, scsiid);
   7203    1.1   mycroft }
   7204    1.1   mycroft 
   7205   1.96      fvdl void
   7206   1.96      fvdl ahc_run_tqinfifo(struct ahc_softc *ahc, int paused)
   7207    1.1   mycroft {
   7208   1.96      fvdl 	struct target_cmd *cmd;
   7209    1.6   mycroft 
   7210    1.6   mycroft 	/*
   7211   1.96      fvdl 	 * If the card supports auto-access pause,
   7212   1.96      fvdl 	 * we can access the card directly regardless
   7213   1.96      fvdl 	 * of whether it is paused or not.
   7214   1.96      fvdl 	 */
   7215   1.96      fvdl 	if ((ahc->features & AHC_AUTOPAUSE) != 0)
   7216   1.96      fvdl 		paused = TRUE;
   7217   1.59        pk 
   7218   1.96      fvdl 	ahc_sync_tqinfifo(ahc, BUS_DMASYNC_POSTREAD);
   7219   1.96      fvdl 	while ((cmd = &ahc->targetcmds[ahc->tqinfifonext])->cmd_valid != 0) {
   7220    1.1   mycroft 
   7221    1.6   mycroft 		/*
   7222   1.96      fvdl 		 * Only advance through the queue if we
   7223   1.96      fvdl 		 * have the resources to process the command.
   7224    1.6   mycroft 		 */
   7225   1.96      fvdl 		if (ahc_handle_target_cmd(ahc, cmd) != 0)
   7226   1.96      fvdl 			break;
   7227   1.42      fvdl 
   7228   1.96      fvdl 		cmd->cmd_valid = 0;
   7229   1.96      fvdl 		ahc_dmamap_sync(ahc, ahc->parent_dmat/*shared_data_dmat*/,
   7230   1.96      fvdl 				ahc->shared_data_dmamap,
   7231   1.96      fvdl 				ahc_targetcmd_offset(ahc, ahc->tqinfifonext),
   7232   1.96      fvdl 				sizeof(struct target_cmd),
   7233   1.96      fvdl 				BUS_DMASYNC_PREREAD);
   7234   1.96      fvdl 		ahc->tqinfifonext++;
   7235   1.96      fvdl 
   7236   1.96      fvdl 		/*
   7237   1.96      fvdl 		 * Lazily update our position in the target mode incoming
   7238   1.96      fvdl 		 * command queue as seen by the sequencer.
   7239   1.96      fvdl 		 */
   7240   1.96      fvdl 		if ((ahc->tqinfifonext & (HOST_TQINPOS - 1)) == 1) {
   7241   1.96      fvdl 			if ((ahc->features & AHC_HS_MAILBOX) != 0) {
   7242   1.96      fvdl 				u_int hs_mailbox;
   7243   1.96      fvdl 
   7244   1.96      fvdl 				hs_mailbox = ahc_inb(ahc, HS_MAILBOX);
   7245   1.96      fvdl 				hs_mailbox &= ~HOST_TQINPOS;
   7246   1.96      fvdl 				hs_mailbox |= ahc->tqinfifonext & HOST_TQINPOS;
   7247   1.96      fvdl 				ahc_outb(ahc, HS_MAILBOX, hs_mailbox);
   7248   1.96      fvdl 			} else {
   7249   1.96      fvdl 				if (!paused)
   7250  1.112     perry 					ahc_pause(ahc);
   7251   1.96      fvdl 				ahc_outb(ahc, KERNEL_TQINPOS,
   7252   1.96      fvdl 					 ahc->tqinfifonext & HOST_TQINPOS);
   7253   1.96      fvdl 				if (!paused)
   7254   1.96      fvdl 					ahc_unpause(ahc);
   7255   1.96      fvdl 			}
   7256    1.6   mycroft 		}
   7257   1.42      fvdl 	}
   7258   1.96      fvdl }
   7259   1.96      fvdl 
   7260   1.96      fvdl static int
   7261   1.96      fvdl ahc_handle_target_cmd(struct ahc_softc *ahc, struct target_cmd *cmd)
   7262   1.96      fvdl {
   7263   1.96      fvdl 	struct	  ahc_tmode_tstate *tstate;
   7264   1.96      fvdl 	struct	  ahc_tmode_lstate *lstate;
   7265   1.96      fvdl 	struct	  ccb_accept_tio *atio;
   7266   1.96      fvdl 	uint8_t *byte;
   7267   1.96      fvdl 	int	  initiator;
   7268   1.96      fvdl 	int	  target;
   7269   1.96      fvdl 	int	  lun;
   7270   1.96      fvdl 
   7271   1.96      fvdl 	initiator = SCSIID_TARGET(ahc, cmd->scsiid);
   7272   1.96      fvdl 	target = SCSIID_OUR_ID(cmd->scsiid);
   7273   1.96      fvdl 	lun    = (cmd->identify & MSG_IDENTIFY_LUNMASK);
   7274   1.96      fvdl 
   7275   1.96      fvdl 	byte = cmd->bytes;
   7276   1.96      fvdl 	tstate = ahc->enabled_targets[target];
   7277   1.96      fvdl 	lstate = NULL;
   7278   1.96      fvdl 	if (tstate != NULL)
   7279   1.96      fvdl 		lstate = tstate->enabled_luns[lun];
   7280   1.42      fvdl 
   7281   1.42      fvdl 	/*
   7282   1.96      fvdl 	 * Commands for disabled luns go to the black hole driver.
   7283   1.42      fvdl 	 */
   7284   1.96      fvdl 	if (lstate == NULL)
   7285   1.96      fvdl 		lstate = ahc->black_hole;
   7286   1.42      fvdl 
   7287   1.96      fvdl 	atio = (struct ccb_accept_tio*)SLIST_FIRST(&lstate->accept_tios);
   7288   1.96      fvdl 	if (atio == NULL) {
   7289   1.96      fvdl 		ahc->flags |= AHC_TQINFIFO_BLOCKED;
   7290   1.96      fvdl 		/*
   7291   1.96      fvdl 		 * Wait for more ATIOs from the peripheral driver for this lun.
   7292   1.96      fvdl 		 */
   7293   1.96      fvdl 		if (bootverbose)
   7294   1.96      fvdl 			printf("%s: ATIOs exhausted\n", ahc_name(ahc));
   7295   1.96      fvdl 		return (1);
   7296   1.96      fvdl 	} else
   7297   1.96      fvdl 		ahc->flags &= ~AHC_TQINFIFO_BLOCKED;
   7298   1.96      fvdl #if 0
   7299   1.96      fvdl 	printf("Incoming command from %d for %d:%d%s\n",
   7300   1.96      fvdl 	       initiator, target, lun,
   7301   1.96      fvdl 	       lstate == ahc->black_hole ? "(Black Holed)" : "");
   7302   1.42      fvdl #endif
   7303   1.96      fvdl 	SLIST_REMOVE_HEAD(&lstate->accept_tios, sim_links.sle);
   7304   1.42      fvdl 
   7305   1.96      fvdl 	if (lstate == ahc->black_hole) {
   7306   1.96      fvdl 		/* Fill in the wildcards */
   7307   1.96      fvdl 		atio->ccb_h.target_id = target;
   7308   1.96      fvdl 		atio->ccb_h.target_lun = lun;
   7309   1.96      fvdl 	}
   7310   1.42      fvdl 
   7311   1.42      fvdl 	/*
   7312   1.96      fvdl 	 * Package it up and send it off to
   7313   1.96      fvdl 	 * whomever has this lun enabled.
   7314   1.42      fvdl 	 */
   7315   1.96      fvdl 	atio->sense_len = 0;
   7316   1.96      fvdl 	atio->init_id = initiator;
   7317   1.96      fvdl 	if (byte[0] != 0xFF) {
   7318   1.96      fvdl 		/* Tag was included */
   7319   1.96      fvdl 		atio->tag_action = *byte++;
   7320   1.96      fvdl 		atio->tag_id = *byte++;
   7321   1.96      fvdl 		atio->ccb_h.flags = CAM_TAG_ACTION_VALID;
   7322   1.96      fvdl 	} else {
   7323   1.96      fvdl 		atio->ccb_h.flags = 0;
   7324   1.42      fvdl 	}
   7325   1.96      fvdl 	byte++;
   7326   1.42      fvdl 
   7327   1.96      fvdl 	/* Okay.  Now determine the cdb size based on the command code */
   7328   1.96      fvdl 	switch (*byte >> CMD_GROUP_CODE_SHIFT) {
   7329   1.96      fvdl 	case 0:
   7330   1.96      fvdl 		atio->cdb_len = 6;
   7331   1.96      fvdl 		break;
   7332   1.96      fvdl 	case 1:
   7333   1.96      fvdl 	case 2:
   7334   1.96      fvdl 		atio->cdb_len = 10;
   7335   1.96      fvdl 		break;
   7336   1.96      fvdl 	case 4:
   7337   1.96      fvdl 		atio->cdb_len = 16;
   7338   1.96      fvdl 		break;
   7339   1.96      fvdl 	case 5:
   7340   1.96      fvdl 		atio->cdb_len = 12;
   7341   1.96      fvdl 		break;
   7342   1.96      fvdl 	case 3:
   7343   1.96      fvdl 	default:
   7344   1.96      fvdl 		/* Only copy the opcode. */
   7345   1.96      fvdl 		atio->cdb_len = 1;
   7346   1.96      fvdl 		printf("Reserved or VU command code type encountered\n");
   7347   1.96      fvdl 		break;
   7348    1.1   mycroft 	}
   7349  1.112     perry 
   7350   1.96      fvdl 	memcpy(atio->cdb_io.cdb_bytes, byte, atio->cdb_len);
   7351   1.42      fvdl 
   7352   1.96      fvdl 	atio->ccb_h.status |= CAM_CDB_RECVD;
   7353   1.42      fvdl 
   7354   1.96      fvdl 	if ((cmd->identify & MSG_IDENTIFY_DISCFLAG) == 0) {
   7355   1.96      fvdl 		/*
   7356   1.96      fvdl 		 * We weren't allowed to disconnect.
   7357   1.96      fvdl 		 * We're hanging on the bus until a
   7358   1.96      fvdl 		 * continue target I/O comes in response
   7359   1.96      fvdl 		 * to this accept tio.
   7360   1.96      fvdl 		 */
   7361   1.96      fvdl #if 0
   7362   1.96      fvdl 		printf("Received Immediate Command %d:%d:%d - %p\n",
   7363   1.96      fvdl 		       initiator, target, lun, ahc->pending_device);
   7364   1.96      fvdl #endif
   7365   1.96      fvdl 		ahc->pending_device = lstate;
   7366   1.96      fvdl 		ahc_freeze_ccb((union ccb *)atio);
   7367   1.96      fvdl 		atio->ccb_h.flags |= CAM_DIS_DISCONNECT;
   7368    1.1   mycroft 	}
   7369   1.96      fvdl 	xpt_done((union ccb*)atio);
   7370   1.96      fvdl 	return (0);
   7371    1.6   mycroft }
   7372   1.42      fvdl #endif
   7373   1.42      fvdl 
   7374   1.96      fvdl static int
   7375   1.96      fvdl ahc_createdmamem(tag, size, flags, mapp, vaddr, baddr, seg, nseg, myname, what)
   7376   1.96      fvdl 	bus_dma_tag_t tag;
   7377   1.96      fvdl 	int size;
   7378   1.96      fvdl 	int flags;
   7379   1.96      fvdl 	bus_dmamap_t *mapp;
   7380   1.96      fvdl 	caddr_t *vaddr;
   7381   1.96      fvdl 	bus_addr_t *baddr;
   7382   1.96      fvdl 	bus_dma_segment_t *seg;
   7383   1.96      fvdl 	int *nseg;
   7384   1.96      fvdl 	const char *myname, *what;
   7385    1.6   mycroft {
   7386   1.96      fvdl 	int error, level = 0;
   7387   1.42      fvdl 
   7388   1.96      fvdl 	if ((error = bus_dmamem_alloc(tag, size, PAGE_SIZE, 0,
   7389  1.117    bouyer 				      seg, 1, nseg, BUS_DMA_WAITOK)) != 0) {
   7390   1.96      fvdl 		printf("%s: failed to allocate DMA mem for %s, error = %d\n",
   7391   1.96      fvdl 			myname, what, error);
   7392   1.96      fvdl 		goto out;
   7393   1.96      fvdl 	}
   7394   1.96      fvdl 	level++;
   7395   1.42      fvdl 
   7396   1.96      fvdl 	if ((error = bus_dmamem_map(tag, seg, *nseg, size, vaddr,
   7397  1.117    bouyer 				    BUS_DMA_WAITOK|BUS_DMA_COHERENT)) != 0) {
   7398   1.96      fvdl 		printf("%s: failed to map DMA mem for %s, error = %d\n",
   7399   1.96      fvdl 			myname, what, error);
   7400   1.96      fvdl 		goto out;
   7401   1.96      fvdl 	}
   7402   1.96      fvdl 	level++;
   7403   1.42      fvdl 
   7404   1.96      fvdl 	if ((error = bus_dmamap_create(tag, size, 1, size, 0,
   7405  1.117    bouyer 				       BUS_DMA_WAITOK | flags, mapp)) != 0) {
   7406  1.119   tsutsui 		printf("%s: failed to create DMA map for %s, error = %d\n",
   7407   1.96      fvdl 			myname, what, error);
   7408   1.96      fvdl 		goto out;
   7409  1.119   tsutsui 	}
   7410   1.96      fvdl 	level++;
   7411   1.42      fvdl 
   7412   1.42      fvdl 
   7413   1.96      fvdl 	if ((error = bus_dmamap_load(tag, *mapp, *vaddr, size, NULL,
   7414  1.117    bouyer 				     BUS_DMA_WAITOK)) != 0) {
   7415  1.119   tsutsui 		printf("%s: failed to load DMA map for %s, error = %d\n",
   7416   1.96      fvdl 			myname, what, error);
   7417   1.96      fvdl 		goto out;
   7418  1.119   tsutsui 	}
   7419   1.42      fvdl 
   7420   1.96      fvdl 	*baddr = (*mapp)->dm_segs[0].ds_addr;
   7421    1.1   mycroft 
   7422   1.96      fvdl 	return 0;
   7423   1.96      fvdl out:
   7424   1.96      fvdl 	printf("ahc_createdmamem error (%d)\n", level);
   7425   1.96      fvdl 	switch (level) {
   7426   1.96      fvdl 	case 3:
   7427   1.96      fvdl 		bus_dmamap_destroy(tag, *mapp);
   7428   1.96      fvdl 		/* FALLTHROUGH */
   7429   1.96      fvdl 	case 2:
   7430   1.96      fvdl 		bus_dmamem_unmap(tag, *vaddr, size);
   7431   1.96      fvdl 		/* FALLTHROUGH */
   7432   1.96      fvdl 	case 1:
   7433   1.96      fvdl 		bus_dmamem_free(tag, seg, *nseg);
   7434   1.96      fvdl 		break;
   7435   1.96      fvdl 	default:
   7436   1.96      fvdl 		break;
   7437   1.42      fvdl 	}
   7438   1.14     gibbs 
   7439  1.113  augustss 	return -1;
   7440   1.14     gibbs }
   7441   1.14     gibbs 
   7442   1.14     gibbs static void
   7443   1.96      fvdl ahc_freedmamem(tag, size, map, vaddr, seg, nseg)
   7444   1.96      fvdl 	bus_dma_tag_t tag;
   7445   1.96      fvdl 	int size;
   7446   1.96      fvdl 	bus_dmamap_t map;
   7447   1.96      fvdl 	caddr_t vaddr;
   7448   1.96      fvdl 	bus_dma_segment_t *seg;
   7449   1.96      fvdl 	int nseg;
   7450   1.14     gibbs {
   7451   1.42      fvdl 
   7452   1.96      fvdl 	bus_dmamap_unload(tag, map);
   7453   1.96      fvdl 	bus_dmamap_destroy(tag, map);
   7454   1.96      fvdl 	bus_dmamem_unmap(tag, vaddr, size);
   7455   1.96      fvdl 	bus_dmamem_free(tag, seg, nseg);
   7456   1.45      fvdl }
   7457