parport

Philip Blundell (Philip.Blundell@pobox.com)
Sat, 23 Aug 1997 18:09:12 -0000


Hi.

Would the people who've been having trouble with parallel port support
recently please try these patches. I'd like to hear reports of success or
failure.

p.

diff -u --recursive --exclude CVS clean/clean-linux/MAINTAINERS linux/MAINTAINERS
--- clean/clean-linux/MAINTAINERS Wed Aug 6 08:56:15 1997
+++ linux/MAINTAINERS Thu Aug 7 19:03:53 1997
@@ -443,7 +443,7 @@
P: Phil Blundell
M: Philip.Blundell@pobox.com
P: Tim Waugh
-M: tmw20@cyberelk.demon.co.uk
+M: tim@cyberelk.demon.co.uk
P: David Campbell
M: campbell@tirian.che.curtin.edu.au
L: linux-parport@torque.net
diff -u --recursive --exclude CVS clean/clean-linux/drivers/char/lp.c linux/drivers/char/lp.c
--- clean/clean-linux/drivers/char/lp.c Wed Aug 6 08:56:53 1997
+++ linux/drivers/char/lp.c Sat Aug 16 17:48:43 1997
@@ -36,11 +36,11 @@
/* if you have more than 3 printers, remember to increase LP_NO */
struct lp_struct lp_table[] =
{
- {NULL, 0, LP_INIT_CHAR, LP_INIT_TIME, LP_INIT_WAIT, NULL, NULL, 0, 0, 0,
+ {NULL, 0, LP_INIT_CHAR, LP_INIT_TIME, LP_INIT_WAIT, NULL, NULL, 0, 0, 0, 0,
{0}},
- {NULL, 0, LP_INIT_CHAR, LP_INIT_TIME, LP_INIT_WAIT, NULL, NULL, 0, 0, 0,
+ {NULL, 0, LP_INIT_CHAR, LP_INIT_TIME, LP_INIT_WAIT, NULL, NULL, 0, 0, 0, 0,
{0}},
- {NULL, 0, LP_INIT_CHAR, LP_INIT_TIME, LP_INIT_WAIT, NULL, NULL, 0, 0, 0,
+ {NULL, 0, LP_INIT_CHAR, LP_INIT_TIME, LP_INIT_WAIT, NULL, NULL, 0, 0, 0, 0,
{0}}
};
#define LP_NO 3
@@ -60,6 +60,41 @@
#undef LP_DEBUG
#undef LP_READ_DEBUG

+static inline void lp_parport_release (int minor)
+{
+ parport_release (lp_table[minor].dev);
+ lp_table[minor].should_relinquish = 0;
+}
+
+static inline void lp_parport_claim (int minor)
+{
+ if (parport_claim (lp_table[minor].dev))
+ sleep_on (&lp_table[minor].lp_wait_q);
+}
+
+static inline void lp_schedule (int minor)
+{
+ if (lp_table[minor].should_relinquish) {
+ lp_parport_release (minor);
+ schedule ();
+ lp_parport_claim (minor);
+ }
+ else
+ schedule ();
+}
+
+
+static int lp_preempt (void *handle)
+{
+ struct lp_struct *lps = (struct lp_struct *)handle;
+
+ /* Just remember that someone wants the port */
+ lps->should_relinquish = 1;
+
+ /* Don't actually release the port now */
+ return 1;
+}
+
static int lp_reset(int minor)
{
w_ctr(minor, LP_PSELECP);
@@ -70,7 +105,8 @@

static inline int lp_char_polled(char lpchar, int minor)
{
- int status, wait = 0;
+ int status;
+ unsigned int wait = 0;
unsigned long count = 0;
struct lp_stats *stats;

@@ -78,7 +114,7 @@
status = r_str(minor);
count++;
if (need_resched)
- schedule();
+ lp_schedule (minor);
} while (!LP_READY(minor, status) && count < LP_CHAR(minor));

if (count == LP_CHAR(minor)) {
@@ -90,11 +126,11 @@
stats->chars++;
/* must wait before taking strobe high, and after taking strobe
low, according spec. Some printers need it, others don't. */
- while (wait != LP_WAIT(minor))
+ while (wait != LP_WAIT(minor)) /* FIXME: should be a udelay() */
wait++;
/* control port takes strobe high */
w_ctr(minor, LP_PSELECP | LP_PINITP | LP_PSTROBE);
- while (wait)
+ while (wait) /* FIXME: should be a udelay() */
wait--;
/* take strobe low */
w_ctr(minor, LP_PSELECP | LP_PINITP);
@@ -116,14 +152,14 @@

static inline int lp_char_interrupt(char lpchar, int minor)
{
- int wait;
+ unsigned int wait;
unsigned long count = 0;
unsigned char status;
struct lp_stats *stats;

do {
if(need_resched)
- schedule();
+ lp_schedule (minor);
if ((status = r_str(minor)) & LP_PBUSY) {
if (!LP_CAREFUL_READY(minor, status))
return 0;
@@ -133,12 +169,12 @@
/* must wait before taking strobe high, and after taking strobe
low, according spec. Some printers need it, others don't. */
wait = 0;
- while (wait != LP_WAIT(minor))
- wait++;
+ while (wait != LP_WAIT(minor)) /* FIXME: should be */
+ wait++; /* a udelay () */
/* control port takes strobe high */
w_ctr(minor, LP_PSELECP | LP_PINITP | LP_PSTROBE);
while (wait)
- wait--;
+ wait--; /* FIXME: should be a udelay() */
/* take strobe low */
w_ctr(minor, LP_PSELECP | LP_PINITP);
/* update waittime statistics */
@@ -164,7 +200,7 @@
struct pardevice *pd = pb->cad;
struct lp_struct *lp_dev = (struct lp_struct *) pd->private;

- if (lp_dev->lp_wait_q)
+ if (waitqueue_active (&lp_dev->lp_wait_q))
wake_up(&lp_dev->lp_wait_q);
}

@@ -221,7 +257,14 @@
}
lp_table[minor].runchars = 0;
current->timeout = jiffies + LP_TIMEOUT_INTERRUPT;
- interruptible_sleep_on(&lp->lp_wait_q);
+ if (lp->should_relinquish) {
+ lp_parport_release (minor);
+ interruptible_sleep_on (&lp->lp_wait_q);
+ lp_parport_claim (minor);
+ }
+ else
+ interruptible_sleep_on(&lp->lp_wait_q);
+
w_ctr(minor, LP_PSELECP | LP_PINITP);
sti();
if (current->signal & ~current->blocked) {
@@ -267,7 +310,7 @@
return temp-buf?temp-buf:-ENOSPC;
current->state = TASK_INTERRUPTIBLE;
current->timeout = jiffies + LP_TIMEOUT_POLLED;
- schedule();
+ lp_schedule (minor);
} else
if (!(status & LP_PSELECD)) {
printk(KERN_INFO "lp%d off-line\n", minor);
@@ -275,7 +318,7 @@
return temp-buf?temp-buf:-EIO;
current->state = TASK_INTERRUPTIBLE;
current->timeout = jiffies + LP_TIMEOUT_POLLED;
- schedule();
+ lp_schedule (minor);
} else
/* not offline or out of paper. on fire? */
if (!(status & LP_PERRORP)) {
@@ -284,7 +327,7 @@
return temp-buf?temp-buf:-EIO;
current->state = TASK_INTERRUPTIBLE;
current->timeout = jiffies + LP_TIMEOUT_POLLED;
- schedule();
+ lp_schedule (minor);
}

/* check for signals before going to sleep */
@@ -302,7 +345,7 @@
lp_table[minor].runchars=0;
current->state = TASK_INTERRUPTIBLE;
current->timeout = jiffies + LP_TIME(minor);
- schedule();
+ lp_schedule (minor);
}
}
return temp-buf;
@@ -322,16 +365,14 @@
/* Claim Parport or sleep until it becomes available
* (see lp_wakeup() for details)
*/
- if (parport_claim(lp_table[minor].dev)) {
- sleep_on(&lp_table[minor].lp_wait_q);
- lp_table[minor].lp_wait_q = NULL;
- }
+ lp_parport_claim (minor);
+
if (LP_IRQ(minor) > 0)
retv = lp_write_interrupt(minor, buf, count);
else
retv = lp_write_polled(minor, buf, count);

- parport_release(lp_table[minor].dev);
+ lp_parport_release (minor);
return retv;
}

@@ -370,10 +411,7 @@
/* Claim Parport or sleep until it becomes available
* (see lp_wakeup() for details)
*/
- if (parport_claim(lp_table[minor].dev)) {
- sleep_on(&lp_table[minor].lp_wait_q);
- lp_table[minor].lp_wait_q = NULL;
- }
+ lp_parport_claim (minor);

temp=buf;
#ifdef LP_READ_DEBUG
@@ -399,7 +437,7 @@
udelay(50);
counter++;
if (need_resched)
- schedule();
+ lp_schedule (minor);
} while ( (status == 0x40) && (counter < 20) );
if ( counter == 20 ) { /* Timeout */
#ifdef LP_READ_DEBUG
@@ -418,7 +456,7 @@
udelay(20);
counter++;
if (need_resched)
- schedule();
+ lp_schedule (minor);
} while ( (status == 0) && (counter < 20) );
if (counter == 20) { /* Timeout */
#ifdef LP_READ_DEBUG
@@ -434,7 +472,7 @@
}
current->state=TASK_INTERRUPTIBLE;
current->timeout=jiffies + LP_TIME(minor);
- schedule();
+ lp_schedule (minor);
}
counter=0;
if (( i & 1) != 0) {
@@ -656,7 +694,7 @@
{
struct lp_struct *lp_dev = (struct lp_struct *) ref;

- if (!lp_dev->lp_wait_q)
+ if (!waitqueue_active (&lp_dev->lp_wait_q))
return; /* Wake up whom? */

/* Claim the Parport */
@@ -691,8 +729,8 @@
(parport[0] == -3 &&
pb->probe_info.class == PARPORT_CLASS_PRINTER)) {
lp_table[count].dev =
- parport_register_device(pb, dev_name, NULL,
- lp_wakeup,
+ parport_register_device(pb, dev_name,
+ lp_preempt, lp_wakeup,
lp_interrupt, PARPORT_DEV_TRAN,
(void *) &lp_table[count]);
lp_table[count].flags |= LP_EXIST;
diff -u --recursive --exclude CVS clean/clean-linux/drivers/misc/BUGS-parport linux/drivers/misc/BUGS-parport
--- clean/clean-linux/drivers/misc/BUGS-parport Thu Jul 31 19:17:33 1997
+++ linux/drivers/misc/BUGS-parport Thu Aug 7 19:03:15 1997
@@ -1,12 +1,5 @@
Currently known (or at least suspected) bugs in parport:

-o /proc/parport is untested under 2.0.XX
-
-o SCSI aborts for PPA under 2.0.29 [reported by jmr]. Under investigation.
-
-o make config (etc) allow you to select CONFIG_PNP_PARPORT=m, CONFIG_PPA=y -
- the resulting kernel won't link.
-
o IEEE1284 code does not do the terminating handshake after transfers, which
seems to upset some devices.

diff -u --recursive --exclude CVS clean/clean-linux/drivers/misc/parport_arc.c linux/drivers/misc/parport_arc.c
--- clean/clean-linux/drivers/misc/parport_arc.c Wed Aug 6 08:56:56 1997
+++ linux/drivers/misc/parport_arc.c Sat Aug 16 17:26:16 1997
@@ -1,7 +1,6 @@
-/* $Id$
- * Parallel-port routines for ARC onboard hardware.
+/* Parallel-port routines for ARC onboard hardware.
*
- * Author: Phil Blundell <pjb27@cam.ac.uk>
+ * Author: Phil Blundell <Philip.Blundell@pobox.com>
*/

#include <linux/tasks.h>
@@ -37,6 +36,20 @@
return data_copy;
}

+static void arc_inc_use_count(void)
+{
+#ifdef MODULE
+ MOD_INC_USE_COUNT;
+#endif
+}
+
+static void arc_dec_use_count(void)
+{
+#ifdef MODULE
+ MOD_DEC_USE_COUNT;
+#endif
+}
+
static struct parport_operations arc_ops =
{
arc_write_data,
@@ -72,5 +85,8 @@

arc_enable_irq,
arc_disable_irq,
- arc_examine_irq
+ arc_examine_irq,
+
+ arc_inc_use_count,
+ arc_dec_use_count
};
diff -u --recursive --exclude CVS clean/clean-linux/drivers/misc/parport_ieee1284.c linux/drivers/misc/parport_ieee1284.c
--- clean/clean-linux/drivers/misc/parport_ieee1284.c Thu Jul 31 19:17:33 1997
+++ linux/drivers/misc/parport_ieee1284.c Sat Aug 16 17:26:36 1997
@@ -1,7 +1,6 @@
-/* $Id$
- * IEEE-1284 implementation for parport.
+/* IEEE-1284 implementation for parport.
*
- * Authors: Philip Blundell <pjb27@cam.ac.uk>
+ * Authors: Phil Blundell <Philip.Blundell@pobox.com>
* Carsten Gross <carsten@sol.wohnheim.uni-ulm.de>
* Jose Renau <renau@acm.org>
*/
diff -u --recursive --exclude CVS clean/clean-linux/drivers/misc/parport_init.c linux/drivers/misc/parport_init.c
--- clean/clean-linux/drivers/misc/parport_init.c Wed Aug 6 08:56:56 1997
+++ linux/drivers/misc/parport_init.c Sat Aug 16 17:26:23 1997
@@ -1,8 +1,7 @@
-/* $Id: parport_init.c,v 1.1.2.2 1997/04/18 15:00:52 phil Exp $
- * Parallel-port initialisation code.
+/* Parallel-port initialisation code.
*
* Authors: David Campbell <campbell@tirian.che.curtin.edu.au>
- * Tim Waugh <tmw20@cam.ac.uk>
+ * Tim Waugh <tim@cyberelk.demon.co.uk>
* Jose Renau <renau@acm.org>
*
* based on work by Grant Guenther <grant@torque.net>
@@ -62,17 +61,6 @@

void cleanup_module(void)
{
- struct parport *port, *next;
-
- for (port = parport_enumerate(); port; port = next) {
- next = port->next;
- if (!(port->flags & PARPORT_FLAG_COMA))
- parport_quiesce(port);
- parport_proc_unregister(port);
- kfree(port->name);
- kfree(port);
- }
-
parport_proc_cleanup();
}
#else
diff -u --recursive --exclude CVS clean/clean-linux/drivers/misc/parport_pc.c linux/drivers/misc/parport_pc.c
--- clean/clean-linux/drivers/misc/parport_pc.c Sat Aug 16 16:11:06 1997
+++ linux/drivers/misc/parport_pc.c Sat Aug 16 16:35:47 1997
@@ -1,13 +1,11 @@
-/* $Id: parport_pc.c,v 1.1.2.3 1997/04/18 15:00:52 phil Exp $
- * Parallel-port routines for PC architecture
+/* Parallel-port routines for PC architecture
*
- * Authors: Phil Blundell <pjb27@cam.ac.uk>
- * Tim Waugh <tmw20@cam.ac.uk>
+ * Authors: Phil Blundell <Philip.Blundell@pobox.com>
+ * Tim Waugh <tim@cyberelk.demon.co.uk>
* Jose Renau <renau@acm.org>
* David Campbell <campbell@tirian.che.curtin.edu.au>
*
- * based on work by Grant Guenther <grant@torque.net>
- * and Philip Blundell <Philip.Blundell@pobox.com>
+ * based on work by Grant Guenther <grant@torque.net> and Phil Blundell.
*/

#include <linux/stddef.h>
@@ -162,12 +160,14 @@

static void pc_save_state(struct parport *p, struct parport_state *s)
{
- /* FIXME */
+ s->u.pc.ctr = pc_read_control(p);
+ s->u.pc.ecr = pc_read_econtrol(p);
}

static void pc_restore_state(struct parport *p, struct parport_state *s)
{
- /* FIXME */
+ pc_write_control(p, s->u.pc.ctr);
+ pc_write_econtrol(p, s->u.pc.ecr);
}

static unsigned int pc_epp_read_block(struct parport *p, void *buf, unsigned int length)
@@ -195,6 +195,20 @@
return 0; /* FIXME */
}

+static void pc_inc_use_count(void)
+{
+#ifdef MODULE
+ MOD_INC_USE_COUNT;
+#endif
+}
+
+static void pc_dec_use_count(void)
+{
+#ifdef MODULE
+ MOD_DEC_USE_COUNT;
+#endif
+}
+
static struct parport_operations pc_ops =
{
pc_write_data,
@@ -230,7 +244,10 @@

pc_enable_irq,
pc_disable_irq,
- pc_examine_irq
+ pc_examine_irq,
+
+ pc_inc_use_count,
+ pc_dec_use_count
};

/******************************************************
@@ -322,7 +339,6 @@
return dma;
}

-#if 0
/* Only called if port supports ECP mode.
*
* The only restriction on DMA channels is that it has to be
@@ -388,7 +404,6 @@

return retv;
}
-#endif

/******************************************************
* MODE detection section:
@@ -449,18 +464,20 @@
oecr = pc_read_econtrol(pb);

r = pc_read_control(pb);
- if ((pc_read_econtrol(pb) & 0x03) == (r & 0x03)) {
- pc_write_control(pb, r ^ 0x03 ); /* Toggle bits 0-1 */
+ if ((pc_read_econtrol(pb) & 0x3) == (r & 0x3)) {
+ pc_write_control(pb, r ^ 0x2 ); /* Toggle bit 1 */

- r= pc_read_control(pb);
- if ((pc_read_econtrol(pb) & 0x03) == (r & 0x03))
+ r = pc_read_control(pb);
+ if ((pc_read_econtrol(pb) & 0x2) == (r & 0x2)) {
+ pc_write_control(pb, octr);
return 0; /* Sure that no ECR register exists */
+ }
}

- if ((pc_read_econtrol(pb) & 0x03 ) != 0x01)
+ if ((pc_read_econtrol(pb) & 0x3 ) != 0x1)
return 0;

- pc_write_econtrol(pb,0x34);
+ pc_write_econtrol(pb, 0x34);
if (pc_read_econtrol(pb) != 0x35)
return 0;

@@ -846,6 +863,10 @@
#undef printmode
printk("]\n");
parport_proc_register(p);
+
+ /* Done probing. Now put the port into a sensible start-up state. */
+ pc_write_control(p, 0xc);
+ pc_write_data(p, 0);
return 1;
}

@@ -877,22 +898,23 @@
MODULE_PARM(irq, "1-" __MODULE_STRING(PC_MAX_PORTS) "i");
MODULE_PARM(dma, "1-" __MODULE_STRING(PC_MAX_PORTS) "i");

-static int init_module(void)
+int init_module(void)
{
return (parport_pc_init(io, irq, dma)?0:1);
}

-static void cleanup_module(void)
+void cleanup_module(void)
{
- struct parport *p = parport_enumerate();
+ struct parport *p = parport_enumerate(), *tmp;
while (p) {
+ tmp = p->next;
if (p->modes & PARPORT_MODE_PCSPP) {
if (!(p->flags & PARPORT_FLAG_COMA))
parport_quiesce(p);
parport_proc_unregister(p);
parport_unregister_port(p);
}
- p = p->next;
+ p = tmp;
}
}
#endif
diff -u --recursive --exclude CVS clean/clean-linux/drivers/misc/parport_procfs.c linux/drivers/misc/parport_procfs.c
--- clean/clean-linux/drivers/misc/parport_procfs.c Wed Aug 6 08:56:57 1997
+++ linux/drivers/misc/parport_procfs.c Sat Aug 16 17:26:29 1997
@@ -1,5 +1,4 @@
-/* $Id: parport_procfs.c,v 1.1.2.2 1997/04/18 15:00:52 phil Exp $
- * Parallel port /proc interface code.
+/* Parallel port /proc interface code.
*
* Authors: David Campbell <campbell@tirian.che.curtin.edu.au>
* Tim Waugh <tmw20@cam.ac.uk>
diff -u --recursive --exclude CVS clean/clean-linux/drivers/misc/parport_share.c linux/drivers/misc/parport_share.c
--- clean/clean-linux/drivers/misc/parport_share.c Wed Aug 6 08:56:57 1997
+++ linux/drivers/misc/parport_share.c Sat Aug 16 17:26:12 1997
@@ -1,8 +1,7 @@
-/* $Id: parport_share.c,v 1.1.2.2 1997/04/18 15:00:52 phil Exp $
- * Parallel-port resource manager code.
+/* Parallel-port resource manager code.
*
* Authors: David Campbell <campbell@tirian.che.curtin.edu.au>
- * Tim Waugh <tmw20@cam.ac.uk>
+ * Tim Waugh <tim@cyberelk.demon.co.uk>
* Jose Renau <renau@acm.org>
*
* based on work by Grant Guenther <grant@torque.net>
@@ -19,6 +18,10 @@
#include <linux/kernel.h>
#include <linux/malloc.h>

+#ifdef CONFIG_KERNELD
+#include <linux/kerneld.h>
+#endif
+
#undef PARPORT_PARANOID

static struct parport *portlist = NULL, *portlist_tail = NULL;
@@ -27,6 +30,10 @@
/* Return a list of all the ports we know about. */
struct parport *parport_enumerate(void)
{
+#ifdef CONFIG_KERNELD
+ if (portlist == NULL)
+ request_module("parport_lowlevel");
+#endif
return portlist;
}

@@ -93,7 +100,8 @@
struct parport *p;
kfree(port->name);
if (portlist == port) {
- portlist = port->next;
+ if ((portlist = port->next) == NULL)
+ portlist_tail = NULL;
} else {
for (p = portlist; (p != NULL) && (p->next != port);
p=p->next);
@@ -184,6 +192,7 @@
port->lurker = tmp;

inc_parport_count();
+ port->ops->inc_use_count();

return tmp;
}
@@ -218,6 +227,7 @@
kfree(dev);

dec_parport_count();
+ port->ops->dec_use_count();

/* If there are no more devices, put the port to sleep. */
if (!port->devices)
diff -u --recursive --exclude CVS clean/clean-linux/drivers/net/Config.in linux/drivers/net/Config.in
--- clean/clean-linux/drivers/net/Config.in Sat Aug 16 16:11:06 1997
+++ linux/drivers/net/Config.in Sat Aug 16 16:32:54 1997
@@ -123,8 +123,8 @@
fi
fi

-if [ ! "$CONFIG_PNP_PARPORT" = "n" ]; then
- dep_tristate 'PLIP (parallel port) support' CONFIG_PLIP $CONFIG_PNP_PARPORT
+if [ ! "$CONFIG_PARPORT" = "n" ]; then
+ dep_tristate 'PLIP (parallel port) support' CONFIG_PLIP $CONFIG_PARPORT
fi

tristate 'PPP (point-to-point) support' CONFIG_PPP
diff -u --recursive --exclude CVS clean/clean-linux/drivers/pnp/parport_probe.c linux/drivers/pnp/parport_probe.c
--- clean/clean-linux/drivers/pnp/parport_probe.c Wed Aug 6 08:57:03 1997
+++ linux/drivers/pnp/parport_probe.c Sat Aug 16 17:50:13 1997
@@ -52,7 +52,7 @@
{
int i;
char *temp=buf;
- int count = 0;
+ unsigned int count = 0;
unsigned char z=0;
unsigned char Byte=0;

diff -u --recursive --exclude CVS clean/clean-linux/drivers/scsi/Config.in linux/drivers/scsi/Config.in
--- clean/clean-linux/drivers/scsi/Config.in Sat Aug 16 16:11:21 1997
+++ linux/drivers/scsi/Config.in Sat Aug 16 16:33:07 1997
@@ -84,8 +84,8 @@
if [ "$CONFIG_MCA" = "y" ]; then
dep_tristate 'IBMMCA SCSI support' CONFIG_SCSI_IBMMCA $CONFIG_SCSI
fi
-if [ "$CONFIG_PNP_PARPORT" != "n" ]; then
- dep_tristate 'IOMEGA Parallel Port ZIP drive SCSI support' CONFIG_SCSI_PPA $CONFIG_SCSI $CONFIG_PNP_PARPORT
+if [ "$CONFIG_PARPORT" != "n" ]; then
+ dep_tristate 'IOMEGA Parallel Port ZIP drive SCSI support' CONFIG_SCSI_PPA $CONFIG_SCSI $CONFIG_PARPORT
if [ "$CONFIG_SCSI_PPA" != "n" ]; then
int ' Pedantic EPP-checking' CONFIG_SCSI_PPA_HAVE_PEDANTIC 2 0 3
int ' EPP timeout' CONFIG_SCSI_PPA_EPP_TIME 128
diff -u --recursive --exclude CVS clean/clean-linux/include/linux/lp.h linux/include/linux/lp.h
--- clean/clean-linux/include/linux/lp.h Thu Jul 31 19:15:24 1997
+++ linux/include/linux/lp.h Sat Aug 16 17:28:32 1997
@@ -123,6 +123,7 @@
unsigned int lastcall;
unsigned int runchars;
unsigned int waittime;
+ unsigned int should_relinquish;
struct lp_stats stats;
};

diff -u --recursive --exclude CVS clean/clean-linux/include/linux/parport.h linux/include/linux/parport.h
--- clean/clean-linux/include/linux/parport.h Wed Aug 6 08:57:45 1997
+++ linux/include/linux/parport.h Sat Aug 16 16:50:08 1997
@@ -81,6 +81,9 @@
void (*enable_irq)(struct parport *);
void (*disable_irq)(struct parport *);
int (*examine_irq)(struct parport *);
+
+ void (*inc_use_count)(void);
+ void (*dec_use_count)(void);
};

#define PARPORT_CONTROL_STROBE 0x1
diff -u --recursive --exclude CVS /tmp/linux-16/drivers/char/lp.c linux/drivers/char/lp.c
--- /tmp/linux-16/drivers/char/lp.c Sun Aug 17 15:56:20 1997
+++ linux/drivers/char/lp.c Sun Aug 17 15:24:59 1997
@@ -247,7 +247,8 @@
}
LP_STAT(minor).sleeps++;
cli();
- w_ctr(minor, LP_PSELECP | LP_PINITP | LP_PINTEN);
+ enable_irq(lp->dev->port->irq);
+ w_ctr(minor, LP_PSELECP|LP_PINITP|LP_PINTEN);
status = r_str(minor);
if ((!(status & LP_PACK) || (status & LP_PBUSY))
&& LP_CAREFUL_READY(minor, status)) {
@@ -257,13 +258,7 @@
}
lp_table[minor].runchars = 0;
current->timeout = jiffies + LP_TIMEOUT_INTERRUPT;
- if (lp->should_relinquish) {
- lp_parport_release (minor);
- interruptible_sleep_on (&lp->lp_wait_q);
- lp_parport_claim (minor);
- }
- else
- interruptible_sleep_on(&lp->lp_wait_q);
+ interruptible_sleep_on(&lp->lp_wait_q);

w_ctr(minor, LP_PSELECP | LP_PINITP);
sti();
diff -u --recursive --exclude CVS /tmp/linux-16/drivers/misc/parport_pc.c linux/drivers/misc/parport_pc.c
--- /tmp/linux-16/drivers/misc/parport_pc.c Sun Aug 17 15:56:20 1997
+++ linux/drivers/misc/parport_pc.c Sun Aug 17 15:33:24 1997
@@ -151,7 +151,7 @@
{
/* FIXME check that resources are free */
if (p->irq != PARPORT_IRQ_NONE)
- request_irq(p->irq, pc_null_intr_func, 0, p->name, NULL);
+ request_irq(p->irq, pc_null_intr_func, 0, p->name, p);
request_region(p->base, p->size, p->name);
if (p->modes & PARPORT_MODE_PCECR)
request_region(p->base+0x400, 3, p->name);
@@ -863,6 +863,7 @@
#undef printmode
printk("]\n");
parport_proc_register(p);
+ p->flags |= PARPORT_FLAG_COMA;

/* Done probing. Now put the port into a sensible start-up state. */
pc_write_control(p, 0xc);
@@ -881,11 +882,8 @@
} else {
/* Probe all the likely ports. */
count += probe_one_port(0x378, PARPORT_IRQ_AUTO, PARPORT_DMA_AUTO);
-
-#if defined(__i386__)
count += probe_one_port(0x278, PARPORT_IRQ_AUTO, PARPORT_DMA_AUTO);
count += probe_one_port(0x3bc, PARPORT_IRQ_AUTO, PARPORT_DMA_AUTO);
-#endif
}
return count;
}