diff options
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/xen-netback/common.h | 1 | ||||
-rw-r--r-- | drivers/net/xen-netback/interface.c | 26 | ||||
-rw-r--r-- | drivers/net/xen-netback/xenbus.c | 17 |
3 files changed, 23 insertions, 21 deletions
diff --git a/drivers/net/xen-netback/common.h b/drivers/net/xen-netback/common.h index a1977430ddfb..5715318d6bab 100644 --- a/drivers/net/xen-netback/common.h +++ b/drivers/net/xen-netback/common.h | |||
@@ -184,6 +184,7 @@ int xenvif_connect(struct xenvif *vif, unsigned long tx_ring_ref, | |||
184 | unsigned long rx_ring_ref, unsigned int tx_evtchn, | 184 | unsigned long rx_ring_ref, unsigned int tx_evtchn, |
185 | unsigned int rx_evtchn); | 185 | unsigned int rx_evtchn); |
186 | void xenvif_disconnect(struct xenvif *vif); | 186 | void xenvif_disconnect(struct xenvif *vif); |
187 | void xenvif_free(struct xenvif *vif); | ||
187 | 188 | ||
188 | int xenvif_xenbus_init(void); | 189 | int xenvif_xenbus_init(void); |
189 | void xenvif_xenbus_fini(void); | 190 | void xenvif_xenbus_fini(void); |
diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c index 77fee1d51fb2..01bb854c7f62 100644 --- a/drivers/net/xen-netback/interface.c +++ b/drivers/net/xen-netback/interface.c | |||
@@ -353,6 +353,9 @@ struct xenvif *xenvif_alloc(struct device *parent, domid_t domid, | |||
353 | } | 353 | } |
354 | 354 | ||
355 | netdev_dbg(dev, "Successfully created xenvif\n"); | 355 | netdev_dbg(dev, "Successfully created xenvif\n"); |
356 | |||
357 | __module_get(THIS_MODULE); | ||
358 | |||
356 | return vif; | 359 | return vif; |
357 | } | 360 | } |
358 | 361 | ||
@@ -366,8 +369,6 @@ int xenvif_connect(struct xenvif *vif, unsigned long tx_ring_ref, | |||
366 | if (vif->tx_irq) | 369 | if (vif->tx_irq) |
367 | return 0; | 370 | return 0; |
368 | 371 | ||
369 | __module_get(THIS_MODULE); | ||
370 | |||
371 | err = xenvif_map_frontend_rings(vif, tx_ring_ref, rx_ring_ref); | 372 | err = xenvif_map_frontend_rings(vif, tx_ring_ref, rx_ring_ref); |
372 | if (err < 0) | 373 | if (err < 0) |
373 | goto err; | 374 | goto err; |
@@ -452,12 +453,6 @@ void xenvif_carrier_off(struct xenvif *vif) | |||
452 | 453 | ||
453 | void xenvif_disconnect(struct xenvif *vif) | 454 | void xenvif_disconnect(struct xenvif *vif) |
454 | { | 455 | { |
455 | /* Disconnect funtion might get called by generic framework | ||
456 | * even before vif connects, so we need to check if we really | ||
457 | * need to do a module_put. | ||
458 | */ | ||
459 | int need_module_put = 0; | ||
460 | |||
461 | if (netif_carrier_ok(vif->dev)) | 456 | if (netif_carrier_ok(vif->dev)) |
462 | xenvif_carrier_off(vif); | 457 | xenvif_carrier_off(vif); |
463 | 458 | ||
@@ -468,23 +463,22 @@ void xenvif_disconnect(struct xenvif *vif) | |||
468 | unbind_from_irqhandler(vif->tx_irq, vif); | 463 | unbind_from_irqhandler(vif->tx_irq, vif); |
469 | unbind_from_irqhandler(vif->rx_irq, vif); | 464 | unbind_from_irqhandler(vif->rx_irq, vif); |
470 | } | 465 | } |
471 | /* vif->irq is valid, we had a module_get in | 466 | vif->tx_irq = 0; |
472 | * xenvif_connect. | ||
473 | */ | ||
474 | need_module_put = 1; | ||
475 | } | 467 | } |
476 | 468 | ||
477 | if (vif->task) | 469 | if (vif->task) |
478 | kthread_stop(vif->task); | 470 | kthread_stop(vif->task); |
479 | 471 | ||
472 | xenvif_unmap_frontend_rings(vif); | ||
473 | } | ||
474 | |||
475 | void xenvif_free(struct xenvif *vif) | ||
476 | { | ||
480 | netif_napi_del(&vif->napi); | 477 | netif_napi_del(&vif->napi); |
481 | 478 | ||
482 | unregister_netdev(vif->dev); | 479 | unregister_netdev(vif->dev); |
483 | 480 | ||
484 | xenvif_unmap_frontend_rings(vif); | ||
485 | |||
486 | free_netdev(vif->dev); | 481 | free_netdev(vif->dev); |
487 | 482 | ||
488 | if (need_module_put) | 483 | module_put(THIS_MODULE); |
489 | module_put(THIS_MODULE); | ||
490 | } | 484 | } |
diff --git a/drivers/net/xen-netback/xenbus.c b/drivers/net/xen-netback/xenbus.c index 1fe48fe364ed..a53782ef1540 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); |
@@ -213,9 +213,18 @@ static void disconnect_backend(struct xenbus_device *dev) | |||
213 | { | 213 | { |
214 | struct backend_info *be = dev_get_drvdata(&dev->dev); | 214 | struct backend_info *be = dev_get_drvdata(&dev->dev); |
215 | 215 | ||
216 | if (be->vif) | ||
217 | xenvif_disconnect(be->vif); | ||
218 | } | ||
219 | |||
220 | static void destroy_backend(struct xenbus_device *dev) | ||
221 | { | ||
222 | struct backend_info *be = dev_get_drvdata(&dev->dev); | ||
223 | |||
216 | if (be->vif) { | 224 | if (be->vif) { |
225 | kobject_uevent(&dev->dev.kobj, KOBJ_OFFLINE); | ||
217 | xenbus_rm(XBT_NIL, dev->nodename, "hotplug-status"); | 226 | xenbus_rm(XBT_NIL, dev->nodename, "hotplug-status"); |
218 | xenvif_disconnect(be->vif); | 227 | xenvif_free(be->vif); |
219 | be->vif = NULL; | 228 | be->vif = NULL; |
220 | } | 229 | } |
221 | } | 230 | } |
@@ -246,14 +255,11 @@ static void frontend_changed(struct xenbus_device *dev, | |||
246 | case XenbusStateConnected: | 255 | case XenbusStateConnected: |
247 | if (dev->state == XenbusStateConnected) | 256 | if (dev->state == XenbusStateConnected) |
248 | break; | 257 | break; |
249 | backend_create_xenvif(be); | ||
250 | if (be->vif) | 258 | if (be->vif) |
251 | connect(be); | 259 | connect(be); |
252 | break; | 260 | break; |
253 | 261 | ||
254 | case XenbusStateClosing: | 262 | case XenbusStateClosing: |
255 | if (be->vif) | ||
256 | kobject_uevent(&dev->dev.kobj, KOBJ_OFFLINE); | ||
257 | disconnect_backend(dev); | 263 | disconnect_backend(dev); |
258 | xenbus_switch_state(dev, XenbusStateClosing); | 264 | xenbus_switch_state(dev, XenbusStateClosing); |
259 | break; | 265 | break; |
@@ -262,6 +268,7 @@ static void frontend_changed(struct xenbus_device *dev, | |||
262 | xenbus_switch_state(dev, XenbusStateClosed); | 268 | xenbus_switch_state(dev, XenbusStateClosed); |
263 | if (xenbus_dev_is_online(dev)) | 269 | if (xenbus_dev_is_online(dev)) |
264 | break; | 270 | break; |
271 | destroy_backend(dev); | ||
265 | /* fall through if not online */ | 272 | /* fall through if not online */ |
266 | case XenbusStateUnknown: | 273 | case XenbusStateUnknown: |
267 | device_unregister(&dev->dev); | 274 | device_unregister(&dev->dev); |