#include "s2io.h"
 #include "s2io-regs.h"
 
-#define DRV_VERSION "2.0.26.1"
+#define DRV_VERSION "2.0.26.2"
 
 /* S2io Driver name & version. */
 static char s2io_driver_name[] = "Neterion";
        struct XENA_dev_config __iomem *bar0 = nic->bar0;
        int i;
 
-       atomic_inc(&nic->isr_cnt);
-
-       if (!is_s2io_card_up(nic)) {
-               atomic_dec(&nic->isr_cnt);
+       if (!is_s2io_card_up(nic))
                return 0;
-       }
 
        mac_control = &nic->mac_control;
        config = &nic->config;
        /* Re enable the Rx interrupts. */
        writeq(0x0, &bar0->rx_traffic_mask);
        readl(&bar0->rx_traffic_mask);
-       atomic_dec(&nic->isr_cnt);
        return pkt_cnt;
 
 no_rx:
                        break;
                }
        }
-       atomic_dec(&nic->isr_cnt);
        return pkt_cnt;
 }
 
 
        disable_irq(dev->irq);
 
-       atomic_inc(&nic->isr_cnt);
        mac_control = &nic->mac_control;
        config = &nic->config;
 
                        break;
                }
        }
-       atomic_dec(&nic->isr_cnt);
        enable_irq(dev->irq);
        return;
 }
        struct ring_info *ring = (struct ring_info *)dev_id;
        struct s2io_nic *sp = ring->nic;
 
-       atomic_inc(&sp->isr_cnt);
-
-       if (!is_s2io_card_up(sp)) {
-               atomic_dec(&sp->isr_cnt);
+       if (!is_s2io_card_up(sp))
                return IRQ_HANDLED;
-       }
 
        rx_intr_handler(ring);
        s2io_chk_rx_buffers(sp, ring->ring_no);
 
-       atomic_dec(&sp->isr_cnt);
        return IRQ_HANDLED;
 }
 
        struct fifo_info *fifo = (struct fifo_info *)dev_id;
        struct s2io_nic *sp = fifo->nic;
 
-       atomic_inc(&sp->isr_cnt);
-
-       if (!is_s2io_card_up(sp)) {
-               atomic_dec(&sp->isr_cnt);
+       if (!is_s2io_card_up(sp))
                return IRQ_HANDLED;
-       }
 
        tx_intr_handler(fifo);
-       atomic_dec(&sp->isr_cnt);
        return IRQ_HANDLED;
 }
 static void s2io_txpic_intr_handle(struct s2io_nic *sp)
        if (pci_channel_offline(sp->pdev))
                return IRQ_NONE;
 
-       atomic_inc(&sp->isr_cnt);
-
-       if (!is_s2io_card_up(sp)) {
-               atomic_dec(&sp->isr_cnt);
+       if (!is_s2io_card_up(sp))
                return IRQ_NONE;
-       }
 
        mac_control = &sp->mac_control;
        config = &sp->config;
         * 1. Rx of packet.
         * 2. Tx complete.
         * 3. Link down.
-        * 4. Error in any functional blocks of the NIC.
         */
        reason = readq(&bar0->general_int_status);
 
-       if (!reason) {
-               /* The interrupt was not raised by us. */
-               atomic_dec(&sp->isr_cnt);
-               return IRQ_NONE;
-       }
-       else if (unlikely(reason == S2IO_MINUS_ONE) ) {
-               /* Disable device and get out */
-               atomic_dec(&sp->isr_cnt);
-               return IRQ_NONE;
+       if (unlikely(reason == S2IO_MINUS_ONE) ) {
+               /* Nothing much can be done. Get out */
+               return IRQ_HANDLED;
        }
 
-       if (napi) {
-               if (reason & GEN_INTR_RXTRAFFIC) {
-                       if (likely (netif_rx_schedule_prep(dev, &sp->napi))) {
-                               __netif_rx_schedule(dev, &sp->napi);
-                               writeq(S2IO_MINUS_ONE, &bar0->rx_traffic_mask);
+       if (reason & (GEN_INTR_RXTRAFFIC |
+               GEN_INTR_TXTRAFFIC | GEN_INTR_TXPIC))
+       {
+               writeq(S2IO_MINUS_ONE, &bar0->general_int_mask);
+
+               if (config->napi) {
+                       if (reason & GEN_INTR_RXTRAFFIC) {
+                               if (likely(netif_rx_schedule_prep(dev,
+                                                       &sp->napi))) {
+                                       __netif_rx_schedule(dev, &sp->napi);
+                                       writeq(S2IO_MINUS_ONE,
+                                              &bar0->rx_traffic_mask);
+                               } else
+                                       writeq(S2IO_MINUS_ONE,
+                                              &bar0->rx_traffic_int);
                        }
-                       else
+               } else {
+                       /*
+                        * rx_traffic_int reg is an R1 register, writing all 1's
+                        * will ensure that the actual interrupt causing bit
+                        * get's cleared and hence a read can be avoided.
+                        */
+                       if (reason & GEN_INTR_RXTRAFFIC)
                                writeq(S2IO_MINUS_ONE, &bar0->rx_traffic_int);
+
+                       for (i = 0; i < config->rx_ring_num; i++)
+                               rx_intr_handler(&mac_control->rings[i]);
                }
-       } else {
+
                /*
-                * Rx handler is called by default, without checking for the
-                * cause of interrupt.
-                * rx_traffic_int reg is an R1 register, writing all 1's
+                * tx_traffic_int reg is an R1 register, writing all 1's
                 * will ensure that the actual interrupt causing bit get's
                 * cleared and hence a read can be avoided.
                 */
-               if (reason & GEN_INTR_RXTRAFFIC)
-                       writeq(S2IO_MINUS_ONE, &bar0->rx_traffic_int);
+               if (reason & GEN_INTR_TXTRAFFIC)
+                       writeq(S2IO_MINUS_ONE, &bar0->tx_traffic_int);
 
-               for (i = 0; i < config->rx_ring_num; i++) {
-                       rx_intr_handler(&mac_control->rings[i]);
-               }
-       }
+               for (i = 0; i < config->tx_fifo_num; i++)
+                       tx_intr_handler(&mac_control->fifos[i]);
 
-       /*
-        * tx_traffic_int reg is an R1 register, writing all 1's
-        * will ensure that the actual interrupt causing bit get's
-        * cleared and hence a read can be avoided.
-        */
-       if (reason & GEN_INTR_TXTRAFFIC)
-               writeq(S2IO_MINUS_ONE, &bar0->tx_traffic_int);
+               if (reason & GEN_INTR_TXPIC)
+                       s2io_txpic_intr_handle(sp);
 
-       for (i = 0; i < config->tx_fifo_num; i++)
-               tx_intr_handler(&mac_control->fifos[i]);
+               /*
+                * Reallocate the buffers from the interrupt handler itself.
+                */
+               if (!config->napi) {
+                       for (i = 0; i < config->rx_ring_num; i++)
+                               s2io_chk_rx_buffers(sp, i);
+               }
+               writeq(sp->general_int_mask, &bar0->general_int_mask);
+               readl(&bar0->general_int_status);
 
-       if (reason & GEN_INTR_TXPIC)
-               s2io_txpic_intr_handle(sp);
-       /*
-        * If the Rx buffer count is below the panic threshold then
-        * reallocate the buffers from the interrupt handler itself,
-        * else schedule a tasklet to reallocate the buffers.
-        */
-       if (!napi) {
-               for (i = 0; i < config->rx_ring_num; i++)
-                       s2io_chk_rx_buffers(sp, i);
-       }
+               return IRQ_HANDLED;
 
-       writeq(0, &bar0->general_int_mask);
-       readl(&bar0->general_int_status);
+       }
+       else if (!reason) {
+               /* The interrupt was not raised by us */
+               return IRQ_NONE;
+       }
 
-       atomic_dec(&sp->isr_cnt);
        return IRQ_HANDLED;
 }
 
 }
 static void s2io_rem_isr(struct s2io_nic * sp)
 {
-       int cnt = 0;
        struct net_device *dev = sp->dev;
        struct swStat *stats = &sp->mac_control.stats_info->sw_stat;
 
                        int vector = sp->entries[i].vector;
                        void *arg = sp->s2io_entries[i].arg;
 
+                       synchronize_irq(vector);
                        free_irq(vector, arg);
                }
 
 
                pci_disable_msix(sp->pdev);
        } else {
+               synchronize_irq(sp->pdev->irq);
                free_irq(sp->pdev->irq, dev);
        }
-       /* Waiting till all Interrupt handlers are complete */
-       cnt = 0;
-       do {
-               msleep(10);
-               if (!atomic_read(&sp->isr_cnt))
-                       break;
-               cnt++;
-       } while(cnt < 5);
 }
 
 static void do_s2io_card_down(struct s2io_nic * sp, int do_io)
        if (*dev_intr_type != INTA)
                napi = 0;
 
-#ifndef CONFIG_PCI_MSI
-       if (*dev_intr_type != INTA) {
-               DBG_PRINT(ERR_DBG, "s2io: This kernel does not support"
-                         "MSI/MSI-X. Defaulting to INTA\n");
-               *dev_intr_type = INTA;
-       }
-#else
        if ((*dev_intr_type != INTA) && (*dev_intr_type != MSI_X)) {
                DBG_PRINT(ERR_DBG, "s2io: Wrong intr_type requested. "
                          "Defaulting to INTA\n");
                *dev_intr_type = INTA;
        }
-#endif
+
        if ((*dev_intr_type == MSI_X) &&
                        ((pdev->device != PCI_DEVICE_ID_HERC_WIN) &&
                        (pdev->device != PCI_DEVICE_ID_HERC_UNI))) {
        mac_control = &sp->mac_control;
        config = &sp->config;
 
+       config->napi = napi;
+
        /* Tx side parameters. */
        config->tx_fifo_num = tx_fifo_num;
        for (i = 0; i < MAX_TX_FIFOS; i++) {
        for (i = 0; i < config->rx_ring_num; i++)
                atomic_set(&sp->rx_bufs_left[i], 0);
 
-       /* Initialize the number of ISRs currently running */
-       atomic_set(&sp->isr_cnt, 0);
-
        /*  initialize the shared memory used by the NIC and the host */
        if (init_shared_mem(sp)) {
                DBG_PRINT(ERR_DBG, "%s: Memory allocation failed\n",