[Linux-parport] [BUG] IRQ storm from linux/drivers/char/ppdev.c

Guan Xin guanx.bac at gmail.com
Thu Aug 12 12:56:02 EDT 2010


Hi All,

When I was using a PCI parallel card, I suffered from IRQ storms with avrdude.

https://savannah.nongnu.org/bugs/?30753

It seems that in "ppdev.c" the IRQ is always enabled everywhere.
I am not familiar with this driver. But the attached nasty patch
solved my problem. Could anyone check it?

Xin


--- ppdev.c.1st	2010-08-01 18:11:14.000000000 -0400
+++ ppdev.c	2010-08-12 11:48:35.742688887 -0400
@@ -90,17 +90,21 @@
 #define PP_EXCL       (1<<1)

 /* Other constants */
-#define PP_INTERRUPT_TIMEOUT (10 * HZ) /* 10s */
 #define PP_BUFFER_SIZE 1024
 #define PARDEVICE_MAX 8

 /* ROUND_UP macro from fs/select.c */
 #define ROUND_UP(x,y) (((x)+(y)-1)/(y))

-static inline void pp_enable_irq (struct pp_struct *pp)
+static inline void pp_verify_irq (struct pp_struct *pp)
 {
 	struct parport *port = pp->pdev->port;
-	port->ops->enable_irq (port);
+
+	if (pp->state.mode == IEEE1284_MODE_COMPAT) {
+		port->ops->disable_irq (port);
+	} else {
+		port->ops->enable_irq (port);
+	}
 }

 static ssize_t pp_read (struct file * file, char __user * buf, size_t count,
@@ -181,7 +185,7 @@
 		bytes_read = -EFAULT;

 	kfree (kbuffer);
-	pp_enable_irq (pp);
+	pp_verify_irq (pp);
 	return bytes_read;
 }

@@ -263,7 +267,7 @@
 	parport_set_timeout (pp->pdev, pp->default_inactivity);

 	kfree (kbuffer);
-	pp_enable_irq (pp);
+	pp_verify_irq (pp);
 	return bytes_written;
 }

@@ -360,7 +364,7 @@

 		/* For interrupt-reporting to work, we need to be
 		 * informed of each interrupt. */
-		pp_enable_irq (pp);
+		pp_verify_irq (pp);

 		/* We may need to fix up the state machine. */
 		info = &pp->pdev->port->ieee1284;
@@ -574,7 +578,7 @@
 			ret = -ENXIO;
 			break;
 		}
-		pp_enable_irq (pp);
+		pp_verify_irq (pp);
 		return ret;

 	case PPWCTLONIRQ:



More information about the Linux-parport mailing list