Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / drivers / net / wireless / strip.c
index 45a26d9..18a4458 100644 (file)
@@ -85,9 +85,9 @@ static const char StripVersion[] = "1.3A-STUART.CHESHIRE";
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/bitops.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
-#include <asm/bitops.h>
 
 # include <linux/ctype.h>
 #include <linux/string.h>
@@ -106,12 +106,13 @@ static const char StripVersion[] = "1.3A-STUART.CHESHIRE";
 #include <linux/seq_file.h>
 #include <linux/serial.h>
 #include <linux/serialP.h>
+#include <linux/rcupdate.h>
 #include <net/arp.h>
 
 #include <linux/ip.h>
 #include <linux/tcp.h>
 #include <linux/time.h>
-
+#include <linux/jiffies.h>
 
 /************************************************************************/
 /* Useful structures and definitions                                   */
@@ -208,7 +209,7 @@ enum {
        NoStructure = 0,        /* Really old firmware */
        StructuredMessages = 1, /* Parsable AT response msgs */
        ChecksummedMessages = 2 /* Parsable AT response msgs with checksums */
-} FirmwareLevel;
+};
 
 struct strip {
        int magic;
@@ -409,12 +410,12 @@ static const MetricomAddress zero_address;
 static const MetricomAddress broadcast_address =
     { {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF} };
 
-static const MetricomKey SIP0Key = { {"SIP0"} };
-static const MetricomKey ARP0Key = { {"ARP0"} };
-static const MetricomKey ATR_Key = { {"ATR "} };
-static const MetricomKey ACK_Key = { {"ACK_"} };
-static const MetricomKey INF_Key = { {"INF_"} };
-static const MetricomKey ERR_Key = { {"ERR_"} };
+static const MetricomKey SIP0Key = { "SIP0" };
+static const MetricomKey ARP0Key = { "ARP0" };
+static const MetricomKey ATR_Key = { "ATR " };
+static const MetricomKey ACK_Key = { "ACK_" };
+static const MetricomKey INF_Key = { "INF_" };
+static const MetricomKey ERR_Key = { "ERR_" };
 
 static const long MaxARPInterval = 60 * HZ;    /* One minute */
 
@@ -436,7 +437,7 @@ static const long LongTime = 0x7FFFFFFF;
 /* Global variables                                                    */
 
 static LIST_HEAD(strip_list);
-static spinlock_t strip_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(strip_lock);
 
 /************************************************************************/
 /* Macros                                                              */
@@ -859,12 +860,9 @@ static int allocate_buffers(struct strip *strip_info, int mtu)
                strip_info->mtu = dev->mtu = mtu;
                return (1);
        }
-       if (r)
-               kfree(r);
-       if (s)
-               kfree(s);
-       if (t)
-               kfree(t);
+       kfree(r);
+       kfree(s);
+       kfree(t);
        return (0);
 }
 
@@ -875,7 +873,7 @@ static int allocate_buffers(struct strip *strip_info, int mtu)
  */
 static int strip_change_mtu(struct net_device *dev, int new_mtu)
 {
-       struct strip *strip_info = dev->priv;
+       struct strip *strip_info = netdev_priv(dev);
        int old_mtu = strip_info->mtu;
        unsigned char *orbuff = strip_info->rx_buff;
        unsigned char *osbuff = strip_info->sx_buff;
@@ -921,13 +919,9 @@ static int strip_change_mtu(struct net_device *dev, int new_mtu)
        printk(KERN_NOTICE "%s: strip MTU changed fom %d to %d.\n",
               strip_info->dev->name, old_mtu, strip_info->mtu);
 
-       if (orbuff)
-               kfree(orbuff);
-       if (osbuff)
-               kfree(osbuff);
-       if (otbuff)
-               kfree(otbuff);
-
+       kfree(orbuff);
+       kfree(osbuff);
+       kfree(otbuff);
        return 0;
 }
 
@@ -1249,7 +1243,7 @@ static void ResetRadio(struct strip *strip_info)
                        set_baud(tty, strip_info->user_baud);
        }
 
-       tty->driver->write(tty, 0, s.string, s.length);
+       tty->driver->write(tty, s.string, s.length);
 #ifdef EXT_COUNTERS
        strip_info->tx_ebytes += s.length;
 #endif
@@ -1271,7 +1265,7 @@ static void strip_write_some_more(struct tty_struct *tty)
 
        if (strip_info->tx_left > 0) {
                int num_written =
-                   tty->driver->write(tty, 0, strip_info->tx_head,
+                   tty->driver->write(tty, strip_info->tx_head,
                                      strip_info->tx_left);
                strip_info->tx_left -= num_written;
                strip_info->tx_head += num_written;
@@ -1348,14 +1342,17 @@ static unsigned char *strip_make_packet(unsigned char *buffer,
         */
        if (haddr.c[0] == 0xFF) {
                u32 brd = 0;
-               struct in_device *in_dev = in_dev_get(strip_info->dev);
-               if (in_dev == NULL)
+               struct in_device *in_dev;
+
+               rcu_read_lock();
+               in_dev = __in_dev_get_rcu(strip_info->dev);
+               if (in_dev == NULL) {
+                       rcu_read_unlock();
                        return NULL;
-               read_lock(&in_dev->lock);
+               }
                if (in_dev->ifa_list)
                        brd = in_dev->ifa_list->ifa_broadcast;
-               read_unlock(&in_dev->lock);
-               in_dev_put(in_dev);
+               rcu_read_unlock();
 
                /* arp_query returns 1 if it succeeds in looking up the address, 0 if it fails */
                if (!arp_query(haddr.c, brd, strip_info->dev)) {
@@ -1500,17 +1497,18 @@ static void strip_send(struct strip *strip_info, struct sk_buff *skb)
        }
 
        if (1) {
-               struct in_device *in_dev = in_dev_get(strip_info->dev);
+               struct in_device *in_dev;
+
                brd = addr = 0;
+               rcu_read_lock();
+               in_dev = __in_dev_get_rcu(strip_info->dev);
                if (in_dev) {
-                       read_lock(&in_dev->lock);
                        if (in_dev->ifa_list) {
                                brd = in_dev->ifa_list->ifa_broadcast;
                                addr = in_dev->ifa_list->ifa_local;
                        }
-                       read_unlock(&in_dev->lock);
-                       in_dev_put(in_dev);
                }
+               rcu_read_unlock();
        }
 
 
@@ -1558,7 +1556,7 @@ static void strip_send(struct strip *strip_info, struct sk_buff *skb)
 /* Encapsulate a datagram and kick it into a TTY queue. */
 static int strip_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-       struct strip *strip_info = (struct strip *) (dev->priv);
+       struct strip *strip_info = netdev_priv(dev);
 
        if (!netif_running(dev)) {
                printk(KERN_ERR "%s: xmit call when iface is down\n",
@@ -1571,7 +1569,7 @@ static int strip_xmit(struct sk_buff *skb, struct net_device *dev)
        del_timer(&strip_info->idle_timer);
 
 
-       if (jiffies - strip_info->pps_timer > HZ) {
+       if (time_after(jiffies, strip_info->pps_timer + HZ)) {
                unsigned long t = jiffies - strip_info->pps_timer;
                unsigned long rx_pps_count = (strip_info->rx_pps_count * HZ * 8 + t / 2) / t;
                unsigned long tx_pps_count = (strip_info->tx_pps_count * HZ * 8 + t / 2) / t;
@@ -1634,7 +1632,7 @@ static int strip_header(struct sk_buff *skb, struct net_device *dev,
                        unsigned short type, void *daddr, void *saddr,
                        unsigned len)
 {
-       struct strip *strip_info = (struct strip *) (dev->priv);
+       struct strip *strip_info = netdev_priv(dev);
        STRIP_Header *header = (STRIP_Header *) skb_push(skb, sizeof(STRIP_Header));
 
        /*printk(KERN_INFO "%s: strip_header 0x%04X %s\n", dev->name, type,
@@ -1643,7 +1641,7 @@ static int strip_header(struct sk_buff *skb, struct net_device *dev,
        header->src_addr = strip_info->true_dev_addr;
        header->protocol = htons(type);
 
-       /*HexDump("strip_header", (struct strip *)(dev->priv), skb->data, skb->data + skb->len); */
+       /*HexDump("strip_header", netdev_priv(dev), skb->data, skb->data + skb->len); */
 
        if (!daddr)
                return (-dev->hard_header_len);
@@ -1677,11 +1675,6 @@ static int strip_rebuild_header(struct sk_buff *skb)
 /************************************************************************/
 /* Receiving routines                                                  */
 
-static int strip_receive_room(struct tty_struct *tty)
-{
-       return 0x10000;         /* We can handle an infinite amount of data. :-) */
-}
-
 /*
  * This function parses the response to the ATS300? command,
  * extracting the radio version and serial number.
@@ -2393,9 +2386,9 @@ static int set_mac_address(struct strip *strip_info,
        return 0;
 }
 
-static int dev_set_mac_address(struct net_device *dev, void *addr)
+static int strip_set_mac_address(struct net_device *dev, void *addr)
 {
-       struct strip *strip_info = (struct strip *) (dev->priv);
+       struct strip *strip_info = netdev_priv(dev);
        struct sockaddr *sa = addr;
        printk(KERN_INFO "%s: strip_set_dev_mac_address called\n", dev->name);
        set_mac_address(strip_info, (MetricomAddress *) sa->sa_data);
@@ -2404,8 +2397,8 @@ static int dev_set_mac_address(struct net_device *dev, void *addr)
 
 static struct net_device_stats *strip_get_stats(struct net_device *dev)
 {
+       struct strip *strip_info = netdev_priv(dev);
        static struct net_device_stats stats;
-       struct strip *strip_info = (struct strip *) (dev->priv);
 
        memset(&stats, 0, sizeof(struct net_device_stats));
 
@@ -2426,7 +2419,7 @@ static struct net_device_stats *strip_get_stats(struct net_device *dev)
 /*
  * Here's the order things happen:
  * When the user runs "slattach -p strip ..."
- *  1. The TTY module calls strip_open
+ *  1. The TTY module calls strip_open;;
  *  2. strip_open calls strip_alloc
  *  3.                  strip_alloc calls register_netdev
  *  4.                  register_netdev calls strip_dev_init
@@ -2449,7 +2442,7 @@ static struct net_device_stats *strip_get_stats(struct net_device *dev)
 
 static int strip_open_low(struct net_device *dev)
 {
-       struct strip *strip_info = (struct strip *) (dev->priv);
+       struct strip *strip_info = netdev_priv(dev);
 
        if (strip_info->tty == NULL)
                return (-ENODEV);
@@ -2482,7 +2475,7 @@ static int strip_open_low(struct net_device *dev)
 
 static int strip_close_low(struct net_device *dev)
 {
-       struct strip *strip_info = (struct strip *) (dev->priv);
+       struct strip *strip_info = netdev_priv(dev);
 
        if (strip_info->tty == NULL)
                return -EBUSY;
@@ -2493,18 +2486,13 @@ static int strip_close_low(struct net_device *dev)
        /*
         * Free all STRIP frame buffers.
         */
-       if (strip_info->rx_buff) {
-               kfree(strip_info->rx_buff);
-               strip_info->rx_buff = NULL;
-       }
-       if (strip_info->sx_buff) {
-               kfree(strip_info->sx_buff);
-               strip_info->sx_buff = NULL;
-       }
-       if (strip_info->tx_buff) {
-               kfree(strip_info->tx_buff);
-               strip_info->tx_buff = NULL;
-       }
+       kfree(strip_info->rx_buff);
+       strip_info->rx_buff = NULL;
+       kfree(strip_info->sx_buff);
+       strip_info->sx_buff = NULL;
+       kfree(strip_info->tx_buff);
+       strip_info->tx_buff = NULL;
+
        del_timer(&strip_info->idle_timer);
        return 0;
 }
@@ -2547,7 +2535,7 @@ static void strip_dev_setup(struct net_device *dev)
        dev->hard_start_xmit = strip_xmit;
        dev->hard_header = strip_header;
        dev->rebuild_header = strip_rebuild_header;
-       dev->set_mac_address = dev_set_mac_address;
+       dev->set_mac_address = strip_set_mac_address;
        dev->get_stats = strip_get_stats;
        dev->change_mtu = strip_change_mtu;
 }
@@ -2659,10 +2647,10 @@ static int strip_open(struct tty_struct *tty)
 
        strip_info->tty = tty;
        tty->disc_data = strip_info;
+       tty->receive_room = 65536;
+
        if (tty->driver->flush_buffer)
                tty->driver->flush_buffer(tty);
-       if (tty->ldisc.flush_buffer)
-               tty->ldisc.flush_buffer(tty);
 
        /*
         * Restore default settings
@@ -2707,7 +2695,7 @@ static void strip_close(struct tty_struct *tty)
 
        unregister_netdev(strip_info->dev);
 
-       tty->disc_data = 0;
+       tty->disc_data = NULL;
        strip_info->tty = NULL;
        printk(KERN_INFO "STRIP: device \"%s\" closed down\n",
               strip_info->dev->name);
@@ -2733,14 +2721,14 @@ static int strip_ioctl(struct tty_struct *tty, struct file *file,
 
        switch (cmd) {
        case SIOCGIFNAME:
-               if(copy_to_user((void *) arg, strip_info->dev->name, strlen(strip_info->dev->name) + 1))
+               if(copy_to_user((void __user *) arg, strip_info->dev->name, strlen(strip_info->dev->name) + 1))
                        return -EFAULT;
                break;
        case SIOCSIFHWADDR:
        {
                MetricomAddress addr;
                //printk(KERN_INFO "%s: SIOCSIFHWADDR\n", strip_info->dev->name);
-               if(copy_from_user(&addr, (void *) arg, sizeof(MetricomAddress)))
+               if(copy_from_user(&addr, (void __user *) arg, sizeof(MetricomAddress)))
                        return -EFAULT;
                return set_mac_address(strip_info, &addr);
        }
@@ -2750,7 +2738,7 @@ static int strip_ioctl(struct tty_struct *tty, struct file *file,
 
        case TCGETS:
        case TCGETA:
-               return n_tty_ioctl(tty, (struct file *) file, cmd, (unsigned long) arg);
+               return n_tty_ioctl(tty, file, cmd, arg);
                break;
        default:
                return -ENOIOCTLCMD;
@@ -2771,7 +2759,6 @@ static struct tty_ldisc strip_ldisc = {
        .close = strip_close,
        .ioctl = strip_ioctl,
        .receive_buf = strip_receive_buf,
-       .receive_room = strip_receive_room,
        .write_wakeup = strip_write_some_more,
 };
 
@@ -2825,7 +2812,7 @@ static void __exit strip_exit_driver(void)
        /* Unregister with the /proc/net file here. */
        proc_net_remove("strip");
 
-       if ((i = tty_register_ldisc(N_STRIP, NULL)))
+       if ((i = tty_unregister_ldisc(N_STRIP)))
                printk(KERN_ERR "STRIP: can't unregister line discipline (err = %d)\n", i);
 
        printk(signoff);