[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] Support S3 for MSI interrupt
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1229698596 0 # Node ID 2dffa6ceb0af954e7f3a9ad7e993b8aee7b7de65 # Parent 738513b106fa262a11cc3254cd6dd67afb3a63e7 Support S3 for MSI interrupt From: "Jiang, Yunhong" <yunhong.jiang@xxxxxxxxx> Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx> --- xen/arch/x86/msi.c | 40 ++++++++++++++++++++++++++++++++++++++++ xen/arch/x86/physdev.c | 18 ++++++++++++++++++ xen/include/asm-x86/msi.h | 1 + xen/include/public/physdev.h | 9 +++++++++ 4 files changed, 68 insertions(+) diff -r 738513b106fa -r 2dffa6ceb0af xen/arch/x86/msi.c --- a/xen/arch/x86/msi.c Fri Dec 19 14:52:32 2008 +0000 +++ b/xen/arch/x86/msi.c Fri Dec 19 14:56:36 2008 +0000 @@ -741,3 +741,43 @@ void pci_cleanup_msi(struct pci_dev *pde msi_free_vectors(pdev); } +int pci_restore_msi_state(struct pci_dev *pdev) +{ + unsigned long flags; + int vector; + struct msi_desc *entry, *tmp; + irq_desc_t *desc; + + ASSERT(spin_is_locked(&pcidevs_lock)); + + if (!pdev) + return -EINVAL; + + list_for_each_entry_safe( entry, tmp, &pdev->msi_list, list ) + { + vector = entry->vector; + desc = &irq_desc[vector]; + + spin_lock_irqsave(&desc->lock, flags); + + ASSERT(desc->msi_desc == entry); + + if (desc->msi_desc != entry) + { + dprintk(XENLOG_ERR, "Restore MSI for dev %x:%x not set before?\n", + pdev->bus, pdev->devfn); + spin_unlock_irqrestore(&desc->lock, flags); + return -EINVAL; + } + + msi_set_enable(pdev, 0); + write_msi_msg(entry, &entry->msg); + + msi_set_enable(pdev, 1); + msi_set_mask_bit(vector, entry->msi_attrib.masked); + spin_unlock_irqrestore(&desc->lock, flags); + } + + return 0; +} + diff -r 738513b106fa -r 2dffa6ceb0af xen/arch/x86/physdev.c --- a/xen/arch/x86/physdev.c Fri Dec 19 14:52:32 2008 +0000 +++ b/xen/arch/x86/physdev.c Fri Dec 19 14:56:36 2008 +0000 @@ -415,6 +415,24 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_H break; } + case PHYSDEVOP_restore_msi: { + struct physdev_restore_msi restore_msi; + struct pci_dev *pdev; + + ret = -EPERM; + if ( !IS_PRIV(v->domain) ) + break; + + ret = -EFAULT; + if ( copy_from_guest(&restore_msi, arg, 1) != 0 ) + break; + + spin_lock(&pcidevs_lock); + pdev = pci_get_pdev(restore_msi.bus, restore_msi.devfn); + ret = pdev ? pci_restore_msi_state(pdev) : -ENODEV; + spin_unlock(&pcidevs_lock); + break; + } default: ret = -ENOSYS; break; diff -r 738513b106fa -r 2dffa6ceb0af xen/include/asm-x86/msi.h --- a/xen/include/asm-x86/msi.h Fri Dec 19 14:52:32 2008 +0000 +++ b/xen/include/asm-x86/msi.h Fri Dec 19 14:56:36 2008 +0000 @@ -79,6 +79,7 @@ extern int setup_msi_irq(struct pci_dev extern int setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc); extern void teardown_msi_vector(int vector); extern int msi_free_vector(struct msi_desc *entry); +extern int pci_restore_msi_state(struct pci_dev *pdev); struct msi_desc { struct { diff -r 738513b106fa -r 2dffa6ceb0af xen/include/public/physdev.h --- a/xen/include/public/physdev.h Fri Dec 19 14:52:32 2008 +0000 +++ b/xen/include/public/physdev.h Fri Dec 19 14:56:36 2008 +0000 @@ -183,6 +183,15 @@ typedef struct physdev_manage_pci physde typedef struct physdev_manage_pci physdev_manage_pci_t; DEFINE_XEN_GUEST_HANDLE(physdev_manage_pci_t); +#define PHYSDEVOP_restore_msi 19 +struct physdev_restore_msi { + /* IN */ + uint8_t bus; + uint8_t devfn; +}; +typedef struct physdev_restore_msi physdev_restore_msi_t; +DEFINE_XEN_GUEST_HANDLE(physdev_restore_msi_t); + /* * Argument to physdev_op_compat() hypercall. Superceded by new physdev_op() * hypercall since 0x00030202. _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |