diff options
author | Casey Leedom <leedom@chelsio.com> | 2011-02-14 07:56:24 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-02-14 20:37:11 -0500 |
commit | 7e9c26295b2ae1be1285c7c9e593c19ce7ea7eba (patch) | |
tree | c8bb3d0decb24c44aca420faa0b0d88dbf1e82c2 /drivers/net/cxgb4vf/cxgb4vf_main.c | |
parent | 843635e0349be9e318be224d6241069a40e23320 (diff) |
cxgb4vf: Quiesce Virtual Interfaces on shutdown ...
When a Virtual Machine is rebooted, KVM currently fails to issue a Function
Level Reset against any "Attached PCI Devices" (AKA "PCI Passthrough"). In
addition to leaving the attached device in a random state in the next booted
kernel (which sort of violates the entire idea of a reboot reseting hardware
state), this leaves our peer thinking that the link is still up. (Note that
a bug has been filed with the KVM folks, #25332, but there's been no
response on that as of yet.) So, we add a "->shutdown()" method for the
Virtual Function PCI Device to handle administrative shutdowns like a
reboot.
Signed-off-by: Casey Leedom <leedom@chelsio.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/cxgb4vf/cxgb4vf_main.c')
-rw-r--r-- | drivers/net/cxgb4vf/cxgb4vf_main.c | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/drivers/net/cxgb4vf/cxgb4vf_main.c b/drivers/net/cxgb4vf/cxgb4vf_main.c index 2be1088ff601..6aad64df4dcb 100644 --- a/drivers/net/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/cxgb4vf/cxgb4vf_main.c | |||
@@ -2862,6 +2862,46 @@ static void __devexit cxgb4vf_pci_remove(struct pci_dev *pdev) | |||
2862 | } | 2862 | } |
2863 | 2863 | ||
2864 | /* | 2864 | /* |
2865 | * "Shutdown" quiesce the device, stopping Ingress Packet and Interrupt | ||
2866 | * delivery. | ||
2867 | */ | ||
2868 | static void __devexit cxgb4vf_pci_shutdown(struct pci_dev *pdev) | ||
2869 | { | ||
2870 | struct adapter *adapter; | ||
2871 | int pidx; | ||
2872 | |||
2873 | adapter = pci_get_drvdata(pdev); | ||
2874 | if (!adapter) | ||
2875 | return; | ||
2876 | |||
2877 | /* | ||
2878 | * Disable all Virtual Interfaces. This will shut down the | ||
2879 | * delivery of all ingress packets into the chip for these | ||
2880 | * Virtual Interfaces. | ||
2881 | */ | ||
2882 | for_each_port(adapter, pidx) { | ||
2883 | struct net_device *netdev; | ||
2884 | struct port_info *pi; | ||
2885 | |||
2886 | if (!test_bit(pidx, &adapter->registered_device_map)) | ||
2887 | continue; | ||
2888 | |||
2889 | netdev = adapter->port[pidx]; | ||
2890 | if (!netdev) | ||
2891 | continue; | ||
2892 | |||
2893 | pi = netdev_priv(netdev); | ||
2894 | t4vf_enable_vi(adapter, pi->viid, false, false); | ||
2895 | } | ||
2896 | |||
2897 | /* | ||
2898 | * Free up all Queues which will prevent further DMA and | ||
2899 | * Interrupts allowing various internal pathways to drain. | ||
2900 | */ | ||
2901 | t4vf_free_sge_resources(adapter); | ||
2902 | } | ||
2903 | |||
2904 | /* | ||
2865 | * PCI Device registration data structures. | 2905 | * PCI Device registration data structures. |
2866 | */ | 2906 | */ |
2867 | #define CH_DEVICE(devid, idx) \ | 2907 | #define CH_DEVICE(devid, idx) \ |
@@ -2894,6 +2934,7 @@ static struct pci_driver cxgb4vf_driver = { | |||
2894 | .id_table = cxgb4vf_pci_tbl, | 2934 | .id_table = cxgb4vf_pci_tbl, |
2895 | .probe = cxgb4vf_pci_probe, | 2935 | .probe = cxgb4vf_pci_probe, |
2896 | .remove = __devexit_p(cxgb4vf_pci_remove), | 2936 | .remove = __devexit_p(cxgb4vf_pci_remove), |
2937 | .shutdown = __devexit_p(cxgb4vf_pci_shutdown), | ||
2897 | }; | 2938 | }; |
2898 | 2939 | ||
2899 | /* | 2940 | /* |