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;
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include <linux/version.h> #include <linux/version.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include "isdn_divert.h" #include "isdn_divert.h"
/**********************************/ /**********************************/
...@@ -51,24 +52,24 @@ static unsigned char extern_wait_max = 4; /* maximum wait in s for external proc ...@@ -51,24 +52,24 @@ static unsigned char extern_wait_max = 4; /* maximum wait in s for external proc
/* timer callback function */ /* timer callback function */
/***************************/ /***************************/
static void deflect_timer_expire(ulong arg) static void deflect_timer_expire(ulong arg)
{ unsigned long flags; {
unsigned long flags;
spinlock_t divert_lock = SPIN_LOCK_UNLOCKED;
struct call_struc *cs = (struct call_struc *) arg; struct call_struc *cs = (struct call_struc *) arg;
save_flags(flags); spin_lock_irqsave(&divert_lock, flags);
cli();
del_timer(&cs->timer); /* delete active timer */ del_timer(&cs->timer); /* delete active timer */
restore_flags(flags); spin_unlock_irqrestore(&divert_lock, flags);
switch(cs->akt_state) switch(cs->akt_state)
{ case DEFLECT_PROCEED: { case DEFLECT_PROCEED:
cs->ics.command = ISDN_CMD_HANGUP; /* cancel action */ cs->ics.command = ISDN_CMD_HANGUP; /* cancel action */
divert_if.ll_cmd(&cs->ics); divert_if.ll_cmd(&cs->ics);
save_flags(flags); spin_lock_irqsave(&divert_lock, flags);
cli();
cs->akt_state = DEFLECT_AUTODEL; /* delete after timeout */ cs->akt_state = DEFLECT_AUTODEL; /* delete after timeout */
cs->timer.expires = jiffies + (HZ * AUTODEL_TIME); cs->timer.expires = jiffies + (HZ * AUTODEL_TIME);
add_timer(&cs->timer); add_timer(&cs->timer);
restore_flags(flags); spin_unlock_irqrestore(&divert_lock, flags);
break; break;
case DEFLECT_ALERT: case DEFLECT_ALERT:
...@@ -76,25 +77,23 @@ static void deflect_timer_expire(ulong arg) ...@@ -76,25 +77,23 @@ static void deflect_timer_expire(ulong arg)
strcpy(cs->ics.parm.setup.phone,cs->deflect_dest); strcpy(cs->ics.parm.setup.phone,cs->deflect_dest);
strcpy(cs->ics.parm.setup.eazmsn,"Testtext delayed"); strcpy(cs->ics.parm.setup.eazmsn,"Testtext delayed");
divert_if.ll_cmd(&cs->ics); divert_if.ll_cmd(&cs->ics);
save_flags(flags); spin_lock_irqsave(&divert_lock, flags);
cli();
cs->akt_state = DEFLECT_AUTODEL; /* delete after timeout */ cs->akt_state = DEFLECT_AUTODEL; /* delete after timeout */
cs->timer.expires = jiffies + (HZ * AUTODEL_TIME); cs->timer.expires = jiffies + (HZ * AUTODEL_TIME);
add_timer(&cs->timer); add_timer(&cs->timer);
restore_flags(flags); spin_unlock_irqrestore(&divert_lock, flags);
break; break;
case DEFLECT_AUTODEL: case DEFLECT_AUTODEL:
default: default:
save_flags(flags); spin_lock_irqsave(&divert_lock, flags);
cli();
if (cs->prev) if (cs->prev)
cs->prev->next = cs->next; /* forward link */ cs->prev->next = cs->next; /* forward link */
else else
divert_head = cs->next; divert_head = cs->next;
if (cs->next) if (cs->next)
cs->next->prev = cs->prev; /* back link */ cs->next->prev = cs->prev; /* back link */
restore_flags(flags); spin_unlock_irqrestore(&divert_lock, flags);
kfree(cs); kfree(cs);
return; return;
...@@ -110,6 +109,7 @@ int cf_command(int drvid, int mode, ...@@ -110,6 +109,7 @@ int cf_command(int drvid, int mode,
u_char proc, char *msn, u_char proc, char *msn,
u_char service, char *fwd_nr, ulong *procid) u_char service, char *fwd_nr, ulong *procid)
{ unsigned long flags; { unsigned long flags;
spinlock_t divert_lock = SPIN_LOCK_UNLOCKED;
int retval,msnlen; int retval,msnlen;
int fwd_len; int fwd_len;
char *p,*ielenp,tmp[60]; char *p,*ielenp,tmp[60];
...@@ -166,10 +166,9 @@ int cf_command(int drvid, int mode, ...@@ -166,10 +166,9 @@ int cf_command(int drvid, int mode,
cs->ics.parm.dss1_io.datalen = p - tmp; /* total len */ cs->ics.parm.dss1_io.datalen = p - tmp; /* total len */
cs->ics.parm.dss1_io.data = tmp; /* start of buffer */ cs->ics.parm.dss1_io.data = tmp; /* start of buffer */
save_flags(flags); spin_lock_irqsave(&divert_lock, flags);
cli();
cs->ics.parm.dss1_io.ll_id = next_id++; /* id for callback */ cs->ics.parm.dss1_io.ll_id = next_id++; /* id for callback */
restore_flags(flags); spin_unlock_irqrestore(&divert_lock, flags);
*procid = cs->ics.parm.dss1_io.ll_id; *procid = cs->ics.parm.dss1_io.ll_id;
sprintf(cs->info,"%d 0x%lx %s%s 0 %s %02x %d%s%s\n", sprintf(cs->info,"%d 0x%lx %s%s 0 %s %02x %d%s%s\n",
...@@ -187,11 +186,10 @@ int cf_command(int drvid, int mode, ...@@ -187,11 +186,10 @@ int cf_command(int drvid, int mode,
if (!retval) if (!retval)
{ cs->prev = NULL; { cs->prev = NULL;
save_flags(flags); spin_lock_irqsave(&divert_lock, flags);
cli();
cs->next = divert_head; cs->next = divert_head;
divert_head = cs; divert_head = cs;
restore_flags(flags); spin_unlock_irqrestore(&divert_lock, flags);
} }
else else
kfree(cs); kfree(cs);
...@@ -206,6 +204,7 @@ int deflect_extern_action(u_char cmd, ulong callid, char *to_nr) ...@@ -206,6 +204,7 @@ int deflect_extern_action(u_char cmd, ulong callid, char *to_nr)
{ struct call_struc *cs; { struct call_struc *cs;
isdn_ctrl ic; isdn_ctrl ic;
unsigned long flags; unsigned long flags;
spinlock_t divert_lock = SPIN_LOCK_UNLOCKED;
int i; int i;
if ((cmd & 0x7F) > 2) return(-EINVAL); /* invalid command */ if ((cmd & 0x7F) > 2) return(-EINVAL); /* invalid command */
...@@ -225,12 +224,11 @@ int deflect_extern_action(u_char cmd, ulong callid, char *to_nr) ...@@ -225,12 +224,11 @@ int deflect_extern_action(u_char cmd, ulong callid, char *to_nr)
del_timer(&cs->timer); del_timer(&cs->timer);
ic.command = ISDN_CMD_HANGUP; ic.command = ISDN_CMD_HANGUP;
i = divert_if.ll_cmd(&ic); i = divert_if.ll_cmd(&ic);
save_flags(flags); spin_lock_irqsave(&divert_lock, flags);
cli();
cs->akt_state = DEFLECT_AUTODEL; /* delete after timeout */ cs->akt_state = DEFLECT_AUTODEL; /* delete after timeout */
cs->timer.expires = jiffies + (HZ * AUTODEL_TIME); cs->timer.expires = jiffies + (HZ * AUTODEL_TIME);
add_timer(&cs->timer); add_timer(&cs->timer);
restore_flags(flags); spin_unlock_irqrestore(&divert_lock, flags);
break; break;
case 1: /* alert */ case 1: /* alert */
...@@ -239,12 +237,12 @@ int deflect_extern_action(u_char cmd, ulong callid, char *to_nr) ...@@ -239,12 +237,12 @@ int deflect_extern_action(u_char cmd, ulong callid, char *to_nr)
del_timer(&cs->timer); del_timer(&cs->timer);
ic.command = ISDN_CMD_ALERT; ic.command = ISDN_CMD_ALERT;
if ((i = divert_if.ll_cmd(&ic))) if ((i = divert_if.ll_cmd(&ic)))
{ save_flags(flags); {
cli(); spin_lock_irqsave(&divert_lock, flags);
cs->akt_state = DEFLECT_AUTODEL; /* delete after timeout */ cs->akt_state = DEFLECT_AUTODEL; /* delete after timeout */
cs->timer.expires = jiffies + (HZ * AUTODEL_TIME); cs->timer.expires = jiffies + (HZ * AUTODEL_TIME);
add_timer(&cs->timer); add_timer(&cs->timer);
restore_flags(flags); spin_unlock_irqrestore(&divert_lock, flags);
} }
else else
cs->akt_state = DEFLECT_ALERT; cs->akt_state = DEFLECT_ALERT;
...@@ -256,12 +254,12 @@ int deflect_extern_action(u_char cmd, ulong callid, char *to_nr) ...@@ -256,12 +254,12 @@ int deflect_extern_action(u_char cmd, ulong callid, char *to_nr)
strcpy(cs->ics.parm.setup.eazmsn, "Testtext manual"); strcpy(cs->ics.parm.setup.eazmsn, "Testtext manual");
ic.command = ISDN_CMD_REDIR; ic.command = ISDN_CMD_REDIR;
if ((i = divert_if.ll_cmd(&ic))) if ((i = divert_if.ll_cmd(&ic)))
{ save_flags(flags); {
cli(); spin_lock_irqsave(&divert_lock, flags);
cs->akt_state = DEFLECT_AUTODEL; /* delete after timeout */ cs->akt_state = DEFLECT_AUTODEL; /* delete after timeout */
cs->timer.expires = jiffies + (HZ * AUTODEL_TIME); cs->timer.expires = jiffies + (HZ * AUTODEL_TIME);
add_timer(&cs->timer); add_timer(&cs->timer);
restore_flags(flags); spin_unlock_irqrestore(&divert_lock, flags);
} }
else else
cs->akt_state = DEFLECT_ALERT; cs->akt_state = DEFLECT_ALERT;
...@@ -277,6 +275,7 @@ int deflect_extern_action(u_char cmd, ulong callid, char *to_nr) ...@@ -277,6 +275,7 @@ int deflect_extern_action(u_char cmd, ulong callid, char *to_nr)
int insertrule(int idx, divert_rule *newrule) int insertrule(int idx, divert_rule *newrule)
{ struct deflect_struc *ds,*ds1=NULL; { struct deflect_struc *ds,*ds1=NULL;
unsigned long flags; unsigned long flags;
spinlock_t divert_lock = SPIN_LOCK_UNLOCKED;
if (!(ds = (struct deflect_struc *) kmalloc(sizeof(struct deflect_struc), if (!(ds = (struct deflect_struc *) kmalloc(sizeof(struct deflect_struc),
GFP_KERNEL))) GFP_KERNEL)))
...@@ -284,8 +283,7 @@ int insertrule(int idx, divert_rule *newrule) ...@@ -284,8 +283,7 @@ int insertrule(int idx, divert_rule *newrule)
ds->rule = *newrule; /* set rule */ ds->rule = *newrule; /* set rule */
save_flags(flags); spin_lock_irqsave(&divert_lock, flags);
cli();
if (idx >= 0) if (idx >= 0)
{ ds1 = table_head; { ds1 = table_head;
...@@ -313,7 +311,7 @@ int insertrule(int idx, divert_rule *newrule) ...@@ -313,7 +311,7 @@ int insertrule(int idx, divert_rule *newrule)
table_head = ds; /* first element */ table_head = ds; /* first element */
} }
restore_flags(flags); spin_unlock_irqrestore(&divert_lock, flags);
return(0); return(0);
} /* insertrule */ } /* insertrule */
...@@ -323,14 +321,14 @@ int insertrule(int idx, divert_rule *newrule) ...@@ -323,14 +321,14 @@ int insertrule(int idx, divert_rule *newrule)
int deleterule(int idx) int deleterule(int idx)
{ struct deflect_struc *ds,*ds1; { struct deflect_struc *ds,*ds1;
unsigned long flags; unsigned long flags;
spinlock_t divert_lock = SPIN_LOCK_UNLOCKED;
if (idx < 0) if (idx < 0)
{ save_flags(flags); { spin_lock_irqsave(&divert_lock, flags);
cli();
ds = table_head; ds = table_head;
table_head = NULL; table_head = NULL;
table_tail = NULL; table_tail = NULL;
restore_flags(flags); spin_unlock_irqrestore(&divert_lock, flags);
while (ds) while (ds)
{ ds1 = ds; { ds1 = ds;
ds = ds->next; ds = ds->next;
...@@ -339,8 +337,7 @@ int deleterule(int idx) ...@@ -339,8 +337,7 @@ int deleterule(int idx)
return(0); return(0);
} }
save_flags(flags); spin_lock_irqsave(&divert_lock, flags);
cli();
ds = table_head; ds = table_head;
while ((ds) && (idx > 0)) while ((ds) && (idx > 0))
...@@ -349,7 +346,8 @@ int deleterule(int idx) ...@@ -349,7 +346,8 @@ int deleterule(int idx)
} }
if (!ds) if (!ds)
{ restore_flags(flags); {
spin_unlock_irqrestore(&divert_lock, flags);
return(-EINVAL); return(-EINVAL);
} }
...@@ -363,7 +361,7 @@ int deleterule(int idx) ...@@ -363,7 +361,7 @@ int deleterule(int idx)
else else
table_head = ds->next; /* start of chain */ table_head = ds->next; /* start of chain */
restore_flags(flags); spin_unlock_irqrestore(&divert_lock, flags);
kfree(ds); kfree(ds);
return(0); return(0);
} /* deleterule */ } /* deleterule */
...@@ -391,6 +389,7 @@ divert_rule *getruleptr(int idx) ...@@ -391,6 +389,7 @@ divert_rule *getruleptr(int idx)
int isdn_divert_icall(isdn_ctrl *ic) int isdn_divert_icall(isdn_ctrl *ic)
{ int retval = 0; { int retval = 0;
unsigned long flags; unsigned long flags;
spinlock_t divert_lock = SPIN_LOCK_UNLOCKED;
struct call_struc *cs = NULL; struct call_struc *cs = NULL;
struct deflect_struc *dv; struct deflect_struc *dv;
char *p,*p1; char *p,*p1;
...@@ -474,10 +473,9 @@ int isdn_divert_icall(isdn_ctrl *ic) ...@@ -474,10 +473,9 @@ int isdn_divert_icall(isdn_ctrl *ic)
else else
cs->timer.expires = 0; cs->timer.expires = 0;
cs->akt_state = dv->rule.action; cs->akt_state = dv->rule.action;
save_flags(flags); spin_lock_irqsave(&divert_lock, flags);
cli();
cs->divert_id = next_id++; /* new sequence number */ cs->divert_id = next_id++; /* new sequence number */
restore_flags(flags); spin_unlock_irqrestore(&divert_lock, flags);
cs->prev = NULL; cs->prev = NULL;
if (cs->akt_state == DEFLECT_ALERT) if (cs->akt_state == DEFLECT_ALERT)
{ strcpy(cs->deflect_dest,dv->rule.to_nr); { strcpy(cs->deflect_dest,dv->rule.to_nr);
...@@ -525,12 +523,11 @@ int isdn_divert_icall(isdn_ctrl *ic) ...@@ -525,12 +523,11 @@ int isdn_divert_icall(isdn_ctrl *ic)
if (cs) if (cs)
{ cs->prev = NULL; { cs->prev = NULL;
save_flags(flags); spin_lock_irqsave(&divert_lock, flags);
cli();
cs->next = divert_head; cs->next = divert_head;
divert_head = cs; divert_head = cs;
if (cs->timer.expires) add_timer(&cs->timer); if (cs->timer.expires) add_timer(&cs->timer);
restore_flags(flags); spin_unlock_irqrestore(&divert_lock, flags);
put_info_buffer(cs->info); put_info_buffer(cs->info);
return(retval); return(retval);
...@@ -543,9 +540,9 @@ int isdn_divert_icall(isdn_ctrl *ic) ...@@ -543,9 +540,9 @@ int isdn_divert_icall(isdn_ctrl *ic)
void deleteprocs(void) void deleteprocs(void)
{ struct call_struc *cs, *cs1; { struct call_struc *cs, *cs1;
unsigned long flags; unsigned long flags;
spinlock_t divert_lock = SPIN_LOCK_UNLOCKED;
save_flags(flags); spin_lock_irqsave(&divert_lock, flags);
cli();
cs = divert_head; cs = divert_head;
divert_head = NULL; divert_head = NULL;
while (cs) while (cs)
...@@ -554,7 +551,7 @@ void deleteprocs(void) ...@@ -554,7 +551,7 @@ void deleteprocs(void)
cs = cs->next; cs = cs->next;
kfree(cs1); kfree(cs1);
} }
restore_flags(flags); spin_unlock_irqrestore(&divert_lock, flags);
} /* deleteprocs */ } /* deleteprocs */
/****************************************************/ /****************************************************/
...@@ -701,6 +698,7 @@ int prot_stat_callback(isdn_ctrl *ic) ...@@ -701,6 +698,7 @@ int prot_stat_callback(isdn_ctrl *ic)
{ struct call_struc *cs, *cs1; { struct call_struc *cs, *cs1;
int i; int i;
unsigned long flags; unsigned long flags;
spinlock_t divert_lock = SPIN_LOCK_UNLOCKED;
cs = divert_head; /* start of list */ cs = divert_head; /* start of list */
cs1 = NULL; cs1 = NULL;
...@@ -769,8 +767,8 @@ int prot_stat_callback(isdn_ctrl *ic) ...@@ -769,8 +767,8 @@ int prot_stat_callback(isdn_ctrl *ic)
} }
if (cs1->ics.driver == -1) if (cs1->ics.driver == -1)
{ save_flags(flags); {
cli(); spin_lock_irqsave(&divert_lock, flags);
del_timer(&cs1->timer); del_timer(&cs1->timer);
if (cs1->prev) if (cs1->prev)
cs1->prev->next = cs1->next; /* forward link */ cs1->prev->next = cs1->next; /* forward link */
...@@ -778,7 +776,7 @@ int prot_stat_callback(isdn_ctrl *ic) ...@@ -778,7 +776,7 @@ int prot_stat_callback(isdn_ctrl *ic)
divert_head = cs1->next; divert_head = cs1->next;
if (cs1->next) if (cs1->next)
cs1->next->prev = cs1->prev; /* back link */ cs1->next->prev = cs1->prev; /* back link */
restore_flags(flags); spin_unlock_irqrestore(&divert_lock, flags);
kfree(cs1); kfree(cs1);
} }
...@@ -792,6 +790,7 @@ int prot_stat_callback(isdn_ctrl *ic) ...@@ -792,6 +790,7 @@ int prot_stat_callback(isdn_ctrl *ic)
int isdn_divert_stat_callback(isdn_ctrl *ic) int isdn_divert_stat_callback(isdn_ctrl *ic)
{ struct call_struc *cs, *cs1; { struct call_struc *cs, *cs1;
unsigned long flags; unsigned long flags;
spinlock_t divert_lock = SPIN_LOCK_UNLOCKED;
int retval; int retval;
retval = -1; retval = -1;
...@@ -826,15 +825,14 @@ int isdn_divert_stat_callback(isdn_ctrl *ic) ...@@ -826,15 +825,14 @@ int isdn_divert_stat_callback(isdn_ctrl *ic)
cs = cs->next; cs = cs->next;
if (cs1->ics.driver == -1) if (cs1->ics.driver == -1)
{ {
save_flags(flags); spin_lock_irqsave(&divert_lock, flags);
cli();
if (cs1->prev) if (cs1->prev)
cs1->prev->next = cs1->next; /* forward link */ cs1->prev->next = cs1->next; /* forward link */
else else
divert_head = cs1->next; divert_head = cs1->next;
if (cs1->next) if (cs1->next)
cs1->next->prev = cs1->prev; /* back link */ cs1->next->prev = cs1->prev; /* back link */
restore_flags(flags); spin_unlock_irqrestore(&divert_lock, flags);
kfree(cs1); kfree(cs1);
} }
} }
......
...@@ -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