aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/pci
diff options
context:
space:
mode:
authorKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>2011-07-06 10:16:21 -0400
committerKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>2011-07-11 13:19:25 -0400
commitfef6e26208879f76bada77c11c80d56ebacb32e4 (patch)
tree7fdcd859444b21fe23217ef67364512a8f50ed9b /arch/x86/pci
parent075d9db13183c102770dc6cefabfee1b832f9614 (diff)
xen/pci: Shuffle code around.
The file is hard to read. Move the code around so that the contents of it follows a uniform format: - setup GSIs - PV, HVM, and initial domain case - then MSI/MSI-x setup - PV, HVM and then initial domain case. - then MSI/MSI-x teardown - same order. - lastly, the __init functions in PV, HVM, and initial domain order. Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Diffstat (limited to 'arch/x86/pci')
-rw-r--r--arch/x86/pci/xen.c346
1 files changed, 173 insertions, 173 deletions
diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c
index f567965c062..ba4077b7304 100644
--- a/arch/x86/pci/xen.c
+++ b/arch/x86/pci/xen.c
@@ -19,6 +19,43 @@
19#include <xen/events.h> 19#include <xen/events.h>
20#include <asm/xen/pci.h> 20#include <asm/xen/pci.h>
21 21
22static int xen_pcifront_enable_irq(struct pci_dev *dev)
23{
24 int rc;
25 int share = 1;
26 int pirq;
27 u8 gsi;
28
29 rc = pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &gsi);
30 if (rc < 0) {
31 dev_warn(&dev->dev, "Xen PCI: failed to read interrupt line: %d\n",
32 rc);
33 return rc;
34 }
35
36 rc = xen_allocate_pirq_gsi(gsi);
37 if (rc < 0) {
38 dev_warn(&dev->dev, "Xen PCI: failed to allocate a PIRQ for GSI%d: %d\n",
39 gsi, rc);
40 return rc;
41 }
42 pirq = rc;
43
44 if (gsi < NR_IRQS_LEGACY)
45 share = 0;
46
47 rc = xen_bind_pirq_gsi_to_irq(gsi, pirq, share, "pcifront");
48 if (rc < 0) {
49 dev_warn(&dev->dev, "Xen PCI: failed to bind GSI%d (PIRQ%d) to IRQ: %d\n",
50 gsi, pirq, rc);
51 return rc;
52 }
53
54 dev->irq = rc;
55 dev_info(&dev->dev, "Xen PCI mapped GSI%d to IRQ%d\n", gsi, dev->irq);
56 return 0;
57}
58
22#ifdef CONFIG_ACPI 59#ifdef CONFIG_ACPI
23static int acpi_register_gsi_xen_hvm(struct device *dev, u32 gsi, 60static int acpi_register_gsi_xen_hvm(struct device *dev, u32 gsi,
24 int trigger, int polarity) 61 int trigger, int polarity)
@@ -58,6 +95,87 @@ static int acpi_register_gsi_xen_hvm(struct device *dev, u32 gsi,
58} 95}
59#endif 96#endif
60 97
98#ifdef CONFIG_XEN_DOM0
99static int xen_register_pirq(u32 gsi, int gsi_override, int triggering)
100{
101 int rc, pirq, irq = -1;
102 struct physdev_map_pirq map_irq;
103 int shareable = 0;
104 char *name;
105
106 if (!xen_pv_domain())
107 return -1;
108
109 if (triggering == ACPI_EDGE_SENSITIVE) {
110 shareable = 0;
111 name = "ioapic-edge";
112 } else {
113 shareable = 1;
114 name = "ioapic-level";
115 }
116 pirq = xen_allocate_pirq_gsi(gsi);
117 if (pirq < 0)
118 goto out;
119
120 if (gsi_override >= 0)
121 irq = xen_bind_pirq_gsi_to_irq(gsi_override, pirq, shareable, name);
122 else
123 irq = xen_bind_pirq_gsi_to_irq(gsi, pirq, shareable, name);
124 if (irq < 0)
125 goto out;
126
127 printk(KERN_DEBUG "xen: --> pirq=%d -> irq=%d (gsi=%d)\n", pirq, irq, gsi);
128
129 map_irq.domid = DOMID_SELF;
130 map_irq.type = MAP_PIRQ_TYPE_GSI;
131 map_irq.index = gsi;
132 map_irq.pirq = pirq;
133
134 rc = HYPERVISOR_physdev_op(PHYSDEVOP_map_pirq, &map_irq);
135 if (rc) {
136 printk(KERN_WARNING "xen map irq failed %d\n", rc);
137 return -1;
138 }
139
140out:
141 return irq;
142}
143
144static int xen_register_gsi(u32 gsi, int gsi_override, int triggering, int polarity)
145{
146 int rc, irq;
147 struct physdev_setup_gsi setup_gsi;
148
149 if (!xen_pv_domain())
150 return -1;
151
152 printk(KERN_DEBUG "xen: registering gsi %u triggering %d polarity %d\n",
153 gsi, triggering, polarity);
154
155 irq = xen_register_pirq(gsi, gsi_override, triggering);
156
157 setup_gsi.gsi = gsi;
158 setup_gsi.triggering = (triggering == ACPI_EDGE_SENSITIVE ? 0 : 1);
159 setup_gsi.polarity = (polarity == ACPI_ACTIVE_HIGH ? 0 : 1);
160
161 rc = HYPERVISOR_physdev_op(PHYSDEVOP_setup_gsi, &setup_gsi);
162 if (rc == -EEXIST)
163 printk(KERN_INFO "Already setup the GSI :%d\n", gsi);
164 else if (rc) {
165 printk(KERN_ERR "Failed to setup GSI :%d, err_code:%d\n",
166 gsi, rc);
167 }
168
169 return irq;
170}
171
172static int acpi_register_gsi_xen(struct device *dev, u32 gsi,
173 int trigger, int polarity)
174{
175 return xen_register_gsi(gsi, -1 /* no GSI override */, trigger, polarity);
176}
177#endif
178
61#if defined(CONFIG_PCI_MSI) 179#if defined(CONFIG_PCI_MSI)
62#include <linux/msi.h> 180#include <linux/msi.h>
63#include <asm/msidef.h> 181#include <asm/msidef.h>
@@ -65,6 +183,46 @@ static int acpi_register_gsi_xen_hvm(struct device *dev, u32 gsi,
65struct xen_pci_frontend_ops *xen_pci_frontend; 183struct xen_pci_frontend_ops *xen_pci_frontend;
66EXPORT_SYMBOL_GPL(xen_pci_frontend); 184EXPORT_SYMBOL_GPL(xen_pci_frontend);
67 185
186/*
187 * For MSI interrupts we have to use drivers/xen/event.s functions to
188 * allocate an irq_desc and setup the right */
189static int xen_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
190{
191 int irq, ret, i;
192 struct msi_desc *msidesc;
193 int *v;
194
195 v = kzalloc(sizeof(int) * max(1, nvec), GFP_KERNEL);
196 if (!v)
197 return -ENOMEM;
198
199 if (type == PCI_CAP_ID_MSIX)
200 ret = xen_pci_frontend_enable_msix(dev, v, nvec);
201 else
202 ret = xen_pci_frontend_enable_msi(dev, v);
203 if (ret)
204 goto error;
205 i = 0;
206 list_for_each_entry(msidesc, &dev->msi_list, list) {
207 irq = xen_bind_pirq_msi_to_irq(dev, msidesc, v[i], 0,
208 (type == PCI_CAP_ID_MSIX) ?
209 "pcifront-msi-x" :
210 "pcifront-msi",
211 DOMID_SELF);
212 if (irq < 0)
213 goto free;
214 i++;
215 }
216 kfree(v);
217 return 0;
218
219error:
220 dev_err(&dev->dev, "Xen PCI frontend has not registered MSI/MSI-X support!\n");
221free:
222 kfree(v);
223 return ret;
224}
225
68#define XEN_PIRQ_MSI_DATA (MSI_DATA_TRIGGER_EDGE | \ 226#define XEN_PIRQ_MSI_DATA (MSI_DATA_TRIGGER_EDGE | \
69 MSI_DATA_LEVEL_ASSERT | (3 << 8) | MSI_DATA_VECTOR(0)) 227 MSI_DATA_LEVEL_ASSERT | (3 << 8) | MSI_DATA_VECTOR(0))
70 228
@@ -123,67 +281,6 @@ error:
123 return -ENODEV; 281 return -ENODEV;
124} 282}
125 283
126/*
127 * For MSI interrupts we have to use drivers/xen/event.s functions to
128 * allocate an irq_desc and setup the right */
129
130
131static int xen_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
132{
133 int irq, ret, i;
134 struct msi_desc *msidesc;
135 int *v;
136
137 v = kzalloc(sizeof(int) * max(1, nvec), GFP_KERNEL);
138 if (!v)
139 return -ENOMEM;
140
141 if (type == PCI_CAP_ID_MSIX)
142 ret = xen_pci_frontend_enable_msix(dev, v, nvec);
143 else
144 ret = xen_pci_frontend_enable_msi(dev, v);
145 if (ret)
146 goto error;
147 i = 0;
148 list_for_each_entry(msidesc, &dev->msi_list, list) {
149 irq = xen_bind_pirq_msi_to_irq(dev, msidesc, v[i], 0,
150 (type == PCI_CAP_ID_MSIX) ?
151 "pcifront-msi-x" :
152 "pcifront-msi",
153 DOMID_SELF);
154 if (irq < 0)
155 goto free;
156 i++;
157 }
158 kfree(v);
159 return 0;
160
161error:
162 dev_err(&dev->dev, "Xen PCI frontend has not registered MSI/MSI-X support!\n");
163free:
164 kfree(v);
165 return ret;
166}
167
168static void xen_teardown_msi_irqs(struct pci_dev *dev)
169{
170 struct msi_desc *msidesc;
171
172 msidesc = list_entry(dev->msi_list.next, struct msi_desc, list);
173 if (msidesc->msi_attrib.is_msix)
174 xen_pci_frontend_disable_msix(dev);
175 else
176 xen_pci_frontend_disable_msi(dev);
177
178 /* Free the IRQ's and the msidesc using the generic code. */
179 default_teardown_msi_irqs(dev);
180}
181
182static void xen_teardown_msi_irq(unsigned int irq)
183{
184 xen_destroy_irq(irq);
185}
186
187#ifdef CONFIG_XEN_DOM0 284#ifdef CONFIG_XEN_DOM0
188static int xen_initdom_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) 285static int xen_initdom_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
189{ 286{
@@ -242,44 +339,28 @@ out:
242 return ret; 339 return ret;
243} 340}
244#endif 341#endif
245#endif
246 342
247static int xen_pcifront_enable_irq(struct pci_dev *dev) 343static void xen_teardown_msi_irqs(struct pci_dev *dev)
248{ 344{
249 int rc; 345 struct msi_desc *msidesc;
250 int share = 1;
251 int pirq;
252 u8 gsi;
253 346
254 rc = pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &gsi); 347 msidesc = list_entry(dev->msi_list.next, struct msi_desc, list);
255 if (rc < 0) { 348 if (msidesc->msi_attrib.is_msix)
256 dev_warn(&dev->dev, "Xen PCI: failed to read interrupt line: %d\n", 349 xen_pci_frontend_disable_msix(dev);
257 rc); 350 else
258 return rc; 351 xen_pci_frontend_disable_msi(dev);
259 }
260 352
261 rc = xen_allocate_pirq_gsi(gsi); 353 /* Free the IRQ's and the msidesc using the generic code. */
262 if (rc < 0) { 354 default_teardown_msi_irqs(dev);
263 dev_warn(&dev->dev, "Xen PCI: failed to allocate a PIRQ for GSI%d: %d\n", 355}
264 gsi, rc);
265 return rc;
266 }
267 pirq = rc;
268 356
269 if (gsi < NR_IRQS_LEGACY) 357static void xen_teardown_msi_irq(unsigned int irq)
270 share = 0; 358{
359 xen_destroy_irq(irq);
360}
271 361
272 rc = xen_bind_pirq_gsi_to_irq(gsi, pirq, share, "pcifront"); 362#endif
273 if (rc < 0) {
274 dev_warn(&dev->dev, "Xen PCI: failed to bind GSI%d (PIRQ%d) to IRQ: %d\n",
275 gsi, pirq, rc);
276 return rc;
277 }
278 363
279 dev->irq = rc;
280 dev_info(&dev->dev, "Xen PCI mapped GSI%d to IRQ%d\n", gsi, dev->irq);
281 return 0;
282}
283 364
284int __init pci_xen_init(void) 365int __init pci_xen_init(void)
285{ 366{
@@ -327,79 +408,6 @@ int __init pci_xen_hvm_init(void)
327} 408}
328 409
329#ifdef CONFIG_XEN_DOM0 410#ifdef CONFIG_XEN_DOM0
330static int xen_register_pirq(u32 gsi, int gsi_override, int triggering)
331{
332 int rc, pirq, irq = -1;
333 struct physdev_map_pirq map_irq;
334 int shareable = 0;
335 char *name;
336
337 if (!xen_pv_domain())
338 return -1;
339
340 if (triggering == ACPI_EDGE_SENSITIVE) {
341 shareable = 0;
342 name = "ioapic-edge";
343 } else {
344 shareable = 1;
345 name = "ioapic-level";
346 }
347 pirq = xen_allocate_pirq_gsi(gsi);
348 if (pirq < 0)
349 goto out;
350
351 if (gsi_override >= 0)
352 irq = xen_bind_pirq_gsi_to_irq(gsi_override, pirq, shareable, name);
353 else
354 irq = xen_bind_pirq_gsi_to_irq(gsi, pirq, shareable, name);
355 if (irq < 0)
356 goto out;
357
358 printk(KERN_DEBUG "xen: --> pirq=%d -> irq=%d (gsi=%d)\n", pirq, irq, gsi);
359
360 map_irq.domid = DOMID_SELF;
361 map_irq.type = MAP_PIRQ_TYPE_GSI;
362 map_irq.index = gsi;
363 map_irq.pirq = pirq;
364
365 rc = HYPERVISOR_physdev_op(PHYSDEVOP_map_pirq, &map_irq);
366 if (rc) {
367 printk(KERN_WARNING "xen map irq failed %d\n", rc);
368 return -1;
369 }
370
371out:
372 return irq;
373}
374
375static int xen_register_gsi(u32 gsi, int gsi_override, int triggering, int polarity)
376{
377 int rc, irq;
378 struct physdev_setup_gsi setup_gsi;
379
380 if (!xen_pv_domain())
381 return -1;
382
383 printk(KERN_DEBUG "xen: registering gsi %u triggering %d polarity %d\n",
384 gsi, triggering, polarity);
385
386 irq = xen_register_pirq(gsi, gsi_override, triggering);
387
388 setup_gsi.gsi = gsi;
389 setup_gsi.triggering = (triggering == ACPI_EDGE_SENSITIVE ? 0 : 1);
390 setup_gsi.polarity = (polarity == ACPI_ACTIVE_HIGH ? 0 : 1);
391
392 rc = HYPERVISOR_physdev_op(PHYSDEVOP_setup_gsi, &setup_gsi);
393 if (rc == -EEXIST)
394 printk(KERN_INFO "Already setup the GSI :%d\n", gsi);
395 else if (rc) {
396 printk(KERN_ERR "Failed to setup GSI :%d, err_code:%d\n",
397 gsi, rc);
398 }
399
400 return irq;
401}
402
403static __init void xen_setup_acpi_sci(void) 411static __init void xen_setup_acpi_sci(void)
404{ 412{
405 int rc; 413 int rc;
@@ -447,12 +455,6 @@ static __init void xen_setup_acpi_sci(void)
447 return; 455 return;
448} 456}
449 457
450static int acpi_register_gsi_xen(struct device *dev, u32 gsi,
451 int trigger, int polarity)
452{
453 return xen_register_gsi(gsi, -1 /* no GSI override */, trigger, polarity);
454}
455
456static int __init pci_xen_initial_domain(void) 458static int __init pci_xen_initial_domain(void)
457{ 459{
458#ifdef CONFIG_PCI_MSI 460#ifdef CONFIG_PCI_MSI
@@ -493,9 +495,7 @@ void __init xen_setup_pirqs(void)
493 trigger ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE); 495 trigger ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE);
494 } 496 }
495} 497}
496#endif
497 498
498#ifdef CONFIG_XEN_DOM0
499struct xen_device_domain_owner { 499struct xen_device_domain_owner {
500 domid_t domain; 500 domid_t domain;
501 struct pci_dev *dev; 501 struct pci_dev *dev;