aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorFrançois Romieu <romieu@nail.test.fr.zoreil.com>2006-08-15 14:10:57 -0400
committerFrancois Romieu <romieu@fr.zoreil.com>2006-08-31 16:15:42 -0400
commit7668a4945ba0e17a61e535a6c67aa64a319a03b4 (patch)
tree08a883a950a69e1105d1eef59ae7f6e6ec318932 /drivers/net
parente68970e7543815133224f79a858e7c9e0c42f4de (diff)
8139cp: pci_get_drvdata(pdev) can not be NULL in suspend handler
1) pci_set_drvdata() is used in cp_{init/remove}_one to initialize/reset driver_data to the relevant value (resp. net_device * and NULL). 2) each of the 3 relevant functions is issued under (device *)->sem: 2.1) pci_unregister_driver -> driver_unregister -> bus_remove_driver -> driver_detach (takes (device *)->sem) -> __device_release_driver(dev) -> dev->bus-remove(dev) (== pci_device_remove) -> drv->remove(pdev) (== cp_remove_one) [...] pci_dev->driver = NULL; 2.2) pci_register_driver -> __pci_register_driver -> driver_register -> bus_add_driver -> driver_attach -> __driver_attach (takes (device *)->sem) -> driver_probe_device(drv, dev) -> dev->bus->probe(dev) (== pci_device_probe) -> _pci_device_probe(drv, pci_dev) -> pci_call_probe(drv, pci_dev, id) -> drv->probe(dev, id) (== cp_init_one) [...] pci_dev->driver = drv; 2.3) suspend_device (takes (device *)->sem) -> dev->bus->suspend(dev) (== pci_device_suspend) checking for drv = pci_dev->driver != NULL [...] -> drv->suspend(pci_dev, state) (== cp_suspend) dev->sem and the state of pci_dev->driver provide the expected result. St Mary's day was a bit rainy here. Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/8139cp.c10
1 files changed, 4 insertions, 6 deletions
diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c
index 94ab3c31e7e1..a123d28113cd 100644
--- a/drivers/net/8139cp.c
+++ b/drivers/net/8139cp.c
@@ -2023,14 +2023,12 @@ static void cp_remove_one (struct pci_dev *pdev)
2023#ifdef CONFIG_PM 2023#ifdef CONFIG_PM
2024static int cp_suspend (struct pci_dev *pdev, pm_message_t state) 2024static int cp_suspend (struct pci_dev *pdev, pm_message_t state)
2025{ 2025{
2026 struct net_device *dev; 2026 struct net_device *dev = pci_get_drvdata(pdev);
2027 struct cp_private *cp; 2027 struct cp_private *cp = netdev_priv(dev);
2028 unsigned long flags; 2028 unsigned long flags;
2029 2029
2030 dev = pci_get_drvdata (pdev); 2030 if (!netif_running(dev))
2031 cp = netdev_priv(dev); 2031 return 0;
2032
2033 if (!dev || !netif_running (dev)) return 0;
2034 2032
2035 netif_device_detach (dev); 2033 netif_device_detach (dev);
2036 netif_stop_queue (dev); 2034 netif_stop_queue (dev);