aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/xen-netback/common.h1
-rw-r--r--drivers/net/xen-netback/interface.c12
-rw-r--r--drivers/net/xen-netback/xenbus.c17
3 files changed, 23 insertions, 7 deletions
diff --git a/drivers/net/xen-netback/common.h b/drivers/net/xen-netback/common.h
index 9d7f1723dd8f..1a285083d24a 100644
--- a/drivers/net/xen-netback/common.h
+++ b/drivers/net/xen-netback/common.h
@@ -115,6 +115,7 @@ struct xenvif *xenvif_alloc(struct device *parent,
115int xenvif_connect(struct xenvif *vif, unsigned long tx_ring_ref, 115int xenvif_connect(struct xenvif *vif, unsigned long tx_ring_ref,
116 unsigned long rx_ring_ref, unsigned int evtchn); 116 unsigned long rx_ring_ref, unsigned int evtchn);
117void xenvif_disconnect(struct xenvif *vif); 117void xenvif_disconnect(struct xenvif *vif);
118void xenvif_free(struct xenvif *vif);
118 119
119void xenvif_get(struct xenvif *vif); 120void xenvif_get(struct xenvif *vif);
120void xenvif_put(struct xenvif *vif); 121void xenvif_put(struct xenvif *vif);
diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c
index d98414168485..3a294c2528d5 100644
--- a/drivers/net/xen-netback/interface.c
+++ b/drivers/net/xen-netback/interface.c
@@ -304,6 +304,9 @@ struct xenvif *xenvif_alloc(struct device *parent, domid_t domid,
304 } 304 }
305 305
306 netdev_dbg(dev, "Successfully created xenvif\n"); 306 netdev_dbg(dev, "Successfully created xenvif\n");
307
308 __module_get(THIS_MODULE);
309
307 return vif; 310 return vif;
308} 311}
309 312
@@ -369,9 +372,14 @@ void xenvif_disconnect(struct xenvif *vif)
369 if (vif->irq) 372 if (vif->irq)
370 unbind_from_irqhandler(vif->irq, vif); 373 unbind_from_irqhandler(vif->irq, vif);
371 374
372 unregister_netdev(vif->dev);
373
374 xen_netbk_unmap_frontend_rings(vif); 375 xen_netbk_unmap_frontend_rings(vif);
376}
377
378void xenvif_free(struct xenvif *vif)
379{
380 unregister_netdev(vif->dev);
375 381
376 free_netdev(vif->dev); 382 free_netdev(vif->dev);
383
384 module_put(THIS_MODULE);
377} 385}
diff --git a/drivers/net/xen-netback/xenbus.c b/drivers/net/xen-netback/xenbus.c
index 410018c4c528..abe24ff000f0 100644
--- a/drivers/net/xen-netback/xenbus.c
+++ b/drivers/net/xen-netback/xenbus.c
@@ -42,7 +42,7 @@ static int netback_remove(struct xenbus_device *dev)
42 if (be->vif) { 42 if (be->vif) {
43 kobject_uevent(&dev->dev.kobj, KOBJ_OFFLINE); 43 kobject_uevent(&dev->dev.kobj, KOBJ_OFFLINE);
44 xenbus_rm(XBT_NIL, dev->nodename, "hotplug-status"); 44 xenbus_rm(XBT_NIL, dev->nodename, "hotplug-status");
45 xenvif_disconnect(be->vif); 45 xenvif_free(be->vif);
46 be->vif = NULL; 46 be->vif = NULL;
47 } 47 }
48 kfree(be); 48 kfree(be);
@@ -203,9 +203,18 @@ static void disconnect_backend(struct xenbus_device *dev)
203{ 203{
204 struct backend_info *be = dev_get_drvdata(&dev->dev); 204 struct backend_info *be = dev_get_drvdata(&dev->dev);
205 205
206 if (be->vif)
207 xenvif_disconnect(be->vif);
208}
209
210static void destroy_backend(struct xenbus_device *dev)
211{
212 struct backend_info *be = dev_get_drvdata(&dev->dev);
213
206 if (be->vif) { 214 if (be->vif) {
215 kobject_uevent(&dev->dev.kobj, KOBJ_OFFLINE);
207 xenbus_rm(XBT_NIL, dev->nodename, "hotplug-status"); 216 xenbus_rm(XBT_NIL, dev->nodename, "hotplug-status");
208 xenvif_disconnect(be->vif); 217 xenvif_free(be->vif);
209 be->vif = NULL; 218 be->vif = NULL;
210 } 219 }
211} 220}
@@ -237,14 +246,11 @@ static void frontend_changed(struct xenbus_device *dev,
237 case XenbusStateConnected: 246 case XenbusStateConnected:
238 if (dev->state == XenbusStateConnected) 247 if (dev->state == XenbusStateConnected)
239 break; 248 break;
240 backend_create_xenvif(be);
241 if (be->vif) 249 if (be->vif)
242 connect(be); 250 connect(be);
243 break; 251 break;
244 252
245 case XenbusStateClosing: 253 case XenbusStateClosing:
246 if (be->vif)
247 kobject_uevent(&dev->dev.kobj, KOBJ_OFFLINE);
248 disconnect_backend(dev); 254 disconnect_backend(dev);
249 xenbus_switch_state(dev, XenbusStateClosing); 255 xenbus_switch_state(dev, XenbusStateClosing);
250 break; 256 break;
@@ -253,6 +259,7 @@ static void frontend_changed(struct xenbus_device *dev,
253 xenbus_switch_state(dev, XenbusStateClosed); 259 xenbus_switch_state(dev, XenbusStateClosed);
254 if (xenbus_dev_is_online(dev)) 260 if (xenbus_dev_is_online(dev))
255 break; 261 break;
262 destroy_backend(dev);
256 /* fall through if not online */ 263 /* fall through if not online */
257 case XenbusStateUnknown: 264 case XenbusStateUnknown:
258 device_unregister(&dev->dev); 265 device_unregister(&dev->dev);