[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [linux-2.6.18-xen] pcifront/back: Fix handling of device disconnect.
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1216212696 -3600 # Node ID 5644f68a7912e39585d9cbf3bc0a3800884ae693 # Parent bd4b58143713a9d379570707a755079c7cb4f62d pcifront/back: Fix handling of device disconnect. Signed-off-by: Yosuke Iwamatsu <y-iwamatsu@xxxxxxxxxxxxx> --- drivers/xen/pciback/xenbus.c | 51 ++++++++++++++++++++++++++++-------------- drivers/xen/pcifront/xenbus.c | 41 +++++++++++++++++---------------- 2 files changed, 56 insertions(+), 36 deletions(-) diff -r bd4b58143713 -r 5644f68a7912 drivers/xen/pciback/xenbus.c --- a/drivers/xen/pciback/xenbus.c Wed Jul 16 11:19:14 2008 +0100 +++ b/drivers/xen/pciback/xenbus.c Wed Jul 16 13:51:36 2008 +0100 @@ -42,22 +42,35 @@ static struct pciback_device *alloc_pdev return pdev; } -static void free_pdev(struct pciback_device *pdev) -{ - if (pdev->be_watching) - unregister_xenbus_watch(&pdev->be_watch); +static void pciback_disconnect(struct pciback_device *pdev) +{ + spin_lock(&pdev->dev_lock); /* Ensure the guest can't trigger our handler before removing devices */ - if (pdev->evtchn_irq != INVALID_EVTCHN_IRQ) + if (pdev->evtchn_irq != INVALID_EVTCHN_IRQ) { unbind_from_irqhandler(pdev->evtchn_irq, pdev); + pdev->evtchn_irq = INVALID_EVTCHN_IRQ; + } /* If the driver domain started an op, make sure we complete it or * delete it before releasing the shared memory */ cancel_delayed_work(&pdev->op_work); flush_scheduled_work(); - if (pdev->sh_info) + if (pdev->sh_info != NULL) { xenbus_unmap_ring_vfree(pdev->xdev, pdev->sh_area); + pdev->sh_info = NULL; + } + + spin_unlock(&pdev->dev_lock); +} + +static void free_pdev(struct pciback_device *pdev) +{ + if (pdev->be_watching) + unregister_xenbus_watch(&pdev->be_watch); + + pciback_disconnect(pdev); pciback_release_devices(pdev); @@ -471,16 +484,6 @@ static void pciback_frontend_changed(str pciback_attach(pdev); break; - case XenbusStateClosing: - xenbus_switch_state(xdev, XenbusStateClosed); - break; - - case XenbusStateUnknown: - case XenbusStateClosed: - dev_dbg(&xdev->dev, "frontend is gone! unregister device\n"); - device_unregister(&xdev->dev); - break; - case XenbusStateReconfiguring: pciback_reconfigure(pdev); break; @@ -490,6 +493,22 @@ static void pciback_frontend_changed(str * Then switch to connected state. */ xenbus_switch_state(xdev, XenbusStateConnected); + break; + + case XenbusStateClosing: + pciback_disconnect(pdev); + xenbus_switch_state(xdev, XenbusStateClosing); + break; + + case XenbusStateClosed: + pciback_disconnect(pdev); + xenbus_switch_state(xdev, XenbusStateClosed); + if (xenbus_dev_is_online(xdev)) + break; + /* fall through if not online */ + case XenbusStateUnknown: + dev_dbg(&xdev->dev, "frontend is gone! unregister device\n"); + device_unregister(&xdev->dev); break; default: diff -r bd4b58143713 -r 5644f68a7912 drivers/xen/pcifront/xenbus.c --- a/drivers/xen/pcifront/xenbus.c Wed Jul 16 11:19:14 2008 +0100 +++ b/drivers/xen/pcifront/xenbus.c Wed Jul 16 13:51:36 2008 +0100 @@ -207,12 +207,17 @@ static int pcifront_try_disconnect(struc prev_state = xenbus_read_driver_state(pdev->xdev->nodename); - if (prev_state < XenbusStateClosing) - err = xenbus_switch_state(pdev->xdev, XenbusStateClosing); - - if (!err && prev_state == XenbusStateConnected) + if (prev_state >= XenbusStateClosing) + goto out; + + if(prev_state == XenbusStateConnected) { + pcifront_free_roots(pdev); pcifront_disconnect(pdev); - + } + + err = xenbus_switch_state(pdev->xdev, XenbusStateClosed); + + out: spin_unlock(&pdev->dev_lock); return err; @@ -370,32 +375,28 @@ static void __init_refok pcifront_backen struct pcifront_device *pdev = xdev->dev.driver_data; switch (be_state) { + case XenbusStateUnknown: + case XenbusStateInitialising: + case XenbusStateInitWait: + case XenbusStateInitialised: + case XenbusStateClosed: + break; + + case XenbusStateConnected: + pcifront_try_connect(pdev); + break; + case XenbusStateClosing: dev_warn(&xdev->dev, "backend going away!\n"); pcifront_try_disconnect(pdev); break; - case XenbusStateUnknown: - case XenbusStateClosed: - dev_warn(&xdev->dev, "backend went away!\n"); - pcifront_try_disconnect(pdev); - - device_unregister(&pdev->xdev->dev); - break; - - case XenbusStateConnected: - pcifront_try_connect(pdev); - break; - case XenbusStateReconfiguring: pcifront_detach_devices(pdev); break; case XenbusStateReconfigured: pcifront_attach_devices(pdev); - break; - - default: break; } } _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |