Date: Tue, 16 Jun 2009 20:43:55 +0200 (CEST) From: Stefan Richter Subject: firewire: net: fix card driver reloading Fix some problems from "firewire: net: allow for unordered unit discovery": - fwnet_remove was missing a list_del, causing fwnet_probe to crash if called after fwnet_remove, e.g. if firewire-ohci was unloaded and reloaded. - fwnet_probe should set its new_netdev flag only if it actually allocated a net_device. - Use dev_set_drvdata and dev_get_drvdata instead of deprecated direct access to device.driver_data. Signed-off-by: Stefan Richter --- drivers/firewire/net.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) Index: b/drivers/firewire/net.c =================================================================== --- a/drivers/firewire/net.c +++ b/drivers/firewire/net.c @@ -1390,7 +1390,8 @@ static int fwnet_add_peer(struct fwnet_d if (!peer) return -ENOMEM; - unit->device.driver_data = peer; + dev_set_drvdata(&unit->device, peer); + peer->dev = dev; peer->guid = (u64)device->config_rom[3] << 32 | device->config_rom[4]; peer->fifo = FWNET_NO_FIFO_ADDR; @@ -1417,27 +1418,26 @@ static int fwnet_probe(struct device *_d struct fw_device *device = fw_parent_device(unit); struct fw_card *card = device->card; struct net_device *net; + bool allocated_netdev = false; struct fwnet_device *dev; unsigned max_mtu; - bool new_netdev; int ret; mutex_lock(&fwnet_device_mutex); dev = fwnet_dev_find(card); if (dev) { - new_netdev = false; net = dev->netdev; goto have_dev; } - new_netdev = true; net = alloc_netdev(sizeof(*dev), "firewire%d", fwnet_init_dev); if (net == NULL) { ret = -ENOMEM; goto out; } + allocated_netdev = true; SET_NETDEV_DEV(net, card->device); dev = netdev_priv(net); @@ -1479,12 +1479,12 @@ static int fwnet_probe(struct device *_d net->name, (unsigned long long)card->guid); have_dev: ret = fwnet_add_peer(dev, unit, device); - if (ret && new_netdev) { + if (ret && allocated_netdev) { unregister_netdev(net); list_del(&dev->dev_link); } out: - if (ret && new_netdev) + if (ret && allocated_netdev) free_netdev(net); mutex_unlock(&fwnet_device_mutex); @@ -1508,7 +1508,7 @@ static void fwnet_remove_peer(struct fwn static int fwnet_remove(struct device *_dev) { - struct fwnet_peer *peer = _dev->driver_data; + struct fwnet_peer *peer = dev_get_drvdata(_dev); struct fwnet_device *dev = peer->dev; struct net_device *net; struct fwnet_packet_task *ptask, *pt_next; @@ -1544,6 +1544,8 @@ static int fwnet_remove(struct device *_ dev_kfree_skb_any(ptask->skb); kmem_cache_free(fwnet_packet_task_cache, ptask); } + list_del(&dev->dev_link); + free_netdev(net); } @@ -1559,7 +1561,7 @@ static int fwnet_remove(struct device *_ static void fwnet_update(struct fw_unit *unit) { struct fw_device *device = fw_parent_device(unit); - struct fwnet_peer *peer = unit->device.driver_data; + struct fwnet_peer *peer = dev_get_drvdata(&unit->device); int generation; generation = device->generation;