2005-02-03 18:44:37

by Greg KH

[permalink] [raw]
Subject: [BK PATCH] PCI fixes for 2.6.11-rc3

Hi,

Here are a few PCI and PCI Hotplug bugfixes 2.6.11-rc3. All of these
patches have been in the past few -mm releases.

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

Patches will be posted to linux-kernel and linux-pci as a follow-up
thread for those who want to see them.

thanks,

greg k-h

MAINTAINERS | 1
drivers/pci/hotplug/rpaphp.h | 7 --
drivers/pci/hotplug/rpaphp_core.c | 39 ++++++++----
drivers/pci/pci-sysfs.c | 1
drivers/pci/pcie/portdrv.h | 7 --
drivers/pci/pcie/portdrv_bus.c | 15 ----
drivers/pci/pcie/portdrv_core.c | 119 +++++++++++++++-----------------------
drivers/pci/pcie/portdrv_pci.c | 22 -------
drivers/pci/probe.c | 2
drivers/pci/quirks.c | 10 +++
10 files changed, 99 insertions(+), 124 deletions(-)
-----


Brian King:
o pci: Add Citrine quirk

Greg Kroah-Hartman:
o PCI: add linux-pci mailing list to PCI maintainers entry

John Rose:
o PCI Hotplug: remove incorrect rpaphp firmware dependency

Kay Sievers:
o PCI: memset rom attribute before using it

Olaf Hering:
o PCI: typo in pci_scan_bus_parented

Tom L. Nguyen:
o PCI: change sysfs representation of PCI-E devices


2005-02-03 17:45:54

by Greg KH

[permalink] [raw]
Subject: [PATCH] PCI: add linux-pci mailing list to PCI maintainers entry.

ChangeSet 1.2045, 2005/02/03 00:41:32-08:00, [email protected]

[PATCH] PCI: add linux-pci mailing list to PCI maintainers entry.

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


MAINTAINERS | 1 +
1 files changed, 1 insertion(+)


diff -Nru a/MAINTAINERS b/MAINTAINERS
--- a/MAINTAINERS 2005-02-03 09:28:32 -08:00
+++ b/MAINTAINERS 2005-02-03 09:28:32 -08:00
@@ -1746,6 +1746,7 @@
P: Greg Kroah-Hartman
M: [email protected]
L: [email protected]
+L: [email protected]
S: Supported

PCI HOTPLUG CORE

2005-02-03 17:51:34

by Greg KH

[permalink] [raw]
Subject: [PATCH] PCI Hotplug: remove incorrect rpaphp firmware dependency

ChangeSet 1.2044, 2005/02/03 00:41:04-08:00, [email protected]

[PATCH] PCI Hotplug: remove incorrect rpaphp firmware dependency

The RPA PCI Hotplug module incorrectly uses a certain firmware property when
determining the hotplug capabilities of a slot. Recent firmware changes have
demonstrated that this property should not be referenced or depended upon by
the OS. This patch removes the dependency, and implements a correct set of
logic for determining hotplug capabilities.

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

diff -puN drivers/pci/hotplug/rpadlpar_core.c~02_rpadebug drivers/pci/hotplug/rpadlpar_core.c


drivers/pci/hotplug/rpaphp.h | 7 ------
drivers/pci/hotplug/rpaphp_core.c | 39 +++++++++++++++++++++++++++-----------
2 files changed, 28 insertions(+), 18 deletions(-)


diff -Nru a/drivers/pci/hotplug/rpaphp.h b/drivers/pci/hotplug/rpaphp.h
--- a/drivers/pci/hotplug/rpaphp.h 2005-02-03 09:28:39 -08:00
+++ b/drivers/pci/hotplug/rpaphp.h 2005-02-03 09:28:39 -08:00
@@ -109,13 +109,6 @@
extern struct list_head rpaphp_slot_head;
extern int num_slots;

-static inline int is_hotplug_capable(struct device_node *dn)
-{
- unsigned char *ptr = get_property(dn, "ibm,fw-pci-hot-plug-ctrl", NULL);
-
- return (int) (ptr != NULL);
-}
-
/* function prototypes */

/* rpaphp_pci.c */
diff -Nru a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c
--- a/drivers/pci/hotplug/rpaphp_core.c 2005-02-03 09:28:39 -08:00
+++ b/drivers/pci/hotplug/rpaphp_core.c 2005-02-03 09:28:39 -08:00
@@ -287,26 +287,43 @@
return 1;
}

-static int is_php_dn(struct device_node *dn, int **indexes, int **names, int **types,
- int **power_domains)
+static int is_php_type(char *drc_type)
{
+ unsigned long value;
+ char *endptr;
+
+ /* PCI Hotplug nodes have an integer for drc_type */
+ value = simple_strtoul(drc_type, &endptr, 10);
+ if (endptr == drc_type)
+ return 0;
+
+ return 1;
+}
+
+static int is_php_dn(struct device_node *dn, int **indexes, int **names,
+ int **types, int **power_domains)
+{
+ int *drc_types;
int rc;

- if (!is_hotplug_capable(dn))
- return (0);
- rc = get_children_props(dn, indexes, names, types, power_domains);
- if (rc)
- return (0);
- return (1);
+ rc = get_children_props(dn, indexes, names, &drc_types, power_domains);
+ if (rc) {
+ if (is_php_type((char *) &drc_types[1])) {
+ *types = drc_types;
+ return 1;
+ }
+ }
+
+ return 0;
}

-static int is_dr_dn(struct device_node *dn, int **indexes, int **names, int **types,
- int **power_domains, int **my_drc_index)
+static int is_dr_dn(struct device_node *dn, int **indexes, int **names,
+ int **types, int **power_domains, int **my_drc_index)
{
int rc;

*my_drc_index = (int *) get_property(dn, "ibm,my-drc-index", NULL);
- if(!*my_drc_index)
+ if(!*my_drc_index)
return (0);

if (!dn->parent)

2005-02-03 18:05:30

by Greg KH

[permalink] [raw]
Subject: [PATCH] PCI: memset rom attribute before using it

ChangeSet 1.2043, 2005/02/03 00:40:37-08:00, [email protected]

[PATCH] PCI: memset rom attribute before using it

Initialize the allocated bin_attribute structure, otherwise unused fields
are pointing to random places.

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


drivers/pci/pci-sysfs.c | 1 +
1 files changed, 1 insertion(+)


diff -Nru a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
--- a/drivers/pci/pci-sysfs.c 2005-02-03 09:28:46 -08:00
+++ b/drivers/pci/pci-sysfs.c 2005-02-03 09:28:46 -08:00
@@ -436,6 +436,7 @@

rom_attr = kmalloc(sizeof(*rom_attr), GFP_ATOMIC);
if (rom_attr) {
+ memset(rom_attr, 0x00, sizeof(*rom_attr));
pdev->rom_attr = rom_attr;
rom_attr->size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
rom_attr->attr.name = "rom";

2005-02-03 18:59:22

by Greg KH

[permalink] [raw]
Subject: [PATCH] pci: Add Citrine quirk

ChangeSet 1.2042, 2005/02/03 00:40:09-08:00, [email protected]

[PATCH] pci: Add Citrine quirk

The IBM Citrine chipset has a feature that if PCI config register
0xA0 is read while DMAs are being performed to it, there is the possiblity
that the parity will be wrong on the PCI bus, causing a parity error and
a master abort. On this chipset, this register is simply a debug register
for the chip developers and the registers after it are not defined.
Patch sets cfg_size to 0xA0 to prevent this problem from being seen.

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


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


diff -Nru a/drivers/pci/quirks.c b/drivers/pci/quirks.c
--- a/drivers/pci/quirks.c 2005-02-03 09:28:53 -08:00
+++ b/drivers/pci/quirks.c 2005-02-03 09:28:53 -08:00
@@ -216,6 +216,16 @@
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443BX_2, quirk_natoma );

/*
+ * This chip can cause PCI parity errors if config register 0xA0 is read
+ * while DMAs are occurring.
+ */
+static void __devinit quirk_citrine(struct pci_dev *dev)
+{
+ dev->cfg_size = 0xA0;
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CITRINE, quirk_citrine );
+
+/*
* S3 868 and 968 chips report region size equal to 32M, but they decode 64M.
* If it's needed, re-allocate the region.
*/

2005-02-03 17:51:35

by Greg KH

[permalink] [raw]
Subject: [PATCH] PCI: typo in pci_scan_bus_parented

ChangeSet 1.2041, 2005/02/03 00:39:41-08:00, [email protected]

[PATCH] PCI: typo in pci_scan_bus_parented

From: Olaf Hering <[email protected]>

printk format string misses a x

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


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


diff -Nru a/drivers/pci/probe.c b/drivers/pci/probe.c
--- a/drivers/pci/probe.c 2005-02-03 09:29:00 -08:00
+++ b/drivers/pci/probe.c 2005-02-03 09:29:00 -08:00
@@ -879,7 +879,7 @@

if (pci_find_bus(pci_domain_nr(b), bus)) {
/* If we already got to this bus through a different bridge, ignore it */
- DBG("PCI: Bus %04:%02x already known\n", pci_domain_nr(b), bus);
+ DBG("PCI: Bus %04x:%02x already known\n", pci_domain_nr(b), bus);
goto err_out;
}
list_add_tail(&b->node, &pci_root_buses);

2005-02-03 19:19:21

by Greg KH

[permalink] [raw]
Subject: [PATCH] PCI: change sysfs representation of PCI-E devices

ChangeSet 1.2046, 2005/02/03 00:42:00-08:00, [email protected]

[PATCH] PCI: change sysfs representation of PCI-E devices

Before changes:

The patch makes the parent of the device pointing to the pci_dev
structure. The parents portX devices are in /sys/devices which
should be removed based on your suggestions. Below is /sys/devices
before any changes made.

/sys/devices
|
__ ide0
|
__ pci0000:00
|
__ pnp0
|
__ port1
| |
| __ port1.00
| |
| __ port1.01
| .
| .
| .
|
__ port2
|
__ port3
|
__ system

After changes:

The parents portX devices are no longer necessary because port1.00
and port1.01 devices shoud have the parent of the pci_dev structure
(based on your suggestion). The patch does the following changes:

- remove code creating and handling the parent portX devices.
- rename portX.YZ to pcieYZ (for example port1.00 renamed to pcie00)
since portX is no longer needed.
- make pcieYZ have the parent of the pci_dev structure.

Below is /sys/devices after changes made to the patch.

/sys/devices
|
__ ide0
|
__ pci0000:00
| |
| __ 0000:00:00.0
| |
| __ 0000:00:04.0
| | |
| . __ class
| . |
| . __ pcie00
| |
| __ pcie01
| .
| .
| .
|
__ platform
|
__ pnp0
|
__ system


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


drivers/pci/pcie/portdrv.h | 7 +-
drivers/pci/pcie/portdrv_bus.c | 15 -----
drivers/pci/pcie/portdrv_core.c | 119 ++++++++++++++++------------------------
drivers/pci/pcie/portdrv_pci.c | 22 +------
4 files changed, 58 insertions(+), 105 deletions(-)


diff -Nru a/drivers/pci/pcie/portdrv.h b/drivers/pci/pcie/portdrv.h
--- a/drivers/pci/pcie/portdrv.h 2005-02-03 09:28:24 -08:00
+++ b/drivers/pci/pcie/portdrv.h 2005-02-03 09:28:24 -08:00
@@ -28,14 +28,13 @@
#define get_descriptor_id(type, service) (((type - 4) << 4) | service)

extern struct bus_type pcie_port_bus_type;
-extern struct device_driver pcieport_generic_driver;
extern int pcie_port_device_probe(struct pci_dev *dev);
extern int pcie_port_device_register(struct pci_dev *dev);
#ifdef CONFIG_PM
-extern int pcie_port_device_suspend(struct pcie_device *dev, u32 state);
-extern int pcie_port_device_resume(struct pcie_device *dev);
+extern int pcie_port_device_suspend(struct pci_dev *dev, u32 state);
+extern int pcie_port_device_resume(struct pci_dev *dev);
#endif
-extern void pcie_port_device_remove(struct pcie_device *dev);
+extern void pcie_port_device_remove(struct pci_dev *dev);
extern void pcie_port_bus_register(void);
extern void pcie_port_bus_unregister(void);

diff -Nru a/drivers/pci/pcie/portdrv_bus.c b/drivers/pci/pcie/portdrv_bus.c
--- a/drivers/pci/pcie/portdrv_bus.c 2005-02-03 09:28:24 -08:00
+++ b/drivers/pci/pcie/portdrv_bus.c 2005-02-03 09:28:24 -08:00
@@ -14,8 +14,6 @@

#include <linux/pcieport_if.h>

-static int generic_probe (struct device *dev) { return 0;}
-static int generic_remove (struct device *dev) { return 0;}
static int pcie_port_bus_match(struct device *dev, struct device_driver *drv);
static int pcie_port_bus_suspend(struct device *dev, u32 state);
static int pcie_port_bus_resume(struct device *dev);
@@ -27,23 +25,14 @@
.resume = pcie_port_bus_resume,
};

-struct device_driver pcieport_generic_driver = {
- .name = "pcieport",
- .bus = &pcie_port_bus_type,
- .probe = generic_probe,
- .remove = generic_remove,
-};
-
static int pcie_port_bus_match(struct device *dev, struct device_driver *drv)
{
struct pcie_device *pciedev;
struct pcie_port_service_driver *driver;

- if ( drv->bus != &pcie_port_bus_type ||
- dev->bus != &pcie_port_bus_type ||
- drv == &pcieport_generic_driver) {
+ if (drv->bus != &pcie_port_bus_type || dev->bus != &pcie_port_bus_type)
return 0;
- }
+
pciedev = to_pcie_device(dev);
driver = to_service_driver(drv);
if ( (driver->id_table->vendor != PCI_ANY_ID &&
diff -Nru a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c
--- a/drivers/pci/pcie/portdrv_core.c 2005-02-03 09:28:24 -08:00
+++ b/drivers/pci/pcie/portdrv_core.c 2005-02-03 09:28:24 -08:00
@@ -17,8 +17,6 @@

extern int pcie_mch_quirk; /* MSI-quirk Indicator */

-extern struct device_driver pcieport_generic_driver;
-
static int pcie_port_probe_service(struct device *dev)
{
struct pcie_device *pciedev;
@@ -103,6 +101,7 @@
*/
static void release_pcie_device(struct device *dev)
{
+ printk(KERN_DEBUG "Free Port Service[%s]\n", dev->bus_id);
kfree(to_pcie_device(dev));
}

@@ -217,18 +216,18 @@
return services;
}

-static void pcie_device_init(struct pcie_device *parent,
- struct pcie_device *dev,
- int port_type, int service_type)
+static void pcie_device_init(struct pci_dev *parent, struct pcie_device *dev,
+ int port_type, int service_type, int irq, int irq_mode)
{
struct device *device;

- if (parent) {
- dev->id.vendor = parent->port->vendor;
- dev->id.device = parent->port->device;
- dev->id.port_type = port_type;
- dev->id.service_type = (1 << service_type);
- }
+ dev->port = parent;
+ dev->interrupt_mode = irq_mode;
+ dev->irq = irq;
+ dev->id.vendor = parent->vendor;
+ dev->id.device = parent->device;
+ dev->id.port_type = port_type;
+ dev->id.service_type = (1 << service_type);

/* Initialize generic device interface */
device = &dev->device;
@@ -240,35 +239,23 @@
device->driver = NULL;
device->driver_data = NULL;
device->release = release_pcie_device; /* callback to free pcie dev */
- sprintf(&device->bus_id[0], "%s.%02x", parent->device.bus_id,
- get_descriptor_id(port_type, service_type));
- device->parent = ((parent == NULL) ? NULL : &parent->device);
+ sprintf(&device->bus_id[0], "pcie%02x",
+ get_descriptor_id(port_type, service_type));
+ device->parent = &parent->dev;
}

-static struct pcie_device* alloc_pcie_device(
- struct pcie_device *parent, struct pci_dev *bridge,
+static struct pcie_device* alloc_pcie_device(struct pci_dev *parent,
int port_type, int service_type, int irq, int irq_mode)
{
struct pcie_device *device;
- static int NR_PORTS = 0;

device = kmalloc(sizeof(struct pcie_device), GFP_KERNEL);
if (!device)
return NULL;

memset(device, 0, sizeof(struct pcie_device));
- device->port = bridge;
- device->interrupt_mode = irq_mode;
- device->irq = irq;
- if (!parent) {
- pcie_device_init(NULL, device, port_type, service_type);
- NR_PORTS++;
- device->device.driver = &pcieport_generic_driver;
- sprintf(&device->device.bus_id[0], "port%d", NR_PORTS);
- } else {
- pcie_device_init(parent, device, port_type, service_type);
- }
- printk(KERN_DEBUG "Allocate Port Device[%s]\n", device->device.bus_id);
+ pcie_device_init(parent, device, port_type, service_type, irq,irq_mode);
+ printk(KERN_DEBUG "Allocate Port Service[%s]\n", device->device.bus_id);
return device;
}

@@ -291,7 +278,6 @@

int pcie_port_device_register(struct pci_dev *dev)
{
- struct pcie_device *parent;
int status, type, capabilities, irq_mode, i;
int vectors[PCIE_PORT_DEVICE_MAXSERVICES];
u16 reg16;
@@ -306,27 +292,13 @@
capabilities = get_port_device_capability(dev);
irq_mode = assign_interrupt_mode(dev, vectors, capabilities);

- /* Allocate parent */
- parent = alloc_pcie_device(NULL, dev, type, 0, dev->irq, irq_mode);
- if (!parent)
- return -ENOMEM;
-
- status = device_register(&parent->device);
- if (status) {
- kfree(parent);
- return status;
- }
- get_device(&parent->device);
- pci_set_drvdata(dev, parent);
-
/* Allocate child services if any */
for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) {
struct pcie_device *child;

if (capabilities & (1 << i)) {
child = alloc_pcie_device(
- parent, /* parent */
- dev, /* Root/Upstream/Downstream */
+ dev, /* parent */
type, /* port type */
i, /* service type */
vectors[i], /* irq */
@@ -345,17 +317,21 @@
}

#ifdef CONFIG_PM
-int pcie_port_device_suspend(struct pcie_device *dev, u32 state)
+int pcie_port_device_suspend(struct pci_dev *dev, u32 state)
{
- struct list_head *head;
+ struct list_head *head, *tmp;
struct device *parent, *child;
struct device_driver *driver;
struct pcie_port_service_driver *service_driver;

- parent = &dev->device;
+ parent = &dev->dev;
head = &parent->children;
- while (!list_empty(head)) {
- child = container_of(head->next, struct device, node);
+ tmp = head->next;
+ while (head != tmp) {
+ child = container_of(tmp, struct device, node);
+ tmp = tmp->next;
+ if (child->bus != &pcie_port_bus_type)
+ continue;
driver = child->driver;
if (!driver)
continue;
@@ -366,17 +342,21 @@
return 0;
}

-int pcie_port_device_resume(struct pcie_device *dev)
+int pcie_port_device_resume(struct pci_dev *dev)
{
- struct list_head *head;
+ struct list_head *head, *tmp;
struct device *parent, *child;
struct device_driver *driver;
struct pcie_port_service_driver *service_driver;

- parent = &dev->device;
+ parent = &dev->dev;
head = &parent->children;
- while (!list_empty(head)) {
- child = container_of(head->next, struct device, node);
+ tmp = head->next;
+ while (head != tmp) {
+ child = container_of(tmp, struct device, node);
+ tmp = tmp->next;
+ if (child->bus != &pcie_port_bus_type)
+ continue;
driver = child->driver;
if (!driver)
continue;
@@ -389,45 +369,46 @@
}
#endif

-void pcie_port_device_remove(struct pcie_device *dev)
+void pcie_port_device_remove(struct pci_dev *dev)
{
- struct list_head *head;
+ struct list_head *head, *tmp;
struct device *parent, *child;
struct device_driver *driver;
struct pcie_port_service_driver *service_driver;
+ int interrupt_mode = PCIE_PORT_INTx_MODE;

- parent = &dev->device;
+ parent = &dev->dev;
head = &parent->children;
- while (!list_empty(head)) {
- child = container_of(head->next, struct device, node);
+ tmp = head->next;
+ while (head != tmp) {
+ child = container_of(tmp, struct device, node);
+ tmp = tmp->next;
+ if (child->bus != &pcie_port_bus_type)
+ continue;
driver = child->driver;
if (driver) {
service_driver = to_service_driver(driver);
if (service_driver->remove)
service_driver->remove(to_pcie_device(child));
}
+ interrupt_mode = (to_pcie_device(child))->interrupt_mode;
put_device(child);
device_unregister(child);
}
-
/* Switch to INTx by default if MSI enabled */
- if (dev->interrupt_mode == PCIE_PORT_MSIX_MODE)
- pci_disable_msix(dev->port);
- else if (dev->interrupt_mode == PCIE_PORT_MSI_MODE)
- pci_disable_msi(dev->port);
- put_device(parent);
- device_unregister(parent);
+ if (interrupt_mode == PCIE_PORT_MSIX_MODE)
+ pci_disable_msix(dev);
+ else if (interrupt_mode == PCIE_PORT_MSI_MODE)
+ pci_disable_msi(dev);
}

void pcie_port_bus_register(void)
{
bus_register(&pcie_port_bus_type);
- driver_register(&pcieport_generic_driver);
}

void pcie_port_bus_unregister(void)
{
- driver_unregister(&pcieport_generic_driver);
bus_unregister(&pcie_port_bus_type);
}

diff -Nru a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c
--- a/drivers/pci/pcie/portdrv_pci.c 2005-02-03 09:28:24 -08:00
+++ b/drivers/pci/pcie/portdrv_pci.c 2005-02-03 09:28:24 -08:00
@@ -63,34 +63,18 @@

static void pcie_portdrv_remove (struct pci_dev *dev)
{
- struct pcie_device *pciedev;
-
- pciedev = (struct pcie_device *)pci_get_drvdata(dev);
- if (pciedev) {
- pcie_port_device_remove(pciedev);
- pci_set_drvdata(dev, NULL);
- }
+ pcie_port_device_remove(dev);
}

#ifdef CONFIG_PM
static int pcie_portdrv_suspend (struct pci_dev *dev, u32 state)
{
- struct pcie_device *pciedev;
-
- pciedev = (struct pcie_device *)pci_get_drvdata(dev);
- if (pciedev)
- pcie_port_device_suspend(pciedev, state);
- return 0;
+ return pcie_port_device_suspend(dev, state);
}

static int pcie_portdrv_resume (struct pci_dev *dev)
{
- struct pcie_device *pciedev;
-
- pciedev = (struct pcie_device *)pci_get_drvdata(dev);
- if (pciedev)
- pcie_port_device_resume(pciedev);
- return 0;
+ return pcie_port_device_resume(dev);
}
#endif


2005-02-07 17:01:10

by David Woodhouse

[permalink] [raw]
Subject: Re: [PATCH] PCI Hotplug: remove incorrect rpaphp firmware dependency

On Thu, 2005-02-03 at 08:41 +0000, Linux Kernel Mailing List wrote:
> [PATCH] PCI Hotplug: remove incorrect rpaphp firmware dependency
>
> The RPA PCI Hotplug module incorrectly uses a certain firmware property when
> determining the hotplug capabilities of a slot. Recent firmware changes have
> demonstrated that this property should not be referenced or depended upon by
> the OS. This patch removes the dependency, and implements a correct set of
> logic for determining hotplug capabilities.
>
> Signed-off-by: John Rose <[email protected]>
> Signed-off-by: Greg Kroah-Hartman <[email protected]>
>
> + rc = get_children_props(dn, indexes, names, &drc_types, power_domains);
> + if (rc) {
> + if (is_php_type((char *) &drc_types[1])) {
> + *types = drc_types;
> + return 1;
> + }
> + }

Er, use the result of the get_children_props() call only if it _failed_?
I suspect that wasn't your intention. This makes my G5 boot again:

--- linux-2.6.10/drivers/pci/hotplug/rpaphp_core.c.orig 2005-02-07 16:41:45.830990208 +0000
+++ linux-2.6.10/drivers/pci/hotplug/rpaphp_core.c 2005-02-07 16:46:15.495868912 +0000
@@ -307,7 +307,7 @@ static int is_php_dn(struct device_node
int rc;

rc = get_children_props(dn, indexes, names, &drc_types, power_domains);
- if (rc) {
+ if (!rc) {
if (is_php_type((char *) &drc_types[1])) {
*types = drc_types;
return 1;




--
dwmw2

2005-02-07 17:43:07

by John Rose

[permalink] [raw]
Subject: Re: [PATCH] PCI Hotplug: remove incorrect rpaphp firmware dependency

> Er, use the result of the get_children_props() call only if it _failed_?
> I suspect that wasn't your intention. This makes my G5 boot again:

Doh, good catch! This was an oversight while patching multiple trees
for this bug. Previous versions of that function use 1 for success.
Sigh. BTW, you're running an RPA module on your G5?

Thanks-
John

2005-02-07 17:47:19

by John Rose

[permalink] [raw]
Subject: Re: [PATCH] PCI Hotplug: remove incorrect rpaphp firmware dependency

Could we please get David's fix in for 2.6.11, since it's apparently
affecting boot in some situations?

Thanks-
John

On Mon, 2005-02-07 at 11:41, John Rose wrote:
> > Er, use the result of the get_children_props() call only if it _failed_?
> > I suspect that wasn't your intention. This makes my G5 boot again:
>
> Doh, good catch! This was an oversight while patching multiple trees
> for this bug. Previous versions of that function use 1 for success.
> Sigh. BTW, you're running an RPA module on your G5?
>
> Thanks-
> John

2005-02-07 19:19:31

by Andrew Morton

[permalink] [raw]
Subject: Re: [PATCH] PCI Hotplug: remove incorrect rpaphp firmware dependency

John Rose <[email protected]> wrote:
>
> Could we please get David's fix in for 2.6.11, since it's apparently
> affecting boot in some situations?

Yup, I can take care of that.

2005-02-07 19:28:36

by David Woodhouse

[permalink] [raw]
Subject: Re: [PATCH] PCI Hotplug: remove incorrect rpaphp firmware dependency

On Mon, 2005-02-07 at 11:41 -0600, John Rose wrote:
> BTW, you're running an RPA module on your G5?

Fedora uses the same ppc64 kernel for both pSeries and G5.

--
dwmw2

2005-02-08 00:24:00

by John Rose

[permalink] [raw]
Subject: Re: [PATCH] PCI Hotplug: remove incorrect rpaphp firmware dependency

> Er, use the result of the get_children_props() call only if it _failed_?
> I suspect that wasn't your intention. This makes my G5 boot again:

Here's an alternate fix for the ppc64 crash during boot. This corrects
the offending function to use more conventional error codes. I'll
follow up with return code cleanups for the entire module, and for RTAS
code, since these are probably too big for 2.6.11.

Please apply, if appropriate.

Thanks-
John

Signed-off-by: John Rose <[email protected]>

diff -puN drivers/pci/hotplug/rpaphp_core.c~01_rpaphp_is_php_fix drivers/pci/hotplug/rpaphp_core.c
--- 2_6_linus/drivers/pci/hotplug/rpaphp_core.c~01_rpaphp_is_php_fix 2005-02-07 18:06:29.000000000 -0600
+++ 2_6_linus-johnrose/drivers/pci/hotplug/rpaphp_core.c 2005-02-07 18:10:15.000000000 -0600
@@ -224,7 +224,7 @@ static int get_children_props(struct dev

if (!indexes || !names || !types || !domains) {
/* Slot does not have dynamically-removable children */
- return 1;
+ return -EINVAL;
}
if (drc_indexes)
*drc_indexes = indexes;
@@ -260,7 +260,7 @@ int rpaphp_get_drc_props(struct device_n
}

rc = get_children_props(dn->parent, &indexes, &names, &types, &domains);
- if (rc) {
+ if (rc < 0) {
return 1;
}

@@ -307,7 +307,7 @@ static int is_php_dn(struct device_node
int rc;

rc = get_children_props(dn, indexes, names, &drc_types, power_domains);
- if (rc) {
+ if (rc >= 0) {
if (is_php_type((char *) &drc_types[1])) {
*types = drc_types;
return 1;
@@ -331,7 +331,7 @@ static int is_dr_dn(struct device_node *

rc = get_children_props(dn->parent, indexes, names, types,
power_domains);
- return (rc == 0);
+ return (rc >= 0);
}

static inline int is_vdevice_root(struct device_node *dn)

_