- patches.arch/x86_mce_intel_decode_physical_address.patch:
[linux-flexiantxendom0-3.2.10.git] / drivers / net / 3c503.c
index 66e0323..baac246 100644 (file)
@@ -380,6 +380,12 @@ out:
     return retval;
 }
 
+static irqreturn_t el2_probe_interrupt(int irq, void *seen)
+{
+       *(bool *)seen = true;
+       return IRQ_HANDLED;
+}
+
 static int
 el2_open(struct net_device *dev)
 {
@@ -391,23 +397,35 @@ el2_open(struct net_device *dev)
 
        outb(EGACFR_NORM, E33G_GACFR);  /* Enable RAM and interrupts. */
        do {
-           retval = request_irq(*irqp, NULL, 0, "bogus", dev);
-           if (retval >= 0) {
+               bool seen;
+
+               retval = request_irq(*irqp, el2_probe_interrupt, 0,
+                                    dev->name, &seen);
+               if (retval == -EBUSY)
+                       continue;
+               if (retval < 0)
+                       goto err_disable;
+
                /* Twinkle the interrupt, and check if it's seen. */
-               unsigned long cookie = probe_irq_on();
+               seen = false;
+               smp_wmb();
                outb_p(0x04 << ((*irqp == 9) ? 2 : *irqp), E33G_IDCFR);
                outb_p(0x00, E33G_IDCFR);
-               if (*irqp == probe_irq_off(cookie) &&   /* It's a good IRQ line! */
-                   ((retval = request_irq(dev->irq = *irqp,
-                                          eip_interrupt, 0,
-                                          dev->name, dev)) == 0))
-                   break;
-           } else {
-                   if (retval != -EBUSY)
-                           return retval;
-           }
+               msleep(1);
+               free_irq(*irqp, el2_probe_interrupt);
+               if (!seen)
+                       continue;
+
+               retval = request_irq(dev->irq = *irqp, eip_interrupt, 0,
+                                    dev->name, dev);
+               if (retval == -EBUSY)
+                       continue;
+               if (retval < 0)
+                       goto err_disable;
        } while (*++irqp);
+
        if (*irqp == 0) {
+       err_disable:
            outb(EGACFR_IRQOFF, E33G_GACFR);    /* disable interrupts. */
            return -EAGAIN;
        }
@@ -555,7 +573,6 @@ el2_block_output(struct net_device *dev, int count,
     }
     blocked:;
     outb_p(ei_status.interface_num==0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL);
-    return;
 }
 
 /* Read the 4 byte, page aligned 8390 specific header. */
@@ -671,7 +688,6 @@ el2_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring
     }
     blocked:;
     outb_p(ei_status.interface_num == 0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL);
-    return;
 }