You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge branch 'linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6
* 'linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6: (109 commits) PCI: fix coding style issue in pci_save_state() PCI: add pci_request_acs PCI: fix BUG_ON triggered by logical PCIe root port removal PCI: remove ifdefed pci_cleanup_aer_correct_error_status PCI: unconditionally clear AER uncorr status register during cleanup x86/PCI: claim SR-IOV BARs in pcibios_allocate_resource PCI: portdrv: remove redundant definitions PCI: portdrv: remove unnecessary struct pcie_port_data PCI: portdrv: minor cleanup for pcie_port_device_register PCI: portdrv: add missing irq cleanup PCI: portdrv: enable device before irq initialization PCI: portdrv: cleanup service irqs initialization PCI: portdrv: check capabilities first PCI: portdrv: move PME capability check PCI: portdrv: remove redundant pcie type calculation PCI: portdrv: cleanup pcie_device registration PCI: portdrv: remove redundant pcie_port_device_probe PCI: Always set prefetchable base/limit upper32 registers PCI: read-modify-write the pcie device control register when initiating pcie flr PCI: show dma_mask bits in /sys ... Fixed up conflicts in: arch/x86/kernel/amd_iommu_init.c drivers/pci/dmar.c drivers/pci/hotplug/acpiphp_glue.c
This commit is contained in:
@@ -37,35 +37,9 @@
|
||||
#include <xen/interface/xen.h>
|
||||
#include <xen/interface/version.h> /* to compile feature.c */
|
||||
#include <xen/features.h> /* to comiple xen-netfront.c */
|
||||
#include <xen/xen.h>
|
||||
#include <asm/xen/hypercall.h>
|
||||
|
||||
/* xen_domain_type is set before executing any C code by early_xen_setup */
|
||||
enum xen_domain_type {
|
||||
XEN_NATIVE, /* running on bare hardware */
|
||||
XEN_PV_DOMAIN, /* running in a PV domain */
|
||||
XEN_HVM_DOMAIN, /* running in a Xen hvm domain*/
|
||||
};
|
||||
|
||||
#ifdef CONFIG_XEN
|
||||
extern enum xen_domain_type xen_domain_type;
|
||||
#else
|
||||
#define xen_domain_type XEN_NATIVE
|
||||
#endif
|
||||
|
||||
#define xen_domain() (xen_domain_type != XEN_NATIVE)
|
||||
#define xen_pv_domain() (xen_domain() && \
|
||||
xen_domain_type == XEN_PV_DOMAIN)
|
||||
#define xen_hvm_domain() (xen_domain() && \
|
||||
xen_domain_type == XEN_HVM_DOMAIN)
|
||||
|
||||
#ifdef CONFIG_XEN_DOM0
|
||||
#define xen_initial_domain() (xen_pv_domain() && \
|
||||
(xen_start_info->flags & SIF_INITDOMAIN))
|
||||
#else
|
||||
#define xen_initial_domain() (0)
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef CONFIG_XEN
|
||||
extern struct shared_info *HYPERVISOR_shared_info;
|
||||
extern struct start_info *xen_start_info;
|
||||
|
||||
+22
-11
@@ -131,6 +131,7 @@ alloc_pci_controller (int seg)
|
||||
}
|
||||
|
||||
struct pci_root_info {
|
||||
struct acpi_device *bridge;
|
||||
struct pci_controller *controller;
|
||||
char *name;
|
||||
};
|
||||
@@ -297,9 +298,20 @@ static __devinit acpi_status add_window(struct acpi_resource *res, void *data)
|
||||
window->offset = offset;
|
||||
|
||||
if (insert_resource(root, &window->resource)) {
|
||||
printk(KERN_ERR "alloc 0x%llx-0x%llx from %s for %s failed\n",
|
||||
window->resource.start, window->resource.end,
|
||||
root->name, info->name);
|
||||
dev_err(&info->bridge->dev,
|
||||
"can't allocate host bridge window %pR\n",
|
||||
&window->resource);
|
||||
} else {
|
||||
if (offset)
|
||||
dev_info(&info->bridge->dev, "host bridge window %pR "
|
||||
"(PCI address [%#llx-%#llx])\n",
|
||||
&window->resource,
|
||||
window->resource.start - offset,
|
||||
window->resource.end - offset);
|
||||
else
|
||||
dev_info(&info->bridge->dev,
|
||||
"host bridge window %pR\n",
|
||||
&window->resource);
|
||||
}
|
||||
|
||||
return AE_OK;
|
||||
@@ -319,8 +331,9 @@ pcibios_setup_root_windows(struct pci_bus *bus, struct pci_controller *ctrl)
|
||||
(res->end - res->start < 16))
|
||||
continue;
|
||||
if (j >= PCI_BUS_NUM_RESOURCES) {
|
||||
printk("Ignoring range [%#llx-%#llx] (%lx)\n",
|
||||
res->start, res->end, res->flags);
|
||||
dev_warn(&bus->dev,
|
||||
"ignoring host bridge window %pR (no space)\n",
|
||||
res);
|
||||
continue;
|
||||
}
|
||||
bus->resource[j++] = res;
|
||||
@@ -364,6 +377,7 @@ pci_acpi_scan_root(struct acpi_device *device, int domain, int bus)
|
||||
goto out3;
|
||||
|
||||
sprintf(name, "PCI Bus %04x:%02x", domain, bus);
|
||||
info.bridge = device;
|
||||
info.controller = controller;
|
||||
info.name = name;
|
||||
acpi_walk_resources(device->handle, METHOD_NAME__CRS,
|
||||
@@ -720,9 +734,6 @@ int ia64_pci_legacy_write(struct pci_bus *bus, u16 port, u32 val, u8 size)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* It's defined in drivers/pci/pci.c */
|
||||
extern u8 pci_cache_line_size;
|
||||
|
||||
/**
|
||||
* set_pci_cacheline_size - determine cacheline size for PCI devices
|
||||
*
|
||||
@@ -731,7 +742,7 @@ extern u8 pci_cache_line_size;
|
||||
*
|
||||
* Code mostly taken from arch/ia64/kernel/palinfo.c:cache_info().
|
||||
*/
|
||||
static void __init set_pci_cacheline_size(void)
|
||||
static void __init set_pci_dfl_cacheline_size(void)
|
||||
{
|
||||
unsigned long levels, unique_caches;
|
||||
long status;
|
||||
@@ -751,7 +762,7 @@ static void __init set_pci_cacheline_size(void)
|
||||
"(status=%ld)\n", __func__, status);
|
||||
return;
|
||||
}
|
||||
pci_cache_line_size = (1 << cci.pcci_line_size) / 4;
|
||||
pci_dfl_cache_line_size = (1 << cci.pcci_line_size) / 4;
|
||||
}
|
||||
|
||||
u64 ia64_dma_get_required_mask(struct device *dev)
|
||||
@@ -782,7 +793,7 @@ EXPORT_SYMBOL_GPL(dma_get_required_mask);
|
||||
|
||||
static int __init pcibios_init(void)
|
||||
{
|
||||
set_pci_cacheline_size();
|
||||
set_pci_dfl_cacheline_size();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
|
||||
#define PCI_IRQ_NONE 0xffffffff
|
||||
|
||||
#define PCI_CACHE_LINE_BYTES 64
|
||||
|
||||
static inline void pcibios_set_master(struct pci_dev *dev)
|
||||
{
|
||||
/* No special bus mastering setup handling */
|
||||
|
||||
@@ -1081,3 +1081,10 @@ void pci_resource_to_user(const struct pci_dev *pdev, int bar,
|
||||
*start = rp->start - offset;
|
||||
*end = rp->end - offset;
|
||||
}
|
||||
|
||||
static int __init pcibios_init(void)
|
||||
{
|
||||
pci_dfl_cache_line_size = 64 >> 2;
|
||||
return 0;
|
||||
}
|
||||
subsys_initcall(pcibios_init);
|
||||
|
||||
@@ -118,11 +118,27 @@ extern int __init pcibios_init(void);
|
||||
|
||||
/* pci-mmconfig.c */
|
||||
|
||||
/* "PCI MMCONFIG %04x [bus %02x-%02x]" */
|
||||
#define PCI_MMCFG_RESOURCE_NAME_LEN (22 + 4 + 2 + 2)
|
||||
|
||||
struct pci_mmcfg_region {
|
||||
struct list_head list;
|
||||
struct resource res;
|
||||
u64 address;
|
||||
char __iomem *virt;
|
||||
u16 segment;
|
||||
u8 start_bus;
|
||||
u8 end_bus;
|
||||
char name[PCI_MMCFG_RESOURCE_NAME_LEN];
|
||||
};
|
||||
|
||||
extern int __init pci_mmcfg_arch_init(void);
|
||||
extern void __init pci_mmcfg_arch_free(void);
|
||||
extern struct pci_mmcfg_region *pci_mmconfig_lookup(int segment, int bus);
|
||||
|
||||
extern struct acpi_mcfg_allocation *pci_mmcfg_config;
|
||||
extern int pci_mmcfg_config_num;
|
||||
extern struct list_head pci_mmcfg_list;
|
||||
|
||||
#define PCI_MMCFG_BUS_OFFSET(bus) ((bus) << 20)
|
||||
|
||||
/*
|
||||
* AMD Fam10h CPUs are buggy, and cannot access MMIO config space
|
||||
|
||||
@@ -37,31 +37,4 @@
|
||||
extern struct shared_info *HYPERVISOR_shared_info;
|
||||
extern struct start_info *xen_start_info;
|
||||
|
||||
enum xen_domain_type {
|
||||
XEN_NATIVE, /* running on bare hardware */
|
||||
XEN_PV_DOMAIN, /* running in a PV domain */
|
||||
XEN_HVM_DOMAIN, /* running in a Xen hvm domain */
|
||||
};
|
||||
|
||||
#ifdef CONFIG_XEN
|
||||
extern enum xen_domain_type xen_domain_type;
|
||||
#else
|
||||
#define xen_domain_type XEN_NATIVE
|
||||
#endif
|
||||
|
||||
#define xen_domain() (xen_domain_type != XEN_NATIVE)
|
||||
#define xen_pv_domain() (xen_domain() && \
|
||||
xen_domain_type == XEN_PV_DOMAIN)
|
||||
#define xen_hvm_domain() (xen_domain() && \
|
||||
xen_domain_type == XEN_HVM_DOMAIN)
|
||||
|
||||
#ifdef CONFIG_XEN_DOM0
|
||||
#include <xen/interface/xen.h>
|
||||
|
||||
#define xen_initial_domain() (xen_pv_domain() && \
|
||||
xen_start_info->flags & SIF_INITDOMAIN)
|
||||
#else /* !CONFIG_XEN_DOM0 */
|
||||
#define xen_initial_domain() (0)
|
||||
#endif /* CONFIG_XEN_DOM0 */
|
||||
|
||||
#endif /* _ASM_X86_XEN_HYPERVISOR_H */
|
||||
|
||||
@@ -1336,6 +1336,9 @@ void __init amd_iommu_detect(void)
|
||||
iommu_detected = 1;
|
||||
amd_iommu_detected = 1;
|
||||
x86_init.iommu.iommu_init = amd_iommu_init;
|
||||
|
||||
/* Make sure ACS will be enabled */
|
||||
pci_request_acs();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,3 +15,8 @@ obj-$(CONFIG_X86_NUMAQ) += numaq_32.o
|
||||
|
||||
obj-y += common.o early.o
|
||||
obj-y += amd_bus.o
|
||||
obj-$(CONFIG_X86_64) += bus_numa.o intel_bus.o
|
||||
|
||||
ifeq ($(CONFIG_PCI_DEBUG),y)
|
||||
EXTRA_CFLAGS += -DDEBUG
|
||||
endif
|
||||
|
||||
+60
-14
@@ -7,6 +7,7 @@
|
||||
#include <asm/pci_x86.h>
|
||||
|
||||
struct pci_root_info {
|
||||
struct acpi_device *bridge;
|
||||
char *name;
|
||||
unsigned int res_num;
|
||||
struct resource *res;
|
||||
@@ -58,6 +59,30 @@ bus_has_transparent_bridge(struct pci_bus *bus)
|
||||
return false;
|
||||
}
|
||||
|
||||
static void
|
||||
align_resource(struct acpi_device *bridge, struct resource *res)
|
||||
{
|
||||
int align = (res->flags & IORESOURCE_MEM) ? 16 : 4;
|
||||
|
||||
/*
|
||||
* Host bridge windows are not BARs, but the decoders on the PCI side
|
||||
* that claim this address space have starting alignment and length
|
||||
* constraints, so fix any obvious BIOS goofs.
|
||||
*/
|
||||
if (!IS_ALIGNED(res->start, align)) {
|
||||
dev_printk(KERN_DEBUG, &bridge->dev,
|
||||
"host bridge window %pR invalid; "
|
||||
"aligning start to %d-byte boundary\n", res, align);
|
||||
res->start &= ~(align - 1);
|
||||
}
|
||||
if (!IS_ALIGNED(res->end + 1, align)) {
|
||||
dev_printk(KERN_DEBUG, &bridge->dev,
|
||||
"host bridge window %pR invalid; "
|
||||
"aligning end to %d-byte boundary\n", res, align);
|
||||
res->end = ALIGN(res->end, align) - 1;
|
||||
}
|
||||
}
|
||||
|
||||
static acpi_status
|
||||
setup_resource(struct acpi_resource *acpi_res, void *data)
|
||||
{
|
||||
@@ -91,11 +116,12 @@ setup_resource(struct acpi_resource *acpi_res, void *data)
|
||||
start = addr.minimum + addr.translation_offset;
|
||||
end = start + addr.address_length - 1;
|
||||
if (info->res_num >= max_root_bus_resources) {
|
||||
printk(KERN_WARNING "PCI: Failed to allocate 0x%lx-0x%lx "
|
||||
"from %s for %s due to _CRS returning more than "
|
||||
"%d resource descriptors\n", (unsigned long) start,
|
||||
(unsigned long) end, root->name, info->name,
|
||||
max_root_bus_resources);
|
||||
if (pci_probe & PCI_USE__CRS)
|
||||
printk(KERN_WARNING "PCI: Failed to allocate "
|
||||
"0x%lx-0x%lx from %s for %s due to _CRS "
|
||||
"returning more than %d resource descriptors\n",
|
||||
(unsigned long) start, (unsigned long) end,
|
||||
root->name, info->name, max_root_bus_resources);
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
@@ -105,14 +131,28 @@ setup_resource(struct acpi_resource *acpi_res, void *data)
|
||||
res->start = start;
|
||||
res->end = end;
|
||||
res->child = NULL;
|
||||
align_resource(info->bridge, res);
|
||||
|
||||
if (!(pci_probe & PCI_USE__CRS)) {
|
||||
dev_printk(KERN_DEBUG, &info->bridge->dev,
|
||||
"host bridge window %pR (ignored)\n", res);
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
if (insert_resource(root, res)) {
|
||||
printk(KERN_ERR "PCI: Failed to allocate 0x%lx-0x%lx "
|
||||
"from %s for %s\n", (unsigned long) res->start,
|
||||
(unsigned long) res->end, root->name, info->name);
|
||||
dev_err(&info->bridge->dev,
|
||||
"can't allocate host bridge window %pR\n", res);
|
||||
} else {
|
||||
info->bus->resource[info->res_num] = res;
|
||||
info->res_num++;
|
||||
if (addr.translation_offset)
|
||||
dev_info(&info->bridge->dev, "host bridge window %pR "
|
||||
"(PCI address [%#llx-%#llx])\n",
|
||||
res, res->start - addr.translation_offset,
|
||||
res->end - addr.translation_offset);
|
||||
else
|
||||
dev_info(&info->bridge->dev,
|
||||
"host bridge window %pR\n", res);
|
||||
}
|
||||
return AE_OK;
|
||||
}
|
||||
@@ -124,6 +164,12 @@ get_current_resources(struct acpi_device *device, int busnum,
|
||||
struct pci_root_info info;
|
||||
size_t size;
|
||||
|
||||
if (!(pci_probe & PCI_USE__CRS))
|
||||
dev_info(&device->dev,
|
||||
"ignoring host bridge windows from ACPI; "
|
||||
"boot with \"pci=use_crs\" to use them\n");
|
||||
|
||||
info.bridge = device;
|
||||
info.bus = bus;
|
||||
info.res_num = 0;
|
||||
acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_resource,
|
||||
@@ -163,8 +209,9 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int do
|
||||
#endif
|
||||
|
||||
if (domain && !pci_domains_supported) {
|
||||
printk(KERN_WARNING "PCI: Multiple domains not supported "
|
||||
"(dom %d, bus %d)\n", domain, busnum);
|
||||
printk(KERN_WARNING "pci_bus %04x:%02x: "
|
||||
"ignored (multiple domains not supported)\n",
|
||||
domain, busnum);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -188,7 +235,8 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int do
|
||||
*/
|
||||
sd = kzalloc(sizeof(*sd), GFP_KERNEL);
|
||||
if (!sd) {
|
||||
printk(KERN_ERR "PCI: OOM, not probing PCI bus %02x\n", busnum);
|
||||
printk(KERN_WARNING "pci_bus %04x:%02x: "
|
||||
"ignored (out of memory)\n", domain, busnum);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -209,9 +257,7 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int do
|
||||
} else {
|
||||
bus = pci_create_bus(NULL, busnum, &pci_root_ops, sd);
|
||||
if (bus) {
|
||||
if (pci_probe & PCI_USE__CRS)
|
||||
get_current_resources(device, busnum, domain,
|
||||
bus);
|
||||
get_current_resources(device, busnum, domain, bus);
|
||||
bus->subordinate = pci_scan_child_bus(bus);
|
||||
}
|
||||
}
|
||||
|
||||
+6
-114
@@ -6,10 +6,10 @@
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
#include <asm/pci-direct.h>
|
||||
#include <asm/mpspec.h>
|
||||
#include <linux/cpumask.h>
|
||||
#endif
|
||||
|
||||
#include "bus_numa.h"
|
||||
|
||||
/*
|
||||
* This discovers the pcibus <-> node mapping on AMD K8.
|
||||
* also get peer root bus resource for io,mmio
|
||||
@@ -17,67 +17,6 @@
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
|
||||
/*
|
||||
* sub bus (transparent) will use entres from 3 to store extra from root,
|
||||
* so need to make sure have enought slot there, increase PCI_BUS_NUM_RESOURCES?
|
||||
*/
|
||||
#define RES_NUM 16
|
||||
struct pci_root_info {
|
||||
char name[12];
|
||||
unsigned int res_num;
|
||||
struct resource res[RES_NUM];
|
||||
int bus_min;
|
||||
int bus_max;
|
||||
int node;
|
||||
int link;
|
||||
};
|
||||
|
||||
/* 4 at this time, it may become to 32 */
|
||||
#define PCI_ROOT_NR 4
|
||||
static int pci_root_num;
|
||||
static struct pci_root_info pci_root_info[PCI_ROOT_NR];
|
||||
|
||||
void x86_pci_root_bus_res_quirks(struct pci_bus *b)
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
struct pci_root_info *info;
|
||||
|
||||
/* don't go for it if _CRS is used already */
|
||||
if (b->resource[0] != &ioport_resource ||
|
||||
b->resource[1] != &iomem_resource)
|
||||
return;
|
||||
|
||||
/* if only one root bus, don't need to anything */
|
||||
if (pci_root_num < 2)
|
||||
return;
|
||||
|
||||
for (i = 0; i < pci_root_num; i++) {
|
||||
if (pci_root_info[i].bus_min == b->number)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == pci_root_num)
|
||||
return;
|
||||
|
||||
printk(KERN_DEBUG "PCI: peer root bus %02x res updated from pci conf\n",
|
||||
b->number);
|
||||
|
||||
info = &pci_root_info[i];
|
||||
for (j = 0; j < info->res_num; j++) {
|
||||
struct resource *res;
|
||||
struct resource *root;
|
||||
|
||||
res = &info->res[j];
|
||||
b->resource[j] = res;
|
||||
if (res->flags & IORESOURCE_IO)
|
||||
root = &ioport_resource;
|
||||
else
|
||||
root = &iomem_resource;
|
||||
insert_resource(root, res);
|
||||
}
|
||||
}
|
||||
|
||||
#define RANGE_NUM 16
|
||||
|
||||
struct res_range {
|
||||
@@ -130,52 +69,6 @@ static void __init update_range(struct res_range *range, size_t start,
|
||||
}
|
||||
}
|
||||
|
||||
static void __init update_res(struct pci_root_info *info, size_t start,
|
||||
size_t end, unsigned long flags, int merge)
|
||||
{
|
||||
int i;
|
||||
struct resource *res;
|
||||
|
||||
if (!merge)
|
||||
goto addit;
|
||||
|
||||
/* try to merge it with old one */
|
||||
for (i = 0; i < info->res_num; i++) {
|
||||
size_t final_start, final_end;
|
||||
size_t common_start, common_end;
|
||||
|
||||
res = &info->res[i];
|
||||
if (res->flags != flags)
|
||||
continue;
|
||||
|
||||
common_start = max((size_t)res->start, start);
|
||||
common_end = min((size_t)res->end, end);
|
||||
if (common_start > common_end + 1)
|
||||
continue;
|
||||
|
||||
final_start = min((size_t)res->start, start);
|
||||
final_end = max((size_t)res->end, end);
|
||||
|
||||
res->start = final_start;
|
||||
res->end = final_end;
|
||||
return;
|
||||
}
|
||||
|
||||
addit:
|
||||
|
||||
/* need to add that */
|
||||
if (info->res_num >= RES_NUM)
|
||||
return;
|
||||
|
||||
res = &info->res[info->res_num];
|
||||
res->name = info->name;
|
||||
res->flags = flags;
|
||||
res->start = start;
|
||||
res->end = end;
|
||||
res->child = NULL;
|
||||
info->res_num++;
|
||||
}
|
||||
|
||||
struct pci_hostbridge_probe {
|
||||
u32 bus;
|
||||
u32 slot;
|
||||
@@ -230,7 +123,6 @@ static int __init early_fill_mp_bus_info(void)
|
||||
int j;
|
||||
unsigned bus;
|
||||
unsigned slot;
|
||||
int found;
|
||||
int node;
|
||||
int link;
|
||||
int def_node;
|
||||
@@ -247,7 +139,7 @@ static int __init early_fill_mp_bus_info(void)
|
||||
if (!early_pci_allowed())
|
||||
return -1;
|
||||
|
||||
found = 0;
|
||||
found_all_numa_early = 0;
|
||||
for (i = 0; i < ARRAY_SIZE(pci_probes); i++) {
|
||||
u32 id;
|
||||
u16 device;
|
||||
@@ -261,12 +153,12 @@ static int __init early_fill_mp_bus_info(void)
|
||||
device = (id>>16) & 0xffff;
|
||||
if (pci_probes[i].vendor == vendor &&
|
||||
pci_probes[i].device == device) {
|
||||
found = 1;
|
||||
found_all_numa_early = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
if (!found_all_numa_early)
|
||||
return 0;
|
||||
|
||||
pci_root_num = 0;
|
||||
@@ -488,7 +380,7 @@ static int __init early_fill_mp_bus_info(void)
|
||||
info = &pci_root_info[i];
|
||||
res_num = info->res_num;
|
||||
busnum = info->bus_min;
|
||||
printk(KERN_DEBUG "bus: [%02x,%02x] on node %x link %x\n",
|
||||
printk(KERN_DEBUG "bus: [%02x, %02x] on node %x link %x\n",
|
||||
info->bus_min, info->bus_max, info->node, info->link);
|
||||
for (j = 0; j < res_num; j++) {
|
||||
res = &info->res[j];
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/pci.h>
|
||||
|
||||
#include "bus_numa.h"
|
||||
|
||||
int pci_root_num;
|
||||
struct pci_root_info pci_root_info[PCI_ROOT_NR];
|
||||
int found_all_numa_early;
|
||||
|
||||
void x86_pci_root_bus_res_quirks(struct pci_bus *b)
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
struct pci_root_info *info;
|
||||
|
||||
/* don't go for it if _CRS is used already */
|
||||
if (b->resource[0] != &ioport_resource ||
|
||||
b->resource[1] != &iomem_resource)
|
||||
return;
|
||||
|
||||
if (!pci_root_num)
|
||||
return;
|
||||
|
||||
/* for amd, if only one root bus, don't need to do anything */
|
||||
if (pci_root_num < 2 && found_all_numa_early)
|
||||
return;
|
||||
|
||||
for (i = 0; i < pci_root_num; i++) {
|
||||
if (pci_root_info[i].bus_min == b->number)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == pci_root_num)
|
||||
return;
|
||||
|
||||
printk(KERN_DEBUG "PCI: peer root bus %02x res updated from pci conf\n",
|
||||
b->number);
|
||||
|
||||
info = &pci_root_info[i];
|
||||
for (j = 0; j < info->res_num; j++) {
|
||||
struct resource *res;
|
||||
struct resource *root;
|
||||
|
||||
res = &info->res[j];
|
||||
b->resource[j] = res;
|
||||
if (res->flags & IORESOURCE_IO)
|
||||
root = &ioport_resource;
|
||||
else
|
||||
root = &iomem_resource;
|
||||
insert_resource(root, res);
|
||||
}
|
||||
}
|
||||
|
||||
void __init update_res(struct pci_root_info *info, size_t start,
|
||||
size_t end, unsigned long flags, int merge)
|
||||
{
|
||||
int i;
|
||||
struct resource *res;
|
||||
|
||||
if (start > end)
|
||||
return;
|
||||
|
||||
if (!merge)
|
||||
goto addit;
|
||||
|
||||
/* try to merge it with old one */
|
||||
for (i = 0; i < info->res_num; i++) {
|
||||
size_t final_start, final_end;
|
||||
size_t common_start, common_end;
|
||||
|
||||
res = &info->res[i];
|
||||
if (res->flags != flags)
|
||||
continue;
|
||||
|
||||
common_start = max((size_t)res->start, start);
|
||||
common_end = min((size_t)res->end, end);
|
||||
if (common_start > common_end + 1)
|
||||
continue;
|
||||
|
||||
final_start = min((size_t)res->start, start);
|
||||
final_end = max((size_t)res->end, end);
|
||||
|
||||
res->start = final_start;
|
||||
res->end = final_end;
|
||||
return;
|
||||
}
|
||||
|
||||
addit:
|
||||
|
||||
/* need to add that */
|
||||
if (info->res_num >= RES_NUM)
|
||||
return;
|
||||
|
||||
res = &info->res[info->res_num];
|
||||
res->name = info->name;
|
||||
res->flags = flags;
|
||||
res->start = start;
|
||||
res->end = end;
|
||||
res->child = NULL;
|
||||
info->res_num++;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
#ifdef CONFIG_X86_64
|
||||
|
||||
/*
|
||||
* sub bus (transparent) will use entres from 3 to store extra from
|
||||
* root, so need to make sure we have enough slot there, Should we
|
||||
* increase PCI_BUS_NUM_RESOURCES?
|
||||
*/
|
||||
#define RES_NUM 16
|
||||
struct pci_root_info {
|
||||
char name[12];
|
||||
unsigned int res_num;
|
||||
struct resource res[RES_NUM];
|
||||
int bus_min;
|
||||
int bus_max;
|
||||
int node;
|
||||
int link;
|
||||
};
|
||||
|
||||
/* 4 at this time, it may become to 32 */
|
||||
#define PCI_ROOT_NR 4
|
||||
extern int pci_root_num;
|
||||
extern struct pci_root_info pci_root_info[PCI_ROOT_NR];
|
||||
extern int found_all_numa_early;
|
||||
|
||||
extern void update_res(struct pci_root_info *info, size_t start,
|
||||
size_t end, unsigned long flags, int merge);
|
||||
#endif
|
||||
+11
-9
@@ -410,8 +410,6 @@ struct pci_bus * __devinit pcibios_scan_root(int busnum)
|
||||
return bus;
|
||||
}
|
||||
|
||||
extern u8 pci_cache_line_size;
|
||||
|
||||
int __init pcibios_init(void)
|
||||
{
|
||||
struct cpuinfo_x86 *c = &boot_cpu_data;
|
||||
@@ -422,15 +420,19 @@ int __init pcibios_init(void)
|
||||
}
|
||||
|
||||
/*
|
||||
* Assume PCI cacheline size of 32 bytes for all x86s except K7/K8
|
||||
* and P4. It's also good for 386/486s (which actually have 16)
|
||||
* Set PCI cacheline size to that of the CPU if the CPU has reported it.
|
||||
* (For older CPUs that don't support cpuid, we se it to 32 bytes
|
||||
* It's also good for 386/486s (which actually have 16)
|
||||
* as quite a few PCI devices do not support smaller values.
|
||||
*/
|
||||
pci_cache_line_size = 32 >> 2;
|
||||
if (c->x86 >= 6 && c->x86_vendor == X86_VENDOR_AMD)
|
||||
pci_cache_line_size = 64 >> 2; /* K7 & K8 */
|
||||
else if (c->x86 > 6 && c->x86_vendor == X86_VENDOR_INTEL)
|
||||
pci_cache_line_size = 128 >> 2; /* P4 */
|
||||
if (c->x86_clflush_size > 0) {
|
||||
pci_dfl_cache_line_size = c->x86_clflush_size >> 2;
|
||||
printk(KERN_DEBUG "PCI: pci_cache_line_size set to %d bytes\n",
|
||||
pci_dfl_cache_line_size << 2);
|
||||
} else {
|
||||
pci_dfl_cache_line_size = 32 >> 2;
|
||||
printk(KERN_DEBUG "PCI: Unknown cacheline size. Setting to 32 bytes\n");
|
||||
}
|
||||
|
||||
pcibios_resource_survey();
|
||||
|
||||
|
||||
@@ -12,8 +12,6 @@ u32 read_pci_config(u8 bus, u8 slot, u8 func, u8 offset)
|
||||
u32 v;
|
||||
outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8);
|
||||
v = inl(0xcfc);
|
||||
if (v != 0xffffffff)
|
||||
pr_debug("%x reading 4 from %x: %x\n", slot, offset, v);
|
||||
return v;
|
||||
}
|
||||
|
||||
@@ -22,7 +20,6 @@ u8 read_pci_config_byte(u8 bus, u8 slot, u8 func, u8 offset)
|
||||
u8 v;
|
||||
outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8);
|
||||
v = inb(0xcfc + (offset&3));
|
||||
pr_debug("%x reading 1 from %x: %x\n", slot, offset, v);
|
||||
return v;
|
||||
}
|
||||
|
||||
@@ -31,28 +28,24 @@ u16 read_pci_config_16(u8 bus, u8 slot, u8 func, u8 offset)
|
||||
u16 v;
|
||||
outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8);
|
||||
v = inw(0xcfc + (offset&2));
|
||||
pr_debug("%x reading 2 from %x: %x\n", slot, offset, v);
|
||||
return v;
|
||||
}
|
||||
|
||||
void write_pci_config(u8 bus, u8 slot, u8 func, u8 offset,
|
||||
u32 val)
|
||||
{
|
||||
pr_debug("%x writing to %x: %x\n", slot, offset, val);
|
||||
outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8);
|
||||
outl(val, 0xcfc);
|
||||
}
|
||||
|
||||
void write_pci_config_byte(u8 bus, u8 slot, u8 func, u8 offset, u8 val)
|
||||
{
|
||||
pr_debug("%x writing to %x: %x\n", slot, offset, val);
|
||||
outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8);
|
||||
outb(val, 0xcfc + (offset&3));
|
||||
}
|
||||
|
||||
void write_pci_config_16(u8 bus, u8 slot, u8 func, u8 offset, u16 val)
|
||||
{
|
||||
pr_debug("%x writing to %x: %x\n", slot, offset, val);
|
||||
outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8);
|
||||
outw(val, 0xcfc + (offset&2));
|
||||
}
|
||||
|
||||
+33
-9
@@ -129,7 +129,9 @@ static void __init pcibios_allocate_bus_resources(struct list_head *bus_list)
|
||||
continue;
|
||||
if (!r->start ||
|
||||
pci_claim_resource(dev, idx) < 0) {
|
||||
dev_info(&dev->dev, "BAR %d: can't allocate resource\n", idx);
|
||||
dev_info(&dev->dev,
|
||||
"can't reserve window %pR\n",
|
||||
r);
|
||||
/*
|
||||
* Something is wrong with the region.
|
||||
* Invalidate the resource to prevent
|
||||
@@ -144,16 +146,29 @@ static void __init pcibios_allocate_bus_resources(struct list_head *bus_list)
|
||||
}
|
||||
}
|
||||
|
||||
struct pci_check_idx_range {
|
||||
int start;
|
||||
int end;
|
||||
};
|
||||
|
||||
static void __init pcibios_allocate_resources(int pass)
|
||||
{
|
||||
struct pci_dev *dev = NULL;
|
||||
int idx, disabled;
|
||||
int idx, disabled, i;
|
||||
u16 command;
|
||||
struct resource *r;
|
||||
|
||||
struct pci_check_idx_range idx_range[] = {
|
||||
{ PCI_STD_RESOURCES, PCI_STD_RESOURCE_END },
|
||||
#ifdef CONFIG_PCI_IOV
|
||||
{ PCI_IOV_RESOURCES, PCI_IOV_RESOURCE_END },
|
||||
#endif
|
||||
};
|
||||
|
||||
for_each_pci_dev(dev) {
|
||||
pci_read_config_word(dev, PCI_COMMAND, &command);
|
||||
for (idx = 0; idx < PCI_ROM_RESOURCE; idx++) {
|
||||
for (i = 0; i < ARRAY_SIZE(idx_range); i++)
|
||||
for (idx = idx_range[i].start; idx <= idx_range[i].end; idx++) {
|
||||
r = &dev->resource[idx];
|
||||
if (r->parent) /* Already allocated */
|
||||
continue;
|
||||
@@ -164,12 +179,12 @@ static void __init pcibios_allocate_resources(int pass)
|
||||
else
|
||||
disabled = !(command & PCI_COMMAND_MEMORY);
|
||||
if (pass == disabled) {
|
||||
dev_dbg(&dev->dev, "resource %#08llx-%#08llx (f=%lx, d=%d, p=%d)\n",
|
||||
(unsigned long long) r->start,
|
||||
(unsigned long long) r->end,
|
||||
r->flags, disabled, pass);
|
||||
dev_dbg(&dev->dev,
|
||||
"BAR %d: reserving %pr (d=%d, p=%d)\n",
|
||||
idx, r, disabled, pass);
|
||||
if (pci_claim_resource(dev, idx) < 0) {
|
||||
dev_info(&dev->dev, "BAR %d: can't allocate resource\n", idx);
|
||||
dev_info(&dev->dev,
|
||||
"can't reserve %pR\n", r);
|
||||
/* We'll assign a new address later */
|
||||
r->end -= r->start;
|
||||
r->start = 0;
|
||||
@@ -182,7 +197,7 @@ static void __init pcibios_allocate_resources(int pass)
|
||||
/* Turn the ROM off, leave the resource region,
|
||||
* but keep it unregistered. */
|
||||
u32 reg;
|
||||
dev_dbg(&dev->dev, "disabling ROM\n");
|
||||
dev_dbg(&dev->dev, "disabling ROM %pR\n", r);
|
||||
r->flags &= ~IORESOURCE_ROM_ENABLE;
|
||||
pci_read_config_dword(dev,
|
||||
dev->rom_base_reg, ®);
|
||||
@@ -282,6 +297,15 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
|
||||
return -EINVAL;
|
||||
|
||||
prot = pgprot_val(vma->vm_page_prot);
|
||||
|
||||
/*
|
||||
* Return error if pat is not enabled and write_combine is requested.
|
||||
* Caller can followup with UC MINUS request and add a WC mtrr if there
|
||||
* is a free mtrr slot.
|
||||
*/
|
||||
if (!pat_enabled && write_combine)
|
||||
return -EINVAL;
|
||||
|
||||
if (pat_enabled && write_combine)
|
||||
prot |= _PAGE_CACHE_WC;
|
||||
else if (pat_enabled || boot_cpu_data.x86 > 3)
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* to read io range from IOH pci conf, need to do it after mmconfig is there
|
||||
*/
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/init.h>
|
||||
#include <asm/pci_x86.h>
|
||||
|
||||
#include "bus_numa.h"
|
||||
|
||||
static inline void print_ioh_resources(struct pci_root_info *info)
|
||||
{
|
||||
int res_num;
|
||||
int busnum;
|
||||
int i;
|
||||
|
||||
printk(KERN_DEBUG "IOH bus: [%02x, %02x]\n",
|
||||
info->bus_min, info->bus_max);
|
||||
res_num = info->res_num;
|
||||
busnum = info->bus_min;
|
||||
for (i = 0; i < res_num; i++) {
|
||||
struct resource *res;
|
||||
|
||||
res = &info->res[i];
|
||||
printk(KERN_DEBUG "IOH bus: %02x index %x %s: [%llx, %llx]\n",
|
||||
busnum, i,
|
||||
(res->flags & IORESOURCE_IO) ? "io port" :
|
||||
"mmio",
|
||||
res->start, res->end);
|
||||
}
|
||||
}
|
||||
|
||||
#define IOH_LIO 0x108
|
||||
#define IOH_LMMIOL 0x10c
|
||||
#define IOH_LMMIOH 0x110
|
||||
#define IOH_LMMIOH_BASEU 0x114
|
||||
#define IOH_LMMIOH_LIMITU 0x118
|
||||
#define IOH_LCFGBUS 0x11c
|
||||
|
||||
static void __devinit pci_root_bus_res(struct pci_dev *dev)
|
||||
{
|
||||
u16 word;
|
||||
u32 dword;
|
||||
struct pci_root_info *info;
|
||||
u16 io_base, io_end;
|
||||
u32 mmiol_base, mmiol_end;
|
||||
u64 mmioh_base, mmioh_end;
|
||||
int bus_base, bus_end;
|
||||
|
||||
if (pci_root_num >= PCI_ROOT_NR) {
|
||||
printk(KERN_DEBUG "intel_bus.c: PCI_ROOT_NR is too small\n");
|
||||
return;
|
||||
}
|
||||
|
||||
info = &pci_root_info[pci_root_num];
|
||||
pci_root_num++;
|
||||
|
||||
pci_read_config_word(dev, IOH_LCFGBUS, &word);
|
||||
bus_base = (word & 0xff);
|
||||
bus_end = (word & 0xff00) >> 8;
|
||||
sprintf(info->name, "PCI Bus #%02x", bus_base);
|
||||
info->bus_min = bus_base;
|
||||
info->bus_max = bus_end;
|
||||
|
||||
pci_read_config_word(dev, IOH_LIO, &word);
|
||||
io_base = (word & 0xf0) << (12 - 4);
|
||||
io_end = (word & 0xf000) | 0xfff;
|
||||
update_res(info, io_base, io_end, IORESOURCE_IO, 0);
|
||||
|
||||
pci_read_config_dword(dev, IOH_LMMIOL, &dword);
|
||||
mmiol_base = (dword & 0xff00) << (24 - 8);
|
||||
mmiol_end = (dword & 0xff000000) | 0xffffff;
|
||||
update_res(info, mmiol_base, mmiol_end, IORESOURCE_MEM, 0);
|
||||
|
||||
pci_read_config_dword(dev, IOH_LMMIOH, &dword);
|
||||
mmioh_base = ((u64)(dword & 0xfc00)) << (26 - 10);
|
||||
mmioh_end = ((u64)(dword & 0xfc000000) | 0x3ffffff);
|
||||
pci_read_config_dword(dev, IOH_LMMIOH_BASEU, &dword);
|
||||
mmioh_base |= ((u64)(dword & 0x7ffff)) << 32;
|
||||
pci_read_config_dword(dev, IOH_LMMIOH_LIMITU, &dword);
|
||||
mmioh_end |= ((u64)(dword & 0x7ffff)) << 32;
|
||||
update_res(info, mmioh_base, mmioh_end, IORESOURCE_MEM, 0);
|
||||
|
||||
print_ioh_resources(info);
|
||||
}
|
||||
|
||||
/* intel IOH */
|
||||
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x342e, pci_root_bus_res);
|
||||
+179
-189
File diff suppressed because it is too large
Load Diff
@@ -27,18 +27,10 @@ static int mmcfg_last_accessed_cpu;
|
||||
*/
|
||||
static u32 get_base_addr(unsigned int seg, int bus, unsigned devfn)
|
||||
{
|
||||
struct acpi_mcfg_allocation *cfg;
|
||||
int cfg_num;
|
||||
struct pci_mmcfg_region *cfg = pci_mmconfig_lookup(seg, bus);
|
||||
|
||||
for (cfg_num = 0; cfg_num < pci_mmcfg_config_num; cfg_num++) {
|
||||
cfg = &pci_mmcfg_config[cfg_num];
|
||||
if (cfg->pci_segment == seg &&
|
||||
(cfg->start_bus_number <= bus) &&
|
||||
(cfg->end_bus_number >= bus))
|
||||
return cfg->address;
|
||||
}
|
||||
|
||||
/* Fall back to type 0 */
|
||||
if (cfg)
|
||||
return cfg->address;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -47,7 +39,7 @@ static u32 get_base_addr(unsigned int seg, int bus, unsigned devfn)
|
||||
*/
|
||||
static void pci_exp_set_dev_base(unsigned int base, int bus, int devfn)
|
||||
{
|
||||
u32 dev_base = base | (bus << 20) | (devfn << 12);
|
||||
u32 dev_base = base | PCI_MMCFG_BUS_OFFSET(bus) | (devfn << 12);
|
||||
int cpu = smp_processor_id();
|
||||
if (dev_base != mmcfg_last_accessed_device ||
|
||||
cpu != mmcfg_last_accessed_cpu) {
|
||||
|
||||
+23
-65
@@ -12,38 +12,15 @@
|
||||
#include <asm/e820.h>
|
||||
#include <asm/pci_x86.h>
|
||||
|
||||
/* Static virtual mapping of the MMCONFIG aperture */
|
||||
struct mmcfg_virt {
|
||||
struct acpi_mcfg_allocation *cfg;
|
||||
char __iomem *virt;
|
||||
};
|
||||
static struct mmcfg_virt *pci_mmcfg_virt;
|
||||
|
||||
static char __iomem *get_virt(unsigned int seg, unsigned bus)
|
||||
{
|
||||
struct acpi_mcfg_allocation *cfg;
|
||||
int cfg_num;
|
||||
|
||||
for (cfg_num = 0; cfg_num < pci_mmcfg_config_num; cfg_num++) {
|
||||
cfg = pci_mmcfg_virt[cfg_num].cfg;
|
||||
if (cfg->pci_segment == seg &&
|
||||
(cfg->start_bus_number <= bus) &&
|
||||
(cfg->end_bus_number >= bus))
|
||||
return pci_mmcfg_virt[cfg_num].virt;
|
||||
}
|
||||
|
||||
/* Fall back to type 0 */
|
||||
return NULL;
|
||||
}
|
||||
#define PREFIX "PCI: "
|
||||
|
||||
static char __iomem *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn)
|
||||
{
|
||||
char __iomem *addr;
|
||||
struct pci_mmcfg_region *cfg = pci_mmconfig_lookup(seg, bus);
|
||||
|
||||
addr = get_virt(seg, bus);
|
||||
if (!addr)
|
||||
return NULL;
|
||||
return addr + ((bus << 20) | (devfn << 12));
|
||||
if (cfg && cfg->virt)
|
||||
return cfg->virt + (PCI_MMCFG_BUS_OFFSET(bus) | (devfn << 12));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int pci_mmcfg_read(unsigned int seg, unsigned int bus,
|
||||
@@ -109,42 +86,30 @@ static struct pci_raw_ops pci_mmcfg = {
|
||||
.write = pci_mmcfg_write,
|
||||
};
|
||||
|
||||
static void __iomem * __init mcfg_ioremap(struct acpi_mcfg_allocation *cfg)
|
||||
static void __iomem * __init mcfg_ioremap(struct pci_mmcfg_region *cfg)
|
||||
{
|
||||
void __iomem *addr;
|
||||
u64 start, size;
|
||||
int num_buses;
|
||||
|
||||
start = cfg->start_bus_number;
|
||||
start <<= 20;
|
||||
start += cfg->address;
|
||||
size = cfg->end_bus_number + 1 - cfg->start_bus_number;
|
||||
size <<= 20;
|
||||
start = cfg->address + PCI_MMCFG_BUS_OFFSET(cfg->start_bus);
|
||||
num_buses = cfg->end_bus - cfg->start_bus + 1;
|
||||
size = PCI_MMCFG_BUS_OFFSET(num_buses);
|
||||
addr = ioremap_nocache(start, size);
|
||||
if (addr) {
|
||||
printk(KERN_INFO "PCI: Using MMCONFIG at %Lx - %Lx\n",
|
||||
start, start + size - 1);
|
||||
addr -= cfg->start_bus_number << 20;
|
||||
}
|
||||
if (addr)
|
||||
addr -= PCI_MMCFG_BUS_OFFSET(cfg->start_bus);
|
||||
return addr;
|
||||
}
|
||||
|
||||
int __init pci_mmcfg_arch_init(void)
|
||||
{
|
||||
int i;
|
||||
pci_mmcfg_virt = kzalloc(sizeof(*pci_mmcfg_virt) *
|
||||
pci_mmcfg_config_num, GFP_KERNEL);
|
||||
if (pci_mmcfg_virt == NULL) {
|
||||
printk(KERN_ERR "PCI: Can not allocate memory for mmconfig structures\n");
|
||||
return 0;
|
||||
}
|
||||
struct pci_mmcfg_region *cfg;
|
||||
|
||||
for (i = 0; i < pci_mmcfg_config_num; ++i) {
|
||||
pci_mmcfg_virt[i].cfg = &pci_mmcfg_config[i];
|
||||
pci_mmcfg_virt[i].virt = mcfg_ioremap(&pci_mmcfg_config[i]);
|
||||
if (!pci_mmcfg_virt[i].virt) {
|
||||
printk(KERN_ERR "PCI: Cannot map mmconfig aperture for "
|
||||
"segment %d\n",
|
||||
pci_mmcfg_config[i].pci_segment);
|
||||
list_for_each_entry(cfg, &pci_mmcfg_list, list) {
|
||||
cfg->virt = mcfg_ioremap(cfg);
|
||||
if (!cfg->virt) {
|
||||
printk(KERN_ERR PREFIX "can't map MMCONFIG at %pR\n",
|
||||
&cfg->res);
|
||||
pci_mmcfg_arch_free();
|
||||
return 0;
|
||||
}
|
||||
@@ -155,19 +120,12 @@ int __init pci_mmcfg_arch_init(void)
|
||||
|
||||
void __init pci_mmcfg_arch_free(void)
|
||||
{
|
||||
int i;
|
||||
struct pci_mmcfg_region *cfg;
|
||||
|
||||
if (pci_mmcfg_virt == NULL)
|
||||
return;
|
||||
|
||||
for (i = 0; i < pci_mmcfg_config_num; ++i) {
|
||||
if (pci_mmcfg_virt[i].virt) {
|
||||
iounmap(pci_mmcfg_virt[i].virt + (pci_mmcfg_virt[i].cfg->start_bus_number << 20));
|
||||
pci_mmcfg_virt[i].virt = NULL;
|
||||
pci_mmcfg_virt[i].cfg = NULL;
|
||||
list_for_each_entry(cfg, &pci_mmcfg_list, list) {
|
||||
if (cfg->virt) {
|
||||
iounmap(cfg->virt + PCI_MMCFG_BUS_OFFSET(cfg->start_bus));
|
||||
cfg->virt = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
kfree(pci_mmcfg_virt);
|
||||
pci_mmcfg_virt = NULL;
|
||||
}
|
||||
|
||||
@@ -27,7 +27,9 @@
|
||||
#include <linux/page-flags.h>
|
||||
#include <linux/highmem.h>
|
||||
#include <linux/console.h>
|
||||
#include <linux/pci.h>
|
||||
|
||||
#include <xen/xen.h>
|
||||
#include <xen/interface/xen.h>
|
||||
#include <xen/interface/version.h>
|
||||
#include <xen/interface/physdev.h>
|
||||
@@ -1175,7 +1177,11 @@ asmlinkage void __init xen_start_kernel(void)
|
||||
add_preferred_console("xenboot", 0, NULL);
|
||||
add_preferred_console("tty", 0, NULL);
|
||||
add_preferred_console("hvc", 0, NULL);
|
||||
} else {
|
||||
/* Make sure ACS will be enabled */
|
||||
pci_request_acs();
|
||||
}
|
||||
|
||||
|
||||
xen_raw_console_write("about to get started...\n");
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user