aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorMartin Michlmayr <tbm@cyrius.com>2012-10-04 17:11:25 -0700
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-10-13 05:28:03 +0900
commitfe77d1bb93b50233d9d2932d348c1a78214ea485 (patch)
tree5f1d7bef4ae649f3a884ec44b9ec45d1d115a002 /drivers/scsi
parentfaaeea39363ad54b3dfe23cc982e484f6e54aa5a (diff)
downloadkernel_samsung_smdk4412-fe77d1bb93b50233d9d2932d348c1a78214ea485.tar.gz
kernel_samsung_smdk4412-fe77d1bb93b50233d9d2932d348c1a78214ea485.tar.bz2
kernel_samsung_smdk4412-fe77d1bb93b50233d9d2932d348c1a78214ea485.zip
drivers/scsi/atp870u.c: fix bad use of udelay
commit 0f6d93aa9d96cc9022b51bd10d462b03296be146 upstream. 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. [jrnieder@gmail.com: adding context] Signed-off-by: Martin Michlmayr <tbm@cyrius.com> Signed-off-by: Jonathan Nieder <jrnieder@gmail.com> Cc: James Bottomley <James.Bottomley@HansenPartnership.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/atp870u.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c
index 7e6eca4a125..59fc5a1fdae 100644
--- a/drivers/scsi/atp870u.c
+++ b/drivers/scsi/atp870u.c
@@ -1174,7 +1174,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);