From ffeff788d6b10e342b4a887f28d339dfec1737f6 Mon Sep 17 00:00:00 2001 From: Kristen Accardi Date: Wed, 2 Nov 2005 16:24:32 -0800 Subject: [PATCH] pci: store PCI_INTERRUPT_PIN in pci_dev Store the value of the INTERRUPT_PIN in the pci_dev structure so that it can be retrieved later. Signed-off-by: Kristen Carlson Accardi Signed-off-by: Greg Kroah-Hartman --- drivers/pci/probe.c | 1 + include/linux/pci.h | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index fce2cb2112d81..2f82e63323f3f 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -571,6 +571,7 @@ static void pci_read_irq(struct pci_dev *dev) unsigned char irq; pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &irq); + dev->pin = irq; if (irq) pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq); dev->irq = irq; diff --git a/include/linux/pci.h b/include/linux/pci.h index de690ca73d580..b32f70fe2dbd0 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -98,6 +98,7 @@ struct pci_dev { unsigned int class; /* 3 bytes: (base,sub,prog-if) */ u8 hdr_type; /* PCI header type (`multi' flag masked out) */ u8 rom_base_reg; /* which config register controls the ROM */ + u8 pin; /* which interrupt pin this device uses */ struct pci_driver *driver; /* which driver has allocated this device */ u64 dma_mask; /* Mask of the bits of bus address this -- cgit 1.2.3-korg From 8015a01486a0f789c9e98e8bf1f12a3ccb535b30 Mon Sep 17 00:00:00 2001 From: Kristen Accardi Date: Wed, 2 Nov 2005 16:24:35 -0800 Subject: [PATCH] apci: use pin stored in pci_dev Use the stored value of the Interrupt Pin, rather than try to read it again. Signed-off-by: Kristen Carlson Accardi Signed-off-by: Greg Kroah-Hartman --- drivers/acpi/pci_irq.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c index 09567c2edcfb5..e567c03b238ee 100644 --- a/drivers/acpi/pci_irq.c +++ b/drivers/acpi/pci_irq.c @@ -361,8 +361,7 @@ acpi_pci_irq_derive(struct pci_dev *dev, if ((bridge->class >> 8) == PCI_CLASS_BRIDGE_CARDBUS) { /* PC card has the same IRQ as its cardbridge */ - pci_read_config_byte(bridge, PCI_INTERRUPT_PIN, - &bridge_pin); + bridge_pin = bridge->pin; if (!bridge_pin) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No interrupt pin configured for device %s\n", @@ -412,7 +411,7 @@ int acpi_pci_irq_enable(struct pci_dev *dev) if (!dev) return_VALUE(-EINVAL); - pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); + pin = dev->pin; if (!pin) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No interrupt pin configured for device %s\n", @@ -503,7 +502,7 @@ void acpi_pci_irq_disable(struct pci_dev *dev) if (!dev || !dev->bus) return_VOID; - pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); + pin = dev->pin; if (!pin) return_VOID; pin--; -- cgit 1.2.3-korg From 514d207db1fa3c3d2bd7990ebed8d81cebc7875b Mon Sep 17 00:00:00 2001 From: Kristen Accardi Date: Wed, 2 Nov 2005 16:24:39 -0800 Subject: [PATCH] pci: use pin stored in pci_dev Use the stored value of the interrupt pin rather than try to read the config again. Signed-off-by: Kristen Carlson Accardi Signed-off-by: Greg Kroah-Hartman --- drivers/pci/pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 8e287a828d5d3..81b9b8d9bceb3 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -587,7 +587,7 @@ pci_get_interrupt_pin(struct pci_dev *dev, struct pci_dev **bridge) { u8 pin; - pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); + pin = dev->pin; if (!pin) return -1; pin--; -- cgit 1.2.3-korg From 3efd273b4d52f0d3ae5ce61b2161cb3752f360a0 Mon Sep 17 00:00:00 2001 From: Kristen Accardi Date: Wed, 2 Nov 2005 16:55:49 -0800 Subject: [PATCH] pci: call pci_read_irq for bridges Call pci_read_irq() for bridges too, so that the pin value is stored for bridges that require interrupts. Signed-off-by: Kristen Carlson Accardi Signed-off-by: Greg Kroah-Hartman --- drivers/pci/probe.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 2f82e63323f3f..79be37a533973 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -625,6 +625,7 @@ static int pci_setup_device(struct pci_dev * dev) /* The PCI-to-PCI bridge spec requires that subtractive decoding (i.e. transparent) bridge must have programming interface code of 0x01. */ + pci_read_irq(dev); dev->transparent = ((dev->class & 0xff) == 1); pci_read_bases(dev, 2, PCI_ROM_ADDRESS1); break; -- cgit 1.2.3-korg From 7d51ceb34c7991633c36a5bab3066927ac7c661c Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Sun, 6 Nov 2005 23:39:32 -0800 Subject: [PATCH] PCI: pci_find_device remove (alpha/kernel/sys_sio.c) Signed-off-by: Jiri Slaby Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- arch/alpha/kernel/sys_sio.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/alpha/kernel/sys_sio.c b/arch/alpha/kernel/sys_sio.c index 47df48a6ddb7f..131a2d9f79d30 100644 --- a/arch/alpha/kernel/sys_sio.c +++ b/arch/alpha/kernel/sys_sio.c @@ -105,7 +105,7 @@ sio_collect_irq_levels(void) struct pci_dev *dev = NULL; /* Iterate through the devices, collecting IRQ levels. */ - while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { + for_each_pci_dev(dev) { if ((dev->class >> 16 == PCI_BASE_CLASS_BRIDGE) && (dev->class >> 8 != PCI_CLASS_BRIDGE_PCMCIA)) continue; @@ -229,8 +229,8 @@ alphabook1_init_pci(void) */ dev = NULL; - while ((dev = pci_find_device(PCI_VENDOR_ID_NCR, PCI_ANY_ID, dev))) { - if (dev->device == PCI_DEVICE_ID_NCR_53C810 + while ((dev = pci_get_device(PCI_VENDOR_ID_NCR, PCI_ANY_ID, dev))) { + if (dev->device == PCI_DEVICE_ID_NCR_53C810 || dev->device == PCI_DEVICE_ID_NCR_53C815 || dev->device == PCI_DEVICE_ID_NCR_53C820 || dev->device == PCI_DEVICE_ID_NCR_53C825) { -- cgit 1.2.3-korg From 94517252b7c8e26de7238eb2c1450cb7c69f1af6 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Sun, 6 Nov 2005 23:39:30 -0800 Subject: [PATCH] PCI: pci_find_device remove (alpha/kernel/sys_alcor.c) Signed-off-by: Jiri Slaby Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- arch/alpha/kernel/sys_alcor.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/alpha/kernel/sys_alcor.c b/arch/alpha/kernel/sys_alcor.c index 145dcde143aee..d7f0e97fe56fb 100644 --- a/arch/alpha/kernel/sys_alcor.c +++ b/arch/alpha/kernel/sys_alcor.c @@ -254,7 +254,7 @@ alcor_init_pci(void) * motherboard, by looking for a 21040 TULIP in slot 6, which is * built into XLT and BRET/MAVERICK, but not available on ALCOR. */ - dev = pci_find_device(PCI_VENDOR_ID_DEC, + dev = pci_get_device(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP, NULL); if (dev && dev->devfn == PCI_DEVFN(6,0)) { @@ -262,6 +262,7 @@ alcor_init_pci(void) printk(KERN_INFO "%s: Detected AS500 or XLT motherboard.\n", __FUNCTION__); } + pci_dev_put(dev); } -- cgit 1.2.3-korg From cee029538151c0e7bb3cd1c298f222deeecb5ab8 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Sun, 6 Nov 2005 23:39:34 -0800 Subject: [PATCH] PCI: pci_find_device remove (ppc/kernel/pci.c) Signed-off-by: Jiri Slaby Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman arch/ppc/kernel/pci.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) --- arch/ppc/kernel/pci.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/arch/ppc/kernel/pci.c b/arch/ppc/kernel/pci.c index 50c75eec8874d..704c846b2b0f5 100644 --- a/arch/ppc/kernel/pci.c +++ b/arch/ppc/kernel/pci.c @@ -503,7 +503,7 @@ pcibios_allocate_resources(int pass) u16 command; struct resource *r; - while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { + for_each_pci_dev(dev) { pci_read_config_word(dev, PCI_COMMAND, &command); for (idx = 0; idx < 6; idx++) { r = &dev->resource[idx]; @@ -540,7 +540,7 @@ pcibios_assign_resources(void) int idx; struct resource *r; - while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { + for_each_pci_dev(dev) { int class = dev->class >> 8; /* Don't touch classless devices and host bridges */ @@ -867,14 +867,15 @@ pci_device_from_OF_node(struct device_node* node, u8* bus, u8* devfn) */ if (!pci_to_OF_bus_map) return 0; - while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { - if (pci_to_OF_bus_map[dev->bus->number] != *bus) - continue; - if (dev->devfn != *devfn) - continue; - *bus = dev->bus->number; - return 0; - } + + for_each_pci_dev(dev) + if (pci_to_OF_bus_map[dev->bus->number] == *bus && + dev->devfn == *devfn) { + *bus = dev->bus->number; + pci_dev_put(dev); + return 0; + } + return -ENODEV; } EXPORT_SYMBOL(pci_device_from_OF_node); -- cgit 1.2.3-korg From 48d68773629d52ef118cd3f78eef7545d68517ef Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Sun, 6 Nov 2005 23:39:35 -0800 Subject: [PATCH] PCI: pci_find_device remove (ppc/platforms/85xx/mpc85xx_cds_common.c) Signed-off-by: Jiri Slaby Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- arch/ppc/platforms/85xx/mpc85xx_cds_common.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/arch/ppc/platforms/85xx/mpc85xx_cds_common.c b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c index 5e8cc5ec6ab5d..2959e3c4083d0 100644 --- a/arch/ppc/platforms/85xx/mpc85xx_cds_common.c +++ b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c @@ -351,10 +351,10 @@ mpc85xx_cds_fixup_via(struct pci_controller *hose) void __init mpc85xx_cds_pcibios_fixup(void) { - struct pci_dev *dev = NULL; + struct pci_dev *dev; u_char c; - if ((dev = pci_find_device(PCI_VENDOR_ID_VIA, + if ((dev = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, NULL))) { /* * U-Boot does not set the enable bits @@ -371,21 +371,24 @@ mpc85xx_cds_pcibios_fixup(void) */ dev->irq = 14; pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); + pci_dev_put(dev); } /* * Force legacy USB interrupt routing */ - if ((dev = pci_find_device(PCI_VENDOR_ID_VIA, + if ((dev = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_2, NULL))) { dev->irq = 10; pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 10); + pci_dev_put(dev); } - if ((dev = pci_find_device(PCI_VENDOR_ID_VIA, + if ((dev = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_2, dev))) { dev->irq = 11; pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 11); + pci_dev_put(dev); } } #endif /* CONFIG_PCI */ -- cgit 1.2.3-korg From 619daa2e4c80881d64875db22029a2181f07eaf9 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Sun, 6 Nov 2005 23:39:33 -0800 Subject: [PATCH] PCI: pci_find_device remove (frv/mb93090-mb00/pci-frv.c) Signed-off-by: Jiri Slaby Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- arch/frv/mb93090-mb00/pci-frv.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/arch/frv/mb93090-mb00/pci-frv.c b/arch/frv/mb93090-mb00/pci-frv.c index 83e5489cf039a..0a26bf6f1cd42 100644 --- a/arch/frv/mb93090-mb00/pci-frv.c +++ b/arch/frv/mb93090-mb00/pci-frv.c @@ -142,9 +142,7 @@ static void __init pcibios_allocate_resources(int pass) u16 command; struct resource *r, *pr; - while (dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev), - dev != NULL - ) { + for_each_pci_dev(dev) { pci_read_config_word(dev, PCI_COMMAND, &command); for(idx = 0; idx < 6; idx++) { r = &dev->resource[idx]; @@ -188,9 +186,7 @@ static void __init pcibios_assign_resources(void) int idx; struct resource *r; - while (dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev), - dev != NULL - ) { + for_each_pci_dev(dev) { int class = dev->class >> 8; /* Don't touch classless devices and host bridges */ -- cgit 1.2.3-korg From d08fa1a22e4b7240ac081ba57a67ce8e8cf94cc7 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Sun, 6 Nov 2005 23:39:35 -0800 Subject: [PATCH] PCI: pci_find_device remove (sparc64/kernel/ebus.c) Signed-off-by: Jiri Slaby Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- arch/sparc64/kernel/ebus.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/arch/sparc64/kernel/ebus.c b/arch/sparc64/kernel/ebus.c index 6ffbeb7019401..7991e919d8ab6 100644 --- a/arch/sparc64/kernel/ebus.c +++ b/arch/sparc64/kernel/ebus.c @@ -527,18 +527,12 @@ static struct pci_dev *find_next_ebus(struct pci_dev *start, int *is_rio_p) { struct pci_dev *pdev = start; - do { - pdev = pci_find_device(PCI_VENDOR_ID_SUN, PCI_ANY_ID, pdev); - if (pdev && - (pdev->device == PCI_DEVICE_ID_SUN_EBUS || - pdev->device == PCI_DEVICE_ID_SUN_RIO_EBUS)) + while ((pdev = pci_get_device(PCI_VENDOR_ID_SUN, PCI_ANY_ID, pdev))) + if (pdev->device == PCI_DEVICE_ID_SUN_EBUS || + pdev->device == PCI_DEVICE_ID_SUN_RIO_EBUS) break; - } while (pdev != NULL); - if (pdev && (pdev->device == PCI_DEVICE_ID_SUN_RIO_EBUS)) - *is_rio_p = 1; - else - *is_rio_p = 0; + *is_rio_p = !!(pdev && (pdev->device == PCI_DEVICE_ID_SUN_RIO_EBUS)); return pdev; } @@ -637,6 +631,7 @@ void __init ebus_init(void) ebus->is_rio = is_rio; ++num_ebus; } + pci_dev_put(pdev); /* XXX for the case, when ebusnd is 0, is it OK? */ #ifdef CONFIG_SUN_AUXIO auxio_probe(); -- cgit 1.2.3-korg From 3c94792f017c8c90d2ca84b0f4cd9c143471d5e3 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Sun, 6 Nov 2005 23:39:33 -0800 Subject: [PATCH] PCI: arch: pci_find_device remove (frv/mb93090-mb00/pci-irq.c) Signed-off-by: Jiri Slaby Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- arch/frv/mb93090-mb00/pci-irq.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/arch/frv/mb93090-mb00/pci-irq.c b/arch/frv/mb93090-mb00/pci-irq.c index 24622d89b1ca4..c4a1144c98b0e 100644 --- a/arch/frv/mb93090-mb00/pci-irq.c +++ b/arch/frv/mb93090-mb00/pci-irq.c @@ -48,9 +48,7 @@ void __init pcibios_fixup_irqs(void) struct pci_dev *dev = NULL; uint8_t line, pin; - while (dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev), - dev != NULL - ) { + for_each_pci_dev(dev) { pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); if (pin) { dev->irq = pci_bus0_irq_routing[PCI_SLOT(dev->devfn)][pin - 1]; -- cgit 1.2.3-korg From fb37fb960689aa1346e2621a946f230285c03593 Mon Sep 17 00:00:00 2001 From: Hanna Linder Date: Sun, 6 Nov 2005 23:39:36 -0800 Subject: [PATCH] PCI: arch/i386/pci/acpi.c: use for_each_pci_dev Signed-off-by: Hanna Linder Signed-off-by: Maximilian Attems Signed-off-by: Domen Puncer Signed-off-by: Alexey Dobriyan Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- arch/i386/pci/acpi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/i386/pci/acpi.c b/arch/i386/pci/acpi.c index 4c4522b43be5e..b33aea845f584 100644 --- a/arch/i386/pci/acpi.c +++ b/arch/i386/pci/acpi.c @@ -53,7 +53,7 @@ static int __init pci_acpi_init(void) * don't use pci_enable_device(). */ printk(KERN_INFO "PCI: Routing PCI interrupts for all devices because \"pci=routeirq\" specified\n"); - while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) + for_each_pci_dev(dev) acpi_pci_irq_enable(dev); } else printk(KERN_INFO "PCI: If a device doesn't work, try \"pci=routeirq\". If it helps, post a report\n"); -- cgit 1.2.3-korg From 8c9ad508c8737ca46a4c55b1062d159b86f7cee2 Mon Sep 17 00:00:00 2001 From: Sergey Vlasov Date: Mon, 14 Nov 2005 20:30:50 +0300 Subject: [PATCH] PCIE: make bus_id for PCI Express devices unique The bus_id string must be unique for all devices of that bus in the system, not just for devices with the same parent - otherwise multiple symlinks with identical names appear in /sys/bus/pci_express/devices. Signed-off-by: Sergey Vlasov Signed-off-by: Greg Kroah-Hartman --- drivers/pci/pcie/portdrv_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c index 467a4ceccf106..e4e5f1e8d8168 100644 --- a/drivers/pci/pcie/portdrv_core.c +++ b/drivers/pci/pcie/portdrv_core.c @@ -238,8 +238,8 @@ static void pcie_device_init(struct pci_dev *parent, struct pcie_device *dev, device->driver = NULL; device->driver_data = NULL; device->release = release_pcie_device; /* callback to free pcie dev */ - sprintf(&device->bus_id[0], "pcie%02x", - get_descriptor_id(port_type, service_type)); + snprintf(device->bus_id, sizeof(device->bus_id), "%s:pcie%02x", + pci_name(parent), get_descriptor_id(port_type, service_type)); device->parent = &parent->dev; } -- cgit 1.2.3-korg From 88d69a1dff4014889782ebad24ed3e964a8844bc Mon Sep 17 00:00:00 2001 From: "Jordan, William P" Date: Mon, 21 Nov 2005 22:51:57 -0800 Subject: [PATCH] PCI Hotplug: ibmphp_pci.c copy-n-paste fix I noticed what appears to be a cut/paste error in drivers/pci/hotplug/ibmphp_pci.c: Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/ibmphp_pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pci/hotplug/ibmphp_pci.c b/drivers/pci/hotplug/ibmphp_pci.c index b1ba429e0a2dd..155133fe5c123 100644 --- a/drivers/pci/hotplug/ibmphp_pci.c +++ b/drivers/pci/hotplug/ibmphp_pci.c @@ -969,7 +969,7 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno) debug ("io 32\n"); need_io_upper = TRUE; } - if ((io_base & PCI_PREF_RANGE_TYPE_MASK) == PCI_PREF_RANGE_TYPE_64) { + if ((pfmem_base & PCI_PREF_RANGE_TYPE_MASK) == PCI_PREF_RANGE_TYPE_64) { debug ("pfmem 64\n"); need_pfmem_upper = TRUE; } -- cgit 1.2.3-korg From 2555f7bdd3b0db47f6e1d7bb887981654e2261b3 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Mon, 21 Nov 2005 00:05:21 +0100 Subject: [PATCH] PCI Hotplug: cpqphp_ctrl.c: remove dead code The Coverity checker spotted that we already did return -ENOMEM if (!p_mem_node). Signed-off-by: Adrian Bunk Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/cpqphp_ctrl.c | 28 +++++++--------------------- 1 file changed, 7 insertions(+), 21 deletions(-) diff --git a/drivers/pci/hotplug/cpqphp_ctrl.c b/drivers/pci/hotplug/cpqphp_ctrl.c index 10a5a7674a8ac..771ed34b18198 100644 --- a/drivers/pci/hotplug/cpqphp_ctrl.c +++ b/drivers/pci/hotplug/cpqphp_ctrl.c @@ -2630,29 +2630,15 @@ static int configure_new_function(struct controller *ctrl, struct pci_func *func hold_mem_node = NULL; } - /* If we have prefetchable memory resources copy them and - * fill in the bridge's memory range registers. Otherwise, - * fill in the range registers with values that disable them. */ - if (p_mem_node) { - memcpy(hold_p_mem_node, p_mem_node, sizeof(struct pci_resource)); - p_mem_node->next = NULL; - - /* set Pre Mem base and Limit registers */ - temp_word = p_mem_node->base >> 16; - rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_BASE, temp_word); - - temp_word = (p_mem_node->base + p_mem_node->length - 1) >> 16; - rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word); - } else { - temp_word = 0xFFFF; - rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_BASE, temp_word); + memcpy(hold_p_mem_node, p_mem_node, sizeof(struct pci_resource)); + p_mem_node->next = NULL; - temp_word = 0x0000; - rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word); + /* set Pre Mem base and Limit registers */ + temp_word = p_mem_node->base >> 16; + rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_BASE, temp_word); - kfree(hold_p_mem_node); - hold_p_mem_node = NULL; - } + temp_word = (p_mem_node->base + p_mem_node->length - 1) >> 16; + rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word); /* Adjust this to compensate for extra adjustment in first loop */ irqs.barber_pole--; -- cgit 1.2.3-korg From e00e57efa3448b18c0deedce32732e28683cb73d Mon Sep 17 00:00:00 2001 From: Kenji Kaneshige Date: Fri, 25 Nov 2005 12:21:25 +0900 Subject: [PATCH] shpchp: replace pci_find_slot() with pci_get_slot() This patch replaces pci_find_slot() with pci_get_slot() in the SHPCHP driver. This enables SHPCHP driver to work on multiple PCI segment systems. Signed-off-by: Kenji Kaneshige Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/shpchp_pci.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/drivers/pci/hotplug/shpchp_pci.c b/drivers/pci/hotplug/shpchp_pci.c index 38009bc0fd5de..19e1a5e1e30b8 100644 --- a/drivers/pci/hotplug/shpchp_pci.c +++ b/drivers/pci/hotplug/shpchp_pci.c @@ -89,10 +89,11 @@ int shpchp_configure_device(struct slot *p_slot) struct pci_bus *parent = p_slot->ctrl->pci_dev->subordinate; int num, fn; - dev = pci_find_slot(p_slot->bus, PCI_DEVFN(p_slot->device, 0)); + dev = pci_get_slot(parent, PCI_DEVFN(p_slot->device, 0)); if (dev) { err("Device %s already exists at %x:%x, cannot hot-add\n", pci_name(dev), p_slot->bus, p_slot->device); + pci_dev_put(dev); return -EINVAL; } @@ -103,12 +104,13 @@ int shpchp_configure_device(struct slot *p_slot) } for (fn = 0; fn < 8; fn++) { - if (!(dev = pci_find_slot(p_slot->bus, - PCI_DEVFN(p_slot->device, fn)))) + dev = pci_get_slot(parent, PCI_DEVFN(p_slot->device, fn)); + if (!dev) continue; if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) { err("Cannot hot-add display device %s\n", pci_name(dev)); + pci_dev_put(dev); continue; } if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) || @@ -124,18 +126,21 @@ int shpchp_configure_device(struct slot *p_slot) } if (busnr >= end) { err("No free bus for hot-added bridge\n"); + pci_dev_put(dev); continue; } child = pci_add_new_bus(parent, dev, busnr); if (!child) { err("Cannot add new bus for %s\n", pci_name(dev)); + pci_dev_put(dev); continue; } child->subordinate = pci_do_scan_bus(child); pci_bus_size_bridges(child); } program_fw_provided_values(dev); + pci_dev_put(dev); } pci_bus_assign_resources(parent); @@ -149,17 +154,19 @@ int shpchp_unconfigure_device(struct slot *p_slot) int rc = 0; int j; u8 bctl = 0; - + struct pci_bus *parent = p_slot->ctrl->pci_dev->subordinate; + dbg("%s: bus/dev = %x/%x\n", __FUNCTION__, p_slot->bus, p_slot->device); for (j=0; j<8 ; j++) { - struct pci_dev* temp = pci_find_slot(p_slot->bus, + struct pci_dev* temp = pci_get_slot(parent, (p_slot->device << 3) | j); if (!temp) continue; if ((temp->class >> 16) == PCI_BASE_CLASS_DISPLAY) { err("Cannot remove display device %s\n", pci_name(temp)); + pci_dev_put(temp); continue; } if (temp->hdr_type == PCI_HEADER_TYPE_BRIDGE) { @@ -167,10 +174,12 @@ int shpchp_unconfigure_device(struct slot *p_slot) if (bctl & PCI_BRIDGE_CTL_VGA) { err("Cannot remove display device %s\n", pci_name(temp)); + pci_dev_put(temp); continue; } } pci_remove_bus_device(temp); + pci_dev_put(temp); } return rc; } -- cgit 1.2.3-korg From 6558b6ab145ceead45632e4214cd5ef14f48f412 Mon Sep 17 00:00:00 2001 From: Kenji Kaneshige Date: Thu, 24 Nov 2005 13:44:01 +0900 Subject: [PATCH] shpchp: fix improper reference to Slot Avail Regsister The hpc_get_max_bus_speed() function of the SHPCHP driver seems to refer wrong bits in the "Slot Avail Register I" and "Slot Avail Register II". This patch fixes this bug. And this also cleanup the code. Signed-off-by: Kenji Kaneshige Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/shpchp_hpc.c | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c index 9987a6fd65b85..3c1d3b4b0408e 100644 --- a/drivers/pci/hotplug/shpchp_hpc.c +++ b/drivers/pci/hotplug/shpchp_hpc.c @@ -1121,7 +1121,6 @@ static int hpc_get_max_bus_speed (struct slot *slot, enum pci_bus_speed *value) int retval = 0; u8 pi; u32 slot_avail1, slot_avail2; - int slot_num; DBG_ENTER_ROUTINE @@ -1140,39 +1139,39 @@ static int hpc_get_max_bus_speed (struct slot *slot, enum pci_bus_speed *value) slot_avail2 = readl(php_ctlr->creg + SLOT_AVAIL2); if (pi == 2) { - if ((slot_num = ((slot_avail2 & SLOT_133MHZ_PCIX_533) >> 27) ) != 0 ) + if (slot_avail2 & SLOT_133MHZ_PCIX_533) bus_speed = PCIX_133MHZ_533; - else if ((slot_num = ((slot_avail2 & SLOT_100MHZ_PCIX_533) >> 23) ) != 0 ) + else if (slot_avail2 & SLOT_100MHZ_PCIX_533) bus_speed = PCIX_100MHZ_533; - else if ((slot_num = ((slot_avail2 & SLOT_66MHZ_PCIX_533) >> 19) ) != 0 ) + else if (slot_avail2 & SLOT_66MHZ_PCIX_533) bus_speed = PCIX_66MHZ_533; - else if ((slot_num = ((slot_avail2 & SLOT_133MHZ_PCIX_266) >> 15) ) != 0 ) + else if (slot_avail2 & SLOT_133MHZ_PCIX_266) bus_speed = PCIX_133MHZ_266; - else if ((slot_num = ((slot_avail2 & SLOT_100MHZ_PCIX_266) >> 11) ) != 0 ) + else if (slot_avail2 & SLOT_100MHZ_PCIX_266) bus_speed = PCIX_100MHZ_266; - else if ((slot_num = ((slot_avail2 & SLOT_66MHZ_PCIX_266) >> 7) ) != 0 ) + else if (slot_avail2 & SLOT_66MHZ_PCIX_266) bus_speed = PCIX_66MHZ_266; - else if ((slot_num = ((slot_avail1 & SLOT_133MHZ_PCIX) >> 23) ) != 0 ) + else if (slot_avail1 & SLOT_133MHZ_PCIX) bus_speed = PCIX_133MHZ; - else if ((slot_num = ((slot_avail1 & SLOT_100MHZ_PCIX) >> 15) ) != 0 ) + else if (slot_avail1 & SLOT_100MHZ_PCIX) bus_speed = PCIX_100MHZ; - else if ((slot_num = ((slot_avail1 & SLOT_66MHZ_PCIX) >> 7) ) != 0 ) + else if (slot_avail1 & SLOT_66MHZ_PCIX) bus_speed = PCIX_66MHZ; - else if ((slot_num = (slot_avail2 & SLOT_66MHZ)) != 0 ) + else if (slot_avail2 & SLOT_66MHZ) bus_speed = PCI_66MHZ; - else if ((slot_num = (slot_avail1 & SLOT_33MHZ)) != 0 ) + else if (slot_avail1 & SLOT_33MHZ) bus_speed = PCI_33MHZ; else bus_speed = PCI_SPEED_UNKNOWN; } else { - if ((slot_num = ((slot_avail1 & SLOT_133MHZ_PCIX) >> 23) ) != 0 ) + if (slot_avail1 & SLOT_133MHZ_PCIX) bus_speed = PCIX_133MHZ; - else if ((slot_num = ((slot_avail1 & SLOT_100MHZ_PCIX) >> 15) ) != 0 ) + else if (slot_avail1 & SLOT_100MHZ_PCIX) bus_speed = PCIX_100MHZ; - else if ((slot_num = ((slot_avail1 & SLOT_66MHZ_PCIX) >> 7) ) != 0 ) + else if (slot_avail1 & SLOT_66MHZ_PCIX) bus_speed = PCIX_66MHZ; - else if ((slot_num = (slot_avail2 & SLOT_66MHZ)) != 0 ) + else if (slot_avail2 & SLOT_66MHZ) bus_speed = PCI_66MHZ; - else if ((slot_num = (slot_avail1 & SLOT_33MHZ)) != 0 ) + else if (slot_avail1 & SLOT_33MHZ) bus_speed = PCI_33MHZ; else bus_speed = PCI_SPEED_UNKNOWN; } -- cgit 1.2.3-korg From 87d6c5593111844f308af7d5106b3fd259b36514 Mon Sep 17 00:00:00 2001 From: Kenji Kaneshige Date: Thu, 24 Nov 2005 11:35:05 +0900 Subject: [PATCH] shpchp: fix improper reference to Mode 1 ECC Capability" bit The hpc_get_mode1_ECC_cap() function of SHPCHP driver seems to refer the wrong bit for refering the "Mode 1 ECC Capability" bit. This bug seems not to cause any problem so far. But I think this should be fixed. This patch fixes this bug. Signed-off-by: Kenji Kaneshige Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/shpchp_hpc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c index 3c1d3b4b0408e..f5a8bf374634a 100644 --- a/drivers/pci/hotplug/shpchp_hpc.c +++ b/drivers/pci/hotplug/shpchp_hpc.c @@ -604,7 +604,7 @@ static int hpc_get_mode1_ECC_cap(struct slot *slot, u8 *mode) sec_bus_status = readw(php_ctlr->creg + SEC_BUS_CONFIG); if (pi == 2) { - *mode = (sec_bus_status & 0x0100) >> 7; + *mode = (sec_bus_status & 0x0100) >> 8; } else { retval = -1; } -- cgit 1.2.3-korg From 0455986cce45d28511f59a29d6cecc17d6b65720 Mon Sep 17 00:00:00 2001 From: Kenji Kaneshige Date: Thu, 24 Nov 2005 11:36:59 +0900 Subject: [PATCH] shpchp: fix improper mmio mapping Current SHPCHP driver seems not to map MMIO region properly. This patch fixes this bug. This patch also cleanup the code. Signed-off-by: Kenji Kaneshige Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/shpchp.h | 3 ++ drivers/pci/hotplug/shpchp_core.c | 2 -- drivers/pci/hotplug/shpchp_hpc.c | 73 ++++++++++++++++++++++++--------------- 3 files changed, 49 insertions(+), 29 deletions(-) diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h index 08ad26a0cae70..55b0cd15f3485 100644 --- a/drivers/pci/hotplug/shpchp.h +++ b/drivers/pci/hotplug/shpchp.h @@ -98,6 +98,9 @@ struct controller { enum pci_bus_speed speed; u32 first_slot; /* First physical slot number */ u8 slot_bus; /* Bus where the slots handled by this controller sit */ + u32 cap_offset; + unsigned long mmio_base; + unsigned long mmio_size; }; struct hotplug_params { diff --git a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c index 63628e01dd436..d81f8a75b495d 100644 --- a/drivers/pci/hotplug/shpchp_core.c +++ b/drivers/pci/hotplug/shpchp_core.c @@ -377,8 +377,6 @@ static int shpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) goto err_out_free_ctrl; } - ctrl->pci_dev = pdev; /* pci_dev of the P2P bridge */ - pci_set_drvdata(pdev, ctrl); ctrl->pci_bus = kmalloc (sizeof (*ctrl->pci_bus), GFP_KERNEL); diff --git a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c index f5a8bf374634a..d82987f075b2d 100644 --- a/drivers/pci/hotplug/shpchp_hpc.c +++ b/drivers/pci/hotplug/shpchp_hpc.c @@ -791,7 +791,7 @@ static void hpc_release_ctlr(struct controller *ctrl) } if (php_ctlr->pci_dev) { iounmap(php_ctlr->creg); - release_mem_region(pci_resource_start(php_ctlr->pci_dev, 0), pci_resource_len(php_ctlr->pci_dev, 0)); + release_mem_region(ctrl->mmio_base, ctrl->mmio_size); php_ctlr->pci_dev = NULL; } @@ -1320,19 +1320,34 @@ static struct hpc_ops shpchp_hpc_ops = { .check_cmd_status = hpc_check_cmd_status, }; +inline static int shpc_indirect_creg_read(struct controller *ctrl, int index, + u32 *value) +{ + int rc; + u32 cap_offset = ctrl->cap_offset; + struct pci_dev *pdev = ctrl->pci_dev; + + rc = pci_write_config_byte(pdev, cap_offset + DWORD_SELECT, index); + if (rc) + return rc; + return pci_read_config_dword(pdev, cap_offset + DWORD_DATA, value); +} + int shpc_init(struct controller * ctrl, struct pci_dev * pdev) { struct php_ctlr_state_s *php_ctlr, *p; void *instance_id = ctrl; - int rc; + int rc, num_slots = 0; u8 hp_slot; static int first = 1; - u32 shpc_cap_offset, shpc_base_offset; + u32 shpc_base_offset; u32 tempdword, slot_reg; u8 i; DBG_ENTER_ROUTINE + ctrl->pci_dev = pdev; /* pci_dev of the P2P bridge */ + spin_lock_init(&list_lock); php_ctlr = (struct php_ctlr_state_s *) kmalloc(sizeof(struct php_ctlr_state_s), GFP_KERNEL); @@ -1347,41 +1362,45 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) if ((pdev->vendor == PCI_VENDOR_ID_AMD) || (pdev->device == PCI_DEVICE_ID_AMD_GOLAM_7450)) { - shpc_base_offset = 0; /* amd shpc driver doesn't use this; assume 0 */ + /* amd shpc driver doesn't use Base Offset; assume 0 */ + ctrl->mmio_base = pci_resource_start(pdev, 0); + ctrl->mmio_size = pci_resource_len(pdev, 0); } else { - if ((shpc_cap_offset = pci_find_capability(pdev, PCI_CAP_ID_SHPC)) == 0) { - err("%s : shpc_cap_offset == 0\n", __FUNCTION__); + ctrl->cap_offset = pci_find_capability(pdev, PCI_CAP_ID_SHPC); + if (!ctrl->cap_offset) { + err("%s : cap_offset == 0\n", __FUNCTION__); goto abort_free_ctlr; } - dbg("%s: shpc_cap_offset = %x\n", __FUNCTION__, shpc_cap_offset); - - rc = pci_write_config_byte(pdev, (u8)shpc_cap_offset + DWORD_SELECT , BASE_OFFSET); + dbg("%s: cap_offset = %x\n", __FUNCTION__, ctrl->cap_offset); + + rc = shpc_indirect_creg_read(ctrl, 0, &shpc_base_offset); if (rc) { - err("%s : pci_word_config_byte failed\n", __FUNCTION__); + err("%s: cannot read base_offset\n", __FUNCTION__); goto abort_free_ctlr; } - - rc = pci_read_config_dword(pdev, (u8)shpc_cap_offset + DWORD_DATA, &shpc_base_offset); + + rc = shpc_indirect_creg_read(ctrl, 3, &tempdword); if (rc) { - err("%s : pci_read_config_dword failed\n", __FUNCTION__); + err("%s: cannot read slot config\n", __FUNCTION__); goto abort_free_ctlr; } + num_slots = tempdword & SLOT_NUM; + dbg("%s: num_slots (indirect) %x\n", __FUNCTION__, num_slots); - for (i = 0; i <= 14; i++) { - rc = pci_write_config_byte(pdev, (u8)shpc_cap_offset + DWORD_SELECT , i); - if (rc) { - err("%s : pci_word_config_byte failed\n", __FUNCTION__); - goto abort_free_ctlr; - } - - rc = pci_read_config_dword(pdev, (u8)shpc_cap_offset + DWORD_DATA, &tempdword); + for (i = 0; i < 9 + num_slots; i++) { + rc = shpc_indirect_creg_read(ctrl, i, &tempdword); if (rc) { - err("%s : pci_read_config_dword failed\n", __FUNCTION__); + err("%s: cannot read creg (index = %d)\n", + __FUNCTION__, i); goto abort_free_ctlr; } dbg("%s: offset %d: value %x\n", __FUNCTION__,i, tempdword); } + + ctrl->mmio_base = + pci_resource_start(pdev, 0) + shpc_base_offset; + ctrl->mmio_size = 0x24 + 0x4 * num_slots; } if (first) { @@ -1395,16 +1414,16 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) if (pci_enable_device(pdev)) goto abort_free_ctlr; - if (!request_mem_region(pci_resource_start(pdev, 0) + shpc_base_offset, pci_resource_len(pdev, 0), MY_NAME)) { + if (!request_mem_region(ctrl->mmio_base, ctrl->mmio_size, MY_NAME)) { err("%s: cannot reserve MMIO region\n", __FUNCTION__); goto abort_free_ctlr; } - php_ctlr->creg = ioremap(pci_resource_start(pdev, 0) + shpc_base_offset, pci_resource_len(pdev, 0)); + php_ctlr->creg = ioremap(ctrl->mmio_base, ctrl->mmio_size); if (!php_ctlr->creg) { - err("%s: cannot remap MMIO region %lx @ %lx\n", __FUNCTION__, pci_resource_len(pdev, 0), - pci_resource_start(pdev, 0) + shpc_base_offset); - release_mem_region(pci_resource_start(pdev, 0) + shpc_base_offset, pci_resource_len(pdev, 0)); + err("%s: cannot remap MMIO region %lx @ %lx\n", __FUNCTION__, + ctrl->mmio_size, ctrl->mmio_base); + release_mem_region(ctrl->mmio_base, ctrl->mmio_size); goto abort_free_ctlr; } dbg("%s: php_ctlr->creg %p\n", __FUNCTION__, php_ctlr->creg); -- cgit 1.2.3-korg From f467f6187fc60c954a9509b3a3e17ef89a4f6f22 Mon Sep 17 00:00:00 2001 From: Kenji Kaneshige Date: Thu, 24 Nov 2005 11:39:29 +0900 Subject: [PATCH] shpchp: fix improper write to Command Completion Detect bit Current SHPCHP driver writes a '0' to the Command Completion Detect bit to clear the Command Complete Interrupt Pending. But according to the SHPC spec (See 4.7.3.1 System Interrupts), SHPCHP driver must write '1'. This patch fixes this bug. Signed-off-by: Kenji Kaneshige Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/shpchp_hpc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c index d82987f075b2d..f25e11645071c 100644 --- a/drivers/pci/hotplug/shpchp_hpc.c +++ b/drivers/pci/hotplug/shpchp_hpc.c @@ -1058,11 +1058,11 @@ static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs) if (intr_loc & 0x0001) { /* * Command Complete Interrupt Pending - * RO only - clear by writing 0 to the Command Completion + * RO only - clear by writing 1 to the Command Completion * Detect bit in Controller SERR-INT register */ temp_dword = readl(php_ctlr->creg + SERR_INTR_ENABLE); - temp_dword &= 0xfffeffff; + temp_dword &= 0xfffdffff; writel(temp_dword, php_ctlr->creg + SERR_INTR_ENABLE); wake_up_interruptible(&ctrl->queue); } -- cgit 1.2.3-korg From bd62e271401c5ebf33a0dd24d89baf706f213251 Mon Sep 17 00:00:00 2001 From: Kenji Kaneshige Date: Fri, 25 Nov 2005 12:28:53 +0900 Subject: [PATCH] shpchp: fix improper wait for command completion Current SHPCHP driver uses msleep_interruptible() function to wait for a command completion event. But I think this would cause an unnecessary long wait until timeout, if command completion interrupt came before task state was changed to TASK_INTERRUPTIBLE. This patch fixes this issue. With this patch, command completion becomes faster as follows: o Without this patch # time echo 1 > power real 0m4.708s user 0m0.000s sys 0m0.524s o With this patch # time echo 1 > power real 0m2.221s user 0m0.000s sys 0m0.532s Signed-off-by: Kenji Kaneshige Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/shpchp.h | 1 + drivers/pci/hotplug/shpchp_ctrl.c | 37 ------------------------------------- drivers/pci/hotplug/shpchp_hpc.c | 26 ++++++++++++++++++++++++++ 3 files changed, 27 insertions(+), 37 deletions(-) diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h index 55b0cd15f3485..ce0e9b6ce8337 100644 --- a/drivers/pci/hotplug/shpchp.h +++ b/drivers/pci/hotplug/shpchp.h @@ -101,6 +101,7 @@ struct controller { u32 cap_offset; unsigned long mmio_base; unsigned long mmio_size; + volatile int cmd_busy; }; struct hotplug_params { diff --git a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c index 58619359ad08f..25ccb0e475936 100644 --- a/drivers/pci/hotplug/shpchp_ctrl.c +++ b/drivers/pci/hotplug/shpchp_ctrl.c @@ -248,7 +248,6 @@ static int change_bus_speed(struct controller *ctrl, struct slot *p_slot, up(&ctrl->crit_sect); return WRONG_BUS_FREQUENCY; } - wait_for_ctrl_irq (ctrl); if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) { err("%s: Can't set bus speed/mode in the case of adapter & bus mismatch\n", @@ -330,9 +329,6 @@ static int board_added(struct slot *p_slot) up(&ctrl->crit_sect); return -1; } - - /* Wait for the command to complete */ - wait_for_ctrl_irq (ctrl); rc = p_slot->hpc_ops->check_cmd_status(ctrl); if (rc) { @@ -352,7 +348,6 @@ static int board_added(struct slot *p_slot) up(&ctrl->crit_sect); return WRONG_BUS_FREQUENCY; } - wait_for_ctrl_irq (ctrl); if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) { err("%s: Can't set bus speed/mode in the case of adapter & bus mismatch\n", @@ -367,7 +362,6 @@ static int board_added(struct slot *p_slot) up(&ctrl->crit_sect); return rc; } - wait_for_ctrl_irq (ctrl); if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) { err("%s: Failed to enable slot, error code(%d)\n", __FUNCTION__, rc); @@ -494,7 +488,6 @@ static int board_added(struct slot *p_slot) up(&ctrl->crit_sect); return rc; } - wait_for_ctrl_irq (ctrl); if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) { err("%s: Failed to enable slot, error code(%d)\n", __FUNCTION__, rc); @@ -532,9 +525,6 @@ static int board_added(struct slot *p_slot) p_slot->hpc_ops->green_led_on(p_slot); - /* Wait for the command to complete */ - wait_for_ctrl_irq (ctrl); - /* Done with exclusive hardware access */ up(&ctrl->crit_sect); @@ -552,8 +542,6 @@ err_exit: up(&ctrl->crit_sect); return rc; } - /* Wait for the command to complete */ - wait_for_ctrl_irq (ctrl); rc = p_slot->hpc_ops->check_cmd_status(ctrl); if (rc) { @@ -603,8 +591,6 @@ static int remove_board(struct slot *p_slot) up(&ctrl->crit_sect); return rc; } - /* Wait for the command to complete */ - wait_for_ctrl_irq (ctrl); rc = p_slot->hpc_ops->check_cmd_status(ctrl); if (rc) { @@ -621,8 +607,6 @@ static int remove_board(struct slot *p_slot) up(&ctrl->crit_sect); return rc; } - /* Wait for the command to complete */ - wait_for_ctrl_irq (ctrl); /* Done with exclusive hardware access */ up(&ctrl->crit_sect); @@ -676,9 +660,6 @@ static void shpchp_pushbutton_thread (unsigned long slot) p_slot->hpc_ops->green_led_off(p_slot); - /* Wait for the command to complete */ - wait_for_ctrl_irq (p_slot->ctrl); - /* Done with exclusive hardware access */ up(&p_slot->ctrl->crit_sect); } @@ -790,14 +771,9 @@ static void interrupt_event_handler(struct controller *ctrl) down(&ctrl->crit_sect); p_slot->hpc_ops->green_led_on(p_slot); - /* Wait for the command to complete */ - wait_for_ctrl_irq (ctrl); p_slot->hpc_ops->set_attention_status(p_slot, 0); - /* Wait for the command to complete */ - wait_for_ctrl_irq (ctrl); - /* Done with exclusive hardware access */ up(&ctrl->crit_sect); break; @@ -806,12 +782,8 @@ static void interrupt_event_handler(struct controller *ctrl) down(&ctrl->crit_sect); p_slot->hpc_ops->green_led_off(p_slot); - /* Wait for the command to complete */ - wait_for_ctrl_irq (ctrl); p_slot->hpc_ops->set_attention_status(p_slot, 0); - /* Wait for the command to complete */ - wait_for_ctrl_irq (ctrl); /* Done with exclusive hardware access */ up(&ctrl->crit_sect); @@ -845,14 +817,9 @@ static void interrupt_event_handler(struct controller *ctrl) /* blink green LED and turn off amber */ p_slot->hpc_ops->green_led_blink(p_slot); - /* Wait for the command to complete */ - wait_for_ctrl_irq (ctrl); p_slot->hpc_ops->set_attention_status(p_slot, 0); - /* Wait for the command to complete */ - wait_for_ctrl_irq (ctrl); - /* Done with exclusive hardware access */ up(&ctrl->crit_sect); @@ -870,12 +837,8 @@ static void interrupt_event_handler(struct controller *ctrl) down(&ctrl->crit_sect); p_slot->hpc_ops->set_attention_status(p_slot, 1); - /* Wait for the command to complete */ - wait_for_ctrl_irq (ctrl); p_slot->hpc_ops->green_led_off(p_slot); - /* Wait for the command to complete */ - wait_for_ctrl_irq (ctrl); /* Done with exclusive hardware access */ up(&ctrl->crit_sect); diff --git a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c index f25e11645071c..b4226ff3a8544 100644 --- a/drivers/pci/hotplug/shpchp_hpc.c +++ b/drivers/pci/hotplug/shpchp_hpc.c @@ -275,6 +275,25 @@ static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int seconds) return; } +static inline int shpc_wait_cmd(struct controller *ctrl) +{ + int retval = 0; + unsigned int timeout_msec = shpchp_poll_mode ? 2000 : 1000; + unsigned long timeout = msecs_to_jiffies(timeout_msec); + int rc = wait_event_interruptible_timeout(ctrl->queue, + !ctrl->cmd_busy, timeout); + if (!rc) { + retval = -EIO; + err("Command not completed in %d msec\n", timeout_msec); + } else if (rc < 0) { + retval = -EINTR; + info("Command was interrupted by a signal\n"); + } + ctrl->cmd_busy = 0; + + return retval; +} + static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd) { struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; @@ -314,8 +333,14 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd) /* To make sure the Controller Busy bit is 0 before we send out the * command. */ + slot->ctrl->cmd_busy = 1; writew(temp_word, php_ctlr->creg + CMD); + /* + * Wait for command completion. + */ + retval = shpc_wait_cmd(slot->ctrl); + DBG_LEAVE_ROUTINE return retval; } @@ -1064,6 +1089,7 @@ static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs) temp_dword = readl(php_ctlr->creg + SERR_INTR_ENABLE); temp_dword &= 0xfffdffff; writel(temp_dword, php_ctlr->creg + SERR_INTR_ENABLE); + ctrl->cmd_busy = 0; wake_up_interruptible(&ctrl->queue); } -- cgit 1.2.3-korg From 81745512c6bb78fc78265b881206b3f6800dd09f Mon Sep 17 00:00:00 2001 From: Daniel Marjamäki Date: Thu, 1 Dec 2005 18:01:28 +0100 Subject: [PATCH] PCI: irq.c: trivial printk and DBG updates MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Updated printk and DBG with appropriate KERN_*. Signed-off-by: Daniel Marjamäki Signed-off-by: Greg Kroah-Hartman --- arch/i386/pci/irq.c | 42 +++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/arch/i386/pci/irq.c b/arch/i386/pci/irq.c index ee8e01697d96c..e715aa930036a 100644 --- a/arch/i386/pci/irq.c +++ b/arch/i386/pci/irq.c @@ -78,7 +78,7 @@ static inline struct irq_routing_table * pirq_check_routing_table(u8 *addr) for (i=0; i < rt->size; i++) sum += addr[i]; if (!sum) { - DBG("PCI: Interrupt Routing Table found at 0x%p\n", rt); + DBG(KERN_DEBUG "PCI: Interrupt Routing Table found at 0x%p\n", rt); return rt; } return NULL; @@ -128,7 +128,7 @@ static void __init pirq_peer_trick(void) #ifdef DEBUG { int j; - DBG("%02x:%02x slot=%02x", e->bus, e->devfn/8, e->slot); + DBG(KERN_DEBUG "%02x:%02x slot=%02x", e->bus, e->devfn/8, e->slot); for(j=0; j<4; j++) DBG(" %d:%02x/%04x", j, e->irq[j].link, e->irq[j].bitmap); DBG("\n"); @@ -160,10 +160,10 @@ void eisa_set_level_irq(unsigned int irq) return; eisa_irq_mask |= (1 << irq); - printk("PCI: setting IRQ %u as level-triggered\n", irq); + printk(KERN_DEBUG "PCI: setting IRQ %u as level-triggered\n", irq); val = inb(port); if (!(val & mask)) { - DBG(" -> edge"); + DBG(KERN_DEBUG " -> edge"); outb(val | mask, port); } } @@ -677,11 +677,11 @@ static __init int ali_router_probe(struct irq_router *r, struct pci_dev *router, { case PCI_DEVICE_ID_AL_M1533: case PCI_DEVICE_ID_AL_M1563: - printk("PCI: Using ALI IRQ Router\n"); - r->name = "ALI"; - r->get = pirq_ali_get; - r->set = pirq_ali_set; - return 1; + printk(KERN_DEBUG "PCI: Using ALI IRQ Router\n"); + r->name = "ALI"; + r->get = pirq_ali_get; + r->set = pirq_ali_set; + return 1; } return 0; } @@ -749,12 +749,13 @@ static void __init pirq_find_router(struct irq_router *r) r->get = NULL; r->set = NULL; - DBG("PCI: Attempting to find IRQ router for %04x:%04x\n", + DBG(KERN_DEBUG "PCI: Attempting to find IRQ router for %04x:%04x\n", rt->rtr_vendor, rt->rtr_device); pirq_router_dev = pci_find_slot(rt->rtr_bus, rt->rtr_devfn); if (!pirq_router_dev) { - DBG("PCI: Interrupt router not found at %02x:%02x\n", rt->rtr_bus, rt->rtr_devfn); + DBG(KERN_DEBUG "PCI: Interrupt router not found at " + "%02x:%02x\n", rt->rtr_bus, rt->rtr_devfn); return; } @@ -799,7 +800,7 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign) /* Find IRQ pin */ pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); if (!pin) { - DBG(" -> no interrupt pin\n"); + DBG(KERN_DEBUG " -> no interrupt pin\n"); return 0; } pin = pin - 1; @@ -809,16 +810,16 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign) if (!pirq_table) return 0; - DBG("IRQ for %s[%c]", pci_name(dev), 'A' + pin); + DBG(KERN_DEBUG "IRQ for %s[%c]", pci_name(dev), 'A' + pin); info = pirq_get_info(dev); if (!info) { - DBG(" -> not found in routing table\n"); + DBG(" -> not found in routing table\n" KERN_DEBUG); return 0; } pirq = info->irq[pin].link; mask = info->irq[pin].bitmap; if (!pirq) { - DBG(" -> not routed\n"); + DBG(" -> not routed\n" KERN_DEBUG); return 0; } DBG(" -> PIRQ %02x, mask %04x, excl %04x", pirq, mask, pirq_table->exclusive_irqs); @@ -848,7 +849,10 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign) newirq = dev->irq; if (newirq && !((1 << newirq) & mask)) { if ( pci_probe & PCI_USE_PIRQ_MASK) newirq = 0; - else printk(KERN_WARNING "PCI: IRQ %i for device %s doesn't match PIRQ mask - try pci=usepirqmask\n", newirq, pci_name(dev)); + else printk("\n" KERN_WARNING + "PCI: IRQ %i for device %s doesn't match PIRQ mask " + "- try pci=usepirqmask\n" KERN_DEBUG, newirq, + pci_name(dev)); } if (!newirq && assign) { for (i = 0; i < 16; i++) { @@ -923,14 +927,14 @@ static void __init pcibios_fixup_irqs(void) struct pci_dev *dev = NULL; u8 pin; - DBG("PCI: IRQ fixup\n"); + DBG(KERN_DEBUG "PCI: IRQ fixup\n"); while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { /* * If the BIOS has set an out of range IRQ number, just ignore it. * Also keep track of which IRQ's are already in use. */ if (dev->irq >= 16) { - DBG("%s: ignoring bogus IRQ %d\n", pci_name(dev), dev->irq); + DBG(KERN_DEBUG "%s: ignoring bogus IRQ %d\n", pci_name(dev), dev->irq); dev->irq = 0; } /* If the IRQ is already assigned to a PCI device, ignore its ISA use penalty */ @@ -1039,7 +1043,7 @@ static struct dmi_system_id __initdata pciirq_dmi_table[] = { static int __init pcibios_irq_init(void) { - DBG("PCI: IRQ init\n"); + DBG(KERN_DEBUG "PCI: IRQ init\n"); if (pcibios_enable_irq || raw_pci_ops == NULL) return 0; -- cgit 1.2.3-korg From d681db4aed4453c7d34adfbb64956271186514e9 Mon Sep 17 00:00:00 2001 From: "linas@austin.ibm.com" Date: Thu, 1 Dec 2005 18:56:14 -0600 Subject: [PATCH] PCI Hotplug/powerpc: remove duplicated code The RPAPHP code contains a routine that duplicates some existing code. This patch removes the rpaphp version of the code. Signed-off-by: Linas Vepstas Acked-by: John Rose Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/rpadlpar_core.c | 3 ++- drivers/pci/hotplug/rpaphp_pci.c | 14 +------------- 2 files changed, 3 insertions(+), 14 deletions(-) diff --git a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c index cc03609f45d02..0173641c41499 100644 --- a/drivers/pci/hotplug/rpadlpar_core.c +++ b/drivers/pci/hotplug/rpadlpar_core.c @@ -154,7 +154,8 @@ static struct pci_dev *dlpar_pci_add_bus(struct device_node *dn) struct pci_controller *phb = pdn->phb; struct pci_dev *dev = NULL; - rpaphp_eeh_init_nodes(dn); + eeh_add_device_tree_early(dn); + /* Add EADS device to PHB bus, adding new entry to bus->devices */ dev = of_create_pci_dev(dn, phb->bus, pdn->devfn); if (!dev) { diff --git a/drivers/pci/hotplug/rpaphp_pci.c b/drivers/pci/hotplug/rpaphp_pci.c index 4b35097b3d9fb..fc2368710cf71 100644 --- a/drivers/pci/hotplug/rpaphp_pci.c +++ b/drivers/pci/hotplug/rpaphp_pci.c @@ -287,18 +287,6 @@ rpaphp_pci_config_slot(struct pci_bus *bus) return dev; } -void rpaphp_eeh_init_nodes(struct device_node *dn) -{ - struct device_node *sib; - - for (sib = dn->child; sib; sib = sib->sibling) - rpaphp_eeh_init_nodes(sib); - eeh_add_device_early(dn); - return; - -} -EXPORT_SYMBOL_GPL(rpaphp_eeh_init_nodes); - static void print_slot_pci_funcs(struct pci_bus *bus) { struct device_node *dn; @@ -324,7 +312,7 @@ int rpaphp_config_pci_adapter(struct pci_bus *bus) if (!dn) goto exit; - rpaphp_eeh_init_nodes(dn); + eeh_add_device_tree_early(dn); dev = rpaphp_pci_config_slot(bus); if (!dev) { err("%s: can't find any devices.\n", __FUNCTION__); -- cgit 1.2.3-korg From cd5b50be8d8e8e6170da3a261fc625fd603f9dc4 Mon Sep 17 00:00:00 2001 From: "linas@austin.ibm.com" Date: Thu, 1 Dec 2005 18:59:58 -0600 Subject: [PATCH] PCI Hotplug/powerpc: more removal of duplicated code The RPAPHP code contains two routines that appear to be gratuitous copies of very similar pci code. In particular, rpaphp_claim_resource ~~ pci_claim_resource (there is a minor, non-functional difference) rpadlpar_claim_one_bus == pcibios_claim_one_bus (the code is identical) This patch removes the rpaphp versions of the code. Signed-off-by: Linas Vepstas Acked-by: John Rose Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/rpadlpar_core.c | 24 +----------------------- drivers/pci/hotplug/rpaphp_pci.c | 24 +----------------------- 2 files changed, 2 insertions(+), 46 deletions(-) diff --git a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c index 0173641c41499..7d93dbaf628de 100644 --- a/drivers/pci/hotplug/rpadlpar_core.c +++ b/drivers/pci/hotplug/rpadlpar_core.c @@ -112,28 +112,6 @@ static struct slot *find_slot(struct device_node *dn) return NULL; } -static void rpadlpar_claim_one_bus(struct pci_bus *b) -{ - struct list_head *ld; - struct pci_bus *child_bus; - - for (ld = b->devices.next; ld != &b->devices; ld = ld->next) { - struct pci_dev *dev = pci_dev_b(ld); - int i; - - for (i = 0; i < PCI_NUM_RESOURCES; i++) { - struct resource *r = &dev->resource[i]; - - if (r->parent || !r->start || !r->flags) - continue; - rpaphp_claim_resource(dev, i); - } - } - - list_for_each_entry(child_bus, &b->children, node) - rpadlpar_claim_one_bus(child_bus); -} - static struct pci_dev *dlpar_find_new_dev(struct pci_bus *parent, struct device_node *dev_dn) { @@ -171,7 +149,7 @@ static struct pci_dev *dlpar_pci_add_bus(struct device_node *dn) rpaphp_init_new_devs(dev->subordinate); /* Claim new bus resources */ - rpadlpar_claim_one_bus(dev->bus); + pcibios_claim_one_bus(dev->bus); /* ioremap() for child bus, which may or may not succeed */ (void) remap_bus_range(dev->bus); diff --git a/drivers/pci/hotplug/rpaphp_pci.c b/drivers/pci/hotplug/rpaphp_pci.c index fc2368710cf71..6f21c73be3c03 100644 --- a/drivers/pci/hotplug/rpaphp_pci.c +++ b/drivers/pci/hotplug/rpaphp_pci.c @@ -62,28 +62,6 @@ struct pci_bus *rpaphp_find_pci_bus(struct device_node *dn) } EXPORT_SYMBOL_GPL(rpaphp_find_pci_bus); -int rpaphp_claim_resource(struct pci_dev *dev, int resource) -{ - struct resource *res = &dev->resource[resource]; - struct resource *root = pci_find_parent_resource(dev, res); - char *dtype = resource < PCI_BRIDGE_RESOURCES ? "device" : "bridge"; - int err = -EINVAL; - - if (root != NULL) { - err = request_resource(root, res); - } - - if (err) { - err("PCI: %s region %d of %s %s [%lx:%lx]\n", - root ? "Address space collision on" : - "No parent found for", - resource, dtype, pci_name(dev), res->start, res->end); - } - return err; -} - -EXPORT_SYMBOL_GPL(rpaphp_claim_resource); - static int rpaphp_get_sensor_state(struct slot *slot, int *state) { int rc; @@ -177,7 +155,7 @@ void rpaphp_fixup_new_pci_devices(struct pci_bus *bus, int fix_bus) if (r->parent || !r->start || !r->flags) continue; - rpaphp_claim_resource(dev, i); + pci_claim_resource(dev, i); } } } -- cgit 1.2.3-korg From 81f154427c0c50b6492d454abf98e15c1c2e354e Mon Sep 17 00:00:00 2001 From: Kenji Kaneshige Date: Mon, 5 Dec 2005 19:31:00 +0900 Subject: [PATCH] shpchp: Implement get_address callback The following patch implements .get_address callback of hotplug_slot_ops for SHPCHP driver. With this patch, we can see bus address of hotplug slots as follows: $ cat address 0000:0b:01 Signed-off-by: Kenji Kaneshige Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/shpchp_core.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c index d81f8a75b495d..a2b3f0010cece 100644 --- a/drivers/pci/hotplug/shpchp_core.c +++ b/drivers/pci/hotplug/shpchp_core.c @@ -65,6 +65,7 @@ static int get_power_status (struct hotplug_slot *slot, u8 *value); static int get_attention_status (struct hotplug_slot *slot, u8 *value); static int get_latch_status (struct hotplug_slot *slot, u8 *value); static int get_adapter_status (struct hotplug_slot *slot, u8 *value); +static int get_address (struct hotplug_slot *slot, u32 *value); static int get_max_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value); static int get_cur_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value); @@ -77,6 +78,7 @@ static struct hotplug_slot_ops shpchp_hotplug_slot_ops = { .get_attention_status = get_attention_status, .get_latch_status = get_latch_status, .get_adapter_status = get_adapter_status, + .get_address = get_address, .get_max_bus_speed = get_max_bus_speed, .get_cur_bus_speed = get_cur_bus_speed, }; @@ -314,6 +316,18 @@ static int get_adapter_status (struct hotplug_slot *hotplug_slot, u8 *value) return 0; } +static int get_address (struct hotplug_slot *hotplug_slot, u32 *value) +{ + struct slot *slot = get_slot (hotplug_slot, __FUNCTION__); + struct pci_bus *bus = slot->ctrl->pci_dev->subordinate; + + dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); + + *value = (pci_domain_nr(bus) << 16) | (slot->bus << 8) | slot->device; + + return 0; +} + static int get_max_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value) { struct slot *slot = get_slot (hotplug_slot, __FUNCTION__); -- cgit 1.2.3-korg From 9d265124d051c2cf6716639239609d83f736dcdb Mon Sep 17 00:00:00 2001 From: Daniel Yeisley Date: Mon, 5 Dec 2005 07:06:43 -0500 Subject: [PATCH] PCI Quirk: 1K I/O space granularity on Intel P64H2 I've implemented a quirk to take advantage of the 1KB I/O space granularity option on the Intel P64H2 PCI Bridge. I had to change probe.c because it sets the resource start and end to be aligned on 4k boundaries (after the quirk sets them to 1k boundaries). I've tested this patch on a Unisys ES7000-600 both with and without the 1KB option enabled. I also tested this on a 2 processor Dell box that doesn't have a P64H2 to make sure there were no negative affects there. Signed-off-by: Dan Yeisley Signed-off-by: Greg Kroah-Hartman --- drivers/pci/probe.c | 6 ++++-- drivers/pci/quirks.c | 26 ++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 79be37a533973..00ba6a03dca56 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -264,8 +264,10 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child) if (base <= limit) { res->flags = (io_base_lo & PCI_IO_RANGE_TYPE_MASK) | IORESOURCE_IO; - res->start = base; - res->end = limit + 0xfff; + if (!res->start) + res->start = base; + if (!res->end) + res->end = limit + 0xfff; } res = child->resource[1]; diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index f28ebdd3958a5..605f0df0bfba9 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -1342,6 +1342,32 @@ void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev) pci_do_fixups(dev, start, end); } +/* Enable 1k I/O space granularity on the Intel P64H2 */ +static void __devinit quirk_p64h2_1k_io(struct pci_dev *dev) +{ + u16 en1k; + u8 io_base_lo, io_limit_lo; + unsigned long base, limit; + struct resource *res = dev->resource + PCI_BRIDGE_RESOURCES; + + pci_read_config_word(dev, 0x40, &en1k); + + if (en1k & 0x200) { + printk(KERN_INFO "PCI: Enable I/O Space to 1 KB Granularity\n"); + + pci_read_config_byte(dev, PCI_IO_BASE, &io_base_lo); + pci_read_config_byte(dev, PCI_IO_LIMIT, &io_limit_lo); + base = (io_base_lo & (PCI_IO_RANGE_MASK | 0x0c)) << 8; + limit = (io_limit_lo & (PCI_IO_RANGE_MASK | 0x0c)) << 8; + + if (base <= limit) { + res->start = base; + res->end = limit + 0x3ff; + } + } +} +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1460, quirk_p64h2_1k_io); + EXPORT_SYMBOL(pcie_mch_quirk); #ifdef CONFIG_HOTPLUG EXPORT_SYMBOL(pci_fixup_device); -- cgit 1.2.3-korg From c7ab337f91b59f71a30c3ab71e3bdfff41671977 Mon Sep 17 00:00:00 2001 From: Thomas Schaefer Date: Thu, 8 Dec 2005 11:55:57 -0800 Subject: [PATCH] pciehp: handle sticky power-fault status This patch disables power fault, MRL sensor and presence detection interrupts when a PCIe slot is powered-off and enables those interrupts when it is powered-on again. This is necessary to prevent the associated events from causing an endless cycle of interrupts due to the power-fault bit, which stays set till power is restored to the slot. Signed-off-by: Thomas Schaefer Signed-off-by: Rajesh Shah Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/pciehp_hpc.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index ac1e495c314ea..77e530321de2c 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c @@ -787,8 +787,13 @@ static int hpc_power_on_slot(struct slot * slot) slot_cmd = (slot_ctrl & ~PWR_CTRL) | POWER_ON; + /* Enable detection that we turned off at slot power-off time */ if (!pciehp_poll_mode) - slot_cmd = slot_cmd | HP_INTR_ENABLE; + slot_cmd = slot_cmd | + PWR_FAULT_DETECT_ENABLE | + MRL_DETECT_ENABLE | + PRSN_DETECT_ENABLE | + HP_INTR_ENABLE; retval = pcie_write_cmd(slot, slot_cmd); @@ -833,8 +838,18 @@ static int hpc_power_off_slot(struct slot * slot) slot_cmd = (slot_ctrl & ~PWR_CTRL) | POWER_OFF; + /* + * If we get MRL or presence detect interrupts now, the isr + * will notice the sticky power-fault bit too and issue power + * indicator change commands. This will lead to an endless loop + * of command completions, since the power-fault bit remains on + * till the slot is powered on again. + */ if (!pciehp_poll_mode) - slot_cmd = slot_cmd | HP_INTR_ENABLE; + slot_cmd = (slot_cmd & + ~PWR_FAULT_DETECT_ENABLE & + ~MRL_DETECT_ENABLE & + ~PRSN_DETECT_ENABLE) | HP_INTR_ENABLE; retval = pcie_write_cmd(slot, slot_cmd); -- cgit 1.2.3-korg From 0eb3bcfd088e3234f7af29e189a7900ccfdd278a Mon Sep 17 00:00:00 2001 From: Rajesh Shah Date: Thu, 8 Dec 2005 12:12:25 -0800 Subject: [PATCH] pciehp: allow bridged card hotplug This patch fixes bugs in the pciehp driver that prevent hot-add of a card with PCI bridges on it. Signed-off-by: Rajesh Shah Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/pciehp_pci.c | 52 +++++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c index 647673a7d2248..4017fb03a0b81 100644 --- a/drivers/pci/hotplug/pciehp_pci.c +++ b/drivers/pci/hotplug/pciehp_pci.c @@ -34,6 +34,31 @@ #include "../pci.h" #include "pciehp.h" +static int pciehp_add_bridge(struct pci_dev *dev) +{ + struct pci_bus *parent = dev->bus; + int pass, busnr, start = parent->secondary; + int end = parent->subordinate; + + for (busnr = start; busnr <= end; busnr++) { + if (!pci_find_bus(pci_domain_nr(parent), busnr)) + break; + } + if (busnr-- > end) { + err("No bus number available for hot-added bridge %s\n", + pci_name(dev)); + return -1; + } + for (pass = 0; pass < 2; pass++) + busnr = pci_scan_bridge(parent, dev, busnr, pass); + if (!dev->subordinate) + return -1; + pci_bus_size_bridges(dev->subordinate); + pci_bus_assign_resources(parent); + pci_enable_bridges(parent); + pci_bus_add_devices(parent); + return 0; +} int pciehp_configure_device(struct slot *p_slot) { @@ -55,8 +80,8 @@ int pciehp_configure_device(struct slot *p_slot) } for (fn = 0; fn < 8; fn++) { - if (!(dev = pci_find_slot(p_slot->bus, - PCI_DEVFN(p_slot->device, fn)))) + dev = pci_get_slot(parent, PCI_DEVFN(p_slot->device, fn)); + if (!dev) continue; if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) { err("Cannot hot-add display device %s\n", @@ -65,27 +90,7 @@ int pciehp_configure_device(struct slot *p_slot) } if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) || (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) { - /* Find an unused bus number for the new bridge */ - struct pci_bus *child; - unsigned char busnr, start = parent->secondary; - unsigned char end = parent->subordinate; - for (busnr = start; busnr <= end; busnr++) { - if (!pci_find_bus(pci_domain_nr(parent), - busnr)) - break; - } - if (busnr >= end) { - err("No free bus for hot-added bridge\n"); - continue; - } - child = pci_add_new_bus(parent, dev, busnr); - if (!child) { - err("Cannot add new bus for %s\n", - pci_name(dev)); - continue; - } - child->subordinate = pci_do_scan_bus(child); - pci_bus_size_bridges(child); + pciehp_add_bridge(dev); } /* TBD: program firmware provided _HPP values */ /* program_fw_provided_values(dev); */ @@ -93,7 +98,6 @@ int pciehp_configure_device(struct slot *p_slot) pci_bus_assign_resources(parent); pci_bus_add_devices(parent); - pci_enable_bridges(parent); return 0; } -- cgit 1.2.3-korg From 498879417756effe6dc385ee04645a83d724fdef Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Thu, 8 Dec 2005 16:53:12 +0100 Subject: [PATCH] PCI: use bus numbers sparsely, if necessary Add a warning if a child bus may be inaccessible because the parent bridge has wrong secondary or subordinate bus numbers. Note that this may or may not happen on "transparent" bridges, as can be seen in bug #5557. Also, if we do not fix up the assignment of bus numbers, try to make use of the bus number space available. Signed-off-by: Dominik Brodowski Signed-off-by: Greg Kroah-Hartman --- drivers/pci/probe.c | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 00ba6a03dca56..3c9834d808501 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -433,7 +433,7 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max { struct pci_bus *child; int is_cardbus = (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS); - u32 buses, i; + u32 buses, i, j = 0; u16 bctl; pci_read_config_dword(dev, PCI_PRIMARY_BUS, &buses); @@ -543,10 +543,29 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max * as cards with a PCI-to-PCI bridge can be * inserted later. */ - for (i=0; iparent) { + if ((!pcibios_assign_all_busses()) && + (parent->subordinate > max) && + (parent->subordinate <= max+i)) { + j = 1; + } + parent = parent->parent; + } + if (j) { + /* + * Often, there are two cardbus bridges + * -- try to leave one valid bus number + * for each one. + */ + i /= 2; + break; + } + } max += i; pci_fixup_parent_subordinate_busnr(child, max); } @@ -561,6 +580,22 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max sprintf(child->name, (is_cardbus ? "PCI CardBus #%02x" : "PCI Bus #%02x"), child->number); + while (bus->parent) { + if ((child->subordinate > bus->subordinate) || + (child->number > bus->subordinate) || + (child->number < bus->number) || + (child->subordinate < bus->number)) { + printk(KERN_WARNING "PCI: Bus #%02x (-#%02x) may be " + "hidden behind%s bridge #%02x (-#%02x)%s\n", + child->number, child->subordinate, + bus->self->transparent ? " transparent" : " ", + bus->number, bus->subordinate, + pcibios_assign_all_busses() ? " " : + " (try 'pci=assign-busses')"); + } + bus = bus->parent; + } + return max; } -- cgit 1.2.3-korg From ac7dc65ac0b945270548414491efa9c4357417d9 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Tue, 13 Dec 2005 18:09:16 +1100 Subject: [PATCH] PCI: Export pci_cfg_space_size The powerpc PCI code sets up the PCI tree without doing config space accesses in most cases, from the firmware tree. However, it still wants to call pci_cfg_space_size() under some conditions, thus it needs to be made non-static (though I don't see a point to export it to modules). Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Greg Kroah-Hartman --- drivers/pci/probe.c | 2 +- include/linux/pci.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 3c9834d808501..adfad4fd6a13d 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -717,7 +717,7 @@ static void pci_release_dev(struct device *dev) * reading the dword at 0x100 which must either be 0 or a valid extended * capability header. */ -static int pci_cfg_space_size(struct pci_dev *dev) +int pci_cfg_space_size(struct pci_dev *dev) { int pos; u32 status; diff --git a/include/linux/pci.h b/include/linux/pci.h index b32f70fe2dbd0..d0e003926744a 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -449,6 +449,7 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max, int pass void pci_walk_bus(struct pci_bus *top, void (*cb)(struct pci_dev *, void *), void *userdata); +int pci_cfg_space_size(struct pci_dev *dev); /* kmem_cache style wrapper around pci_alloc_consistent() */ -- cgit 1.2.3-korg From 5d135dff536f30022674d463ce3119bb28e045df Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Fri, 9 Dec 2005 11:55:03 -0800 Subject: [PATCH] PCI: document sysfs rom file interface idr gently pointed out today that not only is the sysfs rom file interface somewhat unintuitive (despite my efforts and initial implementation), but it's also undocumented! This patch to Documentation/filesystems/sysfs-pci.txt corrects the latter problem; the former is a userland ABI now though, so we're stuck with it for awhile at least. Signed-off-by: Jesse Barnes Signed-off-by: Greg Kroah-Hartman --- Documentation/filesystems/sysfs-pci.txt | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/Documentation/filesystems/sysfs-pci.txt b/Documentation/filesystems/sysfs-pci.txt index 988a62fae11f8..7ba2baa165ffd 100644 --- a/Documentation/filesystems/sysfs-pci.txt +++ b/Documentation/filesystems/sysfs-pci.txt @@ -1,4 +1,5 @@ Accessing PCI device resources through sysfs +-------------------------------------------- sysfs, usually mounted at /sys, provides access to PCI resources on platforms that support it. For example, a given bus might look like this: @@ -47,14 +48,21 @@ files, each with their own function. binary - file contains binary data cpumask - file contains a cpumask type -The read only files are informational, writes to them will be ignored. -Writable files can be used to perform actions on the device (e.g. changing -config space, detaching a device). mmapable files are available via an -mmap of the file at offset 0 and can be used to do actual device programming -from userspace. Note that some platforms don't support mmapping of certain -resources, so be sure to check the return value from any attempted mmap. +The read only files are informational, writes to them will be ignored, with +the exception of the 'rom' file. Writable files can be used to perform +actions on the device (e.g. changing config space, detaching a device). +mmapable files are available via an mmap of the file at offset 0 and can be +used to do actual device programming from userspace. Note that some platforms +don't support mmapping of certain resources, so be sure to check the return +value from any attempted mmap. + +The 'rom' file is special in that it provides read-only access to the device's +ROM file, if available. It's disabled by default, however, so applications +should write the string "1" to the file to enable it before attempting a read +call, and disable it following the access by writing "0" to the file. Accessing legacy resources through sysfs +---------------------------------------- Legacy I/O port and ISA memory resources are also provided in sysfs if the underlying platform supports them. They're located in the PCI class heirarchy, @@ -75,6 +83,7 @@ simply dereference the returned pointer (after checking for errors of course) to access legacy memory space. Supporting PCI access on new platforms +-------------------------------------- In order to support PCI resource mapping as described above, Linux platform code must define HAVE_PCI_MMAP and provide a pci_mmap_page_range function. -- cgit 1.2.3-korg From efbf62e9f4d93c3716a4d6d3221d537c71e299a2 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Sun, 11 Dec 2005 06:42:18 +0100 Subject: [PATCH] PCI: Reduce nr of ptr derefs in drivers/pci/hotplug/cpqphp_core.c Here's a small patch to reduce the nr of pointer dereferences in drivers/pci/hotplug/cpqphp_core.c Benefits of this patch: - micro speed optimization due to fewer pointer derefs - generated code is slightly smaller - tiny line length and whitespace cleanup - better readability Signed-off-by: Jesper Juhl Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/cpqphp_core.c | 121 +++++++++++++++++++++----------------- 1 file changed, 67 insertions(+), 54 deletions(-) diff --git a/drivers/pci/hotplug/cpqphp_core.c b/drivers/pci/hotplug/cpqphp_core.c index 9aed8efe6a114..d3644709a0352 100644 --- a/drivers/pci/hotplug/cpqphp_core.c +++ b/drivers/pci/hotplug/cpqphp_core.c @@ -327,7 +327,9 @@ static int ctrl_slot_setup(struct controller *ctrl, void __iomem *smbios_start, void __iomem *smbios_table) { - struct slot *new_slot; + struct slot *slot; + struct hotplug_slot *hotplug_slot; + struct hotplug_slot_info *hotplug_slot_info; u8 number_of_slots; u8 slot_device; u8 slot_number; @@ -345,93 +347,105 @@ static int ctrl_slot_setup(struct controller *ctrl, slot_number = ctrl->first_slot; while (number_of_slots) { - new_slot = kmalloc(sizeof(*new_slot), GFP_KERNEL); - if (!new_slot) + slot = kmalloc(sizeof(*slot), GFP_KERNEL); + if (!slot) goto error; - memset(new_slot, 0, sizeof(struct slot)); - new_slot->hotplug_slot = kmalloc(sizeof(*(new_slot->hotplug_slot)), + memset(slot, 0, sizeof(struct slot)); + slot->hotplug_slot = kmalloc(sizeof(*(slot->hotplug_slot)), GFP_KERNEL); - if (!new_slot->hotplug_slot) + if (!slot->hotplug_slot) goto error_slot; - memset(new_slot->hotplug_slot, 0, sizeof(struct hotplug_slot)); + hotplug_slot = slot->hotplug_slot; + memset(hotplug_slot, 0, sizeof(struct hotplug_slot)); - new_slot->hotplug_slot->info = - kmalloc(sizeof(*(new_slot->hotplug_slot->info)), + hotplug_slot->info = + kmalloc(sizeof(*(hotplug_slot->info)), GFP_KERNEL); - if (!new_slot->hotplug_slot->info) + if (!hotplug_slot->info) goto error_hpslot; - memset(new_slot->hotplug_slot->info, 0, + hotplug_slot_info = hotplug_slot->info; + memset(hotplug_slot_info, 0, sizeof(struct hotplug_slot_info)); - new_slot->hotplug_slot->name = kmalloc(SLOT_NAME_SIZE, GFP_KERNEL); - if (!new_slot->hotplug_slot->name) + hotplug_slot->name = kmalloc(SLOT_NAME_SIZE, GFP_KERNEL); + + if (!hotplug_slot->name) goto error_info; - new_slot->ctrl = ctrl; - new_slot->bus = ctrl->bus; - new_slot->device = slot_device; - new_slot->number = slot_number; - dbg("slot->number = %d\n",new_slot->number); + slot->ctrl = ctrl; + slot->bus = ctrl->bus; + slot->device = slot_device; + slot->number = slot_number; + dbg("slot->number = %d\n", slot->number); slot_entry = get_SMBIOS_entry(smbios_start, smbios_table, 9, slot_entry); - while (slot_entry && (readw(slot_entry + SMBIOS_SLOT_NUMBER) != new_slot->number)) { + while (slot_entry && (readw(slot_entry + SMBIOS_SLOT_NUMBER) != + slot->number)) { slot_entry = get_SMBIOS_entry(smbios_start, smbios_table, 9, slot_entry); } - new_slot->p_sm_slot = slot_entry; + slot->p_sm_slot = slot_entry; - init_timer(&new_slot->task_event); - new_slot->task_event.expires = jiffies + 5 * HZ; - new_slot->task_event.function = cpqhp_pushbutton_thread; + init_timer(&slot->task_event); + slot->task_event.expires = jiffies + 5 * HZ; + slot->task_event.function = cpqhp_pushbutton_thread; //FIXME: these capabilities aren't used but if they are // they need to be correctly implemented - new_slot->capabilities |= PCISLOT_REPLACE_SUPPORTED; - new_slot->capabilities |= PCISLOT_INTERLOCK_SUPPORTED; + slot->capabilities |= PCISLOT_REPLACE_SUPPORTED; + slot->capabilities |= PCISLOT_INTERLOCK_SUPPORTED; - if (is_slot64bit(new_slot)) - new_slot->capabilities |= PCISLOT_64_BIT_SUPPORTED; - if (is_slot66mhz(new_slot)) - new_slot->capabilities |= PCISLOT_66_MHZ_SUPPORTED; + if (is_slot64bit(slot)) + slot->capabilities |= PCISLOT_64_BIT_SUPPORTED; + if (is_slot66mhz(slot)) + slot->capabilities |= PCISLOT_66_MHZ_SUPPORTED; if (ctrl->speed == PCI_SPEED_66MHz) - new_slot->capabilities |= PCISLOT_66_MHZ_OPERATION; + slot->capabilities |= PCISLOT_66_MHZ_OPERATION; - ctrl_slot = slot_device - (readb(ctrl->hpc_reg + SLOT_MASK) >> 4); + ctrl_slot = + slot_device - (readb(ctrl->hpc_reg + SLOT_MASK) >> 4); // Check presence - new_slot->capabilities |= ((((~tempdword) >> 23) | ((~tempdword) >> 15)) >> ctrl_slot) & 0x02; + slot->capabilities |= + ((((~tempdword) >> 23) | + ((~tempdword) >> 15)) >> ctrl_slot) & 0x02; // Check the switch state - new_slot->capabilities |= ((~tempdword & 0xFF) >> ctrl_slot) & 0x01; + slot->capabilities |= + ((~tempdword & 0xFF) >> ctrl_slot) & 0x01; // Check the slot enable - new_slot->capabilities |= ((read_slot_enable(ctrl) << 2) >> ctrl_slot) & 0x04; + slot->capabilities |= + ((read_slot_enable(ctrl) << 2) >> ctrl_slot) & 0x04; /* register this slot with the hotplug pci core */ - new_slot->hotplug_slot->release = &release_slot; - new_slot->hotplug_slot->private = new_slot; - make_slot_name(new_slot->hotplug_slot->name, SLOT_NAME_SIZE, new_slot); - new_slot->hotplug_slot->ops = &cpqphp_hotplug_slot_ops; + hotplug_slot->release = &release_slot; + hotplug_slot->private = slot; + make_slot_name(hotplug_slot->name, SLOT_NAME_SIZE, slot); + hotplug_slot->ops = &cpqphp_hotplug_slot_ops; - new_slot->hotplug_slot->info->power_status = get_slot_enabled(ctrl, new_slot); - new_slot->hotplug_slot->info->attention_status = cpq_get_attention_status(ctrl, new_slot); - new_slot->hotplug_slot->info->latch_status = cpq_get_latch_status(ctrl, new_slot); - new_slot->hotplug_slot->info->adapter_status = get_presence_status(ctrl, new_slot); + hotplug_slot_info->power_status = get_slot_enabled(ctrl, slot); + hotplug_slot_info->attention_status = + cpq_get_attention_status(ctrl, slot); + hotplug_slot_info->latch_status = + cpq_get_latch_status(ctrl, slot); + hotplug_slot_info->adapter_status = + get_presence_status(ctrl, slot); - dbg ("registering bus %d, dev %d, number %d, " + dbg("registering bus %d, dev %d, number %d, " "ctrl->slot_device_offset %d, slot %d\n", - new_slot->bus, new_slot->device, - new_slot->number, ctrl->slot_device_offset, + slot->bus, slot->device, + slot->number, ctrl->slot_device_offset, slot_number); - result = pci_hp_register (new_slot->hotplug_slot); + result = pci_hp_register(hotplug_slot); if (result) { - err ("pci_hp_register failed with error %d\n", result); + err("pci_hp_register failed with error %d\n", result); goto error_name; } - new_slot->next = ctrl->slot; - ctrl->slot = new_slot; + slot->next = ctrl->slot; + ctrl->slot = slot; number_of_slots--; slot_device++; @@ -439,15 +453,14 @@ static int ctrl_slot_setup(struct controller *ctrl, } return 0; - error_name: - kfree(new_slot->hotplug_slot->name); + kfree(hotplug_slot->name); error_info: - kfree(new_slot->hotplug_slot->info); + kfree(hotplug_slot_info); error_hpslot: - kfree(new_slot->hotplug_slot); + kfree(hotplug_slot); error_slot: - kfree(new_slot); + kfree(slot); error: return result; } -- cgit 1.2.3-korg From f5c99dfc11dce8f26c1ceedb6595fa0eac335ea3 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Sun, 11 Dec 2005 06:42:38 +0100 Subject: [PATCH] PCI: Reduce nr of ptr derefs in drivers/pci/hotplug/rpaphp_pci.c Here's a small patch to reduce the nr. of pointer dereferences in drivers/pci/hotplug/rpaphp_pci.c Benefits: - micro speed optimization due to fewer pointer derefs - generated code should be slightly smaller - better readability note: due to lack of both hardware and cross-compile tools this patch is, unfortunately, completely untested. Signed-off-by: Jesper Juhl Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/rpaphp_pci.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/pci/hotplug/rpaphp_pci.c b/drivers/pci/hotplug/rpaphp_pci.c index 6f21c73be3c03..396b54b0c8474 100644 --- a/drivers/pci/hotplug/rpaphp_pci.c +++ b/drivers/pci/hotplug/rpaphp_pci.c @@ -336,13 +336,14 @@ EXPORT_SYMBOL_GPL(rpaphp_unconfig_pci_adapter); static int setup_pci_hotplug_slot_info(struct slot *slot) { + struct hotplug_slot_info *hotplug_slot_info = slot->hotplug_slot->info; + dbg("%s Initilize the PCI slot's hotplug->info structure ...\n", __FUNCTION__); - rpaphp_get_power_status(slot, &slot->hotplug_slot->info->power_status); + rpaphp_get_power_status(slot, &hotplug_slot_info->power_status); rpaphp_get_pci_adapter_status(slot, 1, - &slot->hotplug_slot->info-> - adapter_status); - if (slot->hotplug_slot->info->adapter_status == NOT_VALID) { + &hotplug_slot_info->adapter_status); + if (hotplug_slot_info->adapter_status == NOT_VALID) { err("%s: NOT_VALID: skip dn->full_name=%s\n", __FUNCTION__, slot->dn->full_name); return -EINVAL; -- cgit 1.2.3-korg From c2dea6553090a3fd06ffa9ba512a09fdac4d1b6e Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Sun, 11 Dec 2005 06:43:09 +0100 Subject: [PATCH] PCI: Reduce nr of ptr derefs in drivers/pci/hotplug/pciehprm_acpi.c Here's a small patch to reduce the nr. of pointer dereferences in drivers/pci/hotplug/pciehprm_acpi.c Benefits: - micro speed optimization due to fewer pointer derefs - generated code is slightly smaller - better readability Signed-off-by: Jesper Juhl Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/pciehprm_acpi.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/pci/hotplug/pciehprm_acpi.c b/drivers/pci/hotplug/pciehprm_acpi.c index ae244e2186207..2bdb30f68bf8c 100644 --- a/drivers/pci/hotplug/pciehprm_acpi.c +++ b/drivers/pci/hotplug/pciehprm_acpi.c @@ -174,7 +174,9 @@ int pciehp_get_hp_hw_control_from_firmware(struct pci_dev *dev) acpi_status status; acpi_handle chandle, handle = DEVICE_ACPI_HANDLE(&(dev->dev)); struct pci_dev *pdev = dev; + struct pci_bus *parent; u8 *path_name; + /* * Per PCI firmware specification, we should run the ACPI _OSC * method to get control of hotplug hardware before using it. @@ -190,17 +192,18 @@ int pciehp_get_hp_hw_control_from_firmware(struct pci_dev *dev) */ if (!pdev || !pdev->bus->parent) break; + parent = pdev->bus->parent; dbg("Could not find %s in acpi namespace, trying parent\n", pci_name(pdev)); - if (!pdev->bus->parent->self) + if (!parent->self) /* Parent must be a host bridge */ handle = acpi_get_pci_rootbridge_handle( - pci_domain_nr(pdev->bus->parent), - pdev->bus->parent->number); + pci_domain_nr(parent), + parent->number); else handle = DEVICE_ACPI_HANDLE( - &(pdev->bus->parent->self->dev)); - pdev = pdev->bus->parent->self; + &(parent->self->dev)); + pdev = parent->self; } while (handle) { -- cgit 1.2.3-korg From 121082e2ab09d5e90ac27e38900c018e6f37bcdf Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Sun, 11 Dec 2005 06:41:42 +0100 Subject: [PATCH] PCI: Reduce nr of ptr derefs in drivers/pci/hotplug/pciehp_core.c Here's a small patch to reduce the nr. of pointer dereferences in drivers/pci/hotplug/pciehp_core.c Benefits: - micro speed optimization due to fewer pointer derefs - generated code is slightly smaller - small line length cleanup - better readability Signed-off-by: Jesper Juhl Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/pciehp_core.c | 90 ++++++++++++++++++++++----------------- 1 file changed, 50 insertions(+), 40 deletions(-) diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c index 8df7048603480..986e202e0b0b2 100644 --- a/drivers/pci/hotplug/pciehp_core.c +++ b/drivers/pci/hotplug/pciehp_core.c @@ -103,7 +103,10 @@ static void release_slot(struct hotplug_slot *hotplug_slot) static int init_slots(struct controller *ctrl) { - struct slot *new_slot; + struct slot *slot; + struct hpc_ops *hpc_ops; + struct hotplug_slot *hotplug_slot; + struct hotplug_slot_info *hotplug_slot_info; u8 number_of_slots; u8 slot_device; u32 slot_number; @@ -114,59 +117,66 @@ static int init_slots(struct controller *ctrl) slot_number = ctrl->first_slot; while (number_of_slots) { - new_slot = kmalloc(sizeof(*new_slot), GFP_KERNEL); - if (!new_slot) + slot = kmalloc(sizeof(*slot), GFP_KERNEL); + if (!slot) goto error; - memset(new_slot, 0, sizeof(struct slot)); - new_slot->hotplug_slot = - kmalloc(sizeof(*(new_slot->hotplug_slot)), + memset(slot, 0, sizeof(struct slot)); + slot->hotplug_slot = + kmalloc(sizeof(*(slot->hotplug_slot)), GFP_KERNEL); - if (!new_slot->hotplug_slot) + if (!slot->hotplug_slot) goto error_slot; - memset(new_slot->hotplug_slot, 0, sizeof(struct hotplug_slot)); + hotplug_slot = slot->hotplug_slot; + memset(hotplug_slot, 0, sizeof(struct hotplug_slot)); - new_slot->hotplug_slot->info = - kmalloc(sizeof(*(new_slot->hotplug_slot->info)), + hotplug_slot->info = + kmalloc(sizeof(*(hotplug_slot->info)), GFP_KERNEL); - if (!new_slot->hotplug_slot->info) + if (!hotplug_slot->info) goto error_hpslot; - memset(new_slot->hotplug_slot->info, 0, + hotplug_slot_info = hotplug_slot->info; + memset(hotplug_slot_info, 0, sizeof(struct hotplug_slot_info)); - new_slot->hotplug_slot->name = kmalloc(SLOT_NAME_SIZE, - GFP_KERNEL); - if (!new_slot->hotplug_slot->name) + hotplug_slot->name = kmalloc(SLOT_NAME_SIZE, GFP_KERNEL); + if (!hotplug_slot->name) goto error_info; - new_slot->ctrl = ctrl; - new_slot->bus = ctrl->slot_bus; - new_slot->device = slot_device; - new_slot->hpc_ops = ctrl->hpc_ops; + slot->ctrl = ctrl; + slot->bus = ctrl->slot_bus; + slot->device = slot_device; + slot->hpc_ops = hpc_ops = ctrl->hpc_ops; - new_slot->number = ctrl->first_slot; - new_slot->hp_slot = slot_device - ctrl->slot_device_offset; + slot->number = ctrl->first_slot; + slot->hp_slot = slot_device - ctrl->slot_device_offset; /* register this slot with the hotplug pci core */ - new_slot->hotplug_slot->private = new_slot; - new_slot->hotplug_slot->release = &release_slot; - make_slot_name(new_slot->hotplug_slot->name, SLOT_NAME_SIZE, new_slot); - new_slot->hotplug_slot->ops = &pciehp_hotplug_slot_ops; - - new_slot->hpc_ops->get_power_status(new_slot, &(new_slot->hotplug_slot->info->power_status)); - new_slot->hpc_ops->get_attention_status(new_slot, &(new_slot->hotplug_slot->info->attention_status)); - new_slot->hpc_ops->get_latch_status(new_slot, &(new_slot->hotplug_slot->info->latch_status)); - new_slot->hpc_ops->get_adapter_status(new_slot, &(new_slot->hotplug_slot->info->adapter_status)); - - dbg("Registering bus=%x dev=%x hp_slot=%x sun=%x slot_device_offset=%x\n", - new_slot->bus, new_slot->device, new_slot->hp_slot, new_slot->number, ctrl->slot_device_offset); - result = pci_hp_register (new_slot->hotplug_slot); + hotplug_slot->private = slot; + hotplug_slot->release = &release_slot; + make_slot_name(hotplug_slot->name, SLOT_NAME_SIZE, slot); + hotplug_slot->ops = &pciehp_hotplug_slot_ops; + + hpc_ops->get_power_status(slot, + &(hotplug_slot_info->power_status)); + hpc_ops->get_attention_status(slot, + &(hotplug_slot_info->attention_status)); + hpc_ops->get_latch_status(slot, + &(hotplug_slot_info->latch_status)); + hpc_ops->get_adapter_status(slot, + &(hotplug_slot_info->adapter_status)); + + dbg("Registering bus=%x dev=%x hp_slot=%x sun=%x " + "slot_device_offset=%x\n", + slot->bus, slot->device, slot->hp_slot, slot->number, + ctrl->slot_device_offset); + result = pci_hp_register(hotplug_slot); if (result) { err ("pci_hp_register failed with error %d\n", result); goto error_name; } - new_slot->next = ctrl->slot; - ctrl->slot = new_slot; + slot->next = ctrl->slot; + ctrl->slot = slot; number_of_slots--; slot_device++; @@ -176,13 +186,13 @@ static int init_slots(struct controller *ctrl) return 0; error_name: - kfree(new_slot->hotplug_slot->name); + kfree(hotplug_slot->name); error_info: - kfree(new_slot->hotplug_slot->info); + kfree(hotplug_slot_info); error_hpslot: - kfree(new_slot->hotplug_slot); + kfree(hotplug_slot); error_slot: - kfree(new_slot); + kfree(slot); error: return result; } -- cgit 1.2.3-korg From 9f3f4681291fc88864bb27f8f3832b95bb53aae5 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 14 Dec 2005 09:37:26 -0800 Subject: [PATCH] PCI Hotplug: fix up the sysfs file in the compaq pci hotplug driver The Compaq PCI Hotplug driver was creating 2 sysfs files that contained nothing but debug information, and had way more than "one value" in them. This patch converts the code to use debugfs for these files instead. Compile tested only. Cc: Kay Sievers Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/cpqphp.h | 8 ++- drivers/pci/hotplug/cpqphp_core.c | 6 +- drivers/pci/hotplug/cpqphp_sysfs.c | 138 +++++++++++++++++++++++++++++++------ 3 files changed, 127 insertions(+), 25 deletions(-) diff --git a/drivers/pci/hotplug/cpqphp.h b/drivers/pci/hotplug/cpqphp.h index 092491e25ef2b..cb88404c89fe0 100644 --- a/drivers/pci/hotplug/cpqphp.h +++ b/drivers/pci/hotplug/cpqphp.h @@ -317,6 +317,7 @@ struct controller { u16 vendor_id; struct work_struct int_task_event; wait_queue_head_t queue; /* sleep & wake process */ + struct dentry *dentry; /* debugfs dentry */ }; struct irq_mapping { @@ -399,8 +400,11 @@ struct resource_lists { #define msg_button_ignore "PCI slot #%d - button press ignored. (action in progress...)\n" -/* sysfs functions for the hotplug controller info */ -extern void cpqhp_create_ctrl_files (struct controller *ctrl); +/* debugfs functions for the hotplug controller info */ +extern void cpqhp_initialize_debugfs (void); +extern void cpqhp_shutdown_debugfs (void); +extern void cpqhp_create_debugfs_files (struct controller *ctrl); +extern void cpqhp_remove_debugfs_files (struct controller *ctrl); /* controller functions */ extern void cpqhp_pushbutton_thread (unsigned long event_pointer); diff --git a/drivers/pci/hotplug/cpqphp_core.c b/drivers/pci/hotplug/cpqphp_core.c index d3644709a0352..b3659ffccac9c 100644 --- a/drivers/pci/hotplug/cpqphp_core.c +++ b/drivers/pci/hotplug/cpqphp_core.c @@ -479,6 +479,8 @@ static int ctrl_slot_cleanup (struct controller * ctrl) old_slot = next_slot; } + cpqhp_remove_debugfs_files(ctrl); + //Free IRQ associated with hot plug device free_irq(ctrl->interrupt, ctrl); //Unmap the memory @@ -1275,7 +1277,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) // Done with exclusive hardware access up(&ctrl->crit_sect); - cpqhp_create_ctrl_files(ctrl); + cpqhp_create_debugfs_files(ctrl); return 0; @@ -1515,6 +1517,7 @@ static int __init cpqhpc_init(void) cpqhp_debug = debug; info (DRIVER_DESC " version: " DRIVER_VERSION "\n"); + cpqhp_initialize_debugfs(); result = pci_register_driver(&cpqhpc_driver); dbg("pci_register_driver = %d\n", result); return result; @@ -1528,6 +1531,7 @@ static void __exit cpqhpc_cleanup(void) dbg("pci_unregister_driver\n"); pci_unregister_driver(&cpqhpc_driver); + cpqhp_shutdown_debugfs(); } diff --git a/drivers/pci/hotplug/cpqphp_sysfs.c b/drivers/pci/hotplug/cpqphp_sysfs.c index 4c11048ad51b4..bbfeed767ff1f 100644 --- a/drivers/pci/hotplug/cpqphp_sysfs.c +++ b/drivers/pci/hotplug/cpqphp_sysfs.c @@ -33,22 +33,15 @@ #include #include #include +#include #include "cpqphp.h" - -/* A few routines that create sysfs entries for the hot plug controller */ - -static ssize_t show_ctrl (struct device *dev, struct device_attribute *attr, char *buf) +static int show_ctrl (struct controller *ctrl, char *buf) { - struct pci_dev *pci_dev; - struct controller *ctrl; - char * out = buf; + char *out = buf; int index; struct pci_resource *res; - pci_dev = container_of (dev, struct pci_dev, dev); - ctrl = pci_get_drvdata(pci_dev); - out += sprintf(buf, "Free resources: memory\n"); index = 11; res = ctrl->mem_head; @@ -80,22 +73,16 @@ static ssize_t show_ctrl (struct device *dev, struct device_attribute *attr, cha return out - buf; } -static DEVICE_ATTR (ctrl, S_IRUGO, show_ctrl, NULL); -static ssize_t show_dev (struct device *dev, struct device_attribute *attr, char *buf) +static int show_dev (struct controller *ctrl, char *buf) { - struct pci_dev *pci_dev; - struct controller *ctrl; char * out = buf; int index; struct pci_resource *res; struct pci_func *new_slot; struct slot *slot; - pci_dev = container_of (dev, struct pci_dev, dev); - ctrl = pci_get_drvdata(pci_dev); - - slot=ctrl->slot; + slot = ctrl->slot; while (slot) { new_slot = cpqhp_slot_find(slot->bus, slot->device, 0); @@ -134,10 +121,117 @@ static ssize_t show_dev (struct device *dev, struct device_attribute *attr, char return out - buf; } -static DEVICE_ATTR (dev, S_IRUGO, show_dev, NULL); -void cpqhp_create_ctrl_files (struct controller *ctrl) +static int spew_debug_info(struct controller *ctrl, char *data, int size) { - device_create_file (&ctrl->pci_dev->dev, &dev_attr_ctrl); - device_create_file (&ctrl->pci_dev->dev, &dev_attr_dev); + int used; + + used = size - show_ctrl(ctrl, data); + used = (size - used) - show_dev(ctrl, &data[used]); + return used; +} + +struct ctrl_dbg { + int size; + char *data; + struct controller *ctrl; +}; + +#define MAX_OUTPUT (4*PAGE_SIZE) + +static int open(struct inode *inode, struct file *file) +{ + struct controller *ctrl = inode->u.generic_ip; + struct ctrl_dbg *dbg; + int retval = -ENOMEM; + + lock_kernel(); + dbg = kmalloc(sizeof(*dbg), GFP_KERNEL); + if (!dbg) + goto exit; + dbg->data = kmalloc(MAX_OUTPUT, GFP_KERNEL); + if (!dbg->data) { + kfree(dbg); + goto exit; + } + dbg->size = spew_debug_info(ctrl, dbg->data, MAX_OUTPUT); + file->private_data = dbg; + retval = 0; +exit: + unlock_kernel(); + return retval; +} + +static loff_t lseek(struct file *file, loff_t off, int whence) +{ + struct ctrl_dbg *dbg; + loff_t new = -1; + + lock_kernel(); + dbg = file->private_data; + + switch (whence) { + case 0: + new = off; + break; + case 1: + new = file->f_pos + off; + break; + } + if (new < 0 || new > dbg->size) { + unlock_kernel(); + return -EINVAL; + } + unlock_kernel(); + return (file->f_pos = new); } + +static ssize_t read(struct file *file, char __user *buf, + size_t nbytes, loff_t *ppos) +{ + struct ctrl_dbg *dbg = file->private_data; + return simple_read_from_buffer(buf, nbytes, ppos, dbg->data, dbg->size); +} + +static int release(struct inode *inode, struct file *file) +{ + struct ctrl_dbg *dbg = file->private_data; + + kfree(dbg->data); + kfree(dbg); + return 0; +} + +static struct file_operations debug_ops = { + .owner = THIS_MODULE, + .open = open, + .llseek = lseek, + .read = read, + .release = release, +}; + +static struct dentry *root; + +void cpqhp_initialize_debugfs(void) +{ + if (!root) + root = debugfs_create_dir("cpqhp", NULL); +} + +void cpqhp_shutdown_debugfs(void) +{ + debugfs_remove(root); +} + +void cpqhp_create_debugfs_files(struct controller *ctrl) +{ + ctrl->dentry = debugfs_create_file(ctrl->pci_dev->dev.bus_id, S_IRUGO, root, ctrl, &debug_ops); +} + +void cpqhp_remove_debugfs_files(struct controller *ctrl) +{ + if (ctrl->dentry) + debugfs_remove(ctrl->dentry); + ctrl->dentry = NULL; +} + -- cgit 1.2.3-korg From c64b5eead93f9d3a8ca0e9ca0ffba0b99dc565b9 Mon Sep 17 00:00:00 2001 From: Kristen Accardi Date: Wed, 14 Dec 2005 09:37:26 -0800 Subject: [PATCH] acpiphp: only size new bus Only size the bus that has been added. Signed-off-by: Kristen Carlson Accardi Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/acpiphp_glue.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index 8e21f6ab89a15..509a5b3ae998f 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c @@ -794,12 +794,14 @@ static int enable_device(struct acpiphp_slot *slot) if (PCI_SLOT(dev->devfn) != slot->device) continue; if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || - dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) + dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) { max = pci_scan_bridge(bus, dev, max, pass); + if (pass && dev->subordinate) + pci_bus_size_bridges(dev->subordinate); + } } } - pci_bus_size_bridges(bus); pci_bus_assign_resources(bus); acpiphp_sanitize_bus(bus); pci_enable_bridges(bus); -- cgit 1.2.3-korg From 54c762fe62d9ff0982f38e80cbec9c59104311e9 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Thu, 22 Dec 2005 01:08:52 +0100 Subject: [PATCH] PCI: drivers/pci: some cleanups This patch contains the following cleanups: - hotplug/pciehp_core.c: make the needlessly global hpdriver_context static - #if 0 the following unused functions: - pci.c: pci_bus_max_busnr() - pci.c: pci_max_busnr() - proc.c: pci_proc_attach_bus() - remove.c: pci_remove_device_safe Signed-off-by: Adrian Bunk Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/pciehp_core.c | 2 +- drivers/pci/pci.c | 5 +++-- drivers/pci/pci.h | 5 ----- drivers/pci/proc.c | 3 ++- drivers/pci/remove.c | 3 ++- 5 files changed, 8 insertions(+), 10 deletions(-) diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c index 986e202e0b0b2..4fb569018a240 100644 --- a/drivers/pci/hotplug/pciehp_core.c +++ b/drivers/pci/hotplug/pciehp_core.c @@ -512,7 +512,7 @@ static void __exit unload_pciehpd(void) } -int hpdriver_context = 0; +static int hpdriver_context = 0; static void pciehp_remove (struct pcie_device *device) { diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 81b9b8d9bceb3..d2a633efa10ab 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -19,6 +19,7 @@ #include /* isa_dma_bridge_buggy */ #include "pci.h" +#if 0 /** * pci_bus_max_busnr - returns maximum PCI bus number of given bus' children @@ -63,6 +64,8 @@ pci_max_busnr(void) return max; } +#endif /* 0 */ + static int __pci_find_next_cap(struct pci_bus *bus, unsigned int devfn, u8 pos, int cap) { u8 id; @@ -917,8 +920,6 @@ EXPORT_SYMBOL_GPL(pci_restore_bars); EXPORT_SYMBOL(pci_enable_device_bars); EXPORT_SYMBOL(pci_enable_device); EXPORT_SYMBOL(pci_disable_device); -EXPORT_SYMBOL(pci_max_busnr); -EXPORT_SYMBOL(pci_bus_max_busnr); EXPORT_SYMBOL(pci_find_capability); EXPORT_SYMBOL(pci_bus_find_capability); EXPORT_SYMBOL(pci_release_regions); diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 294849d24590b..a6dfee2f6d2ba 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -26,20 +26,15 @@ extern int pci_user_write_config_dword(struct pci_dev *dev, int where, u32 val); #ifdef CONFIG_PROC_FS extern int pci_proc_attach_device(struct pci_dev *dev); extern int pci_proc_detach_device(struct pci_dev *dev); -extern int pci_proc_attach_bus(struct pci_bus *bus); extern int pci_proc_detach_bus(struct pci_bus *bus); #else static inline int pci_proc_attach_device(struct pci_dev *dev) { return 0; } static inline int pci_proc_detach_device(struct pci_dev *dev) { return 0; } -static inline int pci_proc_attach_bus(struct pci_bus *bus) { return 0; } static inline int pci_proc_detach_bus(struct pci_bus *bus) { return 0; } #endif /* Functions for PCI Hotplug drivers to use */ extern unsigned int pci_do_scan_bus(struct pci_bus *bus); -extern int pci_remove_device_safe(struct pci_dev *dev); -extern unsigned char pci_max_busnr(void); -extern unsigned char pci_bus_max_busnr(struct pci_bus *bus); extern int pci_bus_find_capability (struct pci_bus *bus, unsigned int devfn, int cap); extern void pci_remove_legacy_files(struct pci_bus *bus); diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c index 9eb465727fce4..d21894c63f8e0 100644 --- a/drivers/pci/proc.c +++ b/drivers/pci/proc.c @@ -431,6 +431,7 @@ int pci_proc_detach_device(struct pci_dev *dev) return 0; } +#if 0 int pci_proc_attach_bus(struct pci_bus* bus) { struct proc_dir_entry *de = bus->procdir; @@ -447,6 +448,7 @@ int pci_proc_attach_bus(struct pci_bus* bus) } return 0; } +#endif /* 0 */ int pci_proc_detach_bus(struct pci_bus* bus) { @@ -612,7 +614,6 @@ __initcall(pci_proc_init); #ifdef CONFIG_HOTPLUG EXPORT_SYMBOL(pci_proc_attach_device); -EXPORT_SYMBOL(pci_proc_attach_bus); EXPORT_SYMBOL(pci_proc_detach_bus); #endif diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c index 27a294b6965d4..1a6bf9de166fa 100644 --- a/drivers/pci/remove.c +++ b/drivers/pci/remove.c @@ -48,6 +48,7 @@ static void pci_destroy_dev(struct pci_dev *dev) * in question is not being used by a driver. * Returns 0 on success. */ +#if 0 int pci_remove_device_safe(struct pci_dev *dev) { if (pci_dev_driver(dev)) @@ -55,7 +56,7 @@ int pci_remove_device_safe(struct pci_dev *dev) pci_destroy_dev(dev); return 0; } -EXPORT_SYMBOL(pci_remove_device_safe); +#endif /* 0 */ void pci_remove_bus(struct pci_bus *pci_bus) { -- cgit 1.2.3-korg From 19272684b8e2fff39941e4c044d26ad349dd1a69 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Sat, 17 Dec 2005 09:27:50 -0800 Subject: [PATCH] PCI: update Toshiba ohci quirk DMI table I upgraded my Toshiba Satellite BIOS recently to see if it would fix an ACPI related problem I have (http://bugzilla.kernel.org/show_bug.cgi?id=5727). Unfortunately, it didn't, and moreover, Toshiba chose to change the system version in the DMI table with the update, causing the OHCI1394 related quirk to break. This patch updates the DMI table for the quirk to include Toshiba's new version name for this machine; I've tested it and it seems to work fine. Signed-off-by: Jesse Barnes Signed-off-by: Greg Kroah-Hartman --- arch/i386/pci/fixup.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/i386/pci/fixup.c b/arch/i386/pci/fixup.c index eeb1b1f2d548b..65f67070db644 100644 --- a/arch/i386/pci/fixup.c +++ b/arch/i386/pci/fixup.c @@ -413,6 +413,13 @@ static struct dmi_system_id __devinitdata toshiba_ohci1394_dmi_table[] = { DMI_MATCH(DMI_PRODUCT_VERSION, "PSM4"), }, }, + { + .ident = "Toshiba A40 based laptop", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), + DMI_MATCH(DMI_PRODUCT_VERSION, "PSA40U"), + }, + }, { } }; -- cgit 1.2.3-korg From 392a1ce761bc3b3a5d642ee341c1ff082cbb71f0 Mon Sep 17 00:00:00 2001 From: linas Date: Wed, 16 Nov 2005 17:10:41 -0600 Subject: [PATCH] PCI Error Recovery: header file patch Various PCI bus errors can be signaled by newer PCI controllers. Recovering from those errors requires an infrastructure to notify affected device drivers of the error, and a way of walking through a reset sequence. This patch adds a set of callbacks to be used by error recovery routines to notify device drivers of the various stages of recovery. Signed-off-by: Linas Vepstas Signed-off-by: Greg Kroah-Hartman --- include/linux/pci.h | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/include/linux/pci.h b/include/linux/pci.h index d0e003926744a..0a44072383ec4 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -78,6 +78,23 @@ typedef int __bitwise pci_power_t; #define PCI_UNKNOWN ((pci_power_t __force) 5) #define PCI_POWER_ERROR ((pci_power_t __force) -1) +/** The pci_channel state describes connectivity between the CPU and + * the pci device. If some PCI bus between here and the pci device + * has crashed or locked up, this info is reflected here. + */ +typedef unsigned int __bitwise pci_channel_state_t; + +enum pci_channel_state { + /* I/O channel is in normal state */ + pci_channel_io_normal = (__force pci_channel_state_t) 1, + + /* I/O to channel is blocked */ + pci_channel_io_frozen = (__force pci_channel_state_t) 2, + + /* PCI card is dead */ + pci_channel_io_perm_failure = (__force pci_channel_state_t) 3, +}; + /* * The pci_dev structure is used to describe PCI devices. */ @@ -111,6 +128,7 @@ struct pci_dev { this is D0-D3, D0 being fully functional, and D3 being off. */ + pci_channel_state_t error_state; /* current connectivity state */ struct device dev; /* Generic device interface */ /* device is compatible with these IDs */ @@ -233,6 +251,54 @@ struct pci_dynids { unsigned int use_driver_data:1; /* pci_driver->driver_data is used */ }; +/* ---------------------------------------------------------------- */ +/** PCI Error Recovery System (PCI-ERS). If a PCI device driver provides + * a set fof callbacks in struct pci_error_handlers, then that device driver + * will be notified of PCI bus errors, and will be driven to recovery + * when an error occurs. + */ + +typedef unsigned int __bitwise pci_ers_result_t; + +enum pci_ers_result { + /* no result/none/not supported in device driver */ + PCI_ERS_RESULT_NONE = (__force pci_ers_result_t) 1, + + /* Device driver can recover without slot reset */ + PCI_ERS_RESULT_CAN_RECOVER = (__force pci_ers_result_t) 2, + + /* Device driver wants slot to be reset. */ + PCI_ERS_RESULT_NEED_RESET = (__force pci_ers_result_t) 3, + + /* Device has completely failed, is unrecoverable */ + PCI_ERS_RESULT_DISCONNECT = (__force pci_ers_result_t) 4, + + /* Device driver is fully recovered and operational */ + PCI_ERS_RESULT_RECOVERED = (__force pci_ers_result_t) 5, +}; + +/* PCI bus error event callbacks */ +struct pci_error_handlers +{ + /* PCI bus error detected on this device */ + pci_ers_result_t (*error_detected)(struct pci_dev *dev, + enum pci_channel_state error); + + /* MMIO has been re-enabled, but not DMA */ + pci_ers_result_t (*mmio_enabled)(struct pci_dev *dev); + + /* PCI Express link has been reset */ + pci_ers_result_t (*link_reset)(struct pci_dev *dev); + + /* PCI slot has been reset */ + pci_ers_result_t (*slot_reset)(struct pci_dev *dev); + + /* Device driver may resume normal operations */ + void (*resume)(struct pci_dev *dev); +}; + +/* ---------------------------------------------------------------- */ + struct module; struct pci_driver { struct list_head node; @@ -245,6 +311,7 @@ struct pci_driver { int (*enable_wake) (struct pci_dev *dev, pci_power_t state, int enable); /* Enable wake event */ void (*shutdown) (struct pci_dev *dev); + struct pci_error_handlers *err_handler; struct device_driver driver; struct pci_dynids dynids; }; -- cgit 1.2.3-korg From 065c6359071c6d7d1f8b2839317471d1d97fc70b Mon Sep 17 00:00:00 2001 From: "linas@austin.ibm.com" Date: Fri, 2 Dec 2005 19:16:18 -0600 Subject: [PATCH] PCI Error Recovery: documentation Various PCI bus errors can be signaled by newer PCI controllers. Recovering from those errors requires an infrastructure to notify affected device drivers of the error, and a way of walking through a reset sequence. This patch adds documentation describing the current error recovery proposal. Signed-off-by: Linas Vepstas Signed-off-by: Greg Kroah-Hartman --- Documentation/pci-error-recovery.txt | 246 +++++++++++++++++++++++++++++++++++ MAINTAINERS | 7 + 2 files changed, 253 insertions(+) create mode 100644 Documentation/pci-error-recovery.txt diff --git a/Documentation/pci-error-recovery.txt b/Documentation/pci-error-recovery.txt new file mode 100644 index 0000000000000..d089967e4948b --- /dev/null +++ b/Documentation/pci-error-recovery.txt @@ -0,0 +1,246 @@ + + PCI Error Recovery + ------------------ + May 31, 2005 + + Current document maintainer: + Linas Vepstas + + +Some PCI bus controllers are able to detect certain "hard" PCI errors +on the bus, such as parity errors on the data and address busses, as +well as SERR and PERR errors. These chipsets are then able to disable +I/O to/from the affected device, so that, for example, a bad DMA +address doesn't end up corrupting system memory. These same chipsets +are also able to reset the affected PCI device, and return it to +working condition. This document describes a generic API form +performing error recovery. + +The core idea is that after a PCI error has been detected, there must +be a way for the kernel to coordinate with all affected device drivers +so that the pci card can be made operational again, possibly after +performing a full electrical #RST of the PCI card. The API below +provides a generic API for device drivers to be notified of PCI +errors, and to be notified of, and respond to, a reset sequence. + +Preliminary sketch of API, cut-n-pasted-n-modified email from +Ben Herrenschmidt, circa 5 april 2005 + +The error recovery API support is exposed to the driver in the form of +a structure of function pointers pointed to by a new field in struct +pci_driver. The absence of this pointer in pci_driver denotes an +"non-aware" driver, behaviour on these is platform dependant. +Platforms like ppc64 can try to simulate pci hotplug remove/add. + +The definition of "pci_error_token" is not covered here. It is based on +Seto's work on the synchronous error detection. We still need to define +functions for extracting infos out of an opaque error token. This is +separate from this API. + +This structure has the form: + +struct pci_error_handlers +{ + int (*error_detected)(struct pci_dev *dev, pci_error_token error); + int (*mmio_enabled)(struct pci_dev *dev); + int (*resume)(struct pci_dev *dev); + int (*link_reset)(struct pci_dev *dev); + int (*slot_reset)(struct pci_dev *dev); +}; + +A driver doesn't have to implement all of these callbacks. The +only mandatory one is error_detected(). If a callback is not +implemented, the corresponding feature is considered unsupported. +For example, if mmio_enabled() and resume() aren't there, then the +driver is assumed as not doing any direct recovery and requires +a reset. If link_reset() is not implemented, the card is assumed as +not caring about link resets, in which case, if recover is supported, +the core can try recover (but not slot_reset() unless it really did +reset the slot). If slot_reset() is not supported, link_reset() can +be called instead on a slot reset. + +At first, the call will always be : + + 1) error_detected() + + Error detected. This is sent once after an error has been detected. At +this point, the device might not be accessible anymore depending on the +platform (the slot will be isolated on ppc64). The driver may already +have "noticed" the error because of a failing IO, but this is the proper +"synchronisation point", that is, it gives a chance to the driver to +cleanup, waiting for pending stuff (timers, whatever, etc...) to +complete; it can take semaphores, schedule, etc... everything but touch +the device. Within this function and after it returns, the driver +shouldn't do any new IOs. Called in task context. This is sort of a +"quiesce" point. See note about interrupts at the end of this doc. + + Result codes: + - PCIERR_RESULT_CAN_RECOVER: + Driever returns this if it thinks it might be able to recover + the HW by just banging IOs or if it wants to be given + a chance to extract some diagnostic informations (see + below). + - PCIERR_RESULT_NEED_RESET: + Driver returns this if it thinks it can't recover unless the + slot is reset. + - PCIERR_RESULT_DISCONNECT: + Return this if driver thinks it won't recover at all, + (this will detach the driver ? or just leave it + dangling ? to be decided) + +So at this point, we have called error_detected() for all drivers +on the segment that had the error. On ppc64, the slot is isolated. What +happens now typically depends on the result from the drivers. If all +drivers on the segment/slot return PCIERR_RESULT_CAN_RECOVER, we would +re-enable IOs on the slot (or do nothing special if the platform doesn't +isolate slots) and call 2). If not and we can reset slots, we go to 4), +if neither, we have a dead slot. If it's an hotplug slot, we might +"simulate" reset by triggering HW unplug/replug though. + +>>> Current ppc64 implementation assumes that a device driver will +>>> *not* schedule or semaphore in this routine; the current ppc64 +>>> implementation uses one kernel thread to notify all devices; +>>> thus, of one device sleeps/schedules, all devices are affected. +>>> Doing better requires complex multi-threaded logic in the error +>>> recovery implementation (e.g. waiting for all notification threads +>>> to "join" before proceeding with recovery.) This seems excessively +>>> complex and not worth implementing. + +>>> The current ppc64 implementation doesn't much care if the device +>>> attempts i/o at this point, or not. I/O's will fail, returning +>>> a value of 0xff on read, and writes will be dropped. If the device +>>> driver attempts more than 10K I/O's to a frozen adapter, it will +>>> assume that the device driver has gone into an infinite loop, and +>>> it will panic the the kernel. + + 2) mmio_enabled() + + This is the "early recovery" call. IOs are allowed again, but DMA is +not (hrm... to be discussed, I prefer not), with some restrictions. This +is NOT a callback for the driver to start operations again, only to +peek/poke at the device, extract diagnostic information, if any, and +eventually do things like trigger a device local reset or some such, +but not restart operations. This is sent if all drivers on a segment +agree that they can try to recover and no automatic link reset was +performed by the HW. If the platform can't just re-enable IOs without +a slot reset or a link reset, it doesn't call this callback and goes +directly to 3) or 4). All IOs should be done _synchronously_ from +within this callback, errors triggered by them will be returned via +the normal pci_check_whatever() api, no new error_detected() callback +will be issued due to an error happening here. However, such an error +might cause IOs to be re-blocked for the whole segment, and thus +invalidate the recovery that other devices on the same segment might +have done, forcing the whole segment into one of the next states, +that is link reset or slot reset. + + Result codes: + - PCIERR_RESULT_RECOVERED + Driver returns this if it thinks the device is fully + functionnal and thinks it is ready to start + normal driver operations again. There is no + guarantee that the driver will actually be + allowed to proceed, as another driver on the + same segment might have failed and thus triggered a + slot reset on platforms that support it. + + - PCIERR_RESULT_NEED_RESET + Driver returns this if it thinks the device is not + recoverable in it's current state and it needs a slot + reset to proceed. + + - PCIERR_RESULT_DISCONNECT + Same as above. Total failure, no recovery even after + reset driver dead. (To be defined more precisely) + +>>> The current ppc64 implementation does not implement this callback. + + 3) link_reset() + + This is called after the link has been reset. This is typically +a PCI Express specific state at this point and is done whenever a +non-fatal error has been detected that can be "solved" by resetting +the link. This call informs the driver of the reset and the driver +should check if the device appears to be in working condition. +This function acts a bit like 2) mmio_enabled(), in that the driver +is not supposed to restart normal driver I/O operations right away. +Instead, it should just "probe" the device to check it's recoverability +status. If all is right, then the core will call resume() once all +drivers have ack'd link_reset(). + + Result codes: + (identical to mmio_enabled) + +>>> The current ppc64 implementation does not implement this callback. + + 4) slot_reset() + + This is called after the slot has been soft or hard reset by the +platform. A soft reset consists of asserting the adapter #RST line +and then restoring the PCI BARs and PCI configuration header. If the +platform supports PCI hotplug, then it might instead perform a hard +reset by toggling power on the slot off/on. This call gives drivers +the chance to re-initialize the hardware (re-download firmware, etc.), +but drivers shouldn't restart normal I/O processing operations at +this point. (See note about interrupts; interrupts aren't guaranteed +to be delivered until the resume() callback has been called). If all +device drivers report success on this callback, the patform will call +resume() to complete the error handling and let the driver restart +normal I/O processing. + +A driver can still return a critical failure for this function if +it can't get the device operational after reset. If the platform +previously tried a soft reset, it migh now try a hard reset (power +cycle) and then call slot_reset() again. It the device still can't +be recovered, there is nothing more that can be done; the platform +will typically report a "permanent failure" in such a case. The +device will be considered "dead" in this case. + + Result codes: + - PCIERR_RESULT_DISCONNECT + Same as above. + +>>> The current ppc64 implementation does not try a power-cycle reset +>>> if the driver returned PCIERR_RESULT_DISCONNECT. However, it should. + + 5) resume() + + This is called if all drivers on the segment have returned +PCIERR_RESULT_RECOVERED from one of the 3 prevous callbacks. +That basically tells the driver to restart activity, tht everything +is back and running. No result code is taken into account here. If +a new error happens, it will restart a new error handling process. + +That's it. I think this covers all the possibilities. The way those +callbacks are called is platform policy. A platform with no slot reset +capability for example may want to just "ignore" drivers that can't +recover (disconnect them) and try to let other cards on the same segment +recover. Keep in mind that in most real life cases, though, there will +be only one driver per segment. + +Now, there is a note about interrupts. If you get an interrupt and your +device is dead or has been isolated, there is a problem :) + +After much thinking, I decided to leave that to the platform. That is, +the recovery API only precies that: + + - There is no guarantee that interrupt delivery can proceed from any +device on the segment starting from the error detection and until the +restart callback is sent, at which point interrupts are expected to be +fully operational. + + - There is no guarantee that interrupt delivery is stopped, that is, ad +river that gets an interrupts after detecting an error, or that detects +and error within the interrupt handler such that it prevents proper +ack'ing of the interrupt (and thus removal of the source) should just +return IRQ_NOTHANDLED. It's up to the platform to deal with taht +condition, typically by masking the irq source during the duration of +the error handling. It is expected that the platform "knows" which +interrupts are routed to error-management capable slots and can deal +with temporarily disabling that irq number during error processing (this +isn't terribly complex). That means some IRQ latency for other devices +sharing the interrupt, but there is simply no other way. High end +platforms aren't supposed to share interrupts between many devices +anyway :) + + +Revised: 31 May 2005 Linas Vepstas diff --git a/MAINTAINERS b/MAINTAINERS index 270e28c0506aa..8024d1b700656 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1994,6 +1994,13 @@ M: hch@infradead.org L: linux-abi-devel@lists.sourceforge.net S: Maintained +PCI ERROR RECOVERY +P: Linas Vepstas +M: linas@austin.ibm.com +L: linux-kernel@vger.kernel.org +L: linux-pci@atrey.karlin.mff.cuni.cz +S: Supported + PCI SOUND DRIVERS (ES1370, ES1371 and SONICVIBES) P: Thomas Sailer M: sailer@ife.ee.ethz.ch -- cgit 1.2.3-korg From d1d6da8f9fb9a0633a2f36b84b292752d78f7d31 Mon Sep 17 00:00:00 2001 From: Richard Knutsson Date: Wed, 30 Nov 2005 00:59:14 +0100 Subject: [PATCH] arch: Replace pci_module_init() with pci_register_driver() Replace obsolete pci_module_init() with pci_register_driver(). Signed-off-by: Richard Knutsson Signed-off-by: Greg Kroah-Hartman --- arch/i386/kernel/scx200.c | 2 +- arch/mips/vr41xx/common/vrc4173.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/i386/kernel/scx200.c b/arch/i386/kernel/scx200.c index 9c968ae67c43d..321f5fd26e750 100644 --- a/arch/i386/kernel/scx200.c +++ b/arch/i386/kernel/scx200.c @@ -143,7 +143,7 @@ static int __init scx200_init(void) { printk(KERN_INFO NAME ": NatSemi SCx200 Driver\n"); - return pci_module_init(&scx200_pci_driver); + return pci_register_driver(&scx200_pci_driver); } static void __exit scx200_cleanup(void) diff --git a/arch/mips/vr41xx/common/vrc4173.c b/arch/mips/vr41xx/common/vrc4173.c index 462a9af30eef7..cc52e75e14e72 100644 --- a/arch/mips/vr41xx/common/vrc4173.c +++ b/arch/mips/vr41xx/common/vrc4173.c @@ -561,7 +561,7 @@ static int __devinit vrc4173_init(void) { int err; - err = pci_module_init(&vrc4173_driver); + err = pci_register_driver(&vrc4173_driver); if (err < 0) return err; -- cgit 1.2.3-korg From 9bfab8cec652c80b4864b4d9247520dca042c2df Mon Sep 17 00:00:00 2001 From: Richard Knutsson Date: Wed, 30 Nov 2005 00:59:34 +0100 Subject: [PATCH] drivers/block: Replace pci_module_init() with pci_register_driver() Replace obsolete pci_module_init() with pci_register_driver(). Signed-off-by: Richard Knutsson Signed-off-by: Greg Kroah-Hartman --- drivers/block/DAC960.c | 2 +- drivers/block/cciss.c | 2 +- drivers/block/sx8.c | 2 +- drivers/block/umem.c | 2 +- drivers/media/radio/radio-gemtek-pci.c | 2 +- drivers/media/radio/radio-maxiradio.c | 2 +- drivers/media/video/bttv-driver.c | 2 +- drivers/media/video/saa7134/saa7134-core.c | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c index 4a7bb7dfce851..6ede1f352c295 100644 --- a/drivers/block/DAC960.c +++ b/drivers/block/DAC960.c @@ -7179,7 +7179,7 @@ static int DAC960_init_module(void) { int ret; - ret = pci_module_init(&DAC960_pci_driver); + ret = pci_register_driver(&DAC960_pci_driver); #ifdef DAC960_GAM_MINOR if (!ret) DAC960_gam_init(); diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index e4e9f255bd1f7..12d7b9bdfa93b 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -3360,7 +3360,7 @@ static int __init cciss_init(void) printk(KERN_INFO DRIVER_NAME "\n"); /* Register for our PCI devices */ - return pci_module_init(&cciss_pci_driver); + return pci_register_driver(&cciss_pci_driver); } static void __exit cciss_cleanup(void) diff --git a/drivers/block/sx8.c b/drivers/block/sx8.c index c0cdc182a8b0b..a7e0975c8c9f9 100644 --- a/drivers/block/sx8.c +++ b/drivers/block/sx8.c @@ -1755,7 +1755,7 @@ static void carm_remove_one (struct pci_dev *pdev) static int __init carm_init(void) { - return pci_module_init(&carm_driver); + return pci_register_driver(&carm_driver); } static void __exit carm_exit(void) diff --git a/drivers/block/umem.c b/drivers/block/umem.c index 15299e7a1ade6..a3614e6a68d0b 100644 --- a/drivers/block/umem.c +++ b/drivers/block/umem.c @@ -1174,7 +1174,7 @@ static int __init mm_init(void) printk(KERN_INFO DRIVER_VERSION " : " DRIVER_DESC "\n"); - retval = pci_module_init(&mm_pci_driver); + retval = pci_register_driver(&mm_pci_driver); if (retval) return -ENOMEM; diff --git a/drivers/media/radio/radio-gemtek-pci.c b/drivers/media/radio/radio-gemtek-pci.c index 630cc786d0a4f..78b2888bf581f 100644 --- a/drivers/media/radio/radio-gemtek-pci.c +++ b/drivers/media/radio/radio-gemtek-pci.c @@ -394,7 +394,7 @@ static struct pci_driver gemtek_pci_driver = static int __init gemtek_pci_init_module( void ) { - return pci_module_init( &gemtek_pci_driver ); + return pci_register_driver( &gemtek_pci_driver ); } static void __exit gemtek_pci_cleanup_module( void ) diff --git a/drivers/media/radio/radio-maxiradio.c b/drivers/media/radio/radio-maxiradio.c index 02d39a50d5ed2..7b33d8f2f8f8d 100644 --- a/drivers/media/radio/radio-maxiradio.c +++ b/drivers/media/radio/radio-maxiradio.c @@ -337,7 +337,7 @@ static struct pci_driver maxiradio_driver = { static int __init maxiradio_radio_init(void) { - return pci_module_init(&maxiradio_driver); + return pci_register_driver(&maxiradio_driver); } static void __exit maxiradio_radio_exit(void) diff --git a/drivers/media/video/bttv-driver.c b/drivers/media/video/bttv-driver.c index 1ddf9ba613ef9..00bd8ea5eaeb7 100644 --- a/drivers/media/video/bttv-driver.c +++ b/drivers/media/video/bttv-driver.c @@ -4253,7 +4253,7 @@ static int bttv_init_module(void) bttv_check_chipset(); bus_register(&bttv_sub_bus_type); - return pci_module_init(&bttv_pci_driver); + return pci_register_driver(&bttv_pci_driver); } static void bttv_cleanup_module(void) diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c index 23d8747338ede..21cb3d6be839c 100644 --- a/drivers/media/video/saa7134/saa7134-core.c +++ b/drivers/media/video/saa7134/saa7134-core.c @@ -1156,7 +1156,7 @@ static int saa7134_init(void) printk(KERN_INFO "saa7130/34: snapshot date %04d-%02d-%02d\n", SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100); #endif - return pci_module_init(&saa7134_pci_driver); + return pci_register_driver(&saa7134_pci_driver); } static void saa7134_fini(void) -- cgit 1.2.3-korg From 46654728b55bf5d09dc91fa45f532131d8a609f2 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 6 Dec 2005 15:33:15 -0800 Subject: [PATCH] drivers/sound/oss: Replace pci_module_init() with pci_register_driver() Replace obsolete pci_module_init() with pci_register_driver(). Signed-off-by: Greg Kroah-Hartman Signed-off-by: Richard Knutsson --- sound/oss/ad1889.c | 2 +- sound/oss/btaudio.c | 2 +- sound/oss/cmpci.c | 2 +- sound/oss/cs4281/cs4281m.c | 2 +- sound/oss/cs46xx.c | 2 +- sound/oss/emu10k1/main.c | 2 +- sound/oss/es1370.c | 2 +- sound/oss/es1371.c | 2 +- sound/oss/ite8172.c | 2 +- sound/oss/kahlua.c | 2 +- sound/oss/maestro.c | 2 +- sound/oss/nec_vrc5477.c | 2 +- sound/oss/nm256_audio.c | 2 +- sound/oss/rme96xx.c | 2 +- sound/oss/sonicvibes.c | 2 +- sound/oss/ymfpci.c | 2 +- 16 files changed, 16 insertions(+), 16 deletions(-) diff --git a/sound/oss/ad1889.c b/sound/oss/ad1889.c index 2cfd214e4c2a4..a0d73f3431003 100644 --- a/sound/oss/ad1889.c +++ b/sound/oss/ad1889.c @@ -1089,7 +1089,7 @@ static struct pci_driver ad1889_driver = { static int __init ad1889_init_module(void) { - return pci_module_init(&ad1889_driver); + return pci_register_driver(&ad1889_driver); } static void ad1889_exit_module(void) diff --git a/sound/oss/btaudio.c b/sound/oss/btaudio.c index a85093fec7bed..4007a5680acb9 100644 --- a/sound/oss/btaudio.c +++ b/sound/oss/btaudio.c @@ -1101,7 +1101,7 @@ static int btaudio_init_module(void) digital ? "digital" : "", analog && digital ? "+" : "", analog ? "analog" : ""); - return pci_module_init(&btaudio_pci_driver); + return pci_register_driver(&btaudio_pci_driver); } static void btaudio_cleanup_module(void) diff --git a/sound/oss/cmpci.c b/sound/oss/cmpci.c index 74dcca78c6c0c..7cfbb08db5371 100644 --- a/sound/oss/cmpci.c +++ b/sound/oss/cmpci.c @@ -3366,7 +3366,7 @@ static struct pci_driver cm_driver = { static int __init init_cmpci(void) { printk(KERN_INFO "cmpci: version $Revision: 6.82 $ time " __TIME__ " " __DATE__ "\n"); - return pci_module_init(&cm_driver); + return pci_register_driver(&cm_driver); } static void __exit cleanup_cmpci(void) diff --git a/sound/oss/cs4281/cs4281m.c b/sound/oss/cs4281/cs4281m.c index 46dd41dc2a340..0720365f64388 100644 --- a/sound/oss/cs4281/cs4281m.c +++ b/sound/oss/cs4281/cs4281m.c @@ -4461,7 +4461,7 @@ static int __init cs4281_init_module(void) printk(KERN_INFO "cs4281: version v%d.%02d.%d time " __TIME__ " " __DATE__ "\n", CS4281_MAJOR_VERSION, CS4281_MINOR_VERSION, CS4281_ARCH); - rtn = pci_module_init(&cs4281_pci_driver); + rtn = pci_register_driver(&cs4281_pci_driver); CS_DBGOUT(CS_INIT | CS_FUNCTION, 2, printk(KERN_INFO "cs4281: cs4281_init_module()- (%d)\n",rtn)); diff --git a/sound/oss/cs46xx.c b/sound/oss/cs46xx.c index 0da4d93f04a65..58e25c82eaf29 100644 --- a/sound/oss/cs46xx.c +++ b/sound/oss/cs46xx.c @@ -5690,7 +5690,7 @@ static int __init cs46xx_init_module(void) int rtn = 0; CS_DBGOUT(CS_INIT | CS_FUNCTION, 2, printk(KERN_INFO "cs46xx: cs46xx_init_module()+ \n")); - rtn = pci_module_init(&cs46xx_pci_driver); + rtn = pci_register_driver(&cs46xx_pci_driver); if(rtn == -ENODEV) { diff --git a/sound/oss/emu10k1/main.c b/sound/oss/emu10k1/main.c index 9b905bae423eb..23241cbdd90f4 100644 --- a/sound/oss/emu10k1/main.c +++ b/sound/oss/emu10k1/main.c @@ -1428,7 +1428,7 @@ static int __init emu10k1_init_module(void) { printk(KERN_INFO "Creative EMU10K1 PCI Audio Driver, version " DRIVER_VERSION ", " __TIME__ " " __DATE__ "\n"); - return pci_module_init(&emu10k1_pci_driver); + return pci_register_driver(&emu10k1_pci_driver); } static void __exit emu10k1_cleanup_module(void) diff --git a/sound/oss/es1370.c b/sound/oss/es1370.c index 8538085086e7c..ae55c536613a0 100644 --- a/sound/oss/es1370.c +++ b/sound/oss/es1370.c @@ -2779,7 +2779,7 @@ static struct pci_driver es1370_driver = { static int __init init_es1370(void) { printk(KERN_INFO "es1370: version v0.38 time " __TIME__ " " __DATE__ "\n"); - return pci_module_init(&es1370_driver); + return pci_register_driver(&es1370_driver); } static void __exit cleanup_es1370(void) diff --git a/sound/oss/es1371.c b/sound/oss/es1371.c index 12a56d5ab4985..5c697f162579d 100644 --- a/sound/oss/es1371.c +++ b/sound/oss/es1371.c @@ -3090,7 +3090,7 @@ static struct pci_driver es1371_driver = { static int __init init_es1371(void) { printk(KERN_INFO PFX "version v0.32 time " __TIME__ " " __DATE__ "\n"); - return pci_module_init(&es1371_driver); + return pci_register_driver(&es1371_driver); } static void __exit cleanup_es1371(void) diff --git a/sound/oss/ite8172.c b/sound/oss/ite8172.c index 26e5944b6ba86..8fd2f9a9e6681 100644 --- a/sound/oss/ite8172.c +++ b/sound/oss/ite8172.c @@ -2206,7 +2206,7 @@ static struct pci_driver it8172_driver = { static int __init init_it8172(void) { info("version v0.5 time " __TIME__ " " __DATE__); - return pci_module_init(&it8172_driver); + return pci_register_driver(&it8172_driver); } static void __exit cleanup_it8172(void) diff --git a/sound/oss/kahlua.c b/sound/oss/kahlua.c index 808c5ef969be0..2835a7c038efa 100644 --- a/sound/oss/kahlua.c +++ b/sound/oss/kahlua.c @@ -218,7 +218,7 @@ static struct pci_driver kahlua_driver = { static int __init kahlua_init_module(void) { printk(KERN_INFO "Cyrix Kahlua VSA1 XpressAudio support (c) Copyright 2003 Red Hat Inc\n"); - return pci_module_init(&kahlua_driver); + return pci_register_driver(&kahlua_driver); } static void __devexit kahlua_cleanup_module(void) diff --git a/sound/oss/maestro.c b/sound/oss/maestro.c index f9ac5b16f61ac..d4b569acf7643 100644 --- a/sound/oss/maestro.c +++ b/sound/oss/maestro.c @@ -3624,7 +3624,7 @@ static int __init init_maestro(void) { int rc; - rc = pci_module_init(&maestro_pci_driver); + rc = pci_register_driver(&maestro_pci_driver); if (rc < 0) return rc; diff --git a/sound/oss/nec_vrc5477.c b/sound/oss/nec_vrc5477.c index 9ac4bf7e1e894..fbb9170e8e0ac 100644 --- a/sound/oss/nec_vrc5477.c +++ b/sound/oss/nec_vrc5477.c @@ -2045,7 +2045,7 @@ static struct pci_driver vrc5477_ac97_driver = { static int __init init_vrc5477_ac97(void) { printk("Vrc5477 AC97 driver: version v0.2 time " __TIME__ " " __DATE__ " by Jun Sun\n"); - return pci_module_init(&vrc5477_ac97_driver); + return pci_register_driver(&vrc5477_ac97_driver); } static void __exit cleanup_vrc5477_ac97(void) diff --git a/sound/oss/nm256_audio.c b/sound/oss/nm256_audio.c index 42d8f05689c21..7de079b202f21 100644 --- a/sound/oss/nm256_audio.c +++ b/sound/oss/nm256_audio.c @@ -1644,7 +1644,7 @@ module_param(force_load, bool, 0); static int __init do_init_nm256(void) { printk (KERN_INFO "NeoMagic 256AV/256ZX audio driver, version 1.1p\n"); - return pci_module_init(&nm256_pci_driver); + return pci_register_driver(&nm256_pci_driver); } static void __exit cleanup_nm256 (void) diff --git a/sound/oss/rme96xx.c b/sound/oss/rme96xx.c index 318dc51009fe2..faa0b7919b652 100644 --- a/sound/oss/rme96xx.c +++ b/sound/oss/rme96xx.c @@ -1095,7 +1095,7 @@ static int __init init_rme96xx(void) devices = ((devices-1) & RME96xx_MASK_DEVS) + 1; printk(KERN_INFO RME_MESS" reserving %d dsp device(s)\n",devices); numcards = 0; - return pci_module_init(&rme96xx_driver); + return pci_register_driver(&rme96xx_driver); } static void __exit cleanup_rme96xx(void) diff --git a/sound/oss/sonicvibes.c b/sound/oss/sonicvibes.c index 17d0e461f8d86..71b05e2f69776 100644 --- a/sound/oss/sonicvibes.c +++ b/sound/oss/sonicvibes.c @@ -2765,7 +2765,7 @@ static int __init init_sonicvibes(void) if (!(wavetable_mem = __get_free_pages(GFP_KERNEL, 20-PAGE_SHIFT))) printk(KERN_INFO "sv: cannot allocate 1MB of contiguous nonpageable memory for wavetable data\n"); #endif - return pci_module_init(&sv_driver); + return pci_register_driver(&sv_driver); } static void __exit cleanup_sonicvibes(void) diff --git a/sound/oss/ymfpci.c b/sound/oss/ymfpci.c index 8dae59bd05a29..f8bd72e46f57d 100644 --- a/sound/oss/ymfpci.c +++ b/sound/oss/ymfpci.c @@ -2680,7 +2680,7 @@ static struct pci_driver ymfpci_driver = { static int __init ymf_init_module(void) { - return pci_module_init(&ymfpci_driver); + return pci_register_driver(&ymfpci_driver); } static void __exit ymf_cleanup_module (void) -- cgit 1.2.3-korg From 93b47684f60cf25e8cefe19a21d94aa0257fdf36 Mon Sep 17 00:00:00 2001 From: Richard Knutsson Date: Wed, 30 Nov 2005 01:00:35 +0100 Subject: [PATCH] drivers/*rest*: Replace pci_module_init() with pci_register_driver() Replace obsolete pci_module_init() with pci_register_driver(). Signed-off-by: Richard Knutsson Signed-off-by: Greg Kroah-Hartman --- drivers/hwmon/vt8231.c | 2 +- drivers/parport/parport_serial.c | 2 +- drivers/pcmcia/vrc4173_cardu.c | 2 +- drivers/serial/serial_txx9.c | 2 +- drivers/video/cyblafb.c | 1 + 5 files changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/hwmon/vt8231.c b/drivers/hwmon/vt8231.c index d00a726d0239a..3eb08f004c0f8 100644 --- a/drivers/hwmon/vt8231.c +++ b/drivers/hwmon/vt8231.c @@ -841,7 +841,7 @@ static int __devinit vt8231_pci_probe(struct pci_dev *dev, static int __init sm_vt8231_init(void) { - return pci_module_init(&vt8231_pci_driver); + return pci_register_driver(&vt8231_pci_driver); } static void __exit sm_vt8231_exit(void) diff --git a/drivers/parport/parport_serial.c b/drivers/parport/parport_serial.c index d3dad0aac7cb8..76dd077e3184f 100644 --- a/drivers/parport/parport_serial.c +++ b/drivers/parport/parport_serial.c @@ -464,7 +464,7 @@ static struct pci_driver parport_serial_pci_driver = { static int __init parport_serial_init (void) { - return pci_module_init (&parport_serial_pci_driver); + return pci_register_driver (&parport_serial_pci_driver); } static void __exit parport_serial_exit (void) diff --git a/drivers/pcmcia/vrc4173_cardu.c b/drivers/pcmcia/vrc4173_cardu.c index 1b277d2c1c96d..b502db2790e05 100644 --- a/drivers/pcmcia/vrc4173_cardu.c +++ b/drivers/pcmcia/vrc4173_cardu.c @@ -561,7 +561,7 @@ static int __devinit vrc4173_cardu_init(void) { vrc4173_cardu_slots = 0; - return pci_module_init(&vrc4173_cardu_driver); + return pci_register_driver(&vrc4173_cardu_driver); } static void __devexit vrc4173_cardu_exit(void) diff --git a/drivers/serial/serial_txx9.c b/drivers/serial/serial_txx9.c index f10c86d60b647..995d9dd9ddd59 100644 --- a/drivers/serial/serial_txx9.c +++ b/drivers/serial/serial_txx9.c @@ -1195,7 +1195,7 @@ static int __init serial_txx9_init(void) serial_txx9_register_ports(&serial_txx9_reg); #ifdef ENABLE_SERIAL_TXX9_PCI - ret = pci_module_init(&serial_txx9_pci_driver); + ret = pci_register_driver(&serial_txx9_pci_driver); #endif } return ret; diff --git a/drivers/video/cyblafb.c b/drivers/video/cyblafb.c index e9f5dee67e3cc..2b972461a030b 100644 --- a/drivers/video/cyblafb.c +++ b/drivers/video/cyblafb.c @@ -1666,6 +1666,7 @@ static int __devinit cyblafb_init(void) #endif output("CyblaFB version %s initializing\n", VERSION); return pci_module_init(&cyblafb_pci_driver); + return pci_register_driver(&cyblafb_pci_driver); } static void __exit cyblafb_exit(void) -- cgit 1.2.3-korg