Re: [PARPORT] Fast polling


Andrea Arcangeli (andrea@e-mind.com)
Thu, 17 Dec 1998 19:51:58 +0100 (CET)


On Thu, 17 Dec 1998, Andrea Arcangeli wrote:

>>I'm making a patch-2.1.131-ac11-1284-3 now, and will be uploading it soon.
>
>Could you send it to me by email as usual? (for sloww link reasons ;)

OK here my diff against it. The lp patch should be right. The polling
removed could be fixed in another way but it would be very tricky since we
should play with the preempt function of the pardevice.

Index: linux/drivers/char/lp.c
diff -u linux/drivers/char/lp.c:1.1.4.2 linux/drivers/char/lp.c:1.1.1.1.2.5
--- linux/drivers/char/lp.c:1.1.4.2 Thu Dec 17 19:06:15 1998
+++ linux/drivers/char/lp.c Wed Dec 16 19:46:58 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,22 +190,41 @@
 {
         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);
 }
 
 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)
- else parport_yield_blocking (lp_table[minor].dev);
+ 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))
+ {
+ sti();
+ goto polling;
+ }
+ } else {
+ sti();
+ goto polling;
+ }
+ sti();
+ }
 }
 
 static int lp_check_status(int minor)
@@ -564,8 +579,6 @@
         unsigned int count = 0;
         unsigned int i;
         struct parport *port;
-
- init_waitqueue (&err_waitq);
 
         switch (parport_nr[0])
         {
Index: linux/drivers/misc/parport_ieee1284.c
diff -u linux/drivers/misc/parport_ieee1284.c:1.1.4.2 linux/drivers/misc/parport_ieee1284.c:1.1.1.1.2.7
--- linux/drivers/misc/parport_ieee1284.c:1.1.4.2 Thu Dec 17 19:06:58 1998
+++ linux/drivers/misc/parport_ieee1284.c Wed Dec 16 19:16:14 1998
@@ -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) == -1)
+ DPRINTK (KERN_DEBUG "Woo hoo! Interrupt make sense!\n");
+#endif
         parport_ieee1284_wakeup (port);
 
         if (port->ieee1284.phase == IEEE1284_PH_REV_IDLE) {
Index: linux/drivers/misc/parport_ieee1284_ops.c
diff -u linux/drivers/misc/parport_ieee1284_ops.c:1.1.4.2 linux/drivers/misc/parport_ieee1284_ops.c:1.1.2.11
--- linux/drivers/misc/parport_ieee1284_ops.c:1.1.4.2 Thu Dec 17 19:06:59 1998
+++ linux/drivers/misc/parport_ieee1284_ops.c Thu Dec 17 19:27:43 1998
@@ -73,12 +73,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,
@@ -129,7 +123,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;
@@ -137,10 +131,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/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

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:57 EST