Bug 6970

Summary: ISDN/hisax doesn't work on ARM architecture
Product: Drivers Reporter: Tomasz Chmielewski (tch)
Component: ISDNAssignee: Karsten Keil (kernel)
Status: CLOSED PATCH_ALREADY_AVAILABLE    
Severity: high    
Priority: P2    
Hardware: i386   
OS: Linux   
Kernel Version: 2.6.17 Subsystem:
Regression: --- Bisected commit-id:

Description Tomasz Chmielewski 2006-08-07 02:55:17 UTC
Most recent kernel where this bug did not occur:
Distribution:
Hardware Environment:
Software Environment:
Problem Description:

Steps to reproduce:
Currently, hisax driver will not work on ARM architecture.

This is because in hisax.h we have:

#define HZDELAY(jiffs) {int tout = jiffs; while (tout--) 
udelay(1000000/HZ);}


This will work on most architectures, but not on ARM (and on m68k I 
suppose).

When we try to load the hisax module on arm, it will fail:

hisax: Unknown symbol __bad_udelay


Here's a quick workaround:

hisax will only work on ARM when we change "#define HZDELAY..." in hisax.h to match:

#define HZDELAY(jiffs) {int tout = jiffs; while (tout--) 
udelay(268435456 / (1000000/HZ));}
Comment 1 Karsten Keil 2006-09-07 03:19:20 UTC
I do not understand the formula, why using 268435456 here ?
Comment 2 Tomasz Chmielewski 2006-09-07 03:36:39 UTC
I took the idea from http://lwn.net/Articles/142512/ - perhaps it was wrong to
use, but worked for me.

You should received a patch on 07.08.2006:

diff -puN drivers/isdn/hisax/hisax.h~isdn-work-around-excessive-udelay
drivers/isdn/hisax/hisax.h
--- a/drivers/isdn/hisax/hisax.h~isdn-work-around-excessive-udelay
+++ a/drivers/isdn/hisax/hisax.h
@@ -1316,7 +1316,18 @@ void dlogframe(struct IsdnCardState *cs,
 void iecpy(u_char * dest, u_char * iestart, int ieoffset);
 #endif	/* __KERNEL__ */
 
-#define HZDELAY(jiffs) {int tout = jiffs; while (tout--) udelay(1000000/HZ);}
+/*
+ * Busywait delay for `jiffs' jiffies
+ */
+#define HZDELAY(jiffs) do {					\
+		int tout = jiffs;				\
+								\
+		while (tout--) {				\
+			int loops = USEC_PER_SEC / HZ;		\
+			while (loops--)				\
+				udelay(1);			\
+		}						\
+	} while (0)
 
 int ll_run(struct IsdnCardState *cs, int addfeatures);
 int CallcNew(void);
Comment 3 Tomasz Chmielewski 2007-04-28 13:39:15 UTC
The patch was already 
Comment 4 Tomasz Chmielewski 2007-04-28 13:40:14 UTC
The patch was already added on 02.10.2006:

The patch titled

     isdn: work around excessive udelay()

has been removed from the -mm tree.  Its filename is

     isdn-work-around-excessive-udelay.patch

This patch was dropped because it was merged into mainline or a subsystem tree