floating-point abuse in 2.1.113

Mikael Pettersson (mikpe@csd.uu.se)
Tue, 4 Aug 1998 11:29:14 +0200 (MET DST)


On Sat, 1 Aug 1998, Raul Miller wrote:

> ibmmca.c:2140: #error Floating point in kernel - shoot programmer
> make[3]: *** [ibmmca.o] Error 1
> make[3]: Leaving directory `/usr/local/src/linux/drivers/scsi'

Right. Floating-point is banned within the Linux kernel, yet some
drivers use it, perhaps accidentally. Some time ago I suggested
using gcc's "-msoft-float" option to catch these at kernel link time
or module insertion time. I've done this now, by building a monster
kernel with everything that would compile configured into it.

The results are that at least five drivers use f.p. in the kernel:
char/{radio-aztech,radio-aimslab}, scsi/{ibmmca,wd7000}, and isdn/pcbit.
Note that 4 of these manage to produce f.p. code without using
explicit float/double variables or casts, so just grepping for those
keywords won't catch these types of mistakes.

Patch not tested. YMMV. I'm cc:ing this to the drivers' authors.

/Mikael

--- linux-2.1.113/drivers/char/radio-aztech.c.orig Mon Jun 8 23:55:37 1998
+++ linux-2.1.113/drivers/char/radio-aztech.c Mon Aug 3 20:59:03 1998
@@ -113,7 +113,7 @@
{
int i;

- frequency = (frequency / 16.0) * 100; /* massage data a bit */
+ frequency = (frequency * 100) / 16; /* massage data a bit */

frequency += 1070; /* tuning needs 24 data bits */
frequency /= 5;
@@ -177,8 +177,8 @@
return -EFAULT;
if(v.tuner) /* Only 1 tuner */
return -EINVAL;
- v.rangelow=(int)(87.9*16);
- v.rangehigh=(int)(107.8*16);
+ v.rangelow=(879*16)/10;
+ v.rangehigh=(1078*16)/10;
v.flags=0;
v.mode=VIDEO_MODE_AUTO;
v.signal=0xFFFF*az_getsigstr(az);
--- linux-2.1.113/drivers/char/radio-aimslab.c.orig Tue Jul 21 21:29:24 1998
+++ linux-2.1.113/drivers/char/radio-aimslab.c Mon Aug 3 20:58:49 1998
@@ -155,7 +155,7 @@

/* adapted from radio-aztech.c */

- freq = (freq / 16.0) * 100; /* massage the data a little */
+ freq = (freq * 100) / 16; /* massage the data a little */
freq += 1070; /* IF = 10.7 MHz */
freq /= 5; /* ref = 25 kHz */

@@ -223,8 +223,8 @@
return -EFAULT;
if(v.tuner) /* Only 1 tuner */
return -EINVAL;
- v.rangelow=(int)(88.0*16);
- v.rangehigh=(int)(108.0*16);
+ v.rangelow=(88*16);
+ v.rangehigh=(108*16);
v.flags=0;
v.mode=VIDEO_MODE_AUTO;
v.signal=0xFFFF*rt_getsigstr(rt);
--- linux-2.1.113/drivers/scsi/ibmmca.c.orig Sat Jul 25 18:01:00 1998
+++ linux-2.1.113/drivers/scsi/ibmmca.c Mon Aug 3 20:52:32 1998
@@ -2137,8 +2137,7 @@
{
if (IBM_DS.total_accesses == 0) return (0);
if (IBM_DS.ldn_access[ldn] == 0) return (0);
-#error Floating point in kernel - shoot programmer
- return((int)(((float)IBM_DS.ldn_access[ldn]/(float)IBM_DS.total_accesses)*(float)100.000));
+ return (IBM_DS.ldn_access[ldn] * 100) / IBM_DS.total_accesses;
}

/* calculate total amount of r/w-accesses */
--- linux-2.1.113/drivers/scsi/wd7000.c.orig Fri May 22 17:34:00 1998
+++ linux-2.1.113/drivers/scsi/wd7000.c Mon Aug 3 20:52:32 1998
@@ -666,7 +666,7 @@
configs[wd7000_card_num].bus_on = BUS_ON;
}
else
- configs[wd7000_card_num].bus_on = ints[4] / 125.0;
+ configs[wd7000_card_num].bus_on = ints[4] / 125;
}
else
configs[wd7000_card_num].bus_on = BUS_ON;
@@ -678,7 +678,7 @@
configs[wd7000_card_num].bus_off = BUS_OFF;
}
else
- configs[wd7000_card_num].bus_off = ints[5] / 125.0;
+ configs[wd7000_card_num].bus_off = ints[5] / 125;
}
else
configs[wd7000_card_num].bus_off = BUS_OFF;
--- linux-2.1.113/drivers/isdn/pcbit/pcbit.h.orig Tue Apr 23 11:31:35 1996
+++ linux-2.1.113/drivers/isdn/pcbit/pcbit.h Mon Aug 3 20:52:33 1998
@@ -98,7 +98,7 @@
};

#define STATS_TIMER (10*HZ)
-#define ERRTIME (0.1*HZ)
+#define ERRTIME (HZ/10)

/* MRU */
#define MAXBUFSIZE 1534

-
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.altern.org/andrebalsa/doc/lkml-faq.html