Commit e6926b12 authored by Kai Germaschewski's avatar Kai Germaschewski

ISDN: New timer handling for read timer

Again, use a per ttyI timer handler to feed arrived data into the
ttyI. Really, there shouldn't be the need for any timer at all,
rather working flow control, but that'll take a bit to fix.
parent 942e6612
......@@ -506,7 +506,7 @@ isdn_audio_goertzel(int *sample, modem_info * info)
((sk2 * sk2) >> AMP_BITS);
}
skb_queue_tail(&info->dtmf_queue, skb);
isdn_timer_ctrl(ISDN_TIMER_MODEMREAD, 1);
mod_timer(&info->read_timer, jiffies + 4);
}
void
......@@ -565,7 +565,7 @@ isdn_audio_eval_dtmf(modem_info * info)
restore_flags(flags);
/* Schedule dequeuing */
if ((dev->modempoll) && (info->rcvsched))
isdn_timer_ctrl(ISDN_TIMER_MODEMREAD, 1);
mod_timer(&info->read_timer, jiffies + 4);
} else
kfree_skb(skb);
s->last = what;
......@@ -680,7 +680,7 @@ isdn_audio_put_dle_code(modem_info * info, u_char code)
restore_flags(flags);
/* Schedule dequeuing */
if ((dev->modempoll) && (info->rcvsched))
isdn_timer_ctrl(ISDN_TIMER_MODEMREAD, 1);
mod_timer(&info->read_timer, jiffies + 4);
}
void
......
......@@ -1153,43 +1153,6 @@ isdn_dc2minor(int di, int ch)
return -1;
}
static void
isdn_timer_funct(ulong dummy)
{
int tf = dev->tflags;
if (tf & ISDN_TIMER_FAST) {
if (tf & ISDN_TIMER_MODEMREAD)
isdn_tty_readmodem();
}
if (tf)
{
unsigned long flags;
save_flags(flags);
cli();
mod_timer(&dev->timer, jiffies+ISDN_TIMER_RES);
restore_flags(flags);
}
}
void
isdn_timer_ctrl(int tf, int onoff)
{
unsigned long flags;
int old_tflags;
save_flags(flags);
cli();
old_tflags = dev->tflags;
if (onoff)
dev->tflags |= tf;
else
dev->tflags &= ~tf;
if (dev->tflags && !old_tflags)
mod_timer(&dev->timer, jiffies+ISDN_TIMER_RES);
restore_flags(flags);
}
static int
__drv_command(struct isdn_driver *drv, isdn_ctrl *c)
{
......@@ -2366,8 +2329,6 @@ static int __init isdn_init(void)
goto err_drv_fsm;
}
memset(dev, 0, sizeof(*dev));
init_timer(&dev->timer);
dev->timer.function = isdn_timer_funct;
init_MUTEX(&dev->sem);
init_waitqueue_head(&dev->info_waitq);
for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
......@@ -2435,7 +2396,6 @@ static void __exit isdn_exit(void)
isdn_tty_exit();
unregister_chrdev(ISDN_MAJOR, "isdn");
isdn_cleanup_devfs();
del_timer_sync(&dev->timer);
vfree(dev);
fsm_free(&drv_fsm);
fsm_free(&slot_fsm);
......
......@@ -60,7 +60,6 @@ extern void isdn_unlock_drivers(void);
extern void isdn_free_channel(int di, int ch, int usage);
extern void isdn_info_update(void);
extern char *isdn_map_eaz2msn(char *msn, int di);
extern void isdn_timer_ctrl(int tf, int onoff);
extern int isdn_getnum(char **);
extern int isdn_msncmp( const char *, const char *);
#if defined(ISDN_DEBUG_NET_DUMP) || defined(ISDN_DEBUG_MODEM_DUMP)
......
......@@ -229,61 +229,53 @@ isdn_tty_readbchan(struct modem_info *info, u_char * buf, u_char * fp, int len)
* It tries getting received data from the receive queue an stuff it into
* the tty's flip-buffer.
*/
void
isdn_tty_readmodem(void)
static void
isdn_tty_readmodem(unsigned long data)
{
int resched = 0;
int midx;
int i;
struct modem_info *info = (struct modem_info *) data;
int c;
int r;
ulong flags;
struct tty_struct *tty;
modem_info *info;
for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
if ((midx = isdn_slot_m_idx(i)) >= 0) {
info = &isdn_mdm.info[midx];
if (info->online) {
r = 0;
if (!info->online)
return;
r = 0;
#ifdef CONFIG_ISDN_AUDIO
isdn_audio_eval_dtmf(info);
if ((info->vonline & 1) && (info->emu.vpar[1]))
isdn_audio_eval_silence(info);
#endif
if ((tty = info->tty)) {
if (info->mcr & UART_MCR_RTS) {
c = TTY_FLIPBUF_SIZE - tty->flip.count;
if (c > 0) {
save_flags(flags);
cli();
r = isdn_tty_readbchan(info,
tty->flip.char_buf_ptr,
tty->flip.flag_buf_ptr, c);
/* CISCO AsyncPPP Hack */
if (!(info->emu.mdmreg[REG_CPPP] & BIT_CPPP))
memset(tty->flip.flag_buf_ptr, 0, r);
tty->flip.count += r;
tty->flip.flag_buf_ptr += r;
tty->flip.char_buf_ptr += r;
if (r)
schedule_delayed_work(&tty->flip.work, 1);
restore_flags(flags);
}
} else
r = 1;
} else
r = 1;
if (r) {
info->rcvsched = 0;
resched = 1;
} else
info->rcvsched = 1;
isdn_audio_eval_dtmf(info);
if ((info->vonline & 1) && (info->emu.vpar[1]))
isdn_audio_eval_silence(info);
#endif
if ((tty = info->tty)) {
if (info->mcr & UART_MCR_RTS) {
c = TTY_FLIPBUF_SIZE - tty->flip.count;
if (c > 0) {
save_flags(flags);
cli();
r = isdn_tty_readbchan(info,
tty->flip.char_buf_ptr,
tty->flip.flag_buf_ptr, c);
/* CISCO AsyncPPP Hack */
if (!(info->emu.mdmreg[REG_CPPP] & BIT_CPPP))
memset(tty->flip.flag_buf_ptr, 0, r);
tty->flip.count += r;
tty->flip.flag_buf_ptr += r;
tty->flip.char_buf_ptr += r;
if (r)
schedule_delayed_work(&tty->flip.work, 1);
restore_flags(flags);
}
}
}
if (!resched)
isdn_timer_ctrl(ISDN_TIMER_MODEMREAD, 0);
} else
r = 1;
} else
r = 1;
if (r) {
info->rcvsched = 0;
mod_timer(&info->read_timer, jiffies + 4);
} else
info->rcvsched = 1;
}
static int
......@@ -393,8 +385,8 @@ isdn_tty_rcv_skb(struct isdn_slot *slot, struct sk_buff *skb)
);
restore_flags(flags);
/* Schedule dequeuing */
if ((dev->modempoll) && (info->rcvsched))
isdn_timer_ctrl(ISDN_TIMER_MODEMREAD, 1);
if (dev->modempoll && info->rcvsched)
mod_timer(&info->read_timer, jiffies + 4);
return 1;
}
......@@ -2138,6 +2130,9 @@ isdn_tty_init(void)
init_timer(&info->connect_timer);
info->connect_timer.data = (unsigned long) info;
info->connect_timer.function = isdn_tty_connect_timer;
init_timer(&info->read_timer);
info->read_timer.data = (unsigned long) info;
info->read_timer.function = isdn_tty_readmodem;
skb_queue_head_init(&info->rpqueue);
info->xmit_size = ISDN_SERIAL_XMIT_SIZE;
skb_queue_head_init(&info->xmit_queue);
......@@ -2570,9 +2565,8 @@ isdn_tty_at_cout(char *msg, modem_info * info)
isdn_tty_queue_tail(info, skb, skb->len);
restore_flags(flags);
/* Schedule dequeuing */
if ((dev->modempoll) && (info->rcvsched))
isdn_timer_ctrl(ISDN_TIMER_MODEMREAD, 1);
if (dev->modempoll && info->rcvsched)
mod_timer(&info->read_timer, jiffies + 4);
} else {
restore_flags(flags);
schedule_delayed_work(&tty->flip.work, 1);
......
......@@ -99,7 +99,6 @@
(info->emu.mdmreg[REG_L3PROT] == ISDN_PROTO_L3_FCLASS2))
extern int isdn_tty_init(void);
extern void isdn_tty_readmodem(void);
extern int isdn_tty_find_icall(struct isdn_slot *slot, setup_parm *setup);
extern void isdn_tty_cleanup_xmit(modem_info *);
extern int isdn_tty_capi_facility(capi_msg *cm);
......
......@@ -235,11 +235,6 @@ typedef struct {
#define USG_MODEMORVOICE(x) (((x & ISDN_USAGE_MASK)==ISDN_USAGE_MODEM) || \
((x & ISDN_USAGE_MASK)==ISDN_USAGE_VOICE) )
/* Timer-delays and scheduling-flags */
#define ISDN_TIMER_RES 4 /* Main Timer-Resolution */
#define ISDN_TIMER_MODEMREAD 1
#define ISDN_TIMER_FAST (ISDN_TIMER_MODEMREAD)
/* GLOBAL_FLAGS */
#define ISDN_GLOBAL_STOPPED 1
......@@ -355,6 +350,7 @@ typedef struct modem_info {
struct timer_list escape_timer; /* to recognize +++ escape */
struct timer_list ring_timer; /* for writing 'RING' responses */
struct timer_list connect_timer; /* waiting for CONNECT */
struct timer_list read_timer; /* read incoming data */
struct termios normal_termios; /* For saving termios structs */
struct termios callout_termios;
wait_queue_head_t open_wait, close_wait;
......@@ -409,7 +405,6 @@ typedef struct isdn_devt {
int global_flags;
infostruct *infochain; /* List of open info-devs. */
wait_queue_head_t info_waitq; /* Wait-Queue for isdninfo */
struct timer_list timer; /* Misc.-function Timer */
struct task_struct *profd; /* For iprofd */
struct semaphore sem; /* serialize list access*/
unsigned long global_features;
......
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