[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 2/6] Allow safe resume for pci FE/BE
Make pci FE/BE resumable. Signed-off-by Kevin Tian <kevin.tian@xxxxxxxxx> diff -r eeff197b56e4 -r 7c8c027475f5 linux-2.6-xen-sparse/drivers/xen/pciback/xenbus.c --- a/linux-2.6-xen-sparse/drivers/xen/pciback/xenbus.c Mon Feb 05 16:57:58 2007 +0800 +++ b/linux-2.6-xen-sparse/drivers/xen/pciback/xenbus.c Mon Feb 05 16:58:10 2007 +0800 @@ -114,8 +114,11 @@ static int pciback_attach(struct pciback XenbusStateInitialised) goto out; - /* Wait for frontend to state that it has published the configuration */ - if (xenbus_read_driver_state(pdev->xdev->otherend) != + /* Wait for frontend to state that it has published the + * configuration. Frontend may be in connected state + * immediately after resume. + */ + if (xenbus_read_driver_state(pdev->xdev->otherend) < XenbusStateInitialised) goto out; diff -r eeff197b56e4 -r 7c8c027475f5 linux-2.6-xen-sparse/drivers/xen/pcifront/xenbus.c --- a/linux-2.6-xen-sparse/drivers/xen/pcifront/xenbus.c Mon Feb 05 16:57:58 2007 +0800 +++ b/linux-2.6-xen-sparse/drivers/xen/pcifront/xenbus.c Mon Feb 05 16:58:10 2007 +0800 @@ -21,48 +21,59 @@ static struct pcifront_device *alloc_pde if (pdev == NULL) goto out; + pdev->sh_info = NULL; + xdev->dev.driver_data = pdev; + pdev->xdev = xdev; + + INIT_LIST_HEAD(&pdev->root_buses); + + spin_lock_init(&pdev->dev_lock); + spin_lock_init(&pdev->sh_info_lock); + + pdev->evtchn = INVALID_EVTCHN; + pdev->gnt_ref = INVALID_GRANT_REF; + + dev_dbg(&xdev->dev, "Allocated pdev @ 0x%p pdev->sh_info @ 0x%p\n", + pdev, pdev->sh_info); + out: + return pdev; +} + +static void free_pdev(struct pcifront_device *pdev) +{ + dev_dbg(&pdev->xdev->dev, "freeing pdev @ 0x%p\n", pdev); + + if (pdev->evtchn != INVALID_EVTCHN) { + xenbus_free_evtchn(pdev->xdev, pdev->evtchn); + pdev->evtchn = INVALID_EVTCHN; + } + + if (pdev->gnt_ref != INVALID_GRANT_REF) { + gnttab_end_foreign_access(pdev->gnt_ref, 0, + (unsigned long)pdev->sh_info); + pdev->gnt_ref = INVALID_GRANT_REF; + pdev->sh_info = NULL; + } +} + +static int setup_shring(struct pcifront_device *pdev) +{ + int err; + pdev->sh_info = (struct xen_pci_sharedinfo *)__get_free_page(GFP_KERNEL); - if (pdev->sh_info == NULL) { - kfree(pdev); - pdev = NULL; - goto out; - } + if (pdev->sh_info == NULL) + return -ENOMEM; + pdev->sh_info->flags = 0; - - xdev->dev.driver_data = pdev; - pdev->xdev = xdev; - - INIT_LIST_HEAD(&pdev->root_buses); - - spin_lock_init(&pdev->dev_lock); - spin_lock_init(&pdev->sh_info_lock); - - pdev->evtchn = INVALID_EVTCHN; - pdev->gnt_ref = INVALID_GRANT_REF; - - dev_dbg(&xdev->dev, "Allocated pdev @ 0x%p pdev->sh_info @ 0x%p\n", - pdev, pdev->sh_info); - out: - return pdev; -} - -static void free_pdev(struct pcifront_device *pdev) -{ - dev_dbg(&pdev->xdev->dev, "freeing pdev @ 0x%p\n", pdev); - - pcifront_free_roots(pdev); - - if (pdev->evtchn != INVALID_EVTCHN) - xenbus_free_evtchn(pdev->xdev, pdev->evtchn); - - if (pdev->gnt_ref != INVALID_GRANT_REF) - gnttab_end_foreign_access(pdev->gnt_ref, 0, - (unsigned long)pdev->sh_info); - - pdev->xdev->dev.driver_data = NULL; - - kfree(pdev); + err = xenbus_grant_ring(pdev->xdev, virt_to_mfn(pdev->sh_info)); + if (err < 0) + goto out; + pdev->gnt_ref = err; + + err = xenbus_alloc_evtchn(pdev->xdev, &pdev->evtchn); + out: + return err; } static int pcifront_publish_info(struct pcifront_device *pdev) @@ -70,14 +81,8 @@ static int pcifront_publish_info(struct int err = 0; struct xenbus_transaction trans; - err = xenbus_grant_ring(pdev->xdev, virt_to_mfn(pdev->sh_info)); + err = setup_shring(pdev); if (err < 0) - goto out; - - pdev->gnt_ref = err; - - err = xenbus_alloc_evtchn(pdev->xdev, &pdev->evtchn); - if (err) goto out; do_publish: @@ -263,10 +268,38 @@ static int pcifront_xenbus_probe(struct static int pcifront_xenbus_remove(struct xenbus_device *xdev) { - if (xdev->dev.driver_data) - free_pdev(xdev->dev.driver_data); - + struct pcifront_device *pdev = xdev->dev.driver_data; + + if (!pdev) + return 0; + + pcifront_free_roots(pdev); + + free_pdev(pdev); + + pdev->xdev->dev.driver_data = NULL; + + kfree(pdev); return 0; +} + +static int pcifront_xenbus_resume(struct xenbus_device *dev) +{ + struct pcifront_device *pdev = dev->dev.driver_data; + int err; + + dev_dbg(&pdev->xdev->dev, "pcifront_xenbus_resume: %s\n", + dev->nodename); + + free_pdev(pdev); + + err = pcifront_publish_info(pdev); + if (err) + goto out; + + err = xenbus_switch_state(pdev->xdev, XenbusStateConnected); + out: + return err; } static struct xenbus_device_id xenpci_ids[] = { @@ -280,6 +313,7 @@ static struct xenbus_driver xenbus_pcifr .ids = xenpci_ids, .probe = pcifront_xenbus_probe, .remove = pcifront_xenbus_remove, + .resume = pcifront_xenbus_resume, .otherend_changed = pcifront_backend_changed, }; Attachment:
pcifront_resume.patch _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |