ia64/xen-unstable

view xen/arch/x86/x86_64/mmconfig_64.c @ 19837:eb82fc994ab2

VT-d: remove debug prints and turn on qinval read/write drains

This cleanup patch removes debug prints and turn on read and write
drains for VT-d queue invalidation if HW supports them.

Signed-off-by: Allen Kay <allen.m.kay@intel.com>
author Keir Fraser <keir.fraser@citrix.com>
date Thu Jun 25 13:06:44 2009 +0100 (2009-06-25)
parents 42fe00c6f8b4
children
line source
1 /*
2 * mmconfig.c - Low-level direct PCI config space access via MMCONFIG
3 *
4 * This is an 64bit optimized version that always keeps the full mmconfig
5 * space mapped. This allows lockless config space operation.
6 *
7 * copied from Linux
8 */
10 #include <xen/mm.h>
11 #include <xen/acpi.h>
12 #include <xen/xmalloc.h>
13 #include <xen/pci.h>
14 #include <xen/pci_regs.h>
16 #include "mmconfig.h"
18 /* Static virtual mapping of the MMCONFIG aperture */
19 struct mmcfg_virt {
20 struct acpi_mcfg_allocation *cfg;
21 char __iomem *virt;
22 };
23 static struct mmcfg_virt *pci_mmcfg_virt;
25 static char __iomem *get_virt(unsigned int seg, unsigned bus)
26 {
27 struct acpi_mcfg_allocation *cfg;
28 int cfg_num;
30 for (cfg_num = 0; cfg_num < pci_mmcfg_config_num; cfg_num++) {
31 cfg = pci_mmcfg_virt[cfg_num].cfg;
32 if (cfg->pci_segment == seg &&
33 (cfg->start_bus_number <= bus) &&
34 (cfg->end_bus_number >= bus))
35 return pci_mmcfg_virt[cfg_num].virt;
36 }
38 /* Fall back to type 0 */
39 return NULL;
40 }
42 static char __iomem *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn)
43 {
44 char __iomem *addr;
46 addr = get_virt(seg, bus);
47 if (!addr)
48 return NULL;
49 return addr + ((bus << 20) | (devfn << 12));
50 }
52 int pci_mmcfg_read(unsigned int seg, unsigned int bus,
53 unsigned int devfn, int reg, int len, u32 *value)
54 {
55 char __iomem *addr;
57 /* Why do we have this when nobody checks it. How about a BUG()!? -AK */
58 if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095))) {
59 err: *value = -1;
60 return -EINVAL;
61 }
63 addr = pci_dev_base(seg, bus, devfn);
64 if (!addr)
65 goto err;
67 switch (len) {
68 case 1:
69 *value = mmio_config_readb(addr + reg);
70 break;
71 case 2:
72 *value = mmio_config_readw(addr + reg);
73 break;
74 case 4:
75 *value = mmio_config_readl(addr + reg);
76 break;
77 }
79 return 0;
80 }
82 int pci_mmcfg_write(unsigned int seg, unsigned int bus,
83 unsigned int devfn, int reg, int len, u32 value)
84 {
85 char __iomem *addr;
87 /* Why do we have this when nobody checks it. How about a BUG()!? -AK */
88 if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095)))
89 return -EINVAL;
91 addr = pci_dev_base(seg, bus, devfn);
92 if (!addr)
93 return -EINVAL;
95 switch (len) {
96 case 1:
97 mmio_config_writeb(addr + reg, value);
98 break;
99 case 2:
100 mmio_config_writew(addr + reg, value);
101 break;
102 case 4:
103 mmio_config_writel(addr + reg, value);
104 break;
105 }
107 return 0;
108 }
110 static void __iomem * __init mcfg_ioremap(struct acpi_mcfg_allocation *cfg)
111 {
112 void __iomem *addr;
113 unsigned long virt;
114 unsigned long mfn;
115 unsigned long size, nr_mfn;
117 virt = PCI_MCFG_VIRT_START + (cfg->pci_segment * (1 << 22)) +
118 (cfg->start_bus_number * (1 << 20));
119 mfn = cfg->address >> PAGE_SHIFT;
120 size = (cfg->end_bus_number - cfg->start_bus_number) << 20;
121 nr_mfn = size >> PAGE_SHIFT;
123 map_pages_to_xen(virt, mfn, nr_mfn, PAGE_HYPERVISOR_NOCACHE);
124 addr = (void __iomem *) virt;
126 return addr;
127 }
129 int __init pci_mmcfg_arch_init(void)
130 {
131 int i;
132 pci_mmcfg_virt = xmalloc_bytes(sizeof(*pci_mmcfg_virt) * pci_mmcfg_config_num);
133 if (pci_mmcfg_virt == NULL) {
134 printk(KERN_ERR "PCI: Can not allocate memory for mmconfig structures\n");
135 return 0;
136 }
137 memset(pci_mmcfg_virt, 0, sizeof(*pci_mmcfg_virt) * pci_mmcfg_config_num);
139 for (i = 0; i < pci_mmcfg_config_num; ++i) {
140 pci_mmcfg_virt[i].cfg = &pci_mmcfg_config[i];
141 pci_mmcfg_virt[i].virt = mcfg_ioremap(&pci_mmcfg_config[i]);
142 if (!pci_mmcfg_virt[i].virt) {
143 printk(KERN_ERR "PCI: Cannot map mmconfig aperture for "
144 "segment %d\n",
145 pci_mmcfg_config[i].pci_segment);
146 pci_mmcfg_arch_free();
147 return 0;
148 }
149 }
150 return 1;
151 }
153 void __init pci_mmcfg_arch_free(void)
154 {
155 int i;
157 if (pci_mmcfg_virt == NULL)
158 return;
160 for (i = 0; i < pci_mmcfg_config_num; ++i) {
161 if (pci_mmcfg_virt[i].virt) {
162 iounmap(pci_mmcfg_virt[i].virt);
163 pci_mmcfg_virt[i].virt = NULL;
164 pci_mmcfg_virt[i].cfg = NULL;
165 }
166 }
168 xfree(pci_mmcfg_virt);
169 pci_mmcfg_virt = NULL;
170 }