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