* [PATCH/RFC v2] [SCSI] atp870u: Fix bad use of udelay
[not found] ` <1231536107.3235.50.camel@localhost.localdomain>
@ 2012-04-24 7:49 ` Jonathan Nieder
2012-04-24 21:18 ` Andrew Morton
0 siblings, 1 reply; 2+ messages in thread
From: Jonathan Nieder @ 2012-04-24 7:49 UTC (permalink / raw)
To: linux-arm-kernel
From: Martin Michlmayr <tbm@cyrius.com>
The ACARD driver calls udelay() with a value > 2000, which leads to
to the following compilation error on ARM:
ERROR: "__bad_udelay" [drivers/scsi/atp870u.ko] undefined!
make[1]: *** [__modpost] Error 1
This is because udelay is defined on ARM, roughly speaking, as
#define udelay(n) ((n) > 2000 ? __bad_udelay() : \
__const_udelay((n) * ((2199023U*HZ)>>11)))
The argument to __const_udelay is the number of jiffies to wait
divided by 4, but this does not work unless the multiplication does
not overflow, and that is what the build error is designed to prevent.
The intended behavior can be achieved by using mdelay to call udelay
multiple times in a loop.
[jn: adding context]
Signed-off-by: Martin Michlmayr <tbm@cyrius.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Cc: <stable@vger.kernel.org>
---
Hi James,
Three years ago, you wrote[1]:
>>> * akpm at linux-foundation.org <akpm@linux-foundation.org> [2009-01-09 12:28]:
>>>> The ACARD driver calls udelay() with a value > 2000, which leads to
>>>> to the following compilation error on ARM:
>>>> ERROR: "__bad_udelay" [drivers/scsi/atp870u.ko] undefined!
>>>> make[1]: *** [__modpost] Error 1
>>>> Fix this by using a combination of mdelay and udelay.
[...]
> It's wrong to silence a warning or build break while keeping the effect
> it was complaining about it's hiding a bug. Now if the warning is
> wrong, we can take it out of the ARM build ... but I've got to say it
> looks right: the udelay in this driver will lock a UP system solid for
> 2ms.
Sorry for the very slow response. I think the patch was inadequately
explained and that it is actually a good patch.
Here's the patch again with a description that helped me convince
myself it is ok. Could you look it over and let me know what you
think?
Thanks,
Jonathan
[1] http://thread.gmane.org/gmane.linux.scsi/47523/focus=47533
drivers/scsi/atp870u.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c
index 68ce08552f69..a540162ac59c 100644
--- a/drivers/scsi/atp870u.c
+++ b/drivers/scsi/atp870u.c
@@ -1173,7 +1173,16 @@ wait_io1:
outw(val, tmport);
outb(2, 0x80);
TCM_SYNC:
- udelay(0x800);
+ /*
+ * The funny division into multiple delays is to accomodate
+ * arches like ARM where udelay() multiplies its argument by
+ * a large number to initialize a loop counter. To avoid
+ * overflow, the maximum supported udelay is 2000 microseconds.
+ *
+ * XXX it would be more polite to find a way to use msleep()
+ */
+ mdelay(2);
+ udelay(48);
if ((inb(tmport) & 0x80) == 0x00) { /* bsy ? */
outw(0, tmport--);
outb(0, tmport);
--
1.7.10
^ permalink raw reply related [flat|nested] 2+ messages in thread
* [PATCH/RFC v2] [SCSI] atp870u: Fix bad use of udelay
2012-04-24 7:49 ` [PATCH/RFC v2] [SCSI] atp870u: Fix bad use of udelay Jonathan Nieder
@ 2012-04-24 21:18 ` Andrew Morton
0 siblings, 0 replies; 2+ messages in thread
From: Andrew Morton @ 2012-04-24 21:18 UTC (permalink / raw)
To: linux-arm-kernel
On Tue, 24 Apr 2012 02:49:16 -0500
Jonathan Nieder <jrnieder@gmail.com> wrote:
> From: Martin Michlmayr <tbm@cyrius.com>
>
> The ACARD driver calls udelay() with a value > 2000, which leads to
> to the following compilation error on ARM:
> ERROR: "__bad_udelay" [drivers/scsi/atp870u.ko] undefined!
> make[1]: *** [__modpost] Error 1
>
> ...
>
> --- a/drivers/scsi/atp870u.c
> +++ b/drivers/scsi/atp870u.c
> @@ -1173,7 +1173,16 @@ wait_io1:
> outw(val, tmport);
> outb(2, 0x80);
> TCM_SYNC:
> - udelay(0x800);
> + /*
> + * The funny division into multiple delays is to accomodate
> + * arches like ARM where udelay() multiplies its argument by
> + * a large number to initialize a loop counter. To avoid
> + * overflow, the maximum supported udelay is 2000 microseconds.
> + *
> + * XXX it would be more polite to find a way to use msleep()
> + */
> + mdelay(2);
> + udelay(48);
> if ((inb(tmport) & 0x80) == 0x00) { /* bsy ? */
> outw(0, tmport--);
> outb(0, tmport);
Fair enough, I say. Looking at this driver, I do think it's best to
minimally fix the build and then tiptoe away very delicately lest
something explode.
That being said, I'm glad the kernel has a function called "fun_scam".
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2012-04-24 21:18 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <200901092028.n09KSAeI024551@imap1.linux-foundation.org>
[not found] ` <20090109205835.GB5069@deprecation.cyrius.com>
[not found] ` <20090109130308.bfde281e.akpm@linux-foundation.org>
[not found] ` <1231536107.3235.50.camel@localhost.localdomain>
2012-04-24 7:49 ` [PATCH/RFC v2] [SCSI] atp870u: Fix bad use of udelay Jonathan Nieder
2012-04-24 21:18 ` Andrew Morton
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).