⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sd53c8xx.c

📁 著名操作系统Plan 9的第三版的部分核心源代码。现在很难找到了。Plan 9是bell实验室开发的Unix后继者。
💻 C
📖 第 1 页 / 共 4 页
字号:
	else		maxscf = NSCF;	/*	 * search large clock factors first since this should	 * result in more reliable transfers	 */	for (scf = maxscf; scf >= 1; scf--) {		for (xferp = 0; xferp < 8; xferp++) {			unsigned char v = c->synctab[scf - 1][xferp];			if (v == 0)				continue;			if (v >= tpf && v < besttpf) {				besttpf = v;				bestscfi = scf;				bestxferp = xferp;			}		}	}	if (besttpf == 1000)		return 0;	if (scfp)		*scfp = bestscfi;	if (xferpp)		*xferpp = bestxferp;	return besttpf;}static voidsynctabinit(Controller *c){	int scf;	unsigned long scsilimit;	int xferp;	unsigned long cr, sr;	int tpf;	int fast;	int maxscf;	if (c->v->feature & Ultra2)		maxscf = NULTRA2SCF;	else if (c->v->feature & Ultra)		maxscf = NULTRASCF;	else		maxscf = NSCF;	/*	 * for chips with no clock doubler, but Ultra capable (e.g. 860, or interestingly the	 * first spin of the 875), assume 80MHz	 * otherwise use the internal (33 Mhz) or external (40MHz) default	 */	if ((c->v->feature & Ultra) != 0 && (c->v->feature & (ClockDouble | ClockQuad)) == 0)		c->sclk = ULTRA_NOCLOCKDOUBLE_SCLK;	else		c->sclk = SCLK;	/*	 * otherwise, if the chip is Ultra capable, but has a slow(ish) clock,	 * invoke the doubler	 */	if (SCLK <= 40000000) {		if (c->v->feature & ClockDouble) {			c->sclk *= 2;			c->clockmult = 1;		}		else if (c->v->feature & ClockQuad) {			c->sclk *= 4;			c->clockmult = 1;		}		else			c->clockmult = 0;	}	else		c->clockmult = 0;	/* derive CCF from sclk */	/* woebetide anyone with SCLK < 16.7 or > 80MHz */	if (c->sclk <= 25 * MEGA)		c->ccf = 1;	else if (c->sclk <= 3750000)		c->ccf = 2;	else if (c->sclk <= 50 * MEGA)		c->ccf = 3;	else if (c->sclk <= 75 * MEGA)		c->ccf = 4;	else if ((c->v->feature & ClockDouble) && c->sclk <= 80 * MEGA)		c->ccf = 5;	else if ((c->v->feature & ClockQuad) && c->sclk <= 120 * MEGA)		c->ccf = 6;	else if ((c->v->feature & ClockQuad) && c->sclk <= 160 * MEGA)		c->ccf = 7;	for (scf = 1; scf < maxscf; scf++) {		/* check for legal core rate */		/* round up so we run slower for safety */	   	cr = (c->sclk * 2 + cf2[scf] - 1) / cf2[scf];		if (cr <= MAXSYNCCORERATE) {			scsilimit = MAXSYNCSCSIRATE;			fast = 0;		}		else if (cr <= MAXFASTSYNCCORERATE) {			scsilimit = MAXFASTSYNCSCSIRATE;			fast = 1;		}		else if ((c->v->feature & Ultra) && cr <= MAXULTRASYNCCORERATE) {			scsilimit = MAXULTRASYNCSCSIRATE;			fast = 2;		}		else if ((c->v->feature & Ultra2) && cr <= MAXULTRA2SYNCCORERATE) {			scsilimit = MAXULTRA2SYNCSCSIRATE;			fast = 3;		}		else			continue;		for (xferp = 11; xferp >= 4; xferp--) {			int ok;			int tp;			/* calculate scsi rate - round up again */			/* start from sclk for accuracy */			int totaldivide = xferp * cf2[scf];			sr = (c->sclk * 2 + totaldivide - 1) / totaldivide;			if (sr > scsilimit)				break;			/*			 * now work out transfer period			 * round down now so that period is pessimistic			 */			tp = (MEGA * 1000) / sr;			/*			 * bounds check it			 */			if (tp < 25 || tp > 255 * 4)				continue;			/*			 * spot stupid special case for Ultra or Ultra2			 * while working out factor			 */			if (tp == 25)				tpf = 10;			else if (tp == 50)				tpf = 12;			else if (tp < 52)				continue;			else				tpf = tp / 4;			/*			 * now check tpf looks sensible			 * given core rate			 */			switch (fast) {			case 0:				/* scf must be ccf for SCSI 1 */				ok = tpf >= 50 && scf == c->ccf;				break;			case 1:				ok = tpf >= 25 && tpf < 50;				break;			case 2:				/*				 * must use xferp of 4, or 5 at a pinch				 * for an Ultra transfer				 */				ok = xferp <= 5 && tpf >= 12 && tpf < 25;				break;			case 3:				ok = xferp == 4 && (tpf == 10 || tpf == 11);				break;			default:				ok = 0;			}			if (!ok)				continue;			c->synctab[scf - 1][xferp - 4] = tpf;		}	}#ifndef NO_ULTRA2	if (c->v->feature & Ultra2)		tpf = 10;	else#endif	if (c->v->feature & Ultra)		tpf = 12;	else		tpf = 25;	for (; tpf < 256; tpf++) {		if (chooserate(c, tpf, &scf, &xferp) == tpf) {			unsigned tp = tpf == 10 ? 25 : (tpf == 12 ? 50 : tpf * 4);			unsigned long khz = (MEGA + tp - 1) / (tp);			KPRINT("sd53c8xx: tpf=%d scf=%d.%.1d xferp=%d mhz=%ld.%.3ld\n",			    tpf, cf2[scf] / 2, (cf2[scf] & 1) ? 5 : 0,			    xferp + 4, khz / 1000, khz % 1000);			USED(khz);			if (c->tpf == 0)				c->tpf = tpf;	/* note lowest value for controller */		}	}}static voidsynctodsa(Dsa *dsa, Controller *c){/*	KPRINT("synctodsa(dsa=%lux, target=%d, scntl3=%.2lx sxfer=%.2x)\n",	    dsa, dsa->target, c->scntl3[dsa->target], c->sxfer[dsa->target]);*/	dsa->scntl3 = c->scntl3[dsa->target];	dsa->sxfer = c->sxfer[dsa->target];}static voidsetsync(Dsa *dsa, Controller *c, int target, uchar ultra, uchar scf, uchar xferp, uchar reqack){	c->scntl3[target] =	    (c->scntl3[target] & 0x08) | (((scf << 4) | c->ccf | (ultra << 7)) & ~0x08);	c->sxfer[target] = (xferp << 5) | reqack;	c->s[target] = BothDone;	if (dsa) {		synctodsa(dsa, c);		c->n->scntl3 = c->scntl3[target];		c->n->sxfer = c->sxfer[target];	}}static voidsetasync(Dsa *dsa, Controller *c, int target){	setsync(dsa, c, target, 0, c->ccf, 0, 0);}static voidsetwide(Dsa *dsa, Controller *c, int target, uchar wide){	c->scntl3[target] = wide ? (1 << 3) : 0;	setasync(dsa, c, target);	c->s[target] = WideDone;}static intbuildsdtrmsg(uchar *buf, uchar tpf, uchar offset){	*buf++ = X_MSG;	*buf++ = 3;	*buf++ = X_MSG_SDTR;	*buf++ = tpf;	*buf = offset;	return 5;}static intbuildwdtrmsg(uchar *buf, uchar expo){	*buf++ = X_MSG;	*buf++ = 2;	*buf++ = X_MSG_WDTR;	*buf = expo;	return 4;}static voidstart(Controller *c, long entry){	ulong p;	if (c->running)		panic("sd53c8xx: start called while running");	c->running = 1;	p = c->scriptpa + entry;	lesetl(c->n->dsp, p);	if (c->ssm)		c->n->dcntl |= 0x4;		/* start DMA in SSI mode */}static voidncrcontinue(Controller *c){	if (c->running)		panic("sd53c8xx: ncrcontinue called while running");	/* set the start DMA bit to continue execution */	c->running = 1;	c->n->dcntl |= 0x4;}static voidsoftreset(Controller *c){	Ncr *n = c->n;	n->istat = Srst;		/* software reset */	n->istat = 0;	/* general initialisation */	n->scid = (1 << 6) | 7;		/* respond to reselect, ID 7 */	n->respid = 1 << 7;		/* response ID = 7 */#ifdef INTERNAL_SCLK	n->stest1 = 0x80;		/* disable external scsi clock */#else	n->stest1 = 0x00;#endif	n->stime0 = 0xdd;		/* about 0.5 second timeout on each device */	n->scntl0 |= 0x8;		/* Enable parity checking */	/* continued setup */	n->sien0 = 0x8f;	n->sien1 = 0x04;	n->dien = 0x7d;	n->stest3 = 0x80;		/* TolerANT enable */	c->running = 0;	if (c->v->feature & BigFifo)		n->ctest5 = (1 << 5);	n->dmode = c->v->burst << 6;	/* set burst length bits */	if (c->v->burst & 4)		n->ctest5 |= (1 << 2);	/* including overflow into ctest5 bit 2 */	if (c->v->feature & Prefetch)		n->dcntl |= (1 << 5);	/* prefetch enable */	else if (c->v->feature & BurstOpCodeFetch)		n->dmode |= (1 << 1);	/* burst opcode fetch */	if (c->v->feature & Differential) {		/* chip capable */		if ((c->feature & Differential) || (n->gpreg & 0x8) == 0) {			/* user enabled, or bit 3 of GPREG clear (Symbios cards) */			if (n->sstat2 & (1 << 2))				print("sd53c8xx: can't go differential; wrong cable\n");			else {				n->stest2 = (1 << 5);				print("sd53c8xx: differential mode set\n");			}		}	}	if (c->clockmult) {		n->stest1 |= (1 << 3);	/* power up doubler */		delay(2);		n->stest3 |= (1 << 5);	/* stop clock */		n->stest1 |= (1 << 2);	/* enable doubler */		n->stest3 &= ~(1 << 5);	/* start clock */		/* pray */	}}static voidmsgsm(Dsa *dsa, Controller *c, int msg, int *cont, int *wakeme){	uchar histpf, hisreqack;	int tpf;	int scf, xferp;	int len;	Ncr *n = c->n;	switch (c->s[dsa->target]) {	case SyncInit:		switch (msg) {		case A_SIR_MSG_SDTR:			/* reply to my SDTR */			histpf = n->scratcha[2];			hisreqack = n->scratcha[3];			KPRINT("sd53c8xx: %d: SDTN response %d %d\n",			    dsa->target, histpf, hisreqack);			if (hisreqack == 0)				setasync(dsa, c, dsa->target);			else {				/* hisreqack should be <= c->v->maxsyncoff */				tpf = chooserate(c, histpf, &scf, &xferp);				KPRINT("sd53c8xx: %d: SDTN: using %d %d\n",				    dsa->target, tpf, hisreqack);				setsync(dsa, c, dsa->target, tpf < 25, scf, xferp, hisreqack);			}			*cont = -2;			return;		case A_SIR_EV_PHASE_SWITCH_AFTER_ID:			/* target ignored ATN for message after IDENTIFY - not SCSI-II */			KPRINT("sd53c8xx: %d: illegal phase switch after ID message - SCSI-1 device?\n", dsa->target);			KPRINT("sd53c8xx: %d: SDTN: async\n", dsa->target);			setasync(dsa, c, dsa->target);			*cont = E_to_decisions;			return;		case A_SIR_MSG_REJECT:			/* rejection of my SDTR */			KPRINT("sd53c8xx: %d: SDTN: rejected SDTR\n", dsa->target);		//async:			KPRINT("sd53c8xx: %d: SDTN: async\n", dsa->target);			setasync(dsa, c, dsa->target);			*cont = -2;			return;		}		break;	case WideInit:		switch (msg) {		case A_SIR_MSG_WDTR:			/* reply to my WDTR */			KPRINT("sd53c8xx: %d: WDTN: response %d\n",			    dsa->target, n->scratcha[2]);			setwide(dsa, c, dsa->target, n->scratcha[2]);			*cont = -2;			return;		case A_SIR_EV_PHASE_SWITCH_AFTER_ID:			/* target ignored ATN for message after IDENTIFY - not SCSI-II */			KPRINT("sd53c8xx: %d: illegal phase switch after ID message - SCSI-1 device?\n", dsa->target);			setwide(dsa, c, dsa->target, 0);			*cont = E_to_decisions;			return;		case A_SIR_MSG_REJECT:			/* rejection of my SDTR */			KPRINT("sd53c8xx: %d: WDTN: rejected WDTR\n", dsa->target);			setwide(dsa, c, dsa->target, 0);			*cont = -2;			return;		}		break;	case NeitherDone:	case WideDone:	case BothDone:		switch (msg) {		case A_SIR_MSG_WDTR: {			uchar hiswide, mywide;			hiswide = n->scratcha[2];			mywide = (c->v->feature & Wide) != 0;			KPRINT("sd53c8xx: %d: WDTN: target init %d\n",			    dsa->target, hiswide);			if (hiswide < mywide)				mywide = hiswide;			KPRINT("sd53c8xx: %d: WDTN: responding %d\n",			    dsa->target, mywide);			setwide(dsa, c, dsa->target, mywide);			len = buildwdtrmsg(dsa->msg_out, mywide);			setmovedata(&dsa->msg_out_buf, DMASEG(dsa->msg_out), len);			*cont = E_response;			c->s[dsa->target] = WideResponse;			return;		}		case A_SIR_MSG_SDTR:#ifdef ASYNC_ONLY			*cont = E_reject;			return;#else			/* target decides to renegotiate */			histpf = n->scratcha[2];			hisreqack = n->scratcha[3];			KPRINT("sd53c8xx: %d: SDTN: target init %d %d\n",			    dsa->target, histpf, hisreqack);			if (hisreqack == 0) {				/* he wants asynchronous */				setasync(dsa, c, dsa->target);				tpf = 0;			}			else {				/* he wants synchronous */				tpf = chooserate(c, histpf, &scf, &xferp);				if (hisreqack > c->v->maxsyncoff)					hisreqack = c->v->maxsyncoff;				KPRINT("sd53c8xx: %d: using %d %d\n",				    dsa->target, tpf, hisreqack);				setsync(dsa, c, dsa->target, tpf < 25, scf, xferp, hisreqack);			}			/* build my SDTR message */			len = buildsdtrmsg(dsa->msg_out, tpf, hisreqack);			setmovedata(&dsa->msg_out_buf, DMASEG(dsa->msg_out), len);			*cont = E_response;			c->s[dsa->target] = SyncResponse;			return;#endif		}		break;	case WideResponse:		switch (msg) {		case A_SIR_EV_RESPONSE_OK:			c->s[dsa->target] = WideDone;			KPRINT("sd53c8xx: %d: WDTN: response accepted\n", dsa->target);			*cont = -2;			return;		case A_SIR_MSG_REJECT:			setwide(dsa, c, dsa->target, 0);			KPRINT("sd53c8xx: %d: WDTN: response REJECTed\n", dsa->target);			*cont = -2;			return;		}		break;	case SyncResponse:		switch (msg) {		case A_SIR_EV_RESPONSE_OK:			c->s[dsa->target] = BothDone;			KPRINT("sd53c8xx: %d: SDTN: response accepted (%s)\n",			    dsa->target, phase[n->sstat1 & 7]);			*cont = -2;			return;	/* chf */		case A_SIR_MSG_REJECT:			setasync(dsa, c, dsa->target);			KPRINT("sd53c8xx: %d: SDTN: response REJECTed\n", dsa->target);			*cont = -2;			return;		}		break;	}	KPRINT("sd53c8xx: %d: msgsm: state %d msg %d\n",	    dsa->target, c->s[dsa->target], msg);	*wakeme = 1;	return;}static voidcalcblockdma(Dsa *d, ulong base, ulong count){	ulong blocks;	if (DEBUG(3))		blocks = 0;	else {		blocks = count / A_BSIZE;		if (blocks > 255)			blocks = 255;	}	d->dmablks = blocks;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -