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

📄 parport_pc.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 5 页
字号:
{	int devid,devrev,oldid,x_devid,x_devrev,x_oldid;	/* First probe without key */	outb(0x20,io);	x_devid=inb(io+1);	outb(0x21,io);	x_devrev=inb(io+1);	outb(0x09,io);	x_oldid=inb(io+1);	outb(key,io);	outb(key,io);     /* Write Magic Sequence to EFER, extended                             funtion enable register */	outb(0x20,io);    /* Write EFIR, extended function index register */	devid=inb(io+1);  /* Read EFDR, extended function data register */	outb(0x21,io);	devrev=inb(io+1);	outb(0x09,io);	oldid=inb(io+1);	outb(0xaa,io);    /* Magic Seal */	if ((x_devid == devid) && (x_devrev == devrev) && (x_oldid == oldid))		return; /* protection against false positives */	decode_winbond(io,key,devid,devrev,oldid);}static void __devinit winbond_check2(int io,int key){        int devid,devrev,oldid,x_devid,x_devrev,x_oldid;	/* First probe without the key */	outb(0x20,io+2);	x_devid=inb(io+2);	outb(0x21,io+1);	x_devrev=inb(io+2);	outb(0x09,io+1);	x_oldid=inb(io+2);        outb(key,io);     /* Write Magic Byte to EFER, extended                             funtion enable register */        outb(0x20,io+2);  /* Write EFIR, extended function index register */        devid=inb(io+2);  /* Read EFDR, extended function data register */        outb(0x21,io+1);        devrev=inb(io+2);        outb(0x09,io+1);        oldid=inb(io+2);        outb(0xaa,io);    /* Magic Seal */	if ((x_devid == devid) && (x_devrev == devrev) && (x_oldid == oldid))		return; /* protection against false positives */        decode_winbond(io,key,devid,devrev,oldid);}static void __devinit smsc_check(int io, int key){        int id,rev,oldid,oldrev,x_id,x_rev,x_oldid,x_oldrev;	/* First probe without the key */	outb(0x0d,io);	x_oldid=inb(io+1);	outb(0x0e,io);	x_oldrev=inb(io+1);	outb(0x20,io);	x_id=inb(io+1);	outb(0x21,io);	x_rev=inb(io+1);        outb(key,io);        outb(key,io);     /* Write Magic Sequence to EFER, extended                             funtion enable register */        outb(0x0d,io);    /* Write EFIR, extended function index register */        oldid=inb(io+1);  /* Read EFDR, extended function data register */        outb(0x0e,io);        oldrev=inb(io+1);	outb(0x20,io);	id=inb(io+1);	outb(0x21,io);	rev=inb(io+1);        outb(0xaa,io);    /* Magic Seal */	if ((x_id == id) && (x_oldrev == oldrev) &&	    (x_oldid == oldid) && (x_rev == rev))		return; /* protection against false positives */        decode_smsc(io,key,oldid,oldrev);}static void __devinit detect_and_report_winbond (void){ 	if (verbose_probing)		printk(KERN_DEBUG "Winbond Super-IO detection, now testing ports 3F0,370,250,4E,2E ...\n");	winbond_check(0x3f0,0x87);	winbond_check(0x370,0x87);	winbond_check(0x2e ,0x87);	winbond_check(0x4e ,0x87);	winbond_check(0x3f0,0x86);	winbond_check2(0x250,0x88); 	winbond_check2(0x250,0x89);}static void __devinit detect_and_report_smsc (void){	if (verbose_probing)		printk(KERN_DEBUG "SMSC Super-IO detection, now testing Ports 2F0, 370 ...\n");	smsc_check(0x3f0,0x55);	smsc_check(0x370,0x55);	smsc_check(0x3f0,0x44);	smsc_check(0x370,0x44);}#endif /* CONFIG_PARPORT_PC_SUPERIO */static int __devinit get_superio_dma (struct parport *p){	int i=0;	while( (superios[i].io != p->base) && (i<NR_SUPERIOS))		i++;	if (i!=NR_SUPERIOS)		return superios[i].dma;	return PARPORT_DMA_NONE;}static int __devinit get_superio_irq (struct parport *p){	int i=0;        while( (superios[i].io != p->base) && (i<NR_SUPERIOS))                i++;        if (i!=NR_SUPERIOS)                return superios[i].irq;        return PARPORT_IRQ_NONE;}	/* --- Mode detection ------------------------------------- *//* * Checks for port existence, all ports support SPP MODE * Returns:  *         0           :  No parallel port at this adress *  PARPORT_MODE_PCSPP :  SPP port detected  *                        (if the user specified an ioport himself, *                         this shall always be the case!) * */static int __devinit parport_SPP_supported(struct parport *pb){	unsigned char r, w;	/*	 * first clear an eventually pending EPP timeout 	 * I (sailer@ife.ee.ethz.ch) have an SMSC chipset	 * that does not even respond to SPP cycles if an EPP	 * timeout is pending	 */	clear_epp_timeout(pb);	/* Do a simple read-write test to make sure the port exists. */	w = 0xc;	outb (w, CONTROL (pb));	/* Is there a control register that we can read from?  Some	 * ports don't allow reads, so read_control just returns a	 * software copy. Some ports _do_ allow reads, so bypass the	 * software copy here.  In addition, some bits aren't	 * writable. */	r = inb (CONTROL (pb));	if ((r & 0xf) == w) {		w = 0xe;		outb (w, CONTROL (pb));		r = inb (CONTROL (pb));		outb (0xc, CONTROL (pb));		if ((r & 0xf) == w)			return PARPORT_MODE_PCSPP;	}	if (user_specified)		/* That didn't work, but the user thinks there's a		 * port here. */		printk (KERN_INFO "parport 0x%lx (WARNING): CTR: "			"wrote 0x%02x, read 0x%02x\n", pb->base, w, r);	/* Try the data register.  The data lines aren't tri-stated at	 * this stage, so we expect back what we wrote. */	w = 0xaa;	parport_pc_write_data (pb, w);	r = parport_pc_read_data (pb);	if (r == w) {		w = 0x55;		parport_pc_write_data (pb, w);		r = parport_pc_read_data (pb);		if (r == w)			return PARPORT_MODE_PCSPP;	}	if (user_specified) {		/* Didn't work, but the user is convinced this is the		 * place. */		printk (KERN_INFO "parport 0x%lx (WARNING): DATA: "			"wrote 0x%02x, read 0x%02x\n", pb->base, w, r);		printk (KERN_INFO "parport 0x%lx: You gave this address, "			"but there is probably no parallel port there!\n",			pb->base);	}	/* It's possible that we can't read the control register or	 * the data register.  In that case just believe the user. */	if (user_specified)		return PARPORT_MODE_PCSPP;	return 0;}/* Check for ECR * * Old style XT ports alias io ports every 0x400, hence accessing ECR * on these cards actually accesses the CTR. * * Modern cards don't do this but reading from ECR will return 0xff * regardless of what is written here if the card does NOT support * ECP. * * We first check to see if ECR is the same as CTR.  If not, the low * two bits of ECR aren't writable, so we check by writing ECR and * reading it back to see if it's what we expect. */static int __devinit parport_ECR_present(struct parport *pb){	struct parport_pc_private *priv = pb->private_data;	unsigned char r = 0xc;	outb (r, CONTROL (pb));	if ((inb (ECONTROL (pb)) & 0x3) == (r & 0x3)) {		outb (r ^ 0x2, CONTROL (pb)); /* Toggle bit 1 */		r = inb (CONTROL (pb));		if ((inb (ECONTROL (pb)) & 0x2) == (r & 0x2))			goto no_reg; /* Sure that no ECR register exists */	}		if ((inb (ECONTROL (pb)) & 0x3 ) != 0x1)		goto no_reg;	ECR_WRITE (pb, 0x34);	if (inb (ECONTROL (pb)) != 0x35)		goto no_reg;	priv->ecr = 1;	outb (0xc, CONTROL (pb));		/* Go to mode 000 */	frob_set_mode (pb, ECR_SPP);	return 1; no_reg:	outb (0xc, CONTROL (pb));	return 0; }#ifdef CONFIG_PARPORT_1284/* Detect PS/2 support. * * Bit 5 (0x20) sets the PS/2 data direction; setting this high * allows us to read data from the data lines.  In theory we would get back * 0xff but any peripheral attached to the port may drag some or all of the * lines down to zero.  So if we get back anything that isn't the contents * of the data register we deem PS/2 support to be present.  * * Some SPP ports have "half PS/2" ability - you can't turn off the line * drivers, but an external peripheral with sufficiently beefy drivers of * its own can overpower them and assert its own levels onto the bus, from * where they can then be read back as normal.  Ports with this property * and the right type of device attached are likely to fail the SPP test, * (as they will appear to have stuck bits) and so the fact that they might * be misdetected here is rather academic.  */static int __devinit parport_PS2_supported(struct parport *pb){	int ok = 0;  	clear_epp_timeout(pb);	/* try to tri-state the buffer */	parport_pc_data_reverse (pb);		parport_pc_write_data(pb, 0x55);	if (parport_pc_read_data(pb) != 0x55) ok++;	parport_pc_write_data(pb, 0xaa);	if (parport_pc_read_data(pb) != 0xaa) ok++;	/* cancel input mode */	parport_pc_data_forward (pb);	if (ok) {		pb->modes |= PARPORT_MODE_TRISTATE;	} else {		struct parport_pc_private *priv = pb->private_data;		priv->ctr_writable &= ~0x20;	}	return ok;}#ifdef CONFIG_PARPORT_PC_FIFOstatic int __devinit parport_ECP_supported(struct parport *pb){	int i;	int config, configb;	int pword;	struct parport_pc_private *priv = pb->private_data;	/* Translate ECP intrLine to ISA irq value */		static const int intrline[]= { 0, 7, 9, 10, 11, 14, 15, 5 }; 	/* If there is no ECR, we have no hope of supporting ECP. */	if (!priv->ecr)		return 0;	/* Find out FIFO depth */	ECR_WRITE (pb, ECR_SPP << 5); /* Reset FIFO */	ECR_WRITE (pb, ECR_TST << 5); /* TEST FIFO */	for (i=0; i < 1024 && !(inb (ECONTROL (pb)) & 0x02); i++)		outb (0xaa, FIFO (pb));	/*	 * Using LGS chipset it uses ECR register, but	 * it doesn't support ECP or FIFO MODE	 */	if (i == 1024) {		ECR_WRITE (pb, ECR_SPP << 5);		return 0;	}	priv->fifo_depth = i;	if (verbose_probing)		printk (KERN_DEBUG "0x%lx: FIFO is %d bytes\n", pb->base, i);	/* Find out writeIntrThreshold */	frob_econtrol (pb, 1<<2, 1<<2);	frob_econtrol (pb, 1<<2, 0);	for (i = 1; i <= priv->fifo_depth; i++) {		inb (FIFO (pb));		udelay (50);		if (inb (ECONTROL (pb)) & (1<<2))			break;	}	if (i <= priv->fifo_depth) {		if (verbose_probing)			printk (KERN_DEBUG "0x%lx: writeIntrThreshold is %d\n",				pb->base, i);	} else		/* Number of bytes we know we can write if we get an                   interrupt. */		i = 0;	priv->writeIntrThreshold = i;	/* Find out readIntrThreshold */	frob_set_mode (pb, ECR_PS2); /* Reset FIFO and enable PS2 */	parport_pc_data_reverse (pb); /* Must be in PS2 mode */	frob_set_mode (pb, ECR_TST); /* Test FIFO */	frob_econtrol (pb, 1<<2, 1<<2);	frob_econtrol (pb, 1<<2, 0);	for (i = 1; i <= priv->fifo_depth; i++) {		outb (0xaa, FIFO (pb));		if (inb (ECONTROL (pb)) & (1<<2))			break;	}	if (i <= priv->fifo_depth) {		if (verbose_probing)			printk (KERN_INFO "0x%lx: readIntrThreshold is %d\n",				pb->base, i);	} else		/* Number of bytes we can read if we get an interrupt. */		i = 0;	priv->readIntrThreshold = i;	ECR_WRITE (pb, ECR_SPP << 5); /* Reset FIFO */	ECR_WRITE (pb, 0xf4); /* Configuration mode */	config = inb (CONFIGA (pb));	pword = (config >> 4) & 0x7;	switch (pword) {	case 0:		pword = 2;		printk (KERN_WARNING "0x%lx: Unsupported pword size!\n",			pb->base);		break;	case 2:		pword = 4;		printk (KERN_WARNING "0x%lx: Unsupported pword size!\n",			pb->base);		break;	default:		printk (KERN_WARNING "0x%lx: Unknown implementation ID\n",			pb->base);		/* Assume 1 */	case 1:		pword = 1;	}	priv->pword = pword;	if (verbose_probing) {		printk (KERN_DEBUG "0x%lx: PWord is %d bits\n", pb->base, 8 * pword);				printk (KERN_DEBUG "0x%lx: Interrupts are ISA-%s\n", pb->base,			config & 0x80 ? "Level" : "Pulses");		configb = inb (CONFIGB (pb));		printk (KERN_DEBUG "0x%lx: ECP port cfgA=0x%02x cfgB=0x%02x\n",			pb->base, config, configb);		printk (KERN_DEBUG "0x%lx: ECP settings irq=", pb->base);		if ((configb >>3) & 0x07)			printk("%d",intrline[(configb >>3) & 0x07]);		else			printk("<none or set by other means>");		printk (" dma=");		if( (configb & 0x03 ) == 0x00)			printk("<none or set by other means>\n");		else			printk("%d\n",configb & 0x07);	}	/* Go back to mode 000 */	frob_set_mode (pb, ECR_SPP);	return 1;}#endifstatic int __devinit parport_ECPPS2_supported(struct parport *pb){	const struct parport_pc_private *priv = pb->private_data;	int result;	unsigned char oecr;	if (!priv->ecr)		return 0;	oecr = inb (ECONTROL (pb));	ECR_WRITE (pb, ECR_PS2 << 5);	result = parport_PS2_supported(pb);	ECR_WRITE (pb, oecr);	return result;}/* EPP mode detection  */static int __devinit parport_EPP_supported(struct parport *pb){	const struct parport_pc_private *priv = pb->private_data;	/*	 * Theory:	 *	Bit 0 of STR is the EPP timeout bit, this bit is 0	 *	when EPP is possible and is set high when an EPP timeout	 *	occurs (EPP uses the HALT line to stop the CPU while it does	 *	the byte transfer, an EPP timeout occurs if the attached	 *	device fails to respond after 10 micro seconds).	 *	 *	This bit is cleared by either reading it (National Semi)	 *	or writing a 1 to the bit (SMC, UMC, WinBond), others ???	 *	This bit is always high in non EPP modes.	 */	/* If EPP timeout bit clear then EPP available */	if (!clear_epp_timeout(pb)) {		return 0;  /* No way to clear timeout */	}	/* Check for Intel bug. */	if (priv->ecr) {		unsigned char i;		for (i = 0x00; i < 0x80; i += 0x20) {			ECR_WRITE (pb, i);			if (clear_epp_timeout (pb)) {				/* Phony EPP in ECP. */				return 0;			}		}	}	pb->modes |= PARPORT_MODE_EPP;	/* Set up access functions to use EPP hardware. */	pb->ops->epp_read_data = parport_pc_epp_read_data;	pb->ops->epp_write_data = parport_pc_epp_write_data;	pb->ops->epp_read_addr = parport_pc_epp_read_addr;	pb->ops->epp_write_addr = parport_pc_epp_write_addr;	return 1;}

⌨️ 快捷键说明

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