[Linux-parport] Problem with ECP+EPP

Eduardo Pérez Ureta eduardo.perez at uc3m.es
Fri Apr 22 03:56:20 EDT 2005


Could you send this patches to the Linux parport maintainer so this gets
in the kernel as soon as possible?

It's a shame having these new machines not recognizing EPP.

That has to be a buggy check after all as it doesn't seem new Intel
chipsets to be buggy.

On 2005-04-20 13:18:04 +0000, vdb128 at picaros.org wrote:
> > > > /* 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;
> > > > 		}
> > > > 	}
> > > > }
> 
> This code often disables the EPP mode where it shouldn't.  Moreover,
> it enables interrupts and usually initiates a spurious interrupt.  If
> another handler is already installed (shared IRQ) then the 
> kernel will not disable the IRQ in the PIC, which leads to a screaming
> interrupt for PCI cards ... locking up the system.  The PCI intx# lines
> are level sensitive.
> 
> So I support removal of the Intel test and propose to combine 
> parport_EPP_supported() and parport_ECPEPP_supported() into one 
> routine.  This gives something like 
> 
> 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, ECR_EPP<<5 | 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, 
> 	 *	Netmos, Oxford Semi)
> 	 *	or writing a 1 to the bit (SMC, UMC, WinBond), others ???
> 	 *	This bit is always high in non EPP modes.  (except Netmos)
> 	 */
> 
> 	/* If EPP timeout bit clear then EPP available */
> 	if (!clear_epp_timeout(pb)) 
> 		goto end;  /* No way to clear timeout */
> 
> 	pb->modes |= PARPORT_MODE_EPP;
> 
> 	/* Set up access functions to use EPP hardware. */
> 	if(!priv->ecrok) {
> 	  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;
> 	} else {
> 	  /* Set up access functions to use ECP+EPP hardware. */
> 	  pb->ops->epp_read_data = parport_pc_ecpepp_read_data;
> 	  pb->ops->epp_write_data = parport_pc_ecpepp_write_data;
> 	  pb->ops->epp_read_addr = parport_pc_ecpepp_read_addr;
> 	  pb->ops->epp_write_addr = parport_pc_ecpepp_write_addr;
> 	}
> 
> 	result=1;
>  end:
> 	if (priv->ecrok) 
> 	  ECR_WRITE (pb, oecr);
> 
> 	if (verbose_probing) {
> 	  printk (KERN_DEBUG "parport_EPP_supported(%s): result=%d\n", 
> 		  pb->name, result);
> 	}
> 	return(result);
> }
> 
> The EPP detection in parport_pc_probe_port() then reduces to
> 
>   if (base != 0x3bc && !check_region(base+0x3, 5))
>     parport_EPP_supported(p);
> 
> A further description is at  picaros.org/ftp/key/parport-2.4.23.diff .
> This diff modifies too much but might get ported to the 2.6 kernel in
> parts if there is interest.  (the cli sti should be replaced by semaphores)



More information about the Linux-parport mailing list