public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* Initial bits to help pull jiffies out of drivers
@ 2004-07-27 19:59 Alan Cox
  2004-08-02 21:33 ` Tim Bird
  2004-08-03  8:27 ` Arjan van de Ven
  0 siblings, 2 replies; 6+ messages in thread
From: Alan Cox @ 2004-07-27 19:59 UTC (permalink / raw)
  To: linux-kernel

This is really for comment, the basic idea is to add some relative
timer functionality. This gives us timeout objects as well as pulling
jiffies use into one place in the timer code. The need for the old
interfaces never goes away however because some code uses a previous
event base to construct timeouts to avoid sliding due to the latency
between service and re-addition.

(please cc me on comments)

diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.8-rc2/drivers/char/amiserial.c linux-2.6.8-rc2/drivers/char/amiserial.c
--- linux.vanilla-2.6.8-rc2/drivers/char/amiserial.c	2004-07-27 19:21:10.210292240 +0100
+++ linux-2.6.8-rc2/drivers/char/amiserial.c	2004-07-27 13:36:28.000000000 +0100
@@ -1587,8 +1587,9 @@
 static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
 {
 	struct async_struct * info = (struct async_struct *)tty->driver_data;
-	unsigned long orig_jiffies, char_time;
+	unsigned long char_time;
 	int lsr;
+	struct timer_list t;
 
 	if (serial_paranoia_check(info, tty->name, "rs_wait_until_sent"))
 		return;
@@ -1596,7 +1597,6 @@
 	if (info->xmit_fifo_size == 0)
 		return; /* Just in case.... */
 
-	orig_jiffies = jiffies;
 	/*
 	 * Set the check interval to be 1/5 of the estimated time to
 	 * send a single character, and make it at least 1.  The check
@@ -1622,24 +1622,30 @@
 	 */
 	if (!timeout || timeout > 2*info->timeout)
 		timeout = 2*info->timeout;
+	init_timer(&t);
+	t.expires = timeout;
+	t.function = timer_noop;
+	
+	add_timeout(&t);
+
 #ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
 	printk("In rs_wait_until_sent(%d) check=%lu...", timeout, char_time);
-	printk("jiff=%lu...", jiffies);
 #endif
 	while(!((lsr = custom.serdatr) & SDR_TSRE)) {
 #ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
-		printk("serdatr = %d (jiff=%lu)...", lsr, jiffies);
+		printk("serdatr = %d ...", lsr);
 #endif
 		current->state = TASK_INTERRUPTIBLE;
 		schedule_timeout(char_time);
 		if (signal_pending(current))
 			break;
-		if (timeout && time_after(jiffies, orig_jiffies + timeout))
+		if (timeout && !timer_pending(&t))
 			break;
 	}
+	del_timeout(&t);
 	current->state = TASK_RUNNING;
 #ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
-	printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies);
+	printk("lsr = %d ...done\n", lsr);
 #endif
 }
 
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.8-rc2/drivers/char/cyclades.c linux-2.6.8-rc2/drivers/char/cyclades.c
--- linux.vanilla-2.6.8-rc2/drivers/char/cyclades.c	2004-07-27 19:22:42.715229352 +0100
+++ linux-2.6.8-rc2/drivers/char/cyclades.c	2004-07-27 12:40:46.000000000 +0100
@@ -959,10 +959,10 @@
 #ifdef CONFIG_CYZ_INTR
     if (test_and_clear_bit(Cy_EVENT_Z_RX_FULL, &info->event)) {
 	if (cyz_rx_full_timer[info->line].function == NULL) {
-	    cyz_rx_full_timer[info->line].expires = jiffies + 1;
+	    cyz_rx_full_timer[info->line].expires = 1;
 	    cyz_rx_full_timer[info->line].function = cyz_rx_restart;
 	    cyz_rx_full_timer[info->line].data = (unsigned long)info;
-	    add_timer(&cyz_rx_full_timer[info->line]);
+	    add_timeout(&cyz_rx_full_timer[info->line]);
 	}
     }
 #endif
@@ -1908,17 +1908,17 @@
 static void
 cyz_poll(unsigned long arg)
 {
-  struct cyclades_card *cinfo;
-  struct cyclades_port *info;
-  struct tty_struct *tty;
-  static volatile struct FIRM_ID *firm_id;
-  static volatile struct ZFW_CTRL *zfw_ctrl;
-  static volatile struct BOARD_CTRL *board_ctrl;
-  static volatile struct CH_CTRL *ch_ctrl;
-  static volatile struct BUF_CTRL *buf_ctrl;
-  int card, port;
+	struct cyclades_card *cinfo;
+	struct cyclades_port *info;
+	struct tty_struct *tty;
+	static volatile struct FIRM_ID *firm_id;
+	static volatile struct ZFW_CTRL *zfw_ctrl;
+	static volatile struct BOARD_CTRL *board_ctrl;
+	static volatile struct CH_CTRL *ch_ctrl;
+	static volatile struct BUF_CTRL *buf_ctrl;
+	int card, port;
 
-    cyz_timerlist.expires = jiffies + (HZ);
+    cyz_timerlist.expires = HZ;
     for (card = 0 ; card < NR_CARDS ; card++){
 	cinfo = &cy_card[card];
 
@@ -1951,9 +1951,9 @@
 	    cyz_handle_tx(info, ch_ctrl, buf_ctrl);
 	}
 	/* poll every 'cyz_polling_cycle' period */
-	cyz_timerlist.expires = jiffies + cyz_polling_cycle;
+	cyz_timerlist.expires = cyz_polling_cycle;
     }
-    add_timer(&cyz_timerlist);
+    add_timeout(&cyz_timerlist);
 
     return;
 } /* cyz_poll */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.8-rc2/drivers/char/ds1286.c linux-2.6.8-rc2/drivers/char/ds1286.c
--- linux.vanilla-2.6.8-rc2/drivers/char/ds1286.c	2004-07-27 19:22:42.737226008 +0100
+++ linux-2.6.8-rc2/drivers/char/ds1286.c	2004-07-27 13:41:38.000000000 +0100
@@ -434,8 +434,7 @@
 static void ds1286_get_time(struct rtc_time *rtc_tm)
 {
 	unsigned char save_control;
-	unsigned int flags;
-	unsigned long uip_watchdog = jiffies;
+	unsigned long flags;
 
 	/*
 	 * read RTC once any update in progress is done. The update
@@ -448,8 +447,7 @@
 	 */
 
 	if (ds1286_is_updating() != 0)
-		while (jiffies - uip_watchdog < 2*HZ/100)
-			barrier();
+		mdelay(20);
 
 	/*
 	 * Only the values that we read from the RTC are set. We leave
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.8-rc2/drivers/char/dtlk.c linux-2.6.8-rc2/drivers/char/dtlk.c
--- linux.vanilla-2.6.8-rc2/drivers/char/dtlk.c	2004-07-27 19:22:42.738225856 +0100
+++ linux-2.6.8-rc2/drivers/char/dtlk.c	2004-07-27 13:39:33.000000000 +0100
@@ -241,12 +241,6 @@
 	unsigned long expires;
 
 	TRACE_TEXT(" dtlk_poll");
-	/*
-	   static long int j;
-	   printk(".");
-	   printk("<%ld>", jiffies-j);
-	   j=jiffies;
-	 */
 	poll_wait(file, &dtlk_process_list, wait);
 
 	if (dtlk_has_indexing && dtlk_readable()) {
@@ -260,8 +254,8 @@
 	/* there are no exception conditions */
 
 	/* There won't be any interrupts, so we set a timer instead. */
-	expires = jiffies + 3*HZ / 100;
-	mod_timer(&dtlk_timer, expires);
+	expires = 3*HZ / 100;
+	mod_timeout(&dtlk_timer, expires);
 
 	return mask;
 }
@@ -385,7 +379,7 @@
 static int dtlk_readable(void)
 {
 #ifdef TRACING
-	printk(" dtlk_readable=%u@%u", inb_p(dtlk_port_lpc) != 0x7f, jiffies);
+	printk(" dtlk_readable=%u", inb_p(dtlk_port_lpc) != 0x7f);
 #endif
 	return inb_p(dtlk_port_lpc) != 0x7f;
 }
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.8-rc2/drivers/char/epca.c linux-2.6.8-rc2/drivers/char/epca.c
--- linux.vanilla-2.6.8-rc2/drivers/char/epca.c	2004-07-27 19:21:10.262284336 +0100
+++ linux-2.6.8-rc2/drivers/char/epca.c	2004-07-27 13:37:00.000000000 +0100
@@ -1806,7 +1806,7 @@
 
 	init_timer(&epca_timer);
 	epca_timer.function = epcapoll;
-	mod_timer(&epca_timer, jiffies + HZ/25);
+	mod_timeout(&epca_timer, HZ/25);
 
 	restore_flags(flags);
 
@@ -2155,7 +2155,7 @@
 
 	} /* End for each card */
 
-	mod_timer(&epca_timer, jiffies + (HZ / 25));
+	mod_timeout(&epca_timer, (HZ / 25));
 
 	restore_flags(flags);
 } /* End epcapoll */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.8-rc2/drivers/char/isicom.c linux-2.6.8-rc2/drivers/char/isicom.c
--- linux.vanilla-2.6.8-rc2/drivers/char/isicom.c	2004-07-27 19:21:11.907034296 +0100
+++ linux-2.6.8-rc2/drivers/char/isicom.c	2004-07-27 13:38:51.000000000 +0100
@@ -153,12 +153,13 @@
 								
 			inw(base+0x8);
 			
-			for(t=jiffies+HZ/100;time_before(jiffies, t););
+			msleep(10);
 				
 			outw(0,base+0x8); /* Reset */
 			
 			for(j=1;j<=3;j++) {
-				for(t=jiffies+HZ;time_before(jiffies, t););
+			{
+				msleep(1000);
 				printk(".");
 			}	
 			signature=(inw(base+0x4)) & 0xff;	
@@ -465,10 +466,10 @@
 	if (!re_schedule)	
 		return;
 	init_timer(&tx);
-	tx.expires = jiffies + HZ/100;
+	tx.expires = HZ/100;
 	tx.data = 0;
 	tx.function = isicom_tx;
-	add_timer(&tx);
+	add_timeout(&tx);
 	
 	return;	
 }		
@@ -1894,11 +1895,11 @@
 	}
 	
 	init_timer(&tx);
-	tx.expires = jiffies + 1;
+	tx.expires = 1;
 	tx.data = 0;
 	tx.function = isicom_tx;
 	re_schedule = 1;
-	add_timer(&tx);
+	add_timeout(&tx);
 	
 	return 0;
 }
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.8-rc2/drivers/char/moxa.c linux-2.6.8-rc2/drivers/char/moxa.c
--- linux.vanilla-2.6.8-rc2/drivers/char/moxa.c	2004-07-27 19:21:12.611927136 +0100
+++ linux-2.6.8-rc2/drivers/char/moxa.c	2004-07-27 13:34:10.000000000 +0100
@@ -363,9 +363,9 @@
 
 	init_timer(&moxaTimer);
 	moxaTimer.function = moxa_poll;
-	moxaTimer.expires = jiffies + (HZ / 50);
+	moxaTimer.expires = (HZ / 50);
 	moxaTimer_on = 1;
-	add_timer(&moxaTimer);
+	add_timeout(&moxaTimer);
 
 	/* Find the boards defined in source code */
 	numBoards = 0;
@@ -927,9 +927,9 @@
 
 	if (MoxaDriverPoll() < 0) {
 		moxaTimer.function = moxa_poll;
-		moxaTimer.expires = jiffies + (HZ / 50);
+		moxaTimer.expires = HZ / 50;
 		moxaTimer_on = 1;
-		add_timer(&moxaTimer);
+		add_timeout(&moxaTimer);
 		return;
 	}
 	for (card = 0; card < MAX_BOARDS; card++) {
@@ -973,9 +973,9 @@
 	}
 
 	moxaTimer.function = moxa_poll;
-	moxaTimer.expires = jiffies + (HZ / 50);
+	moxaTimer.expires = HZ / 50;
 	moxaTimer_on = 1;
-	add_timer(&moxaTimer);
+	add_timeout(&moxaTimer);
 }
 
 /******************************************************************************/
@@ -1101,9 +1101,9 @@
 	ch->statusflags |= EMPTYWAIT;
 	moxaEmptyTimer_on[ch->port] = 0;
 	del_timer(&moxaEmptyTimer[ch->port]);
-	moxaEmptyTimer[ch->port].expires = jiffies + HZ;
+	moxaEmptyTimer[ch->port].expires = HZ;
 	moxaEmptyTimer_on[ch->port] = 1;
-	add_timer(&moxaEmptyTimer[ch->port]);
+	add_timeout(&moxaEmptyTimer[ch->port]);
 	restore_flags(flags);
 }
 
@@ -1123,9 +1123,9 @@
 			wake_up_interruptible(&ch->tty->write_wait);
 			return;
 		}
-		moxaEmptyTimer[ch->port].expires = jiffies + HZ;
+		moxaEmptyTimer[ch->port].expires = HZ;
 		moxaEmptyTimer_on[ch->port] = 1;
-		add_timer(&moxaEmptyTimer[ch->port]);
+		add_timeout(&moxaEmptyTimer[ch->port]);
 	} else
 		ch->statusflags &= ~EMPTYWAIT;
 }
@@ -2668,10 +2668,10 @@
 	ofsAddr = moxaTableAddr[port];
 	if (ms100) {
 		moxafunc(ofsAddr, FC_SendBreak, Magic_code);
-		moxadelay(ms100 * (HZ / 10));
+		msleep(ms100 * 100);
 	} else {
 		moxafunc(ofsAddr, FC_SendBreak, Magic_code);
-		moxadelay(HZ / 4);	/* 250 ms */
+		msleep(250);
 	}
 	moxafunc(ofsAddr, FC_StopBreak, Magic_code);
 }
@@ -2742,17 +2742,6 @@
 /*****************************************************************************
  *	Static local functions: 					     *
  *****************************************************************************/
-/*
- * moxadelay - delays a specified number ticks
- */
-static void moxadelay(int tick)
-{
-	unsigned long st, et;
-
-	st = jiffies;
-	et = st + tick;
-	while (time_before(jiffies, et));
-}
 
 static void moxafunc(unsigned long ofsAddr, int cmd, ushort arg)
 {
@@ -2764,15 +2753,19 @@
 
 static void wait_finish(unsigned long ofsAddr)
 {
-	unsigned long i, j;
+	struct timer_list t;
+	init_timer(&t);
+	t.expires = moxaFuncTout;
+	t.function = timer_noop;
+	add_timeout(&t);	
 
-	i = jiffies;
 	while (readw(ofsAddr + FuncCode) != 0) {
 		j = jiffies;
-		if ((j - i) > moxaFuncTout) {
+		if (!timer_pending(&t)) {
 			return;
 		}
 	}
+	del_timeout(&t);
 }
 
 static void low_water_check(unsigned long ofsAddr)
@@ -2799,7 +2792,7 @@
 		return -EFAULT;
 	baseAddr = moxaBaseAddr[cardno];
 	writeb(HW_reset, baseAddr + Control_reg);	/* reset */
-	moxadelay(1);		/* delay 10 ms */
+	msleep(10);
 	for (i = 0; i < 4096; i++)
 		writeb(0, baseAddr + i);	/* clear fix page */
 	for (i = 0; i < len; i++)
@@ -2970,7 +2963,7 @@
 			for (i = 0; i < 100; i++) {
 				if (readw(baseAddr + C218_key) == keycode)
 					break;
-				moxadelay(1);	/* delay 10 ms */
+				msleep(10);	/* delay 10 ms */
 			}
 			if (readw(baseAddr + C218_key) != keycode) {
 				return (-1);
@@ -2982,7 +2975,7 @@
 		for (i = 0; i < 100; i++) {
 			if (readw(baseAddr + C218_key) == keycode)
 				break;
-			moxadelay(1);	/* delay 10 ms */
+			msleep(10);	/* delay 10 ms */
 		}
 		retry++;
 	} while ((readb(baseAddr + C218chksum_ok) != 1) && (retry < 3));
@@ -2993,7 +2986,7 @@
 	for (i = 0; i < 100; i++) {
 		if (readw(baseAddr + Magic_no) == Magic_code)
 			break;
-		moxadelay(1);	/* delay 10 ms */
+		msleep(10);	/* delay 10 ms */
 	}
 	if (readw(baseAddr + Magic_no) != Magic_code) {
 		return (-1);
@@ -3003,7 +2996,7 @@
 	for (i = 0; i < 100; i++) {
 		if (readw(baseAddr + Magic_no) == Magic_code)
 			break;
-		moxadelay(1);	/* delay 10 ms */
+		msleep(10);	/* delay 10 ms */
 	}
 	if (readw(baseAddr + Magic_no) != Magic_code) {
 		return (-1);
@@ -3045,7 +3038,7 @@
 			for (i = 0; i < 10; i++) {
 				if (readw(baseAddr + C320_key) == C320_KeyCode)
 					break;
-				moxadelay(1);
+				msleep(10);
 			}
 			if (readw(baseAddr + C320_key) != C320_KeyCode)
 				return (-1);
@@ -3056,7 +3049,7 @@
 		for (i = 0; i < 10; i++) {
 			if (readw(baseAddr + C320_key) == C320_KeyCode)
 				break;
-			moxadelay(1);
+			msleep(10);
 		}
 		retry++;
 	} while ((readb(baseAddr + C320chksum_ok) != 1) && (retry < 3));
@@ -3066,7 +3059,7 @@
 	for (i = 0; i < 600; i++) {
 		if (readw(baseAddr + Magic_no) == Magic_code)
 			break;
-		moxadelay(1);
+		msleep(10);
 	}
 	if (readw(baseAddr + Magic_no) != Magic_code)
 		return (-100);
@@ -3085,7 +3078,7 @@
 	for (i = 0; i < 500; i++) {
 		if (readw(baseAddr + Magic_no) == Magic_code)
 			break;
-		moxadelay(1);
+		msleep(10);
 	}
 	if (readw(baseAddr + Magic_no) != Magic_code)
 		return (-102);
@@ -3099,7 +3092,7 @@
 	for (i = 0; i < 600; i++) {
 		if (readw(baseAddr + Magic_no) == Magic_code)
 			break;
-		moxadelay(1);
+		msleep(10);
 	}
 	if (readw(baseAddr + Magic_no) != Magic_code)
 		return (-102);
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.8-rc2/drivers/char/n_r3964.c linux-2.6.8-rc2/drivers/char/n_r3964.c
--- linux.vanilla-2.6.8-rc2/drivers/char/n_r3964.c	2004-07-27 19:22:42.762222208 +0100
+++ linux-2.6.8-rc2/drivers/char/n_r3964.c	2004-07-27 12:39:33.000000000 +0100
@@ -446,7 +446,7 @@
       pInfo->state = R3964_TX_REQUEST;
       pInfo->nRetry=0;
       pInfo->flags &= ~R3964_ERROR;
-      mod_timer(&pInfo->tmr, jiffies + R3964_TO_QVZ);
+      mod_timeout(&pInfo->tmr, R3964_TO_QVZ);
 
       spin_unlock_irqrestore(&pInfo->lock, flags);
 
@@ -474,7 +474,7 @@
       flush(pInfo);
       pInfo->state = R3964_TX_REQUEST;
       pInfo->nRetry++;
-      mod_timer(&pInfo->tmr, jiffies + R3964_TO_QVZ);
+      mod_timeout(&pInfo->tmr, R3964_TO_QVZ);
    }
    else
    {
@@ -533,7 +533,7 @@
          put_char(pInfo, pInfo->bcc);
       }
       pInfo->state = R3964_WAIT_FOR_TX_ACK;
-      mod_timer(&pInfo->tmr, jiffies + R3964_TO_QVZ);
+      mod_timeout(&pInfo->tmr, R3964_TO_QVZ);
    }
    flush(pInfo);
 }
@@ -569,7 +569,7 @@
       {
          pInfo->state=R3964_WAIT_FOR_RX_REPEAT;
          pInfo->nRetry++;
-	 mod_timer(&pInfo->tmr, jiffies + R3964_TO_RX_PANIC);
+	 mod_timeout(&pInfo->tmr, R3964_TO_RX_PANIC);
       }
       else
       {
@@ -668,7 +668,7 @@
             TRACE_PE("TRANSMITTING - got invalid char");
  
             pInfo->state = R3964_WAIT_ZVZ_BEFORE_TX_RETRY;
-	    mod_timer(&pInfo->tmr, jiffies + R3964_TO_ZVZ);
+	    mod_timeout(&pInfo->tmr, R3964_TO_ZVZ);
          }
          break;
       case R3964_WAIT_FOR_TX_ACK:
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.8-rc2/drivers/char/nwbutton.c linux-2.6.8-rc2/drivers/char/nwbutton.c
--- linux.vanilla-2.6.8-rc2/drivers/char/nwbutton.c	2004-07-27 19:21:12.979871200 +0100
+++ linux-2.6.8-rc2/drivers/char/nwbutton.c	2004-07-27 12:38:43.000000000 +0100
@@ -154,8 +154,8 @@
 	button_press_count++;
 	init_timer (&button_timer);
 	button_timer.function = button_sequence_finished;
-	button_timer.expires = (jiffies + bdelay);
-	add_timer (&button_timer);
+	button_timer.expires = bdelay;
+	add_timeout(&button_timer);
 
 	return IRQ_HANDLED;
 }
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.8-rc2/drivers/char/nwflash.c linux-2.6.8-rc2/drivers/char/nwflash.c
--- linux.vanilla-2.6.8-rc2/drivers/char/nwflash.c	2004-07-27 19:21:12.049012712 +0100
+++ linux-2.6.8-rc2/drivers/char/nwflash.c	2004-07-27 13:14:49.000000000 +0100
@@ -354,8 +354,8 @@
 {
 	volatile unsigned int c1;
 	volatile unsigned char *pWritePtr;
-	unsigned long timeout;
 	int temp, temp1;
+	struct timer_list t;
 
 	/*
 	 * orange LED == erase
@@ -404,12 +404,16 @@
 	 */
 	flash_wait(HZ / 100);
 
+	init_timer(&t);
+	t.function = timer_noop;
+	t.expires = 10 * HZ;
+	add_timeout(&t);
+
 	/*
 	 * wait while erasing in process (up to 10 sec)
 	 */
-	timeout = jiffies + 10 * HZ;
 	c1 = 0;
-	while (!(c1 & 0x80) && time_before(jiffies, timeout)) {
+	while (!(c1 & 0x80) && timer_pending(&t)) {
 		flash_wait(HZ / 100);
 		/*
 		 * read any address
@@ -417,7 +421,8 @@
 		c1 = *(volatile unsigned char *) (pWritePtr);
 		//              printk("Flash_erase: status=%X.\n",c1);
 	}
-
+	del_timeout(&t);
+	
 	/*
 	 * set flash for normal read access
 	 */
@@ -469,6 +474,7 @@
 	unsigned int offset;
 	unsigned long timeout;
 	unsigned long timeout1;
+	struct timer_list t, t2;
 
 	/*
 	 * red LED == write
@@ -489,13 +495,22 @@
 	/*
 	 * wait up to 30 sec for this block
 	 */
-	timeout = jiffies + 30 * HZ;
+	 
+	init_timer(&t);
+	t.function = timer_noop;
+	init_timer(&t2);
+	t2.function = timer_noop;
+	t.expires = 30 * HZ;
+	add_timeout(&t);
 
 	for (offset = 0; offset < count; offset++, pWritePtr++) {
 		uAddress = (unsigned int) pWritePtr;
 		uAddress &= 0xFFFFFFFC;
 		if (__get_user(c2, buf + offset))
+		{
+			del_timeout(&t);
 			return -EFAULT;
+		}
 
 	  WriteRetry:
 	  	/*
@@ -533,26 +548,30 @@
 		/*
 		 * wait up to 1 sec for this byte
 		 */
-		timeout1 = jiffies + 1 * HZ;
+		t2.expires = 1 * HZ;
+		add_timeout(&t2);
 
 		/*
 		 * while not ready...
 		 */
-		while (!(c1 & 0x80) && time_before(jiffies, timeout1))
+		while (!(c1 & 0x80) && timer_pending(&t2))
 			c1 = *(volatile unsigned char *) (FLASH_BASE + 0x8000);
 
 		/*
 		 * if timeout getting status
 		 */
-		if (time_after_eq(jiffies, timeout1)) {
+		if (!timer_pending(&t2)) {
 			kick_open();
 			/*
 			 * reset err
 			 */
 			*(volatile unsigned char *) (FLASH_BASE + 0x8000) = 0x50;
 
+			/* t2 is already expired.. */
 			goto WriteRetry;
 		}
+		del_timeout(&t2);
+		
 		/*
 		 * switch on read access, as a default flash operation mode
 		 */
@@ -576,7 +595,7 @@
 			/*
 			 * before timeout?
 			 */
-			if (time_before(jiffies, timeout)) {
+			if (timer_pending(&t)) {
 				if (flashdebug)
 					printk(KERN_DEBUG "write_block: Retrying write at 0x%X)n",
 					       pWritePtr - FLASH_BASE);
@@ -601,12 +620,15 @@
 				/*
 				 * return error -2
 				 */
+				del_timeout(&t);
 				return -2;
 
 			}
 		}
 	}
 
+	del_timeout(&t);
+	
 	/*
 	 * green LED == read/verify
 	 */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.8-rc2/drivers/char/pcxx.c linux-2.6.8-rc2/drivers/char/pcxx.c
--- linux.vanilla-2.6.8-rc2/drivers/char/pcxx.c	2004-07-27 19:21:12.736908136 +0100
+++ linux-2.6.8-rc2/drivers/char/pcxx.c	2004-07-27 13:29:21.000000000 +0100
@@ -1548,7 +1548,7 @@
 	/*
 	 * Start up the poller to check for events on all enabled boards
 	 */
-	mod_timer(&pcxx_timer, HZ/25);
+	mod_timeout(&pcxx_timer, HZ/25);
 
 	if (verbose)
 		printk(KERN_NOTICE "PC/Xx: Driver with %d card(s) ready.\n", enabled_cards);
@@ -1593,7 +1593,7 @@
 		memoff(ch);
 	}
 
-	mod_timer(&pcxx_timer, jiffies + HZ/25);
+	mod_timeout(&pcxx_timer, HZ/25);
 	restore_flags(flags);
 }
 
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.8-rc2/drivers/char/rocket.c linux-2.6.8-rc2/drivers/char/rocket.c
--- linux.vanilla-2.6.8-rc2/drivers/char/rocket.c	2004-07-27 19:22:42.768221296 +0100
+++ linux-2.6.8-rc2/drivers/char/rocket.c	2004-07-27 13:28:04.000000000 +0100
@@ -553,7 +553,7 @@
 	 * Reset the timer so we get called at the next clock tick (10ms).
 	 */
 	if (atomic_read(&rp_num_ports_open))
-		mod_timer(&rocket_timer, jiffies + POLL_PERIOD);
+		mod_timeout(&rocket_timer, POLL_PERIOD);
 }
 
 /*
@@ -1001,7 +1001,7 @@
 		}
 	}
 	/*  Starts (or resets) the maint polling loop */
-	mod_timer(&rocket_timer, jiffies + POLL_PERIOD);
+	mod_timeout(&rocket_timer, POLL_PERIOD);
 
 	retval = block_til_ready(tty, filp, info);
 	if (retval) {
@@ -1502,19 +1502,22 @@
 {
 	struct r_port *info = (struct r_port *) tty->driver_data;
 	CHANNEL_t *cp;
-	unsigned long orig_jiffies;
 	int check_time, exit_time;
 	int txcnt;
+	struct timer_list t;
 
 	if (rocket_paranoia_check(info, "rp_wait_until_sent"))
 		return;
 
 	cp = &info->channel;
 
-	orig_jiffies = jiffies;
+	init_timer(&t);
+	t.function = timer_noop;
+	t.expires = timeout;
+	add_timeout(&t);
+
 #ifdef ROCKET_DEBUG_WAIT_UNTIL_SENT
-	printk(KERN_INFO "In RP_wait_until_sent(%d) (jiff=%lu)...", timeout,
-	       jiffies);
+	printk(KERN_INFO "In RP_wait_until_sent(%d)...", timeout);
 	printk(KERN_INFO "cps=%d...", info->cps);
 #endif
 	while (1) {
@@ -1527,11 +1530,14 @@
 			check_time = HZ * txcnt / info->cps;
 		}
 		if (timeout) {
-			exit_time = orig_jiffies + timeout - jiffies;
-			if (exit_time <= 0)
+			if (!timer_pending(&t))
 				break;
+/* FIXME: Does this check actually matter anyway ? Do we need an
+   upstream "time_remaining(&t)) */
+#if 0
 			if (exit_time < check_time)
 				check_time = exit_time;
+#endif				
 		}
 		if (check_time == 0)
 			check_time = 1;
@@ -1543,9 +1549,10 @@
 		if (signal_pending(current))
 			break;
 	}
+	del_timeout(&t);
 	current->state = TASK_RUNNING;
 #ifdef ROCKET_DEBUG_WAIT_UNTIL_SENT
-	printk(KERN_INFO "txcnt = %d (jiff=%lu)...done\n", txcnt, jiffies);
+	printk(KERN_INFO "txcnt = %d ...done\n", txcnt);
 #endif
 }
 
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.8-rc2/drivers/char/rtc.c linux-2.6.8-rc2/drivers/char/rtc.c
--- linux.vanilla-2.6.8-rc2/drivers/char/rtc.c	2004-07-27 19:22:42.769221144 +0100
+++ linux-2.6.8-rc2/drivers/char/rtc.c	2004-07-27 12:37:54.000000000 +0100
@@ -239,7 +239,7 @@
 	}
 
 	if (rtc_status & RTC_TIMER_ON)
-		mod_timer(&rtc_irq_timer, jiffies + HZ/rtc_freq + 2*HZ/100);
+		mod_timeout(&rtc_irq_timer, HZ/rtc_freq + 2*HZ/100);
 
 	spin_unlock (&rtc_lock);
 
@@ -422,8 +422,8 @@
 
 		if (!(rtc_status & RTC_TIMER_ON)) {
 			spin_lock_irq (&rtc_lock);
-			rtc_irq_timer.expires = jiffies + HZ/rtc_freq + 2*HZ/100;
-			add_timer(&rtc_irq_timer);
+			rtc_irq_timer.expires = HZ/rtc_freq + 2*HZ/100;
+			add_timeout(&rtc_irq_timer);
 			rtc_status |= RTC_TIMER_ON;
 			spin_unlock_irq (&rtc_lock);
 		}
@@ -1096,7 +1096,7 @@
 
 	/* Just in case someone disabled the timer from behind our back... */
 	if (rtc_status & RTC_TIMER_ON)
-		mod_timer(&rtc_irq_timer, jiffies + HZ/rtc_freq + 2*HZ/100);
+		mod_timeout(&rtc_irq_timer,HZ/rtc_freq + 2*HZ/100);
 
 	rtc_irq_data += ((rtc_freq/HZ)<<8);
 	rtc_irq_data &= ~0xff;
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.8-rc2/drivers/char/scan_keyb.c linux-2.6.8-rc2/drivers/char/scan_keyb.c
--- linux.vanilla-2.6.8-rc2/drivers/char/scan_keyb.c	2004-07-27 19:21:12.734908440 +0100
+++ linux-2.6.8-rc2/drivers/char/scan_keyb.c	2004-07-27 12:33:23.000000000 +0100
@@ -30,8 +30,8 @@
 	int length;
 };
 
-static int scan_jiffies=0;
-static struct scan_keyboard *keyboards=NULL;
+static int scan_jiffies = 0;
+static struct scan_keyboard *keyboards = NULL;
 struct timer_list scan_timer;
 
 static void check_kbd(const unsigned char *table,
@@ -89,10 +89,10 @@
 	}
 
 	init_timer(&scan_timer);
-	scan_timer.expires = jiffies + SCANHZ;
+	scan_timer.expires = SCANHZ;
 	scan_timer.data = 0;
 	scan_timer.function = scan_kbd;
-	add_timer(&scan_timer);
+	add_timeout(&scan_timer);
 }
 
 
@@ -140,10 +140,10 @@
 void __init scan_kbd_init(void)
 {
 	init_timer(&scan_timer);
-	scan_timer.expires = jiffies + SCANHZ;
+	scan_timer.expires = SCANHZ;
 	scan_timer.data = 0;
 	scan_timer.function = scan_kbd;
-	add_timer(&scan_timer);
+	add_timeout(&scan_timer);
 
 	printk(KERN_INFO "Generic scan keyboard driver initialized\n");
 }
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.8-rc2/drivers/char/specialix.c linux-2.6.8-rc2/drivers/char/specialix.c
--- linux.vanilla-2.6.8-rc2/drivers/char/specialix.c	2004-07-27 19:21:12.146997816 +0100
+++ linux-2.6.8-rc2/drivers/char/specialix.c	2004-07-27 13:23:20.000000000 +0100
@@ -306,18 +306,6 @@
 }
 
 	
-/* Must be called with enabled interrupts */
-/* Ugly. Very ugly. Don't use this for anything else than initialization 
-   code */
-static inline void sx_long_delay(unsigned long delay)
-{
-	unsigned long i;
-	
-	for (i = jiffies + delay; time_after(i, jiffies); ) ;
-}
-
-
-
 /* Set the IRQ using the RTS lines that run to the PAL on the board.... */
 int sx_set_irq ( struct specialix_board *bp)
 {
@@ -356,7 +344,7 @@
 	sx_wait_CCR_off(bp);			   /* Wait for CCR ready        */
 	sx_out_off(bp, CD186x_CCR, CCR_HARDRESET);      /* Reset CD186x chip          */
 	sti();
-	sx_long_delay(HZ/20);                      /* Delay 0.05 sec            */
+	msleep(HZ/20); 		                     /* Delay 0.05 sec            */
 	cli();
 	sx_out_off(bp, CD186x_GIVR, SX_ID);             /* Set ID for this chip      */
 	sx_out_off(bp, CD186x_GICR, 0);                 /* Clear all bits            */
@@ -408,8 +396,8 @@
 		sx_interrupt (((struct specialix_board *)data)->irq, 
 		              NULL, NULL);
 	}
-	missed_irq_timer.expires = jiffies + HZ;
-	add_timer (&missed_irq_timer);
+	missed_irq_timer.expires = HZ;
+	add_timeout(&missed_irq_timer);
 }
 #endif
 
@@ -474,7 +462,7 @@
 		sx_wait_CCR(bp);
 		sx_out(bp, CD186x_CCR, CCR_TXEN);        /* Enable transmitter     */
 		sx_out(bp, CD186x_IER, IER_TXRDY);       /* Enable tx empty intr   */
-		sx_long_delay(HZ/20);	       		
+		msleep(HZ/20);	       		
 		irqs = probe_irq_off(irqs);
 
 #if SPECIALIX_DEBUG > 2
@@ -540,8 +528,8 @@
 	init_timer (&missed_irq_timer);
 	missed_irq_timer.function = missed_irq;
 	missed_irq_timer.data = (unsigned long) bp;
-	missed_irq_timer.expires = jiffies + HZ;
-	add_timer (&missed_irq_timer);
+	missed_irq_timer.expires = HZ;
+	add_timeout(&missed_irq_timer);
 #endif
 
 	printk(KERN_INFO"sx%d: specialix IO8+ board detected at 0x%03x, IRQ %d, CD%d Rev. %c.\n",
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.8-rc2/drivers/char/stallion.c linux-2.6.8-rc2/drivers/char/stallion.c
--- linux.vanilla-2.6.8-rc2/drivers/char/stallion.c	2004-07-27 19:22:42.774220384 +0100
+++ linux-2.6.8-rc2/drivers/char/stallion.c	2004-07-27 12:36:48.000000000 +0100
@@ -1848,7 +1848,9 @@
 static void stl_waituntilsent(struct tty_struct *tty, int timeout)
 {
 	stlport_t	*portp;
-	unsigned long	tend;
+	struct timer     t;
+	
+	timer_init(&t);
 
 #if DEBUG
 	printk("stl_waituntilsent(tty=%x,timeout=%d)\n", (int) tty, timeout);
@@ -1862,15 +1864,19 @@
 
 	if (timeout == 0)
 		timeout = HZ;
-	tend = jiffies + timeout;
+
+	t.expires = timeout;
+	t.function = timer_noop;
+	add_timeout(&t);
 
 	while (stl_datastate(portp)) {
 		if (signal_pending(current))
 			break;
 		stl_delay(2);
-		if (time_after_eq(jiffies, tend))
+		if (!timeout_pending(&t))
 			break;
 	}
+	del_timeout(&t);
 }
 
 /*****************************************************************************/
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.8-rc2/drivers/char/sx.c linux-2.6.8-rc2/drivers/char/sx.c
--- linux.vanilla-2.6.8-rc2/drivers/char/sx.c	2004-07-27 19:21:12.799898560 +0100
+++ linux-2.6.8-rc2/drivers/char/sx.c	2004-07-27 12:34:32.000000000 +0100
@@ -1295,8 +1295,8 @@
 
 	init_timer(&board->timer);
 
-	board->timer.expires = jiffies + sx_poll;
-	add_timer (&board->timer);
+	board->timer.expires = sx_poll;
+	add_timeout (&board->timer);
 	func_exit ();
 }
 
@@ -1514,7 +1514,7 @@
 			sx_dprintk (SX_DEBUG_CLOSE, "sent the force_close command.\n");
 	}
 
-	sx_dprintk (SX_DEBUG_CLOSE, "waited %d jiffies for close. count=%d\n", 
+	sx_dprintk (SX_DEBUG_CLOSE, "waited %d jiffies for close. count=%d\n",
 	            5 * HZ - to - 1, port->gs.count);
 
 	if(port->gs.count) {
@@ -2013,8 +2013,8 @@
 		if (board->poll) {
 			board->timer.data = (unsigned long) board;
 			board->timer.function = sx_pollfunc;
-			board->timer.expires = jiffies + board->poll;
-			add_timer (&board->timer);
+			board->timer.expires = board->poll;
+			add_timeout(&board->timer);
 		}
 	} else {
 		board->irq = 0;
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.8-rc2/drivers/char/synclink.c linux-2.6.8-rc2/drivers/char/synclink.c
--- linux.vanilla-2.6.8-rc2/drivers/char/synclink.c	2004-07-27 19:21:12.192990824 +0100
+++ linux-2.6.8-rc2/drivers/char/synclink.c	2004-07-27 13:21:17.000000000 +0100
@@ -3296,6 +3296,7 @@
 {
 	struct mgsl_struct * info = (struct mgsl_struct *)tty->driver_data;
 	unsigned long orig_jiffies, char_time;
+	struct timer_list t;
 
 	if (!info )
 		return;
@@ -3324,9 +3325,16 @@
 			char_time++;
 	} else
 		char_time = 1;
+	
+	init_timer(&t);
+	t.expires = timeout;
+	t.function = timer_noop;
 		
 	if (timeout)
+	{
 		char_time = MIN(char_time, timeout);
+		add_timeout(&t);
+	}
 		
 	if ( info->params.mode == MGSL_MODE_HDLC ||
 		info->params.mode == MGSL_MODE_RAW ) {
@@ -3335,7 +3343,7 @@
 			schedule_timeout(char_time);
 			if (signal_pending(current))
 				break;
-			if (timeout && time_after(jiffies, orig_jiffies + timeout))
+			if (timeout && !timer_pending(&t))
 				break;
 		}
 	} else {
@@ -3345,10 +3353,11 @@
 			schedule_timeout(char_time);
 			if (signal_pending(current))
 				break;
-			if (timeout && time_after(jiffies, orig_jiffies + timeout))
+			if (timeout && !timer_pending(&t))
 				break;
 		}
 	}
+	del_timeout(&t);
       
 exit:
 	if (debug_level >= DEBUG_LEVEL_INFO)
@@ -4187,7 +4196,7 @@
 				info->get_tx_holding_index=0;
 
 			/* restart transmit timer */
-			mod_timer(&info->tx_timer, jiffies + jiffies_from_ms(5000));
+			mod_timeout(&info->tx_timer, jiffies_from_ms(5000));
 
 			ret = 1;
 		}
@@ -5819,8 +5828,8 @@
 			
 			usc_TCmd( info, TCmd_SendFrame );
 			
-			info->tx_timer.expires = jiffies + jiffies_from_ms(5000);
-			add_timer(&info->tx_timer);	
+			info->tx_timer.expires = jiffies_from_ms(5000);
+			add_timeout(&info->tx_timer);	
 		}
 		info->tx_active = 1;
 	}
@@ -7246,9 +7255,9 @@
 	char *TmpPtr;
 	BOOLEAN rc = TRUE;
 	unsigned short status=0;
-	unsigned long EndTime;
 	unsigned long flags;
 	MGSL_PARAMS tmp_params;
+	struct timer_list t;
 
 	/* save current port options */
 	memcpy(&tmp_params,&info->params,sizeof(MGSL_PARAMS));
@@ -7353,10 +7362,13 @@
 	/*************************************************************/
 
 	/* Wait 100ms for interrupt. */
-	EndTime = jiffies + jiffies_from_ms(100);
+	init_timer(&t);
+	t.expires = jiffies_from_ms(100);
+	t.function = timer_noop;
+	add_timeout(&t);
 
 	for(;;) {
-		if (time_after(jiffies, EndTime)) {
+		if (!timer_pending(&t)) {
 			rc = FALSE;
 			break;
 		}
@@ -7369,6 +7381,7 @@
 			/* INITG (BIT 4) is inactive (no entry read in progress) AND */
 			/* BUSY  (BIT 5) is active (channel still active). */
 			/* This means the buffer entry read has completed. */
+			del_timer(&t);
 			break;
 		}
 	}
@@ -7409,10 +7422,11 @@
 	/**********************************/
 	
 	/* Wait 100ms */
-	EndTime = jiffies + jiffies_from_ms(100);
+	t.expires = jiffies_from_ms(100);
+	add_timeout(&t);
 
 	for(;;) {
-		if (time_after(jiffies, EndTime)) {
+		if (!timer_pending(&t)) {
 			rc = FALSE;
 			break;
 		}
@@ -7431,6 +7445,7 @@
 					break;
 			}
 	}
+	del_timeout(&t);
 
 
 	if ( rc == TRUE )
@@ -7451,7 +7466,8 @@
 		/******************************/
 
 		/* Wait 100ms */
-		EndTime = jiffies + jiffies_from_ms(100);
+		t.expires = jiffies_from_ms(100);
+		add_timeout(&t);
 
 		/* While timer not expired wait for transmit complete */
 
@@ -7460,7 +7476,7 @@
 		spin_unlock_irqrestore(&info->irq_spinlock,flags);
 
 		while ( !(status & (BIT6+BIT5+BIT4+BIT2+BIT1)) ) {
-			if (time_after(jiffies, EndTime)) {
+			if (!timer_pending(&t)) {
 				rc = FALSE;
 				break;
 			}
@@ -7470,6 +7486,7 @@
 			spin_unlock_irqrestore(&info->irq_spinlock,flags);
 		}
 	}
+	del_timeout(&t);
 
 
 	if ( rc == TRUE ){
@@ -7482,17 +7499,19 @@
 		/* WAIT FOR RECEIVE COMPLETE */
 
 		/* Wait 100ms */
-		EndTime = jiffies + jiffies_from_ms(100);
+		t.expires = jiffies_from_ms(100);
+		add_timeout(&t);
 
 		/* Wait for 16C32 to write receive status to buffer entry. */
 		status=info->rx_buffer_list[0].status;
 		while ( status == 0 ) {
-			if (time_after(jiffies, EndTime)) {
+			if (!timer_pending(&t)) {
 				rc = FALSE;
 				break;
 			}
 			status=info->rx_buffer_list[0].status;
 		}
+		del_timeout(&t);
 	}
 
 
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.8-rc2/drivers/char/synclinkmp.c linux-2.6.8-rc2/drivers/char/synclinkmp.c
--- linux.vanilla-2.6.8-rc2/drivers/char/synclinkmp.c	2004-07-27 19:22:42.777219928 +0100
+++ linux-2.6.8-rc2/drivers/char/synclinkmp.c	2004-07-27 13:15:19.000000000 +0100
@@ -1127,7 +1127,8 @@
 {
 	SLMP_INFO * info = (SLMP_INFO *)tty->driver_data;
 	unsigned long orig_jiffies, char_time;
-
+	struct timer_list t;
+	
 	if (!info )
 		return;
 
@@ -1141,7 +1142,9 @@
 	if (!(info->flags & ASYNC_INITIALIZED))
 		goto exit;
 
-	orig_jiffies = jiffies;
+	init_timer(&t);
+	t.function = timer_noop;
+	t.expires = timeout;
 
 	/* Set check interval to 1/5 of estimated time to
 	 * send a character, and make it at least 1. The check
@@ -1157,15 +1160,18 @@
 		char_time = 1;
 
 	if (timeout)
+	{
 		char_time = MIN(char_time, timeout);
-
+		add_timeout(t);
+	}
+	
 	if ( info->params.mode == MGSL_MODE_HDLC ) {
 		while (info->tx_active) {
 			set_current_state(TASK_INTERRUPTIBLE);
 			schedule_timeout(char_time);
 			if (signal_pending(current))
 				break;
-			if (timeout && time_after(jiffies, orig_jiffies + timeout))
+			if (timeout && !timer_pending(&t)))
 				break;
 		}
 	} else {
@@ -1176,10 +1182,11 @@
 			schedule_timeout(char_time);
 			if (signal_pending(current))
 				break;
-			if (timeout && time_after(jiffies, orig_jiffies + timeout))
+			if (timeout && !timer_pending(&t)))
 				break;
 		}
 	}
+	del_timeout(t);
 
 exit:
 	if (debug_level >= DEBUG_LEVEL_INFO)
@@ -2573,8 +2580,8 @@
 
 	change_params(info);
 
-	info->status_timer.expires = jiffies + jiffies_from_ms(10);
-	add_timer(&info->status_timer);
+	info->status_timer.expires = jiffies_from_ms(10);
+	add_timeout(&info->status_timer);
 
 	if (info->tty)
 		clear_bit(TTY_IO_ERROR, &info->tty->flags);
@@ -4129,8 +4136,8 @@
 			write_reg(info, TXDMA + DIR, 0x40);		/* enable Tx DMA interrupts (EOM) */
 			write_reg(info, TXDMA + DSR, 0xf2);		/* clear Tx DMA IRQs, enable Tx DMA */
 	
-			info->tx_timer.expires = jiffies + jiffies_from_ms(5000);
-			add_timer(&info->tx_timer);
+			info->tx_timer.expires = jiffies_from_ms(5000);
+			add_timeout(&info->tx_timer);
 		}
 		else {
 			tx_load_fifo(info);
@@ -5424,8 +5431,8 @@
 
 	info->status_timer.data = (unsigned long)info;
 	info->status_timer.function = status_timeout;
-	info->status_timer.expires = jiffies + jiffies_from_ms(10);
-	add_timer(&info->status_timer);
+	info->status_timer.expires = jiffies_from_ms(10);
+	add_timeout(&info->status_timer);
 }
 
 
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.8-rc2/drivers/char/tpqic02.c linux-2.6.8-rc2/drivers/char/tpqic02.c
--- linux.vanilla-2.6.8-rc2/drivers/char/tpqic02.c	2004-07-27 19:21:12.650921208 +0100
+++ linux-2.6.8-rc2/drivers/char/tpqic02.c	2004-07-27 13:15:05.000000000 +0100
@@ -511,9 +511,10 @@
 /* Wait for a command to complete, with timeout */
 static int wait_for_ready(time_t timeout)
 {
+	struct timer_list t;
 	int stat;
 	unsigned long spin_t;
-
+	
 	/* Wait for ready or exception, without driving the loadavg up too much.
 	 * In most cases, the tape drive already has READY asserted,
 	 * so optimize for that case.
@@ -527,18 +528,23 @@
 		return TE_OK;	/* covers 99.99% of all calls */
 
 	/* Then use schedule() a few times */
-	spin_t = 3;		/* max 0.03 sec busy waiting */
-	if (spin_t > timeout)
-		spin_t = timeout;
-	timeout -= spin_t;
-	spin_t += jiffies;
+	
+	timer_init(&t);
+	t.function = timer_noop;
+	
+	t.expires = (3 * HZ) / 100;		/* max 0.03 sec busy waiting */
+	if (t.expires > timeout)
+		t.expires = timeout;
+	timeout -= t.expires;
+	
+	add_timeout(&t);
 
-	/* FIXME...*/
-	while (((stat = inb_p(QIC02_STAT_PORT) & QIC02_STAT_MASK) == QIC02_STAT_MASK)  && time_before(jiffies, spin_t))
+	while (((stat = inb_p(QIC02_STAT_PORT) & QIC02_STAT_MASK) == QIC02_STAT_MASK)  && timeout_pending(&t))
 	{
 		set_current_state(TASK_UNINTERRUPTIBLE);
 		schedule_timeout(1);	/* don't waste all the CPU time */
 	}
+	del_timeout(&t);
 	if ((stat & QIC02_STAT_READY) == 0)
 		return TE_OK;
 
@@ -548,17 +554,21 @@
 	 * A interval of less than 0.10 sec will not be noticed by the user,
 	 * more than 0.40 sec may give noticeable delays.
 	 */
-	spin_t += timeout;
+
+	t.expires = timeout;
+	add_timeout(&t);
+	
 	TPQDEB({printk("wait_for_ready: additional timeout: %d\n", spin_t);})
 
 	    /* not ready and no exception && timeout not expired yet */
-	while (((stat = inb_p(QIC02_STAT_PORT) & QIC02_STAT_MASK) == QIC02_STAT_MASK) && time_before(jiffies, spin_t)) {
+	while (((stat = inb_p(QIC02_STAT_PORT) & QIC02_STAT_MASK) == QIC02_STAT_MASK) && timer_pending(&t)) {
 		/* be `nice` to other processes on long operations... */
 		current->state = TASK_INTERRUPTIBLE;
 		/* nap 0.30 sec between checks, */
 		/* but could be woken up earlier by signals... */
 		schedule_timeout(3 * HZ / 10);
 	}
+	del_timeout(&t);
 
 	/* don't use jiffies for this test because it may have changed by now */
 	if ((stat & QIC02_STAT_MASK) == QIC02_STAT_MASK) {
@@ -1254,16 +1264,12 @@
 			tpqputs(TPQD_ALWAYS, "Cartridge is write-protected.");
 			return -EACCES;
 		} else {
-			time_t t = jiffies;
-
 			/* Plain GNU mt(1) 2.2 erases a tape in O_RDONLY. :-( */
 			if (mode_access == READ)
 				return -EACCES;
 
-			/* FIXME */
 			/* give user a few seconds to pull out tape */
-			while (jiffies - t < 4 * HZ)
-				schedule();
+			msleep(4000);
 		}
 
 		/* don't bother writing filemark first */
@@ -1685,7 +1691,7 @@
 			wake_up(&qic02_tape_transfer);
 		} else {
 			/* start next transfer, account for track-switching time */
-			mod_timer(&tp_timer, jiffies + 6 * HZ);
+			mod_timeout(&tp_timer, 6 * HZ);
 			dma_transfer();
 		}
 	} else {
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.8-rc2/drivers/char/vt.c linux-2.6.8-rc2/drivers/char/vt.c
--- linux.vanilla-2.6.8-rc2/drivers/char/vt.c	2004-07-27 19:22:42.782219168 +0100
+++ linux-2.6.8-rc2/drivers/char/vt.c	2004-07-27 12:22:49.000000000 +0100
@@ -2562,7 +2562,7 @@
 	console_timer.function = blank_screen_t;
 	if (blankinterval) {
 		blank_state = blank_normal_wait;
-		mod_timer(&console_timer, jiffies + blankinterval);
+		mod_timeout(&console_timer, blankinterval);
 	}
 
 	/*
@@ -2842,7 +2842,7 @@
 
 	if (vesa_off_interval) {
 		blank_state = blank_vesa_wait,
-		mod_timer(&console_timer, jiffies + vesa_off_interval);
+		mod_timeout(&console_timer, vesa_off_interval);
 	}
 
     	if (vesa_blank_mode)
@@ -2872,7 +2872,7 @@
 		return; /* but leave console_blanked != 0 */
 
 	if (blankinterval) {
-		mod_timer(&console_timer, jiffies + blankinterval);
+		mod_timeout(&console_timer, blankinterval);
 		blank_state = blank_normal_wait;
 	}
 
@@ -2923,7 +2923,7 @@
 	if (console_blanked)
 		unblank_screen();
 	else if (blankinterval) {
-		mod_timer(&console_timer, jiffies + blankinterval);
+		mod_timeout(&console_timer, blankinterval);
 		blank_state = blank_normal_wait;
 	}
 }
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.8-rc2/include/linux/timer.h linux-2.6.8-rc2/include/linux/timer.h
--- linux.vanilla-2.6.8-rc2/include/linux/timer.h	2004-07-27 19:20:56.000000000 +0100
+++ linux-2.6.8-rc2/include/linux/timer.h	2004-07-27 18:50:27.000000000 +0100
@@ -5,6 +5,7 @@
 #include <linux/list.h>
 #include <linux/spinlock.h>
 #include <linux/stddef.h>
+#include <linux/jiffies.h>
 
 struct tvec_t_base_s;
 
@@ -65,7 +66,8 @@
 extern int del_timer(struct timer_list * timer);
 extern int __mod_timer(struct timer_list *timer, unsigned long expires);
 extern int mod_timer(struct timer_list *timer, unsigned long expires);
-
+extern int mod_timeout(struct timer_list *timer, unsigned long expires);
+extern void timer_noop(unsigned long unused);
 extern unsigned long next_timer_interrupt(void);
 
 /***
@@ -87,6 +89,30 @@
 	__mod_timer(timer, timer->expires);
 }
 
+/***
+ * add_timeout - start a timeout
+ * @timer: the timer to be added
+ *
+ * The kernel will do a ->function(->data) callback from the
+ * timer interrupt at the ->expired point in the future. The
+ * current time is added to the offset before the timer is
+ * inserted.
+ *
+ * The timer's ->expired, ->function (and if the handler uses it, ->data)
+ * fields must be set prior calling this function. If the timeout ->function
+ * is NULL the timeout will expire and no action will be taken.
+ */
+ 
+static inline void add_timeout(struct timer_list * timer)
+{
+	if(timer->function == NULL)
+		timer->function = timer_noop;
+	/* This will shift when we go tickless, for now the goal
+	   is to get jiffies in one place only */
+	timer->expires += jiffies;
+	__mod_timer(timer, timer->expires);
+}
+
 #ifdef CONFIG_SMP
   extern int del_timer_sync(struct timer_list *timer);
   extern int del_singleshot_timer_sync(struct timer_list *timer);
@@ -95,6 +121,10 @@
 # define del_singleshot_timer_sync(t) del_timer(t)
 #endif
 
+/* For API neatness only */
+#define del_timeout(t)	del_timer(t)
+#define timeout_pending(t) timer_pending(t)
+
 extern void init_timers(void);
 extern void run_local_timers(void);
 extern void it_real_fn(unsigned long);
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.8-rc2/kernel/timer.c linux-2.6.8-rc2/kernel/timer.c
--- linux.vanilla-2.6.8-rc2/kernel/timer.c	2004-07-27 19:22:53.046658736 +0100
+++ linux-2.6.8-rc2/kernel/timer.c	2004-07-27 18:51:13.000000000 +0100
@@ -211,7 +211,7 @@
 
 EXPORT_SYMBOL(__mod_timer);
 
-/***
+/**
  * add_timer_on - start a timer on a particular CPU
  * @timer: the timer to be added
  * @cpu: the CPU to start it on
@@ -233,9 +233,10 @@
 	spin_unlock_irqrestore(&base->lock, flags);
 }
 
-/***
+/**
  * mod_timer - modify a timer's timeout
  * @timer: the timer to be modified
+ * @expires: time of expiry
  *
  * mod_timer is a more efficient way to update the expire field of an
  * active timer (if the timer is inactive it will be activated)
@@ -269,7 +270,46 @@
 	return __mod_timer(timer, expires);
 }
 
-EXPORT_SYMBOL(mod_timer);
+/**
+ * mod_timeout - modify a timer's timeout
+ * @timer: the timer to be modified
+ * @expires: time of expiry relative to now
+ *
+ * mod_timer is a more efficient way to update the expire field of an
+ * active timer (if the timer is inactive it will be activated)
+ *
+ * mod_timer(timer, expires) is equivalent to:
+ *
+ *     del_timer(timer); timer->expires = expires; add_timer(timer);
+ *
+ * Note that if there are multiple unserialized concurrent users of the
+ * same timer, then mod_timer() is the only safe way to modify the timeout,
+ * since add_timer() cannot modify an already running timer.
+ *
+ * The function returns whether it has modified a pending timer or not.
+ * (ie. mod_timer() of an inactive timer returns 0, mod_timer() of an
+ * active timer returns 1.)
+ */
+
+int mod_timeout(struct timer_list *timer, unsigned long expires)
+{
+	BUG_ON(!timer->function);
+
+	check_timer(timer);
+	expires += jiffies;
+
+	/*
+	 * This is a common optimization triggered by the
+	 * networking code - if the timer is re-modified
+	 * to be the same thing then just return:
+	 */
+	if (timer->expires == expires && timer_pending(timer))
+		return 1;
+
+	return __mod_timer(timer, expires);
+}
+
+EXPORT_SYMBOL(mod_timeout);
 
 /***
  * del_timer - deactive a timer.
@@ -411,7 +451,21 @@
 	return index;
 }
 
-/***
+/**
+ * timer_noop 	-	null timer function
+ * @unused: passed by callback
+ *
+ * This function provides a "no-op" for timers whose expiry is tested
+ * elsewhere but take no action when expiring
+ */
+ 
+void timer_noop(unsigned long unused)
+{
+}
+
+EXPORT_SYMBOL(timer_noop);
+
+/**
  * __run_timers - run all expired timers (if any) on this CPU.
  * @base: the timer vector to be processed.
  *

^ permalink raw reply	[flat|nested] 6+ messages in thread
[parent not found: <2mGr0-7w6-27@gated-at.bofh.it>]
* Re: Initial bits to help pull jiffies out of drivers
@ 2004-08-05 13:57 Martin Schwidefsky
  0 siblings, 0 replies; 6+ messages in thread
From: Martin Schwidefsky @ 2004-08-05 13:57 UTC (permalink / raw)
  To: Arjan van de Ven; +Cc: Alan Cox, linux-kernel

Hi Alan,

> > This is really for comment, the basic idea is to add some relative
> > timer functionality. This gives us timeout objects as well as pulling
> > jiffies use into one place in the timer code. The need for the old
> > interfaces never goes away however because some code uses a previous
> > event base to construct timeouts to avoid sliding due to the latency
> > between service and re-addition.
> 
> My gripe with this is that the interface still is relative-to-HZ time.
> I'm convinced that driver(writers) are better off with an absolute time
> interface, eg add_timeout_ms(), add_timeout_us() etc.
> (which btw also give a hint about the accuracy required, so that the
> kernel can group milisecond delays together even when they got scheduled
> at different usecs, once we get timers that accurate)

This bothered me as well. I think we should try really hard to
get away from jiffies & HZ in the device drivers and hide the
conversion to jiffies in the add_timeout/mod_timeout functions
for now (until one day we can rip out jiffies alltogether).
Arnd Bergmann created a patch for the s390 device driver to
use the timeout interface. Patch is attach for whoever is
interested.

blue skies,
  Martin.

diff -urN linux-2.6.8-rc3/drivers/s390/block/dasd.c linux-2.6.8-rc3-s390/drivers/s390/block/dasd.c
--- linux-2.6.8-rc3/drivers/s390/block/dasd.c	Thu Aug  5 15:34:26 2004
+++ linux-2.6.8-rc3-s390/drivers/s390/block/dasd.c	Thu Aug  5 15:36:57 2004
@@ -747,7 +747,6 @@
 		return -EIO;
 	}
 	cqr->startclk = get_clock();
-	cqr->starttime = jiffies;
 	cqr->retries--;
 	rc = ccw_device_start(device->cdev, cqr->cpaddr, (long) cqr,
 			      cqr->lpm, 0);
@@ -808,17 +807,17 @@
 {
 	if (expires == 0) {
 		if (timer_pending(&device->timer))
-			del_timer(&device->timer);
+			del_timeout(&device->timer);
 		return;
 	}
 	if (timer_pending(&device->timer)) {
-		if (mod_timer(&device->timer, jiffies + expires))
+		if (mod_timeout(&device->timer, expires))
 			return;
 	}
 	device->timer.function = dasd_timeout_device;
 	device->timer.data = (unsigned long) device;
-	device->timer.expires = jiffies + expires;
-	add_timer(&device->timer);
+	device->timer.expires = expires;
+	add_timeout(&device->timer);
 }
 
 /*
@@ -828,7 +827,7 @@
 dasd_clear_timer(struct dasd_device *device)
 {
 	if (timer_pending(&device->timer))
-		del_timer(&device->timer);
+		del_timeout(&device->timer);
 }
 
 static void
@@ -1198,10 +1197,11 @@
 		return;
 	cqr = list_entry(device->ccw_queue.next, struct dasd_ccw_req, list);
 	if (cqr->status == DASD_CQR_IN_IO && cqr->expires != 0) {
-		if (time_after_eq(jiffies, cqr->expires + cqr->starttime)) {
+		if (get_clock() <= (jiffies_to_clock(cqr->expires)
+						 + cqr->startclk)) {
 			if (device->discipline->term_IO(cqr) != 0)
 				/* Hmpf, try again in 1/10 sec */
-				dasd_set_timer(device, 10);
+				dasd_set_timer(device, (10 * HZ) / 1000);
 		}
 	}
 }
@@ -1478,7 +1478,6 @@
 		/* termination successful */
 		cqr->status = DASD_CQR_QUEUED;
 		cqr->startclk = cqr->stopclk = 0;
-		cqr->starttime = 0;
 	}
 	return rc;
 }
diff -urN linux-2.6.8-rc3/drivers/s390/char/con3215.c linux-2.6.8-rc3-s390/drivers/s390/char/con3215.c
--- linux-2.6.8-rc3/drivers/s390/char/con3215.c	Wed Jun 16 07:19:42 2004
+++ linux-2.6.8-rc3-s390/drivers/s390/char/con3215.c	Thu Aug  5 15:36:57 2004
@@ -300,7 +300,7 @@
 
 	spin_lock_irqsave(raw->lock, flags);
 	if (raw->flags & RAW3215_TIMER_RUNS) {
-		del_timer(&raw->timer);
+		del_timeout(&raw->timer);
 		raw->flags &= ~RAW3215_TIMER_RUNS;
 		raw3215_mk_write_req(raw);
 		raw3215_start_io(raw);
@@ -327,16 +327,16 @@
 			/* execute write requests bigger than minimum size */
 			raw3215_start_io(raw);
 			if (raw->flags & RAW3215_TIMER_RUNS) {
-				del_timer(&raw->timer);
+				del_timeout(&raw->timer);
 				raw->flags &= ~RAW3215_TIMER_RUNS;
 			}
 		} else if (!(raw->flags & RAW3215_TIMER_RUNS)) {
 			/* delay small writes */
 			init_timer(&raw->timer);
-			raw->timer.expires = RAW3215_TIMEOUT + jiffies;
+			raw->timer.expires = RAW3215_TIMEOUT;
 			raw->timer.data = (unsigned long) raw;
 			raw->timer.function = raw3215_timeout;
-			add_timer(&raw->timer);
+			add_timeout(&raw->timer);
 			raw->flags |= RAW3215_TIMER_RUNS;
 		}
 	}
diff -urN linux-2.6.8-rc3/drivers/s390/char/sclp.c linux-2.6.8-rc3-s390/drivers/s390/char/sclp.c
--- linux-2.6.8-rc3/drivers/s390/char/sclp.c	Thu Aug  5 15:34:26 2004
+++ linux-2.6.8-rc3-s390/drivers/s390/char/sclp.c	Thu Aug  5 15:36:57 2004
@@ -132,13 +132,13 @@
 			 * Try again later.
 			 */
 			if (!timer_pending(&sclp_busy_timer) ||
-			    !mod_timer(&sclp_busy_timer,
-				       jiffies + SCLP_BUSY_POLL_INTERVAL*HZ)) {
+			    !mod_timeout(&sclp_busy_timer,
+				       SCLP_BUSY_POLL_INTERVAL*HZ)) {
 				sclp_busy_timer.function =
 					(void *) sclp_start_request;
 				sclp_busy_timer.expires =
-					jiffies + SCLP_BUSY_POLL_INTERVAL*HZ;
-				add_timer(&sclp_busy_timer);
+					SCLP_BUSY_POLL_INTERVAL*HZ;
+				add_timeout(&sclp_busy_timer);
 			}
 			break;
 		}
@@ -648,13 +648,12 @@
 		   change event, so initially, polling is the only alternative
 		   for us to ever become operational. */
 		if (!timer_pending(&retry_timer) ||
-		    !mod_timer(&retry_timer,
-			       jiffies + SCLP_INIT_POLL_INTERVAL*HZ)) {
+		    !mod_timeout(&retry_timer,
+			       SCLP_INIT_POLL_INTERVAL*HZ)) {
 			retry_timer.function = sclp_init_mask_retry;
 			retry_timer.data = 0;
-			retry_timer.expires = jiffies +
-				SCLP_INIT_POLL_INTERVAL*HZ;
-			add_timer(&retry_timer);
+			retry_timer.expires = SCLP_INIT_POLL_INTERVAL*HZ;
+			add_timeout(&retry_timer);
 		}
 	} else {
 		sclp_receive_mask = sccb->sclp_receive_mask;
diff -urN linux-2.6.8-rc3/drivers/s390/char/sclp_con.c linux-2.6.8-rc3-s390/drivers/s390/char/sclp_con.c
--- linux-2.6.8-rc3/drivers/s390/char/sclp_con.c	Wed Jun 16 07:19:23 2004
+++ linux-2.6.8-rc3-s390/drivers/s390/char/sclp_con.c	Thu Aug  5 15:36:57 2004
@@ -150,12 +150,12 @@
 	} while (count > 0);
 	/* Setup timer to output current console buffer after 1/10 second */
 	if (sclp_conbuf != NULL && sclp_chars_in_buffer(sclp_conbuf) != 0 &&
-	    !timer_pending(&sclp_con_timer)) {
+	    !timeout_pending(&sclp_con_timer)) {
 		init_timer(&sclp_con_timer);
 		sclp_con_timer.function = sclp_console_timeout;
 		sclp_con_timer.data = 0UL;
-		sclp_con_timer.expires = jiffies + HZ/10;
-		add_timer(&sclp_con_timer);
+		sclp_con_timer.expires = HZ/10;
+		add_timeout(&sclp_con_timer);
 	}
 	spin_unlock_irqrestore(&sclp_con_lock, flags);
 }
@@ -179,8 +179,7 @@
 
 	sclp_conbuf_emit();
 	spin_lock_irqsave(&sclp_con_lock, flags);
-	if (timer_pending(&sclp_con_timer))
-		del_timer(&sclp_con_timer);
+	del_timeout(&sclp_con_timer);
 	while (sclp_con_buffer_count > 0) {
 		spin_unlock_irqrestore(&sclp_con_lock, flags);
 		sclp_sync_wait();
diff -urN linux-2.6.8-rc3/drivers/s390/char/sclp_rw.c linux-2.6.8-rc3-s390/drivers/s390/char/sclp_rw.c
--- linux-2.6.8-rc3/drivers/s390/char/sclp_rw.c	Wed Jun 16 07:19:22 2004
+++ linux-2.6.8-rc3-s390/drivers/s390/char/sclp_rw.c	Thu Aug  5 15:36:57 2004
@@ -428,9 +428,8 @@
 		/* wait some time, then retry request */
 		buffer->retry_timer.function = sclp_buffer_retry;
 		buffer->retry_timer.data = (unsigned long) buffer;
-		buffer->retry_timer.expires = jiffies +
-						SCLP_BUFFER_RETRY_INTERVAL*HZ;
-		add_timer(&buffer->retry_timer);
+		buffer->retry_timer.expires = SCLP_BUFFER_RETRY_INTERVAL*HZ;
+		add_timeout(&buffer->retry_timer);
 		return;
 
 	default:
diff -urN linux-2.6.8-rc3/drivers/s390/char/sclp_tty.c linux-2.6.8-rc3-s390/drivers/s390/char/sclp_tty.c
--- linux-2.6.8-rc3/drivers/s390/char/sclp_tty.c	Wed Jun 16 07:18:58 2004
+++ linux-2.6.8-rc3-s390/drivers/s390/char/sclp_tty.c	Thu Aug  5 15:36:57 2004
@@ -376,8 +376,8 @@
 			init_timer(&sclp_tty_timer);
 			sclp_tty_timer.function = sclp_tty_timeout;
 			sclp_tty_timer.data = 0UL;
-			sclp_tty_timer.expires = jiffies + HZ/10;
-			add_timer(&sclp_tty_timer);
+			sclp_tty_timer.expires = HZ/10;
+			add_timeout(&sclp_tty_timer);
 		}
 	} else {
 		if (sclp_ttybuf != NULL &&
diff -urN linux-2.6.8-rc3/drivers/s390/char/tape_std.c linux-2.6.8-rc3-s390/drivers/s390/char/tape_std.c
--- linux-2.6.8-rc3/drivers/s390/char/tape_std.c	Wed Jun 16 07:18:37 2004
+++ linux-2.6.8-rc3-s390/drivers/s390/char/tape_std.c	Thu Aug  5 15:36:57 2004
@@ -76,12 +76,12 @@
 	init_timer(&timeout);
 	timeout.function = tape_std_assign_timeout;
 	timeout.data     = (unsigned long) request;
-	timeout.expires  = jiffies + 2 * HZ;
-	add_timer(&timeout);
+	timeout.expires  = 2 * HZ;
+	add_timeout(&timeout);
 
 	rc = tape_do_io_interruptible(device, request);
 
-	del_timer(&timeout);
+	del_timeout(&timeout);
 
 	if (rc != 0) {
 		PRINT_WARN("%s: assign failed - device might be busy\n",
diff -urN linux-2.6.8-rc3/drivers/s390/char/tty3270.c linux-2.6.8-rc3-s390/drivers/s390/char/tty3270.c
--- linux-2.6.8-rc3/drivers/s390/char/tty3270.c	Wed Jun 16 07:19:01 2004
+++ linux-2.6.8-rc3-s390/drivers/s390/char/tty3270.c	Thu Aug  5 15:36:57 2004
@@ -126,19 +126,19 @@
 	if (expires == 0) {
 		if (timer_pending(&tp->timer)) {
 			raw3270_put_view(&tp->view);
-			del_timer(&tp->timer);
+			del_timeout(&tp->timer);
 		}
 		return;
 	}
 	if (timer_pending(&tp->timer)) {
-		if (mod_timer(&tp->timer, jiffies + expires))
+		if (mod_timeout(&tp->timer, expires))
 			return;
 	}
 	raw3270_get_view(&tp->view);
 	tp->timer.function = (void (*)(unsigned long)) tty3270_update;
 	tp->timer.data = (unsigned long) tp;
-	tp->timer.expires = jiffies + expires;
-	add_timer(&tp->timer);
+	tp->timer.expires = expires;
+	add_timeout(&tp->timer);
 }
 
 /*
diff -urN linux-2.6.8-rc3/drivers/s390/cio/device_fsm.c linux-2.6.8-rc3-s390/drivers/s390/cio/device_fsm.c
--- linux-2.6.8-rc3/drivers/s390/cio/device_fsm.c	Thu Aug  5 15:34:27 2004
+++ linux-2.6.8-rc3-s390/drivers/s390/cio/device_fsm.c	Thu Aug  5 15:36:57 2004
@@ -80,17 +80,17 @@
 ccw_device_set_timeout(struct ccw_device *cdev, int expires)
 {
 	if (expires == 0) {
-		del_timer(&cdev->private->timer);
+		del_timeout(&cdev->private->timer);
 		return;
 	}
 	if (timer_pending(&cdev->private->timer)) {
-		if (mod_timer(&cdev->private->timer, jiffies + expires))
+		if (mod_timeout(&cdev->private->timer, expires))
 			return;
 	}
 	cdev->private->timer.function = ccw_device_timeout;
 	cdev->private->timer.data = (unsigned long) cdev;
-	cdev->private->timer.expires = jiffies + expires;
-	add_timer(&cdev->private->timer);
+	cdev->private->timer.expires = expires;
+	add_timeout(&cdev->private->timer);
 }
 
 /*
diff -urN linux-2.6.8-rc3/drivers/s390/crypto/z90main.c linux-2.6.8-rc3-s390/drivers/s390/crypto/z90main.c
--- linux-2.6.8-rc3/drivers/s390/crypto/z90main.c	Wed Jun 16 07:18:38 2004
+++ linux-2.6.8-rc3-s390/drivers/s390/crypto/z90main.c	Thu Aug  5 15:36:57 2004
@@ -677,7 +677,7 @@
 	init_timer(&cleanup_timer);
 	cleanup_timer.function = z90crypt_cleanup_task;
 	cleanup_timer.data = 0;
-	cleanup_timer.expires = jiffies + (CLEANUPTIME * HZ);
+	cleanup_timer.expires = CLEANUPTIME * HZ;
 	add_timer(&cleanup_timer);
 
 	/* Set up the proc file system */
@@ -696,7 +696,7 @@
 	init_timer(&config_timer);
 	config_timer.function = z90crypt_config_task;
 	config_timer.data = 0;
-	config_timer.expires = jiffies + (INITIAL_CONFIGTIME * HZ);
+	config_timer.expires = INITIAL_CONFIGTIME * HZ;
 	add_timer(&config_timer);
 
 	/* Set up the reader task */
@@ -704,7 +704,7 @@
 	init_timer(&reader_timer);
 	reader_timer.function = z90crypt_schedule_reader_task;
 	reader_timer.data = 0;
-	reader_timer.expires = jiffies + (READERTIME * HZ / 1000);
+	reader_timer.expires = READERTIME * HZ / 1000;
 	add_timer(&reader_timer);
 
 	if ((result = z90_register_ioctl32s()))
@@ -2496,7 +2496,7 @@
 {
 	if (timer_pending(&reader_timer))
 		return;
-	if (mod_timer(&reader_timer, jiffies+(READERTIME*HZ/1000)) != 0)
+	if (mod_timeout(&reader_timer, READERTIME*HZ/1000) != 0)
 		PRINTK("Timer pending while modifying reader timer\n");
 }
 
@@ -2508,8 +2508,6 @@
 	unsigned char __user *resp_addr;
 	static unsigned char buff[1024];
 
-	PDEBUG("jiffies %ld\n", jiffies);
-
 	/**
 	 * we use workavail = 2 to ensure 2 passes with nothing dequeued before
 	 * exiting the loop. If remaining == 0 after the loop, there is no work
@@ -2567,7 +2565,7 @@
 {
 	if (timer_pending(&config_timer))
 		return;
-	if (mod_timer(&config_timer, jiffies+(expiration*HZ)) != 0)
+	if (mod_timer(&config_timer, expiration*HZ) != 0)
 		PRINTK("Timer pending while modifying config timer\n");
 }
 
@@ -2576,8 +2574,6 @@
 {
 	int rc;
 
-	PDEBUG("jiffies %ld\n", jiffies);
-
 	if ((rc = refresh_z90crypt(&z90crypt.cdx)))
 		PRINTK("Error %d detected in refresh_z90crypt.\n", rc);
 	/* If return was fatal, don't bother reconfiguring */
@@ -2590,7 +2586,7 @@
 {
 	if (timer_pending(&cleanup_timer))
 		return;
-	if (mod_timer(&cleanup_timer, jiffies+(CLEANUPTIME*HZ)) != 0)
+	if (mod_timer(&cleanup_timer, CLEANUPTIME*HZ) != 0)
 		PRINTK("Timer pending while modifying cleanup timer\n");
 }
 
@@ -2679,7 +2675,6 @@
 static void
 z90crypt_cleanup_task(unsigned long ptr)
 {
-	PDEBUG("jiffies %ld\n", jiffies);
 	spin_lock_irq(&queuespinlock);
 	if (z90crypt.mask.st_count <= 0) // no devices!
 		helper_drain_queues();
diff -urN linux-2.6.8-rc3/drivers/s390/net/ctctty.c linux-2.6.8-rc3-s390/drivers/s390/net/ctctty.c
--- linux-2.6.8-rc3/drivers/s390/net/ctctty.c	Thu Aug  5 15:34:27 2004
+++ linux-2.6.8-rc3-s390/drivers/s390/net/ctctty.c	Thu Aug  5 15:36:57 2004
@@ -475,7 +475,7 @@
 		info->mcr &= ~(UART_MCR_DTR | UART_MCR_RTS);
 	if (info->tty)
 		set_bit(TTY_IO_ERROR, &info->tty->flags);
-	mod_timer(&info->stoptimer, jiffies + (10 * HZ));
+	mod_timeout(&info->stoptimer, 10 * HZ);
 	skb_queue_purge(&info->tx_queue);
 	skb_queue_purge(&info->rx_queue);
 	info->flags &= ~CTC_ASYNC_INITIALIZED;
@@ -1000,7 +1000,7 @@
 {
 	ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;
 	ulong flags;
-	ulong timeout;
+
 	DBF_TEXT(trace, 3, __FUNCTION__);
 	if (!info || ctc_tty_paranoia_check(info, tty->name, "ctc_tty_close"))
 		return;
@@ -1045,21 +1045,26 @@
 	 * line status register.
 	 */
 	if (info->flags & CTC_ASYNC_INITIALIZED) {
+		struct timer_list t;
 		tty_wait_until_sent(tty, 30*HZ); /* 30 seconds timeout */
 		/*
 		 * Before we drop DTR, make sure the UART transmitter
 		 * has completely drained; this is especially
 		 * important if there is a transmit FIFO!
 		 */
-		timeout = jiffies + HZ;
+		init_timer(&t);
+		t.expires = HZ;
+		t.function = timer_noop;
+		add_timeout(&t);
 		while (!(info->lsr & UART_LSR_TEMT)) {
 			set_current_state(TASK_INTERRUPTIBLE);
 			spin_unlock_irqrestore(&ctc_tty_lock, flags);
 			schedule_timeout(HZ/2);
 			spin_lock_irqsave(&ctc_tty_lock, flags);
-			if (time_after(jiffies,timeout))
+			if (!timer_pending(&t))
 				break;
 		}
+		del_timeout(&t);
 	}
 	ctc_tty_shutdown(info);
 	if (tty->driver->flush_buffer) {
diff -urN linux-2.6.8-rc3/drivers/s390/net/fsm.c linux-2.6.8-rc3-s390/drivers/s390/net/fsm.c
--- linux-2.6.8-rc3/drivers/s390/net/fsm.c	Wed Jun 16 07:19:23 2004
+++ linux-2.6.8-rc3-s390/drivers/s390/net/fsm.c	Thu Aug  5 15:36:57 2004
@@ -164,7 +164,7 @@
 	printk(KERN_DEBUG "fsm(%s): Delete timer %p\n", this->fi->name,
 		this);
 #endif
-	del_timer(&this->tl);
+	del_timeout(&this->tl);
 }
 
 int
@@ -181,37 +181,16 @@
 	this->tl.data = (long)this;
 	this->expire_event = event;
 	this->event_arg = arg;
-	this->tl.expires = jiffies + (millisec * HZ) / 1000;
-	add_timer(&this->tl);
+	this->tl.expires = (millisec * HZ) / 1000;
+	add_timeout(&this->tl);
 	return 0;
 }
 
-/* FIXME: this function is never used, why */
-void
-fsm_modtimer(fsm_timer *this, int millisec, int event, void *arg)
-{
-
-#if FSM_TIMER_DEBUG
-	printk(KERN_DEBUG "fsm(%s): Restart timer %p %dms\n",
-		this->fi->name, this, millisec);
-#endif
-
-	del_timer(&this->tl);
-	init_timer(&this->tl);
-	this->tl.function = (void *)fsm_expire_timer;
-	this->tl.data = (long)this;
-	this->expire_event = event;
-	this->event_arg = arg;
-	this->tl.expires = jiffies + (millisec * HZ) / 1000;
-	add_timer(&this->tl);
-}
-
 EXPORT_SYMBOL(init_fsm);
 EXPORT_SYMBOL(kfree_fsm);
 EXPORT_SYMBOL(fsm_settimer);
 EXPORT_SYMBOL(fsm_deltimer);
 EXPORT_SYMBOL(fsm_addtimer);
-EXPORT_SYMBOL(fsm_modtimer);
 EXPORT_SYMBOL(fsm_getstate_str);
 
 #if FSM_DEBUG_HISTORY
diff -urN linux-2.6.8-rc3/drivers/s390/net/fsm.h linux-2.6.8-rc3-s390/drivers/s390/net/fsm.h
--- linux-2.6.8-rc3/drivers/s390/net/fsm.h	Wed Jun 16 07:19:44 2004
+++ linux-2.6.8-rc3-s390/drivers/s390/net/fsm.h	Thu Aug  5 15:36:57 2004
@@ -252,14 +252,4 @@
  */
 extern int fsm_addtimer(fsm_timer *timer, int millisec, int event, void *arg);
 
-/**
- * Modifies a timer of an FSM.
- *
- * @param timer    The timer to modify.
- * @param millisec Duration, after which the timer should expire.
- * @param event    Event, to trigger if timer expires.
- * @param arg      Generic argument, provided to expiry function.
- */
-extern void fsm_modtimer(fsm_timer *timer, int millisec, int event, void *arg);
-
 #endif /* _FSM_H_ */
diff -urN linux-2.6.8-rc3/drivers/s390/net/lcs.c linux-2.6.8-rc3-s390/drivers/s390/net/lcs.c
--- linux-2.6.8-rc3/drivers/s390/net/lcs.c	Thu Aug  5 15:34:27 2004
+++ linux-2.6.8-rc3-s390/drivers/s390/net/lcs.c	Thu Aug  5 15:36:57 2004
@@ -29,6 +29,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/delay.h>
 #include <linux/if.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
@@ -720,10 +721,10 @@
 	init_timer(&timer);
 	timer.function = lcs_lancmd_timeout;
 	timer.data = (unsigned long) &reply;
-	timer.expires = jiffies + HZ*card->lancmd_timeout;
-	add_timer(&timer);
+	timer.expires = HZ*card->lancmd_timeout;
+	add_timeout(&timer);
 	wait_event(reply.wait_q, reply.received);
-	del_timer(&timer);
+	del_timeout(&timer);
 	LCS_DBF_TEXT_(4, trace, "rc:%d",reply.rc);
 	return reply.rc ? -EIO : 0;
 }
diff -urN linux-2.6.8-rc3/drivers/s390/net/qeth_main.c linux-2.6.8-rc3-s390/drivers/s390/net/qeth_main.c
--- linux-2.6.8-rc3/drivers/s390/net/qeth_main.c	Thu Aug  5 15:34:27 2004
+++ linux-2.6.8-rc3-s390/drivers/s390/net/qeth_main.c	Thu Aug  5 15:36:57 2004
@@ -1771,9 +1771,9 @@
 	timer.function = qeth_cmd_timeout;
 	timer.data = (unsigned long) reply;
 	if (IS_IPA(iob->data))
-		timer.expires = jiffies + QETH_IPA_TIMEOUT;
+		timer.expires = QETH_IPA_TIMEOUT;
 	else
-		timer.expires = jiffies + QETH_TIMEOUT;
+		timer.expires = QETH_TIMEOUT;
 	init_waitqueue_head(&reply->wait_q);
 	spin_lock_irqsave(&card->lock, flags);
 	list_add_tail(&reply->list, &card->cmd_waiter_list);
@@ -1799,9 +1799,9 @@
 		wake_up(&card->wait_q);
 		return rc;
 	}
-	add_timer(&timer);
+	add_timeout(&timer);
 	wait_event(reply->wait_q, reply->received);
-	del_timer(&timer);
+	del_timeout(&timer);
 	rc = reply->rc;
 	qeth_put_reply(reply);
 	return rc;
diff -urN linux-2.6.8-rc3/drivers/s390/scsi/zfcp_erp.c linux-2.6.8-rc3-s390/drivers/s390/scsi/zfcp_erp.c
--- linux-2.6.8-rc3/drivers/s390/scsi/zfcp_erp.c	Thu Aug  5 15:34:27 2004
+++ linux-2.6.8-rc3-s390/drivers/s390/scsi/zfcp_erp.c	Thu Aug  5 15:36:57 2004
@@ -1560,8 +1560,8 @@
 	init_timer(&erp_action->timer);
 	erp_action->timer.function = zfcp_erp_memwait_handler;
 	erp_action->timer.data = (unsigned long) erp_action;
-	erp_action->timer.expires = jiffies + ZFCP_ERP_MEMWAIT_TIMEOUT;
-	add_timer(&erp_action->timer);
+	erp_action->timer.expires = ZFCP_ERP_MEMWAIT_TIMEOUT;
+	add_timeout(&erp_action->timer);
 
 	return retval;
 }
@@ -3292,7 +3292,6 @@
 	init_timer(&erp_action->timer);
 	erp_action->timer.function = zfcp_erp_timeout_handler;
 	erp_action->timer.data = (unsigned long) erp_action;
-	/* jiffies will be added in zfcp_fsf_req_send */
 	erp_action->timer.expires = ZFCP_ERP_FSFREQ_TIMEOUT;
 }
 
diff -urN linux-2.6.8-rc3/drivers/s390/scsi/zfcp_fsf.c linux-2.6.8-rc3-s390/drivers/s390/scsi/zfcp_fsf.c
--- linux-2.6.8-rc3/drivers/s390/scsi/zfcp_fsf.c	Thu Aug  5 15:34:27 2004
+++ linux-2.6.8-rc3-s390/drivers/s390/scsi/zfcp_fsf.c	Thu Aug  5 15:36:57 2004
@@ -1154,7 +1154,7 @@
 	zfcp_fsf_start_scsi_er_timer(adapter);
 	retval = zfcp_fsf_req_send(fsf_req, NULL);
 	if (retval) {
-		del_timer(&adapter->scsi_er_timer);
+		del_timeout(&adapter->scsi_er_timer);
 		ZFCP_LOG_INFO("error: Failed to send abort command request "
 			      "on adapter %s, port 0x%016Lx, unit 0x%016Lx\n",
 			      zfcp_get_busid_by_adapter(adapter),
@@ -1190,7 +1190,7 @@
 	unsigned char status_qual =
 	    new_fsf_req->qtcb->header.fsf_status_qual.word[0];
 
-	del_timer(&new_fsf_req->adapter->scsi_er_timer);
+	del_timeout(&new_fsf_req->adapter->scsi_er_timer);
 
 	if (new_fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) {
 		/* do not set ZFCP_STATUS_FSFREQ_ABORTSUCCEEDED */
@@ -3581,7 +3581,7 @@
 	zfcp_fsf_start_scsi_er_timer(adapter);
 	retval = zfcp_fsf_req_send(fsf_req, NULL);
 	if (retval) {
-		del_timer(&adapter->scsi_er_timer);
+		del_timeout(&adapter->scsi_er_timer);
 		ZFCP_LOG_INFO("error: Could not send an FCP-command (task "
 			      "management) on adapter %s, port 0x%016Lx for "
 			      "unit LUN 0x%016Lx\n",
@@ -4278,7 +4278,7 @@
 	struct zfcp_unit *unit =
 	    fsf_req->data.send_fcp_command_task_management.unit;
 
-	del_timer(&fsf_req->adapter->scsi_er_timer);
+	del_timeout(&fsf_req->adapter->scsi_er_timer);
 	if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) {
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_TMFUNCFAILED;
 		goto skip_fsfstatus;
@@ -4877,10 +4877,8 @@
 	list_add_tail(&fsf_req->list, &adapter->fsf_req_list_head);
 	write_unlock_irqrestore(&adapter->fsf_req_list_lock, flags);
 
-	/* figure out expiration time of timeout and start timeout */
 	if (unlikely(timer)) {
-		timer->expires += jiffies;
-		add_timer(timer);
+		add_timeout(timer);
 	}
 
 	ZFCP_LOG_TRACE("request queue of adapter %s: "
diff -urN linux-2.6.8-rc3/include/asm-s390/timex.h linux-2.6.8-rc3-s390/include/asm-s390/timex.h
--- linux-2.6.8-rc3/include/asm-s390/timex.h	Wed Jun 16 07:18:52 2004
+++ linux-2.6.8-rc3-s390/include/asm-s390/timex.h	Thu Aug  5 15:36:57 2004
@@ -37,4 +37,8 @@
 	return clk;
 }
 
+#define clock_to_jiffies(clk) ((((unsigned long)(a) >> 12)) / (1000000 / HZ))
+#define jiffies_to_clock(jiffies) ((unsigned long long) \
+				(4096ull * 1000ull * 1000ull / HZ * jiffies))
+
 #endif


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2004-08-05 14:02 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-07-27 19:59 Initial bits to help pull jiffies out of drivers Alan Cox
2004-08-02 21:33 ` Tim Bird
2004-08-02 21:52   ` Alan Cox
2004-08-03  8:27 ` Arjan van de Ven
     [not found] <2mGr0-7w6-27@gated-at.bofh.it>
2004-08-02 23:35 ` Andi Kleen
  -- strict thread matches above, loose matches on Subject: below --
2004-08-05 13:57 Martin Schwidefsky

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox