X-Git-Url: http://pilppa.org/gitweb/?a=blobdiff_plain;f=drivers%2Fnet%2Fwan%2Fcycx_x25.c;h=35dea3bea95dfe91490a39274e938753ae729147;hb=b5bb14386eabcb4229ade2bc0a2b237ca166d37d;hp=5a7303dc0965e7b5db3f8af3aa35202755602a51;hpb=7fbb8759eff9a348efa5f352ffaa51c364837c4b;p=linux-2.6-omap-h63xx.git diff --git a/drivers/net/wan/cycx_x25.c b/drivers/net/wan/cycx_x25.c index 5a7303dc096..35dea3bea95 100644 --- a/drivers/net/wan/cycx_x25.c +++ b/drivers/net/wan/cycx_x25.c @@ -199,6 +199,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); @@ -376,11 +378,12 @@ static int cycx_wan_new_if(struct wan_device *wandev, struct net_device *dev, return -EINVAL; } - /* allocate and initialize private data */ - chan = kzalloc(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; + chan = netdev_priv(dev); strcpy(chan->name, conf->name); chan->card = card; chan->link = conf->port; @@ -396,14 +399,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; } } @@ -429,41 +432,31 @@ 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) { - 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; - - if (chan->svc) { - kfree(chan->local_addr); - if (chan->state == WAN_CONNECTED) - del_timer(&chan->timer); - } + struct cycx_x25_channel *chan = netdev_priv(dev); - kfree(chan); - dev->priv = NULL; + if (chan->svc) { + kfree(chan->local_addr); + if (chan->state == WAN_CONNECTED) + del_timer(&chan->timer); } return 0; @@ -477,30 +470,37 @@ static const struct header_ops cycx_header_ops = { .rebuild = cycx_netdevice_rebuild_header, }; -/* Initialize Linux network interface. - * - * This routine is called only once for each interface, during Linux network - * interface registration. Returning anything but zero will fail interface - * registration. */ -static int cycx_netdevice_init(struct net_device *dev) -{ - struct cycx_x25_channel *chan = dev->priv; - struct cycx_device *card = chan->card; - struct wan_device *wandev = &card->wandev; +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->open = cycx_netdevice_open; - dev->stop = cycx_netdevice_stop; + dev->netdev_ops = &cycx_netdev_ops; dev->header_ops = &cycx_header_ops; - 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 */ +} + +/* Initialize Linux network interface. + * + * This routine is called only once for each interface, during Linux network + * interface registration. Returning anything but zero will fail interface + * registration. */ +static int cycx_netdevice_init(struct net_device *dev) +{ + struct cycx_x25_channel *chan = netdev_priv(dev); + struct cycx_device *card = chan->card; + struct wan_device *wandev = &card->wandev; if (!chan->svc) *(__be16*)dev->dev_addr = htons(chan->lcn); @@ -542,7 +542,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); @@ -596,7 +596,7 @@ static int cycx_netdevice_rebuild_header(struct sk_buff *skb) static int 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) @@ -670,7 +670,7 @@ free_packet: * 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; } @@ -783,7 +783,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) { @@ -843,7 +843,6 @@ static void cycx_x25_irq_rx(struct cycx_device *card, struct cycx_x25_cmd *cmd) skb_reset_mac_header(skb); netif_rx(skb); - dev->last_rx = jiffies; /* timestamp */ } /* Connect interrupt handler. */ @@ -884,7 +883,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); @@ -914,7 +913,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); } @@ -954,7 +953,7 @@ static void cycx_x25_irq_disconnect(struct cycx_device *card, 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); @@ -1302,7 +1301,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; @@ -1319,7 +1318,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; @@ -1337,7 +1336,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) { @@ -1362,7 +1361,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); @@ -1375,7 +1374,7 @@ 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); @@ -1387,7 +1386,7 @@ static void cycx_x25_chan_timer(unsigned long d) /* 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; @@ -1453,7 +1452,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; @@ -1494,7 +1493,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. */ @@ -1547,7 +1545,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); @@ -1600,7 +1598,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),