2004-11-13 00:55:27

by Greg KH

[permalink] [raw]
Subject: [BK PATCH] PCI fixes for 2.6.10-rc1

Hi,

Here are some PCI patches for 2.6.10-rc1. They include:
- pci roms ysfs interface
- lots of some pci_find_device fixes
- other minor stuff.

Almost all of these patches lot of these have been in the past few -mm
releases.

Please pull from:
bk://kernel.bkbits.net/gregkh/linux/pci-2.6

thanks,

greg k-h

p.s. I'll send these as patches in response to this email to lkml for
those who want to see them.


arch/i386/pci/changelog | 62 -----
Documentation/kernel-parameters.txt | 12 +
arch/i386/kernel/acpi/boot.c | 10
arch/i386/kernel/quirks.c | 4
arch/i386/pci/acpi.c | 32 +-
arch/i386/pci/common.c | 4
arch/i386/pci/fixup.c | 129 ++++++++++
arch/i386/pci/irq.c | 41 ++-
arch/i386/pci/mmconfig.c | 5
arch/ia64/pci/pci.c | 66 ++++-
arch/ppc/platforms/chrp_pci.c | 2
arch/ppc/platforms/gemini_pci.c | 2
arch/ppc/platforms/k2.c | 3
arch/ppc/platforms/lopec.c | 3
arch/ppc/platforms/mcpn765.c | 7
arch/ppc/platforms/pcore.c | 3
arch/ppc/platforms/pmac_pci.c | 4
arch/ppc/platforms/pplus.c | 9
arch/ppc/platforms/prep_pci.c | 15 -
arch/ppc/platforms/prpmc750.c | 3
arch/ppc/platforms/sandpoint.c | 3
arch/sh/drivers/pci/fixups-dreamcast.c | 2
arch/sparc/kernel/ebus.c | 6
arch/sparc64/kernel/isa.c | 2
arch/sparc64/kernel/pci_iommu.c | 3
arch/v850/kernel/rte_mb_a_pci.c | 2
arch/x86_64/kernel/pci-gart.c | 2
arch/x86_64/pci/mmconfig.c | 3
drivers/atm/idt77252.c | 12 -
drivers/char/agp/sis-agp.c | 2
drivers/char/cyclades.c | 4
drivers/char/drm/drm_drv.h | 3
drivers/char/watchdog/scx200_wdt.c | 12 -
drivers/ide/ide.c | 14 +
drivers/isdn/tpam/tpam_main.c | 4
drivers/media/video/zr36120.c | 5
drivers/misc/ibmasm/module.c | 6
drivers/net/tulip/de4x5.c | 8
drivers/pci/Makefile | 8
drivers/pci/bus.c | 31 +-
drivers/pci/hotplug/acpiphp_glue.c | 4
drivers/pci/hotplug/cpcihp_generic.c | 18 -
drivers/pci/hotplug/fakephp.c | 128 ++++++++++
drivers/pci/hotplug/ibmphp_core.c | 10
drivers/pci/hotplug/pciehp.h | 21 +
drivers/pci/hotplug/pciehp_core.c | 18 -
drivers/pci/hotplug/pciehp_ctrl.c | 391 +++++++++++++++++++++------------
drivers/pci/hotplug/pciehp_hpc.c | 36 ++-
drivers/pci/hotplug/pciehp_pci.c | 8
drivers/pci/hotplug/pciehprm_acpi.c | 43 +++
drivers/pci/hotplug/shpchp_ctrl.c | 34 ++
drivers/pci/hotplug/shpchp_hpc.c | 1
drivers/pci/pci-acpi.c | 209 +++++++++++++++++
drivers/pci/pci-driver.c | 15 -
drivers/pci/pci-sysfs.c | 120 ++++++++++
drivers/pci/pci.c | 12 +
drivers/pci/pci.h | 6
drivers/pci/probe.c | 33 +-
drivers/pci/quirks.c | 19 +
drivers/pci/remove.c | 2
drivers/pci/rom.c | 225 ++++++++++++++++++
drivers/pci/setup-res.c | 2
drivers/video/matrox/matroxfb_base.c | 7
include/asm-generic/vmlinux.lds.h | 3
include/linux/ioport.h | 5
include/linux/pci-acpi.h | 61 +++++
include/linux/pci.h | 43 ++-
include/linux/pci_ids.h | 8
sound/pci/cmipci.c | 7
69 files changed, 1613 insertions(+), 424 deletions(-)
-----

<jdittmer:ppp0.net>:
o fakephp: add pci bus rescan ability
o fakephp: introduce pci_bus_add_device

<thockin:google.com>:
o PCI: small PCI probe patch for odd 64 bit BARs

Adrian Bunk:
o PCI: kill old PCI changelog

Bjorn Helgaas:
o PCI: remove unconditional PCI ACPI IRQ routing
o PCI: propagate pci_enable_device() errors
o acpi: better encapsulate eisa_set_level_irq()

Dely Sy:
o PCI: ASPM patch for
o PCI: Updated patch to fix adapter speed mismatch for 2.6 kernel
o PCI: Updated patch to add ExpressCard support

Greg Kroah-Hartman:
o PCI Hotplug: fix up remaining MODULE_PARAM usage in pci hotplug drivers
o PCI: remove kernel log message about drivers not calling pci_disable_device()
o PCI: use pci_dev_present() in irq.c check

Hanna V. Linder:
o prep_pci.c: replace pci_find_device with pci_get_device
o pplus.c: replace pci_find_device with pci_get_device
o pmac_pci.c: replace pci_find_device with pci_get_device
o pcore.c: replace pci_find_device with pci_get_device
o mcpn765.c: replace pci_find_device with pci_get_device
o prpmc750.c: replace pci_find_device with pci_get_device
o sandpoint.c: replace pci_find_device with pci_get_device
o fixups-dreamcast.c: replace pci_find_device with pci_get_device
o ebus.c: replace pci_find_device with pci_get_device
o isa.c: replace pci_find_device with pci_get_device
o pci_iommu.c: replace pci_find_device with pci_get_device
o ret_mb_a_pci.c: replace pci_find_device with pci_get_device
o pci-gart.c: replace pci_find_device with pci_get_device
o sis-agp.c: replace pci_find_device with pci_get_device
o drm_drv.h: replace pci_find_device
o cmipci.c: convert pci_find_device to pci_get_device
o k2.c: replace pci_find_device with pci_get_device
o lopec.c: replace pci_find_device with pci_get_device
o matroxfb_base.c: convert pci_find_device to pci_get_device
o gemini_pci.c: replace pci_find_device with for_each_pci_dev
o chrp_pci.c: replace pci_find_device with for_each_pci_dev
o ibmphp_core.c: replace pci_get_device with pci_dev_present
o scx200_wdt.c: replace pci_find_device with pci_dev_present
o ide.c: replace pci_find_device with pci_dev_present
o zr36120.c: Convert pci_find_device to pci_dev_present
o cyclades.c: replace pci_find_device
o PCI: Changed pci_find_device to pci_get_device

Ivan Kokshaysky:
o PCI: add pci_fixup_early

Jon Smirl:
o PCI: add PCI ROMs to sysfs

Kenji Kaneshige:
o PCI: add hook for PCI resource deallocation

Thomas Gleixner:
o Lock initializer unifying Batch 2 (PCI)

Tom L. Nguyen:
o PCI: pci-mmconfig fix


2004-11-12 23:28:49

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] PCI fixes for 2.6.10-rc1

ChangeSet 1.2026.66.16, 2004/11/05 15:06:26-08:00, [email protected]

[PATCH] PCI: add PCI ROMs to sysfs

Linus has requested that the sysfs rom attribute be changed to require
enabling before it works. echo "0" to the attribute to disable,
echoing anything else enables the rom output. The concern is that
something like a file browser could inadvertently read the attribute
and change the state of the hardware without the user's knowledge.

The attached patch includes the previous patch plus the enabling logic.

[root@smirl 0000:02:02.0]#
[root@smirl 0000:02:02.0]# cat rom
cat: rom: Invalid argument
[root@smirl 0000:02:02.0]# echo "1" >rom
[root@smirl 0000:02:02.0]# hexdump -C -n 20 rom
00000000 55 aa 60 e9 d6 01 00 00 00 00 00 00 00 00 00 00 |U.`.............|
00000010 00 00 00 00 |....|
00000014
[root@smirl 0000:02:02.0]# echo "0" >rom
[root@smirl 0000:02:02.0]# hexdump -C -n 20 rom
hexdump: rom: Invalid argument
[root@smirl 0000:02:02.0]#




Signed-off-by: Jon Smirl <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


arch/i386/pci/fixup.c | 38 ++++++++
drivers/pci/Makefile | 3
drivers/pci/pci-sysfs.c | 120 +++++++++++++++++++++++++
drivers/pci/pci.h | 4
drivers/pci/probe.c | 2
drivers/pci/remove.c | 2
drivers/pci/rom.c | 225 ++++++++++++++++++++++++++++++++++++++++++++++++
drivers/pci/setup-res.c | 2
include/linux/ioport.h | 5 +
include/linux/pci.h | 8 +
10 files changed, 404 insertions(+), 5 deletions(-)


diff -Nru a/arch/i386/pci/fixup.c b/arch/i386/pci/fixup.c
--- a/arch/i386/pci/fixup.c 2004-11-12 15:12:58 -08:00
+++ b/arch/i386/pci/fixup.c 2004-11-12 15:12:58 -08:00
@@ -346,3 +346,41 @@
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MCH_PC, pcie_rootport_aspm_quirk );
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MCH_PC1, pcie_rootport_aspm_quirk );

+/*
+ * Fixup to mark boot BIOS video selected by BIOS before it changes
+ *
+ * From information provided by "Jon Smirl" <[email protected]>
+ *
+ * The standard boot ROM sequence for an x86 machine uses the BIOS
+ * to select an initial video card for boot display. This boot video
+ * card will have it's BIOS copied to C0000 in system RAM.
+ * IORESOURCE_ROM_SHADOW is used to associate the boot video
+ * card with this copy. On laptops this copy has to be used since
+ * the main ROM may be compressed or combined with another image.
+ * See pci_map_rom() for use of this flag. IORESOURCE_ROM_SHADOW
+ * is marked here since the boot video device will be the only enabled
+ * video device at this point.
+ *
+ */static void __devinit pci_fixup_video(struct pci_dev *pdev)
+{
+ struct pci_dev *bridge;
+ struct pci_bus *bus;
+ u16 l;
+
+ if ((pdev->class >> 8) != PCI_CLASS_DISPLAY_VGA)
+ return;
+
+ /* Is VGA routed to us? */
+ bus = pdev->bus;
+ while (bus) {
+ bridge = bus->self;
+ if (bridge) {
+ pci_read_config_word(bridge, PCI_BRIDGE_CONTROL, &l);
+ if (!(l & PCI_BRIDGE_CTL_VGA))
+ return;
+ }
+ bus = bus->parent;
+ }
+ pdev->resource[PCI_ROM_RESOURCE].flags |= IORESOURCE_ROM_SHADOW;
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_video);
diff -Nru a/drivers/pci/Makefile b/drivers/pci/Makefile
--- a/drivers/pci/Makefile 2004-11-12 15:12:58 -08:00
+++ b/drivers/pci/Makefile 2004-11-12 15:12:58 -08:00
@@ -3,7 +3,8 @@
#

obj-y += access.o bus.o probe.o remove.o pci.o quirks.o \
- names.o pci-driver.o search.o pci-sysfs.o
+ names.o pci-driver.o search.o pci-sysfs.o \
+ rom.o
obj-$(CONFIG_PROC_FS) += proc.o

ifndef CONFIG_SPARC64
diff -Nru a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
--- a/drivers/pci/pci-sysfs.c 2004-11-12 15:12:58 -08:00
+++ b/drivers/pci/pci-sysfs.c 2004-11-12 15:12:58 -08:00
@@ -5,6 +5,8 @@
* (C) Copyright 2002-2004 IBM Corp.
* (C) Copyright 2003 Matthew Wilcox
* (C) Copyright 2003 Hewlett-Packard
+ * (C) Copyright 2004 Jon Smirl <[email protected]>
+ * (C) Copyright 2004 Silicon Graphics, Inc. Jesse Barnes <[email protected]>
*
* File attributes for PCI devices
*
@@ -20,6 +22,8 @@

#include "pci.h"

+static int sysfs_initialized; /* = 0 */
+
/* show configuration fields */
#define pci_config_attr(field, format_string) \
static ssize_t \
@@ -164,6 +168,65 @@
return count;
}

+/**
+ * pci_write_rom - used to enable access to the PCI ROM display
+ * @kobj: kernel object handle
+ * @buf: user input
+ * @off: file offset
+ * @count: number of byte in input
+ *
+ * writing anything except 0 enables it
+ */
+static ssize_t
+pci_write_rom(struct kobject *kobj, char *buf, loff_t off, size_t count)
+{
+ struct pci_dev *pdev = to_pci_dev(container_of(kobj, struct device, kobj));
+
+ if ((off == 0) && (*buf == '0') && (count == 2))
+ pdev->rom_attr_enabled = 0;
+ else
+ pdev->rom_attr_enabled = 1;
+
+ return count;
+}
+
+/**
+ * pci_read_rom - read a PCI ROM
+ * @kobj: kernel object handle
+ * @buf: where to put the data we read from the ROM
+ * @off: file offset
+ * @count: number of bytes to read
+ *
+ * Put @count bytes starting at @off into @buf from the ROM in the PCI
+ * device corresponding to @kobj.
+ */
+static ssize_t
+pci_read_rom(struct kobject *kobj, char *buf, loff_t off, size_t count)
+{
+ struct pci_dev *pdev = to_pci_dev(container_of(kobj, struct device, kobj));
+ void __iomem *rom;
+ size_t size;
+
+ if (!pdev->rom_attr_enabled)
+ return -EINVAL;
+
+ rom = pci_map_rom(pdev, &size); /* size starts out as PCI window size */
+ if (!rom)
+ return 0;
+
+ if (off >= size)
+ count = 0;
+ else {
+ if (off + count > size)
+ count = size - off;
+
+ memcpy_fromio(buf, rom + off, count);
+ }
+ pci_unmap_rom(pdev, rom);
+
+ return count;
+}
+
static struct bin_attribute pci_config_attr = {
.attr = {
.name = "config",
@@ -186,13 +249,68 @@
.write = pci_write_config,
};

-void pci_create_sysfs_dev_files (struct pci_dev *pdev)
+int pci_create_sysfs_dev_files (struct pci_dev *pdev)
{
+ if (!sysfs_initialized)
+ return -EACCES;
+
if (pdev->cfg_size < 4096)
sysfs_create_bin_file(&pdev->dev.kobj, &pci_config_attr);
else
sysfs_create_bin_file(&pdev->dev.kobj, &pcie_config_attr);

+ /* If the device has a ROM, try to expose it in sysfs. */
+ if (pci_resource_len(pdev, PCI_ROM_RESOURCE)) {
+ struct bin_attribute *rom_attr;
+
+ rom_attr = kmalloc(sizeof(*rom_attr), GFP_ATOMIC);
+ if (rom_attr) {
+ pdev->rom_attr = rom_attr;
+ rom_attr->size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
+ rom_attr->attr.name = "rom";
+ rom_attr->attr.mode = S_IRUSR;
+ rom_attr->attr.owner = THIS_MODULE;
+ rom_attr->read = pci_read_rom;
+ rom_attr->write = pci_write_rom;
+ sysfs_create_bin_file(&pdev->dev.kobj, rom_attr);
+ }
+ }
/* add platform-specific attributes */
pcibios_add_platform_entries(pdev);
+
+ return 0;
+}
+
+/**
+ * pci_remove_sysfs_dev_files - cleanup PCI specific sysfs files
+ * @pdev: device whose entries we should free
+ *
+ * Cleanup when @pdev is removed from sysfs.
+ */
+void pci_remove_sysfs_dev_files(struct pci_dev *pdev)
+{
+ if (pdev->cfg_size < 4096)
+ sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr);
+ else
+ sysfs_remove_bin_file(&pdev->dev.kobj, &pcie_config_attr);
+
+ if (pci_resource_len(pdev, PCI_ROM_RESOURCE)) {
+ if (pdev->rom_attr) {
+ sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_attr);
+ kfree(pdev->rom_attr);
+ }
+ }
}
+
+static int __init pci_sysfs_init(void)
+{
+ struct pci_dev *pdev = NULL;
+
+ sysfs_initialized = 1;
+ while ((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL)
+ pci_create_sysfs_dev_files(pdev);
+
+ return 0;
+}
+
+__initcall(pci_sysfs_init);
diff -Nru a/drivers/pci/pci.h b/drivers/pci/pci.h
--- a/drivers/pci/pci.h 2004-11-12 15:12:58 -08:00
+++ b/drivers/pci/pci.h 2004-11-12 15:12:58 -08:00
@@ -2,7 +2,9 @@

extern int pci_hotplug (struct device *dev, char **envp, int num_envp,
char *buffer, int buffer_size);
-extern void pci_create_sysfs_dev_files(struct pci_dev *pdev);
+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,
unsigned long size, unsigned long align,
unsigned long min, unsigned int type_mask,
diff -Nru a/drivers/pci/probe.c b/drivers/pci/probe.c
--- a/drivers/pci/probe.c 2004-11-12 15:12:58 -08:00
+++ b/drivers/pci/probe.c 2004-11-12 15:12:58 -08:00
@@ -170,7 +170,7 @@
if (sz && sz != 0xffffffff) {
sz = pci_size(l, sz, PCI_ROM_ADDRESS_MASK);
if (sz) {
- res->flags = (l & PCI_ROM_ADDRESS_ENABLE) |
+ res->flags = (l & IORESOURCE_ROM_ENABLE) |
IORESOURCE_MEM | IORESOURCE_PREFETCH |
IORESOURCE_READONLY | IORESOURCE_CACHEABLE;
res->start = l & PCI_ROM_ADDRESS_MASK;
diff -Nru a/drivers/pci/remove.c b/drivers/pci/remove.c
--- a/drivers/pci/remove.c 2004-11-12 15:12:58 -08:00
+++ b/drivers/pci/remove.c 2004-11-12 15:12:58 -08:00
@@ -16,6 +16,7 @@

msi_remove_pci_irq_vectors(dev);

+ pci_cleanup_rom(dev);
for (i = 0; i < PCI_NUM_RESOURCES; i++) {
struct resource *res = dev->resource + i;
if (res->parent)
@@ -26,6 +27,7 @@
static void pci_destroy_dev(struct pci_dev *dev)
{
pci_proc_detach_device(dev);
+ pci_remove_sysfs_dev_files(dev);
device_unregister(&dev->dev);

/* Remove the device from the device lists, and prevent any further
diff -Nru a/drivers/pci/rom.c b/drivers/pci/rom.c
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/drivers/pci/rom.c 2004-11-12 15:12:58 -08:00
@@ -0,0 +1,225 @@
+/*
+ * drivers/pci/rom.c
+ *
+ * (C) Copyright 2004 Jon Smirl <[email protected]>
+ * (C) Copyright 2004 Silicon Graphics, Inc. Jesse Barnes <[email protected]>
+ *
+ * PCI ROM access routines
+ *
+ */
+
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+
+#include "pci.h"
+
+/**
+ * pci_enable_rom - enable ROM decoding for a PCI device
+ * @dev: PCI device to enable
+ *
+ * Enable ROM decoding on @dev. This involves simply turning on the last
+ * bit of the PCI ROM BAR. Note that some cards may share address decoders
+ * between the ROM and other resources, so enabling it may disable access
+ * to MMIO registers or other card memory.
+ */
+static void
+pci_enable_rom(struct pci_dev *pdev)
+{
+ u32 rom_addr;
+
+ pci_read_config_dword(pdev, pdev->rom_base_reg, &rom_addr);
+ rom_addr |= PCI_ROM_ADDRESS_ENABLE;
+ pci_write_config_dword(pdev, pdev->rom_base_reg, rom_addr);
+}
+
+/**
+ * pci_disable_rom - disable ROM decoding for a PCI device
+ * @dev: PCI device to disable
+ *
+ * Disable ROM decoding on a PCI device by turning off the last bit in the
+ * ROM BAR.
+ */
+static void
+pci_disable_rom(struct pci_dev *pdev)
+{
+ u32 rom_addr;
+ pci_read_config_dword(pdev, pdev->rom_base_reg, &rom_addr);
+ rom_addr &= ~PCI_ROM_ADDRESS_ENABLE;
+ pci_write_config_dword(pdev, pdev->rom_base_reg, rom_addr);
+}
+
+/**
+ * pci_map_rom - map a PCI ROM to kernel space
+ * @dev: pointer to pci device struct
+ * @size: pointer to receive size of pci window over ROM
+ * @return: kernel virtual pointer to image of ROM
+ *
+ * Map a PCI ROM into kernel space. If ROM is boot video ROM,
+ * the shadow BIOS copy will be returned instead of the
+ * actual ROM.
+ */
+void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size)
+{
+ struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
+ loff_t start;
+ void __iomem *rom;
+ void __iomem *image;
+ int last_image;
+
+ if (res->flags & IORESOURCE_ROM_SHADOW) { /* IORESOURCE_ROM_SHADOW only set on x86 */
+ start = (loff_t)0xC0000; /* primary video rom always starts here */
+ *size = 0x20000; /* cover C000:0 through E000:0 */
+ } else {
+ if (res->flags & IORESOURCE_ROM_COPY) {
+ *size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
+ return (void __iomem *)pci_resource_start(pdev, PCI_ROM_RESOURCE);
+ } else {
+ /* assign the ROM an address if it doesn't have one */
+ if (res->parent == NULL)
+ pci_assign_resource(pdev, PCI_ROM_RESOURCE);
+
+ start = pci_resource_start(pdev, PCI_ROM_RESOURCE);
+ *size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
+ if (*size == 0)
+ return NULL;
+
+ /* Enable ROM space decodes */
+ pci_enable_rom(pdev);
+ }
+ }
+
+ rom = ioremap(start, *size);
+ if (!rom) {
+ /* restore enable if ioremap fails */
+ if (!(res->flags & (IORESOURCE_ROM_ENABLE | IORESOURCE_ROM_SHADOW | IORESOURCE_ROM_COPY)))
+ pci_disable_rom(pdev);
+ return NULL;
+ }
+
+ /* Try to find the true size of the ROM since sometimes the PCI window */
+ /* size is much larger than the actual size of the ROM. */
+ /* True size is important if the ROM is going to be copied. */
+ image = rom;
+ do {
+ void __iomem *pds;
+ /* Standard PCI ROMs start out with these bytes 55 AA */
+ if (readb(image) != 0x55)
+ break;
+ if (readb(image + 1) != 0xAA)
+ break;
+ /* get the PCI data structure and check its signature */
+ pds = image + readw(image + 24);
+ if (readb(pds) != 'P')
+ break;
+ if (readb(pds + 1) != 'C')
+ break;
+ if (readb(pds + 2) != 'I')
+ break;
+ if (readb(pds + 3) != 'R')
+ break;
+ last_image = readb(pds + 21) & 0x80;
+ /* this length is reliable */
+ image += readw(pds + 16) * 512;
+ } while (!last_image);
+
+ *size = image - rom;
+
+ return rom;
+}
+
+/**
+ * pci_map_rom_copy - map a PCI ROM to kernel space, create a copy
+ * @dev: pointer to pci device struct
+ * @size: pointer to receive size of pci window over ROM
+ * @return: kernel virtual pointer to image of ROM
+ *
+ * Map a PCI ROM into kernel space. If ROM is boot video ROM,
+ * the shadow BIOS copy will be returned instead of the
+ * actual ROM.
+ */
+void __iomem *pci_map_rom_copy(struct pci_dev *pdev, size_t *size)
+{
+ struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
+ void __iomem *rom;
+
+ rom = pci_map_rom(pdev, size);
+ if (!rom)
+ return NULL;
+
+ if (res->flags & (IORESOURCE_ROM_COPY | IORESOURCE_ROM_SHADOW))
+ return rom;
+
+ res->start = (unsigned long)kmalloc(*size, GFP_KERNEL);
+ if (!res->start)
+ return rom;
+
+ res->end = res->start + *size;
+ memcpy_fromio((void*)res->start, rom, *size);
+ pci_unmap_rom(pdev, rom);
+ res->flags |= IORESOURCE_ROM_COPY;
+
+ return (void __iomem *)res->start;
+}
+
+/**
+ * pci_unmap_rom - unmap the ROM from kernel space
+ * @dev: pointer to pci device struct
+ * @rom: virtual address of the previous mapping
+ *
+ * Remove a mapping of a previously mapped ROM
+ */
+void
+pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom)
+{
+ struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
+
+ if (res->flags & IORESOURCE_ROM_COPY)
+ return;
+
+ iounmap(rom);
+
+ /* Disable again before continuing, leave enabled if pci=rom */
+ if (!(res->flags & (IORESOURCE_ROM_ENABLE | IORESOURCE_ROM_SHADOW)))
+ pci_disable_rom(pdev);
+}
+
+/**
+ * pci_remove_rom - disable the ROM and remove its sysfs attribute
+ * @dev: pointer to pci device struct
+ *
+ */
+void
+pci_remove_rom(struct pci_dev *pdev)
+{
+ struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
+
+ if (pci_resource_len(pdev, PCI_ROM_RESOURCE))
+ sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_attr);
+ if (!(res->flags & (IORESOURCE_ROM_ENABLE | IORESOURCE_ROM_SHADOW | IORESOURCE_ROM_COPY)))
+ pci_disable_rom(pdev);
+}
+
+/**
+ * pci_cleanup_rom - internal routine for freeing the ROM copy created
+ * by pci_map_rom_copy called from remove.c
+ * @dev: pointer to pci device struct
+ *
+ */
+void
+pci_cleanup_rom(struct pci_dev *pdev)
+{
+ struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
+ if (res->flags & IORESOURCE_ROM_COPY) {
+ kfree((void*)res->start);
+ res->flags &= ~IORESOURCE_ROM_COPY;
+ res->start = 0;
+ res->end = 0;
+ }
+}
+
+EXPORT_SYMBOL(pci_map_rom);
+EXPORT_SYMBOL(pci_map_rom_copy);
+EXPORT_SYMBOL(pci_unmap_rom);
+EXPORT_SYMBOL(pci_remove_rom);
diff -Nru a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c
--- a/drivers/pci/setup-res.c 2004-11-12 15:12:58 -08:00
+++ b/drivers/pci/setup-res.c 2004-11-12 15:12:58 -08:00
@@ -56,7 +56,7 @@
if (resno < 6) {
reg = PCI_BASE_ADDRESS_0 + 4 * resno;
} else if (resno == PCI_ROM_RESOURCE) {
- new |= res->flags & PCI_ROM_ADDRESS_ENABLE;
+ new |= res->flags & IORESOURCE_ROM_ENABLE;
reg = dev->rom_base_reg;
} else {
/* Hmm, non-standard resource. */
diff -Nru a/include/linux/ioport.h b/include/linux/ioport.h
--- a/include/linux/ioport.h 2004-11-12 15:12:58 -08:00
+++ b/include/linux/ioport.h 2004-11-12 15:12:58 -08:00
@@ -82,6 +82,11 @@
#define IORESOURCE_MEM_SHADOWABLE (1<<5) /* dup: IORESOURCE_SHADOWABLE */
#define IORESOURCE_MEM_EXPANSIONROM (1<<6)

+/* PCI ROM control bits (IORESOURCE_BITS) */
+#define IORESOURCE_ROM_ENABLE (1<<0) /* ROM is enabled, same as PCI_ROM_ADDRESS_ENABLE */
+#define IORESOURCE_ROM_SHADOW (1<<1) /* ROM is copy at C000:0 */
+#define IORESOURCE_ROM_COPY (1<<2) /* ROM is alloc'd copy, resource field overlaid */
+
/* PC/ISA/whatever - the normal PC address spaces: IO and memory */
extern struct resource ioport_resource;
extern struct resource iomem_resource;
diff -Nru a/include/linux/pci.h b/include/linux/pci.h
--- a/include/linux/pci.h 2004-11-12 15:12:58 -08:00
+++ b/include/linux/pci.h 2004-11-12 15:12:58 -08:00
@@ -537,6 +537,8 @@
unsigned int is_busmaster:1; /* device is busmaster */

u32 saved_config_space[16]; /* config space saved at suspend time */
+ struct bin_attribute *rom_attr; /* attribute descriptor for sysfs ROM entry */
+ int rom_attr_enabled; /* has display of the rom attribute been enabled? */
#ifdef CONFIG_PCI_NAMES
#define PCI_NAME_SIZE 96
#define PCI_NAME_HALF __stringify(43) /* less than half to handle slop */
@@ -784,6 +786,12 @@
int pci_dac_set_dma_mask(struct pci_dev *dev, u64 mask);
int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask);
int pci_assign_resource(struct pci_dev *dev, int i);
+
+/* ROM control related routines */
+void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size);
+void __iomem *pci_map_rom_copy(struct pci_dev *pdev, size_t *size);
+void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom);
+void pci_remove_rom(struct pci_dev *pdev);

/* Power management related routines */
int pci_save_state(struct pci_dev *dev);

2004-11-12 23:25:56

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] PCI fixes for 2.6.10-rc1

ChangeSet 1.2091.1.5, 2004/11/12 14:01:55-08:00, [email protected]

[PATCH] chrp_pci.c: replace pci_find_device with for_each_pci_dev

Signed-off-by: Hanna Linder <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


arch/ppc/platforms/chrp_pci.c | 2 +-
1 files changed, 1 insertion(+), 1 deletion(-)


diff -Nru a/arch/ppc/platforms/chrp_pci.c b/arch/ppc/platforms/chrp_pci.c
--- a/arch/ppc/platforms/chrp_pci.c 2004-11-12 15:11:26 -08:00
+++ b/arch/ppc/platforms/chrp_pci.c 2004-11-12 15:11:26 -08:00
@@ -158,7 +158,7 @@
struct device_node *np;

/* PCI interrupts are controlled by the OpenPIC */
- while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
+ for_each_pci_dev(dev) {
np = pci_device_to_OF_node(dev);
if ((np != 0) && (np->n_intrs > 0) && (np->intrs[0].line != 0))
dev->irq = np->intrs[0].line;

2004-11-12 23:25:59

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] PCI fixes for 2.6.10-rc1

ChangeSet 1.2026.66.13, 2004/11/05 15:05:24-08:00, [email protected]

[PATCH] PCI: add pci_fixup_early

Port Ivan's early PCI fixups patch to 2.6.10-rc1. Also fix some indentation
to make it less than 80 columns.

From: Ivan Kokshaysky <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


drivers/pci/probe.c | 3 +++
include/asm-generic/vmlinux.lds.h | 3 +++
include/linux/pci.h | 34 ++++++++++++++++++----------------
3 files changed, 24 insertions(+), 16 deletions(-)


diff -Nru a/drivers/pci/probe.c b/drivers/pci/probe.c
--- a/drivers/pci/probe.c 2004-11-12 15:13:20 -08:00
+++ b/drivers/pci/probe.c 2004-11-12 15:13:20 -08:00
@@ -478,6 +478,9 @@
/* "Unknown power state" */
dev->current_state = 4;

+ /* Early fixups, before probing the BARs */
+ pci_fixup_device(pci_fixup_early, dev);
+
switch (dev->hdr_type) { /* header type */
case PCI_HEADER_TYPE_NORMAL: /* standard header */
if (class == PCI_CLASS_BRIDGE_PCI)
diff -Nru a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
--- a/include/asm-generic/vmlinux.lds.h 2004-11-12 15:13:20 -08:00
+++ b/include/asm-generic/vmlinux.lds.h 2004-11-12 15:13:20 -08:00
@@ -18,6 +18,9 @@
\
/* PCI quirks */ \
.pci_fixup : AT(ADDR(.pci_fixup) - LOAD_OFFSET) { \
+ VMLINUX_SYMBOL(__start_pci_fixups_early) = .; \
+ *(.pci_fixup_early) \
+ VMLINUX_SYMBOL(__end_pci_fixups_early) = .; \
VMLINUX_SYMBOL(__start_pci_fixups_header) = .; \
*(.pci_fixup_header) \
VMLINUX_SYMBOL(__end_pci_fixups_header) = .; \
diff -Nru a/include/linux/pci.h b/include/linux/pci.h
--- a/include/linux/pci.h 2004-11-12 15:13:20 -08:00
+++ b/include/linux/pci.h 2004-11-12 15:13:20 -08:00
@@ -989,31 +989,33 @@
*/

struct pci_fixup {
- u16 vendor, device; /* You can use PCI_ANY_ID here of course */
+ u16 vendor, device; /* You can use PCI_ANY_ID here of course */
void (*hook)(struct pci_dev *dev);
};

enum pci_fixup_pass {
- pci_fixup_header, /* Called immediately after reading configuration header */
+ pci_fixup_early, /* Before probing BARs */
+ pci_fixup_header, /* After reading configuration header */
pci_fixup_final, /* Final phase of device fixups */
pci_fixup_enable, /* pci_enable_device() time */
};

/* Anonymous variables would be nice... */
-#define DECLARE_PCI_FIXUP_HEADER(vendor, device, hook) \
- static struct pci_fixup __pci_fixup_##vendor##device##hook __attribute_used__ \
- __attribute__((__section__(".pci_fixup_header"))) = { \
- vendor, device, hook };
-
-#define DECLARE_PCI_FIXUP_FINAL(vendor, device, hook) \
- static struct pci_fixup __pci_fixup_##vendor##device##hook __attribute_used__ \
- __attribute__((__section__(".pci_fixup_final"))) = { \
- vendor, device, hook };
-
-#define DECLARE_PCI_FIXUP_ENABLE(vendor, device, hook) \
- static struct pci_fixup __pci_fixup_##vendor##device##hook __attribute_used__ \
- __attribute__((__section__(".pci_fixup_enable"))) = { \
- vendor, device, hook };
+#define DECLARE_PCI_FIXUP_SECTION(section, name, vendor, device, hook) \
+ static struct pci_fixup __pci_fixup_##name __attribute_used__ \
+ __attribute__((__section__(#section))) = { vendor, device, hook };
+#define DECLARE_PCI_FIXUP_EARLY(vendor, device, hook) \
+ DECLARE_PCI_FIXUP_SECTION(.pci_fixup_early, \
+ vendor##device##hook, vendor, device, hook)
+#define DECLARE_PCI_FIXUP_HEADER(vendor, device, hook) \
+ DECLARE_PCI_FIXUP_SECTION(.pci_fixup_header, \
+ vendor##device##hook, vendor, device, hook)
+#define DECLARE_PCI_FIXUP_FINAL(vendor, device, hook) \
+ DECLARE_PCI_FIXUP_SECTION(.pci_fixup_final, \
+ vendor##device##hook, vendor, device, hook)
+#define DECLARE_PCI_FIXUP_ENABLE(vendor, device, hook) \
+ DECLARE_PCI_FIXUP_SECTION(.pci_fixup_enable, \
+ vendor##device##hook, vendor, device, hook)


void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev);

2004-11-12 23:35:18

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] PCI fixes for 2.6.10-rc1

ChangeSet 1.2026.66.19, 2004/11/10 16:44:13-08:00, [email protected]

[PATCH] zr36120.c: Convert pci_find_device to pci_dev_present

--On Thursday, September 30, 2004 10:27:48 AM +0200 Gerd Knorr <[email protected]> wrote:
>> The whole driver is CONFIG_BROKEN anyway... I only verified my changes
>> didn't add new compiler errors. What part should I remove? Just this check?
>
> pci/quirks.c does these checks and sets the flags.
> Replacing with a check for "pci_pci_problems & PCIPCI_TRITON" should do.
>
> bttv does simliar things in bttv_check_chipset() (bttv-cards.c),
> you might want to have a look there ...
>

Thanks a lot for your help. Is this what you were thinking?

Signed-off-by: Hanna Linder <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


drivers/media/video/zr36120.c | 5 +----
1 files changed, 1 insertion(+), 4 deletions(-)


diff -Nru a/drivers/media/video/zr36120.c b/drivers/media/video/zr36120.c
--- a/drivers/media/video/zr36120.c 2004-11-12 15:12:34 -08:00
+++ b/drivers/media/video/zr36120.c 2004-11-12 15:12:34 -08:00
@@ -145,14 +145,11 @@
static
void __init handle_chipset(void)
{
- struct pci_dev *dev = NULL;
-
/* Just in case some nut set this to something dangerous */
if (triton1)
triton1 = ZORAN_VDC_TRICOM;

- while ((dev = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82437, dev)))
- {
+ if (pci_pci_problems & PCIPCI_TRITON) {
printk(KERN_INFO "zoran: Host bridge 82437FX Triton PIIX\n");
triton1 = ZORAN_VDC_TRICOM;
}

2004-11-12 23:35:16

by Greg KH

[permalink] [raw]
Subject: [PATCH] PCI fixes for 2.6.10-rc1

ChangeSet 1.2000.10.1, 2004/10/20 15:35:44-07:00, [email protected]

PCI: use pci_dev_present() in irq.c check

Signed-off-by: Greg Kroah-Hartman <[email protected]>


arch/i386/pci/irq.c | 16 ++++++----------
1 files changed, 6 insertions(+), 10 deletions(-)


diff -Nru a/arch/i386/pci/irq.c b/arch/i386/pci/irq.c
--- a/arch/i386/pci/irq.c 2004-11-12 15:14:50 -08:00
+++ b/arch/i386/pci/irq.c 2004-11-12 15:14:50 -08:00
@@ -452,21 +452,17 @@

#endif

-
static __init int intel_router_probe(struct irq_router *r, struct pci_dev *router, u16 device)
{
- struct pci_dev *dev1, *dev2;
+ static struct pci_device_id pirq_440gx[] = {
+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_0) },
+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_2) },
+ { },
+ };

/* 440GX has a proprietary PIRQ router -- don't use it */
- dev1 = pci_get_device(PCI_VENDOR_ID_INTEL,
- PCI_DEVICE_ID_INTEL_82443GX_0, NULL);
- dev2 = pci_get_device(PCI_VENDOR_ID_INTEL,
- PCI_DEVICE_ID_INTEL_82443GX_2, NULL);
- if ((dev1 != NULL) || (dev2 != NULL)) {
- pci_dev_put(dev1);
- pci_dev_put(dev2);
+ if (pci_dev_present(pirq_440gx))
return 0;
- }

switch(device)
{

2004-11-12 23:31:55

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] PCI fixes for 2.6.10-rc1

ChangeSet 1.2026.55.3, 2004/11/01 15:02:37-08:00, [email protected]

[PATCH] PCI: Updated patch to fix adapter speed mismatch for 2.6 kernel

After doing more testing, I found that I couldn't use quirk to set the flag
to identify the chipset, for there are platforms that have other bridge
chip with PCI-X hotpluggable slots in the same system. Therefore, I use
the vendor id and device id to identify the bridge chip that needs the
workaround. The code doing the workaround remains unchanged.


Signed-off-by: Dely Sy <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


drivers/pci/hotplug/shpchp_ctrl.c | 34 ++++++++++++++++++++++++++++++++++
1 files changed, 34 insertions(+)


diff -Nru a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c
--- a/drivers/pci/hotplug/shpchp_ctrl.c 2004-11-12 15:13:50 -08:00
+++ b/drivers/pci/hotplug/shpchp_ctrl.c 2004-11-12 15:13:50 -08:00
@@ -1157,6 +1157,40 @@
return -1;
}

+
+ if ((ctrl->pci_dev->vendor == 0x8086) && (ctrl->pci_dev->device == 0x0332)) {
+ if (slots_not_empty)
+ return WRONG_BUS_FREQUENCY;
+
+ if ((rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, PCI_SPEED_33MHz))) {
+ err("%s: Issue of set bus speed mode command failed\n", __FUNCTION__);
+ up(&ctrl->crit_sect);
+ return WRONG_BUS_FREQUENCY;
+ }
+ wait_for_ctrl_irq (ctrl);
+
+ if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) {
+ err("%s: Can't set bus speed/mode in the case of adapter & bus mismatch\n",
+ __FUNCTION__);
+ err("%s: Error code (%d)\n", __FUNCTION__, rc);
+ up(&ctrl->crit_sect);
+ return WRONG_BUS_FREQUENCY;
+ }
+ /* turn on board, blink green LED, turn off Amber LED */
+ if ((rc = p_slot->hpc_ops->slot_enable(p_slot))) {
+ err("%s: Issue of Slot Enable command failed\n", __FUNCTION__);
+ up(&ctrl->crit_sect);
+ return rc;
+ }
+ wait_for_ctrl_irq (ctrl);
+
+ if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) {
+ err("%s: Failed to enable slot, error code(%d)\n", __FUNCTION__, rc);
+ up(&ctrl->crit_sect);
+ return rc;
+ }
+ }
+
rc = p_slot->hpc_ops->get_adapter_speed(p_slot, &adapter_speed);
/* 0 = PCI 33Mhz, 1 = PCI 66 Mhz, 2 = PCI-X 66 PA, 4 = PCI-X 66 ECC, */
/* 5 = PCI-X 133 PA, 7 = PCI-X 133 ECC, 0xa = PCI-X 133 Mhz 266, */

2004-11-12 23:44:45

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] PCI fixes for 2.6.10-rc1

ChangeSet 1.2091.1.16, 2004/11/12 14:09:21-08:00, [email protected]

[PATCH] isa.c: replace pci_find_device with pci_get_device

As pci_find_device is going away I've replaced it with pci_get_device.

Signed-off-by: Hanna Linder <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


arch/sparc64/kernel/isa.c | 2 +-
1 files changed, 1 insertion(+), 1 deletion(-)


diff -Nru a/arch/sparc64/kernel/isa.c b/arch/sparc64/kernel/isa.c
--- a/arch/sparc64/kernel/isa.c 2004-11-12 15:10:04 -08:00
+++ b/arch/sparc64/kernel/isa.c 2004-11-12 15:10:04 -08:00
@@ -262,7 +262,7 @@
device = PCI_DEVICE_ID_AL_M1533;

pdev = NULL;
- while ((pdev = pci_find_device(vendor, device, pdev)) != NULL) {
+ while ((pdev = pci_get_device(vendor, device, pdev)) != NULL) {
struct pcidev_cookie *pdev_cookie;
struct pci_pbm_info *pbm;
struct sparc_isa_bridge *isa_br;

2004-11-12 23:44:48

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] PCI fixes for 2.6.10-rc1

ChangeSet 1.2091.1.25, 2004/11/12 14:12:34-08:00, [email protected]

[PATCH] prep_pci.c: replace pci_find_device with pci_get_device

Signed-off-by: Hanna Linder <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


arch/ppc/platforms/prep_pci.c | 15 +++++++++------
1 files changed, 9 insertions(+), 6 deletions(-)


diff -Nru a/arch/ppc/platforms/prep_pci.c b/arch/ppc/platforms/prep_pci.c
--- a/arch/ppc/platforms/prep_pci.c 2004-11-12 15:08:57 -08:00
+++ b/arch/ppc/platforms/prep_pci.c 2004-11-12 15:08:57 -08:00
@@ -1069,7 +1069,7 @@
* Perform specific configuration for the Via Tech or
* or Winbond PCI-ISA-Bridge part.
*/
- if ((dev = pci_find_device(PCI_VENDOR_ID_VIA,
+ if ((dev = pci_get_device(PCI_VENDOR_ID_VIA,
PCI_DEVICE_ID_VIA_82C586_1, dev))) {
/*
* PPCBUG does not set the enable bits
@@ -1080,7 +1080,7 @@
reg |= 0x03; /* IDE: Chip Enable Bits */
pci_write_config_byte(dev, 0x40, reg);
}
- if ((dev = pci_find_device(PCI_VENDOR_ID_VIA,
+ if ((dev = pci_get_device(PCI_VENDOR_ID_VIA,
PCI_DEVICE_ID_VIA_82C586_2,
dev)) && (dev->devfn = 0x5a)) {
/* Force correct USB interrupt */
@@ -1089,7 +1089,7 @@
PCI_INTERRUPT_LINE,
dev->irq);
}
- if ((dev = pci_find_device(PCI_VENDOR_ID_WINBOND,
+ if ((dev = pci_get_device(PCI_VENDOR_ID_WINBOND,
PCI_DEVICE_ID_WINBOND_83C553, dev))) {
/* Clear PCI Interrupt Routing Control Register. */
short_reg = 0x0000;
@@ -1100,9 +1100,10 @@
pci_write_config_byte(dev, 0x43, reg);
}
}
+ pci_dev_put(dev);
}

- if ((dev = pci_find_device(PCI_VENDOR_ID_WINBOND,
+ if ((dev = pci_get_device(PCI_VENDOR_ID_WINBOND,
PCI_DEVICE_ID_WINBOND_82C105, dev))){
if (OpenPIC_Addr){
/*
@@ -1121,6 +1122,7 @@
pci_write_config_dword(dev, 0x40, 0x10ff08a1);
}
}
+ pci_dev_put(dev);
}

static void __init
@@ -1207,7 +1209,7 @@
printk("Setting PCI interrupts for a \"%s\"\n", Motherboard_map_name);

/* Iterate through all the PCI devices, setting the IRQ */
- while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
+ for_each_pci_dev(dev) {
/*
* If we have residual data, then this is easy: query the
* residual data for the IRQ line allocated to the device.
@@ -1260,12 +1262,13 @@
* instead of 0xc0000. vgacon.c (for example) is completely unaware of
* this little quirk.
*/
- dev = pci_find_device(PCI_VENDOR_ID_WD, PCI_DEVICE_ID_WD_90C, NULL);
+ dev = pci_get_device(PCI_VENDOR_ID_WD, PCI_DEVICE_ID_WD_90C, NULL);
if (dev) {
dev->resource[1].end -= dev->resource[1].start;
dev->resource[1].start = 0;
/* tell the hardware */
pci_write_config_dword(dev, PCI_BASE_ADDRESS_1, 0x0);
+ pci_dev_put(dev);
}
#endif
}

2004-11-13 00:55:28

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] PCI fixes for 2.6.10-rc1

ChangeSet 1.2026.35.5, 2004/10/28 16:25:06-05:00, [email protected]

[PATCH] PCI: add hook for PCI resource deallocation

From: Kenji Kaneshige <[email protected]>

This patch adds a hook 'pcibios_disable_device()' into pci_disable_device()
to call architecture specific PCI resource deallocation code. It's a
opposite part of pcibios_enable_device(). We need this hook to deallocate
architecture specific PCI resource such as IRQ resource, etc.. This patch
is just for adding the hook, so 'pcibios_disable_device()' is defined as a
null function on all architecture so far.

I tested this patch on i386, x86_64 and ia64. But it has not been tested
on other architectures because I don't have these machines.

Signed-off-by: Kenji Kaneshige <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


drivers/pci/pci.c | 12 ++++++++++++
1 files changed, 12 insertions(+)


diff -Nru a/drivers/pci/pci.c b/drivers/pci/pci.c
--- a/drivers/pci/pci.c 2004-11-12 15:14:21 -08:00
+++ b/drivers/pci/pci.c 2004-11-12 15:14:21 -08:00
@@ -375,6 +375,16 @@
}

/**
+ * pcibios_disable_device - disable arch specific PCI resources for device dev
+ * @dev: the PCI device to disable
+ *
+ * Disables architecture specific PCI resources for the device. This
+ * is the default implementation. Architecture implementations can
+ * override this.
+ */
+void __attribute__ ((weak)) pcibios_disable_device (struct pci_dev *dev) {}
+
+/**
* pci_disable_device - Disable PCI device after use
* @dev: PCI device to be disabled
*
@@ -394,6 +404,8 @@
pci_command &= ~PCI_COMMAND_MASTER;
pci_write_config_word(dev, PCI_COMMAND, pci_command);
}
+
+ pcibios_disable_device(dev);
}

/**

2004-11-13 00:55:26

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] PCI fixes for 2.6.10-rc1

ChangeSet 1.2091.1.20, 2004/11/12 14:10:46-08:00, [email protected]

[PATCH] prpmc750.c: replace pci_find_device with pci_get_device

As pci_find_device is going away I've replaced it with pci_get_device.


Signed-off-by: Hanna Linder <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


arch/ppc/platforms/prpmc750.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletion(-)


diff -Nru a/arch/ppc/platforms/prpmc750.c b/arch/ppc/platforms/prpmc750.c
--- a/arch/ppc/platforms/prpmc750.c 2004-11-12 15:09:34 -08:00
+++ b/arch/ppc/platforms/prpmc750.c 2004-11-12 15:09:34 -08:00
@@ -109,7 +109,7 @@
* resource subsystem doesn't fixup the
* PCI mem resources on the CL5446.
*/
- if ((dev = pci_find_device(PCI_VENDOR_ID_CIRRUS,
+ if ((dev = pci_get_device(PCI_VENDOR_ID_CIRRUS,
PCI_DEVICE_ID_CIRRUS_5446, 0))) {
dev->resource[0].start += PRPMC750_PCI_PHY_MEM_OFFSET;
dev->resource[0].end += PRPMC750_PCI_PHY_MEM_OFFSET;
@@ -121,6 +121,7 @@
outb(0x0f, 0x3c4);
/* Set proper DRAM config */
outb(0xdf, 0x3c5);
+ pci_dev_put(dev);
}
}


2004-11-13 00:55:26

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] PCI fixes for 2.6.10-rc1

ChangeSet 1.2091.1.9, 2004/11/12 14:06:23-08:00, [email protected]

[PATCH] k2.c: replace pci_find_device with pci_get_device

As pci_find_device is going away I have replaced this call with
pci_get_device.

Signed-off-by: Hanna Linder <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


arch/ppc/platforms/k2.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletion(-)


diff -Nru a/arch/ppc/platforms/k2.c b/arch/ppc/platforms/k2.c
--- a/arch/ppc/platforms/k2.c 2004-11-12 15:10:57 -08:00
+++ b/arch/ppc/platforms/k2.c 2004-11-12 15:10:57 -08:00
@@ -116,7 +116,7 @@
/*
* Enable DMA support on hdc
*/
- ide_dev = pci_find_device(PCI_VENDOR_ID_AL,
+ ide_dev = pci_get_device(PCI_VENDOR_ID_AL,
PCI_DEVICE_ID_AL_M5229, NULL);

if (ide_dev) {
@@ -126,6 +126,7 @@
ide_dma_base = pci_resource_start(ide_dev, 4);
outb(0x00, ide_dma_base + 0x2);
outb(0x20, ide_dma_base + 0xa);
+ pci_dev_put(ide_dev);
}
#endif
}

2004-11-13 00:55:24

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] PCI fixes for 2.6.10-rc1

ChangeSet 1.2091.1.18, 2004/11/12 14:10:03-08:00, [email protected]

[PATCH] fixups-dreamcast.c: replace pci_find_device with pci_get_device

As pci_find_device is going away I've replaced it with pci_get_device
and pci_dev_put.


Signed-off-by: Hanna Linder <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


arch/sh/drivers/pci/fixups-dreamcast.c | 2 +-
1 files changed, 1 insertion(+), 1 deletion(-)


diff -Nru a/arch/sh/drivers/pci/fixups-dreamcast.c b/arch/sh/drivers/pci/fixups-dreamcast.c
--- a/arch/sh/drivers/pci/fixups-dreamcast.c 2004-11-12 15:09:49 -08:00
+++ b/arch/sh/drivers/pci/fixups-dreamcast.c 2004-11-12 15:09:49 -08:00
@@ -62,7 +62,7 @@
{
struct pci_dev *dev = 0;

- while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
+ for_each_pci_dev(dev) {
/*
* The interrupt routing semantics here are quite trivial.
*

2004-11-12 23:44:47

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] PCI fixes for 2.6.10-rc1

ChangeSet 1.2091.1.10, 2004/11/12 14:07:13-08:00, [email protected]

[PATCH] cmipci.c: convert pci_find_device to pci_get_device

As pci_find_device is going away I've replaced it with pci_get_device.


Signed-off-by: Hanna Linder <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


sound/pci/cmipci.c | 7 +++++--
1 files changed, 5 insertions(+), 2 deletions(-)


diff -Nru a/sound/pci/cmipci.c b/sound/pci/cmipci.c
--- a/sound/pci/cmipci.c 2004-11-12 15:10:49 -08:00
+++ b/sound/pci/cmipci.c 2004-11-12 15:10:49 -08:00
@@ -2572,6 +2572,10 @@
long iomidi = mpu_port[dev];
long iosynth = fm_port[dev];
int pcm_index, pcm_spdif_index;
+ static struct pci_device_id intel_82437vx[] = {
+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82437VX) },
+ { },
+ };

*rcmipci = NULL;

@@ -2647,8 +2651,7 @@
switch (pci->device) {
case PCI_DEVICE_ID_CMEDIA_CM8738:
case PCI_DEVICE_ID_CMEDIA_CM8738B:
- /* PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82437VX */
- if (! pci_find_device(0x8086, 0x7030, NULL))
+ if (!pci_dev_present(intel_82437vx))
snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_TXVX);
break;
default:

2004-11-12 23:44:47

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] PCI fixes for 2.6.10-rc1

ChangeSet 1.2091.1.2, 2004/11/11 16:32:25-08:00, [email protected]

[PATCH] fakephp: introduce pci_bus_add_device

fakephp needs to add newly discovered devices to the global pci list.
Therefore seperate out the appropriate chunk from pci_bus_add_devices
to pci_bus_add_device to add a single device to sysfs, procfs
and the global device list.

Signed-off-by: Jan Dittmer <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


drivers/pci/bus.c | 31 +++++++++++++++++++++----------
include/linux/pci.h | 1 +
2 files changed, 22 insertions(+), 10 deletions(-)


diff -Nru a/drivers/pci/bus.c b/drivers/pci/bus.c
--- a/drivers/pci/bus.c 2004-11-12 15:11:49 -08:00
+++ b/drivers/pci/bus.c 2004-11-12 15:11:49 -08:00
@@ -69,6 +69,25 @@
}

/**
+ * add a single device
+ * @dev: device to add
+ *
+ * This adds a single pci device to the global
+ * device list and adds sysfs and procfs entries
+ */
+void __devinit pci_bus_add_device(struct pci_dev *dev)
+{
+ device_add(&dev->dev);
+
+ spin_lock(&pci_bus_lock);
+ list_add_tail(&dev->global_list, &pci_devices);
+ spin_unlock(&pci_bus_lock);
+
+ pci_proc_attach_device(dev);
+ pci_create_sysfs_dev_files(dev);
+}
+
+/**
* pci_bus_add_devices - insert newly discovered PCI devices
* @bus: bus to check for new devices
*
@@ -91,16 +110,7 @@
*/
if (!list_empty(&dev->global_list))
continue;
-
- device_add(&dev->dev);
-
- spin_lock(&pci_bus_lock);
- list_add_tail(&dev->global_list, &pci_devices);
- spin_unlock(&pci_bus_lock);
-
- pci_proc_attach_device(dev);
- pci_create_sysfs_dev_files(dev);
-
+ pci_bus_add_device(dev);
}

list_for_each_entry(dev, &bus->devices, bus_list) {
@@ -136,5 +146,6 @@
}

EXPORT_SYMBOL(pci_bus_alloc_resource);
+EXPORT_SYMBOL_GPL(pci_bus_add_device);
EXPORT_SYMBOL(pci_bus_add_devices);
EXPORT_SYMBOL(pci_enable_bridges);
diff -Nru a/include/linux/pci.h b/include/linux/pci.h
--- a/include/linux/pci.h 2004-11-12 15:11:49 -08:00
+++ b/include/linux/pci.h 2004-11-12 15:11:49 -08:00
@@ -715,6 +715,7 @@
int pci_scan_slot(struct pci_bus *bus, int devfn);
struct pci_dev * pci_scan_single_device(struct pci_bus *bus, int devfn);
unsigned int pci_scan_child_bus(struct pci_bus *bus);
+void pci_bus_add_device(struct pci_dev *dev);
void pci_bus_add_devices(struct pci_bus *bus);
void pci_name_device(struct pci_dev *dev);
char *pci_class_name(u32 class);

2004-11-12 23:44:46

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] PCI fixes for 2.6.10-rc1

ChangeSet 1.2026.35.6, 2004/10/28 16:26:11-05:00, [email protected]

[PATCH] PCI: Changed pci_find_device to pci_get_device

From: Hanna Linder <[email protected]>

Another simple patch to complete the /i386 conversion to pci_get_device. I
was able to compile and boot this patch to verify it didn't break anything
(on my T22).

Signed-off-by: Hanna Linder <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


arch/i386/pci/acpi.c | 2 +-
1 files changed, 1 insertion(+), 1 deletion(-)


diff -Nru a/arch/i386/pci/acpi.c b/arch/i386/pci/acpi.c
--- a/arch/i386/pci/acpi.c 2004-11-12 15:14:14 -08:00
+++ b/arch/i386/pci/acpi.c 2004-11-12 15:14:14 -08:00
@@ -41,7 +41,7 @@
printk(KERN_INFO "** was specified. If this was required to make a driver work,\n");
printk(KERN_INFO "** please email the output of \"lspci\" to [email protected]\n");
printk(KERN_INFO "** so I can fix the driver.\n");
- while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL)
+ while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL)
acpi_pci_irq_enable(dev);
} else {
printk(KERN_INFO "** PCI interrupts are no longer routed automatically. If this\n");

2004-11-12 23:44:46

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] PCI fixes for 2.6.10-rc1

ChangeSet 1.2026.66.11, 2004/11/05 14:09:34-08:00, [email protected]

PCI: remove kernel log message about drivers not calling pci_disable_device()

Signed-off-by: Greg Kroah-Hartman <[email protected]>


drivers/pci/pci-driver.c | 15 ++++++---------
1 files changed, 6 insertions(+), 9 deletions(-)


diff -Nru a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
--- a/drivers/pci/pci-driver.c 2004-11-12 15:13:35 -08:00
+++ b/drivers/pci/pci-driver.c 2004-11-12 15:13:35 -08:00
@@ -271,17 +271,14 @@
pci_dev->driver = NULL;
}

-#ifdef CONFIG_DEBUG_KERNEL
/*
- * If the driver decides to stop using the device, it should
- * call pci_disable_device().
+ * We would love to complain here if pci_dev->is_enabled is set, that
+ * the driver should have called pci_disable_device(), but the
+ * unfortunate fact is there are too many odd BIOS and bridge setups
+ * that don't like drivers doing that all of the time.
+ * Oh well, we can dream of sane hardware when we sleep, no matter how
+ * horrible the crap we have to deal with is when we are awake...
*/
- if (pci_dev->is_enabled) {
- dev_warn(&pci_dev->dev, "Device was removed without properly "
- "calling pci_disable_device(). This may need fixing.\n");
- /* WARN_ON(1); */
- }
-#endif /* CONFIG_DEBUG_KERNEL */

pci_dev_put(pci_dev);
return 0;

2004-11-12 23:41:54

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] PCI fixes for 2.6.10-rc1

ChangeSet 1.2091.1.15, 2004/11/12 14:09:00-08:00, [email protected]

[PATCH] pci_iommu.c: replace pci_find_device with pci_get_device

As pci_find_device is going away I've replaced it with pci_get_device.

Signed-off-by: Hanna Linder <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


arch/sparc64/kernel/pci_iommu.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletion(-)


diff -Nru a/arch/sparc64/kernel/pci_iommu.c b/arch/sparc64/kernel/pci_iommu.c
--- a/arch/sparc64/kernel/pci_iommu.c 2004-11-12 15:10:12 -08:00
+++ b/arch/sparc64/kernel/pci_iommu.c 2004-11-12 15:10:12 -08:00
@@ -814,7 +814,7 @@
/* ALI sound chips generate 31-bits of DMA, a special register
* determines what bit 31 is emitted as.
*/
- ali_isa_bridge = pci_find_device(PCI_VENDOR_ID_AL,
+ ali_isa_bridge = pci_get_device(PCI_VENDOR_ID_AL,
PCI_DEVICE_ID_AL_M1533,
NULL);

@@ -824,6 +824,7 @@
else
val &= ~0x01;
pci_write_config_byte(ali_isa_bridge, 0x7e, val);
+ pci_dev_put(ali_isa_bridge);
}

int pci_dma_supported(struct pci_dev *pdev, u64 device_mask)

2004-11-13 01:26:02

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] PCI fixes for 2.6.10-rc1

ChangeSet 1.2091.1.7, 2004/11/12 14:03:20-08:00, [email protected]

[PATCH] matroxfb_base.c: convert pci_find_device to pci_get_device

As pci_find_device is going away I've replaced it with pci_get_device.

Signed-off-by: Hanna Linder <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


drivers/video/matrox/matroxfb_base.c | 7 ++++++-
1 files changed, 6 insertions(+), 1 deletion(-)


diff -Nru a/drivers/video/matrox/matroxfb_base.c b/drivers/video/matrox/matroxfb_base.c
--- a/drivers/video/matrox/matroxfb_base.c 2004-11-12 15:11:12 -08:00
+++ b/drivers/video/matrox/matroxfb_base.c 2004-11-12 15:11:12 -08:00
@@ -1580,6 +1580,11 @@
unsigned int memsize;
int err;

+ static struct pci_device_id intel_82437[] = {
+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82437) },
+ { },
+ };
+
DBG(__FUNCTION__)

/* set default values... */
@@ -1684,7 +1689,7 @@
mga_option |= MX_OPTION_BSWAP;
/* disable palette snooping */
cmd &= ~PCI_COMMAND_VGA_PALETTE;
- if (pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82437, NULL)) {
+ if (pci_dev_present(intel_82437)) {
if (!(mga_option & 0x20000000) && !ACCESS_FBINFO(devflags.nopciretry)) {
printk(KERN_WARNING "matroxfb: Disabling PCI retries due to i82437 present\n");
}

2004-11-13 01:25:59

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] PCI fixes for 2.6.10-rc1

ChangeSet 1.2026.35.3, 2004/10/28 15:15:12-05:00, [email protected]

[PATCH] PCI: propagate pci_enable_device() errors

From: Bjorn Helgaas <[email protected]>

Jeff Garzik pointed out that I should have propagated the error returned
from pci_enable_device() rather than making up -ENODEV.

Propagate pci_enable_device() error returns rather than using -ENODEV.

Signed-off-by: Bjorn Helgaas <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


drivers/atm/idt77252.c | 4 ++--
drivers/isdn/tpam/tpam_main.c | 4 ++--
drivers/misc/ibmasm/module.c | 6 +++---
drivers/net/tulip/de4x5.c | 4 ++--
4 files changed, 9 insertions(+), 9 deletions(-)


diff -Nru a/drivers/atm/idt77252.c b/drivers/atm/idt77252.c
--- a/drivers/atm/idt77252.c 2004-11-12 15:14:36 -08:00
+++ b/drivers/atm/idt77252.c 2004-11-12 15:14:36 -08:00
@@ -3685,9 +3685,9 @@
int i, err;


- if (pci_enable_device(pcidev)) {
+ if ((err = pci_enable_device(pcidev))) {
printk("idt77252: can't enable PCI device at %s\n", pci_name(pcidev));
- return -ENODEV;
+ return err;
}

if (pci_read_config_word(pcidev, PCI_REVISION_ID, &revision)) {
diff -Nru a/drivers/isdn/tpam/tpam_main.c b/drivers/isdn/tpam/tpam_main.c
--- a/drivers/isdn/tpam/tpam_main.c 2004-11-12 15:14:36 -08:00
+++ b/drivers/isdn/tpam/tpam_main.c 2004-11-12 15:14:36 -08:00
@@ -88,10 +88,10 @@
tpam_card *card, *c;
int i, err;

- if (pci_enable_device(dev)) {
+ if ((err = pci_enable_device(dev))) {
printk(KERN_ERR "TurboPAM: can't enable PCI device at %s\n",
pci_name(dev));
- return -ENODEV;
+ return err;
}

/* allocate memory for the board structure */
diff -Nru a/drivers/misc/ibmasm/module.c b/drivers/misc/ibmasm/module.c
--- a/drivers/misc/ibmasm/module.c 2004-11-12 15:14:36 -08:00
+++ b/drivers/misc/ibmasm/module.c 2004-11-12 15:14:36 -08:00
@@ -59,13 +59,13 @@

static int __init ibmasm_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
{
- int result = -ENOMEM;
+ int err, result = -ENOMEM;
struct service_processor *sp;

- if (pci_enable_device(pdev)) {
+ if ((err = pci_enable_device(pdev))) {
printk(KERN_ERR "%s: can't enable PCI device at %s\n",
DRIVER_NAME, pci_name(pdev));
- return -ENODEV;
+ return err;
}

sp = kmalloc(sizeof(struct service_processor), GFP_KERNEL);
diff -Nru a/drivers/net/tulip/de4x5.c b/drivers/net/tulip/de4x5.c
--- a/drivers/net/tulip/de4x5.c 2004-11-12 15:14:36 -08:00
+++ b/drivers/net/tulip/de4x5.c 2004-11-12 15:14:36 -08:00
@@ -2242,8 +2242,8 @@
return -ENODEV;

/* Ok, the device seems to be for us. */
- if (pci_enable_device (pdev))
- return -ENODEV;
+ if ((error = pci_enable_device (pdev)))
+ return error;

if (!(dev = alloc_etherdev (sizeof (struct de4x5_private)))) {
error = -ENOMEM;

2004-11-12 23:41:54

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] PCI fixes for 2.6.10-rc1

ChangeSet 1.2091.1.13, 2004/11/12 14:08:14-08:00, [email protected]

[PATCH] pci-gart.c: replace pci_find_device with pci_get_device

As pci_find_device is going away I've replaced it with pci_get_device.


Signed-off-by: Hanna Linder <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


arch/x86_64/kernel/pci-gart.c | 2 +-
1 files changed, 1 insertion(+), 1 deletion(-)


diff -Nru a/arch/x86_64/kernel/pci-gart.c b/arch/x86_64/kernel/pci-gart.c
--- a/arch/x86_64/kernel/pci-gart.c 2004-11-12 15:10:27 -08:00
+++ b/arch/x86_64/kernel/pci-gart.c 2004-11-12 15:10:27 -08:00
@@ -81,7 +81,7 @@

#define for_all_nb(dev) \
dev = NULL; \
- while ((dev = pci_find_device(PCI_VENDOR_ID_AMD, 0x1103, dev))!=NULL)\
+ while ((dev = pci_get_device(PCI_VENDOR_ID_AMD, 0x1103, dev))!=NULL)\
if (dev->bus->number == 0 && \
(PCI_SLOT(dev->devfn) >= 24) && (PCI_SLOT(dev->devfn) <= 31))


2004-11-12 23:41:53

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] PCI fixes for 2.6.10-rc1

ChangeSet 1.2091.1.21, 2004/11/12 14:11:07-08:00, [email protected]

[PATCH] mcpn765.c: replace pci_find_device with pci_get_device

As pci_find_device is going away I've replaced it with pci_get_device
and pci_dev_put.


Signed-off-by: Hanna Linder <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


arch/ppc/platforms/mcpn765.c | 7 ++++---
1 files changed, 4 insertions(+), 3 deletions(-)


diff -Nru a/arch/ppc/platforms/mcpn765.c b/arch/ppc/platforms/mcpn765.c
--- a/arch/ppc/platforms/mcpn765.c 2004-11-12 15:09:26 -08:00
+++ b/arch/ppc/platforms/mcpn765.c 2004-11-12 15:09:27 -08:00
@@ -185,7 +185,7 @@
struct pci_dev *dev;
u_char c;

- if ((dev = pci_find_device(PCI_VENDOR_ID_VIA,
+ if ((dev = pci_get_device(PCI_VENDOR_ID_VIA,
PCI_DEVICE_ID_VIA_82C586_0,
NULL)) == NULL) {
printk("No VIA ISA bridge found\n");
@@ -209,8 +209,8 @@
pci_write_config_dword(dev, 0x54, 0);
pci_write_config_byte(dev, 0x58, 0);

-
- if ((dev = pci_find_device(PCI_VENDOR_ID_VIA,
+ pci_dev_put(dev);
+ if ((dev = pci_get_device(PCI_VENDOR_ID_VIA,
PCI_DEVICE_ID_VIA_82C586_1,
NULL)) == NULL) {
printk("No VIA ISA bridge found\n");
@@ -225,6 +225,7 @@
pci_read_config_byte(dev, 0x40, &c);
c |= 0x03;
pci_write_config_byte(dev, 0x40, c);
+ pci_dev_put(dev);

return;
}

2004-11-12 23:41:52

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] PCI fixes for 2.6.10-rc1

ChangeSet 1.2091.1.19, 2004/11/12 14:10:24-08:00, [email protected]

[PATCH] sandpoint.c: replace pci_find_device with pci_get_device

As pci_find_device is going away I've replaced it with pci_get_device.


Signed-off-by: Hanna Linder <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


arch/ppc/platforms/sandpoint.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletion(-)


diff -Nru a/arch/ppc/platforms/sandpoint.c b/arch/ppc/platforms/sandpoint.c
--- a/arch/ppc/platforms/sandpoint.c 2004-11-12 15:09:42 -08:00
+++ b/arch/ppc/platforms/sandpoint.c 2004-11-12 15:09:42 -08:00
@@ -575,7 +575,7 @@
static void
sandpoint_ide_probe(void)
{
- struct pci_dev *pdev = pci_find_device(PCI_VENDOR_ID_WINBOND,
+ struct pci_dev *pdev = pci_get_device(PCI_VENDOR_ID_WINBOND,
PCI_DEVICE_ID_WINBOND_82C105, NULL);

if (pdev) {
@@ -584,6 +584,7 @@
sandpoint_ide_ctl_regbase[0]=pdev->resource[1].start;
sandpoint_ide_ctl_regbase[1]=pdev->resource[3].start;
sandpoint_idedma_regbase=pdev->resource[4].start;
+ pci_dev_put(dev);
}

sandpoint_ide_ports_known = 1;

2004-11-12 23:41:52

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] PCI fixes for 2.6.10-rc1

ChangeSet 1.2091.1.3, 2004/11/11 16:33:31-08:00, [email protected]

[PATCH] fakephp: add pci bus rescan ability

This adds the ability to rescan the pci bus for newly inserted,
reprogrammed or previously disabled pci devices.
To initiate a rescan you need to write '1' to any of the
/sys/bus/pci/slots/*/power control files. No known pci devices
will be touched.
Additionally this fixes a bug, when someone tries to disable
a device with subfunctions. The subfunctions will be disabled first now.

Short demo:
# modprobe fakephp
# ls /sys/bus/pci/slots | grep "0000:04"
0000:04:02.0
0000:04:02.1
0000:04:02.2
0000:04:03.0
0000:04:03.1
# echo -n 0 > /sys/bus/pci/slots/0000\:04\:02.0/power
# ls /sys/bus/pci/slots | grep "0000:04"
0000:04:03.0
0000:04:03.1
# echo -n 1 > /sys/bus/pci/slots/0000\:03\:01.0/power
# ls /sys/bus/pci/slots | grep "0000:04"
0000:04:02.0
0000:04:02.1
0000:04:02.2
0000:04:03.0
0000:04:03.1
# lspci | grep "0000:04"
0000:04:02.0 Multimedia audio controller: Creative Labs SB Audigy (rev 03)
0000:04:02.1 Input device controller: Creative Labs SB Audigy MIDI/Gameport (rev 03)
0000:04:02.2 FireWire (IEEE 1394): Creative Labs SB Audigy FireWire Port
0000:04:03.0 SCSI storage controller: Adaptec AHA-3960D / AIC-7899A U160/m (rev 01)
0000:04:03.1 SCSI storage controller: Adaptec AHA-3960D / AIC-7899A U160/m (rev 01)

Signed-off-by: Jan Dittmer <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


drivers/pci/hotplug/fakephp.c | 126 ++++++++++++++++++++++++++++++++++++++++++
1 files changed, 126 insertions(+)


diff -Nru a/drivers/pci/hotplug/fakephp.c b/drivers/pci/hotplug/fakephp.c
--- a/drivers/pci/hotplug/fakephp.c 2004-11-12 15:11:41 -08:00
+++ b/drivers/pci/hotplug/fakephp.c 2004-11-12 15:11:41 -08:00
@@ -165,14 +165,123 @@
err("Problem unregistering a slot %s\n", dslot->slot->name);
}

+/**
+ * Rescan slot.
+ * Tries hard not to re-enable already existing devices
+ * also handles scanning of subfunctions
+ *
+ * @param temp Device template. Should be set: bus and devfn.
+ */
+static void pci_rescan_slot(struct pci_dev *temp)
+{
+ struct pci_bus *bus = temp->bus;
+ struct pci_dev *dev;
+ int func;
+ u8 hdr_type;
+ if (!pci_read_config_byte(temp, PCI_HEADER_TYPE, &hdr_type)) {
+ temp->hdr_type = hdr_type & 0x7f;
+ if (!pci_find_slot(bus->number, temp->devfn)) {
+ dev = pci_scan_single_device(bus, temp->devfn);
+ if (dev) {
+ dbg("New device on %s function %x:%x\n",
+ bus->name, temp->devfn >> 3,
+ temp->devfn & 7);
+ pci_bus_add_device(dev);
+ add_slot(dev);
+ }
+ }
+ /* multifunction device? */
+ if (!(hdr_type & 0x80))
+ return;
+
+ /* continue scanning for other functions */
+ for (func = 1, temp->devfn++; func < 8; func++, temp->devfn++) {
+ if (pci_read_config_byte(temp, PCI_HEADER_TYPE, &hdr_type))
+ continue;
+ temp->hdr_type = hdr_type & 0x7f;
+
+ if (!pci_find_slot(bus->number, temp->devfn)) {
+ dev = pci_scan_single_device(bus, temp->devfn);
+ if (dev) {
+ dbg("New device on %s function %x:%x\n",
+ bus->name, temp->devfn >> 3,
+ temp->devfn & 7);
+ pci_bus_add_device(dev);
+ add_slot(dev);
+ }
+ }
+ }
+ }
+}
+
+
+/**
+ * Rescan PCI bus.
+ * call pci_rescan_slot for each possible function of the bus
+ *
+ * @param bus
+ */
+static void pci_rescan_bus(const struct pci_bus *bus)
+{
+ unsigned int devfn;
+ struct pci_dev *dev;
+ dev = kmalloc(sizeof(struct pci_dev), GFP_KERNEL);
+ if (!dev)
+ return;
+
+ memset(dev, 0, sizeof(dev));
+ dev->bus = (struct pci_bus*)bus;
+ dev->sysdata = bus->sysdata;
+ for (devfn = 0; devfn < 0x100; devfn += 8) {
+ dev->devfn = devfn;
+ pci_rescan_slot(dev);
+ }
+ kfree(dev);
+}
+
+/* recursively scan all buses */
+static void pci_rescan_buses(const struct list_head *list)
+{
+ const struct list_head *l;
+ list_for_each(l,list) {
+ const struct pci_bus *b = pci_bus_b(l);
+ pci_rescan_bus(b);
+ pci_rescan_buses(&b->children);
+ }
+}
+
+/* initiate rescan of all pci buses */
+static inline void pci_rescan(void) {
+ pci_rescan_buses(&pci_root_buses);
+}
+
+
static int enable_slot(struct hotplug_slot *hotplug_slot)
{
+ /* mis-use enable_slot for rescanning of the pci bus */
+ pci_rescan();
return -ENODEV;
}

+/* find the hotplug_slot for the pci_dev */
+static struct hotplug_slot *get_slot_from_dev(struct pci_dev *dev)
+{
+ struct dummy_slot *dslot;
+
+ list_for_each_entry(dslot, &slot_list, node) {
+ if (dslot->dev == dev)
+ return dslot->slot;
+ }
+ return NULL;
+}
+
+
static int disable_slot(struct hotplug_slot *slot)
{
struct dummy_slot *dslot;
+ struct hotplug_slot *hslot;
+ struct pci_dev *dev;
+ int func;

if (!slot)
return -ENODEV;
@@ -184,6 +293,23 @@
if (dslot->dev->subordinate) {
err("Can't remove PCI devices with other PCI devices behind it yet.\n");
return -ENODEV;
+ }
+ /* search for subfunctions and disable them first */
+ if (!(dslot->dev->devfn & 7)) {
+ for (func = 1; func < 8; func++) {
+ dev = pci_find_slot(dslot->dev->bus->number,
+ dslot->dev->devfn + func);
+ if (dev) {
+ hslot = get_slot_from_dev(dev);
+ if (hslot)
+ disable_slot(hslot);
+ else {
+ err("Hotplug slot not found for subfunction of PCI device\n");
+ return -ENODEV;
+ }
+ } else
+ dbg("No device in slot found\n");
+ }
}

/* remove the device from the pci core */

2004-11-12 23:41:51

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] PCI fixes for 2.6.10-rc1

ChangeSet 1.2091.1.24, 2004/11/12 14:12:11-08:00, [email protected]

[PATCH] pplus.c: replace pci_find_device with pci_get_device

Signed-off-by: Hanna Linder <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


arch/ppc/platforms/pplus.c | 9 +++++----
1 files changed, 5 insertions(+), 4 deletions(-)


diff -Nru a/arch/ppc/platforms/pplus.c b/arch/ppc/platforms/pplus.c
--- a/arch/ppc/platforms/pplus.c 2004-11-12 15:09:04 -08:00
+++ b/arch/ppc/platforms/pplus.c 2004-11-12 15:09:04 -08:00
@@ -359,7 +359,7 @@
* Perform specific configuration for the Via Tech or
* or Winbond PCI-ISA-Bridge part.
*/
- if ((dev = pci_find_device(PCI_VENDOR_ID_VIA,
+ if ((dev = pci_get_device(PCI_VENDOR_ID_VIA,
PCI_DEVICE_ID_VIA_82C586_1, dev))) {
/*
* PPCBUG does not set the enable bits
@@ -371,7 +371,7 @@
pci_write_config_byte(dev, 0x40, reg);
}

- if ((dev = pci_find_device(PCI_VENDOR_ID_VIA,
+ if ((dev = pci_get_device(PCI_VENDOR_ID_VIA,
PCI_DEVICE_ID_VIA_82C586_2,
dev)) && (dev->devfn = 0x5a)) {
/* Force correct USB interrupt */
@@ -379,7 +379,7 @@
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
}

- if ((dev = pci_find_device(PCI_VENDOR_ID_WINBOND,
+ if ((dev = pci_get_device(PCI_VENDOR_ID_WINBOND,
PCI_DEVICE_ID_WINBOND_83C553, dev))) {
/* Clear PCI Interrupt Routing Control Register. */
short_reg = 0x0000;
@@ -389,7 +389,7 @@
pci_write_config_byte(dev, 0x43, reg);
}

- if ((dev = pci_find_device(PCI_VENDOR_ID_WINBOND,
+ if ((dev = pci_get_device(PCI_VENDOR_ID_WINBOND,
PCI_DEVICE_ID_WINBOND_82C105, dev))) {
/*
* Disable LEGIRQ mode so PCI INTS are routed
@@ -401,6 +401,7 @@
dev->irq = 14;
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
}
+ pci_dev_put(dev);
}

void __init pplus_set_VIA_IDE_legacy(void)

2004-11-12 23:41:51

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] PCI fixes for 2.6.10-rc1

ChangeSet 1.2026.66.20, 2004/11/10 16:44:40-08:00, [email protected]

[PATCH] ide.c: replace pci_find_device with pci_dev_present

As pci_find_device is going away it needs to be replaced. In this case the dev
returned from pci_find_device was not being used so pci_dev_present was the
appropriate replacement.

This has been compile and boot tested on a T22.

Signed-off-by: Hanna Linder <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


drivers/ide/ide.c | 7 ++++++-
1 files changed, 6 insertions(+), 1 deletion(-)


diff -Nru a/drivers/ide/ide.c b/drivers/ide/ide.c
--- a/drivers/ide/ide.c 2004-11-12 15:12:26 -08:00
+++ b/drivers/ide/ide.c 2004-11-12 15:12:26 -08:00
@@ -335,11 +335,16 @@

int ide_system_bus_speed (void)
{
+ static struct pci_device_id pci_default[] = {
+ { PCI_DEVICE(PCI_ANY_ID, PCI_ANY_ID) },
+ { }
+ };
+
if (!system_bus_speed) {
if (idebus_parameter) {
/* user supplied value */
system_bus_speed = idebus_parameter;
- } else if (pci_find_device(PCI_ANY_ID, PCI_ANY_ID, NULL) != NULL) {
+ } else if (pci_dev_present(pci_default)) {
/* safe default value for PCI */
system_bus_speed = 33;
} else {

2004-11-12 23:41:51

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] PCI fixes for 2.6.10-rc1

ChangeSet 1.2091.1.23, 2004/11/12 14:11:49-08:00, [email protected]

[PATCH] pmac_pci.c: replace pci_find_device with pci_get_device

As pci_find_device is going away I've replaced it with pci_get_device.


Signed-off-by: Hanna Linder <[email protected]>


arch/ppc/platforms/pmac_pci.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)


diff -Nru a/arch/ppc/platforms/pmac_pci.c b/arch/ppc/platforms/pmac_pci.c
--- a/arch/ppc/platforms/pmac_pci.c 2004-11-12 15:09:11 -08:00
+++ b/arch/ppc/platforms/pmac_pci.c 2004-11-12 15:09:11 -08:00
@@ -889,7 +889,7 @@
* should find the device node and apply the interrupt
* obtained from the OF device-tree
*/
- while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
+ for_each_pci_dev(dev) {
struct device_node *node;
node = pci_device_to_OF_node(dev);
/* this is the node, see if it has interrupts */
@@ -989,7 +989,7 @@
*
* -- BenH
*/
- while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
+ for_each_pci_dev(dev) {
if ((dev->class >> 16) == PCI_BASE_CLASS_STORAGE)
pci_enable_device(dev);
}

2004-11-12 23:41:45

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] PCI fixes for 2.6.10-rc1

ChangeSet 1.2026.55.2, 2004/11/01 14:51:06-08:00, [email protected]

[PATCH] PCI: Updated patch to add ExpressCard support

This patch adds ExpressCard support to pciehp driver. It also includes
the code that implements _OSC method call in driver/pci/pci-acpi.c for
use by the drivers.


Signed-off-by: Dely Sy <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


drivers/pci/Makefile | 5
drivers/pci/hotplug/pciehp.h | 21 +
drivers/pci/hotplug/pciehp_core.c | 18 -
drivers/pci/hotplug/pciehp_ctrl.c | 382 ++++++++++++++++++++++--------------
drivers/pci/hotplug/pciehp_hpc.c | 30 +-
drivers/pci/hotplug/pciehprm_acpi.c | 43 +++-
drivers/pci/pci-acpi.c | 209 +++++++++++++++++++
include/linux/pci-acpi.h | 61 +++++
8 files changed, 601 insertions(+), 168 deletions(-)


diff -Nru a/drivers/pci/Makefile b/drivers/pci/Makefile
--- a/drivers/pci/Makefile 2004-11-12 15:13:59 -08:00
+++ b/drivers/pci/Makefile 2004-11-12 15:13:59 -08:00
@@ -28,6 +28,11 @@
obj-$(CONFIG_X86_VISWS) += setup-irq.o
obj-$(CONFIG_PCI_MSI) += msi.o

+#
+# ACPI Related PCI FW Functions
+#
+obj-$(CONFIG_ACPI) += pci-acpi.o
+
# Cardbus & CompactPCI use setup-bus
obj-$(CONFIG_HOTPLUG) += setup-bus.o

diff -Nru a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h
--- a/drivers/pci/hotplug/pciehp.h 2004-11-12 15:13:59 -08:00
+++ b/drivers/pci/hotplug/pciehp.h 2004-11-12 15:13:59 -08:00
@@ -127,8 +127,7 @@
enum pci_bus_speed speed;
u32 first_slot; /* First physical slot number */ /* PCIE only has 1 slot */
u8 slot_bus; /* Bus where the slots handled by this controller sit */
- u8 push_flag;
- u16 ctlrcap;
+ u8 ctrlcap;
u16 vendor_id;
};

@@ -180,6 +179,21 @@

#define DISABLE_CARD 1

+/* Field definitions in Slot Capabilities Register */
+#define ATTN_BUTTN_PRSN 0x00000001
+#define PWR_CTRL_PRSN 0x00000002
+#define MRL_SENS_PRSN 0x00000004
+#define ATTN_LED_PRSN 0x00000008
+#define PWR_LED_PRSN 0x00000010
+#define HP_SUPR_RM_SUP 0x00000020
+
+#define ATTN_BUTTN(cap) (cap & ATTN_BUTTN_PRSN)
+#define POWER_CTRL(cap) (cap & PWR_CTRL_PRSN)
+#define MRL_SENS(cap) (cap & MRL_SENS_PRSN)
+#define ATTN_LED(cap) (cap & ATTN_LED_PRSN)
+#define PWR_LED(cap) (cap & PWR_LED_PRSN)
+#define HP_SUPR_RM(cap) (cap & HP_SUPR_RM_SUP)
+
/*
* error Messages
*/
@@ -312,8 +326,7 @@
int *num_ctlr_slots,
int *first_device_num,
int *physical_slot_num,
- int *updown,
- int *flags);
+ u8 *ctrlcap);

struct hpc_ops {
int (*power_on_slot) (struct slot *slot);
diff -Nru a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c
--- a/drivers/pci/hotplug/pciehp_core.c 2004-11-12 15:13:59 -08:00
+++ b/drivers/pci/hotplug/pciehp_core.c 2004-11-12 15:13:59 -08:00
@@ -204,11 +204,10 @@
int num_ctlr_slots; /* Not needed; PCI Express has 1 slot per port*/
int first_device_num; /* Not needed */
int physical_slot_num;
- int updown; /* Not needed */
+ u8 ctrlcap;
int rc;
- int flags; /* Not needed */

- rc = pcie_get_ctlr_slot_config(ctrl, &num_ctlr_slots, &first_device_num, &physical_slot_num, &updown, &flags);
+ rc = pcie_get_ctlr_slot_config(ctrl, &num_ctlr_slots, &first_device_num, &physical_slot_num, &ctrlcap);
if (rc) {
err("%s: get_ctlr_slot_config fail for b:d (%x:%x)\n", __FUNCTION__, ctrl->bus, ctrl->device);
return (-1);
@@ -217,10 +216,10 @@
ctrl->num_slots = num_ctlr_slots; /* PCI Express has 1 slot per port */
ctrl->slot_device_offset = first_device_num;
ctrl->first_slot = physical_slot_num;
- ctrl->slot_num_inc = updown; /* Not needed */ /* either -1 or 1 */
+ ctrl->ctrlcap = ctrlcap;

- dbg("%s: bus(0x%x) num_slot(0x%x) 1st_dev(0x%x) psn(0x%x) updown(%d) for b:d (%x:%x)\n",
- __FUNCTION__, ctrl->slot_bus, num_ctlr_slots, first_device_num, physical_slot_num, updown,
+ dbg("%s: bus(0x%x) num_slot(0x%x) 1st_dev(0x%x) psn(0x%x) ctrlcap(%x) for b:d (%x:%x)\n",
+ __FUNCTION__, ctrl->slot_bus, num_ctlr_slots, first_device_num, physical_slot_num, ctrlcap,
ctrl->bus, ctrl->device);

return (0);
@@ -237,7 +236,9 @@
dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);

hotplug_slot->info->attention_status = status;
- slot->hpc_ops->set_attention_status(slot, status);
+
+ if (ATTN_LED(slot->ctrl->ctrlcap))
+ slot->hpc_ops->set_attention_status(slot, status);

return 0;
}
@@ -451,7 +452,8 @@

t_slot->hpc_ops->get_adapter_status(t_slot, &value); /* Check if slot is occupied */
dbg("%s: adpater value %x\n", __FUNCTION__, value);
- if (!value) {
+
+ if ((POWER_CTRL(ctrl->ctrlcap)) && !value) {
rc = t_slot->hpc_ops->power_off_slot(t_slot); /* Power off slot if not occupied*/
if (rc) {
/* Done with exclusive hardware access */
diff -Nru a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c
--- a/drivers/pci/hotplug/pciehp_ctrl.c 2004-11-12 15:13:59 -08:00
+++ b/drivers/pci/hotplug/pciehp_ctrl.c 2004-11-12 15:13:59 -08:00
@@ -51,6 +51,7 @@
static struct semaphore event_exit; /* guard ensure thread has exited before calling it quits */
static int event_finished;
static unsigned long pushbutton_pending; /* = 0 */
+static unsigned long surprise_rm_pending; /* = 0 */

u8 pciehp_handle_attention_button(u8 hp_slot, void *inst_id)
{
@@ -1063,25 +1064,29 @@
/* Wait for exclusive access to hardware */
down(&ctrl->crit_sect);

- /* turn off slot, turn on Amber LED, turn off Green LED */
- if (pslot->hpc_ops->power_off_slot(pslot)) {
- err("%s: Issue of Slot Power Off command failed\n", __FUNCTION__);
- up(&ctrl->crit_sect);
- return;
+ /* turn off slot, turn on Amber LED, turn off Green LED if supported*/
+ if (POWER_CTRL(ctrl->ctrlcap)) {
+ if (pslot->hpc_ops->power_off_slot(pslot)) {
+ err("%s: Issue of Slot Power Off command failed\n", __FUNCTION__);
+ up(&ctrl->crit_sect);
+ return;
+ }
+ wait_for_ctrl_irq (ctrl);
}
- wait_for_ctrl_irq (ctrl);

- pslot->hpc_ops->green_led_off(pslot);
-
- wait_for_ctrl_irq (ctrl);
+ if (PWR_LED(ctrl->ctrlcap)) {
+ pslot->hpc_ops->green_led_off(pslot);
+ wait_for_ctrl_irq (ctrl);
+ }

- /* turn on Amber LED */
- if (pslot->hpc_ops->set_attention_status(pslot, 1)) {
- err("%s: Issue of Set Attention Led command failed\n", __FUNCTION__);
- up(&ctrl->crit_sect);
- return;
+ if (ATTN_LED(ctrl->ctrlcap)) {
+ if (pslot->hpc_ops->set_attention_status(pslot, 1)) {
+ err("%s: Issue of Set Attention Led command failed\n", __FUNCTION__);
+ up(&ctrl->crit_sect);
+ return;
+ }
+ wait_for_ctrl_irq (ctrl);
}
- wait_for_ctrl_irq (ctrl);

/* Done with exclusive hardware access */
up(&ctrl->crit_sect);
@@ -1112,20 +1117,24 @@
/* Wait for exclusive access to hardware */
down(&ctrl->crit_sect);

- /* Power on slot */
- rc = p_slot->hpc_ops->power_on_slot(p_slot);
- if (rc) {
- up(&ctrl->crit_sect);
- return -1;
- }
+ if (POWER_CTRL(ctrl->ctrlcap)) {
+ /* Power on slot */
+ rc = p_slot->hpc_ops->power_on_slot(p_slot);
+ if (rc) {
+ up(&ctrl->crit_sect);
+ return -1;
+ }

- /* Wait for the command to complete */
- wait_for_ctrl_irq (ctrl);
+ /* Wait for the command to complete */
+ wait_for_ctrl_irq (ctrl);
+ }

- p_slot->hpc_ops->green_led_blink(p_slot);
+ if (PWR_LED(ctrl->ctrlcap)) {
+ p_slot->hpc_ops->green_led_blink(p_slot);

- /* Wait for the command to complete */
- wait_for_ctrl_irq (ctrl);
+ /* Wait for the command to complete */
+ wait_for_ctrl_irq (ctrl);
+ }

/* Done with exclusive hardware access */
up(&ctrl->crit_sect);
@@ -1211,19 +1220,19 @@
pciehp_configure_device(ctrl, new_func);
}
} while (new_func);
-
- /* Wait for exclusive access to hardware */
- down(&ctrl->crit_sect);
-
- p_slot->hpc_ops->green_led_on(p_slot);
-
- /* Wait for the command to complete */
- wait_for_ctrl_irq (ctrl);
-
-
- /* Done with exclusive hardware access */
- up(&ctrl->crit_sect);
-
+
+ if (PWR_LED(ctrl->ctrlcap)) {
+ /* Wait for exclusive access to hardware */
+ down(&ctrl->crit_sect);
+
+ p_slot->hpc_ops->green_led_on(p_slot);
+
+ /* Wait for the command to complete */
+ wait_for_ctrl_irq (ctrl);
+
+ /* Done with exclusive hardware access */
+ up(&ctrl->crit_sect);
+ }
} else {
set_slot_off(ctrl, p_slot);
return -1;
@@ -1289,21 +1298,25 @@
/* Wait for exclusive access to hardware */
down(&ctrl->crit_sect);

- /* power off slot */
- rc = p_slot->hpc_ops->power_off_slot(p_slot);
- if (rc) {
- err("%s: Issue of Slot Disable command failed\n", __FUNCTION__);
- up(&ctrl->crit_sect);
- return rc;
+ if (POWER_CTRL(ctrl->ctrlcap)) {
+ /* power off slot */
+ rc = p_slot->hpc_ops->power_off_slot(p_slot);
+ if (rc) {
+ err("%s: Issue of Slot Disable command failed\n", __FUNCTION__);
+ up(&ctrl->crit_sect);
+ return rc;
+ }
+ /* Wait for the command to complete */
+ wait_for_ctrl_irq (ctrl);
}
- /* Wait for the command to complete */
- wait_for_ctrl_irq (ctrl);

- /* turn off Green LED */
- p_slot->hpc_ops->green_led_off(p_slot);
+ if (PWR_LED(ctrl->ctrlcap)) {
+ /* turn off Green LED */
+ p_slot->hpc_ops->green_led_off(p_slot);

- /* Wait for the command to complete */
- wait_for_ctrl_irq (ctrl);
+ /* Wait for the command to complete */
+ wait_for_ctrl_irq (ctrl);
+ }

/* Done with exclusive hardware access */
up(&ctrl->crit_sect);
@@ -1368,7 +1381,6 @@
up(&event_semaphore);
}

-
/**
* pciehp_pushbutton_thread
*
@@ -1399,7 +1411,55 @@
p_slot->state = POWERON_STATE;
dbg("In add_board, b:d(%x:%x)\n", p_slot->bus, p_slot->device);

- if (pciehp_enable_slot(p_slot)) {
+ if (pciehp_enable_slot(p_slot) && PWR_LED(p_slot->ctrl->ctrlcap)) {
+ /* Wait for exclusive access to hardware */
+ down(&p_slot->ctrl->crit_sect);
+
+ p_slot->hpc_ops->green_led_off(p_slot);
+
+ /* Wait for the command to complete */
+ wait_for_ctrl_irq (p_slot->ctrl);
+
+ /* Done with exclusive hardware access */
+ up(&p_slot->ctrl->crit_sect);
+ }
+ p_slot->state = STATIC_STATE;
+ }
+
+ return;
+}
+
+/**
+ * pciehp_surprise_rm_thread
+ *
+ * Scheduled procedure to handle blocking stuff for the surprise removal
+ * Handles all pending events and exits.
+ *
+ */
+static void pciehp_surprise_rm_thread(unsigned long slot)
+{
+ struct slot *p_slot = (struct slot *) slot;
+ u8 getstatus;
+
+ surprise_rm_pending = 0;
+
+ if (!p_slot) {
+ dbg("%s: Error! slot NULL\n", __FUNCTION__);
+ return;
+ }
+
+ p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus);
+ if (!getstatus) {
+ p_slot->state = POWEROFF_STATE;
+ dbg("In removing board, b:d(%x:%x)\n", p_slot->bus, p_slot->device);
+
+ pciehp_disable_slot(p_slot);
+ p_slot->state = STATIC_STATE;
+ } else {
+ p_slot->state = POWERON_STATE;
+ dbg("In add_board, b:d(%x:%x)\n", p_slot->bus, p_slot->device);
+
+ if (pciehp_enable_slot(p_slot) && PWR_LED(p_slot->ctrl->ctrlcap)) {
/* Wait for exclusive access to hardware */
down(&p_slot->ctrl->crit_sect);

@@ -1418,6 +1478,7 @@
}


+
/* this is the main worker thread */
static int event_thread(void* data)
{
@@ -1436,6 +1497,8 @@
/* Do stuff here */
if (pushbutton_pending)
pciehp_pushbutton_thread(pushbutton_pending);
+ else if (surprise_rm_pending)
+ pciehp_surprise_rm_thread(surprise_rm_pending);
else
for (ctrl = pciehp_ctrl_list; ctrl; ctrl=ctrl->next)
interrupt_event_handler(ctrl);
@@ -1528,16 +1591,18 @@
case BLINKINGOFF_STATE:
/* Wait for exclusive access to hardware */
down(&ctrl->crit_sect);
-
- p_slot->hpc_ops->green_led_on(p_slot);
- /* Wait for the command to complete */
- wait_for_ctrl_irq (ctrl);
-
- p_slot->hpc_ops->set_attention_status(p_slot, 0);
-
- /* Wait for the command to complete */
- wait_for_ctrl_irq (ctrl);
-
+
+ if (PWR_LED(ctrl->ctrlcap)) {
+ p_slot->hpc_ops->green_led_on(p_slot);
+ /* Wait for the command to complete */
+ wait_for_ctrl_irq (ctrl);
+ }
+ if (ATTN_LED(ctrl->ctrlcap)) {
+ p_slot->hpc_ops->set_attention_status(p_slot, 0);
+
+ /* Wait for the command to complete */
+ wait_for_ctrl_irq (ctrl);
+ }
/* Done with exclusive hardware access */
up(&ctrl->crit_sect);
break;
@@ -1545,14 +1610,16 @@
/* Wait for exclusive access to hardware */
down(&ctrl->crit_sect);

- p_slot->hpc_ops->green_led_off(p_slot);
- /* Wait for the command to complete */
- wait_for_ctrl_irq (ctrl);
-
- p_slot->hpc_ops->set_attention_status(p_slot, 0);
- /* Wait for the command to complete */
- wait_for_ctrl_irq (ctrl);
-
+ if (PWR_LED(ctrl->ctrlcap)) {
+ p_slot->hpc_ops->green_led_off(p_slot);
+ /* Wait for the command to complete */
+ wait_for_ctrl_irq (ctrl);
+ }
+ if (ATTN_LED(ctrl->ctrlcap)){
+ p_slot->hpc_ops->set_attention_status(p_slot, 0);
+ /* Wait for the command to complete */
+ wait_for_ctrl_irq (ctrl);
+ }
/* Done with exclusive hardware access */
up(&ctrl->crit_sect);

@@ -1566,59 +1633,83 @@
}
/* ***********Button Pressed (No action on 1st press...) */
else if (ctrl->event_queue[loop].event_type == INT_BUTTON_PRESS) {
- dbg("Button pressed\n");
-
- p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
- if (getstatus) {
- /* slot is on */
- dbg("slot is on\n");
- p_slot->state = BLINKINGOFF_STATE;
- info(msg_button_off, p_slot->number);
- } else {
- /* slot is off */
- dbg("slot is off\n");
- p_slot->state = BLINKINGON_STATE;
- info(msg_button_on, p_slot->number);
- }
-
- /* Wait for exclusive access to hardware */
- down(&ctrl->crit_sect);
-
- /* blink green LED and turn off amber */
- p_slot->hpc_ops->green_led_blink(p_slot);
- /* Wait for the command to complete */
- wait_for_ctrl_irq (ctrl);

- p_slot->hpc_ops->set_attention_status(p_slot, 0);
+ if (ATTN_BUTTN(ctrl->ctrlcap)) {
+ dbg("Button pressed\n");
+ p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
+ if (getstatus) {
+ /* slot is on */
+ dbg("slot is on\n");
+ p_slot->state = BLINKINGOFF_STATE;
+ info(msg_button_off, p_slot->number);
+ } else {
+ /* slot is off */
+ dbg("slot is off\n");
+ p_slot->state = BLINKINGON_STATE;
+ info(msg_button_on, p_slot->number);
+ }

- /* Wait for the command to complete */
- wait_for_ctrl_irq (ctrl);
+ /* Wait for exclusive access to hardware */
+ down(&ctrl->crit_sect);

- /* Done with exclusive hardware access */
- up(&ctrl->crit_sect);
+ /* blink green LED and turn off amber */
+ if (PWR_LED(ctrl->ctrlcap)) {
+ p_slot->hpc_ops->green_led_blink(p_slot);
+ /* Wait for the command to complete */
+ wait_for_ctrl_irq (ctrl);
+ }
+
+ if (ATTN_LED(ctrl->ctrlcap)) {
+ p_slot->hpc_ops->set_attention_status(p_slot, 0);
+
+ /* Wait for the command to complete */
+ wait_for_ctrl_irq (ctrl);
+ }
+
+ /* Done with exclusive hardware access */
+ up(&ctrl->crit_sect);

- init_timer(&p_slot->task_event);
- p_slot->task_event.expires = jiffies + 5 * HZ; /* 5 second delay */
- p_slot->task_event.function = (void (*)(unsigned long)) pushbutton_helper_thread;
- p_slot->task_event.data = (unsigned long) p_slot;
+ init_timer(&p_slot->task_event);
+ p_slot->task_event.expires = jiffies + 5 * HZ; /* 5 second delay */
+ p_slot->task_event.function = (void (*)(unsigned long)) pushbutton_helper_thread;
+ p_slot->task_event.data = (unsigned long) p_slot;

- dbg("add_timer p_slot = %p\n", (void *) p_slot);
- add_timer(&p_slot->task_event);
+ dbg("add_timer p_slot = %p\n", (void *) p_slot);
+ add_timer(&p_slot->task_event);
+ }
}
/***********POWER FAULT********************/
else if (ctrl->event_queue[loop].event_type == INT_POWER_FAULT) {
- dbg("power fault\n");
- /* Wait for exclusive access to hardware */
- down(&ctrl->crit_sect);
+ if (POWER_CTRL(ctrl->ctrlcap)) {
+ dbg("power fault\n");
+ /* Wait for exclusive access to hardware */
+ down(&ctrl->crit_sect);

- p_slot->hpc_ops->set_attention_status(p_slot, 1);
- wait_for_ctrl_irq (ctrl);
-
- p_slot->hpc_ops->green_led_off(p_slot);
- wait_for_ctrl_irq (ctrl);
+ if (ATTN_LED(ctrl->ctrlcap)) {
+ p_slot->hpc_ops->set_attention_status(p_slot, 1);
+ wait_for_ctrl_irq (ctrl);
+ }
+
+ if (PWR_LED(ctrl->ctrlcap)) {
+ p_slot->hpc_ops->green_led_off(p_slot);
+ wait_for_ctrl_irq (ctrl);
+ }

- /* Done with exclusive hardware access */
- up(&ctrl->crit_sect);
+ /* Done with exclusive hardware access */
+ up(&ctrl->crit_sect);
+ }
+ }
+ /***********SURPRISE REMOVAL********************/
+ else if ((ctrl->event_queue[loop].event_type == INT_PRESENCE_ON) ||
+ (ctrl->event_queue[loop].event_type == INT_PRESENCE_OFF)) {
+ if (HP_SUPR_RM(ctrl->ctrlcap)) {
+ dbg("Surprise Removal\n");
+ if (p_slot) {
+ surprise_rm_pending = (unsigned long) p_slot;
+ up(&event_semaphore);
+ update_slot_info(p_slot);
+ }
+ }
} else {
/* refresh notification */
if (p_slot)
@@ -1648,25 +1739,29 @@

/* Check to see if (latch closed, card present, power off) */
down(&p_slot->ctrl->crit_sect);
+
rc = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus);
if (rc || !getstatus) {
info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number);
up(&p_slot->ctrl->crit_sect);
return 1;
}
-
- rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
- if (rc || getstatus) {
- info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number);
- up(&p_slot->ctrl->crit_sect);
- return 1;
+ if (MRL_SENS(p_slot->ctrl->ctrlcap)) {
+ rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
+ if (rc || getstatus) {
+ info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number);
+ up(&p_slot->ctrl->crit_sect);
+ return 1;
+ }
}

- rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
- if (rc || getstatus) {
- info("%s: already enabled on slot(%x)\n", __FUNCTION__, p_slot->number);
- up(&p_slot->ctrl->crit_sect);
- return 1;
+ if (POWER_CTRL(p_slot->ctrl->ctrlcap)) {
+ rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
+ if (rc || getstatus) {
+ info("%s: already enabled on slot(%x)\n", __FUNCTION__, p_slot->number);
+ up(&p_slot->ctrl->crit_sect);
+ return 1;
+ }
}
up(&p_slot->ctrl->crit_sect);

@@ -1735,26 +1830,33 @@
/* Check to see if (latch closed, card present, power on) */
down(&p_slot->ctrl->crit_sect);

- ret = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus);
- if (ret || !getstatus) {
- info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number);
- up(&p_slot->ctrl->crit_sect);
- return 1;
+ if (!HP_SUPR_RM(p_slot->ctrl->ctrlcap)) {
+ ret = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus);
+ if (ret || !getstatus) {
+ info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number);
+ up(&p_slot->ctrl->crit_sect);
+ return 1;
+ }
}

- ret = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
- if (ret || getstatus) {
- info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number);
- up(&p_slot->ctrl->crit_sect);
- return 1;
+ if (MRL_SENS(p_slot->ctrl->ctrlcap)) {
+ ret = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
+ if (ret || getstatus) {
+ info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number);
+ up(&p_slot->ctrl->crit_sect);
+ return 1;
+ }
}

- ret = p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
- if (ret || !getstatus) {
- info("%s: already disabled slot(%x)\n", __FUNCTION__, p_slot->number);
- up(&p_slot->ctrl->crit_sect);
- return 1;
+ if (POWER_CTRL(p_slot->ctrl->ctrlcap)) {
+ ret = p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
+ if (ret || !getstatus) {
+ info("%s: already disabled slot(%x)\n", __FUNCTION__, p_slot->number);
+ up(&p_slot->ctrl->crit_sect);
+ return 1;
+ }
}
+
up(&p_slot->ctrl->crit_sect);

func = pciehp_slot_find(p_slot->bus, p_slot->device, index++);
diff -Nru a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
--- a/drivers/pci/hotplug/pciehp_hpc.c 2004-11-12 15:13:59 -08:00
+++ b/drivers/pci/hotplug/pciehp_hpc.c 2004-11-12 15:13:59 -08:00
@@ -182,7 +182,7 @@
#define MRL_SENS_PRSN 0x00000004
#define ATTN_LED_PRSN 0x00000008
#define PWR_LED_PRSN 0x00000010
-#define HP_SUPR_RM 0x00000020
+#define HP_SUPR_RM_SUP 0x00000020
#define HP_CAP 0x00000040
#define SLOT_PWR_VALUE 0x000003F8
#define SLOT_PWR_LIMIT 0x00000C00
@@ -237,8 +237,8 @@
static spinlock_t hpc_event_lock;

DEFINE_DBG_BUFFER /* Debug string buffer for entire HPC defined here */
-static struct php_ctlr_state_s *php_ctlr_list_head; /* HPC state linked list */
-static int ctlr_seq_num; /* Controller sequence # */
+static struct php_ctlr_state_s *php_ctlr_list_head = 0; /* HPC state linked list */
+static int ctlr_seq_num = 0; /* Controller sequence # */
static spinlock_t list_lock;

static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs);
@@ -691,8 +691,7 @@
int *num_ctlr_slots, /* number of slots in this HPC; only 1 in PCIE */
int *first_device_num, /* PCI dev num of the first slot in this PCIE */
int *physical_slot_num, /* phy slot num of the first slot in this PCIE */
- int *updown, /* physical_slot_num increament: 1 or -1 */
- int *flags)
+ u8 *ctrlcap)
{
struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle;
u32 slot_cap;
@@ -716,8 +715,9 @@
}

*physical_slot_num = slot_cap >> 19;
-
- *updown = -1;
+ dbg("%s: PSN %d \n", __FUNCTION__, *physical_slot_num);
+
+ *ctrlcap = slot_cap & 0x0000007f;

DBG_LEAVE_ROUTINE
return 0;
@@ -1259,7 +1259,7 @@
static int first = 1;
u16 temp_word;
u16 cap_reg;
- u16 intr_enable;
+ u16 intr_enable = 0;
u32 slot_cap;
int cap_base, saved_cap_base;
u16 slot_status, slot_ctrl;
@@ -1412,6 +1412,7 @@
} else
php_ctlr->irq = pdev->irq;
}
+
rc = request_irq(php_ctlr->irq, pcie_isr, SA_SHIRQ, MY_NAME, (void *) ctrl);
dbg("%s: request_irq %d for hpc%d (returns %d)\n", __FUNCTION__, php_ctlr->irq, ctlr_seq_num, rc);
if (rc) {
@@ -1426,9 +1427,18 @@
goto abort_free_ctlr;
}
dbg("%s: SLOT_CTRL %x value read %x\n", __FUNCTION__, SLOT_CTRL, temp_word);
+ dbg("%s: slot_cap %x\n", __FUNCTION__, slot_cap);

- intr_enable = ATTN_BUTTN_ENABLE | PWR_FAULT_DETECT_ENABLE | MRL_DETECT_ENABLE |
- PRSN_DETECT_ENABLE;
+ intr_enable = intr_enable | PRSN_DETECT_ENABLE;
+
+ if (ATTN_BUTTN(slot_cap))
+ intr_enable = intr_enable | ATTN_BUTTN_ENABLE;
+
+ if (POWER_CTRL(slot_cap))
+ intr_enable = intr_enable | PWR_FAULT_DETECT_ENABLE;
+
+ if (MRL_SENS(slot_cap))
+ intr_enable = intr_enable | MRL_DETECT_ENABLE;

temp_word = (temp_word & ~intr_enable) | intr_enable;

diff -Nru a/drivers/pci/hotplug/pciehprm_acpi.c b/drivers/pci/hotplug/pciehprm_acpi.c
--- a/drivers/pci/hotplug/pciehprm_acpi.c 2004-11-12 15:13:59 -08:00
+++ b/drivers/pci/hotplug/pciehprm_acpi.c 2004-11-12 15:13:59 -08:00
@@ -32,6 +32,7 @@
#include <linux/init.h>
#include <linux/acpi.h>
#include <linux/efi.h>
+#include <linux/pci-acpi.h>
#include <asm/uaccess.h>
#include <asm/system.h>
#ifdef CONFIG_IA64
@@ -50,6 +51,14 @@
#define METHOD_NAME__HPP "_HPP"
#define METHOD_NAME_OSHP "OSHP"

+/* Status code for running acpi method to gain native control */
+#define NC_NOT_RUN 0
+#define OSC_NOT_EXIST 1
+#define OSC_RUN_FAILED 2
+#define OSHP_NOT_EXIST 3
+#define OSHP_RUN_FAILED 4
+#define NC_RUN_SUCCESS 5
+
#define PHP_RES_BUS 0xA0
#define PHP_RES_IO 0xA1
#define PHP_RES_MEM 0xA2
@@ -125,7 +134,9 @@
}

static void acpi_get__hpp ( struct acpi_bridge *ab);
-static void acpi_run_oshp ( struct acpi_bridge *ab);
+static int acpi_run_oshp ( struct acpi_bridge *ab);
+static int osc_run_status = NC_NOT_RUN;
+static int oshp_run_status = NC_NOT_RUN;

static int acpi_add_slot_to_php_slots(
struct acpi_bridge *ab,
@@ -158,8 +169,9 @@
ab->scanned += 1;
if (!ab->_hpp)
acpi_get__hpp(ab);
-
- acpi_run_oshp(ab);
+
+ if (osc_run_status == OSC_NOT_EXIST)
+ oshp_run_status = acpi_run_oshp(ab);

if (sun != samesun) {
info("acpi_pciehprm: Slot sun(%x) at s:b:d:f=0x%02x:%02x:%02x:%02x\n",
@@ -238,7 +250,7 @@
kfree(ret_buf.pointer);
}

-static void acpi_run_oshp ( struct acpi_bridge *ab)
+static int acpi_run_oshp ( struct acpi_bridge *ab)
{
acpi_status status;
u8 *path_name = acpi_path_name(ab->handle);
@@ -248,9 +260,13 @@
status = acpi_evaluate_object(ab->handle, METHOD_NAME_OSHP, NULL, &ret_buf);
if (ACPI_FAILURE(status)) {
err("acpi_pciehprm:%s OSHP fails=0x%x\n", path_name, status);
- } else
+ oshp_run_status = (status == AE_NOT_FOUND) ? OSHP_NOT_EXIST : OSHP_RUN_FAILED;
+ } else {
+ oshp_run_status = NC_RUN_SUCCESS;
dbg("acpi_pciehprm:%s OSHP passes =0x%x\n", path_name, status);
- return;
+ dbg("acpi_pciehprm:%s oshp_run_status =0x%x\n", path_name, oshp_run_status);
+ }
+ return oshp_run_status;
}

static acpi_status acpi_evaluate_crs(
@@ -1056,6 +1072,16 @@
kfree(ab);
return NULL;
}
+
+ status = pci_osc_control_set (OSC_PCI_EXPRESS_NATIVE_HP_CONTROL);
+ if (ACPI_FAILURE(status)) {
+ err("%s: status %x\n", __FUNCTION__, status);
+ osc_run_status = (status == AE_NOT_FOUND) ? OSC_NOT_EXIST : OSC_RUN_FAILED;
+ } else {
+ osc_run_status = NC_RUN_SUCCESS;
+ }
+ dbg("%s: osc_run_status %x\n", __FUNCTION__, osc_run_status);
+
build_a_bridge(ab, ab);

return ab;
@@ -1140,6 +1166,11 @@
rc = pciehprm_acpi_scan_pci();
if (rc)
return rc;
+
+ if ((oshp_run_status != NC_RUN_SUCCESS) && (osc_run_status != NC_RUN_SUCCESS)) {
+ err("Fails to gain control of native hot-plug\n");
+ rc = -ENODEV;
+ }

dbg("pciehprm ACPI init %s\n", (rc)?"fail":"success");
return rc;
diff -Nru a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/drivers/pci/pci-acpi.c 2004-11-12 15:13:59 -08:00
@@ -0,0 +1,209 @@
+/*
+ * File: pci-acpi.c
+ * Purpose: Provide PCI supports in ACPI
+ *
+ * Copyright (C) 2004 Intel
+ * Copyright (C) Tom Long Nguyen ([email protected])
+ */
+
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/module.h>
+#include <acpi/acpi.h>
+#include <acpi/acnamesp.h>
+#include <acpi/acresrc.h>
+#include <acpi/acpi_bus.h>
+
+#include <linux/pci-acpi.h>
+
+static u32 ctrlset_buf[3] = {0, 0, 0};
+static u32 global_ctrlsets = 0;
+u8 OSC_UUID[16] = {0x5B, 0x4D, 0xDB, 0x33, 0xF7, 0x1F, 0x1C, 0x40, 0x96, 0x57, 0x74, 0x41, 0xC0, 0x3D, 0xD7, 0x66};
+
+static acpi_status
+acpi_query_osc (
+ acpi_handle handle,
+ u32 level,
+ void *context,
+ void **retval )
+{
+ acpi_status status;
+ struct acpi_object_list input;
+ union acpi_object in_params[4];
+ struct acpi_buffer output;
+ union acpi_object out_obj;
+ u32 osc_dw0;
+
+ /* Setting up output buffer */
+ output.length = sizeof(out_obj) + 3*sizeof(u32);
+ output.pointer = &out_obj;
+
+ /* Setting up input parameters */
+ input.count = 4;
+ input.pointer = in_params;
+ in_params[0].type = ACPI_TYPE_BUFFER;
+ in_params[0].buffer.length = 16;
+ in_params[0].buffer.pointer = OSC_UUID;
+ in_params[1].type = ACPI_TYPE_INTEGER;
+ in_params[1].integer.value = 1;
+ in_params[2].type = ACPI_TYPE_INTEGER;
+ in_params[2].integer.value = 3;
+ in_params[3].type = ACPI_TYPE_BUFFER;
+ in_params[3].buffer.length = 12;
+ in_params[3].buffer.pointer = (u8 *)context;
+
+ status = acpi_evaluate_object(handle, "_OSC", &input, &output);
+ if (ACPI_FAILURE (status)) {
+ printk(KERN_DEBUG
+ "Evaluate _OSC Set fails. Status = 0x%04x\n", status);
+ return status;
+ }
+ if (out_obj.type != ACPI_TYPE_BUFFER) {
+ printk(KERN_DEBUG
+ "Evaluate _OSC returns wrong type\n");
+ return AE_TYPE;
+ }
+ osc_dw0 = *((u32 *) out_obj.buffer.pointer);
+ if (osc_dw0) {
+ if (osc_dw0 & OSC_REQUEST_ERROR)
+ printk(KERN_DEBUG "_OSC request fails\n");
+ if (osc_dw0 & OSC_INVALID_UUID_ERROR)
+ printk(KERN_DEBUG "_OSC invalid UUID\n");
+ if (osc_dw0 & OSC_INVALID_REVISION_ERROR)
+ printk(KERN_DEBUG "_OSC invalid revision\n");
+ if (osc_dw0 & OSC_CAPABILITIES_MASK_ERROR) {
+ /* Update Global Control Set */
+ global_ctrlsets = *((u32 *)(out_obj.buffer.pointer+8));
+ return AE_OK;
+ }
+ return AE_ERROR;
+ }
+
+ /* Update Global Control Set */
+ global_ctrlsets = *((u32 *)(out_obj.buffer.pointer + 8));
+ return AE_OK;
+}
+
+
+static acpi_status
+acpi_run_osc (
+ acpi_handle handle,
+ u32 level,
+ void *context,
+ void **retval )
+{
+ acpi_status status;
+ struct acpi_object_list input;
+ union acpi_object in_params[4];
+ struct acpi_buffer output;
+ union acpi_object out_obj;
+ u32 osc_dw0;
+
+ /* Setting up output buffer */
+ output.length = sizeof(out_obj) + 3*sizeof(u32);
+ output.pointer = &out_obj;
+
+ /* Setting up input parameters */
+ input.count = 4;
+ input.pointer = in_params;
+ in_params[0].type = ACPI_TYPE_BUFFER;
+ in_params[0].buffer.length = 16;
+ in_params[0].buffer.pointer = OSC_UUID;
+ in_params[1].type = ACPI_TYPE_INTEGER;
+ in_params[1].integer.value = 1;
+ in_params[2].type = ACPI_TYPE_INTEGER;
+ in_params[2].integer.value = 3;
+ in_params[3].type = ACPI_TYPE_BUFFER;
+ in_params[3].buffer.length = 12;
+ in_params[3].buffer.pointer = (u8 *)context;
+
+ status = acpi_evaluate_object(handle, "_OSC", &input, &output);
+ if (ACPI_FAILURE (status)) {
+ printk(KERN_DEBUG
+ "Evaluate _OSC Set fails. Status = 0x%04x\n", status);
+ return status;
+ }
+ if (out_obj.type != ACPI_TYPE_BUFFER) {
+ printk(KERN_DEBUG
+ "Evaluate _OSC returns wrong type\n");
+ return AE_TYPE;
+ }
+ osc_dw0 = *((u32 *) out_obj.buffer.pointer);
+ if (osc_dw0) {
+ if (osc_dw0 & OSC_REQUEST_ERROR)
+ printk(KERN_DEBUG "_OSC request fails\n");
+ if (osc_dw0 & OSC_INVALID_UUID_ERROR)
+ printk(KERN_DEBUG "_OSC invalid UUID\n");
+ if (osc_dw0 & OSC_INVALID_REVISION_ERROR)
+ printk(KERN_DEBUG "_OSC invalid revision\n");
+ if (osc_dw0 & OSC_CAPABILITIES_MASK_ERROR) {
+ printk(KERN_DEBUG "_OSC FW not grant req. control\n");
+ return AE_SUPPORT;
+ }
+ return AE_ERROR;
+ }
+ return AE_OK;
+}
+
+/**
+ * pci_osc_support_set - register OS support to Firmware
+ * @flags: OS support bits
+ *
+ * Update OS support fields and doing a _OSC Query to obtain an update
+ * from Firmware on supported control bits.
+ **/
+acpi_status pci_osc_support_set(u32 flags)
+{
+ u32 temp;
+
+ if (!(flags & OSC_SUPPORT_MASKS)) {
+ return AE_TYPE;
+ }
+ ctrlset_buf[OSC_SUPPORT_TYPE] |= (flags & OSC_SUPPORT_MASKS);
+
+ /* do _OSC query for all possible controls */
+ temp = ctrlset_buf[OSC_CONTROL_TYPE];
+ ctrlset_buf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE;
+ ctrlset_buf[OSC_CONTROL_TYPE] = OSC_CONTROL_MASKS;
+ acpi_get_devices ( PCI_ROOT_HID_STRING,
+ acpi_query_osc,
+ ctrlset_buf,
+ NULL );
+ ctrlset_buf[OSC_QUERY_TYPE] = !OSC_QUERY_ENABLE;
+ ctrlset_buf[OSC_CONTROL_TYPE] = temp;
+ return AE_OK;
+}
+EXPORT_SYMBOL(pci_osc_support_set);
+
+/**
+ * pci_osc_control_set - commit requested control to Firmware
+ * @flags: driver's requested control bits
+ *
+ * Attempt to take control from Firmware on requested control bits.
+ **/
+acpi_status pci_osc_control_set(u32 flags)
+{
+ acpi_status status;
+ u32 ctrlset;
+
+ ctrlset = (flags & OSC_CONTROL_MASKS);
+ if (!ctrlset) {
+ return AE_TYPE;
+ }
+ if (ctrlset_buf[OSC_SUPPORT_TYPE] &&
+ ((global_ctrlsets & ctrlset) != ctrlset)) {
+ return AE_SUPPORT;
+ }
+ ctrlset_buf[OSC_CONTROL_TYPE] |= ctrlset;
+ status = acpi_get_devices ( PCI_ROOT_HID_STRING,
+ acpi_run_osc,
+ ctrlset_buf,
+ NULL );
+ if (ACPI_FAILURE (status)) {
+ ctrlset_buf[OSC_CONTROL_TYPE] &= ~ctrlset;
+ }
+
+ return status;
+}
+EXPORT_SYMBOL(pci_osc_control_set);
diff -Nru a/include/linux/pci-acpi.h b/include/linux/pci-acpi.h
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/include/linux/pci-acpi.h 2004-11-12 15:13:59 -08:00
@@ -0,0 +1,61 @@
+/*
+ * File pci-acpi.h
+ *
+ * Copyright (C) 2004 Intel
+ * Copyright (C) Tom Long Nguyen ([email protected])
+ */
+
+#ifndef _PCI_ACPI_H_
+#define _PCI_ACPI_H_
+
+#define OSC_QUERY_TYPE 0
+#define OSC_SUPPORT_TYPE 1
+#define OSC_CONTROL_TYPE 2
+#define OSC_SUPPORT_MASKS 0x1f
+
+/*
+ * _OSC DW0 Definition
+ */
+#define OSC_QUERY_ENABLE 1
+#define OSC_REQUEST_ERROR 2
+#define OSC_INVALID_UUID_ERROR 4
+#define OSC_INVALID_REVISION_ERROR 8
+#define OSC_CAPABILITIES_MASK_ERROR 16
+
+/*
+ * _OSC DW1 Definition (OS Support Fields)
+ */
+#define OSC_EXT_PCI_CONFIG_SUPPORT 1
+#define OSC_ACTIVE_STATE_PWR_SUPPORT 2
+#define OSC_CLOCK_PWR_CAPABILITY_SUPPORT 4
+#define OSC_PCI_SEGMENT_GROUPS_SUPPORT 8
+#define OSC_MSI_SUPPORT 16
+
+/*
+ * _OSC DW1 Definition (OS Control Fields)
+ */
+#define OSC_PCI_EXPRESS_NATIVE_HP_CONTROL 1
+#define OSC_SHPC_NATIVE_HP_CONTROL 2
+#define OSC_PCI_EXPRESS_PME_CONTROL 4
+#define OSC_PCI_EXPRESS_AER_CONTROL 8
+#define OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL 16
+
+#define OSC_CONTROL_MASKS (OSC_PCI_EXPRESS_NATIVE_HP_CONTROL | \
+ OSC_SHPC_NATIVE_HP_CONTROL | \
+ OSC_PCI_EXPRESS_PME_CONTROL | \
+ OSC_PCI_EXPRESS_AER_CONTROL | \
+ OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL)
+
+#ifdef CONFIG_ACPI
+extern acpi_status pci_osc_control_set(u32 flags);
+extern acpi_status pci_osc_support_set(u32 flags);
+#else
+#if !defined(acpi_status)
+typedef u32 acpi_status;
+#define AE_ERROR (acpi_status) (0x0001)
+#endif
+static inline acpi_status pci_osc_control_set(u32 flags) {return AE_ERROR;}
+static inline acpi_status pci_osc_support_set(u32 flags) {return AE_ERROR;}
+#endif
+
+#endif /* _PCI_ACPI_H_ */

2004-11-13 01:56:23

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] PCI fixes for 2.6.10-rc1

ChangeSet 1.2026.66.21, 2004/11/10 16:45:21-08:00, [email protected]

[PATCH] scx200_wdt.c: replace pci_find_device with pci_dev_present

Patch to replace the soon to be defunct pci_find_device with the
new function pci_dev_present. I found 8 .c files (outside of /drivers/net)
that used pci_find_device without the dev it returned. therefore it
was replaceable with the new function.


Signed-off-by: Hanna Linder <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


drivers/char/watchdog/scx200_wdt.c | 12 ++++++------
1 files changed, 6 insertions(+), 6 deletions(-)


diff -Nru a/drivers/char/watchdog/scx200_wdt.c b/drivers/char/watchdog/scx200_wdt.c
--- a/drivers/char/watchdog/scx200_wdt.c 2004-11-12 15:12:19 -08:00
+++ b/drivers/char/watchdog/scx200_wdt.c 2004-11-12 15:12:19 -08:00
@@ -217,6 +217,11 @@
static int __init scx200_wdt_init(void)
{
int r;
+ static struct pci_device_id ns_sc[] = {
+ { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SCx200_BRIDGE) },
+ { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SC1100_BRIDGE) },
+ { },
+ };

printk(KERN_DEBUG NAME ": NatSemi SCx200 Watchdog Driver\n");

@@ -224,12 +229,7 @@
* First check that this really is a NatSemi SCx200 CPU or a Geode
* SC1100 processor
*/
- if ((pci_find_device(PCI_VENDOR_ID_NS,
- PCI_DEVICE_ID_NS_SCx200_BRIDGE,
- NULL)) == NULL
- && (pci_find_device(PCI_VENDOR_ID_NS,
- PCI_DEVICE_ID_NS_SC1100_BRIDGE,
- NULL)) == NULL)
+ if (!pci_dev_present(ns_sc))
return -ENODEV;

/* More sanity checks, verify that the configuration block is there */

2004-11-12 23:31:54

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] PCI fixes for 2.6.10-rc1

ChangeSet 1.2091.1.6, 2004/11/12 14:02:20-08:00, [email protected]

[PATCH] gemini_pci.c: replace pci_find_device with for_each_pci_dev

Signed-off-by: Hanna Linder <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


arch/ppc/platforms/gemini_pci.c | 2 +-
1 files changed, 1 insertion(+), 1 deletion(-)


diff -Nru a/arch/ppc/platforms/gemini_pci.c b/arch/ppc/platforms/gemini_pci.c
--- a/arch/ppc/platforms/gemini_pci.c 2004-11-12 15:11:19 -08:00
+++ b/arch/ppc/platforms/gemini_pci.c 2004-11-12 15:11:19 -08:00
@@ -15,7 +15,7 @@
int i;
struct pci_dev *dev = NULL;

- while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
+ for_each_pci_dev(dev) {
for(i = 0; i < 6; i++) {
if (dev->resource[i].flags & IORESOURCE_IO) {
dev->resource[i].start |= (0xfe << 24);

2004-11-13 01:56:22

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] PCI fixes for 2.6.10-rc1

ChangeSet 1.2026.66.14, 2004/11/05 15:05:43-08:00, [email protected]

[PATCH] Lock initializer unifying Batch 2 (PCI)

To make spinlock/rwlock initialization consistent all over the kernel,
this patch converts explicit lock-initializers into spin_lock_init() and
rwlock_init() calls.

Currently, spinlocks and rwlocks are initialized in two different ways:

lock = SPIN_LOCK_UNLOCKED
spin_lock_init(&lock)

rwlock = RW_LOCK_UNLOCKED
rwlock_init(&rwlock)

this patch converts all explicit lock initializations to
spin_lock_init() or rwlock_init(). (Besides consistency this also helps
automatic lock validators and debugging code.)

The conversion was done with a script, it was verified manually and it
was reviewed, compiled and tested as far as possible on x86, ARM, PPC.

There is no runtime overhead or actual code change resulting out of this
patch, because spin_lock_init() and rwlock_init() are macros and are
thus equivalent to the explicit initialization method.

That's the second batch of the unifying patches.

Signed-off-by: Thomas Gleixner <[email protected]>
Acked-by: Ingo Molnar <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


drivers/pci/hotplug/acpiphp_glue.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)


diff -Nru a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
--- a/drivers/pci/hotplug/acpiphp_glue.c 2004-11-12 15:13:13 -08:00
+++ b/drivers/pci/hotplug/acpiphp_glue.c 2004-11-12 15:13:13 -08:00
@@ -389,7 +389,7 @@

bridge->pci_bus = pci_find_bus(seg, bus);

- bridge->res_lock = SPIN_LOCK_UNLOCKED;
+ spin_lock_init(&bridge->res_lock);

/* to be overridden when we decode _CRS */
bridge->sub = bridge->bus;
@@ -457,7 +457,7 @@
return;
}

- bridge->res_lock = SPIN_LOCK_UNLOCKED;
+ spin_lock_init(&bridge->res_lock);

bridge->bus = bridge->pci_bus->number;
bridge->sub = bridge->pci_bus->subordinate;

2004-11-13 01:56:21

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] PCI fixes for 2.6.10-rc1

ChangeSet 1.2091.1.22, 2004/11/12 14:11:29-08:00, [email protected]

[PATCH] pcore.c: replace pci_find_device with pci_get_device

As pci_find_device is going away I've replaced it with pci_get_device
and pci_dev_put.


Signed-off-by: Hanna Linder <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


arch/ppc/platforms/pcore.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletion(-)


diff -Nru a/arch/ppc/platforms/pcore.c b/arch/ppc/platforms/pcore.c
--- a/arch/ppc/platforms/pcore.c 2004-11-12 15:09:19 -08:00
+++ b/arch/ppc/platforms/pcore.c 2004-11-12 15:09:19 -08:00
@@ -89,7 +89,7 @@
{
struct pci_dev *dev;

- if ((dev = pci_find_device(PCI_VENDOR_ID_WINBOND,
+ if ((dev = pci_get_device(PCI_VENDOR_ID_WINBOND,
PCI_DEVICE_ID_WINBOND_83C553,
0)))
{
@@ -108,6 +108,7 @@
*/
outb(0x00, PCORE_WINBOND_PRI_EDG_LVL);
outb(0x1e, PCORE_WINBOND_SEC_EDG_LVL);
+ pci_dev_put(dev);
}
}


2004-11-12 23:31:54

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] PCI fixes for 2.6.10-rc1

ChangeSet 1.2091.1.11, 2004/11/12 14:07:33-08:00, [email protected]

[PATCH] drm_drv.h: replace pci_find_device

As pci_find_device is going away I've replaced it with pci_get_device.
for_each_pci_dev is a macro wrapper around pci_get_device.


Signed-off-by: Hanna Linder <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


drivers/char/drm/drm_drv.h | 3 +--
1 files changed, 1 insertion(+), 2 deletions(-)


diff -Nru a/drivers/char/drm/drm_drv.h b/drivers/char/drm/drm_drv.h
--- a/drivers/char/drm/drm_drv.h 2004-11-12 15:10:42 -08:00
+++ b/drivers/char/drm/drm_drv.h 2004-11-12 15:10:42 -08:00
@@ -556,9 +556,8 @@

DRM(mem_init)();

- while ((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) {
+ for_each_pci_dev(pdev)
DRM(probe)(pdev);
- }
return 0;
}


2004-11-12 23:31:53

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] PCI fixes for 2.6.10-rc1

ChangeSet 1.2026.66.17, 2004/11/05 15:06:47-08:00, [email protected]

[PATCH] cyclades.c: replace pci_find_device

As pci_find_device is going away I've replaced it with pci_get_device.
If someone with this hardware could test it I would appreciate it.


Signed-off-by: Hanna Linder <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


drivers/char/cyclades.c | 2 +-
1 files changed, 1 insertion(+), 1 deletion(-)


diff -Nru a/drivers/char/cyclades.c b/drivers/char/cyclades.c
--- a/drivers/char/cyclades.c 2004-11-12 15:12:50 -08:00
+++ b/drivers/char/cyclades.c 2004-11-12 15:12:50 -08:00
@@ -4725,7 +4725,7 @@
for (i = 0; i < NR_CARDS; i++) {
/* look for a Cyclades card by vendor and device id */
while((device_id = cy_pci_dev_id[dev_index]) != 0) {
- if((pdev = pci_find_device(PCI_VENDOR_ID_CYCLADES,
+ if((pdev = pci_get_device(PCI_VENDOR_ID_CYCLADES,
device_id, pdev)) == NULL) {
dev_index++; /* try next device id */
} else {

2004-11-12 23:31:53

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] PCI fixes for 2.6.10-rc1

ChangeSet 1.2026.66.15, 2004/11/05 15:06:04-08:00, [email protected]

[PATCH] PCI: ASPM patch for

This is the ASPM patch against 2.6.10-rc1-mm2.

As mentioned in my last email, this patch has a slight difference than
the one for 2.6.10-rc1, because the irqbalance quirk was moved from
drivers/pci/quirks.c in 2.6.10-rc1 to arch/i386/kernel/quirks.c in
2.6.10-rc1-mm2.

Signed-off-by: Dely Sy <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


arch/i386/kernel/quirks.c | 4 -
arch/i386/pci/fixup.c | 91 ++++++++++++++++++++++++++++++++++++++
drivers/pci/hotplug/pciehp_ctrl.c | 9 +++
drivers/pci/hotplug/pciehp_hpc.c | 6 +-
drivers/pci/hotplug/pciehp_pci.c | 8 +++
drivers/pci/hotplug/shpchp_hpc.c | 1
drivers/pci/pci.h | 2
drivers/pci/quirks.c | 18 ++++---
include/linux/pci_ids.h | 8 ++-
9 files changed, 133 insertions(+), 14 deletions(-)


diff -Nru a/arch/i386/kernel/quirks.c b/arch/i386/kernel/quirks.c
--- a/arch/i386/kernel/quirks.c 2004-11-12 15:13:05 -08:00
+++ b/arch/i386/kernel/quirks.c 2004-11-12 15:13:05 -08:00
@@ -6,7 +6,7 @@

#if defined(CONFIG_X86_IO_APIC) && defined(CONFIG_SMP)

-void __init quirk_intel_irqbalance(struct pci_dev *dev)
+void __devinit quirk_intel_irqbalance(struct pci_dev *dev)
{
u8 config, rev;
u32 word;
@@ -45,5 +45,5 @@
}
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7320_MCH, quirk_intel_irqbalance);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7525_MCH, quirk_intel_irqbalance);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SMCH, quirk_intel_irqbalance);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7520_MCH, quirk_intel_irqbalance);
#endif
diff -Nru a/arch/i386/pci/fixup.c b/arch/i386/pci/fixup.c
--- a/arch/i386/pci/fixup.c 2004-11-12 15:13:05 -08:00
+++ b/arch/i386/pci/fixup.c 2004-11-12 15:13:05 -08:00
@@ -255,3 +255,94 @@
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2, pci_fixup_nforce2);

+/* Max PCI Express root ports */
+#define MAX_PCIEROOT 6
+static int quirk_aspm_offset[MAX_PCIEROOT << 3];
+
+#define GET_INDEX(a, b) (((a - PCI_DEVICE_ID_INTEL_MCH_PA) << 3) + b)
+
+static int quirk_pcie_aspm_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value)
+{
+ return raw_pci_ops->read(0, bus->number, devfn, where, size, value);
+}
+
+/*
+ * Replace the original pci bus ops for write with a new one that will filter
+ * the request to insure ASPM cannot be enabled.
+ */
+static int quirk_pcie_aspm_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value)
+{
+ u8 offset;
+
+ offset = quirk_aspm_offset[GET_INDEX(bus->self->device, devfn)];
+
+ if ((offset) && (where == offset))
+ value = value & 0xfffffffc;
+
+ return raw_pci_ops->write(0, bus->number, devfn, where, size, value);
+}
+
+struct pci_ops quirk_pcie_aspm_ops = {
+ .read = quirk_pcie_aspm_read,
+ .write = quirk_pcie_aspm_write,
+};
+
+/*
+ * Prevents PCI Express ASPM (Active State Power Management) being enabled.
+ *
+ * Save the register offset, where the ASPM control bits are located,
+ * for each PCI Express device that is in the device list of
+ * the root port in an array for fast indexing. Replace the bus ops
+ * with the modified one.
+ */
+void pcie_rootport_aspm_quirk(struct pci_dev *pdev)
+{
+ int cap_base, i;
+ struct pci_bus *pbus;
+ struct pci_dev *dev;
+
+ if ((pbus = pdev->subordinate) == NULL)
+ return;
+
+ /*
+ * Check if the DID of pdev matches one of the six root ports. This
+ * check is needed in the case this function is called directly by the
+ * hot-plug driver.
+ */
+ if ((pdev->device < PCI_DEVICE_ID_INTEL_MCH_PA) ||
+ (pdev->device > PCI_DEVICE_ID_INTEL_MCH_PC1))
+ return;
+
+ if (list_empty(&pbus->devices)) {
+ /*
+ * If no device is attached to the root port at power-up or
+ * after hot-remove, the pbus->devices is empty and this code
+ * will set the offsets to zero and the bus ops to parent's bus
+ * ops, which is unmodified.
+ */
+ for (i= GET_INDEX(pdev->device, 0); i <= GET_INDEX(pdev->device, 7); ++i)
+ quirk_aspm_offset[i] = 0;
+
+ pbus->ops = pbus->parent->ops;
+ } else {
+ /*
+ * If devices are attached to the root port at power-up or
+ * after hot-add, the code loops through the device list of
+ * each root port to save the register offsets and replace the
+ * bus ops.
+ */
+ list_for_each_entry(dev, &pbus->devices, bus_list) {
+ /* There are 0 to 8 devices attached to this bus */
+ cap_base = pci_find_capability(dev, PCI_CAP_ID_EXP);
+ quirk_aspm_offset[GET_INDEX(pdev->device, dev->devfn)]= cap_base + 0x10;
+ }
+ pbus->ops = &quirk_pcie_aspm_ops;
+ }
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MCH_PA, pcie_rootport_aspm_quirk );
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MCH_PA1, pcie_rootport_aspm_quirk );
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MCH_PB, pcie_rootport_aspm_quirk );
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MCH_PB1, pcie_rootport_aspm_quirk );
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MCH_PC, pcie_rootport_aspm_quirk );
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MCH_PC1, pcie_rootport_aspm_quirk );
+
diff -Nru a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c
--- a/drivers/pci/hotplug/pciehp_ctrl.c 2004-11-12 15:13:05 -08:00
+++ b/drivers/pci/hotplug/pciehp_ctrl.c 2004-11-12 15:13:05 -08:00
@@ -38,6 +38,7 @@
#include <linux/wait.h>
#include <linux/smp_lock.h>
#include <linux/pci.h>
+#include "../pci.h"
#include "pciehp.h"
#include "pciehprm.h"

@@ -1220,7 +1221,13 @@
pciehp_configure_device(ctrl, new_func);
}
} while (new_func);
-
+
+ /*
+ * Some PCI Express root ports require fixup after hot-plug operation.
+ */
+ if (pcie_mch_quirk)
+ pci_fixup_device(pci_fixup_final, ctrl->pci_dev);
+
if (PWR_LED(ctrl->ctrlcap)) {
/* Wait for exclusive access to hardware */
down(&ctrl->crit_sect);
diff -Nru a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
--- a/drivers/pci/hotplug/pciehp_hpc.c 2004-11-12 15:13:05 -08:00
+++ b/drivers/pci/hotplug/pciehp_hpc.c 2004-11-12 15:13:05 -08:00
@@ -741,6 +741,8 @@
if (php_ctlr->irq) {
free_irq(php_ctlr->irq, ctrl);
php_ctlr->irq = 0;
+ if (!pcie_mch_quirk)
+ pci_disable_msi(php_ctlr->pci_dev);
}
}
if (php_ctlr->pci_dev)
@@ -1402,8 +1404,8 @@
start_int_poll_timer( php_ctlr, 10 ); /* start with 10 second delay */
} else {
/* Installs the interrupt handler */
- dbg("%s: pciehp_msi_quirk = %x\n", __FUNCTION__, pciehp_msi_quirk);
- if (!pciehp_msi_quirk) {
+ dbg("%s: pcie_mch_quirk = %x\n", __FUNCTION__, pcie_mch_quirk);
+ if (!pcie_mch_quirk) {
rc = pci_enable_msi(pdev);
if (rc) {
info("Can't get msi for the hotplug controller\n");
diff -Nru a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c
--- a/drivers/pci/hotplug/pciehp_pci.c 2004-11-12 15:13:05 -08:00
+++ b/drivers/pci/hotplug/pciehp_pci.c 2004-11-12 15:13:05 -08:00
@@ -82,9 +82,11 @@
{
int rc = 0;
int j;
+ struct pci_bus *pbus;

dbg("%s: bus/dev/func = %x/%x/%x\n", __FUNCTION__, func->bus,
func->device, func->function);
+ pbus = func->pci_dev->bus;

for (j=0; j<8 ; j++) {
struct pci_dev* temp = pci_find_slot(func->bus,
@@ -93,6 +95,12 @@
pci_remove_bus_device(temp);
}
}
+ /*
+ * Some PCI Express root ports require fixup after hot-plug operation.
+ */
+ if (pcie_mch_quirk)
+ pci_fixup_device(pci_fixup_final, pbus->self);
+
return rc;
}

diff -Nru a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c
--- a/drivers/pci/hotplug/shpchp_hpc.c 2004-11-12 15:13:05 -08:00
+++ b/drivers/pci/hotplug/shpchp_hpc.c 2004-11-12 15:13:05 -08:00
@@ -792,6 +792,7 @@
if (php_ctlr->irq) {
free_irq(php_ctlr->irq, ctrl);
php_ctlr->irq = 0;
+ pci_disable_msi(php_ctlr->pci_dev);
}
}
if (php_ctlr->pci_dev) {
diff -Nru a/drivers/pci/pci.h b/drivers/pci/pci.h
--- a/drivers/pci/pci.h 2004-11-12 15:13:05 -08:00
+++ b/drivers/pci/pci.h 2004-11-12 15:13:05 -08:00
@@ -61,7 +61,7 @@
/* Lock for read/write access to pci device and bus lists */
extern spinlock_t pci_bus_lock;

-extern int pciehp_msi_quirk;
+extern int pcie_mch_quirk;
extern struct device_attribute pci_dev_attrs[];

/**
diff -Nru a/drivers/pci/quirks.c b/drivers/pci/quirks.c
--- a/drivers/pci/quirks.c 2004-11-12 15:13:05 -08:00
+++ b/drivers/pci/quirks.c 2004-11-12 15:13:05 -08:00
@@ -1135,7 +1135,7 @@
#endif

#ifdef CONFIG_SCSI_SATA
-static void __init quirk_intel_ide_combined(struct pci_dev *pdev)
+static void __devinit quirk_intel_ide_combined(struct pci_dev *pdev)
{
u8 prog, comb, tmp;
int ich = 0;
@@ -1209,14 +1209,15 @@
#endif /* CONFIG_SCSI_SATA */


-int pciehp_msi_quirk;
+int pcie_mch_quirk;

-static void __devinit quirk_pciehp_msi(struct pci_dev *pdev)
+static void __devinit quirk_pcie_mch(struct pci_dev *pdev)
{
- pciehp_msi_quirk = 1;
+ pcie_mch_quirk = 1;
}
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SMCH, quirk_pciehp_msi );
-
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7520_MCH, quirk_pcie_mch );
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7320_MCH, quirk_pcie_mch );
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7525_MCH, quirk_pcie_mch );

static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, struct pci_fixup *end)
{
@@ -1265,4 +1266,7 @@
pci_do_fixups(dev, start, end);
}

-EXPORT_SYMBOL(pciehp_msi_quirk);
+EXPORT_SYMBOL(pcie_mch_quirk);
+#ifdef CONFIG_HOTPLUG
+EXPORT_SYMBOL(pci_fixup_device);
+#endif
diff -Nru a/include/linux/pci_ids.h b/include/linux/pci_ids.h
--- a/include/linux/pci_ids.h 2004-11-12 15:13:05 -08:00
+++ b/include/linux/pci_ids.h 2004-11-12 15:13:05 -08:00
@@ -2206,8 +2206,14 @@
#define PCI_DEVICE_ID_INTEL_82830_CGC 0x3577
#define PCI_DEVICE_ID_INTEL_82855GM_HB 0x3580
#define PCI_DEVICE_ID_INTEL_82855GM_IG 0x3582
-#define PCI_DEVICE_ID_INTEL_SMCH 0x3590
+#define PCI_DEVICE_ID_INTEL_E7520_MCH 0x3590
#define PCI_DEVICE_ID_INTEL_E7320_MCH 0x3592
+#define PCI_DEVICE_ID_INTEL_MCH_PA 0x3595
+#define PCI_DEVICE_ID_INTEL_MCH_PA1 0x3596
+#define PCI_DEVICE_ID_INTEL_MCH_PB 0x3597
+#define PCI_DEVICE_ID_INTEL_MCH_PB1 0x3598
+#define PCI_DEVICE_ID_INTEL_MCH_PC 0x3599
+#define PCI_DEVICE_ID_INTEL_MCH_PC1 0x359a
#define PCI_DEVICE_ID_INTEL_E7525_MCH 0x359e
#define PCI_DEVICE_ID_INTEL_80310 0x530d
#define PCI_DEVICE_ID_INTEL_82371SB_0 0x7000

2004-11-12 23:31:52

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] PCI fixes for 2.6.10-rc1

ChangeSet 1.2091.1.8, 2004/11/12 14:04:45-08:00, [email protected]

[PATCH] lopec.c: replace pci_find_device with pci_get_device

As pci_find_device is going away I have replaced this call with
pci_get_device.

Signed-off-by: Hanna Linder <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


arch/ppc/platforms/lopec.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletion(-)


diff -Nru a/arch/ppc/platforms/lopec.c b/arch/ppc/platforms/lopec.c
--- a/arch/ppc/platforms/lopec.c 2004-11-12 15:11:04 -08:00
+++ b/arch/ppc/platforms/lopec.c 2004-11-12 15:11:04 -08:00
@@ -189,7 +189,7 @@
static void
lopec_ide_probe(void)
{
- struct pci_dev *dev = pci_find_device(PCI_VENDOR_ID_WINBOND,
+ struct pci_dev *dev = pci_get_device(PCI_VENDOR_ID_WINBOND,
PCI_DEVICE_ID_WINBOND_82C105,
NULL);
lopec_ide_ports_known = 1;
@@ -200,6 +200,7 @@
lopec_ide_ctl_regbase[0] = dev->resource[1].start;
lopec_ide_ctl_regbase[1] = dev->resource[3].start;
lopec_idedma_regbase = dev->resource[4].start;
+ pci_dev_put(dev);
}
}


2004-11-12 23:31:48

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] PCI fixes for 2.6.10-rc1

ChangeSet 1.2026.35.4, 2004/10/28 15:56:14-05:00, [email protected]

[PATCH] PCI: remove unconditional PCI ACPI IRQ routing

From: Bjorn Helgaas <[email protected]>

Now that PCI interrupts are routed in pci_enable_device(), remove the
unconditional routing previously done in pci_acpi_init().

This has the potential to break drivers that don't use pci_enable_device()
correctly, so I also added a "pci=routeirq" kernel option that restores the
previous behavior. I intend to remove that option, along with all the code
below, in a month or so.

Signed-off-by: Bjorn Helgaas <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


Documentation/kernel-parameters.txt | 4 ++++
arch/i386/pci/acpi.c | 30 ++++++++++++++++++++++--------
arch/i386/pci/common.c | 4 ++++
arch/ia64/pci/pci.c | 33 ++++++++++++++++++++++++++-------
4 files changed, 56 insertions(+), 15 deletions(-)


diff -Nru a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
--- a/Documentation/kernel-parameters.txt 2004-11-12 15:14:28 -08:00
+++ b/Documentation/kernel-parameters.txt 2004-11-12 15:14:28 -08:00
@@ -912,6 +912,10 @@
enabled.
noacpi [IA-32] Do not use ACPI for IRQ routing
or for PCI scanning.
+ routeirq Do IRQ routing for all PCI devices.
+ This is normally done in pci_enable_device(),
+ so this option is a temporary workaround
+ for broken drivers that don't call it.

firmware [ARM] Do not re-enumerate the bus but
instead just use the configuration
diff -Nru a/arch/i386/pci/acpi.c b/arch/i386/pci/acpi.c
--- a/arch/i386/pci/acpi.c 2004-11-12 15:14:28 -08:00
+++ b/arch/i386/pci/acpi.c 2004-11-12 15:14:28 -08:00
@@ -15,6 +15,7 @@
return pcibios_scan_root(busnum);
}

+extern int pci_routeirq;
static int __init pci_acpi_init(void)
{
struct pci_dev *dev = NULL;
@@ -30,14 +31,27 @@
pcibios_scanned++;
pcibios_enable_irq = acpi_pci_irq_enable;

- /*
- * PCI IRQ routing is set up by pci_enable_device(), but we
- * also do it here in case there are still broken drivers that
- * don't use pci_enable_device().
- */
- while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL)
- acpi_pci_irq_enable(dev);
-
+ if (pci_routeirq) {
+ /*
+ * PCI IRQ routing is set up by pci_enable_device(), but we
+ * also do it here in case there are still broken drivers that
+ * don't use pci_enable_device().
+ */
+ printk(KERN_INFO "** Routing PCI interrupts for all devices because \"pci=routeirq\"\n");
+ printk(KERN_INFO "** was specified. If this was required to make a driver work,\n");
+ printk(KERN_INFO "** please email the output of \"lspci\" to [email protected]\n");
+ printk(KERN_INFO "** so I can fix the driver.\n");
+ while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL)
+ acpi_pci_irq_enable(dev);
+ } else {
+ printk(KERN_INFO "** PCI interrupts are no longer routed automatically. If this\n");
+ printk(KERN_INFO "** causes a device to stop working, it is probably because the\n");
+ printk(KERN_INFO "** driver failed to call pci_enable_device(). As a temporary\n");
+ printk(KERN_INFO "** workaround, the \"pci=routeirq\" argument restores the old\n");
+ printk(KERN_INFO "** behavior. If this argument makes the device work again,\n");
+ printk(KERN_INFO "** please email the output of \"lspci\" to [email protected]\n");
+ printk(KERN_INFO "** so I can fix the driver.\n");
+ }
#ifdef CONFIG_X86_IO_APIC
if (acpi_ioapic)
print_IO_APIC();
diff -Nru a/arch/i386/pci/common.c b/arch/i386/pci/common.c
--- a/arch/i386/pci/common.c 2004-11-12 15:14:28 -08:00
+++ b/arch/i386/pci/common.c 2004-11-12 15:14:28 -08:00
@@ -23,6 +23,7 @@
unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2 |
PCI_PROBE_MMCONF;

+int pci_routeirq;
int pcibios_last_bus = -1;
struct pci_bus *pci_root_bus = NULL;
struct pci_raw_ops *raw_pci_ops;
@@ -226,6 +227,9 @@
return NULL;
} else if (!strcmp(str, "assign-busses")) {
pci_probe |= PCI_ASSIGN_ALL_BUSSES;
+ return NULL;
+ } else if (!strcmp(str, "routeirq")) {
+ pci_routeirq = 1;
return NULL;
}
return str;
diff -Nru a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c
--- a/arch/ia64/pci/pci.c 2004-11-12 15:14:28 -08:00
+++ b/arch/ia64/pci/pci.c 2004-11-12 15:14:28 -08:00
@@ -46,6 +46,8 @@
#define DBG(x...)
#endif

+static int pci_routeirq;
+
/*
* Low-level SAL-based PCI configuration access functions. Note that SAL
* calls are already serialized (via sal_lock), so we don't need another
@@ -141,13 +143,28 @@

acpi_get_devices(NULL, acpi_map_iosapic, NULL, NULL);
#endif
- /*
- * PCI IRQ routing is set up by pci_enable_device(), but we
- * also do it here in case there are still broken drivers that
- * don't use pci_enable_device().
- */
- while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL)
- acpi_pci_irq_enable(dev);
+
+ if (pci_routeirq) {
+ /*
+ * PCI IRQ routing is set up by pci_enable_device(), but we
+ * also do it here in case there are still broken drivers that
+ * don't use pci_enable_device().
+ */
+ printk(KERN_INFO "** Routing PCI interrupts for all devices because \"pci=routeirq\"\n");
+ printk(KERN_INFO "** was specified. If this was required to make a driver work,\n");
+ printk(KERN_INFO "** please email the output of \"lspci\" to [email protected]\n");
+ printk(KERN_INFO "** so I can fix the driver.\n");
+ while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL)
+ acpi_pci_irq_enable(dev);
+ } else {
+ printk(KERN_INFO "** PCI interrupts are no longer routed automatically. If this\n");
+ printk(KERN_INFO "** causes a device to stop working, it is probably because the\n");
+ printk(KERN_INFO "** driver failed to call pci_enable_device(). As a temporary\n");
+ printk(KERN_INFO "** workaround, the \"pci=routeirq\" argument restores the old\n");
+ printk(KERN_INFO "** behavior. If this argument makes the device work again,\n");
+ printk(KERN_INFO "** please email the output of \"lspci\" to [email protected]\n");
+ printk(KERN_INFO "** so I can fix the driver.\n");
+ }

return 0;
}
@@ -443,6 +460,8 @@
char * __init
pcibios_setup (char *str)
{
+ if (!strcmp(str, "routeirq"))
+ pci_routeirq = 1;
return NULL;
}


2004-11-12 23:25:59

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] PCI fixes for 2.6.10-rc1

ChangeSet 1.2026.66.12, 2004/11/05 15:05:02-08:00, [email protected]

[PATCH] PCI: kill old PCI changelog

There's not much value in shipping a changelog who's last update was
five years ago.


Signed-off-by: Adrian Bunk <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


arch/i386/pci/changelog | 62 ------------------------------------------------
1 files changed, 62 deletions(-)


diff -Nru a/arch/i386/pci/changelog b/arch/i386/pci/changelog
--- a/arch/i386/pci/changelog 2004-11-12 15:13:28 -08:00
+++ /dev/null Wed Dec 31 16:00:00 196900
@@ -1,62 +0,0 @@
-/*
- * CHANGELOG :
- * Jun 17, 1994 : Modified to accommodate the broken pre-PCI BIOS SPECIFICATION
- * Revision 2.0 present on <[email protected]>'s ASUS mainboard.
- *
- * Jan 5, 1995 : Modified to probe PCI hardware at boot time by Frederic
- * Potter, [email protected]
- *
- * Jan 10, 1995 : Modified to store the information about configured pci
- * devices into a list, which can be accessed via /proc/pci by
- * Curtis Varner, [email protected]
- *
- * Jan 12, 1995 : CPU-PCI bridge optimization support by Frederic Potter.
- * Alpha version. Intel & UMC chipset support only.
- *
- * Apr 16, 1995 : Source merge with the DEC Alpha PCI support. Most of the code
- * moved to drivers/pci/pci.c.
- *
- * Dec 7, 1996 : Added support for direct configuration access of boards
- * with Intel compatible access schemes ([email protected])
- *
- * Feb 3, 1997 : Set internal functions to static, save/restore flags
- * avoid dead locks reading broken PCI BIOS, [email protected]
- *
- * Apr 26, 1997 : Fixed case when there is BIOS32, but not PCI BIOS
- * ([email protected])
- *
- * May 7, 1997 : Added some missing cli()'s. [mj]
- *
- * Jun 20, 1997 : Corrected problems in "conf1" type accesses.
- * ([email protected])
- *
- * Aug 2, 1997 : Split to PCI BIOS handling and direct PCI access parts
- * and cleaned it up... Martin Mares <[email protected]>
- *
- * Feb 6, 1998 : No longer using BIOS to find devices and device classes. [mj]
- *
- * May 1, 1998 : Support for peer host bridges. [mj]
- *
- * Jun 19, 1998 : Changed to use spinlocks, so that PCI configuration space
- * can be accessed from interrupts even on SMP systems. [mj]
- *
- * August 1998 : Better support for peer host bridges and more paranoid
- * checks for direct hardware access. Ugh, this file starts to look as
- * a large gallery of common hardware bug workarounds (watch the comments)
- * -- the PCI specs themselves are sane, but most implementors should be
- * hit hard with \hammer scaled \magstep5. [mj]
- *
- * Jan 23, 1999 : More improvements to peer host bridge logic. i450NX fixup. [mj]
- *
- * Feb 8, 1999 : Added UM8886BF I/O address fixup. [mj]
- *
- * August 1999 : New resource management and configuration access stuff. [mj]
- *
- * Sep 19, 1999 : Use PCI IRQ routing tables for detection of peer host bridges.
- * Based on ideas by Chris Frantz and David Hinds. [mj]
- *
- * Sep 28, 1999 : Handle unreported/unassigned IRQs. Thanks to Shuu Yamaguchi
- * for a lot of patience during testing. [mj]
- *
- * Oct 8, 1999 : Split to pci-i386.c, pci-pc.c and pci-visws.c. [mj]
- */
\ No newline at end of file

2004-11-13 02:17:44

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] PCI fixes for 2.6.10-rc1

ChangeSet 1.2026.66.23, 2004/11/11 15:40:24-08:00, [email protected]

PCI Hotplug: fix up remaining MODULE_PARAM usage in pci hotplug drivers

Signed-off-by: Greg Kroah-Hartman <[email protected]>


drivers/pci/hotplug/cpcihp_generic.c | 14 +++++++-------
drivers/pci/hotplug/fakephp.c | 2 +-
drivers/pci/hotplug/ibmphp_core.c | 2 +-
3 files changed, 9 insertions(+), 9 deletions(-)


diff -Nru a/drivers/pci/hotplug/cpcihp_generic.c b/drivers/pci/hotplug/cpcihp_generic.c
--- a/drivers/pci/hotplug/cpcihp_generic.c 2004-11-12 15:12:04 -08:00
+++ b/drivers/pci/hotplug/cpcihp_generic.c 2004-11-12 15:12:04 -08:00
@@ -63,7 +63,7 @@

/* local variables */
static int debug;
-static char* bridge;
+static char bridge[256];
static u8 bridge_busnr;
static u8 bridge_slot;
static struct pci_bus *bus;
@@ -209,15 +209,15 @@
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
-MODULE_PARM(debug, "i");
+module_param(debug, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug, "Debugging mode enabled or not");
-MODULE_PARM(bridge, "s");
+module_param_string(bridge, bridge, 256, 0);
MODULE_PARM_DESC(bridge, "Hotswap bus bridge device, <bus>:<slot> (bus and slot are in hexadecimal)");
-MODULE_PARM(first_slot, "b");
+module_param(first_slot, byte, 0);
MODULE_PARM_DESC(first_slot, "Hotswap bus first slot number");
-MODULE_PARM(last_slot, "b");
+module_param(last_slot, byte, 0);
MODULE_PARM_DESC(last_slot, "Hotswap bus last slot number");
-MODULE_PARM(port, "h");
+module_param(port, ushort, 0);
MODULE_PARM_DESC(port, "#ENUM signal I/O port");
-MODULE_PARM(enum_bit, "i");
+module_param(enum_bit, int, 0);
MODULE_PARM_DESC(enum_bit, "#ENUM signal bit (0-7)");
diff -Nru a/drivers/pci/hotplug/fakephp.c b/drivers/pci/hotplug/fakephp.c
--- a/drivers/pci/hotplug/fakephp.c 2004-11-12 15:12:04 -08:00
+++ b/drivers/pci/hotplug/fakephp.c 2004-11-12 15:12:04 -08:00
@@ -227,6 +227,6 @@
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
-MODULE_PARM(debug, "i");
+module_param(debug, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug, "Debugging mode enabled or not");

diff -Nru a/drivers/pci/hotplug/ibmphp_core.c b/drivers/pci/hotplug/ibmphp_core.c
--- a/drivers/pci/hotplug/ibmphp_core.c 2004-11-12 15:12:04 -08:00
+++ b/drivers/pci/hotplug/ibmphp_core.c 2004-11-12 15:12:04 -08:00
@@ -51,7 +51,7 @@
int ibmphp_debug;

static int debug;
-MODULE_PARM (debug, "i");
+module_param(debug, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC (debug, "Debugging mode enabled or not");
MODULE_LICENSE ("GPL");
MODULE_DESCRIPTION (DRIVER_DESC);

2004-11-12 23:25:58

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] PCI fixes for 2.6.10-rc1

ChangeSet 1.2026.35.2, 2004/10/28 15:14:02-05:00, [email protected]

[PATCH] acpi: better encapsulate eisa_set_level_irq()

From: Bjorn Helgaas <[email protected]>

Move the "only do this once" stuff from acpi_register_gsi() into
eisa_set_level().

Signed-off-by: Bjorn Helgaas <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


arch/i386/kernel/acpi/boot.c | 8 +-------
arch/i386/pci/irq.c | 9 ++++++++-
2 files changed, 9 insertions(+), 8 deletions(-)


diff -Nru a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c
--- a/arch/i386/kernel/acpi/boot.c 2004-11-12 15:14:43 -08:00
+++ b/arch/i386/kernel/acpi/boot.c 2004-11-12 15:14:43 -08:00
@@ -457,16 +457,10 @@
* Make sure all (legacy) PCI IRQs are set as level-triggered.
*/
if (acpi_irq_model == ACPI_IRQ_MODEL_PIC) {
- static u16 irq_mask;
extern void eisa_set_level_irq(unsigned int irq);

- if (edge_level == ACPI_LEVEL_SENSITIVE) {
- if ((gsi < 16) && !((1 << gsi) & irq_mask)) {
- Dprintk(KERN_DEBUG PREFIX "Setting GSI %u as level-triggered\n", gsi);
- irq_mask |= (1 << gsi);
+ if (edge_level == ACPI_LEVEL_SENSITIVE)
eisa_set_level_irq(gsi);
- }
- }
}
#endif

diff -Nru a/arch/i386/pci/irq.c b/arch/i386/pci/irq.c
--- a/arch/i386/pci/irq.c 2004-11-12 15:14:43 -08:00
+++ b/arch/i386/pci/irq.c 2004-11-12 15:14:43 -08:00
@@ -127,8 +127,15 @@
{
unsigned char mask = 1 << (irq & 7);
unsigned int port = 0x4d0 + (irq >> 3);
- unsigned char val = inb(port);
+ unsigned char val;
+ static u16 eisa_irq_mask;

+ if (irq >= 16 || (1 << irq) & eisa_irq_mask)
+ return;
+
+ eisa_irq_mask |= (1 << irq);
+ printk("PCI: setting IRQ %u as level-triggered\n", irq);
+ val = inb(port);
if (!(val & mask)) {
DBG(" -> edge");
outb(val | mask, port);

2004-11-12 23:25:58

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] PCI fixes for 2.6.10-rc1

ChangeSet 1.2091.1.14, 2004/11/12 14:08:40-08:00, [email protected]

[PATCH] ret_mb_a_pci.c: replace pci_find_device with pci_get_device

As pci_find_device is going away I've replaced it with pci_get_device.


Signed-off-by: Hanna Linder <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


arch/v850/kernel/rte_mb_a_pci.c | 2 +-
1 files changed, 1 insertion(+), 1 deletion(-)


diff -Nru a/arch/v850/kernel/rte_mb_a_pci.c b/arch/v850/kernel/rte_mb_a_pci.c
--- a/arch/v850/kernel/rte_mb_a_pci.c 2004-11-12 15:10:19 -08:00
+++ b/arch/v850/kernel/rte_mb_a_pci.c 2004-11-12 15:10:19 -08:00
@@ -254,7 +254,7 @@
struct pci_dev *dev = NULL;
struct resource *r;

- while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
+ for_each_pci_dev(dev) {
unsigned di_num;
unsigned class = dev->class >> 8;


2004-11-12 23:25:57

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] PCI fixes for 2.6.10-rc1

ChangeSet 1.2026.66.22, 2004/11/10 17:38:03-08:00, [email protected]

[PATCH] ibmphp_core.c: replace pci_get_device with pci_dev_present

This can be converted to pci_dev_present as the dev returned is never used.
Compile tested.

Signed-off-by: Hanna Linder <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


drivers/pci/hotplug/ibmphp_core.c | 8 +++++---
1 files changed, 5 insertions(+), 3 deletions(-)


diff -Nru a/drivers/pci/hotplug/ibmphp_core.c b/drivers/pci/hotplug/ibmphp_core.c
--- a/drivers/pci/hotplug/ibmphp_core.c 2004-11-12 15:12:11 -08:00
+++ b/drivers/pci/hotplug/ibmphp_core.c 2004-11-12 15:12:11 -08:00
@@ -838,8 +838,11 @@
int rc;
u8 speed;
u8 cmd = 0x0;
- struct pci_dev *dev = NULL;
int retval;
+ static struct pci_device_id ciobx[] = {
+ { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, 0x0101) },
+ { },
+ };

debug ("%s - entry slot # %d\n", __FUNCTION__, slot_cur->number);
if (SET_BUS_STATUS (slot_cur->ctrl) && is_bus_empty (slot_cur)) {
@@ -886,8 +889,7 @@
break;
case BUS_SPEED_133:
/* This is to take care of the bug in CIOBX chip */
- while ((dev = pci_get_device(PCI_VENDOR_ID_SERVERWORKS,
- 0x0101, dev)) != NULL)
+ if (pci_dev_present(ciobx))
ibmphp_hpc_writeslot (slot_cur, HPC_BUS_100PCIXMODE);
cmd = HPC_BUS_133PCIXMODE;
break;

2004-11-12 23:25:57

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] PCI fixes for 2.6.10-rc1

ChangeSet 1.2091.1.4, 2004/11/12 14:01:32-08:00, [email protected]

[PATCH] PCI: small PCI probe patch for odd 64 bit BARs

On Thu, Nov 11, 2004 at 09:54:19AM -0800, Greg KH wrote:
> I'll wait till you test this on 2.6 before applying it.

OK. Tested now on real hardware in 32 bit and 64 bit kernels. 32 bit
found another dumbness, that we can fix up.

Some PCI bridges default their UPPER prefetch windows to an unused state
of base > limit. We should not use those values if we find that. It
might be nice to reprogram them to 0, in fact.

Yes, BIOS should fix that up, but apparently, some do not.


Signed-Off-By: Tim Hockin <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


drivers/pci/probe.c | 28 +++++++++++++++++++---------
1 files changed, 19 insertions(+), 9 deletions(-)


diff -Nru a/drivers/pci/probe.c b/drivers/pci/probe.c
--- a/drivers/pci/probe.c 2004-11-12 15:11:34 -08:00
+++ b/drivers/pci/probe.c 2004-11-12 15:11:34 -08:00
@@ -144,9 +144,11 @@
pci_write_config_dword(dev, reg+4, ~0);
pci_read_config_dword(dev, reg+4, &sz);
pci_write_config_dword(dev, reg+4, l);
- if (~sz)
- res->end = res->start + 0xffffffff +
- (((unsigned long) ~sz) << 32);
+ sz = pci_size(l, sz, 0xffffffff);
+ if (sz) {
+ /* This BAR needs > 4GB? Wow. */
+ res->end |= (unsigned long)sz<<32;
+ }
#else
if (l) {
printk(KERN_ERR "PCI: Unable to handle 64-bit address for device %s\n", pci_name(dev));
@@ -243,15 +245,23 @@
u32 mem_base_hi, mem_limit_hi;
pci_read_config_dword(dev, PCI_PREF_BASE_UPPER32, &mem_base_hi);
pci_read_config_dword(dev, PCI_PREF_LIMIT_UPPER32, &mem_limit_hi);
+
+ /*
+ * Some bridges set the base > limit by default, and some
+ * (broken) BIOSes do not initialize them. If we find
+ * this, just assume they are not being used.
+ */
+ if (mem_base_hi <= mem_limit_hi) {
#if BITS_PER_LONG == 64
- base |= ((long) mem_base_hi) << 32;
- limit |= ((long) mem_limit_hi) << 32;
+ base |= ((long) mem_base_hi) << 32;
+ limit |= ((long) mem_limit_hi) << 32;
#else
- if (mem_base_hi || mem_limit_hi) {
- printk(KERN_ERR "PCI: Unable to handle 64-bit address space for %s\n", child->name);
- return;
- }
+ if (mem_base_hi || mem_limit_hi) {
+ printk(KERN_ERR "PCI: Unable to handle 64-bit address space for bridge %s\n", pci_name(dev));
+ return;
+ }
#endif
+ }
}
if (base <= limit) {
res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM | IORESOURCE_PREFETCH;

2004-11-12 23:25:56

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] PCI fixes for 2.6.10-rc1

ChangeSet 1.2091.1.12, 2004/11/12 14:07:54-08:00, [email protected]

[PATCH] sis-agp.c: replace pci_find_device with pci_get_device

As pci_find_device is going away soon I have converted this file to use
pci_get_device instead. for_each_pci_dev is a macro wrapper around
pci_get_device.

Signed-off-by: Hanna Linder <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


drivers/char/agp/sis-agp.c | 2 +-
1 files changed, 1 insertion(+), 1 deletion(-)


diff -Nru a/drivers/char/agp/sis-agp.c b/drivers/char/agp/sis-agp.c
--- a/drivers/char/agp/sis-agp.c 2004-11-12 15:10:34 -08:00
+++ b/drivers/char/agp/sis-agp.c 2004-11-12 15:10:34 -08:00
@@ -86,7 +86,7 @@
command |= AGPSTAT_AGP_ENABLE;
rate = (command & 0x7) << 2;

- while ((device = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, device)) != NULL) {
+ for_each_pci_dev(device) {
u8 agp = pci_find_capability(device, PCI_CAP_ID_AGP);
if (!agp)
continue;

2004-11-13 02:33:31

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] PCI fixes for 2.6.10-rc1

ChangeSet 1.2026.66.18, 2004/11/10 16:43:46-08:00, [email protected]

[PATCH] PCI: pci-mmconfig fix

Here I have attached pci mmconfig fix for 2.6.9 kernel.

This will fix the flush error in pci_mmcfg_write.

When pci_mmcfg_write is used to program the PMCSR in the Power
Management Capability structure of PCI config space in the PCI Express
device to a different power state, the dummy readl to flush the previous
write violates the transition delay specified in the PCI power
management spec. Please see PCI Power Management Spec. 1.2 Table 5-6.
For example, while changing the power state of the device through PMCSR
register, a transition delay of 10msec is required before any access can
be made to the device.

Since the configuration write access for PCI Express is non posted,
flushing is not necessary and it will be safe to remove the dummy
readl.

This patch will remove dummy readl function implemented in
"pci_mmcfg_write" and use set_fixmap_nocahe instead of set_fixmap.

Signed-off-by: Sundarapandian Durairaj <[email protected]>
Signed-off-by: T. Long Nguyen <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


arch/i386/pci/mmconfig.c | 5 +----
arch/x86_64/pci/mmconfig.c | 3 ---
2 files changed, 1 insertion(+), 7 deletions(-)


diff -Nru a/arch/i386/pci/mmconfig.c b/arch/i386/pci/mmconfig.c
--- a/arch/i386/pci/mmconfig.c 2004-11-12 15:12:43 -08:00
+++ b/arch/i386/pci/mmconfig.c 2004-11-12 15:12:43 -08:00
@@ -30,7 +30,7 @@
u32 dev_base = pci_mmcfg_base_addr | (bus << 20) | (devfn << 12);
if (dev_base != mmcfg_last_accessed_device) {
mmcfg_last_accessed_device = dev_base;
- set_fixmap(FIX_PCIE_MCFG, dev_base);
+ set_fixmap_nocache(FIX_PCIE_MCFG, dev_base);
}
}

@@ -84,9 +84,6 @@
writel(value, mmcfg_virt_addr + reg);
break;
}
-
- /* Dummy read to flush PCI write */
- readl(mmcfg_virt_addr);

spin_unlock_irqrestore(&pci_config_lock, flags);

diff -Nru a/arch/x86_64/pci/mmconfig.c b/arch/x86_64/pci/mmconfig.c
--- a/arch/x86_64/pci/mmconfig.c 2004-11-12 15:12:43 -08:00
+++ b/arch/x86_64/pci/mmconfig.c 2004-11-12 15:12:43 -08:00
@@ -63,9 +63,6 @@
break;
}

- /* Dummy read to flush PCI write */
- readl(addr);
-
return 0;
}


2004-11-13 02:33:31

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] PCI fixes for 2.6.10-rc1

ChangeSet 1.2091.1.17, 2004/11/12 14:09:41-08:00, [email protected]

[PATCH] ebus.c: replace pci_find_device with pci_get_device

Signed-off-by: Hanna Linder <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


arch/sparc/kernel/ebus.c | 6 ++++--
1 files changed, 4 insertions(+), 2 deletions(-)


diff -Nru a/arch/sparc/kernel/ebus.c b/arch/sparc/kernel/ebus.c
--- a/arch/sparc/kernel/ebus.c 2004-11-12 15:09:57 -08:00
+++ b/arch/sparc/kernel/ebus.c 2004-11-12 15:09:57 -08:00
@@ -275,7 +275,7 @@
}
}

- pdev = pci_find_device(PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_EBUS, 0);
+ pdev = pci_get_device(PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_EBUS, 0);
if (!pdev) {
return;
}
@@ -342,7 +342,7 @@
}

next_ebus:
- pdev = pci_find_device(PCI_VENDOR_ID_SUN,
+ pdev = pci_get_device(PCI_VENDOR_ID_SUN,
PCI_DEVICE_ID_SUN_EBUS, pdev);
if (!pdev)
break;
@@ -356,4 +356,6 @@
ebus->next = 0;
++num_ebus;
}
+ if (pdev)
+ pci_dev_put(pdev);
}

2004-11-13 07:33:57

by James Tabor

[permalink] [raw]
Subject: Re: [PATCH] PCI fixes for 2.6.10-rc1


Woooo!
At least change the subject line!
James

Greg KH wrote:
> ChangeSet 1.2026.66.20, 2004/11/10 16:44:40-08:00, [email protected]

2004-11-13 09:12:15

by Russell King

[permalink] [raw]
Subject: Re: [PATCH] PCI fixes for 2.6.10-rc1

On Fri, Nov 12, 2004 at 03:21:58PM -0800, Greg KH wrote:
> ChangeSet 1.2091.1.2, 2004/11/11 16:32:25-08:00, [email protected]
>
> [PATCH] fakephp: introduce pci_bus_add_device
>
> fakephp needs to add newly discovered devices to the global pci list.
> Therefore seperate out the appropriate chunk from pci_bus_add_devices
> to pci_bus_add_device to add a single device to sysfs, procfs
> and the global device list.

Why is this needed? pci_bus_add_devices() is designed to only add new
devices to the device tree - new devices have an empty dev->global_list.

Just calling pci_bus_add_devices() for the parent bus should suffice.

--
Russell King
Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/
maintainer of: 2.6 PCMCIA - http://pcmcia.arm.linux.org.uk/
2.6 Serial core

2004-11-13 10:03:52

by Jan Dittmer

[permalink] [raw]
Subject: Re: [PATCH] PCI fixes for 2.6.10-rc1

Russell King wrote:
> On Fri, Nov 12, 2004 at 03:21:58PM -0800, Greg KH wrote:
>
>>ChangeSet 1.2091.1.2, 2004/11/11 16:32:25-08:00, [email protected]
>>
>>[PATCH] fakephp: introduce pci_bus_add_device
>>
>>fakephp needs to add newly discovered devices to the global pci list.
>>Therefore seperate out the appropriate chunk from pci_bus_add_devices
>>to pci_bus_add_device to add a single device to sysfs, procfs
>>and the global device list.
>
>
> Why is this needed? pci_bus_add_devices() is designed to only add new
> devices to the device tree - new devices have an empty dev->global_list.
>
> Just calling pci_bus_add_devices() for the parent bus should suffice.

The device got removed from bus->devices, so I can't call that.
pci_do_scan_bus would probably the correct function to call.
But it isn't aware of already existing devices and doesn't allow
to add the hotplug slot after discovering new devices.
Well I could walk the device tree afterwards and find unbound
devices. Still pci_scan_slot would rescan and reenable all devices.
What do I overlook?

Thanks,

Jan

2004-11-13 10:22:13

by Russell King

[permalink] [raw]
Subject: Re: [PATCH] PCI fixes for 2.6.10-rc1

On Sat, Nov 13, 2004 at 11:03:15AM +0100, Jan Dittmer wrote:
> Russell King wrote:
> > Why is this needed? pci_bus_add_devices() is designed to only add new
> > devices to the device tree - new devices have an empty dev->global_list.
> >
> > Just calling pci_bus_add_devices() for the parent bus should suffice.
>
> The device got removed from bus->devices, so I can't call that.

This sounds very wrong. Why did it get removed from bus->devices ?

If it isn't on bus->devices, how does pci_bus_add_device() help?
Sure you get it onto the global list and into the device tree,
but it won't be attached to the parent bus properly.

I think what you want to be using is:

int __devinit pci_scan_slot(struct pci_bus *bus, int devfn)

to discover the new device, which will do the right thing from the
point of setting stuff up before calling pci_bus_add_device*().

--
Russell King
Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/
maintainer of: 2.6 PCMCIA - http://pcmcia.arm.linux.org.uk/
2.6 Serial core

2004-11-13 10:45:26

by Jan Dittmer

[permalink] [raw]
Subject: Re: [PATCH] PCI fixes for 2.6.10-rc1

Russell King wrote:
> On Sat, Nov 13, 2004 at 11:03:15AM +0100, Jan Dittmer wrote:
>
>>Russell King wrote:
>>
>>>Why is this needed? pci_bus_add_devices() is designed to only add new
>>>devices to the device tree - new devices have an empty dev->global_list.
>>>
>>>Just calling pci_bus_add_devices() for the parent bus should suffice.
>>
>>The device got removed from bus->devices, so I can't call that.
>
>
> This sounds very wrong. Why did it get removed from bus->devices ?
>
> If it isn't on bus->devices, how does pci_bus_add_device() help?
> Sure you get it onto the global list and into the device tree,
> but it won't be attached to the parent bus properly.
>
> I think what you want to be using is:
>
> int __devinit pci_scan_slot(struct pci_bus *bus, int devfn)
>
> to discover the new device, which will do the right thing from the
> point of setting stuff up before calling pci_bus_add_device*().
>

I don't see how pci_scan_slot helps me here. I already call
pci_scan_single_device which seems just about the same.

Thanks, Jan

2004-11-13 10:48:15

by Russell King

[permalink] [raw]
Subject: Re: [PATCH] PCI fixes for 2.6.10-rc1

On Sat, Nov 13, 2004 at 11:45:00AM +0100, Jan Dittmer wrote:
> > This sounds very wrong. Why did it get removed from bus->devices ?
> >
> > If it isn't on bus->devices, how does pci_bus_add_device() help?
> > Sure you get it onto the global list and into the device tree,
> > but it won't be attached to the parent bus properly.
> >
> > I think what you want to be using is:
> >
> > int __devinit pci_scan_slot(struct pci_bus *bus, int devfn)
> >
> > to discover the new device, which will do the right thing from the
> > point of setting stuff up before calling pci_bus_add_device*().
> >
>
> I don't see how pci_scan_slot helps me here. I already call
> pci_scan_single_device which seems just about the same.

Which is also acceptable. The device will be on the bus->devices list.
I still don't see why you can't use pci_bus_add_devices() though, or
why you think you need to remove it from the bus->devices list.

--
Russell King
Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/
maintainer of: 2.6 PCMCIA - http://pcmcia.arm.linux.org.uk/
2.6 Serial core

2004-11-13 10:58:29

by Jan Dittmer

[permalink] [raw]
Subject: Re: [PATCH] PCI fixes for 2.6.10-rc1

Russell King wrote:
> On Sat, Nov 13, 2004 at 11:45:00AM +0100, Jan Dittmer wrote:
>
>>>This sounds very wrong. Why did it get removed from bus->devices ?
>>>
>>>If it isn't on bus->devices, how does pci_bus_add_device() help?
>>>Sure you get it onto the global list and into the device tree,
>>>but it won't be attached to the parent bus properly.
>>>
>>>I think what you want to be using is:
>>>
>>>int __devinit pci_scan_slot(struct pci_bus *bus, int devfn)
>>>
>>>to discover the new device, which will do the right thing from the
>>>point of setting stuff up before calling pci_bus_add_device*().
>>>
>>
>>I don't see how pci_scan_slot helps me here. I already call
>>pci_scan_single_device which seems just about the same.
>
>
> Which is also acceptable. The device will be on the bus->devices list.
> I still don't see why you can't use pci_bus_add_devices() though, or
> why you think you need to remove it from the bus->devices list.
>

It's needed for fakephp, where the device gets removed from bus->devices
if you disable the slot. pci_scan_single_device then re-adds the
device to the list when enabling the slot again.

Jan