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

📄 ppw9xring0init.c

📁 simple MIPS EJTAG u-boot loader
💻 C
📖 第 1 页 / 共 2 页
字号:
/*****************************************************************************//* *      ppw9xring0init.c  --  Parport direct access under Win9x using Ring0 hack (init routines). * *      Copyright (C) 1998-2000  Thomas Sailer (sailer@ife.ee.ethz.ch) * *      This program is free software; you can redistribute it and/or modify *      it under the terms of the GNU General Public License as published by *      the Free Software Foundation; either version 2 of the License, or *      (at your option) any later version. * *      This program is distributed in the hope that it will be useful, *      but WITHOUT ANY WARRANTY; without even the implied warranty of *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *      GNU General Public License for more details. * *      You should have received a copy of the GNU General Public License *      along with this program; if not, write to the Free Software *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * *  Please note that the GPL allows you to use the driver, NOT the radio. *  In order to use the radio, you need a license from the communications *  authority of your country. * *//*****************************************************************************/#if defined(HAVE_SYS_IO_H)#include <sys/io.h>#elif defined(HAVE_ASM_IO_H)#include <asm/io.h>#endif#include <errno.h>#include <string.h>#include "parport.h"/* ---------------------------------------------------------------------- */#ifndef HAVE_IOPL#ifdef HAVE_WINDOWS_H#include <windows.h>extern inline int iopl(unsigned int level){        OSVERSIONINFO info;        info.dwOSVersionInfoSize = sizeof(info);        if (GetVersionEx(&info) &&            (info.dwPlatformId == VER_PLATFORM_WIN32s ||             info.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS))                return 0;        return 1;}#elseextern inline int iopl(unsigned int level){        return 0;}#endif#endif/* ---------------------------------------------------------------------- *//* LPT registers *//* ECP specific registers */#define LPTREG_ECONTROL       0x402#define LPTREG_CONFIGB        0x401#define LPTREG_CONFIGA        0x400#define LPTREG_TFIFO          0x400#define LPTREG_DFIFO          0x400#define LPTREG_AFIFO          0x000#define LPTREG_DSR            0x001#define LPTREG_DCR            0x002/* EPP specific registers */#define LPTREG_EPPDATA        0x004#define LPTREG_EPPADDR        0x003/* standard registers */#define LPTREG_CONTROL        0x002#define LPTREG_STATUS         0x001#define LPTREG_DATA           0x000/* ECP config A */#define LPTCFGA_INTRISALEVEL  0x80#define LPTCFGA_IMPIDMASK     0x70#define LPTCFGA_IMPID16BIT    0x00#define LPTCFGA_IMPID8BIT     0x10#define LPTCFGA_IMPID32BIT    0x20#define LPTCFGA_NOPIPELINE    0x04#define LPTCFGA_PWORDCOUNT    0x03/* ECP config B */#define LPTCFGB_COMPRESS      0x80#define LPTCFGB_INTRVALUE     0x40#define LPTCFGB_IRQMASK       0x38#define LPTCFGB_IRQ5          0x38#define LPTCFGB_IRQ15         0x30#define LPTCFGB_IRQ14         0x28#define LPTCFGB_IRQ11         0x20#define LPTCFGB_IRQ10         0x18#define LPTCFGB_IRQ9          0x10#define LPTCFGB_IRQ7          0x08#define LPTCFGB_IRQJUMPER     0x00#define LPTCFGB_DMAMASK       0x07#define LPTCFGB_DMA7          0x07#define LPTCFGB_DMA6          0x06#define LPTCFGB_DMA5          0x05#define LPTCFGB_DMAJUMPER16   0x04#define LPTCFGB_DMA3          0x03#define LPTCFGB_DMA2          0x02#define LPTCFGB_DMA1          0x01#define LPTCFGB_DMAJUMPER8    0x00/* ECP ECR */#define LPTECR_MODEMASK       0xe0#define LPTECR_MODESPP        0x00#define LPTECR_MODEPS2        0x20#define LPTECR_MODESPPFIFO    0x40#define LPTECR_MODEECP        0x60#define LPTECR_MODEECPEPP     0x80#define LPTECR_MODETEST       0xc0#define LPTECR_MODECFG        0xe0#define LPTECR_NERRINTRDIS    0x10#define LPTECR_DMAEN          0x08#define LPTECR_SERVICEINTR    0x04#define LPTECR_FIFOFULL       0x02#define LPTECR_FIFOEMPTY      0x01/* ---------------------------------------------------------------------- */extern unsigned int pp_w9xring0_iobase;extern unsigned int pp_w9xring0_flags;extern const struct parport_ops parport_w9xring0_ops, parport_w9xring0_emul_ops;extern unsigned char ring0_inb(unsigned int port);extern void ring0_outb(unsigned char val, unsigned int port);extern void ring0_outsb(unsigned int port, const unsigned char *bp, unsigned int count);extern void ring0_insb(unsigned int port, unsigned char *bp, unsigned int count);extern int pp_w9xring0_epp_clear_timeout(void);#define FLAGS_PCSPP              (1<<0)#define FLAGS_PCPS2              (1<<1)#define FLAGS_PCEPP              (1<<2)#define FLAGS_PCECR              (1<<3)  /* ECR Register Exists */#define FLAGS_PCECP              (1<<4)#define FLAGS_PCECPEPP           (1<<5)#define FLAGS_PCECPPS2           (1<<6)/* ---------------------------------------------------------------------- */#if 0#ifndef EPPEMULstatic int detect_epp(void){	/* pulse PROGRAM low, reset FPGA just to be safe */	ring0_outb(LPTCTRL_ADDRSTB, iobase+LPTREG_CONTROL);	usleep(10);	ring0_outb(LPTCTRL_PROGRAM, iobase+LPTREG_CONTROL);	/* start of ordinary test */	if (!epp_clear_timeout())		return -1;	ring0_outb(ring0_inb(iobase + LPTREG_CONTROL) | 0x20, iobase + LPTREG_CONTROL);	ring0_outb(ring0_inb(iobase + LPTREG_CONTROL) | 0x10, iobase + LPTREG_CONTROL);	epp_clear_timeout();	ring0_inb(iobase + LPTREG_EPPDATA);	/* udelay(30); */	if (ring0_inb(iobase + LPTREG_STATUS) & LPTSTAT_EPPTIMEOUT) {		epp_clear_timeout();		return 0;	}	/*return -1;*/	lprintf(3, "warning: no EPP timeout\n");	return 0;}#endif /* !EPPEMUL */static int detect_ecr(void){	unsigned char r, oc, oec;	oec = ring0_inb(iobase + LPTREG_ECONTROL);	oc = ring0_inb(iobase + LPTREG_CONTROL);	if ((oc & 3) == (oec & 3)) {		ring0_outb(oc ^ 2, iobase + LPTREG_CONTROL);		r = ring0_inb(iobase + LPTREG_CONTROL);		if ((ring0_inb(iobase + LPTREG_ECONTROL) & 2) == (r & 2)) {			ring0_outb(oc, iobase + LPTREG_CONTROL);			return -1;		}	}	if ((oec & 3) != 1)		return -1;	ring0_outb(0x34, iobase + LPTREG_ECONTROL);	r = ring0_inb(iobase + LPTREG_ECONTROL);	ring0_outb(oc, iobase + LPTREG_CONTROL);	ring0_outb(oec, iobase + LPTREG_ECONTROL);	return -(r != 0x35);}int detect_port(void){	ring0_outb(LPTCTRL_ADDRSTB, iobase+LPTREG_CONTROL);	pp_w9xring0_epp_clear_timeout();  /* prevent lockup of some SMSC IC's */	/* this routine is mostly copied from Linux Kernel parport */	ring0_outb(0xc, iobase+LPTREG_ECONTROL);	ring0_outb(0xc, iobase+LPTREG_CONTROL);	ring0_outb(0xaa, iobase+LPTREG_DATA);	if (ring0_inb(iobase+LPTREG_DATA) != 0xaa)		goto fail_spp;	ring0_outb(0x55, iobase+LPTREG_DATA);	if (ring0_inb(iobase+LPTREG_DATA) != 0x55)		goto fail_spp;#ifdef EPPEMUL	/* tentatively enable PS/2 mode if ECP port */	ring0_outb(0x20, iobase + LPTREG_ECONTROL);	ring0_outb(LPTCTRL_PROGRAM, iobase+LPTREG_CONTROL);	if ((ring0_inb(iobase+LPTREG_CONTROL) & 0x3f) != LPTCTRL_PROGRAM)		goto fail_ps2;	ring0_outb(LPTCTRL_PROGRAM | LPTCTRL_W9XRING0ION, iobase+LPTREG_CONTROL);	if ((ring0_inb(iobase+LPTREG_CONTROL) & 0x3f) != (LPTCTRL_PROGRAM | LPTCTRL_W9XRING0ION))		goto fail_ps2;	return 0;  fail_ps2:	lprintf(3, "parport (PS/2 bidir) test failed\n");	return -1;#else /* !EPPEMUL */	if (!detect_ecr()) {		ring0_outb(0x80, iobase + LPTREG_ECONTROL);		lprintf(3, "parport SMSC style ECP+EPP detected\n");		return 0;	}	if (!detect_epp())		return 0;	/* goto fail_epp; */  fail_epp:	lprintf(3, "parport (EPP) test failed\n");	return -1;#endif /* !EPPEMUL */  fail_spp:	lprintf(3, "parport (SPP) test failed\n");	return -1;}/* ---------------------------------------------------------------------- *//* * ECP routines */static void ecp_port_cap(void){	static const char *pwordstr[8] = { "2 bytes", "1 byte", "4 bytes", "3?", "4?", 					   "5?", "6?", "7?" };	static const char *irqstr[8] = { "jumpered", "7", "9", "10", "11", "14", "15", "5" };	static const char *dmastr[8] = { "jumpered 8bit", "1", "2", "3", "jumpered 16bit", "5", "6", "7" };	unsigned char cnfga, cnfgb;	unsigned int cnt, fwcnt, wthr = ~0, frcnt, rthr = ~0;	ring0_outb(0x30, iobase + LPTREG_ECONTROL); /* PS/2 mode */	ring0_outb(0xf0, iobase + LPTREG_ECONTROL); /* config mode */	cnfga = ring0_inb(iobase + LPTREG_CONFIGA);	cnfgb = ring0_inb(iobase + LPTREG_CONFIGB);	ring0_outb(cnfgb & 0x7f, iobase + LPTREG_CONFIGB);  /* disable compression */	ring0_outb(0x30, iobase + LPTREG_ECONTROL); /* PS/2 mode */	ring0_outb(0x04, iobase + LPTREG_DCR); /* w9xring0ion=output */	ring0_outb(0xd0, iobase + LPTREG_ECONTROL); /* test mode */	for (cnt = 0; cnt < 1024 && !(ring0_inb(iobase + LPTREG_ECONTROL) & 0x02); cnt++)		ring0_outb(0, iobase + LPTREG_TFIFO);	ring0_outb(0xd0, iobase + LPTREG_ECONTROL); /* test mode, clear serviceintr */	for (fwcnt = 0; fwcnt < 1024 && !(ring0_inb(iobase + LPTREG_ECONTROL) & 0x01); fwcnt++) {		ring0_inb(iobase + LPTREG_TFIFO);		if (ring0_inb(iobase + LPTREG_ECONTROL) & 0x04) {			wthr = fwcnt;			ring0_outb(0xd0, iobase + LPTREG_ECONTROL); /* test mode, clear serviceintr */		}	}	ring0_outb(0x24, iobase + LPTREG_DCR); /* w9xring0ion=input */	ring0_outb(0xd0, iobase + LPTREG_ECONTROL); /* test mode */	for (cnt = 0; cnt < 1024 && !(ring0_inb(iobase + LPTREG_ECONTROL) & 0x02); cnt++)		ring0_outb(0, iobase + LPTREG_TFIFO);	ring0_outb(0xd0, iobase + LPTREG_ECONTROL); /* test mode, clear serviceintr */	for (frcnt = 0; frcnt < 1024 && !(ring0_inb(iobase + LPTREG_ECONTROL) & 0x01); frcnt++) {		ring0_inb(iobase + LPTREG_TFIFO);		if (ring0_inb(iobase + LPTREG_ECONTROL) & 0x04) {			rthr = frcnt;			ring0_outb(0xd0, iobase + LPTREG_ECONTROL); /* test mode, clear serviceintr */		}	}	ring0_outb(0x30, iobase + LPTREG_ECONTROL); /* PS/2 mode */	ring0_outb(0x04, iobase + LPTREG_DCR); /* w9xring0ion=output */	lprintf(3, "ECP capabilities: %s int, PWord %s, %sextra tx pipe, IRQ %s, DMA %s\n"		"Tx: FIFO size %d threshold %d  Rx: FIFO size %d threshold %d\n",		(cnfga & 0x80) ? "level" : "edge", pwordstr[(cnfga >> 4) & 7],		(cnfga & 0x04) ? "no" : "", irqstr[(cnfgb >> 3) & 7], dmastr[cnfgb & 7],		fwcnt, wthr, frcnt, rthr);}int detect_port_ecp(void){	epp_clear_timeout();  /* prevent lockup of some SMSC IC's */	/* this routine is mostly copied from Linux Kernel parport */	ring0_outb(0xc, iobase+LPTREG_ECONTROL);	ring0_outb(0xc, iobase+LPTREG_CONTROL);	ring0_outb(0xaa, iobase+LPTREG_DATA);	if (ring0_inb(iobase+LPTREG_DATA) != 0xaa)		goto fail_spp;	ring0_outb(0x55, iobase+LPTREG_DATA);	if (ring0_inb(iobase+LPTREG_DATA) != 0x55)		goto fail_spp;	/* check for ECP ECR mode */	if (detect_ecr())		goto fail_ecp;	ecp_port_cap();	return 0;  fail_ecp:	lprintf(0, "parport (ECP) test failed\n");	return -1;  fail_spp:	lprintf(0, "parport (SPP) test failed\n");	return -1;}#endif/* ---------------------------------------------------------------------- */static int parport_spp(void){	pp_w9xring0_epp_clear_timeout();  /* prevent lockup of some SMSC IC's */	/* this routine is mostly copied from Linux Kernel parport */	ring0_outb(0xc, pp_w9xring0_iobase+LPTREG_ECONTROL);	ring0_outb(0xc, pp_w9xring0_iobase+LPTREG_CONTROL);	ring0_outb(0xaa, pp_w9xring0_iobase+LPTREG_DATA);	if (ring0_inb(pp_w9xring0_iobase+LPTREG_DATA) != 0xaa)		return 0;

⌨️ 快捷键说明

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