diff options
Diffstat (limited to 'drivers/isdn/i4l/isdn_tty.c')
-rw-r--r-- | drivers/isdn/i4l/isdn_tty.c | 75 |
1 files changed, 36 insertions, 39 deletions
diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c index 8c404b4e2482..f190a99604f0 100644 --- a/drivers/isdn/i4l/isdn_tty.c +++ b/drivers/isdn/i4l/isdn_tty.c | |||
@@ -64,37 +64,42 @@ isdn_tty_try_read(modem_info * info, struct sk_buff *skb) | |||
64 | int c; | 64 | int c; |
65 | int len; | 65 | int len; |
66 | struct tty_struct *tty; | 66 | struct tty_struct *tty; |
67 | char last; | ||
67 | 68 | ||
68 | if (info->online) { | 69 | if (info->online) { |
69 | if ((tty = info->tty)) { | 70 | if ((tty = info->tty)) { |
70 | if (info->mcr & UART_MCR_RTS) { | 71 | if (info->mcr & UART_MCR_RTS) { |
71 | c = TTY_FLIPBUF_SIZE - tty->flip.count; | ||
72 | len = skb->len | 72 | len = skb->len |
73 | #ifdef CONFIG_ISDN_AUDIO | 73 | #ifdef CONFIG_ISDN_AUDIO |
74 | + ISDN_AUDIO_SKB_DLECOUNT(skb) | 74 | + ISDN_AUDIO_SKB_DLECOUNT(skb) |
75 | #endif | 75 | #endif |
76 | ; | 76 | ; |
77 | |||
78 | c = tty_buffer_request_room(tty, len); | ||
77 | if (c >= len) { | 79 | if (c >= len) { |
78 | #ifdef CONFIG_ISDN_AUDIO | 80 | #ifdef CONFIG_ISDN_AUDIO |
79 | if (ISDN_AUDIO_SKB_DLECOUNT(skb)) | 81 | if (ISDN_AUDIO_SKB_DLECOUNT(skb)) { |
80 | while (skb->len--) { | 82 | int l = skb->len; |
83 | unsigned char *dp = skb->data; | ||
84 | while (--l) { | ||
81 | if (*skb->data == DLE) | 85 | if (*skb->data == DLE) |
82 | tty_insert_flip_char(tty, DLE, 0); | 86 | tty_insert_flip_char(tty, DLE, 0); |
83 | tty_insert_flip_char(tty, *skb->data++, 0); | 87 | tty_insert_flip_char(tty, *dp++, 0); |
88 | } | ||
89 | last = *dp; | ||
84 | } else { | 90 | } else { |
85 | #endif | 91 | #endif |
86 | memcpy(tty->flip.char_buf_ptr, | 92 | if(len > 1) |
87 | skb->data, len); | 93 | tty_insert_flip_string(tty, skb->data, len - 1); |
88 | tty->flip.count += len; | 94 | last = skb->data[len - 1]; |
89 | tty->flip.char_buf_ptr += len; | ||
90 | memset(tty->flip.flag_buf_ptr, 0, len); | ||
91 | tty->flip.flag_buf_ptr += len; | ||
92 | #ifdef CONFIG_ISDN_AUDIO | 95 | #ifdef CONFIG_ISDN_AUDIO |
93 | } | 96 | } |
94 | #endif | 97 | #endif |
95 | if (info->emu.mdmreg[REG_CPPP] & BIT_CPPP) | 98 | if (info->emu.mdmreg[REG_CPPP] & BIT_CPPP) |
96 | tty->flip.flag_buf_ptr[len - 1] = 0xff; | 99 | tty_insert_flip_char(tty, last, 0xFF); |
97 | schedule_delayed_work(&tty->flip.work, 1); | 100 | else |
101 | tty_insert_flip_char(tty, last, TTY_NORMAL); | ||
102 | tty_flip_buffer_push(tty); | ||
98 | kfree_skb(skb); | 103 | kfree_skb(skb); |
99 | return 1; | 104 | return 1; |
100 | } | 105 | } |
@@ -114,7 +119,6 @@ isdn_tty_readmodem(void) | |||
114 | int resched = 0; | 119 | int resched = 0; |
115 | int midx; | 120 | int midx; |
116 | int i; | 121 | int i; |
117 | int c; | ||
118 | int r; | 122 | int r; |
119 | struct tty_struct *tty; | 123 | struct tty_struct *tty; |
120 | modem_info *info; | 124 | modem_info *info; |
@@ -131,20 +135,13 @@ isdn_tty_readmodem(void) | |||
131 | #endif | 135 | #endif |
132 | if ((tty = info->tty)) { | 136 | if ((tty = info->tty)) { |
133 | if (info->mcr & UART_MCR_RTS) { | 137 | if (info->mcr & UART_MCR_RTS) { |
134 | c = TTY_FLIPBUF_SIZE - tty->flip.count; | 138 | /* CISCO AsyncPPP Hack */ |
135 | if (c > 0) { | 139 | if (!(info->emu.mdmreg[REG_CPPP] & BIT_CPPP)) |
136 | r = isdn_readbchan(info->isdn_driver, info->isdn_channel, | 140 | r = isdn_readbchan_tty(info->isdn_driver, info->isdn_channel, tty, 0); |
137 | tty->flip.char_buf_ptr, | 141 | else |
138 | tty->flip.flag_buf_ptr, c, NULL); | 142 | r = isdn_readbchan_tty(info->isdn_driver, info->isdn_channel, tty, 1); |
139 | /* CISCO AsyncPPP Hack */ | 143 | if (r) |
140 | if (!(info->emu.mdmreg[REG_CPPP] & BIT_CPPP)) | 144 | tty_flip_buffer_push(tty); |
141 | memset(tty->flip.flag_buf_ptr, 0, r); | ||
142 | tty->flip.count += r; | ||
143 | tty->flip.flag_buf_ptr += r; | ||
144 | tty->flip.char_buf_ptr += r; | ||
145 | if (r) | ||
146 | schedule_delayed_work(&tty->flip.work, 1); | ||
147 | } | ||
148 | } else | 145 | } else |
149 | r = 1; | 146 | r = 1; |
150 | } else | 147 | } else |
@@ -249,7 +246,7 @@ isdn_tty_rcv_skb(int i, int di, int channel, struct sk_buff *skb) | |||
249 | } | 246 | } |
250 | #endif | 247 | #endif |
251 | #endif | 248 | #endif |
252 | /* Try to deliver directly via tty-flip-buf if queue is empty */ | 249 | /* Try to deliver directly via tty-buf if queue is empty */ |
253 | spin_lock_irqsave(&info->readlock, flags); | 250 | spin_lock_irqsave(&info->readlock, flags); |
254 | if (skb_queue_empty(&dev->drv[di]->rpqueue[channel])) | 251 | if (skb_queue_empty(&dev->drv[di]->rpqueue[channel])) |
255 | if (isdn_tty_try_read(info, skb)) { | 252 | if (isdn_tty_try_read(info, skb)) { |
@@ -534,7 +531,7 @@ isdn_tty_senddown(modem_info * info) | |||
534 | /* The next routine is called once from within timer-interrupt | 531 | /* The next routine is called once from within timer-interrupt |
535 | * triggered within isdn_tty_modem_ncarrier(). It calls | 532 | * triggered within isdn_tty_modem_ncarrier(). It calls |
536 | * isdn_tty_modem_result() to stuff a "NO CARRIER" Message | 533 | * isdn_tty_modem_result() to stuff a "NO CARRIER" Message |
537 | * into the tty's flip-buffer. | 534 | * into the tty's buffer. |
538 | */ | 535 | */ |
539 | static void | 536 | static void |
540 | isdn_tty_modem_do_ncarrier(unsigned long data) | 537 | isdn_tty_modem_do_ncarrier(unsigned long data) |
@@ -2347,6 +2344,7 @@ isdn_tty_at_cout(char *msg, modem_info * info) | |||
2347 | u_long flags; | 2344 | u_long flags; |
2348 | struct sk_buff *skb = NULL; | 2345 | struct sk_buff *skb = NULL; |
2349 | char *sp = NULL; | 2346 | char *sp = NULL; |
2347 | int l = strlen(msg); | ||
2350 | 2348 | ||
2351 | if (!msg) { | 2349 | if (!msg) { |
2352 | printk(KERN_WARNING "isdn_tty: Null-Message in isdn_tty_at_cout\n"); | 2350 | printk(KERN_WARNING "isdn_tty: Null-Message in isdn_tty_at_cout\n"); |
@@ -2359,16 +2357,16 @@ isdn_tty_at_cout(char *msg, modem_info * info) | |||
2359 | return; | 2357 | return; |
2360 | } | 2358 | } |
2361 | 2359 | ||
2362 | /* use queue instead of direct flip, if online and */ | 2360 | /* use queue instead of direct, if online and */ |
2363 | /* data is in queue or flip buffer is full */ | 2361 | /* data is in queue or buffer is full */ |
2364 | if ((info->online) && (((tty->flip.count + strlen(msg)) >= TTY_FLIPBUF_SIZE) || | 2362 | if ((info->online && tty_buffer_request_room(tty, l) < l) || |
2365 | (!skb_queue_empty(&dev->drv[info->isdn_driver]->rpqueue[info->isdn_channel])))) { | 2363 | (!skb_queue_empty(&dev->drv[info->isdn_driver]->rpqueue[info->isdn_channel]))) { |
2366 | skb = alloc_skb(strlen(msg), GFP_ATOMIC); | 2364 | skb = alloc_skb(l, GFP_ATOMIC); |
2367 | if (!skb) { | 2365 | if (!skb) { |
2368 | spin_unlock_irqrestore(&info->readlock, flags); | 2366 | spin_unlock_irqrestore(&info->readlock, flags); |
2369 | return; | 2367 | return; |
2370 | } | 2368 | } |
2371 | sp = skb_put(skb, strlen(msg)); | 2369 | sp = skb_put(skb, l); |
2372 | #ifdef CONFIG_ISDN_AUDIO | 2370 | #ifdef CONFIG_ISDN_AUDIO |
2373 | ISDN_AUDIO_SKB_DLECOUNT(skb) = 0; | 2371 | ISDN_AUDIO_SKB_DLECOUNT(skb) = 0; |
2374 | ISDN_AUDIO_SKB_LOCK(skb) = 0; | 2372 | ISDN_AUDIO_SKB_LOCK(skb) = 0; |
@@ -2392,9 +2390,8 @@ isdn_tty_at_cout(char *msg, modem_info * info) | |||
2392 | if (skb) { | 2390 | if (skb) { |
2393 | *sp++ = c; | 2391 | *sp++ = c; |
2394 | } else { | 2392 | } else { |
2395 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) | 2393 | if(tty_insert_flip_char(tty, c, TTY_NORMAL) == 0) |
2396 | break; | 2394 | break; |
2397 | tty_insert_flip_char(tty, c, 0); | ||
2398 | } | 2395 | } |
2399 | } | 2396 | } |
2400 | if (skb) { | 2397 | if (skb) { |
@@ -2402,12 +2399,12 @@ isdn_tty_at_cout(char *msg, modem_info * info) | |||
2402 | dev->drv[info->isdn_driver]->rcvcount[info->isdn_channel] += skb->len; | 2399 | dev->drv[info->isdn_driver]->rcvcount[info->isdn_channel] += skb->len; |
2403 | spin_unlock_irqrestore(&info->readlock, flags); | 2400 | spin_unlock_irqrestore(&info->readlock, flags); |
2404 | /* Schedule dequeuing */ | 2401 | /* Schedule dequeuing */ |
2405 | if ((dev->modempoll) && (info->rcvsched)) | 2402 | if (dev->modempoll && info->rcvsched) |
2406 | isdn_timer_ctrl(ISDN_TIMER_MODEMREAD, 1); | 2403 | isdn_timer_ctrl(ISDN_TIMER_MODEMREAD, 1); |
2407 | 2404 | ||
2408 | } else { | 2405 | } else { |
2409 | spin_unlock_irqrestore(&info->readlock, flags); | 2406 | spin_unlock_irqrestore(&info->readlock, flags); |
2410 | schedule_delayed_work(&tty->flip.work, 1); | 2407 | tty_flip_buffer_push(tty); |
2411 | } | 2408 | } |
2412 | } | 2409 | } |
2413 | 2410 | ||