aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sfc
diff options
context:
space:
mode:
authorBen Hutchings <bhutchings@solarflare.com>2008-12-13 01:09:38 -0500
committerDavid S. Miller <davem@davemloft.net>2008-12-13 01:09:38 -0500
commit7dde596ef79982327d8992a579a137b4035ad599 (patch)
treed14cc58d0ea48dbece0f18b3c6823176969ecd74 /drivers/net/sfc
parent0c53d8c84047d86169bd4147bb8f5adf2772d2bb (diff)
sfc: Fix synchronisation of efx_mtd_{probe,rename,remove}
Currently efx_mtd_rename() can race with the probe() and remove() functions. Move probe() before device registration and remove() after unregistration. Move initialisation/update of all names based on the netdev name into a new function and call it under the RTNL immediately after registration. Signed-off-by: Ben Hutchings <bhutchings@solarflare.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/sfc')
-rw-r--r--drivers/net/sfc/efx.c33
1 files changed, 18 insertions, 15 deletions
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
index 8f832bf1e4d2..086629c0fe57 100644
--- a/drivers/net/sfc/efx.c
+++ b/drivers/net/sfc/efx.c
@@ -1517,18 +1517,21 @@ static const struct net_device_ops efx_netdev_ops = {
1517#endif 1517#endif
1518}; 1518};
1519 1519
1520static void efx_update_name(struct efx_nic *efx)
1521{
1522 strcpy(efx->name, efx->net_dev->name);
1523 efx_mtd_rename(efx);
1524 efx_set_channel_names(efx);
1525}
1526
1520static int efx_netdev_event(struct notifier_block *this, 1527static int efx_netdev_event(struct notifier_block *this,
1521 unsigned long event, void *ptr) 1528 unsigned long event, void *ptr)
1522{ 1529{
1523 struct net_device *net_dev = ptr; 1530 struct net_device *net_dev = ptr;
1524 1531
1525 if (net_dev->netdev_ops == &efx_netdev_ops && event == NETDEV_CHANGENAME) { 1532 if (net_dev->netdev_ops == &efx_netdev_ops &&
1526 struct efx_nic *efx = netdev_priv(net_dev); 1533 event == NETDEV_CHANGENAME)
1527 1534 efx_update_name(netdev_priv(net_dev));
1528 strcpy(efx->name, net_dev->name);
1529 efx_mtd_rename(efx);
1530 efx_set_channel_names(efx);
1531 }
1532 1535
1533 return NOTIFY_DONE; 1536 return NOTIFY_DONE;
1534} 1537}
@@ -1568,8 +1571,10 @@ static int efx_register_netdev(struct efx_nic *efx)
1568 EFX_ERR(efx, "could not register net dev\n"); 1571 EFX_ERR(efx, "could not register net dev\n");
1569 return rc; 1572 return rc;
1570 } 1573 }
1571 strcpy(efx->name, net_dev->name); 1574
1572 efx_set_channel_names(efx); 1575 rtnl_lock();
1576 efx_update_name(efx);
1577 rtnl_unlock();
1573 1578
1574 rc = device_create_file(&efx->pci_dev->dev, &dev_attr_phy_type); 1579 rc = device_create_file(&efx->pci_dev->dev, &dev_attr_phy_type);
1575 if (rc) { 1580 if (rc) {
@@ -1978,8 +1983,6 @@ static void efx_pci_remove(struct pci_dev *pci_dev)
1978 if (!efx) 1983 if (!efx)
1979 return; 1984 return;
1980 1985
1981 efx_mtd_remove(efx);
1982
1983 /* Mark the NIC as fini, then stop the interface */ 1986 /* Mark the NIC as fini, then stop the interface */
1984 rtnl_lock(); 1987 rtnl_lock();
1985 efx->state = STATE_FINI; 1988 efx->state = STATE_FINI;
@@ -1993,6 +1996,8 @@ static void efx_pci_remove(struct pci_dev *pci_dev)
1993 1996
1994 efx_unregister_netdev(efx); 1997 efx_unregister_netdev(efx);
1995 1998
1999 efx_mtd_remove(efx);
2000
1996 /* Wait for any scheduled resets to complete. No more will be 2001 /* Wait for any scheduled resets to complete. No more will be
1997 * scheduled from this point because efx_stop_all() has been 2002 * scheduled from this point because efx_stop_all() has been
1998 * called, we are no longer registered with driverlink, and 2003 * called, we are no longer registered with driverlink, and
@@ -2146,17 +2151,15 @@ static int __devinit efx_pci_probe(struct pci_dev *pci_dev,
2146 /* Switch to the running state before we expose the device to 2151 /* Switch to the running state before we expose the device to
2147 * the OS. This is to ensure that the initial gathering of 2152 * the OS. This is to ensure that the initial gathering of
2148 * MAC stats succeeds. */ 2153 * MAC stats succeeds. */
2149 rtnl_lock();
2150 efx->state = STATE_RUNNING; 2154 efx->state = STATE_RUNNING;
2151 rtnl_unlock(); 2155
2156 efx_mtd_probe(efx); /* allowed to fail */
2152 2157
2153 rc = efx_register_netdev(efx); 2158 rc = efx_register_netdev(efx);
2154 if (rc) 2159 if (rc)
2155 goto fail5; 2160 goto fail5;
2156 2161
2157 EFX_LOG(efx, "initialisation successful\n"); 2162 EFX_LOG(efx, "initialisation successful\n");
2158
2159 efx_mtd_probe(efx); /* allowed to fail */
2160 return 0; 2163 return 0;
2161 2164
2162 fail5: 2165 fail5: