[Linux-parport] EPP mode on SIIG Cyberparallel PCI

vdb128 at picaros.org vdb128 at picaros.org
Tue Feb 24 02:44:22 GMT 2004


> I just commented out that section (and rebuilt and installed the modules) and 
> sudenly EPP mode sprang into life. I'd be interested to here if the same 
> problem affects anyone else.

Even worse, the code snippet unmasks (enables) the nFault/nError ECP 
interrupt.  On Netmos chips, the line is then routed to the PCI INTX# line
which will trigger if nError is asserted.  This usually locks up the 
system if the interrupt is shared since the previously installed handler
is called forever.  (the level sensitive INTX# is held active)

A typical symptom is that the PC boots correctly when the printer is 
turned on, but locks up otherwise.

The test incorrectly disables EPP on National PC87306B (Intel TC430HX board)
and Netmos two port 9710:9815 chipsets.  It works for the oxford 12pci840.

My code, with the Intel test, is as follows (full patch is in the archive) :

static int __devinit parport_EPP_supported(struct parport *pb)
{
	struct parport_pc_private *priv = pb->private_data;
	int result=0;
	unsigned char oecr=0x34;

	if (priv->ecrok) {
	  oecr = inb (ECONTROL (pb));
	  /* Search for SMC style EPP+ECP mode */
	  ECR_WRITE (pb, 0x80 | 0x14);        /* EPP no interrupts for PCI */
	  outb (0x04, CONTROL (pb));
	}

	/*
	 * 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)) {
	        result=-1;
		goto end;  /* No way to clear timeout */
	}

	/* Check for Intel bug. */
	if (priv->ecrok) {
		int i;
		unsigned char mode[5]={
		  ECR_SPP, ECR_PS2, ECR_PPF, ECR_ECP, ECR_EPP
		};
		for (i = 0; i < 5; i++) {
		  frob_set_mode (pb, mode[i]);
		  if (mode[i]!=ECR_EPP && clear_epp_timeout (pb)) {
		    /* Phony EPP in ECP. */
		    result=-10-i;
		    goto end;
		  }
		}
	}
  ...



More information about the Linux-parport mailing list