patch-2.4.18 linux/drivers/parport/parport_pc.c
Next file: linux/drivers/parport/share.c
Previous file: linux/drivers/parport/ChangeLog
Back to the patch index
Back to the overall index
- Lines: 458
- Date:
Mon Jan 14 19:08:50 2002
- Orig file:
linux.orig/drivers/parport/parport_pc.c
- Orig date:
Mon Feb 18 20:18:40 2002
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/parport/parport_pc.c linux/drivers/parport/parport_pc.c
@@ -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 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 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 @@
}
/* 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 @@
/* 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 @@
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 @@
* 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_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_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_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 @@
{
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 @@
{
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 @@
{
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 @@
{
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 @@
/* 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 @@
left--;
}
-dump_parport_state ("leave fifo_write_block_dma", port);
+dump_parport_state ("leave fifo_write_block_pio", port);
return length - left;
}
@@ -840,7 +858,7 @@
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++) {
@@ -852,7 +870,7 @@
}
/* 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,
@@ -937,7 +955,7 @@
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++) {
@@ -949,7 +967,7 @@
}
/* 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 */
@@ -1116,7 +1134,7 @@
}
/* 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);
@@ -1719,7 +1737,7 @@
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;
@@ -1727,7 +1745,7 @@
outb (0xc, CONTROL (pb));
/* Go to mode 000 */
- frob_econtrol (pb, 0xe0, ECR_SPP << 5);
+ frob_set_mode (pb, ECR_SPP);
return 1;
@@ -1797,8 +1815,8 @@
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));
@@ -1807,7 +1825,7 @@
* 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;
}
@@ -1837,9 +1855,9 @@
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++) {
@@ -1858,8 +1876,8 @@
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) {
@@ -1904,7 +1922,7 @@
}
/* Go back to mode 000 */
- frob_econtrol (pb, 0xe0, ECR_SPP << 5);
+ frob_set_mode (pb, ECR_SPP);
return 1;
}
@@ -1920,11 +1938,9 @@
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;
}
@@ -1956,7 +1972,7 @@
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;
@@ -1987,11 +2003,11 @@
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. */
@@ -2028,12 +2044,12 @@
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;
}
@@ -2045,16 +2061,16 @@
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;
@@ -2096,7 +2112,7 @@
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)
@@ -2121,7 +2137,9 @@
*/
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);
@@ -2147,6 +2165,9 @@
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;
}
@@ -2158,7 +2179,7 @@
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.
@@ -2166,7 +2187,7 @@
if ((dma & 0x03) == 0)
dma = PARPORT_DMA_NONE;
- outb (oecr, ECONTROL (p));
+ ECR_WRITE (p, oecr);
return dma;
}
@@ -2212,7 +2233,7 @@
}
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;
@@ -2374,7 +2395,7 @@
* 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);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)