--- linux-2.4.23/drivers/char/serial-dist.c Fri Nov 28 19:26:20 2003
+++ linux-2.4.23/drivers/char/serial.c Wed Dec 3 01:18:54 2003
@@ -4375,6 +4375,11 @@
pbn_computone_4,
pbn_computone_6,
pbn_computone_8,
+ pbn_b1_1_921600,
+ pbn_b1_bt_2_921600,
+ pbn_b1_bt_4_921600,
+ pbn_b1_bt_8_921600,
+ pbn_b4_2_921600,
};
static struct pci_board pci_boards[] __devinitdata = {
@@ -4483,6 +4488,11 @@
0x40, 2, NULL, 0x200 },
{ SPCI_FL_BASE0, 8, 921600, /* IOMEM */ /* pbn_computone_8 */
0x40, 2, NULL, 0x200 },
+ { SPCI_FL_BASE1, 1, 921600}, /* IOMEM*/ /* pbn_b1_1_921600 */
+ { SPCI_FL_BASE1 | SPCI_FL_BASE_TABLE, 2, 921600}, /* pbn_b1_bt_2_921600 */
+ { SPCI_FL_BASE1 | SPCI_FL_BASE_TABLE, 4, 921600}, /* pbn_b1_bt_4_921600 */
+ { SPCI_FL_BASE1 | SPCI_FL_BASE_TABLE, 8, 921600}, /* pbn_b1_bt_8_921600 */
+ { SPCI_FL_BASE4 , 2, 921600}, /* pbn_b4_2_921600 */
};
/*
@@ -4764,19 +4774,22 @@
PCI_ANY_ID, PCI_ANY_ID, 0, 0,
pbn_b0_4_921600 },
{ PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_100L,
- PCI_ANY_ID, PCI_ANY_ID,
- SPCI_FL_BASE1, 1, 921600 },
+ PCI_ANY_ID, PCI_ANY_ID,0,0,pbn_b1_1_921600},
{ PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200L,
- PCI_ANY_ID, PCI_ANY_ID,
- SPCI_FL_BASE1 | SPCI_FL_BASE_TABLE, 2, 921600 },
+ PCI_ANY_ID, PCI_ANY_ID,0,0,pbn_b1_bt_2_921600 },
/* The 400L and 800L have a custom hack in get_pci_port */
+ /* changed by damian gruszka VScom (TM) VS Vision Systems GmbH */
{ PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_400L,
- PCI_ANY_ID, PCI_ANY_ID,
- SPCI_FL_BASE_TABLE, 4, 921600 },
+ PCI_ANY_ID, PCI_ANY_ID,0,0,pbn_b1_bt_4_921600},
{ PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800L,
- PCI_ANY_ID, PCI_ANY_ID,
- SPCI_FL_BASE_TABLE, 8, 921600 },
-
+ PCI_ANY_ID, PCI_ANY_ID,0,0,pbn_b1_bt_8_921600},
+ { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200I,
+ PCI_ANY_ID, PCI_ANY_ID,0,0,pbn_b4_2_921600},
+ /* VScom HV2 cards damian gruszka VScom (TM) */
+ { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_100HV2,
+ PCI_ANY_ID, PCI_ANY_ID,0,0,pbn_b0_1_921600},
+ { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200HV2,
+ PCI_ANY_ID, PCI_ANY_ID,0,0,pbn_b0_bt_2_921600},
{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_10x_550,
PCI_ANY_ID, PCI_ANY_ID, 0, 0,
pbn_siig10x_0 },
--- linux-2.4.23/drivers/parport/parport_serial-dist.c Sat Aug 3 02:39:44 2002
+++ linux-2.4.23/drivers/parport/parport_serial.c Wed Dec 3 01:18:54 2003
@@ -46,6 +46,10 @@
siig_2p1s_20x,
siig_1s1p_20x,
siig_2s1p_20x,
+ /* d.gruszka VScom (R) */
+ vscom_2s1p_210s,
+ titan_430l,
+ titan_420l,
};
@@ -84,6 +88,9 @@
/* siig_2p1s_20x */ { 2, { { 1, 2 }, { 3, 4 }, } },
/* siig_1s1p_20x */ { 1, { { 1, 2 }, } },
/* siig_2s1p_20x */ { 1, { { 2, 3 }, } },
+ /* vscom_2s1p_210s */ { 1, { { 5, -1}, } },
+ /* titan_430l */ { 3, { { 3, -1},{ 4, -1},{4,-1},}},
+ /* titan_420l */ { 2, { { 3, -1},{ 4, -1},}},
};
static struct pci_device_id parport_serial_pci_tbl[] __devinitdata = {
@@ -132,7 +139,12 @@
PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2s1p_20x },
{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_20x_850,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2s1p_20x },
-
+ { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_TITAN_210S,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, vscom_2s1p_210s },
+ { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_430L,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, titan_430l },
+ { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_420L,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, titan_420l },
{ 0, } /* terminate list */
};
MODULE_DEVICE_TABLE(pci,parport_serial_pci_tbl);
@@ -185,6 +197,10 @@
/* siig_2p1s_20x */ { SPCI_FL_BASE0, 1, 921600, 0, 0, siig20x_init_fn },
/* siig_1s1p_20x */ { SPCI_FL_BASE0, 1, 921600, 0, 0, siig20x_init_fn },
/* siig_2s1p_20x */ { SPCI_FL_BASE0, 1, 921600, 0, 0, siig20x_init_fn },
+/* d.gruszka VScom (R) */
+/* vscom_2s1p_210s */ { SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 2, 921600 },
+/* titan_420l */ { SPCI_FL_BASE1 | SPCI_FL_BASE_TABLE, 4, 921600 },
+/* titan_430l */ { SPCI_FL_BASE1 | SPCI_FL_BASE_TABLE, 4, 921600 },
};
struct parport_serial_private {
@@ -235,6 +251,12 @@
case 7: base_idx=idx-2; /* BAR 5*/
}
+ if((dev->vendor == PCI_VENDOR_ID_TITAN) &&
+ ((dev->device & 0xFF00) == 0x8000) && (idx >= 2))
+ {
+ base_idx = 4;
+ offset = 8 * (idx-2);
+ }
port = pci_resource_start(dev, base_idx) + offset;
if ((board->flags & SPCI_FL_BASE_TABLE) == 0)
@@ -321,6 +343,9 @@
io_lo += hi; /* Reinterpret the meaning of
"hi" as an offset (see SYBA
def.) */
+ /* D.Gruszka damian.gruszka@vscom.de */
+ if(((i == titan_430l) || (i == titan_420l )) && (n >= 1))
+ io_lo += 16+(n-1)*8;
/* TODO: test if sharing interrupts works */
printk (KERN_DEBUG "PCI parallel port detected: %04x:%04x, "
"I/O at %#lx(%#lx)\n",
--- linux-2.4.23/drivers/parport/parport_pc-dist.c Fri Jun 13 16:51:35 2003
+++ linux-2.4.23/drivers/parport/parport_pc.c Thu Dec 4 05:34:08 2003
@@ -77,6 +77,7 @@
#define ECR_WRITE(p,v) frob_econtrol((p),0xff,(v))
#undef DEBUG
+/* #define DEBUG 1 */
#ifdef DEBUG
#define DPRINTK printk
@@ -93,24 +94,26 @@
} superios[NR_SUPERIOS] __devinitdata = { {0,},};
static int user_specified __devinitdata = 0;
-#if defined(CONFIG_PARPORT_PC_FIFO) || defined(CONFIG_PARPORT_PC_SUPERIO)
-static int verbose_probing;
-#endif
+static int verbose_probing=0;
static int registered_parport;
/* frob_control, but for ECR */
static void frob_econtrol (struct parport *pb, unsigned char m,
unsigned char v)
{
- unsigned char ectr = 0;
+ unsigned char ecr = 0;
+ struct parport_pc_private *priv=
+ (struct parport_pc_private *) pb->private_data;
+#ifdef DEBUG
+ ecr = inb (ECONTROL (pb));
+ printk(KERN_DEBUG "frob_econtrol(%s,%02x,%02x): %02x -> %02x\n",
+ pb->name, m, v, ecr, (ecr & ~m) ^ v);
+#endif
if (m != 0xff)
- ectr = inb (ECONTROL (pb));
+ ecr = 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));
+ outb ((priv->ecr=(ecr & ~m) ^ v), ECONTROL (pb));
}
static void __inline__ frob_set_mode (struct parport *p, int mode)
@@ -133,7 +136,7 @@
DPRINTK(KERN_INFO "parport change_mode ECP-ISA to mode 0x%02x\n",m);
- if (!priv->ecr) {
+ if (!priv->ecrok) {
printk (KERN_DEBUG "change_mode: but there's no ECR!\n");
return 0;
}
@@ -263,6 +266,68 @@
static void parport_pc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
+ struct parport *pb=(struct parport *)dev_id;
+ struct parport_pc_private *priv=
+ (struct parport_pc_private *) pb->private_data;
+ unsigned char dsr, dsr2, ecr=0;
+ int our=0;
+
+ /* The level sensitive PCI INTX# is held until DSR is read.
+ * Even worse, some boards just route ACK# to INTX#. It must
+ * be cleared since the IRQ controller otherwise retriggers when
+ * this handler returns (locking up the system). */
+ dsr=inb(STATUS(pb));
+
+ if(priv->irqshare == PARPORT_IRQ_NONE) our|=1;
+
+ /* Bit 2 (nINT aka nPRINT) resets on DSR read for true PS2 ports.
+ * ox12pci840 1415:8403 : int at rising ACK#, full nINT support
+ * National PC87306B : int at rising ACK#, but nINT==1
+ * Netmos 9710:9815 : INTX#==ACK#, nINT reset impossible if ACK#==0
+ */
+ if(priv->ctr & 0x10) { /* ACK# irq enabled */
+ if(!(dsr & 0x04)) { /* got nINT */
+ our|=2;
+ if(!priv->irqok) priv->irqok=our;
+ } else if(!priv->irqok) {
+ our|=4; /* fallback false alarm */
+ }
+ }
+ dsr2=inb(STATUS(pb));
+ if((our & 2) && !(dsr2 & 0x04)) {
+ our|=8;
+ priv->ctr&=~0x10;
+ outb(priv->ctr, CONTROL(pb)); /* mask INTX# level coupled ACK# */
+ dsr2=inb(STATUS(pb));
+ }
+
+ if(priv->ecrok) {
+ ecr=inb(ECONTROL(pb));
+
+ /* Bit 3 is set for an nErrIntrEn or serviceIntr if enabled. */
+ if((ecr & 0x04) && (priv->ecr & 0x14)!=0x14) {
+ our|=0x10;
+ priv->ecr=ecr | 0x14;
+ outb(priv->ecr, ECONTROL(pb)); /* unassert INTX# */
+ }
+ }
+
+#ifdef DEBUG
+ { static int cnt=0;
+ if(cnt<512) {
+ printk(KERN_DEBUG "%s: irq=%d/%d dsr=0x%02x/0x%02x ecr=0x%02x"
+ " our=0x%02x %d\n",
+ pb->name, irq, pb->irq, dsr, dsr2, ecr, our, cnt);
+ cnt++;
+ }
+#if(DEBUG>1)
+ else {
+ disable_irq_nosync(irq);
+ }
+#endif
+ }
+#endif
+ if(our)
parport_generic_irq(irq, (struct parport *) dev_id, regs);
}
@@ -341,8 +406,7 @@
void parport_pc_enable_irq(struct parport *p)
{
- if (p->irq != PARPORT_IRQ_NONE)
- __parport_pc_frob_control (p, 0x10, 0x10);
+ __parport_pc_frob_control (p, 0x10, 0x10); /* NOP if _IRQ_NONE */
}
void parport_pc_data_forward (struct parport *p)
@@ -363,15 +427,15 @@
/* Set ackIntEn */
s->u.pc.ctr |= 0x10;
- s->u.pc.ecr = 0x34; /* NetMos chip can cause problems 0x24;
- * D.Gruszka VScom */
+ 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)
{
const struct parport_pc_private *priv = p->physport->private_data;
s->u.pc.ctr = priv->ctr;
- if (priv->ecr)
+ if (priv->ecrok)
s->u.pc.ecr = inb (ECONTROL (p));
}
@@ -381,7 +445,7 @@
register unsigned char c = s->u.pc.ctr & priv->ctr_writable;
outb (c, CONTROL (p));
priv->ctr = c;
- if (priv->ecr)
+ if (priv->ecrok)
ECR_WRITE (p, s->u.pc.ecr);
}
@@ -1645,6 +1709,7 @@
static int __devinit parport_SPP_supported(struct parport *pb)
{
unsigned char r, w;
+ int ok=0;
/*
* first clear an eventually pending EPP timeout
@@ -1669,8 +1734,10 @@
outb (w, CONTROL (pb));
r = inb (CONTROL (pb));
outb (0xc, CONTROL (pb));
- if ((r & 0xf) == w)
- return PARPORT_MODE_PCSPP;
+ if ((r & 0xf) == w) {
+ ok=PARPORT_MODE_PCSPP;
+ goto end;
+ }
}
if (user_specified)
@@ -1688,8 +1755,10 @@
w = 0x55;
parport_pc_write_data (pb, w);
r = parport_pc_read_data (pb);
- if (r == w)
- return PARPORT_MODE_PCSPP;
+ if (r == w) {
+ ok=PARPORT_MODE_PCSPP;
+ goto end;
+ }
}
if (user_specified) {
@@ -1705,9 +1774,15 @@
/* It's possible that we can't read the control register or
* the data register. In that case just believe the user. */
if (user_specified)
- return PARPORT_MODE_PCSPP;
+ ok=PARPORT_MODE_PCSPP;
- return 0;
+ end:
+ if (verbose_probing) {
+ unsigned char dsr=parport_pc_read_status(pb);
+ printk (KERN_DEBUG "parport_SPP_supported(%s): dsr=0x%02x ok=%d\n",
+ pb->name, dsr, ok);
+ }
+ return(ok);
}
/* Check for ECR
@@ -1727,6 +1802,7 @@
{
struct parport_pc_private *priv = pb->private_data;
unsigned char r = 0xc;
+ int ok=0;
outb (r, CONTROL (pb));
if ((inb (ECONTROL (pb)) & 0x3) == (r & 0x3)) {
@@ -1737,24 +1813,27 @@
goto no_reg; /* Sure that no ECR register exists */
}
- if ((inb (ECONTROL (pb)) & 0x3 ) != 0x1)
+ if ((inb (ECONTROL (pb)) & 0x3 ) != 0x1) {
+ ok=-1;
goto no_reg;
-
+ }
ECR_WRITE (pb, 0x34);
- if (inb (ECONTROL (pb)) != 0x35)
+ if (inb (ECONTROL (pb)) != 0x35) {
+ ok=-2;
goto no_reg;
-
- priv->ecr = 1;
- outb (0xc, CONTROL (pb));
+ }
+ ok=priv->ecrok = 1;
/* Go to mode 000 */
frob_set_mode (pb, ECR_SPP);
- return 1;
-
no_reg:
outb (0xc, CONTROL (pb));
- return 0;
+
+ if (verbose_probing)
+ printk (KERN_DEBUG "parport_ECR_present(%s): ok=%d\n", pb->name, ok);
+ if(ok<0) ok=0;
+ return(ok);
}
#ifdef CONFIG_PARPORT_1284
@@ -1777,7 +1856,14 @@
static int __devinit parport_PS2_supported(struct parport *pb)
{
+ struct parport_pc_private *priv = pb->private_data;
int ok = 0;
+ unsigned char oecr=0x34;
+
+ if (priv->ecrok) {
+ oecr = inb (ECONTROL (pb));
+ ECR_WRITE (pb, ECR_PS2<<5 | 0x14); /* and disable PCI interrupts */
+ }
clear_epp_timeout(pb);
@@ -1793,13 +1879,17 @@
/* cancel input mode */
parport_pc_data_forward (pb);
- if (ok) {
+ if (ok)
pb->modes |= PARPORT_MODE_TRISTATE;
- } else {
- struct parport_pc_private *priv = pb->private_data;
+ else
priv->ctr_writable &= ~0x20;
- }
+ if(priv->ecrok)
+ ECR_WRITE (pb, oecr);
+
+ if (verbose_probing)
+ printk (KERN_DEBUG "parport_PS2_supported(%s): ok=%d\n",
+ pb->name, ok);
return ok;
}
@@ -1814,7 +1904,7 @@
static const int intrline[]= { 0, 7, 9, 10, 11, 14, 15, 5 };
/* If there is no ECR, we have no hope of supporting ECP. */
- if (!priv->ecr)
+ if (!priv->ecrok)
return 0;
/* Find out FIFO depth */
@@ -1931,27 +2021,20 @@
}
#endif
-static int __devinit parport_ECPPS2_supported(struct parport *pb)
-{
- const struct parport_pc_private *priv = pb->private_data;
- int result;
- unsigned char oecr;
-
- if (!priv->ecr)
- return 0;
-
- oecr = inb (ECONTROL (pb));
- ECR_WRITE (pb, ECR_PS2 << 5);
- result = parport_PS2_supported(pb);
- ECR_WRITE (pb, oecr);
- return result;
-}
-
/* EPP mode detection */
static int __devinit parport_EPP_supported(struct parport *pb)
{
- const struct parport_pc_private *priv = pb->private_data;
+ struct parport_pc_private *priv = pb->private_data;
+ int result=0;
+ unsigned char oecr=0x34;
+
+ if (priv->ecrok) {
+ oecr = inb (ECONTROL (pb));
+ /* Search for SMC style EPP+ECP mode */
+ ECR_WRITE (pb, 0x80 | 0x14); /* EPP no interrupts for PCI */
+ outb (0x04, CONTROL (pb));
+ }
/*
* Theory:
@@ -1968,17 +2051,22 @@
/* If EPP timeout bit clear then EPP available */
if (!clear_epp_timeout(pb)) {
- return 0; /* No way to clear timeout */
+ result=-1;
+ goto end; /* No way to clear timeout */
}
/* Check for Intel bug. */
- if (priv->ecr) {
- unsigned char i;
- for (i = 0x00; i < 0x80; i += 0x20) {
- ECR_WRITE (pb, i);
- if (clear_epp_timeout (pb)) {
+ if (priv->ecrok) {
+ int i;
+ unsigned char mode[5]={
+ ECR_SPP, ECR_PS2, ECR_PPF, ECR_ECP, ECR_EPP
+ };
+ for (i = 0; i < 5; i++) {
+ frob_set_mode (pb, mode[i]);
+ if (mode[i]!=ECR_EPP && clear_epp_timeout (pb)) {
/* Phony EPP in ECP. */
- return 0;
+ result=-10-i;
+ goto end;
}
}
}
@@ -1986,33 +2074,12 @@
pb->modes |= PARPORT_MODE_EPP;
/* Set up access functions to use EPP hardware. */
+ if(!priv->ecrok) {
pb->ops->epp_read_data = parport_pc_epp_read_data;
pb->ops->epp_write_data = parport_pc_epp_write_data;
pb->ops->epp_read_addr = parport_pc_epp_read_addr;
pb->ops->epp_write_addr = parport_pc_epp_write_addr;
-
- return 1;
-}
-
-static int __devinit parport_ECPEPP_supported(struct parport *pb)
-{
- struct parport_pc_private *priv = pb->private_data;
- int result;
- unsigned char oecr;
-
- if (!priv->ecr) {
- return 0;
- }
-
- oecr = inb (ECONTROL (pb));
- /* Search for SMC style EPP+ECP mode */
- ECR_WRITE (pb, 0x80);
- outb (0x04, CONTROL (pb));
- result = parport_EPP_supported(pb);
-
- ECR_WRITE (pb, oecr);
-
- if (result) {
+ } else {
/* Set up access functions to use ECP+EPP hardware. */
pb->ops->epp_read_data = parport_pc_ecpepp_read_data;
pb->ops->epp_write_data = parport_pc_ecpepp_write_data;
@@ -2020,19 +2087,23 @@
pb->ops->epp_write_addr = parport_pc_ecpepp_write_addr;
}
- return result;
+ result=1;
+ end:
+ if (priv->ecrok)
+ ECR_WRITE (pb, oecr);
+
+ if (verbose_probing)
+ printk (KERN_DEBUG "parport_EPP_supported(%s): result=%d\n",
+ pb->name, result);
+ if(result<0) result=0;
+ return(result);
}
#else /* No IEEE 1284 support */
/* Don't bother probing for modes we know we won't use. */
static int __devinit parport_PS2_supported(struct parport *pb) { return 0; }
-#ifdef CONFIG_PARPORT_PC_FIFO
-static int __devinit parport_ECP_supported(struct parport *pb) { return 0; }
-#endif
static int __devinit parport_EPP_supported(struct parport *pb) { return 0; }
-static int __devinit parport_ECPEPP_supported(struct parport *pb){return 0;}
-static int __devinit parport_ECPPS2_supported(struct parport *pb){return 0;}
#endif /* No IEEE 1284 support */
@@ -2053,6 +2124,10 @@
irq = lookup[intrLine];
ECR_WRITE (pb, oecr);
+
+ if (verbose_probing)
+ printk (KERN_DEBUG "programmable_irq_support(%s): irq=%d\n",
+ pb->name, irq);
return irq;
}
@@ -2071,13 +2146,21 @@
/* If Full FIFO sure that writeIntrThreshold is generated */
for (i=0; i < 1024 && !(inb (ECONTROL (pb)) & 0x02) ; i++)
outb (0xaa, FIFO (pb));
-
+ if(i<1024) {
+ struct parport_pc_private *priv = pb->private_data;
+ priv->fifo_depth = i;
+ }
+ udelay (10);
+ ECR_WRITE (pb, ECR_SPP << 5 | 0x14); /* disable shared PCI INTX# */
pb->irq = probe_irq_off(irqs);
- ECR_WRITE (pb, ECR_SPP << 5);
if (pb->irq <= 0)
pb->irq = PARPORT_IRQ_NONE;
+ if (verbose_probing)
+ printk (KERN_DEBUG "irq_probe_ECP(%s): irq=%d irqs=0x%08lx i=%d\n",
+ pb->name, pb->irq, irqs, i);
+
return pb->irq;
}
@@ -2121,6 +2204,8 @@
if (pb->irq <= 0)
pb->irq = PARPORT_IRQ_NONE;
+ if (verbose_probing)
+ printk (KERN_DEBUG "irq_probe_EPP(%s): irq=%d\n", pb->name, pb->irq);
return pb->irq;
#endif /* Advanced detection */
}
@@ -2142,14 +2227,14 @@
{
struct parport_pc_private *priv = pb->private_data;
- if (priv->ecr) {
+ if (priv->ecrok) {
pb->irq = programmable_irq_support(pb);
if (pb->irq == PARPORT_IRQ_NONE)
pb->irq = irq_probe_ECP(pb);
}
- if ((pb->irq == PARPORT_IRQ_NONE) && priv->ecr &&
+ if ((pb->irq == PARPORT_IRQ_NONE) && priv->ecrok &&
(pb->modes & PARPORT_MODE_EPP))
pb->irq = irq_probe_EPP(pb);
@@ -2192,7 +2277,7 @@
static int __devinit parport_dma_probe (struct parport *p)
{
const struct parport_pc_private *priv = p->private_data;
- if (priv->ecr)
+ if (priv->ecrok)
p->dma = programmable_dma_support(p); /* ask ECP chipset first */
if (p->dma == PARPORT_DMA_NONE) {
/* ask known Super-IO chips proper, although these
@@ -2216,6 +2301,8 @@
struct parport tmp;
struct parport *p = &tmp;
int probedirq = PARPORT_IRQ_NONE;
+ char tmpname[16]="@";
+
if (check_region(base, 3)) return NULL;
priv = kmalloc (sizeof (struct parport_pc_private), GFP_KERNEL);
if (!priv) {
@@ -2232,13 +2319,18 @@
memcpy (ops, &parport_pc_ops, sizeof (struct parport_operations));
priv->ctr = 0xc;
priv->ctr_writable = ~0x10;
- priv->ecr = 0;
+ priv->irqshare = PARPORT_IRQ_AUTO;
+ priv->irqok = 0;
+ priv->ecrok = 0;
+ priv->ecr = 0x34;
priv->fifo_depth = 0;
priv->dma_buf = 0;
priv->dma_handle = 0;
priv->dev = dev;
p->base = base;
p->base_hi = base_hi;
+ sprintf(&tmpname[1],"%lx", base);
+ p->name= tmpname;
p->irq = irq;
p->dma = dma;
p->modes = PARPORT_MODE_PCSPP | PARPORT_MODE_SAFEININT;
@@ -2249,40 +2341,31 @@
if (base_hi && !check_region(base_hi,3))
parport_ECR_present(p);
- if (base != 0x3bc) {
- if (!check_region(base+0x3, 5)) {
- if (!parport_EPP_supported(p))
- parport_ECPEPP_supported(p);
- }
- }
if (!parport_SPP_supported (p)) {
/* No port. */
kfree (priv);
kfree (ops);
return NULL;
}
- if (priv->ecr)
- parport_ECPPS2_supported(p);
- else
- parport_PS2_supported (p);
- if (!(p = parport_register_port(base, PARPORT_IRQ_NONE,
- PARPORT_DMA_NONE, ops))) {
+ if (!(p = parport_register_port(base, irq, dma, ops))) {
kfree (priv);
kfree (ops);
return NULL;
}
-
p->base_hi = base_hi;
p->modes = tmp.modes;
- p->size = (p->modes & PARPORT_MODE_EPP)?8:3;
p->private_data = priv;
+ p->size = 3;
- printk(KERN_INFO "%s: PC-style at 0x%lx", p->name, p->base);
- if (p->base_hi && priv->ecr)
- printk(" (0x%lx)", p->base_hi);
- p->irq = irq;
- p->dma = dma;
+ if (base != 0x3bc && !check_region(base+0x3, 5))
+ parport_EPP_supported(p);
+
+ parport_PS2_supported (p);
+
+ if(p->modes & PARPORT_MODE_EPP) p->size = 8;
+
+ /* irq setup */
if (p->irq == PARPORT_IRQ_AUTO) {
p->irq = PARPORT_IRQ_NONE;
parport_irq_probe(p);
@@ -2293,7 +2376,6 @@
p->irq = PARPORT_IRQ_NONE;
}
if (p->irq != PARPORT_IRQ_NONE) {
- printk(", irq %d", p->irq);
priv->ctr_writable |= 0x10;
if (p->dma == PARPORT_DMA_AUTO) {
@@ -2301,8 +2383,60 @@
parport_dma_probe(p);
}
}
- if (p->dma == PARPORT_DMA_AUTO) /* To use DMA, giving the irq
- is mandatory (see above) */
+ if (probedirq != PARPORT_IRQ_NONE) {
+ if(dev && dev->irq!=probedirq)
+ printk(KERN_WARNING "%s: irq %d detected, but PCI routed to %d\n",
+ p->name, probedirq, dev->irq);
+ else
+ printk(KERN_INFO "%s: irq %d detected\n", p->name, probedirq);
+ }
+ if(priv->irqshare == PARPORT_IRQ_AUTO) {
+ if(probedirq != PARPORT_IRQ_NONE) priv->irqshare=probedirq;
+ else if(dev && dev->irq) priv->irqshare=dev->irq;
+ else if(p->modes & PARPORT_MODE_TRISTATE) priv->irqshare=p->irq;
+ else priv->irqshare=PARPORT_IRQ_NONE;
+ }
+
+ parport_proc_register(p);
+
+ request_region (p->base, 3, p->name);
+ if (p->size > 3)
+ request_region (p->base + 3, p->size - 3, p->name);
+ if (priv->ecrok)
+ request_region (p->base_hi, 3, p->name);
+
+ /* irq handler request */
+ if(p->irq != PARPORT_IRQ_NONE) {
+ unsigned long flags=
+ priv->irqshare!=PARPORT_IRQ_NONE ? SA_SHIRQ : 0;
+ if(request_irq (p->irq, parport_pc_interrupt,
+ flags, p->name, p)) {
+ printk (KERN_WARNING "%s: irq %d in use,"
+ " resorting to polled operation\n", p->name, p->irq);
+ p->irq = PARPORT_IRQ_NONE;
+ p->dma = PARPORT_DMA_NONE;
+ priv->irqshare= PARPORT_IRQ_NONE;
+ }
+ } else if(priv->irqshare != PARPORT_IRQ_NONE) {
+ /* handler for spurious IRQs */
+ if (request_irq (priv->irqshare, parport_pc_interrupt,
+ SA_SHIRQ, p->name, p)) {
+ printk (KERN_DEBUG "%s: irq %d in use, handler not installed\n",
+ p->name, priv->irqshare);
+ priv->irqshare=PARPORT_IRQ_NONE;
+ }
+ }
+
+ printk(KERN_INFO "%s: PC-style at 0x%lx", p->name, p->base);
+ if (p->base_hi && priv->ecrok)
+ printk(" (0x%lx)", p->base_hi);
+ if (p->irq != PARPORT_IRQ_NONE)
+ printk(", irq %d", p->irq);
+ if(priv->irqshare != PARPORT_IRQ_NONE)
+ printk(", irqshare %d", priv->irqshare);
+
+ /* To use DMA, giving the irq is mandatory (see above) */
+ if (p->dma == PARPORT_DMA_AUTO)
p->dma = PARPORT_DMA_NONE;
#ifdef CONFIG_PARPORT_PC_FIFO
@@ -2343,28 +2477,10 @@
printk ("(,...)");
#endif /* CONFIG_PARPORT_1284 */
printk("]\n");
- if (probedirq != PARPORT_IRQ_NONE)
- printk(KERN_INFO "%s: irq %d detected\n", p->name, probedirq);
- parport_proc_register(p);
-
- request_region (p->base, 3, p->name);
- if (p->size > 3)
- request_region (p->base + 3, p->size - 3, p->name);
- if (p->modes & PARPORT_MODE_ECP)
- request_region (p->base_hi, 3, p->name);
-
- if (p->irq != PARPORT_IRQ_NONE) {
- if (request_irq (p->irq, parport_pc_interrupt,
- 0, p->name, p)) {
- printk (KERN_WARNING "%s: irq %d in use, "
- "resorting to polled operation\n",
- p->name, p->irq);
- p->irq = PARPORT_IRQ_NONE;
- p->dma = PARPORT_DMA_NONE;
- }
+ /* dma request */
#ifdef CONFIG_PARPORT_PC_FIFO
- if (p->dma != PARPORT_DMA_NONE) {
+ if (p->irq != PARPORT_IRQ_NONE && p->dma != PARPORT_DMA_NONE) {
if (request_dma (p->dma, p->name)) {
printk (KERN_WARNING "%s: dma %d in use, "
"resorting to PIO operation\n",
@@ -2386,10 +2502,9 @@
}
}
#endif /* CONFIG_PARPORT_PC_FIFO */
- }
/* Done probing. Now put the port into a sensible start-up state. */
- if (priv->ecr)
+ if (priv->ecrok)
/*
* Put the ECP detected port in PS2 mode.
* Do this also for ports that have ECR but don't do ECP.
@@ -2409,18 +2524,18 @@
void parport_pc_unregister_port (struct parport *p)
{
-#ifdef CONFIG_PARPORT_PC_FIFO
struct parport_pc_private *priv = p->private_data;
-#endif /* CONFIG_PARPORT_PC_FIFO */
struct parport_operations *ops = p->ops;
+ int irqeff= p->irq!=PARPORT_IRQ_NONE ? p->irq : priv->irqshare;
+
if (p->dma != PARPORT_DMA_NONE)
free_dma(p->dma);
- if (p->irq != PARPORT_IRQ_NONE)
- free_irq(p->irq, p);
+ if (irqeff != PARPORT_IRQ_NONE)
+ free_irq(irqeff, p);
release_region(p->base, 3);
if (p->size > 3)
release_region(p->base + 3, p->size - 3);
- if (p->modes & PARPORT_MODE_ECP)
+ if (priv->ecrok)
release_region(p->base_hi, 3);
parport_proc_unregister(p);
#ifdef CONFIG_PARPORT_PC_FIFO
@@ -2429,7 +2544,7 @@
priv->dma_buf,
priv->dma_handle);
#endif /* CONFIG_PARPORT_PC_FIFO */
- kfree (p->private_data);
+ kfree (priv);
parport_unregister_port(p);
kfree (ops); /* hope no-one cached it */
}
@@ -2699,7 +2814,10 @@
oxsemi_840,
aks_0100,
mobility_pp,
-};
+ vscom_010s,
+ vscom_020s,
+ oxsemi_952,
+}; /* 45 entries */
/* each element directly indexed from enum list, above
@@ -2765,10 +2883,13 @@
/* The Oxford Semi cards are unusual: 954 doesn't support ECP,
* and 840 locks up if you write 1 to bit 2! */
/* oxsemi_954 */ { 1, { { 0, -1 }, } },
- /* oxsemi_840 */ { 1, { { 0, -1 }, } },
+ /* oxsemi_840 */ { 1, { { 0, 1 }, } },
/* aks_0100 */ { 1, { { 0, -1 }, } },
/* mobility_pp */ { 1, { { 0, 1 }, } },
-};
+ /* vscom_010s */ { 1, { { 2, 1 }, } },
+ /* vscom_020s */ { 2, { { 2, -1 },{3,-1}} },
+ /* oxsemi_952 */ { 1, { { 0, 1 }, } },
+}; /* 45 entries */
static struct pci_device_id parport_pc_pci_tbl[] __devinitdata = {
/* Super-IO onboard chips */
@@ -2795,6 +2916,9 @@
PCI_ANY_ID, PCI_ANY_ID, 0, 0, boca_ioppar },
{ PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
PCI_SUBVENDOR_ID_EXSYS, PCI_SUBDEVICE_ID_EXSYS_4014, 0,0, plx_9050 },
+ /* VScom / Titan parallel ports */
+ { PCI_VENDOR_ID_PLX, 0x1147, PCI_ANY_ID, PCI_ANY_ID, 0,0, vscom_020s },
+ { PCI_VENDOR_ID_PLX, 0x1146, PCI_ANY_ID, PCI_ANY_ID, 0,0, vscom_010s },
/* PCI_VENDOR_ID_TIMEDIA/SUNIX has many differing cards ...*/
{ 0x1409, 0x7168, 0x1409, 0x4078, 0, 0, timedia_4078a },
{ 0x1409, 0x7168, 0x1409, 0x4079, 0, 0, timedia_4079h },
@@ -2827,6 +2951,10 @@
{ PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_010L,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, titan_010l },
{ 0x9710, 0x9815, 0x1000, 0x0020, 0, 0, titan_1284p2 },
+ { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_010H,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, oxsemi_954 },
+ { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_010HV2,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, oxsemi_952 },
/* PCI_VENDOR_ID_AVLAB/Intek21 has another bunch of cards ...*/
{ 0x14db, 0x2120, PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1p}, /* AFAVLAB_TK9902 */
{ 0x14db, 0x2121, PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_2p},
@@ -2840,6 +2968,7 @@
};
MODULE_DEVICE_TABLE(pci,parport_pc_pci_tbl);
+static int pci_autoirq=PARPORT_IRQ_NONE;
static int __devinit parport_pc_pci_probe (struct pci_dev *dev,
const struct pci_device_id *id)
{
@@ -2862,20 +2991,25 @@
int lo = cards[i].addr[n].lo;
int hi = cards[i].addr[n].hi;
unsigned long io_lo, io_hi;
+ int irq;
+
io_lo = pci_resource_start (dev, lo);
io_hi = 0;
if ((hi >= 0) && (hi <= 6))
io_hi = pci_resource_start (dev, hi);
else if (hi > 6)
io_lo += hi; /* Reinterpret the meaning of
- "hi" as an offset (see SYBA
- def.) */
+ "hi" as an offset (see SYBA def.) */
/* TODO: test if sharing interrupts works */
- printk (KERN_DEBUG "PCI parallel port detected: %04x:%04x, "
- "I/O at %#lx(%#lx)\n",
- parport_pc_pci_tbl[i + last_sio].vendor,
- parport_pc_pci_tbl[i + last_sio].device, io_lo, io_hi);
- if (parport_pc_probe_port (io_lo, io_hi, PARPORT_IRQ_NONE,
+ if(pci_autoirq == PARPORT_IRQ_AUTO && dev->irq)
+ irq=dev->irq;
+ else
+ irq=PARPORT_IRQ_NONE;
+
+ printk (KERN_DEBUG "PCI parallel port detected: %04x:%04x,"
+ " I/O at %#lx(%#lx)\n", id->vendor, id->device,
+ io_lo, io_hi);
+ if (parport_pc_probe_port (io_lo, io_hi, irq,
PARPORT_DMA_NONE, dev))
count++;
}
@@ -2957,6 +3091,9 @@
/* ISA ports and whatever (see asm/parport.h). */
count += parport_pc_find_nonpci_ports (autoirq, autodma);
+#ifdef CONFIG_PCI
+ pci_autoirq=autoirq;
+#endif /* CONFIG_PCI */
r = pci_register_driver (&parport_pc_pci_driver);
if (r >= 0) {
registered_parport = 1;
@@ -3012,10 +3149,8 @@
MODULE_PARM(irq, "1-" __MODULE_STRING(PARPORT_PC_MAX_PORTS) "s");
MODULE_PARM_DESC(dma, "DMA channel");
MODULE_PARM(dma, "1-" __MODULE_STRING(PARPORT_PC_MAX_PORTS) "s");
-#if defined(CONFIG_PARPORT_PC_FIFO) || defined(CONFIG_PARPORT_PC_SUPERIO)
MODULE_PARM_DESC(verbose_probing, "Log chit-chat during initialisation");
MODULE_PARM(verbose_probing, "i");
-#endif
int init_module(void)
{
--- linux-2.4.23/drivers/parport/ieee1284_ops-dist.c Fri Dec 21 18:41:55 2001
+++ linux-2.4.23/drivers/parport/ieee1284_ops.c Wed Dec 3 01:04:36 2003
@@ -40,7 +40,7 @@
const void *buffer, size_t len,
int flags)
{
- int no_irq = 1;
+ int no_irq = port->irq == PARPORT_IRQ_NONE ? 1 : 0;
ssize_t count = 0;
const unsigned char *addr = buffer;
unsigned char byte;
@@ -48,10 +48,7 @@
unsigned char ctl = (PARPORT_CONTROL_SELECT
| PARPORT_CONTROL_INIT);
- if (port->irq != PARPORT_IRQ_NONE) {
- parport_enable_irq (port);
- no_irq = 0;
- }
+ if (!no_irq) parport_enable_irq (port);
port->physport->ieee1284.phase = IEEE1284_PH_FWD_DATA;
parport_write_control (port, ctl);
--- linux-2.4.23/include/linux/pci_ids-dist.h Fri Nov 28 19:26:21 2003
+++ linux-2.4.23/include/linux/pci_ids.h Wed Dec 3 01:15:29 2003
@@ -1638,10 +1638,19 @@
#define PCI_DEVICE_ID_TITAN_210L 0x8021
#define PCI_DEVICE_ID_TITAN_400L 0x8040
#define PCI_DEVICE_ID_TITAN_800L 0x8080
+#define PCI_DEVICE_ID_TITAN_430L 0x8043
+#define PCI_DEVICE_ID_TITAN_420L 0x8042
#define PCI_DEVICE_ID_TITAN_100 0xA001
#define PCI_DEVICE_ID_TITAN_200 0xA005
#define PCI_DEVICE_ID_TITAN_400 0xA003
#define PCI_DEVICE_ID_TITAN_800B 0xA004
+/* d.gruszka VScom (R) */
+#define PCI_DEVICE_ID_TITAN_200I 0x8028
+#define PCI_DEVICE_ID_TITAN_100HV2 0xE010
+#define PCI_DEVICE_ID_TITAN_200HV2 0xE020
+#define PCI_DEVICE_ID_TITAN_010HV2 0xE001
+#define PCI_DEVICE_ID_TITAN_010H 0xA000
+#define PCI_DEVICE_ID_TITAN_210S 0x1078
#define PCI_VENDOR_ID_PANACOM 0x14d4
#define PCI_DEVICE_ID_PANACOM_QUADMODEM 0x0400
--- linux-2.4.23/include/linux/parport_pc-dist.h Wed Nov 14 23:52:47 2001
+++ linux-2.4.23/include/linux/parport_pc.h Wed Dec 3 22:53:31 2003
@@ -22,8 +22,17 @@
/* Bitmask of writable CTR bits. */
unsigned char ctr_writable;
+ /* A value >=0 signals the shared irq line */
+ int irqshare;
+
+ /* Set nonzero when DSR bit 2 nINT works */
+ int irqok;
+
/* Whether or not there's an ECR. */
- int ecr;
+ int ecrok;
+
+ /* Last value written for shared IRQ detection */
+ unsigned char ecr;
/* Number of PWords that FIFO will hold. */
int fifo_depth;
@@ -111,17 +120,26 @@
unsigned char val)
{
struct parport_pc_private *priv = p->physport->private_data;
- unsigned char ctr = priv->ctr;
+ unsigned char ctr;
#ifdef DEBUG_PARPORT
+ ctr = priv->ctr;
printk (KERN_DEBUG
"__parport_pc_frob_control(%02x,%02x): %02x -> %02x\n",
mask, val, ctr, ((ctr & ~mask) ^ val) & priv->ctr_writable);
#endif
- ctr = (ctr & ~mask) ^ val;
+ /* The PCI irq handler modifies priv->ctr typically when we are
+ * raising STB# (end of +5V/0V/+5V strobe)
+ * STB# ------+ +-------
+ * +-+
+ * ^^^^^^^^printer lowers ACK# here
+ */
+ cli();
+ ctr = (priv->ctr & ~mask) ^ val;
ctr &= priv->ctr_writable; /* only write writable bits. */
- outb (ctr, CONTROL (p));
priv->ctr = ctr; /* Update soft copy */
- return ctr;
+ sti();
+ outb (priv->ctr, CONTROL (p));
+ return priv->ctr;
}
extern __inline__ void parport_pc_data_reverse (struct parport *p)
-- 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 2b29 : Thu Dec 11 2003 - 19:13:58 EST