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