[PATCH] S2io: Timer based slowpath handling

Hi,
This patch implements the slow-path handling functions(link
state change, hardware errors) as a timer. It is not
handled in interrupt handler as was done previously.

Signed-off-by: Ravinandan Arakali <ravinandan.arakali@neterion.com>
Signed-off-by: Raghavendra Koushik <raghavendra.koushik@neterion.com>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index aff1fb7..ee498d2 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -168,6 +168,12 @@
 #define S2IO_TEST_LEN	sizeof(s2io_gstrings) / ETH_GSTRING_LEN
 #define S2IO_STRINGS_LEN	S2IO_TEST_LEN * ETH_GSTRING_LEN
 
+#define S2IO_TIMER_CONF(timer, handle, arg, exp)		\
+			init_timer(&timer);			\
+			timer.function = handle;		\
+			timer.data = (unsigned long) arg;	\
+			mod_timer(&timer, (jiffies + exp))	\
+
 /*
  * Constants to be programmed into the Xena's registers, to configure
  * the XAUI.
@@ -2741,6 +2747,7 @@
 setting_mac_address_failed:
 	free_irq(sp->pdev->irq, dev);
 isr_registration_failed:
+	del_timer_sync(&sp->alarm_timer);
 	s2io_reset(sp);
 hw_init_failed:
 	return err;
@@ -2898,6 +2905,15 @@
 	return 0;
 }
 
+static void
+s2io_alarm_handle(unsigned long data)
+{
+	nic_t *sp = (nic_t *)data;
+
+	alarm_intr_handler(sp);
+	mod_timer(&sp->alarm_timer, jiffies + HZ / 2);
+}
+
 /**
  *  s2io_isr - ISR handler of the device .
  *  @irq: the irq of the device.
@@ -2942,9 +2958,6 @@
 		return IRQ_NONE;
 	}
 
-	if (reason & (GEN_ERROR_INTR))
-		alarm_intr_handler(sp);
-
 #ifdef CONFIG_S2IO_NAPI
 	if (reason & GEN_INTR_RXTRAFFIC) {
 		if (netif_rx_schedule_prep(dev)) {
@@ -4394,6 +4407,7 @@
 	unsigned long flags;
 	register u64 val64 = 0;
 
+	del_timer_sync(&sp->alarm_timer);
 	/* If s2io_set_link task is executing, wait till it completes. */
 	while (test_and_set_bit(0, &(sp->link_state))) {
 		msleep(50);
@@ -4496,6 +4510,8 @@
 		return -ENODEV;
 	}
 
+	S2IO_TIMER_CONF(sp->alarm_timer, s2io_alarm_handle, sp, (HZ/2));
+
 	atomic_set(&sp->card_state, CARD_UP);
 	return 0;
 }