Time for a little audit.
loops_per_sec isn't actually used a lot - there's more code in the tree
to calculate and report than there is that actually uses it. Whatever.
The value of loops_per_sec is meaningless outside the context of a call
to __delay(). Unfortunately a lot of drivers either:
1: Assume a time relationship between a loop in the driver and the loop
in __delay() by doing something like:
for (i = 0; i < loops_per_sec / something; i++)
driver_stuff();
or
2: Assume that the implementation of __delay() will never change and
that all CPUs run at the same speed by calling:
__delay(MAGIC_CONSTANT);
drivers/block/acsi.c is fragile:
long tries = loops_per_sec / HZ / 8 * timeout;
while( --tries >= 0 )
if (!(mfp.par_dt_reg & 0x20)) return( 1 );
Assumes that there's an 8:1 ratio between this loop and the __delay()
loop. This is for Atari - should be OK.
drivers/net/appletalk/ltpc.c:
for(i=0;i<20000;i++) {
if ( c != inb_p(dev->base_addr+6) ) return 0;
for(timeout=loops_per_sec/1000; timeout > 0; timeout--)
;
Not sure what arch this is for, but it's fragile and dependent upon CPU
speed.
drivers/scsi/eata_dma.c:
while (inb((u32)(cmd->host->base) + HA_RAUXSTAT) & HA_ABUSY)
if (--loop == 0) {
printk("eata_reset: exit, timeout error.\n");
restore_flags(flags);
DBG(DBG_ABNORM && DBG_DELAY, DELAY(1));
return (SCSI_RESET_ERROR);
}
This will now take twice as long to time out. Dependent upon CPU speed.
drivers/sound/wavfront.c:
for (i = 0; i < short_loop_cnt; i++) {
if (wavefront_status() & mask) {
return 1;
}
}
The only one which caters for differently clocked SMP CPUs. Doubled in
2.3.99. Dependent upon CPU speed.
arch/alpha/kernel/time.c:
__delay(1000000);
Presumably safe for now, but should use loops_per_sec. Dependent on CPU
speed.
arch/ppc/xmon/xmon.c
__delay(200);
Ditto.
drivers/video/atyfb.c:
__delay(2000);
Halved. Dependent upon CPU speed.
drivers/video/platinumfb.c:
__delay(5000);
__delay(2000);
Halved. Dependent...
drivers/video/valkyriefb.c:
__delay(20000);
Halved. Dependent...
I suggest the way to restore determinism to all of this is to unexport
loops_per_sec and __delay(), then to reimplement everything with
udelay() (and, perhaps, ndelay()).
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/
This archive was generated by hypermail 2b29 : Thu Mar 23 2000 - 21:00:24 EST