diff --git a/[refs] b/[refs] index f2e05879e097..f6b6ffb7a965 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 4bdc1b96504f5f562b129afd48ca03d79aeb1fd9 +refs/heads/master: 1ac00cc21337b0b667493d9af79d88537de90aa3 diff --git a/trunk/Documentation/ABI/testing/sysfs-bus-pci b/trunk/Documentation/ABI/testing/sysfs-bus-pci index e638e15a8895..ceddcff4082a 100644 --- a/trunk/Documentation/ABI/testing/sysfs-bus-pci +++ b/trunk/Documentation/ABI/testing/sysfs-bus-pci @@ -1,46 +1,3 @@ -What: /sys/bus/pci/drivers/.../bind -Date: December 2003 -Contact: linux-pci@vger.kernel.org -Description: - Writing a device location to this file will cause - the driver to attempt to bind to the device found at - this location. This is useful for overriding default - bindings. The format for the location is: DDDD:BB:DD.F. - That is Domain:Bus:Device.Function and is the same as - found in /sys/bus/pci/devices/. For example: - # echo 0000:00:19.0 > /sys/bus/pci/drivers/foo/bind - (Note: kernels before 2.6.28 may require echo -n). - -What: /sys/bus/pci/drivers/.../unbind -Date: December 2003 -Contact: linux-pci@vger.kernel.org -Description: - Writing a device location to this file will cause the - driver to attempt to unbind from the device found at - this location. This may be useful when overriding default - bindings. The format for the location is: DDDD:BB:DD.F. - That is Domain:Bus:Device.Function and is the same as - found in /sys/bus/pci/devices/. For example: - # echo 0000:00:19.0 > /sys/bus/pci/drivers/foo/unbind - (Note: kernels before 2.6.28 may require echo -n). - -What: /sys/bus/pci/drivers/.../new_id -Date: December 2003 -Contact: linux-pci@vger.kernel.org -Description: - Writing a device ID to this file will attempt to - dynamically add a new device ID to a PCI device driver. - This may allow the driver to support more hardware than - was included in the driver's static device ID support - table at compile time. The format for the device ID is: - VVVV DDDD SVVV SDDD CCCC MMMM PPPP. That is Vendor ID, - Device ID, Subsystem Vendor ID, Subsystem Device ID, - Class, Class Mask, and Private Driver Data. The Vendor ID - and Device ID fields are required, the rest are optional. - Upon successfully adding an ID, the driver will probe - for the device and attempt to bind to it. For example: - # echo "8086 10f5" > /sys/bus/pci/drivers/foo/new_id - What: /sys/bus/pci/devices/.../vpd Date: February 2008 Contact: Ben Hutchings diff --git a/trunk/arch/powerpc/sysdev/ppc4xx_pci.c b/trunk/arch/powerpc/sysdev/ppc4xx_pci.c index 77fae5f64f2e..5558d932b4d5 100644 --- a/trunk/arch/powerpc/sysdev/ppc4xx_pci.c +++ b/trunk/arch/powerpc/sysdev/ppc4xx_pci.c @@ -204,6 +204,23 @@ static int __init ppc4xx_setup_one_pci_PMM(struct pci_controller *hose, { u32 ma, pcila, pciha; + /* Hack warning ! The "old" PCI 2.x cell only let us configure the low + * 32-bit of incoming PLB addresses. The top 4 bits of the 36-bit + * address are actually hard wired to a value that appears to depend + * on the specific SoC. For example, it's 0 on 440EP and 1 on 440EPx. + * + * The trick here is we just crop those top bits and ignore them when + * programming the chip. That means the device-tree has to be right + * for the specific part used (we don't print a warning if it's wrong + * but on the other hand, you'll crash quickly enough), but at least + * this code should work whatever the hard coded value is + */ + plb_addr &= 0xffffffffull; + + /* Note: Due to the above hack, the test below doesn't actually test + * if you address is above 4G, but it tests that address and + * (address + size) are both contained in the same 4G + */ if ((plb_addr + size) > 0xffffffffull || !is_power_of_2(size) || size < 0x1000 || (plb_addr & (size - 1)) != 0) { printk(KERN_WARNING "%s: Resource out of range\n", diff --git a/trunk/drivers/pci/hotplug/pciehp.h b/trunk/drivers/pci/hotplug/pciehp.h index 39ae37589fda..db85284ffb62 100644 --- a/trunk/drivers/pci/hotplug/pciehp.h +++ b/trunk/drivers/pci/hotplug/pciehp.h @@ -111,7 +111,6 @@ struct controller { int cmd_busy; unsigned int no_cmd_complete:1; unsigned int link_active_reporting:1; - unsigned int notification_enabled:1; }; #define INT_BUTTON_IGNORE 0 @@ -171,7 +170,6 @@ extern int pciehp_configure_device(struct slot *p_slot); extern int pciehp_unconfigure_device(struct slot *p_slot); extern void pciehp_queue_pushbutton_work(struct work_struct *work); struct controller *pcie_init(struct pcie_device *dev); -int pcie_init_notification(struct controller *ctrl); int pciehp_enable_slot(struct slot *p_slot); int pciehp_disable_slot(struct slot *p_slot); int pcie_enable_notification(struct controller *ctrl); diff --git a/trunk/drivers/pci/hotplug/pciehp_core.c b/trunk/drivers/pci/hotplug/pciehp_core.c index 681e3912b821..c2485542f543 100644 --- a/trunk/drivers/pci/hotplug/pciehp_core.c +++ b/trunk/drivers/pci/hotplug/pciehp_core.c @@ -434,13 +434,6 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_ goto err_out_release_ctlr; } - /* Enable events after we have setup the data structures */ - rc = pcie_init_notification(ctrl); - if (rc) { - ctrl_err(ctrl, "Notification initialization failed\n"); - goto err_out_release_ctlr; - } - /* Check if slot is occupied */ t_slot = pciehp_find_slot(ctrl, ctrl->slot_device_offset); t_slot->hpc_ops->get_adapter_status(t_slot, &value); diff --git a/trunk/drivers/pci/hotplug/pciehp_hpc.c b/trunk/drivers/pci/hotplug/pciehp_hpc.c index 7a16c6897bb9..71a8012886b0 100644 --- a/trunk/drivers/pci/hotplug/pciehp_hpc.c +++ b/trunk/drivers/pci/hotplug/pciehp_hpc.c @@ -934,7 +934,7 @@ static void pcie_disable_notification(struct controller *ctrl) ctrl_warn(ctrl, "Cannot disable software notification\n"); } -int pcie_init_notification(struct controller *ctrl) +static int pcie_init_notification(struct controller *ctrl) { if (pciehp_request_irq(ctrl)) return -1; @@ -942,17 +942,13 @@ int pcie_init_notification(struct controller *ctrl) pciehp_free_irq(ctrl); return -1; } - ctrl->notification_enabled = 1; return 0; } static void pcie_shutdown_notification(struct controller *ctrl) { - if (ctrl->notification_enabled) { - pcie_disable_notification(ctrl); - pciehp_free_irq(ctrl); - ctrl->notification_enabled = 0; - } + pcie_disable_notification(ctrl); + pciehp_free_irq(ctrl); } static int pcie_init_slot(struct controller *ctrl) @@ -1114,8 +1110,13 @@ struct controller *pcie_init(struct pcie_device *dev) if (pcie_init_slot(ctrl)) goto abort_ctrl; + if (pcie_init_notification(ctrl)) + goto abort_slot; + return ctrl; +abort_slot: + pcie_cleanup_slot(ctrl); abort_ctrl: kfree(ctrl); abort: diff --git a/trunk/drivers/pci/pcie/aer/aerdrv_core.c b/trunk/drivers/pci/pcie/aer/aerdrv_core.c index d0c973685868..aac7006949f1 100644 --- a/trunk/drivers/pci/pcie/aer/aerdrv_core.c +++ b/trunk/drivers/pci/pcie/aer/aerdrv_core.c @@ -108,34 +108,6 @@ int pci_cleanup_aer_correct_error_status(struct pci_dev *dev) } #endif /* 0 */ - -static void set_device_error_reporting(struct pci_dev *dev, void *data) -{ - bool enable = *((bool *)data); - - if (dev->pcie_type != PCIE_RC_PORT && - dev->pcie_type != PCIE_SW_UPSTREAM_PORT && - dev->pcie_type != PCIE_SW_DOWNSTREAM_PORT) - return; - - if (enable) - pci_enable_pcie_error_reporting(dev); - else - pci_disable_pcie_error_reporting(dev); -} - -/** - * set_downstream_devices_error_reporting - enable/disable the error reporting bits on the root port and its downstream ports. - * @dev: pointer to root port's pci_dev data structure - * @enable: true = enable error reporting, false = disable error reporting. - */ -static void set_downstream_devices_error_reporting(struct pci_dev *dev, - bool enable) -{ - set_device_error_reporting(dev, &enable); - pci_walk_bus(dev->subordinate, set_device_error_reporting, &enable); -} - static int find_device_iter(struct device *device, void *data) { struct pci_dev *dev; @@ -553,11 +525,15 @@ void aer_enable_rootport(struct aer_rpc *rpc) pci_read_config_dword(pdev, aer_pos + PCI_ERR_UNCOR_STATUS, ®32); pci_write_config_dword(pdev, aer_pos + PCI_ERR_UNCOR_STATUS, reg32); - /* - * Enable error reporting for the root port device and downstream port - * devices. - */ - set_downstream_devices_error_reporting(pdev, true); + /* Enable Root Port device reporting error itself */ + pci_read_config_word(pdev, pos+PCI_EXP_DEVCTL, ®16); + reg16 = reg16 | + PCI_EXP_DEVCTL_CERE | + PCI_EXP_DEVCTL_NFERE | + PCI_EXP_DEVCTL_FERE | + PCI_EXP_DEVCTL_URRE; + pci_write_config_word(pdev, pos+PCI_EXP_DEVCTL, + reg16); /* Enable Root Port's interrupt in response to error messages */ pci_write_config_dword(pdev, @@ -577,12 +553,6 @@ static void disable_root_aer(struct aer_rpc *rpc) u32 reg32; int pos; - /* - * Disable error reporting for the root port device and downstream port - * devices. - */ - set_downstream_devices_error_reporting(pdev, false); - pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ERR); /* Disable Root's interrupt in response to error messages */ pci_write_config_dword(pdev, pos + PCI_ERR_ROOT_COMMAND, 0); diff --git a/trunk/drivers/pci/pcie/portdrv_pci.c b/trunk/drivers/pci/pcie/portdrv_pci.c index 248b4db91552..f9b874eaeb9f 100644 --- a/trunk/drivers/pci/pcie/portdrv_pci.c +++ b/trunk/drivers/pci/pcie/portdrv_pci.c @@ -97,6 +97,8 @@ static int __devinit pcie_portdrv_probe (struct pci_dev *dev, pcie_portdrv_save_config(dev); + pci_enable_pcie_error_reporting(dev); + return 0; } diff --git a/trunk/drivers/pci/quirks.c b/trunk/drivers/pci/quirks.c index f20d55368edb..baad093aafe3 100644 --- a/trunk/drivers/pci/quirks.c +++ b/trunk/drivers/pci/quirks.c @@ -1584,7 +1584,6 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_ */ #define AMD_813X_MISC 0x40 #define AMD_813X_NOIOAMODE (1<<0) -#define AMD_813X_REV_B2 0x13 static void quirk_disable_amd_813x_boot_interrupt(struct pci_dev *dev) { @@ -1592,8 +1591,6 @@ static void quirk_disable_amd_813x_boot_interrupt(struct pci_dev *dev) if (noioapicquirk) return; - if (dev->revision == AMD_813X_REV_B2) - return; pci_read_config_dword(dev, AMD_813X_MISC, &pci_config_dword); pci_config_dword &= ~AMD_813X_NOIOAMODE; @@ -1984,6 +1981,7 @@ static void __devinit quirk_msi_ht_cap(struct pci_dev *dev) DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT2000_PCIE, quirk_msi_ht_cap); + /* The nVidia CK804 chipset may have 2 HT MSI mappings. * MSI are supported if the MSI capability set in any of these mappings. */ @@ -2034,9 +2032,6 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT1000_PXB, ht_enable_msi_mapping); -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8132_BRIDGE, - ht_enable_msi_mapping); - /* The P5N32-SLI Premium motherboard from Asus has a problem with msi * for the MCP55 NIC. It is not yet determined whether the msi problem * also affects other devices. As for now, turn off msi for this device. @@ -2053,100 +2048,10 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_15, nvenet_msi_disable); -static void __devinit nv_ht_enable_msi_mapping(struct pci_dev *dev) -{ - struct pci_dev *host_bridge; - int pos; - int i, dev_no; - int found = 0; - - dev_no = dev->devfn >> 3; - for (i = dev_no; i >= 0; i--) { - host_bridge = pci_get_slot(dev->bus, PCI_DEVFN(i, 0)); - if (!host_bridge) - continue; - - pos = pci_find_ht_capability(host_bridge, HT_CAPTYPE_SLAVE); - if (pos != 0) { - found = 1; - break; - } - pci_dev_put(host_bridge); - } - - if (!found) - return; - - /* root did that ! */ - if (msi_ht_cap_enabled(host_bridge)) - goto out; - - ht_enable_msi_mapping(dev); - -out: - pci_dev_put(host_bridge); -} - -static void __devinit ht_disable_msi_mapping(struct pci_dev *dev) -{ - int pos, ttl = 48; - - pos = pci_find_ht_capability(dev, HT_CAPTYPE_MSI_MAPPING); - while (pos && ttl--) { - u8 flags; - - if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS, - &flags) == 0) { - dev_info(&dev->dev, "Enabling HT MSI Mapping\n"); - - pci_write_config_byte(dev, pos + HT_MSI_FLAGS, - flags & ~HT_MSI_FLAGS_ENABLE); - } - pos = pci_find_next_ht_capability(dev, pos, - HT_CAPTYPE_MSI_MAPPING); - } -} - -static int __devinit ht_check_msi_mapping(struct pci_dev *dev) -{ - int pos, ttl = 48; - int found = 0; - - /* check if there is HT MSI cap or enabled on this device */ - pos = pci_find_ht_capability(dev, HT_CAPTYPE_MSI_MAPPING); - while (pos && ttl--) { - u8 flags; - - if (found < 1) - found = 1; - if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS, - &flags) == 0) { - if (flags & HT_MSI_FLAGS_ENABLE) { - if (found < 2) { - found = 2; - break; - } - } - } - pos = pci_find_next_ht_capability(dev, pos, - HT_CAPTYPE_MSI_MAPPING); - } - - return found; -} - static void __devinit nv_msi_ht_cap_quirk(struct pci_dev *dev) { struct pci_dev *host_bridge; - int pos; - int found; - - /* check if there is HT MSI cap or enabled on this device */ - found = ht_check_msi_mapping(dev); - - /* no HT MSI CAP */ - if (found == 0) - return; + int pos, ttl = 48; /* * HT MSI mapping should be disabled on devices that are below @@ -2162,19 +2067,24 @@ static void __devinit nv_msi_ht_cap_quirk(struct pci_dev *dev) pos = pci_find_ht_capability(host_bridge, HT_CAPTYPE_SLAVE); if (pos != 0) { /* Host bridge is to HT */ - if (found == 1) { - /* it is not enabled, try to enable it */ - nv_ht_enable_msi_mapping(dev); - } + ht_enable_msi_mapping(dev); return; } - /* HT MSI is not enabled */ - if (found == 1) - return; - /* Host bridge is not to HT, disable HT MSI mapping on this device */ - ht_disable_msi_mapping(dev); + pos = pci_find_ht_capability(dev, HT_CAPTYPE_MSI_MAPPING); + while (pos && ttl--) { + u8 flags; + + if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS, + &flags) == 0) { + dev_info(&dev->dev, "Disabling HT MSI mapping"); + pci_write_config_byte(dev, pos + HT_MSI_FLAGS, + flags & ~HT_MSI_FLAGS_ENABLE); + } + pos = pci_find_next_ht_capability(dev, pos, + HT_CAPTYPE_MSI_MAPPING); + } } DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, nv_msi_ht_cap_quirk); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AL, PCI_ANY_ID, nv_msi_ht_cap_quirk);