Re: [PARPORT] RE: id_probe


Tim Waugh (tim@cyberelk.demon.co.uk)
Thu, 29 Apr 1999 20:01:23 +0100 (GMT)


On Thu, 29 Apr 1999 grant@torque.net wrote:

> Eek. I thought the whole idea of parport_frob_control was to avoid
> this possibility. While the control port is readable on most ports,
> it was write-only in the original PC spec.

Here's a patch for 2.2.7 that should fix parport_frob_control for the PC
driver. The driver now keeps track of what it thinks CTR should be.

Stefan, could you apply this patch and see if it makes any difference?

Thanks,
Tim.
*/

<URL:ftp://ftp.torque.net/pub/parport/patch-softctr>:
--- linux/include/linux/parport_pc.h~ Tue Jan 26 00:04:37 1999
+++ linux/include/linux/parport_pc.h Thu Apr 29 19:27:02 1999
@@ -60,23 +60,11 @@
         return inb(p->base+DATA);
 }
 
-extern __inline__ void parport_pc_write_control(struct parport *p, unsigned char d)
-{
- outb(d, p->base+CONTROL);
-}
-
 extern __inline__ unsigned char parport_pc_read_control(struct parport *p)
 {
         return inb(p->base+CONTROL);
 }
 
-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;
-}
-
 extern __inline__ void parport_pc_write_status(struct parport *p, unsigned char d)
 {
         outb(d, p->base+STATUS);
@@ -103,6 +91,12 @@
         outb(((old & ~mask) ^ val), p->base+ECONTROL);
         return old;
 }
+
+/* These aren't inlined because they need to mess with the soft copy
+ * of ctr, internal to parport_pc.c. */
+extern void parport_pc_write_control (struct parport *p, unsigned char ctr);
+extern unsigned char parport_pc_frob_control (struct parport *p,
+ unsigned char m, unsigned char v);
 
 extern void parport_pc_change_mode(struct parport *p, int m);
 
--- linux/drivers/misc/parport_pc.c~ Wed Mar 24 01:42:59 1999
+++ linux/drivers/misc/parport_pc.c Thu Apr 29 19:21:11 1999
@@ -53,6 +53,8 @@
    than PARPORT_MAX (in <linux/parport.h>). */
 #define PARPORT_PC_MAX_PORTS 8
 
+static volatile unsigned char parport_pc_ctr;
+
 static void parport_pc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
         parport_generic_irq(irq, (struct parport *) dev_id, regs);
@@ -104,6 +106,7 @@
 void parport_pc_write_control(struct parport *p, unsigned char d)
 {
         outb(d, p->base+CONTROL);
+ parport_pc_ctr = d; /* update soft copy */
 }
 
 unsigned char parport_pc_read_control(struct parport *p)
@@ -113,9 +116,10 @@
 
 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;
+ unsigned char ctr = parport_pc_ctr;
+ ctr = (ctr & ~mask) ^ val;
+ outb(ctr, p->base+CONTROL);
+ return parport_pc_ctr = ctr; /* update soft copy */
 }
 
 void parport_pc_write_status(struct parport *p, unsigned char d)
--- linux/drivers/misc/parport_ieee1284.c~ Thu Apr 29 19:36:12 1999
+++ linux/drivers/misc/parport_ieee1284.c Thu Apr 29 19:46:36 1999
@@ -48,25 +48,29 @@
 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, (PARPORT_CONTROL_STROBE |
+ PARPORT_CONTROL_AUTOFD), 0);
         udelay(1);
         parport_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, (PARPORT_CONTROL_SELECT |
+ PARPORT_CONTROL_AUTOFD),
+ PARPORT_CONTROL_AUTOFD);
         if (parport_wait_peripheral(port, 0x78, 0x38)) {
- parport_write_control(port,
- (parport_read_control(port) & ~2) | 8);
+ port->ops->frob_control (port, (PARPORT_CONTROL_SELECT |
+ PARPORT_CONTROL_AUTOFD),
+ PARPORT_CONTROL_SELECT);
                 return 0;
         }
         /* nStrobe low */
- parport_write_control(port, parport_read_control(port) | 1);
+ port->ops->frob_control (port, PARPORT_CONTROL_STROBE,
+ PARPORT_CONTROL_STROBE);
         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, (PARPORT_CONTROL_STROBE |
+ PARPORT_CONTROL_AUTOFD), 0);
         udelay(1);
         /* Data available? */
         parport_wait_peripheral (port, PARPORT_STATUS_ACK, PARPORT_STATUS_ACK);

-- 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 Thu 29 Apr 1999 - 15:24:40 EDT