[PATCH] Virtual IO devices don't have bridges

linas at austin.ibm.com linas at austin.ibm.com
Sat Jun 26 04:00:16 EST 2004


Hi,

Resending, I guess I needed the following line:

Signed-off-by: Linas Vepstas <linas at linas.org>

On Wed, Jun 23, 2004 at 01:49:18PM -0500, linas at austin.ibm.com wrote:
>
> Hi Linda, Greg,
>
> Below follows a set of patches to the ppc64 pci hotplug code.
> If there are no objections from Linda or the other pSeries
> hotplug maintainers, then Greg, please apply to your sources.
>
> The three fixes are:
> -- Virtual I/O (VIO) devices do not have PCI bridges associated
>    with them.  Thus, performing a loop over all devices, when
>    a VIO device was in the list caused a null-pointer deref.
>    Appearently, no one ever tried to hot-unplug a pci slot
>    on a system that had VIO devices on it before.
>
> -- slot-remove ordering problem. EEH remove should be done last,
>    after the pci slot remove.  This caused certain oddball but
>    mostly harmless trouble in certain obscure hardware-failure
>    testing scenarios.
>
> -- Minor performance tweak to the struct slot structure.
>    Putting the two u8 members of the struct will shrink the
>    total struct size by 8 bytes.  Moving the struct list_head
>    from last place to first place in the struct will avoid
>    an add-immediate instruction generated by the compiler,
>    without adversly afecting ofther member access.
>
> Linas

--- drivers/pci/hotplug/rpaphp_pci.c.orig	2004-06-23 11:55:37.000000000 -0500
+++ drivers/pci/hotplug/rpaphp_pci.c	2004-06-23 13:22:01.000000000 -0500
@@ -376,8 +376,8 @@ int rpaphp_unconfig_pci_adapter(struct s

 		func = list_entry(ln, struct rpaphp_pci_func, sibling);
 		if (func->pci_dev) {
-			rpaphp_eeh_remove_bus_device(func->pci_dev);
 			pci_remove_bus_device(func->pci_dev);
+			rpaphp_eeh_remove_bus_device(func->pci_dev);
 		}
 		kfree(func);
 	}
@@ -513,9 +513,18 @@ struct hotplug_slot *rpaphp_find_hotplug
 		struct list_head *ln;

 		slot = list_entry(tmp, struct slot, rpaphp_slot_list);
+		if (slot->bridge == NULL) {
+			if (slot->dev_type == PCI_DEV) {
+				printk (KERN_WARNING "PCI slot missing bridge %s %s \n",
+				                    slot->name, slot->location);
+			}
+			continue;
+		}
+
 		bus = slot->bridge->subordinate;
-		if (!bus)
-			return NULL; /* shouldn't be here */
+		if (!bus) {
+			continue;  /* should never happen? */
+		}
 		for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) {
                                 struct pci_dev *pdev = pci_dev_b(ln);
 				if (pdev == dev)
--- drivers/pci/hotplug/rpaphp.h.orig	2004-06-18 16:10:47.000000000 -0500
+++ drivers/pci/hotplug/rpaphp.h	2004-06-23 13:28:20.000000000 -0500
@@ -85,6 +85,7 @@ struct rpaphp_pci_func {
  * struct slot - slot information for each *physical* slot
  */
 struct slot {
+	struct list_head rpaphp_slot_list;
 	int state;
 	u32 index;
 	u32 type;
@@ -92,6 +93,7 @@ struct slot {
 	char *name;
 	char *location;
 	u8 removable;
+	u8 dev_type;		/* VIO or PCI */
 	struct device_node *dn;	/* slot's device_node in OFDT */
 				/* dn has phb info */
 	struct pci_dev *bridge;	/* slot's pci_dev in pci_devices */
@@ -99,9 +101,7 @@ struct slot {
 		struct list_head pci_funcs; /* pci_devs in PCI slot */
 		struct vio_dev *vio_dev; /* vio_dev in VIO slot */
 	} dev;
-	u8 dev_type;		/* VIO or PCI */
 	struct hotplug_slot *hotplug_slot;
-	struct list_head rpaphp_slot_list;
 };

 extern struct hotplug_slot_ops rpaphp_hotplug_slot_ops;


** Sent via the linuxppc64-dev mail list. See http://lists.linuxppc.org/





More information about the Linuxppc64-dev mailing list