#include <linux/version.h>
#include <linux/proc_fs.h>
+
#include "isdn_divert.h"
/**********************************/
static struct deflect_struc *table_tail = NULL;
static unsigned char extern_wait_max = 4; /* maximum wait in s for external process */
+DEFINE_SPINLOCK(divert_lock);
+
/***************************/
/* timer callback function */
/***************************/
static void deflect_timer_expire(ulong arg)
-{ unsigned long flags;
+{
+ unsigned long flags;
struct call_struc *cs = (struct call_struc *) arg;
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&divert_lock, flags);
del_timer(&cs->timer); /* delete active timer */
- restore_flags(flags);
+ spin_unlock_irqrestore(&divert_lock, flags);
switch(cs->akt_state)
{ case DEFLECT_PROCEED:
cs->ics.command = ISDN_CMD_HANGUP; /* cancel action */
divert_if.ll_cmd(&cs->ics);
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&divert_lock, flags);
cs->akt_state = DEFLECT_AUTODEL; /* delete after timeout */
cs->timer.expires = jiffies + (HZ * AUTODEL_TIME);
add_timer(&cs->timer);
- restore_flags(flags);
+ spin_unlock_irqrestore(&divert_lock, flags);
break;
case DEFLECT_ALERT:
cs->ics.command = ISDN_CMD_REDIR; /* protocol */
strcpy(cs->ics.parm.setup.phone,cs->deflect_dest);
strcpy(cs->ics.parm.setup.eazmsn,"Testtext delayed");
- divert_if.ll_cmd(&cs->ics);
- save_flags(flags);
- cli();
+ divert_if.ll_cmd(&cs->ics);
+ spin_lock_irqsave(&divert_lock, flags);
cs->akt_state = DEFLECT_AUTODEL; /* delete after timeout */
cs->timer.expires = jiffies + (HZ * AUTODEL_TIME);
add_timer(&cs->timer);
- restore_flags(flags);
+ spin_unlock_irqrestore(&divert_lock, flags);
break;
case DEFLECT_AUTODEL:
default:
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&divert_lock, flags);
if (cs->prev)
cs->prev->next = cs->next; /* forward link */
else
divert_head = cs->next;
if (cs->next)
cs->next->prev = cs->prev; /* back link */
- restore_flags(flags);
+ spin_unlock_irqrestore(&divert_lock, flags);
kfree(cs);
return;
cs->ics.parm.dss1_io.datalen = p - tmp; /* total len */
cs->ics.parm.dss1_io.data = tmp; /* start of buffer */
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&divert_lock, flags);
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;
sprintf(cs->info,"%d 0x%lx %s%s 0 %s %02x %d%s%s\n",
if (!retval)
{ cs->prev = NULL;
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&divert_lock, flags);
cs->next = divert_head;
divert_head = cs;
- restore_flags(flags);
+ spin_unlock_irqrestore(&divert_lock, flags);
}
else
kfree(cs);
{ case 0: /* hangup */
del_timer(&cs->timer);
ic.command = ISDN_CMD_HANGUP;
- i = divert_if.ll_cmd(&ic);
- save_flags(flags);
- cli();
+ i = divert_if.ll_cmd(&ic);
+ spin_lock_irqsave(&divert_lock, flags);
cs->akt_state = DEFLECT_AUTODEL; /* delete after timeout */
cs->timer.expires = jiffies + (HZ * AUTODEL_TIME);
add_timer(&cs->timer);
- restore_flags(flags);
+ spin_unlock_irqrestore(&divert_lock, flags);
break;
case 1: /* alert */
del_timer(&cs->timer);
ic.command = ISDN_CMD_ALERT;
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->timer.expires = jiffies + (HZ * AUTODEL_TIME);
add_timer(&cs->timer);
- restore_flags(flags);
+ spin_unlock_irqrestore(&divert_lock, flags);
}
else
cs->akt_state = DEFLECT_ALERT;
strcpy(cs->ics.parm.setup.eazmsn, "Testtext manual");
ic.command = ISDN_CMD_REDIR;
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->timer.expires = jiffies + (HZ * AUTODEL_TIME);
add_timer(&cs->timer);
- restore_flags(flags);
+ spin_unlock_irqrestore(&divert_lock, flags);
}
else
cs->akt_state = DEFLECT_ALERT;
ds->rule = *newrule; /* set rule */
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&divert_lock, flags);
if (idx >= 0)
{ ds1 = table_head;
table_head = ds; /* first element */
}
- restore_flags(flags);
+ spin_unlock_irqrestore(&divert_lock, flags);
return(0);
} /* insertrule */
unsigned long flags;
if (idx < 0)
- { save_flags(flags);
- cli();
+ { spin_lock_irqsave(&divert_lock, flags);
ds = table_head;
table_head = NULL;
table_tail = NULL;
- restore_flags(flags);
+ spin_unlock_irqrestore(&divert_lock, flags);
while (ds)
{ ds1 = ds;
ds = ds->next;
return(0);
}
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&divert_lock, flags);
ds = table_head;
while ((ds) && (idx > 0))
}
if (!ds)
- { restore_flags(flags);
+ {
+ spin_unlock_irqrestore(&divert_lock, flags);
return(-EINVAL);
}
else
table_head = ds->next; /* start of chain */
- restore_flags(flags);
+ spin_unlock_irqrestore(&divert_lock, flags);
kfree(ds);
return(0);
} /* deleterule */
else
cs->timer.expires = 0;
cs->akt_state = dv->rule.action;
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&divert_lock, flags);
cs->divert_id = next_id++; /* new sequence number */
- restore_flags(flags);
+ spin_unlock_irqrestore(&divert_lock, flags);
cs->prev = NULL;
if (cs->akt_state == DEFLECT_ALERT)
{ strcpy(cs->deflect_dest,dv->rule.to_nr);
if (cs)
{ cs->prev = NULL;
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&divert_lock, flags);
cs->next = divert_head;
divert_head = cs;
if (cs->timer.expires) add_timer(&cs->timer);
- restore_flags(flags);
+ spin_unlock_irqrestore(&divert_lock, flags);
put_info_buffer(cs->info);
return(retval);
{ struct call_struc *cs, *cs1;
unsigned long flags;
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&divert_lock, flags);
cs = divert_head;
divert_head = NULL;
while (cs)
cs = cs->next;
kfree(cs1);
}
- restore_flags(flags);
+ spin_unlock_irqrestore(&divert_lock, flags);
} /* deleteprocs */
/****************************************************/
}
if (cs1->ics.driver == -1)
- { save_flags(flags);
- cli();
+ {
+ spin_lock_irqsave(&divert_lock, flags);
del_timer(&cs1->timer);
if (cs1->prev)
cs1->prev->next = cs1->next; /* forward link */
divert_head = cs1->next;
if (cs1->next)
cs1->next->prev = cs1->prev; /* back link */
- restore_flags(flags);
+ spin_unlock_irqrestore(&divert_lock, flags);
kfree(cs1);
}
cs = cs->next;
if (cs1->ics.driver == -1)
{
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&divert_lock, flags);
if (cs1->prev)
cs1->prev->next = cs1->next; /* forward link */
else
divert_head = cs1->next;
if (cs1->next)
cs1->next->prev = cs1->prev; /* back link */
- restore_flags(flags);
+ spin_unlock_irqrestore(&divert_lock, flags);
kfree(cs1);
}
}