linux/drivers/net/wan/x25_asy.c
<<
>>
Prefs
   1/*
   2 *      Things to sort out:
   3 *
   4 *      o       tbusy handling
   5 *      o       allow users to set the parameters
   6 *      o       sync/async switching ?
   7 *
   8 *      Note: This does _not_ implement CCITT X.25 asynchronous framing
   9 *      recommendations. Its primarily for testing purposes. If you wanted
  10 *      to do CCITT then in theory all you need is to nick the HDLC async
  11 *      checksum routines from ppp.c
  12 *      Changes:
  13 *
  14 *      2000-10-29      Henner Eisen    lapb_data_indication() return status.
  15 */
  16
  17#include <linux/module.h>
  18
  19#include <asm/system.h>
  20#include <linux/uaccess.h>
  21#include <linux/bitops.h>
  22#include <linux/string.h>
  23#include <linux/mm.h>
  24#include <linux/interrupt.h>
  25#include <linux/in.h>
  26#include <linux/tty.h>
  27#include <linux/errno.h>
  28#include <linux/netdevice.h>
  29#include <linux/etherdevice.h>
  30#include <linux/skbuff.h>
  31#include <linux/if_arp.h>
  32#include <linux/x25.h>
  33#include <linux/lapb.h>
  34#include <linux/init.h>
  35#include <linux/rtnetlink.h>
  36#include "x25_asy.h"
  37
  38#include <net/x25device.h>
  39
  40static struct net_device **x25_asy_devs;
  41static int x25_asy_maxdev = SL_NRUNIT;
  42
  43module_param(x25_asy_maxdev, int, 0);
  44MODULE_LICENSE("GPL");
  45
  46static int x25_asy_esc(unsigned char *p, unsigned char *d, int len);
  47static void x25_asy_unesc(struct x25_asy *sl, unsigned char c);
  48static void x25_asy_setup(struct net_device *dev);
  49
  50/* Find a free X.25 channel, and link in this `tty' line. */
  51static struct x25_asy *x25_asy_alloc(void)
  52{
  53        struct net_device *dev = NULL;
  54        struct x25_asy *sl;
  55        int i;
  56
  57        if (x25_asy_devs == NULL)
  58                return NULL;    /* Master array missing ! */
  59
  60        for (i = 0; i < x25_asy_maxdev; i++) {
  61                dev = x25_asy_devs[i];
  62
  63                /* Not allocated ? */
  64                if (dev == NULL)
  65                        break;
  66
  67                sl = netdev_priv(dev);
  68                /* Not in use ? */
  69                if (!test_and_set_bit(SLF_INUSE, &sl->flags))
  70                        return sl;
  71        }
  72
  73
  74        /* Sorry, too many, all slots in use */
  75        if (i >= x25_asy_maxdev)
  76                return NULL;
  77
  78        /* If no channels are available, allocate one */
  79        if (!dev) {
  80                char name[IFNAMSIZ];
  81                sprintf(name, "x25asy%d", i);
  82
  83                dev = alloc_netdev(sizeof(struct x25_asy),
  84                                   name, x25_asy_setup);
  85                if (!dev)
  86                        return NULL;
  87
  88                /* Initialize channel control data */
  89                sl = netdev_priv(dev);
  90                dev->base_addr    = i;
  91
  92                /* register device so that it can be ifconfig'ed       */
  93                if (register_netdev(dev) == 0) {
  94                        /* (Re-)Set the INUSE bit.   Very Important! */
  95                        set_bit(SLF_INUSE, &sl->flags);
  96                        x25_asy_devs[i] = dev;
  97                        return sl;
  98                } else {
  99                        printk(KERN_WARNING "x25_asy_alloc() - register_netdev() failure.\n");
 100                        free_netdev(dev);
 101                }
 102        }
 103        return NULL;
 104}
 105
 106
 107/* Free an X.25 channel. */
 108static void x25_asy_free(struct x25_asy *sl)
 109{
 110        /* Free all X.25 frame buffers. */
 111        kfree(sl->rbuff);
 112        sl->rbuff = NULL;
 113        kfree(sl->xbuff);
 114        sl->xbuff = NULL;
 115
 116        if (!test_and_clear_bit(SLF_INUSE, &sl->flags))
 117                printk(KERN_ERR "%s: x25_asy_free for already free unit.\n",
 118                        sl->dev->name);
 119}
 120
 121static 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 = 2 * newmtu;
 126
 127        xbuff = kmalloc(len + 4, GFP_ATOMIC);
 128        rbuff = kmalloc(len + 4, GFP_ATOMIC);
 129
 130        if (xbuff == NULL || rbuff == NULL) {
 131                printk(KERN_WARNING "%s: unable to grow X.25 buffers, MTU change cancelled.\n",
 132                       dev->name);
 133                kfree(xbuff);
 134                kfree(rbuff);
 135                return -ENOMEM;
 136        }
 137
 138        spin_lock_bh(&sl->lock);
 139        xbuff    = xchg(&sl->xbuff, xbuff);
 140        if (sl->xleft)  {
 141                if (sl->xleft <= len)  {
 142                        memcpy(sl->xbuff, sl->xhead, sl->xleft);
 143                } else  {
 144                        sl->xleft = 0;
 145                        dev->stats.tx_dropped++;
 146                }
 147        }
 148        sl->xhead = sl->xbuff;
 149
 150        rbuff    = xchg(&sl->rbuff, rbuff);
 151        if (sl->rcount)  {
 152                if (sl->rcount <= len) {
 153                        memcpy(sl->rbuff, rbuff, sl->rcount);
 154                } else  {
 155                        sl->rcount = 0;
 156                        dev->stats.rx_over_errors++;
 157                        set_bit(SLF_ERROR, &sl->flags);
 158                }
 159        }
 160
 161        dev->mtu    = newmtu;
 162        sl->buffsize = len;
 163
 164        spin_unlock_bh(&sl->lock);
 165
 166        kfree(xbuff);
 167        kfree(rbuff);
 168        return 0;
 169}
 170
 171
 172/* Set the "sending" flag.  This must be atomic, hence the ASM. */
 173
 174static inline void x25_asy_lock(struct x25_asy *sl)
 175{
 176        netif_stop_queue(sl->dev);
 177}
 178
 179
 180/* Clear the "sending" flag.  This must be atomic, hence the ASM. */
 181
 182static inline void x25_asy_unlock(struct x25_asy *sl)
 183{
 184        netif_wake_queue(sl->dev);
 185}
 186
 187/* Send one completely decapsulated IP datagram to the IP layer. */
 188
 189static void x25_asy_bump(struct x25_asy *sl)
 190{
 191        struct net_device *dev = sl->dev;
 192        struct sk_buff *skb;
 193        int count;
 194        int err;
 195
 196        count = sl->rcount;
 197        dev->stats.rx_bytes += count;
 198
 199        skb = dev_alloc_skb(count+1);
 200        if (skb == NULL) {
 201                printk(KERN_WARNING "%s: memory squeeze, dropping packet.\n",
 202                        sl->dev->name);
 203                dev->stats.rx_dropped++;
 204                return;
 205        }
 206        skb_push(skb, 1);       /* LAPB internal control */
 207        memcpy(skb_put(skb, count), sl->rbuff, count);
 208        skb->protocol = x25_type_trans(skb, sl->dev);
 209        err = lapb_data_received(skb->dev, skb);
 210        if (err != LAPB_OK) {
 211                kfree_skb(skb);
 212                printk(KERN_DEBUG "x25_asy: data received err - %d\n", err);
 213        } else {
 214                netif_rx(skb);
 215                dev->stats.rx_packets++;
 216        }
 217}
 218
 219/* Encapsulate one IP datagram and stuff into a TTY queue. */
 220static void x25_asy_encaps(struct x25_asy *sl, unsigned char *icp, int len)
 221{
 222        unsigned char *p;
 223        int actual, count, mtu = sl->dev->mtu;
 224
 225        if (len > mtu) {
 226                /* Sigh, shouldn't occur BUT ... */
 227                len = mtu;
 228                printk(KERN_DEBUG "%s: truncating oversized transmit packet!\n",
 229                                        sl->dev->name);
 230                sl->dev->stats.tx_dropped++;
 231                x25_asy_unlock(sl);
 232                return;
 233        }
 234
 235        p = icp;
 236        count = x25_asy_esc(p, (unsigned char *) sl->xbuff, len);
 237
 238        /* Order of next two lines is *very* important.
 239         * When we are sending a little amount of data,
 240         * the transfer may be completed inside driver.write()
 241         * routine, because it's running with interrupts enabled.
 242         * In this case we *never* got WRITE_WAKEUP event,
 243         * if we did not request it before write operation.
 244         *       14 Oct 1994  Dmitry Gorodchanin.
 245         */
 246        set_bit(TTY_DO_WRITE_WAKEUP, &sl->tty->flags);
 247        actual = sl->tty->ops->write(sl->tty, sl->xbuff, count);
 248        sl->xleft = count - actual;
 249        sl->xhead = sl->xbuff + actual;
 250        /* VSV */
 251        clear_bit(SLF_OUTWAIT, &sl->flags);     /* reset outfill flag */
 252}
 253
 254/*
 255 * Called by the driver when there's room for more data.  If we have
 256 * more packets to send, we send them here.
 257 */
 258static void x25_asy_write_wakeup(struct tty_struct *tty)
 259{
 260        int actual;
 261        struct x25_asy *sl = tty->disc_data;
 262
 263        /* First make sure we're connected. */
 264        if (!sl || sl->magic != X25_ASY_MAGIC || !netif_running(sl->dev))
 265                return;
 266
 267        if (sl->xleft <= 0) {
 268                /* Now serial buffer is almost free & we can start
 269                 * transmission of another packet */
 270                sl->dev->stats.tx_packets++;
 271                clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
 272                x25_asy_unlock(sl);
 273                return;
 274        }
 275
 276        actual = tty->ops->write(tty, sl->xhead, sl->xleft);
 277        sl->xleft -= actual;
 278        sl->xhead += actual;
 279}
 280
 281static void x25_asy_timeout(struct net_device *dev)
 282{
 283        struct x25_asy *sl = netdev_priv(dev);
 284
 285        spin_lock(&sl->lock);
 286        if (netif_queue_stopped(dev)) {
 287                /* May be we must check transmitter timeout here ?
 288                 *      14 Oct 1994 Dmitry Gorodchanin.
 289                 */
 290                printk(KERN_WARNING "%s: transmit timed out, %s?\n", dev->name,
 291                       (tty_chars_in_buffer(sl->tty) || sl->xleft) ?
 292                       "bad line quality" : "driver error");
 293                sl->xleft = 0;
 294                clear_bit(TTY_DO_WRITE_WAKEUP, &sl->tty->flags);
 295                x25_asy_unlock(sl);
 296        }
 297        spin_unlock(&sl->lock);
 298}
 299
 300/* Encapsulate an IP datagram and kick it into a TTY queue. */
 301
 302static netdev_tx_t x25_asy_xmit(struct sk_buff *skb,
 303                                      struct net_device *dev)
 304{
 305        struct x25_asy *sl = netdev_priv(dev);
 306        int err;
 307
 308        if (!netif_running(sl->dev)) {
 309                printk(KERN_ERR "%s: xmit call when iface is down\n",
 310                        dev->name);
 311                kfree_skb(skb);
 312                return NETDEV_TX_OK;
 313        }
 314
 315        switch (skb->data[0]) {
 316        case 0x00:
 317                break;
 318        case 0x01: /* Connection request .. do nothing */
 319                err = lapb_connect_request(dev);
 320                if (err != LAPB_OK)
 321                        printk(KERN_ERR "x25_asy: lapb_connect_request error - %d\n", err);
 322                kfree_skb(skb);
 323                return NETDEV_TX_OK;
 324        case 0x02: /* Disconnect request .. do nothing - hang up ?? */
 325                err = lapb_disconnect_request(dev);
 326                if (err != LAPB_OK)
 327                        printk(KERN_ERR "x25_asy: lapb_disconnect_request error - %d\n", err);
 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                printk(KERN_ERR "x25_asy: 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
 363static 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
 374static 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                printk(KERN_ERR "x25_asy: 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
 399static 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                printk(KERN_ERR "x25_asy: out of memory\n");
 408                return;
 409        }
 410
 411        ptr  = skb_put(skb, 1);
 412        *ptr = 0x01;
 413
 414        skb->protocol = x25_type_trans(skb, sl->dev);
 415        netif_rx(skb);
 416}
 417
 418static 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                printk(KERN_ERR "x25_asy: out of memory\n");
 427                return;
 428        }
 429
 430        ptr  = skb_put(skb, 1);
 431        *ptr = 0x02;
 432
 433        skb->protocol = x25_type_trans(skb, sl->dev);
 434        netif_rx(skb);
 435}
 436
 437static 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
 448/* Open the low-level part of the X.25 channel. Easy! */
 449static int x25_asy_open(struct net_device *dev)
 450{
 451        struct x25_asy *sl = netdev_priv(dev);
 452        unsigned long len;
 453        int err;
 454
 455        if (sl->tty == NULL)
 456                return -ENODEV;
 457
 458        /*
 459         * Allocate the X.25 frame buffers:
 460         *
 461         * rbuff        Receive buffer.
 462         * xbuff        Transmit buffer.
 463         */
 464
 465        len = dev->mtu * 2;
 466
 467        sl->rbuff = kmalloc(len + 4, GFP_KERNEL);
 468        if (sl->rbuff == NULL)
 469                goto norbuff;
 470        sl->xbuff = kmalloc(len + 4, GFP_KERNEL);
 471        if (sl->xbuff == NULL)
 472                goto noxbuff;
 473
 474        sl->buffsize = len;
 475        sl->rcount   = 0;
 476        sl->xleft    = 0;
 477        sl->flags   &= (1 << SLF_INUSE);      /* Clear ESCAPE & ERROR flags */
 478
 479        netif_start_queue(dev);
 480
 481        /*
 482         *      Now attach LAPB
 483         */
 484        err = lapb_register(dev, &x25_asy_callbacks);
 485        if (err == LAPB_OK)
 486                return 0;
 487
 488        /* Cleanup */
 489        kfree(sl->xbuff);
 490noxbuff:
 491        kfree(sl->rbuff);
 492norbuff:
 493        return -ENOMEM;
 494}
 495
 496
 497/* Close the low-level part of the X.25 channel. Easy! */
 498static int x25_asy_close(struct net_device *dev)
 499{
 500        struct x25_asy *sl = netdev_priv(dev);
 501        int err;
 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        err = lapb_unregister(dev);
 511        if (err != LAPB_OK)
 512                printk(KERN_ERR "x25_asy_close: lapb_unregister error -%d\n",
 513                        err);
 514        spin_unlock(&sl->lock);
 515        return 0;
 516}
 517
 518/*
 519 * Handle the 'receiver data ready' interrupt.
 520 * This function is called by the 'tty_io' module in the kernel when
 521 * 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 */
 524
 525static void x25_asy_receive_buf(struct tty_struct *tty,
 526                                const unsigned char *cp, char *fp, int count)
 527{
 528        struct x25_asy *sl = tty->disc_data;
 529
 530        if (!sl || sl->magic != X25_ASY_MAGIC || !netif_running(sl->dev))
 531                return;
 532
 533
 534        /* Read the characters out of the buffer */
 535        while (count--) {
 536                if (fp && *fp++) {
 537                        if (!test_and_set_bit(SLF_ERROR, &sl->flags))
 538                                sl->dev->stats.rx_errors++;
 539                        cp++;
 540                        continue;
 541                }
 542                x25_asy_unesc(sl, *cp++);
 543        }
 544}
 545
 546/*
 547 * Open the high-level part of the X.25 channel.
 548 * This function is called by the TTY module when the
 549 * X.25 line discipline is called for.  Because we are
 550 * sure the tty line exists, we only have to link it to
 551 * a free X.25 channel...
 552 */
 553
 554static int x25_asy_open_tty(struct tty_struct *tty)
 555{
 556        struct x25_asy *sl = tty->disc_data;
 557        int err;
 558
 559        if (tty->ops->write == NULL)
 560                return -EOPNOTSUPP;
 561
 562        /* First make sure we're not already connected. */
 563        if (sl && sl->magic == X25_ASY_MAGIC)
 564                return -EEXIST;
 565
 566        /* OK.  Find a free X.25 channel to use. */
 567        sl = x25_asy_alloc();
 568        if (sl == NULL)
 569                return -ENFILE;
 570
 571        sl->tty = tty;
 572        tty->disc_data = sl;
 573        tty->receive_room = 65536;
 574        tty_driver_flush_buffer(tty);
 575        tty_ldisc_flush(tty);
 576
 577        /* Restore default settings */
 578        sl->dev->type = ARPHRD_X25;
 579
 580        /* Perform the low-level X.25 async init */
 581        err = x25_asy_open(sl->dev);
 582        if (err)
 583                return err;
 584        /* Done.  We have linked the TTY line to a channel. */
 585        return sl->dev->base_addr;
 586}
 587
 588
 589/*
 590 * Close down an X.25 channel.
 591 * This means flushing out any pending queues, and then restoring the
 592 * TTY line discipline to what it was before it got hooked to X.25
 593 * (which usually is TTY again).
 594 */
 595static void x25_asy_close_tty(struct tty_struct *tty)
 596{
 597        struct x25_asy *sl = tty->disc_data;
 598
 599        /* First make sure we're connected. */
 600        if (!sl || sl->magic != X25_ASY_MAGIC)
 601                return;
 602
 603        rtnl_lock();
 604        if (sl->dev->flags & IFF_UP)
 605                dev_close(sl->dev);
 606        rtnl_unlock();
 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
 617static 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
 654static 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. */
 686static 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
 708static 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
 716static 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 */
 725static 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->netdev_ops         = &x25_asy_netdev_ops;
 740        dev->watchdog_timeo     = HZ*20;
 741        dev->hard_header_len    = 0;
 742        dev->addr_len           = 0;
 743        dev->type               = ARPHRD_X25;
 744        dev->tx_queue_len       = 10;
 745
 746        /* New-style flags. */
 747        dev->flags              = IFF_NOARP;
 748}
 749
 750static struct tty_ldisc_ops x25_ldisc = {
 751        .owner          = THIS_MODULE,
 752        .magic          = TTY_LDISC_MAGIC,
 753        .name           = "X.25",
 754        .open           = x25_asy_open_tty,
 755        .close          = x25_asy_close_tty,
 756        .ioctl          = x25_asy_ioctl,
 757        .receive_buf    = x25_asy_receive_buf,
 758        .write_wakeup   = x25_asy_write_wakeup,
 759};
 760
 761static int __init init_x25_asy(void)
 762{
 763        if (x25_asy_maxdev < 4)
 764                x25_asy_maxdev = 4; /* Sanity */
 765
 766        printk(KERN_INFO "X.25 async: version 0.00 ALPHA "
 767                        "(dynamic channels, max=%d).\n", x25_asy_maxdev);
 768
 769        x25_asy_devs = kcalloc(x25_asy_maxdev, sizeof(struct net_device *),
 770                                GFP_KERNEL);
 771        if (!x25_asy_devs) {
 772                printk(KERN_WARNING "X25 async: Can't allocate x25_asy_ctrls[] "
 773                                "array! Uaargh! (-> No X.25 available)\n");
 774                return -ENOMEM;
 775        }
 776
 777        return tty_register_ldisc(N_X25, &x25_ldisc);
 778}
 779
 780
 781static void __exit exit_x25_asy(void)
 782{
 783        struct net_device *dev;
 784        int i;
 785
 786        for (i = 0; i < x25_asy_maxdev; i++) {
 787                dev = x25_asy_devs[i];
 788                if (dev) {
 789                        struct x25_asy *sl = netdev_priv(dev);
 790
 791                        spin_lock_bh(&sl->lock);
 792                        if (sl->tty)
 793                                tty_hangup(sl->tty);
 794
 795                        spin_unlock_bh(&sl->lock);
 796                        /*
 797                         * VSV = if dev->start==0, then device
 798                         * unregistered while close proc.
 799                         */
 800                        unregister_netdev(dev);
 801                        free_netdev(dev);
 802                }
 803        }
 804
 805        kfree(x25_asy_devs);
 806        tty_unregister_ldisc(N_X25);
 807}
 808
 809module_init(init_x25_asy);
 810module_exit(exit_x25_asy);
 811