]> git.neil.brown.name Git - history.git/commitdiff
ISDN: New timer handling for "+++" escape sequence
authorKai Germaschewski <kai@tp1.ruhr-uni-bochum.de>
Tue, 29 Oct 2002 14:57:04 +0000 (08:57 -0600)
committerKai Germaschewski <kai@tp1.ruhr-uni-bochum.de>
Tue, 29 Oct 2002 14:57:04 +0000 (08:57 -0600)
Instead of having one common timer and walking the list of
all ISDN channels, which might be possibly associated with a
ttyI and even more possibly so waiting for the silence period
after "+++", just use a per ttyI timer, which only gets activated
when necessary.

drivers/isdn/i4l/isdn_common.c
drivers/isdn/i4l/isdn_tty.c
drivers/isdn/i4l/isdn_tty.h
include/linux/isdn.h

index 3a2f833798f01c255b0d4403b603c62f4148b002..238bd997dbde3d37120c44ef9bc54f815df5b09a 100644 (file)
@@ -1163,8 +1163,6 @@ isdn_timer_funct(ulong dummy)
        if (tf & ISDN_TIMER_FAST) {
                if (tf & ISDN_TIMER_MODEMREAD)
                        isdn_tty_readmodem();
-               if (tf & ISDN_TIMER_MODEMPLUS)
-                       isdn_tty_modem_escape();
                if (tf & ISDN_TIMER_MODEMXMIT)
                        isdn_tty_modem_xmit();
        }
@@ -1983,7 +1981,7 @@ isdn_get_free_slot(int usage, int l2_proto, int l3_proto,
        for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
                slot = &slots[i];
 
-               if (drivers[slot->di]->fi.state != ST_DRV_RUNNING)
+               if (!slot->drv || slot->drv->fi.state != ST_DRV_RUNNING)
                        continue;
                
                if (!USG_NONE(slots[i].usage))
index 3a57ba4fa2c0536eb516b813b38ae561aa0ad71e..5635c9ff3658d9b0608fa71a8739fc6e67e35143 100644 (file)
@@ -26,7 +26,9 @@
 /* Prototypes */
 
 static int isdn_tty_edit_at(const char *, int, modem_info *, int);
-static void isdn_tty_check_esc(const u_char *, u_char, int, int *, int *, int);
+static void isdn_tty_escape_timer(unsigned long data);
+static void isdn_tty_check_esc(struct modem_info *info, 
+                              const unsigned char *p, int count);
 static void isdn_tty_modem_reset_regs(modem_info *, int);
 static void isdn_tty_cmd_ATA(modem_info *);
 static void isdn_tty_flush_buffer(struct tty_struct *);
@@ -1228,13 +1230,6 @@ isdn_tty_write(struct tty_struct *tty, int from_user, const u_char * buf, int co
                    || (info->vonline & 3)
 #endif
                        ) {
-#ifdef CONFIG_ISDN_AUDIO
-                       if (!info->vonline)
-#endif
-                               isdn_tty_check_esc(buf, m->mdmreg[REG_ESC], c,
-                                                  &(m->pluscount),
-                                                  &(m->lastplus),
-                                                  from_user);
                        if (from_user) {
                                if (copy_from_user(&(info->xmit_buf[info->xmit_count]), buf, c)) {
                                        total = -EFAULT;
@@ -1242,6 +1237,10 @@ isdn_tty_write(struct tty_struct *tty, int from_user, const u_char * buf, int co
                                }
                        } else
                                memcpy(&(info->xmit_buf[info->xmit_count]), buf, c);
+#ifdef CONFIG_ISDN_AUDIO
+                       if (!info->vonline)
+#endif
+                               isdn_tty_check_esc(info, &info->xmit_buf[info->xmit_count], c);
 #ifdef CONFIG_ISDN_AUDIO
                        if (info->vonline) {
                                int cc = isdn_tty_handleDLEdown(info, m, c);
@@ -2131,6 +2130,9 @@ isdn_tty_init(void)
                init_waitqueue_head(&info->open_wait);
                init_waitqueue_head(&info->close_wait);
                info->isdn_slot = NULL;
+               init_timer(&info->escape_timer);
+               info->escape_timer.data = (unsigned long) info;
+               info->escape_timer.function = isdn_tty_escape_timer;
                skb_queue_head_init(&info->rpqueue);
                info->xmit_size = ISDN_SERIAL_XMIT_SIZE;
                skb_queue_head_init(&info->xmit_queue);
@@ -2595,55 +2597,56 @@ isdn_tty_off_hook(void)
 #define PLUSWAIT1 (HZ/2)        /* 0.5 sec. */
 #define PLUSWAIT2 (HZ*3/2)      /* 1.5 sec */
 
+static void
+isdn_tty_escape_timer(unsigned long data)
+{
+       struct modem_info *info = (struct modem_info *) data;
+
+       if (!info->online)
+               return;
+       
+       info->emu.pluscount = 0;
+       info->online = 0;
+       isdn_tty_modem_result(RESULT_OK, info);
+}
+
 /*
  * Check Buffer for Modem-escape-sequence, activate timer-callback to
  * isdn_tty_modem_escape() if sequence found.
- *
- * Parameters:
- *   p          pointer to databuffer
- *   plus       escape-character
- *   count      length of buffer
- *   pluscount  count of valid escape-characters so far
- *   lastplus   timestamp of last character
  */
-static void
-isdn_tty_check_esc(const u_char * p, u_char plus, int count, int *pluscount,
-                  int *lastplus, int from_user)
+static void isdn_tty_check_esc(struct modem_info *info, 
+                              const unsigned char *p, int count)
 {
-       char cbuf[3];
+       unsigned char plus = info->emu.mdmreg[REG_ESC];
 
        if (plus > 127)
                return;
+
        if (count > 3) {
                p += count - 3;
                count = 3;
-               *pluscount = 0;
+               info->emu.pluscount = 0;
+               info->emu.lastplus = jiffies;
        }
-       if (from_user) {
-               if (copy_from_user(cbuf, p, count))
-                       return;
-               p = cbuf;
-       }
-       while (count > 0) {
-               if (*(p++) == plus) {
-                       if ((*pluscount)++) {
-                               /* Time since last '+' > 0.5 sec. ? */
-                               if (time_after(jiffies, *lastplus + PLUSWAIT1))
-                                       *pluscount = 1;
-                       } else {
-                               /* Time since last non-'+' < 1.5 sec. ? */
-                               if (time_before(jiffies, *lastplus + PLUSWAIT2))
-                                       *pluscount = 0;
-                       }
-                       if ((*pluscount == 3) && (count == 1))
-                               isdn_timer_ctrl(ISDN_TIMER_MODEMPLUS, 1);
-                       if (*pluscount > 3)
-                               *pluscount = 1;
-               } else
-                       *pluscount = 0;
-               *lastplus = jiffies;
-               count--;
+       for (; count > 0; info->emu.lastplus = jiffies, count--) {
+               if (*(p++) != plus) {
+                       info->emu.pluscount = 0;
+                       continue;
+               }
+               if (info->emu.pluscount == 0) {
+                       if (time_after(jiffies, info->emu.lastplus + PLUSWAIT2))
+                               info->emu.pluscount = 1;
+               } else {
+                       if (time_after(jiffies, info->emu.lastplus + PLUSWAIT1))
+                               info->emu.pluscount = 1;
+                       else
+                               info->emu.pluscount++;
+               }
        }
+       if (info->emu.pluscount == 3)
+               mod_timer(&info->escape_timer, jiffies + PLUSWAIT2);
+       else
+               del_timer(&info->escape_timer);
 }
 
 /*
@@ -3977,36 +3980,6 @@ isdn_tty_edit_at(const char *p, int count, modem_info * info, int user)
        return total;
 }
 
-/*
- * Switch all modem-channels who are online and got a valid
- * escape-sequence 1.5 seconds ago, to command-mode.
- * This function is called every second via timer-interrupt from within
- * timer-dispatcher isdn_timer_function()
- */
-void
-isdn_tty_modem_escape(void)
-{
-       int ton = 0;
-       int i;
-       int midx;
-
-       for (i = 0; i < ISDN_MAX_CHANNELS; i++)
-               if (USG_MODEM(isdn_slot_usage(i)))
-                       if ((midx = isdn_slot_m_idx(i)) >= 0) {
-                               modem_info *info = &isdn_mdm.info[midx];
-                               if (info->online) {
-                                       ton = 1;
-                                       if ((info->emu.pluscount == 3) &&
-                                           time_after(jiffies , info->emu.lastplus + PLUSWAIT2)) {
-                                               info->emu.pluscount = 0;
-                                               info->online = 0;
-                                               isdn_tty_modem_result(RESULT_OK, info);
-                                       }
-                               }
-                       }
-       isdn_timer_ctrl(ISDN_TIMER_MODEMPLUS, ton);
-}
-
 /*
  * Put a RING-message to all modem-channels who have the RI-bit set.
  * This function is called every second via timer-interrupt from within
index 060302c6a589de2496f01e3304fb6dfceaf08c76..d0f53375bb54e028daa85d457e9d6ab0fe1cd71c 100644 (file)
@@ -98,7 +98,6 @@
        ((info->emu.mdmreg[REG_L2PROT] == ISDN_PROTO_L2_FAX) && \
         (info->emu.mdmreg[REG_L3PROT] == ISDN_PROTO_L3_FCLASS2))
 
-extern void isdn_tty_modem_escape(void);
 extern void isdn_tty_modem_ring(void);
 extern void isdn_tty_carrier_timeout(void);
 extern void isdn_tty_modem_xmit(void);
index c5352e5d1194d8185e093d710d3f6e8c7fe7f496..a9067e07e325ba321980a4f59b830319216390f2 100644 (file)
@@ -242,12 +242,10 @@ typedef struct {
 #define ISDN_TIMER_RINGING     5 /* tty RINGs = ISDN_TIMER_1SEC * this factor       */
 #define ISDN_TIMER_KEEPINT    10 /* Cisco-Keepalive = ISDN_TIMER_1SEC * this factor */
 #define ISDN_TIMER_MODEMREAD   1
-#define ISDN_TIMER_MODEMPLUS   2
 #define ISDN_TIMER_MODEMRING   4
 #define ISDN_TIMER_MODEMXMIT   8
 #define ISDN_TIMER_CARRIER   256 /* Wait for Carrier */
-#define ISDN_TIMER_FAST      (ISDN_TIMER_MODEMREAD | ISDN_TIMER_MODEMPLUS | \
-                              ISDN_TIMER_MODEMXMIT)
+#define ISDN_TIMER_FAST      (ISDN_TIMER_MODEMREAD | ISDN_TIMER_MODEMXMIT)
 #define ISDN_TIMER_SLOW      (ISDN_TIMER_MODEMRING | ISDN_TIMER_CARRIER)
 
 /* GLOBAL_FLAGS */
@@ -363,6 +361,7 @@ typedef struct modem_info {
 #endif
   struct tty_struct    *tty;            /* Pointer to corresponding tty   */
   atemu                 emu;             /* AT-emulator data               */
+  struct timer_list     escape_timer;    /* to recognize +++ escape        */
   struct termios       normal_termios;  /* For saving termios structs     */
   struct termios       callout_termios;
   wait_queue_head_t    open_wait, close_wait;