[PATCH] Printing problems?

Tim Waugh (tim@cyberelk.demon.co.uk)
Mon, 3 May 1999 18:26:26 +0100 (GMT)


If you are having trouble printing, please try this patch and let me know
whether it has any effect.

If you _aren't_ having trouble printing, please try this patch anyway and
let me know that it doesn't break anything. ;-)

The two things addressed by this patch are:
- parallel port chips that have write-only control ports, and
- printers that are sloppy with PError and Select when nothing's wrong.

The problem that you might see fixed by this patch is that things worked
in 2.0 but don't in 2.2.

Let me know of successes and failures..

Thanks,
Tim.
*/

diff -durN linux-2.2.7/drivers/char/lp.c linux-2.2.7-ctr/drivers/char/lp.c
--- linux-2.2.7/drivers/char/lp.c Wed Mar 24 01:42:57 1999
+++ linux-2.2.7-ctr/drivers/char/lp.c Mon May 3 18:20:26 1999
@@ -202,9 +202,7 @@
/* Test if the printer is not acking the strobe */
#define LP_NO_ACKING(status) ((status) & LP_PACK)
/* Test if the printer has error conditions */
-#define LP_NO_ERROR(status) \
- (((status) & (LP_POUTPA|LP_PSELECD|LP_PERRORP)) == \
- (LP_PSELECD|LP_PERRORP))
+#define LP_NO_ERROR(status) ((status) & LP_PERRORP)

#undef LP_DEBUG
#undef LP_READ_DEBUG
@@ -424,7 +422,10 @@
{
unsigned int last = lp_table[minor].last_error;
unsigned char status = r_str(minor);
- if ((status & LP_POUTPA)) {
+ if (status & LP_PERRORP)
+ /* No error. */
+ last = 0;
+ else if ((status & LP_POUTPA)) {
if (last != LP_POUTPA) {
last = LP_POUTPA;
printk(KERN_INFO "lp%d out of paper\n", minor);
@@ -434,13 +435,12 @@
last = LP_PSELECD;
printk(KERN_INFO "lp%d off-line\n", minor);
}
- } else if (!(status & LP_PERRORP)) {
+ } else {
if (last != LP_PERRORP) {
last = LP_PERRORP;
- printk(KERN_INFO "lp%d on fire!\n", minor);
+ printk(KERN_INFO "lp%d on fire\n", minor);
}
}
- else last = 0;

lp_table[minor].last_error = last;

diff -durN linux-2.2.7/drivers/misc/parport_ieee1284.c linux-2.2.7-ctr/drivers/misc/parport_ieee1284.c
--- linux-2.2.7/drivers/misc/parport_ieee1284.c Wed Mar 24 01:42:59 1999
+++ linux-2.2.7-ctr/drivers/misc/parport_ieee1284.c Mon May 3 12:50:21 1999
@@ -26,7 +26,7 @@
unsigned char status;

for (counter = 0; counter < 20; counter++) {
- status = parport_read_status(port);
+ status = port->ops->read_status(port);
if ((status & mask) == result)
return 0;
udelay(25);
@@ -35,7 +35,7 @@
}
current->state = TASK_INTERRUPTIBLE;
schedule_timeout(HZ/25); /* wait for 40ms */
- status = parport_read_status(port);
+ status = port->ops->read_status(port);
return ((status & mask) == result)?0:1;
}

@@ -48,27 +48,24 @@
int parport_ieee1284_nibble_mode_ok(struct parport *port, unsigned char mode)
{
/* make sure it's a valid state, set nStrobe & nAutoFeed high */
- parport_write_control(port, (parport_read_control(port) \
- & ~1 ) & ~2);
+ port->ops->frob_control (port, 0x3, 0x0);
udelay(1);
- parport_write_data(port, mode);
+ port->ops->write_data(port, mode);
udelay(400);
/* nSelectIn high, nAutoFd low */
- parport_write_control(port, (parport_read_control(port) & ~8) | 2);
+ port->ops->frob_control(port, 0xa, 0x2);
if (parport_wait_peripheral(port, 0x78, 0x38)) {
- parport_write_control(port,
- (parport_read_control(port) & ~2) | 8);
+ port->ops->frob_control(port, 0xa, 0x8);
return 0;
}
/* nStrobe low */
- parport_write_control(port, parport_read_control(port) | 1);
+ port->ops->frob_control (port, 1, 1);
udelay(1); /* Strobe wait */
/* nStrobe high, nAutoFeed low, last step before transferring
* reverse data */
- parport_write_control(port, (parport_read_control(port) \
- & ~1) & ~2);
+ port->ops->frob_control (port, 3, 0);
udelay(1);
/* Data available? */
parport_wait_peripheral (port, PARPORT_STATUS_ACK, PARPORT_STATUS_ACK);
- return (parport_read_status(port) & PARPORT_STATUS_ERROR)?1:2;
+ return (port->ops->read_status(port) & PARPORT_STATUS_ERROR)?1:2;
}
diff -durN linux-2.2.7/drivers/misc/parport_init.c linux-2.2.7-ctr/drivers/misc/parport_init.c
--- linux-2.2.7/drivers/misc/parport_init.c Sun Jan 3 01:55:05 1999
+++ linux-2.2.7-ctr/drivers/misc/parport_init.c Mon May 3 13:28:19 1999
@@ -131,7 +131,6 @@
#endif

/* Exported symbols for modules. */
-
EXPORT_SYMBOL(parport_claim);
EXPORT_SYMBOL(parport_claim_or_block);
EXPORT_SYMBOL(parport_release);
diff -durN linux-2.2.7/drivers/misc/parport_pc.c linux-2.2.7-ctr/drivers/misc/parport_pc.c
--- linux-2.2.7/drivers/misc/parport_pc.c Wed Mar 24 01:42:59 1999
+++ linux-2.2.7-ctr/drivers/misc/parport_pc.c Mon May 3 18:10:03 1999
@@ -103,19 +103,24 @@

void parport_pc_write_control(struct parport *p, unsigned char d)
{
+ struct parport_pc_private *priv = p->private_data;
+ priv->ctr = d;/* update soft copy */
outb(d, p->base+CONTROL);
}

unsigned char parport_pc_read_control(struct parport *p)
{
- return inb(p->base+CONTROL);
+ struct parport_pc_private *priv = p->private_data;
+ return priv->ctr;
}

unsigned char parport_pc_frob_control(struct parport *p, unsigned char mask, unsigned char val)
{
- unsigned char old = inb(p->base+CONTROL);
- outb(((old & ~mask) ^ val), p->base+CONTROL);
- return old;
+ struct parport_pc_private *priv = p->private_data;
+ unsigned char ctr = priv->ctr;
+ ctr = (ctr & ~mask) ^ val;
+ outb (ctr, p->base+CONTROL);
+ return priv->ctr = ctr; /* update soft copy */
}

void parport_pc_write_status(struct parport *p, unsigned char d)
@@ -712,6 +717,15 @@
if (check_region(base, 3)) return 0;
if (!(p = parport_register_port(base, irq, dma, &parport_pc_ops)))
return 0;
+ p->private_data = kmalloc (sizeof (struct parport_pc_private),
+ GFP_KERNEL);
+ if (!p->private_data) {
+ /* Not enough memory. */
+ printk (KERN_DEBUG "parport (0x%lx): no memory!\n", base);
+ parport_unregister_port (p);
+ return 0;
+ }
+ ((struct parport_pc_private *) (p->private_data))->ctr = 0xc;
if (p->base != 0x3bc) {
if (!check_region(base+0x400,3)) {
p->modes |= parport_ECR_present(p);
@@ -725,6 +739,7 @@
}
if (!parport_SPP_supported(p)) {
/* No port. */
+ kfree (p->private_data);
parport_unregister_port (p);
return 0;
}
@@ -829,6 +844,7 @@
if (!(p->flags & PARPORT_FLAG_COMA))
parport_quiesce(p);
parport_proc_unregister(p);
+ kfree (p->private_data);
parport_unregister_port(p);
}
p = tmp;
diff -durN linux-2.2.7/include/linux/parport_pc.h linux-2.2.7-ctr/include/linux/parport_pc.h
--- linux-2.2.7/include/linux/parport_pc.h Tue Jan 26 00:04:37 1999
+++ linux-2.2.7-ctr/include/linux/parport_pc.h Mon May 3 13:28:04 1999
@@ -14,8 +14,15 @@
#define STATUS 0x1
#define DATA 0

+/* Private data for PC low-level driver. */
+struct parport_pc_private {
+ /* Contents of CTR. */
+ unsigned char ctr;
+};
+
extern int parport_pc_epp_clear_timeout(struct parport *pb);

+extern volatile unsigned char parport_pc_ctr;

extern __inline__ void parport_pc_write_epp(struct parport *p, unsigned char d)
{
@@ -62,19 +69,24 @@

extern __inline__ void parport_pc_write_control(struct parport *p, unsigned char d)
{
+ struct parport_pc_private *priv = p->private_data;
+ priv->ctr = d;/* update soft copy */
outb(d, p->base+CONTROL);
}

extern __inline__ unsigned char parport_pc_read_control(struct parport *p)
{
- return inb(p->base+CONTROL);
+ struct parport_pc_private *priv = p->private_data;
+ return priv->ctr;
}

extern __inline__ unsigned char parport_pc_frob_control(struct parport *p, unsigned char mask, unsigned char val)
{
- unsigned char old = inb(p->base+CONTROL);
- outb(((old & ~mask) ^ val), p->base+CONTROL);
- return old;
+ struct parport_pc_private *priv = p->private_data;
+ unsigned char ctr = priv->ctr;
+ ctr = (ctr & ~mask) ^ val;
+ outb (ctr, p->base+CONTROL);
+ return priv->ctr = ctr; /* update soft copy */
}

extern __inline__ void parport_pc_write_status(struct parport *p, unsigned char d)

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/