patch-1.3.71 linux/include/linux/interrupt.h

Next file: linux/include/linux/loop.h
Previous file: linux/include/linux/binfmts.h
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v1.3.70/linux/include/linux/interrupt.h linux/include/linux/interrupt.h
@@ -15,14 +15,10 @@
 };
 
 
-struct bh_struct {
-	void (*routine)(void *);
-	void *data;
-};
-
+extern int bh_mask_count[32];
 extern unsigned long bh_active;
 extern unsigned long bh_mask;
-extern struct bh_struct bh_base[32];
+extern void (*bh_base[32])(void);
 
 asmlinkage void do_bottom_half(void);
 
@@ -41,21 +37,38 @@
 	CM206_BH
 };
 
+extern inline void init_bh(int nr, void (*routine)(void))
+{
+	bh_base[nr] = routine;
+	bh_mask_count[nr] = 0;
+	bh_mask |= 1 << nr;
+}
+
 extern inline void mark_bh(int nr)
 {
 	set_bit(nr, &bh_active);
 }
 
+/*
+ * These use a mask count to correctly handle
+ * nested disable/enable calls
+ */
 extern inline void disable_bh(int nr)
 {
-	clear_bit(nr, &bh_mask);
+	bh_mask &= ~(1 << nr);
+	bh_mask_count[nr]++;
 }
 
 extern inline void enable_bh(int nr)
 {
-	set_bit(nr, &bh_mask);
+	if (!--bh_mask_count[nr])
+		bh_mask |= 1 << nr;
 }
 
+/*
+ * start_bh_atomic/end_bh_atomic also nest
+ * naturally by using a counter
+ */
 extern inline void start_bh_atomic(void)
 {
 	intr_count++;

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov with Sam's (original) version
of this