[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [linux-2.6.18-xen] MSI-X: enhancement
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1218631574 -3600 # Node ID 359b1e70d9eb7afbad732bfdc6a52169af7ff8c1 # Parent c110692c140f99169a88a4904e37438acd5b656d MSI-X: enhancement Signed-off-by: Yu Zhao <yu.zhao@xxxxxxxxx> --- drivers/pci/msi-xen.c | 56 +++++++++++++++++++++++++++++----------- include/xen/interface/physdev.h | 13 +++++---- 2 files changed, 49 insertions(+), 20 deletions(-) diff -r c110692c140f -r 359b1e70d9eb drivers/pci/msi-xen.c --- a/drivers/pci/msi-xen.c Wed Aug 13 10:00:09 2008 +0100 +++ b/drivers/pci/msi-xen.c Wed Aug 13 13:46:14 2008 +0100 @@ -166,11 +166,27 @@ static int msi_unmap_pirq(struct pci_dev return 0; } +static u64 find_table_base(struct pci_dev *dev, int pos) +{ + u8 bar; + u32 reg; + unsigned long flags; + + pci_read_config_dword(dev, msix_table_offset_reg(pos), ®); + bar = reg & PCI_MSIX_FLAGS_BIRMASK; + + flags = pci_resource_flags(dev, bar); + if (flags & (IORESOURCE_DISABLED | IORESOURCE_UNSET | IORESOURCE_BUSY)) + return 0; + + return pci_resource_start(dev, bar); +} + /* * Protected by msi_lock */ static int msi_map_pirq_to_vector(struct pci_dev *dev, int pirq, - int entry_nr, int msi) + int entry_nr, u64 table_base) { struct physdev_map_pirq map_irq; int rc; @@ -182,10 +198,10 @@ static int msi_map_pirq_to_vector(struct map_irq.type = MAP_PIRQ_TYPE_MSI; map_irq.index = -1; map_irq.pirq = pirq; - map_irq.msi_info.bus = dev->bus->number; - map_irq.msi_info.devfn = dev->devfn; - map_irq.msi_info.entry_nr = entry_nr; - map_irq.msi_info.msi = msi; + map_irq.bus = dev->bus->number; + map_irq.devfn = dev->devfn; + map_irq.entry_nr = entry_nr; + map_irq.table_base = table_base; if ((rc = HYPERVISOR_physdev_op(PHYSDEVOP_map_pirq, &map_irq))) printk(KERN_WARNING "map irq failed\n"); @@ -196,9 +212,9 @@ static int msi_map_pirq_to_vector(struct return map_irq.pirq; } -static int msi_map_vector(struct pci_dev *dev, int entry_nr, int msi) -{ - return msi_map_pirq_to_vector(dev, -1, entry_nr, msi); +static int msi_map_vector(struct pci_dev *dev, int entry_nr, u64 table_base) +{ + return msi_map_pirq_to_vector(dev, -1, entry_nr, table_base); } static int msi_init(void) @@ -290,7 +306,7 @@ void pci_restore_msi_state(struct pci_de if (!dev->msi_enabled) return; - pirq = msi_map_pirq_to_vector(dev, dev->irq, 0, 1); + pirq = msi_map_pirq_to_vector(dev, dev->irq, 0, 0); if (pirq < 0) return; enable_msi_mode(dev, pos, PCI_CAP_ID_MSI); @@ -330,6 +346,7 @@ void pci_restore_msix_state(struct pci_d { int pos; unsigned long flags; + u64 table_base; struct msi_dev_list *msi_dev_entry; struct msi_pirq_entry *pirq_entry, *tmp; @@ -341,11 +358,15 @@ void pci_restore_msix_state(struct pci_d return; msi_dev_entry = get_msi_dev_pirq_list(dev); + table_base = find_table_base(dev, pos); + if (!table_base) + return; spin_lock_irqsave(&msi_dev_entry->pirq_list_lock, flags); list_for_each_entry_safe(pirq_entry, tmp, - &msi_dev_entry->pirq_list_head, list) - msi_map_pirq_to_vector(dev, pirq_entry->pirq, pirq_entry->entry_nr, 0); + &msi_dev_entry->pirq_list_head, list) + msi_map_pirq_to_vector(dev, pirq_entry->pirq, + pirq_entry->entry_nr, table_base); spin_unlock_irqrestore(&msi_dev_entry->pirq_list_lock, flags); enable_msi_mode(dev, pos, PCI_CAP_ID_MSIX); @@ -366,10 +387,10 @@ static int msi_capability_init(struct pc int pos, pirq; u16 control; - pos = pci_find_capability(dev, PCI_CAP_ID_MSI); + pos = pci_find_capability(dev, PCI_CAP_ID_MSI); pci_read_config_word(dev, msi_control_reg(pos), &control); - pirq = msi_map_vector(dev, 0, 1); + pirq = msi_map_vector(dev, 0, 0); if (pirq < 0) return -EBUSY; @@ -394,12 +415,18 @@ static int msix_capability_init(struct p static int msix_capability_init(struct pci_dev *dev, struct msix_entry *entries, int nvec) { + u64 table_base; int pirq, i, j, mapped, pos; struct msi_dev_list *msi_dev_entry = get_msi_dev_pirq_list(dev); struct msi_pirq_entry *pirq_entry; if (!msi_dev_entry) return -ENOMEM; + + pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); + table_base = find_table_base(dev, pos); + if (!table_base) + return -ENODEV; /* MSI-X Table Initialization */ for (i = 0; i < nvec; i++) { @@ -417,7 +444,7 @@ static int msix_capability_init(struct p } if (mapped) continue; - pirq = msi_map_vector(dev, entries[i].entry, 0); + pirq = msi_map_vector(dev, entries[i].entry, table_base); if (pirq < 0) break; attach_pirq_entry(pirq, entries[i].entry, msi_dev_entry); @@ -433,7 +460,6 @@ static int msix_capability_init(struct p return -EBUSY; } - pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); enable_msi_mode(dev, pos, PCI_CAP_ID_MSIX); dev->msix_enabled = 1; diff -r c110692c140f -r 359b1e70d9eb include/xen/interface/physdev.h --- a/include/xen/interface/physdev.h Wed Aug 13 10:00:09 2008 +0100 +++ b/include/xen/interface/physdev.h Wed Aug 13 13:46:14 2008 +0100 @@ -121,7 +121,7 @@ struct physdev_irq { }; typedef struct physdev_irq physdev_irq_t; DEFINE_XEN_GUEST_HANDLE(physdev_irq_t); - + #define MAP_PIRQ_TYPE_MSI 0x0 #define MAP_PIRQ_TYPE_GSI 0x1 #define MAP_PIRQ_TYPE_UNKNOWN 0x2 @@ -136,10 +136,13 @@ struct physdev_map_pirq { /* IN or OUT */ int pirq; /* IN */ - struct { - int bus, devfn, entry_nr; - int msi; /* 0 - MSIX 1 - MSI */ - } msi_info; + int bus; + /* IN */ + int devfn; + /* IN */ + int entry_nr; + /* IN */ + uint64_t table_base; }; typedef struct physdev_map_pirq physdev_map_pirq_t; DEFINE_XEN_GUEST_HANDLE(physdev_map_pirq_t); _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |