diff options
author | François Romieu <romieu@nail.test.fr.zoreil.com> | 2006-08-15 14:10:57 -0400 |
---|---|---|
committer | Francois Romieu <romieu@fr.zoreil.com> | 2006-08-31 16:15:42 -0400 |
commit | 7668a4945ba0e17a61e535a6c67aa64a319a03b4 (patch) | |
tree | 08a883a950a69e1105d1eef59ae7f6e6ec318932 /drivers/net/8139cp.c | |
parent | e68970e7543815133224f79a858e7c9e0c42f4de (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/8139cp.c')
-rw-r--r-- | drivers/net/8139cp.c | 10 |
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 |
2024 | static int cp_suspend (struct pci_dev *pdev, pm_message_t state) | 2024 | static 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); |