patch-2.1.105 linux/drivers/misc/parport_pc.c

Next file: linux/drivers/misc/parport_share.c
Previous file: linux/drivers/misc/parport_ax.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.104/linux/drivers/misc/parport_pc.c linux/drivers/misc/parport_pc.c
@@ -3,7 +3,8 @@
  * 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>
+ *          David Campbell <campbell@torque.net>
+ *          Andrea Arcangeli <arcangeli@mbox.queen.it>
  *
  * based on work by Grant Guenther <grant@torque.net> and Phil Blundell.
  */
@@ -171,16 +172,24 @@
 	return 0;
 }
 
+void parport_pc_init_state(struct parport_state *s)
+{
+	s->u.pc.ctr = 0xc;
+	s->u.pc.ecr = 0x0;
+}
+
 void parport_pc_save_state(struct parport *p, struct parport_state *s)
 {
 	s->u.pc.ctr = parport_pc_read_control(p);
-	s->u.pc.ecr = parport_pc_read_econtrol(p);
+	if (p->modes & PARPORT_MODE_PCECR)
+		s->u.pc.ecr = parport_pc_read_econtrol(p);
 }
 
 void parport_pc_restore_state(struct parport *p, struct parport_state *s)
 {
 	parport_pc_write_control(p, s->u.pc.ctr);
-	parport_pc_write_econtrol(p, s->u.pc.ecr);
+	if (p->modes & PARPORT_MODE_PCECR)
+		parport_pc_write_econtrol(p, s->u.pc.ecr);
 }
 
 size_t parport_pc_epp_read_block(struct parport *p, void *buf, size_t length)
@@ -264,6 +273,7 @@
 	parport_pc_ecp_write_block,
 	parport_pc_ecp_read_block,
 	
+	parport_pc_init_state,
 	parport_pc_save_state,
 	parport_pc_restore_state,
 
@@ -304,7 +314,6 @@
 static int parport_SPP_supported(struct parport *pb)
 {
 	/* Do a simple read-write test to make sure the port exists. */
-	parport_pc_write_econtrol(pb, 0xc);
 	parport_pc_write_control(pb, 0xc);
 	parport_pc_write_data(pb, 0xaa);
 	if (parport_pc_read_data(pb) != 0xaa) return 0;
@@ -362,12 +371,13 @@
 static int parport_ECP_supported(struct parport *pb)
 {
 	int i;
-	unsigned char oecr = parport_pc_read_econtrol(pb);
+	unsigned char oecr;
 	
 	/* If there is no ECR, we have no hope of supporting ECP. */
 	if (!(pb->modes & PARPORT_MODE_PCECR))
 		return 0;
 
+	oecr = parport_pc_read_econtrol(pb);
 	/*
 	 * Using LGS chipset it uses ECR register, but
 	 * it doesn't support ECP or FIFO MODE
@@ -417,11 +427,12 @@
 static int parport_ECPEPP_supported(struct parport *pb)
 {
 	int mode;
-	unsigned char oecr = parport_pc_read_econtrol(pb);
+	unsigned char oecr;
 
 	if (!(pb->modes & PARPORT_MODE_PCECR))
 		return 0;
-	
+
+	oecr = parport_pc_read_econtrol(pb);
 	/* Search for SMC style EPP+ECP mode */
 	parport_pc_write_econtrol(pb, 0x80);
 	
@@ -472,11 +483,12 @@
 static int parport_ECPPS2_supported(struct parport *pb)
 {
 	int mode;
-	unsigned char oecr = parport_pc_read_econtrol(pb);
+	unsigned char oecr;
 
 	if (!(pb->modes & PARPORT_MODE_PCECR))
 		return 0;
-	
+
+	oecr = parport_pc_read_econtrol(pb);
 	parport_pc_write_econtrol(pb, 0x20);
 	
 	mode = parport_PS2_supported(pb);
@@ -536,12 +548,15 @@
 {
 	int irqs;
 	unsigned char octr = parport_pc_read_control(pb);
-	unsigned char oecr = parport_pc_read_econtrol(pb);
+	unsigned char oecr;
 
 #ifndef ADVANCED_DETECT
 	return PARPORT_IRQ_NONE;
 #endif
-	
+
+	if (pb->modes & PARPORT_MODE_PCECR)
+		oecr = parport_pc_read_econtrol(pb);
+
 	sti();
 	irqs = probe_irq_on();
 
@@ -560,7 +575,8 @@
 	udelay(20);
 
 	pb->irq = probe_irq_off (irqs);
-	parport_pc_write_econtrol(pb, oecr);
+	if (pb->modes & PARPORT_MODE_PCECR)
+		parport_pc_write_econtrol(pb, oecr);
 	parport_pc_write_control(pb, octr);
 
 	if (pb->irq <= 0)
@@ -573,12 +589,14 @@
 {
 	int irqs;
 	unsigned char octr = parport_pc_read_control(pb);
-	unsigned char oecr = parport_pc_read_econtrol(pb);
+	unsigned char oecr;
 
 #ifndef ADVANCED_DETECT
 	return PARPORT_IRQ_NONE;
 #endif
 
+	if (pb->modes & PARPORT_MODE_PCECR)
+		oecr = parport_pc_read_econtrol(pb);
 	probe_irq_off(probe_irq_on());	/* Clear any interrupts */
 	irqs = probe_irq_on();
 
@@ -602,7 +620,8 @@
 	if (pb->irq <= 0)
 		pb->irq = PARPORT_IRQ_NONE;	/* No interrupt detected */
 	
-	parport_pc_write_econtrol(pb, oecr);
+	if (pb->modes & PARPORT_MODE_PCECR)
+		parport_pc_write_econtrol(pb, oecr);
 	parport_pc_write_control(pb, octr);
 	return pb->irq;
 }
@@ -616,8 +635,6 @@
  */
 static int parport_irq_probe(struct parport *pb)
 {
-	unsigned char oecr = parport_pc_read_econtrol (pb);
-
 	if (pb->modes & PARPORT_MODE_PCECR) {
 		pb->irq = programmable_irq_support(pb);
 		if (pb->irq != PARPORT_IRQ_NONE)
@@ -628,10 +645,8 @@
 		pb->irq = irq_probe_ECP(pb);
 
 	if (pb->irq == PARPORT_IRQ_NONE && 
-	    (pb->modes & PARPORT_MODE_PCECPEPP)) {
+	    (pb->modes & PARPORT_MODE_PCECPEPP))
 		pb->irq = irq_probe_EPP(pb);
-		parport_pc_write_econtrol(pb, oecr);
-	}
 
 	epp_clear_timeout(pb);
 
@@ -644,7 +659,6 @@
 		pb->irq = irq_probe_SPP(pb);
 
 out:
-	parport_pc_write_econtrol (pb, oecr);
 	return pb->irq;
 }
 
@@ -708,7 +722,11 @@
 	p->flags |= PARPORT_FLAG_COMA;
 
 	/* Done probing.  Now put the port into a sensible start-up state. */
-	parport_pc_write_econtrol(p, 0xc);
+	if (p->modes & PARPORT_MODE_PCECR)
+		/*
+		 * Put the ECP detected port in the more SPP like mode.
+		 */
+		parport_pc_write_econtrol(p, 0x0);
 	parport_pc_write_control(p, 0xc);
 	parport_pc_write_data(p, 0);
 

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov