Signed-off-by: Andrew Morton --- 25-akpm/Documentation/pci.txt | 13 25-akpm/Documentation/power/pci.txt | 51 +- 25-akpm/arch/alpha/kernel/console.c | 2 25-akpm/arch/alpha/kernel/pci.c | 20 25-akpm/arch/alpha/kernel/pci_impl.h | 1 25-akpm/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c | 3 25-akpm/arch/i386/kernel/cpu/cpufreq/speedstep-ich.c | 15 25-akpm/arch/i386/kernel/cpu/cyrix.c | 11 25-akpm/arch/i386/kernel/cpu/mtrr/main.c | 8 25-akpm/arch/i386/kernel/scx200.c | 67 +- 25-akpm/arch/i386/pci/fixup.c | 38 + 25-akpm/arch/i386/pci/i386.c | 18 25-akpm/arch/i386/pci/irq.c | 20 25-akpm/arch/ia64/pci/pci.c | 6 25-akpm/arch/ia64/sn/io/machvec/pci_bus_cvlink.c | 4 25-akpm/arch/ppc/kernel/pci.c | 28 - 25-akpm/arch/ppc64/kernel/pSeries_pci.c | 303 ++++++++++-- 25-akpm/arch/ppc64/kernel/pci.c | 167 ++++-- 25-akpm/arch/ppc64/kernel/pci.h | 6 25-akpm/arch/ppc64/kernel/pci_dn.c | 12 25-akpm/arch/sparc/kernel/pcic.c | 6 25-akpm/drivers/acpi/motherboard.c | 6 25-akpm/drivers/acpi/processor.c | 15 25-akpm/drivers/atm/idt77252.c | 13 25-akpm/drivers/char/agp/intel-agp.c | 2 25-akpm/drivers/char/agp/intel-mch-agp.c | 2 25-akpm/drivers/char/applicom.c | 2 25-akpm/drivers/char/drm/drm_fops.h | 7 25-akpm/drivers/char/ipmi/ipmi_si_intf.c | 14 25-akpm/drivers/media/video/bttv-cards.c | 6 25-akpm/drivers/media/video/bttv-driver.c | 4 25-akpm/drivers/media/video/bttvp.h | 1 25-akpm/drivers/media/video/cx88/cx88-video.c | 4 25-akpm/drivers/media/video/cx88/cx88.h | 1 25-akpm/drivers/media/video/meye.c | 4 25-akpm/drivers/media/video/meye.h | 1 25-akpm/drivers/message/fusion/mptbase.c | 4 25-akpm/drivers/message/fusion/mptbase.h | 3 25-akpm/drivers/misc/ibmasm/ibmasm.h | 2 25-akpm/drivers/misc/ibmasm/ibmasmfs.c | 4 25-akpm/drivers/misc/ibmasm/lowlevel.c | 2 25-akpm/drivers/misc/ibmasm/lowlevel.h | 30 - 25-akpm/drivers/misc/ibmasm/uart.c | 2 25-akpm/drivers/net/3c59x.c | 11 25-akpm/drivers/net/8139cp.c | 5 25-akpm/drivers/net/8139too.c | 6 25-akpm/drivers/net/amd8111e.c | 4 25-akpm/drivers/net/amd8111e.h | 1 25-akpm/drivers/net/b44.c | 4 25-akpm/drivers/net/b44.h | 1 25-akpm/drivers/net/e100.c | 5 25-akpm/drivers/net/e1000/e1000.h | 1 25-akpm/drivers/net/e1000/e1000_main.c | 4 25-akpm/drivers/net/eepro100.c | 7 25-akpm/drivers/net/irda/vlsi_ir.c | 4 25-akpm/drivers/net/irda/vlsi_ir.h | 1 25-akpm/drivers/net/ixgb/ixgb.h | 1 25-akpm/drivers/net/ixgb/ixgb_main.c | 2 25-akpm/drivers/net/pci-skeleton.c | 5 25-akpm/drivers/net/s2io.c | 4 25-akpm/drivers/net/s2io.h | 1 25-akpm/drivers/net/sis900.c | 6 25-akpm/drivers/net/tg3.c | 8 25-akpm/drivers/net/tg3.h | 1 25-akpm/drivers/net/tulip/xircom_tulip_cb.c | 7 25-akpm/drivers/net/typhoon.c | 7 25-akpm/drivers/net/via-rhine.c | 4 25-akpm/drivers/net/via-velocity.c | 4 25-akpm/drivers/net/via-velocity.h | 4 25-akpm/drivers/net/wan/sbni.c | 6 25-akpm/drivers/net/wireless/airo.c | 5 25-akpm/drivers/net/wireless/prism54/islpci_dev.h | 1 25-akpm/drivers/net/wireless/prism54/islpci_hotplug.c | 4 25-akpm/drivers/net/wireless/prism54/islpci_mgt.c | 4 25-akpm/drivers/pci/Makefile | 3 25-akpm/drivers/pci/hotplug/acpiphp_ibm.c | 101 ++-- 25-akpm/drivers/pci/hotplug/cpcihp_zt5550.c | 15 25-akpm/drivers/pci/hotplug/cpqphp.h | 9 25-akpm/drivers/pci/hotplug/cpqphp_core.c | 38 - 25-akpm/drivers/pci/hotplug/cpqphp_ctrl.c | 4 25-akpm/drivers/pci/hotplug/cpqphp_nvram.h | 12 25-akpm/drivers/pci/hotplug/cpqphp_pci.c | 12 25-akpm/drivers/pci/hotplug/ibmphp_core.c | 2 25-akpm/drivers/pci/hotplug/ibmphp_ebda.c | 4 25-akpm/drivers/pci/hotplug/ibmphp_hpc.c | 28 - 25-akpm/drivers/pci/hotplug/pciehp.h | 11 25-akpm/drivers/pci/hotplug/pciehp_core.c | 4 25-akpm/drivers/pci/hotplug/pciehp_ctrl.c | 5 25-akpm/drivers/pci/hotplug/pciehp_hpc.c | 6 25-akpm/drivers/pci/hotplug/pciehp_pci.c | 7 25-akpm/drivers/pci/hotplug/rpadlpar_core.c | 170 +++++- 25-akpm/drivers/pci/hotplug/rpaphp.h | 4 25-akpm/drivers/pci/hotplug/rpaphp_core.c | 147 +++-- 25-akpm/drivers/pci/hotplug/rpaphp_pci.c | 80 ++- 25-akpm/drivers/pci/hotplug/rpaphp_slot.c | 11 25-akpm/drivers/pci/hotplug/rpaphp_vio.c | 4 25-akpm/drivers/pci/hotplug/shpchp.h | 9 25-akpm/drivers/pci/hotplug/shpchp_core.c | 4 25-akpm/drivers/pci/hotplug/shpchp_ctrl.c | 451 ++++-------------- 25-akpm/drivers/pci/hotplug/shpchp_hpc.c | 10 25-akpm/drivers/pci/hotplug/shpchprm_acpi.c | 6 25-akpm/drivers/pci/msi.c | 20 25-akpm/drivers/pci/msi.h | 2 25-akpm/drivers/pci/pci-driver.c | 51 -- 25-akpm/drivers/pci/pci-sysfs.c | 94 +++ 25-akpm/drivers/pci/pci.c | 40 - 25-akpm/drivers/pci/pci.h | 28 + 25-akpm/drivers/pci/pci.ids | 8 25-akpm/drivers/pci/probe.c | 38 + 25-akpm/drivers/pci/proc.c | 5 25-akpm/drivers/pci/quirks.c | 137 ++++- 25-akpm/drivers/pci/remove.c | 2 25-akpm/drivers/pci/rom.c | 225 ++++++++ 25-akpm/drivers/pci/search.c | 77 ++- 25-akpm/drivers/pci/setup-bus.c | 12 25-akpm/drivers/pci/setup-irq.c | 2 25-akpm/drivers/pci/setup-res.c | 2 25-akpm/drivers/pcmcia/yenta_socket.c | 12 25-akpm/drivers/pcmcia/yenta_socket.h | 2 25-akpm/drivers/pnp/system.c | 6 25-akpm/drivers/scsi/eata.c | 12 25-akpm/drivers/scsi/ipr.c | 4 25-akpm/drivers/scsi/ipr.h | 1 25-akpm/drivers/scsi/megaraid/megaraid_mbox.c | 8 25-akpm/drivers/scsi/nsp32.c | 5 25-akpm/drivers/scsi/nsp32.h | 3 25-akpm/drivers/usb/core/hcd-pci.c | 4 25-akpm/drivers/usb/core/hcd.h | 1 25-akpm/drivers/usb/gadget/goku_udc.c | 2 25-akpm/drivers/usb/gadget/net2280.c | 2 25-akpm/drivers/usb/host/ehci-hcd.c | 2 25-akpm/drivers/usb/host/ohci-pci.c | 2 25-akpm/drivers/usb/host/uhci-hcd.c | 2 25-akpm/drivers/video/i810/i810.h | 1 25-akpm/drivers/video/i810/i810_main.c | 4 25-akpm/include/asm-generic/vmlinux.lds.h | 3 25-akpm/include/asm-ppc64/pci-bridge.h | 6 25-akpm/include/asm-ppc64/pci.h | 2 25-akpm/include/linux/ioport.h | 5 25-akpm/include/linux/pci.h | 46 + 25-akpm/include/linux/pci_ids.h | 10 25-akpm/sound/core/init.c | 2 25-akpm/sound/oss/ali5455.c | 5 25-akpm/sound/oss/i810_audio.c | 5 144 files changed, 1991 insertions(+), 1122 deletions(-) diff -puN arch/alpha/kernel/console.c~bk-pci arch/alpha/kernel/console.c --- 25/arch/alpha/kernel/console.c~bk-pci 2004-10-01 20:07:40.060071640 -0700 +++ 25-akpm/arch/alpha/kernel/console.c 2004-10-01 20:07:40.301035008 -0700 @@ -47,7 +47,7 @@ locate_and_init_vga(void *(*sel_func)(vo if (!sel_func) sel_func = (void *)default_vga_hose_select; - for(dev=NULL; (dev=pci_find_class(PCI_CLASS_DISPLAY_VGA << 8, dev));) { + for(dev=NULL; (dev=pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, dev));) { if (!hose) hose = dev->sysdata; else hose = sel_func(hose, dev->sysdata); } diff -puN arch/alpha/kernel/pci.c~bk-pci arch/alpha/kernel/pci.c --- 25/arch/alpha/kernel/pci.c~bk-pci 2004-10-01 20:07:40.061071488 -0700 +++ 25-akpm/arch/alpha/kernel/pci.c 2004-10-01 20:07:40.302034856 -0700 @@ -227,7 +227,7 @@ pdev_save_srm_config(struct pci_dev *dev tmp->next = srm_saved_configs; tmp->dev = dev; - pci_save_state(dev, tmp->regs); + pci_save_state(dev); srm_saved_configs = tmp; } @@ -243,7 +243,7 @@ pci_restore_srm_config(void) /* Restore SRM config. */ for (tmp = srm_saved_configs; tmp; tmp = tmp->next) { - pci_restore_state(tmp->dev, tmp->regs); + pci_restore_state(tmp->dev); } } #endif @@ -280,7 +280,6 @@ pcibios_fixup_bus(struct pci_bus *bus) /* Propagate hose info into the subordinate devices. */ struct pci_controller *hose = bus->sysdata; - struct list_head *ln; struct pci_dev *dev = bus->self; if (!dev) { @@ -304,9 +303,7 @@ pcibios_fixup_bus(struct pci_bus *bus) pcibios_fixup_device_resources(dev, bus); } - for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) { - struct pci_dev *dev = pci_dev_b(ln); - + list_for_each_entry(dev, &bus->devices, bus_list) { pdev_save_srm_config(dev); if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI) pcibios_fixup_device_resources(dev, bus); @@ -403,11 +400,10 @@ pcibios_set_master(struct pci_dev *dev) static void __init pcibios_claim_one_bus(struct pci_bus *b) { - struct list_head *ld; + struct pci_dev *dev; struct pci_bus *child_bus; - for (ld = b->devices.next; ld != &b->devices; ld = ld->next) { - struct pci_dev *dev = pci_dev_b(ld); + list_for_each_entry(dev, &b->devices, bus_list) { int i; for (i = 0; i < PCI_NUM_RESOURCES; i++) { @@ -426,12 +422,10 @@ pcibios_claim_one_bus(struct pci_bus *b) static void __init pcibios_claim_console_setup(void) { - struct list_head *lb; + struct pci_bus *b; - for(lb = pci_root_buses.next; lb != &pci_root_buses; lb = lb->next) { - struct pci_bus *b = pci_bus_b(lb); + list_for_each_entry(b, &pci_root_buses, node) pcibios_claim_one_bus(b); - } } void __init diff -puN arch/alpha/kernel/pci_impl.h~bk-pci arch/alpha/kernel/pci_impl.h --- 25/arch/alpha/kernel/pci_impl.h~bk-pci 2004-10-01 20:07:40.062071336 -0700 +++ 25-akpm/arch/alpha/kernel/pci_impl.h 2004-10-01 20:07:40.302034856 -0700 @@ -166,7 +166,6 @@ struct pdev_srm_saved_conf { struct pdev_srm_saved_conf *next; struct pci_dev *dev; - u32 regs[16]; }; extern void pci_restore_srm_config(void); diff -puN arch/i386/kernel/cpu/cpufreq/gx-suspmod.c~bk-pci arch/i386/kernel/cpu/cpufreq/gx-suspmod.c --- 25/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c~bk-pci 2004-10-01 20:07:40.064071032 -0700 +++ 25-akpm/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c 2004-10-01 20:07:40.303034704 -0700 @@ -199,7 +199,7 @@ static __init struct pci_dev *gx_detect_ } /* detect which companion chip is used */ - while ((gx_pci = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, gx_pci)) != NULL) { + while ((gx_pci = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, gx_pci)) != NULL) { if ((pci_match_device (gx_chipset_tbl, gx_pci)) != NULL) { return gx_pci; } @@ -499,6 +499,7 @@ static int __init cpufreq_gx_init(void) static void __exit cpufreq_gx_exit(void) { cpufreq_unregister_driver(&gx_suspmod_driver); + pci_dev_put(gx_params->cs55x0); kfree(gx_params); } diff -puN arch/i386/kernel/cpu/cpufreq/speedstep-ich.c~bk-pci arch/i386/kernel/cpu/cpufreq/speedstep-ich.c --- 25/arch/i386/kernel/cpu/cpufreq/speedstep-ich.c~bk-pci 2004-10-01 20:07:40.066070728 -0700 +++ 25-akpm/arch/i386/kernel/cpu/cpufreq/speedstep-ich.c 2004-10-01 20:07:40.304034552 -0700 @@ -171,7 +171,7 @@ static int speedstep_activate (void) */ static unsigned int speedstep_detect_chipset (void) { - speedstep_chipset_dev = pci_find_subsys(PCI_VENDOR_ID_INTEL, + speedstep_chipset_dev = pci_get_subsys(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, PCI_ANY_ID, PCI_ANY_ID, @@ -179,7 +179,7 @@ static unsigned int speedstep_detect_chi if (speedstep_chipset_dev) return 4; /* 4-M */ - speedstep_chipset_dev = pci_find_subsys(PCI_VENDOR_ID_INTEL, + speedstep_chipset_dev = pci_get_subsys(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, PCI_ANY_ID, PCI_ANY_ID, @@ -188,7 +188,7 @@ static unsigned int speedstep_detect_chi return 3; /* 3-M */ - speedstep_chipset_dev = pci_find_subsys(PCI_VENDOR_ID_INTEL, + speedstep_chipset_dev = pci_get_subsys(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_10, PCI_ANY_ID, PCI_ANY_ID, @@ -201,7 +201,7 @@ static unsigned int speedstep_detect_chi static struct pci_dev *hostbridge; u8 rev = 0; - hostbridge = pci_find_subsys(PCI_VENDOR_ID_INTEL, + hostbridge = pci_get_subsys(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82815_MC, PCI_ANY_ID, PCI_ANY_ID, @@ -214,9 +214,11 @@ static unsigned int speedstep_detect_chi if (rev < 5) { dprintk(KERN_INFO "cpufreq: hostbridge does not support speedstep\n"); speedstep_chipset_dev = NULL; + pci_dev_put(hostbridge); return 0; } + pci_dev_put(hostbridge); return 2; /* 2-M */ } @@ -397,8 +399,10 @@ static int __init speedstep_init(void) } /* activate speedstep support */ - if (speedstep_activate()) + if (speedstep_activate()) { + pci_dev_put(speedstep_chipset_dev); return -EINVAL; + } return cpufreq_register_driver(&speedstep_driver); } @@ -411,6 +415,7 @@ static int __init speedstep_init(void) */ static void __exit speedstep_exit(void) { + pci_dev_put(speedstep_chipset_dev); cpufreq_unregister_driver(&speedstep_driver); } diff -puN arch/i386/kernel/cpu/cyrix.c~bk-pci arch/i386/kernel/cpu/cyrix.c --- 25/arch/i386/kernel/cpu/cyrix.c~bk-pci 2004-10-01 20:07:40.067070576 -0700 +++ 25-akpm/arch/i386/kernel/cpu/cyrix.c 2004-10-01 20:07:40.305034400 -0700 @@ -187,6 +187,14 @@ static void __init geode_configure(void) } +#ifdef CONFIG_PCI +static struct pci_device_id cyrix_55x0[] = { + { PCI_DEVICE(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5510) }, + { PCI_DEVICE(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5520) }, + { }, +}; +#endif + static void __init init_cyrix(struct cpuinfo_x86 *c) { unsigned char dir0, dir0_msn, dir0_lsn, dir1 = 0; @@ -274,8 +282,7 @@ static void __init init_cyrix(struct cpu /* * The 5510/5520 companion chips have a funky PIT. */ - if (pci_find_device(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5510, NULL) || - pci_find_device(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5520, NULL)) + if (pci_dev_present(cyrix_55x0)) pit_latch_buggy = 1; /* GXm supports extended cpuid levels 'ala' AMD */ diff -puN arch/i386/kernel/cpu/mtrr/main.c~bk-pci arch/i386/kernel/cpu/mtrr/main.c --- 25/arch/i386/kernel/cpu/mtrr/main.c~bk-pci 2004-10-01 20:07:40.068070424 -0700 +++ 25-akpm/arch/i386/kernel/cpu/mtrr/main.c 2004-10-01 20:07:40.305034400 -0700 @@ -77,22 +77,24 @@ static int have_wrcomb(void) { struct pci_dev *dev; - if ((dev = pci_find_class(PCI_CLASS_BRIDGE_HOST << 8, NULL)) != NULL) { + if ((dev = pci_get_class(PCI_CLASS_BRIDGE_HOST << 8, NULL)) != NULL) { /* ServerWorks LE chipsets have problems with write-combining Don't allow it and leave room for other chipsets to be tagged */ if (dev->vendor == PCI_VENDOR_ID_SERVERWORKS && dev->device == PCI_DEVICE_ID_SERVERWORKS_LE) { printk(KERN_INFO "mtrr: Serverworks LE detected. Write-combining disabled.\n"); + pci_dev_put(dev); return 0; } /* Intel 450NX errata # 23. Non ascending cachline evictions to write combining memory may resulting in data corruption */ if (dev->vendor == PCI_VENDOR_ID_INTEL && - dev->device == PCI_DEVICE_ID_INTEL_82451NX) - { + dev->device == PCI_DEVICE_ID_INTEL_82451NX) { printk(KERN_INFO "mtrr: Intel 450NX MMC detected. Write-combining disabled.\n"); + pci_dev_put(dev); return 0; } + pci_dev_put(dev); } return (mtrr_if->have_wrcomb ? mtrr_if->have_wrcomb() : 0); } diff -puN arch/i386/kernel/scx200.c~bk-pci arch/i386/kernel/scx200.c --- 25/arch/i386/kernel/scx200.c~bk-pci 2004-10-01 20:07:40.070070120 -0700 +++ 25-akpm/arch/i386/kernel/scx200.c 2004-10-01 20:07:40.306034248 -0700 @@ -22,9 +22,47 @@ MODULE_LICENSE("GPL"); unsigned scx200_gpio_base = 0; long scx200_gpio_shadow[2]; +static struct pci_device_id scx200_tbl[] = { + { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SCx200_BRIDGE) }, + { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SC1100_BRIDGE) }, + { }, +}; +MODULE_DEVICE_TABLE(pci,scx200_tbl); + +static int __devinit scx200_probe(struct pci_dev *, const struct pci_device_id *); + +static struct pci_driver scx200_pci_driver = { + .name = "scx200", + .id_table = scx200_tbl, + .probe = scx200_probe, +}; + spinlock_t scx200_gpio_lock = SPIN_LOCK_UNLOCKED; static spinlock_t scx200_gpio_config_lock = SPIN_LOCK_UNLOCKED; +static int __devinit scx200_probe(struct pci_dev *pdev, const struct pci_device_id *ent) +{ + int bank; + unsigned base; + + base = pci_resource_start(pdev, 0); + printk(KERN_INFO NAME ": GPIO base 0x%x\n", base); + + if (request_region(base, SCx200_GPIO_SIZE, "NatSemi SCx200 GPIO") == 0) { + printk(KERN_ERR NAME ": can't allocate I/O for GPIOs\n"); + return -EBUSY; + } + + scx200_gpio_base = base; + + /* read the current values driven on the GPIO signals */ + for (bank = 0; bank < 2; ++bank) + scx200_gpio_shadow[bank] = inl(scx200_gpio_base + 0x10 * bank); + + return 0; + +} + u32 scx200_gpio_configure(int index, u32 mask, u32 bits) { u32 config, new_config; @@ -77,39 +115,14 @@ void scx200_gpio_dump(unsigned index) int __init scx200_init(void) { - struct pci_dev *bridge; - int bank; - unsigned base; - printk(KERN_INFO NAME ": NatSemi SCx200 Driver\n"); - if ((bridge = pci_find_device(PCI_VENDOR_ID_NS, - PCI_DEVICE_ID_NS_SCx200_BRIDGE, - NULL)) == NULL - && (bridge = pci_find_device(PCI_VENDOR_ID_NS, - PCI_DEVICE_ID_NS_SC1100_BRIDGE, - NULL)) == NULL) - return -ENODEV; - - base = pci_resource_start(bridge, 0); - printk(KERN_INFO NAME ": GPIO base 0x%x\n", base); - - if (request_region(base, SCx200_GPIO_SIZE, "NatSemi SCx200 GPIO") == 0) { - printk(KERN_ERR NAME ": can't allocate I/O for GPIOs\n"); - return -EBUSY; - } - - scx200_gpio_base = base; - - /* read the current values driven on the GPIO signals */ - for (bank = 0; bank < 2; ++bank) - scx200_gpio_shadow[bank] = inl(scx200_gpio_base + 0x10 * bank); - - return 0; + return pci_module_init(&scx200_pci_driver); } void __exit scx200_cleanup(void) { + pci_unregister_driver(&scx200_pci_driver); release_region(scx200_gpio_base, SCx200_GPIO_SIZE); } diff -puN arch/i386/pci/fixup.c~bk-pci arch/i386/pci/fixup.c --- 25/arch/i386/pci/fixup.c~bk-pci 2004-10-01 20:07:40.071069968 -0700 +++ 25-akpm/arch/i386/pci/fixup.c 2004-10-01 20:07:40.307034096 -0700 @@ -255,3 +255,41 @@ static void __init pci_fixup_nforce2(str } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2, pci_fixup_nforce2); +/* + * Fixup to mark boot BIOS video selected by BIOS before it changes + * + * From information provided by "Jon Smirl" + * + * 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 -puN arch/i386/pci/i386.c~bk-pci arch/i386/pci/i386.c --- 25/arch/i386/pci/i386.c~bk-pci 2004-10-01 20:07:40.072069816 -0700 +++ 25-akpm/arch/i386/pci/i386.c 2004-10-01 20:07:40.308033944 -0700 @@ -96,15 +96,13 @@ pcibios_align_resource(void *data, struc static void __init pcibios_allocate_bus_resources(struct list_head *bus_list) { - struct list_head *ln; struct pci_bus *bus; struct pci_dev *dev; int idx; struct resource *r, *pr; /* Depth-First Search on bus tree */ - for (ln=bus_list->next; ln != bus_list; ln=ln->next) { - bus = pci_bus_b(ln); + list_for_each_entry(bus, bus_list, node) { if ((dev = bus->self)) { for (idx = PCI_BRIDGE_RESOURCES; idx < PCI_NUM_RESOURCES; idx++) { r = &dev->resource[idx]; @@ -126,7 +124,7 @@ static void __init pcibios_allocate_reso u16 command; struct resource *r, *pr; - 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) { pci_read_config_word(dev, PCI_COMMAND, &command); for(idx = 0; idx < 6; idx++) { r = &dev->resource[idx]; @@ -164,13 +162,13 @@ static void __init pcibios_allocate_reso } } -static void __init pcibios_assign_resources(void) +static int __init pcibios_assign_resources(void) { struct pci_dev *dev = NULL; int idx; struct resource *r; - 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) { int class = dev->class >> 8; /* Don't touch classless devices and host bridges */ @@ -204,6 +202,7 @@ static void __init pcibios_assign_resour pci_assign_resource(dev, PCI_ROM_RESOURCE); } } + return 0; } void __init pcibios_resource_survey(void) @@ -212,9 +211,14 @@ void __init pcibios_resource_survey(void pcibios_allocate_bus_resources(&pci_root_buses); pcibios_allocate_resources(0); pcibios_allocate_resources(1); - pcibios_assign_resources(); } +/** + * called in fs_initcall (one below subsys_initcall), + * give a chance for motherboard reserve resources + */ +fs_initcall(pcibios_assign_resources); + int pcibios_enable_resources(struct pci_dev *dev, int mask) { u16 cmd, old_cmd; diff -puN arch/i386/pci/irq.c~bk-pci arch/i386/pci/irq.c --- 25/arch/i386/pci/irq.c~bk-pci 2004-10-01 20:07:40.074069512 -0700 +++ 25-akpm/arch/i386/pci/irq.c 2004-10-01 20:07:40.309033792 -0700 @@ -455,12 +455,18 @@ static int pirq_bios_set(struct pci_dev static __init int intel_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) { + struct pci_dev *dev1, *dev2; + /* 440GX has a proprietary PIRQ router -- don't use it */ - if ( pci_find_device(PCI_VENDOR_ID_INTEL, - PCI_DEVICE_ID_INTEL_82443GX_0, NULL) || - pci_find_device(PCI_VENDOR_ID_INTEL, - PCI_DEVICE_ID_INTEL_82443GX_2, NULL)) + 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); return 0; + } switch(device) { @@ -804,7 +810,7 @@ static int pcibios_lookup_irq(struct pci printk(KERN_INFO "PCI: %s IRQ %d for device %s\n", msg, irq, pci_name(dev)); /* Update IRQ for all devices with the same pirq value */ - while ((dev2 = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev2)) != NULL) { + while ((dev2 = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev2)) != NULL) { pci_read_config_byte(dev2, PCI_INTERRUPT_PIN, &pin); if (!pin) continue; @@ -838,7 +844,7 @@ static void __init pcibios_fixup_irqs(vo u8 pin; DBG("PCI: IRQ fixup\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) { /* * If the BIOS has set an out of range IRQ number, just ignore it. * Also keep track of which IRQ's are already in use. @@ -854,7 +860,7 @@ static void __init pcibios_fixup_irqs(vo } dev = NULL; - 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) { pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); #ifdef CONFIG_X86_IO_APIC /* diff -puN arch/ia64/pci/pci.c~bk-pci arch/ia64/pci/pci.c --- 25/arch/ia64/pci/pci.c~bk-pci 2004-10-01 20:07:40.075069360 -0700 +++ 25-akpm/arch/ia64/pci/pci.c 2004-10-01 20:07:40.309033792 -0700 @@ -365,10 +365,10 @@ pcibios_fixup_device_resources (struct p void __devinit pcibios_fixup_bus (struct pci_bus *b) { - struct list_head *ln; + struct pci_dev *dev; - for (ln = b->devices.next; ln != &b->devices; ln = ln->next) - pcibios_fixup_device_resources(pci_dev_b(ln), b); + list_for_each_entry(dev, &b->devices, bus_list) + pcibios_fixup_device_resources(dev, b); return; } diff -puN arch/ia64/sn/io/machvec/pci_bus_cvlink.c~bk-pci arch/ia64/sn/io/machvec/pci_bus_cvlink.c --- 25/arch/ia64/sn/io/machvec/pci_bus_cvlink.c~bk-pci 2004-10-01 20:07:40.076069208 -0700 +++ 25-akpm/arch/ia64/sn/io/machvec/pci_bus_cvlink.c 2004-10-01 20:07:40.310033640 -0700 @@ -832,7 +832,6 @@ sn_pci_init (void) { int i = 0; struct pci_controller *controller; - struct list_head *ln; struct pci_bus *pci_bus = NULL; struct pci_dev *pci_dev = NULL; int ret; @@ -879,8 +878,7 @@ sn_pci_init (void) /* * Initialize the pci bus vertex in the pci_bus struct. */ - for( ln = pci_root_buses.next; ln != &pci_root_buses; ln = ln->next) { - pci_bus = pci_bus_b(ln); + list_for_each_entry(pci_bus, &pci_root_buses, node) { ret = sn_pci_fixup_bus(pci_bus); if ( ret ) { printk(KERN_WARNING diff -puN arch/ppc64/kernel/pci.c~bk-pci arch/ppc64/kernel/pci.c --- 25/arch/ppc64/kernel/pci.c~bk-pci 2004-10-01 20:07:40.078068904 -0700 +++ 25-akpm/arch/ppc64/kernel/pci.c 2004-10-01 20:07:40.316032728 -0700 @@ -179,26 +179,11 @@ void pcibios_align_resource(void *data, res->start = start; } -/* - * Allocate pci_controller(phb) initialized common variables. - */ -struct pci_controller * __init -pci_alloc_pci_controller(enum phb_types controller_type) +static void phb_set_model(struct pci_controller *hose, + enum phb_types controller_type) { - struct pci_controller *hose; char *model; -#ifdef CONFIG_PPC_ISERIES - hose = (struct pci_controller *)kmalloc(sizeof(struct pci_controller), GFP_KERNEL); -#else - hose = (struct pci_controller *)alloc_bootmem(sizeof(struct pci_controller)); -#endif - if(hose == NULL) { - printk(KERN_ERR "PCI: Allocate pci_controller failed.\n"); - return NULL; - } - memset(hose, 0, sizeof(struct pci_controller)); - switch(controller_type) { #ifdef CONFIG_PPC_ISERIES case phb_type_hypervisor: @@ -226,21 +211,71 @@ pci_alloc_pci_controller(enum phb_types strcpy(hose->what,model); else memcpy(hose->what,model,7); - hose->type = controller_type; - hose->global_number = global_phb_number++; +} +/* + * Allocate pci_controller(phb) initialized common variables. + */ +struct pci_controller * __init +pci_alloc_pci_controller(enum phb_types controller_type) +{ + struct pci_controller *hose; + +#ifdef CONFIG_PPC_ISERIES + hose = (struct pci_controller *)kmalloc(sizeof(struct pci_controller), + GFP_KERNEL); +#else + hose = (struct pci_controller *)alloc_bootmem(sizeof(struct pci_controller)); +#endif + if (hose == NULL) { + printk(KERN_ERR "PCI: Allocate pci_controller failed.\n"); + return NULL; + } + memset(hose, 0, sizeof(struct pci_controller)); + + phb_set_model(hose, controller_type); + + hose->is_dynamic = 0; + hose->type = controller_type; + hose->global_number = global_phb_number++; + + list_add_tail(&hose->list_node, &hose_list); + + return hose; +} + +/* + * Dymnamically allocate pci_controller(phb), initialize common variables. + */ +struct pci_controller * +pci_alloc_phb_dynamic(enum phb_types controller_type) +{ + struct pci_controller *hose; + + hose = (struct pci_controller *)kmalloc(sizeof(struct pci_controller), + GFP_KERNEL); + if(hose == NULL) { + printk(KERN_ERR "PCI: Allocate pci_controller failed.\n"); + return NULL; + } + memset(hose, 0, sizeof(struct pci_controller)); + + phb_set_model(hose, controller_type); + + hose->is_dynamic = 1; + hose->type = controller_type; + hose->global_number = global_phb_number++; list_add_tail(&hose->list_node, &hose_list); - return hose; + return hose; } static void __init pcibios_claim_one_bus(struct pci_bus *b) { - struct list_head *ld; + struct pci_dev *dev; struct pci_bus *child_bus; - for (ld = b->devices.next; ld != &b->devices; ld = ld->next) { - struct pci_dev *dev = pci_dev_b(ld); + list_for_each_entry(dev, &b->devices, bus_list) { int i; for (i = 0; i < PCI_NUM_RESOURCES; i++) { @@ -259,12 +294,10 @@ static void __init pcibios_claim_one_bus #ifndef CONFIG_PPC_ISERIES static void __init pcibios_claim_of_setup(void) { - struct list_head *lb; + struct pci_bus *b; - for (lb = pci_root_buses.next; lb != &pci_root_buses; lb = lb->next) { - struct pci_bus *b = pci_bus_b(lb); + list_for_each_entry(b, &pci_root_buses, node) pcibios_claim_one_bus(b); - } } #endif @@ -303,7 +336,7 @@ static int __init pcibios_init(void) ppc_md.pcibios_fixup(); /* Cache the location of the ISA bridge (if we have one) */ - ppc64_isabridge_dev = pci_find_class(PCI_CLASS_BRIDGE_ISA << 8, NULL); + ppc64_isabridge_dev = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, NULL); if (ppc64_isabridge_dev != NULL) printk("ISA bridge at %s\n", pci_name(ppc64_isabridge_dev)); @@ -534,7 +567,7 @@ void pcibios_add_platform_entries(struct #define ISA_SPACE_MASK 0x1 #define ISA_SPACE_IO 0x1 -static void pci_process_ISA_OF_ranges(struct device_node *isa_node, +static void __devinit pci_process_ISA_OF_ranges(struct device_node *isa_node, unsigned long phb_io_base_phys, void * phb_io_base_virt) { @@ -579,8 +612,8 @@ static void pci_process_ISA_OF_ranges(st } } -void __init pci_process_bridge_OF_ranges(struct pci_controller *hose, - struct device_node *dev, int primary) +void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose, + struct device_node *dev) { unsigned int *ranges; unsigned long size; @@ -589,7 +622,6 @@ void __init pci_process_bridge_OF_ranges struct resource *res; int np, na = prom_n_addr_cells(dev); unsigned long pci_addr, cpu_phys_addr; - struct device_node *isa_dn; np = na + 5; @@ -617,31 +649,11 @@ void __init pci_process_bridge_OF_ranges switch (ranges[0] >> 24) { case 1: /* I/O space */ hose->io_base_phys = cpu_phys_addr; - hose->io_base_virt = reserve_phb_iospace(size); - PPCDBG(PPCDBG_PHBINIT, - "phb%d io_base_phys 0x%lx io_base_virt 0x%lx\n", - hose->global_number, hose->io_base_phys, - (unsigned long) hose->io_base_virt); - - if (primary) { - pci_io_base = (unsigned long)hose->io_base_virt; - isa_dn = of_find_node_by_type(NULL, "isa"); - if (isa_dn) { - isa_io_base = pci_io_base; - pci_process_ISA_OF_ranges(isa_dn, - hose->io_base_phys, - hose->io_base_virt); - of_node_put(isa_dn); - /* Allow all IO */ - io_page_mask = -1; - } - } + hose->pci_io_size = size; res = &hose->io_resource; res->flags = IORESOURCE_IO; res->start = pci_addr; - res->start += (unsigned long)hose->io_base_virt - - pci_io_base; break; case 2: /* memory space */ memno = 0; @@ -668,6 +680,55 @@ void __init pci_process_bridge_OF_ranges } } +void __init pci_setup_phb_io(struct pci_controller *hose, int primary) +{ + unsigned long size = hose->pci_io_size; + unsigned long io_virt_offset; + struct resource *res; + struct device_node *isa_dn; + + hose->io_base_virt = reserve_phb_iospace(size); + PPCDBG(PPCDBG_PHBINIT, "phb%d io_base_phys 0x%lx io_base_virt 0x%lx\n", + hose->global_number, hose->io_base_phys, + (unsigned long) hose->io_base_virt); + + if (primary) { + pci_io_base = (unsigned long)hose->io_base_virt; + isa_dn = of_find_node_by_type(NULL, "isa"); + if (isa_dn) { + isa_io_base = pci_io_base; + pci_process_ISA_OF_ranges(isa_dn, hose->io_base_phys, + hose->io_base_virt); + of_node_put(isa_dn); + /* Allow all IO */ + io_page_mask = -1; + } + } + + io_virt_offset = (unsigned long)hose->io_base_virt - pci_io_base; + res = &hose->io_resource; + res->start += io_virt_offset; + res->end += io_virt_offset; +} + +void __devinit pci_setup_phb_io_dynamic(struct pci_controller *hose) +{ + unsigned long size = hose->pci_io_size; + unsigned long io_virt_offset; + struct resource *res; + + hose->io_base_virt = __ioremap(hose->io_base_phys, size, + _PAGE_NO_CACHE); + PPCDBG(PPCDBG_PHBINIT, "phb%d io_base_phys 0x%lx io_base_virt 0x%lx\n", + hose->global_number, hose->io_base_phys, + (unsigned long) hose->io_base_virt); + + io_virt_offset = (unsigned long)hose->io_base_virt - pci_io_base; + res = &hose->io_resource; + res->start += io_virt_offset; + res->end += io_virt_offset; +} + /*********************************************************************** * pci_find_hose_for_OF_device * diff -puN arch/ppc64/kernel/pci_dn.c~bk-pci arch/ppc64/kernel/pci_dn.c --- 25/arch/ppc64/kernel/pci_dn.c~bk-pci 2004-10-01 20:07:40.079068752 -0700 +++ 25-akpm/arch/ppc64/kernel/pci_dn.c 2004-10-01 20:07:40.317032576 -0700 @@ -42,7 +42,7 @@ * Traverse_func that inits the PCI fields of the device node. * NOTE: this *must* be done before read/write config to the device. */ -static void * __init update_dn_pci_info(struct device_node *dn, void *data) +static void * __devinit update_dn_pci_info(struct device_node *dn, void *data) { struct pci_controller *phb = data; u32 *regs; @@ -139,6 +139,12 @@ static void *traverse_all_pci_devices(tr return NULL; } +void __devinit pci_devs_phb_init_dynamic(struct pci_controller *phb) +{ + /* Update dn->phb ptrs for new phb and children devices */ + traverse_pci_devices((struct device_node *)phb->arch_data, + update_dn_pci_info, phb); +} /* * Traversal func that looks for a value. @@ -196,11 +202,9 @@ void __init pci_devs_phb_init(void) static void __init pci_fixup_bus_sysdata_list(struct list_head *bus_list) { - struct list_head *ln; struct pci_bus *bus; - for (ln = bus_list->next; ln != bus_list; ln = ln->next) { - bus = pci_bus_b(ln); + list_for_each_entry(bus, bus_list, node) { if (bus->self) bus->sysdata = bus->self->sysdata; pci_fixup_bus_sysdata_list(&bus->children); diff -puN arch/ppc64/kernel/pci.h~bk-pci arch/ppc64/kernel/pci.h --- 25/arch/ppc64/kernel/pci.h~bk-pci 2004-10-01 20:07:40.080068600 -0700 +++ 25-akpm/arch/ppc64/kernel/pci.h 2004-10-01 20:07:40.317032576 -0700 @@ -15,7 +15,12 @@ extern unsigned long isa_io_base; extern struct pci_controller* pci_alloc_pci_controller(enum phb_types controller_type); +extern struct pci_controller* pci_alloc_phb_dynamic(enum phb_types controller_type); +extern void pci_setup_phb_io(struct pci_controller *hose, int primary); + extern struct pci_controller* pci_find_hose_for_OF_device(struct device_node* node); +extern void pci_setup_phb_io_dynamic(struct pci_controller *hose); + extern struct list_head hose_list; extern int global_phb_number; @@ -36,6 +41,7 @@ void *traverse_pci_devices(struct device void *data); void pci_devs_phb_init(void); +void pci_devs_phb_init_dynamic(struct pci_controller *phb); void pci_fix_bus_sysdata(void); struct device_node *fetch_dev_dn(struct pci_dev *dev); diff -puN arch/ppc64/kernel/pSeries_pci.c~bk-pci arch/ppc64/kernel/pSeries_pci.c --- 25/arch/ppc64/kernel/pSeries_pci.c~bk-pci 2004-10-01 20:07:40.082068296 -0700 +++ 25-akpm/arch/ppc64/kernel/pSeries_pci.c 2004-10-01 20:07:40.314033032 -0700 @@ -190,7 +190,7 @@ void __init init_pci_config_tokens (void ibm_write_pci_config = rtas_token("ibm,write-pci-config"); } -unsigned long __init get_phb_buid (struct device_node *phb) +unsigned long __devinit get_phb_buid (struct device_node *phb) { int addr_cells; unsigned int *buid_vals; @@ -220,48 +220,85 @@ unsigned long __init get_phb_buid (struc return buid; } -static struct pci_controller * __init alloc_phb(struct device_node *dev, - unsigned int addr_size_words) +static enum phb_types get_phb_type(struct device_node *dev) { - struct pci_controller *phb; - unsigned int *ui_ptr = NULL, len; - struct reg_property64 reg_struct; - int *bus_range; + enum phb_types type; char *model; - enum phb_types phb_type; - struct property *of_prop; model = (char *)get_property(dev, "model", NULL); if (!model) { - printk(KERN_ERR "alloc_phb: phb has no model property\n"); + printk(KERN_ERR "%s: phb has no model property\n", + __FUNCTION__); model = ""; } + if (strstr(model, "Python")) { + type = phb_type_python; + } else if (strstr(model, "Speedwagon")) { + type = phb_type_speedwagon; + } else if (strstr(model, "Winnipeg")) { + type = phb_type_winnipeg; + } else { + printk(KERN_ERR "%s: unknown PHB %s\n", __FUNCTION__, model); + type = phb_type_unknown; + } + + return type; +} + +int get_phb_reg_prop(struct device_node *dev, unsigned int addr_size_words, + struct reg_property64 *reg) +{ + unsigned int *ui_ptr = NULL, len; + /* Found a PHB, now figure out where his registers are mapped. */ ui_ptr = (unsigned int *) get_property(dev, "reg", &len); if (ui_ptr == NULL) { PPCDBG(PPCDBG_PHBINIT, "\tget reg failed.\n"); - return NULL; + return 1; } if (addr_size_words == 1) { - reg_struct.address = ((struct reg_property32 *)ui_ptr)->address; - reg_struct.size = ((struct reg_property32 *)ui_ptr)->size; + reg->address = ((struct reg_property32 *)ui_ptr)->address; + reg->size = ((struct reg_property32 *)ui_ptr)->size; } else { - reg_struct = *((struct reg_property64 *)ui_ptr); + *reg = *((struct reg_property64 *)ui_ptr); } - if (strstr(model, "Python")) { - phb_type = phb_type_python; - } else if (strstr(model, "Speedwagon")) { - phb_type = phb_type_speedwagon; - } else if (strstr(model, "Winnipeg")) { - phb_type = phb_type_winnipeg; - } else { - printk(KERN_ERR "alloc_phb: unknown PHB %s\n", model); - phb_type = phb_type_unknown; - } + return 0; +} + +int phb_set_bus_ranges(struct device_node *dev, struct pci_controller *phb) +{ + int *bus_range; + unsigned int len; + + bus_range = (int *) get_property(dev, "bus-range", &len); + if (bus_range == NULL || len < 2 * sizeof(int)) { + return 1; + } + + phb->first_busno = bus_range[0]; + phb->last_busno = bus_range[1]; + + return 0; +} + +static struct pci_controller *alloc_phb(struct device_node *dev, + unsigned int addr_size_words) +{ + struct pci_controller *phb; + struct reg_property64 reg_struct; + enum phb_types phb_type; + struct property *of_prop; + int rc; + + phb_type = get_phb_type(dev); + + rc = get_phb_reg_prop(dev, addr_size_words, ®_struct); + if (rc) + return NULL; phb = pci_alloc_pci_controller(phb_type); if (phb == NULL) @@ -270,11 +307,9 @@ static struct pci_controller * __init al if (phb_type == phb_type_python) python_countermeasures(reg_struct.address); - bus_range = (int *) get_property(dev, "bus-range", &len); - if (bus_range == NULL || len < 2 * sizeof(int)) { - kfree(phb); + rc = phb_set_bus_ranges(dev, phb); + if (rc) return NULL; - } of_prop = (struct property *)alloc_bootmem(sizeof(struct property) + sizeof(phb->global_number)); @@ -291,9 +326,6 @@ static struct pci_controller * __init al memcpy(of_prop->value, &phb->global_number, sizeof(phb->global_number)); prom_add_property(dev, of_prop); - phb->first_busno = bus_range[0]; - phb->last_busno = bus_range[1]; - phb->arch_data = dev; phb->ops = &rtas_pci_ops; @@ -302,6 +334,40 @@ static struct pci_controller * __init al return phb; } +static struct pci_controller * __devinit alloc_phb_dynamic(struct device_node *dev, unsigned int addr_size_words) +{ + struct pci_controller *phb; + struct reg_property64 reg_struct; + enum phb_types phb_type; + int rc; + + phb_type = get_phb_type(dev); + + rc = get_phb_reg_prop(dev, addr_size_words, ®_struct); + if (rc) + return NULL; + + phb = pci_alloc_phb_dynamic(phb_type); + if (phb == NULL) + return NULL; + + if (phb_type == phb_type_python) + python_countermeasures(reg_struct.address); + + rc = phb_set_bus_ranges(dev, phb); + if (rc) + return NULL; + + /* TODO: linux,pci-domain? */ + + phb->arch_data = dev; + phb->ops = &rtas_pci_ops; + + phb->buid = get_phb_buid(dev); + + return phb; +} + unsigned long __init find_and_init_phbs(void) { struct device_node *node; @@ -330,7 +396,8 @@ unsigned long __init find_and_init_phbs( if (!phb) continue; - pci_process_bridge_OF_ranges(phb, node, index == 0); + pci_process_bridge_OF_ranges(phb, node); + pci_setup_phb_io(phb, index == 0); if (naca->interrupt_controller == IC_OPEN_PIC) { int addr = root_size_cells * (index + 2) - 1; @@ -346,6 +413,34 @@ unsigned long __init find_and_init_phbs( return 0; } +struct pci_controller * __devinit init_phb_dynamic(struct device_node *dn) +{ + struct device_node *root = of_find_node_by_path("/"); + unsigned int root_size_cells = 0; + struct pci_controller *phb; + struct pci_bus *bus; + + root_size_cells = prom_n_size_cells(root); + + phb = alloc_phb_dynamic(dn, root_size_cells); + if (!phb) + return NULL; + + pci_process_bridge_OF_ranges(phb, dn); + + pci_setup_phb_io_dynamic(phb); + of_node_put(root); + + pci_devs_phb_init_dynamic(phb); + phb->last_busno = 0xff; + bus = pci_scan_bus(phb->first_busno, phb->ops, phb->arch_data); + phb->bus = bus; + phb->last_busno = bus->subordinate; + + return phb; +} +EXPORT_SYMBOL(init_phb_dynamic); + #if 0 void pcibios_name_device(struct pci_dev *dev) { @@ -372,6 +467,96 @@ void pcibios_name_device(struct pci_dev DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pcibios_name_device); #endif +void __devinit pcibios_fixup_device_resources(struct pci_dev *dev, + struct pci_bus *bus) +{ + /* Update device resources. */ + struct pci_controller *hose = PCI_GET_PHB_PTR(bus); + int i; + + for (i = 0; i < PCI_NUM_RESOURCES; i++) { + if (dev->resource[i].flags & IORESOURCE_IO) { + unsigned long offset = (unsigned long)hose->io_base_virt - pci_io_base; + unsigned long start, end, mask; + + start = dev->resource[i].start += offset; + end = dev->resource[i].end += offset; + + /* Need to allow IO access to pages that are in the + ISA range */ + if (start < MAX_ISA_PORT) { + if (end > MAX_ISA_PORT) + end = MAX_ISA_PORT; + + start >>= PAGE_SHIFT; + end >>= PAGE_SHIFT; + + /* get the range of pages for the map */ + mask = ((1 << (end+1))-1) ^ ((1 << start)-1); + io_page_mask |= mask; + } + } + else if (dev->resource[i].flags & IORESOURCE_MEM) { + dev->resource[i].start += hose->pci_mem_offset; + dev->resource[i].end += hose->pci_mem_offset; + } + } +} +EXPORT_SYMBOL(pcibios_fixup_device_resources); + +void __devinit pcibios_fixup_bus(struct pci_bus *bus) +{ + struct pci_controller *hose = PCI_GET_PHB_PTR(bus); + struct list_head *ln; + + /* XXX or bus->parent? */ + struct pci_dev *dev = bus->self; + struct resource *res; + int i; + + if (!dev) { + /* Root bus. */ + + hose->bus = bus; + bus->resource[0] = res = &hose->io_resource; + if (!res->flags) + BUG(); /* No I/O resource for this PHB? */ + + if (request_resource(&ioport_resource, res)) + printk(KERN_ERR "Failed to request IO on " + "PCI domain %d\n", pci_domain_nr(bus)); + + + for (i = 0; i < 3; ++i) { + res = &hose->mem_resources[i]; + if (!res->flags && i == 0) + BUG(); /* No memory resource for this PHB? */ + bus->resource[i+1] = res; + if (res->flags && request_resource(&iomem_resource, res)) + printk(KERN_ERR "Failed to request MEM on " + "PCI domain %d\n", + pci_domain_nr(bus)); + } + } else if (pci_probe_only && + (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) { + /* This is a subordinate bridge */ + + pci_read_bridge_bases(bus); + pcibios_fixup_device_resources(dev, bus); + } + + /* XXX Need to check why Alpha doesnt do this - Anton */ + if (!pci_probe_only) + return; + + for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) { + struct pci_dev *dev = pci_dev_b(ln); + if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI) + pcibios_fixup_device_resources(dev, bus); + } +} +EXPORT_SYMBOL(pcibios_fixup_bus); + static void check_s7a(void) { struct device_node *root; @@ -464,7 +649,7 @@ int remap_bus_range(struct pci_bus *bus) } EXPORT_SYMBOL(remap_bus_range); -static void phbs_fixup_io(void) +static void phbs_remap_io(void) { struct pci_controller *hose, *tmp; @@ -472,6 +657,56 @@ static void phbs_fixup_io(void) remap_bus_range(hose->bus); } +/* RPA-specific bits for removing PHBs */ +int pcibios_remove_root_bus(struct pci_controller *phb) +{ + struct pci_bus *b = phb->bus; + struct resource *res; + int rc, i; + + res = b->resource[0]; + if (!res->flags) { + printk(KERN_ERR "%s: no IO resource for PHB %s\n", __FUNCTION__, + b->name); + return 1; + } + + rc = unmap_bus_range(b); + if (rc) { + printk(KERN_ERR "%s: failed to unmap IO on bus %s\n", + __FUNCTION__, b->name); + return 1; + } + + if (release_resource(res)) { + printk(KERN_ERR "%s: failed to release IO on bus %s\n", + __FUNCTION__, b->name); + return 1; + } + + for (i = 1; i < 3; ++i) { + res = b->resource[i]; + if (!res->flags && i == 0) { + printk(KERN_ERR "%s: no MEM resource for PHB %s\n", + __FUNCTION__, b->name); + return 1; + } + if (res->flags && release_resource(res)) { + printk(KERN_ERR + "%s: failed to release IO %d on bus %s\n", + __FUNCTION__, i, b->name); + return 1; + } + } + + list_del(&phb->list_node); + if (phb->is_dynamic) + kfree(phb); + + return 0; +} +EXPORT_SYMBOL(pcibios_remove_root_bus); + static void __init pSeries_request_regions(void) { struct device_node *i8042; @@ -511,7 +746,7 @@ void __init pSeries_final_fixup(void) } } - phbs_fixup_io(); + phbs_remap_io(); pSeries_request_regions(); pci_fix_bus_sysdata(); diff -puN arch/ppc/kernel/pci.c~bk-pci arch/ppc/kernel/pci.c --- 25/arch/ppc/kernel/pci.c~bk-pci 2004-10-01 20:07:40.083068144 -0700 +++ 25-akpm/arch/ppc/kernel/pci.c 2004-10-01 20:07:40.312033336 -0700 @@ -231,14 +231,12 @@ EXPORT_SYMBOL(pcibios_align_resource); static void __init pcibios_allocate_bus_resources(struct list_head *bus_list) { - struct list_head *ln; struct pci_bus *bus; int i; struct resource *res, *pr; /* Depth-First Search on bus tree */ - for (ln = bus_list->next; ln != bus_list; ln=ln->next) { - bus = pci_bus_b(ln); + list_for_each_entry(bus, bus_list, node) { for (i = 0; i < 4; ++i) { if ((res = bus->resource[i]) == NULL || !res->flags || res->start > res->end) @@ -381,7 +379,6 @@ probe_resource(struct pci_bus *parent, s struct pci_bus *bus; struct pci_dev *dev; struct resource *r; - struct list_head *ln; int i; for (r = pr->child; r != NULL; r = r->sibling) { @@ -390,9 +387,7 @@ probe_resource(struct pci_bus *parent, s return 1; } } - for (ln = parent->children.next; ln != &parent->children; - ln = ln->next) { - bus = pci_bus_b(ln); + list_for_each_entry(bus, &parent->children, node) { for (i = 0; i < 4; ++i) { if ((r = bus->resource[i]) == NULL) continue; @@ -406,8 +401,7 @@ probe_resource(struct pci_bus *parent, s } } } - for (ln = parent->devices.next; ln != &parent->devices; ln=ln->next) { - dev = pci_dev_b(ln); + list_for_each_entry(dev, &parent->devices, bus_list) { for (i = 0; i < 6; ++i) { r = &dev->resource[i]; if (!r->flags || (r->flags & IORESOURCE_UNSET)) @@ -1102,7 +1096,7 @@ do_update_p2p_io_resource(struct pci_bus static int __init check_for_io_childs(struct pci_bus *bus, struct resource* res, int *found_vga) { - struct list_head *ln; + struct pci_dev *dev; int i; int rc = 0; @@ -1110,8 +1104,7 @@ check_for_io_childs(struct pci_bus *bus, res->end = ((res->end + __sz) / (__sz + 1)) * (__sz + 1) + __sz; \ } while (0) - for (ln=bus->devices.next; ln != &bus->devices; ln=ln->next) { - struct pci_dev *dev = pci_dev_b(ln); + list_for_each_entry(dev, &bus->devices, bus_list) { u16 class = dev->class >> 8; if (class == PCI_CLASS_DISPLAY_VGA || @@ -1152,7 +1145,7 @@ check_for_io_childs(struct pci_bus *bus, static void __init do_fixup_p2p_level(struct pci_bus *bus) { - struct list_head *ln; + struct pci_bus *b; int i, parent_io; int has_vga = 0; @@ -1163,8 +1156,7 @@ do_fixup_p2p_level(struct pci_bus *bus) if (parent_io >= 4) return; - for (ln=bus->children.next; ln != &bus->children; ln=ln->next) { - struct pci_bus *b = pci_bus_b(ln); + list_for_each_entry(b, &bus->children, node) { struct pci_dev *d = b->self; struct pci_controller* hose = (struct pci_controller *)d->sysdata; struct resource *res = b->resource[0]; @@ -1237,12 +1229,10 @@ do_fixup_p2p_level(struct pci_bus *bus) static void pcibios_fixup_p2p_bridges(void) { - struct list_head *ln; + struct pci_bus *b; - for(ln=pci_root_buses.next; ln != &pci_root_buses; ln=ln->next) { - struct pci_bus *b = pci_bus_b(ln); + list_for_each_entry(b, &pci_root_buses, node) do_fixup_p2p_level(b); - } } #endif /* CONFIG_PPC_PMAC */ diff -puN arch/sparc/kernel/pcic.c~bk-pci arch/sparc/kernel/pcic.c --- 25/arch/sparc/kernel/pcic.c~bk-pci 2004-10-01 20:07:40.085067840 -0700 +++ 25-akpm/arch/sparc/kernel/pcic.c 2004-10-01 20:07:40.318032424 -0700 @@ -603,7 +603,7 @@ pcic_fill_irq(struct linux_pcic *pcic, s */ void __init pcibios_fixup_bus(struct pci_bus *bus) { - struct list_head *walk; + struct pci_dev *dev; int i, has_io, has_mem; unsigned int cmd; struct linux_pcic *pcic; @@ -625,9 +625,7 @@ void __init pcibios_fixup_bus(struct pci return; } - walk = &bus->devices; - for (walk = walk->next; walk != &bus->devices; walk = walk->next) { - struct pci_dev *dev = pci_dev_b(walk); + list_for_each_entry(dev, &bus->devices, bus_list) { /* * Comment from i386 branch: diff -puN Documentation/pci.txt~bk-pci Documentation/pci.txt --- 25/Documentation/pci.txt~bk-pci 2004-10-01 20:07:40.086067688 -0700 +++ 25-akpm/Documentation/pci.txt 2004-10-01 20:07:40.299035312 -0700 @@ -141,16 +141,16 @@ for PCI devices manually using the follo Searching by vendor and device ID: struct pci_dev *dev = NULL; - while (dev = pci_find_device(VENDOR_ID, DEVICE_ID, dev)) + while (dev = pci_get_device(VENDOR_ID, DEVICE_ID, dev)) configure_device(dev); Searching by class ID (iterate in a similar way): - pci_find_class(CLASS_ID, dev) + pci_get_class(CLASS_ID, dev) Searching by both vendor/device and subsystem vendor/device ID: - pci_find_subsys(VENDOR_ID, DEVICE_ID, SUBSYS_VENDOR_ID, SUBSYS_DEVICE_ID, dev). + pci_get_subsys(VENDOR_ID, DEVICE_ID, SUBSYS_VENDOR_ID, SUBSYS_DEVICE_ID, dev). You can use the constant PCI_ANY_ID as a wildcard replacement for VENDOR_ID or DEVICE_ID. This allows searching for any device from a @@ -275,11 +275,12 @@ pci_present() of PCI subsystem when tr devices just return NULL. pcibios_(read|write)_* Superseded by their pci_(read|write)_* counterparts. -pcibios_find_* Superseded by their pci_find_* counterparts. -pci_for_each_dev() Superseded by pci_find_device() +pcibios_find_* Superseded by their pci_get_* counterparts. +pci_for_each_dev() Superseded by pci_get_device() pci_for_each_dev_reverse() Superseded by pci_find_device_reverse() pci_for_each_bus() Superseded by pci_find_next_bus() pci_find_device() Superseded by pci_get_device() pci_find_subsys() Superseded by pci_get_subsys() -pcibios_find_class() Superseded by pci_find_class() +pcibios_find_class() Superseded by pci_get_class() +pci_find_class() Superseded by pci_get_class() pci_(read|write)_*_nodev() Superseded by pci_bus_(read|write)_*() diff -puN Documentation/power/pci.txt~bk-pci Documentation/power/pci.txt --- 25/Documentation/power/pci.txt~bk-pci 2004-10-01 20:07:40.087067536 -0700 +++ 25-akpm/Documentation/power/pci.txt 2004-10-01 20:07:40.301035008 -0700 @@ -5,6 +5,7 @@ PCI Power Management An overview of the concepts and the related functions in the Linux kernel Patrick Mochel +(and others) --------------------------------------------------------------------------- @@ -31,10 +32,15 @@ The PCI PM spec defines 4 operating stat the higher the number, the longer the latency is for the device to return to an operational state (D0). +There are actually two D3 states. When someone talks about D3, they usually +mean D3hot, which corresponds to an ACPI D2 state (power is reduced, the +device may lose some context). But they may also mean D3cold, which is an +ACPI D3 state (power is fully off, all state was discarded); or both. + Bus power management is not covered in this version of this document. -Note that all PCI devices support D0 and D3 by default, regardless of whether or -not they implement any of the PCI PM spec. +Note that all PCI devices support D0 and D3cold by default, regardless of +whether or not they implement any of the PCI PM spec. The possible state transitions that a device can undergo are: @@ -204,15 +210,16 @@ if (dev->driver && dev->driver->suspend) dev->driver->suspend(dev,state); A driver uses this function to actually transition the device into a low power -state. This may include disabling I/O, memory and bus-mastering, as well as -physically transitioning the device to a lower power state. +state. This should include disabling I/O, IRQs, and bus-mastering, as well as +physically transitioning the device to a lower power state; it may also include +calls to pci_enable_wake(). Bus mastering may be disabled by doing: pci_disable_device(dev); For devices that support the PCI PM Spec, this may be used to set the device's -power state: +power state to match the suspend() parameter: pci_set_power_state(dev,state); @@ -223,7 +230,7 @@ The driver should be sure to track the c obviate the need for some operations. The driver should update the current_state field in its pci_dev structure in -this function. +this function, except for PM-capable devices when pci_set_power_state is used. resume ------ @@ -237,16 +244,28 @@ The resume callback may be called from a transition the device to the D0 state. The driver is responsible for reenabling any features of the device that had -been disabled during previous suspend calls and restoring all state that was -saved in previous save_state calls. +been disabled during previous suspend calls, such as IRQs and bus mastering, +as well as calling pci_restore_state(). + +If the device is currently in D3, it may need to be reinitialized in resume(). -If the device is currently in D3, it must be completely reinitialized, as it -must be assumed that the device has lost all of its context (even that of its -PCI config space). For almost all current drivers, this means that the -initialization code that the driver does at boot must be separated out and -called again from the resume callback. Note that some values for the device may -not have to be probed for this time around if they are saved before entering the -low power state. + * Some types of devices, like bus controllers, will preserve context in D3hot + (using Vcc power). Their drivers will often want to avoid re-initializing + them after re-entering D0 (perhaps to avoid resetting downstream devices). + + * Other kinds of devices in D3hot will discard device context as part of a + soft reset when re-entering the D0 state. + + * Devices resuming from D3cold always go through a power-on reset. Some + device context can also be preserved using Vaux power. + + * Some systems hide D3cold resume paths from drivers. For example, on PCs + the resume path for suspend-to-disk often runs BIOS powerup code, which + will sometimes re-initialize the device. + +To handle resets during D3 to D0 transitions, it may be convenient to share +device initialization code between probe() and resume(). Device parameters +can also be saved before the driver suspends into D3, avoiding re-probe. If the device supports the PCI PM Spec, it can use this to physically transition the device to D0: @@ -263,7 +282,7 @@ The driver should take note of the state ensure correct (and speedy) operation. The driver should update the current_state field in its pci_dev structure in -this function. +this function, except for PM-capable devices when pci_set_power_state is used. enable_wake diff -puN drivers/acpi/motherboard.c~bk-pci drivers/acpi/motherboard.c --- 25/drivers/acpi/motherboard.c~bk-pci 2004-10-01 20:07:40.089067232 -0700 +++ 25-akpm/drivers/acpi/motherboard.c 2004-10-01 20:07:40.319032272 -0700 @@ -170,4 +170,8 @@ static int __init acpi_motherboard_init( return 0; } -subsys_initcall(acpi_motherboard_init); +/** + * Reserve motherboard resources after PCI claim BARs, + * but before PCI assign resources for uninitialized PCI devices + */ +fs_initcall(acpi_motherboard_init); diff -puN drivers/acpi/processor.c~bk-pci drivers/acpi/processor.c --- 25/drivers/acpi/processor.c~bk-pci 2004-10-01 20:07:40.090067080 -0700 +++ 25-akpm/drivers/acpi/processor.c 2004-10-01 20:07:40.321031968 -0700 @@ -213,11 +213,13 @@ acpi_processor_errata_piix4 ( * each IDE controller's DMA status to make sure we catch all * DMA activity. */ - dev = pci_find_subsys(PCI_VENDOR_ID_INTEL, + dev = pci_get_subsys(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB, PCI_ANY_ID, PCI_ANY_ID, NULL); - if (dev) + if (dev) { errata.piix4.bmisx = pci_resource_start(dev, 4); + pci_dev_put(dev); + } /* * Type-F DMA @@ -228,7 +230,7 @@ acpi_processor_errata_piix4 ( * disable C3 support if this is enabled, as some legacy * devices won't operate well if fast DMA is disabled. */ - dev = pci_find_subsys(PCI_VENDOR_ID_INTEL, + dev = pci_get_subsys(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_0, PCI_ANY_ID, PCI_ANY_ID, NULL); if (dev) { @@ -236,6 +238,7 @@ acpi_processor_errata_piix4 ( pci_read_config_byte(dev, 0x77, &value2); if ((value1 & 0x80) || (value2 & 0x80)) errata.piix4.fdma = 1; + pci_dev_put(dev); } break; @@ -267,10 +270,12 @@ acpi_processor_errata ( /* * PIIX4 */ - dev = pci_find_subsys(PCI_VENDOR_ID_INTEL, + dev = pci_get_subsys(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3, PCI_ANY_ID, PCI_ANY_ID, NULL); - if (dev) + if (dev) { result = acpi_processor_errata_piix4(dev); + pci_dev_put(dev); + } return_VALUE(result); } diff -puN drivers/atm/idt77252.c~bk-pci drivers/atm/idt77252.c --- 25/drivers/atm/idt77252.c~bk-pci 2004-10-01 20:07:40.102065256 -0700 +++ 25-akpm/drivers/atm/idt77252.c 2004-10-01 20:07:40.324031512 -0700 @@ -1266,8 +1266,9 @@ idt77252_rx_raw(struct idt77252_dev *car head = IDT77252_PRV_PADDR(queue) + (queue->data - queue->head - 16); tail = readl(SAR_REG_RAWCT); - pci_dma_sync_single(card->pcidev, IDT77252_PRV_PADDR(queue), - queue->end - queue->head - 16, PCI_DMA_FROMDEVICE); + pci_dma_sync_single_for_cpu(card->pcidev, IDT77252_PRV_PADDR(queue), + queue->end - queue->head - 16, + PCI_DMA_FROMDEVICE); while (head != tail) { unsigned int vpi, vci, pti; @@ -1360,10 +1361,10 @@ drop: if (next) { card->raw_cell_head = next; queue = card->raw_cell_head; - pci_dma_sync_single(card->pcidev, - IDT77252_PRV_PADDR(queue), - queue->end - queue->data, - PCI_DMA_FROMDEVICE); + pci_dma_sync_single_for_cpu(card->pcidev, + IDT77252_PRV_PADDR(queue), + queue->end - queue->data, + PCI_DMA_FROMDEVICE); } else { card->raw_cell_head = NULL; printk("%s: raw cell queue overrun\n", diff -puN drivers/char/agp/intel-agp.c~bk-pci drivers/char/agp/intel-agp.c --- 25/drivers/char/agp/intel-agp.c~bk-pci 2004-10-01 20:07:40.103065104 -0700 +++ 25-akpm/drivers/char/agp/intel-agp.c 2004-10-01 20:07:40.326031208 -0700 @@ -1723,7 +1723,7 @@ static int agp_intel_resume(struct pci_d { struct agp_bridge_data *bridge = pci_get_drvdata(pdev); - pci_restore_state(pdev, pdev->saved_config_space); + pci_restore_state(pdev); if (bridge->driver == &intel_generic_driver) intel_configure(); diff -puN drivers/char/agp/intel-mch-agp.c~bk-pci drivers/char/agp/intel-mch-agp.c --- 25/drivers/char/agp/intel-mch-agp.c~bk-pci 2004-10-01 20:07:40.105064800 -0700 +++ 25-akpm/drivers/char/agp/intel-mch-agp.c 2004-10-01 20:07:40.326031208 -0700 @@ -573,7 +573,7 @@ static int agp_intelmch_resume(struct pc { struct agp_bridge_data *bridge = pci_get_drvdata(pdev); - pci_restore_state(pdev, pdev->saved_config_space); + pci_restore_state(pdev); if (bridge->driver == &intel_845_driver) intel_845_configure(); diff -puN drivers/char/applicom.c~bk-pci drivers/char/applicom.c --- 25/drivers/char/applicom.c~bk-pci 2004-10-01 20:07:40.106064648 -0700 +++ 25-akpm/drivers/char/applicom.c 2004-10-01 20:07:40.327031056 -0700 @@ -200,7 +200,7 @@ int __init applicom_init(void) /* No mem and irq given - check for a PCI card */ - while ( (dev = pci_find_class(PCI_CLASS_OTHERS << 16, dev))) { + while ( (dev = pci_get_class(PCI_CLASS_OTHERS << 16, dev))) { if (dev->vendor != PCI_VENDOR_ID_APPLICOM) continue; diff -puN drivers/char/drm/drm_fops.h~bk-pci drivers/char/drm/drm_fops.h --- 25/drivers/char/drm/drm_fops.h~bk-pci 2004-10-01 20:07:40.107064496 -0700 +++ 25-akpm/drivers/char/drm/drm_fops.h 2004-10-01 20:07:40.328030904 -0700 @@ -99,8 +99,11 @@ int DRM(open_helper)(struct inode *inode */ if (!dev->hose) { struct pci_dev *pci_dev; - pci_dev = pci_find_class(PCI_CLASS_DISPLAY_VGA << 8, NULL); - if (pci_dev) dev->hose = pci_dev->sysdata; + pci_dev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, NULL); + if (pci_dev) { + dev->hose = pci_dev->sysdata; + pci_dev_put(pci_dev); + } if (!dev->hose) { struct pci_bus *b = pci_bus_b(pci_root_buses.next); if (b) dev->hose = b->sysdata; diff -puN drivers/char/ipmi/ipmi_si_intf.c~bk-pci drivers/char/ipmi/ipmi_si_intf.c --- 25/drivers/char/ipmi/ipmi_si_intf.c~bk-pci 2004-10-01 20:07:40.109064192 -0700 +++ 25-akpm/drivers/char/ipmi/ipmi_si_intf.c 2004-10-01 20:07:40.337029536 -0700 @@ -1775,10 +1775,10 @@ static int find_pci_smic(int intf_num, s pci_smic_checked = 1; - if ((pci_dev = pci_find_device(PCI_HP_VENDOR_ID, PCI_MMC_DEVICE_ID, + if ((pci_dev = pci_get_device(PCI_HP_VENDOR_ID, PCI_MMC_DEVICE_ID, NULL))) ; - else if ((pci_dev = pci_find_class(PCI_ERMC_CLASSCODE, NULL)) && + else if ((pci_dev = pci_get_class(PCI_ERMC_CLASSCODE, NULL)) && pci_dev->subsystem_vendor == PCI_HP_VENDOR_ID) fe_rmc = 1; else @@ -1787,6 +1787,7 @@ static int find_pci_smic(int intf_num, s error = pci_read_config_word(pci_dev, PCI_MMC_ADDR_CW, &base_addr); if (error) { + pci_dev_put(pci_dev); printk(KERN_ERR "ipmi_si: pci_read_config_word() failed (%d).\n", error); @@ -1796,6 +1797,7 @@ static int find_pci_smic(int intf_num, s /* Bit 0: 1 specifies programmed I/O, 0 specifies memory mapped I/O */ if (!(base_addr & 0x0001)) { + pci_dev_put(pci_dev); printk(KERN_ERR "ipmi_si: memory mapped I/O not supported for PCI" " smic.\n"); @@ -1807,11 +1809,14 @@ static int find_pci_smic(int intf_num, s /* Data register starts at base address + 1 in eRMC */ ++base_addr; - if (!is_new_interface(-1, IPMI_IO_ADDR_SPACE, base_addr)) - return -ENODEV; + if (!is_new_interface(-1, IPMI_IO_ADDR_SPACE, base_addr)) { + pci_dev_put(pci_dev); + return -ENODEV; + } info = kmalloc(sizeof(*info), GFP_KERNEL); if (!info) { + pci_dev_put(pci_dev); printk(KERN_ERR "ipmi_si: Could not allocate SI data (5)\n"); return -ENOMEM; } @@ -1834,6 +1839,7 @@ static int find_pci_smic(int intf_num, s printk("ipmi_si: Found PCI SMIC at I/O address 0x%lx\n", (long unsigned int) base_addr); + pci_dev_put(pci_dev); return 0; } #endif /* CONFIG_PCI */ diff -puN drivers/media/video/bttv-cards.c~bk-pci drivers/media/video/bttv-cards.c --- 25/drivers/media/video/bttv-cards.c~bk-pci 2004-10-01 20:07:40.111063888 -0700 +++ 25-akpm/drivers/media/video/bttv-cards.c 2004-10-01 20:07:40.340029080 -0700 @@ -4045,7 +4045,7 @@ void __devinit bttv_check_chipset(void) #if 0 /* print which chipset we have */ - while ((dev = pci_find_class(PCI_CLASS_BRIDGE_HOST << 8,dev))) + while ((dev = pci_get_class(PCI_CLASS_BRIDGE_HOST << 8,dev))) printk(KERN_INFO "bttv: Host bridge is %s\n",pci_name(dev)); #endif @@ -4064,8 +4064,8 @@ void __devinit bttv_check_chipset(void) if (UNSET != latency) printk(KERN_INFO "bttv: pci latency fixup [%d]\n",latency); - while ((dev = pci_find_device(PCI_VENDOR_ID_INTEL, - PCI_DEVICE_ID_INTEL_82441, dev))) { + while ((dev = pci_get_device(PCI_VENDOR_ID_INTEL, + PCI_DEVICE_ID_INTEL_82441, dev))) { unsigned char b; pci_read_config_byte(dev, 0x53, &b); if (bttv_debug) diff -puN drivers/media/video/bttv-driver.c~bk-pci drivers/media/video/bttv-driver.c --- 25/drivers/media/video/bttv-driver.c~bk-pci 2004-10-01 20:07:40.113063584 -0700 +++ 25-akpm/drivers/media/video/bttv-driver.c 2004-10-01 20:07:40.343028624 -0700 @@ -3944,7 +3944,7 @@ static int bttv_suspend(struct pci_dev * btv->state.gpio_data = gpio_read(); /* save pci state */ - pci_save_state(pci_dev, btv->state.pci_cfg); + pci_save_state(pci_dev); if (0 != pci_set_power_state(pci_dev, state)) { pci_disable_device(pci_dev); btv->state.disabled = 1; @@ -3965,7 +3965,7 @@ static int bttv_resume(struct pci_dev *p btv->state.disabled = 0; } pci_set_power_state(pci_dev, 0); - pci_restore_state(pci_dev, btv->state.pci_cfg); + pci_restore_state(pci_dev); /* restore bt878 state */ bttv_reinit_bt848(btv); diff -puN drivers/media/video/bttvp.h~bk-pci drivers/media/video/bttvp.h --- 25/drivers/media/video/bttvp.h~bk-pci 2004-10-01 20:07:40.114063432 -0700 +++ 25-akpm/drivers/media/video/bttvp.h 2004-10-01 20:07:40.344028472 -0700 @@ -277,7 +277,6 @@ struct bttv_input { }; struct bttv_suspend_state { - u32 pci_cfg[64 / sizeof(u32)]; u32 gpio_enable; u32 gpio_data; int disabled; diff -puN drivers/media/video/cx88/cx88.h~bk-pci drivers/media/video/cx88/cx88.h --- 25/drivers/media/video/cx88/cx88.h~bk-pci 2004-10-01 20:07:40.116063128 -0700 +++ 25-akpm/drivers/media/video/cx88/cx88.h 2004-10-01 20:07:40.346028168 -0700 @@ -216,7 +216,6 @@ struct cx8800_fh { }; struct cx8800_suspend_state { - u32 pci_cfg[64 / sizeof(u32)]; int disabled; }; diff -puN drivers/media/video/cx88/cx88-video.c~bk-pci drivers/media/video/cx88/cx88-video.c --- 25/drivers/media/video/cx88/cx88-video.c~bk-pci 2004-10-01 20:07:40.117062976 -0700 +++ 25-akpm/drivers/media/video/cx88/cx88-video.c 2004-10-01 20:07:40.345028320 -0700 @@ -2545,7 +2545,7 @@ static int cx8800_suspend(struct pci_dev cx8800_shutdown(dev); del_timer(&dev->vidq.timeout); - pci_save_state(pci_dev, dev->state.pci_cfg); + pci_save_state(pci_dev); if (0 != pci_set_power_state(pci_dev, state)) { pci_disable_device(pci_dev); dev->state.disabled = 1; @@ -2564,7 +2564,7 @@ static int cx8800_resume(struct pci_dev dev->state.disabled = 0; } pci_set_power_state(pci_dev, 0); - pci_restore_state(pci_dev, dev->state.pci_cfg); + pci_restore_state(pci_dev); /* re-initialize hardware */ cx8800_reset(dev); diff -puN drivers/media/video/meye.c~bk-pci drivers/media/video/meye.c --- 25/drivers/media/video/meye.c~bk-pci 2004-10-01 20:07:40.119062672 -0700 +++ 25-akpm/drivers/media/video/meye.c 2004-10-01 20:07:40.347028016 -0700 @@ -1236,7 +1236,7 @@ static struct video_device meye_template #ifdef CONFIG_PM static int meye_suspend(struct pci_dev *pdev, u32 state) { - pci_save_state(pdev, meye.pm_state); + pci_save_state(pdev); meye.pm_mchip_mode = meye.mchip_mode; mchip_hic_stop(); mchip_set(MCHIP_MM_INTA, 0x0); @@ -1245,7 +1245,7 @@ static int meye_suspend(struct pci_dev * static int meye_resume(struct pci_dev *pdev) { - pci_restore_state(pdev, meye.pm_state); + pci_restore_state(pdev); pci_write_config_word(meye.mchip_dev, MCHIP_PCI_SOFTRESET_SET, 1); mchip_delay(MCHIP_HIC_CMD, 0); diff -puN drivers/media/video/meye.h~bk-pci drivers/media/video/meye.h --- 25/drivers/media/video/meye.h~bk-pci 2004-10-01 20:07:40.120062520 -0700 +++ 25-akpm/drivers/media/video/meye.h 2004-10-01 20:07:40.348027864 -0700 @@ -315,7 +315,6 @@ struct meye { struct video_picture picture; /* video picture parameters */ struct meye_params params; /* additional parameters */ #ifdef CONFIG_PM - u32 pm_state[16]; /* PCI configuration space */ u8 pm_mchip_mode; /* old mchip mode */ #endif }; diff -puN drivers/message/fusion/mptbase.c~bk-pci drivers/message/fusion/mptbase.c --- 25/drivers/message/fusion/mptbase.c~bk-pci 2004-10-01 20:07:40.122062216 -0700 +++ 25-akpm/drivers/message/fusion/mptbase.c 2004-10-01 20:07:40.352027256 -0700 @@ -1517,7 +1517,7 @@ mptbase_suspend(struct pci_dev *pdev, u3 } } - pci_save_state(pdev, ioc->PciState); + pci_save_state(pdev); /* put ioc into READY_STATE */ if(SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) { @@ -1557,7 +1557,7 @@ mptbase_resume(struct pci_dev *pdev) ioc->name, pdev, pci_name(pdev), device_state); pci_set_power_state(pdev, 0); - pci_restore_state(pdev, ioc->PciState); + pci_restore_state(pdev); pci_enable_device(pdev); /* enable interrupts */ diff -puN drivers/message/fusion/mptbase.h~bk-pci drivers/message/fusion/mptbase.h --- 25/drivers/message/fusion/mptbase.h~bk-pci 2004-10-01 20:07:40.124061912 -0700 +++ 25-akpm/drivers/message/fusion/mptbase.h 2004-10-01 20:07:40.354026952 -0700 @@ -663,9 +663,6 @@ typedef struct _MPT_ADAPTER FCPortPage0_t fc_port_page0[2]; LANPage0_t lan_cnfg_page0; LANPage1_t lan_cnfg_page1; -#ifdef CONFIG_PM - u32 PciState[64]; /* save PCI state to this area */ -#endif u8 FirstWhoInit; u8 upload_fw; /* If set, do a fw upload */ u8 reload_fw; /* Force a FW Reload on next reset */ diff -puN drivers/misc/ibmasm/ibmasmfs.c~bk-pci drivers/misc/ibmasm/ibmasmfs.c --- 25/drivers/misc/ibmasm/ibmasmfs.c~bk-pci 2004-10-01 20:07:40.125061760 -0700 +++ 25-akpm/drivers/misc/ibmasm/ibmasmfs.c 2004-10-01 20:07:40.355026800 -0700 @@ -520,7 +520,7 @@ static int remote_settings_file_close(st static ssize_t remote_settings_file_read(struct file *file, char __user *buf, size_t count, loff_t *offset) { - unsigned long address = (unsigned long)file->private_data; + void __iomem *address = (void __iomem *)file->private_data; unsigned char *page; int retval; int len = 0; @@ -554,7 +554,7 @@ exit: static ssize_t remote_settings_file_write(struct file *file, const char __user *ubuff, size_t count, loff_t *offset) { - unsigned long address = (unsigned long)file->private_data; + void __iomem *address = (void __iomem *)file->private_data; char *buff; unsigned int value; diff -puN drivers/misc/ibmasm/ibmasm.h~bk-pci drivers/misc/ibmasm/ibmasm.h --- 25/drivers/misc/ibmasm/ibmasm.h~bk-pci 2004-10-01 20:07:40.127061456 -0700 +++ 25-akpm/drivers/misc/ibmasm/ibmasm.h 2004-10-01 20:07:40.354026952 -0700 @@ -158,7 +158,7 @@ struct remote_queue { struct service_processor { struct list_head node; spinlock_t lock; - void *base_address; + void __iomem *base_address; unsigned int irq; struct command *current_command; struct command *heartbeat; diff -puN drivers/misc/ibmasm/lowlevel.c~bk-pci drivers/misc/ibmasm/lowlevel.c --- 25/drivers/misc/ibmasm/lowlevel.c~bk-pci 2004-10-01 20:07:40.128061304 -0700 +++ 25-akpm/drivers/misc/ibmasm/lowlevel.c 2004-10-01 20:07:40.355026800 -0700 @@ -58,7 +58,7 @@ irqreturn_t ibmasm_interrupt_handler(int { u32 mfa; struct service_processor *sp = (struct service_processor *)dev_id; - void *base_address = sp->base_address; + void __iomem *base_address = sp->base_address; if (!sp_interrupt_pending(base_address)) return IRQ_NONE; diff -puN drivers/misc/ibmasm/lowlevel.h~bk-pci drivers/misc/ibmasm/lowlevel.h --- 25/drivers/misc/ibmasm/lowlevel.h~bk-pci 2004-10-01 20:07:40.130061000 -0700 +++ 25-akpm/drivers/misc/ibmasm/lowlevel.h 2004-10-01 20:07:40.356026648 -0700 @@ -52,51 +52,51 @@ #define SCOUT_COM_C_BASE 0x0200 #define SCOUT_COM_D_BASE 0x0300 -static inline int sp_interrupt_pending(void *base_address) +static inline int sp_interrupt_pending(void __iomem *base_address) { return SP_INTR_MASK & readl(base_address + INTR_STATUS_REGISTER); } -static inline int uart_interrupt_pending(void *base_address) +static inline int uart_interrupt_pending(void __iomem *base_address) { return UART_INTR_MASK & readl(base_address + INTR_STATUS_REGISTER); } -static inline void ibmasm_enable_interrupts(void *base_address, int mask) +static inline void ibmasm_enable_interrupts(void __iomem *base_address, int mask) { - void *ctrl_reg = base_address + INTR_CONTROL_REGISTER; + void __iomem *ctrl_reg = base_address + INTR_CONTROL_REGISTER; writel( readl(ctrl_reg) & ~mask, ctrl_reg); } -static inline void ibmasm_disable_interrupts(void *base_address, int mask) +static inline void ibmasm_disable_interrupts(void __iomem *base_address, int mask) { - void *ctrl_reg = base_address + INTR_CONTROL_REGISTER; + void __iomem *ctrl_reg = base_address + INTR_CONTROL_REGISTER; writel( readl(ctrl_reg) | mask, ctrl_reg); } -static inline void enable_sp_interrupts(void *base_address) +static inline void enable_sp_interrupts(void __iomem *base_address) { ibmasm_enable_interrupts(base_address, SP_INTR_MASK); } -static inline void disable_sp_interrupts(void *base_address) +static inline void disable_sp_interrupts(void __iomem *base_address) { ibmasm_disable_interrupts(base_address, SP_INTR_MASK); } -static inline void enable_uart_interrupts(void *base_address) +static inline void enable_uart_interrupts(void __iomem *base_address) { ibmasm_enable_interrupts(base_address, UART_INTR_MASK); } -static inline void disable_uart_interrupts(void *base_address) +static inline void disable_uart_interrupts(void __iomem *base_address) { ibmasm_disable_interrupts(base_address, UART_INTR_MASK); } #define valid_mfa(mfa) ( (mfa) != NO_MFAS_AVAILABLE ) -static inline u32 get_mfa_outbound(void *base_address) +static inline u32 get_mfa_outbound(void __iomem *base_address) { int retry; u32 mfa; @@ -109,12 +109,12 @@ static inline u32 get_mfa_outbound(void return mfa; } -static inline void set_mfa_outbound(void *base_address, u32 mfa) +static inline void set_mfa_outbound(void __iomem *base_address, u32 mfa) { writel(mfa, base_address + OUTBOUND_QUEUE_PORT); } -static inline u32 get_mfa_inbound(void *base_address) +static inline u32 get_mfa_inbound(void __iomem *base_address) { u32 mfa = readl(base_address + INBOUND_QUEUE_PORT); @@ -124,12 +124,12 @@ static inline u32 get_mfa_inbound(void * return mfa; } -static inline void set_mfa_inbound(void *base_address, u32 mfa) +static inline void set_mfa_inbound(void __iomem *base_address, u32 mfa) { writel(mfa, base_address + INBOUND_QUEUE_PORT); } -static inline struct i2o_message *get_i2o_message(void *base_address, u32 mfa) +static inline struct i2o_message *get_i2o_message(void __iomem *base_address, u32 mfa) { return (struct i2o_message *)(GET_MFA_ADDR(mfa) + base_address); } diff -puN drivers/misc/ibmasm/uart.c~bk-pci drivers/misc/ibmasm/uart.c --- 25/drivers/misc/ibmasm/uart.c~bk-pci 2004-10-01 20:07:40.131060848 -0700 +++ 25-akpm/drivers/misc/ibmasm/uart.c 2004-10-01 20:07:40.356026648 -0700 @@ -34,7 +34,7 @@ void ibmasm_register_uart(struct service_processor *sp) { struct serial_struct serial; - unsigned char *iomem_base; + void __iomem *iomem_base; iomem_base = sp->base_address + SCOUT_COM_B_BASE; diff -puN drivers/net/3c59x.c~bk-pci drivers/net/3c59x.c --- 25/drivers/net/3c59x.c~bk-pci 2004-10-01 20:07:40.133060544 -0700 +++ 25-akpm/drivers/net/3c59x.c 2004-10-01 20:07:40.359026192 -0700 @@ -817,7 +817,7 @@ struct vortex_private { partner_flow_ctrl:1, /* Partner supports flow control */ has_nway:1, enable_wol:1, /* Wake-on-LAN is enabled */ - pm_state_valid:1, /* power_state[] has sane contents */ + pm_state_valid:1, /* pci_dev->saved_config_space has sane contents */ open:1, medialock:1, must_free_region:1, /* Flag: if zero, Cardbus owns the I/O region */ @@ -834,7 +834,6 @@ struct vortex_private { u16 io_size; /* Size of PCI region (for release_region) */ spinlock_t lock; /* Serialise access to device & its vortex_private */ spinlock_t mdio_lock; /* Serialise access to mdio hardware */ - u32 power_state[16]; }; #ifdef CONFIG_PCI @@ -1487,7 +1486,7 @@ static int __devinit vortex_probe1(struc #endif if (pdev && vp->enable_wol) { vp->pm_state_valid = 1; - pci_save_state(VORTEX_PCI(vp), vp->power_state); + pci_save_state(VORTEX_PCI(vp)); acpi_set_WOL(dev); } retval = register_netdev(dev); @@ -1544,7 +1543,7 @@ vortex_up(struct net_device *dev) if (VORTEX_PCI(vp) && vp->enable_wol) { pci_set_power_state(VORTEX_PCI(vp), 0); /* Go active */ - pci_restore_state(VORTEX_PCI(vp), vp->power_state); + pci_restore_state(VORTEX_PCI(vp)); } /* Before initializing select the active media port. */ @@ -2701,7 +2700,7 @@ vortex_down(struct net_device *dev, int outl(0, ioaddr + DownListPtr); if (final_down && VORTEX_PCI(vp) && vp->enable_wol) { - pci_save_state(VORTEX_PCI(vp), vp->power_state); + pci_save_state(VORTEX_PCI(vp)); acpi_set_WOL(dev); } } @@ -3159,7 +3158,7 @@ static void __devexit vortex_remove_one if (VORTEX_PCI(vp) && vp->enable_wol) { pci_set_power_state(VORTEX_PCI(vp), 0); /* Go active */ if (vp->pm_state_valid) - pci_restore_state(VORTEX_PCI(vp), vp->power_state); + pci_restore_state(VORTEX_PCI(vp)); } /* Should really use issue_and_wait() here */ outw(TotalReset|0x14, dev->base_addr + EL3_CMD); diff -puN drivers/net/8139cp.c~bk-pci drivers/net/8139cp.c --- 25/drivers/net/8139cp.c~bk-pci 2004-10-01 20:07:40.134060392 -0700 +++ 25-akpm/drivers/net/8139cp.c 2004-10-01 20:07:40.365025280 -0700 @@ -371,7 +371,6 @@ struct cp_private { #endif unsigned int wol_enabled : 1; /* Is Wake-on-LAN enabled? */ - u32 power_state[16]; struct mii_if_info mii_if; }; @@ -1883,7 +1882,7 @@ static int cp_suspend (struct pci_dev *p spin_unlock_irqrestore (&cp->lock, flags); if (cp->pdev && cp->wol_enabled) { - pci_save_state (cp->pdev, cp->power_state); + pci_save_state (cp->pdev); cp_set_d3_state (cp); } @@ -1902,7 +1901,7 @@ static int cp_resume (struct pci_dev *pd if (cp->pdev && cp->wol_enabled) { pci_set_power_state (cp->pdev, 0); - pci_restore_state (cp->pdev, cp->power_state); + pci_restore_state (cp->pdev); } cp_init_hw (cp); diff -puN drivers/net/8139too.c~bk-pci drivers/net/8139too.c --- 25/drivers/net/8139too.c~bk-pci 2004-10-01 20:07:40.136060088 -0700 +++ 25-akpm/drivers/net/8139too.c 2004-10-01 20:07:40.369024672 -0700 @@ -573,7 +573,6 @@ struct rtl8139_private { void *mmio_addr; int drv_flags; struct pci_dev *pci_dev; - u32 pci_state[16]; u32 msg_enable; struct net_device_stats stats; unsigned char *rx_ring; @@ -2593,7 +2592,7 @@ static int rtl8139_suspend (struct pci_d void *ioaddr = tp->mmio_addr; unsigned long flags; - pci_save_state (pdev, tp->pci_state); + pci_save_state (pdev); if (!netif_running (dev)) return 0; @@ -2621,9 +2620,8 @@ static int rtl8139_suspend (struct pci_d static int rtl8139_resume (struct pci_dev *pdev) { struct net_device *dev = pci_get_drvdata (pdev); - struct rtl8139_private *tp = dev->priv; - pci_restore_state (pdev, tp->pci_state); + pci_restore_state (pdev); if (!netif_running (dev)) return 0; pci_set_power_state (pdev, 0); diff -puN drivers/net/amd8111e.c~bk-pci drivers/net/amd8111e.c --- 25/drivers/net/amd8111e.c~bk-pci 2004-10-01 20:07:40.138059784 -0700 +++ 25-akpm/drivers/net/amd8111e.c 2004-10-01 20:07:40.375023760 -0700 @@ -1835,7 +1835,7 @@ static int amd8111e_suspend(struct pci_d pci_enable_wake(pci_dev, 4, 0); /* 4 == D3 cold */ } - pci_save_state(pci_dev, lp->pm_state); + pci_save_state(pci_dev); pci_set_power_state(pci_dev, 3); return 0; @@ -1849,7 +1849,7 @@ static int amd8111e_resume(struct pci_de return 0; pci_set_power_state(pci_dev, 0); - pci_restore_state(pci_dev, lp->pm_state); + pci_restore_state(pci_dev); pci_enable_wake(pci_dev, 3, 0); pci_enable_wake(pci_dev, 4, 0); /* D3 cold */ diff -puN drivers/net/amd8111e.h~bk-pci drivers/net/amd8111e.h --- 25/drivers/net/amd8111e.h~bk-pci 2004-10-01 20:07:40.139059632 -0700 +++ 25-akpm/drivers/net/amd8111e.h 2004-10-01 20:07:40.376023608 -0700 @@ -780,7 +780,6 @@ struct amd8111e_priv{ struct amd8111e_link_config link_config; int pm_cap; - u32 pm_state[12]; struct net_device *next; int mii; diff -puN drivers/net/b44.c~bk-pci drivers/net/b44.c --- 25/drivers/net/b44.c~bk-pci 2004-10-01 20:07:40.141059328 -0700 +++ 25-akpm/drivers/net/b44.c 2004-10-01 20:07:40.378023304 -0700 @@ -1841,7 +1841,7 @@ static int __devinit b44_init_one(struct pci_set_drvdata(pdev, dev); - pci_save_state(bp->pdev, bp->pci_cfg_state); + pci_save_state(bp->pdev); printk(KERN_INFO "%s: Broadcom 4400 10/100BaseT Ethernet ", dev->name); for (i = 0; i < 6; i++) @@ -1907,7 +1907,7 @@ static int b44_resume(struct pci_dev *pd struct net_device *dev = pci_get_drvdata(pdev); struct b44 *bp = dev->priv; - pci_restore_state(pdev, bp->pci_cfg_state); + pci_restore_state(pdev); if (!netif_running(dev)) return 0; diff -puN drivers/net/b44.h~bk-pci drivers/net/b44.h --- 25/drivers/net/b44.h~bk-pci 2004-10-01 20:07:40.142059176 -0700 +++ 25-akpm/drivers/net/b44.h 2004-10-01 20:07:40.380023000 -0700 @@ -433,7 +433,6 @@ struct b44 { u32 rx_pending; u32 tx_pending; - u32 pci_cfg_state[64 / sizeof(u32)]; u8 phy_addr; u8 core_unit; diff -puN drivers/net/e1000/e1000.h~bk-pci drivers/net/e1000/e1000.h --- 25/drivers/net/e1000/e1000.h~bk-pci 2004-10-01 20:07:40.143059024 -0700 +++ 25-akpm/drivers/net/e1000/e1000.h 2004-10-01 20:07:40.383022544 -0700 @@ -252,7 +252,6 @@ struct e1000_adapter { struct e1000_desc_ring test_rx_ring; - uint32_t pci_state[16]; int msg_enable; }; #endif /* _E1000_H_ */ diff -puN drivers/net/e1000/e1000_main.c~bk-pci drivers/net/e1000/e1000_main.c --- 25/drivers/net/e1000/e1000_main.c~bk-pci 2004-10-01 20:07:40.145058720 -0700 +++ 25-akpm/drivers/net/e1000/e1000_main.c 2004-10-01 20:07:40.387021936 -0700 @@ -2856,7 +2856,7 @@ e1000_suspend(struct pci_dev *pdev, uint pci_enable_wake(pdev, 4, 0); /* 4 == D3 cold */ } - pci_save_state(pdev, adapter->pci_state); + pci_save_state(pdev); if(adapter->hw.mac_type >= e1000_82540 && adapter->hw.media_type == e1000_media_type_copper) { @@ -2887,7 +2887,7 @@ e1000_resume(struct pci_dev *pdev) ret = pci_enable_device(pdev); pci_set_power_state(pdev, 0); - pci_restore_state(pdev, adapter->pci_state); + pci_restore_state(pdev); pci_enable_wake(pdev, 3, 0); pci_enable_wake(pdev, 4, 0); /* 4 == D3 cold */ diff -puN drivers/net/e100.c~bk-pci drivers/net/e100.c --- 25/drivers/net/e100.c~bk-pci 2004-10-01 20:07:40.147058416 -0700 +++ 25-akpm/drivers/net/e100.c 2004-10-01 20:07:40.382022696 -0700 @@ -563,7 +563,6 @@ struct nic { u16 leds; u16 eeprom_wc; u16 eeprom[256]; - u32 pm_state[16]; }; static inline void e100_write_flush(struct nic *nic) @@ -2326,7 +2325,7 @@ static int e100_suspend(struct pci_dev * e100_hw_reset(nic); netif_device_detach(netdev); - pci_save_state(pdev, nic->pm_state); + pci_save_state(pdev); pci_enable_wake(pdev, state, nic->flags & (wol_magic | e100_asf(nic))); pci_disable_device(pdev); pci_set_power_state(pdev, state); @@ -2340,7 +2339,7 @@ static int e100_resume(struct pci_dev *p struct nic *nic = netdev_priv(netdev); pci_set_power_state(pdev, 0); - pci_restore_state(pdev, nic->pm_state); + pci_restore_state(pdev); e100_hw_init(nic); netif_device_attach(netdev); diff -puN drivers/net/eepro100.c~bk-pci drivers/net/eepro100.c --- 25/drivers/net/eepro100.c~bk-pci 2004-10-01 20:07:40.148058264 -0700 +++ 25-akpm/drivers/net/eepro100.c 2004-10-01 20:07:40.396020568 -0700 @@ -462,9 +462,6 @@ struct speedo_private { unsigned short partner; /* Link partner caps. */ struct mii_if_info mii_if; /* MII API hooks, info */ u32 msg_enable; /* debug message level */ -#ifdef CONFIG_PM - u32 pm_state[16]; -#endif }; /* The parameters for a CmdConfigure operation. @@ -2290,7 +2287,7 @@ static int eepro100_suspend(struct pci_d struct speedo_private *sp = netdev_priv(dev); void __iomem *ioaddr = sp->regs; - pci_save_state(pdev, sp->pm_state); + pci_save_state(pdev); if (!netif_running(dev)) return 0; @@ -2310,7 +2307,7 @@ static int eepro100_resume(struct pci_de struct speedo_private *sp = netdev_priv(dev); void __iomem *ioaddr = sp->regs; - pci_restore_state(pdev, sp->pm_state); + pci_restore_state(pdev); if (!netif_running(dev)) return 0; diff -puN drivers/net/irda/vlsi_ir.c~bk-pci drivers/net/irda/vlsi_ir.c --- 25/drivers/net/irda/vlsi_ir.c~bk-pci 2004-10-01 20:07:40.150057960 -0700 +++ 25-akpm/drivers/net/irda/vlsi_ir.c 2004-10-01 20:07:40.398020264 -0700 @@ -1768,7 +1768,7 @@ static int vlsi_irda_suspend(struct pci_ if (netif_running(ndev)) { netif_device_detach(ndev); vlsi_stop_hw(idev); - pci_save_state(pdev, idev->cfg_space); + pci_save_state(pdev); if (!idev->new_baud) /* remember speed settings to restore on resume */ idev->new_baud = idev->baud; @@ -1819,7 +1819,7 @@ static int vlsi_irda_resume(struct pci_d } if (netif_running(ndev)) { - pci_restore_state(pdev, idev->cfg_space); + pci_restore_state(pdev); vlsi_start_hw(idev); netif_device_attach(ndev); } diff -puN drivers/net/irda/vlsi_ir.h~bk-pci drivers/net/irda/vlsi_ir.h --- 25/drivers/net/irda/vlsi_ir.h~bk-pci 2004-10-01 20:07:40.151057808 -0700 +++ 25-akpm/drivers/net/irda/vlsi_ir.h 2004-10-01 20:07:40.399020112 -0700 @@ -769,7 +769,6 @@ typedef struct vlsi_irda_dev { spinlock_t lock; struct semaphore sem; - u32 cfg_space[64/sizeof(u32)]; u8 resume_ok; struct proc_dir_entry *proc_entry; diff -puN drivers/net/ixgb/ixgb.h~bk-pci drivers/net/ixgb/ixgb.h --- 25/drivers/net/ixgb/ixgb.h~bk-pci 2004-10-01 20:07:40.153057504 -0700 +++ 25-akpm/drivers/net/ixgb/ixgb.h 2004-10-01 20:07:40.400019960 -0700 @@ -178,6 +178,5 @@ struct ixgb_adapter { /* structs defined in ixgb_hw.h */ struct ixgb_hw hw; struct ixgb_hw_stats stats; - uint32_t pci_state[16]; }; #endif /* _IXGB_H_ */ diff -puN drivers/net/ixgb/ixgb_main.c~bk-pci drivers/net/ixgb/ixgb_main.c --- 25/drivers/net/ixgb/ixgb_main.c~bk-pci 2004-10-01 20:07:40.154057352 -0700 +++ 25-akpm/drivers/net/ixgb/ixgb_main.c 2004-10-01 20:07:40.407018896 -0700 @@ -2101,7 +2101,7 @@ static int ixgb_suspend(struct pci_dev * if (netif_running(netdev)) ixgb_down(adapter, TRUE); - pci_save_state(pdev, adapter->pci_state); + pci_save_state(pdev); state = (state > 0) ? 3 : 0; pci_set_power_state(pdev, state); diff -puN drivers/net/pci-skeleton.c~bk-pci drivers/net/pci-skeleton.c --- 25/drivers/net/pci-skeleton.c~bk-pci 2004-10-01 20:07:40.156057048 -0700 +++ 25-akpm/drivers/net/pci-skeleton.c 2004-10-01 20:07:40.410018440 -0700 @@ -481,7 +481,6 @@ struct netdrv_private { unsigned int mediasense:1; /* Media sensing in progress. */ spinlock_t lock; chip_t chipset; - u32 pci_state[16]; /* Data saved during suspend */ }; MODULE_AUTHOR ("Jeff Garzik "); @@ -1921,7 +1920,7 @@ static int netdrv_suspend (struct pci_de spin_unlock_irqrestore (&tp->lock, flags); - pci_save_state (pdev, tp->pci_state); + pci_save_state (pdev); pci_set_power_state (pdev, 3); return 0; @@ -1936,7 +1935,7 @@ static int netdrv_resume (struct pci_dev if (!netif_running(dev)) return 0; pci_set_power_state (pdev, 0); - pci_restore_state (pdev, tp->pci_state); + pci_restore_state (pdev); netif_device_attach (dev); netdrv_hw_start (dev); diff -puN drivers/net/s2io.c~bk-pci drivers/net/s2io.c --- 25/drivers/net/s2io.c~bk-pci 2004-10-01 20:07:40.158056744 -0700 +++ 25-akpm/drivers/net/s2io.c 2004-10-01 20:07:40.413017984 -0700 @@ -1935,7 +1935,7 @@ void s2io_reset(nic_t * sp) schedule_timeout(HZ / 4); /* Restore the PCI state saved during initializarion. */ - pci_restore_state(sp->pdev, sp->config_space); + pci_restore_state(sp->pdev); s2io_init_pci(sp); set_current_state(TASK_UNINTERRUPTIBLE); @@ -4238,7 +4238,7 @@ s2io_init_nic(struct pci_dev *pdev, cons goto register_failed; } - pci_save_state(sp->pdev, sp->config_space); + pci_save_state(sp->pdev); /* Setting swapper control on the NIC, for proper reset operation */ if (s2io_set_swapper(sp)) { diff -puN drivers/net/s2io.h~bk-pci drivers/net/s2io.h --- 25/drivers/net/s2io.h~bk-pci 2004-10-01 20:07:40.159056592 -0700 +++ 25-akpm/drivers/net/s2io.h 2004-10-01 20:07:40.414017832 -0700 @@ -667,7 +667,6 @@ typedef struct s2io_nic { u8 cache_line; u32 rom_expansion; u16 pcix_cmd; - u32 config_space[256 / sizeof(u32)]; u32 irq; atomic_t rx_bufs_left[MAX_RX_RINGS]; diff -puN drivers/net/sis900.c~bk-pci drivers/net/sis900.c --- 25/drivers/net/sis900.c~bk-pci 2004-10-01 20:07:40.161056288 -0700 +++ 25-akpm/drivers/net/sis900.c 2004-10-01 20:07:40.418017224 -0700 @@ -172,7 +172,6 @@ struct sis900_private { unsigned int tx_full; /* The Tx queue is full. */ u8 host_bridge_rev; - u32 pci_state[16]; }; MODULE_AUTHOR("Jim Huang , Ollie Lho "); @@ -2226,7 +2225,6 @@ static void __devexit sis900_remove(stru static int sis900_suspend(struct pci_dev *pci_dev, u32 state) { struct net_device *net_dev = pci_get_drvdata(pci_dev); - struct sis900_private *sis_priv = net_dev->priv; long ioaddr = net_dev->base_addr; if(!netif_running(net_dev)) @@ -2239,7 +2237,7 @@ static int sis900_suspend(struct pci_dev outl(RxDIS | TxDIS | inl(ioaddr + cr), ioaddr + cr); pci_set_power_state(pci_dev, 3); - pci_save_state(pci_dev, sis_priv->pci_state); + pci_save_state(pci_dev); return 0; } @@ -2252,7 +2250,7 @@ static int sis900_resume(struct pci_dev if(!netif_running(net_dev)) return 0; - pci_restore_state(pci_dev, sis_priv->pci_state); + pci_restore_state(pci_dev); pci_set_power_state(pci_dev, 0); sis900_init_rxfilter(net_dev); diff -puN drivers/net/tg3.c~bk-pci drivers/net/tg3.c --- 25/drivers/net/tg3.c~bk-pci 2004-10-01 20:07:40.163055984 -0700 +++ 25-akpm/drivers/net/tg3.c 2004-10-01 20:07:40.424016312 -0700 @@ -3788,7 +3788,7 @@ static int tg3_chip_reset(struct tg3 *tp val |= PCISTATE_RETRY_SAME_DMA; pci_write_config_dword(tp->pdev, TG3PCI_PCISTATE, val); - pci_restore_state(tp->pdev, tp->pci_cfg_state); + pci_restore_state(tp->pdev); /* Make sure PCI-X relaxed ordering bit is clear. */ pci_read_config_dword(tp->pdev, TG3PCI_X_CAPS, &val); @@ -8316,7 +8316,7 @@ static int __devinit tg3_init_one(struct */ if ((tr32(HOSTCC_MODE) & HOSTCC_MODE_ENABLE) || (tr32(WDMAC_MODE) & WDMAC_MODE_ENABLE)) { - pci_save_state(tp->pdev, tp->pci_cfg_state); + pci_save_state(tp->pdev); tw32(MEMARB_MODE, MEMARB_MODE_ENABLE); tg3_halt(tp); } @@ -8355,7 +8355,7 @@ static int __devinit tg3_init_one(struct * of the PCI config space. We need to restore this after * GRC_MISC_CFG core clock resets and some resume events. */ - pci_save_state(tp->pdev, tp->pci_cfg_state); + pci_save_state(tp->pdev); printk(KERN_INFO "%s: Tigon3 [partno(%s) rev %04x PHY(%s)] (PCI%s:%s:%s) %sBaseT Ethernet ", dev->name, @@ -8474,7 +8474,7 @@ static int tg3_resume(struct pci_dev *pd if (!netif_running(dev)) return 0; - pci_restore_state(tp->pdev, tp->pci_cfg_state); + pci_restore_state(tp->pdev); err = tg3_set_power_state(tp, 0); if (err) diff -puN drivers/net/tg3.h~bk-pci drivers/net/tg3.h --- 25/drivers/net/tg3.h~bk-pci 2004-10-01 20:07:40.165055680 -0700 +++ 25-akpm/drivers/net/tg3.h 2004-10-01 20:07:40.426016008 -0700 @@ -2120,7 +2120,6 @@ struct tg3 { u8 pci_lat_timer; u8 pci_hdr_type; u8 pci_bist; - u32 pci_cfg_state[64 / sizeof(u32)]; int pm_cap; diff -puN drivers/net/tulip/xircom_tulip_cb.c~bk-pci drivers/net/tulip/xircom_tulip_cb.c --- 25/drivers/net/tulip/xircom_tulip_cb.c~bk-pci 2004-10-01 20:07:40.167055376 -0700 +++ 25-akpm/drivers/net/tulip/xircom_tulip_cb.c 2004-10-01 20:07:40.430015400 -0700 @@ -329,9 +329,6 @@ struct xircom_private { int saved_if_port; struct pci_dev *pdev; spinlock_t lock; -#ifdef CONFIG_PM - u32 pci_state[16]; -#endif }; static int mdio_read(struct net_device *dev, int phy_id, int location); @@ -1663,7 +1660,7 @@ static int xircom_suspend(struct pci_dev if (tp->open) xircom_down(dev); - pci_save_state(pdev, tp->pci_state); + pci_save_state(pdev); pci_disable_device(pdev); pci_set_power_state(pdev, 3); @@ -1679,7 +1676,7 @@ static int xircom_resume(struct pci_dev pci_set_power_state(pdev,0); pci_enable_device(pdev); - pci_restore_state(pdev, tp->pci_state); + pci_restore_state(pdev); /* Bring the chip out of sleep mode. Caution: Snooze mode does not work with some boards! */ diff -puN drivers/net/typhoon.c~bk-pci drivers/net/typhoon.c --- 25/drivers/net/typhoon.c~bk-pci 2004-10-01 20:07:40.169055072 -0700 +++ 25-akpm/drivers/net/typhoon.c 2004-10-01 20:07:40.435014640 -0700 @@ -287,7 +287,6 @@ struct typhoon { u16 xcvr_select; u16 wol_events; u32 offload; - u32 pci_state[16]; /* unused stuff (future use) */ int capabilities; @@ -1859,7 +1858,7 @@ typhoon_wakeup(struct typhoon *tp, int w void __iomem *ioaddr = tp->ioaddr; pci_set_power_state(pdev, 0); - pci_restore_state(pdev, tp->pci_state); + pci_restore_state(pdev); /* Post 2.x.x versions of the Sleep Image require a reset before * we can download the Runtime Image. But let's not make users of @@ -2339,7 +2338,7 @@ typhoon_init_one(struct pci_dev *pdev, c tp->dev = dev; /* need to be able to restore PCI state after a suspend */ - pci_save_state(pdev, tp->pci_state); + pci_save_state(pdev); /* Init sequence: * 1) Reset the adapter to clear any bad juju @@ -2513,7 +2512,7 @@ typhoon_remove_one(struct pci_dev *pdev) unregister_netdev(dev); pci_set_power_state(pdev, 0); - pci_restore_state(pdev, tp->pci_state); + pci_restore_state(pdev); typhoon_reset(tp->ioaddr, NoWait); iounmap(tp->ioaddr); pci_free_consistent(pdev, sizeof(struct typhoon_shared), diff -puN drivers/net/via-rhine.c~bk-pci drivers/net/via-rhine.c --- 25/drivers/net/via-rhine.c~bk-pci 2004-10-01 20:07:40.170054920 -0700 +++ 25-akpm/drivers/net/via-rhine.c 2004-10-01 20:07:40.437014336 -0700 @@ -1951,7 +1951,7 @@ static int rhine_suspend(struct pci_dev return 0; netif_device_detach(dev); - pci_save_state(pdev, pdev->saved_config_space); + pci_save_state(pdev); spin_lock_irqsave(&rp->lock, flags); rhine_shutdown(&pdev->dev); @@ -1975,7 +1975,7 @@ static int rhine_resume(struct pci_dev * printk(KERN_INFO "%s: Entering power state D0 %s (%d).\n", dev->name, ret ? "failed" : "succeeded", ret); - pci_restore_state(pdev, pdev->saved_config_space); + pci_restore_state(pdev); spin_lock_irqsave(&rp->lock, flags); #ifdef USE_MMIO diff -puN drivers/net/via-velocity.c~bk-pci drivers/net/via-velocity.c --- 25/drivers/net/via-velocity.c~bk-pci 2004-10-01 20:07:40.172054616 -0700 +++ 25-akpm/drivers/net/via-velocity.c 2004-10-01 20:07:40.440013880 -0700 @@ -3221,7 +3221,7 @@ static int velocity_suspend(struct pci_d netif_device_detach(vptr->dev); spin_lock_irqsave(&vptr->lock, flags); - pci_save_state(pdev, vptr->pci_state); + pci_save_state(pdev); #ifdef ETHTOOL_GWOL if (vptr->flags & VELOCITY_FLAGS_WOL_ENABLED) { velocity_get_ip(vptr); @@ -3254,7 +3254,7 @@ static int velocity_resume(struct pci_de pci_set_power_state(pdev, 0); pci_enable_wake(pdev, 0, 0); - pci_restore_state(pdev, vptr->pci_state); + pci_restore_state(pdev); mac_wol_reset(vptr->mac_regs); diff -puN drivers/net/via-velocity.h~bk-pci drivers/net/via-velocity.h --- 25/drivers/net/via-velocity.h~bk-pci 2004-10-01 20:07:40.173054464 -0700 +++ 25-akpm/drivers/net/via-velocity.h 2004-10-01 20:07:40.441013728 -0700 @@ -1739,10 +1739,6 @@ struct velocity_info { struct net_device *dev; struct net_device_stats stats; -#ifdef CONFIG_PM - u32 pci_state[16]; -#endif - dma_addr_t rd_pool_dma; dma_addr_t td_pool_dma[TX_QUEUE_NO]; diff -puN drivers/net/wan/sbni.c~bk-pci drivers/net/wan/sbni.c --- 25/drivers/net/wan/sbni.c~bk-pci 2004-10-01 20:07:40.175054160 -0700 +++ 25-akpm/drivers/net/wan/sbni.c 2004-10-01 20:07:40.442013576 -0700 @@ -294,7 +294,7 @@ sbni_pci_probe( struct net_device *dev { struct pci_dev *pdev = NULL; - while( (pdev = pci_find_class( PCI_CLASS_NETWORK_OTHER << 8, pdev )) + while( (pdev = pci_get_class( PCI_CLASS_NETWORK_OTHER << 8, pdev )) != NULL ) { int pci_irq_line; unsigned long pci_ioaddr; @@ -331,10 +331,14 @@ sbni_pci_probe( struct net_device *dev /* avoiding re-enable dual adapters */ if( (pci_ioaddr & 7) == 0 && pci_enable_device( pdev ) ) { release_region( pci_ioaddr, SBNI_IO_EXTENT ); + pci_dev_put( pdev ); return -EIO; } if( sbni_probe1( dev, pci_ioaddr, pci_irq_line ) ) { SET_NETDEV_DEV(dev, &pdev->dev); + /* not the best thing to do, but this is all messed up + for hotplug systems anyway... */ + pci_dev_put( pdev ); return 0; } } diff -puN drivers/net/wireless/airo.c~bk-pci drivers/net/wireless/airo.c --- 25/drivers/net/wireless/airo.c~bk-pci 2004-10-01 20:07:40.177053856 -0700 +++ 25-akpm/drivers/net/wireless/airo.c 2004-10-01 20:07:40.448012664 -0700 @@ -1211,7 +1211,6 @@ struct airo_info { SsidRid *SSID; APListRid *APList; #define PCI_SHARED_LEN 2*MPI_MAX_FIDS*PKTSIZE+RIDSIZE - u32 pci_state[16]; char proc_name[IFNAMSIZ]; }; @@ -5496,7 +5495,7 @@ static int airo_pci_suspend(struct pci_d issuecommand(ai, &cmd, &rsp); pci_enable_wake(pdev, state, 1); - pci_save_state(pdev, ai->pci_state); + pci_save_state(pdev); return pci_set_power_state(pdev, state); } @@ -5507,7 +5506,7 @@ static int airo_pci_resume(struct pci_de Resp rsp; pci_set_power_state(pdev, 0); - pci_restore_state(pdev, ai->pci_state); + pci_restore_state(pdev); pci_enable_wake(pdev, ai->power, 0); if (ai->power > 1) { diff -puN drivers/net/wireless/prism54/islpci_dev.h~bk-pci drivers/net/wireless/prism54/islpci_dev.h --- 25/drivers/net/wireless/prism54/islpci_dev.h~bk-pci 2004-10-01 20:07:40.179053552 -0700 +++ 25-akpm/drivers/net/wireless/prism54/islpci_dev.h 2004-10-01 20:07:40.449012512 -0700 @@ -110,7 +110,6 @@ typedef struct { /* PCI bus allocation & configuration members */ struct pci_dev *pdev; /* PCI structure information */ - u32 pci_state[16]; /* used for suspend/resume */ char firmware[33]; void *device_base; /* ioremapped device base address */ diff -puN drivers/net/wireless/prism54/islpci_hotplug.c~bk-pci drivers/net/wireless/prism54/islpci_hotplug.c --- 25/drivers/net/wireless/prism54/islpci_hotplug.c~bk-pci 2004-10-01 20:07:40.180053400 -0700 +++ 25-akpm/drivers/net/wireless/prism54/islpci_hotplug.c 2004-10-01 20:07:40.449012512 -0700 @@ -273,7 +273,7 @@ prism54_suspend(struct pci_dev *pdev, u3 printk(KERN_NOTICE "%s: got suspend request (state %d)\n", ndev->name, state); - pci_save_state(pdev, priv->pci_state); + pci_save_state(pdev); /* tell the device not to trigger interrupts for now... */ isl38xx_disable_interrupts(priv->device_base); @@ -297,7 +297,7 @@ prism54_resume(struct pci_dev *pdev) printk(KERN_NOTICE "%s: got resume request\n", ndev->name); - pci_restore_state(pdev, priv->pci_state); + pci_restore_state(pdev); /* alright let's go into the PREBOOT state */ islpci_reset(priv, 1); diff -puN drivers/net/wireless/prism54/islpci_mgt.c~bk-pci drivers/net/wireless/prism54/islpci_mgt.c --- 25/drivers/net/wireless/prism54/islpci_mgt.c~bk-pci 2004-10-01 20:07:40.181053248 -0700 +++ 25-akpm/drivers/net/wireless/prism54/islpci_mgt.c 2004-10-01 20:07:40.450012360 -0700 @@ -319,8 +319,8 @@ islpci_mgt_receive(struct net_device *nd } /* Ensure the results of device DMA are visible to the CPU. */ - pci_dma_sync_single(priv->pdev, buf->pci_addr, - buf->size, PCI_DMA_FROMDEVICE); + pci_dma_sync_single_for_cpu(priv->pdev, buf->pci_addr, + buf->size, PCI_DMA_FROMDEVICE); /* Perform endianess conversion for PIMFOR header in-place. */ header = pimfor_decode_header(buf->mem, frag_len); diff -puN drivers/pci/hotplug/acpiphp_ibm.c~bk-pci drivers/pci/hotplug/acpiphp_ibm.c --- 25/drivers/pci/hotplug/acpiphp_ibm.c~bk-pci 2004-10-01 20:07:40.183052944 -0700 +++ 25-akpm/drivers/pci/hotplug/acpiphp_ibm.c 2004-10-01 20:07:40.451012208 -0700 @@ -64,6 +64,8 @@ do { \ #define IBM_HARDWARE_ID1 "IBM37D0" #define IBM_HARDWARE_ID2 "IBM37D4" +#define hpslot_to_sun(A) (((struct slot *)((A)->private))->acpi_slot->sun) + /* union apci_descriptor - allows access to the * various device descriptors that are embedded in the * aPCI table @@ -84,6 +86,7 @@ union apci_descriptor { u8 attn; u8 status[2]; u8 sun; + u8 res[3]; } slot; struct { u8 type; @@ -128,6 +131,43 @@ static struct acpiphp_attention_info ibm .owner = THIS_MODULE, }; +/** + * ibm_slot_from_id - workaround for bad ibm hardware + * @id: the slot number that linux refers to the slot by + * + * Description: this method returns the aCPI slot descriptor + * corresponding to the Linux slot number. This descriptor + * has info about the aPCI slot id and attention status. + * This descriptor must be freed using kfree when done. + **/ +static union apci_descriptor *ibm_slot_from_id(int id) +{ + int ind = 0, size; + union apci_descriptor *ret = NULL, *des; + char *table; + + size = ibm_get_table_from_acpi(&table); + des = (union apci_descriptor *)table; + if (memcmp(des->header.sig, "aPCI", 4) != 0) + goto ibm_slot_done; + + des = (union apci_descriptor *)&table[ind += des->header.len]; + while (ind < size && (des->generic.type != 0x82 || + des->slot.slot_num != id)) { + des = (union apci_descriptor *)&table[ind += des->generic.len]; + } + + if (ind < size && des->slot.slot_num == id) + ret = des; + +ibm_slot_done: + if (ret) { + ret = kmalloc(sizeof(union apci_descriptor), GFP_KERNEL); + memcpy(ret, des, sizeof(union apci_descriptor)); + } + kfree(table); + return ret; +} /** * ibm_set_attention_status - callback method to set the attention LED @@ -139,32 +179,34 @@ static struct acpiphp_attention_info ibm **/ static int ibm_set_attention_status(struct hotplug_slot *slot, u8 status) { - int retval = 0; union acpi_object args[2]; struct acpi_object_list params = { .pointer = args, .count = 2 }; acpi_status stat; - unsigned long rc = 0; - struct acpiphp_slot *acpi_slot; + unsigned long rc; + union apci_descriptor *ibm_slot; - acpi_slot = ((struct slot *)(slot->private))->acpi_slot; + ibm_slot = ibm_slot_from_id(hpslot_to_sun(slot)); - dbg("%s: set slot %d attention status to %d\n", __FUNCTION__, - acpi_slot->sun, (status ? 1 : 0)); + dbg("%s: set slot %d (%d) attention status to %d\n", __FUNCTION__, + ibm_slot->slot.slot_num, ibm_slot->slot.slot_id, + (status ? 1 : 0)); args[0].type = ACPI_TYPE_INTEGER; - args[0].integer.value = acpi_slot->sun; + args[0].integer.value = ibm_slot->slot.slot_id; args[1].type = ACPI_TYPE_INTEGER; args[1].integer.value = (status) ? 1 : 0; + kfree(ibm_slot); + stat = acpi_evaluate_integer(ibm_acpi_handle, "APLS", ¶ms, &rc); if (ACPI_FAILURE(stat)) { - retval = -ENODEV; err("APLS evaluation failed: 0x%08x\n", stat); + return -ENODEV; } else if (!rc) { - retval = -ERANGE; err("APLS method failed: 0x%08lx\n", rc); + return -ERANGE; } - return retval; + return 0; } /** @@ -181,38 +223,21 @@ static int ibm_set_attention_status(stru **/ static int ibm_get_attention_status(struct hotplug_slot *slot, u8 *status) { - int retval = -EINVAL, ind = 0, size; - char *table = NULL; - struct acpiphp_slot *acpi_slot; - union apci_descriptor *des; + union apci_descriptor *ibm_slot; - acpi_slot = ((struct slot *)(slot->private))->acpi_slot; + ibm_slot = ibm_slot_from_id(hpslot_to_sun(slot)); - size = ibm_get_table_from_acpi(&table); - if (size <= 0 || !table) - goto get_attn_done; - // read the header - des = (union apci_descriptor *)&table[ind]; - if (memcmp(des->header.sig, "aPCI", 4) != 0) - goto get_attn_done; - des = (union apci_descriptor *)&table[ind += des->header.len]; - while (ind < size && (des->generic.type != 0x82 || - des->slot.slot_id != acpi_slot->sun)) - des = (union apci_descriptor *)&table[ind += des->generic.len]; - if (ind < size && des->slot.slot_id == acpi_slot->sun) { - retval = 0; - if (des->slot.attn & 0xa0 || des->slot.status[1] & 0x08) - *status = 1; - else - *status = 0; - } + if (ibm_slot->slot.attn & 0xa0 || ibm_slot->slot.status[1] & 0x08) + *status = 1; + else + *status = 0; - dbg("%s: get slot %d attention status is %d retval=%x\n", - __FUNCTION__, acpi_slot->sun, *status, retval); + dbg("%s: get slot %d (%d) attention status is %d\n", __FUNCTION__, + ibm_slot->slot.slot_num, ibm_slot->slot.slot_id, + *status); -get_attn_done: - kfree(table); - return retval; + kfree(ibm_slot); + return 0; } /** diff -puN drivers/pci/hotplug/cpcihp_zt5550.c~bk-pci drivers/pci/hotplug/cpcihp_zt5550.c --- 25/drivers/pci/hotplug/cpcihp_zt5550.c~bk-pci 2004-10-01 20:07:40.184052792 -0700 +++ 25-akpm/drivers/pci/hotplug/cpcihp_zt5550.c 2004-10-01 20:07:40.452012056 -0700 @@ -69,11 +69,11 @@ static struct pci_bus *bus0; static struct pci_dev *hc_dev; /* Host controller register addresses */ -static void *hc_registers; -static void *csr_hc_index; -static void *csr_hc_data; -static void *csr_int_status; -static void *csr_int_mask; +static void __iomem *hc_registers; +static void __iomem *csr_hc_index; +static void __iomem *csr_hc_data; +static void __iomem *csr_int_status; +static void __iomem *csr_int_mask; static int zt5550_hc_config(struct pci_dev *pdev) @@ -219,12 +219,13 @@ static int zt5550_hc_init_one (struct pc dbg("registered controller"); /* Look for first device matching cPCI bus's bridge vendor and device IDs */ - if(!(bus0_dev = pci_find_device(PCI_VENDOR_ID_DEC, + if(!(bus0_dev = pci_get_device(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21154, NULL))) { status = -ENODEV; goto init_register_error; } bus0 = bus0_dev->subordinate; + pci_dev_put(bus0_dev); status = cpci_hp_register_bus(bus0, 0x0a, 0x0f); if(status != 0) { @@ -282,7 +283,7 @@ static int __init zt5550_init(void) if(!r) return -EBUSY; - return pci_module_init(&zt5550_hc_driver); + return pci_register_driver(&zt5550_hc_driver); } static void __exit diff -puN drivers/pci/hotplug/cpqphp_core.c~bk-pci drivers/pci/hotplug/cpqphp_core.c --- 25/drivers/pci/hotplug/cpqphp_core.c~bk-pci 2004-10-01 20:07:40.186052488 -0700 +++ 25-akpm/drivers/pci/hotplug/cpqphp_core.c 2004-10-01 20:07:40.454011752 -0700 @@ -55,9 +55,9 @@ struct controller *cpqhp_ctrl_list; /* = struct pci_func *cpqhp_slot_list[256]; /* local variables */ -static void *smbios_table; -static void *smbios_start; -static void *cpqhp_rom_start; +static void __iomem *smbios_table; +static void __iomem *smbios_start; +static void __iomem *cpqhp_rom_start; static int power_mode; static int debug; @@ -123,10 +123,10 @@ static inline int is_slot66mhz(struct sl * Returns pointer to the head of the SMBIOS tables (or NULL) * */ -static void * detect_SMBIOS_pointer(void *begin, void *end) +static void __iomem * detect_SMBIOS_pointer(void __iomem *begin, void __iomem *end) { - void *fp; - void *endp; + void __iomem *fp; + void __iomem *endp; u8 temp1, temp2, temp3, temp4; int status = 0; @@ -232,13 +232,14 @@ static int pci_print_IRQ_route (void) * * returns a pointer to an SMBIOS structure or NULL if none found */ -static void *get_subsequent_smbios_entry(void *smbios_start, - void *smbios_table, void *curr) +static void __iomem *get_subsequent_smbios_entry(void __iomem *smbios_start, + void __iomem *smbios_table, + void __iomem *curr) { u8 bail = 0; u8 previous_byte = 1; - void *p_temp; - void *p_max; + void __iomem *p_temp; + void __iomem *p_max; if (!smbios_table || !curr) return(NULL); @@ -282,8 +283,10 @@ static void *get_subsequent_smbios_entry * * returns a pointer to an SMBIOS structure or %NULL if none found */ -static void *get_SMBIOS_entry(void *smbios_start, void *smbios_table, u8 type, - void * previous) +static void __iomem *get_SMBIOS_entry(void __iomem *smbios_start, + void __iomem *smbios_table, + u8 type, + void __iomem *previous) { if (!smbios_table) return NULL; @@ -319,8 +322,9 @@ static void release_slot(struct hotplug_ kfree(slot); } -static int ctrl_slot_setup(struct controller * ctrl, void *smbios_start, - void *smbios_table) +static int ctrl_slot_setup(struct controller *ctrl, + void __iomem *smbios_start, + void __iomem *smbios_table) { struct slot *new_slot; u8 number_of_slots; @@ -328,7 +332,7 @@ static int ctrl_slot_setup(struct contro u8 slot_number; u8 ctrl_slot; u32 tempdword; - void *slot_entry= NULL; + void __iomem *slot_entry= NULL; int result = -ENOMEM; dbg("%s\n", __FUNCTION__); @@ -1483,8 +1487,8 @@ static int __init cpqhpc_init(void) cpqhp_debug = debug; info (DRIVER_DESC " version: " DRIVER_VERSION "\n"); - result = pci_module_init(&cpqhpc_driver); - dbg("pci_module_init = %d\n", result); + result = pci_register_driver(&cpqhpc_driver); + dbg("pci_register_driver = %d\n", result); return result; } diff -puN drivers/pci/hotplug/cpqphp_ctrl.c~bk-pci drivers/pci/hotplug/cpqphp_ctrl.c --- 25/drivers/pci/hotplug/cpqphp_ctrl.c~bk-pci 2004-10-01 20:07:40.187052336 -0700 +++ 25-akpm/drivers/pci/hotplug/cpqphp_ctrl.c 2004-10-01 20:07:40.457011296 -0700 @@ -69,10 +69,8 @@ static void long_delay(int delay) init_waitqueue_head(&delay_wait); add_wait_queue(&delay_wait, &wait); - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(delay); + msleep_interruptible(jiffies_to_msecs(delay)); remove_wait_queue(&delay_wait, &wait); - set_current_state(TASK_RUNNING); up(&delay_sem); } diff -puN drivers/pci/hotplug/cpqphp.h~bk-pci drivers/pci/hotplug/cpqphp.h --- 25/drivers/pci/hotplug/cpqphp.h~bk-pci 2004-10-01 20:07:40.189052032 -0700 +++ 25-akpm/drivers/pci/hotplug/cpqphp.h 2004-10-01 20:07:40.453011904 -0700 @@ -268,7 +268,7 @@ struct slot { struct timer_list task_event; u8 hp_slot; struct controller *ctrl; - void *p_sm_slot; + void __iomem *p_sm_slot; struct hotplug_slot *hotplug_slot; }; @@ -287,7 +287,7 @@ struct controller { struct controller *next; u32 ctrl_int_comp; struct semaphore crit_sect; /* critical section semaphore */ - void *hpc_reg; /* cookie for our pci controller location */ + void __iomem *hpc_reg; /* cookie for our pci controller location */ struct pci_resource *mem_head; struct pci_resource *p_mem_head; struct pci_resource *io_head; @@ -405,7 +405,7 @@ extern void cpqhp_create_ctrl_files (st /* controller functions */ extern void cpqhp_pushbutton_thread (unsigned long event_pointer); extern irqreturn_t cpqhp_ctrl_intr (int IRQ, void *data, struct pt_regs *regs); -extern int cpqhp_find_available_resources (struct controller *ctrl, void *rom_start); +extern int cpqhp_find_available_resources (struct controller *ctrl, void __iomem *rom_start); extern int cpqhp_event_start_thread (void); extern void cpqhp_event_stop_thread (void); extern struct pci_func *cpqhp_slot_create (unsigned char busnumber); @@ -707,9 +707,8 @@ static inline int wait_for_ctrl_irq(stru dbg("%s - start\n", __FUNCTION__); add_wait_queue(&ctrl->queue, &wait); - set_current_state(TASK_INTERRUPTIBLE); /* Sleep for up to 1 second to wait for the LED to change. */ - schedule_timeout(1*HZ); + msleep_interruptible(1000); remove_wait_queue(&ctrl->queue, &wait); if (signal_pending(current)) retval = -EINTR; diff -puN drivers/pci/hotplug/cpqphp_nvram.h~bk-pci drivers/pci/hotplug/cpqphp_nvram.h --- 25/drivers/pci/hotplug/cpqphp_nvram.h~bk-pci 2004-10-01 20:07:40.190051880 -0700 +++ 25-akpm/drivers/pci/hotplug/cpqphp_nvram.h 2004-10-01 20:07:40.457011296 -0700 @@ -30,26 +30,26 @@ #ifndef CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM -static inline void compaq_nvram_init (void *rom_start) +static inline void compaq_nvram_init (void __iomem *rom_start) { return; } -static inline int compaq_nvram_load (void *rom_start, struct controller *ctrl) +static inline int compaq_nvram_load (void __iomem *rom_start, struct controller *ctrl) { return 0; } -static inline int compaq_nvram_store (void *rom_start) +static inline int compaq_nvram_store (void __iomem *rom_start) { return 0; } #else -extern void compaq_nvram_init (void *rom_start); -extern int compaq_nvram_load (void *rom_start, struct controller *ctrl); -extern int compaq_nvram_store (void *rom_start); +extern void compaq_nvram_init (void __iomem *rom_start); +extern int compaq_nvram_load (void __iomem *rom_start, struct controller *ctrl); +extern int compaq_nvram_store (void __iomem *rom_start); #endif diff -puN drivers/pci/hotplug/cpqphp_pci.c~bk-pci drivers/pci/hotplug/cpqphp_pci.c --- 25/drivers/pci/hotplug/cpqphp_pci.c~bk-pci 2004-10-01 20:07:40.191051728 -0700 +++ 25-akpm/drivers/pci/hotplug/cpqphp_pci.c 2004-10-01 20:07:40.458011144 -0700 @@ -51,10 +51,10 @@ static u16 unused_IRQ; * find the Hot Plug Resource Table in the specified region of memory. * */ -static void *detect_HRT_floating_pointer(void *begin, void *end) +static void __iomem *detect_HRT_floating_pointer(void __iomem *begin, void __iomem *end) { - void *fp; - void *endp; + void __iomem *fp; + void __iomem *endp; u8 temp1, temp2, temp3, temp4; int status = 0; @@ -1162,12 +1162,13 @@ int cpqhp_valid_replace(struct controlle * * returns 0 if success */ -int cpqhp_find_available_resources (struct controller *ctrl, void *rom_start) +int cpqhp_find_available_resources(struct controller *ctrl, void __iomem *rom_start) { u8 temp; u8 populated_slot; u8 bridged_slot; - void *one_slot; + void __iomem *one_slot; + void __iomem *rom_resource_table; struct pci_func *func = NULL; int i = 10, index; u32 temp_dword, rc; @@ -1175,7 +1176,6 @@ int cpqhp_find_available_resources (stru struct pci_resource *p_mem_node; struct pci_resource *io_node; struct pci_resource *bus_node; - void *rom_resource_table; rom_resource_table = detect_HRT_floating_pointer(rom_start, rom_start+0xffff); dbg("rom_resource_table = %p\n", rom_resource_table); diff -puN drivers/pci/hotplug/ibmphp_core.c~bk-pci drivers/pci/hotplug/ibmphp_core.c --- 25/drivers/pci/hotplug/ibmphp_core.c~bk-pci 2004-10-01 20:07:40.193051424 -0700 +++ 25-akpm/drivers/pci/hotplug/ibmphp_core.c 2004-10-01 20:07:40.459010992 -0700 @@ -886,7 +886,7 @@ static int set_bus (struct slot * slot_c break; case BUS_SPEED_133: /* This is to take care of the bug in CIOBX chip */ - while ((dev = pci_find_device(PCI_VENDOR_ID_SERVERWORKS, + while ((dev = pci_get_device(PCI_VENDOR_ID_SERVERWORKS, 0x0101, dev)) != NULL) ibmphp_hpc_writeslot (slot_cur, HPC_BUS_100PCIXMODE); cmd = HPC_BUS_133PCIXMODE; diff -puN drivers/pci/hotplug/ibmphp_ebda.c~bk-pci drivers/pci/hotplug/ibmphp_ebda.c --- 25/drivers/pci/hotplug/ibmphp_ebda.c~bk-pci 2004-10-01 20:07:40.194051272 -0700 +++ 25-akpm/drivers/pci/hotplug/ibmphp_ebda.c 2004-10-01 20:07:40.460010840 -0700 @@ -63,7 +63,7 @@ static LIST_HEAD (rio_vg_head); static LIST_HEAD (rio_lo_head); static LIST_HEAD (opt_vg_head); static LIST_HEAD (opt_lo_head); -static void *io_mem; +static void __iomem *io_mem; /* Local functions */ static int ebda_rsrc_controller (void); @@ -1246,7 +1246,7 @@ int ibmphp_register_pci (void) list_for_each (tmp, &ebda_hpc_head) { ctrl = list_entry (tmp, struct controller, ebda_hpc_list); if (ctrl->ctlr_type == 1) { - rc = pci_module_init (&ibmphp_driver); + rc = pci_register_driver(&ibmphp_driver); break; } } diff -puN drivers/pci/hotplug/ibmphp_hpc.c~bk-pci drivers/pci/hotplug/ibmphp_hpc.c --- 25/drivers/pci/hotplug/ibmphp_hpc.c~bk-pci 2004-10-01 20:07:40.196050968 -0700 +++ 25-akpm/drivers/pci/hotplug/ibmphp_hpc.c 2004-10-01 20:07:40.462010536 -0700 @@ -108,8 +108,8 @@ static struct semaphore sem_exit; // mak //---------------------------------------------------------------------------- // local function prototypes //---------------------------------------------------------------------------- -static u8 i2c_ctrl_read (struct controller *, void *, u8); -static u8 i2c_ctrl_write (struct controller *, void *, u8, u8); +static u8 i2c_ctrl_read (struct controller *, void __iomem *, u8); +static u8 i2c_ctrl_write (struct controller *, void __iomem *, u8, u8); static u8 hpc_writecmdtoindex (u8, u8); static u8 hpc_readcmdtoindex (u8, u8); static void get_hpc_access (void); @@ -118,7 +118,7 @@ static void poll_hpc (void); static int process_changeinstatus (struct slot *, struct slot *); static int process_changeinlatch (u8, u8, struct controller *); static int hpc_poll_thread (void *); -static int hpc_wait_ctlr_notworking (int, struct controller *, void *, u8 *); +static int hpc_wait_ctlr_notworking (int, struct controller *, void __iomem *, u8 *); //---------------------------------------------------------------------------- @@ -147,11 +147,11 @@ void __init ibmphp_hpc_initvars (void) * Action: read from HPC over I2C * *---------------------------------------------------------------------*/ -static u8 i2c_ctrl_read (struct controller *ctlr_ptr, void *WPGBbar, u8 index) +static u8 i2c_ctrl_read (struct controller *ctlr_ptr, void __iomem *WPGBbar, u8 index) { u8 status; int i; - void *wpg_addr; // base addr + offset + void __iomem *wpg_addr; // base addr + offset unsigned long wpg_data; // data to/from WPG LOHI format unsigned long ultemp; unsigned long data; // actual data HILO format @@ -255,10 +255,10 @@ static u8 i2c_ctrl_read (struct controll * * Return 0 or error codes *---------------------------------------------------------------------*/ -static u8 i2c_ctrl_write (struct controller *ctlr_ptr, void *WPGBbar, u8 index, u8 cmd) +static u8 i2c_ctrl_write (struct controller *ctlr_ptr, void __iomem *WPGBbar, u8 index, u8 cmd) { u8 rc; - void *wpg_addr; // base addr + offset + void __iomem *wpg_addr; // base addr + offset unsigned long wpg_data; // data to/from WPG LOHI format unsigned long ultemp; unsigned long data; // actual data HILO format @@ -399,7 +399,7 @@ static u8 pci_ctrl_write (struct control return rc; } -static u8 ctrl_read (struct controller *ctlr, void *base, u8 offset) +static u8 ctrl_read (struct controller *ctlr, void __iomem *base, u8 offset) { u8 rc; switch (ctlr->ctlr_type) { @@ -419,7 +419,7 @@ static u8 ctrl_read (struct controller * return rc; } -static u8 ctrl_write (struct controller *ctlr, void *base, u8 offset, u8 data) +static u8 ctrl_write (struct controller *ctlr, void __iomem *base, u8 offset, u8 data) { u8 rc = 0; switch (ctlr->ctlr_type) { @@ -536,7 +536,7 @@ static u8 hpc_readcmdtoindex (u8 cmd, u8 *---------------------------------------------------------------------*/ int ibmphp_hpc_readslot (struct slot * pslot, u8 cmd, u8 * pstatus) { - void *wpg_bbar = NULL; + void __iomem *wpg_bbar = NULL; struct controller *ctlr_ptr; struct list_head *pslotlist; u8 index, status; @@ -660,7 +660,7 @@ int ibmphp_hpc_readslot (struct slot * p // remove physical to logical address mapping if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4)) - iounmap (wpg_bbar); + iounmap (wpg_bbar); free_hpc_access (); @@ -675,7 +675,7 @@ int ibmphp_hpc_readslot (struct slot * p *---------------------------------------------------------------------*/ int ibmphp_hpc_writeslot (struct slot * pslot, u8 cmd) { - void *wpg_bbar = NULL; + void __iomem *wpg_bbar = NULL; struct controller *ctlr_ptr; u8 index, status; int busindex; @@ -764,7 +764,7 @@ int ibmphp_hpc_writeslot (struct slot * // remove physical to logical address mapping if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4)) - iounmap (wpg_bbar); + iounmap (wpg_bbar); free_hpc_access (); debug_polling ("%s - Exit rc[%d]\n", __FUNCTION__, rc); @@ -1130,7 +1130,7 @@ void __exit ibmphp_hpc_stop_poll_thread * Return 0, HPC_ERROR * Value: *---------------------------------------------------------------------*/ -static int hpc_wait_ctlr_notworking (int timeout, struct controller *ctlr_ptr, void *wpg_bbar, +static int hpc_wait_ctlr_notworking (int timeout, struct controller *ctlr_ptr, void __iomem *wpg_bbar, u8 * pstatus) { int rc = 0; diff -puN drivers/pci/hotplug/pciehp_core.c~bk-pci drivers/pci/hotplug/pciehp_core.c --- 25/drivers/pci/hotplug/pciehp_core.c~bk-pci 2004-10-01 20:07:40.197050816 -0700 +++ 25-akpm/drivers/pci/hotplug/pciehp_core.c 2004-10-01 20:07:40.463010384 -0700 @@ -602,8 +602,8 @@ static int __init pcied_init(void) retval = pciehprm_init(PCI); if (!retval) { - retval = pci_module_init(&pcie_driver); - dbg("pci_module_init = %d\n", retval); + retval = pci_register_driver(&pcie_driver); + dbg("pci_register_driver = %d\n", retval); info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); } diff -puN drivers/pci/hotplug/pciehp_ctrl.c~bk-pci drivers/pci/hotplug/pciehp_ctrl.c --- 25/drivers/pci/hotplug/pciehp_ctrl.c~bk-pci 2004-10-01 20:07:40.199050512 -0700 +++ 25-akpm/drivers/pci/hotplug/pciehp_ctrl.c 2004-10-01 20:07:40.465010080 -0700 @@ -38,6 +38,7 @@ #include #include #include +#include "../pci.h" #include "pciehp.h" #include "pciehprm.h" @@ -1212,6 +1213,10 @@ static u32 board_added(struct pci_func * } } while (new_func); + /* Some PCI Express devices require ASPM fixup after hot-plug operation. */ + if (pcie_mch_quirk) + pcie_rootport_aspm_quirk(ctrl->pci_dev); + /* Wait for exclusive access to hardware */ down(&ctrl->crit_sect); diff -puN drivers/pci/hotplug/pciehp.h~bk-pci drivers/pci/hotplug/pciehp.h --- 25/drivers/pci/hotplug/pciehp.h~bk-pci 2004-10-01 20:07:40.200050360 -0700 +++ 25-akpm/drivers/pci/hotplug/pciehp.h 2004-10-01 20:07:40.463010384 -0700 @@ -31,6 +31,7 @@ #include #include +#include #include #include #include "pci_hotplug.h" @@ -261,14 +262,12 @@ static inline int wait_for_ctrl_irq(stru dbg("%s : start\n", __FUNCTION__); add_wait_queue(&ctrl->queue, &wait); - set_current_state(TASK_INTERRUPTIBLE); - if (!pciehp_poll_mode) { + if (!pciehp_poll_mode) /* Sleep for up to 1 second */ - schedule_timeout(1*HZ); - } else - schedule_timeout(2.5*HZ); + msleep_interruptible(1000); + else + msleep_interruptible(2500); - set_current_state(TASK_RUNNING); remove_wait_queue(&ctrl->queue, &wait); if (signal_pending(current)) retval = -EINTR; diff -puN drivers/pci/hotplug/pciehp_hpc.c~bk-pci drivers/pci/hotplug/pciehp_hpc.c --- 25/drivers/pci/hotplug/pciehp_hpc.c~bk-pci 2004-10-01 20:07:40.202050056 -0700 +++ 25-akpm/drivers/pci/hotplug/pciehp_hpc.c 2004-10-01 20:07:40.466009928 -0700 @@ -741,6 +741,8 @@ static void hpc_release_ctlr(struct cont 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 @@ int pcie_init(struct controller * ctrl, 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 -puN drivers/pci/hotplug/pciehp_pci.c~bk-pci drivers/pci/hotplug/pciehp_pci.c --- 25/drivers/pci/hotplug/pciehp_pci.c~bk-pci 2004-10-01 20:07:40.203049904 -0700 +++ 25-akpm/drivers/pci/hotplug/pciehp_pci.c 2004-10-01 20:07:40.467009776 -0700 @@ -82,9 +82,11 @@ int pciehp_unconfigure_device(struct pci { 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,11 @@ int pciehp_unconfigure_device(struct pci pci_remove_bus_device(temp); } } + + /* Some PCI Express devices require ASPM fixup after hot-plug operation. */ + if (pcie_mch_quirk) + pcie_rootport_aspm_quirk(pbus->self); + return rc; } diff -puN drivers/pci/hotplug/rpadlpar_core.c~bk-pci drivers/pci/hotplug/rpadlpar_core.c --- 25/drivers/pci/hotplug/rpadlpar_core.c~bk-pci 2004-10-01 20:07:40.205049600 -0700 +++ 25-akpm/drivers/pci/hotplug/rpadlpar_core.c 2004-10-01 20:07:40.469009472 -0700 @@ -25,6 +25,10 @@ static DECLARE_MUTEX(rpadlpar_sem); +#define NODE_TYPE_VIO 1 +#define NODE_TYPE_SLOT 2 +#define NODE_TYPE_PHB 3 + static struct device_node *find_php_slot_vio_node(char *drc_name) { struct device_node *child; @@ -44,21 +48,50 @@ static struct device_node *find_php_slot return NULL; } -static struct device_node *find_php_slot_pci_node(char *drc_name) +/* Find dlpar-capable pci node that contains the specified name and type */ +static struct device_node *find_php_slot_pci_node(char *drc_name, + char *drc_type) { struct device_node *np = NULL; char *name; + char *type; + int rc; - while ((np = of_find_node_by_type(np, "pci"))) - if (is_hotplug_capable(np)) { - name = rpaphp_get_drc_name(np); - if (name && (!strcmp(drc_name, name))) + while ((np = of_find_node_by_type(np, "pci"))) { + rc = rpaphp_get_drc_props(np, NULL, &name, &type, NULL); + if (rc == 0) + if (!strcmp(drc_name, name) && !strcmp(drc_type, type)) break; - } + } return np; } +static struct device_node *find_newly_added_node(char *drc_name, int *node_type) +{ + struct device_node *dn; + + dn = find_php_slot_pci_node(drc_name, "SLOT"); + if (dn) { + *node_type = NODE_TYPE_SLOT; + return dn; + } + + dn = find_php_slot_pci_node(drc_name, "PHB"); + if (dn) { + *node_type = NODE_TYPE_PHB; + return dn; + } + + dn = find_php_slot_vio_node(drc_name); + if (dn) { + *node_type = NODE_TYPE_VIO; + return dn; + } + + return NULL; +} + static struct slot *find_slot(char *drc_name) { struct list_head *tmp, *n; @@ -125,12 +158,8 @@ static int pci_add_secondary_bus(struct dn->bussubno = child->number; - /* ioremap() for child bus */ - if (remap_bus_range(child)) { - printk(KERN_ERR "%s: could not ioremap() child bus\n", - __FUNCTION__); - return 1; - } + /* ioremap() for child bus, which may or may not succeed */ + remap_bus_range(child); return 0; } @@ -205,6 +234,71 @@ static inline int dlpar_add_pci_slot(cha return 0; } +static int dlpar_remove_root_bus(struct pci_controller *phb) +{ + struct pci_bus *phb_bus; + int rc; + + phb_bus = phb->bus; + if (!(list_empty(&phb_bus->children) && + list_empty(&phb_bus->devices))) { + return -EBUSY; + } + + rc = pcibios_remove_root_bus(phb); + if (rc) + return -EIO; + + device_unregister(phb_bus->bridge); + pci_remove_bus(phb_bus); + + return 0; +} + +static int dlpar_remove_phb(struct slot *slot) +{ + struct pci_controller *phb; + struct device_node *dn; + int rc = 0; + + dn = slot->dn; + if (!dn) { + printk(KERN_ERR "%s: unexpected NULL slot device node\n", + __FUNCTION__); + return -EIO; + } + + phb = dn->phb; + if (!phb) { + printk(KERN_ERR "%s: unexpected NULL phb pointer\n", + __FUNCTION__); + return -EIO; + } + + if (rpaphp_remove_slot(slot)) { + printk(KERN_ERR "%s: unable to remove hotplug slot %s\n", + __FUNCTION__, slot->location); + return -EIO; + } + + rc = dlpar_remove_root_bus(phb); + if (rc) + return rc; + + return 0; +} + +static int dlpar_add_phb(struct device_node *dn) +{ + struct pci_controller *phb; + + phb = init_phb_dynamic(dn); + if (!phb) + return 1; + + return 0; +} + /** * dlpar_add_slot - DLPAR add an I/O Slot * @drc_name: drc-name of newly added slot @@ -220,7 +314,8 @@ static inline int dlpar_add_pci_slot(cha */ int dlpar_add_slot(char *drc_name) { - struct device_node *dn; + struct device_node *dn = NULL; + int node_type; int rc = 0; if (down_interruptible(&rpadlpar_sem)) @@ -232,18 +327,27 @@ int dlpar_add_slot(char *drc_name) goto exit; } - dn = find_php_slot_vio_node(drc_name); + dn = find_newly_added_node(drc_name, &node_type); if (!dn) { - dn = find_php_slot_pci_node(drc_name); - if (dn) + rc = -ENODEV; + goto exit; + } + + switch (node_type) { + case NODE_TYPE_VIO: + /* Just add hotplug slot */ + break; + case NODE_TYPE_SLOT: rc = dlpar_add_pci_slot(drc_name, dn); - else { - rc = -ENODEV; - goto exit; - } + break; + case NODE_TYPE_PHB: + rc = dlpar_add_phb(dn); + break; + default: + printk("%s: unexpected node type\n", __FUNCTION__); + return -EIO; } - /* Add hotplug slot for new VIOA or PCI */ if (!rc && rpaphp_add_slot(dn)) { printk(KERN_ERR "%s: unable to add hotplug slot %s\n", __FUNCTION__, drc_name); @@ -337,7 +441,8 @@ int dlpar_remove_slot(char *drc_name) return -ERESTARTSYS; if (!find_php_slot_vio_node(drc_name) && - !find_php_slot_pci_node(drc_name)) { + !find_php_slot_pci_node(drc_name, "SLOT") && + !find_php_slot_pci_node(drc_name, "PHB")) { rc = -ENODEV; goto exit; } @@ -348,17 +453,18 @@ int dlpar_remove_slot(char *drc_name) goto exit; } - switch (slot->dev_type) { - case PCI_DEV: - rc = dlpar_remove_pci_slot(slot, drc_name); - break; - - case VIO_DEV: - rc = dlpar_remove_vio_slot(slot, drc_name); - break; + if (slot->type == PHB) { + rc = dlpar_remove_phb(slot); + } else { + switch (slot->dev_type) { + case PCI_DEV: + rc = dlpar_remove_pci_slot(slot, drc_name); + break; - default: - rc = -EIO; + case VIO_DEV: + rc = dlpar_remove_vio_slot(slot, drc_name); + break; + } } exit: up(&rpadlpar_sem); diff -puN drivers/pci/hotplug/rpaphp_core.c~bk-pci drivers/pci/hotplug/rpaphp_core.c --- 25/drivers/pci/hotplug/rpaphp_core.c~bk-pci 2004-10-01 20:07:40.206049448 -0700 +++ 25-akpm/drivers/pci/hotplug/rpaphp_core.c 2004-10-01 20:07:40.470009320 -0700 @@ -63,7 +63,6 @@ static int get_power_status(struct hotpl static int get_attention_status(struct hotplug_slot *slot, u8 * value); static int get_adapter_status(struct hotplug_slot *slot, u8 * value); static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value); -static int rpaphp_disable_slot(struct pci_dev *dev); struct hotplug_slot_ops rpaphp_hotplug_slot_ops = { .owner = THIS_MODULE, @@ -212,32 +211,91 @@ int rpaphp_remove_slot(struct slot *slot return deregister_slot(slot); } -static int get_dn_properties(struct device_node *dn, int **indexes, int **names, - int **types, int **power_domains) +static int get_children_props(struct device_node *dn, int **drc_indexes, + int **drc_names, int **drc_types, int **drc_power_domains) { - *indexes = (int *) get_property(dn, "ibm,drc-indexes", NULL); + int *indexes, *names; + int *types, *domains; - /* &names[1] contains NULL terminated slot names */ - *names = (int *) get_property(dn, "ibm,drc-names", NULL); + indexes = (int *) get_property(dn, "ibm,drc-indexes", NULL); + names = (int *) get_property(dn, "ibm,drc-names", NULL); + types = (int *) get_property(dn, "ibm,drc-types", NULL); + domains = (int *) get_property(dn, "ibm,drc-power-domains", NULL); + + if (!indexes || !names || !types || !domains) { + /* Slot does not have dynamically-removable children */ + return 1; + } + if (drc_indexes) + *drc_indexes = indexes; + if (drc_names) + /* &drc_names[1] contains NULL terminated slot names */ + *drc_names = names; + if (drc_types) + /* &drc_types[1] contains NULL terminated slot types */ + *drc_types = types; + if (drc_power_domains) + *drc_power_domains = domains; - /* &types[1] contains NULL terminated slot types */ - *types = (int *) get_property(dn, "ibm,drc-types", NULL); - - /* power_domains[1...n] are the slot power domains */ - *power_domains = (int *) get_property(dn, "ibm,drc-power-domains", NULL); - - if (*indexes && *names && *types && *power_domains) - return (1); - - return (0); + return 0; +} + +/* To get the DRC props describing the current node, first obtain it's + * my-drc-index property. Next obtain the DRC list from it's parent. Use + * the my-drc-index for correlation, and obtain the requested properties. + */ +int rpaphp_get_drc_props(struct device_node *dn, int *drc_index, + char **drc_name, char **drc_type, int *drc_power_domain) +{ + int *indexes, *names; + int *types, *domains; + unsigned int *my_index; + char *name_tmp, *type_tmp; + int i, rc; + + my_index = (int *) get_property(dn, "ibm,my-drc-index", NULL); + if (!my_index) { + /* Node isn't DLPAR/hotplug capable */ + return 1; + } + + rc = get_children_props(dn->parent, &indexes, &names, &types, &domains); + if (rc) { + return 1; + } + + name_tmp = (char *) &names[1]; + type_tmp = (char *) &types[1]; + + /* Iterate through parent properties, looking for my-drc-index */ + for (i = 0; i < indexes[0]; i++) { + if ((unsigned int) indexes[i + 1] == *my_index) { + if (drc_name) + *drc_name = name_tmp; + if (drc_type) + *drc_type = type_tmp; + if (drc_index) + *drc_index = *my_index; + if (drc_power_domain) + *drc_power_domain = domains[i+1]; + return 0; + } + name_tmp += (strlen(name_tmp) + 1); + type_tmp += (strlen(type_tmp) + 1); + } + + return 1; } static int is_php_dn(struct device_node *dn, int **indexes, int **names, int **types, int **power_domains) { + int rc; + if (!is_hotplug_capable(dn)) return (0); - if (!get_dn_properties(dn, indexes, names, types, power_domains)) + rc = get_children_props(dn, indexes, names, types, power_domains); + if (rc) return (0); return (1); } @@ -245,8 +303,7 @@ static int is_php_dn(struct device_node static int is_dr_dn(struct device_node *dn, int **indexes, int **names, int **types, int **power_domains, int **my_drc_index) { - if (!is_hotplug_capable(dn)) - return (0); + int rc; *my_drc_index = (int *) get_property(dn, "ibm,my-drc-index", NULL); if(!*my_drc_index) @@ -255,7 +312,9 @@ static int is_dr_dn(struct device_node * if (!dn->parent) return (0); - return get_dn_properties(dn->parent, indexes, names, types, power_domains); + rc = get_children_props(dn->parent, indexes, names, types, + power_domains); + return (rc == 0); } static inline int is_vdevice_root(struct device_node *dn) @@ -263,34 +322,10 @@ static inline int is_vdevice_root(struct return !strcmp(dn->name, "vdevice"); } -char *rpaphp_get_drc_name(struct device_node *dn) +int is_dlpar_type(const char *type_str) { - char *name, *ptr = NULL; - int *drc_names, *drc_indexes, i; - struct device_node *parent = dn->parent; - u32 *my_drc_index; - - if (!parent) - return NULL; - - my_drc_index = (u32 *) get_property(dn, "ibm,my-drc-index", NULL); - if (!my_drc_index) - return NULL; - - drc_names = (int *) get_property(parent, "ibm,drc-names", NULL); - drc_indexes = (int *) get_property(parent, "ibm,drc-indexes", NULL); - if (!drc_names || !drc_indexes) - return NULL; - - name = (char *) &drc_names[1]; - for (i = 0; i < drc_indexes[0]; i++, name += (strlen(name) + 1)) { - if (drc_indexes[i + 1] == *my_drc_index) { - ptr = (char *) name; - break; - } - } - - return ptr; + /* Only register DLPAR-capable nodes of drc-type PHB or SLOT */ + return (!strcmp(type_str, "PHB") || !strcmp(type_str, "SLOT")); } /**************************************************************** @@ -329,15 +364,18 @@ int rpaphp_add_slot(struct device_node * for (i = 0; i < indexes[0]; i++, name += (strlen(name) + 1), type += (strlen(type) + 1)) { - if ( slot_type == HOTPLUG || - (slot_type == EMBEDDED && indexes[i + 1] == my_drc_index[0])) { - + if (slot_type == HOTPLUG || + (slot_type == EMBEDDED && + indexes[i + 1] == my_drc_index[0] && + is_dlpar_type(type))) { if (!(slot = alloc_slot_struct(dn, indexes[i + 1], name, power_domains[i + 1]))) { retval = -ENOMEM; goto exit; } - if (slot_type == EMBEDDED) + if (!strcmp(type, "PHB")) + slot->type = PHB; + else if (slot_type == EMBEDDED) slot->type = EMBEDDED; else slot->type = simple_strtoul(type, NULL, 10); @@ -442,11 +480,6 @@ exit: return retval; } -static int rpaphp_disable_slot(struct pci_dev *dev) -{ - return disable_slot(rpaphp_find_hotplug_slot(dev)); -} - static int disable_slot(struct hotplug_slot *hotplug_slot) { int retval = -EINVAL; @@ -483,4 +516,4 @@ module_exit(rpaphp_exit); EXPORT_SYMBOL_GPL(rpaphp_add_slot); EXPORT_SYMBOL_GPL(rpaphp_remove_slot); EXPORT_SYMBOL_GPL(rpaphp_slot_head); -EXPORT_SYMBOL_GPL(rpaphp_get_drc_name); +EXPORT_SYMBOL_GPL(rpaphp_get_drc_props); diff -puN drivers/pci/hotplug/rpaphp.h~bk-pci drivers/pci/hotplug/rpaphp.h --- 25/drivers/pci/hotplug/rpaphp.h~bk-pci 2004-10-01 20:07:40.207049296 -0700 +++ 25-akpm/drivers/pci/hotplug/rpaphp.h 2004-10-01 20:07:40.469009472 -0700 @@ -30,6 +30,7 @@ #include #include "pci_hotplug.h" +#define PHB 2 #define HOTPLUG 1 #define EMBEDDED 0 @@ -129,7 +130,8 @@ extern struct hotplug_slot *rpaphp_find_ /* rpaphp_core.c */ extern int rpaphp_add_slot(struct device_node *dn); extern int rpaphp_remove_slot(struct slot *slot); -extern char *rpaphp_get_drc_name(struct device_node *dn); +extern int rpaphp_get_drc_props(struct device_node *dn, int *drc_index, + char **drc_name, char **drc_type, int *drc_power_domain); /* rpaphp_vio.c */ extern int rpaphp_get_vio_adapter_status(struct slot *slot, int is_init, u8 * value); diff -puN drivers/pci/hotplug/rpaphp_pci.c~bk-pci drivers/pci/hotplug/rpaphp_pci.c --- 25/drivers/pci/hotplug/rpaphp_pci.c~bk-pci 2004-10-01 20:07:40.209048992 -0700 +++ 25-akpm/drivers/pci/hotplug/rpaphp_pci.c 2004-10-01 20:07:40.471009168 -0700 @@ -117,33 +117,40 @@ static int rpaphp_get_sensor_state(struc int rpaphp_get_pci_adapter_status(struct slot *slot, int is_init, u8 * value) { int state, rc; - *value = NOT_VALID; + struct device_node *child_dn; + struct pci_dev *child_dev; + *value = NOT_VALID; rc = rpaphp_get_sensor_state(slot, &state); if (rc) goto exit; - if (state == PRESENT) { + + if ((state == EMPTY) || (slot->type == PHB)) { + dbg("slot is empty\n"); + *value = EMPTY; + } + else if (state == PRESENT) { if (!is_init) /* at run-time slot->state can be changed by */ /* config/unconfig adapter */ *value = slot->state; else { - if (!slot->dn->child) + child_dn = slot->dn->child; + if (child_dn) + child_dev = rpaphp_find_pci_dev(child_dn); + + if (child_dev) + *value = CONFIGURED; + else if (!child_dn) dbg("%s: %s is not valid OFDT node\n", __FUNCTION__, slot->dn->full_name); - else if (rpaphp_find_pci_dev(slot->dn->child)) - *value = CONFIGURED; else { err("%s: can't find pdev of adapter in slot[%s]\n", __FUNCTION__, slot->dn->full_name); *value = NOT_CONFIGURED; } } - } else if (state == EMPTY) { - dbg("slot is empty\n"); - *value = state; } - exit: return rc; } @@ -408,15 +415,52 @@ static int setup_pci_hotplug_slot_info(s return 0; } +static int set_phb_slot_name(struct slot *slot) +{ + struct device_node *dn; + struct pci_controller *phb; + struct pci_bus *bus; + + dn = slot->dn; + if (!dn) { + return 1; + } + phb = dn->phb; + if (!phb) { + return 1; + } + bus = phb->bus; + if (!bus) { + return 1; + } + + sprintf(slot->name, "%04x:%02x:%02x.%x", pci_domain_nr(bus), + bus->number, 0, 0); + return 0; +} + static int setup_pci_slot(struct slot *slot) { - slot->bridge = rpaphp_find_bridge_pdev(slot); - if (!slot->bridge) { /* slot being added doesn't have pci_dev yet */ - err("%s: no pci_dev for bridge dn %s\n", __FUNCTION__, slot->name); - goto exit_rc; + int rc; + + if (slot->type == PHB) { + rc = set_phb_slot_name(slot); + if (rc) { + err("%s: failed to set phb slot name\n", __FUNCTION__); + goto exit_rc; + } + } else { + slot->bridge = rpaphp_find_bridge_pdev(slot); + if (!slot->bridge) { + /* slot being added doesn't have pci_dev yet */ + err("%s: no pci_dev for bridge dn %s\n", + __FUNCTION__, slot->name); + goto exit_rc; + } + dbg("%s set slot->name to %s\n", __FUNCTION__, + pci_name(slot->bridge)); + strcpy(slot->name, pci_name(slot->bridge)); } - dbg("%s set slot->name to %s\n", __FUNCTION__, pci_name(slot->bridge)); - strcpy(slot->name, pci_name(slot->bridge)); /* find slot's pci_dev if it's not empty */ if (slot->hotplug_slot->info->adapter_status == EMPTY) { @@ -470,10 +514,10 @@ int register_pci_slot(struct slot *slot) int rc = 1; slot->dev_type = PCI_DEV; - if (slot->type == EMBEDDED) - slot->removable = EMBEDDED; + if ((slot->type == EMBEDDED) || (slot->type == PHB)) + slot->removable = 0; else - slot->removable = HOTPLUG; + slot->removable = 1; INIT_LIST_HEAD(&slot->dev.pci_funcs); if (setup_pci_hotplug_slot_info(slot)) goto exit_rc; diff -puN drivers/pci/hotplug/rpaphp_slot.c~bk-pci drivers/pci/hotplug/rpaphp_slot.c --- 25/drivers/pci/hotplug/rpaphp_slot.c~bk-pci 2004-10-01 20:07:40.210048840 -0700 +++ 25-akpm/drivers/pci/hotplug/rpaphp_slot.c 2004-10-01 20:07:40.472009016 -0700 @@ -246,12 +246,7 @@ int rpaphp_get_power_status(struct slot { int rc = 0, level; - if (slot->type == EMBEDDED) { - dbg("%s set to POWER_ON for EMBEDDED slot %s\n", - __FUNCTION__, slot->location); - *value = POWER_ON; - } - else { + if (slot->type == HOTPLUG) { rc = rtas_get_power_level(slot->power_domain, &level); if (!rc) { dbg("%s the power level of slot %s(pwd-domain:0x%x) is %d\n", @@ -260,6 +255,10 @@ int rpaphp_get_power_status(struct slot } else err("failed to get power-level for slot(%s), rc=0x%x\n", slot->location, rc); + } else { + dbg("%s report POWER_ON for EMBEDDED or PHB slot %s\n", + __FUNCTION__, slot->location); + *value = (u8) POWER_ON; } return rc; diff -puN drivers/pci/hotplug/rpaphp_vio.c~bk-pci drivers/pci/hotplug/rpaphp_vio.c --- 25/drivers/pci/hotplug/rpaphp_vio.c~bk-pci 2004-10-01 20:07:40.211048688 -0700 +++ 25-akpm/drivers/pci/hotplug/rpaphp_vio.c 2004-10-01 20:07:40.473008864 -0700 @@ -74,8 +74,8 @@ int register_vio_slot(struct device_node int rc = 1; struct slot *slot = NULL; - name = rpaphp_get_drc_name(dn); - if (!name) + rc = rpaphp_get_drc_props(dn, NULL, &name, NULL, NULL); + if (rc) goto exit_rc; index = (u32 *) get_property(dn, "ibm,my-drc-index", NULL); if (!index) diff -puN drivers/pci/hotplug/shpchp_core.c~bk-pci drivers/pci/hotplug/shpchp_core.c --- 25/drivers/pci/hotplug/shpchp_core.c~bk-pci 2004-10-01 20:07:40.212048536 -0700 +++ 25-akpm/drivers/pci/hotplug/shpchp_core.c 2004-10-01 20:07:40.474008712 -0700 @@ -599,8 +599,8 @@ static int __init shpcd_init(void) retval = shpchprm_init(PCI); if (!retval) { - retval = pci_module_init(&shpc_driver); - dbg("%s: pci_module_init = %d\n", __FUNCTION__, retval); + retval = pci_register_driver(&shpc_driver); + dbg("%s: pci_register_driver = %d\n", __FUNCTION__, retval); info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); } diff -puN drivers/pci/hotplug/shpchp_ctrl.c~bk-pci drivers/pci/hotplug/shpchp_ctrl.c --- 25/drivers/pci/hotplug/shpchp_ctrl.c~bk-pci 2004-10-01 20:07:40.214048232 -0700 +++ 25-akpm/drivers/pci/hotplug/shpchp_ctrl.c 2004-10-01 20:07:40.479007952 -0700 @@ -1050,7 +1050,64 @@ static int is_bridge(struct pci_func * f /* The following routines constitute the bulk of the hotplug controller logic */ +static u32 change_bus_speed(struct controller *ctrl, struct slot *p_slot, enum pci_bus_speed speed) +{ + u32 rc = 0; + dbg("%s: change to speed %d\n", __FUNCTION__, speed); + down(&ctrl->crit_sect); + if ((rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, speed))) { + 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; + } + up(&ctrl->crit_sect); + return rc; +} + +static u32 fix_bus_speed(struct controller *ctrl, struct slot *pslot, u8 flag, +enum pci_bus_speed asp, enum pci_bus_speed bsp, enum pci_bus_speed msp) +{ + u32 rc = 0; + + if (flag != 0) { /* Other slots on the same bus are occupied */ + if ( asp < bsp ) { + err("%s: speed of bus %x and adapter %x mismatch\n", __FUNCTION__, bsp, asp); + return WRONG_BUS_FREQUENCY; + } + } else { + /* Other slots on the same bus are empty */ + if (msp == bsp) { + /* if adapter_speed >= bus_speed, do nothing */ + if (asp < bsp) { + /* + * Try to lower bus speed to accommodate the adapter if other slots + * on the same controller are empty + */ + if ((rc = change_bus_speed(ctrl, pslot, asp))) + return rc; + } + } else { + if (asp < msp) { + if ((rc = change_bus_speed(ctrl, pslot, asp))) + return rc; + } else { + if ((rc = change_bus_speed(ctrl, pslot, msp))) + return rc; + } + } + } + return rc; +} /** * board_added - Called after a board has been added to the system. @@ -1061,14 +1118,13 @@ static int is_bridge(struct pci_func * f */ static u32 board_added(struct pci_func * func, struct controller * ctrl) { - u8 hp_slot, slot; + u8 hp_slot; u8 slots_not_empty = 0; int index; u32 temp_register = 0xFFFFFFFF; u32 retval, rc = 0; struct pci_func *new_func = NULL; - struct pci_func *t_func = NULL; - struct slot *p_slot, *pslot; + struct slot *p_slot; struct resource_lists res_lists; enum pci_bus_speed adapter_speed, bus_speed, max_bus_speed; u8 pi, mode; @@ -1132,258 +1188,72 @@ static u32 board_added(struct pci_func * /* Done with exclusive hardware access */ up(&ctrl->crit_sect); - rc = p_slot->hpc_ops->get_prog_int(p_slot, &pi); - if (rc) { + if ((rc = p_slot->hpc_ops->get_prog_int(p_slot, &pi))) { err("%s: Can't get controller programming interface, set it to 1\n", __FUNCTION__); pi = 1; } + + /* Check if there are other slots or devices on the same bus */ + if (!list_empty(&ctrl->pci_dev->subordinate->devices)) + slots_not_empty = 1; + + dbg("%s: slots_not_empty %d, pi %d\n", __FUNCTION__, + slots_not_empty, pi); + dbg("adapter_speed %d, bus_speed %d, max_bus_speed %d\n", + adapter_speed, bus_speed, max_bus_speed); + if (pi == 2) { - for ( slot = 0; slot < ctrl->num_slots; slot++) { - if (slot != hp_slot) { - pslot = shpchp_find_slot(ctrl, slot + ctrl->slot_device_offset); - t_func = shpchp_slot_find(pslot->bus, pslot->device, 0); - slots_not_empty |= t_func->is_a_board; - } + dbg("%s: In PI = %d\n", __FUNCTION__, pi); + if ((rc = p_slot->hpc_ops->get_mode1_ECC_cap(p_slot, &mode))) { + err("%s: Can't get Mode1_ECC, set mode to 0\n", __FUNCTION__); + mode = 0; } switch (adapter_speed) { - case PCI_SPEED_133MHz_PCIX_533: + case PCI_SPEED_133MHz_PCIX_533: case PCI_SPEED_133MHz_PCIX_266: - if ((( bus_speed < 0xa ) || (bus_speed < 0xd)) && (max_bus_speed > bus_speed) && - ((max_bus_speed <= 0xa) || (max_bus_speed <= 0xd)) && (!slots_not_empty)) { - - /* Wait for exclusive access to hardware */ - down(&ctrl->crit_sect); - - rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, max_bus_speed); - if (rc) { - err("%s: Issue of set bus speed mode command failed\n", __FUNCTION__); - /* Done with exclusive hardware access */ - up(&ctrl->crit_sect); - return WRONG_BUS_FREQUENCY; - } - - /* Wait for the command to complete */ - wait_for_ctrl_irq (ctrl); - - rc = p_slot->hpc_ops->check_cmd_status(ctrl); - if (rc) { - 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); - /* Done with exclusive hardware access */ - up(&ctrl->crit_sect); - return WRONG_BUS_FREQUENCY; - } - /* Done with exclusive hardware access */ - up(&ctrl->crit_sect); - } - break; + if ((bus_speed != adapter_speed) && + ((rc = fix_bus_speed(ctrl, p_slot, slots_not_empty, adapter_speed, bus_speed, max_bus_speed)))) + return rc; + break; case PCI_SPEED_133MHz_PCIX_ECC: case PCI_SPEED_133MHz_PCIX: - - rc = p_slot->hpc_ops->get_mode1_ECC_cap(p_slot, &mode); - - if (rc) { - err("%s: PI is 1 \n", __FUNCTION__); - return WRONG_BUS_FREQUENCY; - } - if (mode) { /* Bus - Mode 1 ECC */ - - if (bus_speed > 0x7) { - err("%s: speed of bus %x and adapter %x mismatch\n", __FUNCTION__, bus_speed, adapter_speed); - return WRONG_BUS_FREQUENCY; - } - - if ((bus_speed < 0x7) && (max_bus_speed <= 0x7) && - (bus_speed < max_bus_speed) && (!slots_not_empty)) { - - /* Wait for exclusive access to hardware */ - down(&ctrl->crit_sect); - - rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, max_bus_speed); - if (rc) { - err("%s: Issue of set bus speed mode command failed\n", __FUNCTION__); - /* Done with exclusive hardware access */ - up(&ctrl->crit_sect); - return WRONG_BUS_FREQUENCY; - } - - /* Wait for the command to complete */ - wait_for_ctrl_irq (ctrl); - - rc = p_slot->hpc_ops->check_cmd_status(ctrl); - if (rc) { - 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); - /* Done with exclusive hardware access */ - up(&ctrl->crit_sect); - return WRONG_BUS_FREQUENCY; - } - /* Done with exclusive hardware access */ - up(&ctrl->crit_sect); - } + if ((bus_speed != 0x7) && + ((rc = fix_bus_speed(ctrl, p_slot, slots_not_empty, adapter_speed, bus_speed, max_bus_speed)))) + return rc; } else { - if (bus_speed > 0x4) { - err("%s: speed of bus %x and adapter %x mismatch\n", __FUNCTION__, bus_speed, adapter_speed); - return WRONG_BUS_FREQUENCY; - } - - if ((bus_speed < 0x4) && (max_bus_speed <= 0x4) && - (bus_speed < max_bus_speed) && (!slots_not_empty)) { - - /* Wait for exclusive access to hardware */ - down(&ctrl->crit_sect); - - rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, max_bus_speed); - if (rc) { - err("%s: Issue of set bus speed mode command failed\n", __FUNCTION__); - /* Done with exclusive hardware access */ - up(&ctrl->crit_sect); - return WRONG_BUS_FREQUENCY; - } - - /* Wait for the command to complete */ - wait_for_ctrl_irq (ctrl); - - rc = p_slot->hpc_ops->check_cmd_status(ctrl); - if (rc) { - 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); - /* Done with exclusive hardware access */ - up(&ctrl->crit_sect); - return WRONG_BUS_FREQUENCY; - } - /* Done with exclusive hardware access */ - up(&ctrl->crit_sect); - } + if ((bus_speed != 0x4) && + ((rc = fix_bus_speed(ctrl, p_slot, slots_not_empty, adapter_speed, bus_speed, max_bus_speed)))) + return rc; } break; case PCI_SPEED_66MHz_PCIX_ECC: case PCI_SPEED_66MHz_PCIX: - - rc = p_slot->hpc_ops->get_mode1_ECC_cap(p_slot, &mode); - - if (rc) { - err("%s: PI is 1 \n", __FUNCTION__); - return WRONG_BUS_FREQUENCY; - } - if (mode) { /* Bus - Mode 1 ECC */ - - if (bus_speed > 0x5) { - err("%s: speed of bus %x and adapter %x mismatch\n", __FUNCTION__, bus_speed, adapter_speed); - return WRONG_BUS_FREQUENCY; - } - - if ((bus_speed < 0x5) && (max_bus_speed <= 0x5) && - (bus_speed < max_bus_speed) && (!slots_not_empty)) { - - /* Wait for exclusive access to hardware */ - down(&ctrl->crit_sect); - - rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, max_bus_speed); - if (rc) { - err("%s: Issue of set bus speed mode command failed\n", __FUNCTION__); - /* Done with exclusive hardware access */ - up(&ctrl->crit_sect); - return WRONG_BUS_FREQUENCY; - } - - /* Wait for the command to complete */ - wait_for_ctrl_irq (ctrl); - - rc = p_slot->hpc_ops->check_cmd_status(ctrl); - if (rc) { - 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); - /* Done with exclusive hardware access */ - up(&ctrl->crit_sect); - return WRONG_BUS_FREQUENCY; - } - /* Done with exclusive hardware access */ - up(&ctrl->crit_sect); - } + if ((bus_speed != 0x5) && + ((rc = fix_bus_speed(ctrl, p_slot, slots_not_empty, adapter_speed, bus_speed, max_bus_speed)))) + return rc; } else { - if (bus_speed > 0x2) { - err("%s: speed of bus %x and adapter %x mismatch\n", __FUNCTION__, bus_speed, adapter_speed); - return WRONG_BUS_FREQUENCY; - } - - if ((bus_speed < 0x2) && (max_bus_speed <= 0x2) && - (bus_speed < max_bus_speed) && (!slots_not_empty)) { - - /* Wait for exclusive access to hardware */ - down(&ctrl->crit_sect); - - rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, max_bus_speed); - if (rc) { - err("%s: Issue of set bus speed mode command failed\n", __FUNCTION__); - /* Done with exclusive hardware access */ - up(&ctrl->crit_sect); - return WRONG_BUS_FREQUENCY; - } - - /* Wait for the command to complete */ - wait_for_ctrl_irq (ctrl); - - rc = p_slot->hpc_ops->check_cmd_status(ctrl); - if (rc) { - 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); - /* Done with exclusive hardware access */ - up(&ctrl->crit_sect); - return WRONG_BUS_FREQUENCY; - } - /* Done with exclusive hardware access */ - up(&ctrl->crit_sect); - } + if ((bus_speed != 0x2) && + ((rc = fix_bus_speed(ctrl, p_slot, slots_not_empty, adapter_speed, bus_speed, max_bus_speed)))) + return rc; } break; case PCI_SPEED_66MHz: - if (bus_speed > 0x1) { - err("%s: speed of bus %x and adapter %x mismatch\n", __FUNCTION__, bus_speed, adapter_speed); - return WRONG_BUS_FREQUENCY; - } - if (bus_speed == 0x1) - ; - if ((bus_speed == 0x0) && ( max_bus_speed == 0x1)) { - /* Wait for exclusive access to hardware */ - down(&ctrl->crit_sect); - - rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, max_bus_speed); - if (rc) { - err("%s: Issue of set bus speed mode command failed\n", __FUNCTION__); - /* Done with exclusive hardware access */ - up(&ctrl->crit_sect); - return WRONG_BUS_FREQUENCY; - } - - /* Wait for the command to complete */ - wait_for_ctrl_irq (ctrl); - - rc = p_slot->hpc_ops->check_cmd_status(ctrl); - if (rc) { - 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); - /* Done with exclusive hardware access */ - up(&ctrl->crit_sect); - return WRONG_BUS_FREQUENCY; - } - /* Done with exclusive hardware access */ - up(&ctrl->crit_sect); - } + if ((bus_speed != 0x1) && + ((rc = fix_bus_speed(ctrl, p_slot, slots_not_empty, adapter_speed, bus_speed, max_bus_speed)))) + return rc; break; case PCI_SPEED_33MHz: if (bus_speed > 0x0) { - err("%s: speed of bus %x and adapter %x mismatch\n", __FUNCTION__, bus_speed, adapter_speed); - return WRONG_BUS_FREQUENCY; + if (slots_not_empty == 0) { + if ((rc = change_bus_speed(ctrl, p_slot, adapter_speed))) + return rc; + } else { + err("%s: speed of bus %x and adapter %x mismatch\n", __FUNCTION__, bus_speed, adapter_speed); + return WRONG_BUS_FREQUENCY; + } } break; default: @@ -1391,133 +1261,34 @@ static u32 board_added(struct pci_func * return WRONG_BUS_FREQUENCY; } } else { - /* if adpater_speed == bus_speed, nothing to do here */ - if (adapter_speed != bus_speed) { - for ( slot = 0; slot < ctrl->num_slots; slot++) { - if (slot != hp_slot) { - pslot = shpchp_find_slot(ctrl, slot + ctrl->slot_device_offset); - t_func = shpchp_slot_find(pslot->bus, pslot->device, 0); - slots_not_empty |= t_func->is_a_board; - } - } - - if (slots_not_empty != 0) { /* Other slots on the same bus are occupied */ - if ( adapter_speed < bus_speed ) { - err("%s: speed of bus %x and adapter %x mismatch\n", __FUNCTION__, bus_speed, adapter_speed); - return WRONG_BUS_FREQUENCY; - } - /* Do nothing if adapter_speed >= bus_speed */ - } - } - - if ((adapter_speed != bus_speed) && (slots_not_empty == 0)) { - /* Other slots on the same bus are empty */ - - rc = p_slot->hpc_ops->get_max_bus_speed(p_slot, &max_bus_speed); - if (rc || max_bus_speed == PCI_SPEED_UNKNOWN) { - err("%s: Can't get max bus operation speed\n", __FUNCTION__); - max_bus_speed = bus_speed; - } - - if (max_bus_speed == bus_speed) { - /* if adapter_speed >= bus_speed, do nothing */ - if (adapter_speed < bus_speed) { - /* - * Try to lower bus speed to accommodate the adapter if other slots - * on the same controller are empty - */ - - /* Wait for exclusive access to hardware */ - down(&ctrl->crit_sect); - - rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, adapter_speed); - if (rc) { - err("%s: Issue of set bus speed mode command failed\n", __FUNCTION__); - up(&ctrl->crit_sect); - return WRONG_BUS_FREQUENCY; - } - - /* Wait for the command to complete */ - wait_for_ctrl_irq (ctrl); - - rc = p_slot->hpc_ops->check_cmd_status(ctrl); - if (rc) { - 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; - } - /* Done with exclusive hardware access */ - up(&ctrl->crit_sect); - - } - } else { - /* Wait for exclusive access to hardware */ - down(&ctrl->crit_sect); - - /* max_bus_speed != bus_speed. Note: max_bus_speed should be > than bus_speed */ - if (adapter_speed < max_bus_speed) - rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, adapter_speed); - else - rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, max_bus_speed); - - if (rc) { - err("%s: Issue of set bus speed mode command failed\n", __FUNCTION__); - /* Done with exclusive hardware access */ - up(&ctrl->crit_sect); - return WRONG_BUS_FREQUENCY; - } - - /* Wait for the command to complete */ - wait_for_ctrl_irq (ctrl); - - rc = p_slot->hpc_ops->check_cmd_status(ctrl); - if (rc) { - 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); - /* Done with exclusive hardware access */ - up(&ctrl->crit_sect); - return WRONG_BUS_FREQUENCY; - } - /* Done with exclusive hardware access */ - up(&ctrl->crit_sect); - - } - } + /* If adpater_speed == bus_speed, nothing to do here */ + dbg("%s: In PI = %d\n", __FUNCTION__, pi); + if ((adapter_speed != bus_speed) && + ((rc = fix_bus_speed(ctrl, p_slot, slots_not_empty, adapter_speed, bus_speed, max_bus_speed)))) + return rc; } - /* Wait for exclusive access to hardware */ down(&ctrl->crit_sect); - /* turn on board, blink green LED, turn off Amber LED */ - rc = p_slot->hpc_ops->slot_enable(p_slot); - - if (rc) { + if ((rc = p_slot->hpc_ops->slot_enable(p_slot))) { err("%s: Issue of Slot Enable command failed\n", __FUNCTION__); - /* Done with exclusive hardware access */ up(&ctrl->crit_sect); return rc; } - /* Wait for the command to complete */ wait_for_ctrl_irq (ctrl); - rc = p_slot->hpc_ops->check_cmd_status(ctrl); - if (rc) { + if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) { err("%s: Failed to enable slot, error code(%d)\n", __FUNCTION__, rc); - /* Done with exclusive hardware access */ up(&ctrl->crit_sect); return rc; } - /* Done with exclusive hardware access */ up(&ctrl->crit_sect); /* Wait for ~1 second */ dbg("%s: before long_delay\n", __FUNCTION__); wait_for_ctrl_irq (ctrl); - dbg("%s: afterlong_delay\n", __FUNCTION__); + dbg("%s: after long_delay\n", __FUNCTION__); dbg("%s: func status = %x\n", __FUNCTION__, func->status); /* Check for a power fault */ @@ -2163,12 +1934,14 @@ int shpchp_disable_slot (struct slot *p_ u32 rc = 0; int ret = 0; unsigned int devfn; - struct pci_bus *pci_bus = p_slot->ctrl->pci_dev->subordinate; + struct pci_bus *pci_bus; struct pci_func *func; if (!p_slot->ctrl) return 1; + pci_bus = p_slot->ctrl->pci_dev->subordinate; + /* Check to see if (latch closed, card present, power on) */ down(&p_slot->ctrl->crit_sect); diff -puN drivers/pci/hotplug/shpchp.h~bk-pci drivers/pci/hotplug/shpchp.h --- 25/drivers/pci/hotplug/shpchp.h~bk-pci 2004-10-01 20:07:40.216047928 -0700 +++ 25-akpm/drivers/pci/hotplug/shpchp.h 2004-10-01 20:07:40.473008864 -0700 @@ -31,6 +31,7 @@ #include #include +#include #include #include #include "pci_hotplug.h" @@ -311,7 +312,7 @@ struct php_ctlr_state_s { php_intr_callback_t presence_change_callback; php_intr_callback_t power_fault_callback; void *callback_instance_id; - void *creg; /* Ptr to controller register space */ + void __iomem *creg; /* Ptr to controller register space */ }; /* Inline functions */ @@ -381,16 +382,14 @@ static inline int wait_for_ctrl_irq (str dbg("%s : start\n",__FUNCTION__); add_wait_queue(&ctrl->queue, &wait); - set_current_state(TASK_INTERRUPTIBLE); if (!shpchp_poll_mode) { /* Sleep for up to 1 second */ - schedule_timeout(1*HZ); + msleep_interruptible(1000); } else { /* Sleep for up to 2 seconds */ - schedule_timeout(2*HZ); + msleep_interruptible(2000); } - set_current_state(TASK_RUNNING); remove_wait_queue(&ctrl->queue, &wait); if (signal_pending(current)) retval = -EINTR; diff -puN drivers/pci/hotplug/shpchp_hpc.c~bk-pci drivers/pci/hotplug/shpchp_hpc.c --- 25/drivers/pci/hotplug/shpchp_hpc.c~bk-pci 2004-10-01 20:07:40.217047776 -0700 +++ 25-akpm/drivers/pci/hotplug/shpchp_hpc.c 2004-10-01 20:07:40.480007800 -0700 @@ -792,6 +792,7 @@ static void hpc_release_ctlr(struct cont 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) { @@ -1158,7 +1159,7 @@ static irqreturn_t shpc_isr(int IRQ, voi hp_slot, php_ctlr->callback_instance_id); /* Clear all slot events */ - temp_dword = 0xe01fffff; + temp_dword = 0xe01f3fff; dbg("%s: Clearing slot events, temp_dword = %x\n", __FUNCTION__, temp_dword); writel(temp_dword, php_ctlr->creg + SLOT1 + (4*hp_slot)); @@ -1492,8 +1493,7 @@ int shpc_init(struct controller * ctrl, goto abort_free_ctlr; } - php_ctlr->creg = (struct ctrl_reg *) - ioremap(pci_resource_start(pdev, 0) + shpc_base_offset, pci_resource_len(pdev, 0)); + php_ctlr->creg = ioremap(pci_resource_start(pdev, 0) + shpc_base_offset, pci_resource_len(pdev, 0)); if (!php_ctlr->creg) { err("%s: cannot remap MMIO region %lx @ %lx\n", __FUNCTION__, pci_resource_len(pdev, 0), pci_resource_start(pdev, 0) + shpc_base_offset); @@ -1539,7 +1539,7 @@ int shpc_init(struct controller * ctrl, slot_reg = readl(php_ctlr->creg + SLOT1 + 4*hp_slot ); dbg("%s: Default Logical Slot Register %d value %x\n", __FUNCTION__, hp_slot, slot_reg); - tempdword = 0xffffffff; + tempdword = 0xffff3fff; writel(tempdword, php_ctlr->creg + SLOT1 + (4*hp_slot)); } @@ -1592,7 +1592,7 @@ int shpc_init(struct controller * ctrl, slot_reg = readl(php_ctlr->creg + SLOT1 + 4*hp_slot ); dbg("%s: Default Logical Slot Register %d value %x\n", __FUNCTION__, hp_slot, slot_reg); - tempdword = 0xe01fffff; + tempdword = 0xe01f3fff; writel(tempdword, php_ctlr->creg + SLOT1 + (4*hp_slot)); } if (!shpchp_poll_mode) { diff -puN drivers/pci/hotplug/shpchprm_acpi.c~bk-pci drivers/pci/hotplug/shpchprm_acpi.c --- 25/drivers/pci/hotplug/shpchprm_acpi.c~bk-pci 2004-10-01 20:07:40.219047472 -0700 +++ 25-akpm/drivers/pci/hotplug/shpchprm_acpi.c 2004-10-01 20:07:40.482007496 -0700 @@ -1396,17 +1396,19 @@ static int configure_existing_function( static int bind_pci_resources_to_slots ( struct controller *ctrl) { struct pci_func *func, new_func; - int busn = ctrl->bus; + int busn = ctrl->slot_bus; int devn, funn; u32 vid; for (devn = 0; devn < 32; devn++) { for (funn = 0; funn < 8; funn++) { + /* if (devn == ctrl->device && funn == ctrl->function) continue; + */ /* find out if this entry is for an occupied slot */ vid = 0xFFFFFFFF; - pci_bus_read_config_dword(ctrl->pci_bus, PCI_DEVFN(devn, funn), PCI_VENDOR_ID, &vid); + pci_bus_read_config_dword(ctrl->pci_dev->subordinate, PCI_DEVFN(devn, funn), PCI_VENDOR_ID, &vid); if (vid != 0xFFFFFFFF) { func = shpchp_slot_find(busn, devn, funn); diff -puN drivers/pci/Makefile~bk-pci drivers/pci/Makefile --- 25/drivers/pci/Makefile~bk-pci 2004-10-01 20:07:40.220047320 -0700 +++ 25-akpm/drivers/pci/Makefile 2004-10-01 20:07:40.450012360 -0700 @@ -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 -puN drivers/pci/msi.c~bk-pci drivers/pci/msi.c --- 25/drivers/pci/msi.c~bk-pci 2004-10-01 20:07:40.221047168 -0700 +++ 25-akpm/drivers/pci/msi.c 2004-10-01 20:07:40.483007344 -0700 @@ -66,7 +66,7 @@ static void msi_set_mask_bit(unsigned in int pos; u32 mask_bits; - pos = entry->mask_base; + pos = (int)entry->mask_base; pci_read_config_dword(entry->dev, pos, &mask_bits); mask_bits &= ~(1); mask_bits |= flag; @@ -548,7 +548,7 @@ static int msi_capability_init(struct pc dev->irq = vector; entry->dev = dev; if (is_mask_bit_support(control)) { - entry->mask_base = msi_mask_bits_reg(pos, + entry->mask_base = (void __iomem *)msi_mask_bits_reg(pos, is_64bit_address(control)); } /* Replace with MSI handler */ @@ -606,7 +606,7 @@ static int msix_capability_init(struct p u32 phys_addr, table_offset; u16 control; u8 bir; - void *base; + void __iomem *base; pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); /* Request & Map MSI-X table region */ @@ -642,7 +642,7 @@ static int msix_capability_init(struct p entry->msi_attrib.maskbit = 1; entry->msi_attrib.default_vector = dev->irq; entry->dev = dev; - entry->mask_base = (unsigned long)base; + entry->mask_base = base; if (!head) { entry->link.head = vector; entry->link.tail = vector; @@ -806,7 +806,7 @@ static int msi_free_vector(struct pci_de { struct msi_desc *entry; int head, entry_nr, type; - unsigned long base = 0L; + void __iomem *base; unsigned long flags; spin_lock_irqsave(&msi_lock, flags); @@ -857,7 +857,7 @@ static int msi_free_vector(struct pci_de phys_addr = pci_resource_start (dev, bir); phys_addr += (u32)(table_offset & ~PCI_MSIX_FLAGS_BIRMASK); - iounmap((void*)base); + iounmap(base); release_mem_region(phys_addr, nr_entries * PCI_MSIX_ENTRY_SIZE); } @@ -869,8 +869,8 @@ static int msi_free_vector(struct pci_de static int reroute_msix_table(int head, struct msix_entry *entries, int *nvec) { int vector = head, tail = 0; - int i = 0, j = 0, nr_entries = 0; - unsigned long base = 0L; + int i, j = 0, nr_entries = 0; + void __iomem *base; unsigned long flags; spin_lock_irqsave(&msi_lock, flags); @@ -1099,7 +1099,7 @@ void msi_remove_pci_irq_vectors(struct p if ((pos = pci_find_capability(dev, PCI_CAP_ID_MSIX)) > 0 && !msi_lookup_vector(dev, PCI_CAP_ID_MSIX)) { int vector, head, tail = 0, warning = 0; - unsigned long base = 0L; + void __iomem *base = NULL; vector = head = dev->irq; while (head != tail) { @@ -1129,7 +1129,7 @@ void msi_remove_pci_irq_vectors(struct p phys_addr = pci_resource_start (dev, bir); phys_addr += (u32)(table_offset & ~PCI_MSIX_FLAGS_BIRMASK); - iounmap((void*)base); + iounmap(base); release_mem_region(phys_addr, PCI_MSIX_ENTRY_SIZE * multi_msix_capable(control)); printk(KERN_DEBUG "Driver[%d:%d:%d] unloaded wo doing free_irq on all vectors\n", diff -puN drivers/pci/msi.h~bk-pci drivers/pci/msi.h --- 25/drivers/pci/msi.h~bk-pci 2004-10-01 20:07:40.223046864 -0700 +++ 25-akpm/drivers/pci/msi.h 2004-10-01 20:07:40.484007192 -0700 @@ -152,7 +152,7 @@ struct msi_desc { __u16 tail; }link; - unsigned long mask_base; + void __iomem *mask_base; struct pci_dev *dev; }; diff -puN drivers/pci/pci.c~bk-pci drivers/pci/pci.c --- 25/drivers/pci/pci.c~bk-pci 2004-10-01 20:07:40.224046712 -0700 +++ 25-akpm/drivers/pci/pci.c 2004-10-01 20:07:40.487006736 -0700 @@ -308,14 +308,12 @@ pci_set_power_state(struct pci_dev *dev, * (>= 64 bytes). */ int -pci_save_state(struct pci_dev *dev, u32 *buffer) +pci_save_state(struct pci_dev *dev) { int i; - if (buffer) { - /* XXX: 100% dword access ok here? */ - for (i = 0; i < 16; i++) - pci_read_config_dword(dev, i * 4,&buffer[i]); - } + /* XXX: 100% dword access ok here? */ + for (i = 0; i < 16; i++) + pci_read_config_dword(dev, i * 4,&dev->saved_config_space[i]); return 0; } @@ -326,27 +324,12 @@ pci_save_state(struct pci_dev *dev, u32 * */ int -pci_restore_state(struct pci_dev *dev, u32 *buffer) +pci_restore_state(struct pci_dev *dev) { int i; - if (buffer) { - for (i = 0; i < 16; i++) - pci_write_config_dword(dev,i * 4, buffer[i]); - } - /* - * otherwise, write the context information we know from bootup. - * This works around a problem where warm-booting from Windows - * combined with a D3(hot)->D0 transition causes PCI config - * header data to be forgotten. - */ - else { - for (i = 0; i < 6; i ++) - pci_write_config_dword(dev, - PCI_BASE_ADDRESS_0 + (i * 4), - dev->resource[i].start); - pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); - } + for (i = 0; i < 16; i++) + pci_write_config_dword(dev,i * 4, dev->saved_config_space[i]); return 0; } @@ -382,8 +365,13 @@ pci_enable_device_bars(struct pci_dev *d int pci_enable_device(struct pci_dev *dev) { + int err; + dev->is_enabled = 1; - return pci_enable_device_bars(dev, (1 << PCI_NUM_RESOURCES) - 1); + if ((err = pci_enable_device_bars(dev, (1 << PCI_NUM_RESOURCES) - 1))) + return err; + pci_fixup_device(pci_fixup_enable, dev); + return 0; } /** @@ -744,7 +732,7 @@ static int __devinit pci_init(void) { struct pci_dev *dev = NULL; - 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) { pci_fixup_device(pci_fixup_final, dev); } return 0; diff -puN drivers/pci/pci-driver.c~bk-pci drivers/pci/pci-driver.c --- 25/drivers/pci/pci-driver.c~bk-pci 2004-10-01 20:07:40.226046408 -0700 +++ 25-akpm/drivers/pci/pci-driver.c 2004-10-01 20:07:40.485007040 -0700 @@ -14,27 +14,6 @@ * Registration of PCI drivers and handling of hot-pluggable devices. */ -/** - * pci_match_one_device - Tell if a PCI device structure has a matching - * PCI device id structure - * @id: single PCI device id structure to match - * @dev: the PCI device structure to match against - * - * Returns the matching pci_device_id structure or %NULL if there is no match. - */ - -static inline const struct pci_device_id * -pci_match_one_device(const struct pci_device_id *id, const struct pci_dev *dev) -{ - if ((id->vendor == PCI_ANY_ID || id->vendor == dev->vendor) && - (id->device == PCI_ANY_ID || id->device == dev->device) && - (id->subvendor == PCI_ANY_ID || id->subvendor == dev->subsystem_vendor) && - (id->subdevice == PCI_ANY_ID || id->subdevice == dev->subsystem_device) && - !((id->class ^ dev->class) & id->class_mask)) - return id; - return NULL; -} - /* * Dynamic device IDs are disabled for !CONFIG_HOTPLUG */ @@ -291,6 +270,19 @@ static int pci_device_remove(struct devi drv->remove(pci_dev); pci_dev->driver = NULL; } + +#ifdef CONFIG_DEBUG_KERNEL + /* + * If the driver decides to stop using the device, it should + * call pci_disable_device(). + */ + 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; } @@ -317,7 +309,7 @@ static int pci_device_suspend(struct dev if (drv && drv->suspend) i = drv->suspend(pci_dev, dev_state); - pci_save_state(pci_dev, pci_dev->saved_config_space); + pci_save_state(pci_dev); return i; } @@ -329,7 +321,7 @@ static int pci_device_suspend(struct dev static void pci_default_resume(struct pci_dev *pci_dev) { /* restore the PCI config space */ - pci_restore_state(pci_dev, pci_dev->saved_config_space); + pci_restore_state(pci_dev); /* if the device was enabled before suspend, reenable */ if (pci_dev->is_enabled) pci_enable_device(pci_dev); @@ -513,16 +505,9 @@ static int pci_bus_match(struct device * */ struct pci_dev *pci_dev_get(struct pci_dev *dev) { - struct device *tmp; - - if (!dev) - return NULL; - - tmp = get_device(&dev->dev); - if (tmp) - return to_pci_dev(tmp); - else - return NULL; + if (dev) + get_device(&dev->dev); + return dev; } /** diff -puN drivers/pci/pci.h~bk-pci drivers/pci/pci.h --- 25/drivers/pci/pci.h~bk-pci 2004-10-01 20:07:40.228046104 -0700 +++ 25-akpm/drivers/pci/pci.h 2004-10-01 20:07:40.487006736 -0700 @@ -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, @@ -61,5 +63,27 @@ extern int pci_visit_dev(struct pci_visi /* 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 void pcie_rootport_aspm_quirk(struct pci_dev *pdev); extern struct device_attribute pci_dev_attrs[]; + +/** + * pci_match_one_device - Tell if a PCI device structure has a matching + * PCI device id structure + * @id: single PCI device id structure to match + * @dev: the PCI device structure to match against + * + * Returns the matching pci_device_id structure or %NULL if there is no match. + */ +static inline const struct pci_device_id * +pci_match_one_device(const struct pci_device_id *id, const struct pci_dev *dev) +{ + if ((id->vendor == PCI_ANY_ID || id->vendor == dev->vendor) && + (id->device == PCI_ANY_ID || id->device == dev->device) && + (id->subvendor == PCI_ANY_ID || id->subvendor == dev->subsystem_vendor) && + (id->subdevice == PCI_ANY_ID || id->subdevice == dev->subsystem_device) && + !((id->class ^ dev->class) & id->class_mask)) + return id; + return NULL; +} + diff -puN drivers/pci/pci.ids~bk-pci drivers/pci/pci.ids --- 25/drivers/pci/pci.ids~bk-pci 2004-10-01 20:07:40.230045800 -0700 +++ 25-akpm/drivers/pci/pci.ids 2004-10-01 20:07:40.494005672 -0700 @@ -8429,9 +8429,9 @@ 84e6 460GX - 82466GX Wide and fast PCI eXpander Bridge (WXB) 84ea 460GX - 84460GX AGP Bridge (GXB function 1) 8500 IXP4xx Family Network Processor (IXP420, 421, 422, 425 and IXC1100) - 9000 Intel IXP2000 Family Network Processor - 9001 Intel IXP2400 Network Processor - 9004 Intel IXP2800 Network Processor + 9000 IXP2000 Family Network Processor + 9001 IXP2400 Network Processor + 9004 IXP2800 Network Processor 9621 Integrated RAID 9622 Integrated RAID 9641 Integrated RAID @@ -8440,7 +8440,7 @@ # observed, and documented in Intel revision note; new mask of 1011:0026 b154 21154 PCI-to-PCI Bridge b555 21555 Non transparent PCI-to-PCI Bridge - 1331 0030 Radisys ENP-2611 + 1331 0030 ENP-2611 4c53 1050 CT7 mainboard 4c53 1051 CE7 mainboard e4bf 1000 CC8-1-BLUES diff -puN drivers/pci/pci-sysfs.c~bk-pci drivers/pci/pci-sysfs.c --- 25/drivers/pci/pci-sysfs.c~bk-pci 2004-10-01 20:07:40.232045496 -0700 +++ 25-akpm/drivers/pci/pci-sysfs.c 2004-10-01 20:07:40.486006888 -0700 @@ -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 + * (C) Copyright 2004 Silicon Graphics, Inc. Jesse Barnes * * 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,40 @@ pci_write_config(struct kobject *kobj, c 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; + + 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 +224,67 @@ static struct bin_attribute pcie_config_ .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; + 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_get_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) + pci_create_sysfs_dev_files(pdev); + + return 0; } + +__initcall(pci_sysfs_init); diff -puN drivers/pci/probe.c~bk-pci drivers/pci/probe.c --- 25/drivers/pci/probe.c~bk-pci 2004-10-01 20:07:40.234045192 -0700 +++ 25-akpm/drivers/pci/probe.c 2004-10-01 20:07:40.496005368 -0700 @@ -170,7 +170,7 @@ static void pci_read_bases(struct pci_de 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; @@ -750,6 +750,7 @@ unsigned int __devinit pci_do_scan_bus(s struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent, int bus, struct pci_ops *ops, void *sysdata) { + int error; struct pci_bus *b; struct device *dev; @@ -769,9 +770,7 @@ struct pci_bus * __devinit pci_scan_bus_ if (pci_find_bus(pci_domain_nr(b), bus)) { /* If we already got to this bus through a different bridge, ignore it */ DBG("PCI: Bus %02x already known\n", bus); - kfree(dev); - kfree(b); - return NULL; + goto err_out; } list_add_tail(&b->node, &pci_root_buses); @@ -779,15 +778,23 @@ struct pci_bus * __devinit pci_scan_bus_ dev->parent = parent; dev->release = pci_release_bus_bridge_dev; sprintf(dev->bus_id, "pci%04x:%02x", pci_domain_nr(b), bus); - device_register(dev); + error = device_register(dev); + if (error) + goto dev_reg_err; b->bridge = get_device(dev); b->class_dev.class = &pcibus_class; sprintf(b->class_dev.class_id, "%04x:%02x", pci_domain_nr(b), bus); - class_device_register(&b->class_dev); - class_device_create_file(&b->class_dev, &class_device_attr_cpuaffinity); - - sysfs_create_link(&b->class_dev.kobj, &b->bridge->kobj, "bridge"); + error = class_device_register(&b->class_dev); + if (error) + goto class_dev_reg_err; + error = class_device_create_file(&b->class_dev, &class_device_attr_cpuaffinity); + if (error) + goto class_dev_create_file_err; + + error = sysfs_create_link(&b->class_dev.kobj, &b->bridge->kobj, "bridge"); + if (error) + goto sys_create_link_err; b->number = b->secondary = bus; b->resource[0] = &ioport_resource; @@ -798,6 +805,19 @@ struct pci_bus * __devinit pci_scan_bus_ pci_bus_add_devices(b); return b; + +sys_create_link_err: + class_device_remove_file(&b->class_dev, &class_device_attr_cpuaffinity); +class_dev_create_file_err: + class_device_unregister(&b->class_dev); +class_dev_reg_err: + device_unregister(dev); +dev_reg_err: + list_del(&b->node); +err_out: + kfree(dev); + kfree(b); + return NULL; } EXPORT_SYMBOL(pci_scan_bus_parented); diff -puN drivers/pci/proc.c~bk-pci drivers/pci/proc.c --- 25/drivers/pci/proc.c~bk-pci 2004-10-01 20:07:40.235045040 -0700 +++ 25-akpm/drivers/pci/proc.c 2004-10-01 20:07:40.496005368 -0700 @@ -379,7 +379,7 @@ static struct seq_operations proc_bus_pc .show = show_device }; -struct proc_dir_entry *proc_bus_pci_dir; +static struct proc_dir_entry *proc_bus_pci_dir; int pci_proc_attach_device(struct pci_dev *dev) { @@ -599,7 +599,7 @@ static int __init pci_proc_init(void) if (entry) entry->proc_fops = &proc_bus_pci_dev_operations; proc_initialized = 1; - 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) { pci_proc_attach_device(dev); } legacy_proc_init(); @@ -612,6 +612,5 @@ __initcall(pci_proc_init); EXPORT_SYMBOL(pci_proc_attach_device); EXPORT_SYMBOL(pci_proc_attach_bus); EXPORT_SYMBOL(pci_proc_detach_bus); -EXPORT_SYMBOL(proc_bus_pci_dir); #endif diff -puN drivers/pci/quirks.c~bk-pci drivers/pci/quirks.c --- 25/drivers/pci/quirks.c~bk-pci 2004-10-01 20:07:40.236044888 -0700 +++ 25-akpm/drivers/pci/quirks.c 2004-10-01 20:07:40.499004912 -0700 @@ -18,6 +18,7 @@ #include #include #include +#include "pci.h" #undef DEBUG @@ -30,7 +31,7 @@ static void __devinit quirk_passive_rele /* We have to make sure a particular bit is set in the PIIX3 ISA bridge, so we have to go out and find it. */ - while ((d = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_0, d))) { + while ((d = pci_get_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_0, d))) { pci_read_config_byte(d, 0x82, &dlc); if (!(dlc & 1<<1)) { printk(KERN_ERR "PCI: PIIX3: Enabling Passive Release on %s\n", pci_name(d)); @@ -116,21 +117,21 @@ static void __devinit quirk_vialatency(s /* Ok we have a potential problem chipset here. Now see if we have a buggy southbridge */ - p = pci_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, NULL); + p = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, NULL); if (p!=NULL) { pci_read_config_byte(p, PCI_CLASS_REVISION, &rev); /* 0x40 - 0x4f == 686B, 0x10 - 0x2f == 686A; thanks Dan Hollis */ /* Check for buggy part revisions */ - if (rev < 0x40 || rev > 0x42) - return; + if (rev < 0x40 || rev > 0x42) + goto exit; } else { - p = pci_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231, NULL); + p = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231, NULL); if (p==NULL) /* No problem parts */ - return; + goto exit; pci_read_config_byte(p, PCI_CLASS_REVISION, &rev); /* Check for buggy part revisions */ if (rev < 0x10 || rev > 0x12) - return; + goto exit; } /* @@ -153,6 +154,8 @@ static void __devinit quirk_vialatency(s busarb |= (1<<4); pci_write_config_byte(dev, 0x76, busarb); printk(KERN_INFO "Applying VIA southbridge workaround.\n"); +exit: + pci_dev_put(p); } DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8363_0, quirk_vialatency ); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8371_1, quirk_vialatency ); @@ -491,9 +494,9 @@ static void __devinit quirk_via_irqpic(s pci_write_config_byte(dev, PCI_INTERRUPT_LINE, new_irq); } } -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_2, quirk_via_irqpic ); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_5, quirk_via_irqpic ); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_6, quirk_via_irqpic ); +DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_2, quirk_via_irqpic ); +DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_5, quirk_via_irqpic ); +DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_6, quirk_via_irqpic ); /* @@ -978,13 +981,105 @@ static void __init quirk_intel_ide_combi DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, quirk_intel_ide_combined ); #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 ); + +/* 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_bus_find_capability(pbus, dev->devfn, 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 ); static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, struct pci_fixup *end) @@ -992,7 +1087,7 @@ static void pci_do_fixups(struct pci_dev while (f < end) { if ((f->vendor == dev->vendor || f->vendor == (u16) PCI_ANY_ID) && (f->device == dev->device || f->device == (u16) PCI_ANY_ID)) { - pr_debug(KERN_INFO "PCI: Calling quirk %p for %s\n", f->hook, pci_name(dev)); + pr_debug("PCI: Calling quirk %p for %s\n", f->hook, pci_name(dev)); f->hook(dev); } f++; @@ -1003,6 +1098,9 @@ extern struct pci_fixup __start_pci_fixu extern struct pci_fixup __end_pci_fixups_header[]; extern struct pci_fixup __start_pci_fixups_final[]; extern struct pci_fixup __end_pci_fixups_final[]; +extern struct pci_fixup __start_pci_fixups_enable[]; +extern struct pci_fixup __end_pci_fixups_enable[]; + void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev) { @@ -1018,6 +1116,12 @@ void pci_fixup_device(enum pci_fixup_pas start = __start_pci_fixups_final; end = __end_pci_fixups_final; break; + + case pci_fixup_enable: + start = __start_pci_fixups_enable; + end = __end_pci_fixups_enable; + break; + default: /* stupid compiler warning, you would think with an enum... */ return; @@ -1025,4 +1129,5 @@ void pci_fixup_device(enum pci_fixup_pas pci_do_fixups(dev, start, end); } -EXPORT_SYMBOL(pciehp_msi_quirk); +EXPORT_SYMBOL(pcie_mch_quirk); +EXPORT_SYMBOL(pcie_rootport_aspm_quirk); diff -puN drivers/pci/remove.c~bk-pci drivers/pci/remove.c --- 25/drivers/pci/remove.c~bk-pci 2004-10-01 20:07:40.238044584 -0700 +++ 25-akpm/drivers/pci/remove.c 2004-10-01 20:07:40.499004912 -0700 @@ -16,6 +16,7 @@ static void pci_free_resources(struct pc 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_free_resources(struct pc 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 -puN /dev/null drivers/pci/rom.c --- /dev/null 2003-09-15 06:40:47.000000000 -0700 +++ 25-akpm/drivers/pci/rom.c 2004-10-01 20:07:40.500004760 -0700 @@ -0,0 +1,225 @@ +/* + * drivers/pci/rom.c + * + * (C) Copyright 2004 Jon Smirl + * (C) Copyright 2004 Silicon Graphics, Inc. Jesse Barnes + * + * PCI ROM access routines + * + */ + + +#include +#include +#include + +#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 -puN drivers/pci/search.c~bk-pci drivers/pci/search.c --- 25/drivers/pci/search.c~bk-pci 2004-10-01 20:07:40.239044432 -0700 +++ 25-akpm/drivers/pci/search.c 2004-10-01 20:07:40.501004608 -0700 @@ -1,16 +1,17 @@ /* * PCI searching functions. * - * Copyright 1993 -- 1997 Drew Eckhardt, Frederic Potter, - * David Mosberger-Tang - * Copyright 1997 -- 2000 Martin Mares - * Copyright 2003 -- Greg Kroah-Hartman + * Copyright (C) 1993 -- 1997 Drew Eckhardt, Frederic Potter, + * David Mosberger-Tang + * Copyright (C) 1997 -- 2000 Martin Mares + * Copyright (C) 2003 -- 2004 Greg Kroah-Hartman */ #include #include #include #include +#include "pci.h" spinlock_t pci_bus_lock = SPIN_LOCK_UNLOCKED; @@ -156,10 +157,11 @@ struct pci_dev * pci_get_slot(struct pci * the pci device returned by this function can disappear at any moment in * time. */ -struct pci_dev * -pci_find_subsys(unsigned int vendor, unsigned int device, - unsigned int ss_vendor, unsigned int ss_device, - const struct pci_dev *from) +static struct pci_dev * pci_find_subsys(unsigned int vendor, + unsigned int device, + unsigned int ss_vendor, + unsigned int ss_device, + const struct pci_dev *from) { struct list_head *n; struct pci_dev *dev; @@ -257,12 +259,6 @@ exit: * @from: Previous PCI device found in search, or %NULL for new search. * * Iterates through the list of known PCI devices. If a PCI device is - * found with a matching @vendor and @device, a pointer to its device structure is - * returned. Otherwise, %NULL is returned. - * A new search is initiated by passing %NULL to the @from argument. - * Otherwise if @from is not %NULL, searches continue from next device on the global list. - * - * Iterates through the list of known PCI devices. If a PCI device is * found with a matching @vendor and @device, the reference count to the * device is incremented and a pointer to its device structure is returned. * Otherwise, %NULL is returned. A new search is initiated by passing %NULL @@ -312,25 +308,26 @@ exit: return dev; } - /** - * pci_find_class - begin or continue searching for a PCI device by class + * pci_get_class - begin or continue searching for a PCI device by class * @class: search for a PCI device with this class designation * @from: Previous PCI device found in search, or %NULL for new search. * * Iterates through the list of known PCI devices. If a PCI device is - * found with a matching @class, a pointer to its device structure is - * returned. Otherwise, %NULL is returned. + * found with a matching @class, the reference count to the device is + * incremented and a pointer to its device structure is returned. + * Otherwise, %NULL is returned. * A new search is initiated by passing %NULL to the @from argument. * Otherwise if @from is not %NULL, searches continue from next device - * on the global list. + * on the global list. The reference count for @from is always decremented + * if it is not %NULL. */ -struct pci_dev * -pci_find_class(unsigned int class, const struct pci_dev *from) +struct pci_dev *pci_get_class(unsigned int class, struct pci_dev *from) { struct list_head *n; struct pci_dev *dev; + WARN_ON(in_interrupt()); spin_lock(&pci_bus_lock); n = from ? from->global_list.next : pci_devices.next; @@ -342,16 +339,50 @@ pci_find_class(unsigned int class, const } dev = NULL; exit: + pci_dev_put(from); + dev = pci_dev_get(dev); spin_unlock(&pci_bus_lock); return dev; } +/** + * pci_dev_present - Returns 1 if device matching the device list is present, 0 if not. + * @ids: A pointer to a null terminated list of struct pci_device_id structures + * that describe the type of PCI device the caller is trying to find. + * + * Obvious fact: You do not have a reference to any device that might be found + * by this function, so if that device is removed from the system right after + * this function is finished, the value will be stale. Use this function to + * find devices that are usually built into a system, or for a general hint as + * to if another device happens to be present at this specific moment in time. + */ +int pci_dev_present(const struct pci_device_id *ids) +{ + struct pci_dev *dev; + int found = 0; + + WARN_ON(in_interrupt()); + spin_lock(&pci_bus_lock); + while (ids->vendor || ids->subvendor || ids->class_mask) { + list_for_each_entry(dev, &pci_devices, global_list) { + if (pci_match_one_device(ids, dev)) { + found = 1; + goto exit; + } + } + ids++; + } +exit: + spin_unlock(&pci_bus_lock); + return found; +} +EXPORT_SYMBOL(pci_dev_present); + EXPORT_SYMBOL(pci_find_bus); -EXPORT_SYMBOL(pci_find_class); EXPORT_SYMBOL(pci_find_device); EXPORT_SYMBOL(pci_find_device_reverse); EXPORT_SYMBOL(pci_find_slot); -EXPORT_SYMBOL(pci_find_subsys); EXPORT_SYMBOL(pci_get_device); EXPORT_SYMBOL(pci_get_subsys); EXPORT_SYMBOL(pci_get_slot); +EXPORT_SYMBOL(pci_get_class); diff -puN drivers/pci/setup-bus.c~bk-pci drivers/pci/setup-bus.c --- 25/drivers/pci/setup-bus.c~bk-pci 2004-10-01 20:07:40.241044128 -0700 +++ 25-akpm/drivers/pci/setup-bus.c 2004-10-01 20:07:40.502004456 -0700 @@ -533,16 +533,16 @@ EXPORT_SYMBOL(pci_bus_assign_resources); void __init pci_assign_unassigned_resources(void) { - struct list_head *ln; + struct pci_bus *bus; /* Depth first, calculate sizes and alignments of all subordinate buses. */ - list_for_each(ln, &pci_root_buses) { - pci_bus_size_bridges(pci_bus_b(ln)); + list_for_each_entry(bus, &pci_root_buses, node) { + pci_bus_size_bridges(bus); } /* Depth last, allocate resources and update the hardware. */ - list_for_each(ln, &pci_root_buses) { - pci_bus_assign_resources(pci_bus_b(ln)); - pci_enable_bridges(pci_bus_b(ln)); + list_for_each_entry(bus, &pci_root_buses, node) { + pci_bus_assign_resources(bus); + pci_enable_bridges(bus); } } diff -puN drivers/pci/setup-irq.c~bk-pci drivers/pci/setup-irq.c --- 25/drivers/pci/setup-irq.c~bk-pci 2004-10-01 20:07:40.242043976 -0700 +++ 25-akpm/drivers/pci/setup-irq.c 2004-10-01 20:07:40.503004304 -0700 @@ -65,7 +65,7 @@ pci_fixup_irqs(u8 (*swizzle)(struct pci_ int (*map_irq)(struct pci_dev *, u8, u8)) { struct pci_dev *dev = NULL; - 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) { pdev_fixup_irq(dev, swizzle, map_irq); } } diff -puN drivers/pci/setup-res.c~bk-pci drivers/pci/setup-res.c --- 25/drivers/pci/setup-res.c~bk-pci 2004-10-01 20:07:40.243043824 -0700 +++ 25-akpm/drivers/pci/setup-res.c 2004-10-01 20:07:40.503004304 -0700 @@ -56,7 +56,7 @@ pci_update_resource(struct pci_dev *dev, 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 -puN drivers/pcmcia/yenta_socket.c~bk-pci drivers/pcmcia/yenta_socket.c --- 25/drivers/pcmcia/yenta_socket.c~bk-pci 2004-10-01 20:07:40.245043520 -0700 +++ 25-akpm/drivers/pcmcia/yenta_socket.c 2004-10-01 20:07:40.504004152 -0700 @@ -1023,9 +1023,9 @@ static int yenta_dev_suspend (struct pci socket->type->save_state(socket); /* FIXME: pci_save_state needs to have a better interface */ - pci_save_state(dev, socket->saved_state); - pci_read_config_dword(dev, 16*4, &socket->saved_state[16]); - pci_read_config_dword(dev, 17*4, &socket->saved_state[17]); + pci_save_state(dev); + pci_read_config_dword(dev, 16*4, &socket->saved_state[0]); + pci_read_config_dword(dev, 17*4, &socket->saved_state[1]); pci_set_power_state(dev, 3); } @@ -1040,9 +1040,9 @@ static int yenta_dev_resume (struct pci_ if (socket) { pci_set_power_state(dev, 0); /* FIXME: pci_restore_state needs to have a better interface */ - pci_restore_state(dev, socket->saved_state); - pci_write_config_dword(dev, 16*4, socket->saved_state[16]); - pci_write_config_dword(dev, 17*4, socket->saved_state[17]); + pci_restore_state(dev); + pci_write_config_dword(dev, 16*4, socket->saved_state[0]); + pci_write_config_dword(dev, 17*4, socket->saved_state[1]); if (socket->type && socket->type->restore_state) socket->type->restore_state(socket); diff -puN drivers/pcmcia/yenta_socket.h~bk-pci drivers/pcmcia/yenta_socket.h --- 25/drivers/pcmcia/yenta_socket.h~bk-pci 2004-10-01 20:07:40.246043368 -0700 +++ 25-akpm/drivers/pcmcia/yenta_socket.h 2004-10-01 20:07:40.504004152 -0700 @@ -120,7 +120,7 @@ struct yenta_socket { unsigned int private[8]; /* PCI saved state */ - u32 saved_state[18]; + u32 saved_state[2]; }; diff -puN drivers/pnp/system.c~bk-pci drivers/pnp/system.c --- 25/drivers/pnp/system.c~bk-pci 2004-10-01 20:07:40.247043216 -0700 +++ 25-akpm/drivers/pnp/system.c 2004-10-01 20:07:40.505004000 -0700 @@ -104,4 +104,8 @@ static int __init pnp_system_init(void) return pnp_register_driver(&system_pnp_driver); } -subsys_initcall(pnp_system_init); +/** + * Reserve motherboard resources after PCI claim BARs, + * but before PCI assign resources for uninitialized PCI devices + */ +fs_initcall(pnp_system_init); diff -puN drivers/scsi/eata.c~bk-pci drivers/scsi/eata.c --- 25/drivers/scsi/eata.c~bk-pci 2004-10-01 20:07:40.249042912 -0700 +++ 25-akpm/drivers/scsi/eata.c 2004-10-01 20:07:40.507003696 -0700 @@ -1005,7 +1005,7 @@ static struct pci_dev *get_pci_dev(unsig unsigned int addr; struct pci_dev *dev = NULL; - while((dev = pci_find_class(PCI_CLASS_STORAGE_SCSI << 8, dev))) { + while((dev = pci_get_class(PCI_CLASS_STORAGE_SCSI << 8, dev))) { addr = pci_resource_start (dev, 0); #if defined(DEBUG_PCI_DETECT) @@ -1013,6 +1013,11 @@ static struct pci_dev *get_pci_dev(unsig driver_name, dev->bus->number, dev->devfn, addr); #endif + /* we are in so much trouble for a pci hotplug system with this driver + * anyway, so doing this at least lets people unload the driver and not + * cause memory problems, but in general this is a bad thing to do (this + * driver needs to be converted to the proper PCI api someday... */ + pci_dev_put(dev); if (addr + PCI_BASE_ADDRESS_0 == port_base) return dev; } @@ -1027,7 +1032,7 @@ static void enable_pci_ports(void) { struct pci_dev *dev = NULL; - while((dev = pci_find_class(PCI_CLASS_STORAGE_SCSI << 8, dev))) { + while((dev = pci_get_class(PCI_CLASS_STORAGE_SCSI << 8, dev))) { #if defined(DEBUG_PCI_DETECT) printk("%s: enable_pci_ports, bus %d, devfn 0x%x.\n", @@ -1454,7 +1459,7 @@ static void add_pci_ports(void) { for (k = 0; k < MAX_PCI; k++) { - if (!(dev = pci_find_class(PCI_CLASS_STORAGE_SCSI << 8, dev))) break; + if (!(dev = pci_get_class(PCI_CLASS_STORAGE_SCSI << 8, dev))) break; if (pci_enable_device (dev)) { @@ -1478,6 +1483,7 @@ static void add_pci_ports(void) { addr + PCI_BASE_ADDRESS_0; } + pci_dev_put(dev); #endif /* end CONFIG_PCI */ return; diff -puN drivers/scsi/ipr.c~bk-pci drivers/scsi/ipr.c --- 25/drivers/scsi/ipr.c~bk-pci 2004-10-01 20:07:40.251042608 -0700 +++ 25-akpm/drivers/scsi/ipr.c 2004-10-01 20:07:40.512002936 -0700 @@ -4935,7 +4935,7 @@ static int ipr_reset_restore_cfg_space(s int rc; ENTER; - rc = pci_restore_state(ioa_cfg->pdev, ioa_cfg->pci_cfg_buf); + rc = pci_restore_state(ioa_cfg->pdev); if (rc != PCIBIOS_SUCCESSFUL) { ipr_cmd->ioasa.ioasc = cpu_to_be32(IPR_IOASC_PCI_ACCESS_ERROR); @@ -5749,7 +5749,7 @@ static int __devinit ipr_probe_ioa(struc } /* Save away PCI config space for use following IOA reset */ - rc = pci_save_state(pdev, ioa_cfg->pci_cfg_buf); + rc = pci_save_state(pdev); if (rc != PCIBIOS_SUCCESSFUL) { dev_err(&pdev->dev, "Failed to save PCI config space\n"); diff -puN drivers/scsi/ipr.h~bk-pci drivers/scsi/ipr.h --- 25/drivers/scsi/ipr.h~bk-pci 2004-10-01 20:07:40.253042304 -0700 +++ 25-akpm/drivers/scsi/ipr.h 2004-10-01 20:07:40.513002784 -0700 @@ -889,7 +889,6 @@ struct ipr_ioa_cfg { unsigned long ioa_mailbox; struct ipr_interrupts regs; - u32 pci_cfg_buf[64]; u16 saved_pcix_cmd_reg; u16 reset_retries; diff -puN drivers/scsi/megaraid/megaraid_mbox.c~bk-pci drivers/scsi/megaraid/megaraid_mbox.c --- 25/drivers/scsi/megaraid/megaraid_mbox.c~bk-pci 2004-10-01 20:07:40.255042000 -0700 +++ 25-akpm/drivers/scsi/megaraid/megaraid_mbox.c 2004-10-01 20:07:40.516002328 -0700 @@ -1554,12 +1554,12 @@ mbox_post_cmd(adapter_t *adapter, scb_t if (scb->dma_direction == PCI_DMA_TODEVICE) { if (!scb->scp->use_sg) { // sg list not used - pci_dma_sync_single(adapter->pdev, ccb->buf_dma_h, + pci_dma_sync_single_for_cpu(adapter->pdev, ccb->buf_dma_h, scb->scp->request_bufflen, PCI_DMA_TODEVICE); } else { - pci_dma_sync_sg(adapter->pdev, scb->scp->request_buffer, + pci_dma_sync_sg_for_cpu(adapter->pdev, scb->scp->request_buffer, scb->scp->use_sg, PCI_DMA_TODEVICE); } } @@ -2332,7 +2332,7 @@ megaraid_mbox_sync_scb(adapter_t *adapte case MRAID_DMA_WBUF: if (scb->dma_direction == PCI_DMA_FROMDEVICE) { - pci_dma_sync_single(adapter->pdev, + pci_dma_sync_single_for_cpu(adapter->pdev, ccb->buf_dma_h, scb->scp->request_bufflen, PCI_DMA_FROMDEVICE); @@ -2345,7 +2345,7 @@ megaraid_mbox_sync_scb(adapter_t *adapte case MRAID_DMA_WSG: if (scb->dma_direction == PCI_DMA_FROMDEVICE) { - pci_dma_sync_sg(adapter->pdev, + pci_dma_sync_sg_for_cpu(adapter->pdev, scb->scp->request_buffer, scb->scp->use_sg, PCI_DMA_FROMDEVICE); } diff -puN drivers/scsi/nsp32.c~bk-pci drivers/scsi/nsp32.c --- 25/drivers/scsi/nsp32.c~bk-pci 2004-10-01 20:07:40.257041696 -0700 +++ 25-akpm/drivers/scsi/nsp32.c 2004-10-01 20:07:40.518002024 -0700 @@ -3439,11 +3439,10 @@ static int nsp32_prom_read_bit(nsp32_hw_ static int nsp32_suspend(struct pci_dev *pdev, u32 state) { struct Scsi_Host *host = pci_get_drvdata(pdev); - nsp32_hw_data *data = (nsp32_hw_data *)host->hostdata; nsp32_msg(KERN_INFO, "pci-suspend: pdev=0x%p, state=%ld, slot=%s, host=0x%p", pdev, state, pci_name(pdev), host); - pci_save_state (pdev, data->PciState); + pci_save_state (pdev); pci_disable_device (pdev); pci_set_power_state(pdev, state); @@ -3461,7 +3460,7 @@ static int nsp32_resume(struct pci_dev * pci_set_power_state(pdev, 0); pci_enable_wake (pdev, 0, 0); - pci_restore_state (pdev, data->PciState); + pci_restore_state (pdev); reg = nsp32_read2(data->BaseAddress, INDEX_REG); diff -puN drivers/scsi/nsp32.h~bk-pci drivers/scsi/nsp32.h --- 25/drivers/scsi/nsp32.h~bk-pci 2004-10-01 20:07:40.258041544 -0700 +++ 25-akpm/drivers/scsi/nsp32.h 2004-10-01 20:07:40.519001872 -0700 @@ -605,9 +605,6 @@ typedef struct _nsp32_hw_data { unsigned char msginbuf [MSGINBUF_MAX]; /* megin buffer */ char msgin_len; /* msginbuf length */ -#ifdef CONFIG_PM - u32 PciState[16]; /* save PCI state to this area */ -#endif } nsp32_hw_data; /* diff -puN drivers/usb/core/hcd.h~bk-pci drivers/usb/core/hcd.h --- 25/drivers/usb/core/hcd.h~bk-pci 2004-10-01 20:07:40.260041240 -0700 +++ 25-akpm/drivers/usb/core/hcd.h 2004-10-01 20:07:40.521001568 -0700 @@ -81,7 +81,6 @@ struct usb_hcd { /* usb_bus.hcpriv point #ifdef CONFIG_PCI int region; /* pci region for regs */ - u32 pci_state [16]; /* for PM state save */ #endif #define HCD_BUFFER_POOLS 4 diff -puN drivers/usb/core/hcd-pci.c~bk-pci drivers/usb/core/hcd-pci.c --- 25/drivers/usb/core/hcd-pci.c~bk-pci 2004-10-01 20:07:40.261041088 -0700 +++ 25-akpm/drivers/usb/core/hcd-pci.c 2004-10-01 20:07:40.520001720 -0700 @@ -305,7 +305,7 @@ int usb_hcd_pci_suspend (struct pci_dev retval); else { hcd->state = HCD_STATE_SUSPENDED; - pci_save_state (dev, hcd->pci_state); + pci_save_state (dev); #ifdef CONFIG_USB_SUSPEND pci_enable_wake (dev, state, hcd->remote_wakeup); pci_enable_wake (dev, 4, hcd->remote_wakeup); @@ -365,7 +365,7 @@ int usb_hcd_pci_resume (struct pci_dev * return retval; } pci_set_master (dev); - pci_restore_state (dev, hcd->pci_state); + pci_restore_state (dev); #ifdef CONFIG_USB_SUSPEND pci_enable_wake (dev, dev->current_state, 0); pci_enable_wake (dev, 4, 0); diff -puN drivers/usb/gadget/goku_udc.c~bk-pci drivers/usb/gadget/goku_udc.c --- 25/drivers/usb/gadget/goku_udc.c~bk-pci 2004-10-01 20:07:40.263040784 -0700 +++ 25-akpm/drivers/usb/gadget/goku_udc.c 2004-10-01 20:07:40.522001416 -0700 @@ -1976,7 +1976,7 @@ static struct pci_driver goku_pci_driver static int __init init (void) { - return pci_module_init (&goku_pci_driver); + return pci_register_driver (&goku_pci_driver); } module_init (init); diff -puN drivers/usb/gadget/net2280.c~bk-pci drivers/usb/gadget/net2280.c --- 25/drivers/usb/gadget/net2280.c~bk-pci 2004-10-01 20:07:40.264040632 -0700 +++ 25-akpm/drivers/usb/gadget/net2280.c 2004-10-01 20:07:40.524001112 -0700 @@ -2935,7 +2935,7 @@ static int __init init (void) { if (!use_dma) use_dma_chaining = 0; - return pci_module_init (&net2280_pci_driver); + return pci_register_driver (&net2280_pci_driver); } module_init (init); diff -puN drivers/usb/host/ehci-hcd.c~bk-pci drivers/usb/host/ehci-hcd.c --- 25/drivers/usb/host/ehci-hcd.c~bk-pci 2004-10-01 20:07:40.266040328 -0700 +++ 25-akpm/drivers/usb/host/ehci-hcd.c 2004-10-01 20:07:40.525000960 -0700 @@ -1092,7 +1092,7 @@ static int __init init (void) sizeof (struct ehci_qh), sizeof (struct ehci_qtd), sizeof (struct ehci_itd), sizeof (struct ehci_sitd)); - return pci_module_init (&ehci_pci_driver); + return pci_register_driver (&ehci_pci_driver); } module_init (init); diff -puN drivers/usb/host/ohci-pci.c~bk-pci drivers/usb/host/ohci-pci.c --- 25/drivers/usb/host/ohci-pci.c~bk-pci 2004-10-01 20:07:40.267040176 -0700 +++ 25-akpm/drivers/usb/host/ohci-pci.c 2004-10-01 20:07:40.526000808 -0700 @@ -279,7 +279,7 @@ static int __init ohci_hcd_pci_init (voi pr_debug ("%s: block sizes: ed %Zd td %Zd\n", hcd_name, sizeof (struct ed), sizeof (struct td)); - return pci_module_init (&ohci_pci_driver); + return pci_register_driver (&ohci_pci_driver); } module_init (ohci_hcd_pci_init); diff -puN drivers/usb/host/uhci-hcd.c~bk-pci drivers/usb/host/uhci-hcd.c --- 25/drivers/usb/host/uhci-hcd.c~bk-pci 2004-10-01 20:07:40.269039872 -0700 +++ 25-akpm/drivers/usb/host/uhci-hcd.c 2004-10-01 20:07:40.528000504 -0700 @@ -2534,7 +2534,7 @@ static int __init uhci_hcd_init(void) if (!uhci_up_cachep) goto up_failed; - retval = pci_module_init(&uhci_pci_driver); + retval = pci_register_driver(&uhci_pci_driver); if (retval) goto init_failed; diff -puN drivers/video/i810/i810.h~bk-pci drivers/video/i810/i810.h --- 25/drivers/video/i810/i810.h~bk-pci 2004-10-01 20:07:40.270039720 -0700 +++ 25-akpm/drivers/video/i810/i810.h 2004-10-01 20:07:40.528000504 -0700 @@ -254,7 +254,6 @@ struct i810fb_par { drm_agp_t *drm_agp; atomic_t use_count; u32 pseudo_palette[17]; - u32 pci_state[16]; unsigned long mmio_start_phys; u8 *mmio_start_virtual; u32 pitch; diff -puN drivers/video/i810/i810_main.c~bk-pci drivers/video/i810/i810_main.c --- 25/drivers/video/i810/i810_main.c~bk-pci 2004-10-01 20:07:40.272039416 -0700 +++ 25-akpm/drivers/video/i810/i810_main.c 2004-10-01 20:07:40.530000200 -0700 @@ -1517,7 +1517,7 @@ static int i810fb_suspend(struct pci_dev par->drm_agp->unbind_memory(par->i810_gtt.i810_cursor_memory); pci_disable_device(dev); } - pci_save_state(dev, par->pci_state); + pci_save_state(dev); pci_set_power_state(dev, state); return 0; @@ -1531,7 +1531,7 @@ static int i810fb_resume(struct pci_dev if (par->cur_state == 0) return 0; - pci_restore_state(dev, par->pci_state); + pci_restore_state(dev); pci_set_power_state(dev, 0); pci_enable_device(dev); par->drm_agp->bind_memory(par->i810_gtt.i810_fb_memory, diff -puN include/asm-generic/vmlinux.lds.h~bk-pci include/asm-generic/vmlinux.lds.h --- 25/include/asm-generic/vmlinux.lds.h~bk-pci 2004-10-01 20:07:40.273039264 -0700 +++ 25-akpm/include/asm-generic/vmlinux.lds.h 2004-10-01 20:07:40.530000200 -0700 @@ -24,6 +24,9 @@ VMLINUX_SYMBOL(__start_pci_fixups_final) = .; \ *(.pci_fixup_final) \ VMLINUX_SYMBOL(__end_pci_fixups_final) = .; \ + VMLINUX_SYMBOL(__start_pci_fixups_enable) = .; \ + *(.pci_fixup_enable) \ + VMLINUX_SYMBOL(__end_pci_fixups_enable) = .; \ } \ \ /* Kernel symbol table: Normal symbols */ \ diff -puN include/asm-ppc64/pci-bridge.h~bk-pci include/asm-ppc64/pci-bridge.h --- 25/include/asm-ppc64/pci-bridge.h~bk-pci 2004-10-01 20:07:40.274039112 -0700 +++ 25-akpm/include/asm-ppc64/pci-bridge.h 2004-10-01 20:07:40.531000048 -0700 @@ -34,6 +34,7 @@ struct pci_controller { char what[8]; /* Eye catcher */ enum phb_types type; /* Type of hardware */ struct pci_bus *bus; + char is_dynamic; void *arch_data; struct list_head list_node; @@ -47,6 +48,7 @@ struct pci_controller { * the PCI memory space in the CPU bus space */ unsigned long pci_mem_offset; + unsigned long pci_io_size; struct pci_ops *ops; volatile unsigned int *cfg_addr; @@ -88,7 +90,9 @@ static inline struct device_node *pci_de } extern void pci_process_bridge_OF_ranges(struct pci_controller *hose, - struct device_node *dev, int primary); + struct device_node *dev); + +extern int pcibios_remove_root_bus(struct pci_controller *phb); /* Use this macro after the PCI bus walk for max performance when it * is known that sysdata is correct. diff -puN include/asm-ppc64/pci.h~bk-pci include/asm-ppc64/pci.h --- 25/include/asm-ppc64/pci.h~bk-pci 2004-10-01 20:07:40.276038808 -0700 +++ 25-akpm/include/asm-ppc64/pci.h 2004-10-01 20:07:40.531000048 -0700 @@ -229,6 +229,8 @@ remap_bus_range(struct pci_bus *bus); extern void pcibios_fixup_device_resources(struct pci_dev *dev, struct pci_bus *bus); +extern struct pci_controller *init_phb_dynamic(struct device_node *dn); + extern int pci_read_irq_line(struct pci_dev *dev); extern void pcibios_add_platform_entries(struct pci_dev *dev); diff -puN include/linux/ioport.h~bk-pci include/linux/ioport.h --- 25/include/linux/ioport.h~bk-pci 2004-10-01 20:07:40.277038656 -0700 +++ 25-akpm/include/linux/ioport.h 2004-10-01 20:07:40.531999896 -0700 @@ -82,6 +82,11 @@ struct resource_list { #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 -puN include/linux/pci.h~bk-pci include/linux/pci.h --- 25/include/linux/pci.h~bk-pci 2004-10-01 20:07:40.278038504 -0700 +++ 25-akpm/include/linux/pci.h 2004-10-01 20:07:40.535999288 -0700 @@ -1,5 +1,5 @@ /* - * $Id: pci.h,v 1.87 1998/10/11 15:13:12 mj Exp $ + * pci.h * * PCI defines and function prototypes * Copyright 1994, Drew Eckhardt @@ -537,6 +537,7 @@ struct pci_dev { 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 */ #ifdef CONFIG_PCI_NAMES #define PCI_NAME_SIZE 96 #define PCI_NAME_HALF __stringify(43) /* less than half to handle slop */ @@ -721,10 +722,6 @@ extern void pci_remove_bus_device(struct struct pci_dev *pci_find_device (unsigned int vendor, unsigned int device, const struct pci_dev *from); struct pci_dev *pci_find_device_reverse (unsigned int vendor, unsigned int device, const struct pci_dev *from); -struct pci_dev *pci_find_subsys (unsigned int vendor, unsigned int device, - unsigned int ss_vendor, unsigned int ss_device, - const struct pci_dev *from); -struct pci_dev *pci_find_class (unsigned int class, const struct pci_dev *from); struct pci_dev *pci_find_slot (unsigned int bus, unsigned int devfn); int pci_find_capability (struct pci_dev *dev, int cap); int pci_find_ext_capability (struct pci_dev *dev, int cap); @@ -735,6 +732,8 @@ struct pci_dev *pci_get_subsys (unsigned unsigned int ss_vendor, unsigned int ss_device, struct pci_dev *from); struct pci_dev *pci_get_slot (struct pci_bus *bus, unsigned int devfn); +struct pci_dev *pci_get_class (unsigned int class, struct pci_dev *from); +int pci_dev_present(const struct pci_device_id *ids); int pci_bus_read_config_byte (struct pci_bus *bus, unsigned int devfn, int where, u8 *val); int pci_bus_read_config_word (struct pci_bus *bus, unsigned int devfn, int where, u16 *val); @@ -780,9 +779,15 @@ int pci_dac_set_dma_mask(struct pci_dev 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, u32 *buffer); -int pci_restore_state(struct pci_dev *dev, u32 *buffer); +int pci_save_state(struct pci_dev *dev); +int pci_restore_state(struct pci_dev *dev); int pci_set_power_state(struct pci_dev *dev, int state); int pci_enable_wake(struct pci_dev *dev, u32 state, int enable); @@ -862,10 +867,6 @@ extern void msi_remove_pci_irq_vectors(s #include -/* Backwards compat, remove in 2.7.x */ -#define pci_dma_sync_single pci_dma_sync_single_for_cpu -#define pci_dma_sync_sg pci_dma_sync_sg_for_cpu - /* * If the system does not have PCI, clearly these return errors. Define * these as simple inline functions to avoid hair in drivers. @@ -884,16 +885,9 @@ _PCI_NOP_ALL(write,) static inline struct pci_dev *pci_find_device(unsigned int vendor, unsigned int device, const struct pci_dev *from) { return NULL; } -static inline struct pci_dev *pci_find_class(unsigned int class, const struct pci_dev *from) -{ return NULL; } - static inline struct pci_dev *pci_find_slot(unsigned int bus, unsigned int devfn) { return NULL; } -static inline struct pci_dev *pci_find_subsys(unsigned int vendor, unsigned int device, -unsigned int ss_vendor, unsigned int ss_device, const struct pci_dev *from) -{ return NULL; } - static inline struct pci_dev *pci_get_device (unsigned int vendor, unsigned int device, struct pci_dev *from) { return NULL; } @@ -901,6 +895,11 @@ static inline struct pci_dev *pci_get_su unsigned int ss_vendor, unsigned int ss_device, struct pci_dev *from) { return NULL; } +static inline struct pci_dev *pci_get_class(unsigned int class, struct pci_dev *from) +{ return NULL; } +static inline int pci_dev_present(const struct pci_device_id *ids) +{ return 0; } + static inline void pci_set_master(struct pci_dev *dev) { } static inline int pci_enable_device(struct pci_dev *dev) { return -EIO; } static inline void pci_disable_device(struct pci_dev *dev) { } @@ -915,8 +914,8 @@ static inline int pci_find_ext_capabilit static inline const struct pci_device_id *pci_match_device(const struct pci_device_id *ids, const struct pci_dev *dev) { return NULL; } /* Power management related routines */ -static inline int pci_save_state(struct pci_dev *dev, u32 *buffer) { return 0; } -static inline int pci_restore_state(struct pci_dev *dev, u32 *buffer) { return 0; } +static inline int pci_save_state(struct pci_dev *dev) { return 0; } +static inline int pci_restore_state(struct pci_dev *dev) { return 0; } static inline int pci_set_power_state(struct pci_dev *dev, int state) { return 0; } static inline int pci_enable_wake(struct pci_dev *dev, u32 state, int enable) { return 0; } @@ -1010,6 +1009,7 @@ struct pci_fixup { enum pci_fixup_pass { pci_fixup_header, /* Called immediately after reading configuration header */ pci_fixup_final, /* Final phase of device fixups */ + pci_fixup_enable, /* pci_enable_device() time */ }; /* Anonymous variables would be nice... */ @@ -1023,6 +1023,12 @@ enum pci_fixup_pass { __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 }; + + void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev); extern int pci_pci_problems; diff -puN include/linux/pci_ids.h~bk-pci include/linux/pci_ids.h --- 25/include/linux/pci_ids.h~bk-pci 2004-10-01 20:07:40.280038200 -0700 +++ 25-akpm/include/linux/pci_ids.h 2004-10-01 20:07:40.537998984 -0700 @@ -2204,7 +2204,15 @@ #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 #define PCI_DEVICE_ID_INTEL_82371SB_1 0x7010 diff -puN sound/core/init.c~bk-pci sound/core/init.c --- 25/sound/core/init.c~bk-pci 2004-10-01 20:07:40.282037896 -0700 +++ 25-akpm/sound/core/init.c 2004-10-01 20:07:40.538998832 -0700 @@ -801,7 +801,7 @@ int snd_card_pci_resume(struct pci_dev * if (card->power_state == SNDRV_CTL_POWER_D0) return 0; /* restore the PCI config space */ - pci_restore_state(dev, dev->saved_config_space); + pci_restore_state(dev); /* FIXME: correct state value? */ return card->pm_resume(card, 0); } diff -puN sound/oss/ali5455.c~bk-pci sound/oss/ali5455.c --- 25/sound/oss/ali5455.c~bk-pci 2004-10-01 20:07:40.284037592 -0700 +++ 25-akpm/sound/oss/ali5455.c 2004-10-01 20:07:40.541998376 -0700 @@ -311,7 +311,6 @@ struct ali_card { u16 pci_id; #ifdef CONFIG_PM u16 pm_suspended; - u32 pm_save_state[64 / sizeof(u32)]; int pm_saved_mixer_settings[SOUND_MIXER_NRDEVICES][NR_AC97]; #endif /* soundcore stuff */ @@ -3576,7 +3575,7 @@ static int ali_pm_suspend(struct pci_dev } } } - pci_save_state(dev, card->pm_save_state); /* XXX do we need this? */ + pci_save_state(dev); /* XXX do we need this? */ pci_disable_device(dev); /* disable busmastering */ pci_set_power_state(dev, 3); /* Zzz. */ return 0; @@ -3588,7 +3587,7 @@ static int ali_pm_resume(struct pci_dev int num_ac97, i = 0; struct ali_card *card = pci_get_drvdata(dev); pci_enable_device(dev); - pci_restore_state(dev, card->pm_save_state); + pci_restore_state(dev); /* observation of a toshiba portege 3440ct suggests that the hardware has to be more or less completely reinitialized from scratch after an apm suspend. Works For Me. -dan */ diff -puN sound/oss/i810_audio.c~bk-pci sound/oss/i810_audio.c --- 25/sound/oss/i810_audio.c~bk-pci 2004-10-01 20:07:40.285037440 -0700 +++ 25-akpm/sound/oss/i810_audio.c 2004-10-01 20:07:40.543998072 -0700 @@ -406,7 +406,6 @@ struct i810_card { u16 pci_id_internal; /* used to access card_cap[] */ #ifdef CONFIG_PM u16 pm_suspended; - u32 pm_save_state[64/sizeof(u32)]; int pm_saved_mixer_settings[SOUND_MIXER_NRDEVICES][NR_AC97]; #endif /* soundcore stuff */ @@ -3385,7 +3384,7 @@ static int i810_pm_suspend(struct pci_de } } } - pci_save_state(dev,card->pm_save_state); /* XXX do we need this? */ + pci_save_state(dev); /* XXX do we need this? */ pci_disable_device(dev); /* disable busmastering */ pci_set_power_state(dev,3); /* Zzz. */ @@ -3398,7 +3397,7 @@ static int i810_pm_resume(struct pci_dev int num_ac97,i=0; struct i810_card *card=pci_get_drvdata(dev); pci_enable_device(dev); - pci_restore_state (dev,card->pm_save_state); + pci_restore_state (dev); /* observation of a toshiba portege 3440ct suggests that the hardware has to be more or less completely reinitialized from _