ahc_bus_dmamap_sync(ahc->sc_dmat, ahc->shared_data_dmamap,
bus_dmamap_sync(ahc->sc_dmat, ahc->shared_data_dmamap,
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);}