Andrea Arcangeli (andrea@e-mind.com)
Wed, 16 Dec 1998 16:06:47 +0100 (CET)
On Wed, 16 Dec 1998, Tim Waugh wrote:
>Hi Andrea,
>
>Attached is my latest upload to torque.net.
I am CCing also to linux-parport just to allow more people to complain
about my patches. 
Here an diff against your patch-2.1.131-ac11-1284-2:
This first is a bugfix. Due this bug I readded in my tree the comma at the
end of every parport lowlevel ops ;)
Index: linux/drivers/misc/parport_arc.c
diff -u linux/drivers/misc/parport_arc.c:1.1.4.1 linux/drivers/misc/parport_arc.c:1.1.1.1.2.5
--- linux/drivers/misc/parport_arc.c:1.1.4.1	Wed Dec 16 13:19:22 1998
+++ linux/drivers/misc/parport_arc.c	Wed Dec 16 15:24:23 1998
@@ -124,7 +124,7 @@
         
         parport_ieee1284_write_compat,
         parport_ieee1284_read_nibble,
-	parport_ieee1284_read_byte
+	parport_ieee1284_read_byte,
 };
 
 /* --- Initialisation code -------------------------------- */
Index: linux/drivers/misc/parport_ax.c
diff -u linux/drivers/misc/parport_ax.c:1.1.4.1 linux/drivers/misc/parport_ax.c:1.1.1.1.2.6
--- linux/drivers/misc/parport_ax.c:1.1.4.1	Wed Dec 16 13:19:22 1998
+++ linux/drivers/misc/parport_ax.c	Wed Dec 16 15:24:24 1998
@@ -323,7 +323,7 @@
 
         parport_ax_inc_use_count,
         parport_ax_dec_use_count,
-	parport_ax_fill_inode
+	parport_ax_fill_inode,
 
         parport_ieee1284_write_epp,
         parport_ieee1284_read_epp,
@@ -333,7 +333,7 @@
 
         parport_ieee1284_write_compat,
         parport_ieee1284_read_nibble,
-	parport_ieee1284_read_byte
+	parport_ieee1284_read_byte,
 };
 
 
This will allow us at least to use best the polling loop. I also
reinserted the interrupt make sense message because I want to see when I
am really using irqs ;) 
Index: linux/drivers/misc/parport_ieee1284.c
diff -u linux/drivers/misc/parport_ieee1284.c:1.1.4.1 linux/drivers/misc/parport_ieee1284.c:1.1.1.1.2.6
--- linux/drivers/misc/parport_ieee1284.c:1.1.4.1	Wed Dec 16 13:19:22 1998
+++ linux/drivers/misc/parport_ieee1284.c	Wed Dec 16 15:18:28 1998
@@ -52,7 +52,7 @@
          * How about making a note (in the device structure) of how long
          * it takes, so we know for next time?
          */
-	for (counter = 0; counter < 20; counter++) {
+	for (counter = 0; counter < 100; counter++) {
                 status = parport_read_status(port);
                 if ((status & mask) == result)
                         return 0;
@@ -60,7 +60,7 @@
                         return -EINTR;
                 if (current->need_resched)
                         break;
-		udelay(25);
+		udelay(5);
         }
 
         /* 40ms of slow polling. */
@@ -314,11 +314,18 @@
 void parport_ieee1284_interrupt (int which, void *handle, struct pt_regs *regs)
 {
         struct parport *port = handle;
+#ifdef	DEBUG
+	struct semaphore *sem = &port->ieee1284.sem;
+#endif
         if (!(port->cad->flags & PARPORT_DEV_IEEE1284IRQ)) {
                 port->cad->flags |= PARPORT_DEV_IEEE1284IRQ;
                 DPRINTK (KERN_DEBUG "Woo hoo! Using interrupts!\n");
         }
 
+#ifdef	DEBUG
+	if (!atomic_read(&sem->count))
+		DPRINTK (KERN_DEBUG "Woo hoo! Interrupt make sense!\n");
+#endif
         parport_ieee1284_wakeup (port);
 
         if (port->ieee1284.phase == IEEE1284_PH_REV_IDLE) {
Here the most important thing. Yesterday I didn' t understood well the
point of your code. That was emergency code that runs for 5 sec. If the
port is shared we can' t really gain the port for such long time. This way
my ppa returned to run continously and _fast_ whatever I done with the
printer. Also the printing is _fast_ while ppa is running cp /dev/sda
/dev/null btw ;). There' s no noticable slowdown with my new printer using
parport sharing or not.
Index: linux/drivers/misc/parport_ieee1284_ops.c
diff -u linux/drivers/misc/parport_ieee1284_ops.c:1.1.4.1 linux/drivers/misc/parport_ieee1284_ops.c:1.1.2.10
--- linux/drivers/misc/parport_ieee1284_ops.c:1.1.4.1	Wed Dec 16 13:19:22 1998
+++ linux/drivers/misc/parport_ieee1284_ops.c	Wed Dec 16 15:55:54 1998
@@ -79,12 +79,6 @@
  * Host-to-peripheral data transfer functions *
  *                                          ***/
 
-static inline
-int polling (struct pardevice *dev)
-{
-	return !(dev->flags & PARPORT_DEV_IEEE1284IRQ);
-}
-
 /* Compatibility mode. */
 int parport_ieee1284_write_compat (struct parport *port,
                                    const void *buffer, size_t len,
@@ -135,7 +129,7 @@
                                 goto stop;
 
                         /* Yield the port for a while. */
-			if (count && polling (dev))
+			if (count)
                                 parport_release (dev);
                         timer.expires = jiffies + wait;
                         timer.data = (unsigned long) port;
@@ -143,10 +137,10 @@
                         add_timer (&timer);
                         down_interruptible (&port->ieee1284.sem);
                         del_timer (&timer);
-			if (count && polling (dev))
+			if (count)
                                 parport_claim_or_block (dev);
 
-			/* Is there a signal pending? */
+			/* We unblocked due a signal? */
                         if (signal_pending (current))
                                 goto stop;
 
Index: linux/drivers/misc/parport_pc.c
diff -u linux/drivers/misc/parport_pc.c:1.1.4.1 linux/drivers/misc/parport_pc.c:1.1.1.1.2.4
--- linux/drivers/misc/parport_pc.c:1.1.4.1	Wed Dec 16 13:19:22 1998
+++ linux/drivers/misc/parport_pc.c	Wed Dec 16 15:24:24 1998
@@ -322,7 +322,7 @@
 
         parport_ieee1284_write_compat,
         parport_ieee1284_read_nibble,
-	parport_ieee1284_read_byte
+	parport_ieee1284_read_byte,
 };
 
 /* --- Mode detection ------------------------------------- */
Index: linux/include/linux/lp.h
diff -u linux/include/linux/lp.h:1.1.4.1 linux/include/linux/lp.h:1.1.1.1.2.4
--- linux/include/linux/lp.h:1.1.4.1	Wed Dec 16 13:22:08 1998
+++ linux/include/linux/lp.h	Wed Dec 16 15:18:28 1998
@@ -97,8 +97,8 @@
 #define LP_STAT(minor)	lp_table[(minor)].stats		/* statistics area */
 #endif
 #define LP_BUFFER_SIZE 256
-
 #define LP_BASE(x)	lp_table[(x)].dev->port->base
+#define LP_ERR_WAITQ(x)	(&lp_table[(x)].err_waitq)
 
 #ifdef LP_STATS
 struct lp_stats {
@@ -123,7 +123,7 @@
         unsigned int runchars;
         struct lp_stats stats;
 #endif
-	struct wait_queue *wait_q;
+	struct wait_queue *err_waitq;
         unsigned int last_error;
 };
 
@@ -170,10 +170,18 @@
  */
 #define LP_DELAY 	50
 
+#define LP_PREEMPTED(minor) (lp_table[(minor)].dev->port->waithead != NULL)
+
 /*
  * function prototypes
  */
 
 extern int lp_init(void);
+
+extern __inline__ void wakeup_err_waitq(struct wait_queue ** err_waitq)
+{
+	if (waitqueue_active (err_waitq))
+		wake_up_interruptible (err_waitq);
+}
 
 #endif
This is an update to lp. We can' t use a static waitqueue for the LP_NO
printers. The waitqueue that we was used to use for irq driven operation
now is unused and we can use it for the error sleeping. Tell me if there'
s something not clear here (seems clear to me now). Theorically we should
do something very similar also in write_compat (where now I removed the
`&& polling (dev)')  to handle the irq and parport sharing as best...
Index: linux/drivers/char/lp.c
diff -u linux/drivers/char/lp.c:1.1.4.1 linux/drivers/char/lp.c:1.1.1.1.2.4
--- linux/drivers/char/lp.c:1.1.4.1	Wed Dec 16 13:18:43 1998
+++ linux/drivers/char/lp.c	Wed Dec 16 15:18:26 1998
@@ -155,17 +155,13 @@
 
 /* --- parport support ----------------------------------------- */
 
-static struct wait_queue *err_waitq;
-
 static int lp_preempt(void *handle)
 {
-       struct lp_struct *lps = (struct lp_struct *)handle;
-
-       if (waitqueue_active (&lps->wait_q))
-               wake_up_interruptible(&lps->wait_q);
+	struct lp_struct *lp_dev = (struct lp_struct *)handle;
+	wakeup_err_waitq(&lp_dev->err_waitq);
 
-       /* Don't actually release the port now */
-       return 1;
+	/* Don't actually release the port now */
+	return 1;
 }
 
 #define lp_parport_release(x)	do { parport_release(lp_table[(x)].dev); } while (0);
@@ -194,21 +190,42 @@
 {
         struct lp_struct *lp_dev = (struct lp_struct *) dev_id;
         parport_ieee1284_interrupt (irq, lp_dev->dev->port, regs);
-	if (waitqueue_active (&err_waitq))
-		wake_up_interruptible (&err_waitq);
+	wakeup_err_waitq(&lp_dev->err_waitq);
 }
 
+#define REVERT_TO_POLLING			\
+do {						\
+	sti();					\
+	goto polling;				\
+} while (0)
+
 static void lp_error (int minor)
 {
-	int polling;
+	int polled;
 
         if (LP_F(minor) & LP_ABORT)
                 return;
+
+	polled = !(lp_table[minor].dev->flags & PARPORT_DEV_IEEE1284IRQ);
 
-	polling = !(lp_table[minor].dev->flags & PARPORT_DEV_IEEE1284IRQ);
-	if (polling) lp_parport_release (minor);
-	interruptible_sleep_on_timeout (&err_waitq, LP_TIMEOUT_POLLED);
-	if (polling) lp_parport_claim (minor);
+	if (polled)
+	{
+	polling:
+		lp_parport_release (minor);
+		schedule_timeout(LP_TIMEOUT_POLLED);
+		lp_parport_claim (minor);
+	} else {
+		cli();
+		if (!LP_PREEMPTED(minor))
+		{
+			interruptible_sleep_on_timeout (LP_ERR_WAITQ(minor),
+							LP_TIMEOUT_INTERRUPT);
+			if (LP_PREEMPTED(minor))
+				REVERT_TO_POLLING;
+		} else
+			REVERT_TO_POLLING;
+		sti();
+	}
 }
 
 static int lp_check_status(int minor)
@@ -563,8 +580,6 @@
         unsigned int count = 0;
         unsigned int i;
         struct parport *port;
-
-	init_waitqueue (&err_waitq);
 
         switch (parport_nr[0])
         {
Andrea Arcangeli
--  To unsubscribe, send mail to: linux-parport-request@torque.net --
--  with the single word "unsubscribe" in the body of the message. --
This archive was generated by hypermail 2.0b3 on Wed 30 Dec 1998 - 10:18:56 EST