From ce5ccdef1090367f3024b4d5e7908bf6bd2929ae Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Mon, 16 Jul 2007 23:27:10 -0500 Subject: [PATCH 01/10] PCI: Move prototypes for pci_bus_find_capability to include/linux/pci.h We need pci_bus_find_capability() in some arch/powerpc code so move the prototype into a header accessible to it. Also kill the duplicate prototype for pci_bus_alloc_resource(). Signed-off-by: Kumar Gala Signed-off-by: Greg Kroah-Hartman --- drivers/pci/pci.h | 8 +------- include/linux/pci.h | 3 +++ 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index c6e132d7c0f..4c36e80f6d2 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -5,12 +5,7 @@ extern int pci_uevent(struct device *dev, char **envp, int num_envp, extern int pci_create_sysfs_dev_files(struct pci_dev *pdev); extern void pci_remove_sysfs_dev_files(struct pci_dev *pdev); extern void pci_cleanup_rom(struct pci_dev *dev); -extern int pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, - resource_size_t size, resource_size_t align, - resource_size_t min, unsigned int type_mask, - void (*alignf)(void *, struct resource *, - resource_size_t, resource_size_t), - void *alignf_data); + /* Firmware callbacks */ extern pci_power_t (*platform_pci_choose_state)(struct pci_dev *dev, pm_message_t state); extern int (*platform_pci_set_power_state)(struct pci_dev *dev, pci_power_t state); @@ -35,7 +30,6 @@ static inline int pci_proc_detach_bus(struct pci_bus *bus) { return 0; } /* Functions for PCI Hotplug drivers to use */ extern unsigned int pci_do_scan_bus(struct pci_bus *bus); -extern int pci_bus_find_capability (struct pci_bus *bus, unsigned int devfn, int cap); extern void pci_remove_legacy_files(struct pci_bus *bus); diff --git a/include/linux/pci.h b/include/linux/pci.h index e7d8d4e19a5..325225c4845 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -578,6 +578,9 @@ int pci_set_power_state(struct pci_dev *dev, pci_power_t state); pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state); int pci_enable_wake(struct pci_dev *dev, pci_power_t state, int enable); +/* Functions for PCI Hotplug drivers to use */ +int pci_bus_find_capability (struct pci_bus *bus, unsigned int devfn, int cap); + /* Helper functions for low-level code (drivers/pci/setup-[bus,res].c) */ void pci_bus_assign_resources(struct pci_bus *bus); void pci_bus_size_bridges(struct pci_bus *bus); From 4e68fc97b17470365a65bc569523dd9012730e44 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Tue, 3 Jul 2007 11:03:18 +0200 Subject: [PATCH 02/10] PCI: quirk_e100_interrupt() called too early quirk_e100_interrupts() is called after PCI controller is initialized and before PCI bus enumeration is performed. On some powerpc platforms which modify PCI controller configuration and set different MEM and IO windows than those set by firmware quirk_e100_interrupt() is causing kernel panic as it tries to read from device BAR0 offets which at this time points to a invalid PCI window (set by firmware). This patch delays the quirk_100_interrupt() to pci_fixup_final phase, which happens after bus enumeration and before PCI enable and device driver initialization. Signed-off-by: Marian Balakowicz Signed-off-by: Greg Kroah-Hartman --- drivers/pci/quirks.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index c559085c89a..ab1c5c5d03f 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -1485,7 +1485,7 @@ static void __devinit quirk_e100_interrupt(struct pci_dev *dev) iounmap(csr); } -DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, quirk_e100_interrupt); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, quirk_e100_interrupt); static void __devinit fixup_rev1_53c810(struct pci_dev* dev) { From 5ca24814247fa4c039b893bf80fc05d0e5d41b00 Mon Sep 17 00:00:00 2001 From: Rolf Eike Beer Date: Thu, 19 Jul 2007 17:48:44 -0700 Subject: [PATCH 03/10] PCI: Document pci_iomap() This useful interface is hardly mentioned anywhere in the in-tree documentation. Signed-off-by: Rolf Eike Beer Cc: Tejun Heo Acked-by: Randy Dunlap Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- Documentation/DocBook/deviceiobook.tmpl | 3 ++- include/asm-i386/io.h | 3 +++ lib/iomap.c | 15 ++++++++++++++- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/Documentation/DocBook/deviceiobook.tmpl b/Documentation/DocBook/deviceiobook.tmpl index 90ed23df1f6..c917de681cc 100644 --- a/Documentation/DocBook/deviceiobook.tmpl +++ b/Documentation/DocBook/deviceiobook.tmpl @@ -316,7 +316,8 @@ CPU B: spin_unlock_irqrestore(&dev_lock, flags) Public Functions Provided -!Einclude/asm-i386/io.h +!Iinclude/asm-i386/io.h +!Elib/iomap.c diff --git a/include/asm-i386/io.h b/include/asm-i386/io.h index 7b65b5b0003..e8e0bd64112 100644 --- a/include/asm-i386/io.h +++ b/include/asm-i386/io.h @@ -112,6 +112,9 @@ extern void __iomem * __ioremap(unsigned long offset, unsigned long size, unsign * writew/writel functions and the other mmio helpers. The returned * address is not guaranteed to be usable directly as a virtual * address. + * + * If the area you are trying to map is a PCI BAR you should have a + * look at pci_iomap(). */ static inline void __iomem * ioremap(unsigned long offset, unsigned long size) diff --git a/lib/iomap.c b/lib/iomap.c index a57d262a5ed..864f2ec1966 100644 --- a/lib/iomap.c +++ b/lib/iomap.c @@ -240,7 +240,20 @@ void ioport_unmap(void __iomem *addr) EXPORT_SYMBOL(ioport_map); EXPORT_SYMBOL(ioport_unmap); -/* Create a virtual mapping cookie for a PCI BAR (memory or IO) */ +/** + * pci_iomap - create a virtual mapping cookie for a PCI BAR + * @dev: PCI device that owns the BAR + * @bar: BAR number + * @maxlen: length of the memory to map + * + * Using this function you will get a __iomem address to your device BAR. + * You can access it using ioread*() and iowrite*(). These functions hide + * the details if this is a MMIO or PIO address space and will just do what + * you expect from them in the correct way. + * + * @maxlen specifies the maximum length to map. If you want to get access to + * the complete BAR without checking for its length first, pass %0 here. + * */ void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen) { unsigned long start = pci_resource_start(dev, bar); From 60ac8f20feb0bba8caee63be3e7ca5801fe16d4c Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Tue, 24 Jul 2007 11:16:37 +0200 Subject: [PATCH 04/10] pci/hotplug/cpqphp_ctrl.c: remove stale BKL use remove stale BKL use from drivers/pci/hotplug/cpqphp_ctrl.c. Signed-off-by: Ingo Molnar Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/cpqphp_ctrl.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/pci/hotplug/cpqphp_ctrl.c b/drivers/pci/hotplug/cpqphp_ctrl.c index 79ff6b4de3a..37d72f123a8 100644 --- a/drivers/pci/hotplug/cpqphp_ctrl.c +++ b/drivers/pci/hotplug/cpqphp_ctrl.c @@ -1746,10 +1746,8 @@ static void pushbutton_helper_thread(unsigned long data) static int event_thread(void* data) { struct controller *ctrl; - lock_kernel(); + daemonize("phpd_event"); - - unlock_kernel(); while (1) { dbg("!!!!event_thread sleeping\n"); From d55bef515a01c85aa65c03c285ea8d285fcbab3b Mon Sep 17 00:00:00 2001 From: Bernhard Kaindl Date: Mon, 30 Jul 2007 20:35:13 +0200 Subject: [PATCH 05/10] PCI: lets kill the 'PCI hidden behind bridge' message MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adrian Bunk wrote: > Alois Nešpor wrote >> PCI: Bus #0b (-#0e) is hidden behind transparent bridge #0a (-#0b) (try 'pci=assign-busses') >> Please report the result to linux-kernel to fix this permanently" >> >> dmesg: >> "Yenta: Raising subordinate bus# of parent bus (#0a) from #0b to #0e" >> without pci=assign-busses and nothing with pci=assign-busses. > > Bernhard? Ok, lets kill the message. As Alois Nešpor also saw, that's fixed up by Yenta, so PCI does not have to warn about it. PCI could still warn about it if is_cardbus is 0 in that instance of pci_scan_bridge(), but so far I have not seen a report where this would have been the case so I think we can spare the kernel of that check (removes ~300 lines of asm) unless debugging is done. History: The whole check was added in the days before we had the fixup for this in Yenta and pci=assign-busses was the only way to get CardBus cards detected on many (not all) of the machines which give this warning. In theory, there could be cases when this warning would be triggered and it's not cardbus, then the warning should still apply, but I think this should only be the case when working on a completely broken PCI setup, but one may have already enabled the debug code in drivers/pci and the patched check would then trigger. I do not sign this off yet because it's completely untested so far, but everyone is free to test it (with the #ifdef DEBUG replaced by #if 1 and pr_debug( changed to printk(. We may also dump the whole check (remove everything within the #ifdef from the source) if that's perferred. On Alois Nešpor's machine this would then (only when debugging) this message: "PCI: Bus #0b (-#0e) is partially hidden behind transparent bridge #0a (-#0b)" "partially" should be in the message on his machine because #0b of #0b-#0e is reachable behind #0a-#0b, but not #0c-#0e. But that differentiation is now moot anyway because the fixup in Yenta takes care of it as far as I could see so far, which means that unless somebody is debugging a totally broken PCI setup, this message is not needed anymore, not even for debugging PCI. Ok, here the patch with the following changes: * Refined to say that the bus is only partially hidden when the parent bus numbers are not totally way off (outside of) the child bus range * remove the reference to pci=assign-busses and the plea to report it We could add a pure source code-only comment to keep a reference to pci=assign-busses the in case when this is triggered by someone who is debugging the cause of this message and looking the way to solve it. From: Bernhard Kaindl Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/pci/probe.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 34b8dae0d90..27e00b2d7b5 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -653,20 +653,20 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max, int pass sprintf(child->name, (is_cardbus ? "PCI CardBus #%02x" : "PCI Bus #%02x"), child->number); + /* Has only triggered on CardBus, fixup is in yenta_socket */ while (bus->parent) { if ((child->subordinate > bus->subordinate) || (child->number > bus->subordinate) || (child->number < bus->number) || (child->subordinate < bus->number)) { - printk(KERN_WARNING "PCI: Bus #%02x (-#%02x) is " - "hidden behind%s bridge #%02x (-#%02x)%s\n", - child->number, child->subordinate, - bus->self->transparent ? " transparent" : " ", - bus->number, bus->subordinate, - pcibios_assign_all_busses() ? " " : - " (try 'pci=assign-busses')"); - printk(KERN_WARNING "Please report the result to " - " to fix this permanently\n"); + pr_debug("PCI: Bus #%02x (-#%02x) is %s" + "hidden behind%s bridge #%02x (-#%02x)\n", + child->number, child->subordinate, + (bus->number > child->subordinate && + bus->subordinate < child->number) ? + "wholly " : " partially", + bus->self->transparent ? " transparent" : " ", + bus->number, bus->subordinate); } bus = bus->parent; } From 2637e5b539f5f153f2124dbad087b5216bc68d6d Mon Sep 17 00:00:00 2001 From: Brice Goglin Date: Tue, 14 Aug 2007 12:43:48 +0200 Subject: [PATCH 06/10] PCI: make pcie_get_readrq visible in pci.h [PATCH] PCI: make pcie_get_readrq visible in pci.h pcie_get_readrq() is EXPORT_SYMBOL'ed, but its prototype is not visible in pci.h, add it there. This is needed by some network drivers. Signed-off-by: Brice Goglin Acked-by: Peter Oruba Signed-off-by: Greg Kroah-Hartman --- include/linux/pci.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/linux/pci.h b/include/linux/pci.h index 325225c4845..038a0dc7273 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -557,6 +557,7 @@ int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask); int pcix_get_max_mmrbc(struct pci_dev *dev); int pcix_get_mmrbc(struct pci_dev *dev); int pcix_set_mmrbc(struct pci_dev *dev, int mmrbc); +int pcie_get_readrq(struct pci_dev *dev); int pcie_set_readrq(struct pci_dev *dev, int rq); void pci_update_resource(struct pci_dev *dev, struct resource *res, int resno); int __must_check pci_assign_resource(struct pci_dev *dev, int i); From 4be8f906435a6af241821ab5b94b2b12cb7d57d8 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 16 Aug 2007 14:34:42 +0900 Subject: [PATCH 07/10] PCI: disable MSI on RS690 RS690 can't do MSI like its predecessors. Disable MSI on RS690. Signed-off-by: Tejun Heo Cc: Henry Su Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/pci/quirks.c | 1 + include/linux/pci_ids.h | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index ab1c5c5d03f..ca89ed92cd0 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -1650,6 +1650,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_GCN DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT1000_PCIX, quirk_disable_all_msi); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS400_200, quirk_disable_all_msi); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS480, quirk_disable_all_msi); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS690, quirk_disable_all_msi); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VT3351, quirk_disable_all_msi); /* Disable MSI on chipsets that are known to not support it */ diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 8938d59013c..0d6279c60b3 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -360,6 +360,7 @@ #define PCI_DEVICE_ID_ATI_RS400_166 0x5a32 #define PCI_DEVICE_ID_ATI_RS400_200 0x5a33 #define PCI_DEVICE_ID_ATI_RS480 0x5950 +#define PCI_DEVICE_ID_ATI_RS690 0x7910 /* ATI IXP Chipset */ #define PCI_DEVICE_ID_ATI_IXP200_IDE 0x4349 #define PCI_DEVICE_ID_ATI_IXP200_SMBUS 0x4353 From aea6a433f50cd89b9cbd10850fd0b32f961f9883 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sat, 18 Aug 2007 03:03:10 +0900 Subject: [PATCH 08/10] PCI: disable MSI on RD580 RD580 can't do MSI like its predecessors. Disable MSI on RD580. Signed-off-by: Tejun Heo CC: stable Signed-off-by: Greg Kroah-Hartman --- drivers/pci/quirks.c | 1 + include/linux/pci_ids.h | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index ca89ed92cd0..ebfc1de7579 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -1650,6 +1650,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_GCN DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT1000_PCIX, quirk_disable_all_msi); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS400_200, quirk_disable_all_msi); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS480, quirk_disable_all_msi); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RD580, quirk_disable_all_msi); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS690, quirk_disable_all_msi); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VT3351, quirk_disable_all_msi); diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 0d6279c60b3..80c27d7bf02 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -360,6 +360,7 @@ #define PCI_DEVICE_ID_ATI_RS400_166 0x5a32 #define PCI_DEVICE_ID_ATI_RS400_200 0x5a33 #define PCI_DEVICE_ID_ATI_RS480 0x5950 +#define PCI_DEVICE_ID_ATI_RD580 0x5952 #define PCI_DEVICE_ID_ATI_RS690 0x7910 /* ATI IXP Chipset */ #define PCI_DEVICE_ID_ATI_IXP200_IDE 0x4349 From f122392f679ebed39db08074f935d770504623eb Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 21 Aug 2007 14:33:01 +0900 Subject: [PATCH 09/10] PCI: disable MSI on RX790 RX790 can't do MSI like its predecessors. Disable MSI on RX790. Signed-off-by: Tejun Heo Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/pci/quirks.c | 1 + include/linux/pci_ids.h | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index ebfc1de7579..31f680f238c 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -1651,6 +1651,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT1 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS400_200, quirk_disable_all_msi); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS480, quirk_disable_all_msi); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RD580, quirk_disable_all_msi); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RX790, quirk_disable_all_msi); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS690, quirk_disable_all_msi); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VT3351, quirk_disable_all_msi); diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 80c27d7bf02..f77944e432f 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -361,6 +361,7 @@ #define PCI_DEVICE_ID_ATI_RS400_200 0x5a33 #define PCI_DEVICE_ID_ATI_RS480 0x5950 #define PCI_DEVICE_ID_ATI_RD580 0x5952 +#define PCI_DEVICE_ID_ATI_RX790 0x5957 #define PCI_DEVICE_ID_ATI_RS690 0x7910 /* ATI IXP Chipset */ #define PCI_DEVICE_ID_ATI_IXP200_IDE 0x4349 From 18166c1a50dc4f5b121ab2bd4fdf178404db9d99 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sun, 19 Aug 2007 12:03:07 +0200 Subject: [PATCH 10/10] PCI: Run k8t_sound_hostbridge quirk only when needed The k8t_sound_hostbridge PCI quick fires on my motherboard (Jetway K8M8MS) while it shouldn't: the on-board sound chip is not disabled and is working just fine. Looking at the code, I see that we are running the quirk for two distinct register values (0x88 and 0xc8) and then clear bit 6 (0x40). However value 0x88 already has bit 6 cleared so this is a no-op. This is what happens on my board. Thus I believe that the quirk should only be run for register value 0xc8. Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- drivers/pci/quirks.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 31f680f238c..2d40f437b9f 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -947,7 +947,7 @@ static void k8t_sound_hostbridge(struct pci_dev *dev) unsigned char val; pci_read_config_byte(dev, 0x50, &val); - if (val == 0x88 || val == 0xc8) { + if (val == 0xc8) { /* Assume it's probably a MSI-K8T-Neo2Fir */ printk(KERN_INFO "PCI: MSI-K8T-Neo2Fir, attempting to turn soundcard ON\n"); pci_write_config_byte(dev, 0x50, val & (~0x40));