ahc_bus_dmamap_sync(ahc->sc_dmat, ahc->shared_data_dmamap,
bus_dmamap_sync(ahc->sc_dmat, ahc->shared_data_dmamap,
STATIC void	ahc_setup_target_msgin __P((struct ahc_softc *ahc,					    struct ahc_devinfo *devinfo));STATIC int	ahc_handle_msg_reject __P((struct ahc_softc *ahc,					   struct ahc_devinfo *devinfo));STATIC void	ahc_clear_msg_state __P((struct ahc_softc *ahc));STATIC void	ahc_handle_message_phase __P((struct ahc_softc *ahc,					      struct scsi_link *sc_link));STATIC int	ahc_sent_msg __P((struct ahc_softc *ahc, u_int msgtype,				  int full));typedef enum {	MSGLOOP_IN_PROG,	MSGLOOP_MSGCOMPLETE,	MSGLOOP_TERMINATED} msg_loop_stat;#ifdef __HAS_NEW_BUS_DMAMAP_SYNC#define	ahc_bus_dmamap_sync(tag, map, off, len, op)	\    bus_dmamap_sync((tag), (map), (off), (len), (op))#else#define	ahc_bus_dmamap_sync(tag, map, off, len, op)	\    bus_dmamap_sync((tag), (map), (op))#endifSTATIC int	ahc_parse_msg __P((struct ahc_softc *ahc,				   struct scsi_link *sc_link,				   struct ahc_devinfo *devinfo));STATIC void	ahc_handle_ign_wide_residue __P((struct ahc_softc *ahc,						 struct ahc_devinfo *devinfo));STATIC void	ahc_handle_devreset __P((struct ahc_softc *ahc,					 struct ahc_devinfo *devinfo,					 int status, char *message,					 int verbose_level));#ifdef AHC_DUMP_SEQSTATIC void	ahc_dumpseq __P((struct ahc_softc *ahc));#endifSTATIC void	ahc_loadseq __P((struct ahc_softc *ahc));STATIC int	ahc_check_patch __P((struct ahc_softc *ahc,				     struct patch **start_patch,				     int start_instr, int *skip_addr));STATIC void	ahc_download_instr __P((struct ahc_softc *ahc,					int instrptr, u_int8_t *dconsts));STATIC int	ahc_match_scb __P((struct scb *scb, int target, char channel,				   int lun, u_int tag, role_t role));#ifdef AHC_DEBUGSTATIC void	ahc_print_scb __P((struct scb *scb));#endifSTATIC int	ahc_search_qinfifo __P((struct ahc_softc *ahc, int target,					char channel, int lun, u_int tag,					role_t role, u_int32_t status,					ahc_search_action action));STATIC int	ahc_reset_channel __P((struct ahc_softc *ahc, char channel,				       int initiate_reset));STATIC int	ahc_abort_scbs __P((struct ahc_softc *ahc, int target,				    char channel, int lun, u_int tag,				    role_t role, u_int32_t status));STATIC int	ahc_search_disc_list __P((struct ahc_softc *ahc, int target,					  char channel, int lun, u_int tag,					  int stop_on_first, int remove,					  int save_state));STATIC u_int	ahc_rem_scb_from_disc_list __P((struct ahc_softc *ahc,						u_int prev, u_int scbptr));STATIC void	ahc_add_curscb_to_free_list __P((struct ahc_softc *ahc));STATIC void	ahc_clear_intstat __P((struct ahc_softc *ahc));STATIC void	ahc_reset_current_bus __P((struct ahc_softc *ahc));STATIC struct ahc_syncrate *		ahc_devlimited_syncrate __P((struct ahc_softc *ahc, u_int *period));STATIC struct ahc_syncrate *		ahc_find_syncrate __P((struct ahc_softc *ahc, u_int *period,				       u_int maxsync));STATIC u_int ahc_find_period __P((struct ahc_softc *ahc, u_int scsirate,				  u_int maxsync));STATIC void	ahc_validate_offset __P((struct ahc_softc *ahc,					 struct ahc_syncrate *syncrate,					 u_int *offset, int wide)); STATIC void	ahc_update_target_msg_request __P((struct ahc_softc *ahc,					      struct ahc_devinfo *devinfo,					      struct ahc_initiator_tinfo *tinfo,					      int force, int paused));STATIC void	ahc_set_syncrate __P((struct ahc_softc *ahc,				      struct ahc_devinfo *devinfo,				      struct ahc_syncrate *syncrate,				      u_int period, u_int offset,				      u_int type, int paused, int done));STATIC void	ahc_set_width __P((struct ahc_softc *ahc,			      struct ahc_devinfo *devinfo,			      u_int width, u_int type, int paused, int done));STATIC void	ahc_set_tags __P((struct ahc_softc *ahc,				  struct ahc_devinfo *devinfo,int enable));STATIC int      ahc_istagged_device __P((struct ahc_softc *ahc,					 struct scsi_xfer *xs,					 int nocmdcheck));STATIC void     ahc_check_tags __P((struct ahc_softc *ahc,				    struct scsi_xfer *xs));STATIC void	ahc_construct_sdtr __P((struct ahc_softc *ahc,				   u_int period, u_int offset));STATIC void	ahc_construct_wdtr __P((struct ahc_softc *ahc, u_int bus_width));STATIC void	ahc_calc_residual __P((struct scb *scb));STATIC void	ahc_update_pending_syncrates __P((struct ahc_softc *ahc));STATIC void	ahc_set_recoveryscb __P((struct ahc_softc *ahc,					 struct scb *scb));STATIC void ahc_timeout __P((void *));static __inline int  sequencer_paused __P((struct ahc_softc *ahc));static __inline void pause_sequencer __P((struct ahc_softc *ahc));static __inline void unpause_sequencer __P((struct ahc_softc *ahc));STATIC void restart_sequencer __P((struct ahc_softc *ahc));static __inline u_int ahc_index_busy_tcl __P((struct ahc_softc *ahc,					      u_int tcl, int unbusy)); static __inline void	ahc_busy_tcl __P((struct ahc_softc *ahc,					  struct scb *scb));static __inline int	ahc_isbusy_tcl __P((struct ahc_softc *ahc,					    struct scb *scb));static __inline void ahc_freeze_ccb __P((struct scb* scb));static __inline void ahcsetccbstatus __P((struct scsi_xfer *xs, int status));STATIC void ahc_run_qoutfifo __P((struct ahc_softc *ahc));static __inline struct ahc_initiator_tinfo *	ahc_fetch_transinfo __P((struct ahc_softc *ahc, char channel,				 u_int our_id, u_int target,				 struct tmode_tstate **tstate));STATIC void ahcfreescb __P((struct ahc_softc *ahc, struct scb *scb));static __inline struct scb *ahcgetscb __P((struct ahc_softc *ahc));int    ahc_createdmamem __P((struct ahc_softc *ahc, int size,			     bus_dmamap_t *mapp, caddr_t *vaddr,			     bus_addr_t *baddr, bus_dma_segment_t *segs,			     int *nseg, const char *what));STATIC void ahc_freedmamem __P((bus_dma_tag_t tag, int size,				bus_dmamap_t map, caddr_t vaddr,				bus_dma_segment_t *seg, int nseg));STATIC void ahcminphys __P((struct buf *bp));STATIC INLINE	struct scsi_xfer *ahc_first_xs __P((struct ahc_softc *));STATIC INLINE	void   ahc_list_insert_before __P((struct ahc_softc *ahc,						   struct scsi_xfer *xs,						   struct scsi_xfer *next_xs));STATIC INLINE	void   ahc_list_insert_head __P((struct ahc_softc *ahc,						 struct scsi_xfer *xs));STATIC INLINE	void   ahc_list_insert_tail __P((struct ahc_softc *ahc,						 struct scsi_xfer *xs));STATIC INLINE	void   ahc_list_remove __P((struct ahc_softc *ahc,					    struct scsi_xfer *xs));STATIC INLINE	struct scsi_xfer *ahc_list_next __P((struct ahc_softc *ahc,						     struct scsi_xfer *xs));STATIC int32_t ahc_scsi_cmd __P((struct scsi_xfer *xs));static __inline void ahc_swap_hscb __P((struct hardware_scb *));static __inline void ahc_swap_sg __P((struct ahc_dma_seg *));struct cfdriver ahc_cd = {	NULL, "ahc", DV_DULL};static struct scsi_adapter ahc_switch ={	ahc_scsi_cmd,	ahcminphys,	0,	0,};/* the below structure is so we have a default dev struct for our link struct */static struct scsi_device ahc_dev ={	NULL, /* Use default error handler */	NULL, /* have a queue, served by this */	NULL, /* have no async handler */	NULL, /* Use default 'done' routine */};static __inline voidahc_swap_hscb(struct hardware_scb *hscb){	hscb->SG_pointer = htole32(hscb->SG_pointer);	hscb->data = htole32(hscb->data);	hscb->datalen = htole32(hscb->datalen);	/*	 * No need to swap cmdpointer; it's either 0 or set to	 * cmdstore_busaddr, which is already swapped.	 */}static __inline voidahc_swap_sg(struct ahc_dma_seg *sg){	sg->addr = htole32(sg->addr);	sg->len = htole32(sg->len);}STATIC voidahcminphys(bp)	struct buf *bp;{/* * Even though the card can transfer up to 16megs per command * we are limited by the number of segments in the dma segment * list that we can hold.  The worst case is that all pages are * discontinuous physically, hense the "page per segment" limit * enforced here. */	if (bp->b_bcount > ((AHC_NSEG - 1) * PAGE_SIZE)) {		bp->b_bcount = ((AHC_NSEG - 1) * PAGE_SIZE);	}	minphys(bp);}static __inline u_int32_tahc_hscb_busaddr(struct ahc_softc *ahc, u_int index){	return (ahc->scb_data->hscb_busaddr		+ (sizeof(struct hardware_scb) * index));}#define AHC_BUSRESET_DELAY	25	/* Reset delay in us */static __inline intsequencer_paused(ahc)	struct ahc_softc *ahc;{	return ((ahc_inb(ahc, HCNTRL) & PAUSE) != 0);}static __inline voidpause_sequencer(ahc)	struct ahc_softc *ahc;{	ahc_outb(ahc, HCNTRL, ahc->pause);	/*	 * Since the sequencer can disable pausing in a critical section, we	 * must loop until it actually stops.	 */	while (sequencer_paused(ahc) == 0)		;}static __inline voidunpause_sequencer(ahc)	struct ahc_softc *ahc;{	if ((ahc_inb(ahc, INTSTAT) & (SCSIINT | SEQINT | BRKADRINT)) == 0)		ahc_outb(ahc, HCNTRL, ahc->unpause);}/* * Restart the sequencer program from address zero */STATIC voidrestart_sequencer(ahc)	struct ahc_softc *ahc;{	u_int i;	pause_sequencer(ahc);	/*	 * Everytime we restart the sequencer, there	 * is the possiblitity that we have restarted	 * within a three instruction window where an	 * SCB has been marked free but has not made it	 * onto the free list.  Since SCSI events(bus reset,	 * unexpected bus free) will always freeze the	 * sequencer, we cannot close this window.  To	 * avoid losing an SCB, we reconsitute the free	 * list every time we restart the sequencer.	 */	ahc_outb(ahc, FREE_SCBH, SCB_LIST_NULL);	for (i = 0; i < ahc->scb_data->maxhscbs; i++) {				ahc_outb(ahc, SCBPTR, i);		if (ahc_inb(ahc, SCB_TAG) == SCB_LIST_NULL)			ahc_add_curscb_to_free_list(ahc);	}	ahc_outb(ahc, SEQCTL, FASTMODE|SEQRESET);	unpause_sequencer(ahc);}static __inline u_intahc_index_busy_tcl(ahc, tcl, unbusy)	struct ahc_softc *ahc;	u_int tcl;	int unbusy;{	u_int scbid;	scbid = ahc->untagged_scbs[tcl];	if (unbusy) {		ahc->untagged_scbs[tcl] = SCB_LIST_NULL;		ahc_bus_dmamap_sync(ahc->sc_dmat, ahc->shared_data_dmamap,		    UNTAGGEDSCB_OFFSET * 256, 256, BUS_DMASYNC_PREWRITE);	}	return (scbid);}static __inline voidahc_busy_tcl(ahc, scb)	struct ahc_softc *ahc;	struct scb *scb;{	ahc->untagged_scbs[scb->hscb->tcl] = scb->hscb->tag;	ahc_bus_dmamap_sync(ahc->sc_dmat, ahc->shared_data_dmamap, 	    UNTAGGEDSCB_OFFSET * 256, 256, BUS_DMASYNC_PREWRITE);}static __inline intahc_isbusy_tcl(ahc, scb)	struct ahc_softc *ahc;	struct scb *scb;{	return ahc->untagged_scbs[scb->hscb->tcl] != SCB_LIST_NULL;}static __inline voidahc_freeze_ccb(scb)	struct scb *scb;{	struct scsi_xfer *xs = scb->xs;	struct ahc_softc *ahc = (struct ahc_softc *)xs->sc_link->adapter_softc;	int target;	target = xs->sc_link->target;	if (!(scb->flags & SCB_FREEZE_QUEUE)) {		ahc->devqueue_blocked[target]++;		scb->flags |= SCB_FREEZE_QUEUE;	}}static __inline voidahcsetccbstatus(xs, status)	struct scsi_xfer *xs;	int status;{	xs->error = status;}static __inline struct ahc_initiator_tinfo *ahc_fetch_transinfo(ahc, channel, our_id, remote_id, tstate)	struct ahc_softc *ahc;	char channel;	u_int our_id;	u_int remote_id;	struct tmode_tstate **tstate;{	/*	 * Transfer data structures are stored from the perspective	 * of the target role.  Since the parameters for a connection	 * in the initiator role to a given target are the same as	 * when the roles are reversed, we pretend we are the target.	 */	if (channel == 'B')		our_id += 8;	*tstate = ahc->enabled_targets[our_id];	return (&(*tstate)->transinfo[remote_id]);}STATIC voidahc_run_qoutfifo(ahc)	struct ahc_softc *ahc;{	struct scb *scb;	u_int  scb_index;	ahc_bus_dmamap_sync(ahc->sc_dmat, ahc->shared_data_dmamap, 	    0, 256, BUS_DMASYNC_POSTREAD);	while (ahc->qoutfifo[ahc->qoutfifonext] != SCB_LIST_NULL) {		scb_index = ahc->qoutfifo[ahc->qoutfifonext];		ahc->qoutfifo[ahc->qoutfifonext++] = SCB_LIST_NULL;		scb = &ahc->scb_data->scbarray[scb_index];		if (scb_index >= ahc->scb_data->numscbs		  || (scb->flags & SCB_ACTIVE) == 0) {			printf("%s: WARNING no command for scb %d "			       "(cmdcmplt)\nQOUTPOS = %d\n",			       ahc_name(ahc), scb_index,			       ahc->qoutfifonext - 1);			continue;		}		/*		 * Save off the residual		 * if there is one.		 */		if (scb->hscb->residual_SG_count != 0)			ahc_calc_residual(scb);		else			scb->xs->resid = 0;		ahc_done(ahc, scb);	}}/* * An scb (and hence an scb entry on the board) is put onto the * free list. */STATIC voidahcfreescb(ahc, scb)	struct ahc_softc *ahc;	struct scb *scb;{       	struct hardware_scb *hscb;	int opri;	hscb = scb->hscb;#ifdef AHC_DEBUG	if (ahc_debug & AHC_SHOWSCBALLOC)		printf("%s: free SCB tag %x\n", ahc_name(ahc), hscb->tag);#endif	opri = splbio();	if ((ahc->flags & AHC_RESOURCE_SHORTAGE) != 0 ||	    (scb->flags & SCB_RECOVERY_SCB) != 0) {		ahc->flags &= ~AHC_RESOURCE_SHORTAGE;		ahc->queue_blocked = 0;	}	/* Clean up for the next user */	scb->flags = SCB_FREE;	hscb->control = 0;	hscb->status = 0;	timeout_del(&scb->xs->stimeout);	SLIST_INSERT_HEAD(&ahc->scb_data->free_scbs, scb, links);	splx(opri);}/* * Get a free scb, either one already assigned to a hardware slot * on the adapter or one that will require an SCB to be paged out before * use. If there are none, see if we can allocate a new SCB.  Otherwise * either return an error or sleep. */static __inline struct scb *ahcgetscb(ahc)	struct ahc_softc *ahc;{	struct scb *scbp;	int opri;	opri = splbio();	if ((scbp = SLIST_FIRST(&ahc->scb_data->free_scbs))) {		SLIST_REMOVE_HEAD(&ahc->scb_data->free_scbs, links);	} else {		ahcallocscbs(ahc);		scbp = SLIST_FIRST(&ahc->scb_data->free_scbs);		if (scbp != NULL)			SLIST_REMOVE_HEAD(&ahc->scb_data->free_scbs, links);	}	splx(opri);	return (scbp);}intahc_createdmamem(ahc, size, mapp, vaddr, baddr, seg, nseg, what)	struct ahc_softc *ahc;	int size;	bus_dmamap_t *mapp;	caddr_t *vaddr;	bus_addr_t *baddr;	bus_dma_segment_t *seg;	int *nseg;	const char *what;{	int error, level = 0;	int dma_flags = BUS_DMA_NOWAIT;	bus_dma_tag_t tag = ahc->sc_dmat;	const char *myname = ahc_name(ahc);	if ((ahc->chip & AHC_VL) !=0)		dma_flags |= ISABUS_DMA_32BIT;		if ((error = bus_dmamem_alloc(tag, size, NBPG, 0,			seg, 1, nseg, BUS_DMA_NOWAIT)) != 0) {		printf("%s: failed to allocate DMA mem for %s, error = %d\n",			myname, what, error);		goto out;	}	level++;	if ((error = bus_dmamem_map(tag, seg, *nseg, size, vaddr,			BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) != 0) {		printf("%s: failed to map DMA mem for %s, error = %d\n",			myname, what, error);		goto out;	}	level++;	if ((error = bus_dmamap_create(tag, size, 1, size, 0,			dma_flags, mapp)) != 0) {		printf("%s: failed to create DMA map for %s, error = %d\n",			myname, what, error);		goto out;        }	level++;	if ((error = bus_dmamap_load(tag, *mapp, *vaddr, size, NULL,			BUS_DMA_NOWAIT)) != 0) {		printf("%s: failed to load DMA map for %s, error = %d\n",			myname, what, error);		goto out;        }	*baddr = (*mapp)->dm_segs[0].ds_addr;	return 0;out:	switch (level) {	case 3:		bus_dmamap_destroy(tag, *mapp);		/* FALLTHROUGH */	case 2:		bus_dmamem_unmap(tag, *vaddr, size);		/* FALLTHROUGH */	case 1:		bus_dmamem_free(tag, seg, *nseg);		break;	default:		break;	}	return error;}STATIC voidahc_freedmamem(tag, size, map, vaddr, seg, nseg)	bus_dma_tag_t tag;	int size;	bus_dmamap_t map;	caddr_t vaddr;	bus_dma_segment_t *seg;	int nseg;{	bus_dmamap_unload(tag, map);	bus_dmamap_destroy(tag, map);	bus_dmamem_unmap(tag, vaddr, size);	bus_dmamem_free(tag, seg, nseg);}#ifdef  AHC_DEBUGSTATIC voidahc_print_scb(scb)	struct scb *scb;{	struct hardware_scb *hscb = scb->hscb;	printf("scb:%p tag %x control:0x%x tcl:0x%x cmdlen:%d cmdpointer:0x%lx\n",		scb,		hscb->tag,		hscb->control,		hscb->tcl,		hscb->cmdlen,		(unsigned long)le32toh(hscb->cmdpointer));	printf("        datlen:%u data:0x%lx segs:0x%x segp:0x%lx\n",		le32toh(hscb->datalen),		(unsigned long)(le32toh(hscb->data)),		hscb->SG_count,		(unsigned long)(le32toh(hscb->SG_pointer)));	printf("	sg_addr:%lx sg_len:%lu\n",		(unsigned long)(le32toh(scb->sg_list[0].addr)),		(unsigned long)(le32toh(scb->sg_list[0].len)));	printf("	cdb:%x %x %x %x %x %x %x %x %x %x %x %x\n",		hscb->cmdstore[0], hscb->cmdstore[1], hscb->cmdstore[2],		hscb->cmdstore[3], hscb->cmdstore[4], hscb->cmdstore[5],		hscb->cmdstore[6], hscb->cmdstore[7], hscb->cmdstore[8],		hscb->cmdstore[9], hscb->cmdstore[10], hscb->cmdstore[11]);}#endifstatic struct {        u_int8_t errno;	char *errmesg;} hard_error[] = {	{ ILLHADDR,	"Illegal Host Access" },	{ ILLSADDR,	"Illegal Sequencer Address referrenced" },	{ ILLOPCODE,	"Illegal Opcode in sequencer program" },	{ SQPARERR,	"Sequencer Parity Error" },	{ DPARERR,	"Data-path Parity Error" },	{ MPARERR,	"Scratch or SCB Memory Parity Error" },	{ PCIERRSTAT,	"PCI Error detected" },	{ CIOPARERR,	"CIOBUS Parity Error" },};static const int num_errors = sizeof(hard_error)/sizeof(hard_error[0]);static struct {        u_int8_t phase;        u_int8_t mesg_out; /* Message response to parity errors */	char *phasemsg;} phase_table[] = {	{ P_DATAOUT,	MSG_NOOP,		"in Data-out phase"	},	{ P_DATAIN,	MSG_INITIATOR_DET_ERR,	"in Data-in phase"	},	{ P_COMMAND,	MSG_NOOP,		"in Command phase"	},	{ P_MESGOUT,	MSG_NOOP,		"in Message-out phase"	},	{ P_STATUS,	MSG_INITIATOR_DET_ERR,	"in Status phase"	},	{ P_MESGIN,	MSG_PARITY_ERROR,	"in Message-in phase"	},	{ P_BUSFREE,	MSG_NOOP,		"while idle"		},	{ 0,		MSG_NOOP,		"in unknown phase"	}};static const int num_phases = (sizeof(phase_table)/sizeof(phase_table[0])) - 1;/* * Valid SCSIRATE values.  (p. 3-17) * Provides a mapping of tranfer periods in ns to the proper value to * stick in the scsiscfr reg to use that transfer rate. */#define AHC_SYNCRATE_DT		0#define AHC_SYNCRATE_ULTRA2	1#define AHC_SYNCRATE_ULTRA	3#define AHC_SYNCRATE_FAST	6static struct ahc_syncrate ahc_syncrates[] = {      /* ultra2    fast/ultra  period     rate */	{ 0x42,      0x000,      9,      "80.0" },	{ 0x03,      0x000,     10,      "40.0" },	{ 0x04,      0x000,     11,      "33.0" },	{ 0x05,      0x100,     12,      "20.0" },	{ 0x06,      0x110,     15,      "16.0" },	{ 0x07,      0x120,     18,      "13.4" },	{ 0x08,      0x000,     25,      "10.0" },	{ 0x19,      0x010,     31,      "8.0"  },	{ 0x1a,      0x020,     37,      "6.67" },	{ 0x1b,      0x030,     43,      "5.7"  },	{ 0x1c,      0x040,     50,      "5.0"  },	{ 0x00,      0x050,     56,      "4.4"  },	{ 0x00,      0x060,     62,      "4.0"  },	{ 0x00,      0x070,     68,      "3.6"  },	{ 0x00,      0x000,      0,      NULL   }};/* * Allocate a controller structure for a new device and initialize it. * ahc_reset should be called before now since we assume that the card * is paused. */voidahc_construct(ahc, iot, ioh, chip, flags, features, channel)	struct  ahc_softc *ahc;	bus_space_tag_t iot;	bus_space_handle_t ioh;	ahc_chip chip;	ahc_flag flags;	ahc_feature features;	u_char channel;{	/*	 * find unit and check we have that many defined	 */	LIST_INIT(&ahc->pending_scbs);	ahc->sc_iot = iot;	ahc->sc_ioh = ioh;	ahc->chip = chip;	ahc->flags = flags;	ahc->features = features;	ahc->channel = channel;	ahc->scb_data = NULL;	ahc->pci_intr_func = NULL;	ahc->unpause = (ahc_inb(ahc, HCNTRL) & IRQMS) | INTEN;	/* The IRQMS bit is only valid on VL and EISA chips */	if ((ahc->chip & AHC_PCI) != 0)		ahc->unpause &= ~IRQMS;	ahc->pause = ahc->unpause | PAUSE;}voidahc_free(ahc)	struct ahc_softc *ahc;{	ahcfiniscbdata(ahc);	if (ahc->init_level != 0)		ahc_freedmamem(ahc->sc_dmat, ahc->shared_data_size,		    ahc->shared_data_dmamap, ahc->qoutfifo,		    &ahc->shared_data_seg, ahc->shared_data_nseg);	if (ahc->scb_data != NULL)		free(ahc->scb_data, M_DEVBUF);	if (ahc->pci_data != NULL)		free(ahc->pci_data, M_DEVBUF);	return;}STATIC intahcinitscbdata(ahc)	struct ahc_softc *ahc;{	struct scb_data *scb_data;	int i;		scb_data = ahc->scb_data;	SLIST_INIT(&scb_data->free_scbs);	SLIST_INIT(&scb_data->sg_maps);	/* Allocate SCB resources */	scb_data->scbarray =	    (struct scb *)malloc(sizeof(struct scb) * AHC_SCB_MAX,				 M_DEVBUF, M_NOWAIT);	if (scb_data->scbarray == NULL)		return (ENOMEM);	bzero(scb_data->scbarray, sizeof(struct scb) * AHC_SCB_MAX);	/* Determine the number of hardware SCBs and initialize them */	scb_data->maxhscbs = ahc_probe_scbs(ahc);	/* SCB 0 heads the free list */	ahc_outb(ahc, FREE_SCBH, 0);	for (i = 0; i < ahc->scb_data->maxhscbs; i++) {		ahc_outb(ahc, SCBPTR, i);		/* Clear the control byte. */		ahc_outb(ahc, SCB_CONTROL, 0);		/* Set the next pointer */		ahc_outb(ahc, SCB_NEXT, i+1);		/* Make the tag number invalid */		ahc_outb(ahc, SCB_TAG, SCB_LIST_NULL);	}	/* Make sure that the last SCB terminates the free list */	ahc_outb(ahc, SCBPTR, i-1);	ahc_outb(ahc, SCB_NEXT, SCB_LIST_NULL);	/* Ensure we clear the 0 SCB's control byte. */	ahc_outb(ahc, SCBPTR, 0);	ahc_outb(ahc, SCB_CONTROL, 0);	scb_data->maxhscbs = i;	if (ahc->scb_data->maxhscbs == 0)		panic("%s: No SCB space found", ahc_name(ahc));	/*	 * Create our DMA tags.  These tags define the kinds of device	 * accessable memory allocations and memory mappings we will	 * need to perform during normal operation.	 *	 * Unless we need to further restrict the allocation, we rely	 * on the restrictions of the parent dmat, hence the common	 * use of MAXADDR and MAXSIZE.	 */	if (ahc_createdmamem(ahc,	    AHC_SCB_MAX * sizeof(struct hardware_scb), 	    &scb_data->hscb_dmamap, (caddr_t *)&scb_data->hscbs, 	    &scb_data->hscb_busaddr, &scb_data->hscb_seg,	    &scb_data->hscb_nseg, "hardware SCB structures") < 0)		goto error_exit;	scb_data->init_level++;	if (ahc_createdmamem(ahc,	    AHC_SCB_MAX * sizeof(struct scsi_sense_data),	    &scb_data->sense_dmamap, (caddr_t *)&scb_data->sense,	    &scb_data->sense_busaddr, &scb_data->sense_seg,	    &scb_data->sense_nseg, "sense buffers") < 0)		goto error_exit;	scb_data->init_level++;	/* Perform initial CCB allocation */	bzero(scb_data->hscbs, AHC_SCB_MAX * sizeof(struct hardware_scb));	ahcallocscbs(ahc);	if (scb_data->numscbs == 0) {		printf("%s: ahc_init_scb_data - "		       "Unable to allocate initial scbs\n",		       ahc_name(ahc));		goto error_exit;	}	scb_data->init_level++;	/*	 * Note that we were successfull	 */	return 0; error_exit:	return ENOMEM;}STATIC voidahcfiniscbdata(ahc)	struct ahc_softc *ahc;{	struct scb_data *scb_data;	scb_data = ahc->scb_data;	switch (scb_data->init_level) {	default:	case 3:	{		struct sg_map_node *sg_map;		while ((sg_map = SLIST_FIRST(&scb_data->sg_maps))!= NULL) {			SLIST_REMOVE_HEAD(&scb_data->sg_maps, links);			ahc_freedmamem(ahc->sc_dmat, PAGE_SIZE,			    sg_map->sg_dmamap, (caddr_t)sg_map->sg_vaddr,			    &sg_map->sg_dmasegs, sg_map->sg_nseg);			free(sg_map, M_DEVBUF);		}	}	/*FALLTHROUGH*/	case 2:		ahc_freedmamem(ahc->sc_dmat,		    AHC_SCB_MAX * sizeof(struct scsi_sense_data),		    scb_data->sense_dmamap, (caddr_t)scb_data->sense,		    &scb_data->sense_seg, scb_data->sense_nseg);	/*FALLTHROUGH*/	case 1:		ahc_freedmamem(ahc->sc_dmat,		    AHC_SCB_MAX * sizeof(struct hardware_scb), 		    scb_data->hscb_dmamap, (caddr_t)scb_data->hscbs,		    &scb_data->hscb_seg, scb_data->hscb_nseg);	/*FALLTHROUGH*/	}	if (scb_data->scbarray != NULL)		free(scb_data->scbarray, M_DEVBUF);}voidahc_xxx_reset(devname, iot, ioh)	char *devname;	bus_space_tag_t iot;	bus_space_handle_t ioh;{	u_char hcntrl;	int wait;#ifdef AHC_DUMP_SEQ	ahc_dumpseq(ahc);#endif	/* Retain the IRQ type accross the chip reset */	hcntrl = (bus_space_read_1(iot, ioh, HCNTRL) & IRQMS) | INTEN;	bus_space_write_1(iot, ioh, HCNTRL, CHIPRST | PAUSE);	/*	 * Ensure that the reset has finished	 */	wait = 1000;	while (--wait && !(bus_space_read_1(iot, ioh, HCNTRL) & CHIPRSTACK))		DELAY(1000);	if (wait == 0) {		printf("%s: WARNING - Failed chip reset!  "				 "Trying to initialize anyway.\n", devname);	}	bus_space_write_1(iot, ioh, HCNTRL, hcntrl | PAUSE);}intahc_reset(ahc)	struct ahc_softc *ahc;{	u_int	sblkctl;	int	wait;	#ifdef AHC_DUMP_SEQ	if (ahc->init_level == 0)		ahc_dumpseq(ahc);#endif	ahc_outb(ahc, HCNTRL, CHIPRST | ahc->pause);	/*	 * Ensure that the reset has finished	 */	wait = 1000;	do {		DELAY(1000);	} while (--wait && !(ahc_inb(ahc, HCNTRL) & CHIPRSTACK));	if (wait == 0) {		printf("%s: WARNING - Failed chip reset!  "		       "Trying to initialize anyway.\n", ahc_name(ahc));	}	ahc_outb(ahc, HCNTRL, ahc->pause);	/* Determine channel configuration */	sblkctl = ahc_inb(ahc, SBLKCTL) & (SELBUSB|SELWIDE);	/* No Twin Channel PCI cards */	if ((ahc->chip & AHC_PCI) != 0)		sblkctl &= ~SELBUSB;	switch (sblkctl) {	case 0:		/* Single Narrow Channel */		break;	case 2:		/* Wide Channel */		ahc->features |= AHC_WIDE;		break;	case 8:		/* Twin Channel */		ahc->features |= AHC_TWIN;		break;	default:		printf(" Unsupported adapter type.  Ignoring\n");		return(-1);	}	return (0);}/* * Called when we have an active connection to a target on the bus, * this function finds the nearest syncrate to the input period limited * by the capabilities of the bus connectivity of the target. */STATIC struct ahc_syncrate *ahc_devlimited_syncrate(ahc, period)	struct ahc_softc *ahc;	u_int *period;{	u_int	maxsync;	if ((ahc->features & AHC_ULTRA2) != 0) {		if ((ahc_inb(ahc, SBLKCTL) & ENAB40) != 0		 && (ahc_inb(ahc, SSTAT2) & EXP_ACTIVE) == 0) {			maxsync = AHC_SYNCRATE_ULTRA2;		} else {			maxsync = AHC_SYNCRATE_ULTRA;		}	} else if ((ahc->features & AHC_ULTRA) != 0) {		maxsync = AHC_SYNCRATE_ULTRA;	} else {		maxsync = AHC_SYNCRATE_FAST;	}	return (ahc_find_syncrate(ahc, period, maxsync));}/* * Look up the valid period to SCSIRATE conversion in our table. * Return the period and offset that should be sent to the target * if this was the beginning of an SDTR. */STATIC struct ahc_syncrate *ahc_find_syncrate(ahc, period, maxsync)	struct ahc_softc *ahc;	u_int *period;	u_int maxsync;{	struct ahc_syncrate *syncrate;	syncrate = &ahc_syncrates[maxsync];	while ((syncrate->rate != NULL)	    && ((ahc->features & AHC_ULTRA2) == 0	     || (syncrate->sxfr_u2 != 0))) {		if (*period <= syncrate->period) {			/*			 * When responding to a target that requests			 * sync, the requested rate may fall between			 * two rates that we can output, but still be			 * a rate that we can receive.  Because of this,			 * we want to respond to the target with			 * the same rate that it sent to us even			 * if the period we use to send data to it			 * is lower.  Only lower the response period			 * if we must.			 */			if (syncrate == &ahc_syncrates[maxsync])				*period = syncrate->period;			break;		}		syncrate++;	}	if ((*period == 0)	 || (syncrate->rate == NULL)	 || ((ahc->features & AHC_ULTRA2) != 0	  && (syncrate->sxfr_u2 == 0))) {		/* Use asynchronous transfers. */		*period = 0;		syncrate = NULL;	}	return (syncrate);}STATIC u_intahc_find_period(ahc, scsirate, maxsync)	struct ahc_softc *ahc;	u_int scsirate;	u_int maxsync;{	struct ahc_syncrate *syncrate;	if ((ahc->features & AHC_ULTRA2) != 0)		scsirate &= SXFR_ULTRA2;	else		scsirate &= SXFR;	syncrate = &ahc_syncrates[maxsync];	while (syncrate->rate != NULL) {		if ((ahc->features & AHC_ULTRA2) != 0) {			if (syncrate->sxfr_u2 == 0)				break;			else if (scsirate == (syncrate->sxfr_u2 & SXFR_ULTRA2))				return (syncrate->period);		} else if (scsirate == (syncrate->sxfr & SXFR)) {				return (syncrate->period);		}		syncrate++;	}	return (0); /* async */}STATIC voidahc_validate_offset(ahc, syncrate, offset, wide)	struct ahc_softc *ahc;	struct ahc_syncrate *syncrate;	u_int *offset;	int wide;{	u_int maxoffset;	/* Limit offset to what we can do */	if (syncrate == NULL) {		maxoffset = 0;	} else if ((ahc->features & AHC_ULTRA2) != 0) {		maxoffset = MAX_OFFSET_ULTRA2;	} else {		if (wide)			maxoffset = MAX_OFFSET_16BIT;		else			maxoffset = MAX_OFFSET_8BIT;	}	*offset = MIN(*offset, maxoffset);}STATIC voidahc_update_target_msg_request(ahc, devinfo, tinfo, force, paused)	struct ahc_softc *ahc;	struct ahc_devinfo *devinfo;	struct ahc_initiator_tinfo *tinfo;	int force;	int paused;{	u_int targ_msg_req_orig;	targ_msg_req_orig = ahc->targ_msg_req;	if (tinfo->current.period != tinfo->goal.period	    || tinfo->current.width != tinfo->goal.width	    || tinfo->current.offset != tinfo->goal.offset	    || (force && (tinfo->goal.period != 0	    || tinfo->goal.width != MSG_EXT_WDTR_BUS_8_BIT)))		ahc->targ_msg_req |= devinfo->target_mask;	else		ahc->targ_msg_req &= ~devinfo->target_mask;	if (ahc->targ_msg_req != targ_msg_req_orig) {		/* Update the message request bit for this target */		if ((ahc->features & AHC_HS_MAILBOX) != 0) {			if (paused) {				ahc_outb(ahc, TARGET_MSG_REQUEST,					 ahc->targ_msg_req & 0xFF);				ahc_outb(ahc, TARGET_MSG_REQUEST + 1,					 (ahc->targ_msg_req >> 8) & 0xFF);			} else {				ahc_outb(ahc, HS_MAILBOX,					 0x01 << HOST_MAILBOX_SHIFT);			}		} else {			if (!paused)				pause_sequencer(ahc);			ahc_outb(ahc, TARGET_MSG_REQUEST,				 ahc->targ_msg_req & 0xFF);			ahc_outb(ahc, TARGET_MSG_REQUEST + 1,				 (ahc->targ_msg_req >> 8) & 0xFF);			if (!paused)				unpause_sequencer(ahc);		}	}}STATIC voidahc_set_syncrate(ahc, devinfo, syncrate, period, offset, type, paused, done)	struct ahc_softc *ahc;	struct ahc_devinfo *devinfo;	struct ahc_syncrate *syncrate;	u_int period;	u_int offset;	u_int type;	int paused;	int done;{	struct	ahc_initiator_tinfo *tinfo;	struct	tmode_tstate *tstate;	u_int	old_period;	u_int	old_offset;	int	active = (type & AHC_TRANS_ACTIVE) == AHC_TRANS_ACTIVE;	if (syncrate == NULL) {		period = 0;		offset = 0;	}	tinfo = ahc_fetch_transinfo(ahc, devinfo->channel,				    devinfo->our_scsiid,				    devinfo->target, &tstate);	old_period = tinfo->current.period;	old_offset = tinfo->current.offset;	if ((type & AHC_TRANS_CUR) != 0	 && (old_period != period || old_offset != offset)) {		u_int	scsirate;		scsirate = tinfo->scsirate;		if ((ahc->features & AHC_ULTRA2) != 0) {			/* XXX */			/* Force single edge until DT is fully implemented */			scsirate &= ~(SXFR_ULTRA2|SINGLE_EDGE|ENABLE_CRC);			if (syncrate != NULL)				scsirate |= syncrate->sxfr_u2|SINGLE_EDGE;			if (active)				ahc_outb(ahc, SCSIOFFSET, offset);		} else {			scsirate &= ~(SXFR|SOFS);			/*			 * Ensure Ultra mode is set properly for			 * this target.			 */			tstate->ultraenb &= ~devinfo->target_mask;			if (syncrate != NULL) {				if (syncrate->sxfr & ULTRA_SXFR) {					tstate->ultraenb |=						devinfo->target_mask;				}				scsirate |= syncrate->sxfr & SXFR;				scsirate |= offset & SOFS;			}			if (active) {				u_int sxfrctl0;				sxfrctl0 = ahc_inb(ahc, SXFRCTL0);				sxfrctl0 &= ~FAST20;				if (tstate->ultraenb & devinfo->target_mask)					sxfrctl0 |= FAST20;				ahc_outb(ahc, SXFRCTL0, sxfrctl0);			}		}		if (active)			ahc_outb(ahc, SCSIRATE, scsirate);		tinfo->scsirate = scsirate;		tinfo->current.period = period;		tinfo->current.offset = offset;		/* Update the syncrates in any pending scbs */		ahc_update_pending_syncrates(ahc);	}	/*	 * Print messages if we're verbose and at the end of a negotiation	 * cycle.	 */	if (done) {		if (offset != 0) {			printf("%s: target %d synchronous at %sMHz, "			       "offset = 0x%x\n", ahc_name(ahc),			       devinfo->target, syncrate->rate, offset);		} else {			printf("%s: target %d using "			       "asynchronous transfers\n",			       ahc_name(ahc), devinfo->target);		}	}	if ((type & AHC_TRANS_GOAL) != 0) {		tinfo->goal.period = period;		tinfo->goal.offset = offset;	}	if ((type & AHC_TRANS_USER) != 0) {		tinfo->user.period = period;		tinfo->user.offset = offset;	}	ahc_update_target_msg_request(ahc, devinfo, tinfo,				      /*force*/FALSE,				      paused);}STATIC voidahc_set_width(ahc, devinfo, width, type, paused, done)	struct ahc_softc *ahc;	struct ahc_devinfo *devinfo;	u_int width;	u_int type;	int paused;	int done;{	struct ahc_initiator_tinfo *tinfo;	struct tmode_tstate *tstate;	u_int  oldwidth;	int    active = (type & AHC_TRANS_ACTIVE) == AHC_TRANS_ACTIVE;	tinfo = ahc_fetch_transinfo(ahc, devinfo->channel,				    devinfo->our_scsiid,				    devinfo->target,				    &tstate);	oldwidth = tinfo->current.width;	if ((type & AHC_TRANS_CUR) != 0 && oldwidth != width) {		u_int	scsirate;		scsirate =  tinfo->scsirate;		scsirate &= ~WIDEXFER;		if (width == MSG_EXT_WDTR_BUS_16_BIT)			scsirate |= WIDEXFER;		tinfo->scsirate = scsirate;		if (active)			ahc_outb(ahc, SCSIRATE, scsirate);		tinfo->current.width = width;	}	if (done) {		printf("%s: target %d using %dbit transfers\n",		       ahc_name(ahc), devinfo->target,		       8 * (0x01 << width));	}	if ((type & AHC_TRANS_GOAL) != 0)		tinfo->goal.width = width;	if ((type & AHC_TRANS_USER) != 0)		tinfo->user.width = width;	ahc_update_target_msg_request(ahc, devinfo, tinfo,				      /*force*/FALSE, paused);}STATIC voidahc_set_tags(ahc, devinfo, enable)	struct ahc_softc *ahc;	struct ahc_devinfo *devinfo;	int enable;{	struct ahc_initiator_tinfo *tinfo;	struct tmode_tstate *tstate;	tinfo = ahc_fetch_transinfo(ahc, devinfo->channel,				    devinfo->our_scsiid,				    devinfo->target,				    &tstate);	if (enable)		tstate->tagenable |= devinfo->target_mask;	else {		tstate->tagenable &= ~devinfo->target_mask;		tstate->tagdisable |= devinfo->target_mask;	}}/* * Attach all the sub-devices we can find */intahc_attach(ahc)	struct ahc_softc *ahc;{	/*	 * Initialize the software queue.	 */	LIST_INIT(&ahc->sc_xxxq);#ifdef AHC_BROKEN_CACHE	if (cpu_class == CPUCLASS_386)	/* doesn't have "wbinvd" instruction */		ahc_broken_cache = 0;#endif	/*	 * fill in the prototype scsi_links.	 */	ahc->sc_link.adapter_target = ahc->our_id;	if (ahc->features & AHC_WIDE)		ahc->sc_link.adapter_buswidth = 16;	ahc->sc_link.adapter_softc = ahc;	ahc->sc_link.adapter = &ahc_switch;	ahc->sc_link.openings = 2;	ahc->sc_link.device = &ahc_dev;	ahc->sc_link.flags = SCSIDEBUG_LEVEL;		if (ahc->features & AHC_TWIN) {		/* Configure the second scsi bus */		ahc->sc_link_b = ahc->sc_link;		ahc->sc_link_b.adapter_target = ahc->our_id_b;		if (ahc->features & AHC_WIDE)			ahc->sc_link.adapter_buswidth = 16;	}	/*	 * ask the adapter what subunits are present	 */	if ((ahc->flags & AHC_CHANNEL_B_PRIMARY) == 0) {		/* make IS_SCSIBUS_B() == false, while probing channel A */		ahc->sc_link_b.scsibus = 0xff;		config_found((void *)ahc, &ahc->sc_link, scsiprint);		if (ahc->features & AHC_TWIN)			config_found((void *)ahc, &ahc->sc_link_b, scsiprint);	} else {		/*		 * if implementation of IS_SCSIBUS_B() is changed to use		 * ahc->sc_link.scsibus, then "ahc->sc_link.scsibus = 0xff;"		 * is needed, here.		 */		/* assert(ahc->features & AHC_TWIN); */		config_found((void *)ahc, &ahc->sc_link_b, scsiprint);		config_found((void *)ahc, &ahc->sc_link, scsiprint);	}	return 1;}STATIC voidahc_fetch_devinfo(ahc, devinfo)	struct ahc_softc *ahc;	struct ahc_devinfo *devinfo;{	u_int	saved_tcl;	role_t	role;	int	our_id;	if (ahc_inb(ahc, SSTAT0) & TARGET)		role = ROLE_TARGET;	else		role = ROLE_INITIATOR;	if (role == ROLE_TARGET	 && (ahc->features & AHC_MULTI_TID) != 0	 && (ahc_inb(ahc, SEQ_FLAGS) & CMDPHASE_PENDING) != 0) {		/* We were selected, so pull our id from TARGIDIN */		our_id = ahc_inb(ahc, TARGIDIN) & OID;	} else if ((ahc->features & AHC_ULTRA2) != 0)		our_id = ahc_inb(ahc, SCSIID_ULTRA2) & OID;	else		our_id = ahc_inb(ahc, SCSIID) & OID;	saved_tcl = ahc_inb(ahc, SAVED_TCL);	ahc_compile_devinfo(devinfo, our_id, TCL_TARGET(saved_tcl),			    TCL_LUN(saved_tcl), TCL_CHANNEL(ahc, saved_tcl),			    role);}STATIC voidahc_compile_devinfo(devinfo, our_id, target, lun, channel, role)	struct ahc_devinfo *devinfo;	u_int our_id;	u_int target;	u_int lun;	char channel;	role_t role;{	devinfo->our_scsiid = our_id;	devinfo->target = target;	devinfo->lun = lun;	devinfo->target_offset = target;	devinfo->channel = channel;	devinfo->role = role;	if (channel == 'B')		devinfo->target_offset += 8;	devinfo->target_mask = (0x01 << devinfo->target_offset);}/* * Catch an interrupt from the adapter */intahc_intr(void *arg){	struct	ahc_softc *ahc;	u_int	intstat;	ahc = (struct ahc_softc *)arg; 	intstat = ahc_inb(ahc, INTSTAT);	/*	 * Any interrupts to process?	 */	if ((intstat & INT_PEND) == 0) {		if (ahc->pci_intr_func && ahc->pci_intr_func(ahc)) {#ifdef AHC_DEBUG			printf("%s: bus intr: CCHADDR %x HADDR %x SEQADDR %x\n",			    ahc_name(ahc),			    ahc_inb(ahc, CCHADDR) |			    (ahc_inb(ahc, CCHADDR+1) << 8)			    | (ahc_inb(ahc, CCHADDR+2) << 16)			    | (ahc_inb(ahc, CCHADDR+3) << 24),			    ahc_inb(ahc, HADDR) | (ahc_inb(ahc, HADDR+1) << 8)			    | (ahc_inb(ahc, HADDR+2) << 16)			    | (ahc_inb(ahc, HADDR+3) << 24),			    ahc_inb(ahc, SEQADDR0) |			    (ahc_inb(ahc, SEQADDR1) << 8));#endif			return 1;		}		return 0;	}	if (intstat & CMDCMPLT) {		ahc_outb(ahc, CLRINT, CLRCMDINT);		ahc_run_qoutfifo(ahc);	}	if (intstat & BRKADRINT) {		/*		 * We upset the sequencer :-(		 * Lookup the error message		 */		int i, error, num_errors;		error = ahc_inb(ahc, ERROR);		num_errors =  sizeof(hard_error)/sizeof(hard_error[0]);		for (i = 0; error != 1 && i < num_errors; i++)			error >>= 1;		panic("%s: brkadrint, %s at seqaddr = 0x%x\n",		      ahc_name(ahc), hard_error[i].errmesg,		      ahc_inb(ahc, SEQADDR0) |		      (ahc_inb(ahc, SEQADDR1) << 8));		/* Tell everyone that this HBA is no longer availible */		ahc_abort_scbs(ahc, ALL_TARGETS, ALL_CHANNELS,			       ALL_LUNS, SCB_LIST_NULL, ROLE_UNKNOWN,			       XS_DRIVER_STUFFUP);	}	if (intstat & SEQINT)		ahc_handle_seqint(ahc, intstat);	if (intstat & SCSIINT)		ahc_handle_scsiint(ahc, intstat);	return(1);}STATIC struct tmode_tstate *ahc_alloc_tstate(ahc, scsi_id, channel)	struct ahc_softc *ahc;	u_int scsi_id;	char channel;{	struct tmode_tstate *master_tstate;	struct tmode_tstate *tstate;	int i, s;	master_tstate = ahc->enabled_targets[ahc->our_id];	if (channel == 'B') {		scsi_id += 8;		master_tstate = ahc->enabled_targets[ahc->our_id_b + 8];	}	if (ahc->enabled_targets[scsi_id] != NULL	 && ahc->enabled_targets[scsi_id] != master_tstate)		panic("%s: ahc_alloc_tstate - Target already allocated",		      ahc_name(ahc));	tstate = malloc(sizeof(*tstate), M_DEVBUF, M_NOWAIT);	if (tstate == NULL)		return (NULL);	/*	 * If we have allocated a master tstate, copy user settings from	 * the master tstate (taken from SRAM or the EEPROM) for this	 * channel, but reset our current and goal settings to async/narrow	 * until an initiator talks to us.	 */	if (master_tstate != NULL) {		bcopy(master_tstate, tstate, sizeof(*tstate));		tstate->ultraenb = 0;		for (i = 0; i < 16; i++) {			bzero(&tstate->transinfo[i].current,			      sizeof(tstate->transinfo[i].current));			bzero(&tstate->transinfo[i].goal,			      sizeof(tstate->transinfo[i].goal));		}	} else		bzero(tstate, sizeof(*tstate));	s = splbio();	ahc->enabled_targets[scsi_id] = tstate;	splx(s);	return (tstate);}STATIC voidahc_handle_seqint(ahc, intstat)	struct ahc_softc *ahc;	u_int intstat;{	struct scb *scb;	struct ahc_devinfo devinfo;		ahc_fetch_devinfo(ahc, &devinfo);	/*	 * Clear the upper byte that holds SEQINT status	 * codes and clear the SEQINT bit. We will unpause	 * the sequencer, if appropriate, after servicing	 * the request.	 */	ahc_outb(ahc, CLRINT, CLRSEQINT);	switch (intstat & SEQINT_MASK) {	case NO_MATCH:	{		/* Ensure we don't leave the selection hardware on */		ahc_outb(ahc, SCSISEQ,			 ahc_inb(ahc, SCSISEQ) & (ENSELI|ENRSELI|ENAUTOATNP));		printf("%s:%c:%d: no active SCB for reconnecting "		       "target - issuing BUS DEVICE RESET\n",		       ahc_name(ahc), devinfo.channel, devinfo.target);		printf("SAVED_TCL == 0x%x, ARG_1 == 0x%x, SEQ_FLAGS == 0x%x\n",		       ahc_inb(ahc, SAVED_TCL), ahc_inb(ahc, ARG_1),		       ahc_inb(ahc, SEQ_FLAGS));		ahc->msgout_buf[0] = MSG_BUS_DEV_RESET;		ahc->msgout_len = 1;		ahc->msgout_index = 0;		ahc->msg_type = MSG_TYPE_INITIATOR_MSGOUT;		ahc_outb(ahc, MSG_OUT, HOST_MSG);		ahc_outb(ahc, SCSISIGO, ahc_inb(ahc, LASTPHASE) | ATNO);		break;	}	case UPDATE_TMSG_REQ:		ahc_outb(ahc, TARGET_MSG_REQUEST, ahc->targ_msg_req & 0xFF);		ahc_outb(ahc, TARGET_MSG_REQUEST + 1,			 (ahc->targ_msg_req >> 8) & 0xFF);		ahc_outb(ahc, HS_MAILBOX, 0);		break;	case SEND_REJECT: 	{		u_int rejbyte = ahc_inb(ahc, ACCUM);		printf("%s:%c:%d: Warning - unknown message received from "		       "target (0x%x).  Rejecting\n", 		       ahc_name(ahc), devinfo.channel, devinfo.target, rejbyte);		break; 	}	case NO_IDENT: 	{		/*		 * The reconnecting target either did not send an identify		 * message, or did, but we didn't find and SCB to match and		 * before it could respond to our ATN/abort, it hit a dataphase.		 * The only safe thing to do is to blow it away with a bus		 * reset.		 */		int found;		printf("%s:%c:%d: Target did not send an IDENTIFY message. "		       "LASTPHASE = 0x%x, SAVED_TCL == 0x%x\n",		       ahc_name(ahc), devinfo.channel, devinfo.target,		       ahc_inb(ahc, LASTPHASE), ahc_inb(ahc, SAVED_TCL));		found = ahc_reset_channel(ahc, devinfo.channel, 					  /*initiate reset*/TRUE);		printf("%s: Issued Channel %c Bus Reset. "		       "%d SCBs aborted\n", ahc_name(ahc), devinfo.channel,		       found);		return;	}	case BAD_PHASE:	{		u_int lastphase;		lastphase = ahc_inb(ahc, LASTPHASE);		if (lastphase == P_BUSFREE) {			printf("%s:%c:%d: Missed busfree.  Curphase = 0x%x\n",			       ahc_name(ahc), devinfo.channel, devinfo.target,			       ahc_inb(ahc, SCSISIGI));			restart_sequencer(ahc);			return;		} else {			printf("%s:%c:%d: unknown scsi bus phase %x.  "			       "Attempting to continue\n",			       ahc_name(ahc), devinfo.channel, devinfo.target,			       ahc_inb(ahc, SCSISIGI));		}		break; 	}	case BAD_STATUS:	{		u_int  scb_index;		struct hardware_scb *hscb;		struct scsi_xfer *xs;		/*		 * The sequencer will notify us when a command		 * has an error that would be of interest to		 * the kernel.  This allows us to leave the sequencer		 * running in the common case of command completes		 * without error.  The sequencer will already have		 * dma'd the SCB back up to us, so we can reference		 * the in kernel copy directly.		 */		scb_index = ahc_inb(ahc, SCB_TAG);		scb = &ahc->scb_data->scbarray[scb_index];		/*		 * Set the default return value to 0 (don't		 * send sense).  The sense code will change		 * this if needed.		 */		ahc_outb(ahc, RETURN_1, 0);		if (!(scb_index < ahc->scb_data->numscbs		   && (scb->flags & SCB_ACTIVE) != 0)) {			printf("%s:%c:%d: ahc_intr - referenced scb "			       "not valid during seqint 0x%x scb(%d)\n",			       ahc_name(ahc), devinfo.channel,			       devinfo.target, intstat, scb_index);			goto unpause;		}		hscb = scb->hscb; 		xs = scb->xs;		/* Don't want to clobber the original sense code */		if ((scb->flags & SCB_SENSE) != 0) {			/*			 * Clear the SCB_SENSE Flag and have			 * the sequencer do a normal command			 * complete.			 */			scb->flags &= ~SCB_SENSE;			ahcsetccbstatus(xs, XS_DRIVER_STUFFUP);			break;		}		/* Freeze the queue unit the client sees the error. */		ahc_freeze_devq(ahc, xs->sc_link);		ahc_freeze_ccb(scb);		xs->status = hscb->status;		switch (hscb->status) {		case SCSI_OK:			printf("%s: Interrupted for staus of 0???\n",			       ahc_name(ahc));			break;		case SCSI_CHECK:#ifdef AHC_DEBUG			if (ahc_debug & AHC_SHOWSENSE) {				sc_print_addr(scb->xs->sc_link);				printf("SCB %d: requests Check Status\n",				       scb->hscb->tag);			}#endif							if (xs->error == XS_NOERROR &&			    !(scb->flags & SCB_SENSE)) {				struct ahc_dma_seg *sg;				struct scsi_sense *sc;				struct ahc_initiator_tinfo *tinfo;				struct tmode_tstate *tstate;				sg = scb->sg_list;				sc = (struct scsi_sense *)(&hscb->cmdstore); 				/*				 * Save off the residual if there is one.				 */				if (hscb->residual_SG_count != 0)					ahc_calc_residual(scb);				else					xs->resid = 0;#ifdef AHC_DEBUG				if (ahc_debug & AHC_SHOWSENSE) {					sc_print_addr(scb->xs->sc_link);					printf("Sending Sense\n");				}#endif				sg->addr = ahc->scb_data->sense_busaddr +					(hscb->tag*sizeof(struct scsi_sense_data));								sg->len = sizeof(struct scsi_sense_data);				sc->opcode = REQUEST_SENSE;				sc->byte2 =  SCB_LUN(scb) << 5;				sc->unused[0] = 0;				sc->unused[1] = 0;				sc->length = sg->len;				sc->control = 0;				/*				 * Would be nice to preserve DISCENB here,				 * but due to the way we page SCBs, we can't.				 */				hscb->control = 0;				/*				 * This request sense could be because the				 * the device lost power or in some other				 * way has lost our transfer negotiations.				 * Renegotiate if appropriate.				 */				ahc_calc_residual(scb);#ifdef AHC_DEBUG				if (ahc_debug & AHC_SHOWSENSE) {					sc_print_addr(xs->sc_link);					printf("Sense: datalen %d resid %d"					       "chan %d id %d targ %d\n",					       xs->datalen, xs->resid,					       devinfo.channel,					       devinfo.our_scsiid,					       devinfo.target);				}#endif				if (xs->datalen > 0 &&				    xs->resid == xs->datalen) {				tinfo = ahc_fetch_transinfo(ahc,							    devinfo.channel,							    devinfo.our_scsiid,							    devinfo.target,							    &tstate);					ahc_update_target_msg_request(ahc,							      &devinfo,							      tinfo,							      /*force*/TRUE,							      /*paused*/TRUE);				}				hscb->status = 0;				hscb->SG_count = 1;				hscb->SG_pointer = scb->sg_list_phys;				hscb->data = sg->addr; 				hscb->datalen = sg->len;				hscb->cmdpointer = hscb->cmdstore_busaddr;				hscb->cmdlen = sizeof(*sc);				scb->sg_count = hscb->SG_count;				ahc_swap_hscb(hscb);				ahc_swap_sg(scb->sg_list);				scb->flags |= SCB_SENSE;				/*				 * Ensure the target is busy since this				 * will be an untagged request.				 */				ahc_busy_tcl(ahc, scb);				ahc_outb(ahc, RETURN_1, SEND_SENSE);				/*				 * Ensure we have enough time to actually				 * retrieve the sense.				 */				if (!(scb->xs->flags & SCSI_POLL))					timeout_add(&scb->xs->stimeout, 5 * hz);			}			break;		case SCSI_BUSY:			/*			 * Requeue any transactions that haven't been			 * sent yet.			 */			ahc_freeze_devq(ahc, xs->sc_link);			ahc_freeze_ccb(scb);			break;		}		break;	}	case TRACE_POINT:	{		printf("SSTAT2 = 0x%x DFCNTRL = 0x%x\n", ahc_inb(ahc, SSTAT2),		       ahc_inb(ahc, DFCNTRL));		printf("SSTAT3 = 0x%x DSTATUS = 0x%x\n", ahc_inb(ahc, SSTAT3),		       ahc_inb(ahc, DFSTATUS));		printf("SSTAT0 = 0x%x, SCB_DATACNT = 0x%x\n",		       ahc_inb(ahc, SSTAT0),		       ahc_inb(ahc, SCB_DATACNT));		break;	}	case HOST_MSG_LOOP:	{		/*		 * The sequencer has encountered a message phase		 * that requires host assistance for completion.		 * While handling the message phase(s), we will be		 * notified by the sequencer after each byte is		 * transfered so we can track bus phases.		 *		 * If this is the first time we've seen a HOST_MSG_LOOP,		 * initialize the state of the host message loop.		 */		if (ahc->msg_type == MSG_TYPE_NONE) {			u_int bus_phase;			bus_phase = ahc_inb(ahc, SCSISIGI) & PHASE_MASK;			if (bus_phase != P_MESGIN			 && bus_phase != P_MESGOUT) {				printf("ahc_intr: HOST_MSG_LOOP bad "				       "phase 0x%x\n",				      bus_phase);				/*				 * Probably transitioned to bus free before				 * we got here.  Just punt the message.				 */				ahc_clear_intstat(ahc);				restart_sequencer(ahc);			}			if (devinfo.role == ROLE_INITIATOR) {				struct scb *scb;				u_int scb_index;				scb_index = ahc_inb(ahc, SCB_TAG);				scb = &ahc->scb_data->scbarray[scb_index];				if (bus_phase == P_MESGOUT)					ahc_setup_initiator_msgout(ahc,								   &devinfo,								   scb);				else {					ahc->msg_type =					    MSG_TYPE_INITIATOR_MSGIN;					ahc->msgin_index = 0;				}			} else {				if (bus_phase == P_MESGOUT) {					ahc->msg_type =					    MSG_TYPE_TARGET_MSGOUT;					ahc->msgin_index = 0;				} else 					/* XXX Ever executed??? */					ahc_setup_target_msgin(ahc, &devinfo);			}		}		/* Pass a NULL path so that handlers generate their own */		ahc_handle_message_phase(ahc, /*path*/NULL);		break;	}	case PERR_DETECTED:	{		/*		 * If we've cleared the parity error interrupt		 * but the sequencer still believes that SCSIPERR		 * is true, it must be that the parity error is		 * for the currently presented byte on the bus,		 * and we are not in a phase (data-in) where we will		 * eventually ack this byte.  Ack the byte and		 * throw it away in the hope that the target will		 * take us to message out to deliver the appropriate		 * error message.		 */		if ((intstat & SCSIINT) == 0		 && (ahc_inb(ahc, SSTAT1) & SCSIPERR) != 0) {			u_int curphase;			/*			 * The hardware will only let you ack bytes			 * if the expected phase in SCSISIGO matches			 * the current phase.  Make sure this is			 * currently the case.			 */			curphase = ahc_inb(ahc, SCSISIGI) & PHASE_MASK;			ahc_outb(ahc, LASTPHASE, curphase);			ahc_outb(ahc, SCSISIGO, curphase);			ahc_inb(ahc, SCSIDATL);		}		break;	}	case DATA_OVERRUN:	{		/*		 * When the sequencer detects an overrun, it		 * places the controller in "BITBUCKET" mode		 * and allows the target to complete its transfer.		 * Unfortunately, none of the counters get updated		 * when the controller is in this mode, so we have		 * no way of knowing how large the overrun was.		 */		u_int scbindex = ahc_inb(ahc, SCB_TAG);		u_int lastphase = ahc_inb(ahc, LASTPHASE);		int i;		scb = &ahc->scb_data->scbarray[scbindex];		for (i = 0; i < num_phases; i++) {			if (lastphase == phase_table[i].phase)				break;		}		sc_print_addr(scb->xs->sc_link);		printf("data overrun detected %s."		       "  Tag == 0x%x.\n",		       phase_table[i].phasemsg,  		       scb->hscb->tag);		sc_print_addr(scb->xs->sc_link);		printf("%s seen Data Phase.  Length = %d.  NumSGs = %d.\n",		       ahc_inb(ahc, SEQ_FLAGS) & DPHASE ? "Have" : "Haven't",		       scb->xs->datalen, scb->sg_count);		if (scb->sg_count > 0) {			for (i = 0; i < scb->sg_count; i++) {				printf("sg[%d] - Addr 0x%x : Length %d\n",				       i,				       (unsigned int)le32toh(scb->sg_list[i].addr),				       (unsigned int)le32toh(scb->sg_list[i].len));			}		}		/*		 * Set this and it will take affect when the		 * target does a command complete.		 */		ahc_freeze_devq(ahc, scb->xs->sc_link);		ahcsetccbstatus(scb->xs, XS_DRIVER_STUFFUP);		ahc_freeze_ccb(scb);		break;	}	case TRACEPOINT:	{		printf("TRACEPOINT: RETURN_2 = %d\n", ahc_inb(ahc, RETURN_2));#if 0		printf("SSTAT1 == 0x%x\n", ahc_inb(ahc, SSTAT1));		printf("SSTAT0 == 0x%x\n", ahc_inb(ahc, SSTAT0));		printf(", SCSISIGI == 0x%x\n", ahc_inb(ahc, SCSISIGI));		printf("TRACEPOINT: CCHCNT = %d, SG_COUNT = %d\n",		       ahc_inb(ahc, CCHCNT), ahc_inb(ahc, SG_COUNT));		printf("TRACEPOINT: SCB_TAG = %d\n", ahc_inb(ahc, SCB_TAG));		printf("TRACEPOINT1: CCHADDR = %d, CCHCNT = %d, SCBPTR = %d\n",		       ahc_inb(ahc, CCHADDR)		    | (ahc_inb(ahc, CCHADDR+1) << 8)		    | (ahc_inb(ahc, CCHADDR+2) << 16)		    | (ahc_inb(ahc, CCHADDR+3) << 24),		       ahc_inb(ahc, CCHCNT)		    | (ahc_inb(ahc, CCHCNT+1) << 8)		    | (ahc_inb(ahc, CCHCNT+2) << 16),		       ahc_inb(ahc, SCBPTR));		printf("TRACEPOINT: WAITING_SCBH = %d\n", 		       ahc_inb(ahc, WAITING_SCBH));		printf("TRACEPOINT: SCB_TAG = %d\n", ahc_inb(ahc, SCB_TAG));#endif		break;	}#if NOT_YET	/* XXX Fill these in later */	case MESG_BUFFER_BUSY:		break;	case MSGIN_PHASEMIS:		break;#endif	default:		printf("ahc_intr: seqint, "		       "intstat == 0x%x, scsisigi = 0x%x\n",		       intstat, ahc_inb(ahc, SCSISIGI));		break;	}	unpause:	/*	 *  The sequencer is paused immediately on	 *  a SEQINT, so we should restart it when	 *  we're done.	 */	unpause_sequencer(ahc);}STATIC voidahc_handle_scsiint(ahc, intstat)	struct ahc_softc *ahc;	u_int intstat;{	u_int	scb_index;	u_int	status;	struct	scb *scb;	char	cur_channel;	char	intr_channel;	if ((ahc->features & AHC_TWIN) != 0	 && ((ahc_inb(ahc, SBLKCTL) & SELBUSB) != 0))		cur_channel = 'B';	else		cur_channel = 'A';	intr_channel = cur_channel;	status = ahc_inb(ahc, SSTAT1);	if (status == 0) {		if ((ahc->features & AHC_TWIN) != 0) {			/* Try the other channel */		 	ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) ^ SELBUSB);			status = ahc_inb(ahc, SSTAT1);		 	ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) ^ SELBUSB);			intr_channel = (cur_channel == 'A') ? 'B' : 'A';		}		if (status == 0) {			printf("%s: Spurious SCSI interrupt\n", ahc_name(ahc));			return;		}	}	scb_index = ahc_inb(ahc, SCB_TAG);	if (scb_index < ahc->scb_data->numscbs) {		scb = &ahc->scb_data->scbarray[scb_index];		if ((scb->flags & SCB_ACTIVE) == 0		 || (ahc_inb(ahc, SEQ_FLAGS) & IDENTIFY_SEEN) == 0)			scb = NULL;	} else		scb = NULL;	if ((status & SCSIRSTI) != 0) {		printf("%s: Someone reset channel %c\n",			ahc_name(ahc), intr_channel);		ahc_reset_channel(ahc, intr_channel, /* Initiate Reset */FALSE);	} else if ((status & SCSIPERR) != 0) {		/*		 * Determine the bus phase and queue an appropriate message.		 * SCSIPERR is latched true as soon as a parity error		 * occurs.  If the sequencer acked the transfer that		 * caused the parity error and the currently presented		 * transfer on the bus has correct parity, SCSIPERR will		 * be cleared by CLRSCSIPERR.  Use this to determine if		 * we should look at the last phase the sequencer recorded,		 * or the current phase presented on the bus.		 */		u_int mesg_out;		u_int curphase;		u_int errorphase;		u_int lastphase;		int   i;		lastphase = ahc_inb(ahc, LASTPHASE);		curphase = ahc_inb(ahc, SCSISIGI) & PHASE_MASK;		ahc_outb(ahc, CLRSINT1, CLRSCSIPERR);		/*		 * For all phases save DATA, the sequencer won't		 * automatically ack a byte that has a parity error		 * in it.  So the only way that the current phase		 * could be 'data-in' is if the parity error is for		 * an already acked byte in the data phase.  During		 * synchronous data-in transfers, we may actually		 * ack bytes before latching the current phase in		 * LASTPHASE, leading to the discrepancy between		 * curphase and lastphase.		 */		if ((ahc_inb(ahc, SSTAT1) & SCSIPERR) != 0		 || curphase == P_DATAIN)			errorphase = curphase;		else			errorphase = lastphase;		for (i = 0; i < num_phases; i++) {			if (errorphase == phase_table[i].phase)				break;		}		mesg_out = phase_table[i].mesg_out;		if (scb != NULL)			sc_print_addr(scb->xs->sc_link);		else			printf("%s:%c:%d: ", ahc_name(ahc),			       intr_channel,			       TCL_TARGET(ahc_inb(ahc, SAVED_TCL)));				printf("parity error detected %s. "		       "SEQADDR(0x%x) SCSIRATE(0x%x)\n",		       phase_table[i].phasemsg,		       ahc_inb(ahc, SEQADDR0) | (ahc_inb(ahc, SEQADDR1) << 8),		       ahc_inb(ahc, SCSIRATE));		/*		 * We've set the hardware to assert ATN if we   		 * get a parity error on "in" phases, so all we  		 * need to do is stuff the message buffer with		 * the appropriate message.  "In" phases have set		 * mesg_out to something other than MSG_NOP.		 */		if (mesg_out != MSG_NOOP) {			if (ahc->msg_type != MSG_TYPE_NONE)				ahc->send_msg_perror = TRUE;			else				ahc_outb(ahc, MSG_OUT, mesg_out);		}		ahc_outb(ahc, CLRINT, CLRSCSIINT);		unpause_sequencer(ahc);	} else if ((status & BUSFREE) != 0		&& (ahc_inb(ahc, SIMODE1) & ENBUSFREE) != 0) {		/*		 * First look at what phase we were last in.		 * If its message out, chances are pretty good		 * that the busfree was in response to one of		 * our abort requests.		 */		u_int lastphase = ahc_inb(ahc, LASTPHASE);		u_int saved_tcl = ahc_inb(ahc, SAVED_TCL);		u_int target = TCL_TARGET(saved_tcl);		u_int initiator_role_id = TCL_SCSI_ID(ahc, saved_tcl);		char channel = TCL_CHANNEL(ahc, saved_tcl);		int printerror = 1;		ahc_outb(ahc, SCSISEQ,			 ahc_inb(ahc, SCSISEQ) & (ENSELI|ENRSELI|ENAUTOATNP));		if (lastphase == P_MESGOUT) {			u_int message;			u_int tag;			message = ahc->msgout_buf[ahc->msgout_index - 1];			tag = SCB_LIST_NULL;			switch (message) {			case MSG_ABORT_TAG:				tag = scb->hscb->tag;				/* FALLTRHOUGH */			case MSG_ABORT:				sc_print_addr(scb->xs->sc_link);				printf("SCB %d - Abort %s Completed.\n",				       scb->hscb->tag, tag == SCB_LIST_NULL ?				       "" : "Tag");				ahc_abort_scbs(ahc, target, channel,					       TCL_LUN(saved_tcl), tag,					       ROLE_INITIATOR,					       XS_DRIVER_STUFFUP);				printerror = 0;				break;			case MSG_BUS_DEV_RESET:			{				struct ahc_devinfo devinfo;				if (scb != NULL &&				    (scb->xs->flags & SCSI_RESET)				 && ahc_match_scb(scb, target, channel,						  TCL_LUN(saved_tcl),						  SCB_LIST_NULL,						  ROLE_INITIATOR)) {					ahcsetccbstatus(scb->xs, XS_NOERROR);				}				ahc_compile_devinfo(&devinfo,						    initiator_role_id,						    target,						    TCL_LUN(saved_tcl),						    channel,						    ROLE_INITIATOR);				ahc_handle_devreset(ahc, &devinfo,						    XS_RESET,						    "Bus Device Reset",						    /*verbose_level*/0);				printerror = 0;				break;			}			default:				break;			}		}		if (printerror != 0) {			int i;			if (scb != NULL) {				u_int tag;				if ((scb->hscb->control & TAG_ENB) != 0)					tag = scb->hscb->tag;				else					tag = SCB_LIST_NULL;				ahc_abort_scbs(ahc, target, channel,					       SCB_LUN(scb), tag,					       ROLE_INITIATOR,					       XS_DRIVER_STUFFUP);				sc_print_addr(scb->xs->sc_link);			} else {				/*				 * We had not fully identified this connection,				 * so we cannot abort anything.				 */				printf("%s: ", ahc_name(ahc));			}			for (i = 0; i < num_phases; i++) {				if (lastphase == phase_table[i].phase)					break;			}			printf("Unexpected busfree %s\n"			       "SEQADDR == 0x%x\n",			       phase_table[i].phasemsg, ahc_inb(ahc, SEQADDR0)				| (ahc_inb(ahc, SEQADDR1) << 8));		}		ahc_clear_msg_state(ahc);		ahc_outb(ahc, SIMODE1, ahc_inb(ahc, SIMODE1) & ~ENBUSFREE);		ahc_outb(ahc, CLRSINT1, CLRBUSFREE|CLRSCSIPERR);		ahc_outb(ahc, CLRINT, CLRSCSIINT);		restart_sequencer(ahc);	} else if ((status & SELTO) != 0) {		u_int scbptr;		scbptr = ahc_inb(ahc, WAITING_SCBH);		ahc_outb(ahc, SCBPTR, scbptr);		scb_index = ahc_inb(ahc, SCB_TAG);		if (scb_index < ahc->scb_data->numscbs) {			scb = &ahc->scb_data->scbarray[scb_index];			if ((scb->flags & SCB_ACTIVE) == 0)				scb = NULL;		} else			scb = NULL;		if (scb == NULL) {			printf("%s: ahc_intr - referenced scb not "			       "valid during SELTO scb(%d, %d)\n",			       ahc_name(ahc), scbptr, scb_index);		} else {			u_int tag;			tag = SCB_LIST_NULL;			if ((scb->hscb->control & MSG_SIMPLE_Q_TAG) != 0)				tag = scb->hscb->tag;			ahc_abort_scbs(ahc, SCB_TARGET(scb), SCB_CHANNEL(scb),				       SCB_LUN(scb), tag,				       ROLE_INITIATOR, XS_SELTIMEOUT);		}		/* Stop the selection */		ahc_outb(ahc, SCSISEQ, 0);		/* No more pending messages */		ahc_clear_msg_state(ahc);		/*		 * Although the driver does not care about the		 * 'Selection in Progress' status bit, the busy		 * LED does.  SELINGO is only cleared by a sucessful		 * selection, so we must manually clear it to ensure		 * the LED turns off just incase no future successful		 * selections occur (e.g. no devices on the bus).		 */		ahc_outb(ahc, CLRSINT0, CLRSELINGO);		/* Clear interrupt state */		ahc_outb(ahc, CLRSINT1, CLRSELTIMEO|CLRBUSFREE|CLRSCSIPERR);		ahc_outb(ahc, CLRINT, CLRSCSIINT);		restart_sequencer(ahc);	} else {		sc_print_addr(scb->xs->sc_link);		printf("Unknown SCSIINT. Status = 0x%x\n", status);		ahc_outb(ahc, CLRSINT1, status);		ahc_outb(ahc, CLRINT, CLRSCSIINT);		unpause_sequencer(ahc);	}}STATIC voidahc_build_transfer_msg(ahc, devinfo)	struct ahc_softc *ahc;	struct ahc_devinfo *devinfo;{	/*	 * We need to initiate transfer negotiations.	 * If our current and goal settings are identical,	 * we want to renegotiate due to a check condition.	 */	struct	ahc_initiator_tinfo *tinfo;	struct	tmode_tstate *tstate;	int	dowide;	int	dosync;	tinfo = ahc_fetch_transinfo(ahc, devinfo->channel,				    devinfo->our_scsiid,				    devinfo->target, &tstate);	dowide = tinfo->current.width != tinfo->goal.width;	dosync = tinfo->current.period != tinfo->goal.period;	if (!dowide && !dosync) {		dowide = tinfo->goal.width != MSG_EXT_WDTR_BUS_8_BIT;		dosync = tinfo->goal.period != 0;	}	if (dowide) {		ahc_construct_wdtr(ahc, tinfo->goal.width);	} else if (dosync) {		struct	ahc_syncrate *rate;		u_int	period;		u_int	offset;		period = tinfo->goal.period;		rate = ahc_devlimited_syncrate(ahc, &period);		offset = tinfo->goal.offset;		ahc_validate_offset(ahc, rate, &offset,				    tinfo->current.width);		ahc_construct_sdtr(ahc, period, offset);	} else {		panic("ahc_intr: AWAITING_MSG for negotiation, "		      "but no negotiation needed\n");		}}STATIC voidahc_setup_initiator_msgout(ahc, devinfo, scb)	struct ahc_softc *ahc;	struct ahc_devinfo *devinfo;	struct scb *scb;{	/*              	 * To facilitate adding multiple messages together,	 * each routine should increment the index and len	 * variables instead of setting them explicitly.	 */             	ahc->msgout_index = 0;	ahc->msgout_len = 0;	if ((scb->flags & SCB_DEVICE_RESET) == 0	 && ahc_inb(ahc, MSG_OUT) == MSG_IDENTIFYFLAG) {		u_int identify_msg;		identify_msg = MSG_IDENTIFYFLAG | SCB_LUN(scb);		if ((scb->hscb->control & DISCENB) != 0)			identify_msg |= MSG_IDENTIFY_DISCFLAG;		ahc->msgout_buf[ahc->msgout_index++] = identify_msg;		ahc->msgout_len++;		if ((scb->hscb->control & TAG_ENB) != 0) {			/* XXX fvdl FreeBSD has tag action passed down */			ahc->msgout_buf[ahc->msgout_index++] = MSG_SIMPLE_Q_TAG;			ahc->msgout_buf[ahc->msgout_index++] = scb->hscb->tag;			ahc->msgout_len += 2;		}	}	if (scb->flags & SCB_DEVICE_RESET) {		ahc->msgout_buf[ahc->msgout_index++] = MSG_BUS_DEV_RESET;		ahc->msgout_len++;				sc_print_addr(scb->xs->sc_link);		printf("Bus Device Reset Message Sent\n");	} else if (scb->flags & SCB_ABORT) {		if ((scb->hscb->control & TAG_ENB) != 0)			ahc->msgout_buf[ahc->msgout_index++] = MSG_ABORT_TAG;		else			ahc->msgout_buf[ahc->msgout_index++] = MSG_ABORT;		ahc->msgout_len++;		sc_print_addr(scb->xs->sc_link);		printf("Abort Message Sent\n");	} else if ((ahc->targ_msg_req & devinfo->target_mask) != 0) {		ahc_build_transfer_msg(ahc, devinfo);	} else {		printf("ahc_intr: AWAITING_MSG for an SCB that "		       "does not have a waiting message");		panic("SCB = %d, SCB Control = %x, MSG_OUT = %x "		      "SCB flags = %x", scb->hscb->tag, scb->hscb->control,		      ahc_inb(ahc, MSG_OUT), scb->flags);	}	/*	 * Clear the MK_MESSAGE flag from the SCB so we aren't	 * asked to send this message again.	 */	ahc_outb(ahc, SCB_CONTROL, ahc_inb(ahc, SCB_CONTROL) & ~MK_MESSAGE);	ahc->msgout_index = 0;	ahc->msg_type = MSG_TYPE_INITIATOR_MSGOUT;}STATIC voidahc_setup_target_msgin(ahc, devinfo)	struct ahc_softc *ahc;	struct ahc_devinfo *devinfo;{	/*              	 * To facilitate adding multiple messages together,	 * each routine should increment the index and len	 * variables instead of setting them explicitly.	 */             	ahc->msgout_index = 0;	ahc->msgout_len = 0;	if ((ahc->targ_msg_req & devinfo->target_mask) != 0)		ahc_build_transfer_msg(ahc, devinfo);	else		panic("ahc_intr: AWAITING target message with no message");	ahc->msgout_index = 0;	ahc->msg_type = MSG_TYPE_TARGET_MSGIN;}