patch-2.1.95 linux/drivers/misc/parport_pc.c
Next file: linux/drivers/net/ne.c
Previous file: linux/drivers/char/tga.c
Back to the patch index
Back to the overall index
- Lines: 161
- Date:
Fri Apr 10 10:10:31 1998
- Orig file:
v2.1.94/linux/drivers/misc/parport_pc.c
- Orig date:
Mon Apr 6 17:41:00 1998
diff -u --recursive --new-file v2.1.94/linux/drivers/misc/parport_pc.c linux/drivers/misc/parport_pc.c
@@ -641,58 +641,6 @@
/* --- IRQ detection -------------------------------------- */
-/* This code is for detecting ECP interrupts (due to problems with the
- * monolithic interrupt probing routines).
- *
- * In short this is a voting system where the interrupt with the most
- * "votes" is the elected interrupt (it SHOULD work...)
- *
- * This is horribly x86-specific at the moment. I'm not convinced it
- * belongs at all.
- */
-
-static int intr_vote[16];
-
-static void parport_vote_intr_func(int irq, void *dev_id, struct pt_regs *regs)
-{
- intr_vote[irq]++;
- return;
-}
-
-static long open_intr_election(void)
-{
- long tmp = 0;
- int i;
-
- /* We ignore the timer - irq 0 */
- for (i = 1; i < 16; i++) {
- intr_vote[i] = 0;
- if (request_irq(i, parport_vote_intr_func,
- SA_INTERRUPT, "probe", intr_vote) == 0)
- tmp |= 1 << i;
- }
- return tmp;
-}
-
-static int close_intr_election(long tmp)
-{
- int irq = PARPORT_IRQ_NONE;
- int i;
-
- /* We ignore the timer - irq 0 */
- for (i = 1; i < 16; i++)
- if (tmp & (1 << i)) {
- if (intr_vote[i]) {
- if (irq != PARPORT_IRQ_NONE)
- /* More than one interrupt */
- return PARPORT_IRQ_NONE;
- irq = i;
- }
- free_irq(i, intr_vote);
- }
- return irq;
-}
-
/* Only if supports ECP mode */
static int programmable_irq_support(struct parport *pb)
{
@@ -714,20 +662,23 @@
static int irq_probe_ECP(struct parport *pb)
{
int irqs, i;
- unsigned char oecr = parport_pc_read_econtrol(pb);
- probe_irq_off(probe_irq_on()); /* Clear any interrupts */
- irqs = open_intr_election();
+ sti();
+ irqs = probe_irq_on();
- parport_pc_write_econtrol(pb, 0x00); /* Reset FIFO */
- parport_pc_write_econtrol(pb, 0xd0); /* TEST FIFO + nErrIntrEn */
+ parport_pc_write_econtrol(pb, 0x00); /* Reset FIFO */
+ parport_pc_write_econtrol(pb, 0xd0); /* TEST FIFO + nErrIntrEn */
/* If Full FIFO sure that WriteIntrThresold is generated */
for (i=0; i < 1024 && !(parport_pc_read_econtrol(pb) & 0x02) ; i++)
parport_pc_write_fifo(pb, 0xaa);
- pb->irq = close_intr_election(irqs);
- parport_pc_write_econtrol(pb, oecr);
+ pb->irq = probe_irq_off(irqs);
+ parport_pc_write_econtrol(pb, 0x00);
+
+ if (pb->irq <= 0)
+ pb->irq = PARPORT_IRQ_NONE;
+
return pb->irq;
}
@@ -745,26 +696,30 @@
return PARPORT_IRQ_NONE;
#endif
- probe_irq_off(probe_irq_on()); /* Clear any interrupts */
- irqs = open_intr_election();
+ sti();
+ irqs = probe_irq_on();
if (pb->modes & PARPORT_MODE_PCECR)
- parport_pc_write_econtrol(pb, parport_pc_read_econtrol(pb) | 0x10);
+ parport_pc_frob_econtrol (pb, 0x10, 0x10);
epp_clear_timeout(pb);
- parport_pc_write_control(pb, parport_pc_read_control(pb) | 0x20);
- parport_pc_write_control(pb, parport_pc_read_control(pb) | 0x10);
+ parport_pc_frob_control (pb, 0x20, 0x20);
+ parport_pc_frob_control (pb, 0x10, 0x10);
epp_clear_timeout(pb);
- /* Device isn't expecting an EPP read
+ /* Device isn't expecting an EPP read
* and generates an IRQ.
*/
parport_pc_read_epp(pb);
udelay(20);
- pb->irq = close_intr_election(irqs);
+ pb->irq = probe_irq_off (irqs);
parport_pc_write_econtrol(pb, oecr);
parport_pc_write_control(pb, octr);
+
+ if (pb->irq <= 0)
+ pb->irq = PARPORT_IRQ_NONE;
+
return pb->irq;
}
@@ -815,16 +770,19 @@
*/
static int parport_irq_probe(struct parport *pb)
{
- if (pb->modes & PARPORT_MODE_PCECR)
+ 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)
+ goto out;
+ }
if (pb->modes & PARPORT_MODE_PCECP)
pb->irq = irq_probe_ECP(pb);
-
+
if (pb->irq == PARPORT_IRQ_NONE &&
(pb->modes & PARPORT_MODE_PCECPEPP)) {
- unsigned char oecr = parport_pc_read_econtrol(pb);
- parport_pc_write_econtrol(pb, 0x80);
pb->irq = irq_probe_EPP(pb);
parport_pc_write_econtrol(pb, oecr);
}
@@ -839,6 +797,8 @@
if (pb->irq == PARPORT_IRQ_NONE)
pb->irq = irq_probe_SPP(pb);
+out:
+ parport_pc_write_econtrol (pb, oecr);
return pb->irq;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov