Commit 77093e9a authored by Tim Waugh's avatar Tim Waugh Committed by Linus Torvalds

[PATCH] 2.5.3-pre6: ecr

This patch (from 2.4.x) cleans up the use of the ECR in parport_pc.

	* drivers/parport/parport_pc.c: Integrate fixes and cleanups
	from Damian Gruszka (VScom).
	* drivers/parport/ChangeLog: Updated.
parent d7b34d08
2002-01-13 Niels Kristian Bech Jensen <nkbj@image.dk>
* parport_pc.c: Change some occurrences of frob_set_mode to
ECR_WRITE. This fixes PLIP.
2001-10-25 Damian Gruszka <damian.gruszka@VisionSystems.de>
* parport_pc.c (ECR_WRITE): Define. If there are forbidden bits
in the ECR register for some chips, this will be a useful place to
put that knowledge.
(change_mode): Use ECR_WRITE.
(parport_pc_restore_state): Likewise.
(parport_ECPPS2_supported): Likewise.
(parport_ECPEPP_supported): Likewise.
(irq_probe_EPP): Likewise.
(programmable_irq_support): Likewise.
(programmable_dma_support): Likewise.
(parport_pc_probe_port): Likewise.
(frob_set_mode): New function. Set the mode bits of the ECR.
(get_fifo_residue): Use frob_set_mode.
(parport_pc_ecpepp_read_data): Likewise.
(parport_pc_ecpepp_write_data): Likewise.
(parport_pc_ecpepp_read_addr): Likewise.
(parport_pc_ecpepp_write_addr): Likewise.
(parport_pc_compat_write_block_pio): Likewise.
(parport_pc_ecp_write_block_pio): Likewise.
(parport_ECR_present): Likewise.
(parport_ECP_supported): Likewise.
(parport_EPP_supported): Likewise.
(parport_ECPEPP_supported): Likewise.
(programmable_irq_support): Likewise.
(irq_probe_ECP): Likewise.
(programmable_dma_support): Likewise.
(parport_pc_enable_irq): Only enable interrupts if we know which
IRQ line they will come from.
(parport_pc_init_state): Set nErrIntrEn at initialisation.
(parport_pc_restore_state): Only write writable bits of CTR.
(parport_irq_probe): If no IRQ is found, take ackIntEn out of the
writable bit set.
2001-10-25 Tim Waugh <twaugh@redhat.com>
* parport_pc.c (parport_pc_fifo_write_block_pio): Correct typo.
(parport_pc_init_state): Only set ackIntEn if we know which IRQ
line the interrupts will come from.
2001-12-07 Tim Waugh <twaugh@redhat.com>
* ieee1284_ops.c (parport_ieee1284_epp_write_addr,
......
......@@ -73,6 +73,8 @@
#define ECR_VND 05
#define ECR_TST 06
#define ECR_CNF 07
#define ECR_MODE_MASK 0xe0
#define ECR_WRITE(p,v) frob_econtrol((p),0xff,(v))
#undef DEBUG
......@@ -100,13 +102,22 @@ static int registered_parport;
static void frob_econtrol (struct parport *pb, unsigned char m,
unsigned char v)
{
unsigned char ectr = inb (ECONTROL (pb));
unsigned char ectr = 0;
if (m != 0xff)
ectr = inb (ECONTROL (pb));
DPRINTK (KERN_DEBUG "frob_econtrol(%02x,%02x): %02x -> %02x\n",
m, v, ectr, (ectr & ~m) ^ v);
outb ((ectr & ~m) ^ v, ECONTROL (pb));
}
static void __inline__ frob_set_mode (struct parport *p, int mode)
{
frob_econtrol (p, ECR_MODE_MASK, mode << 5);
}
#ifdef CONFIG_PARPORT_PC_FIFO
/* Safely change the mode bits in the ECR
Returns:
......@@ -117,7 +128,6 @@ static void frob_econtrol (struct parport *pb, unsigned char m,
static int change_mode(struct parport *p, int m)
{
const struct parport_pc_private *priv = p->physport->private_data;
int ecr = ECONTROL(p);
unsigned char oecr;
int mode;
......@@ -129,7 +139,7 @@ static int change_mode(struct parport *p, int m)
}
/* Bits <7:5> contain the mode. */
oecr = inb (ecr);
oecr = inb (ECONTROL (p));
mode = (oecr >> 5) & 0x7;
if (mode == m) return 0;
......@@ -166,13 +176,13 @@ static int change_mode(struct parport *p, int m)
/* We have to go through mode 001 */
oecr &= ~(7 << 5);
oecr |= ECR_PS2 << 5;
outb (oecr, ecr);
ECR_WRITE (p, oecr);
}
/* Set the mode. */
oecr &= ~(7 << 5);
oecr |= m << 5;
outb (oecr, ecr);
ECR_WRITE (p, oecr);
return 0;
}
......@@ -197,10 +207,10 @@ static int get_fifo_residue (struct parport *p)
residue);
/* Reset the FIFO. */
frob_econtrol (p, 0xe0, ECR_PS2 << 5);
frob_set_mode (p, ECR_PS2);
/* Now change to config mode and clean up. FIXME */
frob_econtrol (p, 0xe0, ECR_CNF << 5);
frob_set_mode (p, ECR_CNF);
cnfga = inb (CONFIGA (p));
printk (KERN_DEBUG "%s: cnfgA contains 0x%02x\n", p->name, cnfga);
......@@ -213,7 +223,7 @@ static int get_fifo_residue (struct parport *p)
* PWord != 1 byte. */
/* Back to PS2 mode. */
frob_econtrol (p, 0xe0, ECR_PS2 << 5);
frob_set_mode (p, ECR_PS2);
DPRINTK (KERN_DEBUG "*** get_fifo_residue: done residue collecting (ecr = 0x%2.2x)\n", inb (ECONTROL (p)));
return residue;
......@@ -331,7 +341,8 @@ void parport_pc_disable_irq(struct parport *p)
void parport_pc_enable_irq(struct parport *p)
{
__parport_pc_frob_control (p, 0x10, 0x10);
if (p->irq != PARPORT_IRQ_NONE)
__parport_pc_frob_control (p, 0x10, 0x10);
}
void parport_pc_data_forward (struct parport *p)
......@@ -346,8 +357,14 @@ void parport_pc_data_reverse (struct parport *p)
void parport_pc_init_state(struct pardevice *dev, struct parport_state *s)
{
s->u.pc.ctr = 0xc | (dev->irq_func ? 0x10 : 0x0);
s->u.pc.ecr = 0x24;
s->u.pc.ctr = 0xc;
if (dev->irq_func &&
dev->port->irq != PARPORT_IRQ_NONE)
/* Set ackIntEn */
s->u.pc.ctr |= 0x10;
s->u.pc.ecr = 0x34; /* NetMos chip can cause problems 0x24;
* D.Gruszka VScom */
}
void parport_pc_save_state(struct parport *p, struct parport_state *s)
......@@ -361,10 +378,11 @@ void parport_pc_save_state(struct parport *p, struct parport_state *s)
void parport_pc_restore_state(struct parport *p, struct parport_state *s)
{
struct parport_pc_private *priv = p->physport->private_data;
outb (s->u.pc.ctr, CONTROL (p));
priv->ctr = s->u.pc.ctr;
register unsigned char c = s->u.pc.ctr & priv->ctr_writable;
outb (c, CONTROL (p));
priv->ctr = c;
if (priv->ecr)
outb (s->u.pc.ecr, ECONTROL (p));
ECR_WRITE (p, s->u.pc.ecr);
}
#ifdef CONFIG_PARPORT_1284
......@@ -516,11 +534,11 @@ static size_t parport_pc_ecpepp_read_data (struct parport *port, void *buf,
{
size_t got;
frob_econtrol (port, 0xe0, ECR_EPP << 5);
frob_set_mode (port, ECR_EPP);
parport_pc_data_reverse (port);
parport_pc_write_control (port, 0x4);
got = parport_pc_epp_read_data (port, buf, length, flags);
frob_econtrol (port, 0xe0, ECR_PS2 << 5);
frob_set_mode (port, ECR_PS2);
return got;
}
......@@ -531,11 +549,11 @@ static size_t parport_pc_ecpepp_write_data (struct parport *port,
{
size_t written;
frob_econtrol (port, 0xe0, ECR_EPP << 5);
frob_set_mode (port, ECR_EPP);
parport_pc_write_control (port, 0x4);
parport_pc_data_forward (port);
written = parport_pc_epp_write_data (port, buf, length, flags);
frob_econtrol (port, 0xe0, ECR_PS2 << 5);
frob_set_mode (port, ECR_PS2);
return written;
}
......@@ -545,11 +563,11 @@ static size_t parport_pc_ecpepp_read_addr (struct parport *port, void *buf,
{
size_t got;
frob_econtrol (port, 0xe0, ECR_EPP << 5);
frob_set_mode (port, ECR_EPP);
parport_pc_data_reverse (port);
parport_pc_write_control (port, 0x4);
got = parport_pc_epp_read_addr (port, buf, length, flags);
frob_econtrol (port, 0xe0, ECR_PS2 << 5);
frob_set_mode (port, ECR_PS2);
return got;
}
......@@ -560,11 +578,11 @@ static size_t parport_pc_ecpepp_write_addr (struct parport *port,
{
size_t written;
frob_econtrol (port, 0xe0, ECR_EPP << 5);
frob_set_mode (port, ECR_EPP);
parport_pc_write_control (port, 0x4);
parport_pc_data_forward (port);
written = parport_pc_epp_write_addr (port, buf, length, flags);
frob_econtrol (port, 0xe0, ECR_PS2 << 5);
frob_set_mode (port, ECR_PS2);
return written;
}
......@@ -612,7 +630,7 @@ static size_t parport_pc_fifo_write_block_pio (struct parport *port,
/* FIFO is full. Wait for interrupt. */
/* Clear serviceIntr */
outb (ecrval & ~(1<<2), ECONTROL (port));
ECR_WRITE (port, ecrval & ~(1<<2));
false_alarm:
ret = parport_wait_event (port, HZ);
if (ret < 0) break;
......@@ -663,7 +681,7 @@ static size_t parport_pc_fifo_write_block_pio (struct parport *port,
left--;
}
dump_parport_state ("leave fifo_write_block_dma", port);
dump_parport_state ("leave fifo_write_block_pio", port);
return length - left;
}
......@@ -837,7 +855,7 @@ size_t parport_pc_compat_write_block_pio (struct parport *port,
printk (KERN_DEBUG "%s: FIFO is stuck\n", port->name);
/* Prevent further data transfer. */
frob_econtrol (port, 0xe0, ECR_TST << 5);
frob_set_mode (port, ECR_TST);
/* Adjust for the contents of the FIFO. */
for (written -= priv->fifo_depth; ; written++) {
......@@ -849,7 +867,7 @@ size_t parport_pc_compat_write_block_pio (struct parport *port,
}
/* Reset the FIFO and return to PS2 mode. */
frob_econtrol (port, 0xe0, ECR_PS2 << 5);
frob_set_mode (port, ECR_PS2);
}
r = parport_wait_peripheral (port,
......@@ -934,7 +952,7 @@ size_t parport_pc_ecp_write_block_pio (struct parport *port,
printk (KERN_DEBUG "%s: FIFO is stuck\n", port->name);
/* Prevent further data transfer. */
frob_econtrol (port, 0xe0, ECR_TST << 5);
frob_set_mode (port, ECR_TST);
/* Adjust for the contents of the FIFO. */
for (written -= priv->fifo_depth; ; written++) {
......@@ -946,7 +964,7 @@ size_t parport_pc_ecp_write_block_pio (struct parport *port,
}
/* Reset the FIFO and return to PS2 mode. */
frob_econtrol (port, 0xe0, ECR_PS2 << 5);
frob_set_mode (port, ECR_PS2);
/* Host transfer recovery. */
parport_pc_data_reverse (port); /* Must be in PS2 mode */
......@@ -1113,7 +1131,7 @@ dump_parport_state ("FIFO empty", port);
}
/* Clear serviceIntr */
outb (ecrval & ~(1<<2), ECONTROL (port));
ECR_WRITE (port, ecrval & ~(1<<2));
false_alarm:
dump_parport_state ("waiting", port);
ret = parport_wait_event (port, HZ);
......@@ -1716,7 +1734,7 @@ static int __devinit parport_ECR_present(struct parport *pb)
if ((inb (ECONTROL (pb)) & 0x3 ) != 0x1)
goto no_reg;
outb (0x34, ECONTROL (pb));
ECR_WRITE (pb, 0x34);
if (inb (ECONTROL (pb)) != 0x35)
goto no_reg;
......@@ -1724,7 +1742,7 @@ static int __devinit parport_ECR_present(struct parport *pb)
outb (0xc, CONTROL (pb));
/* Go to mode 000 */
frob_econtrol (pb, 0xe0, ECR_SPP << 5);
frob_set_mode (pb, ECR_SPP);
return 1;
......@@ -1794,8 +1812,8 @@ static int __devinit parport_ECP_supported(struct parport *pb)
return 0;
/* Find out FIFO depth */
outb (ECR_SPP << 5, ECONTROL (pb)); /* Reset FIFO */
outb (ECR_TST << 5, ECONTROL (pb)); /* TEST FIFO */
ECR_WRITE (pb, ECR_SPP << 5); /* Reset FIFO */
ECR_WRITE (pb, ECR_TST << 5); /* TEST FIFO */
for (i=0; i < 1024 && !(inb (ECONTROL (pb)) & 0x02); i++)
outb (0xaa, FIFO (pb));
......@@ -1804,7 +1822,7 @@ static int __devinit parport_ECP_supported(struct parport *pb)
* it doesn't support ECP or FIFO MODE
*/
if (i == 1024) {
outb (ECR_SPP << 5, ECONTROL (pb));
ECR_WRITE (pb, ECR_SPP << 5);
return 0;
}
......@@ -1834,9 +1852,9 @@ static int __devinit parport_ECP_supported(struct parport *pb)
priv->writeIntrThreshold = i;
/* Find out readIntrThreshold */
frob_econtrol (pb, 0xe0, ECR_PS2 << 5); /* Reset FIFO and enable PS2 */
frob_set_mode (pb, ECR_PS2); /* Reset FIFO and enable PS2 */
parport_pc_data_reverse (pb); /* Must be in PS2 mode */
frob_econtrol (pb, 0xe0, ECR_TST << 5); /* Test FIFO */
frob_set_mode (pb, ECR_TST); /* Test FIFO */
frob_econtrol (pb, 1<<2, 1<<2);
frob_econtrol (pb, 1<<2, 0);
for (i = 1; i <= priv->fifo_depth; i++) {
......@@ -1855,8 +1873,8 @@ static int __devinit parport_ECP_supported(struct parport *pb)
priv->readIntrThreshold = i;
outb (ECR_SPP << 5, ECONTROL (pb)); /* Reset FIFO */
outb (0xf4, ECONTROL (pb)); /* Configuration mode */
ECR_WRITE (pb, ECR_SPP << 5); /* Reset FIFO */
ECR_WRITE (pb, 0xf4); /* Configuration mode */
config = inb (CONFIGA (pb));
pword = (config >> 4) & 0x7;
switch (pword) {
......@@ -1901,7 +1919,7 @@ static int __devinit parport_ECP_supported(struct parport *pb)
}
/* Go back to mode 000 */
frob_econtrol (pb, 0xe0, ECR_SPP << 5);
frob_set_mode (pb, ECR_SPP);
return 1;
}
......@@ -1917,11 +1935,9 @@ static int __devinit parport_ECPPS2_supported(struct parport *pb)
return 0;
oecr = inb (ECONTROL (pb));
outb (ECR_PS2 << 5, ECONTROL (pb));
ECR_WRITE (pb, ECR_PS2 << 5);
result = parport_PS2_supported(pb);
outb (oecr, ECONTROL (pb));
ECR_WRITE (pb, oecr);
return result;
}
......@@ -1953,7 +1969,7 @@ static int __devinit parport_EPP_supported(struct parport *pb)
if (priv->ecr) {
unsigned char i;
for (i = 0x00; i < 0x80; i += 0x20) {
outb (i, ECONTROL (pb));
ECR_WRITE (pb, i);
if (clear_epp_timeout (pb)) {
/* Phony EPP in ECP. */
return 0;
......@@ -1984,11 +2000,11 @@ static int __devinit parport_ECPEPP_supported(struct parport *pb)
oecr = inb (ECONTROL (pb));
/* Search for SMC style EPP+ECP mode */
outb (0x80, ECONTROL (pb));
ECR_WRITE (pb, 0x80);
outb (0x04, CONTROL (pb));
result = parport_EPP_supported(pb);
outb (oecr, ECONTROL (pb));
ECR_WRITE (pb, oecr);
if (result) {
/* Set up access functions to use ECP+EPP hardware. */
......@@ -2025,12 +2041,12 @@ static int __devinit programmable_irq_support(struct parport *pb)
PARPORT_IRQ_NONE, 7, 9, 10, 11, 14, 15, 5
};
outb (ECR_CNF << 5, ECONTROL (pb)); /* Configuration MODE */
ECR_WRITE (pb, ECR_CNF << 5); /* Configuration MODE */
intrLine = (inb (CONFIGB (pb)) >> 3) & 0x07;
irq = lookup[intrLine];
outb (oecr, ECONTROL (pb));
ECR_WRITE (pb, oecr);
return irq;
}
......@@ -2042,16 +2058,16 @@ static int __devinit irq_probe_ECP(struct parport *pb)
sti();
irqs = probe_irq_on();
outb (ECR_SPP << 5, ECONTROL (pb)); /* Reset FIFO */
outb ((ECR_TST << 5) | 0x04, ECONTROL (pb));
outb (ECR_TST << 5, ECONTROL (pb));
ECR_WRITE (pb, ECR_SPP << 5); /* Reset FIFO */
ECR_WRITE (pb, (ECR_TST << 5) | 0x04);
ECR_WRITE (pb, ECR_TST << 5);
/* If Full FIFO sure that writeIntrThreshold is generated */
for (i=0; i < 1024 && !(inb (ECONTROL (pb)) & 0x02) ; i++)
outb (0xaa, FIFO (pb));
pb->irq = probe_irq_off(irqs);
outb (ECR_SPP << 5, ECONTROL (pb));
ECR_WRITE (pb, ECR_SPP << 5);
if (pb->irq <= 0)
pb->irq = PARPORT_IRQ_NONE;
......@@ -2093,7 +2109,7 @@ static int __devinit irq_probe_EPP(struct parport *pb)
pb->irq = probe_irq_off (irqs);
if (pb->modes & PARPORT_MODE_PCECR)
outb (oecr, ECONTROL (pb));
ECR_WRITE (pb, oecr);
parport_pc_write_control(pb, 0xc);
if (pb->irq <= 0)
......@@ -2118,7 +2134,9 @@ static int __devinit irq_probe_SPP(struct parport *pb)
*/
static int __devinit parport_irq_probe(struct parport *pb)
{
const struct parport_pc_private *priv = pb->private_data;
struct parport_pc_private *priv = pb->private_data;
priv->ctr_writable |= 0x10;
if (priv->ecr) {
pb->irq = programmable_irq_support(pb);
......@@ -2144,6 +2162,9 @@ static int __devinit parport_irq_probe(struct parport *pb)
if (pb->irq == PARPORT_IRQ_NONE)
pb->irq = get_superio_irq(pb);
if (pb->irq == PARPORT_IRQ_NONE)
priv->ctr_writable &= ~0x10;
return pb->irq;
}
......@@ -2155,7 +2176,7 @@ static int __devinit programmable_dma_support (struct parport *p)
unsigned char oecr = inb (ECONTROL (p));
int dma;
frob_econtrol (p, 0xe0, ECR_CNF << 5);
frob_set_mode (p, ECR_CNF);
dma = inb (CONFIGB(p)) & 0x07;
/* 000: Indicates jumpered 8-bit DMA if read-only.
......@@ -2163,7 +2184,7 @@ static int __devinit programmable_dma_support (struct parport *p)
if ((dma & 0x03) == 0)
dma = PARPORT_DMA_NONE;
outb (oecr, ECONTROL (p));
ECR_WRITE (p, oecr);
return dma;
}
......@@ -2209,7 +2230,7 @@ struct parport *parport_pc_probe_port (unsigned long int base,
}
memcpy (ops, &parport_pc_ops, sizeof (struct parport_operations));
priv->ctr = 0xc;
priv->ctr_writable = 0xff;
priv->ctr_writable = ~0x10;
priv->ecr = 0;
priv->fifo_depth = 0;
priv->dma_buf = 0;
......@@ -2371,7 +2392,7 @@ struct parport *parport_pc_probe_port (unsigned long int base,
* Put the ECP detected port in PS2 mode.
* Do this also for ports that have ECR but don't do ECP.
*/
outb (0x34, ECONTROL (p));
ECR_WRITE (p, 0x34);
parport_pc_write_data(p, 0);
parport_pc_data_forward (p);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment