aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/xen-netfront.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/xen-netfront.c')
-rw-r--r--drivers/net/xen-netfront.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index 18c85e55e76a..9bd7ddeeb6a5 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
90static DECLARE_WAIT_QUEUE_HEAD(module_unload_q);
91
90struct netfront_stats { 92struct netfront_stats {
91 u64 packets; 93 u64 packets;
92 u64 bytes; 94 u64 bytes;
@@ -1324,6 +1326,7 @@ static struct net_device *xennet_create_dev(struct xenbus_device *dev)
1324 1326
1325 netif_carrier_off(netdev); 1327 netif_carrier_off(netdev);
1326 1328
1329 xenbus_switch_state(dev, XenbusStateInitialising);
1327 return netdev; 1330 return netdev;
1328 1331
1329 exit: 1332 exit:
@@ -2020,10 +2023,12 @@ static void netback_changed(struct xenbus_device *dev,
2020 break; 2023 break;
2021 2024
2022 case XenbusStateClosed: 2025 case XenbusStateClosed:
2026 wake_up_all(&module_unload_q);
2023 if (dev->state == XenbusStateClosed) 2027 if (dev->state == XenbusStateClosed)
2024 break; 2028 break;
2025 /* Missed the backend's CLOSING state -- fallthrough */ 2029 /* Missed the backend's CLOSING state -- fallthrough */
2026 case XenbusStateClosing: 2030 case XenbusStateClosing:
2031 wake_up_all(&module_unload_q);
2027 xenbus_frontend_closed(dev); 2032 xenbus_frontend_closed(dev);
2028 break; 2033 break;
2029 } 2034 }
@@ -2129,6 +2134,20 @@ static int xennet_remove(struct xenbus_device *dev)
2129 2134
2130 dev_dbg(&dev->dev, "%s\n", dev->nodename); 2135 dev_dbg(&dev->dev, "%s\n", dev->nodename);
2131 2136
2137 if (xenbus_read_driver_state(dev->otherend) != XenbusStateClosed) {
2138 xenbus_switch_state(dev, XenbusStateClosing);
2139 wait_event(module_unload_q,
2140 xenbus_read_driver_state(dev->otherend) ==
2141 XenbusStateClosing);
2142
2143 xenbus_switch_state(dev, XenbusStateClosed);
2144 wait_event(module_unload_q,
2145 xenbus_read_driver_state(dev->otherend) ==
2146 XenbusStateClosed ||
2147 xenbus_read_driver_state(dev->otherend) ==
2148 XenbusStateUnknown);
2149 }
2150
2132 xennet_disconnect_backend(info); 2151 xennet_disconnect_backend(info);
2133 2152
2134 unregister_netdev(info->netdev); 2153 unregister_netdev(info->netdev);