diff options
Diffstat (limited to 'drivers/net/xen-netfront.c')
-rw-r--r-- | drivers/net/xen-netfront.c | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index 18c85e55e76a..c5a34671abda 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c | |||
@@ -87,6 +87,8 @@ struct netfront_cb { | |||
87 | /* IRQ name is queue name with "-tx" or "-rx" appended */ | 87 | /* IRQ name is queue name with "-tx" or "-rx" appended */ |
88 | #define IRQ_NAME_SIZE (QUEUE_NAME_SIZE + 3) | 88 | #define IRQ_NAME_SIZE (QUEUE_NAME_SIZE + 3) |
89 | 89 | ||
90 | static DECLARE_WAIT_QUEUE_HEAD(module_unload_q); | ||
91 | |||
90 | struct netfront_stats { | 92 | struct netfront_stats { |
91 | u64 packets; | 93 | u64 packets; |
92 | u64 bytes; | 94 | u64 bytes; |
@@ -2020,10 +2022,12 @@ static void netback_changed(struct xenbus_device *dev, | |||
2020 | break; | 2022 | break; |
2021 | 2023 | ||
2022 | case XenbusStateClosed: | 2024 | case XenbusStateClosed: |
2025 | wake_up_all(&module_unload_q); | ||
2023 | if (dev->state == XenbusStateClosed) | 2026 | if (dev->state == XenbusStateClosed) |
2024 | break; | 2027 | break; |
2025 | /* Missed the backend's CLOSING state -- fallthrough */ | 2028 | /* Missed the backend's CLOSING state -- fallthrough */ |
2026 | case XenbusStateClosing: | 2029 | case XenbusStateClosing: |
2030 | wake_up_all(&module_unload_q); | ||
2027 | xenbus_frontend_closed(dev); | 2031 | xenbus_frontend_closed(dev); |
2028 | break; | 2032 | break; |
2029 | } | 2033 | } |
@@ -2129,6 +2133,20 @@ static int xennet_remove(struct xenbus_device *dev) | |||
2129 | 2133 | ||
2130 | dev_dbg(&dev->dev, "%s\n", dev->nodename); | 2134 | dev_dbg(&dev->dev, "%s\n", dev->nodename); |
2131 | 2135 | ||
2136 | if (xenbus_read_driver_state(dev->otherend) != XenbusStateClosed) { | ||
2137 | xenbus_switch_state(dev, XenbusStateClosing); | ||
2138 | wait_event(module_unload_q, | ||
2139 | xenbus_read_driver_state(dev->otherend) == | ||
2140 | XenbusStateClosing); | ||
2141 | |||
2142 | xenbus_switch_state(dev, XenbusStateClosed); | ||
2143 | wait_event(module_unload_q, | ||
2144 | xenbus_read_driver_state(dev->otherend) == | ||
2145 | XenbusStateClosed || | ||
2146 | xenbus_read_driver_state(dev->otherend) == | ||
2147 | XenbusStateUnknown); | ||
2148 | } | ||
2149 | |||
2132 | xennet_disconnect_backend(info); | 2150 | xennet_disconnect_backend(info); |
2133 | 2151 | ||
2134 | unregister_netdev(info->netdev); | 2152 | unregister_netdev(info->netdev); |