Merge to Fedora kernel-2.6.18-1.2224_FC5 patched with stable patch-2.6.18.1-vs2.0...
[linux-2.6.git] / drivers / net / hamradio / 6pack.c
index 48af4c2..86b3bb9 100644 (file)
@@ -12,7 +12,6 @@
  *             Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
  */
 
-#include <linux/config.h>
 #include <linux/module.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -130,12 +129,11 @@ struct sixpack {
 
 #define AX25_6PACK_HEADER_LEN 0
 
-static void sp_start_tx_timer(struct sixpack *);
 static void sixpack_decode(struct sixpack *, unsigned char[], int);
 static int encode_sixpack(unsigned char *, unsigned char *, int, unsigned char);
 
 /*
- * perform the persistence/slottime algorithm for CSMA access. If the
+ * Perform the persistence/slottime algorithm for CSMA access. If the
  * persistence check was successful, write the data to the serial driver.
  * Note that in case of DAMA operation, the data is not sent here.
  */
@@ -143,7 +141,7 @@ static int encode_sixpack(unsigned char *, unsigned char *, int, unsigned char);
 static void sp_xmit_on_air(unsigned long channel)
 {
        struct sixpack *sp = (struct sixpack *) channel;
-       int actual;
+       int actual, when = sp->slottime;
        static unsigned char random;
 
        random = random * 17 + 41;
@@ -159,20 +157,10 @@ static void sp_xmit_on_air(unsigned long channel)
                sp->tty->driver->write(sp->tty, &sp->led_state, 1);
                sp->status2 = 0;
        } else
-               sp_start_tx_timer(sp);
+               mod_timer(&sp->tx_t, jiffies + ((when + 1) * HZ) / 100);
 }
 
 /* ----> 6pack timer interrupt handler and friends. <---- */
-static void sp_start_tx_timer(struct sixpack *sp)
-{
-       int when = sp->slottime;
-
-       del_timer(&sp->tx_t);
-       sp->tx_t.data = (unsigned long) sp;
-       sp->tx_t.function = sp_xmit_on_air;
-       sp->tx_t.expires = jiffies + ((when + 1) * HZ) / 100;
-       add_timer(&sp->tx_t);
-}
 
 /* Encapsulate one AX.25 frame and stuff into a TTY queue. */
 static void sp_encaps(struct sixpack *sp, unsigned char *icp, int len)
@@ -243,8 +231,7 @@ static void sp_encaps(struct sixpack *sp, unsigned char *icp, int len)
                sp->xleft = count;
                sp->xhead = sp->xbuff;
                sp->status2 = count;
-               if (sp->duplex == 0)
-                       sp_start_tx_timer(sp);
+               sp_xmit_on_air((unsigned long)sp);
        }
 
        return;
@@ -305,7 +292,7 @@ static int sp_header(struct sk_buff *skb, struct net_device *dev,
 {
 #ifdef CONFIG_INET
        if (type != htons(ETH_P_AX25))
-               return ax25_encapsulate(skb, dev, type, daddr, saddr, len);
+               return ax25_hard_header(skb, dev, type, daddr, saddr, len);
 #endif
        return 0;
 }
@@ -320,15 +307,9 @@ static int sp_set_mac_address(struct net_device *dev, void *addr)
 {
        struct sockaddr_ax25 *sa = addr;
 
-       if (sa->sax25_family != AF_AX25)
-               return -EINVAL;
-
-       if (!sa->sax25_ndigis)
-               return -EINVAL;
-
-       spin_lock_irq(&dev->xmit_lock);
+       netif_tx_lock_bh(dev);
        memcpy(dev->dev_addr, &sa->sax25_call, AX25_ADDR_LEN);
-       spin_unlock_irq(&dev->xmit_lock);
+       netif_tx_unlock_bh(dev);
 
        return 0;
 }
@@ -394,13 +375,11 @@ static void sp_bump(struct sixpack *sp, char cmd)
        if ((skb = dev_alloc_skb(count)) == NULL)
                goto out_mem;
 
-       skb->dev = sp->dev;
        ptr = skb_put(skb, count);
        *ptr++ = cmd;   /* KISS command */
 
        memcpy(ptr, sp->cooked_buf + 1, count);
-       skb->mac.raw = skb->data;
-       skb->protocol = htons(ETH_P_AX25);
+       skb->protocol = ax25_type_trans(skb, sp->dev);
        netif_rx(skb);
        sp->dev->last_rx = jiffies;
        sp->stats.rx_packets++;
@@ -476,11 +455,6 @@ out:
 
 /* ----------------------------------------------------------------------- */
 
-static int sixpack_receive_room(struct tty_struct *tty)
-{
-       return 65536;  /* We can handle an infinite amount of data. :-) */
-}
-
 /*
  * Handle the 'receiver data ready' interrupt.
  * This function is called by the 'tty_io' module in the kernel when
@@ -682,12 +656,16 @@ static int sixpack_open(struct tty_struct *tty)
        netif_start_queue(dev);
 
        init_timer(&sp->tx_t);
+       sp->tx_t.function = sp_xmit_on_air;
+       sp->tx_t.data = (unsigned long) sp;
+
        init_timer(&sp->resync_t);
 
        spin_unlock_bh(&sp->lock);
 
        /* Done.  We have linked the TTY line to a channel. */
        tty->disc_data = sp;
+       tty->receive_room = 65536;
 
        /* Now we're ready to register. */
        if (register_netdev(dev))
@@ -756,12 +734,12 @@ static int sixpack_ioctl(struct tty_struct *tty, struct file *file,
 
        switch(cmd) {
        case SIOCGIFNAME:
-               err = copy_to_user((void *) arg, dev->name,
+               err = copy_to_user((void __user *) arg, dev->name,
                                   strlen(dev->name) + 1) ? -EFAULT : 0;
                break;
 
        case SIOCGIFENCAP:
-               err = put_user(0, (int __user *)arg);
+               err = put_user(0, (int __user *) arg);
                break;
 
        case SIOCSIFENCAP:
@@ -788,9 +766,9 @@ static int sixpack_ioctl(struct tty_struct *tty, struct file *file,
                        break;
                }
 
-               spin_lock_irq(&dev->xmit_lock);
+               netif_tx_lock_bh(dev);
                memcpy(dev->dev_addr, &addr, AX25_ADDR_LEN);
-               spin_unlock_irq(&dev->xmit_lock);
+               netif_tx_unlock_bh(dev);
 
                err = 0;
                break;
@@ -819,7 +797,6 @@ static struct tty_ldisc sp_ldisc = {
        .close          = sixpack_close,
        .ioctl          = sixpack_ioctl,
        .receive_buf    = sixpack_receive_buf,
-       .receive_room   = sixpack_receive_room,
        .write_wakeup   = sixpack_write_wakeup,
 };
 
@@ -850,7 +827,7 @@ static void __exit sixpack_exit_driver(void)
 {
        int ret;
 
-       if ((ret = tty_register_ldisc(N_6PACK, NULL)))
+       if ((ret = tty_unregister_ldisc(N_6PACK)))
                printk(msg_unregfail, ret);
 }