diff options
-rw-r--r-- | drivers/net/xen-netback/common.h | 1 | ||||
-rw-r--r-- | drivers/net/xen-netback/interface.c | 12 | ||||
-rw-r--r-- | drivers/net/xen-netback/xenbus.c | 17 |
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, | |||
115 | int xenvif_connect(struct xenvif *vif, unsigned long tx_ring_ref, | 115 | int 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); |
117 | void xenvif_disconnect(struct xenvif *vif); | 117 | void xenvif_disconnect(struct xenvif *vif); |
118 | void xenvif_free(struct xenvif *vif); | ||
118 | 119 | ||
119 | void xenvif_get(struct xenvif *vif); | 120 | void xenvif_get(struct xenvif *vif); |
120 | void xenvif_put(struct xenvif *vif); | 121 | void 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 | |||
378 | void 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 | |||
210 | static 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); |