if (hz > 100 && timeout > 1000)
if (timeout > 1000000)
struct ncr53c9x_ecb *ncr53c9x_get_ecb	__P((struct ncr53c9x_softc *, int));static inline int ncr53c9x_stp2cpb	__P((struct ncr53c9x_softc *, int));static inline void ncr53c9x_setsync	__P((struct ncr53c9x_softc *,					    struct ncr53c9x_tinfo *));static struct ncr53c9x_linfo *ncr53c9x_lunsearch __P((struct ncr53c9x_tinfo *,    int64_t lun));static void ncr53c9x_wrfifo(struct ncr53c9x_softc *, u_char *, int);static int ncr53c9x_rdfifo(struct ncr53c9x_softc *, int);#define NCR_RDFIFO_START	0#define NCR_RDFIFO_CONTINUE	1#define NCR_SET_COUNT(sc, size) do {						\			NCR_WRITE_REG((sc), NCR_TCL, (size));			\			NCR_WRITE_REG((sc), NCR_TCM, (size) >> 8);		\			if ((sc->sc_cfg2 & NCRCFG2_FE) ||			\			    (sc->sc_rev == NCR_VARIANT_FAS366)) {		\				NCR_WRITE_REG((sc), NCR_TCH, (size) >> 16);	\			}							\			if (sc->sc_rev == NCR_VARIANT_FAS366) {			\				NCR_WRITE_REG(sc, NCR_RCH, 0);			\			}							\} while (0)static int ecb_pool_initialized = 0;static struct pool ecb_pool;struct cfdriver esp_cd = {	NULL, "esp", DV_DULL};/* * Names for the NCR53c9x variants, correspnding to the variant tags * in ncr53c9xvar.h. */const char *ncr53c9x_variant_names[] = {	"ESP100",	"ESP100A",	"ESP200",	"NCR53C94",	"NCR53C96",	"ESP406",	"FAS408",	"FAS216",	"AM53C974",	"FAS366/HME",};/* * Search linked list for LUN info by LUN id. */static struct ncr53c9x_linfo *ncr53c9x_lunsearch(ti, lun)	struct ncr53c9x_tinfo *ti;	int64_t lun;{	struct ncr53c9x_linfo *li;	LIST_FOREACH(li, &ti->luns, link)	    if (li->lun == lun)		    return (li);	return (NULL);}/* * Attach this instance, and then all the sub-devices */voidncr53c9x_attach(sc, adapter, dev)	struct ncr53c9x_softc *sc;	struct scsi_adapter *adapter;	struct scsi_device *dev;{	timeout_set(&sc->sc_watchdog, ncr53c9x_watch, sc);	/*	 * Allocate SCSI message buffers.	 * Front-ends can override allocation to avoid alignment	 * handling in the DMA engines. Note that that ncr53c9x_msgout()	 * can request a 1 byte DMA transfer.	 */	if (sc->sc_omess == NULL)		sc->sc_omess = malloc(NCR_MAX_MSG_LEN, M_DEVBUF, M_NOWAIT);	if (sc->sc_imess == NULL)		sc->sc_imess = malloc(NCR_MAX_MSG_LEN+1, M_DEVBUF, M_NOWAIT);	if (sc->sc_omess == NULL || sc->sc_imess == NULL) {		printf("out of memory\n");		return;	}	/*	 * Note, the front-end has set us up to print the chip variation.	 */	if (sc->sc_rev >= NCR_VARIANT_MAX) {		printf("\n%s: unknown variant %d, devices not attached\n",		    sc->sc_dev.dv_xname, sc->sc_rev);		return;	}	printf(": %s, %dMHz, SCSI ID %d\n",	    ncr53c9x_variant_names[sc->sc_rev], sc->sc_freq, sc->sc_id);	sc->sc_ccf = FREQTOCCF(sc->sc_freq);	/* The value *must not* be == 1. Make it 2 */	if (sc->sc_ccf == 1)		sc->sc_ccf = 2;	/*	 * The recommended timeout is 250ms. This register is loaded	 * with a value calculated as follows, from the docs:	 *	 *		(timout period) x (CLK frequency)	 *	reg = -------------------------------------	 *		 8192 x (Clock Conversion Factor)	 *	 * Since CCF has a linear relation to CLK, this generally computes	 * to the constant of 153.	 */	sc->sc_timeout = ((250 * 1000) * sc->sc_freq) / (8192 * sc->sc_ccf);	/* CCF register only has 3 bits; 0 is actually 8 */	sc->sc_ccf &= 7;	/* Reset state & bus */	sc->sc_cfflags = sc->sc_dev.dv_cfdata->cf_flags;	sc->sc_state = 0;	ncr53c9x_init(sc, 1);	/*	 * fill in the prototype scsi_link.	 */	sc->sc_link.adapter_softc = sc;	sc->sc_link.adapter_target = sc->sc_id;	sc->sc_link.adapter = adapter;	sc->sc_link.device = dev;	sc->sc_link.openings = 2;	/*	 * Now try to attach all the sub-devices	 */	config_found(&sc->sc_dev, &sc->sc_link, scsiprint);	timeout_add(&sc->sc_watchdog, 60*hz);}/* * This is the generic ncr53c9x reset function. It does not reset the SCSI bus, * only this controller, but kills any on-going commands, and also stops * and resets the DMA. * * After reset, registers are loaded with the defaults from the attach * routine above. */voidncr53c9x_reset(sc)	struct ncr53c9x_softc *sc;{	/* reset DMA first */	NCRDMA_RESET(sc);	/* reset SCSI chip */	NCRCMD(sc, NCRCMD_RSTCHIP);	NCRCMD(sc, NCRCMD_NOP);	DELAY(500);	/* do these backwards, and fall through */	switch (sc->sc_rev) {	case NCR_VARIANT_ESP406:	case NCR_VARIANT_FAS408:		NCR_WRITE_REG(sc, NCR_CFG5, sc->sc_cfg5 | NCRCFG5_SINT);		NCR_WRITE_REG(sc, NCR_CFG4, sc->sc_cfg4);	case NCR_VARIANT_AM53C974:	case NCR_VARIANT_FAS216:	case NCR_VARIANT_NCR53C94:	case NCR_VARIANT_NCR53C96:	case NCR_VARIANT_ESP200:		sc->sc_features |= NCR_F_HASCFG3;		NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3);	case NCR_VARIANT_ESP100A:		sc->sc_features |= NCR_F_SELATN3;		NCR_WRITE_REG(sc, NCR_CFG2, sc->sc_cfg2);	case NCR_VARIANT_ESP100:		NCR_WRITE_REG(sc, NCR_CFG1, sc->sc_cfg1);		NCR_WRITE_REG(sc, NCR_CCF, sc->sc_ccf);		NCR_WRITE_REG(sc, NCR_SYNCOFF, 0);		NCR_WRITE_REG(sc, NCR_TIMEOUT, sc->sc_timeout);		break;	case NCR_VARIANT_FAS366:		sc->sc_features |=		    NCR_F_SELATN3 | NCR_F_HASCFG3 | NCR_F_FASTSCSI;		sc->sc_cfg3 = NCRFASCFG3_FASTCLK | NCRFASCFG3_OBAUTO;		sc->sc_cfg3_fscsi = NCRFASCFG3_FASTSCSI;		NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3);		sc->sc_cfg2 = 0; /* NCRCFG2_HMEFE | NCRCFG2_HME32 */		NCR_WRITE_REG(sc, NCR_CFG2, sc->sc_cfg2);		NCR_WRITE_REG(sc, NCR_CFG1, sc->sc_cfg1);		NCR_WRITE_REG(sc, NCR_CCF, sc->sc_ccf);		NCR_WRITE_REG(sc, NCR_SYNCOFF, 0);		NCR_WRITE_REG(sc, NCR_TIMEOUT, sc->sc_timeout);		break;	default:		printf("%s: unknown revision code, assuming ESP100\n",		    sc->sc_dev.dv_xname);		NCR_WRITE_REG(sc, NCR_CFG1, sc->sc_cfg1);		NCR_WRITE_REG(sc, NCR_CCF, sc->sc_ccf);		NCR_WRITE_REG(sc, NCR_SYNCOFF, 0);		NCR_WRITE_REG(sc, NCR_TIMEOUT, sc->sc_timeout);	}	if (sc->sc_rev == NCR_VARIANT_AM53C974)		NCR_WRITE_REG(sc, NCR_AMDCFG4, sc->sc_cfg4);#if 0	printf("%s: ncr53c9x_reset: revision %d\n",	    sc->sc_dev.dv_xname, sc->sc_rev);	printf("%s: ncr53c9x_reset: cfg1 0x%x, cfg2 0x%x, cfg3 0x%x, ccf 0x%x, timeout 0x%x\n",	    sc->sc_dev.dv_xname,	    sc->sc_cfg1, sc->sc_cfg2, sc->sc_cfg3,	    sc->sc_ccf, sc->sc_timeout);#endif}/* * Reset the SCSI bus, but not the chip */voidncr53c9x_scsi_reset(sc)	struct ncr53c9x_softc *sc;{	(*sc->sc_glue->gl_dma_stop)(sc);	printf("%s: resetting SCSI bus\n", sc->sc_dev.dv_xname);	NCRCMD(sc, NCRCMD_RSTSCSI);}/* * Initialize ncr53c9x state machine */voidncr53c9x_init(sc, doreset)	struct ncr53c9x_softc *sc;	int doreset;{	struct ncr53c9x_ecb *ecb;	struct ncr53c9x_linfo *li;	int r, i;	NCR_TRACE(("[NCR_INIT(%d) %d] ", doreset, sc->sc_state));	if (!ecb_pool_initialized) {		/* All instances share this pool */		pool_init(&ecb_pool, sizeof(struct ncr53c9x_ecb), 0, 0, 0,		    "ncr53c9x_ecb", NULL);		ecb_pool_initialized = 1;	}	if (sc->sc_state == 0) {		/* First time through; initialize. */		TAILQ_INIT(&sc->ready_list);		sc->sc_nexus = NULL;		bzero(sc->sc_tinfo, sizeof(sc->sc_tinfo));		for (r = 0; r < NCR_NTARG; r++) {			LIST_INIT(&sc->sc_tinfo[r].luns);		}	} else {		/* Cancel any active commands. */		sc->sc_state = NCR_CLEANING;		sc->sc_msgify = 0;		if ((ecb = sc->sc_nexus) != NULL) {			ecb->xs->error = XS_TIMEOUT;			ncr53c9x_done(sc, ecb);		}		for (r = 0; r < 8; r++) {			LIST_FOREACH(li, &sc->sc_tinfo[r].luns, link) {				if ((ecb = li->untagged)) {					li->untagged = NULL;					/*					 * XXXXXXX					 * Should we terminate a command					 * that never reached the disk?					 */					li->busy = 0;					ecb->xs->error = XS_TIMEOUT;					ncr53c9x_done(sc, ecb);				}				for (i = 0; i<256; i++)					if ((ecb = li->queued[i])) {						li->queued[i] = NULL;						ecb->xs->error = XS_TIMEOUT;						ncr53c9x_done(sc, ecb);					}				li->used = 0;			}		}	}	/*	 * reset the chip to a known state	 */	ncr53c9x_reset(sc);	sc->sc_phase = sc->sc_prevphase = INVALID_PHASE;	for (r = 0; r < 8; r++) {		struct ncr53c9x_tinfo *ti = &sc->sc_tinfo[r];/* XXX - config flags per target: low bits: no reselect; high bits: no synch */                ti->flags = ((sc->sc_minsync && !(sc->sc_cfflags & (1<<(r+8))))		    ? 0 : T_SYNCHOFF) |		    ((sc->sc_cfflags & (1<<r)) ? T_RSELECTOFF : 0) |		    T_NEED_TO_RESET;#ifdef DEBUG		 if (ncr53c9x_notag)			 ti->flags &= ~T_TAG;#endif 		ti->period = sc->sc_minsync;		ti->offset = 0;		ti->cfg3 = 0;	}	if (doreset) {		sc->sc_state = NCR_SBR;		NCRCMD(sc, NCRCMD_RSTSCSI);	} else {		sc->sc_state = NCR_IDLE;		ncr53c9x_sched(sc);	}}/* * Read the NCR registers, and save their contents for later use. * NCR_STAT, NCR_STEP & NCR_INTR are mostly zeroed out when reading * NCR_INTR - so make sure it is the last read. * * I think that (from reading the docs) most bits in these registers * only make sense when he DMA CSR has an interrupt showing. Call only * if an interrupt is pending. */__inline__ voidncr53c9x_readregs(sc)	struct ncr53c9x_softc *sc;{	sc->sc_espstat = NCR_READ_REG(sc, NCR_STAT);	/* Only the stepo bits are of interest */	sc->sc_espstep = NCR_READ_REG(sc, NCR_STEP) & NCRSTEP_MASK;	if (sc->sc_rev == NCR_VARIANT_FAS366)		sc->sc_espstat2 = NCR_READ_REG(sc, NCR_STAT2);	sc->sc_espintr = NCR_READ_REG(sc, NCR_INTR);	if (sc->sc_glue->gl_clear_latched_intr != NULL)		(*sc->sc_glue->gl_clear_latched_intr)(sc);	/*	 * Determine the SCSI bus phase, return either a real SCSI bus phase	 * or some pseudo phase we use to detect certain exceptions.	 */	sc->sc_phase = (sc->sc_espintr & NCRINTR_DIS)			? /* Disconnected */ BUSFREE_PHASE			: sc->sc_espstat & NCRSTAT_PHASE;	NCR_MISC(("regs[intr=%02x,stat=%02x,step=%02x,stat2=%02x] ",		sc->sc_espintr, sc->sc_espstat, sc->sc_espstep, sc->sc_espstat2));}/* * Convert Synchronous Transfer Period to chip register Clock Per Byte value. */static inline intncr53c9x_stp2cpb(sc, period)	struct ncr53c9x_softc *sc;	int period;{	int v;	v = (sc->sc_freq * period) / 250;	if (ncr53c9x_cpb2stp(sc, v) < period)		/* Correct round-down error */		v++;	return (v);}static inline voidncr53c9x_setsync(sc, ti)	struct ncr53c9x_softc *sc;	struct ncr53c9x_tinfo *ti;{	u_char syncoff, synctp;	u_char cfg3 = sc->sc_cfg3 | ti->cfg3;	if (ti->flags & T_SYNCMODE) {		syncoff = ti->offset;		synctp = ncr53c9x_stp2cpb(sc, ti->period);		if (sc->sc_features & NCR_F_FASTSCSI) {			/*			 * If the period is 200ns or less (ti->period <= 50),			 * put the chip in Fast SCSI mode.			 */			if (ti->period <= 50)				/*				 * There are (at least) 4 variations of the				 * configuration 3 register.  The drive attach				 * routine sets the appropriate bit to put the				 * chip into Fast SCSI mode so that it doesn't				 * have to be figured out here each time.				 */				cfg3 |= (sc->sc_rev == NCR_VARIANT_AM53C974) ?				    NCRAMDCFG3_FSCSI : NCRCFG3_FSCSI;		}		/*		 * Am53c974 requires different SYNCTP values when the		 * FSCSI bit is off.		 */		if (sc->sc_rev == NCR_VARIANT_AM53C974 &&		    (cfg3 & NCRAMDCFG3_FSCSI) == 0)			synctp--;	} else {		syncoff = 0;		synctp = 0;	}	if (sc->sc_features & NCR_F_HASCFG3)		NCR_WRITE_REG(sc, NCR_CFG3, cfg3);	NCR_WRITE_REG(sc, NCR_SYNCOFF, syncoff);	NCR_WRITE_REG(sc, NCR_SYNCTP, synctp);}/* * Send a command to a target, set the driver state to NCR_SELECTING * and let the caller take care of the rest. * * Keeping this as a function allows me to say that this may be done * by DMA instead of programmed I/O soon. */voidncr53c9x_select(sc, ecb)	struct ncr53c9x_softc *sc;	struct ncr53c9x_ecb *ecb;{	struct scsi_link *sc_link = ecb->xs->sc_link;	int target = sc_link->target;	int lun = sc_link->lun;	struct ncr53c9x_tinfo *ti = &sc->sc_tinfo[target];	int tiflags = ti->flags;	u_char *cmd;	int clen;	int selatn3, selatns;	size_t dmasize;	NCR_TRACE(("[ncr53c9x_select(t%d,l%d,cmd:%x,tag%x,%x)] ",		   target, lun, ecb->cmd.cmd.opcode, ecb->tag[0], ecb->tag[1]));	sc->sc_state = NCR_SELECTING;	/*	 * Schedule the timeout now, the first time we will go away	 * expecting to come back due to an interrupt, because it is	 * always possible that the interrupt may never happen.	 */	if ((ecb->xs->flags & SCSI_POLL) == 0) {		int timeout = ecb->timeout;		if (hz > 100 && timeout > 1000)			timeout = (timeout / 1000) * hz;		else			timeout = (timeout * hz) / 1000;		timeout_add(&ecb->to, timeout);	}	/*	 * The docs say the target register is never reset, and I	 * can't think of a better place to set it	 */	if (sc->sc_rev == NCR_VARIANT_FAS366) {		NCRCMD(sc, NCRCMD_FLUSH);		NCR_WRITE_REG(sc, NCR_SELID, target | NCR_BUSID_HME);	} else {		NCR_WRITE_REG(sc, NCR_SELID, target);	}	ncr53c9x_setsync(sc, ti);	if ((ecb->flags & ECB_SENSE) != 0) {		/*		 * For REQUEST SENSE, we should not send an IDENTIFY or		 * otherwise mangle the target.  There should be no MESSAGE IN		 * phase.		 */		if (sc->sc_features & NCR_F_DMASELECT) {			/* setup DMA transfer for command */			dmasize = clen = ecb->clen;			sc->sc_cmdlen = clen;			sc->sc_cmdp = (caddr_t)&ecb->cmd.cmd;			/* Program the SCSI counter */			NCR_SET_COUNT(sc, dmasize);			if (sc->sc_rev != NCR_VARIANT_FAS366)				NCRCMD(sc, NCRCMD_NOP|NCRCMD_DMA);			/* And get the targets attention */			NCRCMD(sc, NCRCMD_SELNATN | NCRCMD_DMA);			NCRDMA_SETUP(sc, &sc->sc_cmdp, &sc->sc_cmdlen, 0, &dmasize);			NCRDMA_GO(sc);		} else {			ncr53c9x_wrfifo(sc, (u_char *)&ecb->cmd.cmd, ecb->clen);			NCRCMD(sc, NCRCMD_SELNATN);		}		return;	}	selatn3 = selatns = 0;	if (ecb->tag[0] != 0) {		if (sc->sc_features & NCR_F_SELATN3)			/* use SELATN3 to send tag messages */			selatn3 = 1;		else			/* We don't have SELATN3; use SELATNS to send tags */			selatns = 1;	}	if (ti->flags & T_NEGOTIATE) {		/* We have to use SELATNS to send sync/wide messages */		selatn3 = 0;		selatns = 1;	}	cmd = (u_char *)&ecb->cmd.cmd;	if (selatn3) {		/* We'll use tags with SELATN3 */		clen = ecb->clen + 3;		cmd -= 3;		cmd[0] = MSG_IDENTIFY(lun, 1);	/* msg[0] */		cmd[1] = ecb->tag[0];		/* msg[1] */		cmd[2] = ecb->tag[1];		/* msg[2] */	} else {		/* We don't have tags, or will send messages with SELATNS */		clen = ecb->clen + 1;		cmd -= 1;		cmd[0] = MSG_IDENTIFY(lun, (tiflags & T_RSELECTOFF) == 0);	}	if ((sc->sc_features & NCR_F_DMASELECT) && !selatns) {		/* setup DMA transfer for command */		dmasize = clen;		sc->sc_cmdlen = clen;		sc->sc_cmdp = cmd;		/* Program the SCSI counter */		NCR_SET_COUNT(sc, dmasize);		/* load the count in */		/* if (sc->sc_rev != NCR_VARIANT_FAS366) */			NCRCMD(sc, NCRCMD_NOP|NCRCMD_DMA);		/* And get the targets attention */		if (selatn3) {			sc->sc_msgout = SEND_TAG;			sc->sc_flags |= NCR_ATN;			NCRCMD(sc, NCRCMD_SELATN3 | NCRCMD_DMA);		} else			NCRCMD(sc, NCRCMD_SELATN | NCRCMD_DMA);		NCRDMA_SETUP(sc, &sc->sc_cmdp, &sc->sc_cmdlen, 0, &dmasize);		NCRDMA_GO(sc);		return;	}	/*	 * Who am I. This is where we tell the target that we are	 * happy for it to disconnect etc.	 */	/* Now get the command into the FIFO */	ncr53c9x_wrfifo(sc, cmd, clen);	/* And get the targets attention */	if (selatns) {		NCR_MISC(("SELATNS \n"));		/* Arbitrate, select and stop after IDENTIFY message */		NCRCMD(sc, NCRCMD_SELATNS);	} else if (selatn3) {		sc->sc_msgout = SEND_TAG;		sc->sc_flags |= NCR_ATN;		NCRCMD(sc, NCRCMD_SELATN3);	} else		NCRCMD(sc, NCRCMD_SELATN);}voidncr53c9x_free_ecb(sc, ecb, flags)	struct ncr53c9x_softc *sc;	struct ncr53c9x_ecb *ecb;	int flags;{	int s;	s = splbio();	ecb->flags = 0;	pool_put(&ecb_pool, (void *)ecb);	splx(s);}struct ncr53c9x_ecb *ncr53c9x_get_ecb(sc, flags)	struct ncr53c9x_softc *sc;	int flags;{	struct ncr53c9x_ecb *ecb;	int s, wait = 0;	if ((curproc != NULL) && ((flags & SCSI_NOSLEEP) == 0))		wait = PR_WAITOK;	s = splbio();	ecb = (struct ncr53c9x_ecb *)pool_get(&ecb_pool, wait);	splx(s);	if (ecb == NULL)		return (NULL);	bzero(ecb, sizeof(*ecb));	timeout_set(&ecb->to, ncr53c9x_timeout, ecb);	ecb->flags |= ECB_ALLOC;	return (ecb);}