aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wan
diff options
context:
space:
mode:
authorAlan Cox <alan@lxorguk.ukuu.org.uk>2008-04-30 03:54:13 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-30 11:29:47 -0400
commitf34d7a5b7010b82fe97da95496b9971435530062 (patch)
tree87e2abec1e33ed4fe5e63ee2fd000bc2ad745e57 /drivers/net/wan
parent251b8dd7eee30fda089a1dc088abf4fc9a0dee9c (diff)
tty: The big operations rework
- Operations are now a shared const function block as with most other Linux objects - Introduce wrappers for some optional functions to get consistent behaviour - Wrap put_char which used to be patched by the tty layer - Document which functions are needed/optional - Make put_char report success/fail - Cache the driver->ops pointer in the tty as tty->ops - Remove various surplus lock calls we no longer need - Remove proc_write method as noted by Alexey Dobriyan - Introduce some missing sanity checks where certain driver/ldisc combinations would oops as they didn't check needed methods were present [akpm@linux-foundation.org: fix fs/compat_ioctl.c build] [akpm@linux-foundation.org: fix isicom] [akpm@linux-foundation.org: fix arch/ia64/hp/sim/simserial.c build] [akpm@linux-foundation.org: fix kgdb] Signed-off-by: Alan Cox <alan@redhat.com> Acked-by: Greg Kroah-Hartman <gregkh@suse.de> Cc: Jason Wessel <jason.wessel@windriver.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/net/wan')
-rw-r--r--drivers/net/wan/x25_asy.c279
1 files changed, 135 insertions, 144 deletions
diff --git a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c
index 0f8aca8a4d43..249e18053d5f 100644
--- a/drivers/net/wan/x25_asy.c
+++ b/drivers/net/wan/x25_asy.c
@@ -17,7 +17,7 @@
17#include <linux/module.h> 17#include <linux/module.h>
18 18
19#include <asm/system.h> 19#include <asm/system.h>
20#include <asm/uaccess.h> 20#include <linux/uaccess.h>
21#include <linux/bitops.h> 21#include <linux/bitops.h>
22#include <linux/string.h> 22#include <linux/string.h>
23#include <linux/mm.h> 23#include <linux/mm.h>
@@ -95,7 +95,7 @@ static struct x25_asy *x25_asy_alloc(void)
95 x25_asy_devs[i] = dev; 95 x25_asy_devs[i] = dev;
96 return sl; 96 return sl;
97 } else { 97 } else {
98 printk("x25_asy_alloc() - register_netdev() failure.\n"); 98 printk(KERN_WARNING "x25_asy_alloc() - register_netdev() failure.\n");
99 free_netdev(dev); 99 free_netdev(dev);
100 } 100 }
101 } 101 }
@@ -112,23 +112,22 @@ static void x25_asy_free(struct x25_asy *sl)
112 kfree(sl->xbuff); 112 kfree(sl->xbuff);
113 sl->xbuff = NULL; 113 sl->xbuff = NULL;
114 114
115 if (!test_and_clear_bit(SLF_INUSE, &sl->flags)) { 115 if (!test_and_clear_bit(SLF_INUSE, &sl->flags))
116 printk("%s: x25_asy_free for already free unit.\n", sl->dev->name); 116 printk(KERN_ERR "%s: x25_asy_free for already free unit.\n",
117 } 117 sl->dev->name);
118} 118}
119 119
120static int x25_asy_change_mtu(struct net_device *dev, int newmtu) 120static int x25_asy_change_mtu(struct net_device *dev, int newmtu)
121{ 121{
122 struct x25_asy *sl = dev->priv; 122 struct x25_asy *sl = dev->priv;
123 unsigned char *xbuff, *rbuff; 123 unsigned char *xbuff, *rbuff;
124 int len = 2* newmtu; 124 int len = 2 * newmtu;
125 125
126 xbuff = kmalloc(len + 4, GFP_ATOMIC); 126 xbuff = kmalloc(len + 4, GFP_ATOMIC);
127 rbuff = kmalloc(len + 4, GFP_ATOMIC); 127 rbuff = kmalloc(len + 4, GFP_ATOMIC);
128 128
129 if (xbuff == NULL || rbuff == NULL) 129 if (xbuff == NULL || rbuff == NULL) {
130 { 130 printk(KERN_WARNING "%s: unable to grow X.25 buffers, MTU change cancelled.\n",
131 printk("%s: unable to grow X.25 buffers, MTU change cancelled.\n",
132 dev->name); 131 dev->name);
133 kfree(xbuff); 132 kfree(xbuff);
134 kfree(rbuff); 133 kfree(rbuff);
@@ -193,25 +192,23 @@ static void x25_asy_bump(struct x25_asy *sl)
193 int err; 192 int err;
194 193
195 count = sl->rcount; 194 count = sl->rcount;
196 sl->stats.rx_bytes+=count; 195 sl->stats.rx_bytes += count;
197 196
198 skb = dev_alloc_skb(count+1); 197 skb = dev_alloc_skb(count+1);
199 if (skb == NULL) 198 if (skb == NULL) {
200 { 199 printk(KERN_WARNING "%s: memory squeeze, dropping packet.\n",
201 printk("%s: memory squeeze, dropping packet.\n", sl->dev->name); 200 sl->dev->name);
202 sl->stats.rx_dropped++; 201 sl->stats.rx_dropped++;
203 return; 202 return;
204 } 203 }
205 skb_push(skb,1); /* LAPB internal control */ 204 skb_push(skb, 1); /* LAPB internal control */
206 memcpy(skb_put(skb,count), sl->rbuff, count); 205 memcpy(skb_put(skb, count), sl->rbuff, count);
207 skb->protocol = x25_type_trans(skb, sl->dev); 206 skb->protocol = x25_type_trans(skb, sl->dev);
208 if((err=lapb_data_received(skb->dev, skb))!=LAPB_OK) 207 err = lapb_data_received(skb->dev, skb);
209 { 208 if (err != LAPB_OK) {
210 kfree_skb(skb); 209 kfree_skb(skb);
211 printk(KERN_DEBUG "x25_asy: data received err - %d\n",err); 210 printk(KERN_DEBUG "x25_asy: data received err - %d\n", err);
212 } 211 } else {
213 else
214 {
215 netif_rx(skb); 212 netif_rx(skb);
216 sl->dev->last_rx = jiffies; 213 sl->dev->last_rx = jiffies;
217 sl->stats.rx_packets++; 214 sl->stats.rx_packets++;
@@ -224,10 +221,11 @@ static void x25_asy_encaps(struct x25_asy *sl, unsigned char *icp, int len)
224 unsigned char *p; 221 unsigned char *p;
225 int actual, count, mtu = sl->dev->mtu; 222 int actual, count, mtu = sl->dev->mtu;
226 223
227 if (len > mtu) 224 if (len > mtu) {
228 { /* Sigh, shouldn't occur BUT ... */ 225 /* Sigh, shouldn't occur BUT ... */
229 len = mtu; 226 len = mtu;
230 printk ("%s: truncating oversized transmit packet!\n", sl->dev->name); 227 printk(KERN_DEBUG "%s: truncating oversized transmit packet!\n",
228 sl->dev->name);
231 sl->stats.tx_dropped++; 229 sl->stats.tx_dropped++;
232 x25_asy_unlock(sl); 230 x25_asy_unlock(sl);
233 return; 231 return;
@@ -245,7 +243,7 @@ static void x25_asy_encaps(struct x25_asy *sl, unsigned char *icp, int len)
245 * 14 Oct 1994 Dmitry Gorodchanin. 243 * 14 Oct 1994 Dmitry Gorodchanin.
246 */ 244 */
247 sl->tty->flags |= (1 << TTY_DO_WRITE_WAKEUP); 245 sl->tty->flags |= (1 << TTY_DO_WRITE_WAKEUP);
248 actual = sl->tty->driver->write(sl->tty, sl->xbuff, count); 246 actual = sl->tty->ops->write(sl->tty, sl->xbuff, count);
249 sl->xleft = count - actual; 247 sl->xleft = count - actual;
250 sl->xhead = sl->xbuff + actual; 248 sl->xhead = sl->xbuff + actual;
251 /* VSV */ 249 /* VSV */
@@ -265,8 +263,7 @@ static void x25_asy_write_wakeup(struct tty_struct *tty)
265 if (!sl || sl->magic != X25_ASY_MAGIC || !netif_running(sl->dev)) 263 if (!sl || sl->magic != X25_ASY_MAGIC || !netif_running(sl->dev))
266 return; 264 return;
267 265
268 if (sl->xleft <= 0) 266 if (sl->xleft <= 0) {
269 {
270 /* Now serial buffer is almost free & we can start 267 /* Now serial buffer is almost free & we can start
271 * transmission of another packet */ 268 * transmission of another packet */
272 sl->stats.tx_packets++; 269 sl->stats.tx_packets++;
@@ -275,14 +272,14 @@ static void x25_asy_write_wakeup(struct tty_struct *tty)
275 return; 272 return;
276 } 273 }
277 274
278 actual = tty->driver->write(tty, sl->xhead, sl->xleft); 275 actual = tty->ops->write(tty, sl->xhead, sl->xleft);
279 sl->xleft -= actual; 276 sl->xleft -= actual;
280 sl->xhead += actual; 277 sl->xhead += actual;
281} 278}
282 279
283static void x25_asy_timeout(struct net_device *dev) 280static void x25_asy_timeout(struct net_device *dev)
284{ 281{
285 struct x25_asy *sl = (struct x25_asy*)(dev->priv); 282 struct x25_asy *sl = dev->priv;
286 283
287 spin_lock(&sl->lock); 284 spin_lock(&sl->lock);
288 if (netif_queue_stopped(dev)) { 285 if (netif_queue_stopped(dev)) {
@@ -290,7 +287,7 @@ static void x25_asy_timeout(struct net_device *dev)
290 * 14 Oct 1994 Dmitry Gorodchanin. 287 * 14 Oct 1994 Dmitry Gorodchanin.
291 */ 288 */
292 printk(KERN_WARNING "%s: transmit timed out, %s?\n", dev->name, 289 printk(KERN_WARNING "%s: transmit timed out, %s?\n", dev->name,
293 (sl->tty->driver->chars_in_buffer(sl->tty) || sl->xleft) ? 290 (tty_chars_in_buffer(sl->tty) || sl->xleft) ?
294 "bad line quality" : "driver error"); 291 "bad line quality" : "driver error");
295 sl->xleft = 0; 292 sl->xleft = 0;
296 sl->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP); 293 sl->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
@@ -303,31 +300,34 @@ static void x25_asy_timeout(struct net_device *dev)
303 300
304static int x25_asy_xmit(struct sk_buff *skb, struct net_device *dev) 301static int x25_asy_xmit(struct sk_buff *skb, struct net_device *dev)
305{ 302{
306 struct x25_asy *sl = (struct x25_asy*)(dev->priv); 303 struct x25_asy *sl = dev->priv;
307 int err; 304 int err;
308 305
309 if (!netif_running(sl->dev)) { 306 if (!netif_running(sl->dev)) {
310 printk("%s: xmit call when iface is down\n", dev->name); 307 printk(KERN_ERR "%s: xmit call when iface is down\n",
308 dev->name);
311 kfree_skb(skb); 309 kfree_skb(skb);
312 return 0; 310 return 0;
313 } 311 }
314 312
315 switch(skb->data[0]) 313 switch (skb->data[0]) {
316 { 314 case 0x00:
317 case 0x00:break; 315 break;
318 case 0x01: /* Connection request .. do nothing */ 316 case 0x01: /* Connection request .. do nothing */
319 if((err=lapb_connect_request(dev))!=LAPB_OK) 317 err = lapb_connect_request(dev);
320 printk(KERN_ERR "x25_asy: lapb_connect_request error - %d\n", err); 318 if (err != LAPB_OK)
321 kfree_skb(skb); 319 printk(KERN_ERR "x25_asy: lapb_connect_request error - %d\n", err);
322 return 0; 320 kfree_skb(skb);
323 case 0x02: /* Disconnect request .. do nothing - hang up ?? */ 321 return 0;
324 if((err=lapb_disconnect_request(dev))!=LAPB_OK) 322 case 0x02: /* Disconnect request .. do nothing - hang up ?? */
325 printk(KERN_ERR "x25_asy: lapb_disconnect_request error - %d\n", err); 323 err = lapb_disconnect_request(dev);
326 default: 324 if (err != LAPB_OK)
327 kfree_skb(skb); 325 printk(KERN_ERR "x25_asy: lapb_disconnect_request error - %d\n", err);
328 return 0; 326 default:
327 kfree_skb(skb);
328 return 0;
329 } 329 }
330 skb_pull(skb,1); /* Remove control byte */ 330 skb_pull(skb, 1); /* Remove control byte */
331 /* 331 /*
332 * If we are busy already- too bad. We ought to be able 332 * If we are busy already- too bad. We ought to be able
333 * to queue things at this point, to allow for a little 333 * to queue things at this point, to allow for a little
@@ -338,10 +338,10 @@ static int x25_asy_xmit(struct sk_buff *skb, struct net_device *dev)
338 * So, no queues ! 338 * So, no queues !
339 * 14 Oct 1994 Dmitry Gorodchanin. 339 * 14 Oct 1994 Dmitry Gorodchanin.
340 */ 340 */
341 341
342 if((err=lapb_data_request(dev,skb))!=LAPB_OK) 342 err = lapb_data_request(dev, skb);
343 { 343 if (err != LAPB_OK) {
344 printk(KERN_ERR "lapbeth: lapb_data_request error - %d\n", err); 344 printk(KERN_ERR "x25_asy: lapb_data_request error - %d\n", err);
345 kfree_skb(skb); 345 kfree_skb(skb);
346 return 0; 346 return 0;
347 } 347 }
@@ -357,7 +357,7 @@ static int x25_asy_xmit(struct sk_buff *skb, struct net_device *dev)
357 * Called when I frame data arrives. We did the work above - throw it 357 * Called when I frame data arrives. We did the work above - throw it
358 * at the net layer. 358 * at the net layer.
359 */ 359 */
360 360
361static int x25_asy_data_indication(struct net_device *dev, struct sk_buff *skb) 361static int x25_asy_data_indication(struct net_device *dev, struct sk_buff *skb)
362{ 362{
363 skb->dev->last_rx = jiffies; 363 skb->dev->last_rx = jiffies;
@@ -369,24 +369,22 @@ static int x25_asy_data_indication(struct net_device *dev, struct sk_buff *skb)
369 * busy cases too well. Its tricky to see how to do this nicely - 369 * busy cases too well. Its tricky to see how to do this nicely -
370 * perhaps lapb should allow us to bounce this ? 370 * perhaps lapb should allow us to bounce this ?
371 */ 371 */
372 372
373static void x25_asy_data_transmit(struct net_device *dev, struct sk_buff *skb) 373static void x25_asy_data_transmit(struct net_device *dev, struct sk_buff *skb)
374{ 374{
375 struct x25_asy *sl=dev->priv; 375 struct x25_asy *sl = dev->priv;
376 376
377 spin_lock(&sl->lock); 377 spin_lock(&sl->lock);
378 if (netif_queue_stopped(sl->dev) || sl->tty == NULL) 378 if (netif_queue_stopped(sl->dev) || sl->tty == NULL) {
379 {
380 spin_unlock(&sl->lock); 379 spin_unlock(&sl->lock);
381 printk(KERN_ERR "x25_asy: tbusy drop\n"); 380 printk(KERN_ERR "x25_asy: tbusy drop\n");
382 kfree_skb(skb); 381 kfree_skb(skb);
383 return; 382 return;
384 } 383 }
385 /* We were not busy, so we are now... :-) */ 384 /* We were not busy, so we are now... :-) */
386 if (skb != NULL) 385 if (skb != NULL) {
387 {
388 x25_asy_lock(sl); 386 x25_asy_lock(sl);
389 sl->stats.tx_bytes+=skb->len; 387 sl->stats.tx_bytes += skb->len;
390 x25_asy_encaps(sl, skb->data, skb->len); 388 x25_asy_encaps(sl, skb->data, skb->len);
391 dev_kfree_skb(skb); 389 dev_kfree_skb(skb);
392 } 390 }
@@ -396,15 +394,16 @@ static void x25_asy_data_transmit(struct net_device *dev, struct sk_buff *skb)
396/* 394/*
397 * LAPB connection establish/down information. 395 * LAPB connection establish/down information.
398 */ 396 */
399 397
400static void x25_asy_connected(struct net_device *dev, int reason) 398static void x25_asy_connected(struct net_device *dev, int reason)
401{ 399{
402 struct x25_asy *sl = dev->priv; 400 struct x25_asy *sl = dev->priv;
403 struct sk_buff *skb; 401 struct sk_buff *skb;
404 unsigned char *ptr; 402 unsigned char *ptr;
405 403
406 if ((skb = dev_alloc_skb(1)) == NULL) { 404 skb = dev_alloc_skb(1);
407 printk(KERN_ERR "lapbeth: out of memory\n"); 405 if (skb == NULL) {
406 printk(KERN_ERR "x25_asy: out of memory\n");
408 return; 407 return;
409 } 408 }
410 409
@@ -422,7 +421,8 @@ static void x25_asy_disconnected(struct net_device *dev, int reason)
422 struct sk_buff *skb; 421 struct sk_buff *skb;
423 unsigned char *ptr; 422 unsigned char *ptr;
424 423
425 if ((skb = dev_alloc_skb(1)) == NULL) { 424 skb = dev_alloc_skb(1);
425 if (skb == NULL) {
426 printk(KERN_ERR "x25_asy: out of memory\n"); 426 printk(KERN_ERR "x25_asy: out of memory\n");
427 return; 427 return;
428 } 428 }
@@ -449,7 +449,7 @@ static struct lapb_register_struct x25_asy_callbacks = {
449/* Open the low-level part of the X.25 channel. Easy! */ 449/* Open the low-level part of the X.25 channel. Easy! */
450static int x25_asy_open(struct net_device *dev) 450static int x25_asy_open(struct net_device *dev)
451{ 451{
452 struct x25_asy *sl = (struct x25_asy*)(dev->priv); 452 struct x25_asy *sl = dev->priv;
453 unsigned long len; 453 unsigned long len;
454 int err; 454 int err;
455 455
@@ -466,13 +466,11 @@ static int x25_asy_open(struct net_device *dev)
466 len = dev->mtu * 2; 466 len = dev->mtu * 2;
467 467
468 sl->rbuff = kmalloc(len + 4, GFP_KERNEL); 468 sl->rbuff = kmalloc(len + 4, GFP_KERNEL);
469 if (sl->rbuff == NULL) { 469 if (sl->rbuff == NULL)
470 goto norbuff; 470 goto norbuff;
471 }
472 sl->xbuff = kmalloc(len + 4, GFP_KERNEL); 471 sl->xbuff = kmalloc(len + 4, GFP_KERNEL);
473 if (sl->xbuff == NULL) { 472 if (sl->xbuff == NULL)
474 goto noxbuff; 473 goto noxbuff;
475 }
476 474
477 sl->buffsize = len; 475 sl->buffsize = len;
478 sl->rcount = 0; 476 sl->rcount = 0;
@@ -480,11 +478,12 @@ static int x25_asy_open(struct net_device *dev)
480 sl->flags &= (1 << SLF_INUSE); /* Clear ESCAPE & ERROR flags */ 478 sl->flags &= (1 << SLF_INUSE); /* Clear ESCAPE & ERROR flags */
481 479
482 netif_start_queue(dev); 480 netif_start_queue(dev);
483 481
484 /* 482 /*
485 * Now attach LAPB 483 * Now attach LAPB
486 */ 484 */
487 if((err=lapb_register(dev, &x25_asy_callbacks))==LAPB_OK) 485 err = lapb_register(dev, &x25_asy_callbacks);
486 if (err == LAPB_OK)
488 return 0; 487 return 0;
489 488
490 /* Cleanup */ 489 /* Cleanup */
@@ -499,18 +498,20 @@ norbuff:
499/* Close the low-level part of the X.25 channel. Easy! */ 498/* Close the low-level part of the X.25 channel. Easy! */
500static int x25_asy_close(struct net_device *dev) 499static int x25_asy_close(struct net_device *dev)
501{ 500{
502 struct x25_asy *sl = (struct x25_asy*)(dev->priv); 501 struct x25_asy *sl = dev->priv;
503 int err; 502 int err;
504 503
505 spin_lock(&sl->lock); 504 spin_lock(&sl->lock);
506 if (sl->tty) 505 if (sl->tty)
507 sl->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP); 506 sl->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
508 507
509 netif_stop_queue(dev); 508 netif_stop_queue(dev);
510 sl->rcount = 0; 509 sl->rcount = 0;
511 sl->xleft = 0; 510 sl->xleft = 0;
512 if((err=lapb_unregister(dev))!=LAPB_OK) 511 err = lapb_unregister(dev);
513 printk(KERN_ERR "x25_asy_close: lapb_unregister error -%d\n",err); 512 if (err != LAPB_OK)
513 printk(KERN_ERR "x25_asy_close: lapb_unregister error -%d\n",
514 err);
514 spin_unlock(&sl->lock); 515 spin_unlock(&sl->lock);
515 return 0; 516 return 0;
516} 517}
@@ -521,8 +522,9 @@ static int x25_asy_close(struct net_device *dev)
521 * a block of X.25 data has been received, which can now be decapsulated 522 * a block of X.25 data has been received, which can now be decapsulated
522 * and sent on to some IP layer for further processing. 523 * and sent on to some IP layer for further processing.
523 */ 524 */
524 525
525static void x25_asy_receive_buf(struct tty_struct *tty, const unsigned char *cp, char *fp, int count) 526static void x25_asy_receive_buf(struct tty_struct *tty,
527 const unsigned char *cp, char *fp, int count)
526{ 528{
527 struct x25_asy *sl = (struct x25_asy *) tty->disc_data; 529 struct x25_asy *sl = (struct x25_asy *) tty->disc_data;
528 530
@@ -533,9 +535,8 @@ static void x25_asy_receive_buf(struct tty_struct *tty, const unsigned char *cp,
533 /* Read the characters out of the buffer */ 535 /* Read the characters out of the buffer */
534 while (count--) { 536 while (count--) {
535 if (fp && *fp++) { 537 if (fp && *fp++) {
536 if (!test_and_set_bit(SLF_ERROR, &sl->flags)) { 538 if (!test_and_set_bit(SLF_ERROR, &sl->flags))
537 sl->stats.rx_errors++; 539 sl->stats.rx_errors++;
538 }
539 cp++; 540 cp++;
540 continue; 541 continue;
541 } 542 }
@@ -556,31 +557,31 @@ static int x25_asy_open_tty(struct tty_struct *tty)
556 struct x25_asy *sl = (struct x25_asy *) tty->disc_data; 557 struct x25_asy *sl = (struct x25_asy *) tty->disc_data;
557 int err; 558 int err;
558 559
560 if (tty->ops->write == NULL)
561 return -EOPNOTSUPP;
562
559 /* First make sure we're not already connected. */ 563 /* First make sure we're not already connected. */
560 if (sl && sl->magic == X25_ASY_MAGIC) { 564 if (sl && sl->magic == X25_ASY_MAGIC)
561 return -EEXIST; 565 return -EEXIST;
562 }
563 566
564 /* OK. Find a free X.25 channel to use. */ 567 /* OK. Find a free X.25 channel to use. */
565 if ((sl = x25_asy_alloc()) == NULL) { 568 sl = x25_asy_alloc();
569 if (sl == NULL)
566 return -ENFILE; 570 return -ENFILE;
567 }
568 571
569 sl->tty = tty; 572 sl->tty = tty;
570 tty->disc_data = sl; 573 tty->disc_data = sl;
571 tty->receive_room = 65536; 574 tty->receive_room = 65536;
572 if (tty->driver->flush_buffer) { 575 tty_driver_flush_buffer(tty);
573 tty->driver->flush_buffer(tty);
574 }
575 tty_ldisc_flush(tty); 576 tty_ldisc_flush(tty);
576 577
577 /* Restore default settings */ 578 /* Restore default settings */
578 sl->dev->type = ARPHRD_X25; 579 sl->dev->type = ARPHRD_X25;
579 580
580 /* Perform the low-level X.25 async init */ 581 /* Perform the low-level X.25 async init */
581 if ((err = x25_asy_open(sl->dev))) 582 err = x25_asy_open(sl->dev);
583 if (err)
582 return err; 584 return err;
583
584 /* Done. We have linked the TTY line to a channel. */ 585 /* Done. We have linked the TTY line to a channel. */
585 return sl->dev->base_addr; 586 return sl->dev->base_addr;
586} 587}
@@ -601,9 +602,7 @@ static void x25_asy_close_tty(struct tty_struct *tty)
601 return; 602 return;
602 603
603 if (sl->dev->flags & IFF_UP) 604 if (sl->dev->flags & IFF_UP)
604 { 605 dev_close(sl->dev);
605 (void) dev_close(sl->dev);
606 }
607 606
608 tty->disc_data = NULL; 607 tty->disc_data = NULL;
609 sl->tty = NULL; 608 sl->tty = NULL;
@@ -613,8 +612,7 @@ static void x25_asy_close_tty(struct tty_struct *tty)
613 612
614static struct net_device_stats *x25_asy_get_stats(struct net_device *dev) 613static struct net_device_stats *x25_asy_get_stats(struct net_device *dev)
615{ 614{
616 struct x25_asy *sl = (struct x25_asy*)(dev->priv); 615 struct x25_asy *sl = dev->priv;
617
618 return &sl->stats; 616 return &sl->stats;
619} 617}
620 618
@@ -641,21 +639,19 @@ int x25_asy_esc(unsigned char *s, unsigned char *d, int len)
641 * character sequence, according to the X.25 protocol. 639 * character sequence, according to the X.25 protocol.
642 */ 640 */
643 641
644 while (len-- > 0) 642 while (len-- > 0) {
645 { 643 switch (c = *s++) {
646 switch(c = *s++) 644 case X25_END:
647 { 645 *ptr++ = X25_ESC;
648 case X25_END: 646 *ptr++ = X25_ESCAPE(X25_END);
649 *ptr++ = X25_ESC; 647 break;
650 *ptr++ = X25_ESCAPE(X25_END); 648 case X25_ESC:
651 break; 649 *ptr++ = X25_ESC;
652 case X25_ESC: 650 *ptr++ = X25_ESCAPE(X25_ESC);
653 *ptr++ = X25_ESC; 651 break;
654 *ptr++ = X25_ESCAPE(X25_ESC); 652 default:
655 break; 653 *ptr++ = c;
656 default: 654 break;
657 *ptr++ = c;
658 break;
659 } 655 }
660 } 656 }
661 *ptr++ = X25_END; 657 *ptr++ = X25_END;
@@ -665,31 +661,25 @@ int x25_asy_esc(unsigned char *s, unsigned char *d, int len)
665static void x25_asy_unesc(struct x25_asy *sl, unsigned char s) 661static void x25_asy_unesc(struct x25_asy *sl, unsigned char s)
666{ 662{
667 663
668 switch(s) 664 switch (s) {
669 { 665 case X25_END:
670 case X25_END: 666 if (!test_and_clear_bit(SLF_ERROR, &sl->flags)
671 if (!test_and_clear_bit(SLF_ERROR, &sl->flags) && (sl->rcount > 2)) 667 && sl->rcount > 2)
672 { 668 x25_asy_bump(sl);
673 x25_asy_bump(sl); 669 clear_bit(SLF_ESCAPE, &sl->flags);
674 } 670 sl->rcount = 0;
675 clear_bit(SLF_ESCAPE, &sl->flags); 671 return;
676 sl->rcount = 0; 672 case X25_ESC:
677 return; 673 set_bit(SLF_ESCAPE, &sl->flags);
678 674 return;
679 case X25_ESC: 675 case X25_ESCAPE(X25_ESC):
680 set_bit(SLF_ESCAPE, &sl->flags); 676 case X25_ESCAPE(X25_END):
681 return; 677 if (test_and_clear_bit(SLF_ESCAPE, &sl->flags))
682 678 s = X25_UNESCAPE(s);
683 case X25_ESCAPE(X25_ESC): 679 break;
684 case X25_ESCAPE(X25_END): 680 }
685 if (test_and_clear_bit(SLF_ESCAPE, &sl->flags)) 681 if (!test_bit(SLF_ERROR, &sl->flags)) {
686 s = X25_UNESCAPE(s); 682 if (sl->rcount < sl->buffsize) {
687 break;
688 }
689 if (!test_bit(SLF_ERROR, &sl->flags))
690 {
691 if (sl->rcount < sl->buffsize)
692 {
693 sl->rbuff[sl->rcount++] = s; 683 sl->rbuff[sl->rcount++] = s;
694 return; 684 return;
695 } 685 }
@@ -709,7 +699,7 @@ static int x25_asy_ioctl(struct tty_struct *tty, struct file *file,
709 if (!sl || sl->magic != X25_ASY_MAGIC) 699 if (!sl || sl->magic != X25_ASY_MAGIC)
710 return -EINVAL; 700 return -EINVAL;
711 701
712 switch(cmd) { 702 switch (cmd) {
713 case SIOCGIFNAME: 703 case SIOCGIFNAME:
714 if (copy_to_user((void __user *)arg, sl->dev->name, 704 if (copy_to_user((void __user *)arg, sl->dev->name,
715 strlen(sl->dev->name) + 1)) 705 strlen(sl->dev->name) + 1))
@@ -724,8 +714,8 @@ static int x25_asy_ioctl(struct tty_struct *tty, struct file *file,
724 714
725static int x25_asy_open_dev(struct net_device *dev) 715static int x25_asy_open_dev(struct net_device *dev)
726{ 716{
727 struct x25_asy *sl = (struct x25_asy*)(dev->priv); 717 struct x25_asy *sl = dev->priv;
728 if(sl->tty==NULL) 718 if (sl->tty == NULL)
729 return -ENODEV; 719 return -ENODEV;
730 return 0; 720 return 0;
731} 721}
@@ -741,9 +731,9 @@ static void x25_asy_setup(struct net_device *dev)
741 set_bit(SLF_INUSE, &sl->flags); 731 set_bit(SLF_INUSE, &sl->flags);
742 732
743 /* 733 /*
744 * Finish setting up the DEVICE info. 734 * Finish setting up the DEVICE info.
745 */ 735 */
746 736
747 dev->mtu = SL_MTU; 737 dev->mtu = SL_MTU;
748 dev->hard_start_xmit = x25_asy_xmit; 738 dev->hard_start_xmit = x25_asy_xmit;
749 dev->tx_timeout = x25_asy_timeout; 739 dev->tx_timeout = x25_asy_timeout;
@@ -778,9 +768,10 @@ static int __init init_x25_asy(void)
778 x25_asy_maxdev = 4; /* Sanity */ 768 x25_asy_maxdev = 4; /* Sanity */
779 769
780 printk(KERN_INFO "X.25 async: version 0.00 ALPHA " 770 printk(KERN_INFO "X.25 async: version 0.00 ALPHA "
781 "(dynamic channels, max=%d).\n", x25_asy_maxdev ); 771 "(dynamic channels, max=%d).\n", x25_asy_maxdev);
782 772
783 x25_asy_devs = kcalloc(x25_asy_maxdev, sizeof(struct net_device*), GFP_KERNEL); 773 x25_asy_devs = kcalloc(x25_asy_maxdev, sizeof(struct net_device *),
774 GFP_KERNEL);
784 if (!x25_asy_devs) { 775 if (!x25_asy_devs) {
785 printk(KERN_WARNING "X25 async: Can't allocate x25_asy_ctrls[] " 776 printk(KERN_WARNING "X25 async: Can't allocate x25_asy_ctrls[] "
786 "array! Uaargh! (-> No X.25 available)\n"); 777 "array! Uaargh! (-> No X.25 available)\n");
@@ -802,7 +793,7 @@ static void __exit exit_x25_asy(void)
802 struct x25_asy *sl = dev->priv; 793 struct x25_asy *sl = dev->priv;
803 794
804 spin_lock_bh(&sl->lock); 795 spin_lock_bh(&sl->lock);
805 if (sl->tty) 796 if (sl->tty)
806 tty_hangup(sl->tty); 797 tty_hangup(sl->tty);
807 798
808 spin_unlock_bh(&sl->lock); 799 spin_unlock_bh(&sl->lock);