root/drivers/net/wan/x25_asy.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. x25_asy_alloc
  2. x25_asy_free
  3. x25_asy_change_mtu
  4. x25_asy_lock
  5. x25_asy_unlock
  6. x25_asy_bump
  7. x25_asy_encaps
  8. x25_asy_write_wakeup
  9. x25_asy_timeout
  10. x25_asy_xmit
  11. x25_asy_data_indication
  12. x25_asy_data_transmit
  13. x25_asy_connected
  14. x25_asy_disconnected
  15. x25_asy_open
  16. x25_asy_close
  17. x25_asy_receive_buf
  18. x25_asy_open_tty
  19. x25_asy_close_tty
  20. x25_asy_esc
  21. x25_asy_unesc
  22. x25_asy_ioctl
  23. x25_asy_open_dev
  24. x25_asy_setup
  25. init_x25_asy
  26. exit_x25_asy

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  *      Things to sort out:
   4  *
   5  *      o       tbusy handling
   6  *      o       allow users to set the parameters
   7  *      o       sync/async switching ?
   8  *
   9  *      Note: This does _not_ implement CCITT X.25 asynchronous framing
  10  *      recommendations. Its primarily for testing purposes. If you wanted
  11  *      to do CCITT then in theory all you need is to nick the HDLC async
  12  *      checksum routines from ppp.c
  13  *      Changes:
  14  *
  15  *      2000-10-29      Henner Eisen    lapb_data_indication() return status.
  16  */
  17 
  18 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  19 
  20 #include <linux/module.h>
  21 
  22 #include <linux/uaccess.h>
  23 #include <linux/bitops.h>
  24 #include <linux/string.h>
  25 #include <linux/mm.h>
  26 #include <linux/interrupt.h>
  27 #include <linux/in.h>
  28 #include <linux/tty.h>
  29 #include <linux/errno.h>
  30 #include <linux/netdevice.h>
  31 #include <linux/etherdevice.h>
  32 #include <linux/skbuff.h>
  33 #include <linux/if_arp.h>
  34 #include <linux/lapb.h>
  35 #include <linux/init.h>
  36 #include <linux/rtnetlink.h>
  37 #include <linux/slab.h>
  38 #include <net/x25device.h>
  39 #include "x25_asy.h"
  40 
  41 static struct net_device **x25_asy_devs;
  42 static int x25_asy_maxdev = SL_NRUNIT;
  43 
  44 module_param(x25_asy_maxdev, int, 0);
  45 MODULE_LICENSE("GPL");
  46 
  47 static int x25_asy_esc(unsigned char *p, unsigned char *d, int len);
  48 static void x25_asy_unesc(struct x25_asy *sl, unsigned char c);
  49 static void x25_asy_setup(struct net_device *dev);
  50 
  51 /* Find a free X.25 channel, and link in this `tty' line. */
  52 static struct x25_asy *x25_asy_alloc(void)
  53 {
  54         struct net_device *dev = NULL;
  55         struct x25_asy *sl;
  56         int i;
  57 
  58         if (x25_asy_devs == NULL)
  59                 return NULL;    /* Master array missing ! */
  60 
  61         for (i = 0; i < x25_asy_maxdev; i++) {
  62                 dev = x25_asy_devs[i];
  63 
  64                 /* Not allocated ? */
  65                 if (dev == NULL)
  66                         break;
  67 
  68                 sl = netdev_priv(dev);
  69                 /* Not in use ? */
  70                 if (!test_and_set_bit(SLF_INUSE, &sl->flags))
  71                         return sl;
  72         }
  73 
  74 
  75         /* Sorry, too many, all slots in use */
  76         if (i >= x25_asy_maxdev)
  77                 return NULL;
  78 
  79         /* If no channels are available, allocate one */
  80         if (!dev) {
  81                 char name[IFNAMSIZ];
  82                 sprintf(name, "x25asy%d", i);
  83 
  84                 dev = alloc_netdev(sizeof(struct x25_asy), name,
  85                                    NET_NAME_UNKNOWN, x25_asy_setup);
  86                 if (!dev)
  87                         return NULL;
  88 
  89                 /* Initialize channel control data */
  90                 sl = netdev_priv(dev);
  91                 dev->base_addr    = i;
  92 
  93                 /* register device so that it can be ifconfig'ed       */
  94                 if (register_netdev(dev) == 0) {
  95                         /* (Re-)Set the INUSE bit.   Very Important! */
  96                         set_bit(SLF_INUSE, &sl->flags);
  97                         x25_asy_devs[i] = dev;
  98                         return sl;
  99                 } else {
 100                         pr_warn("%s(): register_netdev() failure\n", __func__);
 101                         free_netdev(dev);
 102                 }
 103         }
 104         return NULL;
 105 }
 106 
 107 
 108 /* Free an X.25 channel. */
 109 static void x25_asy_free(struct x25_asy *sl)
 110 {
 111         /* Free all X.25 frame buffers. */
 112         kfree(sl->rbuff);
 113         sl->rbuff = NULL;
 114         kfree(sl->xbuff);
 115         sl->xbuff = NULL;
 116 
 117         if (!test_and_clear_bit(SLF_INUSE, &sl->flags))
 118                 netdev_err(sl->dev, "x25_asy_free for already free unit\n");
 119 }
 120 
 121 static int x25_asy_change_mtu(struct net_device *dev, int newmtu)
 122 {
 123         struct x25_asy *sl = netdev_priv(dev);
 124         unsigned char *xbuff, *rbuff;
 125         int len;
 126 
 127         len = 2 * newmtu;
 128         xbuff = kmalloc(len + 4, GFP_ATOMIC);
 129         rbuff = kmalloc(len + 4, GFP_ATOMIC);
 130 
 131         if (xbuff == NULL || rbuff == NULL) {
 132                 kfree(xbuff);
 133                 kfree(rbuff);
 134                 return -ENOMEM;
 135         }
 136 
 137         spin_lock_bh(&sl->lock);
 138         xbuff    = xchg(&sl->xbuff, xbuff);
 139         if (sl->xleft)  {
 140                 if (sl->xleft <= len)  {
 141                         memcpy(sl->xbuff, sl->xhead, sl->xleft);
 142                 } else  {
 143                         sl->xleft = 0;
 144                         dev->stats.tx_dropped++;
 145                 }
 146         }
 147         sl->xhead = sl->xbuff;
 148 
 149         rbuff    = xchg(&sl->rbuff, rbuff);
 150         if (sl->rcount)  {
 151                 if (sl->rcount <= len) {
 152                         memcpy(sl->rbuff, rbuff, sl->rcount);
 153                 } else  {
 154                         sl->rcount = 0;
 155                         dev->stats.rx_over_errors++;
 156                         set_bit(SLF_ERROR, &sl->flags);
 157                 }
 158         }
 159 
 160         dev->mtu    = newmtu;
 161         sl->buffsize = len;
 162 
 163         spin_unlock_bh(&sl->lock);
 164 
 165         kfree(xbuff);
 166         kfree(rbuff);
 167         return 0;
 168 }
 169 
 170 
 171 /* Set the "sending" flag.  This must be atomic, hence the ASM. */
 172 
 173 static inline void x25_asy_lock(struct x25_asy *sl)
 174 {
 175         netif_stop_queue(sl->dev);
 176 }
 177 
 178 
 179 /* Clear the "sending" flag.  This must be atomic, hence the ASM. */
 180 
 181 static inline void x25_asy_unlock(struct x25_asy *sl)
 182 {
 183         netif_wake_queue(sl->dev);
 184 }
 185 
 186 /* Send one completely decapsulated IP datagram to the IP layer. */
 187 
 188 static void x25_asy_bump(struct x25_asy *sl)
 189 {
 190         struct net_device *dev = sl->dev;
 191         struct sk_buff *skb;
 192         int count;
 193         int err;
 194 
 195         count = sl->rcount;
 196         dev->stats.rx_bytes += count;
 197 
 198         skb = dev_alloc_skb(count+1);
 199         if (skb == NULL) {
 200                 netdev_warn(sl->dev, "memory squeeze, dropping packet\n");
 201                 dev->stats.rx_dropped++;
 202                 return;
 203         }
 204         skb_push(skb, 1);       /* LAPB internal control */
 205         skb_put_data(skb, sl->rbuff, count);
 206         skb->protocol = x25_type_trans(skb, sl->dev);
 207         err = lapb_data_received(skb->dev, skb);
 208         if (err != LAPB_OK) {
 209                 kfree_skb(skb);
 210                 printk(KERN_DEBUG "x25_asy: data received err - %d\n", err);
 211         } else {
 212                 netif_rx(skb);
 213                 dev->stats.rx_packets++;
 214         }
 215 }
 216 
 217 /* Encapsulate one IP datagram and stuff into a TTY queue. */
 218 static void x25_asy_encaps(struct x25_asy *sl, unsigned char *icp, int len)
 219 {
 220         unsigned char *p;
 221         int actual, count, mtu = sl->dev->mtu;
 222 
 223         if (len > mtu) {
 224                 /* Sigh, shouldn't occur BUT ... */
 225                 len = mtu;
 226                 printk(KERN_DEBUG "%s: truncating oversized transmit packet!\n",
 227                                         sl->dev->name);
 228                 sl->dev->stats.tx_dropped++;
 229                 x25_asy_unlock(sl);
 230                 return;
 231         }
 232 
 233         p = icp;
 234         count = x25_asy_esc(p, sl->xbuff, len);
 235 
 236         /* Order of next two lines is *very* important.
 237          * When we are sending a little amount of data,
 238          * the transfer may be completed inside driver.write()
 239          * routine, because it's running with interrupts enabled.
 240          * In this case we *never* got WRITE_WAKEUP event,
 241          * if we did not request it before write operation.
 242          *       14 Oct 1994  Dmitry Gorodchanin.
 243          */
 244         set_bit(TTY_DO_WRITE_WAKEUP, &sl->tty->flags);
 245         actual = sl->tty->ops->write(sl->tty, sl->xbuff, count);
 246         sl->xleft = count - actual;
 247         sl->xhead = sl->xbuff + actual;
 248         /* VSV */
 249         clear_bit(SLF_OUTWAIT, &sl->flags);     /* reset outfill flag */
 250 }
 251 
 252 /*
 253  * Called by the driver when there's room for more data.  If we have
 254  * more packets to send, we send them here.
 255  */
 256 static void x25_asy_write_wakeup(struct tty_struct *tty)
 257 {
 258         int actual;
 259         struct x25_asy *sl = tty->disc_data;
 260 
 261         /* First make sure we're connected. */
 262         if (!sl || sl->magic != X25_ASY_MAGIC || !netif_running(sl->dev))
 263                 return;
 264 
 265         if (sl->xleft <= 0) {
 266                 /* Now serial buffer is almost free & we can start
 267                  * transmission of another packet */
 268                 sl->dev->stats.tx_packets++;
 269                 clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
 270                 x25_asy_unlock(sl);
 271                 return;
 272         }
 273 
 274         actual = tty->ops->write(tty, sl->xhead, sl->xleft);
 275         sl->xleft -= actual;
 276         sl->xhead += actual;
 277 }
 278 
 279 static void x25_asy_timeout(struct net_device *dev)
 280 {
 281         struct x25_asy *sl = netdev_priv(dev);
 282 
 283         spin_lock(&sl->lock);
 284         if (netif_queue_stopped(dev)) {
 285                 /* May be we must check transmitter timeout here ?
 286                  *      14 Oct 1994 Dmitry Gorodchanin.
 287                  */
 288                 netdev_warn(dev, "transmit timed out, %s?\n",
 289                             (tty_chars_in_buffer(sl->tty) || sl->xleft) ?
 290                             "bad line quality" : "driver error");
 291                 sl->xleft = 0;
 292                 clear_bit(TTY_DO_WRITE_WAKEUP, &sl->tty->flags);
 293                 x25_asy_unlock(sl);
 294         }
 295         spin_unlock(&sl->lock);
 296 }
 297 
 298 /* Encapsulate an IP datagram and kick it into a TTY queue. */
 299 
 300 static netdev_tx_t x25_asy_xmit(struct sk_buff *skb,
 301                                       struct net_device *dev)
 302 {
 303         struct x25_asy *sl = netdev_priv(dev);
 304         int err;
 305 
 306         if (!netif_running(sl->dev)) {
 307                 netdev_err(dev, "xmit call when iface is down\n");
 308                 kfree_skb(skb);
 309                 return NETDEV_TX_OK;
 310         }
 311 
 312         switch (skb->data[0]) {
 313         case X25_IFACE_DATA:
 314                 break;
 315         case X25_IFACE_CONNECT: /* Connection request .. do nothing */
 316                 err = lapb_connect_request(dev);
 317                 if (err != LAPB_OK)
 318                         netdev_err(dev, "lapb_connect_request error: %d\n",
 319                                    err);
 320                 kfree_skb(skb);
 321                 return NETDEV_TX_OK;
 322         case X25_IFACE_DISCONNECT: /* do nothing - hang up ?? */
 323                 err = lapb_disconnect_request(dev);
 324                 if (err != LAPB_OK)
 325                         netdev_err(dev, "lapb_disconnect_request error: %d\n",
 326                                    err);
 327                 /* fall through */
 328         default:
 329                 kfree_skb(skb);
 330                 return NETDEV_TX_OK;
 331         }
 332         skb_pull(skb, 1);       /* Remove control byte */
 333         /*
 334          * If we are busy already- too bad.  We ought to be able
 335          * to queue things at this point, to allow for a little
 336          * frame buffer.  Oh well...
 337          * -----------------------------------------------------
 338          * I hate queues in X.25 driver. May be it's efficient,
 339          * but for me latency is more important. ;)
 340          * So, no queues !
 341          *        14 Oct 1994  Dmitry Gorodchanin.
 342          */
 343 
 344         err = lapb_data_request(dev, skb);
 345         if (err != LAPB_OK) {
 346                 netdev_err(dev, "lapb_data_request error: %d\n", err);
 347                 kfree_skb(skb);
 348                 return NETDEV_TX_OK;
 349         }
 350         return NETDEV_TX_OK;
 351 }
 352 
 353 
 354 /*
 355  *      LAPB interface boilerplate
 356  */
 357 
 358 /*
 359  *      Called when I frame data arrives. We did the work above - throw it
 360  *      at the net layer.
 361  */
 362 
 363 static int x25_asy_data_indication(struct net_device *dev, struct sk_buff *skb)
 364 {
 365         return netif_rx(skb);
 366 }
 367 
 368 /*
 369  *      Data has emerged from the LAPB protocol machine. We don't handle
 370  *      busy cases too well. Its tricky to see how to do this nicely -
 371  *      perhaps lapb should allow us to bounce this ?
 372  */
 373 
 374 static void x25_asy_data_transmit(struct net_device *dev, struct sk_buff *skb)
 375 {
 376         struct x25_asy *sl = netdev_priv(dev);
 377 
 378         spin_lock(&sl->lock);
 379         if (netif_queue_stopped(sl->dev) || sl->tty == NULL) {
 380                 spin_unlock(&sl->lock);
 381                 netdev_err(dev, "tbusy drop\n");
 382                 kfree_skb(skb);
 383                 return;
 384         }
 385         /* We were not busy, so we are now... :-) */
 386         if (skb != NULL) {
 387                 x25_asy_lock(sl);
 388                 dev->stats.tx_bytes += skb->len;
 389                 x25_asy_encaps(sl, skb->data, skb->len);
 390                 dev_kfree_skb(skb);
 391         }
 392         spin_unlock(&sl->lock);
 393 }
 394 
 395 /*
 396  *      LAPB connection establish/down information.
 397  */
 398 
 399 static void x25_asy_connected(struct net_device *dev, int reason)
 400 {
 401         struct x25_asy *sl = netdev_priv(dev);
 402         struct sk_buff *skb;
 403         unsigned char *ptr;
 404 
 405         skb = dev_alloc_skb(1);
 406         if (skb == NULL) {
 407                 netdev_err(dev, "out of memory\n");
 408                 return;
 409         }
 410 
 411         ptr  = skb_put(skb, 1);
 412         *ptr = X25_IFACE_CONNECT;
 413 
 414         skb->protocol = x25_type_trans(skb, sl->dev);
 415         netif_rx(skb);
 416 }
 417 
 418 static void x25_asy_disconnected(struct net_device *dev, int reason)
 419 {
 420         struct x25_asy *sl = netdev_priv(dev);
 421         struct sk_buff *skb;
 422         unsigned char *ptr;
 423 
 424         skb = dev_alloc_skb(1);
 425         if (skb == NULL) {
 426                 netdev_err(dev, "out of memory\n");
 427                 return;
 428         }
 429 
 430         ptr  = skb_put(skb, 1);
 431         *ptr = X25_IFACE_DISCONNECT;
 432 
 433         skb->protocol = x25_type_trans(skb, sl->dev);
 434         netif_rx(skb);
 435 }
 436 
 437 static const struct lapb_register_struct x25_asy_callbacks = {
 438         .connect_confirmation = x25_asy_connected,
 439         .connect_indication = x25_asy_connected,
 440         .disconnect_confirmation = x25_asy_disconnected,
 441         .disconnect_indication = x25_asy_disconnected,
 442         .data_indication = x25_asy_data_indication,
 443         .data_transmit = x25_asy_data_transmit,
 444 };
 445 
 446 
 447 /* Open the low-level part of the X.25 channel. Easy! */
 448 static int x25_asy_open(struct net_device *dev)
 449 {
 450         struct x25_asy *sl = netdev_priv(dev);
 451         unsigned long len;
 452         int err;
 453 
 454         if (sl->tty == NULL)
 455                 return -ENODEV;
 456 
 457         /*
 458          * Allocate the X.25 frame buffers:
 459          *
 460          * rbuff        Receive buffer.
 461          * xbuff        Transmit buffer.
 462          */
 463 
 464         len = dev->mtu * 2;
 465 
 466         sl->rbuff = kmalloc(len + 4, GFP_KERNEL);
 467         if (sl->rbuff == NULL)
 468                 goto norbuff;
 469         sl->xbuff = kmalloc(len + 4, GFP_KERNEL);
 470         if (sl->xbuff == NULL)
 471                 goto noxbuff;
 472 
 473         sl->buffsize = len;
 474         sl->rcount   = 0;
 475         sl->xleft    = 0;
 476         sl->flags   &= (1 << SLF_INUSE);      /* Clear ESCAPE & ERROR flags */
 477 
 478         netif_start_queue(dev);
 479 
 480         /*
 481          *      Now attach LAPB
 482          */
 483         err = lapb_register(dev, &x25_asy_callbacks);
 484         if (err == LAPB_OK)
 485                 return 0;
 486 
 487         /* Cleanup */
 488         kfree(sl->xbuff);
 489         sl->xbuff = NULL;
 490 noxbuff:
 491         kfree(sl->rbuff);
 492         sl->rbuff = NULL;
 493 norbuff:
 494         return -ENOMEM;
 495 }
 496 
 497 
 498 /* Close the low-level part of the X.25 channel. Easy! */
 499 static int x25_asy_close(struct net_device *dev)
 500 {
 501         struct x25_asy *sl = netdev_priv(dev);
 502 
 503         spin_lock(&sl->lock);
 504         if (sl->tty)
 505                 clear_bit(TTY_DO_WRITE_WAKEUP, &sl->tty->flags);
 506 
 507         netif_stop_queue(dev);
 508         sl->rcount = 0;
 509         sl->xleft  = 0;
 510         spin_unlock(&sl->lock);
 511         return 0;
 512 }
 513 
 514 /*
 515  * Handle the 'receiver data ready' interrupt.
 516  * This function is called by the 'tty_io' module in the kernel when
 517  * a block of X.25 data has been received, which can now be decapsulated
 518  * and sent on to some IP layer for further processing.
 519  */
 520 
 521 static void x25_asy_receive_buf(struct tty_struct *tty,
 522                                 const unsigned char *cp, char *fp, int count)
 523 {
 524         struct x25_asy *sl = tty->disc_data;
 525 
 526         if (!sl || sl->magic != X25_ASY_MAGIC || !netif_running(sl->dev))
 527                 return;
 528 
 529 
 530         /* Read the characters out of the buffer */
 531         while (count--) {
 532                 if (fp && *fp++) {
 533                         if (!test_and_set_bit(SLF_ERROR, &sl->flags))
 534                                 sl->dev->stats.rx_errors++;
 535                         cp++;
 536                         continue;
 537                 }
 538                 x25_asy_unesc(sl, *cp++);
 539         }
 540 }
 541 
 542 /*
 543  * Open the high-level part of the X.25 channel.
 544  * This function is called by the TTY module when the
 545  * X.25 line discipline is called for.  Because we are
 546  * sure the tty line exists, we only have to link it to
 547  * a free X.25 channel...
 548  */
 549 
 550 static int x25_asy_open_tty(struct tty_struct *tty)
 551 {
 552         struct x25_asy *sl;
 553         int err;
 554 
 555         if (tty->ops->write == NULL)
 556                 return -EOPNOTSUPP;
 557 
 558         /* OK.  Find a free X.25 channel to use. */
 559         sl = x25_asy_alloc();
 560         if (sl == NULL)
 561                 return -ENFILE;
 562 
 563         sl->tty = tty;
 564         tty->disc_data = sl;
 565         tty->receive_room = 65536;
 566         tty_driver_flush_buffer(tty);
 567         tty_ldisc_flush(tty);
 568 
 569         /* Restore default settings */
 570         sl->dev->type = ARPHRD_X25;
 571 
 572         /* Perform the low-level X.25 async init */
 573         err = x25_asy_open(sl->dev);
 574         if (err) {
 575                 x25_asy_free(sl);
 576                 return err;
 577         }
 578         /* Done.  We have linked the TTY line to a channel. */
 579         return 0;
 580 }
 581 
 582 
 583 /*
 584  * Close down an X.25 channel.
 585  * This means flushing out any pending queues, and then restoring the
 586  * TTY line discipline to what it was before it got hooked to X.25
 587  * (which usually is TTY again).
 588  */
 589 static void x25_asy_close_tty(struct tty_struct *tty)
 590 {
 591         struct x25_asy *sl = tty->disc_data;
 592         int err;
 593 
 594         /* First make sure we're connected. */
 595         if (!sl || sl->magic != X25_ASY_MAGIC)
 596                 return;
 597 
 598         rtnl_lock();
 599         if (sl->dev->flags & IFF_UP)
 600                 dev_close(sl->dev);
 601         rtnl_unlock();
 602 
 603         err = lapb_unregister(sl->dev);
 604         if (err != LAPB_OK)
 605                 pr_err("%s: lapb_unregister error: %d\n",
 606                        __func__, err);
 607 
 608         tty->disc_data = NULL;
 609         sl->tty = NULL;
 610         x25_asy_free(sl);
 611 }
 612 
 613  /************************************************************************
 614   *                     STANDARD X.25 ENCAPSULATION                      *
 615   ************************************************************************/
 616 
 617 static int x25_asy_esc(unsigned char *s, unsigned char *d, int len)
 618 {
 619         unsigned char *ptr = d;
 620         unsigned char c;
 621 
 622         /*
 623          * Send an initial END character to flush out any
 624          * data that may have accumulated in the receiver
 625          * due to line noise.
 626          */
 627 
 628         *ptr++ = X25_END;       /* Send 10111110 bit seq */
 629 
 630         /*
 631          * For each byte in the packet, send the appropriate
 632          * character sequence, according to the X.25 protocol.
 633          */
 634 
 635         while (len-- > 0) {
 636                 switch (c = *s++) {
 637                 case X25_END:
 638                         *ptr++ = X25_ESC;
 639                         *ptr++ = X25_ESCAPE(X25_END);
 640                         break;
 641                 case X25_ESC:
 642                         *ptr++ = X25_ESC;
 643                         *ptr++ = X25_ESCAPE(X25_ESC);
 644                         break;
 645                 default:
 646                         *ptr++ = c;
 647                         break;
 648                 }
 649         }
 650         *ptr++ = X25_END;
 651         return ptr - d;
 652 }
 653 
 654 static void x25_asy_unesc(struct x25_asy *sl, unsigned char s)
 655 {
 656 
 657         switch (s) {
 658         case X25_END:
 659                 if (!test_and_clear_bit(SLF_ERROR, &sl->flags) &&
 660                     sl->rcount > 2)
 661                         x25_asy_bump(sl);
 662                 clear_bit(SLF_ESCAPE, &sl->flags);
 663                 sl->rcount = 0;
 664                 return;
 665         case X25_ESC:
 666                 set_bit(SLF_ESCAPE, &sl->flags);
 667                 return;
 668         case X25_ESCAPE(X25_ESC):
 669         case X25_ESCAPE(X25_END):
 670                 if (test_and_clear_bit(SLF_ESCAPE, &sl->flags))
 671                         s = X25_UNESCAPE(s);
 672                 break;
 673         }
 674         if (!test_bit(SLF_ERROR, &sl->flags)) {
 675                 if (sl->rcount < sl->buffsize) {
 676                         sl->rbuff[sl->rcount++] = s;
 677                         return;
 678                 }
 679                 sl->dev->stats.rx_over_errors++;
 680                 set_bit(SLF_ERROR, &sl->flags);
 681         }
 682 }
 683 
 684 
 685 /* Perform I/O control on an active X.25 channel. */
 686 static int x25_asy_ioctl(struct tty_struct *tty, struct file *file,
 687                          unsigned int cmd,  unsigned long arg)
 688 {
 689         struct x25_asy *sl = tty->disc_data;
 690 
 691         /* First make sure we're connected. */
 692         if (!sl || sl->magic != X25_ASY_MAGIC)
 693                 return -EINVAL;
 694 
 695         switch (cmd) {
 696         case SIOCGIFNAME:
 697                 if (copy_to_user((void __user *)arg, sl->dev->name,
 698                                         strlen(sl->dev->name) + 1))
 699                         return -EFAULT;
 700                 return 0;
 701         case SIOCSIFHWADDR:
 702                 return -EINVAL;
 703         default:
 704                 return tty_mode_ioctl(tty, file, cmd, arg);
 705         }
 706 }
 707 
 708 static int x25_asy_open_dev(struct net_device *dev)
 709 {
 710         struct x25_asy *sl = netdev_priv(dev);
 711         if (sl->tty == NULL)
 712                 return -ENODEV;
 713         return 0;
 714 }
 715 
 716 static const struct net_device_ops x25_asy_netdev_ops = {
 717         .ndo_open       = x25_asy_open_dev,
 718         .ndo_stop       = x25_asy_close,
 719         .ndo_start_xmit = x25_asy_xmit,
 720         .ndo_tx_timeout = x25_asy_timeout,
 721         .ndo_change_mtu = x25_asy_change_mtu,
 722 };
 723 
 724 /* Initialise the X.25 driver.  Called by the device init code */
 725 static void x25_asy_setup(struct net_device *dev)
 726 {
 727         struct x25_asy *sl = netdev_priv(dev);
 728 
 729         sl->magic  = X25_ASY_MAGIC;
 730         sl->dev    = dev;
 731         spin_lock_init(&sl->lock);
 732         set_bit(SLF_INUSE, &sl->flags);
 733 
 734         /*
 735          *      Finish setting up the DEVICE info.
 736          */
 737 
 738         dev->mtu                = SL_MTU;
 739         dev->min_mtu            = 0;
 740         dev->max_mtu            = 65534;
 741         dev->netdev_ops         = &x25_asy_netdev_ops;
 742         dev->watchdog_timeo     = HZ*20;
 743         dev->hard_header_len    = 0;
 744         dev->addr_len           = 0;
 745         dev->type               = ARPHRD_X25;
 746         dev->tx_queue_len       = 10;
 747 
 748         /* New-style flags. */
 749         dev->flags              = IFF_NOARP;
 750 }
 751 
 752 static struct tty_ldisc_ops x25_ldisc = {
 753         .owner          = THIS_MODULE,
 754         .magic          = TTY_LDISC_MAGIC,
 755         .name           = "X.25",
 756         .open           = x25_asy_open_tty,
 757         .close          = x25_asy_close_tty,
 758         .ioctl          = x25_asy_ioctl,
 759         .receive_buf    = x25_asy_receive_buf,
 760         .write_wakeup   = x25_asy_write_wakeup,
 761 };
 762 
 763 static int __init init_x25_asy(void)
 764 {
 765         if (x25_asy_maxdev < 4)
 766                 x25_asy_maxdev = 4; /* Sanity */
 767 
 768         pr_info("X.25 async: version 0.00 ALPHA (dynamic channels, max=%d)\n",
 769                 x25_asy_maxdev);
 770 
 771         x25_asy_devs = kcalloc(x25_asy_maxdev, sizeof(struct net_device *),
 772                                 GFP_KERNEL);
 773         if (!x25_asy_devs)
 774                 return -ENOMEM;
 775 
 776         return tty_register_ldisc(N_X25, &x25_ldisc);
 777 }
 778 
 779 
 780 static void __exit exit_x25_asy(void)
 781 {
 782         struct net_device *dev;
 783         int i;
 784 
 785         for (i = 0; i < x25_asy_maxdev; i++) {
 786                 dev = x25_asy_devs[i];
 787                 if (dev) {
 788                         struct x25_asy *sl = netdev_priv(dev);
 789 
 790                         spin_lock_bh(&sl->lock);
 791                         if (sl->tty)
 792                                 tty_hangup(sl->tty);
 793 
 794                         spin_unlock_bh(&sl->lock);
 795                         /*
 796                          * VSV = if dev->start==0, then device
 797                          * unregistered while close proc.
 798                          */
 799                         unregister_netdev(dev);
 800                         free_netdev(dev);
 801                 }
 802         }
 803 
 804         kfree(x25_asy_devs);
 805         tty_unregister_ldisc(N_X25);
 806 }
 807 
 808 module_init(init_x25_asy);
 809 module_exit(exit_x25_asy);

/* [<][>][^][v][top][bottom][index][help] */