diff options
author | Qing He <qing.he@intel.com> | 2010-10-11 10:30:09 -0400 |
---|---|---|
committer | Stefano Stabellini <stefano.stabellini@eu.citrix.com> | 2010-10-22 16:25:44 -0400 |
commit | f731e3ef02b4744f4d7ca2f63539b900e47db31f (patch) | |
tree | 865ef6f817c372b99f0b36dc6f2638df087d51e7 /arch/x86/pci | |
parent | 38aa66fcb79e0a46c24bba96b6f2b851a6ec2037 (diff) |
xen: remap MSIs into pirqs when running as initial domain
Implement xen_create_msi_irq to create an msi and remap it as pirq.
Use xen_create_msi_irq to implement an initial domain specific version
of setup_msi_irqs.
Signed-off-by: Qing He <qing.he@intel.com>
Signed-off-by: Yunhong Jiang <yunhong.jiang@intel.com>
Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Diffstat (limited to 'arch/x86/pci')
-rw-r--r-- | arch/x86/pci/xen.c | 55 |
1 files changed, 37 insertions, 18 deletions
diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c index dd0b5fdb27b9..b3f4b30222fa 100644 --- a/arch/x86/pci/xen.c +++ b/arch/x86/pci/xen.c | |||
@@ -135,14 +135,12 @@ static int xen_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) | |||
135 | if (!v) | 135 | if (!v) |
136 | return -ENOMEM; | 136 | return -ENOMEM; |
137 | 137 | ||
138 | if (!xen_initial_domain()) { | 138 | if (type == PCI_CAP_ID_MSIX) |
139 | if (type == PCI_CAP_ID_MSIX) | 139 | ret = xen_pci_frontend_enable_msix(dev, &v, nvec); |
140 | ret = xen_pci_frontend_enable_msix(dev, &v, nvec); | 140 | else |
141 | else | 141 | ret = xen_pci_frontend_enable_msi(dev, &v); |
142 | ret = xen_pci_frontend_enable_msi(dev, &v); | 142 | if (ret) |
143 | if (ret) | 143 | goto error; |
144 | goto error; | ||
145 | } | ||
146 | i = 0; | 144 | i = 0; |
147 | list_for_each_entry(msidesc, &dev->msi_list, list) { | 145 | list_for_each_entry(msidesc, &dev->msi_list, list) { |
148 | irq = xen_allocate_pirq(v[i], 0, /* not sharable */ | 146 | irq = xen_allocate_pirq(v[i], 0, /* not sharable */ |
@@ -172,23 +170,40 @@ error: | |||
172 | 170 | ||
173 | static void xen_teardown_msi_irqs(struct pci_dev *dev) | 171 | static void xen_teardown_msi_irqs(struct pci_dev *dev) |
174 | { | 172 | { |
175 | /* Only do this when were are in non-privileged mode.*/ | 173 | struct msi_desc *msidesc; |
176 | if (!xen_initial_domain()) { | ||
177 | struct msi_desc *msidesc; | ||
178 | |||
179 | msidesc = list_entry(dev->msi_list.next, struct msi_desc, list); | ||
180 | if (msidesc->msi_attrib.is_msix) | ||
181 | xen_pci_frontend_disable_msix(dev); | ||
182 | else | ||
183 | xen_pci_frontend_disable_msi(dev); | ||
184 | } | ||
185 | 174 | ||
175 | msidesc = list_entry(dev->msi_list.next, struct msi_desc, list); | ||
176 | if (msidesc->msi_attrib.is_msix) | ||
177 | xen_pci_frontend_disable_msix(dev); | ||
178 | else | ||
179 | xen_pci_frontend_disable_msi(dev); | ||
186 | } | 180 | } |
187 | 181 | ||
188 | static void xen_teardown_msi_irq(unsigned int irq) | 182 | static void xen_teardown_msi_irq(unsigned int irq) |
189 | { | 183 | { |
190 | xen_destroy_irq(irq); | 184 | xen_destroy_irq(irq); |
191 | } | 185 | } |
186 | |||
187 | static int xen_initdom_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) | ||
188 | { | ||
189 | int irq, ret; | ||
190 | struct msi_desc *msidesc; | ||
191 | |||
192 | list_for_each_entry(msidesc, &dev->msi_list, list) { | ||
193 | irq = xen_create_msi_irq(dev, msidesc, type); | ||
194 | if (irq < 0) | ||
195 | return -1; | ||
196 | |||
197 | ret = set_irq_msi(irq, msidesc); | ||
198 | if (ret) | ||
199 | goto error; | ||
200 | } | ||
201 | return 0; | ||
202 | |||
203 | error: | ||
204 | xen_destroy_irq(irq); | ||
205 | return ret; | ||
206 | } | ||
192 | #endif | 207 | #endif |
193 | 208 | ||
194 | static int xen_pcifront_enable_irq(struct pci_dev *dev) | 209 | static int xen_pcifront_enable_irq(struct pci_dev *dev) |
@@ -362,6 +377,10 @@ static int acpi_register_gsi_xen(struct device *dev, u32 gsi, | |||
362 | 377 | ||
363 | static int __init pci_xen_initial_domain(void) | 378 | static int __init pci_xen_initial_domain(void) |
364 | { | 379 | { |
380 | #ifdef CONFIG_PCI_MSI | ||
381 | x86_msi.setup_msi_irqs = xen_initdom_setup_msi_irqs; | ||
382 | x86_msi.teardown_msi_irq = xen_teardown_msi_irq; | ||
383 | #endif | ||
365 | xen_setup_acpi_sci(); | 384 | xen_setup_acpi_sci(); |
366 | __acpi_register_gsi = acpi_register_gsi_xen; | 385 | __acpi_register_gsi = acpi_register_gsi_xen; |
367 | 386 | ||