tty: Ldisc revamp
[safe/jmp/linux-2.6] / drivers / net / hamradio / 6pack.c
index 0a84732..19dd0a6 100644 (file)
@@ -3,7 +3,7 @@
  *             devices like TTY. It interfaces between a raw TTY and the
  *             kernel's AX.25 protocol layers.
  *
- * Authors:    Andreas Könsgen <ajk@iehk.rwth-aachen.de>
+ * Authors:    Andreas Könsgen <ajk@iehk.rwth-aachen.de>
  *              Ralf Baechle DL5RB <ralf@linux-mips.org>
  *
  * Quite a lot of stuff "stolen" by Joerg Reuter from slip.c, written by
@@ -33,7 +33,7 @@
 #include <linux/init.h>
 #include <linux/ip.h>
 #include <linux/tcp.h>
-#include <asm/semaphore.h>
+#include <linux/semaphore.h>
 #include <asm/atomic.h>
 
 #define SIXPACK_VERSION    "Revision: 0.3.0"
@@ -148,13 +148,13 @@ static void sp_xmit_on_air(unsigned long channel)
 
        if (((sp->status1 & SIXP_DCD_MASK) == 0) && (random < sp->persistence)) {
                sp->led_state = 0x70;
-               sp->tty->driver->write(sp->tty, &sp->led_state, 1);
+               sp->tty->ops->write(sp->tty, &sp->led_state, 1);
                sp->tx_enable = 1;
-               actual = sp->tty->driver->write(sp->tty, sp->xbuff, sp->status2);
+               actual = sp->tty->ops->write(sp->tty, sp->xbuff, sp->status2);
                sp->xleft -= actual;
                sp->xhead += actual;
                sp->led_state = 0x60;
-               sp->tty->driver->write(sp->tty, &sp->led_state, 1);
+               sp->tty->ops->write(sp->tty, &sp->led_state, 1);
                sp->status2 = 0;
        } else
                mod_timer(&sp->tx_t, jiffies + ((when + 1) * HZ) / 100);
@@ -220,13 +220,13 @@ static void sp_encaps(struct sixpack *sp, unsigned char *icp, int len)
         */
        if (sp->duplex == 1) {
                sp->led_state = 0x70;
-               sp->tty->driver->write(sp->tty, &sp->led_state, 1);
+               sp->tty->ops->write(sp->tty, &sp->led_state, 1);
                sp->tx_enable = 1;
-               actual = sp->tty->driver->write(sp->tty, sp->xbuff, count);
+               actual = sp->tty->ops->write(sp->tty, sp->xbuff, count);
                sp->xleft = count - actual;
                sp->xhead = sp->xbuff + actual;
                sp->led_state = 0x60;
-               sp->tty->driver->write(sp->tty, &sp->led_state, 1);
+               sp->tty->ops->write(sp->tty, &sp->led_state, 1);
        } else {
                sp->xleft = count;
                sp->xhead = sp->xbuff;
@@ -288,10 +288,11 @@ static int sp_close(struct net_device *dev)
 
 /* Return the frame type ID */
 static int sp_header(struct sk_buff *skb, struct net_device *dev,
-       unsigned short type, void *daddr, void *saddr, unsigned len)
+                    unsigned short type, const void *daddr,
+                    const void *saddr, unsigned len)
 {
 #ifdef CONFIG_INET
-       if (type != htons(ETH_P_AX25))
+       if (type != ETH_P_AX25)
                return ax25_hard_header(skb, dev, type, daddr, saddr, len);
 #endif
        return 0;
@@ -323,6 +324,11 @@ static int sp_rebuild_header(struct sk_buff *skb)
 #endif
 }
 
+static const struct header_ops sp_header_ops = {
+       .create         = sp_header,
+       .rebuild        = sp_rebuild_header,
+};
+
 static void sp_setup(struct net_device *dev)
 {
        /* Finish setting up the DEVICE info. */
@@ -331,14 +337,15 @@ static void sp_setup(struct net_device *dev)
        dev->open               = sp_open_dev;
        dev->destructor         = free_netdev;
        dev->stop               = sp_close;
-       dev->hard_header        = sp_header;
+
        dev->get_stats          = sp_get_stats;
        dev->set_mac_address    = sp_set_mac_address;
        dev->hard_header_len    = AX25_MAX_HEADER_LEN;
+       dev->header_ops         = &sp_header_ops;
+
        dev->addr_len           = AX25_ADDR_LEN;
        dev->type               = ARPHRD_AX25;
        dev->tx_queue_len       = 10;
-       dev->rebuild_header     = sp_rebuild_header;
        dev->tx_timeout         = NULL;
 
        /* Only activated in AX.25 mode */
@@ -437,7 +444,7 @@ static void sixpack_write_wakeup(struct tty_struct *tty)
        }
 
        if (sp->tx_enable) {
-               actual = tty->driver->write(tty, sp->xhead, sp->xleft);
+               actual = tty->ops->write(tty, sp->xhead, sp->xleft);
                sp->xleft -= actual;
                sp->xhead += actual;
        }
@@ -484,9 +491,7 @@ static void sixpack_receive_buf(struct tty_struct *tty,
        sixpack_decode(sp, buf, count1);
 
        sp_put(sp);
-       if (test_and_clear_bit(TTY_THROTTLED, &tty->flags)
-           && tty->driver->unthrottle)
-               tty->driver->unthrottle(tty);
+       tty_unthrottle(tty);
 }
 
 /*
@@ -547,8 +552,8 @@ static void resync_tnc(unsigned long channel)
        /* resync the TNC */
 
        sp->led_state = 0x60;
-       sp->tty->driver->write(sp->tty, &sp->led_state, 1);
-       sp->tty->driver->write(sp->tty, &resync_cmd, 1);
+       sp->tty->ops->write(sp->tty, &sp->led_state, 1);
+       sp->tty->ops->write(sp->tty, &resync_cmd, 1);
 
 
        /* Start resync timer again -- the TNC might be still absent */
@@ -566,7 +571,7 @@ static inline int tnc_init(struct sixpack *sp)
 
        tnc_set_sync_state(sp, TNC_UNSYNC_STARTUP);
 
-       sp->tty->driver->write(sp->tty, &inbyte, 1);
+       sp->tty->ops->write(sp->tty, &inbyte, 1);
 
        del_timer(&sp->resync_t);
        sp->resync_t.data = (unsigned long) sp;
@@ -594,6 +599,8 @@ static int sixpack_open(struct tty_struct *tty)
 
        if (!capable(CAP_NET_ADMIN))
                return -EPERM;
+       if (tty->ops->write == NULL)
+               return -EOPNOTSUPP;
 
        dev = alloc_netdev(sizeof(struct sixpack), "sp%d", sp_setup);
        if (!dev) {
@@ -694,7 +701,7 @@ static void sixpack_close(struct tty_struct *tty)
        sp = tty->disc_data;
        tty->disc_data = NULL;
        write_unlock(&disc_data_lock);
-       if (sp == 0)
+       if (!sp)
                return;
 
        /*
@@ -755,26 +762,20 @@ static int sixpack_ioctl(struct tty_struct *tty, struct file *file,
 
                if (copy_from_user(&addr,
                                   (void __user *) arg, AX25_ADDR_LEN)) {
-                       err = -EFAULT;
-                       break;
-               }
-
-               netif_tx_lock_bh(dev);
-               memcpy(dev->dev_addr, &addr, AX25_ADDR_LEN);
-               netif_tx_unlock_bh(dev);
+                               err = -EFAULT;
+                               break;
+                       }
 
-               err = 0;
-               break;
-       }
+                       netif_tx_lock_bh(dev);
+                       memcpy(dev->dev_addr, &addr, AX25_ADDR_LEN);
+                       netif_tx_unlock_bh(dev);
 
-       /* Allow stty to read, but not set, the serial port */
-       case TCGETS:
-       case TCGETA:
-               err = n_tty_ioctl(tty, (struct file *) file, cmd, arg);
-               break;
+                       err = 0;
+                       break;
+               }
 
        default:
-               err = -ENOIOCTLCMD;
+               err = tty_mode_ioctl(tty, file, cmd, arg);
        }
 
        sp_put(sp);
@@ -782,7 +783,7 @@ static int sixpack_ioctl(struct tty_struct *tty, struct file *file,
        return err;
 }
 
-static struct tty_ldisc sp_ldisc = {
+static struct tty_ldisc_ops sp_ldisc = {
        .owner          = THIS_MODULE,
        .magic          = TTY_LDISC_MAGIC,
        .name           = "6pack",
@@ -913,9 +914,9 @@ static void decode_prio_command(struct sixpack *sp, unsigned char cmd)
        } else { /* output watchdog char if idle */
                if ((sp->status2 != 0) && (sp->duplex == 1)) {
                        sp->led_state = 0x70;
-                       sp->tty->driver->write(sp->tty, &sp->led_state, 1);
+                       sp->tty->ops->write(sp->tty, &sp->led_state, 1);
                        sp->tx_enable = 1;
-                       actual = sp->tty->driver->write(sp->tty, sp->xbuff, sp->status2);
+                       actual = sp->tty->ops->write(sp->tty, sp->xbuff, sp->status2);
                        sp->xleft -= actual;
                        sp->xhead += actual;
                        sp->led_state = 0x60;
@@ -925,7 +926,7 @@ static void decode_prio_command(struct sixpack *sp, unsigned char cmd)
        }
 
        /* needed to trigger the TNC watchdog */
-       sp->tty->driver->write(sp->tty, &sp->led_state, 1);
+       sp->tty->ops->write(sp->tty, &sp->led_state, 1);
 
         /* if the state byte has been received, the TNC is present,
            so the resync timer can be reset. */
@@ -955,12 +956,12 @@ static void decode_std_command(struct sixpack *sp, unsigned char cmd)
                        if ((sp->status & SIXP_RX_DCD_MASK) ==
                                SIXP_RX_DCD_MASK) {
                                sp->led_state = 0x68;
-                               sp->tty->driver->write(sp->tty, &sp->led_state, 1);
+                               sp->tty->ops->write(sp->tty, &sp->led_state, 1);
                        }
                } else {
                        sp->led_state = 0x60;
                        /* fill trailing bytes with zeroes */
-                       sp->tty->driver->write(sp->tty, &sp->led_state, 1);
+                       sp->tty->ops->write(sp->tty, &sp->led_state, 1);
                        rest = sp->rx_count;
                        if (rest != 0)
                                 for (i = rest; i <= 3; i++)