diff options
author | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2009-06-16 14:43:55 -0400 |
---|---|---|
committer | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2009-06-16 16:48:09 -0400 |
commit | b01b4babbf204443b5a846a7494546501614cefc (patch) | |
tree | 7488129b4e41cde0b614d8f999064fc33fd211ca /drivers/firewire | |
parent | d645f4dad056a98089df904294f66b96d04e91b6 (diff) |
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 <stefanr@s5r6.in-berlin.de>
Diffstat (limited to 'drivers/firewire')
-rw-r--r-- | drivers/firewire/net.c | 18 |
1 files changed, 10 insertions, 8 deletions
diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c index 95e35a36b01f..47dcb45d720e 100644 --- a/drivers/firewire/net.c +++ b/drivers/firewire/net.c | |||
@@ -1390,7 +1390,8 @@ static int fwnet_add_peer(struct fwnet_device *dev, | |||
1390 | if (!peer) | 1390 | if (!peer) |
1391 | return -ENOMEM; | 1391 | return -ENOMEM; |
1392 | 1392 | ||
1393 | unit->device.driver_data = peer; | 1393 | dev_set_drvdata(&unit->device, peer); |
1394 | |||
1394 | peer->dev = dev; | 1395 | peer->dev = dev; |
1395 | peer->guid = (u64)device->config_rom[3] << 32 | device->config_rom[4]; | 1396 | peer->guid = (u64)device->config_rom[3] << 32 | device->config_rom[4]; |
1396 | peer->fifo = FWNET_NO_FIFO_ADDR; | 1397 | peer->fifo = FWNET_NO_FIFO_ADDR; |
@@ -1417,27 +1418,26 @@ static int fwnet_probe(struct device *_dev) | |||
1417 | struct fw_device *device = fw_parent_device(unit); | 1418 | struct fw_device *device = fw_parent_device(unit); |
1418 | struct fw_card *card = device->card; | 1419 | struct fw_card *card = device->card; |
1419 | struct net_device *net; | 1420 | struct net_device *net; |
1421 | bool allocated_netdev = false; | ||
1420 | struct fwnet_device *dev; | 1422 | struct fwnet_device *dev; |
1421 | unsigned max_mtu; | 1423 | unsigned max_mtu; |
1422 | bool new_netdev; | ||
1423 | int ret; | 1424 | int ret; |
1424 | 1425 | ||
1425 | mutex_lock(&fwnet_device_mutex); | 1426 | mutex_lock(&fwnet_device_mutex); |
1426 | 1427 | ||
1427 | dev = fwnet_dev_find(card); | 1428 | dev = fwnet_dev_find(card); |
1428 | if (dev) { | 1429 | if (dev) { |
1429 | new_netdev = false; | ||
1430 | net = dev->netdev; | 1430 | net = dev->netdev; |
1431 | goto have_dev; | 1431 | goto have_dev; |
1432 | } | 1432 | } |
1433 | 1433 | ||
1434 | new_netdev = true; | ||
1435 | net = alloc_netdev(sizeof(*dev), "firewire%d", fwnet_init_dev); | 1434 | net = alloc_netdev(sizeof(*dev), "firewire%d", fwnet_init_dev); |
1436 | if (net == NULL) { | 1435 | if (net == NULL) { |
1437 | ret = -ENOMEM; | 1436 | ret = -ENOMEM; |
1438 | goto out; | 1437 | goto out; |
1439 | } | 1438 | } |
1440 | 1439 | ||
1440 | allocated_netdev = true; | ||
1441 | SET_NETDEV_DEV(net, card->device); | 1441 | SET_NETDEV_DEV(net, card->device); |
1442 | dev = netdev_priv(net); | 1442 | dev = netdev_priv(net); |
1443 | 1443 | ||
@@ -1479,12 +1479,12 @@ static int fwnet_probe(struct device *_dev) | |||
1479 | net->name, (unsigned long long)card->guid); | 1479 | net->name, (unsigned long long)card->guid); |
1480 | have_dev: | 1480 | have_dev: |
1481 | ret = fwnet_add_peer(dev, unit, device); | 1481 | ret = fwnet_add_peer(dev, unit, device); |
1482 | if (ret && new_netdev) { | 1482 | if (ret && allocated_netdev) { |
1483 | unregister_netdev(net); | 1483 | unregister_netdev(net); |
1484 | list_del(&dev->dev_link); | 1484 | list_del(&dev->dev_link); |
1485 | } | 1485 | } |
1486 | out: | 1486 | out: |
1487 | if (ret && new_netdev) | 1487 | if (ret && allocated_netdev) |
1488 | free_netdev(net); | 1488 | free_netdev(net); |
1489 | 1489 | ||
1490 | mutex_unlock(&fwnet_device_mutex); | 1490 | mutex_unlock(&fwnet_device_mutex); |
@@ -1508,7 +1508,7 @@ static void fwnet_remove_peer(struct fwnet_peer *peer) | |||
1508 | 1508 | ||
1509 | static int fwnet_remove(struct device *_dev) | 1509 | static int fwnet_remove(struct device *_dev) |
1510 | { | 1510 | { |
1511 | struct fwnet_peer *peer = _dev->driver_data; | 1511 | struct fwnet_peer *peer = dev_get_drvdata(_dev); |
1512 | struct fwnet_device *dev = peer->dev; | 1512 | struct fwnet_device *dev = peer->dev; |
1513 | struct net_device *net; | 1513 | struct net_device *net; |
1514 | struct fwnet_packet_task *ptask, *pt_next; | 1514 | struct fwnet_packet_task *ptask, *pt_next; |
@@ -1544,6 +1544,8 @@ static int fwnet_remove(struct device *_dev) | |||
1544 | dev_kfree_skb_any(ptask->skb); | 1544 | dev_kfree_skb_any(ptask->skb); |
1545 | kmem_cache_free(fwnet_packet_task_cache, ptask); | 1545 | kmem_cache_free(fwnet_packet_task_cache, ptask); |
1546 | } | 1546 | } |
1547 | list_del(&dev->dev_link); | ||
1548 | |||
1547 | free_netdev(net); | 1549 | free_netdev(net); |
1548 | } | 1550 | } |
1549 | 1551 | ||
@@ -1559,7 +1561,7 @@ static int fwnet_remove(struct device *_dev) | |||
1559 | static void fwnet_update(struct fw_unit *unit) | 1561 | static void fwnet_update(struct fw_unit *unit) |
1560 | { | 1562 | { |
1561 | struct fw_device *device = fw_parent_device(unit); | 1563 | struct fw_device *device = fw_parent_device(unit); |
1562 | struct fwnet_peer *peer = unit->device.driver_data; | 1564 | struct fwnet_peer *peer = dev_get_drvdata(&unit->device); |
1563 | int generation; | 1565 | int generation; |
1564 | 1566 | ||
1565 | generation = device->generation; | 1567 | generation = device->generation; |