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

📄 sd53c8xx.c

📁 著名操作系统Plan 9的第三版的部分核心源代码。现在很难找到了。Plan 9是bell实验室开发的Unix后继者。
💻 C
📖 第 1 页 / 共 4 页
字号:
	d->dmaaddr[0] = base;	d->dmaaddr[1] = base >> 8;	d->dmaaddr[2] = base >> 16;	d->dmaaddr[3] = base >> 24;	setmovedata(&d->data_buf, base + blocks * A_BSIZE, count - blocks * A_BSIZE);	if (legetl(d->data_buf.dbc) == 0)		d->flag = 1;}static ulongread_mismatch_recover(Controller *c, Ncr *n, Dsa *dsa){	ulong dbc;	uchar dfifo = n->dfifo;	int inchip;	dbc = (n->dbc[2]<<16)|(n->dbc[1]<<8)|n->dbc[0];	if (n->ctest5 & (1 << 5))		inchip = ((dfifo | ((n->ctest5 & 3) << 8)) - (dbc & 0x3ff)) & 0x3ff;	else		inchip = ((dfifo & 0x7f) - (dbc & 0x7f)) & 0x7f;	if (inchip) {		IPRINT("sd53c8xx: %d/%d: read_mismatch_recover: DMA FIFO = %d\n",		    dsa->target, dsa->lun, inchip);	}	if (n->sxfer & 0xf) {		/* SCSI FIFO */		uchar fifo = n->sstat1 >> 4;		if (c->v->maxsyncoff > 8)			fifo |= (n->sstat2 & (1 << 4));		if (fifo) {			inchip += fifo;			IPRINT("sd53c8xx: %d/%d: read_mismatch_recover: SCSI FIFO = %d\n",			    dsa->target, dsa->lun, fifo);		}	}	else {		if (n->sstat0 & (1 << 7)) {			inchip++;			IPRINT("sd53c8xx: %d/%d: read_mismatch_recover: SIDL full\n",			    dsa->target, dsa->lun);		}		if (n->sstat2 & (1 << 7)) {			inchip++;			IPRINT("sd53c8xx: %d/%d: read_mismatch_recover: SIDL msb full\n",			    dsa->target, dsa->lun);		}	}	USED(inchip);	return dbc;}static ulongwrite_mismatch_recover(Ncr *n, Dsa *dsa){	ulong dbc;	uchar dfifo = n->dfifo;	int inchip;	dbc = (n->dbc[2]<<16)|(n->dbc[1]<<8)|n->dbc[0];	USED(dsa);	if (n->ctest5 & (1 << 5))		inchip = ((dfifo | ((n->ctest5 & 3) << 8)) - (dbc & 0x3ff)) & 0x3ff;	else		inchip = ((dfifo & 0x7f) - (dbc & 0x7f)) & 0x7f;#ifdef WMR_DEBUG	if (inchip) {		IPRINT("sd53c8xx: %d/%d: write_mismatch_recover: DMA FIFO = %d\n",		    dsa->target, dsa->lun, inchip);	}#endif	if (n->sstat0 & (1 << 5)) {		inchip++;#ifdef WMR_DEBUG		IPRINT("sd53c8xx: %d/%d: write_mismatch_recover: SODL full\n", dsa->target, dsa->lun);#endif	}	if (n->sstat2 & (1 << 5)) {		inchip++;#ifdef WMR_DEBUG		IPRINT("sd53c8xx: %d/%d: write_mismatch_recover: SODL msb full\n", dsa->target, dsa->lun);#endif	}	if (n->sxfer & 0xf) {		/* synchronous SODR */		if (n->sstat0 & (1 << 6)) {			inchip++;#ifdef WMR_DEBUG			IPRINT("sd53c8xx: %d/%d: write_mismatch_recover: SODR full\n",			    dsa->target, dsa->lun);#endif		}		if (n->sstat2 & (1 << 6)) {			inchip++;#ifdef WMR_DEBUG			IPRINT("sd53c8xx: %d/%d: write_mismatch_recover: SODR msb full\n",			    dsa->target, dsa->lun);#endif		}	}	/* clear the dma fifo */	n->ctest3 |= (1 << 2);	/* wait till done */	while ((n->dstat & Dfe) == 0)		;	return dbc + inchip;}static voidinterrupt(Ureg *ur, void *a){	uchar istat;	ushort sist;	uchar dstat;	int wakeme = 0;	int cont = -1;	Dsa *dsa;	Controller *c = a;	Ncr *n = c->n;	USED(ur);	if (DEBUG(1))		IPRINT("sd53c8xx: int\n");	ilock(c);	istat = n->istat;	if (istat & Intf) {		Dsa *d;		int wokesomething = 0;		if (DEBUG(1))			IPRINT("sd53c8xx: Intfly\n");		n->istat = Intf;		/* search for structures in A_STATE_DONE */		for (d = KPTR(legetl(c->dsalist.head)); d; d = KPTR(legetl(d->next))) {			if (d->stateb == A_STATE_DONE) {				d->p9status = d->status;				if (DEBUG(1))					IPRINT("sd53c8xx: waking up dsa %lux\n", d);				wakeup(d);				wokesomething = 1;			}		}		if (!wokesomething)			IPRINT("sd53c8xx: nothing to wake up\n");	}	if ((istat & (Sip | Dip)) == 0) {		if (DEBUG(1))			IPRINT("sd53c8xx: int end %x\n", istat);		iunlock(c);		return;	}	sist = (n->sist1<<8)|n->sist0;	/* BUG? can two-byte read be inconsistent? */	dstat = n->dstat;	dsa = (Dsa *)DMASEG_TO_KADDR(legetl(n->dsa));	c->running = 0;	if (istat & Sip) {		if (DEBUG(1))			IPRINT("sist = %.4x\n", sist);		if (sist & 0x80) {			ulong addr;			ulong sa;			ulong dbc;			ulong tbc;			int dmablks;			ulong dmaaddr;			addr = legetl(n->dsp);			sa = addr - c->scriptpa;			if (DEBUG(1) || DEBUG(2))				IPRINT("sd53c8xx: %d/%d: Phase Mismatch sa=%.8lux\n",				    dsa->target, dsa->lun, sa);			/*			 * now recover			 */			if (sa == E_data_in_mismatch) {				dbc = read_mismatch_recover(c, n, dsa);				tbc = legetl(dsa->data_buf.dbc) - dbc;				advancedata(&dsa->data_buf, tbc);				if (DEBUG(1) || DEBUG(2))					IPRINT("sd53c8xx: %d/%d: transferred = %ld residue = %ld\n",					    dsa->target, dsa->lun, tbc, legetl(dsa->data_buf.dbc));				cont = E_to_decisions;			}			else if (sa == E_data_in_block_mismatch) {				dbc = read_mismatch_recover(c, n, dsa);				tbc = A_BSIZE - dbc;				/* recover current state from registers */				dmablks = n->scratcha[2];				dmaaddr = legetl(n->scratchb);				/* we have got to dmaaddr + tbc */				/* we have dmablks * A_BSIZE - tbc + residue left to do */				/* so remaining transfer is */				IPRINT("in_block_mismatch: dmaaddr = 0x%lux tbc=%lud dmablks=%d\n",				    dmaaddr, tbc, dmablks);				calcblockdma(dsa, dmaaddr + tbc,				    dmablks * A_BSIZE - tbc + legetl(dsa->data_buf.dbc));				/* copy changes into scratch registers */				IPRINT("recalc: dmablks %d dmaaddr 0x%lx pa 0x%lx dbc %ld\n",				    dsa->dmablks, legetl(dsa->dmaaddr),				    legetl(dsa->data_buf.pa), legetl(dsa->data_buf.dbc));				n->scratcha[2] = dsa->dmablks;				lesetl(n->scratchb, dsa->dmancr);				cont = E_data_block_mismatch_recover;			}			else if (sa == E_data_out_mismatch) {				dbc = write_mismatch_recover(n, dsa);				tbc = legetl(dsa->data_buf.dbc) - dbc;				advancedata(&dsa->data_buf, tbc);				if (DEBUG(1) || DEBUG(2))					IPRINT("sd53c8xx: %d/%d: transferred = %ld residue = %ld\n",					    dsa->target, dsa->lun, tbc, legetl(dsa->data_buf.dbc));				cont = E_to_decisions;			}			else if (sa == E_data_out_block_mismatch) {				dbc = write_mismatch_recover(n, dsa);				tbc = legetl(dsa->data_buf.dbc) - dbc;				/* recover current state from registers */				dmablks = n->scratcha[2];				dmaaddr = legetl(n->scratchb);				/* we have got to dmaaddr + tbc */				/* we have dmablks blocks - tbc + residue left to do */				/* so remaining transfer is */				IPRINT("out_block_mismatch: dmaaddr = %lux tbc=%lud dmablks=%d\n",				    dmaaddr, tbc, dmablks);				calcblockdma(dsa, dmaaddr + tbc,				    dmablks * A_BSIZE - tbc + legetl(dsa->data_buf.dbc));				/* copy changes into scratch registers */				n->scratcha[2] = dsa->dmablks;				lesetl(n->scratchb, dsa->dmancr);				cont = E_data_block_mismatch_recover;			}			else if (sa == E_id_out_mismatch) {				/*				 * target switched phases while attention held during				 * message out. The possibilities are:				 * 1. It didn't like the last message. This is indicated				 *    by the new phase being message_in. Use script to recover				 *				 * 2. It's not SCSI-II compliant. The new phase will be other				 *    than message_in. We should also indicate that the device				 *    is asynchronous, if it's the SDTR that got ignored				 * 				 * For now, if the phase switch is not to message_in, and				 * and it happens after IDENTIFY and before SDTR, we				 * notify the negotiation state machine.				 */				ulong lim = legetl(dsa->msg_out_buf.dbc);				uchar p = n->sstat1 & 7;				dbc = write_mismatch_recover(n, dsa);				tbc = lim - dbc;				IPRINT("sd53c8xx: %d/%d: msg_out_mismatch: %lud/%lud sent, phase %s\n",				    dsa->target, dsa->lun, tbc, lim, phase[p]);				if (p != MessageIn && tbc == 1) {					msgsm(dsa, c, A_SIR_EV_PHASE_SWITCH_AFTER_ID, &cont, &wakeme);				}				else					cont = E_id_out_mismatch_recover;			}			else if (sa == E_cmd_out_mismatch) {				/*				 * probably the command count is longer than the device wants ...				 */				ulong lim = legetl(dsa->cmd_buf.dbc);				uchar p = n->sstat1 & 7;				dbc = write_mismatch_recover(n, dsa);				tbc = lim - dbc;				IPRINT("sd53c8xx: %d/%d: cmd_out_mismatch: %lud/%lud sent, phase %s\n",				    dsa->target, dsa->lun, tbc, lim, phase[p]);				USED(p, tbc);				cont = E_to_decisions;			}			else {				IPRINT("sd53c8xx: %d/%d: ma sa=%.8lux wanted=%s got=%s\n",				    dsa->target, dsa->lun, sa,				    phase[n->dcmd & 7],				    phase[n->sstat1 & 7]);				dumpncrregs(c, 1);				dsa->p9status = SDeio;	/* chf */				wakeme = 1;			}		}		/*else*/ if (sist & 0x400) {			if (DEBUG(0))				IPRINT("sd53c8xx: %d/%d Sto\n", dsa->target, dsa->lun);			dsa->p9status = SDtimeout;			dsa->stateb = A_STATE_DONE;			softreset(c);			cont = E_issue_check;			wakeme = 1;		}		if (sist & 0x1) {			IPRINT("sd53c8xx: %d/%d: parity error\n", dsa->target, dsa->lun);			dsa->parityerror = 1;		}		if (sist & 0x4) {			IPRINT("sd53c8xx: %d/%d: unexpected disconnect\n",			    dsa->target, dsa->lun);			dumpncrregs(c, 1);			//wakeme = 1;			dsa->p9status = SDeio;		}	}	if (istat & Dip) {		if (DEBUG(1))			IPRINT("dstat = %.2x\n", dstat);		/*else*/ if (dstat & Ssi) {			ulong *p = DMASEG_TO_KADDR(legetl(n->dsp));			ulong w = (uchar *)p - (uchar *)c->script;			IPRINT("[%lux]", w);			USED(w);			cont = -2;	/* restart */		}		if (dstat & Sir) {			switch (legetl(n->dsps)) {			case A_SIR_MSG_IO_COMPLETE:				dsa->p9status = dsa->status;				wakeme = 1;				break;			case A_SIR_MSG_SDTR:			case A_SIR_MSG_WDTR:			case A_SIR_MSG_REJECT:			case A_SIR_EV_RESPONSE_OK:				msgsm(dsa, c, legetl(n->dsps), &cont, &wakeme);				break;			case A_SIR_MSG_IGNORE_WIDE_RESIDUE:				/* back up one in the data transfer */				IPRINT("sd53c8xx: %d/%d: ignore wide residue %d, WSR = %d\n",				    dsa->target, dsa->lun, n->scratcha[1], n->scntl2 & 1);				if (dsa->dmablks == 0 && dsa->flag)					IPRINT("sd53c8xx: %d/%d: transfer over; residue ignored\n",					    dsa->target, dsa->lun);				else					calcblockdma(dsa, legetl(dsa->dmaaddr) - 1,					    dsa->dmablks * A_BSIZE + legetl(dsa->data_buf.dbc) + 1);				cont = -2;				break;			case A_SIR_ERROR_NOT_MSG_IN_AFTER_RESELECT:				IPRINT("sd53c8xx: %d: not msg_in after reselect (%s)",				    n->ssid & 7, phase[n->sstat1 & 7]);				dsa = dsafind(c, n->ssid & 7, -1, A_STATE_DISCONNECTED);				dumpncrregs(c, 1);				wakeme = 1;				break;			case A_SIR_NOTIFY_MSG_IN:				IPRINT("sd53c8xx: %d/%d: msg_in %d\n",				    dsa->target, dsa->lun, n->sfbr);				cont = -2;				break;			case A_SIR_NOTIFY_DISC:				IPRINT("sd53c8xx: %d/%d: disconnect:", dsa->target, dsa->lun);				goto dsadump;			case A_SIR_NOTIFY_STATUS:				IPRINT("sd53c8xx: %d/%d: status\n", dsa->target, dsa->lun);				cont = -2;				break;			case A_SIR_NOTIFY_COMMAND:				IPRINT("sd53c8xx: %d/%d: commands\n", dsa->target, dsa->lun);				cont = -2;				break;			case A_SIR_NOTIFY_DATA_IN:				IPRINT("sd53c8xx: %d/%d: data in a %lx b %lx\n",				    dsa->target, dsa->lun, legetl(n->scratcha), legetl(n->scratchb));				cont = -2;				break;			case A_SIR_NOTIFY_BLOCK_DATA_IN:				IPRINT("sd53c8xx: %d/%d: block data in: a2 %x b %lx\n",				    dsa->target, dsa->lun, n->scratcha[2], legetl(n->scratchb));				cont = -2;				break;			case A_SIR_NOTIFY_DATA_OUT:				IPRINT("sd53c8xx: %d/%d: data out\n", dsa->target, dsa->lun);				cont = -2;				break;			case A_SIR_NOTIFY_DUMP:				IPRINT("sd53c8xx: %d/%d: dump\n", dsa->target, dsa->lun);				dumpncrregs(c, 1);				cont = -2;				break;			case A_SIR_NOTIFY_DUMP2:				IPRINT("sd53c8xx: %d/%d: dump2:", dsa->target, dsa->lun);				IPRINT(" sa %lux", legetl(n->dsp) - c->scriptpa);				IPRINT(" dsa %lux", legetl(n->dsa));				IPRINT(" sfbr %ux", n->sfbr);				IPRINT(" a %lux", n->scratcha);				IPRINT(" b %lux", legetl(n->scratchb));				IPRINT(" ssid %ux", n->ssid);				IPRINT("\n");				cont = -2;				break;			case A_SIR_NOTIFY_WAIT_RESELECT:				IPRINT("sd53c8xx: wait reselect\n");				cont = -2;				break;			case A_SIR_NOTIFY_RESELECT:				IPRINT("sd53c8xx: reselect: ssid %.2x sfbr %.2x at %ld\n",				    n->ssid, n->sfbr, TK2MS(m->ticks));				cont = -2;				break;			case A_SIR_NOTIFY_ISSUE:				IPRINT("sd53c8xx: %d/%d: issue:", dsa->target, dsa->lun);			dsadump:				IPRINT(" tgt=%d", dsa->target);				IPRINT(" time=%ld", TK2MS(m->ticks));				IPRINT("\n");				cont = -2;				break;			case A_SIR_NOTIFY_ISSUE_CHECK:				IPRINT("sd53c8xx: issue check\n");				cont = -2;				break;			case A_SIR_NOTIFY_SIGP:				IPRINT("sd53c8xx: responded to SIGP\n");				cont = -2;				break;			case A_SIR_NOTIFY_DUMP_NEXT_CODE: {				ulong *dsp = DMASEG_TO_KADDR(legetl(n->dsp));				int x;				IPRINT("sd53c8xx: code at %lux", dsp - c->script);				for (x = 0; x < 6; x++)					IPRINT(" %.8lux", dsp[x]);				IPRINT("\n");				USED(dsp);				cont = -2;				break;			}			case A_SIR_NOTIFY_WSR:				IPRINT("sd53c8xx: %d/%d: WSR set\n", dsa->target, dsa->lun);				cont = -2;				break;			case A_SIR_NOTIFY_LOAD_SYNC:				IPRINT("sd53c8xx: %d/%d: scntl=%.2x sxfer=%.2x\n",				    dsa->target, dsa->lun, n->scntl3, n->sxfer);				cont = -2;				break;			case A_SIR_NOTIFY_RESELECTED_ON_SELECT:				IPRINT("sd53c8xx: %d/%d: reselected during select\n",				    dsa->target, dsa->lun);				cont = -2;				break;			default:				IPRINT("sd53c8xx: %d/%d: script error %ld\n",					dsa->target, dsa->lun, legetl(n->dsps));				dumpncrregs(c, 1);				wakeme = 1;			}		}		/*else*/ if (dstat & Iid) {			ulong addr = legetl(n->dsp);			ulong dbc = (n->dbc[2]<<16)|(n->dbc[1]<<8)|n->dbc[0];			IPRINT("sd53c8xx: %d/%d: Iid pa=%.8lux sa=%.8lux dbc=%lux\n",			    dsa->target, dsa->lun,			    addr, addr - c->scriptpa, dbc);			addr = (ulong)DMASEG_TO_KADDR(addr);			IPRINT("%.8lux %.8lux %.8lux\n",			    *(ulong *)(addr - 12), *(ulong *)(addr - 8), *(ulong *)(addr - 4));			USED(addr, dbc);			dsa->p9status = SDeio;			wakeme = 1;		}		/*else*/ if (dstat & Bf) {			IPRINT("sd53c8xx: %d/%d: Bus Fault\n", dsa->target, dsa->lun);			dumpncrregs(c, 1);			dsa->p9status = SDeio;			wakeme = 1;		}	}	if (cont == -2)		ncrcontinue(c);	else if (cont >= 0)		start(c, cont);	if (wakeme){		if(dsa->p9status == SDnostatus)			dsa->p9status = SDeio;		wakeup(dsa);	}	iunlock(c);	if (DEBUG(1)) {		IPRINT("sd53c8xx: int end 1\n");	}}static intdone(void *arg){	return ((Dsa *)arg)->p9status != SDnostatus;}static voidsetmovedata(Movedata *d, ulong pa, ulong bc){	d->pa[0] = pa;	d->pa[1] = pa>>8;	d->pa[2] = pa>>16;	d->pa[3] = pa>>24;	d->dbc[0] = bc;	d->dbc[1] = bc>>8;	d->dbc[2] = bc>>16;	d->dbc[3] = bc>>24;}static voidadvancedata(Movedata *d, long v){	lesetl(d->pa, legetl(d->pa) + v);	lesetl(d->dbc, legetl(d->dbc) - v);}static voiddumpwritedata(uchar *data, int datalen){	int i;	uchar *bp;	if (!DEBUG(0)){		USED(data, datalen);		return;	}

⌨️ 快捷键说明

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