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

📄 ppdirect.c

📁 simple MIPS EJTAG u-boot loader
💻 C
📖 第 1 页 / 共 2 页
字号:
{	unsigned tmo = 0x10000;	if (inb(pp_direct_iobase + LPTREG_DSR) & 0x20)		return 0;	/* Event 47: Set nInit high */	outb(0x26, pp_direct_iobase + LPTREG_DCR);	/* Event 49: PError goes high */	while (!(inb(pp_direct_iobase + LPTREG_DSR) & 0x20)) {		if (!(--tmo))			return -1;	}	/* start driving the bus */	outb(0x04, pp_direct_iobase + LPTREG_DCR);	return 0;}static int ecp_reverse(void){	unsigned tmo = 0x10000;	if (!(inb(pp_direct_iobase + LPTREG_DSR) & 0x20))		return 0;	outb(0x24, pp_direct_iobase + LPTREG_DCR);	/* Event 39: Set nInit low to initiate bus reversal */	outb(0x20, pp_direct_iobase + LPTREG_DCR);	while (inb(pp_direct_iobase + LPTREG_DSR) & 0x20) {		if (!(--tmo))			return -1;	}	return 0;}static unsigned emptyfifo(unsigned cnt){	unsigned fcnt = 0;	outb(0xd0, pp_direct_iobase + LPTREG_ECONTROL); /* FIFOtest mode */	while ((inb(pp_direct_iobase + LPTREG_ECONTROL) & 0x01) && fcnt < 32 && fcnt < cnt) {		inb(pp_direct_iobase + LPTREG_TFIFO);		fcnt++;	}	printf("emptyfifo: FIFO contained %d bytes\n", fcnt);	outb(0x30, pp_direct_iobase + LPTREG_ECONTROL); /* PS/2 mode */	return cnt - fcnt;}unsigned parport_direct_ecp_write_data(const void *buf, unsigned sz){	const unsigned char *bp = (const unsigned char *)buf;	unsigned ret = 0;	unsigned tmo = 0x10000;	unsigned char stat;	if (ecp_forward())		return 0;	outb(0x70, pp_direct_iobase + LPTREG_ECONTROL); /* ECP mode */	while (sz > 0) {		while ((stat = inb(pp_direct_iobase + LPTREG_ECONTROL)) & 0x02) {			if (!(--tmo))				return emptyfifo(ret);		}		if (stat & 0x01 && sz >= 8) {			outsb(pp_direct_iobase + LPTREG_DFIFO, bp, 8);			bp += 8;			sz -= 8;			ret += 8;		} else {			outb(*bp++, pp_direct_iobase + LPTREG_DFIFO);			sz--;			ret++;		}		tmo = 0x10000;	}	while (!(inb(pp_direct_iobase + LPTREG_ECONTROL) & 0x01) || !(inb(pp_direct_iobase + LPTREG_DSR) & 0x80)) {		if (!(--tmo))			return emptyfifo(ret);	}	outb(0x30, pp_direct_iobase + LPTREG_ECONTROL); /* PS/2 mode */	return ret;}unsigned parport_direct_ecp_read_data(void *buf, unsigned sz){	unsigned char *bp = (unsigned char *)buf;	unsigned ret = 0;	unsigned tmo = 0x10000;	unsigned char stat;		if (ecp_reverse())		return 0;	outb(0x70, pp_direct_iobase + LPTREG_ECONTROL); /* ECP mode */	while (sz > 0) {		while ((stat = inb(pp_direct_iobase + LPTREG_ECONTROL)) & 0x01)			if (!(--tmo)) {				outb(0xd0, pp_direct_iobase + LPTREG_ECONTROL); /* FIFOTEST mode */				while (!(inb(pp_direct_iobase + LPTREG_ECONTROL) & 0x01) && sz > 0) {					*bp++ = inb(pp_direct_iobase + LPTREG_TFIFO);					sz--;					ret++;				}				outb(0x30, pp_direct_iobase + LPTREG_ECONTROL); /* PS/2 mode */				return ret;			}		if (stat & 0x02 && sz >= 8) {			insb(pp_direct_iobase + LPTREG_DFIFO, bp, 8);			bp += 8;			sz -= 8;			ret += 8;		} else {			*bp++ = inb(pp_direct_iobase + LPTREG_DFIFO);			sz--;			ret++;		}		tmo = 0x10000;	}	outb(0x30, pp_direct_iobase + LPTREG_ECONTROL); /* PS/2 mode */	return ret;}unsigned parport_direct_ecp_write_addr(const void *buf, unsigned sz){	const unsigned char *bp = (const unsigned char *)buf;	unsigned ret = 0;	unsigned tmo = 0x10000;	unsigned char stat;	if (ecp_forward())		return 0;	outb(0x70, pp_direct_iobase + LPTREG_ECONTROL); /* ECP mode */	while (sz > 0) {		while ((stat = inb(pp_direct_iobase + LPTREG_ECONTROL)) & 0x02) {			if (!(--tmo))				return emptyfifo(ret);		}		if (stat & 0x01 && sz >= 8) {			outsb(pp_direct_iobase + LPTREG_AFIFO, bp, 8);			bp += 8;			sz -= 8;			ret += 8;		} else {			outb(*bp++, pp_direct_iobase + LPTREG_AFIFO);			sz--;			ret++;		}		tmo = 0x10000;	}	while (!(inb(pp_direct_iobase + LPTREG_ECONTROL) & 0x01) || !(inb(pp_direct_iobase + LPTREG_DSR) & 0x80)) {		if (!(--tmo))			return emptyfifo(ret); 	}	outb(0x30, pp_direct_iobase + LPTREG_ECONTROL); /* PS/2 mode */	return ret;}/* ---------------------------------------------------------------------- */unsigned parport_direct_emul_ecp_write_data(const void *buf, unsigned sz){	unsigned char *bp = (unsigned char *)buf;	unsigned ret;	unsigned char ctl;	unsigned tmo;	if (ecp_forward())		return 0;	ctl = inb(pp_direct_iobase + LPTREG_CONTROL) & ~PARPORT_CONTROL_AUTOFD;	/* HostAck high (data, not command) */	outb(ctl, pp_direct_iobase + LPTREG_CONTROL);	for (ret = 0; ret < sz; ret++, bp++) {		outb(*bp, pp_direct_iobase + LPTREG_DATA);		outb(ctl | PARPORT_CONTROL_STROBE, pp_direct_iobase + LPTREG_CONTROL);		for (tmo = 0; inb(pp_direct_iobase + LPTREG_STATUS) & PARPORT_STATUS_BUSY; tmo++)			if (tmo > 0x1000)				return ret;		outb(ctl, pp_direct_iobase + LPTREG_CONTROL);		for (tmo = 0; !(inb(pp_direct_iobase + LPTREG_STATUS) & PARPORT_STATUS_BUSY); tmo++)			if (tmo > 0x1000)				return ret;	}	return ret;}unsigned parport_direct_emul_ecp_write_addr(const void *buf, unsigned sz){	unsigned char *bp = (unsigned char *)buf;	unsigned ret;	unsigned char ctl;	unsigned tmo;	if (ecp_forward())		return 0;	ctl = inb(pp_direct_iobase + LPTREG_CONTROL) | PARPORT_CONTROL_AUTOFD;	/* HostAck low (command, not data) */	outb(ctl, pp_direct_iobase + LPTREG_CONTROL);	for (ret = 0; ret < sz; ret++, bp++) {		outb(*bp, pp_direct_iobase + LPTREG_DATA);		outb(ctl | PARPORT_CONTROL_STROBE, pp_direct_iobase + LPTREG_CONTROL);		for (tmo = 0; inb(pp_direct_iobase + LPTREG_STATUS) & PARPORT_STATUS_BUSY; tmo++)			if (tmo > 0x1000)				return ret;		outb(ctl, pp_direct_iobase + LPTREG_CONTROL);		for (tmo = 0; !(inb(pp_direct_iobase + LPTREG_STATUS) & PARPORT_STATUS_BUSY); tmo++)			if (tmo > 0x1000)				return ret;	}	return ret;}unsigned parport_direct_emul_ecp_read_data(void *buf, unsigned sz){	unsigned char *bp = (unsigned char *)buf;	unsigned ret = 0;	unsigned char ctl, stat;	int command;	unsigned tmo;	if (ecp_reverse())		return 0;		ctl = inb(pp_direct_iobase + LPTREG_CONTROL);	/* Set HostAck low to start accepting data. */	outb(ctl | PARPORT_CONTROL_AUTOFD, pp_direct_iobase + LPTREG_CONTROL);	while (ret < sz) {		/* Event 43: Peripheral sets nAck low. It can take as                   long as it wants. */		tmo = 0;		do {			stat = inb(pp_direct_iobase + LPTREG_STATUS);			if ((++tmo) > 0x10000)				goto out;		} while (stat & PARPORT_STATUS_ACK);		/* Is this a command? */		command = stat & PARPORT_STATUS_BUSY;		if (command) {			//lprintf(3, "ECP: warning: emulation does not support RLE\n");			goto out;		}		/* Read the data. */		*bp = inb(pp_direct_iobase + LPTREG_DATA);		/* Event 44: Set HostAck high, acknowledging handshake. */		outb(ctl & ~PARPORT_CONTROL_AUTOFD, pp_direct_iobase + LPTREG_CONTROL);		/* Event 45: The peripheral has 35ms to set nAck high. */		tmo = 0;		do {			stat = inb(pp_direct_iobase + LPTREG_STATUS);			if ((++tmo) > 0x10000)				goto out;		} while (!(stat & PARPORT_STATUS_ACK));		/* Event 46: Set HostAck low and accept the data. */		outb(ctl | PARPORT_CONTROL_AUTOFD, pp_direct_iobase + LPTREG_CONTROL);		/* Normal data byte. */		bp++;		ret++;	} out:	return ret;} /* ---------------------------------------------------------------------- */#if 1unsigned parport_direct_fpgaconfig_write(const void *buf, unsigned sz){	const unsigned char *bp = buf;	unsigned u;	for (u = 0; u < sz; u++, bp++)		outb(*bp, pp_direct_iobase + LPTREG_DATA);	return sz;}#elseunsigned parport_direct_fpgaconfig_write(const void *buf, unsigned sz){	const unsigned char *bp = buf;	unsigned ret = 0;	unsigned tmo = 0x10000;	unsigned char stat;	if (pp_direct_modes & PARPORT_MODE_PCECR) {		outb(0x50, pp_direct_iobase + LPTREG_ECONTROL); /* COMPAT FIFO mode */		while (sz > 0) {			while ((stat = inb(pp_direct_iobase + LPTREG_ECONTROL)) & 0x02) {				if (!(--tmo))					return emptyfifo(ret);			}			if (stat & 0x01 && sz >= 8) {				outsb(pp_direct_iobase + LPTREG_DFIFO, bp, 8);				bp += 8;				sz -= 8;				ret += 8;			} else {				outb(*bp++, pp_direct_iobase + LPTREG_DFIFO);				sz--;				ret++;			}			tmo = 0x10000;		}		while (!(inb(pp_direct_iobase + LPTREG_ECONTROL) & 0x01) || !(inb(pp_direct_iobase + LPTREG_DSR) & 0x80)) {			if (!(--tmo))				return emptyfifo(ret);		}		outb(0x30, pp_direct_iobase + LPTREG_ECONTROL); /* PS/2 mode */		return ret;	}	for (ret = 0; ret < sz; ret++, bp++)		outb(*bp, pp_direct_iobase + LPTREG_DATA);	return sz;}#endif/* ---------------------------------------------------------------------- */const struct parport_ops parport_direct_ops = {	parport_direct_read_data,	parport_direct_write_data,	parport_direct_read_status,	parport_direct_read_control,	parport_direct_write_control,	parport_direct_frob_control,	parport_direct_epp_write_data,	parport_direct_epp_read_data,	parport_direct_epp_write_addr,	parport_direct_epp_read_addr,	parport_direct_ecp_write_data,	parport_direct_ecp_read_data,	parport_direct_ecp_write_addr,	parport_direct_fpgaconfig_write};const struct parport_ops parport_direct_emul_ops = {	parport_direct_read_data,	parport_direct_write_data,	parport_direct_read_status,	parport_direct_read_control,	parport_direct_write_control,	parport_direct_frob_control,	parport_direct_emul_epp_write_data,	parport_direct_emul_epp_read_data,	parport_direct_emul_epp_write_addr,	parport_direct_emul_epp_read_addr,	parport_direct_emul_ecp_write_data,	parport_direct_emul_ecp_read_data,	parport_direct_emul_ecp_write_addr,	parport_direct_fpgaconfig_write};/* ---------------------------------------------------------------------- */struct parport_ops parport_ops = {	parport_direct_read_data,	parport_direct_write_data,	parport_direct_read_status,	parport_direct_read_control,	parport_direct_write_control,	parport_direct_frob_control,	parport_direct_emul_epp_write_data,	parport_direct_emul_epp_read_data,	parport_direct_emul_epp_write_addr,	parport_direct_emul_epp_read_addr,	parport_direct_emul_ecp_write_data,	parport_direct_emul_ecp_read_data,	parport_direct_emul_ecp_write_addr,	parport_direct_fpgaconfig_write};/* ---------------------------------------------------------------------- */

⌨️ 快捷键说明

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