headers: remove sched.h from interrupt.h
[safe/jmp/linux-2.6] / drivers / net / wan / cycx_x25.c
index 5b48cd8..cd8cb95 100644 (file)
 
 #define CYCLOMX_X25_DEBUG 1
 
+#include <linux/ctype.h>       /* isdigit() */
 #include <linux/errno.h>       /* return codes */
 #include <linux/if_arp.h>       /* ARPHRD_HWX25 */
 #include <linux/kernel.h>      /* printk(), and other useful stuff */
 #include <linux/module.h>
 #include <linux/string.h>      /* inline memset(), etc. */
+#include <linux/sched.h>
 #include <linux/slab.h>                /* kmalloc(), kfree() */
 #include <linux/stddef.h>      /* offsetof(), etc. */
 #include <linux/wanrouter.h>   /* WAN router definitions */
@@ -130,15 +132,16 @@ static int cycx_wan_update(struct wan_device *wandev),
           cycx_wan_del_if(struct wan_device *wandev, struct net_device *dev);
 
 /* Network device interface */
-static int cycx_netdevice_init(struct net_device *dev),
-          cycx_netdevice_open(struct net_device *dev),
-          cycx_netdevice_stop(struct net_device *dev),
-          cycx_netdevice_hard_header(struct sk_buff *skb,
-                                    struct net_device *dev, u16 type,
-                                    void *daddr, void *saddr, unsigned len),
-          cycx_netdevice_rebuild_header(struct sk_buff *skb),
-          cycx_netdevice_hard_start_xmit(struct sk_buff *skb,
-                                         struct net_device *dev);
+static int cycx_netdevice_init(struct net_device *dev);
+static int cycx_netdevice_open(struct net_device *dev);
+static int cycx_netdevice_stop(struct net_device *dev);
+static int cycx_netdevice_hard_header(struct sk_buff *skb,
+                                     struct net_device *dev, u16 type,
+                                     const void *daddr, const void *saddr,
+                                     unsigned len);
+static int cycx_netdevice_rebuild_header(struct sk_buff *skb);
+static netdev_tx_t cycx_netdevice_hard_start_xmit(struct sk_buff *skb,
+                                                       struct net_device *dev);
 
 static struct net_device_stats *
                        cycx_netdevice_get_stats(struct net_device *dev);
@@ -197,6 +200,8 @@ static struct net_device *cycx_x25_get_dev_by_lcn(struct wan_device *wandev,
 static struct net_device *
        cycx_x25_get_dev_by_dte_addr(struct wan_device *wandev, char *dte);
 
+static void cycx_x25_chan_setup(struct net_device *dev);
+
 #ifdef CYCLOMX_X25_DEBUG
 static void hex_dump(char *msg, unsigned char *p, int len);
 static void cycx_x25_dump_config(struct cycx_x25_config *conf);
@@ -374,12 +379,12 @@ static int cycx_wan_new_if(struct wan_device *wandev, struct net_device *dev,
                return -EINVAL;
        }
 
-       /* allocate and initialize private data */
-       chan = kmalloc(sizeof(struct cycx_x25_channel), GFP_KERNEL);
-       if (!chan)
+       dev = alloc_netdev(sizeof(struct cycx_x25_channel), conf->name,
+                            cycx_x25_chan_setup);
+       if (!dev)
                return -ENOMEM;
 
-       memset(chan, 0, sizeof(*chan));
+       chan = netdev_priv(dev);
        strcpy(chan->name, conf->name);
        chan->card = card;
        chan->link = conf->port;
@@ -395,14 +400,14 @@ static int cycx_wan_new_if(struct wan_device *wandev, struct net_device *dev,
                        if (len > WAN_ADDRESS_SZ) {
                                printk(KERN_ERR "%s: %s local addr too long!\n",
                                                wandev->name, chan->name);
-                               kfree(chan);
-                               return -EINVAL;
+                               err = -EINVAL;
+                               goto error;
                        } else {
                                chan->local_addr = kmalloc(len + 1, GFP_KERNEL);
 
                                if (!chan->local_addr) {
-                                       kfree(chan);
-                                       return -ENOMEM;
+                                       err = -ENOMEM;
+                                       goto error;
                                }
                        }
 
@@ -418,7 +423,7 @@ static int cycx_wan_new_if(struct wan_device *wandev, struct net_device *dev,
 
                /* Set channel timeouts (default if not specified) */
                chan->idle_tmout = conf->idle_timeout ? conf->idle_timeout : 90;
-       } else if (is_digit(conf->addr[0])) {   /* PVC */
+       } else if (isdigit(conf->addr[0])) {    /* PVC */
                s16 lcn = dec_to_uint(conf->addr, 0);
 
                if (lcn >= card->u.x.lo_pvc && lcn <= card->u.x.hi_pvc)
@@ -428,51 +433,65 @@ static int cycx_wan_new_if(struct wan_device *wandev, struct net_device *dev,
                                "%s: PVC %u is out of range on interface %s!\n",
                                wandev->name, lcn, chan->name);
                        err = -EINVAL;
+                       goto error;
                }
        } else {
                printk(KERN_ERR "%s: invalid media address on interface %s!\n",
                                wandev->name, chan->name);
                err = -EINVAL;
+               goto error;
        }
 
-       if (err) {
-               if (chan->local_addr)
-                       kfree(chan->local_addr);
-
-               kfree(chan);
-               return err;
-       }
-
-       /* prepare network device data space for registration */
-       strcpy(dev->name, chan->name);
-       dev->init = cycx_netdevice_init;
-       dev->priv = chan;
-
        return 0;
+
+error:
+       free_netdev(dev);
+       return err;
 }
 
 /* Delete logical channel. */
 static int cycx_wan_del_if(struct wan_device *wandev, struct net_device *dev)
 {
-       if (dev->priv) {
-               struct cycx_x25_channel *chan = dev->priv;
+       struct cycx_x25_channel *chan = netdev_priv(dev);
 
-               if (chan->svc) {
-                       if (chan->local_addr)
-                               kfree(chan->local_addr);
-
-                       if (chan->state == WAN_CONNECTED)
-                               del_timer(&chan->timer);
-               }
-
-               kfree(chan);
-               dev->priv = NULL;
+       if (chan->svc) {
+               kfree(chan->local_addr);
+               if (chan->state == WAN_CONNECTED)
+                       del_timer(&chan->timer);
        }
 
        return 0;
 }
 
+
 /* Network Device Interface */
+
+static const struct header_ops cycx_header_ops = {
+       .create = cycx_netdevice_hard_header,
+       .rebuild = cycx_netdevice_rebuild_header,
+};
+
+static const struct net_device_ops cycx_netdev_ops = {
+       .ndo_init       = cycx_netdevice_init,
+       .ndo_open       = cycx_netdevice_open,
+       .ndo_stop       = cycx_netdevice_stop,
+       .ndo_start_xmit = cycx_netdevice_hard_start_xmit,
+       .ndo_get_stats  = cycx_netdevice_get_stats,
+};
+
+static void cycx_x25_chan_setup(struct net_device *dev)
+{
+       /* Initialize device driver entry points */
+       dev->netdev_ops         = &cycx_netdev_ops;
+       dev->header_ops         = &cycx_header_ops;
+
+       /* Initialize media-specific parameters */
+       dev->mtu                = CYCX_X25_CHAN_MTU;
+       dev->type               = ARPHRD_HWX25; /* ARP h/w type */
+       dev->hard_header_len    = 0;            /* media header length */
+       dev->addr_len           = 0;            /* hardware address length */
+}
+
 /* Initialize Linux network interface.
  *
  * This routine is called only once for each interface, during Linux network
@@ -480,26 +499,12 @@ static int cycx_wan_del_if(struct wan_device *wandev, struct net_device *dev)
  * registration. */
 static int cycx_netdevice_init(struct net_device *dev)
 {
-       struct cycx_x25_channel *chan = dev->priv;
+       struct cycx_x25_channel *chan = netdev_priv(dev);
        struct cycx_device *card = chan->card;
        struct wan_device *wandev = &card->wandev;
 
-       /* Initialize device driver entry points */
-       dev->open               = cycx_netdevice_open;
-       dev->stop               = cycx_netdevice_stop;
-       dev->hard_header        = cycx_netdevice_hard_header;
-       dev->rebuild_header     = cycx_netdevice_rebuild_header;
-       dev->hard_start_xmit    = cycx_netdevice_hard_start_xmit;
-       dev->get_stats          = cycx_netdevice_get_stats;
-
-       /* Initialize media-specific parameters */
-       dev->mtu                = CYCX_X25_CHAN_MTU;
-       dev->type               = ARPHRD_HWX25; /* ARP h/w type */
-       dev->hard_header_len    = 0;            /* media header length */
-       dev->addr_len           = 0;            /* hardware address length */
-
        if (!chan->svc)
-               *(u16*)dev->dev_addr = htons(chan->lcn);
+               *(__be16*)dev->dev_addr = htons(chan->lcn);
 
        /* Initialize hardware parameters (just for reference) */
        dev->irq                = wandev->irq;
@@ -512,7 +517,6 @@ static int cycx_netdevice_init(struct net_device *dev)
 
        /* Set transmit buffer queue length */
        dev->tx_queue_len       = 10;
-       SET_MODULE_OWNER(dev);
 
        /* Initialize socket buffers */
        cycx_x25_set_chan_state(dev, WAN_DISCONNECTED);
@@ -539,7 +543,7 @@ static int cycx_netdevice_open(struct net_device *dev)
  * o if there's no more open channels then disconnect physical link. */
 static int cycx_netdevice_stop(struct net_device *dev)
 {
-       struct cycx_x25_channel *chan = dev->priv;
+       struct cycx_x25_channel *chan = netdev_priv(dev);
 
        netif_stop_queue(dev);
 
@@ -559,9 +563,10 @@ static int cycx_netdevice_stop(struct net_device *dev)
  * Return:     media header length. */
 static int cycx_netdevice_hard_header(struct sk_buff *skb,
                                      struct net_device *dev, u16 type,
-                                     void *daddr, void *saddr, unsigned len)
+                                     const void *daddr, const void *saddr,
+                                     unsigned len)
 {
-       skb->protocol = type;
+       skb->protocol = htons(type);
 
        return dev->hard_header_len;
 }
@@ -589,29 +594,29 @@ static int cycx_netdevice_rebuild_header(struct sk_buff *skb)
  *    bottom half" (with interrupts enabled).
  * 2. Setting tbusy flag will inhibit further transmit requests from the
  *    protocol stack and can be used for flow control with protocol layer. */
-static int cycx_netdevice_hard_start_xmit(struct sk_buff *skb,
-                                         struct net_device *dev)
+static netdev_tx_t cycx_netdevice_hard_start_xmit(struct sk_buff *skb,
+                                                       struct net_device *dev)
 {
-       struct cycx_x25_channel *chan = dev->priv;
+       struct cycx_x25_channel *chan = netdev_priv(dev);
        struct cycx_device *card = chan->card;
 
        if (!chan->svc)
-               chan->protocol = skb->protocol;
+               chan->protocol = ntohs(skb->protocol);
 
        if (card->wandev.state != WAN_CONNECTED)
                ++chan->ifstats.tx_dropped;
        else if (chan->svc && chan->protocol &&
-                chan->protocol != skb->protocol) {
+                chan->protocol != ntohs(skb->protocol)) {
                printk(KERN_INFO
                       "%s: unsupported Ethertype 0x%04X on interface %s!\n",
-                      card->devname, skb->protocol, dev->name);
+                      card->devname, ntohs(skb->protocol), dev->name);
                ++chan->ifstats.tx_errors;
        } else if (chan->protocol == ETH_P_IP) {
                switch (chan->state) {
                case WAN_DISCONNECTED:
                        if (cycx_x25_chan_connect(dev)) {
                                netif_stop_queue(dev);
-                               return -EBUSY;
+                               return NETDEV_TX_BUSY;
                        }
                        /* fall thru */
                case WAN_CONNECTED:
@@ -620,7 +625,7 @@ static int cycx_netdevice_hard_start_xmit(struct sk_buff *skb,
                        netif_stop_queue(dev);
 
                        if (cycx_x25_chan_send(dev, skb))
-                               return -EBUSY;
+                               return NETDEV_TX_BUSY;
 
                        break;
                default:
@@ -652,21 +657,21 @@ static int cycx_netdevice_hard_start_xmit(struct sk_buff *skb,
                if (cycx_x25_chan_send(dev, skb)) {
                        /* prepare for future retransmissions */
                        skb_push(skb, 1);
-                       return -EBUSY;
+                       return NETDEV_TX_BUSY;
                }
        }
 
 free_packet:
        dev_kfree_skb(skb);
 
-       return 0;
+       return NETDEV_TX_OK;
 }
 
 /* Get Ethernet-style interface statistics.
  * Return a pointer to struct net_device_stats */
 static struct net_device_stats *cycx_netdevice_get_stats(struct net_device *dev)
 {
-       struct cycx_x25_channel *chan = dev->priv;
+       struct cycx_x25_channel *chan = netdev_priv(dev);
 
        return chan ? &chan->ifstats : NULL;
 }
@@ -779,7 +784,7 @@ static void cycx_x25_irq_rx(struct cycx_device *card, struct cycx_x25_cmd *cmd)
                return;
        }
 
-       chan = dev->priv;
+       chan = netdev_priv(dev);
        reset_timer(dev);
 
        if (chan->drop_sequence) {
@@ -837,9 +842,8 @@ static void cycx_x25_irq_rx(struct cycx_device *card, struct cycx_x25_cmd *cmd)
        ++chan->ifstats.rx_packets;
        chan->ifstats.rx_bytes += pktlen;
 
-       skb->mac.raw = skb->data;
+       skb_reset_mac_header(skb);
        netif_rx(skb);
-       dev->last_rx = jiffies;         /* timestamp */
 }
 
 /* Connect interrupt handler. */
@@ -870,7 +874,7 @@ static void cycx_x25_irq_connect(struct cycx_device *card,
                nibble_to_byte(d + (sizeloc >> 1), rem, sizerem, sizeloc & 1);
 
        dprintk(1, KERN_INFO "%s:lcn=%d, local=%s, remote=%s\n",
-                         __FUNCTION__, lcn, loc, rem);
+                         __func__, lcn, loc, rem);
 
        dev = cycx_x25_get_dev_by_dte_addr(wandev, rem);
        if (!dev) {
@@ -880,7 +884,7 @@ static void cycx_x25_irq_connect(struct cycx_device *card,
                return;
        }
 
-       chan = dev->priv;
+       chan = netdev_priv(dev);
        chan->lcn = lcn;
        cycx_x25_connect_response(card, chan);
        cycx_x25_set_chan_state(dev, WAN_CONNECTED);
@@ -898,7 +902,7 @@ static void cycx_x25_irq_connect_confirm(struct cycx_device *card,
        cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
        cycx_peek(&card->hw, cmd->buf + 1, &key, sizeof(key));
        dprintk(1, KERN_INFO "%s: %s:lcn=%d, key=%d\n",
-                         card->devname, __FUNCTION__, lcn, key);
+                         card->devname, __func__, lcn, key);
 
        dev = cycx_x25_get_dev_by_lcn(wandev, -key);
        if (!dev) {
@@ -910,7 +914,7 @@ static void cycx_x25_irq_connect_confirm(struct cycx_device *card,
        }
 
        clear_bit(--key, (void*)&card->u.x.connection_keys);
-       chan = dev->priv;
+       chan = netdev_priv(dev);
        chan->lcn = lcn;
        cycx_x25_set_chan_state(dev, WAN_CONNECTED);
 }
@@ -925,7 +929,7 @@ static void cycx_x25_irq_disconnect_confirm(struct cycx_device *card,
 
        cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
        dprintk(1, KERN_INFO "%s: %s:lcn=%d\n",
-                         card->devname, __FUNCTION__, lcn);
+                         card->devname, __func__, lcn);
        dev = cycx_x25_get_dev_by_lcn(wandev, lcn);
        if (!dev) {
                /* Invalid channel, discard packet */
@@ -946,11 +950,11 @@ static void cycx_x25_irq_disconnect(struct cycx_device *card,
        u8 lcn;
 
        cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
-       dprintk(1, KERN_INFO "%s:lcn=%d\n", __FUNCTION__, lcn);
+       dprintk(1, KERN_INFO "%s:lcn=%d\n", __func__, lcn);
 
        dev = cycx_x25_get_dev_by_lcn(wandev, lcn);
        if (dev) {
-               struct cycx_x25_channel *chan = dev->priv;
+               struct cycx_x25_channel *chan = netdev_priv(dev);
 
                cycx_x25_disconnect_response(card, chan->link, lcn);
                cycx_x25_set_chan_state(dev, WAN_DISCONNECTED);
@@ -1298,7 +1302,7 @@ static struct net_device *cycx_x25_get_dev_by_lcn(struct wan_device *wandev,
        struct cycx_x25_channel *chan;
 
        while (dev) {
-               chan = (struct cycx_x25_channel*)dev->priv;
+               chan = netdev_priv(dev);
 
                if (chan->lcn == lcn)
                        break;
@@ -1315,7 +1319,7 @@ static struct net_device *
        struct cycx_x25_channel *chan;
 
        while (dev) {
-               chan = (struct cycx_x25_channel*)dev->priv;
+               chan = netdev_priv(dev);
 
                if (!strcmp(chan->addr, dte))
                        break;
@@ -1333,7 +1337,7 @@ static struct net_device *
  *             <0      failure */
 static int cycx_x25_chan_connect(struct net_device *dev)
 {
-       struct cycx_x25_channel *chan = dev->priv;
+       struct cycx_x25_channel *chan = netdev_priv(dev);
        struct cycx_device *card = chan->card;
 
        if (chan->svc) {
@@ -1358,7 +1362,7 @@ static int cycx_x25_chan_connect(struct net_device *dev)
  * o if SVC then clear X.25 call */
 static void cycx_x25_chan_disconnect(struct net_device *dev)
 {
-       struct cycx_x25_channel *chan = dev->priv;
+       struct cycx_x25_channel *chan = netdev_priv(dev);
 
        if (chan->svc) {
                x25_clear_call(chan->card, chan->link, chan->lcn, 0, 0);
@@ -1371,19 +1375,19 @@ static void cycx_x25_chan_disconnect(struct net_device *dev)
 static void cycx_x25_chan_timer(unsigned long d)
 {
        struct net_device *dev = (struct net_device *)d;
-       struct cycx_x25_channel *chan = dev->priv;
+       struct cycx_x25_channel *chan = netdev_priv(dev);
 
        if (chan->state == WAN_CONNECTED)
                cycx_x25_chan_disconnect(dev);
        else
                printk(KERN_ERR "%s: %s for svc (%s) not connected!\n",
-                               chan->card->devname, __FUNCTION__, dev->name);
+                               chan->card->devname, __func__, dev->name);
 }
 
 /* Set logical channel state. */
 static void cycx_x25_set_chan_state(struct net_device *dev, u8 state)
 {
-       struct cycx_x25_channel *chan = dev->priv;
+       struct cycx_x25_channel *chan = netdev_priv(dev);
        struct cycx_device *card = chan->card;
        unsigned long flags;
        char *string_state = NULL;
@@ -1397,7 +1401,7 @@ static void cycx_x25_set_chan_state(struct net_device *dev, u8 state)
                switch (state) {
                case WAN_CONNECTED:
                        string_state = "connected!";
-                       *(u16*)dev->dev_addr = htons(chan->lcn);
+                       *(__be16*)dev->dev_addr = htons(chan->lcn);
                        netif_wake_queue(dev);
                        reset_timer(dev);
 
@@ -1449,7 +1453,7 @@ static void cycx_x25_set_chan_state(struct net_device *dev, u8 state)
  *    to the router.  */
 static int cycx_x25_chan_send(struct net_device *dev, struct sk_buff *skb)
 {
-       struct cycx_x25_channel *chan = dev->priv;
+       struct cycx_x25_channel *chan = netdev_priv(dev);
        struct cycx_device *card = chan->card;
        int bitm = 0;           /* final packet */
        unsigned len = skb->len;
@@ -1481,7 +1485,7 @@ static void cycx_x25_chan_send_event(struct net_device *dev, u8 event)
        unsigned char *ptr;
 
        if ((skb = dev_alloc_skb(1)) == NULL) {
-               printk(KERN_ERR "%s: out of memory\n", __FUNCTION__);
+               printk(KERN_ERR "%s: out of memory\n", __func__);
                return;
        }
 
@@ -1490,7 +1494,6 @@ static void cycx_x25_chan_send_event(struct net_device *dev, u8 event)
 
        skb->protocol = x25_type_trans(skb, dev);
        netif_rx(skb);
-       dev->last_rx = jiffies;         /* timestamp */
 }
 
 /* Convert line speed in bps to a number used by cyclom 2x code. */
@@ -1535,7 +1538,7 @@ static unsigned dec_to_uint(u8 *str, int len)
        if (!len)
                len = strlen(str);
 
-       for (; len && is_digit(*str); ++str, --len)
+       for (; len && isdigit(*str); ++str, --len)
                val = (val * 10) + (*str - (unsigned) '0');
 
        return val;
@@ -1543,7 +1546,7 @@ static unsigned dec_to_uint(u8 *str, int len)
 
 static void reset_timer(struct net_device *dev)
 {
-       struct cycx_x25_channel *chan = dev->priv;
+       struct cycx_x25_channel *chan = netdev_priv(dev);
 
        if (chan->svc)
                mod_timer(&chan->timer, jiffies+chan->idle_tmout*HZ);
@@ -1596,7 +1599,7 @@ static void cycx_x25_dump_devs(struct wan_device *wandev)
        printk(KERN_INFO "---------------------------------------\n");
 
        while(dev) {
-               struct cycx_x25_channel *chan = dev->priv;
+               struct cycx_x25_channel *chan = netdev_priv(dev);
 
                printk(KERN_INFO "%-5.5s %-15.15s   %d     ETH_P_%s\n",
                                 chan->name, chan->addr, netif_queue_stopped(dev),