Commit 555983d6 authored by Steffen A. Mork's avatar Steffen A. Mork Committed by Linus Torvalds

[PATCH] Make dss1_divert ISDN module work on SMP again

When I switched my installation from kernel 2.4 to 2.6 I recognized that
the ISDN module dss1_divert was marked incompilable (config option
CONFIG_CLEAN_COMPILE must be turned off). 

The compile problem was the obsolete using of kernel 2.4 critical
sections.  I replaced the cli() stuff with spinlocks as explained in the
Documentation/spinlocks.txt file.  After that the module compiles and
runs as expected. 
Signed-off-by: default avatarSteffen A. Mork <linux-dev@morknet.de>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent f46e994c
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/version.h> #include <linux/version.h>
#include <linux/init.h> #include <linux/init.h>
#include "isdn_divert.h" #include "isdn_divert.h"
MODULE_DESCRIPTION("ISDN4Linux: Call diversion support"); MODULE_DESCRIPTION("ISDN4Linux: Call diversion support");
...@@ -59,23 +60,24 @@ static int __init divert_init(void) ...@@ -59,23 +60,24 @@ static int __init divert_init(void)
/* Module deinit code */ /* Module deinit code */
/**********************/ /**********************/
static void __exit divert_exit(void) static void __exit divert_exit(void)
{ unsigned long flags; {
unsigned long flags;
spinlock_t divert_lock = SPIN_LOCK_UNLOCKED;
int i; int i;
save_flags(flags); spin_lock_irqsave(&divert_lock, flags);
cli();
divert_if.cmd = DIVERT_CMD_REL; /* release */ divert_if.cmd = DIVERT_CMD_REL; /* release */
if ((i = DIVERT_REG_NAME(&divert_if)) != DIVERT_NO_ERR) if ((i = DIVERT_REG_NAME(&divert_if)) != DIVERT_NO_ERR)
{ printk(KERN_WARNING "dss1_divert: error %d releasing module\n",i); { printk(KERN_WARNING "dss1_divert: error %d releasing module\n",i);
restore_flags(flags); spin_unlock_irqrestore(&divert_lock, flags);
return; return;
} }
if (divert_dev_deinit()) if (divert_dev_deinit())
{ printk(KERN_WARNING "dss1_divert: device busy, remove cancelled\n"); { printk(KERN_WARNING "dss1_divert: device busy, remove cancelled\n");
restore_flags(flags); spin_unlock_irqrestore(&divert_lock, flags);
return; return;
} }
restore_flags(flags); spin_unlock_irqrestore(&divert_lock, flags);
deleterule(-1); /* delete all rules and free mem */ deleterule(-1); /* delete all rules and free mem */
deleteprocs(); deleteprocs();
printk(KERN_INFO "dss1_divert module successfully removed \n"); printk(KERN_INFO "dss1_divert module successfully removed \n");
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include <linux/isdnif.h> #include <linux/isdnif.h>
#include "isdn_divert.h" #include "isdn_divert.h"
/*********************************/ /*********************************/
/* Variables for interface queue */ /* Variables for interface queue */
/*********************************/ /*********************************/
...@@ -181,6 +182,7 @@ isdn_divert_ioctl(struct inode *inode, struct file *file, ...@@ -181,6 +182,7 @@ isdn_divert_ioctl(struct inode *inode, struct file *file,
divert_ioctl dioctl; divert_ioctl dioctl;
int i; int i;
unsigned long flags; unsigned long flags;
spinlock_t divert_lock = SPIN_LOCK_UNLOCKED;
divert_rule *rulep; divert_rule *rulep;
char *cp; char *cp;
...@@ -215,10 +217,9 @@ isdn_divert_ioctl(struct inode *inode, struct file *file, ...@@ -215,10 +217,9 @@ isdn_divert_ioctl(struct inode *inode, struct file *file,
case IIOCMODRULE: case IIOCMODRULE:
if (!(rulep = getruleptr(dioctl.getsetrule.ruleidx))) if (!(rulep = getruleptr(dioctl.getsetrule.ruleidx)))
return (-EINVAL); return (-EINVAL);
save_flags(flags); spin_lock_irqsave(&divert_lock, flags);
cli();
*rulep = dioctl.getsetrule.rule; /* copy data */ *rulep = dioctl.getsetrule.rule; /* copy data */
restore_flags(flags); spin_unlock_irqrestore(&divert_lock, flags);
return (0); /* no copy required */ return (0); /* no copy required */
break; break;
......
This diff is collapsed.
...@@ -99,7 +99,7 @@ config ISDN_DRV_LOOP ...@@ -99,7 +99,7 @@ config ISDN_DRV_LOOP
config ISDN_DIVERSION config ISDN_DIVERSION
tristate "Support isdn diversion services" tristate "Support isdn diversion services"
depends on BROKEN && BROKEN_ON_SMP depends on ISDN && ISDN_I4L
help help
This option allows you to use some supplementary diversion This option allows you to use some supplementary diversion
services in conjunction with the HiSax driver on an EURO/DSS1 services in conjunction with the HiSax driver on an EURO/DSS1
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment