From d09f96ceb2ffddbe7ff2f95e925e5ab6102e35c9 Mon Sep 17 00:00:00 2001 From: John Johansen Date: Fri, 27 Aug 2010 18:33:26 -0700 Subject: [PATCH] --- yaml --- r: 210339 b: refs/heads/master c: e819ff519b2d74373eca4a9a2b417ebf4c1e1b29 h: refs/heads/master i: 210337: 8429291d6e3f468d5bb5c1b0772a47c875010fa3 210335: 1a1c134034643367b8f7161d28ceda4afff34072 v: v3 --- [refs] | 2 +- trunk/Documentation/kernel-parameters.txt | 17 ++-- trunk/arch/x86/include/asm/pci.h | 6 +- trunk/drivers/acpi/pci_root.c | 97 ++++++++----------- trunk/drivers/pci/hotplug/acpi_pcihp.c | 6 +- trunk/drivers/pci/hotplug/pciehp.h | 16 ++- trunk/drivers/pci/hotplug/pciehp_acpi.c | 4 +- trunk/drivers/pci/hotplug/pciehp_core.c | 4 +- trunk/drivers/pci/pci.h | 2 - trunk/drivers/pci/pcie/Makefile | 3 +- trunk/drivers/pci/pcie/aer/aerdrv.c | 9 +- trunk/drivers/pci/pcie/aer/aerdrv_acpi.c | 36 +++++++ trunk/drivers/pci/pcie/aer/aerdrv_core.c | 14 ++- trunk/drivers/pci/pcie/pme/Makefile | 8 ++ .../pci/pcie/{pme.c => pme/pcie_pme.c} | 66 +++++++++++-- trunk/drivers/pci/pcie/pme/pcie_pme.h | 28 ++++++ trunk/drivers/pci/pcie/pme/pcie_pme_acpi.c | 54 +++++++++++ trunk/drivers/pci/pcie/portdrv.h | 22 ----- trunk/drivers/pci/pcie/portdrv_acpi.c | 77 --------------- trunk/drivers/pci/pcie/portdrv_core.c | 53 +--------- trunk/drivers/pci/pcie/portdrv_pci.c | 38 ++------ trunk/drivers/pci/slot.c | 2 +- trunk/fs/xfs/linux-2.6/xfs_buf.c | 8 +- trunk/fs/xfs/linux-2.6/xfs_buf.h | 1 + trunk/fs/xfs/linux-2.6/xfs_ioctl.c | 7 -- trunk/fs/xfs/linux-2.6/xfs_iops.c | 2 +- trunk/fs/xfs/xfs_bmap.c | 14 +-- trunk/fs/xfs/xfs_fs.h | 4 +- trunk/fs/xfs/xfs_vnodeops.c | 13 +-- trunk/include/acpi/acpi_bus.h | 3 + trunk/include/linux/acpi.h | 4 +- trunk/include/linux/pci.h | 3 - trunk/security/apparmor/path.c | 38 +++----- 33 files changed, 317 insertions(+), 344 deletions(-) create mode 100644 trunk/drivers/pci/pcie/pme/Makefile rename trunk/drivers/pci/pcie/{pme.c => pme/pcie_pme.c} (83%) create mode 100644 trunk/drivers/pci/pcie/pme/pcie_pme.h create mode 100644 trunk/drivers/pci/pcie/pme/pcie_pme_acpi.c delete mode 100644 trunk/drivers/pci/pcie/portdrv_acpi.c diff --git a/[refs] b/[refs] index 1ad4fb25c172..aebae04f1cd4 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: d56557af19867edb8c0e96f8e26399698a08857f +refs/heads/master: e819ff519b2d74373eca4a9a2b417ebf4c1e1b29 diff --git a/trunk/Documentation/kernel-parameters.txt b/trunk/Documentation/kernel-parameters.txt index 8dd7248508a9..f084af0cb8e0 100644 --- a/trunk/Documentation/kernel-parameters.txt +++ b/trunk/Documentation/kernel-parameters.txt @@ -1974,18 +1974,15 @@ and is between 256 and 4096 characters. It is defined in the file force Enable ASPM even on devices that claim not to support it. WARNING: Forcing ASPM on may cause system lockups. - pcie_ports= [PCIE] PCIe ports handling: - auto Ask the BIOS whether or not to use native PCIe services - associated with PCIe ports (PME, hot-plug, AER). Use - them only if that is allowed by the BIOS. - native Use native PCIe services associated with PCIe ports - unconditionally. - compat Treat PCIe ports as PCI-to-PCI bridges, disable the PCIe - ports driver. - pcie_pme= [PCIE,PM] Native PCIe PME signaling options: + Format: {auto|force}[,nomsi] + auto Use native PCIe PME signaling if the BIOS allows the + kernel to control PCIe config registers of root ports. + force Use native PCIe PME signaling even if the BIOS refuses + to allow the kernel to control the relevant PCIe config + registers. nomsi Do not use MSI for native PCIe PME signaling (this makes - all PCIe root ports use INTx for all services). + all PCIe root ports use INTx for everything). pcmv= [HW,PCMCIA] BadgePAD 4 diff --git a/trunk/arch/x86/include/asm/pci.h b/trunk/arch/x86/include/asm/pci.h index d395540ff894..404a880ea325 100644 --- a/trunk/arch/x86/include/asm/pci.h +++ b/trunk/arch/x86/include/asm/pci.h @@ -27,9 +27,6 @@ extern struct pci_bus *pci_scan_bus_on_node(int busno, struct pci_ops *ops, int node); extern struct pci_bus *pci_scan_bus_with_sysdata(int busno); -#ifdef CONFIG_PCI - -#ifdef CONFIG_PCI_DOMAINS static inline int pci_domain_nr(struct pci_bus *bus) { struct pci_sysdata *sd = bus->sysdata; @@ -40,12 +37,13 @@ static inline int pci_proc_domain(struct pci_bus *bus) { return pci_domain_nr(bus); } -#endif + /* Can be used to override the logic in pci_scan_bus for skipping already-configured bus numbers - to be used for buggy BIOSes or architectures with incomplete PCI setup by the loader */ +#ifdef CONFIG_PCI extern unsigned int pcibios_assign_all_busses(void); extern int pci_legacy_init(void); # ifdef CONFIG_ACPI diff --git a/trunk/drivers/acpi/pci_root.c b/trunk/drivers/acpi/pci_root.c index 3ba8d1f44a73..1f67057af2a5 100644 --- a/trunk/drivers/acpi/pci_root.c +++ b/trunk/drivers/acpi/pci_root.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -225,31 +226,22 @@ static acpi_status acpi_pci_run_osc(acpi_handle handle, return status; } -static acpi_status acpi_pci_query_osc(struct acpi_pci_root *root, - u32 support, - u32 *control) +static acpi_status acpi_pci_query_osc(struct acpi_pci_root *root, u32 flags) { acpi_status status; - u32 result, capbuf[3]; - - support &= OSC_PCI_SUPPORT_MASKS; - support |= root->osc_support_set; + u32 support_set, result, capbuf[3]; + /* do _OSC query for all possible controls */ + support_set = root->osc_support_set | (flags & OSC_PCI_SUPPORT_MASKS); capbuf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE; - capbuf[OSC_SUPPORT_TYPE] = support; - if (control) { - *control &= OSC_PCI_CONTROL_MASKS; - capbuf[OSC_CONTROL_TYPE] = *control | root->osc_control_set; - } else { - /* Run _OSC query for all possible controls. */ - capbuf[OSC_CONTROL_TYPE] = OSC_PCI_CONTROL_MASKS; - } + capbuf[OSC_SUPPORT_TYPE] = support_set; + capbuf[OSC_CONTROL_TYPE] = OSC_PCI_CONTROL_MASKS; status = acpi_pci_run_osc(root->device->handle, capbuf, &result); if (ACPI_SUCCESS(status)) { - root->osc_support_set = support; - if (control) - *control = result; + root->osc_support_set = support_set; + root->osc_control_qry = result; + root->osc_queried = 1; } return status; } @@ -263,7 +255,7 @@ static acpi_status acpi_pci_osc_support(struct acpi_pci_root *root, u32 flags) if (ACPI_FAILURE(status)) return status; mutex_lock(&osc_lock); - status = acpi_pci_query_osc(root, flags, NULL); + status = acpi_pci_query_osc(root, flags); mutex_unlock(&osc_lock); return status; } @@ -373,70 +365,55 @@ struct pci_dev *acpi_get_pci_dev(acpi_handle handle) EXPORT_SYMBOL_GPL(acpi_get_pci_dev); /** - * acpi_pci_osc_control_set - Request control of PCI root _OSC features. - * @handle: ACPI handle of a PCI root bridge (or PCIe Root Complex). - * @mask: Mask of _OSC bits to request control of, place to store control mask. - * @req: Mask of _OSC bits the control of is essential to the caller. - * - * Run _OSC query for @mask and if that is successful, compare the returned - * mask of control bits with @req. If all of the @req bits are set in the - * returned mask, run _OSC request for it. + * acpi_pci_osc_control_set - commit requested control to Firmware + * @handle: acpi_handle for the target ACPI object + * @flags: driver's requested control bits * - * The variable at the @mask address may be modified regardless of whether or - * not the function returns success. On success it will contain the mask of - * _OSC bits the BIOS has granted control of, but its contents are meaningless - * on failure. + * Attempt to take control from Firmware on requested control bits. **/ -acpi_status acpi_pci_osc_control_set(acpi_handle handle, u32 *mask, u32 req) +acpi_status acpi_pci_osc_control_set(acpi_handle handle, u32 flags) { - struct acpi_pci_root *root; acpi_status status; - u32 ctrl, capbuf[3]; + u32 control_req, result, capbuf[3]; acpi_handle tmp; + struct acpi_pci_root *root; - if (!mask) - return AE_BAD_PARAMETER; + status = acpi_get_handle(handle, "_OSC", &tmp); + if (ACPI_FAILURE(status)) + return status; - ctrl = *mask & OSC_PCI_CONTROL_MASKS; - if ((ctrl & req) != req) + control_req = (flags & OSC_PCI_CONTROL_MASKS); + if (!control_req) return AE_TYPE; root = acpi_pci_find_root(handle); if (!root) return AE_NOT_EXIST; - status = acpi_get_handle(handle, "_OSC", &tmp); - if (ACPI_FAILURE(status)) - return status; - mutex_lock(&osc_lock); - - *mask = ctrl | root->osc_control_set; /* No need to evaluate _OSC if the control was already granted. */ - if ((root->osc_control_set & ctrl) == ctrl) + if ((root->osc_control_set & control_req) == control_req) goto out; - /* Need to check the available controls bits before requesting them. */ - while (*mask) { - status = acpi_pci_query_osc(root, root->osc_support_set, mask); + /* Need to query controls first before requesting them */ + if (!root->osc_queried) { + status = acpi_pci_query_osc(root, root->osc_support_set); if (ACPI_FAILURE(status)) goto out; - if (ctrl == *mask) - break; - ctrl = *mask; } - - if ((ctrl & req) != req) { + if ((root->osc_control_qry & control_req) != control_req) { + printk(KERN_DEBUG + "Firmware did not grant requested _OSC control\n"); status = AE_SUPPORT; goto out; } capbuf[OSC_QUERY_TYPE] = 0; capbuf[OSC_SUPPORT_TYPE] = root->osc_support_set; - capbuf[OSC_CONTROL_TYPE] = ctrl; - status = acpi_pci_run_osc(handle, capbuf, mask); + capbuf[OSC_CONTROL_TYPE] = root->osc_control_set | control_req; + status = acpi_pci_run_osc(handle, capbuf, &result); if (ACPI_SUCCESS(status)) - root->osc_control_set = *mask; + root->osc_control_set = result; out: mutex_unlock(&osc_lock); return status; @@ -567,6 +544,14 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) if (flags != base_flags) acpi_pci_osc_support(root, flags); + status = acpi_pci_osc_control_set(root->device->handle, + OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL); + + if (ACPI_FAILURE(status)) { + printk(KERN_INFO "Unable to assume PCIe control: Disabling ASPM\n"); + pcie_no_aspm(); + } + pci_acpi_add_bus_pm_notifier(device, root->bus); if (device->wakeup.flags.run_wake) device_set_run_wake(root->bus->bridge, true); diff --git a/trunk/drivers/pci/hotplug/acpi_pcihp.c b/trunk/drivers/pci/hotplug/acpi_pcihp.c index 3bc72d18b121..45fcc1e96df9 100644 --- a/trunk/drivers/pci/hotplug/acpi_pcihp.c +++ b/trunk/drivers/pci/hotplug/acpi_pcihp.c @@ -338,7 +338,9 @@ int acpi_get_hp_hw_control_from_firmware(struct pci_dev *pdev, u32 flags) acpi_handle chandle, handle; struct acpi_buffer string = { ACPI_ALLOCATE_BUFFER, NULL }; - flags &= OSC_SHPC_NATIVE_HP_CONTROL; + flags &= (OSC_PCI_EXPRESS_NATIVE_HP_CONTROL | + OSC_SHPC_NATIVE_HP_CONTROL | + OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL); if (!flags) { err("Invalid flags %u specified!\n", flags); return -EINVAL; @@ -358,7 +360,7 @@ int acpi_get_hp_hw_control_from_firmware(struct pci_dev *pdev, u32 flags) acpi_get_name(handle, ACPI_FULL_PATHNAME, &string); dbg("Trying to get hotplug control for %s\n", (char *)string.pointer); - status = acpi_pci_osc_control_set(handle, &flags, flags); + status = acpi_pci_osc_control_set(handle, flags); if (ACPI_SUCCESS(status)) goto got_one; if (status == AE_SUPPORT) diff --git a/trunk/drivers/pci/hotplug/pciehp.h b/trunk/drivers/pci/hotplug/pciehp.h index 73d513989263..4ed76b47b6dc 100644 --- a/trunk/drivers/pci/hotplug/pciehp.h +++ b/trunk/drivers/pci/hotplug/pciehp.h @@ -176,11 +176,19 @@ static inline void pciehp_firmware_init(void) { pciehp_acpi_slot_detection_init(); } -#else -#define pciehp_firmware_init() do {} while (0) -static inline int pciehp_acpi_slot_detection_check(struct pci_dev *dev) + +static inline int pciehp_get_hp_hw_control_from_firmware(struct pci_dev *dev) { - return 0; + int retval; + u32 flags = (OSC_PCI_EXPRESS_NATIVE_HP_CONTROL | + OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL); + retval = acpi_get_hp_hw_control_from_firmware(dev, flags); + if (retval) + return retval; + return pciehp_acpi_slot_detection_check(dev); } +#else +#define pciehp_firmware_init() do {} while (0) +#define pciehp_get_hp_hw_control_from_firmware(dev) 0 #endif /* CONFIG_ACPI */ #endif /* _PCIEHP_H */ diff --git a/trunk/drivers/pci/hotplug/pciehp_acpi.c b/trunk/drivers/pci/hotplug/pciehp_acpi.c index 2574700db461..1f4000a5a108 100644 --- a/trunk/drivers/pci/hotplug/pciehp_acpi.c +++ b/trunk/drivers/pci/hotplug/pciehp_acpi.c @@ -85,7 +85,9 @@ static int __init dummy_probe(struct pcie_device *dev) acpi_handle handle; struct dummy_slot *slot, *tmp; struct pci_dev *pdev = dev->port; - + /* Note: pciehp_detect_mode != PCIEHP_DETECT_ACPI here */ + if (pciehp_get_hp_hw_control_from_firmware(pdev)) + return -ENODEV; pos = pci_pcie_cap(pdev); if (!pos) return -ENODEV; diff --git a/trunk/drivers/pci/hotplug/pciehp_core.c b/trunk/drivers/pci/hotplug/pciehp_core.c index aa5f3ff629ff..3588ea61b0dd 100644 --- a/trunk/drivers/pci/hotplug/pciehp_core.c +++ b/trunk/drivers/pci/hotplug/pciehp_core.c @@ -59,7 +59,7 @@ module_param(pciehp_force, bool, 0644); MODULE_PARM_DESC(pciehp_debug, "Debugging mode enabled or not"); MODULE_PARM_DESC(pciehp_poll_mode, "Using polling mechanism for hot-plug events or not"); MODULE_PARM_DESC(pciehp_poll_time, "Polling mechanism frequency, in seconds"); -MODULE_PARM_DESC(pciehp_force, "Force pciehp, even if OSHP is missing"); +MODULE_PARM_DESC(pciehp_force, "Force pciehp, even if _OSC and OSHP are missing"); #define PCIE_MODULE_NAME "pciehp" @@ -235,7 +235,7 @@ static int pciehp_probe(struct pcie_device *dev) dev_info(&dev->device, "Bypassing BIOS check for pciehp use on %s\n", pci_name(dev->port)); - else if (pciehp_acpi_slot_detection_check(dev->port)) + else if (pciehp_get_hp_hw_control_from_firmware(dev->port)) goto err_out_none; ctrl = pcie_init(dev); diff --git a/trunk/drivers/pci/pci.h b/trunk/drivers/pci/pci.h index 7754a678ab15..679c39de6a89 100644 --- a/trunk/drivers/pci/pci.h +++ b/trunk/drivers/pci/pci.h @@ -140,10 +140,8 @@ static inline void pci_msi_init_pci_dev(struct pci_dev *dev) { } #ifdef CONFIG_PCIEAER void pci_no_aer(void); -bool pci_aer_available(void); #else static inline void pci_no_aer(void) { } -static inline bool pci_aer_available(void) { return false; } #endif static inline int pci_no_d1d2(struct pci_dev *dev) diff --git a/trunk/drivers/pci/pcie/Makefile b/trunk/drivers/pci/pcie/Makefile index 00c62df5a9fc..ea654545e7c4 100644 --- a/trunk/drivers/pci/pcie/Makefile +++ b/trunk/drivers/pci/pcie/Makefile @@ -6,11 +6,10 @@ obj-$(CONFIG_PCIEASPM) += aspm.o pcieportdrv-y := portdrv_core.o portdrv_pci.o portdrv_bus.o -pcieportdrv-$(CONFIG_ACPI) += portdrv_acpi.o obj-$(CONFIG_PCIEPORTBUS) += pcieportdrv.o # Build PCI Express AER if needed obj-$(CONFIG_PCIEAER) += aer/ -obj-$(CONFIG_PCIE_PME) += pme.o +obj-$(CONFIG_PCIE_PME) += pme/ diff --git a/trunk/drivers/pci/pcie/aer/aerdrv.c b/trunk/drivers/pci/pcie/aer/aerdrv.c index f409948e1a9b..484cc55194b8 100644 --- a/trunk/drivers/pci/pcie/aer/aerdrv.c +++ b/trunk/drivers/pci/pcie/aer/aerdrv.c @@ -72,11 +72,6 @@ void pci_no_aer(void) pcie_aer_disable = 1; /* has priority over 'forceload' */ } -bool pci_aer_available(void) -{ - return !pcie_aer_disable && pci_msi_enabled(); -} - static int set_device_error_reporting(struct pci_dev *dev, void *data) { bool enable = *((bool *)data); @@ -416,7 +411,9 @@ static void aer_error_resume(struct pci_dev *dev) */ static int __init aer_service_init(void) { - if (!pci_aer_available()) + if (pcie_aer_disable) + return -ENXIO; + if (!pci_msi_enabled()) return -ENXIO; return pcie_port_service_register(&aerdriver); } diff --git a/trunk/drivers/pci/pcie/aer/aerdrv_acpi.c b/trunk/drivers/pci/pcie/aer/aerdrv_acpi.c index 2bb9b8972211..f278d7b0d95d 100644 --- a/trunk/drivers/pci/pcie/aer/aerdrv_acpi.c +++ b/trunk/drivers/pci/pcie/aer/aerdrv_acpi.c @@ -19,6 +19,42 @@ #include #include "aerdrv.h" +/** + * aer_osc_setup - run ACPI _OSC method + * @pciedev: pcie_device which AER is being enabled on + * + * @return: Zero on success. Nonzero otherwise. + * + * Invoked when PCIe bus loads AER service driver. To avoid conflict with + * BIOS AER support requires BIOS to yield AER control to OS native driver. + **/ +int aer_osc_setup(struct pcie_device *pciedev) +{ + acpi_status status = AE_NOT_FOUND; + struct pci_dev *pdev = pciedev->port; + acpi_handle handle = NULL; + + if (acpi_pci_disabled) + return -1; + + handle = acpi_find_root_bridge_handle(pdev); + if (handle) { + status = acpi_pci_osc_control_set(handle, + OSC_PCI_EXPRESS_AER_CONTROL | + OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL); + } + + if (ACPI_FAILURE(status)) { + dev_printk(KERN_DEBUG, &pciedev->device, "AER service couldn't " + "init device: %s\n", + (status == AE_SUPPORT || status == AE_NOT_FOUND) ? + "no _OSC support" : "_OSC failed"); + return -1; + } + + return 0; +} + #ifdef CONFIG_ACPI_APEI static inline int hest_match_pci(struct acpi_hest_aer_common *p, struct pci_dev *pci) diff --git a/trunk/drivers/pci/pcie/aer/aerdrv_core.c b/trunk/drivers/pci/pcie/aer/aerdrv_core.c index 29e268fadf14..fc0b5a93e1de 100644 --- a/trunk/drivers/pci/pcie/aer/aerdrv_core.c +++ b/trunk/drivers/pci/pcie/aer/aerdrv_core.c @@ -772,10 +772,22 @@ void aer_isr(struct work_struct *work) */ int aer_init(struct pcie_device *dev) { + if (pcie_aer_get_firmware_first(dev->port)) { + dev_printk(KERN_DEBUG, &dev->device, + "PCIe errors handled by platform firmware.\n"); + goto out; + } + + if (aer_osc_setup(dev)) + goto out; + + return 0; +out: if (forceload) { dev_printk(KERN_DEBUG, &dev->device, "aerdrv forceload requested.\n"); pcie_aer_force_firmware_first(dev->port, 0); + return 0; } - return 0; + return -ENXIO; } diff --git a/trunk/drivers/pci/pcie/pme/Makefile b/trunk/drivers/pci/pcie/pme/Makefile new file mode 100644 index 000000000000..8b9238053080 --- /dev/null +++ b/trunk/drivers/pci/pcie/pme/Makefile @@ -0,0 +1,8 @@ +# +# Makefile for PCI-Express Root Port PME signaling driver +# + +obj-$(CONFIG_PCIE_PME) += pmedriver.o + +pmedriver-objs := pcie_pme.o +pmedriver-$(CONFIG_ACPI) += pcie_pme_acpi.o diff --git a/trunk/drivers/pci/pcie/pme.c b/trunk/drivers/pci/pcie/pme/pcie_pme.c similarity index 83% rename from trunk/drivers/pci/pcie/pme.c rename to trunk/drivers/pci/pcie/pme/pcie_pme.c index 2f3c90407227..bbdea18693d9 100644 --- a/trunk/drivers/pci/pcie/pme.c +++ b/trunk/drivers/pci/pcie/pme/pcie_pme.c @@ -23,12 +23,37 @@ #include #include -#include "../pci.h" -#include "portdrv.h" +#include "../../pci.h" +#include "pcie_pme.h" #define PCI_EXP_RTSTA_PME 0x10000 /* PME status */ #define PCI_EXP_RTSTA_PENDING 0x20000 /* PME pending */ +/* + * If set, this switch will prevent the PCIe root port PME service driver from + * being registered. Consequently, the interrupt-based PCIe PME signaling will + * not be used by any PCIe root ports in that case. + */ +static bool pcie_pme_disabled = true; + +/* + * The PCI Express Base Specification 2.0, Section 6.1.8, states the following: + * "In order to maintain compatibility with non-PCI Express-aware system + * software, system power management logic must be configured by firmware to use + * the legacy mechanism of signaling PME by default. PCI Express-aware system + * software must notify the firmware prior to enabling native, interrupt-based + * PME signaling." However, if the platform doesn't provide us with a suitable + * notification mechanism or the notification fails, it is not clear whether or + * not we are supposed to use the interrupt-based PCIe PME signaling. The + * switch below can be used to indicate the desired behaviour. When set, it + * will make the kernel use the interrupt-based PCIe PME signaling regardless of + * the platform notification status, although the kernel will attempt to notify + * the platform anyway. When unset, it will prevent the kernel from using the + * the interrupt-based PCIe PME signaling if the platform notification fails, + * which is the default. + */ +static bool pcie_pme_force_enable; + /* * If this switch is set, MSI will not be used for PCIe PME signaling. This * causes the PCIe port driver to use INTx interrupts only, but it turns out @@ -39,13 +64,38 @@ bool pcie_pme_msi_disabled; static int __init pcie_pme_setup(char *str) { - if (!strncmp(str, "nomsi", 5)) - pcie_pme_msi_disabled = true; + if (!strncmp(str, "auto", 4)) + pcie_pme_disabled = false; + else if (!strncmp(str, "force", 5)) + pcie_pme_force_enable = true; + + str = strchr(str, ','); + if (str) { + str++; + str += strspn(str, " \t"); + if (*str && !strcmp(str, "nomsi")) + pcie_pme_msi_disabled = true; + } return 1; } __setup("pcie_pme=", pcie_pme_setup); +/** + * pcie_pme_platform_setup - Ensure that the kernel controls the PCIe PME. + * @srv: PCIe PME root port service to use for carrying out the check. + * + * Notify the platform that the native PCIe PME is going to be used and return + * 'true' if the control of the PCIe PME registers has been acquired from the + * platform. + */ +static bool pcie_pme_platform_setup(struct pcie_device *srv) +{ + if (!pcie_pme_platform_notify(srv)) + return true; + return pcie_pme_force_enable; +} + struct pcie_pme_service_data { spinlock_t lock; struct pcie_device *srv; @@ -58,7 +108,7 @@ struct pcie_pme_service_data { * @dev: PCIe root port or event collector. * @enable: Enable or disable the interrupt. */ -void pcie_pme_interrupt_enable(struct pci_dev *dev, bool enable) +static void pcie_pme_interrupt_enable(struct pci_dev *dev, bool enable) { int rtctl_pos; u16 rtctl; @@ -367,6 +417,9 @@ static int pcie_pme_probe(struct pcie_device *srv) struct pcie_pme_service_data *data; int ret; + if (!pcie_pme_platform_setup(srv)) + return -EACCES; + data = kzalloc(sizeof(*data), GFP_KERNEL); if (!data) return -ENOMEM; @@ -456,7 +509,8 @@ static struct pcie_port_service_driver pcie_pme_driver = { */ static int __init pcie_pme_service_init(void) { - return pcie_port_service_register(&pcie_pme_driver); + return pcie_pme_disabled ? + -ENODEV : pcie_port_service_register(&pcie_pme_driver); } module_init(pcie_pme_service_init); diff --git a/trunk/drivers/pci/pcie/pme/pcie_pme.h b/trunk/drivers/pci/pcie/pme/pcie_pme.h new file mode 100644 index 000000000000..b30d2b7c9775 --- /dev/null +++ b/trunk/drivers/pci/pcie/pme/pcie_pme.h @@ -0,0 +1,28 @@ +/* + * drivers/pci/pcie/pme/pcie_pme.h + * + * PCI Express Root Port PME signaling support + * + * Copyright (C) 2009 Rafael J. Wysocki , Novell Inc. + */ + +#ifndef _PCIE_PME_H_ +#define _PCIE_PME_H_ + +struct pcie_device; + +#ifdef CONFIG_ACPI +extern int pcie_pme_acpi_setup(struct pcie_device *srv); + +static inline int pcie_pme_platform_notify(struct pcie_device *srv) +{ + return pcie_pme_acpi_setup(srv); +} +#else /* !CONFIG_ACPI */ +static inline int pcie_pme_platform_notify(struct pcie_device *srv) +{ + return 0; +} +#endif /* !CONFIG_ACPI */ + +#endif diff --git a/trunk/drivers/pci/pcie/pme/pcie_pme_acpi.c b/trunk/drivers/pci/pcie/pme/pcie_pme_acpi.c new file mode 100644 index 000000000000..83ab2287ae3f --- /dev/null +++ b/trunk/drivers/pci/pcie/pme/pcie_pme_acpi.c @@ -0,0 +1,54 @@ +/* + * PCIe Native PME support, ACPI-related part + * + * Copyright (C) 2009 Rafael J. Wysocki , Novell Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License V2. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include +#include +#include +#include +#include +#include + +/** + * pcie_pme_acpi_setup - Request the ACPI BIOS to release control over PCIe PME. + * @srv - PCIe PME service for a root port or event collector. + * + * Invoked when the PCIe bus type loads PCIe PME service driver. To avoid + * conflict with the BIOS PCIe support requires the BIOS to yield PCIe PME + * control to the kernel. + */ +int pcie_pme_acpi_setup(struct pcie_device *srv) +{ + acpi_status status = AE_NOT_FOUND; + struct pci_dev *port = srv->port; + acpi_handle handle; + int error = 0; + + if (acpi_pci_disabled) + return -ENOSYS; + + dev_info(&port->dev, "Requesting control of PCIe PME from ACPI BIOS\n"); + + handle = acpi_find_root_bridge_handle(port); + if (!handle) + return -EINVAL; + + status = acpi_pci_osc_control_set(handle, + OSC_PCI_EXPRESS_PME_CONTROL | + OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL); + if (ACPI_FAILURE(status)) { + dev_info(&port->dev, + "Failed to receive control of PCIe PME service: %s\n", + (status == AE_SUPPORT || status == AE_NOT_FOUND) ? + "no _OSC support" : "ACPI _OSC failed"); + error = -ENODEV; + } + + return error; +} diff --git a/trunk/drivers/pci/pcie/portdrv.h b/trunk/drivers/pci/pcie/portdrv.h index 7b5aba0a3291..813a5c3427b6 100644 --- a/trunk/drivers/pci/pcie/portdrv.h +++ b/trunk/drivers/pci/pcie/portdrv.h @@ -20,9 +20,6 @@ #define get_descriptor_id(type, service) (((type - 4) << 4) | service) -extern bool pcie_ports_disabled; -extern bool pcie_ports_auto; - extern struct bus_type pcie_port_bus_type; extern int pcie_port_device_register(struct pci_dev *dev); #ifdef CONFIG_PM @@ -33,8 +30,6 @@ extern void pcie_port_device_remove(struct pci_dev *dev); extern int __must_check pcie_port_bus_register(void); extern void pcie_port_bus_unregister(void); -struct pci_dev; - #ifdef CONFIG_PCIE_PME extern bool pcie_pme_msi_disabled; @@ -47,26 +42,9 @@ static inline bool pcie_pme_no_msi(void) { return pcie_pme_msi_disabled; } - -extern void pcie_pme_interrupt_enable(struct pci_dev *dev, bool enable); #else /* !CONFIG_PCIE_PME */ static inline void pcie_pme_disable_msi(void) {} static inline bool pcie_pme_no_msi(void) { return false; } -static inline void pcie_pme_interrupt_enable(struct pci_dev *dev, bool en) {} #endif /* !CONFIG_PCIE_PME */ -#ifdef CONFIG_ACPI -extern int pcie_port_acpi_setup(struct pci_dev *port, int *mask); - -static inline int pcie_port_platform_notify(struct pci_dev *port, int *mask) -{ - return pcie_port_acpi_setup(port, mask); -} -#else /* !CONFIG_ACPI */ -static inline int pcie_port_platform_notify(struct pci_dev *port, int *mask) -{ - return 0; -} -#endif /* !CONFIG_ACPI */ - #endif /* _PORTDRV_H_ */ diff --git a/trunk/drivers/pci/pcie/portdrv_acpi.c b/trunk/drivers/pci/pcie/portdrv_acpi.c deleted file mode 100644 index b7c4cb1ccb23..000000000000 --- a/trunk/drivers/pci/pcie/portdrv_acpi.c +++ /dev/null @@ -1,77 +0,0 @@ -/* - * PCIe Port Native Services Support, ACPI-Related Part - * - * Copyright (C) 2010 Rafael J. Wysocki , Novell Inc. - * - * This file is subject to the terms and conditions of the GNU General Public - * License V2. See the file "COPYING" in the main directory of this archive - * for more details. - */ - -#include -#include -#include -#include -#include -#include - -#include "aer/aerdrv.h" -#include "../pci.h" - -/** - * pcie_port_acpi_setup - Request the BIOS to release control of PCIe services. - * @port: PCIe Port service for a root port or event collector. - * @srv_mask: Bit mask of services that can be enabled for @port. - * - * Invoked when @port is identified as a PCIe port device. To avoid conflicts - * with the BIOS PCIe port native services support requires the BIOS to yield - * control of these services to the kernel. The mask of services that the BIOS - * allows to be enabled for @port is written to @srv_mask. - * - * NOTE: It turns out that we cannot do that for individual port services - * separately, because that would make some systems work incorrectly. - */ -int pcie_port_acpi_setup(struct pci_dev *port, int *srv_mask) -{ - acpi_status status; - acpi_handle handle; - u32 flags; - - if (acpi_pci_disabled) - return 0; - - handle = acpi_find_root_bridge_handle(port); - if (!handle) - return -EINVAL; - - flags = OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL - | OSC_PCI_EXPRESS_NATIVE_HP_CONTROL - | OSC_PCI_EXPRESS_PME_CONTROL; - - if (pci_aer_available()) { - if (pcie_aer_get_firmware_first(port)) - dev_dbg(&port->dev, "PCIe errors handled by BIOS.\n"); - else - flags |= OSC_PCI_EXPRESS_AER_CONTROL; - } - - status = acpi_pci_osc_control_set(handle, &flags, - OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL); - if (ACPI_FAILURE(status)) { - dev_dbg(&port->dev, "ACPI _OSC request failed (code %d)\n", - status); - return -ENODEV; - } - - dev_info(&port->dev, "ACPI _OSC control granted for 0x%02x\n", flags); - - *srv_mask = PCIE_PORT_SERVICE_VC; - if (flags & OSC_PCI_EXPRESS_NATIVE_HP_CONTROL) - *srv_mask |= PCIE_PORT_SERVICE_HP; - if (flags & OSC_PCI_EXPRESS_PME_CONTROL) - *srv_mask |= PCIE_PORT_SERVICE_PME; - if (flags & OSC_PCI_EXPRESS_AER_CONTROL) - *srv_mask |= PCIE_PORT_SERVICE_AER; - - return 0; -} diff --git a/trunk/drivers/pci/pcie/portdrv_core.c b/trunk/drivers/pci/pcie/portdrv_core.c index a9c222d79ebc..e73effbe402c 100644 --- a/trunk/drivers/pci/pcie/portdrv_core.c +++ b/trunk/drivers/pci/pcie/portdrv_core.c @@ -14,8 +14,6 @@ #include #include #include -#include -#include #include "../pci.h" #include "portdrv.h" @@ -238,64 +236,24 @@ static int get_port_device_capability(struct pci_dev *dev) int services = 0, pos; u16 reg16; u32 reg32; - int cap_mask; - int err; - - err = pcie_port_platform_notify(dev, &cap_mask); - if (pcie_ports_auto) { - if (err) { - pcie_no_aspm(); - return 0; - } - } else { - cap_mask = PCIE_PORT_SERVICE_PME | PCIE_PORT_SERVICE_HP - | PCIE_PORT_SERVICE_VC; - if (pci_aer_available()) - cap_mask |= PCIE_PORT_SERVICE_AER; - } pos = pci_pcie_cap(dev); pci_read_config_word(dev, pos + PCI_EXP_FLAGS, ®16); /* Hot-Plug Capable */ - if ((cap_mask & PCIE_PORT_SERVICE_HP) && (reg16 & PCI_EXP_FLAGS_SLOT)) { + if (reg16 & PCI_EXP_FLAGS_SLOT) { pci_read_config_dword(dev, pos + PCI_EXP_SLTCAP, ®32); - if (reg32 & PCI_EXP_SLTCAP_HPC) { + if (reg32 & PCI_EXP_SLTCAP_HPC) services |= PCIE_PORT_SERVICE_HP; - /* - * Disable hot-plug interrupts in case they have been - * enabled by the BIOS and the hot-plug service driver - * is not loaded. - */ - pos += PCI_EXP_SLTCTL; - pci_read_config_word(dev, pos, ®16); - reg16 &= ~(PCI_EXP_SLTCTL_CCIE | PCI_EXP_SLTCTL_HPIE); - pci_write_config_word(dev, pos, reg16); - } } /* AER capable */ - if ((cap_mask & PCIE_PORT_SERVICE_AER) - && pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR)) { + if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR)) services |= PCIE_PORT_SERVICE_AER; - /* - * Disable AER on this port in case it's been enabled by the - * BIOS (the AER service driver will enable it when necessary). - */ - pci_disable_pcie_error_reporting(dev); - } /* VC support */ if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_VC)) services |= PCIE_PORT_SERVICE_VC; /* Root ports are capable of generating PME too */ - if ((cap_mask & PCIE_PORT_SERVICE_PME) - && dev->pcie_type == PCI_EXP_TYPE_ROOT_PORT) { + if (dev->pcie_type == PCI_EXP_TYPE_ROOT_PORT) services |= PCIE_PORT_SERVICE_PME; - /* - * Disable PME interrupt on this port in case it's been enabled - * by the BIOS (the PME service driver will enable it when - * necessary). - */ - pcie_pme_interrupt_enable(dev, false); - } return services; } @@ -536,9 +494,6 @@ static void pcie_port_shutdown_service(struct device *dev) {} */ int pcie_port_service_register(struct pcie_port_service_driver *new) { - if (pcie_ports_disabled) - return -ENODEV; - new->driver.name = (char *)new->name; new->driver.bus = &pcie_port_bus_type; new->driver.probe = pcie_port_probe_service; diff --git a/trunk/drivers/pci/pcie/portdrv_pci.c b/trunk/drivers/pci/pcie/portdrv_pci.c index f9033e190fb6..3debed25e46b 100644 --- a/trunk/drivers/pci/pcie/portdrv_pci.c +++ b/trunk/drivers/pci/pcie/portdrv_pci.c @@ -15,7 +15,6 @@ #include #include #include -#include #include "portdrv.h" #include "aer/aerdrv.h" @@ -30,31 +29,6 @@ MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); -/* If this switch is set, PCIe port native services should not be enabled. */ -bool pcie_ports_disabled; - -/* - * If this switch is set, ACPI _OSC will be used to determine whether or not to - * enable PCIe port native services. - */ -bool pcie_ports_auto = true; - -static int __init pcie_port_setup(char *str) -{ - if (!strncmp(str, "compat", 6)) { - pcie_ports_disabled = true; - } else if (!strncmp(str, "native", 6)) { - pcie_ports_disabled = false; - pcie_ports_auto = false; - } else if (!strncmp(str, "auto", 4)) { - pcie_ports_disabled = false; - pcie_ports_auto = true; - } - - return 1; -} -__setup("pcie_ports=", pcie_port_setup); - /* global data */ static int pcie_portdrv_restore_config(struct pci_dev *dev) @@ -327,11 +301,6 @@ static int __init pcie_portdrv_init(void) { int retval; - if (pcie_ports_disabled) { - pcie_no_aspm(); - return -EACCES; - } - dmi_check_system(pcie_portdrv_dmi_table); retval = pcie_port_bus_register(); @@ -346,4 +315,11 @@ static int __init pcie_portdrv_init(void) return retval; } +static void __exit pcie_portdrv_exit(void) +{ + pci_unregister_driver(&pcie_portdriver); + pcie_port_bus_unregister(); +} + module_init(pcie_portdrv_init); +module_exit(pcie_portdrv_exit); diff --git a/trunk/drivers/pci/slot.c b/trunk/drivers/pci/slot.c index 968cfea04f74..659eaa0fc48f 100644 --- a/trunk/drivers/pci/slot.c +++ b/trunk/drivers/pci/slot.c @@ -49,7 +49,7 @@ static ssize_t address_read_file(struct pci_slot *slot, char *buf) } /* these strings match up with the values in pci_bus_speed */ -static const char *pci_bus_speed_strings[] = { +static char *pci_bus_speed_strings[] = { "33 MHz PCI", /* 0x00 */ "66 MHz PCI", /* 0x01 */ "66 MHz PCI-X", /* 0x02 */ diff --git a/trunk/fs/xfs/linux-2.6/xfs_buf.c b/trunk/fs/xfs/linux-2.6/xfs_buf.c index d72cf2bb054a..ea79072f5210 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_buf.c +++ b/trunk/fs/xfs/linux-2.6/xfs_buf.c @@ -440,7 +440,12 @@ _xfs_buf_find( ASSERT(btp == bp->b_target); if (bp->b_file_offset == range_base && bp->b_buffer_length == range_length) { + /* + * If we look at something, bring it to the + * front of the list for next time. + */ atomic_inc(&bp->b_hold); + list_move(&bp->b_hash_list, &hash->bh_list); goto found; } } @@ -1438,7 +1443,8 @@ xfs_alloc_bufhash( { unsigned int i; - btp->bt_hashshift = external ? 3 : 12; /* 8 or 4096 buckets */ + btp->bt_hashshift = external ? 3 : 8; /* 8 or 256 buckets */ + btp->bt_hashmask = (1 << btp->bt_hashshift) - 1; btp->bt_hash = kmem_zalloc_large((1 << btp->bt_hashshift) * sizeof(xfs_bufhash_t)); for (i = 0; i < (1 << btp->bt_hashshift); i++) { diff --git a/trunk/fs/xfs/linux-2.6/xfs_buf.h b/trunk/fs/xfs/linux-2.6/xfs_buf.h index 2a05614f0b92..d072e5ff923b 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_buf.h +++ b/trunk/fs/xfs/linux-2.6/xfs_buf.h @@ -137,6 +137,7 @@ typedef struct xfs_buftarg { size_t bt_smask; /* per device buffer hash table */ + uint bt_hashmask; uint bt_hashshift; xfs_bufhash_t *bt_hash; diff --git a/trunk/fs/xfs/linux-2.6/xfs_ioctl.c b/trunk/fs/xfs/linux-2.6/xfs_ioctl.c index 4fec427b83ef..237f5ffb2ee8 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_ioctl.c +++ b/trunk/fs/xfs/linux-2.6/xfs_ioctl.c @@ -906,13 +906,6 @@ xfs_ioctl_setattr( if (XFS_FORCED_SHUTDOWN(mp)) return XFS_ERROR(EIO); - /* - * Disallow 32bit project ids because on-disk structure - * is 16bit only. - */ - if ((mask & FSX_PROJID) && (fa->fsx_projid > (__uint16_t)-1)) - return XFS_ERROR(EINVAL); - /* * If disk quotas is on, we make sure that the dquots do exist on disk, * before we start any other transactions. Trying to do this later diff --git a/trunk/fs/xfs/linux-2.6/xfs_iops.c b/trunk/fs/xfs/linux-2.6/xfs_iops.c index b1fc2a6bfe83..68be25dcd301 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_iops.c +++ b/trunk/fs/xfs/linux-2.6/xfs_iops.c @@ -664,7 +664,7 @@ xfs_vn_fiemap( fieinfo->fi_extents_max + 1; bm.bmv_count = min_t(__s32, bm.bmv_count, (PAGE_SIZE * 16 / sizeof(struct getbmapx))); - bm.bmv_iflags = BMV_IF_PREALLOC | BMV_IF_NO_HOLES; + bm.bmv_iflags = BMV_IF_PREALLOC; if (fieinfo->fi_flags & FIEMAP_FLAG_XATTR) bm.bmv_iflags |= BMV_IF_ATTRFORK; if (!(fieinfo->fi_flags & FIEMAP_FLAG_SYNC)) diff --git a/trunk/fs/xfs/xfs_bmap.c b/trunk/fs/xfs/xfs_bmap.c index f90dadd5a968..23f14e595c18 100644 --- a/trunk/fs/xfs/xfs_bmap.c +++ b/trunk/fs/xfs/xfs_bmap.c @@ -5533,24 +5533,12 @@ xfs_getbmap( map[i].br_startblock)) goto out_free_map; + nexleft--; bmv->bmv_offset = out[cur_ext].bmv_offset + out[cur_ext].bmv_length; bmv->bmv_length = max_t(__int64_t, 0, bmvend - bmv->bmv_offset); - - /* - * In case we don't want to return the hole, - * don't increase cur_ext so that we can reuse - * it in the next loop. - */ - if ((iflags & BMV_IF_NO_HOLES) && - map[i].br_startblock == HOLESTARTBLOCK) { - memset(&out[cur_ext], 0, sizeof(out[cur_ext])); - continue; - } - - nexleft--; bmv->bmv_entries++; cur_ext++; } diff --git a/trunk/fs/xfs/xfs_fs.h b/trunk/fs/xfs/xfs_fs.h index 87c2e9d02288..7cf7220e7d5f 100644 --- a/trunk/fs/xfs/xfs_fs.h +++ b/trunk/fs/xfs/xfs_fs.h @@ -114,10 +114,8 @@ struct getbmapx { #define BMV_IF_NO_DMAPI_READ 0x2 /* Do not generate DMAPI read event */ #define BMV_IF_PREALLOC 0x4 /* rtn status BMV_OF_PREALLOC if req */ #define BMV_IF_DELALLOC 0x8 /* rtn status BMV_OF_DELALLOC if req */ -#define BMV_IF_NO_HOLES 0x10 /* Do not return holes */ #define BMV_IF_VALID \ - (BMV_IF_ATTRFORK|BMV_IF_NO_DMAPI_READ|BMV_IF_PREALLOC| \ - BMV_IF_DELALLOC|BMV_IF_NO_HOLES) + (BMV_IF_ATTRFORK|BMV_IF_NO_DMAPI_READ|BMV_IF_PREALLOC|BMV_IF_DELALLOC) /* bmv_oflags values - returned for each non-header segment */ #define BMV_OF_PREALLOC 0x1 /* segment = unwritten pre-allocation */ diff --git a/trunk/fs/xfs/xfs_vnodeops.c b/trunk/fs/xfs/xfs_vnodeops.c index 4c7c7bfb2b2f..66d585c6917c 100644 --- a/trunk/fs/xfs/xfs_vnodeops.c +++ b/trunk/fs/xfs/xfs_vnodeops.c @@ -2299,22 +2299,15 @@ xfs_alloc_file_space( e = allocatesize_fsb; } - /* - * The transaction reservation is limited to a 32-bit block - * count, hence we need to limit the number of blocks we are - * trying to reserve to avoid an overflow. We can't allocate - * more than @nimaps extents, and an extent is limited on disk - * to MAXEXTLEN (21 bits), so use that to enforce the limit. - */ - resblks = min_t(xfs_fileoff_t, (e - s), (MAXEXTLEN * nimaps)); if (unlikely(rt)) { - resrtextents = qblocks = resblks; + resrtextents = qblocks = (uint)(e - s); resrtextents /= mp->m_sb.sb_rextsize; resblks = XFS_DIOSTRAT_SPACE_RES(mp, 0); quota_flag = XFS_QMOPT_RES_RTBLKS; } else { resrtextents = 0; - resblks = qblocks = XFS_DIOSTRAT_SPACE_RES(mp, resblks); + resblks = qblocks = \ + XFS_DIOSTRAT_SPACE_RES(mp, (uint)(e - s)); quota_flag = XFS_QMOPT_RES_REGBLKS; } diff --git a/trunk/include/acpi/acpi_bus.h b/trunk/include/acpi/acpi_bus.h index 4de84ce3a927..baacd98e7cc6 100644 --- a/trunk/include/acpi/acpi_bus.h +++ b/trunk/include/acpi/acpi_bus.h @@ -377,6 +377,9 @@ struct acpi_pci_root { u32 osc_support_set; /* _OSC state of support bits */ u32 osc_control_set; /* _OSC state of control bits */ + u32 osc_control_qry; /* the latest _OSC query result */ + + u32 osc_queried:1; /* has _OSC control been queried? */ }; /* helper */ diff --git a/trunk/include/linux/acpi.h b/trunk/include/linux/acpi.h index c227757feb06..ccf94dc5acdf 100644 --- a/trunk/include/linux/acpi.h +++ b/trunk/include/linux/acpi.h @@ -304,8 +304,8 @@ acpi_status acpi_run_osc(acpi_handle handle, struct acpi_osc_context *context); OSC_PCI_EXPRESS_PME_CONTROL | \ OSC_PCI_EXPRESS_AER_CONTROL | \ OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL) -extern acpi_status acpi_pci_osc_control_set(acpi_handle handle, - u32 *mask, u32 req); + +extern acpi_status acpi_pci_osc_control_set(acpi_handle handle, u32 flags); extern void acpi_early_init(void); #else /* !CONFIG_ACPI */ diff --git a/trunk/include/linux/pci.h b/trunk/include/linux/pci.h index c8d95e369ff4..b1d17956a153 100644 --- a/trunk/include/linux/pci.h +++ b/trunk/include/linux/pci.h @@ -1214,9 +1214,6 @@ static inline struct pci_dev *pci_get_bus_and_slot(unsigned int bus, unsigned int devfn) { return NULL; } -static inline int pci_domain_nr(struct pci_bus *bus) -{ return 0; } - #define dev_is_pci(d) (false) #define dev_is_pf(d) (false) #define dev_num_vf(d) (0) diff --git a/trunk/security/apparmor/path.c b/trunk/security/apparmor/path.c index 19358dc14605..82396050f186 100644 --- a/trunk/security/apparmor/path.c +++ b/trunk/security/apparmor/path.c @@ -59,8 +59,7 @@ static int d_namespace_path(struct path *path, char *buf, int buflen, { struct path root, tmp; char *res; - int deleted, connected; - int error = 0; + int connected, error = 0; /* Get the root we want to resolve too, released below */ if (flags & PATH_CHROOT_REL) { @@ -74,19 +73,8 @@ static int d_namespace_path(struct path *path, char *buf, int buflen, } spin_lock(&dcache_lock); - /* There is a race window between path lookup here and the - * need to strip the " (deleted) string that __d_path applies - * Detect the race and relookup the path - * - * The stripping of (deleted) is a hack that could be removed - * with an updated __d_path - */ - do { - tmp = root; - deleted = d_unlinked(path->dentry); - res = __d_path(path, &tmp, buf, buflen); - - } while (deleted != d_unlinked(path->dentry)); + tmp = root; + res = __d_path(path, &tmp, buf, buflen); spin_unlock(&dcache_lock); *name = res; @@ -98,21 +86,17 @@ static int d_namespace_path(struct path *path, char *buf, int buflen, *name = buf; goto out; } - if (deleted) { - /* On some filesystems, newly allocated dentries appear to the - * security_path hooks as a deleted dentry except without an - * inode allocated. - * - * Remove the appended deleted text and return as string for - * normal mediation, or auditing. The (deleted) string is - * guaranteed to be added in this case, so just strip it. - */ - buf[buflen - 11] = 0; /* - (len(" (deleted)") +\0) */ - if (path->dentry->d_inode && !(flags & PATH_MEDIATE_DELETED)) { + /* Handle two cases: + * 1. A deleted dentry && profile is not allowing mediation of deleted + * 2. On some filesystems, newly allocated dentries appear to the + * security_path hooks as a deleted dentry except without an inode + * allocated. + */ + if (d_unlinked(path->dentry) && path->dentry->d_inode && + !(flags & PATH_MEDIATE_DELETED)) { error = -ENOENT; goto out; - } } /* Determine if the path is connected to the expected root */