···10301030 irqmask=0xMMMM [IA-32] Set a bit mask of IRQs allowed to be assigned10311031 automatically to PCI devices. You can make the kernel10321032 exclude IRQs of your ISA cards this way.10331033+ pirqaddr=0xAAAAA [IA-32] Specify the physical address10341034+ of the PIRQ table (normally generated10351035+ by the BIOS) if it is outside the10361036+ F0000h-100000h range.10331037 lastbus=N [IA-32] Scan all buses till bus #N. Can be useful10341038 if the kernel is unable to find your secondary buses10351039 and you want to tell it explicitly which ones they are.
+49-8
arch/i386/kernel/acpi/boot.c
···159159#endif160160161161#ifdef CONFIG_PCI_MMCONFIG162162-static int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size)162162+/* The physical address of the MMCONFIG aperture. Set from ACPI tables. */163163+struct acpi_table_mcfg_config *pci_mmcfg_config;164164+int pci_mmcfg_config_num;165165+166166+int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size)163167{164168 struct acpi_table_mcfg *mcfg;169169+ unsigned long i;170170+ int config_size;165171166172 if (!phys_addr || !size)167173 return -EINVAL;···178172 return -ENODEV;179173 }180174181181- if (mcfg->base_reserved) {182182- printk(KERN_ERR PREFIX "MMCONFIG not in low 4GB of memory\n");175175+ /* how many config structures do we have */176176+ pci_mmcfg_config_num = 0;177177+ i = size - sizeof(struct acpi_table_mcfg);178178+ while (i >= sizeof(struct acpi_table_mcfg_config)) {179179+ ++pci_mmcfg_config_num;180180+ i -= sizeof(struct acpi_table_mcfg_config);181181+ };182182+ if (pci_mmcfg_config_num == 0) {183183+ printk(KERN_ERR PREFIX "MMCONFIG has no entries\n");183184 return -ENODEV;184185 }185186186186- pci_mmcfg_base_addr = mcfg->base_address;187187+ config_size = pci_mmcfg_config_num * sizeof(*pci_mmcfg_config);188188+ pci_mmcfg_config = kmalloc(config_size, GFP_KERNEL);189189+ if (!pci_mmcfg_config) {190190+ printk(KERN_WARNING PREFIX191191+ "No memory for MCFG config tables\n");192192+ return -ENOMEM;193193+ }194194+195195+ memcpy(pci_mmcfg_config, &mcfg->config, config_size);196196+ for (i = 0; i < pci_mmcfg_config_num; ++i) {197197+ if (mcfg->config[i].base_reserved) {198198+ printk(KERN_ERR PREFIX199199+ "MMCONFIG not in low 4GB of memory\n");200200+ return -ENODEV;201201+ }202202+ }187203188204 return 0;189205}190190-#else191191-#define acpi_parse_mcfg NULL192192-#endif /* !CONFIG_PCI_MMCONFIG */206206+#endif /* CONFIG_PCI_MMCONFIG */193207194208#ifdef CONFIG_X86_LOCAL_APIC195209static int __init···532506}533507EXPORT_SYMBOL(acpi_unmap_lsapic);534508#endif /* CONFIG_ACPI_HOTPLUG_CPU */509509+510510+int511511+acpi_register_ioapic(acpi_handle handle, u64 phys_addr, u32 gsi_base)512512+{513513+ /* TBD */514514+ return -EINVAL;515515+}516516+EXPORT_SYMBOL(acpi_register_ioapic);517517+518518+int519519+acpi_unregister_ioapic(acpi_handle handle, u32 gsi_base)520520+{521521+ /* TBD */522522+ return -EINVAL;523523+}524524+EXPORT_SYMBOL(acpi_unregister_ioapic);535525536526static unsigned long __init537527acpi_scan_rsdp (···11651123 acpi_process_madt();1166112411671125 acpi_table_parse(ACPI_HPET, acpi_parse_hpet);11681168- acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg);1169112611701127 return 0;11711128}
···11111212#include <linux/pci.h>1313#include <linux/init.h>1414+#include <linux/acpi.h>1415#include "pci.h"1515-1616-/* The physical address of the MMCONFIG aperture. Set from ACPI tables. */1717-u32 pci_mmcfg_base_addr;18161917#define mmcfg_virt_addr ((void __iomem *) fix_to_virt(FIX_PCIE_MCFG))2018···2224/*2325 * Functions for accessing PCI configuration space with MMCONFIG accesses2426 */2525-2626-static inline void pci_exp_set_dev_base(int bus, int devfn)2727+static u32 get_base_addr(unsigned int seg, int bus)2728{2828- u32 dev_base = pci_mmcfg_base_addr | (bus << 20) | (devfn << 12);2929+ int cfg_num = -1;3030+ struct acpi_table_mcfg_config *cfg;3131+3232+ while (1) {3333+ ++cfg_num;3434+ if (cfg_num >= pci_mmcfg_config_num) {3535+ /* something bad is going on, no cfg table is found. */3636+ /* so we fall back to the old way we used to do this */3737+ /* and just rely on the first entry to be correct. */3838+ return pci_mmcfg_config[0].base_address;3939+ }4040+ cfg = &pci_mmcfg_config[cfg_num];4141+ if (cfg->pci_segment_group_number != seg)4242+ continue;4343+ if ((cfg->start_bus_number <= bus) &&4444+ (cfg->end_bus_number >= bus))4545+ return cfg->base_address;4646+ }4747+}4848+4949+static inline void pci_exp_set_dev_base(unsigned int seg, int bus, int devfn)5050+{5151+ u32 dev_base = get_base_addr(seg, bus) | (bus << 20) | (devfn << 12);2952 if (dev_base != mmcfg_last_accessed_device) {3053 mmcfg_last_accessed_device = dev_base;3154 set_fixmap_nocache(FIX_PCIE_MCFG, dev_base);···63446445 spin_lock_irqsave(&pci_config_lock, flags);65466666- pci_exp_set_dev_base(bus, devfn);4747+ pci_exp_set_dev_base(seg, bus, devfn);67486849 switch (len) {6950 case 1:···92739374 spin_lock_irqsave(&pci_config_lock, flags);94759595- pci_exp_set_dev_base(bus, devfn);7676+ pci_exp_set_dev_base(seg, bus, devfn);96779778 switch (len) {9879 case 1:···120101{121102 if ((pci_probe & PCI_PROBE_MMCONF) == 0)122103 goto out;123123- if (!pci_mmcfg_base_addr)104104+105105+ acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg);106106+ if ((pci_mmcfg_config_num == 0) ||107107+ (pci_mmcfg_config == NULL) ||108108+ (pci_mmcfg_config[0].base_address == 0))124109 goto out;125110126111 /* Kludge for now. Don't use mmconfig on AMD systems because
+2
arch/i386/pci/numa.c
···115115 return 0;116116117117 pci_root_bus = pcibios_scan_root(0);118118+ if (pci_root_bus)119119+ pci_bus_add_devices(pci_root_bus);118120 if (num_online_nodes() > 1)119121 for_each_online_node(quad) {120122 if (quad == 0)
+1
arch/i386/pci/pci.h
···2727#define PCI_ASSIGN_ALL_BUSSES 0x400028282929extern unsigned int pci_probe;3030+extern unsigned long pirq_table_addr;30313132/* pci-i386.c */3233
···129129 char __iomem *addr; /* base address of IOSAPIC */130130 unsigned int gsi_base; /* first GSI assigned to this IOSAPIC */131131 unsigned short num_rte; /* number of RTE in this IOSAPIC */132132+ int rtes_inuse; /* # of RTEs in use on this IOSAPIC */132133#ifdef CONFIG_NUMA133134 unsigned short node; /* numa node association via pxm */134135#endif135136} iosapic_lists[NR_IOSAPICS];136137137137-static int num_iosapic;138138-139139-static unsigned char pcat_compat __initdata; /* 8259 compatibility flag */138138+static unsigned char pcat_compat __devinitdata; /* 8259 compatibility flag */140139141140static int iosapic_kmalloc_ok;142141static LIST_HEAD(free_rte_list);···148149{149150 int i;150151151151- for (i = 0; i < num_iosapic; i++) {152152+ for (i = 0; i < NR_IOSAPICS; i++) {152153 if ((unsigned) (gsi - iosapic_lists[i].gsi_base) < iosapic_lists[i].num_rte)153154 return i;154155 }···597598 rte->refcnt++;598599 list_add_tail(&rte->rte_list, &iosapic_intr_info[vector].rtes);599600 iosapic_intr_info[vector].count++;601601+ iosapic_lists[index].rtes_inuse++;600602 }601603 else if (vector_is_shared(vector)) {602604 struct iosapic_intr_info *info = &iosapic_intr_info[vector];···778778iosapic_unregister_intr (unsigned int gsi)779779{780780 unsigned long flags;781781- int irq, vector;781781+ int irq, vector, index;782782 irq_desc_t *idesc;783783 u32 low32;784784 unsigned long trigger, polarity;···819819 list_del(&rte->rte_list);820820 iosapic_intr_info[vector].count--;821821 iosapic_free_rte(rte);822822+ index = find_iosapic(gsi);823823+ iosapic_lists[index].rtes_inuse--;824824+ WARN_ON(iosapic_lists[index].rtes_inuse < 0);822825823826 trigger = iosapic_intr_info[vector].trigger;824827 polarity = iosapic_intr_info[vector].polarity;···955952 }956953}957954958958-void __init955955+static inline int956956+iosapic_alloc (void)957957+{958958+ int index;959959+960960+ for (index = 0; index < NR_IOSAPICS; index++)961961+ if (!iosapic_lists[index].addr)962962+ return index;963963+964964+ printk(KERN_WARNING "%s: failed to allocate iosapic\n", __FUNCTION__);965965+ return -1;966966+}967967+968968+static inline void969969+iosapic_free (int index)970970+{971971+ memset(&iosapic_lists[index], 0, sizeof(iosapic_lists[0]));972972+}973973+974974+static inline int975975+iosapic_check_gsi_range (unsigned int gsi_base, unsigned int ver)976976+{977977+ int index;978978+ unsigned int gsi_end, base, end;979979+980980+ /* check gsi range */981981+ gsi_end = gsi_base + ((ver >> 16) & 0xff);982982+ for (index = 0; index < NR_IOSAPICS; index++) {983983+ if (!iosapic_lists[index].addr)984984+ continue;985985+986986+ base = iosapic_lists[index].gsi_base;987987+ end = base + iosapic_lists[index].num_rte - 1;988988+989989+ if (gsi_base < base && gsi_end < base)990990+ continue;/* OK */991991+992992+ if (gsi_base > end && gsi_end > end)993993+ continue; /* OK */994994+995995+ return -EBUSY;996996+ }997997+ return 0;998998+}999999+10001000+int __devinit9591001iosapic_init (unsigned long phys_addr, unsigned int gsi_base)9601002{961961- int num_rte;10031003+ int num_rte, err, index;9621004 unsigned int isa_irq, ver;9631005 char __iomem *addr;10061006+ unsigned long flags;9641007965965- addr = ioremap(phys_addr, 0);966966- ver = iosapic_version(addr);10081008+ spin_lock_irqsave(&iosapic_lock, flags);10091009+ {10101010+ addr = ioremap(phys_addr, 0);10111011+ ver = iosapic_version(addr);9671012968968- /*969969- * The MAX_REDIR register holds the highest input pin970970- * number (starting from 0).971971- * We add 1 so that we can use it for number of pins (= RTEs)972972- */973973- num_rte = ((ver >> 16) & 0xff) + 1;10131013+ if ((err = iosapic_check_gsi_range(gsi_base, ver))) {10141014+ iounmap(addr);10151015+ spin_unlock_irqrestore(&iosapic_lock, flags);10161016+ return err;10171017+ }9741018975975- iosapic_lists[num_iosapic].addr = addr;976976- iosapic_lists[num_iosapic].gsi_base = gsi_base;977977- iosapic_lists[num_iosapic].num_rte = num_rte;10191019+ /*10201020+ * The MAX_REDIR register holds the highest input pin10211021+ * number (starting from 0).10221022+ * We add 1 so that we can use it for number of pins (= RTEs)10231023+ */10241024+ num_rte = ((ver >> 16) & 0xff) + 1;10251025+10261026+ index = iosapic_alloc();10271027+ iosapic_lists[index].addr = addr;10281028+ iosapic_lists[index].gsi_base = gsi_base;10291029+ iosapic_lists[index].num_rte = num_rte;9781030#ifdef CONFIG_NUMA979979- iosapic_lists[num_iosapic].node = MAX_NUMNODES;10311031+ iosapic_lists[index].node = MAX_NUMNODES;9801032#endif981981- num_iosapic++;10331033+ }10341034+ spin_unlock_irqrestore(&iosapic_lock, flags);98210359831036 if ((gsi_base == 0) && pcat_compat) {9841037 /*···1045986 for (isa_irq = 0; isa_irq < 16; ++isa_irq)1046987 iosapic_override_isa_irq(isa_irq, isa_irq, IOSAPIC_POL_HIGH, IOSAPIC_EDGE);1047988 }989989+ return 0;1048990}1049991992992+#ifdef CONFIG_HOTPLUG993993+int994994+iosapic_remove (unsigned int gsi_base)995995+{996996+ int index, err = 0;997997+ unsigned long flags;998998+999999+ spin_lock_irqsave(&iosapic_lock, flags);10001000+ {10011001+ index = find_iosapic(gsi_base);10021002+ if (index < 0) {10031003+ printk(KERN_WARNING "%s: No IOSAPIC for GSI base %u\n",10041004+ __FUNCTION__, gsi_base);10051005+ goto out;10061006+ }10071007+10081008+ if (iosapic_lists[index].rtes_inuse) {10091009+ err = -EBUSY;10101010+ printk(KERN_WARNING "%s: IOSAPIC for GSI base %u is busy\n",10111011+ __FUNCTION__, gsi_base);10121012+ goto out;10131013+ }10141014+10151015+ iounmap(iosapic_lists[index].addr);10161016+ iosapic_free(index);10171017+ }10181018+ out:10191019+ spin_unlock_irqrestore(&iosapic_lock, flags);10201020+ return err;10211021+}10221022+#endif /* CONFIG_HOTPLUG */10231023+10501024#ifdef CONFIG_NUMA10511051-void __init10251025+void __devinit10521026map_iosapic_to_node(unsigned int gsi_base, int node)10531027{10541028 int index;
+33-5
arch/ia64/pci/pci.c
···312312 acpi_walk_resources(device->handle, METHOD_NAME__CRS, add_window,313313 &info);314314315315- pbus = pci_scan_bus(bus, &pci_root_ops, controller);315315+ pbus = pci_scan_bus_parented(NULL, bus, &pci_root_ops, controller);316316 if (pbus)317317 pcibios_setup_root_windows(pbus, controller);318318···373373 res->end = region->end + offset;374374}375375376376+static int __devinit is_valid_resource(struct pci_dev *dev, int idx)377377+{378378+ unsigned int i, type_mask = IORESOURCE_IO | IORESOURCE_MEM;379379+ struct resource *devr = &dev->resource[idx];380380+381381+ if (!dev->bus)382382+ return 0;383383+ for (i=0; i<PCI_BUS_NUM_RESOURCES; i++) {384384+ struct resource *busr = dev->bus->resource[i];385385+386386+ if (!busr || ((busr->flags ^ devr->flags) & type_mask))387387+ continue;388388+ if ((devr->start) && (devr->start >= busr->start) &&389389+ (devr->end <= busr->end))390390+ return 1;391391+ }392392+ return 0;393393+}394394+376395static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev)377396{378397 struct pci_bus_region region;···405386 region.start = dev->resource[i].start;406387 region.end = dev->resource[i].end;407388 pcibios_bus_to_resource(dev, &dev->resource[i], ®ion);408408- pci_claim_resource(dev, i);389389+ if ((is_valid_resource(dev, i)))390390+ pci_claim_resource(dev, i);409391 }410392}411393···418398{419399 struct pci_dev *dev;420400401401+ if (b->self) {402402+ pci_read_bridge_bases(b);403403+ pcibios_fixup_device_resources(b->self);404404+ }421405 list_for_each_entry(dev, &b->devices, bus_list)422406 pcibios_fixup_device_resources(dev);423407···442418 u16 cmd, old_cmd;443419 int idx;444420 struct resource *r;421421+ unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM;445422446423 if (!dev)447424 return -EINVAL;448425449426 pci_read_config_word(dev, PCI_COMMAND, &cmd);450427 old_cmd = cmd;451451- for (idx=0; idx<6; idx++) {428428+ for (idx=0; idx<PCI_NUM_RESOURCES; idx++) {452429 /* Only set up the desired resources. */453430 if (!(mask & (1 << idx)))454431 continue;455432456433 r = &dev->resource[idx];434434+ if (!(r->flags & type_mask))435435+ continue;436436+ if ((idx == PCI_ROM_RESOURCE) &&437437+ (!(r->flags & IORESOURCE_ROM_ENABLE)))438438+ continue;457439 if (!r->start && r->end) {458440 printk(KERN_ERR459441 "PCI: Device %s not available because of resource collisions\n",···471441 if (r->flags & IORESOURCE_MEM)472442 cmd |= PCI_COMMAND_MEMORY;473443 }474474- if (dev->resource[PCI_ROM_RESOURCE].start)475475- cmd |= PCI_COMMAND_MEMORY;476444 if (cmd != old_cmd) {477445 printk("PCI: Enabling device %s (%04x -> %04x)\n", pci_name(dev), old_cmd, cmd);478446 pci_write_config_word(dev, PCI_COMMAND, cmd);
···7788#include <linux/pci.h>99#include <linux/init.h>1010+#include <linux/acpi.h>1011#include "pci.h"11121213#define MMCONFIG_APER_SIZE (256*1024*1024)13141414-/* The physical address of the MMCONFIG aperture. Set from ACPI tables. */1515-u32 pci_mmcfg_base_addr;1616-1715/* Static virtual mapping of the MMCONFIG aperture */1818-char *pci_mmcfg_virt;1616+struct mmcfg_virt {1717+ struct acpi_table_mcfg_config *cfg;1818+ char *virt;1919+};2020+static struct mmcfg_virt *pci_mmcfg_virt;19212020-static inline char *pci_dev_base(unsigned int bus, unsigned int devfn)2222+static char *get_virt(unsigned int seg, int bus)2123{2222- return pci_mmcfg_virt + ((bus << 20) | (devfn << 12));2424+ int cfg_num = -1;2525+ struct acpi_table_mcfg_config *cfg;2626+2727+ while (1) {2828+ ++cfg_num;2929+ if (cfg_num >= pci_mmcfg_config_num) {3030+ /* something bad is going on, no cfg table is found. */3131+ /* so we fall back to the old way we used to do this */3232+ /* and just rely on the first entry to be correct. */3333+ return pci_mmcfg_virt[0].virt;3434+ }3535+ cfg = pci_mmcfg_virt[cfg_num].cfg;3636+ if (cfg->pci_segment_group_number != seg)3737+ continue;3838+ if ((cfg->start_bus_number <= bus) &&3939+ (cfg->end_bus_number >= bus))4040+ return pci_mmcfg_virt[cfg_num].virt;4141+ }4242+}4343+4444+static inline char *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn)4545+{4646+4747+ return get_virt(seg, bus) + ((bus << 20) | (devfn << 12));2348}24492550static int pci_mmcfg_read(unsigned int seg, unsigned int bus,2651 unsigned int devfn, int reg, int len, u32 *value)2752{2828- char *addr = pci_dev_base(bus, devfn); 5353+ char *addr = pci_dev_base(seg, bus, devfn);29543055 if (unlikely(!value || (bus > 255) || (devfn > 255) || (reg > 4095)))3156 return -EINVAL;···7348static int pci_mmcfg_write(unsigned int seg, unsigned int bus,7449 unsigned int devfn, int reg, int len, u32 value)7550{7676- char *addr = pci_dev_base(bus,devfn);5151+ char *addr = pci_dev_base(seg, bus, devfn);77527853 if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095)))7954 return -EINVAL;···1007510176static int __init pci_mmcfg_init(void)10277{7878+ int i;7979+10380 if ((pci_probe & PCI_PROBE_MMCONF) == 0)10481 return 0;105105- if (!pci_mmcfg_base_addr)8282+8383+ acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg);8484+ if ((pci_mmcfg_config_num == 0) ||8585+ (pci_mmcfg_config == NULL) ||8686+ (pci_mmcfg_config[0].base_address == 0))10687 return 0;1078810889 /* Kludge for now. Don't use mmconfig on AMD systems because···11988 return 0; 1208912190 /* RED-PEN i386 doesn't do _nocache right now */122122- pci_mmcfg_virt = ioremap_nocache(pci_mmcfg_base_addr, MMCONFIG_APER_SIZE);123123- if (!pci_mmcfg_virt) { 124124- printk("PCI: Cannot map mmconfig aperture\n");9191+ pci_mmcfg_virt = kmalloc(sizeof(*pci_mmcfg_virt) * pci_mmcfg_config_num, GFP_KERNEL);9292+ if (pci_mmcfg_virt == NULL) {9393+ printk("PCI: Can not allocate memory for mmconfig structures\n");12594 return 0;126126- } 9595+ }9696+ for (i = 0; i < pci_mmcfg_config_num; ++i) {9797+ pci_mmcfg_virt[i].cfg = &pci_mmcfg_config[i];9898+ pci_mmcfg_virt[i].virt = ioremap_nocache(pci_mmcfg_config[i].base_address, MMCONFIG_APER_SIZE);9999+ if (!pci_mmcfg_virt[i].virt) {100100+ printk("PCI: Cannot map mmconfig aperture for segment %d\n",101101+ pci_mmcfg_config[i].pci_segment_group_number);102102+ return 0;103103+ }104104+ printk(KERN_INFO "PCI: Using MMCONFIG at %x\n", pci_mmcfg_config[i].base_address);105105+ }127106128128- printk(KERN_INFO "PCI: Using MMCONFIG at %x\n", pci_mmcfg_base_addr);129107 raw_pci_ops = &pci_mmcfg;130108 pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF;131109
+1-1
drivers/acpi/container.c
···153153 return_VALUE(-ENODEV);154154 }155155156156- result = acpi_bus_scan(*device);156156+ result = acpi_bus_start(*device);157157158158 return_VALUE(result);159159}
+20-7
drivers/acpi/pci_bind.c
···616162626363/**6464- * acpi_os_get_pci_id6464+ * acpi_get_pci_id6565 * ------------------6666 * This function is used by the ACPI Interpreter (a.k.a. Core Subsystem)6767 * to resolve PCI information for ACPI-PCI devices defined in the namespace.6868 * This typically occurs when resolving PCI operation region information.6969 */7070-#ifdef ACPI_FUTURE_USAGE7170acpi_status7272-acpi_os_get_pci_id (7171+acpi_get_pci_id (7372 acpi_handle handle,7473 struct acpi_pci_id *id)7574{···7778 struct acpi_device *device = NULL;7879 struct acpi_pci_data *data = NULL;79808080- ACPI_FUNCTION_TRACE("acpi_os_get_pci_id");8181+ ACPI_FUNCTION_TRACE("acpi_get_pci_id");81828283 if (!id)8384 return_ACPI_STATUS(AE_BAD_PARAMETER);···9192 }92939394 status = acpi_get_data(handle, acpi_pci_data_handler, (void**) &data);9494- if (ACPI_FAILURE(status) || !data || !data->dev) {9595+ if (ACPI_FAILURE(status) || !data) {9596 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 9697 "Invalid ACPI-PCI context for device %s\n",9798 acpi_device_bid(device)));···114115115116 return_ACPI_STATUS(AE_OK);116117}117117-#endif /* ACPI_FUTURE_USAGE */118118+EXPORT_SYMBOL(acpi_get_pci_id);118119119120120121int···128129 char *pathname = NULL;129130 struct acpi_buffer buffer = {0, NULL};130131 acpi_handle handle = NULL;132132+ struct pci_dev *dev;133133+ struct pci_bus *bus;131134132135 ACPI_FUNCTION_TRACE("acpi_pci_bind");133136···194193 * Locate matching device in PCI namespace. If it doesn't exist195194 * this typically means that the device isn't currently inserted196195 * (e.g. docking station, port replicator, etc.).196196+ * We cannot simply search the global pci device list, since197197+ * PCI devices are added to the global pci list when the root198198+ * bridge start ops are run, which may not have happened yet.197199 */198198- data->dev = pci_find_slot(data->id.bus, PCI_DEVFN(data->id.device, data->id.function));200200+ bus = pci_find_bus(data->id.segment, data->id.bus);201201+ if (bus) {202202+ list_for_each_entry(dev, &bus->devices, bus_list) {203203+ if (dev->devfn == PCI_DEVFN(data->id.device,204204+ data->id.function)) {205205+ data->dev = dev;206206+ break;207207+ }208208+ }209209+ }199210 if (!data->dev) {200211 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 201212 "Device %02x:%02x:%02x.%02x not present in PCI namespace\n",
+23-1
drivers/acpi/pci_root.c
···46464747static int acpi_pci_root_add (struct acpi_device *device);4848static int acpi_pci_root_remove (struct acpi_device *device, int type);4949+static int acpi_pci_root_start (struct acpi_device *device);49505051static struct acpi_driver acpi_pci_root_driver = {5152 .name = ACPI_PCI_ROOT_DRIVER_NAME,···5554 .ops = {5655 .add = acpi_pci_root_add,5756 .remove = acpi_pci_root_remove,5757+ .start = acpi_pci_root_start,5858 },5959};6060···171169 if (!root)172170 return_VALUE(-ENOMEM);173171 memset(root, 0, sizeof(struct acpi_pci_root));172172+ INIT_LIST_HEAD(&root->node);174173175174 root->handle = device->handle;176175 strcpy(acpi_device_name(device), ACPI_PCI_ROOT_DEVICE_NAME);···301298 root->id.bus);302299303300end:304304- if (result)301301+ if (result) {302302+ if (!list_empty(&root->node))303303+ list_del(&root->node);305304 kfree(root);305305+ }306306307307 return_VALUE(result);308308}309309310310+static int311311+acpi_pci_root_start (312312+ struct acpi_device *device)313313+{314314+ struct acpi_pci_root *root;315315+316316+ ACPI_FUNCTION_TRACE("acpi_pci_root_start");317317+318318+ list_for_each_entry(root, &acpi_pci_roots, node) {319319+ if (root->handle == device->handle) {320320+ pci_bus_add_devices(root->bus);321321+ return_VALUE(0);322322+ }323323+ }324324+ return_VALUE(-ENODEV);325325+}310326311327static int312328acpi_pci_root_remove (
+1-1
drivers/acpi/processor_core.c
···723723 return_VALUE(-ENODEV);724724 }725725726726- acpi_bus_scan(*device);726726+ acpi_bus_start(*device);727727728728 pr = acpi_driver_data(*device);729729 if (!pr)
+101-25
drivers/acpi/scan.c
···553553 * upon possible configuration and currently allocated resources.554554 */555555556556+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Driver successfully bound to device\n"));557557+ return_VALUE(0);558558+}559559+560560+int561561+acpi_start_single_object (562562+ struct acpi_device *device)563563+{564564+ int result = 0;565565+ struct acpi_driver *driver;566566+567567+ ACPI_FUNCTION_TRACE("acpi_start_single_object");568568+569569+ if (!(driver = device->driver))570570+ return_VALUE(0);571571+556572 if (driver->ops.start) {557573 result = driver->ops.start(device);558574 if (result && driver->ops.remove)559575 driver->ops.remove(device, ACPI_BUS_REMOVAL_NORMAL);560560- return_VALUE(result);561576 }562577563563- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Driver successfully bound to device\n"));564564-565565- if (driver->ops.scan) {566566- driver->ops.scan(device);567567- }568568-569569- return_VALUE(0);578578+ return_VALUE(result);570579}571580572581static int acpi_driver_attach(struct acpi_driver * drv)···595586596587 if (!acpi_bus_match(dev, drv)) {597588 if (!acpi_bus_driver_init(dev, drv)) {589589+ acpi_start_single_object(dev);598590 atomic_inc(&drv->references);599591 count++;600592 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found driver [%s] for device [%s]\n",···10191009}102010101021101110221022-int10231023-acpi_bus_add (10121012+static int10131013+acpi_add_single_object (10241014 struct acpi_device **child,10251015 struct acpi_device *parent,10261016 acpi_handle handle,···10291019 int result = 0;10301020 struct acpi_device *device = NULL;1031102110321032- ACPI_FUNCTION_TRACE("acpi_bus_add");10221022+ ACPI_FUNCTION_TRACE("acpi_add_single_object");1033102310341024 if (!child)10351025 return_VALUE(-EINVAL);···11501140 *11511141 * TBD: Assumes LDM provides driver hot-plug capability.11521142 */11531153- acpi_bus_find_driver(device);11431143+ result = acpi_bus_find_driver(device);1154114411551145end:11561146 if (!result)···1163115311641154 return_VALUE(result);11651155}11661166-EXPORT_SYMBOL(acpi_bus_add);116711561168115711691169-int acpi_bus_scan (struct acpi_device *start)11581158+static int acpi_bus_scan (struct acpi_device *start,11591159+ struct acpi_bus_ops *ops)11701160{11711161 acpi_status status = AE_OK;11721162 struct acpi_device *parent = NULL;···12391229 continue;12401230 }1241123112421242- status = acpi_bus_add(&child, parent, chandle, type);12431243- if (ACPI_FAILURE(status))12441244- continue;12321232+ if (ops->acpi_op_add)12331233+ status = acpi_add_single_object(&child, parent,12341234+ chandle, type);12351235+ else12361236+ status = acpi_bus_get_device(chandle, &child);12371237+12381238+ if (ACPI_FAILURE(status))12391239+ continue;12401240+12411241+ if (ops->acpi_op_start) {12421242+ status = acpi_start_single_object(child);12431243+ if (ACPI_FAILURE(status))12441244+ continue;12451245+ }1245124612461247 /*12471248 * If the device is present, enabled, and functioning then···1278125712791258 return_VALUE(0);12801259}12811281-EXPORT_SYMBOL(acpi_bus_scan);1282126012611261+int12621262+acpi_bus_add (12631263+ struct acpi_device **child,12641264+ struct acpi_device *parent,12651265+ acpi_handle handle,12661266+ int type)12671267+{12681268+ int result;12691269+ struct acpi_bus_ops ops;12701270+12711271+ ACPI_FUNCTION_TRACE("acpi_bus_add");12721272+12731273+ result = acpi_add_single_object(child, parent, handle, type);12741274+ if (!result) {12751275+ memset(&ops, 0, sizeof(ops));12761276+ ops.acpi_op_add = 1;12771277+ result = acpi_bus_scan(*child, &ops);12781278+ }12791279+ return_VALUE(result);12801280+}12811281+EXPORT_SYMBOL(acpi_bus_add);12821282+12831283+int12841284+acpi_bus_start (12851285+ struct acpi_device *device)12861286+{12871287+ int result;12881288+ struct acpi_bus_ops ops;12891289+12901290+ ACPI_FUNCTION_TRACE("acpi_bus_start");12911291+12921292+ if (!device)12931293+ return_VALUE(-EINVAL);12941294+12951295+ result = acpi_start_single_object(device);12961296+ if (!result) {12971297+ memset(&ops, 0, sizeof(ops));12981298+ ops.acpi_op_start = 1;12991299+ result = acpi_bus_scan(device, &ops);13001300+ }13011301+ return_VALUE(result);13021302+}13031303+EXPORT_SYMBOL(acpi_bus_start);1283130412841305static int12851306acpi_bus_trim(struct acpi_device *start,···13941331 /*13951332 * Enumerate all fixed-feature devices.13961333 */13971397- if (acpi_fadt.pwr_button == 0)13981398- result = acpi_bus_add(&device, acpi_root, 13341334+ if (acpi_fadt.pwr_button == 0) {13351335+ result = acpi_add_single_object(&device, acpi_root,13991336 NULL, ACPI_BUS_TYPE_POWER_BUTTON);13371337+ if (!result)13381338+ result = acpi_start_single_object(device);13391339+ }1400134014011401- if (acpi_fadt.sleep_button == 0)14021402- result = acpi_bus_add(&device, acpi_root, 13411341+ if (acpi_fadt.sleep_button == 0) {13421342+ result = acpi_add_single_object(&device, acpi_root,14031343 NULL, ACPI_BUS_TYPE_SLEEP_BUTTON);13441344+ if (!result)13451345+ result = acpi_start_single_object(device);13461346+ }1404134714051348 return_VALUE(result);14061349}···14151346static int __init acpi_scan_init(void)14161347{14171348 int result;13491349+ struct acpi_bus_ops ops;1418135014191351 ACPI_FUNCTION_TRACE("acpi_scan_init");14201352···14271357 /*14281358 * Create the root device in the bus's device tree14291359 */14301430- result = acpi_bus_add(&acpi_root, NULL, ACPI_ROOT_OBJECT, 13601360+ result = acpi_add_single_object(&acpi_root, NULL, ACPI_ROOT_OBJECT,14311361 ACPI_BUS_TYPE_SYSTEM);14321362 if (result)14331363 goto Done;13641364+13651365+ result = acpi_start_single_object(acpi_root);1434136614351367 /*14361368 * Enumerate devices in the ACPI namespace.14371369 */14381370 result = acpi_bus_scan_fixed(acpi_root);14391439- if (!result) 14401440- result = acpi_bus_scan(acpi_root);13711371+ if (!result) {13721372+ memset(&ops, 0, sizeof(ops));13731373+ ops.acpi_op_add = 1;13741374+ ops.acpi_op_start = 1;13751375+ result = acpi_bus_scan(acpi_root, &ops);13761376+ }1441137714421378 if (result)14431379 acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL);
+1-1
drivers/char/moxa.c
···451451 int n = (sizeof(moxa_pcibrds) / sizeof(moxa_pcibrds[0])) - 1;452452 i = 0;453453 while (i < n) {454454- while ((p = pci_find_device(moxa_pcibrds[i].vendor, moxa_pcibrds[i].device, p))!=NULL)454454+ while ((p = pci_get_device(moxa_pcibrds[i].vendor, moxa_pcibrds[i].device, p))!=NULL)455455 {456456 if (pci_enable_device(p))457457 continue;
+2-2
drivers/char/rio/rio_linux.c
···1095109510961096#ifdef CONFIG_PCI10971097 /* First look for the JET devices: */10981098- while ((pdev = pci_find_device (PCI_VENDOR_ID_SPECIALIX, 10981098+ while ((pdev = pci_get_device (PCI_VENDOR_ID_SPECIALIX,10991099 PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8, 11001100 pdev))) {11011101 if (pci_enable_device(pdev)) continue;···11691169 */1170117011711171 /* Then look for the older RIO/PCI devices: */11721172- while ((pdev = pci_find_device (PCI_VENDOR_ID_SPECIALIX, 11721172+ while ((pdev = pci_get_device (PCI_VENDOR_ID_SPECIALIX,11731173 PCI_DEVICE_ID_SPECIALIX_RIO, 11741174 pdev))) {11751175 if (pci_enable_device(pdev)) continue;
···993993 bus = pci_scan_bus_parented(&dev->dev, dino_current_bus,994994 &dino_cfg_ops, NULL);995995 if(bus) {996996+ pci_bus_add_devices(bus);996997 /* This code *depends* on scanning being single threaded997998 * if it isn't, this global bus number count will fail998999 */
+2
drivers/parisc/lba_pci.c
···15701570 lba_bus = lba_dev->hba.hba_bus =15711571 pci_scan_bus_parented(&dev->dev, lba_dev->hba.bus_num.start,15721572 cfg_ops, NULL);15731573+ if (lba_bus)15741574+ pci_bus_add_devices(lba_bus);1573157515741576 /* This is in lieu of calling pci_assign_unassigned_resources() */15751577 if (is_pdc_pat()) {
+7-4
drivers/pci/bus.c
···121121 * If there is an unattached subordinate bus, attach122122 * it and then scan for unattached PCI devices.123123 */124124- if (dev->subordinate && list_empty(&dev->subordinate->node)) {125125- spin_lock(&pci_bus_lock);126126- list_add_tail(&dev->subordinate->node, &dev->bus->children);127127- spin_unlock(&pci_bus_lock);124124+ if (dev->subordinate) {125125+ if (list_empty(&dev->subordinate->node)) {126126+ spin_lock(&pci_bus_lock);127127+ list_add_tail(&dev->subordinate->node,128128+ &dev->bus->children);129129+ spin_unlock(&pci_bus_lock);130130+ }128131 pci_bus_add_devices(dev->subordinate);129132130133 sysfs_create_link(&dev->subordinate->class_dev.kobj, &dev->dev.kobj, "bridge");
···77 * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)88 * Copyright (C) 2002,2003 Takayoshi Kochi (t-kochi@bq.jp.nec.com)99 * Copyright (C) 2002,2003 NEC Corporation1010+ * Copyright (C) 2003-2005 Matthew Wilcox (matthew.wilcox@hp.com)1111+ * Copyright (C) 2003-2005 Hewlett Packard1012 *1113 * All rights reserved.1214 *···54525553struct acpiphp_bridge;5654struct acpiphp_slot;5757-struct pci_resource;58555956/*6057 * struct slot - slot information for each *physical* slot···6463 struct list_head slot_list;65646665 struct acpiphp_slot *acpi_slot;6767-};6868-6969-/*7070- * struct pci_resource - describes pci resource (mem, pfmem, io, bus)7171- */7272-struct pci_resource {7373- struct pci_resource * next;7474- u64 base;7575- u32 length;7666};77677868/**···93101 int type;94102 int nr_slots;951039696- u8 seg;9797- u8 bus;9898- u8 sub;9999-100104 u32 flags;101105102106 /* This bus (host bridge) or Secondary bus (PCI-to-PCI bridge) */···105117 struct hpp_param hpp;106118107119 spinlock_t res_lock;108108-109109- /* available resources on this bus */110110- struct pci_resource *mem_head;111111- struct pci_resource *p_mem_head;112112- struct pci_resource *io_head;113113- struct pci_resource *bus_head;114120};115121116122···145163146164 u8 function; /* pci function# */147165 u32 flags; /* see below */148148-149149- /* resources used for this function */150150- struct pci_resource *mem_head;151151- struct pci_resource *p_mem_head;152152- struct pci_resource *io_head;153153- struct pci_resource *bus_head;154166};155167156168/**···218242extern u8 acpiphp_get_latch_status (struct acpiphp_slot *slot);219243extern u8 acpiphp_get_adapter_status (struct acpiphp_slot *slot);220244extern u32 acpiphp_get_address (struct acpiphp_slot *slot);221221-222222-/* acpiphp_pci.c */223223-extern struct pci_dev *acpiphp_allocate_pcidev (struct pci_bus *pbus, int dev, int fn);224224-extern int acpiphp_configure_slot (struct acpiphp_slot *slot);225225-extern int acpiphp_configure_function (struct acpiphp_func *func);226226-extern void acpiphp_unconfigure_function (struct acpiphp_func *func);227227-extern int acpiphp_detect_pci_resource (struct acpiphp_bridge *bridge);228228-extern int acpiphp_init_func_resource (struct acpiphp_func *func);229229-230230-/* acpiphp_res.c */231231-extern struct pci_resource *acpiphp_get_io_resource (struct pci_resource **head, u32 size);232232-extern struct pci_resource *acpiphp_get_resource (struct pci_resource **head, u32 size);233233-extern struct pci_resource *acpiphp_get_resource_with_base (struct pci_resource **head, u64 base, u32 size);234234-extern int acpiphp_resource_sort_and_combine (struct pci_resource **head);235235-extern struct pci_resource *acpiphp_make_resource (u64 base, u32 length);236236-extern void acpiphp_move_resource (struct pci_resource **from, struct pci_resource **to);237237-extern void acpiphp_free_resource (struct pci_resource **res);238238-extern void acpiphp_dump_resource (struct acpiphp_bridge *bridge); /* debug */239239-extern void acpiphp_dump_func_resource (struct acpiphp_func *func); /* debug */240245241246/* variables */242247extern int acpiphp_debug;
+5-4
drivers/pci/hotplug/acpiphp_core.c
···77 * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)88 * Copyright (C) 2002,2003 Takayoshi Kochi (t-kochi@bq.jp.nec.com)99 * Copyright (C) 2002,2003 NEC Corporation1010+ * Copyright (C) 2003-2005 Matthew Wilcox (matthew.wilcox@hp.com)1111+ * Copyright (C) 2003-2005 Hewlett Packard1012 *1113 * All rights reserved.1214 *···5553static int num_slots;5654static struct acpiphp_attention_info *attention_info;57555858-#define DRIVER_VERSION "0.4"5959-#define DRIVER_AUTHOR "Greg Kroah-Hartman <gregkh@us.ibm.com>, Takayoshi Kochi <t-kochi@bq.jp.nec.com>"5656+#define DRIVER_VERSION "0.5"5757+#define DRIVER_AUTHOR "Greg Kroah-Hartman <gregkh@us.ibm.com>, Takayoshi Kochi <t-kochi@bq.jp.nec.com>, Matthew Wilcox <willy@hp.com>"6058#define DRIVER_DESC "ACPI Hot Plug PCI Controller Driver"61596260MODULE_AUTHOR(DRIVER_AUTHOR);···283281/**284282 * get_address - get pci address of a slot285283 * @hotplug_slot: slot to get status286286- * @busdev: pointer to struct pci_busdev (seg, bus, dev)287287- *284284+ * @value: pointer to struct pci_busdev (seg, bus, dev)288285 */289286static int get_address(struct hotplug_slot *hotplug_slot, u32 *value)290287{
+514-372
drivers/pci/hotplug/acpiphp_glue.c
···44 * Copyright (C) 2002,2003 Takayoshi Kochi (t-kochi@bq.jp.nec.com)55 * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)66 * Copyright (C) 2002,2003 NEC Corporation77+ * Copyright (C) 2003-2005 Matthew Wilcox (matthew.wilcox@hp.com)88+ * Copyright (C) 2003-2005 Hewlett Packard99+ * Copyright (C) 2005 Rajesh Shah (rajesh.shah@intel.com)1010+ * Copyright (C) 2005 Intel Corporation711 *812 * All rights reserved.913 *···2824 *2925 * Send feedback to <t-kochi@bq.jp.nec.com>3026 *2727+ */2828+2929+/*3030+ * Lifetime rules for pci_dev:3131+ * - The one in acpiphp_func has its refcount elevated by pci_get_slot()3232+ * when the driver is loaded or when an insertion event occurs. It loses3333+ * a refcount when its ejected or the driver unloads.3434+ * - The one in acpiphp_bridge has its refcount elevated by pci_get_slot()3535+ * when the bridge is scanned and it loses a refcount when the bridge3636+ * is removed.3137 */32383339#include <linux/init.h>···192178193179 bridge->nr_slots++;194180195195- dbg("found ACPI PCI Hotplug slot at PCI %02x:%02x Slot:%d\n",196196- slot->bridge->bus, slot->device, slot->sun);181181+ dbg("found ACPI PCI Hotplug slot %d at PCI %04x:%02x:%02x\n",182182+ slot->sun, pci_domain_nr(bridge->pci_bus),183183+ bridge->pci_bus->number, slot->device);197184 }198185199186 newfunc->slot = slot;200187 list_add_tail(&newfunc->sibling, &slot->funcs);201188202189 /* associate corresponding pci_dev */203203- newfunc->pci_dev = pci_find_slot(bridge->bus,190190+ newfunc->pci_dev = pci_get_slot(bridge->pci_bus,204191 PCI_DEVFN(device, function));205192 if (newfunc->pci_dev) {206206- if (acpiphp_init_func_resource(newfunc) < 0) {207207- kfree(newfunc);208208- return AE_ERROR;209209- }210193 slot->flags |= (SLOT_ENABLED | SLOT_POWEREDON);211194 }212195···237226 return count;238227}239228240240-241241-/* decode ACPI _CRS data and convert into our internal resource list242242- * TBD: _TRA, etc.243243- */244244-static acpi_status245245-decode_acpi_resource(struct acpi_resource *resource, void *context)246246-{247247- struct acpiphp_bridge *bridge = (struct acpiphp_bridge *) context;248248- struct acpi_resource_address64 address;249249- struct pci_resource *res;250250-251251- if (resource->id != ACPI_RSTYPE_ADDRESS16 &&252252- resource->id != ACPI_RSTYPE_ADDRESS32 &&253253- resource->id != ACPI_RSTYPE_ADDRESS64)254254- return AE_OK;255255-256256- acpi_resource_to_address64(resource, &address);257257-258258- if (address.producer_consumer == ACPI_PRODUCER && address.address_length > 0) {259259- dbg("resource type: %d: 0x%llx - 0x%llx\n", address.resource_type,260260- (unsigned long long)address.min_address_range,261261- (unsigned long long)address.max_address_range);262262- res = acpiphp_make_resource(address.min_address_range,263263- address.address_length);264264- if (!res) {265265- err("out of memory\n");266266- return AE_OK;267267- }268268-269269- switch (address.resource_type) {270270- case ACPI_MEMORY_RANGE:271271- if (address.attribute.memory.cache_attribute == ACPI_PREFETCHABLE_MEMORY) {272272- res->next = bridge->p_mem_head;273273- bridge->p_mem_head = res;274274- } else {275275- res->next = bridge->mem_head;276276- bridge->mem_head = res;277277- }278278- break;279279- case ACPI_IO_RANGE:280280- res->next = bridge->io_head;281281- bridge->io_head = res;282282- break;283283- case ACPI_BUS_NUMBER_RANGE:284284- res->next = bridge->bus_head;285285- bridge->bus_head = res;286286- break;287287- default:288288- /* invalid type */289289- kfree(res);290290- break;291291- }292292- }293293-294294- return AE_OK;295295-}296229297230/* decode ACPI 2.0 _HPP hot plug parameters */298231static void decode_hpp(struct acpiphp_bridge *bridge)···301346 /* decode ACPI 2.0 _HPP (hot plug parameters) */302347 decode_hpp(bridge);303348304304- /* subtract all resources already allocated */305305- acpiphp_detect_pci_resource(bridge);306306-307349 /* register all slot objects under this bridge */308350 status = acpi_walk_namespace(ACPI_TYPE_DEVICE, bridge->handle, (u32)1,309351 register_slot, bridge, NULL);310352311353 /* install notify handler */312312- status = acpi_install_notify_handler(bridge->handle,354354+ if (bridge->type != BRIDGE_TYPE_HOST) {355355+ status = acpi_install_notify_handler(bridge->handle,313356 ACPI_SYSTEM_NOTIFY,314357 handle_hotplug_event_bridge,315358 bridge);316359317317- if (ACPI_FAILURE(status)) {318318- err("failed to register interrupt notify handler\n");360360+ if (ACPI_FAILURE(status)) {361361+ err("failed to register interrupt notify handler\n");362362+ }319363 }320364321365 list_add(&bridge->list, &bridge_list);322322-323323- dbg("Bridge resource:\n");324324- acpiphp_dump_resource(bridge);325366}326367327368328369/* allocate and initialize host bridge data structure */329329-static void add_host_bridge(acpi_handle *handle, int seg, int bus)370370+static void add_host_bridge(acpi_handle *handle, struct pci_bus *pci_bus)330371{331331- acpi_status status;332372 struct acpiphp_bridge *bridge;333373334374 bridge = kmalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL);···334384335385 bridge->type = BRIDGE_TYPE_HOST;336386 bridge->handle = handle;337337- bridge->seg = seg;338338- bridge->bus = bus;339387340340- bridge->pci_bus = pci_find_bus(seg, bus);388388+ bridge->pci_bus = pci_bus;341389342390 spin_lock_init(&bridge->res_lock);343343-344344- /* to be overridden when we decode _CRS */345345- bridge->sub = bridge->bus;346346-347347- /* decode resources */348348-349349- status = acpi_walk_resources(handle, METHOD_NAME__CRS,350350- decode_acpi_resource, bridge);351351-352352- if (ACPI_FAILURE(status)) {353353- err("failed to decode bridge resources\n");354354- kfree(bridge);355355- return;356356- }357357-358358- acpiphp_resource_sort_and_combine(&bridge->io_head);359359- acpiphp_resource_sort_and_combine(&bridge->mem_head);360360- acpiphp_resource_sort_and_combine(&bridge->p_mem_head);361361- acpiphp_resource_sort_and_combine(&bridge->bus_head);362362-363363- dbg("ACPI _CRS resource:\n");364364- acpiphp_dump_resource(bridge);365365-366366- if (bridge->bus_head) {367367- bridge->bus = bridge->bus_head->base;368368- bridge->sub = bridge->bus_head->base + bridge->bus_head->length - 1;369369- }370391371392 init_bridge_misc(bridge);372393}373394374395375396/* allocate and initialize PCI-to-PCI bridge data structure */376376-static void add_p2p_bridge(acpi_handle *handle, int seg, int bus, int dev, int fn)397397+static void add_p2p_bridge(acpi_handle *handle, struct pci_dev *pci_dev)377398{378399 struct acpiphp_bridge *bridge;379379- u8 tmp8;380380- u16 tmp16;381381- u64 base64, limit64;382382- u32 base, limit, base32u, limit32u;383400384401 bridge = kmalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL);385402 if (bridge == NULL) {···358441359442 bridge->type = BRIDGE_TYPE_P2P;360443 bridge->handle = handle;361361- bridge->seg = seg;362444363363- bridge->pci_dev = pci_find_slot(bus, PCI_DEVFN(dev, fn));364364- if (!bridge->pci_dev) {365365- err("Can't get pci_dev\n");366366- kfree(bridge);367367- return;368368- }369369-370370- bridge->pci_bus = bridge->pci_dev->subordinate;445445+ bridge->pci_dev = pci_dev_get(pci_dev);446446+ bridge->pci_bus = pci_dev->subordinate;371447 if (!bridge->pci_bus) {372448 err("This is not a PCI-to-PCI bridge!\n");373373- kfree(bridge);374374- return;449449+ goto err;375450 }376451377452 spin_lock_init(&bridge->res_lock);378453379379- bridge->bus = bridge->pci_bus->number;380380- bridge->sub = bridge->pci_bus->subordinate;381381-382382- /*383383- * decode resources under this P2P bridge384384- */385385-386386- /* I/O resources */387387- pci_read_config_byte(bridge->pci_dev, PCI_IO_BASE, &tmp8);388388- base = tmp8;389389- pci_read_config_byte(bridge->pci_dev, PCI_IO_LIMIT, &tmp8);390390- limit = tmp8;391391-392392- switch (base & PCI_IO_RANGE_TYPE_MASK) {393393- case PCI_IO_RANGE_TYPE_16:394394- base = (base << 8) & 0xf000;395395- limit = ((limit << 8) & 0xf000) + 0xfff;396396- bridge->io_head = acpiphp_make_resource((u64)base, limit - base + 1);397397- if (!bridge->io_head) {398398- err("out of memory\n");399399- kfree(bridge);400400- return;401401- }402402- dbg("16bit I/O range: %04x-%04x\n",403403- (u32)bridge->io_head->base,404404- (u32)(bridge->io_head->base + bridge->io_head->length - 1));405405- break;406406- case PCI_IO_RANGE_TYPE_32:407407- pci_read_config_word(bridge->pci_dev, PCI_IO_BASE_UPPER16, &tmp16);408408- base = ((u32)tmp16 << 16) | ((base << 8) & 0xf000);409409- pci_read_config_word(bridge->pci_dev, PCI_IO_LIMIT_UPPER16, &tmp16);410410- limit = (((u32)tmp16 << 16) | ((limit << 8) & 0xf000)) + 0xfff;411411- bridge->io_head = acpiphp_make_resource((u64)base, limit - base + 1);412412- if (!bridge->io_head) {413413- err("out of memory\n");414414- kfree(bridge);415415- return;416416- }417417- dbg("32bit I/O range: %08x-%08x\n",418418- (u32)bridge->io_head->base,419419- (u32)(bridge->io_head->base + bridge->io_head->length - 1));420420- break;421421- case 0x0f:422422- dbg("I/O space unsupported\n");423423- break;424424- default:425425- warn("Unknown I/O range type\n");426426- }427427-428428- /* Memory resources (mandatory for P2P bridge) */429429- pci_read_config_word(bridge->pci_dev, PCI_MEMORY_BASE, &tmp16);430430- base = (tmp16 & 0xfff0) << 16;431431- pci_read_config_word(bridge->pci_dev, PCI_MEMORY_LIMIT, &tmp16);432432- limit = ((tmp16 & 0xfff0) << 16) | 0xfffff;433433- bridge->mem_head = acpiphp_make_resource((u64)base, limit - base + 1);434434- if (!bridge->mem_head) {435435- err("out of memory\n");436436- kfree(bridge);437437- return;438438- }439439- dbg("32bit Memory range: %08x-%08x\n",440440- (u32)bridge->mem_head->base,441441- (u32)(bridge->mem_head->base + bridge->mem_head->length-1));442442-443443- /* Prefetchable Memory resources (optional) */444444- pci_read_config_word(bridge->pci_dev, PCI_PREF_MEMORY_BASE, &tmp16);445445- base = tmp16;446446- pci_read_config_word(bridge->pci_dev, PCI_PREF_MEMORY_LIMIT, &tmp16);447447- limit = tmp16;448448-449449- switch (base & PCI_MEMORY_RANGE_TYPE_MASK) {450450- case PCI_PREF_RANGE_TYPE_32:451451- base = (base & 0xfff0) << 16;452452- limit = ((limit & 0xfff0) << 16) | 0xfffff;453453- bridge->p_mem_head = acpiphp_make_resource((u64)base, limit - base + 1);454454- if (!bridge->p_mem_head) {455455- err("out of memory\n");456456- kfree(bridge);457457- return;458458- }459459- dbg("32bit Prefetchable memory range: %08x-%08x\n",460460- (u32)bridge->p_mem_head->base,461461- (u32)(bridge->p_mem_head->base + bridge->p_mem_head->length - 1));462462- break;463463- case PCI_PREF_RANGE_TYPE_64:464464- pci_read_config_dword(bridge->pci_dev, PCI_PREF_BASE_UPPER32, &base32u);465465- pci_read_config_dword(bridge->pci_dev, PCI_PREF_LIMIT_UPPER32, &limit32u);466466- base64 = ((u64)base32u << 32) | ((base & 0xfff0) << 16);467467- limit64 = (((u64)limit32u << 32) | ((limit & 0xfff0) << 16)) + 0xfffff;468468-469469- bridge->p_mem_head = acpiphp_make_resource(base64, limit64 - base64 + 1);470470- if (!bridge->p_mem_head) {471471- err("out of memory\n");472472- kfree(bridge);473473- return;474474- }475475- dbg("64bit Prefetchable memory range: %08x%08x-%08x%08x\n",476476- (u32)(bridge->p_mem_head->base >> 32),477477- (u32)(bridge->p_mem_head->base & 0xffffffff),478478- (u32)((bridge->p_mem_head->base + bridge->p_mem_head->length - 1) >> 32),479479- (u32)((bridge->p_mem_head->base + bridge->p_mem_head->length - 1) & 0xffffffff));480480- break;481481- case 0x0f:482482- break;483483- default:484484- warn("Unknown prefetchale memory type\n");485485- }486486-487454 init_bridge_misc(bridge);455455+ return;456456+ err:457457+ pci_dev_put(pci_dev);458458+ kfree(bridge);459459+ return;488460}489461490462···383577{384578 acpi_status status;385579 acpi_handle dummy_handle;386386- unsigned long *segbus = context;387580 unsigned long tmp;388388- int seg, bus, device, function;581581+ int device, function;389582 struct pci_dev *dev;390390-391391- /* get PCI address */392392- seg = (*segbus >> 8) & 0xff;393393- bus = *segbus & 0xff;583583+ struct pci_bus *pci_bus = context;394584395585 status = acpi_get_handle(handle, "_ADR", &dummy_handle);396586 if (ACPI_FAILURE(status))···401599 device = (tmp >> 16) & 0xffff;402600 function = tmp & 0xffff;403601404404- dev = pci_find_slot(bus, PCI_DEVFN(device, function));602602+ dev = pci_get_slot(pci_bus, PCI_DEVFN(device, function));405603406406- if (!dev)407407- return AE_OK;408408-409409- if (!dev->subordinate)410410- return AE_OK;604604+ if (!dev || !dev->subordinate)605605+ goto out;411606412607 /* check if this bridge has ejectable slots */413608 if (detect_ejectable_slots(handle) > 0) {414609 dbg("found PCI-to-PCI bridge at PCI %s\n", pci_name(dev));415415- add_p2p_bridge(handle, seg, bus, device, function);610610+ add_p2p_bridge(handle, dev);416611 }417612613613+ out:614614+ pci_dev_put(dev);418615 return AE_OK;419616}420617···425624 unsigned long tmp;426625 int seg, bus;427626 acpi_handle dummy_handle;627627+ struct pci_bus *pci_bus;428628429629 /* if the bridge doesn't have _STA, we assume it is always there */430630 status = acpi_get_handle(handle, "_STA", &dummy_handle);···455653 bus = 0;456654 }457655458458- /* check if this bridge has ejectable slots */459459- if (detect_ejectable_slots(handle) > 0) {460460- dbg("found PCI host-bus bridge with hot-pluggable slots\n");461461- add_host_bridge(handle, seg, bus);656656+ pci_bus = pci_find_bus(seg, bus);657657+ if (!pci_bus) {658658+ err("Can't find bus %04x:%02x\n", seg, bus);462659 return 0;463660 }464661465465- tmp = seg << 8 | bus;662662+ /* check if this bridge has ejectable slots */663663+ if (detect_ejectable_slots(handle) > 0) {664664+ dbg("found PCI host-bus bridge with hot-pluggable slots\n");665665+ add_host_bridge(handle, pci_bus);666666+ return 0;667667+ }466668467669 /* search P2P bridges under this host bridge */468670 status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,469469- find_p2p_bridge, &tmp, NULL);671671+ find_p2p_bridge, pci_bus, NULL);470672471673 if (ACPI_FAILURE(status))472674 warn("find_p2p_bridge faied (error code = 0x%x)\n",status);···478672 return 0;479673}480674675675+static struct acpiphp_bridge *acpiphp_handle_to_bridge(acpi_handle handle)676676+{677677+ struct list_head *head;678678+ list_for_each(head, &bridge_list) {679679+ struct acpiphp_bridge *bridge = list_entry(head,680680+ struct acpiphp_bridge, list);681681+ if (bridge->handle == handle)682682+ return bridge;683683+ }684684+685685+ return NULL;686686+}687687+688688+static void cleanup_bridge(struct acpiphp_bridge *bridge)689689+{690690+ struct list_head *list, *tmp;691691+ struct acpiphp_slot *slot;692692+ acpi_status status;693693+ acpi_handle handle = bridge->handle;694694+695695+ status = acpi_remove_notify_handler(handle, ACPI_SYSTEM_NOTIFY,696696+ handle_hotplug_event_bridge);697697+ if (ACPI_FAILURE(status))698698+ err("failed to remove notify handler\n");699699+700700+ slot = bridge->slots;701701+ while (slot) {702702+ struct acpiphp_slot *next = slot->next;703703+ list_for_each_safe (list, tmp, &slot->funcs) {704704+ struct acpiphp_func *func;705705+ func = list_entry(list, struct acpiphp_func, sibling);706706+ status = acpi_remove_notify_handler(func->handle,707707+ ACPI_SYSTEM_NOTIFY,708708+ handle_hotplug_event_func);709709+ if (ACPI_FAILURE(status))710710+ err("failed to remove notify handler\n");711711+ pci_dev_put(func->pci_dev);712712+ list_del(list);713713+ kfree(func);714714+ }715715+ kfree(slot);716716+ slot = next;717717+ }718718+719719+ pci_dev_put(bridge->pci_dev);720720+ list_del(&bridge->list);721721+ kfree(bridge);722722+}723723+724724+static acpi_status725725+cleanup_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv)726726+{727727+ struct acpiphp_bridge *bridge;728728+729729+ if (!(bridge = acpiphp_handle_to_bridge(handle)))730730+ return AE_OK;731731+ cleanup_bridge(bridge);732732+ return AE_OK;733733+}481734482735static void remove_bridge(acpi_handle handle)483736{484484- /* No-op for now .. */737737+ struct acpiphp_bridge *bridge;738738+739739+ bridge = acpiphp_handle_to_bridge(handle);740740+ if (bridge) {741741+ cleanup_bridge(bridge);742742+ } else {743743+ /* clean-up p2p bridges under this host bridge */744744+ acpi_walk_namespace(ACPI_TYPE_DEVICE, handle,745745+ (u32)1, cleanup_p2p_bridge, NULL, NULL);746746+ }485747}486748749749+static struct pci_dev * get_apic_pci_info(acpi_handle handle)750750+{751751+ struct acpi_pci_id id;752752+ struct pci_bus *bus;753753+ struct pci_dev *dev;754754+755755+ if (ACPI_FAILURE(acpi_get_pci_id(handle, &id)))756756+ return NULL;757757+758758+ bus = pci_find_bus(id.segment, id.bus);759759+ if (!bus)760760+ return NULL;761761+762762+ dev = pci_get_slot(bus, PCI_DEVFN(id.device, id.function));763763+ if (!dev)764764+ return NULL;765765+766766+ if ((dev->class != PCI_CLASS_SYSTEM_PIC_IOAPIC) &&767767+ (dev->class != PCI_CLASS_SYSTEM_PIC_IOXAPIC))768768+ {769769+ pci_dev_put(dev);770770+ return NULL;771771+ }772772+773773+ return dev;774774+}775775+776776+static int get_gsi_base(acpi_handle handle, u32 *gsi_base)777777+{778778+ acpi_status status;779779+ int result = -1;780780+ unsigned long gsb;781781+ struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};782782+ union acpi_object *obj;783783+ void *table;784784+785785+ status = acpi_evaluate_integer(handle, "_GSB", NULL, &gsb);786786+ if (ACPI_SUCCESS(status)) {787787+ *gsi_base = (u32)gsb;788788+ return 0;789789+ }790790+791791+ status = acpi_evaluate_object(handle, "_MAT", NULL, &buffer);792792+ if (ACPI_FAILURE(status) || !buffer.length || !buffer.pointer)793793+ return -1;794794+795795+ obj = buffer.pointer;796796+ if (obj->type != ACPI_TYPE_BUFFER)797797+ goto out;798798+799799+ table = obj->buffer.pointer;800800+ switch (((acpi_table_entry_header *)table)->type) {801801+ case ACPI_MADT_IOSAPIC:802802+ *gsi_base = ((struct acpi_table_iosapic *)table)->global_irq_base;803803+ result = 0;804804+ break;805805+ case ACPI_MADT_IOAPIC:806806+ *gsi_base = ((struct acpi_table_ioapic *)table)->global_irq_base;807807+ result = 0;808808+ break;809809+ default:810810+ break;811811+ }812812+ out:813813+ acpi_os_free(buffer.pointer);814814+ return result;815815+}816816+817817+static acpi_status818818+ioapic_add(acpi_handle handle, u32 lvl, void *context, void **rv)819819+{820820+ acpi_status status;821821+ unsigned long sta;822822+ acpi_handle tmp;823823+ struct pci_dev *pdev;824824+ u32 gsi_base;825825+ u64 phys_addr;826826+827827+ /* Evaluate _STA if present */828828+ status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);829829+ if (ACPI_SUCCESS(status) && sta != ACPI_STA_ALL)830830+ return AE_CTRL_DEPTH;831831+832832+ /* Scan only PCI bus scope */833833+ status = acpi_get_handle(handle, "_HID", &tmp);834834+ if (ACPI_SUCCESS(status))835835+ return AE_CTRL_DEPTH;836836+837837+ if (get_gsi_base(handle, &gsi_base))838838+ return AE_OK;839839+840840+ pdev = get_apic_pci_info(handle);841841+ if (!pdev)842842+ return AE_OK;843843+844844+ if (pci_enable_device(pdev)) {845845+ pci_dev_put(pdev);846846+ return AE_OK;847847+ }848848+849849+ pci_set_master(pdev);850850+851851+ if (pci_request_region(pdev, 0, "I/O APIC(acpiphp)")) {852852+ pci_disable_device(pdev);853853+ pci_dev_put(pdev);854854+ return AE_OK;855855+ }856856+857857+ phys_addr = pci_resource_start(pdev, 0);858858+ if (acpi_register_ioapic(handle, phys_addr, gsi_base)) {859859+ pci_release_region(pdev, 0);860860+ pci_disable_device(pdev);861861+ pci_dev_put(pdev);862862+ return AE_OK;863863+ }864864+865865+ return AE_OK;866866+}867867+868868+static int acpiphp_configure_ioapics(acpi_handle handle)869869+{870870+ acpi_walk_namespace(ACPI_TYPE_DEVICE, handle,871871+ ACPI_UINT32_MAX, ioapic_add, NULL, NULL);872872+ return 0;873873+}487874488875static int power_on_slot(struct acpiphp_slot *slot)489876{···718719 acpi_status status;719720 struct acpiphp_func *func;720721 struct list_head *l;721721- struct acpi_object_list arg_list;722722- union acpi_object arg;723722724723 int retval = 0;725724···728731 list_for_each (l, &slot->funcs) {729732 func = list_entry(l, struct acpiphp_func, sibling);730733731731- if (func->pci_dev && (func->flags & FUNC_HAS_PS3)) {734734+ if (func->flags & FUNC_HAS_PS3) {732735 status = acpi_evaluate_object(func->handle, "_PS3", NULL, NULL);733736 if (ACPI_FAILURE(status)) {734737 warn("%s: _PS3 failed\n", __FUNCTION__);735735- retval = -1;736736- goto err_exit;737737- } else738738- break;739739- }740740- }741741-742742- list_for_each (l, &slot->funcs) {743743- func = list_entry(l, struct acpiphp_func, sibling);744744-745745- /* We don't want to call _EJ0 on non-existing functions. */746746- if (func->pci_dev && (func->flags & FUNC_HAS_EJ0)) {747747- /* _EJ0 method take one argument */748748- arg_list.count = 1;749749- arg_list.pointer = &arg;750750- arg.type = ACPI_TYPE_INTEGER;751751- arg.integer.value = 1;752752-753753- status = acpi_evaluate_object(func->handle, "_EJ0", &arg_list, NULL);754754- if (ACPI_FAILURE(status)) {755755- warn("%s: _EJ0 failed\n", __FUNCTION__);756738 retval = -1;757739 goto err_exit;758740 } else···758782 */759783static int enable_device(struct acpiphp_slot *slot)760784{761761- u8 bus;762785 struct pci_dev *dev;763763- struct pci_bus *child;786786+ struct pci_bus *bus = slot->bridge->pci_bus;764787 struct list_head *l;765788 struct acpiphp_func *func;766789 int retval = 0;767767- int num;790790+ int num, max, pass;768791769792 if (slot->flags & SLOT_ENABLED)770793 goto err_exit;771794772795 /* sanity check: dev should be NULL when hot-plugged in */773773- dev = pci_find_slot(slot->bridge->bus, PCI_DEVFN(slot->device, 0));796796+ dev = pci_get_slot(bus, PCI_DEVFN(slot->device, 0));774797 if (dev) {775798 /* This case shouldn't happen */776799 err("pci_dev structure already exists.\n");800800+ pci_dev_put(dev);777801 retval = -1;778802 goto err_exit;779803 }780804781781- /* allocate resources to device */782782- retval = acpiphp_configure_slot(slot);783783- if (retval)784784- goto err_exit;785785-786786- /* returned `dev' is the *first function* only! */787787- num = pci_scan_slot(slot->bridge->pci_bus, PCI_DEVFN(slot->device, 0));788788- if (num)789789- pci_bus_add_devices(slot->bridge->pci_bus);790790- dev = pci_find_slot(slot->bridge->bus, PCI_DEVFN(slot->device, 0));791791-792792- if (!dev) {805805+ num = pci_scan_slot(bus, PCI_DEVFN(slot->device, 0));806806+ if (num == 0) {793807 err("No new device found\n");794808 retval = -1;795809 goto err_exit;796810 }797811798798- if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {799799- pci_read_config_byte(dev, PCI_SECONDARY_BUS, &bus);800800- child = (struct pci_bus*) pci_add_new_bus(dev->bus, dev, bus);801801- pci_do_scan_bus(child);812812+ max = bus->secondary;813813+ for (pass = 0; pass < 2; pass++) {814814+ list_for_each_entry(dev, &bus->devices, bus_list) {815815+ if (PCI_SLOT(dev->devfn) != slot->device)816816+ continue;817817+ if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||818818+ dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)819819+ max = pci_scan_bridge(bus, dev, max, pass);820820+ }802821 }822822+823823+ pci_bus_assign_resources(bus);824824+ pci_bus_add_devices(bus);803825804826 /* associate pci_dev to our representation */805827 list_for_each (l, &slot->funcs) {806828 func = list_entry(l, struct acpiphp_func, sibling);807807-808808- func->pci_dev = pci_find_slot(slot->bridge->bus,809809- PCI_DEVFN(slot->device,829829+ func->pci_dev = pci_get_slot(bus, PCI_DEVFN(slot->device,810830 func->function));811811- if (!func->pci_dev)812812- continue;813813-814814- /* configure device */815815- retval = acpiphp_configure_function(func);816816- if (retval)817817- goto err_exit;818831 }819832820833 slot->flags |= SLOT_ENABLED;821821-822822- dbg("Available resources:\n");823823- acpiphp_dump_resource(slot->bridge);824834825835 err_exit:826836 return retval;···828866829867 list_for_each (l, &slot->funcs) {830868 func = list_entry(l, struct acpiphp_func, sibling);869869+ if (!func->pci_dev)870870+ continue;831871832832- if (func->pci_dev)833833- acpiphp_unconfigure_function(func);872872+ pci_remove_bus_device(func->pci_dev);873873+ pci_dev_put(func->pci_dev);874874+ func->pci_dev = NULL;834875 }835876836877 slot->flags &= (~SLOT_ENABLED);···885920}886921887922/**923923+ * acpiphp_eject_slot - physically eject the slot924924+ */925925+static int acpiphp_eject_slot(struct acpiphp_slot *slot)926926+{927927+ acpi_status status;928928+ struct acpiphp_func *func;929929+ struct list_head *l;930930+ struct acpi_object_list arg_list;931931+ union acpi_object arg;932932+933933+ list_for_each (l, &slot->funcs) {934934+ func = list_entry(l, struct acpiphp_func, sibling);935935+936936+ /* We don't want to call _EJ0 on non-existing functions. */937937+ if ((func->flags & FUNC_HAS_EJ0)) {938938+ /* _EJ0 method take one argument */939939+ arg_list.count = 1;940940+ arg_list.pointer = &arg;941941+ arg.type = ACPI_TYPE_INTEGER;942942+ arg.integer.value = 1;943943+944944+ status = acpi_evaluate_object(func->handle, "_EJ0", &arg_list, NULL);945945+ if (ACPI_FAILURE(status)) {946946+ warn("%s: _EJ0 failed\n", __FUNCTION__);947947+ return -1;948948+ } else949949+ break;950950+ }951951+ }952952+ return 0;953953+}954954+955955+/**888956 * acpiphp_check_bridge - re-enumerate devices889957 *890958 * Iterate over all slots under this bridge and make sure that if a···940942 if (retval) {941943 err("Error occurred in disabling\n");942944 goto err_exit;945945+ } else {946946+ acpiphp_eject_slot(slot);943947 }944948 disabled++;945949 } else {···960960961961 err_exit:962962 return retval;963963+}964964+965965+static void program_hpp(struct pci_dev *dev, struct acpiphp_bridge *bridge)966966+{967967+ u16 pci_cmd, pci_bctl;968968+ struct pci_dev *cdev;969969+970970+ /* Program hpp values for this device */971971+ if (!(dev->hdr_type == PCI_HEADER_TYPE_NORMAL ||972972+ (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE &&973973+ (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI)))974974+ return;975975+ pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE,976976+ bridge->hpp.cache_line_size);977977+ pci_write_config_byte(dev, PCI_LATENCY_TIMER,978978+ bridge->hpp.latency_timer);979979+ pci_read_config_word(dev, PCI_COMMAND, &pci_cmd);980980+ if (bridge->hpp.enable_SERR)981981+ pci_cmd |= PCI_COMMAND_SERR;982982+ else983983+ pci_cmd &= ~PCI_COMMAND_SERR;984984+ if (bridge->hpp.enable_PERR)985985+ pci_cmd |= PCI_COMMAND_PARITY;986986+ else987987+ pci_cmd &= ~PCI_COMMAND_PARITY;988988+ pci_write_config_word(dev, PCI_COMMAND, pci_cmd);989989+990990+ /* Program bridge control value and child devices */991991+ if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {992992+ pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER,993993+ bridge->hpp.latency_timer);994994+ pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &pci_bctl);995995+ if (bridge->hpp.enable_SERR)996996+ pci_bctl |= PCI_BRIDGE_CTL_SERR;997997+ else998998+ pci_bctl &= ~PCI_BRIDGE_CTL_SERR;999999+ if (bridge->hpp.enable_PERR)10001000+ pci_bctl |= PCI_BRIDGE_CTL_PARITY;10011001+ else10021002+ pci_bctl &= ~PCI_BRIDGE_CTL_PARITY;10031003+ pci_write_config_word(dev, PCI_BRIDGE_CONTROL, pci_bctl);10041004+ if (dev->subordinate) {10051005+ list_for_each_entry(cdev, &dev->subordinate->devices,10061006+ bus_list)10071007+ program_hpp(cdev, bridge);10081008+ }10091009+ }10101010+}10111011+10121012+static void acpiphp_set_hpp_values(acpi_handle handle, struct pci_bus *bus)10131013+{10141014+ struct acpiphp_bridge bridge;10151015+ struct pci_dev *dev;10161016+10171017+ memset(&bridge, 0, sizeof(bridge));10181018+ bridge.handle = handle;10191019+ decode_hpp(&bridge);10201020+ list_for_each_entry(dev, &bus->devices, bus_list)10211021+ program_hpp(dev, &bridge);10221022+10231023+}10241024+10251025+/*10261026+ * Remove devices for which we could not assign resources, call10271027+ * arch specific code to fix-up the bus10281028+ */10291029+static void acpiphp_sanitize_bus(struct pci_bus *bus)10301030+{10311031+ struct pci_dev *dev;10321032+ int i;10331033+ unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM;10341034+10351035+ list_for_each_entry(dev, &bus->devices, bus_list) {10361036+ for (i=0; i<PCI_BRIDGE_RESOURCES; i++) {10371037+ struct resource *res = &dev->resource[i];10381038+ if ((res->flags & type_mask) && !res->start &&10391039+ res->end) {10401040+ /* Could not assign a required resources10411041+ * for this device, remove it */10421042+ pci_remove_bus_device(dev);10431043+ break;10441044+ }10451045+ }10461046+ }10471047+}10481048+10491049+/* Program resources in newly inserted bridge */10501050+static int acpiphp_configure_bridge (acpi_handle handle)10511051+{10521052+ struct acpi_pci_id pci_id;10531053+ struct pci_bus *bus;10541054+10551055+ if (ACPI_FAILURE(acpi_get_pci_id(handle, &pci_id))) {10561056+ err("cannot get PCI domain and bus number for bridge\n");10571057+ return -EINVAL;10581058+ }10591059+ bus = pci_find_bus(pci_id.segment, pci_id.bus);10601060+ if (!bus) {10611061+ err("cannot find bus %d:%d\n",10621062+ pci_id.segment, pci_id.bus);10631063+ return -EINVAL;10641064+ }10651065+10661066+ pci_bus_size_bridges(bus);10671067+ pci_bus_assign_resources(bus);10681068+ acpiphp_sanitize_bus(bus);10691069+ acpiphp_set_hpp_values(handle, bus);10701070+ pci_enable_bridges(bus);10711071+ acpiphp_configure_ioapics(handle);10721072+ return 0;10731073+}10741074+10751075+static void handle_bridge_insertion(acpi_handle handle, u32 type)10761076+{10771077+ struct acpi_device *device, *pdevice;10781078+ acpi_handle phandle;10791079+10801080+ if ((type != ACPI_NOTIFY_BUS_CHECK) &&10811081+ (type != ACPI_NOTIFY_DEVICE_CHECK)) {10821082+ err("unexpected notification type %d\n", type);10831083+ return;10841084+ }10851085+10861086+ acpi_get_parent(handle, &phandle);10871087+ if (acpi_bus_get_device(phandle, &pdevice)) {10881088+ dbg("no parent device, assuming NULL\n");10891089+ pdevice = NULL;10901090+ }10911091+ if (acpi_bus_add(&device, pdevice, handle, ACPI_BUS_TYPE_DEVICE)) {10921092+ err("cannot add bridge to acpi list\n");10931093+ return;10941094+ }10951095+ if (!acpiphp_configure_bridge(handle) &&10961096+ !acpi_bus_start(device))10971097+ add_bridge(handle);10981098+ else10991099+ err("cannot configure and start bridge\n");11001100+9631101}96411029651103/*···1120982 char objname[64];1121983 struct acpi_buffer buffer = { .length = sizeof(objname),1122984 .pointer = objname };985985+ struct acpi_device *device;112398611241124- bridge = (struct acpiphp_bridge *)context;987987+ if (acpi_bus_get_device(handle, &device)) {988988+ /* This bridge must have just been physically inserted */989989+ handle_bridge_insertion(handle, type);990990+ return;991991+ }992992+993993+ bridge = acpiphp_handle_to_bridge(handle);994994+ if (!bridge) {995995+ err("cannot get bridge info\n");996996+ return;997997+ }11259981126999 acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);11271000···11801031 }11811032}1182103311831183-11841034/**11851035 * handle_hotplug_event_func - handle ACPI event on functions (i.e. slots)11861036 *···12221074 case ACPI_NOTIFY_EJECT_REQUEST:12231075 /* request device eject */12241076 dbg("%s: Device eject notify on %s\n", __FUNCTION__, objname);12251225- acpiphp_disable_slot(func->slot);10771077+ if (!(acpiphp_disable_slot(func->slot)))10781078+ acpiphp_eject_slot(func->slot);12261079 break;1227108012281081 default:···12321083 }12331084}1234108510861086+static int is_root_bridge(acpi_handle handle)10871087+{10881088+ acpi_status status;10891089+ struct acpi_device_info *info;10901090+ struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};10911091+ int i;10921092+10931093+ status = acpi_get_object_info(handle, &buffer);10941094+ if (ACPI_SUCCESS(status)) {10951095+ info = buffer.pointer;10961096+ if ((info->valid & ACPI_VALID_HID) &&10971097+ !strcmp(PCI_ROOT_HID_STRING,10981098+ info->hardware_id.value)) {10991099+ acpi_os_free(buffer.pointer);11001100+ return 1;11011101+ }11021102+ if (info->valid & ACPI_VALID_CID) {11031103+ for (i=0; i < info->compatibility_id.count; i++) {11041104+ if (!strcmp(PCI_ROOT_HID_STRING,11051105+ info->compatibility_id.id[i].value)) {11061106+ acpi_os_free(buffer.pointer);11071107+ return 1;11081108+ }11091109+ }11101110+ }11111111+ }11121112+ return 0;11131113+}11141114+11151115+static acpi_status11161116+find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv)11171117+{11181118+ int *count = (int *)context;11191119+11201120+ if (is_root_bridge(handle)) {11211121+ acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,11221122+ handle_hotplug_event_bridge, NULL);11231123+ (*count)++;11241124+ }11251125+ return AE_OK ;11261126+}1235112712361128static struct acpi_pci_driver acpi_pci_hp_driver = {12371129 .add = add_bridge,···12851095 */12861096int __init acpiphp_glue_init(void)12871097{12881288- int num;10981098+ int num = 0;1289109912901290- if (list_empty(&pci_root_buses))12911291- return -1;12921292-12931293- num = acpi_pci_register_driver(&acpi_pci_hp_driver);11001100+ acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,11011101+ ACPI_UINT32_MAX, find_root_bridges, &num, NULL);1294110212951103 if (num <= 0)12961104 return -1;11051105+ else11061106+ acpi_pci_register_driver(&acpi_pci_hp_driver);1297110712981108 return 0;12991109}···13061116 */13071117void __exit acpiphp_glue_exit(void)13081118{13091309- struct list_head *l1, *l2, *n1, *n2;13101310- struct acpiphp_bridge *bridge;13111311- struct acpiphp_slot *slot, *next;13121312- struct acpiphp_func *func;13131313- acpi_status status;13141314-13151315- list_for_each_safe (l1, n1, &bridge_list) {13161316- bridge = (struct acpiphp_bridge *)l1;13171317- slot = bridge->slots;13181318- while (slot) {13191319- next = slot->next;13201320- list_for_each_safe (l2, n2, &slot->funcs) {13211321- func = list_entry(l2, struct acpiphp_func, sibling);13221322- acpiphp_free_resource(&func->io_head);13231323- acpiphp_free_resource(&func->mem_head);13241324- acpiphp_free_resource(&func->p_mem_head);13251325- acpiphp_free_resource(&func->bus_head);13261326- status = acpi_remove_notify_handler(func->handle,13271327- ACPI_SYSTEM_NOTIFY,13281328- handle_hotplug_event_func);13291329- if (ACPI_FAILURE(status))13301330- err("failed to remove notify handler\n");13311331- kfree(func);13321332- }13331333- kfree(slot);13341334- slot = next;13351335- }13361336- status = acpi_remove_notify_handler(bridge->handle, ACPI_SYSTEM_NOTIFY,13371337- handle_hotplug_event_bridge);13381338- if (ACPI_FAILURE(status))13391339- err("failed to remove notify handler\n");13401340-13411341- acpiphp_free_resource(&bridge->io_head);13421342- acpiphp_free_resource(&bridge->mem_head);13431343- acpiphp_free_resource(&bridge->p_mem_head);13441344- acpiphp_free_resource(&bridge->bus_head);13451345-13461346- kfree(bridge);13471347- }13481348-13491119 acpi_pci_unregister_driver(&acpi_pci_hp_driver);13501120}13511121···1323117313241174 list_for_each (node, &bridge_list) {13251175 bridge = (struct acpiphp_bridge *)node;13261326- dbg("Bus%d %dslot(s)\n", bridge->bus, bridge->nr_slots);11761176+ dbg("Bus %04x:%02x has %d slot%s\n",11771177+ pci_domain_nr(bridge->pci_bus),11781178+ bridge->pci_bus->number, bridge->nr_slots,11791179+ bridge->nr_slots == 1 ? "" : "s");13271180 num_slots += bridge->nr_slots;13281181 }1329118213301330- dbg("Total %dslots\n", num_slots);11831183+ dbg("Total %d slots\n", num_slots);13311184 return num_slots;13321185}13331186···14071254 return retval;14081255}1409125614101410-14111257/**14121258 * acpiphp_disable_slot - power off slot14131259 */···14261274 if (retval)14271275 goto err_exit;1428127614291429- acpiphp_resource_sort_and_combine(&slot->bridge->io_head);14301430- acpiphp_resource_sort_and_combine(&slot->bridge->mem_head);14311431- acpiphp_resource_sort_and_combine(&slot->bridge->p_mem_head);14321432- acpiphp_resource_sort_and_combine(&slot->bridge->bus_head);14331433- dbg("Available resources:\n");14341434- acpiphp_dump_resource(slot->bridge);14351435-14361277 err_exit:14371278 up(&slot->crit_sect);14381279 return retval;···14381293 */14391294u8 acpiphp_get_power_status(struct acpiphp_slot *slot)14401295{14411441- unsigned int sta;14421442-14431443- sta = get_slot_status(slot);14441444-14451445- return (sta & ACPI_STA_ENABLED) ? 1 : 0;12961296+ return (slot->flags & SLOT_POWEREDON);14461297}1447129814481299···14761335u32 acpiphp_get_address(struct acpiphp_slot *slot)14771336{14781337 u32 address;13381338+ struct pci_bus *pci_bus = slot->bridge->pci_bus;1479133914801480- address = ((slot->bridge->seg) << 16) |14811481- ((slot->bridge->bus) << 8) |13401340+ address = (pci_domain_nr(pci_bus) << 16) |13411341+ (pci_bus->number << 8) |14821342 slot->device;1483134314841344 return address;
-449
drivers/pci/hotplug/acpiphp_pci.c
···11-/*22- * ACPI PCI HotPlug PCI configuration space management33- *44- * Copyright (C) 1995,2001 Compaq Computer Corporation55- * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)66- * Copyright (C) 2001,2002 IBM Corp.77- * Copyright (C) 2002 Takayoshi Kochi (t-kochi@bq.jp.nec.com)88- * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)99- * Copyright (C) 2002 NEC Corporation1010- *1111- * All rights reserved.1212- *1313- * This program is free software; you can redistribute it and/or modify1414- * it under the terms of the GNU General Public License as published by1515- * the Free Software Foundation; either version 2 of the License, or (at1616- * your option) any later version.1717- *1818- * This program is distributed in the hope that it will be useful, but1919- * WITHOUT ANY WARRANTY; without even the implied warranty of2020- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or2121- * NON INFRINGEMENT. See the GNU General Public License for more2222- * details.2323- *2424- * You should have received a copy of the GNU General Public License2525- * along with this program; if not, write to the Free Software2626- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.2727- *2828- * Send feedback to <t-kochi@bq.jp.nec.com>2929- *3030- */3131-3232-#include <linux/init.h>3333-#include <linux/module.h>3434-3535-#include <linux/kernel.h>3636-#include <linux/pci.h>3737-#include <linux/acpi.h>3838-#include "../pci.h"3939-#include "pci_hotplug.h"4040-#include "acpiphp.h"4141-4242-#define MY_NAME "acpiphp_pci"4343-4444-4545-/* allocate mem/pmem/io resource to a new function */4646-static int init_config_space (struct acpiphp_func *func)4747-{4848- u32 bar, len;4949- u32 address[] = {5050- PCI_BASE_ADDRESS_0,5151- PCI_BASE_ADDRESS_1,5252- PCI_BASE_ADDRESS_2,5353- PCI_BASE_ADDRESS_3,5454- PCI_BASE_ADDRESS_4,5555- PCI_BASE_ADDRESS_5,5656- 05757- };5858- int count;5959- struct acpiphp_bridge *bridge;6060- struct pci_resource *res;6161- struct pci_bus *pbus;6262- int bus, device, function;6363- unsigned int devfn;6464- u16 tmp;6565-6666- bridge = func->slot->bridge;6767- pbus = bridge->pci_bus;6868- bus = bridge->bus;6969- device = func->slot->device;7070- function = func->function;7171- devfn = PCI_DEVFN(device, function);7272-7373- for (count = 0; address[count]; count++) { /* for 6 BARs */7474- pci_bus_write_config_dword(pbus, devfn,7575- address[count], 0xFFFFFFFF);7676- pci_bus_read_config_dword(pbus, devfn, address[count], &bar);7777-7878- if (!bar) /* This BAR is not implemented */7979- continue;8080-8181- dbg("Device %02x.%02x BAR %d wants %x\n", device, function, count, bar);8282-8383- if (bar & PCI_BASE_ADDRESS_SPACE_IO) {8484- /* This is IO */8585-8686- len = bar & (PCI_BASE_ADDRESS_IO_MASK & 0xFFFF);8787- len = len & ~(len - 1);8888-8989- dbg("len in IO %x, BAR %d\n", len, count);9090-9191- spin_lock(&bridge->res_lock);9292- res = acpiphp_get_io_resource(&bridge->io_head, len);9393- spin_unlock(&bridge->res_lock);9494-9595- if (!res) {9696- err("cannot allocate requested io for %02x:%02x.%d len %x\n",9797- bus, device, function, len);9898- return -1;9999- }100100- pci_bus_write_config_dword(pbus, devfn,101101- address[count],102102- (u32)res->base);103103- res->next = func->io_head;104104- func->io_head = res;105105-106106- } else {107107- /* This is Memory */108108- if (bar & PCI_BASE_ADDRESS_MEM_PREFETCH) {109109- /* pfmem */110110-111111- len = bar & 0xFFFFFFF0;112112- len = ~len + 1;113113-114114- dbg("len in PFMEM %x, BAR %d\n", len, count);115115-116116- spin_lock(&bridge->res_lock);117117- res = acpiphp_get_resource(&bridge->p_mem_head, len);118118- spin_unlock(&bridge->res_lock);119119-120120- if (!res) {121121- err("cannot allocate requested pfmem for %02x:%02x.%d len %x\n",122122- bus, device, function, len);123123- return -1;124124- }125125-126126- pci_bus_write_config_dword(pbus, devfn,127127- address[count],128128- (u32)res->base);129129-130130- if (bar & PCI_BASE_ADDRESS_MEM_TYPE_64) { /* takes up another dword */131131- dbg("inside the pfmem 64 case, count %d\n", count);132132- count += 1;133133- pci_bus_write_config_dword(pbus, devfn,134134- address[count],135135- (u32)(res->base >> 32));136136- }137137-138138- res->next = func->p_mem_head;139139- func->p_mem_head = res;140140-141141- } else {142142- /* regular memory */143143-144144- len = bar & 0xFFFFFFF0;145145- len = ~len + 1;146146-147147- dbg("len in MEM %x, BAR %d\n", len, count);148148-149149- spin_lock(&bridge->res_lock);150150- res = acpiphp_get_resource(&bridge->mem_head, len);151151- spin_unlock(&bridge->res_lock);152152-153153- if (!res) {154154- err("cannot allocate requested pfmem for %02x:%02x.%d len %x\n",155155- bus, device, function, len);156156- return -1;157157- }158158-159159- pci_bus_write_config_dword(pbus, devfn,160160- address[count],161161- (u32)res->base);162162-163163- if (bar & PCI_BASE_ADDRESS_MEM_TYPE_64) {164164- /* takes up another dword */165165- dbg("inside mem 64 case, reg. mem, count %d\n", count);166166- count += 1;167167- pci_bus_write_config_dword(pbus, devfn,168168- address[count],169169- (u32)(res->base >> 32));170170- }171171-172172- res->next = func->mem_head;173173- func->mem_head = res;174174-175175- }176176- }177177- }178178-179179- /* disable expansion rom */180180- pci_bus_write_config_dword(pbus, devfn, PCI_ROM_ADDRESS, 0x00000000);181181-182182- /* set PCI parameters from _HPP */183183- pci_bus_write_config_byte(pbus, devfn, PCI_CACHE_LINE_SIZE,184184- bridge->hpp.cache_line_size);185185- pci_bus_write_config_byte(pbus, devfn, PCI_LATENCY_TIMER,186186- bridge->hpp.latency_timer);187187-188188- pci_bus_read_config_word(pbus, devfn, PCI_COMMAND, &tmp);189189- if (bridge->hpp.enable_SERR)190190- tmp |= PCI_COMMAND_SERR;191191- if (bridge->hpp.enable_PERR)192192- tmp |= PCI_COMMAND_PARITY;193193- pci_bus_write_config_word(pbus, devfn, PCI_COMMAND, tmp);194194-195195- return 0;196196-}197197-198198-/* detect_used_resource - subtract resource under dev from bridge */199199-static int detect_used_resource (struct acpiphp_bridge *bridge, struct pci_dev *dev)200200-{201201- int count;202202-203203- dbg("Device %s\n", pci_name(dev));204204-205205- for (count = 0; count < DEVICE_COUNT_RESOURCE; count++) {206206- struct pci_resource *res;207207- struct pci_resource **head;208208- unsigned long base = dev->resource[count].start;209209- unsigned long len = dev->resource[count].end - base + 1;210210- unsigned long flags = dev->resource[count].flags;211211-212212- if (!flags)213213- continue;214214-215215- dbg("BAR[%d] 0x%lx - 0x%lx (0x%lx)\n", count, base,216216- base + len - 1, flags);217217-218218- if (flags & IORESOURCE_IO) {219219- head = &bridge->io_head;220220- } else if (flags & IORESOURCE_PREFETCH) {221221- head = &bridge->p_mem_head;222222- } else {223223- head = &bridge->mem_head;224224- }225225-226226- spin_lock(&bridge->res_lock);227227- res = acpiphp_get_resource_with_base(head, base, len);228228- spin_unlock(&bridge->res_lock);229229- if (res)230230- kfree(res);231231- }232232-233233- return 0;234234-}235235-236236-237237-/**238238- * acpiphp_detect_pci_resource - detect resources under bridge239239- * @bridge: detect all resources already used under this bridge240240- *241241- * collect all resources already allocated for all devices under a bridge.242242- */243243-int acpiphp_detect_pci_resource (struct acpiphp_bridge *bridge)244244-{245245- struct list_head *l;246246- struct pci_dev *dev;247247-248248- list_for_each (l, &bridge->pci_bus->devices) {249249- dev = pci_dev_b(l);250250- detect_used_resource(bridge, dev);251251- }252252-253253- return 0;254254-}255255-256256-257257-/**258258- * acpiphp_init_slot_resource - gather resource usage information of a slot259259- * @slot: ACPI slot object to be checked, should have valid pci_dev member260260- *261261- * TBD: PCI-to-PCI bridge case262262- * use pci_dev->resource[]263263- */264264-int acpiphp_init_func_resource (struct acpiphp_func *func)265265-{266266- u64 base;267267- u32 bar, len;268268- u32 address[] = {269269- PCI_BASE_ADDRESS_0,270270- PCI_BASE_ADDRESS_1,271271- PCI_BASE_ADDRESS_2,272272- PCI_BASE_ADDRESS_3,273273- PCI_BASE_ADDRESS_4,274274- PCI_BASE_ADDRESS_5,275275- 0276276- };277277- int count;278278- struct pci_resource *res;279279- struct pci_dev *dev;280280-281281- dev = func->pci_dev;282282- dbg("Hot-pluggable device %s\n", pci_name(dev));283283-284284- for (count = 0; address[count]; count++) { /* for 6 BARs */285285- pci_read_config_dword(dev, address[count], &bar);286286-287287- if (!bar) /* This BAR is not implemented */288288- continue;289289-290290- pci_write_config_dword(dev, address[count], 0xFFFFFFFF);291291- pci_read_config_dword(dev, address[count], &len);292292-293293- if (len & PCI_BASE_ADDRESS_SPACE_IO) {294294- /* This is IO */295295- base = bar & 0xFFFFFFFC;296296- len = len & (PCI_BASE_ADDRESS_IO_MASK & 0xFFFF);297297- len = len & ~(len - 1);298298-299299- dbg("BAR[%d] %08x - %08x (IO)\n", count, (u32)base, (u32)base + len - 1);300300-301301- res = acpiphp_make_resource(base, len);302302- if (!res)303303- goto no_memory;304304-305305- res->next = func->io_head;306306- func->io_head = res;307307-308308- } else {309309- /* This is Memory */310310- base = bar & 0xFFFFFFF0;311311- if (len & PCI_BASE_ADDRESS_MEM_PREFETCH) {312312- /* pfmem */313313-314314- len &= 0xFFFFFFF0;315315- len = ~len + 1;316316-317317- if (len & PCI_BASE_ADDRESS_MEM_TYPE_64) { /* takes up another dword */318318- dbg("prefetch mem 64\n");319319- count += 1;320320- }321321- dbg("BAR[%d] %08x - %08x (PMEM)\n", count, (u32)base, (u32)base + len - 1);322322- res = acpiphp_make_resource(base, len);323323- if (!res)324324- goto no_memory;325325-326326- res->next = func->p_mem_head;327327- func->p_mem_head = res;328328-329329- } else {330330- /* regular memory */331331-332332- len &= 0xFFFFFFF0;333333- len = ~len + 1;334334-335335- if (len & PCI_BASE_ADDRESS_MEM_TYPE_64) {336336- /* takes up another dword */337337- dbg("mem 64\n");338338- count += 1;339339- }340340- dbg("BAR[%d] %08x - %08x (MEM)\n", count, (u32)base, (u32)base + len - 1);341341- res = acpiphp_make_resource(base, len);342342- if (!res)343343- goto no_memory;344344-345345- res->next = func->mem_head;346346- func->mem_head = res;347347-348348- }349349- }350350-351351- pci_write_config_dword(dev, address[count], bar);352352- }353353-#if 1354354- acpiphp_dump_func_resource(func);355355-#endif356356-357357- return 0;358358-359359- no_memory:360360- err("out of memory\n");361361- acpiphp_free_resource(&func->io_head);362362- acpiphp_free_resource(&func->mem_head);363363- acpiphp_free_resource(&func->p_mem_head);364364-365365- return -1;366366-}367367-368368-369369-/**370370- * acpiphp_configure_slot - allocate PCI resources371371- * @slot: slot to be configured372372- *373373- * initializes a PCI functions on a device inserted374374- * into the slot375375- *376376- */377377-int acpiphp_configure_slot (struct acpiphp_slot *slot)378378-{379379- struct acpiphp_func *func;380380- struct list_head *l;381381- u8 hdr;382382- u32 dvid;383383- int retval = 0;384384- int is_multi = 0;385385-386386- pci_bus_read_config_byte(slot->bridge->pci_bus,387387- PCI_DEVFN(slot->device, 0),388388- PCI_HEADER_TYPE, &hdr);389389-390390- if (hdr & 0x80)391391- is_multi = 1;392392-393393- list_for_each (l, &slot->funcs) {394394- func = list_entry(l, struct acpiphp_func, sibling);395395- if (is_multi || func->function == 0) {396396- pci_bus_read_config_dword(slot->bridge->pci_bus,397397- PCI_DEVFN(slot->device,398398- func->function),399399- PCI_VENDOR_ID, &dvid);400400- if (dvid != 0xffffffff) {401401- retval = init_config_space(func);402402- if (retval)403403- break;404404- }405405- }406406- }407407-408408- return retval;409409-}410410-411411-/**412412- * acpiphp_configure_function - configure PCI function413413- * @func: function to be configured414414- *415415- * initializes a PCI functions on a device inserted416416- * into the slot417417- *418418- */419419-int acpiphp_configure_function (struct acpiphp_func *func)420420-{421421- /* all handled by the pci core now */422422- return 0;423423-}424424-425425-/**426426- * acpiphp_unconfigure_function - unconfigure PCI function427427- * @func: function to be unconfigured428428- *429429- */430430-void acpiphp_unconfigure_function (struct acpiphp_func *func)431431-{432432- struct acpiphp_bridge *bridge;433433-434434- /* if pci_dev is NULL, ignore it */435435- if (!func->pci_dev)436436- return;437437-438438- pci_remove_bus_device(func->pci_dev);439439-440440- /* free all resources */441441- bridge = func->slot->bridge;442442-443443- spin_lock(&bridge->res_lock);444444- acpiphp_move_resource(&func->io_head, &bridge->io_head);445445- acpiphp_move_resource(&func->mem_head, &bridge->mem_head);446446- acpiphp_move_resource(&func->p_mem_head, &bridge->p_mem_head);447447- acpiphp_move_resource(&func->bus_head, &bridge->bus_head);448448- spin_unlock(&bridge->res_lock);449449-}
-700
drivers/pci/hotplug/acpiphp_res.c
···11-/*22- * ACPI PCI HotPlug Utility functions33- *44- * Copyright (C) 1995,2001 Compaq Computer Corporation55- * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)66- * Copyright (C) 2001 IBM Corp.77- * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)88- * Copyright (C) 2002 Takayoshi Kochi (t-kochi@bq.jp.nec.com)99- * Copyright (C) 2002 NEC Corporation1010- *1111- * All rights reserved.1212- *1313- * This program is free software; you can redistribute it and/or modify1414- * it under the terms of the GNU General Public License as published by1515- * the Free Software Foundation; either version 2 of the License, or (at1616- * your option) any later version.1717- *1818- * This program is distributed in the hope that it will be useful, but1919- * WITHOUT ANY WARRANTY; without even the implied warranty of2020- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or2121- * NON INFRINGEMENT. See the GNU General Public License for more2222- * details.2323- *2424- * You should have received a copy of the GNU General Public License2525- * along with this program; if not, write to the Free Software2626- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.2727- *2828- * Send feedback to <gregkh@us.ibm.com>, <t-kochi@bq.jp.nec.com>2929- *3030- */3131-3232-#include <linux/init.h>3333-#include <linux/module.h>3434-3535-#include <linux/kernel.h>3636-#include <linux/types.h>3737-#include <linux/proc_fs.h>3838-#include <linux/sysctl.h>3939-#include <linux/pci.h>4040-#include <linux/smp.h>4141-#include <linux/smp_lock.h>4242-4343-#include <linux/string.h>4444-#include <linux/mm.h>4545-#include <linux/errno.h>4646-#include <linux/ioport.h>4747-#include <linux/slab.h>4848-#include <linux/interrupt.h>4949-#include <linux/timer.h>5050-5151-#include <linux/ioctl.h>5252-#include <linux/fcntl.h>5353-5454-#include <linux/list.h>5555-5656-#include "pci_hotplug.h"5757-#include "acpiphp.h"5858-5959-#define MY_NAME "acpiphp_res"6060-6161-6262-/*6363- * sort_by_size - sort nodes by their length, smallest first6464- */6565-static int sort_by_size(struct pci_resource **head)6666-{6767- struct pci_resource *current_res;6868- struct pci_resource *next_res;6969- int out_of_order = 1;7070-7171- if (!(*head))7272- return 1;7373-7474- if (!((*head)->next))7575- return 0;7676-7777- while (out_of_order) {7878- out_of_order = 0;7979-8080- /* Special case for swapping list head */8181- if (((*head)->next) &&8282- ((*head)->length > (*head)->next->length)) {8383- out_of_order++;8484- current_res = *head;8585- *head = (*head)->next;8686- current_res->next = (*head)->next;8787- (*head)->next = current_res;8888- }8989-9090- current_res = *head;9191-9292- while (current_res->next && current_res->next->next) {9393- if (current_res->next->length > current_res->next->next->length) {9494- out_of_order++;9595- next_res = current_res->next;9696- current_res->next = current_res->next->next;9797- current_res = current_res->next;9898- next_res->next = current_res->next;9999- current_res->next = next_res;100100- } else101101- current_res = current_res->next;102102- }103103- } /* End of out_of_order loop */104104-105105- return 0;106106-}107107-108108-#if 0109109-/*110110- * sort_by_max_size - sort nodes by their length, largest first111111- */112112-static int sort_by_max_size(struct pci_resource **head)113113-{114114- struct pci_resource *current_res;115115- struct pci_resource *next_res;116116- int out_of_order = 1;117117-118118- if (!(*head))119119- return 1;120120-121121- if (!((*head)->next))122122- return 0;123123-124124- while (out_of_order) {125125- out_of_order = 0;126126-127127- /* Special case for swapping list head */128128- if (((*head)->next) &&129129- ((*head)->length < (*head)->next->length)) {130130- out_of_order++;131131- current_res = *head;132132- *head = (*head)->next;133133- current_res->next = (*head)->next;134134- (*head)->next = current_res;135135- }136136-137137- current_res = *head;138138-139139- while (current_res->next && current_res->next->next) {140140- if (current_res->next->length < current_res->next->next->length) {141141- out_of_order++;142142- next_res = current_res->next;143143- current_res->next = current_res->next->next;144144- current_res = current_res->next;145145- next_res->next = current_res->next;146146- current_res->next = next_res;147147- } else148148- current_res = current_res->next;149149- }150150- } /* End of out_of_order loop */151151-152152- return 0;153153-}154154-#endif155155-156156-/**157157- * get_io_resource - get resource for I/O ports158158- *159159- * this function sorts the resource list by size and then160160- * returns the first node of "size" length that is not in the161161- * ISA aliasing window. If it finds a node larger than "size"162162- * it will split it up.163163- *164164- * size must be a power of two.165165- *166166- * difference from get_resource is handling of ISA aliasing space.167167- *168168- */169169-struct pci_resource *acpiphp_get_io_resource (struct pci_resource **head, u32 size)170170-{171171- struct pci_resource *prevnode;172172- struct pci_resource *node;173173- struct pci_resource *split_node;174174- u64 temp_qword;175175-176176- if (!(*head))177177- return NULL;178178-179179- if (acpiphp_resource_sort_and_combine(head))180180- return NULL;181181-182182- if (sort_by_size(head))183183- return NULL;184184-185185- for (node = *head; node; node = node->next) {186186- if (node->length < size)187187- continue;188188-189189- if (node->base & (size - 1)) {190190- /* this one isn't base aligned properly191191- so we'll make a new entry and split it up */192192- temp_qword = (node->base | (size-1)) + 1;193193-194194- /* Short circuit if adjusted size is too small */195195- if ((node->length - (temp_qword - node->base)) < size)196196- continue;197197-198198- split_node = acpiphp_make_resource(node->base, temp_qword - node->base);199199-200200- if (!split_node)201201- return NULL;202202-203203- node->base = temp_qword;204204- node->length -= split_node->length;205205-206206- /* Put it in the list */207207- split_node->next = node->next;208208- node->next = split_node;209209- } /* End of non-aligned base */210210-211211- /* Don't need to check if too small since we already did */212212- if (node->length > size) {213213- /* this one is longer than we need214214- so we'll make a new entry and split it up */215215- split_node = acpiphp_make_resource(node->base + size, node->length - size);216216-217217- if (!split_node)218218- return NULL;219219-220220- node->length = size;221221-222222- /* Put it in the list */223223- split_node->next = node->next;224224- node->next = split_node;225225- } /* End of too big on top end */226226-227227- /* For IO make sure it's not in the ISA aliasing space */228228- if ((node->base & 0x300L) && !(node->base & 0xfffff000))229229- continue;230230-231231- /* If we got here, then it is the right size232232- Now take it out of the list */233233- if (*head == node) {234234- *head = node->next;235235- } else {236236- prevnode = *head;237237- while (prevnode->next != node)238238- prevnode = prevnode->next;239239-240240- prevnode->next = node->next;241241- }242242- node->next = NULL;243243- /* Stop looping */244244- break;245245- }246246-247247- return node;248248-}249249-250250-251251-#if 0252252-/**253253- * get_max_resource - get the largest resource254254- *255255- * Gets the largest node that is at least "size" big from the256256- * list pointed to by head. It aligns the node on top and bottom257257- * to "size" alignment before returning it.258258- */259259-static struct pci_resource *acpiphp_get_max_resource (struct pci_resource **head, u32 size)260260-{261261- struct pci_resource *max;262262- struct pci_resource *temp;263263- struct pci_resource *split_node;264264- u64 temp_qword;265265-266266- if (!(*head))267267- return NULL;268268-269269- if (acpiphp_resource_sort_and_combine(head))270270- return NULL;271271-272272- if (sort_by_max_size(head))273273- return NULL;274274-275275- for (max = *head;max; max = max->next) {276276-277277- /* If not big enough we could probably just bail,278278- instead we'll continue to the next. */279279- if (max->length < size)280280- continue;281281-282282- if (max->base & (size - 1)) {283283- /* this one isn't base aligned properly284284- so we'll make a new entry and split it up */285285- temp_qword = (max->base | (size-1)) + 1;286286-287287- /* Short circuit if adjusted size is too small */288288- if ((max->length - (temp_qword - max->base)) < size)289289- continue;290290-291291- split_node = acpiphp_make_resource(max->base, temp_qword - max->base);292292-293293- if (!split_node)294294- return NULL;295295-296296- max->base = temp_qword;297297- max->length -= split_node->length;298298-299299- /* Put it next in the list */300300- split_node->next = max->next;301301- max->next = split_node;302302- }303303-304304- if ((max->base + max->length) & (size - 1)) {305305- /* this one isn't end aligned properly at the top306306- so we'll make a new entry and split it up */307307- temp_qword = ((max->base + max->length) & ~(size - 1));308308-309309- split_node = acpiphp_make_resource(temp_qword,310310- max->length + max->base - temp_qword);311311-312312- if (!split_node)313313- return NULL;314314-315315- max->length -= split_node->length;316316-317317- /* Put it in the list */318318- split_node->next = max->next;319319- max->next = split_node;320320- }321321-322322- /* Make sure it didn't shrink too much when we aligned it */323323- if (max->length < size)324324- continue;325325-326326- /* Now take it out of the list */327327- temp = (struct pci_resource*) *head;328328- if (temp == max) {329329- *head = max->next;330330- } else {331331- while (temp && temp->next != max) {332332- temp = temp->next;333333- }334334-335335- temp->next = max->next;336336- }337337-338338- max->next = NULL;339339- return max;340340- }341341-342342- /* If we get here, we couldn't find one */343343- return NULL;344344-}345345-#endif346346-347347-/**348348- * get_resource - get resource (mem, pfmem)349349- *350350- * this function sorts the resource list by size and then351351- * returns the first node of "size" length. If it finds a node352352- * larger than "size" it will split it up.353353- *354354- * size must be a power of two.355355- *356356- */357357-struct pci_resource *acpiphp_get_resource (struct pci_resource **head, u32 size)358358-{359359- struct pci_resource *prevnode;360360- struct pci_resource *node;361361- struct pci_resource *split_node;362362- u64 temp_qword;363363-364364- if (!(*head))365365- return NULL;366366-367367- if (acpiphp_resource_sort_and_combine(head))368368- return NULL;369369-370370- if (sort_by_size(head))371371- return NULL;372372-373373- for (node = *head; node; node = node->next) {374374- dbg("%s: req_size =%x node=%p, base=%x, length=%x\n",375375- __FUNCTION__, size, node, (u32)node->base, node->length);376376- if (node->length < size)377377- continue;378378-379379- if (node->base & (size - 1)) {380380- dbg("%s: not aligned\n", __FUNCTION__);381381- /* this one isn't base aligned properly382382- so we'll make a new entry and split it up */383383- temp_qword = (node->base | (size-1)) + 1;384384-385385- /* Short circuit if adjusted size is too small */386386- if ((node->length - (temp_qword - node->base)) < size)387387- continue;388388-389389- split_node = acpiphp_make_resource(node->base, temp_qword - node->base);390390-391391- if (!split_node)392392- return NULL;393393-394394- node->base = temp_qword;395395- node->length -= split_node->length;396396-397397- /* Put it in the list */398398- split_node->next = node->next;399399- node->next = split_node;400400- } /* End of non-aligned base */401401-402402- /* Don't need to check if too small since we already did */403403- if (node->length > size) {404404- dbg("%s: too big\n", __FUNCTION__);405405- /* this one is longer than we need406406- so we'll make a new entry and split it up */407407- split_node = acpiphp_make_resource(node->base + size, node->length - size);408408-409409- if (!split_node)410410- return NULL;411411-412412- node->length = size;413413-414414- /* Put it in the list */415415- split_node->next = node->next;416416- node->next = split_node;417417- } /* End of too big on top end */418418-419419- dbg("%s: got one!!!\n", __FUNCTION__);420420- /* If we got here, then it is the right size421421- Now take it out of the list */422422- if (*head == node) {423423- *head = node->next;424424- } else {425425- prevnode = *head;426426- while (prevnode->next != node)427427- prevnode = prevnode->next;428428-429429- prevnode->next = node->next;430430- }431431- node->next = NULL;432432- /* Stop looping */433433- break;434434- }435435- return node;436436-}437437-438438-/**439439- * get_resource_with_base - get resource with specific base address440440- *441441- * this function442442- * returns the first node of "size" length located at specified base address.443443- * If it finds a node larger than "size" it will split it up.444444- *445445- * size must be a power of two.446446- *447447- */448448-struct pci_resource *acpiphp_get_resource_with_base (struct pci_resource **head, u64 base, u32 size)449449-{450450- struct pci_resource *prevnode;451451- struct pci_resource *node;452452- struct pci_resource *split_node;453453- u64 temp_qword;454454-455455- if (!(*head))456456- return NULL;457457-458458- if (acpiphp_resource_sort_and_combine(head))459459- return NULL;460460-461461- for (node = *head; node; node = node->next) {462462- dbg(": 1st req_base=%x req_size =%x node=%p, base=%x, length=%x\n",463463- (u32)base, size, node, (u32)node->base, node->length);464464- if (node->base > base)465465- continue;466466-467467- if ((node->base + node->length) < (base + size))468468- continue;469469-470470- if (node->base < base) {471471- dbg(": split 1\n");472472- /* this one isn't base aligned properly473473- so we'll make a new entry and split it up */474474- temp_qword = base;475475-476476- /* Short circuit if adjusted size is too small */477477- if ((node->length - (temp_qword - node->base)) < size)478478- continue;479479-480480- split_node = acpiphp_make_resource(node->base, temp_qword - node->base);481481-482482- if (!split_node)483483- return NULL;484484-485485- node->base = temp_qword;486486- node->length -= split_node->length;487487-488488- /* Put it in the list */489489- split_node->next = node->next;490490- node->next = split_node;491491- }492492-493493- dbg(": 2nd req_base=%x req_size =%x node=%p, base=%x, length=%x\n",494494- (u32)base, size, node, (u32)node->base, node->length);495495-496496- /* Don't need to check if too small since we already did */497497- if (node->length > size) {498498- dbg(": split 2\n");499499- /* this one is longer than we need500500- so we'll make a new entry and split it up */501501- split_node = acpiphp_make_resource(node->base + size, node->length - size);502502-503503- if (!split_node)504504- return NULL;505505-506506- node->length = size;507507-508508- /* Put it in the list */509509- split_node->next = node->next;510510- node->next = split_node;511511- } /* End of too big on top end */512512-513513- dbg(": got one!!!\n");514514- /* If we got here, then it is the right size515515- Now take it out of the list */516516- if (*head == node) {517517- *head = node->next;518518- } else {519519- prevnode = *head;520520- while (prevnode->next != node)521521- prevnode = prevnode->next;522522-523523- prevnode->next = node->next;524524- }525525- node->next = NULL;526526- /* Stop looping */527527- break;528528- }529529- return node;530530-}531531-532532-533533-/**534534- * acpiphp_resource_sort_and_combine535535- *536536- * Sorts all of the nodes in the list in ascending order by537537- * their base addresses. Also does garbage collection by538538- * combining adjacent nodes.539539- *540540- * returns 0 if success541541- */542542-int acpiphp_resource_sort_and_combine (struct pci_resource **head)543543-{544544- struct pci_resource *node1;545545- struct pci_resource *node2;546546- int out_of_order = 1;547547-548548- if (!(*head))549549- return 1;550550-551551- dbg("*head->next = %p\n",(*head)->next);552552-553553- if (!(*head)->next)554554- return 0; /* only one item on the list, already sorted! */555555-556556- dbg("*head->base = 0x%x\n",(u32)(*head)->base);557557- dbg("*head->next->base = 0x%x\n", (u32)(*head)->next->base);558558- while (out_of_order) {559559- out_of_order = 0;560560-561561- /* Special case for swapping list head */562562- if (((*head)->next) &&563563- ((*head)->base > (*head)->next->base)) {564564- node1 = *head;565565- (*head) = (*head)->next;566566- node1->next = (*head)->next;567567- (*head)->next = node1;568568- out_of_order++;569569- }570570-571571- node1 = (*head);572572-573573- while (node1->next && node1->next->next) {574574- if (node1->next->base > node1->next->next->base) {575575- out_of_order++;576576- node2 = node1->next;577577- node1->next = node1->next->next;578578- node1 = node1->next;579579- node2->next = node1->next;580580- node1->next = node2;581581- } else582582- node1 = node1->next;583583- }584584- } /* End of out_of_order loop */585585-586586- node1 = *head;587587-588588- while (node1 && node1->next) {589589- if ((node1->base + node1->length) == node1->next->base) {590590- /* Combine */591591- dbg("8..\n");592592- node1->length += node1->next->length;593593- node2 = node1->next;594594- node1->next = node1->next->next;595595- kfree(node2);596596- } else597597- node1 = node1->next;598598- }599599-600600- return 0;601601-}602602-603603-604604-/**605605- * acpiphp_make_resource - make resource structure606606- * @base: base address of a resource607607- * @length: length of a resource608608- */609609-struct pci_resource *acpiphp_make_resource (u64 base, u32 length)610610-{611611- struct pci_resource *res;612612-613613- res = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);614614- if (res) {615615- memset(res, 0, sizeof(struct pci_resource));616616- res->base = base;617617- res->length = length;618618- }619619-620620- return res;621621-}622622-623623-624624-/**625625- * acpiphp_move_resource - move linked resources from one to another626626- * @from: head of linked resource list627627- * @to: head of linked resource list628628- */629629-void acpiphp_move_resource (struct pci_resource **from, struct pci_resource **to)630630-{631631- struct pci_resource *tmp;632632-633633- while (*from) {634634- tmp = (*from)->next;635635- (*from)->next = *to;636636- *to = *from;637637- *from = tmp;638638- }639639-640640- /* *from = NULL is guaranteed */641641-}642642-643643-644644-/**645645- * acpiphp_free_resource - free all linked resources646646- * @res: head of linked resource list647647- */648648-void acpiphp_free_resource (struct pci_resource **res)649649-{650650- struct pci_resource *tmp;651651-652652- while (*res) {653653- tmp = (*res)->next;654654- kfree(*res);655655- *res = tmp;656656- }657657-658658- /* *res = NULL is guaranteed */659659-}660660-661661-662662-/* debug support functions; will go away sometime :) */663663-static void dump_resource(struct pci_resource *head)664664-{665665- struct pci_resource *p;666666- int cnt;667667-668668- p = head;669669- cnt = 0;670670-671671- while (p) {672672- dbg("[%02d] %08x - %08x\n",673673- cnt++, (u32)p->base, (u32)p->base + p->length - 1);674674- p = p->next;675675- }676676-}677677-678678-void acpiphp_dump_resource(struct acpiphp_bridge *bridge)679679-{680680- dbg("I/O resource:\n");681681- dump_resource(bridge->io_head);682682- dbg("MEM resource:\n");683683- dump_resource(bridge->mem_head);684684- dbg("PMEM resource:\n");685685- dump_resource(bridge->p_mem_head);686686- dbg("BUS resource:\n");687687- dump_resource(bridge->bus_head);688688-}689689-690690-void acpiphp_dump_func_resource(struct acpiphp_func *func)691691-{692692- dbg("I/O resource:\n");693693- dump_resource(func->io_head);694694- dbg("MEM resource:\n");695695- dump_resource(func->mem_head);696696- dbg("PMEM resource:\n");697697- dump_resource(func->p_mem_head);698698- dbg("BUS resource:\n");699699- dump_resource(func->bus_head);700700-}
+3-2
drivers/pci/hotplug/cpqphp_core.c
···6060static void __iomem *cpqhp_rom_start;6161static int power_mode;6262static int debug;6363+static int initialized;63646465#define DRIVER_VERSION "0.9.8"6566#define DRIVER_AUTHOR "Dan Zink <dan.zink@compaq.com>, Greg Kroah-Hartman <greg@kroah.com>"···12721271{12731272 int loop;12741273 int retval = 0;12751275- static int initialized = 0;1276127412771275 if (initialized)12781276 return 0;···14411441 }1442144214431443 // Stop the notification mechanism14441444- cpqhp_event_stop_thread();14441444+ if (initialized)14451445+ cpqhp_event_stop_thread();1445144614461447 //unmap the rom address14471448 if (cpqhp_rom_start)
+35-57
drivers/pci/msi.c
···2828static kmem_cache_t* msi_cachep;29293030static int pci_msi_enable = 1;3131-static int last_alloc_vector = 0;3232-static int nr_released_vectors = 0;3131+static int last_alloc_vector;3232+static int nr_released_vectors;3333static int nr_reserved_vectors = NR_HP_RESERVED_VECTORS;3434-static int nr_msix_devices = 0;3434+static int nr_msix_devices;35353636#ifndef CONFIG_X86_IO_APIC3737int vector_irq[NR_VECTORS] = { [0 ... NR_VECTORS - 1] = -1};···170170 return 0; /* never anything pending */171171}172172173173-static void release_msi(unsigned int vector);174174-static void shutdown_msi_irq(unsigned int vector)175175-{176176- release_msi(vector);177177-}178178-179179-#define shutdown_msi_irq_wo_maskbit shutdown_msi_irq180180-static void enable_msi_irq_wo_maskbit(unsigned int vector) {}181181-static void disable_msi_irq_wo_maskbit(unsigned int vector) {}182182-static void ack_msi_irq_wo_maskbit(unsigned int vector) {}183183-static void end_msi_irq_wo_maskbit(unsigned int vector)184184-{185185- move_msi(vector);186186- ack_APIC_irq();187187-}188188-189173static unsigned int startup_msi_irq_w_maskbit(unsigned int vector)174174+{175175+ startup_msi_irq_wo_maskbit(vector);176176+ unmask_MSI_irq(vector);177177+ return 0; /* never anything pending */178178+}179179+180180+static void shutdown_msi_irq(unsigned int vector)190181{191182 struct msi_desc *entry;192183 unsigned long flags;193184194185 spin_lock_irqsave(&msi_lock, flags);195186 entry = msi_desc[vector];196196- if (!entry || !entry->dev) {197197- spin_unlock_irqrestore(&msi_lock, flags);198198- return 0;199199- }200200- entry->msi_attrib.state = 1; /* Mark it active */187187+ if (entry && entry->dev)188188+ entry->msi_attrib.state = 0; /* Mark it not active */201189 spin_unlock_irqrestore(&msi_lock, flags);202202-203203- unmask_MSI_irq(vector);204204- return 0; /* never anything pending */205190}206191207207-#define shutdown_msi_irq_w_maskbit shutdown_msi_irq208208-#define enable_msi_irq_w_maskbit unmask_MSI_irq209209-#define disable_msi_irq_w_maskbit mask_MSI_irq210210-#define ack_msi_irq_w_maskbit mask_MSI_irq192192+static void end_msi_irq_wo_maskbit(unsigned int vector)193193+{194194+ move_msi(vector);195195+ ack_APIC_irq();196196+}211197212198static void end_msi_irq_w_maskbit(unsigned int vector)213199{214200 move_msi(vector);215201 unmask_MSI_irq(vector);216202 ack_APIC_irq();203203+}204204+205205+static void do_nothing(unsigned int vector)206206+{217207}218208219209/*···213223static struct hw_interrupt_type msix_irq_type = {214224 .typename = "PCI-MSI-X",215225 .startup = startup_msi_irq_w_maskbit,216216- .shutdown = shutdown_msi_irq_w_maskbit,217217- .enable = enable_msi_irq_w_maskbit,218218- .disable = disable_msi_irq_w_maskbit,219219- .ack = ack_msi_irq_w_maskbit,226226+ .shutdown = shutdown_msi_irq,227227+ .enable = unmask_MSI_irq,228228+ .disable = mask_MSI_irq,229229+ .ack = mask_MSI_irq,220230 .end = end_msi_irq_w_maskbit,221231 .set_affinity = set_msi_irq_affinity222232};···229239static struct hw_interrupt_type msi_irq_w_maskbit_type = {230240 .typename = "PCI-MSI",231241 .startup = startup_msi_irq_w_maskbit,232232- .shutdown = shutdown_msi_irq_w_maskbit,233233- .enable = enable_msi_irq_w_maskbit,234234- .disable = disable_msi_irq_w_maskbit,235235- .ack = ack_msi_irq_w_maskbit,242242+ .shutdown = shutdown_msi_irq,243243+ .enable = unmask_MSI_irq,244244+ .disable = mask_MSI_irq,245245+ .ack = mask_MSI_irq,236246 .end = end_msi_irq_w_maskbit,237247 .set_affinity = set_msi_irq_affinity238248};···245255static struct hw_interrupt_type msi_irq_wo_maskbit_type = {246256 .typename = "PCI-MSI",247257 .startup = startup_msi_irq_wo_maskbit,248248- .shutdown = shutdown_msi_irq_wo_maskbit,249249- .enable = enable_msi_irq_wo_maskbit,250250- .disable = disable_msi_irq_wo_maskbit,251251- .ack = ack_msi_irq_wo_maskbit,258258+ .shutdown = shutdown_msi_irq,259259+ .enable = do_nothing,260260+ .disable = do_nothing,261261+ .ack = do_nothing,252262 .end = end_msi_irq_wo_maskbit,253263 .set_affinity = set_msi_irq_affinity254264};···397407{398408 struct msi_desc *entry;399409400400- entry = (struct msi_desc*) kmem_cache_alloc(msi_cachep, SLAB_KERNEL);410410+ entry = kmem_cache_alloc(msi_cachep, SLAB_KERNEL);401411 if (!entry)402412 return NULL;403413···786796 }787797}788798789789-static void release_msi(unsigned int vector)790790-{791791- struct msi_desc *entry;792792- unsigned long flags;793793-794794- spin_lock_irqsave(&msi_lock, flags);795795- entry = msi_desc[vector];796796- if (entry && entry->dev)797797- entry->msi_attrib.state = 0; /* Mark it not active */798798- spin_unlock_irqrestore(&msi_lock, flags);799799-}800800-801799static int msi_free_vector(struct pci_dev* dev, int vector, int reassign)802800{803801 struct msi_desc *entry;···902924/**903925 * pci_enable_msix - configure device's MSI-X capability structure904926 * @dev: pointer to the pci_dev data structure of MSI-X device function905905- * @data: pointer to an array of MSI-X entries927927+ * @entries: pointer to an array of MSI-X entries906928 * @nvec: number of MSI-X vectors requested for allocation by device driver907929 *908930 * Setup the MSI-X capability structure of device function with the number
···6060 char * str = buf;6161 int i;6262 int max = 7;6363+ u64 start, end;63646465 if (pci_dev->subordinate)6566 max = DEVICE_COUNT_RESOURCE;66676768 for (i = 0; i < max; i++) {6868- str += sprintf(str,"0x%016lx 0x%016lx 0x%016lx\n",6969- pci_resource_start(pci_dev,i),7070- pci_resource_end(pci_dev,i),7171- pci_resource_flags(pci_dev,i));6969+ struct resource *res = &pci_dev->resource[i];7070+ pci_resource_to_user(pci_dev, i, res, &start, &end);7171+ str += sprintf(str,"0x%016llx 0x%016llx 0x%016llx\n",7272+ (unsigned long long)start,7373+ (unsigned long long)end,7474+ (unsigned long long)res->flags);7275 }7376 return (str - buf);7477}···316313 struct device, kobj));317314 struct resource *res = (struct resource *)attr->private;318315 enum pci_mmap_state mmap_type;316316+ u64 start, end;317317+ int i;319318320320- vma->vm_pgoff += res->start >> PAGE_SHIFT;319319+ for (i = 0; i < PCI_ROM_RESOURCE; i++)320320+ if (res == &pdev->resource[i])321321+ break;322322+ if (i >= PCI_ROM_RESOURCE)323323+ return -ENODEV;324324+325325+ /* pci_mmap_page_range() expects the same kind of entry as coming326326+ * from /proc/bus/pci/ which is a "user visible" value. If this is327327+ * different from the resource itself, arch will do necessary fixup.328328+ */329329+ pci_resource_to_user(pdev, i, res, &start, &end);330330+ vma->vm_pgoff += start >> PAGE_SHIFT;321331 mmap_type = res->flags & IORESOURCE_MEM ? pci_mmap_mem : pci_mmap_io;322332323333 return pci_mmap_page_range(pdev, vma, mmap_type, 0);
+22-7
drivers/pci/probe.c
···374374 struct pci_bus *child;375375376376 child = pci_alloc_child_bus(parent, dev, busnr);377377- if (child)377377+ if (child) {378378+ spin_lock(&pci_bus_lock);378379 list_add_tail(&child->node, &parent->children);380380+ spin_unlock(&pci_bus_lock);381381+ }379382 return child;380383}381384···414411{415412 struct pci_bus *child;416413 int is_cardbus = (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS);417417- u32 buses;414414+ u32 buses, i;418415 u16 bctl;419416420417 pci_read_config_dword(dev, PCI_PRIMARY_BUS, &buses);···450447 return max;451448 }452449453453- child = pci_alloc_child_bus(bus, dev, busnr);450450+ child = pci_add_new_bus(bus, dev, busnr);454451 if (!child)455452 return max;456453 child->primary = buses & 0xFF;···473470 /* Clear errors */474471 pci_write_config_word(dev, PCI_STATUS, 0xffff);475472476476- child = pci_alloc_child_bus(bus, dev, ++max);473473+ /* Prevent assigning a bus number that already exists.474474+ * This can happen when a bridge is hot-plugged */475475+ if (pci_find_bus(pci_domain_nr(bus), max+1))476476+ return max;477477+ child = pci_add_new_bus(bus, dev, ++max);477478 buses = (buses & 0xff000000)478479 | ((unsigned int)(child->primary) << 0)479480 | ((unsigned int)(child->secondary) << 8)···508501 * as cards with a PCI-to-PCI bridge can be509502 * inserted later.510503 */511511- max += CARDBUS_RESERVE_BUSNR;504504+ for (i=0; i<CARDBUS_RESERVE_BUSNR; i++)505505+ if (pci_find_bus(pci_domain_nr(bus),506506+ max+i+1))507507+ break;508508+ max += i;512509 }513510 /*514511 * Set the subordinate bus number to its real value.···768757 * and the bus list for fixup functions, etc.769758 */770759 INIT_LIST_HEAD(&dev->global_list);760760+ spin_lock(&pci_bus_lock);771761 list_add_tail(&dev->bus_list, &bus->devices);762762+ spin_unlock(&pci_bus_lock);772763773764 return dev;774765}···891878 pr_debug("PCI: Bus %04x:%02x already known\n", pci_domain_nr(b), bus);892879 goto err_out;893880 }881881+ spin_lock(&pci_bus_lock);894882 list_add_tail(&b->node, &pci_root_buses);883883+ spin_unlock(&pci_bus_lock);895884896885 memset(dev, 0, sizeof(*dev));897886 dev->parent = parent;···926911927912 b->subordinate = pci_scan_child_bus(b);928913929929- pci_bus_add_devices(b);930930-931914 return b;932915933916sys_create_link_err:···935922class_dev_reg_err:936923 device_unregister(dev);937924dev_reg_err:925925+ spin_lock(&pci_bus_lock);938926 list_del(&b->node);927927+ spin_unlock(&pci_bus_lock);939928err_out:940929 kfree(dev);941930 kfree(b);
+10-4
drivers/pci/proc.c
···355355 dev->device,356356 dev->irq);357357 /* Here should be 7 and not PCI_NUM_RESOURCES as we need to preserve compatibility */358358- for(i=0; i<7; i++)358358+ for (i=0; i<7; i++) {359359+ u64 start, end;360360+ pci_resource_to_user(dev, i, &dev->resource[i], &start, &end);359361 seq_printf(m, LONG_FORMAT,360360- dev->resource[i].start |362362+ ((unsigned long)start) |361363 (dev->resource[i].flags & PCI_REGION_FLAG_MASK));362362- for(i=0; i<7; i++)364364+ }365365+ for (i=0; i<7; i++) {366366+ u64 start, end;367367+ pci_resource_to_user(dev, i, &dev->resource[i], &start, &end);363368 seq_printf(m, LONG_FORMAT,364369 dev->resource[i].start < dev->resource[i].end ?365365- dev->resource[i].end - dev->resource[i].start + 1 : 0);370370+ (unsigned long)(end - start) + 1 : 0);371371+ }366372 seq_putc(m, '\t');367373 if (drv)368374 seq_printf(m, "%s", drv->name);
+9-5
drivers/pci/remove.c
···18181919static void pci_destroy_dev(struct pci_dev *dev)2020{2121- pci_proc_detach_device(dev);2222- pci_remove_sysfs_dev_files(dev);2323- device_unregister(&dev->dev);2121+ if (!list_empty(&dev->global_list)) {2222+ pci_proc_detach_device(dev);2323+ pci_remove_sysfs_dev_files(dev);2424+ device_unregister(&dev->dev);2525+ spin_lock(&pci_bus_lock);2626+ list_del(&dev->global_list);2727+ dev->global_list.next = dev->global_list.prev = NULL;2828+ spin_unlock(&pci_bus_lock);2929+ }24302531 /* Remove the device from the device lists, and prevent any further2632 * list accesses from this device */2733 spin_lock(&pci_bus_lock);2834 list_del(&dev->bus_list);2929- list_del(&dev->global_list);3035 dev->bus_list.next = dev->bus_list.prev = NULL;3131- dev->global_list.next = dev->global_list.prev = NULL;3236 spin_unlock(&pci_bus_lock);33373438 pci_free_resources(dev);
+4-1
drivers/pci/setup-bus.c
···7272 for (list = head.next; list;) {7373 res = list->res;7474 idx = res - &list->dev->resource[0];7575- pci_assign_resource(list->dev, idx);7575+ if (pci_assign_resource(list->dev, idx)) {7676+ res->start = 0;7777+ res->flags = 0;7878+ }7679 tmp = list;7780 list = list->next;7881 kfree(tmp);
+3-5
drivers/scsi/3w-9xxx.c
···19161916} /* End __twa_shutdown() */1917191719181918/* Wrapper for __twa_shutdown */19191919-static void twa_shutdown(struct device *dev)19191919+static void twa_shutdown(struct pci_dev *pdev)19201920{19211921- struct Scsi_Host *host = pci_get_drvdata(to_pci_dev(dev));19211921+ struct Scsi_Host *host = pci_get_drvdata(pdev);19221922 TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;1923192319241924 __twa_shutdown(tw_dev);···21402140 .id_table = twa_pci_tbl,21412141 .probe = twa_probe,21422142 .remove = twa_remove,21432143- .driver = {21442144- .shutdown = twa_shutdown21452145- }21432143+ .shutdown = twa_shutdown21462144};2147214521482146/* This function is called on driver initialization */
+3-5
drivers/scsi/3w-xxxx.c
···22642264} /* End __tw_shutdown() */2265226522662266/* Wrapper for __tw_shutdown */22672267-static void tw_shutdown(struct device *dev)22672267+static void tw_shutdown(struct pci_dev *pdev)22682268{22692269- struct Scsi_Host *host = pci_get_drvdata(to_pci_dev(dev));22692269+ struct Scsi_Host *host = pci_get_drvdata(pdev);22702270 TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;2271227122722272 __tw_shutdown(tw_dev);···24512451 .id_table = tw_pci_tbl,24522452 .probe = tw_probe,24532453 .remove = tw_remove,24542454- .driver = {24552455- .shutdown = tw_shutdown24562456- }24542454+ .shutdown = tw_shutdown,24572455};2458245624592457/* This function is called on driver initialization */
+4-6
drivers/scsi/ipr.c
···6012601260136013/**60146014 * ipr_shutdown - Shutdown handler.60156015- * @dev: device struct60156015+ * @pdev: pci device struct60166016 *60176017 * This function is invoked upon system shutdown/reboot. It will issue60186018 * an adapter shutdown to the adapter to flush the write cache.···60206020 * Return value:60216021 * none60226022 **/60236023-static void ipr_shutdown(struct device *dev)60236023+static void ipr_shutdown(struct pci_dev *pdev)60246024{60256025- struct ipr_ioa_cfg *ioa_cfg = pci_get_drvdata(to_pci_dev(dev));60256025+ struct ipr_ioa_cfg *ioa_cfg = pci_get_drvdata(pdev);60266026 unsigned long lock_flags = 0;6027602760286028 spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);···60686068 .id_table = ipr_pci_table,60696069 .probe = ipr_probe,60706070 .remove = ipr_remove,60716071- .driver = {60726072- .shutdown = ipr_shutdown,60736073- },60716071+ .shutdown = ipr_shutdown,60746072};6075607360766074/**
···5757 */5858#define PCI_DMA_BUS_IS_PHYS (1)59596060+#ifdef CONFIG_PCI6161+static inline void pci_dma_burst_advice(struct pci_dev *pdev,6262+ enum pci_dma_burst_strategy *strat,6363+ unsigned long *strategy_parameter)6464+{6565+ *strat = PCI_DMA_BURST_INFINITY;6666+ *strategy_parameter = ~0UL;6767+}6868+#endif6969+6070/*6171 * These are pretty much arbitary with the CoMEM implementation.6272 * We have the whole address space to ourselves.
+10
include/asm-i386/pci.h
···9999{100100}101101102102+#ifdef CONFIG_PCI103103+static inline void pci_dma_burst_advice(struct pci_dev *pdev,104104+ enum pci_dma_burst_strategy *strat,105105+ unsigned long *strategy_parameter)106106+{107107+ *strat = PCI_DMA_BURST_INFINITY;108108+ *strategy_parameter = ~0UL;109109+}110110+#endif111111+102112#endif /* __KERNEL__ */103113104114/* implement the pci_ DMA API in terms of the generic device dma_ one */
+9-3
include/asm-ia64/iosapic.h
···7171}72727373extern void __init iosapic_system_init (int pcat_compat);7474-extern void __init iosapic_init (unsigned long address,7474+extern int __devinit iosapic_init (unsigned long address,7575 unsigned int gsi_base);7676+#ifdef CONFIG_HOTPLUG7777+extern int iosapic_remove (unsigned int gsi_base);7878+#endif /* CONFIG_HOTPLUG */7679extern int gsi_to_vector (unsigned int gsi);7780extern int gsi_to_irq (unsigned int gsi);7881extern void iosapic_enable_intr (unsigned int vector);···97949895extern void iosapic_pci_fixup (int);9996#ifdef CONFIG_NUMA100100-extern void __init map_iosapic_to_node (unsigned int, int);9797+extern void __devinit map_iosapic_to_node (unsigned int, int);10198#endif10299#else103100#define iosapic_system_init(pcat_compat) do { } while (0)104104-#define iosapic_init(address,gsi_base) do { } while (0)101101+#define iosapic_init(address,gsi_base) (-EINVAL)102102+#ifdef CONFIG_HOTPLUG103103+#define iosapic_remove(gsi_base) (-ENODEV)104104+#endif /* CONFIG_HOTPLUG */105105#define iosapic_register_intr(gsi,polarity,trigger) (gsi)106106#define iosapic_unregister_intr(irq) do { } while (0)107107#define iosapic_override_isa_irq(isa_irq,gsi,polarity,trigger) do { } while (0)
···230230/* export the pci_ DMA API in terms of the dma_ one */231231#include <asm-generic/pci-dma-compat.h>232232233233+#ifdef CONFIG_PCI234234+static inline void pci_dma_burst_advice(struct pci_dev *pdev,235235+ enum pci_dma_burst_strategy *strat,236236+ unsigned long *strategy_parameter)237237+{238238+ unsigned long cacheline_size;239239+ u8 byte;240240+241241+ pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &byte);242242+ if (byte == 0)243243+ cacheline_size = 1024;244244+ else245245+ cacheline_size = (int) byte * 4;246246+247247+ *strat = PCI_DMA_BURST_MULTIPLE;248248+ *strategy_parameter = cacheline_size;249249+}250250+#endif251251+233252extern void234253pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,235254 struct resource *res);
+16
include/asm-ppc/pci.h
···6969#define pci_unmap_len(PTR, LEN_NAME) (0)7070#define pci_unmap_len_set(PTR, LEN_NAME, VAL) do { } while (0)71717272+#ifdef CONFIG_PCI7373+static inline void pci_dma_burst_advice(struct pci_dev *pdev,7474+ enum pci_dma_burst_strategy *strat,7575+ unsigned long *strategy_parameter)7676+{7777+ *strat = PCI_DMA_BURST_INFINITY;7878+ *strategy_parameter = ~0UL;7979+}8080+#endif8181+7282/*7383 * At present there are very few 32-bit PPC machines that can have7484 * memory above the 4GB point, and we don't support that.···112102 unsigned long offset,113103 unsigned long size,114104 pgprot_t prot);105105+106106+#define HAVE_ARCH_PCI_RESOURCE_TO_USER107107+extern void pci_resource_to_user(const struct pci_dev *dev, int bar,108108+ const struct resource *rsrc,109109+ u64 *start, u64 *end);110110+115111116112#endif /* __KERNEL__ */117113
+26
include/asm-ppc64/pci.h
···7878 return 0;7979}80808181+#ifdef CONFIG_PCI8282+static inline void pci_dma_burst_advice(struct pci_dev *pdev,8383+ enum pci_dma_burst_strategy *strat,8484+ unsigned long *strategy_parameter)8585+{8686+ unsigned long cacheline_size;8787+ u8 byte;8888+8989+ pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &byte);9090+ if (byte == 0)9191+ cacheline_size = 1024;9292+ else9393+ cacheline_size = (int) byte * 4;9494+9595+ *strat = PCI_DMA_BURST_MULTIPLE;9696+ *strategy_parameter = cacheline_size;9797+}9898+#endif9999+81100extern int pci_domain_nr(struct pci_bus *bus);8210183102/* Decide whether to display the domain number in /proc */···154135 unsigned long offset,155136 unsigned long size,156137 pgprot_t prot);138138+139139+#ifdef CONFIG_PPC_MULTIPLATFORM140140+#define HAVE_ARCH_PCI_RESOURCE_TO_USER141141+extern void pci_resource_to_user(const struct pci_dev *dev, int bar,142142+ const struct resource *rsrc,143143+ u64 *start, u64 *end);144144+#endif /* CONFIG_PPC_MULTIPLATFORM */157145158146159147#endif /* __KERNEL__ */