Commit aed0b60e authored by David S. Miller's avatar David S. Miller

Merge nuts.ninka.net:/home/davem/src/BK/network-2.5

into nuts.ninka.net:/home/davem/src/BK/net-2.5
parents 5c9e7fc0 599d98aa
...@@ -795,7 +795,7 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id ...@@ -795,7 +795,7 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id
memset(catc, 0, sizeof(struct catc)); memset(catc, 0, sizeof(struct catc));
netdev = init_etherdev(0, 0); netdev = alloc_etherdev(0);
if (!netdev) { if (!netdev) {
kfree(catc); kfree(catc);
return -EIO; return -EIO;
...@@ -933,6 +933,17 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id ...@@ -933,6 +933,17 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id
for (i = 0; i < 5; i++) printk("%2.2x:", netdev->dev_addr[i]); for (i = 0; i < 5; i++) printk("%2.2x:", netdev->dev_addr[i]);
printk("%2.2x.\n", netdev->dev_addr[i]); printk("%2.2x.\n", netdev->dev_addr[i]);
usb_set_intfdata(intf, catc); usb_set_intfdata(intf, catc);
if (register_netdev(netdev) != 0) {
usb_set_intfdata(intf, NULL);
usb_free_urb(catc->ctrl_urb);
usb_free_urb(catc->tx_urb);
usb_free_urb(catc->rx_urb);
usb_free_urb(catc->irq_urb);
kfree(netdev);
kfree(catc);
return -EIO;
}
return 0; return 0;
} }
......
...@@ -1216,7 +1216,7 @@ static int CDCEther_probe( struct usb_interface *intf, ...@@ -1216,7 +1216,7 @@ static int CDCEther_probe( struct usb_interface *intf,
} }
// Now we need to get a kernel Ethernet interface. // Now we need to get a kernel Ethernet interface.
net = init_etherdev( NULL, 0 ); net = alloc_etherdev(0);
if ( !net ) { if ( !net ) {
// Hmm... The kernel is not sharing today... // Hmm... The kernel is not sharing today...
// Fine, we didn't want it anyway... // Fine, we didn't want it anyway...
...@@ -1263,6 +1263,11 @@ static int CDCEther_probe( struct usb_interface *intf, ...@@ -1263,6 +1263,11 @@ static int CDCEther_probe( struct usb_interface *intf,
// TODO - last minute HACK // TODO - last minute HACK
ether_dev->comm_ep_in = 5; ether_dev->comm_ep_in = 5;
if (register_netdev(net) != 0) {
usb_put_dev(usb);
goto out;
}
/* FIXME!!! This driver needs to be fixed to work with the new USB interface logic /* FIXME!!! This driver needs to be fixed to work with the new USB interface logic
* this is not the correct thing to be doing here, we need to set the interface * this is not the correct thing to be doing here, we need to set the interface
* driver specific data field. * driver specific data field.
...@@ -1270,6 +1275,13 @@ static int CDCEther_probe( struct usb_interface *intf, ...@@ -1270,6 +1275,13 @@ static int CDCEther_probe( struct usb_interface *intf,
// Okay, we are finally done... // Okay, we are finally done...
return 0; return 0;
out:
usb_driver_release_interface( &CDCEther_driver,
&(usb->config[ether_dev->configuration_num].interface[ether_dev->comm_interface]) );
usb_driver_release_interface( &CDCEther_driver,
&(usb->config[ether_dev->configuration_num].interface[ether_dev->data_interface]) );
// bailing out with our tail between our knees // bailing out with our tail between our knees
error_all: error_all:
usb_free_urb(ether_dev->tx_urb); usb_free_urb(ether_dev->tx_urb);
......
...@@ -1016,7 +1016,7 @@ static int kaweth_probe( ...@@ -1016,7 +1016,7 @@ static int kaweth_probe(
kaweth_dbg("Initializing net device."); kaweth_dbg("Initializing net device.");
if(!(netdev = kmalloc(sizeof(struct net_device), GFP_KERNEL))) { if (!(netdev = alloc_etherdev(0))) {
kfree(kaweth); kfree(kaweth);
return -ENOMEM; return -ENOMEM;
} }
...@@ -1054,18 +1054,21 @@ static int kaweth_probe( ...@@ -1054,18 +1054,21 @@ static int kaweth_probe(
SET_MODULE_OWNER(netdev); SET_MODULE_OWNER(netdev);
if (!init_etherdev(netdev, 0)) { usb_set_intfdata(intf, kaweth);
if (register_netdev(netdev) != 0) {
kaweth_err("Error calling init_etherdev."); kaweth_err("Error calling init_etherdev.");
goto err_tx_and_rx; goto err_intfdata;
} }
kaweth_info("kaweth interface created at %s", kaweth->net->name); kaweth_info("kaweth interface created at %s", kaweth->net->name);
kaweth_dbg("Kaweth probe returning."); kaweth_dbg("Kaweth probe returning.");
usb_set_intfdata(intf, kaweth);
return 0; return 0;
err_intfdata:
usb_set_intfdata(intf, NULL);
err_tx_and_rx: err_tx_and_rx:
usb_free_urb(kaweth->rx_urb); usb_free_urb(kaweth->rx_urb);
err_only_tx: err_only_tx:
...@@ -1113,6 +1116,7 @@ static void kaweth_disconnect(struct usb_interface *intf) ...@@ -1113,6 +1116,7 @@ static void kaweth_disconnect(struct usb_interface *intf)
kaweth_dbg("Unregistering net device"); kaweth_dbg("Unregistering net device");
unregister_netdev(kaweth->net); unregister_netdev(kaweth->net);
kfree(kaweth->net);
} }
usb_free_urb(kaweth->rx_urb); usb_free_urb(kaweth->rx_urb);
......
...@@ -865,8 +865,6 @@ static int pegasus_open(struct net_device *net) ...@@ -865,8 +865,6 @@ static int pegasus_open(struct net_device *net)
if (!pegasus->rx_skb) if (!pegasus->rx_skb)
return -ENOMEM; return -ENOMEM;
down(&pegasus->sem);
set_registers(pegasus, EthID, 6, net->dev_addr); set_registers(pegasus, EthID, 6, net->dev_addr);
usb_fill_bulk_urb(pegasus->rx_urb, pegasus->usb, usb_fill_bulk_urb(pegasus->rx_urb, pegasus->usb,
...@@ -894,8 +892,6 @@ static int pegasus_open(struct net_device *net) ...@@ -894,8 +892,6 @@ static int pegasus_open(struct net_device *net)
set_carrier(net); set_carrier(net);
res = 0; res = 0;
exit: exit:
up(&pegasus->sem);
return res; return res;
} }
...@@ -903,13 +899,11 @@ static int pegasus_close(struct net_device *net) ...@@ -903,13 +899,11 @@ static int pegasus_close(struct net_device *net)
{ {
pegasus_t *pegasus = net->priv; pegasus_t *pegasus = net->priv;
down(&pegasus->sem);
pegasus->flags &= ~PEGASUS_RUNNING; pegasus->flags &= ~PEGASUS_RUNNING;
netif_stop_queue(net); netif_stop_queue(net);
if (!(pegasus->flags & PEGASUS_UNPLUG)) if (!(pegasus->flags & PEGASUS_UNPLUG))
disable_net_traffic(pegasus); disable_net_traffic(pegasus);
unlink_all_urbs(pegasus); unlink_all_urbs(pegasus);
up(&pegasus->sem);
return 0; return 0;
} }
...@@ -1068,7 +1062,6 @@ static int pegasus_ioctl(struct net_device *net, struct ifreq *rq, int cmd) ...@@ -1068,7 +1062,6 @@ static int pegasus_ioctl(struct net_device *net, struct ifreq *rq, int cmd)
pegasus_t *pegasus = net->priv; pegasus_t *pegasus = net->priv;
int res; int res;
down(&pegasus->sem);
switch (cmd) { switch (cmd) {
case SIOCETHTOOL: case SIOCETHTOOL:
res = pegasus_ethtool_ioctl(net, rq->ifr_data); res = pegasus_ethtool_ioctl(net, rq->ifr_data);
...@@ -1080,17 +1073,14 @@ static int pegasus_ioctl(struct net_device *net, struct ifreq *rq, int cmd) ...@@ -1080,17 +1073,14 @@ static int pegasus_ioctl(struct net_device *net, struct ifreq *rq, int cmd)
res = 0; res = 0;
break; break;
case SIOCDEVPRIVATE + 2: case SIOCDEVPRIVATE + 2:
if (!capable(CAP_NET_ADMIN)) { if (!capable(CAP_NET_ADMIN))
up(&pegasus->sem);
return -EPERM; return -EPERM;
}
write_mii_word(pegasus, pegasus->phy, data[1] & 0x1f, data[2]); write_mii_word(pegasus, pegasus->phy, data[1] & 0x1f, data[2]);
res = 0; res = 0;
break; break;
default: default:
res = -EOPNOTSUPP; res = -EOPNOTSUPP;
} }
up(&pegasus->sem);
return res; return res;
} }
...@@ -1170,33 +1160,27 @@ static int pegasus_probe(struct usb_interface *intf, ...@@ -1170,33 +1160,27 @@ static int pegasus_probe(struct usb_interface *intf,
struct net_device *net; struct net_device *net;
pegasus_t *pegasus; pegasus_t *pegasus;
int dev_index = id - pegasus_ids; int dev_index = id - pegasus_ids;
int res = -ENOMEM;
usb_get_dev(dev);
if (!(pegasus = kmalloc(sizeof (struct pegasus), GFP_KERNEL))) { if (!(pegasus = kmalloc(sizeof (struct pegasus), GFP_KERNEL))) {
err("out of memory allocating device structure"); err("out of memory allocating device structure");
return -ENOMEM; goto out;
} }
usb_get_dev(dev);
memset(pegasus, 0, sizeof (struct pegasus)); memset(pegasus, 0, sizeof (struct pegasus));
pegasus->dev_index = dev_index; pegasus->dev_index = dev_index;
init_waitqueue_head(&pegasus->ctrl_wait); init_waitqueue_head(&pegasus->ctrl_wait);
if (!alloc_urbs(pegasus)) { if (!alloc_urbs(pegasus))
kfree(pegasus); goto out1;
return -ENOMEM;
}
net = init_etherdev(NULL, 0); net = alloc_etherdev(0);
if (!net) { if (!net)
free_all_urbs(pegasus); goto out2;
kfree(pegasus);
return -ENODEV;
}
init_MUTEX(&pegasus->sem);
tasklet_init(&pegasus->rx_tl, rx_fixup, (unsigned long) pegasus); tasklet_init(&pegasus->rx_tl, rx_fixup, (unsigned long) pegasus);
down(&pegasus->sem);
pegasus->usb = dev; pegasus->usb = dev;
pegasus->net = net; pegasus->net = net;
SET_MODULE_OWNER(net); SET_MODULE_OWNER(net);
...@@ -1221,12 +1205,8 @@ static int pegasus_probe(struct usb_interface *intf, ...@@ -1221,12 +1205,8 @@ static int pegasus_probe(struct usb_interface *intf,
get_interrupt_interval(pegasus); get_interrupt_interval(pegasus);
if (reset_mac(pegasus)) { if (reset_mac(pegasus)) {
err("can't reset MAC"); err("can't reset MAC");
unregister_netdev(pegasus->net); res = -EIO;
free_all_urbs(pegasus); goto out3;
kfree(pegasus->net);
kfree(pegasus);
pegasus = NULL;
goto exit;
} }
set_ethernet_addr(pegasus); set_ethernet_addr(pegasus);
fill_skb_pool(pegasus); fill_skb_pool(pegasus);
...@@ -1240,13 +1220,24 @@ static int pegasus_probe(struct usb_interface *intf, ...@@ -1240,13 +1220,24 @@ static int pegasus_probe(struct usb_interface *intf,
warn("can't locate MII phy, using default"); warn("can't locate MII phy, using default");
pegasus->phy = 1; pegasus->phy = 1;
} }
exit:
up(&pegasus->sem);
if (pegasus) {
usb_set_intfdata(intf, pegasus); usb_set_intfdata(intf, pegasus);
res = register_netdev(net);
if (res)
goto out4;
return 0; return 0;
}
return -EIO; out4:
usb_set_intfdata(intf, NULL);
free_skb_pool(pegasus);
out3:
kfree(net);
out2:
free_all_urbs(pegasus);
out1:
kfree(pegasus);
out:
usb_put_dev(dev);
return res;
} }
static void pegasus_disconnect(struct usb_interface *intf) static void pegasus_disconnect(struct usb_interface *intf)
...@@ -1269,7 +1260,6 @@ static void pegasus_disconnect(struct usb_interface *intf) ...@@ -1269,7 +1260,6 @@ static void pegasus_disconnect(struct usb_interface *intf)
dev_kfree_skb(pegasus->rx_skb); dev_kfree_skb(pegasus->rx_skb);
kfree(pegasus->net); kfree(pegasus->net);
kfree(pegasus); kfree(pegasus);
pegasus = NULL;
} }
static struct usb_driver pegasus_driver = { static struct usb_driver pegasus_driver = {
......
...@@ -98,7 +98,6 @@ typedef struct pegasus { ...@@ -98,7 +98,6 @@ typedef struct pegasus {
struct sk_buff *rx_skb; struct sk_buff *rx_skb;
struct usb_ctrlrequest dr; struct usb_ctrlrequest dr;
wait_queue_head_t ctrl_wait; wait_queue_head_t ctrl_wait;
struct semaphore sem;
spinlock_t rx_pool_lock; spinlock_t rx_pool_lock;
int chip; int chip;
unsigned char intr_buff[8]; unsigned char intr_buff[8];
......
...@@ -88,7 +88,6 @@ MODULE_DEVICE_TABLE(usb, rtl8150_table); ...@@ -88,7 +88,6 @@ MODULE_DEVICE_TABLE(usb, rtl8150_table);
struct rtl8150 { struct rtl8150 {
unsigned long flags; unsigned long flags;
struct usb_device *udev; struct usb_device *udev;
struct semaphore sem;
struct tasklet_struct tl; struct tasklet_struct tl;
struct net_device_stats stats; struct net_device_stats stats;
struct net_device *netdev; struct net_device *netdev;
...@@ -638,8 +637,6 @@ static int rtl8150_open(struct net_device *netdev) ...@@ -638,8 +637,6 @@ static int rtl8150_open(struct net_device *netdev)
if (!dev->rx_skb) if (!dev->rx_skb)
return -ENOMEM; return -ENOMEM;
down(&dev->sem);
set_registers(dev, IDR, 6, netdev->dev_addr); set_registers(dev, IDR, 6, netdev->dev_addr);
usb_fill_bulk_urb(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1), usb_fill_bulk_urb(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1),
...@@ -653,7 +650,6 @@ static int rtl8150_open(struct net_device *netdev) ...@@ -653,7 +650,6 @@ static int rtl8150_open(struct net_device *netdev)
warn("%s: intr_urb submit failed: %d", __FUNCTION__, res); warn("%s: intr_urb submit failed: %d", __FUNCTION__, res);
netif_start_queue(netdev); netif_start_queue(netdev);
enable_net_traffic(dev); enable_net_traffic(dev);
up(&dev->sem);
return res; return res;
} }
...@@ -667,12 +663,10 @@ static int rtl8150_close(struct net_device *netdev) ...@@ -667,12 +663,10 @@ static int rtl8150_close(struct net_device *netdev)
if (!dev) if (!dev)
return -ENODEV; return -ENODEV;
down(&dev->sem);
netif_stop_queue(netdev); netif_stop_queue(netdev);
if (!test_bit(RTL8150_UNPLUG, &dev->flags)) if (!test_bit(RTL8150_UNPLUG, &dev->flags))
disable_net_traffic(dev); disable_net_traffic(dev);
unlink_all_urbs(dev); unlink_all_urbs(dev);
up(&dev->sem);
return res; return res;
} }
...@@ -760,7 +754,6 @@ static int rtl8150_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd) ...@@ -760,7 +754,6 @@ static int rtl8150_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd)
data = (u16 *) & rq->ifr_data; data = (u16 *) & rq->ifr_data;
res = 0; res = 0;
down(&dev->sem);
switch (cmd) { switch (cmd) {
case SIOCETHTOOL: case SIOCETHTOOL:
res = rtl8150_ethtool_ioctl(netdev, rq->ifr_data); res = rtl8150_ethtool_ioctl(netdev, rq->ifr_data);
...@@ -771,16 +764,13 @@ static int rtl8150_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd) ...@@ -771,16 +764,13 @@ static int rtl8150_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd)
read_mii_word(dev, dev->phy, (data[1] & 0x1f), &data[3]); read_mii_word(dev, dev->phy, (data[1] & 0x1f), &data[3]);
break; break;
case SIOCDEVPRIVATE + 2: case SIOCDEVPRIVATE + 2:
if (!capable(CAP_NET_ADMIN)) { if (!capable(CAP_NET_ADMIN))
up(&dev->sem);
return -EPERM; return -EPERM;
}
write_mii_word(dev, dev->phy, (data[1] & 0x1f), data[2]); write_mii_word(dev, dev->phy, (data[1] & 0x1f), data[2]);
break; break;
default: default:
res = -EOPNOTSUPP; res = -EOPNOTSUPP;
} }
up(&dev->sem);
return res; return res;
} }
...@@ -798,18 +788,16 @@ static int rtl8150_probe(struct usb_interface *intf, ...@@ -798,18 +788,16 @@ static int rtl8150_probe(struct usb_interface *intf,
} else } else
memset(dev, 0, sizeof(rtl8150_t)); memset(dev, 0, sizeof(rtl8150_t));
netdev = init_etherdev(NULL, 0); netdev = alloc_etherdev(0);
if (!netdev) { if (!netdev) {
kfree(dev); kfree(dev);
err("Oh boy, out of memory again?!?"); err("Oh boy, out of memory again?!?");
return -ENOMEM; return -ENOMEM;
} }
init_MUTEX(&dev->sem);
tasklet_init(&dev->tl, rx_fixup, (unsigned long)dev); tasklet_init(&dev->tl, rx_fixup, (unsigned long)dev);
spin_lock_init(&dev->rx_pool_lock); spin_lock_init(&dev->rx_pool_lock);
down(&dev->sem);
dev->udev = udev; dev->udev = udev;
dev->netdev = netdev; dev->netdev = netdev;
SET_MODULE_OWNER(netdev); SET_MODULE_OWNER(netdev);
...@@ -828,23 +816,30 @@ static int rtl8150_probe(struct usb_interface *intf, ...@@ -828,23 +816,30 @@ static int rtl8150_probe(struct usb_interface *intf,
if (!alloc_all_urbs(dev)) { if (!alloc_all_urbs(dev)) {
err("out of memory"); err("out of memory");
goto err; goto out;
} }
if (!rtl8150_reset(dev)) { if (!rtl8150_reset(dev)) {
err("couldn't reset the device"); err("couldn't reset the device");
free_all_urbs(dev); goto out1;
goto err;
} }
fill_skb_pool(dev); fill_skb_pool(dev);
set_ethernet_addr(dev); set_ethernet_addr(dev);
info("%s: rtl8150 is detected", netdev->name); info("%s: rtl8150 is detected", netdev->name);
up(&dev->sem);
usb_set_intfdata(intf, dev); usb_set_intfdata(intf, dev);
if (register_netdev(netdev) != 0) {
err("couldn't register the device");
goto out2;
}
return 0; return 0;
err:
unregister_netdev(dev->netdev); out2:
up(&dev->sem); usb_set_intfdata(intf, NULL);
free_skb_pool(dev);
out1:
free_all_urbs(dev);
out:
kfree(netdev); kfree(netdev);
kfree(dev); kfree(dev);
return -EIO; return -EIO;
...@@ -865,8 +860,6 @@ static void rtl8150_disconnect(struct usb_interface *intf) ...@@ -865,8 +860,6 @@ static void rtl8150_disconnect(struct usb_interface *intf)
dev_kfree_skb(dev->rx_skb); dev_kfree_skb(dev->rx_skb);
kfree(dev->netdev); kfree(dev->netdev);
kfree(dev); kfree(dev);
dev->netdev = NULL;
dev = NULL;
} }
} }
......
...@@ -205,7 +205,6 @@ struct usbnet { ...@@ -205,7 +205,6 @@ struct usbnet {
// housekeeping // housekeeping
struct usb_device *udev; struct usb_device *udev;
struct driver_info *driver_info; struct driver_info *driver_info;
struct semaphore mutex;
wait_queue_head_t *wait; wait_queue_head_t *wait;
// i/o info: pipes etc // i/o info: pipes etc
...@@ -214,7 +213,7 @@ struct usbnet { ...@@ -214,7 +213,7 @@ struct usbnet {
struct timer_list delay; struct timer_list delay;
// protocol/interface state // protocol/interface state
struct net_device net; struct net_device *net;
struct net_device_stats stats; struct net_device_stats stats;
int msg_level; int msg_level;
unsigned long data [5]; unsigned long data [5];
...@@ -295,27 +294,24 @@ MODULE_PARM (msg_level, "i"); ...@@ -295,27 +294,24 @@ MODULE_PARM (msg_level, "i");
MODULE_PARM_DESC (msg_level, "Initial message level (default = 1)"); MODULE_PARM_DESC (msg_level, "Initial message level (default = 1)");
#define mutex_lock(x) down(x)
#define mutex_unlock(x) up(x)
#define RUN_CONTEXT (in_irq () ? "in_irq" \ #define RUN_CONTEXT (in_irq () ? "in_irq" \
: (in_interrupt () ? "in_interrupt" : "can sleep")) : (in_interrupt () ? "in_interrupt" : "can sleep"))
#ifdef DEBUG #ifdef DEBUG
#define devdbg(usbnet, fmt, arg...) \ #define devdbg(usbnet, fmt, arg...) \
printk(KERN_DEBUG "%s: " fmt "\n" , (usbnet)->net.name , ## arg) printk(KERN_DEBUG "%s: " fmt "\n" , (usbnet)->net->name , ## arg)
#else #else
#define devdbg(usbnet, fmt, arg...) do {} while(0) #define devdbg(usbnet, fmt, arg...) do {} while(0)
#endif #endif
#define deverr(usbnet, fmt, arg...) \ #define deverr(usbnet, fmt, arg...) \
printk(KERN_ERR "%s: " fmt "\n" , (usbnet)->net.name , ## arg) printk(KERN_ERR "%s: " fmt "\n" , (usbnet)->net->name , ## arg)
#define devwarn(usbnet, fmt, arg...) \ #define devwarn(usbnet, fmt, arg...) \
printk(KERN_WARNING "%s: " fmt "\n" , (usbnet)->net.name , ## arg) printk(KERN_WARNING "%s: " fmt "\n" , (usbnet)->net->name , ## arg)
#define devinfo(usbnet, fmt, arg...) \ #define devinfo(usbnet, fmt, arg...) \
do { if ((usbnet)->msg_level >= 1) \ do { if ((usbnet)->msg_level >= 1) \
printk(KERN_INFO "%s: " fmt "\n" , (usbnet)->net.name , ## arg); \ printk(KERN_INFO "%s: " fmt "\n" , (usbnet)->net->name , ## arg); \
} while (0) } while (0)
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
...@@ -505,7 +501,7 @@ static inline int get_ethernet_addr (struct usbnet *dev, struct ether_desc *e) ...@@ -505,7 +501,7 @@ static inline int get_ethernet_addr (struct usbnet *dev, struct ether_desc *e)
else if (tmp != 12) else if (tmp != 12)
return -EINVAL; return -EINVAL;
for (i = tmp = 0; i < 6; i++, tmp += 2) for (i = tmp = 0; i < 6; i++, tmp += 2)
dev->net.dev_addr [i] = dev->net->dev_addr [i] =
(nibble (buf [tmp]) << 4) + nibble (buf [tmp + 1]); (nibble (buf [tmp]) << 4) + nibble (buf [tmp + 1]);
return 0; return 0;
} }
...@@ -605,7 +601,7 @@ static int cdc_bind (struct usbnet *dev, struct usb_interface *intf) ...@@ -605,7 +601,7 @@ static int cdc_bind (struct usbnet *dev, struct usb_interface *intf)
* in routine cases. info->ether describes the multicast support. * in routine cases. info->ether describes the multicast support.
*/ */
dev->net.mtu = cpu_to_le16p (&info->ether->wMaxSegmentSize) dev->net->mtu = cpu_to_le16p (&info->ether->wMaxSegmentSize)
- ETH_HLEN; - ETH_HLEN;
return 0; return 0;
...@@ -806,18 +802,18 @@ static int genelink_check_connect (struct usbnet *dev) ...@@ -806,18 +802,18 @@ static int genelink_check_connect (struct usbnet *dev)
// detect whether another side is connected // detect whether another side is connected
if ((retval = gl_control_write (dev, GENELINK_CONNECT_WRITE, 0)) != 0) { if ((retval = gl_control_write (dev, GENELINK_CONNECT_WRITE, 0)) != 0) {
dbg ("%s: genelink_check_connect write fail - %X", dbg ("%s: genelink_check_connect write fail - %X",
dev->net.name, retval); dev->net->name, retval);
return retval; return retval;
} }
// usb interrupt read to ack another side // usb interrupt read to ack another side
if ((retval = gl_interrupt_read (dev)) != 0) { if ((retval = gl_interrupt_read (dev)) != 0) {
dbg ("%s: genelink_check_connect read fail - %X", dbg ("%s: genelink_check_connect read fail - %X",
dev->net.name, retval); dev->net->name, retval);
return retval; return retval;
} }
dbg ("%s: genelink_check_connect read success", dev->net.name); dbg ("%s: genelink_check_connect read success", dev->net->name);
return 0; return 0;
} }
...@@ -829,14 +825,14 @@ static int genelink_init (struct usbnet *dev) ...@@ -829,14 +825,14 @@ static int genelink_init (struct usbnet *dev)
// allocate the private data structure // allocate the private data structure
if ((priv = kmalloc (sizeof *priv, GFP_KERNEL)) == 0) { if ((priv = kmalloc (sizeof *priv, GFP_KERNEL)) == 0) {
dbg ("%s: cannot allocate private data per device", dbg ("%s: cannot allocate private data per device",
dev->net.name); dev->net->name);
return -ENOMEM; return -ENOMEM;
} }
// allocate irq urb // allocate irq urb
if ((priv->irq_urb = usb_alloc_urb (0, GFP_KERNEL)) == 0) { if ((priv->irq_urb = usb_alloc_urb (0, GFP_KERNEL)) == 0) {
dbg ("%s: cannot allocate private irq urb per device", dbg ("%s: cannot allocate private irq urb per device",
dev->net.name); dev->net->name);
kfree (priv); kfree (priv);
return -ENOMEM; return -ENOMEM;
} }
...@@ -920,14 +916,11 @@ static int genelink_rx_fixup (struct usbnet *dev, struct sk_buff *skb) ...@@ -920,14 +916,11 @@ static int genelink_rx_fixup (struct usbnet *dev, struct sk_buff *skb)
if (gl_skb) { if (gl_skb) {
// copy the packet data to the new skb // copy the packet data to the new skb
memcpy (gl_skb->data, packet->packet_data, size); memcpy(skb_put(gl_skb, size), packet->packet_data, size);
gl_skb->dev = dev->net;
// set skb data size
gl_skb->len = size;
gl_skb->dev = &dev->net;
// determine the packet's protocol ID // determine the packet's protocol ID
gl_skb->protocol = eth_type_trans (gl_skb, &dev->net); gl_skb->protocol = eth_type_trans (gl_skb, dev->net);
// update the status // update the status
dev->stats.rx_packets++; dev->stats.rx_packets++;
...@@ -1143,7 +1136,7 @@ static void nc_dump_registers (struct usbnet *dev) ...@@ -1143,7 +1136,7 @@ static void nc_dump_registers (struct usbnet *dev)
return; return;
} }
dbg ("%s registers:", dev->net.name); dbg ("%s registers:", dev->net->name);
for (reg = 0; reg < 0x20; reg++) { for (reg = 0; reg < 0x20; reg++) {
int retval; int retval;
...@@ -1156,10 +1149,10 @@ static void nc_dump_registers (struct usbnet *dev) ...@@ -1156,10 +1149,10 @@ static void nc_dump_registers (struct usbnet *dev)
retval = nc_register_read (dev, reg, vp); retval = nc_register_read (dev, reg, vp);
if (retval < 0) if (retval < 0)
dbg ("%s reg [0x%x] ==> error %d", dbg ("%s reg [0x%x] ==> error %d",
dev->net.name, reg, retval); dev->net->name, reg, retval);
else else
dbg ("%s reg [0x%x] = 0x%x", dbg ("%s reg [0x%x] = 0x%x",
dev->net.name, reg, *vp); dev->net->name, reg, *vp);
} }
kfree (vp); kfree (vp);
} }
...@@ -1321,7 +1314,7 @@ static int net1080_reset (struct usbnet *dev) ...@@ -1321,7 +1314,7 @@ static int net1080_reset (struct usbnet *dev)
nc_register_write (dev, REG_TTL, nc_register_write (dev, REG_TTL,
MK_TTL (NC_READ_TTL_MS, TTL_OTHER (ttl)) ); MK_TTL (NC_READ_TTL_MS, TTL_OTHER (ttl)) );
dbg ("%s: assigned TTL, %d ms", dev->net.name, NC_READ_TTL_MS); dbg ("%s: assigned TTL, %d ms", dev->net->name, NC_READ_TTL_MS);
if (dev->msg_level >= 2) if (dev->msg_level >= 2)
devinfo (dev, "port %c, peer %sconnected", devinfo (dev, "port %c, peer %sconnected",
...@@ -1347,7 +1340,7 @@ static int net1080_check_connect (struct usbnet *dev) ...@@ -1347,7 +1340,7 @@ static int net1080_check_connect (struct usbnet *dev)
status = *vp; status = *vp;
kfree (vp); kfree (vp);
if (retval != 0) { if (retval != 0) {
dbg ("%s net1080_check_conn read - %d", dev->net.name, retval); dbg ("%s net1080_check_conn read - %d", dev->net->name, retval);
return retval; return retval;
} }
if ((status & STATUS_CONN_OTHER) != STATUS_CONN_OTHER) if ((status & STATUS_CONN_OTHER) != STATUS_CONN_OTHER)
...@@ -1416,11 +1409,11 @@ static int net1080_rx_fixup (struct usbnet *dev, struct sk_buff *skb) ...@@ -1416,11 +1409,11 @@ static int net1080_rx_fixup (struct usbnet *dev, struct sk_buff *skb)
if (!(skb->len & 0x01) if (!(skb->len & 0x01)
|| MIN_FRAMED > skb->len || MIN_FRAMED > skb->len
|| skb->len > FRAMED_SIZE (dev->net.mtu)) { || skb->len > FRAMED_SIZE (dev->net->mtu)) {
dev->stats.rx_frame_errors++; dev->stats.rx_frame_errors++;
dbg ("rx framesize %d range %d..%d mtu %d", skb->len, dbg ("rx framesize %d range %d..%d mtu %d", skb->len,
(int)MIN_FRAMED, (int)FRAMED_SIZE (dev->net.mtu), (int)MIN_FRAMED, (int)FRAMED_SIZE (dev->net->mtu),
dev->net.mtu); dev->net->mtu);
nc_ensure_sync (dev); nc_ensure_sync (dev);
return 0; return 0;
} }
...@@ -1795,7 +1788,7 @@ static void rx_submit (struct usbnet *dev, struct urb *urb, int flags) ...@@ -1795,7 +1788,7 @@ static void rx_submit (struct usbnet *dev, struct urb *urb, int flags)
#ifdef CONFIG_USB_NET1080 #ifdef CONFIG_USB_NET1080
if (dev->driver_info->flags & FLAG_FRAMING_NC) if (dev->driver_info->flags & FLAG_FRAMING_NC)
size = FRAMED_SIZE (dev->net.mtu); size = FRAMED_SIZE (dev->net->mtu);
else else
#endif #endif
#ifdef CONFIG_USB_GENESYS #ifdef CONFIG_USB_GENESYS
...@@ -1805,10 +1798,10 @@ static void rx_submit (struct usbnet *dev, struct urb *urb, int flags) ...@@ -1805,10 +1798,10 @@ static void rx_submit (struct usbnet *dev, struct urb *urb, int flags)
#endif #endif
#ifdef CONFIG_USB_ZAURUS #ifdef CONFIG_USB_ZAURUS
if (dev->driver_info->flags & FLAG_FRAMING_Z) if (dev->driver_info->flags & FLAG_FRAMING_Z)
size = 6 + (sizeof (struct ethhdr) + dev->net.mtu); size = 6 + (sizeof (struct ethhdr) + dev->net->mtu);
else else
#endif #endif
size = (sizeof (struct ethhdr) + dev->net.mtu); size = (sizeof (struct ethhdr) + dev->net->mtu);
if ((skb = alloc_skb (size, flags)) == 0) { if ((skb = alloc_skb (size, flags)) == 0) {
devdbg (dev, "no rx skb"); devdbg (dev, "no rx skb");
...@@ -1829,8 +1822,8 @@ static void rx_submit (struct usbnet *dev, struct urb *urb, int flags) ...@@ -1829,8 +1822,8 @@ static void rx_submit (struct usbnet *dev, struct urb *urb, int flags)
spin_lock_irqsave (&dev->rxq.lock, lockflags); spin_lock_irqsave (&dev->rxq.lock, lockflags);
if (netif_running (&dev->net) if (netif_running (dev->net)
&& netif_device_present (&dev->net) && netif_device_present (dev->net)
&& !test_bit (EVENT_RX_HALT, &dev->flags)) { && !test_bit (EVENT_RX_HALT, &dev->flags)) {
switch (retval = usb_submit_urb (urb, GFP_ATOMIC)){ switch (retval = usb_submit_urb (urb, GFP_ATOMIC)){
case -EPIPE: case -EPIPE:
...@@ -1841,7 +1834,7 @@ static void rx_submit (struct usbnet *dev, struct urb *urb, int flags) ...@@ -1841,7 +1834,7 @@ static void rx_submit (struct usbnet *dev, struct urb *urb, int flags)
break; break;
case -ENODEV: case -ENODEV:
devdbg (dev, "device gone"); devdbg (dev, "device gone");
netif_device_detach (&dev->net); netif_device_detach (dev->net);
break; break;
default: default:
devdbg (dev, "rx submit, %d", retval); devdbg (dev, "rx submit, %d", retval);
...@@ -1874,8 +1867,8 @@ static inline void rx_process (struct usbnet *dev, struct sk_buff *skb) ...@@ -1874,8 +1867,8 @@ static inline void rx_process (struct usbnet *dev, struct sk_buff *skb)
if (skb->len) { if (skb->len) {
int status; int status;
skb->dev = &dev->net; skb->dev = dev->net;
skb->protocol = eth_type_trans (skb, &dev->net); skb->protocol = eth_type_trans (skb, dev->net);
dev->stats.rx_packets++; dev->stats.rx_packets++;
dev->stats.rx_bytes += skb->len; dev->stats.rx_bytes += skb->len;
...@@ -1968,7 +1961,7 @@ static void rx_complete (struct urb *urb, struct pt_regs *regs) ...@@ -1968,7 +1961,7 @@ static void rx_complete (struct urb *urb, struct pt_regs *regs)
defer_bh (dev, skb); defer_bh (dev, skb);
if (urb) { if (urb) {
if (netif_running (&dev->net) if (netif_running (dev->net)
&& !test_bit (EVENT_RX_HALT, &dev->flags)) { && !test_bit (EVENT_RX_HALT, &dev->flags)) {
rx_submit (dev, urb, GFP_ATOMIC); rx_submit (dev, urb, GFP_ATOMIC);
return; return;
...@@ -2024,7 +2017,6 @@ static int usbnet_stop (struct net_device *net) ...@@ -2024,7 +2017,6 @@ static int usbnet_stop (struct net_device *net)
DECLARE_WAIT_QUEUE_HEAD (unlink_wakeup); DECLARE_WAIT_QUEUE_HEAD (unlink_wakeup);
DECLARE_WAITQUEUE (wait, current); DECLARE_WAITQUEUE (wait, current);
mutex_lock (&dev->mutex);
netif_stop_queue (net); netif_stop_queue (net);
if (dev->msg_level >= 2) if (dev->msg_level >= 2)
...@@ -2054,7 +2046,6 @@ static int usbnet_stop (struct net_device *net) ...@@ -2054,7 +2046,6 @@ static int usbnet_stop (struct net_device *net)
del_timer_sync (&dev->delay); del_timer_sync (&dev->delay);
tasklet_kill (&dev->bh); tasklet_kill (&dev->bh);
mutex_unlock (&dev->mutex);
return 0; return 0;
} }
...@@ -2070,8 +2061,6 @@ static int usbnet_open (struct net_device *net) ...@@ -2070,8 +2061,6 @@ static int usbnet_open (struct net_device *net)
int retval = 0; int retval = 0;
struct driver_info *info = dev->driver_info; struct driver_info *info = dev->driver_info;
mutex_lock (&dev->mutex);
// put into "known safe" state // put into "known safe" state
if (info->reset && (retval = info->reset (dev)) < 0) { if (info->reset && (retval = info->reset (dev)) < 0) {
devinfo (dev, "open reset fail (%d) usbnet usb-%s-%s, %s", devinfo (dev, "open reset fail (%d) usbnet usb-%s-%s, %s",
...@@ -2091,7 +2080,7 @@ static int usbnet_open (struct net_device *net) ...@@ -2091,7 +2080,7 @@ static int usbnet_open (struct net_device *net)
if (dev->msg_level >= 2) if (dev->msg_level >= 2)
devinfo (dev, "open: enable queueing " devinfo (dev, "open: enable queueing "
"(rx %d, tx %d) mtu %d %s framing", "(rx %d, tx %d) mtu %d %s framing",
RX_QLEN (dev), TX_QLEN (dev), dev->net.mtu, RX_QLEN (dev), TX_QLEN (dev), dev->net->mtu,
(info->flags & (FLAG_FRAMING_NC | FLAG_FRAMING_GL)) (info->flags & (FLAG_FRAMING_NC | FLAG_FRAMING_GL))
? ((info->flags & FLAG_FRAMING_NC) ? ((info->flags & FLAG_FRAMING_NC)
? "NetChip" ? "NetChip"
...@@ -2102,7 +2091,6 @@ static int usbnet_open (struct net_device *net) ...@@ -2102,7 +2091,6 @@ static int usbnet_open (struct net_device *net)
// delay posting reads until we're fully open // delay posting reads until we're fully open
tasklet_schedule (&dev->bh); tasklet_schedule (&dev->bh);
done: done:
mutex_unlock (&dev->mutex);
return retval; return retval;
} }
...@@ -2201,7 +2189,7 @@ kevent (void *data) ...@@ -2201,7 +2189,7 @@ kevent (void *data)
status); status);
else { else {
clear_bit (EVENT_TX_HALT, &dev->flags); clear_bit (EVENT_TX_HALT, &dev->flags);
netif_wake_queue (&dev->net); netif_wake_queue (dev->net);
} }
} }
if (test_bit (EVENT_RX_HALT, &dev->flags)) { if (test_bit (EVENT_RX_HALT, &dev->flags)) {
...@@ -2220,7 +2208,7 @@ kevent (void *data) ...@@ -2220,7 +2208,7 @@ kevent (void *data)
if (test_bit (EVENT_RX_MEMORY, &dev->flags)) { if (test_bit (EVENT_RX_MEMORY, &dev->flags)) {
struct urb *urb = 0; struct urb *urb = 0;
if (netif_running (&dev->net)) if (netif_running (dev->net))
urb = usb_alloc_urb (0, GFP_KERNEL); urb = usb_alloc_urb (0, GFP_KERNEL);
else else
clear_bit (EVENT_RX_MEMORY, &dev->flags); clear_bit (EVENT_RX_MEMORY, &dev->flags);
...@@ -2265,7 +2253,7 @@ static void tx_complete (struct urb *urb, struct pt_regs *regs) ...@@ -2265,7 +2253,7 @@ static void tx_complete (struct urb *urb, struct pt_regs *regs)
jiffies + THROTTLE_JIFFIES); jiffies + THROTTLE_JIFFIES);
devdbg (dev, "tx throttle %d", urb->status); devdbg (dev, "tx throttle %d", urb->status);
} }
netif_stop_queue (&dev->net); netif_stop_queue (dev->net);
break; break;
default: default:
devdbg (dev, "tx err %d", entry->urb->status); devdbg (dev, "tx err %d", entry->urb->status);
...@@ -2438,8 +2426,8 @@ static void usbnet_bh (unsigned long param) ...@@ -2438,8 +2426,8 @@ static void usbnet_bh (unsigned long param)
} }
// or are we maybe short a few urbs? // or are we maybe short a few urbs?
} else if (netif_running (&dev->net) } else if (netif_running (dev->net)
&& netif_device_present (&dev->net) && netif_device_present (dev->net)
&& !timer_pending (&dev->delay) && !timer_pending (&dev->delay)
&& !test_bit (EVENT_RX_HALT, &dev->flags)) { && !test_bit (EVENT_RX_HALT, &dev->flags)) {
int temp = dev->rxq.qlen; int temp = dev->rxq.qlen;
...@@ -2461,7 +2449,7 @@ static void usbnet_bh (unsigned long param) ...@@ -2461,7 +2449,7 @@ static void usbnet_bh (unsigned long param)
tasklet_schedule (&dev->bh); tasklet_schedule (&dev->bh);
} }
if (dev->txq.qlen < TX_QLEN (dev)) if (dev->txq.qlen < TX_QLEN (dev))
netif_wake_queue (&dev->net); netif_wake_queue (dev->net);
} }
} }
...@@ -2491,11 +2479,12 @@ static void usbnet_disconnect (struct usb_interface *intf) ...@@ -2491,11 +2479,12 @@ static void usbnet_disconnect (struct usb_interface *intf)
xdev->bus->bus_name, xdev->devpath, xdev->bus->bus_name, xdev->devpath,
dev->driver_info->description); dev->driver_info->description);
unregister_netdev (&dev->net); unregister_netdev (dev->net);
if (dev->driver_info->unbind) if (dev->driver_info->unbind)
dev->driver_info->unbind (dev, intf); dev->driver_info->unbind (dev, intf);
kfree(dev->net);
kfree (dev); kfree (dev);
usb_put_dev (xdev); usb_put_dev (xdev);
} }
...@@ -2523,15 +2512,17 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) ...@@ -2523,15 +2512,17 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
xdev = interface_to_usbdev (udev); xdev = interface_to_usbdev (udev);
interface = &udev->altsetting [udev->act_altsetting]; interface = &udev->altsetting [udev->act_altsetting];
usb_get_dev (xdev);
status = -ENOMEM;
// set up our own records // set up our own records
if (!(dev = kmalloc (sizeof *dev, GFP_KERNEL))) { if (!(dev = kmalloc (sizeof *dev, GFP_KERNEL))) {
dbg ("can't kmalloc dev"); dbg ("can't kmalloc dev");
return -ENOMEM; goto out;
} }
memset (dev, 0, sizeof *dev); memset (dev, 0, sizeof *dev);
init_MUTEX_LOCKED (&dev->mutex);
usb_get_dev (xdev);
dev->udev = xdev; dev->udev = xdev;
dev->driver_info = info; dev->driver_info = info;
dev->msg_level = msg_level; dev->msg_level = msg_level;
...@@ -2546,16 +2537,16 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) ...@@ -2546,16 +2537,16 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
init_timer (&dev->delay); init_timer (&dev->delay);
// set up network interface records // set up network interface records
net = &dev->net; net = alloc_etherdev(0);
if (!net)
goto out1;
SET_MODULE_OWNER (net); SET_MODULE_OWNER (net);
dev->net = net;
net->priv = dev; net->priv = dev;
strcpy (net->name, "usb%d"); strcpy (net->name, "usb%d");
memcpy (net->dev_addr, node_id, sizeof node_id); memcpy (net->dev_addr, node_id, sizeof node_id);
// point-to-point link ... we always use Ethernet headers
// supports win32 interop (some devices) and the bridge driver.
ether_setup (net);
// possible with some EHCI controllers // possible with some EHCI controllers
if (dma_supported (&udev->dev, 0xffffffffffffffffULL)) if (dma_supported (&udev->dev, 0xffffffffffffffffULL))
net->features |= NETIF_F_HIGHDMA; net->features |= NETIF_F_HIGHDMA;
...@@ -2592,26 +2583,37 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) ...@@ -2592,26 +2583,37 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
status = 0; status = 0;
} }
if (status < 0) { if (status < 0)
kfree (dev); goto out2;
return status;
}
dev->maxpacket = usb_maxpacket (dev->udev, dev->out, 1); dev->maxpacket = usb_maxpacket (dev->udev, dev->out, 1);
SET_NETDEV_DEV(&dev->net, &dev->udev->dev); SET_NETDEV_DEV(dev->net, &dev->udev->dev);
register_netdev (&dev->net); status = register_netdev (dev->net);
if (status)
goto out3;
devinfo (dev, "register usbnet at usb-%s-%s, %s", devinfo (dev, "register usbnet at usb-%s-%s, %s",
xdev->bus->bus_name, xdev->devpath, xdev->bus->bus_name, xdev->devpath,
dev->driver_info->description); dev->driver_info->description);
// ok, it's ready to go. // ok, it's ready to go.
usb_set_intfdata (udev, dev); usb_set_intfdata (udev, dev);
mutex_unlock (&dev->mutex);
// start as if the link is up // start as if the link is up
netif_device_attach (&dev->net); netif_device_attach (dev->net);
return 0; return 0;
out3:
if (info->unbind)
info->unbind (dev, udev);
out2:
kfree(net);
out1:
kfree(dev);
out:
usb_put_dev(xdev);
return status;
} }
......
...@@ -333,6 +333,7 @@ struct net_device ...@@ -333,6 +333,7 @@ struct net_device
void *dn_ptr; /* DECnet specific data */ void *dn_ptr; /* DECnet specific data */
void *ip6_ptr; /* IPv6 specific data */ void *ip6_ptr; /* IPv6 specific data */
void *ec_ptr; /* Econet specific data */ void *ec_ptr; /* Econet specific data */
void *ax25_ptr; /* AX.25 specific data */
struct list_head poll_list; /* Link to poll list */ struct list_head poll_list; /* Link to poll list */
int quota; int quota;
......
...@@ -233,7 +233,12 @@ extern void ax25_digi_invert(ax25_digi *, ax25_digi *); ...@@ -233,7 +233,12 @@ extern void ax25_digi_invert(ax25_digi *, ax25_digi *);
/* ax25_dev.c */ /* ax25_dev.c */
extern ax25_dev *ax25_dev_list; extern ax25_dev *ax25_dev_list;
extern spinlock_t ax25_dev_lock; extern spinlock_t ax25_dev_lock;
extern ax25_dev *ax25_dev_ax25dev(struct net_device *);
static inline ax25_dev *ax25_dev_ax25dev(struct net_device *dev)
{
return dev->ax25_ptr;
}
extern ax25_dev *ax25_addr_ax25dev(ax25_address *); extern ax25_dev *ax25_addr_ax25dev(ax25_address *);
extern void ax25_dev_device_up(struct net_device *); extern void ax25_dev_device_up(struct net_device *);
extern void ax25_dev_device_down(struct net_device *); extern void ax25_dev_device_down(struct net_device *);
......
...@@ -34,21 +34,6 @@ ...@@ -34,21 +34,6 @@
ax25_dev *ax25_dev_list; ax25_dev *ax25_dev_list;
spinlock_t ax25_dev_lock = SPIN_LOCK_UNLOCKED; spinlock_t ax25_dev_lock = SPIN_LOCK_UNLOCKED;
ax25_dev *ax25_dev_ax25dev(struct net_device *dev)
{
ax25_dev *ax25_dev, *res = NULL;
spin_lock_bh(&ax25_dev_lock);
for (ax25_dev = ax25_dev_list; ax25_dev != NULL; ax25_dev = ax25_dev->next)
if (ax25_dev->dev == dev) {
res = ax25_dev;
break;
}
spin_unlock_bh(&ax25_dev_lock);
return res;
}
ax25_dev *ax25_addr_ax25dev(ax25_address *addr) ax25_dev *ax25_addr_ax25dev(ax25_address *addr)
{ {
ax25_dev *ax25_dev, *res = NULL; ax25_dev *ax25_dev, *res = NULL;
...@@ -80,6 +65,7 @@ void ax25_dev_device_up(struct net_device *dev) ...@@ -80,6 +65,7 @@ void ax25_dev_device_up(struct net_device *dev)
memset(ax25_dev, 0x00, sizeof(*ax25_dev)); memset(ax25_dev, 0x00, sizeof(*ax25_dev));
dev->ax25_ptr = ax25_dev;
ax25_dev->dev = dev; ax25_dev->dev = dev;
ax25_dev->forward = NULL; ax25_dev->forward = NULL;
...@@ -152,6 +138,7 @@ void ax25_dev_device_down(struct net_device *dev) ...@@ -152,6 +138,7 @@ void ax25_dev_device_down(struct net_device *dev)
s = s->next; s = s->next;
} }
spin_unlock_bh(&ax25_dev_lock); spin_unlock_bh(&ax25_dev_lock);
dev->ax25_ptr = NULL;
ax25_register_sysctl(); ax25_register_sysctl();
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment