Re: [PARPORT] interrupt-driven lp


Andrea Arcangeli (arcangeli@mbox.queen.it)
Thu, 1 Jan 1998 18:58:35 +0100 (CET)


On Thu, 1 Jan 1998, Philip Blundell wrote:

>>I just fixed this yesterday. This allow ppa to run but the scheduling
>>remains a lot of broken (a lot of messages parport0: tring to release
>>parport...).
>
>I don't recognise that message. Can you be a bit more specific about what's
>wrong?

Well, I fixed all bugs in the parport-971230.diff patch. Now the sharing
is perfect. The patch is against parport-971230.diff (with lp.h patch
included).

Andrea[s] Arcangeli

--- linux/include/linux/parport.h 1997/12/31 16:05:03 1.1
+++ linux/include/linux/parport.h 1998/01/01 16:24:27
@@ -260,7 +260,9 @@
 extern int parport_claim(struct pardevice *dev);
 
 /* parport_claim_or_block is the same, but sleeps if the port cannot be
- claimed. It only fails in dire situations. */
+ * claimed. It only fails in dire situations.
+ * WARNING: Can' t be used in interrupt driven functions.
+ */
 extern int parport_claim_or_block(struct pardevice *dev);
 
 /* parport_release reverses a previous parport_claim. This can never fail,
@@ -274,16 +276,7 @@
 
 extern void parport_release(struct pardevice *dev);
 
-extern __inline__ unsigned int parport_yield(struct pardevice *dev,
- unsigned int block)
-{
- unsigned long int timeslip = (jiffies - dev->time);
- if ((timeslip < dev->timeslice) ||
- (atomic_read(&dev->port->waiters) == 0))
- return 1;
- parport_release(dev);
- return (block)?parport_claim_or_block(dev):parport_claim(dev);
-}
+#define PARPORT_YIELD(dev) (jiffies - (dev)->time > (dev)->timeslice)
 
 /* The "modes" entry in parport is a bit field representing the following
  * modes.
--- linux/include/linux/lp.h 1998/01/01 17:37:03 1.1
+++ linux/include/linux/lp.h 1998/01/01 17:37:13
@@ -115,6 +115,7 @@
         unsigned int runchars;
         unsigned int waittime;
         unsigned int should_relinquish;
+ unsigned int must_relinquish;
         struct lp_stats stats;
 };
 
--- linux/drivers/char/lp.c 1997/12/31 16:04:02 1.1
+++ linux/drivers/char/lp.c 1998/01/01 17:44:44
@@ -89,7 +89,7 @@
 struct lp_struct lp_table[LP_NO] =
 {
         [0 ... LP_NO-1] = {NULL, 0, LP_INIT_CHAR, LP_INIT_TIME, LP_INIT_WAIT,
- NULL, NULL, 0, 0, 0, 0, {0}}
+ NULL, NULL, 0, 0, 0, 0, 0, {0}}
 };
 
 /* Test if printer is ready (and optionally has no error conditions) */
@@ -132,8 +132,17 @@
 
 static __inline__ void lp_schedule (int minor)
 {
- if (parport_yield (lp_table[minor].dev, 1) == 1 && need_resched)
- schedule ();
+ struct pardevice *dev = lp_table[minor].dev;
+ if ((PARPORT_YIELD(dev) && lp_table[minor].should_relinquish) ||
+ lp_table[minor].must_relinquish)
+ {
+ lp_table[minor].should_relinquish = 0;
+ lp_table[minor].must_relinquish = 0;
+ parport_release(dev);
+ schedule();
+ parport_claim_or_block(dev);
+ } else
+ schedule();
 }
 
 static int lp_reset(int minor)
@@ -148,12 +157,6 @@
         return retval;
 }
 
-static inline int must_use_polling(int minor)
-{
- return lp_table[minor].dev->port->irq == PARPORT_IRQ_NONE ||
- lp_table[minor].dev->port->devices->next;
-}
-
 static inline int lp_char(char lpchar, int minor)
 {
         int status;
@@ -219,9 +222,10 @@
 
 static void lp_error(int minor)
 {
- if (LP_POLLING(minor)) {
+ if (LP_POLLING(minor) || lp_table[minor].should_relinquish) {
                 current->state = TASK_INTERRUPTIBLE;
                 current->timeout = jiffies + LP_TIMEOUT_POLLED;
+ lp_table[minor].must_relinquish = 1;
                 lp_schedule (minor);
         }
 }
--- linux/drivers/misc/parport_share.c 1998/01/01 16:39:06 1.1
+++ linux/drivers/misc/parport_share.c 1998/01/01 17:55:26
@@ -1,10 +1,11 @@
-/* parport_share.c,v 1.1 1998/01/01 16:39:06 andrea Exp
+/* $Id: parport_share.c,v 1.1 1998/01/01 16:39:06 andrea Exp andrea $
  * Parallel-port resource manager code.
  *
  * Authors: David Campbell <campbell@tirian.che.curtin.edu.au>
  * Tim Waugh <tim@cyberelk.demon.co.uk>
  * Jose Renau <renau@acm.org>
  * Philip Blundell <philb@gnu.org>
+ * Andrea Arcangeli <arcangeli@mbox.queen.it>
  *
  * based on work by Grant Guenther <grant@torque.net>
  * and Philip Blundell
@@ -104,6 +105,8 @@
         portcount++;
 
         tmp->probe_info.class = PARPORT_CLASS_LEGACY; /* assume the worst */
+
+ atomic_set(&tmp->waiters, 0);
         return tmp;
 }
 
@@ -312,13 +315,13 @@
 {
         int r;
         dev->time = jiffies;
- atomic_inc(&dev->port->waiters);
         r = parport_claim(dev);
         if (r == -EAGAIN) {
+ atomic_inc(&dev->port->waiters);
                 sleep_on(&dev->wait_q);
- r = parport_claim(dev); /* never fails */
+ atomic_dec(&dev->port->waiters);
+ return 0;
         }
- atomic_dec(&dev->port->waiters);
         return r;
 }
 
@@ -362,6 +365,7 @@
                                atomic_read(&port->waiters));
                         atomic_set(&port->waiters, 0);
                 } else {
+ parport_claim(oldest); /* never fails */
                         wake_up(&oldest->wait_q);
                         return;
                 }
@@ -379,8 +383,8 @@
                         }
                 }
         }
- for (pd = dev->port->devices; pd; pd = pd->next) {
- if (pd != dev && !(pd->flags & PARPORT_DEV_LURK)) {
+ for (pd = dev->port->devices; pd && pd != dev; pd = pd->next) {
+ if (!(pd->flags & PARPORT_DEV_LURK)) {
                         if (pd->wakeup) {
                                 pd->wakeup(pd->private);
                                 if (dev->port->cad)

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