📄 parport_pc.c
字号:
r = parport_pc_read_data (pb); if (r == w) { w = 0x55; parport_pc_write_data (pb, w); r = parport_pc_read_data (pb); if (r == w) return PARPORT_MODE_PCSPP; } if (user_specified) { /* Didn't work, but the user is convinced this is the * place. */ printk (KERN_DEBUG "parport 0x%lx (WARNING): DATA: " "wrote 0x%02x, read 0x%02x\n", pb->base, w, r); printk (KERN_DEBUG "parport 0x%lx: You gave this address, " "but there is probably no parallel port there!\n", pb->base); } /* 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; return 0;}/* Check for ECR * * Old style XT ports alias io ports every 0x400, hence accessing ECR * on these cards actually accesses the CTR. * * Modern cards don't do this but reading from ECR will return 0xff * regardless of what is written here if the card does NOT support * ECP. * * We first check to see if ECR is the same as CTR. If not, the low * two bits of ECR aren't writable, so we check by writing ECR and * reading it back to see if it's what we expect. */static int __devinit parport_ECR_present(struct parport *pb){ struct parport_pc_private *priv = pb->private_data; unsigned char r = 0xc; outb (r, CONTROL (pb)); if ((inb (ECONTROL (pb)) & 0x3) == (r & 0x3)) { outb (r ^ 0x2, CONTROL (pb)); /* Toggle bit 1 */ r = inb (CONTROL (pb)); if ((inb (ECONTROL (pb)) & 0x2) == (r & 0x2)) goto no_reg; /* Sure that no ECR register exists */ } if ((inb (ECONTROL (pb)) & 0x3 ) != 0x1) goto no_reg; outb (0x34, ECONTROL (pb)); if (inb (ECONTROL (pb)) != 0x35) goto no_reg; priv->ecr = 1; outb (0xc, CONTROL (pb)); /* Go to mode 000 */ frob_econtrol (pb, 0xe0, ECR_SPP << 5); return 1; no_reg: outb (0xc, CONTROL (pb)); return 0; }#ifdef CONFIG_PARPORT_1284/* Detect PS/2 support. * * Bit 5 (0x20) sets the PS/2 data direction; setting this high * allows us to read data from the data lines. In theory we would get back * 0xff but any peripheral attached to the port may drag some or all of the * lines down to zero. So if we get back anything that isn't the contents * of the data register we deem PS/2 support to be present. * * Some SPP ports have "half PS/2" ability - you can't turn off the line * drivers, but an external peripheral with sufficiently beefy drivers of * its own can overpower them and assert its own levels onto the bus, from * where they can then be read back as normal. Ports with this property * and the right type of device attached are likely to fail the SPP test, * (as they will appear to have stuck bits) and so the fact that they might * be misdetected here is rather academic. */static int __devinit parport_PS2_supported(struct parport *pb){ int ok = 0; clear_epp_timeout(pb); /* try to tri-state the buffer */ parport_pc_data_reverse (pb); parport_pc_write_data(pb, 0x55); if (parport_pc_read_data(pb) != 0x55) ok++; parport_pc_write_data(pb, 0xaa); if (parport_pc_read_data(pb) != 0xaa) ok++; /* cancel input mode */ parport_pc_data_forward (pb); if (ok) { pb->modes |= PARPORT_MODE_TRISTATE; } else { struct parport_pc_private *priv = pb->private_data; priv->ctr_writable &= ~0x20; } return ok;}static int __devinit parport_ECP_supported(struct parport *pb){ int i; int config, configb; int pword; struct parport_pc_private *priv = pb->private_data; int intrline[]={0,7,9,10,11,14,15,5}; /* Translate ECP intrLine to ISA irq value */ /* If there is no ECR, we have no hope of supporting ECP. */ if (!priv->ecr) return 0; /* Find out FIFO depth */ outb (ECR_SPP << 5, ECONTROL (pb)); /* Reset FIFO */ outb (ECR_TST << 5, ECONTROL (pb)); /* TEST FIFO */ for (i=0; i < 1024 && !(inb (ECONTROL (pb)) & 0x02); i++) outb (0xaa, FIFO (pb)); /* * Using LGS chipset it uses ECR register, but * it doesn't support ECP or FIFO MODE */ if (i == 1024) { outb (ECR_SPP << 5, ECONTROL (pb)); return 0; } priv->fifo_depth = i; printk (KERN_INFO "0x%lx: FIFO is %d bytes\n", pb->base, i); /* Find out writeIntrThreshold */ frob_econtrol (pb, 1<<2, 1<<2); frob_econtrol (pb, 1<<2, 0); for (i = 1; i <= priv->fifo_depth; i++) { inb (FIFO (pb)); udelay (50); if (inb (ECONTROL (pb)) & (1<<2)) break; } if (i <= priv->fifo_depth) printk (KERN_INFO "0x%lx: writeIntrThreshold is %d\n", pb->base, i); else /* Number of bytes we know we can write if we get an interrupt. */ i = 0; priv->writeIntrThreshold = i; /* Find out readIntrThreshold */ frob_econtrol (pb, 0xe0, ECR_PS2 << 5); /* 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_econtrol (pb, 1<<2, 1<<2); frob_econtrol (pb, 1<<2, 0); for (i = 1; i <= priv->fifo_depth; i++) { outb (0xaa, FIFO (pb)); if (inb (ECONTROL (pb)) & (1<<2)) break; } if (i <= priv->fifo_depth) printk (KERN_INFO "0x%lx: readIntrThreshold is %d\n", pb->base, i); else /* Number of bytes we can read if we get an interrupt. */ i = 0; priv->readIntrThreshold = i; outb (ECR_SPP << 5, ECONTROL (pb)); /* Reset FIFO */ outb (0xf4, ECONTROL (pb)); /* Configuration mode */ config = inb (CONFIGA (pb)); pword = (config >> 4) & 0x7; switch (pword) { case 0: pword = 2; printk (KERN_WARNING "0x%lx: Unsupported pword size!\n", pb->base); break; case 2: pword = 4; printk (KERN_WARNING "0x%lx: Unsupported pword size!\n", pb->base); break; default: printk (KERN_WARNING "0x%lx: Unknown implementation ID\n", pb->base); /* Assume 1 */ case 1: pword = 1; } priv->pword = pword; printk (KERN_DEBUG "0x%lx: PWord is %d bits\n", pb->base, 8 * pword); printk (KERN_DEBUG "0x%lx: Interrupts are ISA-%s\n", pb->base, config & 0x80 ? "Level" : "Pulses"); configb = inb (CONFIGB (pb)); if (!(configb & 0x40)) { printk (KERN_WARNING "0x%lx: possible IRQ conflict!\n", pb->base); pb->irq = PARPORT_IRQ_NONE; } printk (KERN_DEBUG "0x%lx: ECP port cfgA=0x%02x cfgB=0x%02x\n", pb->base, config, configb); printk (KERN_DEBUG "0x%lx: ECP settings irq=", pb->base); if ((configb >>3) & 0x07) printk("%d",intrline[(configb >>3) & 0x07]); else printk("<none or set by other means>"); printk ( " dma="); if( (configb & 0x03 ) == 0x00) printk("<none or set by other means>\n"); else printk("%d\n",configb & 0x07); /* Go back to mode 000 */ frob_econtrol (pb, 0xe0, ECR_SPP << 5); pb->modes |= PARPORT_MODE_ECP | PARPORT_MODE_COMPAT; return 1;}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)); outb (ECR_PS2 << 5, ECONTROL (pb)); result = parport_PS2_supported(pb); outb (oecr, ECONTROL (pb)); return result;}/* EPP mode detection */static int __devinit parport_EPP_supported(struct parport *pb){ const struct parport_pc_private *priv = pb->private_data; /* * Theory: * Bit 0 of STR is the EPP timeout bit, this bit is 0 * when EPP is possible and is set high when an EPP timeout * occurs (EPP uses the HALT line to stop the CPU while it does * the byte transfer, an EPP timeout occurs if the attached * device fails to respond after 10 micro seconds). * * This bit is cleared by either reading it (National Semi) * or writing a 1 to the bit (SMC, UMC, WinBond), others ??? * This bit is always high in non EPP modes. */ /* If EPP timeout bit clear then EPP available */ if (!clear_epp_timeout(pb)) return 0; /* No way to clear timeout */ /* Check for Intel bug. */ if (priv->ecr) { unsigned char i; for (i = 0x00; i < 0x80; i += 0x20) { outb (i, ECONTROL (pb)); if (clear_epp_timeout (pb)) /* Phony EPP in ECP. */ return 0; } } pb->modes |= PARPORT_MODE_EPP; /* Set up access functions to use EPP hardware. */ 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 */ outb (0x80, ECONTROL (pb)); outb (0x04, CONTROL (pb)); result = parport_EPP_supported(pb); outb (oecr, ECONTROL (pb)); if (result) { /* 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; pb->ops->epp_read_addr = parport_pc_ecpepp_read_addr; pb->ops->epp_write_addr = parport_pc_ecpepp_write_addr; } 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; }static int __devinit parport_ECP_supported(struct parport *pb) { return 0; }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 *//* --- IRQ detection -------------------------------------- *//* Only if supports ECP mode */static int __devinit programmable_irq_support(struct parport *pb){ int irq, intrLine; unsigned char oecr = inb (ECONTROL (pb)); static const int lookup[8] = { PARPORT_IRQ_NONE, 7, 9, 10, 11, 14, 15, 5 }; outb (ECR_CNF << 5, ECONTROL (pb)); /* Configuration MODE */ intrLine = (inb (CONFIGB (pb)) >> 3) & 0x07; irq = lookup[intrLine]; outb (oecr, ECONTROL (pb)); return irq;}static int __devinit irq_probe_ECP(struct parport *pb){ int i; unsigned long irqs; 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)); /* 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)); if (pb->irq <= 0) pb->irq = PARPORT_IRQ_NONE; return pb->irq;}/* * This detection seems that only works in National Semiconductors * This doesn't work in SMC, LGS, and Winbond */static int __devinit irq_probe_EPP(struct parport *pb){#ifndef ADVANCED_DETECT return PARPORT_IRQ_NONE;#else int irqs; unsigned char oecr; if (pb->modes & PARPORT_MODE_PCECR) oecr = inb (ECONTROL (pb)); sti(); irqs = probe_irq_on(); if (pb->modes & PARPORT_MODE_PCECR) frob_econtrol (pb, 0x10, 0x10); clear_epp_timeout(pb); parport_pc_frob_control (pb, 0x20, 0x20); parport_pc_frob_control (pb, 0x10, 0x10); clear_epp_timeout(pb); /* Device isn't expecting an EPP read * and generates an IRQ. */ parport_pc_read_epp(pb); udelay(20); pb->irq = probe_irq_off (irqs); if (pb->modes & PARPORT_MODE_PCECR) outb (oecr, ECONTROL (pb)); parport_pc_write_control(pb, 0xc); if (pb->irq <= 0) pb->irq = PARPORT_IRQ_NONE; return pb->irq;#endif /* Advanced detection */}static int __devinit irq_probe_SPP(struct parport *pb){ /* Don't even try to do this. */ return PARPORT_IRQ_NONE;}/* We will attempt to share interrupt requests since other devices * such as sound cards and network cards seem to like using the * printer IRQs. * * When ECP is available we can autoprobe for IRQs. * NOTE: If we can autoprobe it, we can register the IRQ. */static int __devinit parport_irq_probe(struct parport *pb){ const struct parport_pc_private *priv = pb->private_data; if (priv->ecr) { pb->irq = programmable_irq_support(pb); } if (pb->modes & PARPORT_MODE_ECP) pb->irq = irq_probe_ECP(pb); if (pb->irq == PARPORT_IRQ_NONE && priv->ecr && (pb->modes & PARPORT_MODE_EPP)) pb->irq = irq_probe_EPP(pb); clear_epp_timeout(pb); if (pb->irq == PARPORT_IRQ_NONE && (pb->modes & PARPORT_MODE_EPP)) pb->irq = irq_probe_EPP(pb); clear_epp_timeout(pb); if (pb->irq == PARPORT_IRQ_NONE) pb->irq = irq_probe_SPP(pb); if (pb->irq == PARPORT_IRQ_NONE) pb->irq = get_superio_irq(pb); return pb->irq;}/* --- DMA detection -------------------------------------- *//* Only if chipset conforms to ECP ISA Interface Standard */static int __devinit programmable_dma_support (struct parport *p){ unsigned char oecr = inb (ECONTROL (p)); int dma;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -