Skip to contentSkip to conversation

PCI hotplug changes for 2.5.63

PATCH In review Greg KH 2 participants 20 messages Feb 25, 2003 – Mar 1, 2003

Subsystems (2)
lore
Share & tools
lore

Greg KH

author
#0 lore raw

PATCH 1/1 PCI hotplug changes for 2.5.63

Hi,

Here's some patches that clean up the remove logic a lot for the PCI hotplug drivers. The main PCI patches were done by Russell King and Christoph Hellwig, and then I went and cleaned up the PCI Hotplug drivers a lot based on their changes. I also fixed up some exit logic in the IBM PCI hotplug driver, as it was a mess.

Scott, I modified the cPCI core in order to get it to build and link properly again, but as I don't have the hardware to test it, you should probably look over the change and see if I messed anything up or not. Also, I think you are the last user of the pci_visit structure, make sure you really need it, otherwise we can get rid of it entirely from the PCI core.

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

thanks,

greg k-h

 drivers/hotplug/cpqphp_proc.c      |  143 ---------
 drivers/hotplug/Makefile           |    2 
 drivers/hotplug/acpiphp_pci.c      |  191 -------------
 drivers/hotplug/cpci_hotplug_pci.c |   34 --
 drivers/hotplug/cpqphp.h           |   27 -
 drivers/hotplug/cpqphp_core.c      |   18 -
 drivers/hotplug/cpqphp_pci.c       |  204 --------------
 drivers/hotplug/cpqphp_proc.c      |   96 +-----
 drivers/hotplug/cpqphp_sysfs.c     |  143 +++++++++
 drivers/hotplug/ibmphp.h           |    6 
 drivers/hotplug/ibmphp_core.c      |  538 +++++++++----------------------------
 drivers/hotplug/ibmphp_hpc.c       |    2 
 drivers/hotplug/pci_hotplug_core.c |   18 -
 drivers/pci/hotplug.c              |   63 +++-
 drivers/pci/probe.c                |    1 
 include/linux/pci.h                |    4 
 16 files changed, 380 insertions(+), 1110 deletions(-)

-----

[email protected], 2003-02-24 16:35:48-08:00, [email protected]
[PATCH] CPCI core: remove unneeded visit device on unconfigure.

The driver now links properly, but this is untested due to my lack of cPCI hardware.

 drivers/hotplug/cpci_hotplug_pci.c |   34 ----------------------------------
 1 files changed, 34 deletions(-)

------

[email protected], 2003-02-24 16:33:09-08:00, [email protected]
[PATCH] PCI: export pci_scan_bus_parented which is needed by the IBM pci hotplug driver.

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

------

[email protected], 2003-02-24 16:32:16-08:00, [email protected]
[PATCH] IBM PCI Hotplug: convert driver to use pci_bus_remove_device()

Also cleaned up a lot of unnecessary bus walking on device startup and shutdown.

 drivers/hotplug/ibmphp_core.c |  136 ------------------------------------------
 1 files changed, 3 insertions(+), 133 deletions(-)

------

[email protected], 2003-02-24 16:31:00-08:00, [email protected]
[PATCH] ACPI PCI hotplug: convert to use pci_remove_bus_device()

Also got rid of some unneeded bus walking on device init and shutdown.

 drivers/hotplug/acpiphp_pci.c |  146 ------------------------------------------
 1 files changed, 3 insertions(+), 143 deletions(-)

------

[email protected], 2003-02-24 16:30:40-08:00, [email protected]
[PATCH] Compaq PCI Hotplug: remove unused walk of the device on insertion.

 drivers/hotplug/cpqphp_pci.c |   54 -------------------------------------------
 1 files changed, 54 deletions(-)

------

[email protected], 2003-02-24 16:29:53-08:00, [email protected]
[PATCH] Compaq PCI Hotplug: convert to use pci_remove_bus_device instead of custom code.

 drivers/hotplug/cpqphp_pci.c |  104 +------------------------------------------
 1 files changed, 3 insertions(+), 101 deletions(-)

------

[email protected], 2003-02-24 16:28:58-08:00, [email protected]
[PATCH] PCI: Make hot unplugging of PCI buses work

Here's the updated patch:

- Scott spotted a leak my handling of procfs wrt buses.
- I've also killed pci_remove_device() entirely - it is now inlined.
- After one of Alan's mails, I decided that pci_remove_behind_bridge() is a much better name than pci_remove_all_bus_devices()

 drivers/pci/hotplug.c |   63 ++++++++++++++++++++++++++++++++++++++++++++------
 include/linux/pci.h   |    3 +-
 2 files changed, 58 insertions(+), 8 deletions(-)

------

[email protected], 2003-02-24 16:27:59-08:00, [email protected]
[PATCH] PCI: remove check_region abuse (and code duplication) from pci hp code

We have a function pci_dev_driver() to check whether a pci_dev has an driver attached to it. It's handling of legacy devices is a bit simpler than what the hotplug code did (duplicated in various places), but if that stuff is really needed the generic code should be updated.

 drivers/hotplug/acpiphp_pci.c |   45 +----------------------------------------
 drivers/hotplug/cpqphp_pci.c  |   46 +-----------------------------------------
 drivers/hotplug/ibmphp_core.c |   37 +--------------------------------
 include/linux/pci.h           |    1 
 4 files changed, 6 insertions(+), 123 deletions(-)

------

[email protected], 2003-02-24 16:27:32-08:00, [email protected]
[PATCH] Compaq PCI Hotplug: rename cpqphp_proc.c to cpqphp_sysfs.c

 drivers/hotplug/cpqphp_proc.c  |  143 -----------------------------------------
 drivers/hotplug/Makefile       |    2 
 drivers/hotplug/cpqphp_sysfs.c |  143 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 144 insertions(+), 144 deletions(-)

------

[email protected], 2003-02-24 16:26:59-08:00, [email protected]
[PATCH] Compaq PCI Hotplug: move /proc files to sysfs

 drivers/hotplug/cpqphp.h      |   27 -----------
 drivers/hotplug/cpqphp_core.c |   18 -------
 drivers/hotplug/cpqphp_proc.c |   96 +++++++++---------------------------------
 3 files changed, 25 insertions(+), 116 deletions(-)

------

[email protected], 2003-02-24 16:26:14-08:00, [email protected]
[PATCH] PCI Hotplug: remove the list_lock, as we rely on sysfs to detect any duplicate slot names.

 drivers/hotplug/pci_hotplug_core.c |   18 +-----------------
 1 files changed, 1 insertion(+), 17 deletions(-)

------

[email protected], 2003-02-24 16:25:54-08:00, [email protected]
[PATCH] IBM PCI Hotplug: get rid of unneeded ops structure and surrounding logic.

 drivers/hotplug/ibmphp.h      |    5 ---
 drivers/hotplug/ibmphp_core.c |   69 +++++++++---------------------------------
 2 files changed, 15 insertions(+), 59 deletions(-)

------

[email protected], 2003-02-24 16:25:28-08:00, [email protected]
[PATCH] IBM PCI Hotplug: fix typo in previous patch.

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

------

[email protected], 2003-02-24 16:24:48-08:00, [email protected]
[PATCH] IBM PCI Hotplug: Clean up the error handling logic for a number of functions, and fix a locking mess.

Push file://home/greg/linux/BK/pci-2.5 -> file://home/greg/linux/BK/bleed-2.5

 drivers/hotplug/ibmphp.h      |    1 
 drivers/hotplug/ibmphp_core.c |  294 ++++++++++++++++--------------------------
 drivers/hotplug/ibmphp_hpc.c  |    2 
 3 files changed, 120 insertions(+), 177 deletions(-)

------

author
#1 lore raw

PATCH 1/1 PCI hotplug changes for 2.5.63

ChangeSet 1.1022.1.1, 2003/02/24 16:24:48-08:00, [email protected]

[PATCH] IBM PCI Hotplug: Clean up the error handling logic for a number of functions, and fix a locking mess.

drivers/hotplug/ibmphp.h +1 -0
diff -Nru a/drivers/hotplug/ibmphp.h b/drivers/hotplug/ibmphp.h
@@ -761,6 +761,7 @@
 
 extern int ibmphp_init_devno (struct slot **);	/* This function is called from EBDA, so we need it not be static */
 extern int ibmphp_disable_slot (struct hotplug_slot *);	/* This function is called from HPC, so we need it to not be static */
+extern int ibmphp_do_disable_slot (struct slot *slot_cur);
 extern int ibmphp_update_slot_info (struct slot *);	/* This function is called from HPC, so we need it to not be be static */
 extern int ibmphp_configure_card (struct pci_func *, u8);
 extern int ibmphp_unconfigure_card (struct slot **, int);
drivers/hotplug/ibmphp_core.c +118 -176

447 lines not on this page · raw message

drivers/hotplug/ibmphp_hpc.c +1 -1
diff -Nru a/drivers/hotplug/ibmphp_hpc.c b/drivers/hotplug/ibmphp_hpc.c
@@ -1063,7 +1063,7 @@
 	if (disable) {
 		debug ("process_changeinstatus - disable slot\n");
 		pslot->flag = FALSE;
-		rc = ibmphp_disable_slot (pslot->hotplug_slot);
+		rc = ibmphp_do_disable_slot (pslot);
 	}
 
 	if (update || disable) {
author
#2 lore raw

ChangeSet 1.1022.1.2, 2003/02/24 16:25:28-08:00, [email protected]

[PATCH] IBM PCI Hotplug: fix typo in previous patch.

drivers/hotplug/ibmphp_core.c +1 -1
diff -Nru a/drivers/hotplug/ibmphp_core.c b/drivers/hotplug/ibmphp_core.c
@@ -1584,7 +1584,7 @@
 	bus = ibmphp_find_bus (0);
 	if (!bus) {
 		err ("Can't find the root pci bus, can not continue\n");
-		rc -ENODEV;
+		rc = -ENODEV;
 		goto error;
 	}
 	memcpy (ibmphp_pci_bus, bus, sizeof (*ibmphp_pci_bus));
author
#3 lore raw

ChangeSet 1.1022.1.3, 2003/02/24 16:25:54-08:00, [email protected]

[PATCH] IBM PCI Hotplug: get rid of unneeded ops structure and surrounding logic.

drivers/hotplug/ibmphp.h +0 -5
diff -Nru a/drivers/hotplug/ibmphp.h b/drivers/hotplug/ibmphp.h
@@ -683,11 +683,6 @@
 #define ENABLE		1
 #define DISABLE		0
 
-#define ADD		0
-#define REMOVE		1
-#define DETAIL		2
-
-#define MAX_OPS		3
 #define CARD_INFO	0x07
 #define PCIX133		0x07
 #define PCIX66		0x05
drivers/hotplug/ibmphp_core.c +15 -54

101 lines not on this page · raw message

author
#4 lore raw

ChangeSet 1.1022.1.4, 2003/02/24 16:26:14-08:00, [email protected]

[PATCH] PCI Hotplug: remove the list_lock, as we rely on sysfs to detect any duplicate slot names.

drivers/hotplug/pci_hotplug_core.c +1 -17
diff -Nru a/drivers/hotplug/pci_hotplug_core.c b/drivers/hotplug/pci_hotplug_core.c
@@ -67,8 +67,6 @@
 
 //////////////////////////////////////////////////////////////////
 
-static spinlock_t list_lock;
-
 static LIST_HEAD(pci_hotplug_slot_list);
 
 static struct subsystem hotplug_slots_subsys;
@@ -531,23 +529,16 @@
 	if ((slot->info == NULL) || (slot->ops == NULL))
 		return -EINVAL;
 
-	/* make sure we have not already registered this slot */
-	spin_lock (&list_lock);
-	if (get_slot_from_name (slot->name) != NULL) {
-		spin_unlock (&list_lock);
-		return -EINVAL;
-	}
-
 	strncpy(slot->kobj.name, slot->name, KOBJ_NAME_LEN);
 	kobj_set_kset_s(slot, hotplug_slots_subsys);
 
+	/* this can fail if we have already registered a slot with the same name */
 	if (kobject_register(&slot->kobj)) {
 		err("Unable to register kobject");
 		return -EINVAL;
 	}
 		
 	list_add (&slot->slot_list, &pci_hotplug_slot_list);
-	spin_unlock (&list_lock);
 
 	result = fs_add_slot (slot);
 	dbg ("Added slot %s to the list\n", slot->name);
@@ -570,16 +561,11 @@
 	if (slot == NULL)
 		return -ENODEV;
 
-	/* make sure we have this slot in our list before trying to delete it */
-	spin_lock (&list_lock);
 	temp = get_slot_from_name (slot->name);
 	if (temp != slot) {
-		spin_unlock (&list_lock);
 		return -ENODEV;
 	}
-
 	list_del (&slot->slot_list);
-	spin_unlock (&list_lock);
 
 	fs_remove_slot (slot);
 	dbg ("Removed slot %s from the list\n", slot->name);
@@ -638,8 +624,6 @@
 static int __init pci_hotplug_init (void)
 {
 	int result;
-
-	spin_lock_init(&list_lock);
 
 	kset_set_kset_s(&hotplug_slots_subsys, pci_bus_type.subsys);
 	result = subsystem_register(&hotplug_slots_subsys);
author
#5 lore raw

ChangeSet 1.1022.1.5, 2003/02/24 16:26:59-08:00, [email protected]

[PATCH] Compaq PCI Hotplug: move /proc files to sysfs

drivers/hotplug/cpqphp.h +2 -25
diff -Nru a/drivers/hotplug/cpqphp.h b/drivers/hotplug/cpqphp.h
@@ -403,31 +403,8 @@
 #define msg_button_ignore	"PCI slot #%d - button press ignored.  (action in progress...)\n"
 
 
-/* Proc functions for the hotplug controller info */
-#ifdef CONFIG_PROC_FS
-extern int cpqhp_proc_init_ctrl		(void);
-extern int cpqhp_proc_destroy_ctrl	(void);
-extern int cpqhp_proc_create_ctrl	(struct controller *ctrl);
-extern int cpqhp_proc_remove_ctrl	(struct controller *ctrl);
-#else
-static inline int cpqhp_proc_init_ctrl (void)
-{
-	return 0;
-}
-static inline int cpqhp_proc_destroy_ctrl (void)
-{
-	return 0;
-}
-static inline int cpqhp_proc_create_ctrl (struct controller *ctrl)
-{
-	return 0;
-}
-static inline int cpqhp_proc_remove_ctrl (struct controller *ctrl)
-{
-	return 0;
-}
-#endif
-
+/* sysfs functions for the hotplug controller info */
+extern void cpqhp_create_ctrl_files		(struct controller *ctrl);
 
 /* controller functions */
 extern void	cpqhp_pushbutton_thread		(unsigned long event_pointer);
drivers/hotplug/cpqphp_core.c +2 -16
diff -Nru a/drivers/hotplug/cpqphp_core.c b/drivers/hotplug/cpqphp_core.c
@@ -1038,6 +1038,7 @@
 	dbg ("    pcix_support           %s\n", ctrl->pcix_support == 0 ? "not supported" : "supported");
 
 	ctrl->pci_dev = pdev;
+	pci_set_drvdata(pdev, ctrl);
 
 	/* make our own copy of the pci bus structure, as we like tweaking it a lot */
 	ctrl->pci_bus = kmalloc (sizeof (*ctrl->pci_bus), GFP_KERNEL);
@@ -1231,11 +1232,7 @@
 	// Done with exclusive hardware access
 	up(&ctrl->crit_sect);
 
-	rc = cpqhp_proc_create_ctrl (ctrl);
-	if (rc) {
-		err("cpqhp_proc_create_ctrl failed\n");
-		goto err_free_irq;
-	}
+	cpqhp_create_ctrl_files (ctrl);
 
 	return 0;
 
@@ -1309,10 +1306,6 @@
 		goto error;
 	}
 
-	retval = cpqhp_proc_init_ctrl();
-	if (retval)
-		goto error;
-
 	initialized = 1;
 
 	return retval;
@@ -1343,8 +1336,6 @@
 	ctrl = cpqhp_ctrl_list;
 
 	while (ctrl) {
-		cpqhp_proc_remove_ctrl (ctrl);
-
 		if (ctrl->hpc_reg) {
 			u16 misc;
 			rc = read_slot_enable (ctrl);
@@ -1431,8 +1422,6 @@
 		}
 	}
 
-	remove_proc_entry("hpc", 0);
-
 	// Stop the notification mechanism
 	cpqhp_event_stop_thread();
 
@@ -1490,9 +1479,6 @@
 
 static void __exit cpqhpc_cleanup(void)
 {
-	dbg("cleaning up proc entries\n");
-	cpqhp_proc_destroy_ctrl();
-
 	dbg("unload_cpqphpd()\n");
 	unload_cpqphpd();
 
drivers/hotplug/cpqphp_proc.c +21 -75

136 lines not on this page · raw message

author
#6 lore raw

ChangeSet 1.1022.1.6, 2003/02/24 16:27:32-08:00, [email protected]

[PATCH] Compaq PCI Hotplug: rename cpqphp_proc.c to cpqphp_sysfs.c

drivers/hotplug/Makefile +1 -1
diff -Nru a/drivers/hotplug/Makefile b/drivers/hotplug/Makefile
@@ -18,7 +18,7 @@
 
 cpqphp-objs		:=	cpqphp_core.o	\
 				cpqphp_ctrl.o	\
-				cpqphp_proc.o	\
+				cpqphp_sysfs.o	\
 				cpqphp_pci.o
 
 ibmphp-objs		:=	ibmphp_core.o	\
drivers/hotplug/cpqphp_proc.c deleted +0 -143

143 lines not on this page · raw message

drivers/hotplug/cpqphp_sysfs.c new file +143 -0

143 lines not on this page · raw message

author
#7 lore raw

ChangeSet 1.1022.1.7, 2003/02/24 16:27:59-08:00, [email protected]

[PATCH] PCI: remove check_region abuse (and code duplication) from pci hp code

We have a function pci_dev_driver() to check whether a pci_dev has an driver attached to it. It's handling of legacy devices is a bit simpler than what the hotplug code did (duplicated in various places), but if that stuff is really needed the generic code should be updated.

drivers/hotplug/acpiphp_pci.c +2 -43
diff -Nru a/drivers/hotplug/acpiphp_pci.c b/drivers/hotplug/acpiphp_pci.c
@@ -217,47 +217,6 @@
 	return 0;
 }
 
-
-static int is_pci_dev_in_use (struct pci_dev* dev)
-{
-	/*
-	 * dev->driver will be set if the device is in use by a new-style
-	 * driver -- otherwise, check the device's regions to see if any
-	 * driver has claimed them
-	 */
-
-	int i, inuse=0;
-
-	if (dev->driver) return 1; //assume driver feels responsible
-
-	for (i = 0; !dev->driver && !inuse && (i < 6); i++) {
-		if (!pci_resource_start(dev, i))
-			continue;
-
-		if (pci_resource_flags(dev, i) & IORESOURCE_IO)
-			inuse = check_region(pci_resource_start(dev, i),
-					     pci_resource_len(dev, i));
-		else if (pci_resource_flags(dev, i) & IORESOURCE_MEM)
-			inuse = check_mem_region(pci_resource_start(dev, i),
-						 pci_resource_len(dev, i));
-	}
-
-	return inuse;
-}
-
-
-static int pci_hp_remove_device (struct pci_dev *dev)
-{
-	if (is_pci_dev_in_use(dev)) {
-		err("***Cannot safely power down device -- "
-		       "it appears to be in use***\n");
-		return -EBUSY;
-	}
-	pci_remove_device(dev);
-	return 0;
-}
-
-
 /* remove device driver */
 static int unconfigure_pci_dev_driver (struct pci_dev_wrapped *wrapped_dev, struct pci_bus_wrapped *wrapped_bus)
 {
@@ -274,7 +233,7 @@
 		dev->driver = NULL;
 	}
 
-	return is_pci_dev_in_use(dev);
+	return (pci_dev_driver(dev) != NULL);
 }
 
 
@@ -285,7 +244,7 @@
 
 	/* Now, remove the Linux Representation */
 	if (dev) {
-		if (pci_hp_remove_device(dev) == 0) {
+		if (pci_remove_device_safe(dev) == 0) {
 			info("Device %s removed\n", dev->slot_name);
 			kfree(dev); /* Now, remove */
 		} else {
drivers/hotplug/cpqphp_pci.c +2 -44

64 lines not on this page · raw message

drivers/hotplug/ibmphp_core.c +2 -35
diff -Nru a/drivers/hotplug/ibmphp_core.c b/drivers/hotplug/ibmphp_core.c
@@ -781,39 +781,6 @@
 	debug ("%s -- exit\n", __FUNCTION__);
 }
 
-static int ibm_is_pci_dev_in_use (struct pci_dev *dev)
-{
-	int i = 0;
-	int inuse = 0;
-
-	if (dev->driver)
-		return 1;
-
-	for (i = 0; !dev->driver && !inuse && (i < 6); i++) {
-
-		if (!pci_resource_start (dev, i))
-			continue;
-
-		if (pci_resource_flags (dev, i) & IORESOURCE_IO)
-			inuse = check_region (pci_resource_start (dev, i), pci_resource_len (dev, i));
-
-		else if (pci_resource_flags (dev, i) & IORESOURCE_MEM)
-			inuse = check_mem_region (pci_resource_start (dev, i), pci_resource_len (dev, i));
-	}
-
-	return inuse;
-}
-
-static int ibm_pci_hp_remove_device (struct pci_dev *dev)
-{
-	if (ibm_is_pci_dev_in_use (dev)) {
-		err ("***Cannot safely power down device -- it appears to be in use***\n");
-		return -EBUSY;
-	}
-	pci_remove_device (dev);
-	return 0;
-}
-
 static int ibm_unconfigure_visit_pci_dev_phase2 (struct pci_dev_wrapped *wrapped_dev, struct pci_bus_wrapped *wrapped_bus)
 {
 	struct pci_dev *dev = wrapped_dev->dev;
@@ -825,7 +792,7 @@
 	} while (temp_func && (temp_func->function != (dev->devfn & 0x07)));
 
 	if (dev) {
-		if (ibm_pci_hp_remove_device (dev) == 0)
+		if (pci_remove_device_safe(dev) == 0)
 			kfree (dev);    /* Now, remove */
 		else
 			return -1;
@@ -872,7 +839,7 @@
 		dev->driver = NULL;
 	}
 
-	return ibm_is_pci_dev_in_use (dev);
+	return (pci_dev_driver(dev) != NULL);
 }
 
 static struct pci_visit ibm_unconfigure_functions_phase1 = {
include/linux/pci.h +0 -1
diff -Nru a/include/linux/pci.h b/include/linux/pci.h
@@ -692,7 +692,6 @@
 extern int pci_visit_dev(struct pci_visit *fn,
 			 struct pci_dev_wrapped *wrapped_dev,
 			 struct pci_bus_wrapped *wrapped_parent);
-extern int pci_is_dev_in_use(struct pci_dev *dev);
 extern int pci_remove_device_safe(struct pci_dev *dev);
 
 #endif /* CONFIG_PCI */
author
#8 lore raw

ChangeSet 1.1022.1.8, 2003/02/24 16:28:58-08:00, [email protected]

[PATCH] PCI: Make hot unplugging of PCI buses work

Here's the updated patch:

- Scott spotted a leak my handling of procfs wrt buses.
- I've also killed pci_remove_device() entirely - it is now inlined.
- After one of Alan's mails, I decided that pci_remove_behind_bridge() is a much better name than pci_remove_all_bus_devices()

drivers/pci/hotplug.c +56 -7
diff -Nru a/drivers/pci/hotplug.c b/drivers/pci/hotplug.c
@@ -10,6 +10,7 @@
 #define DBG(x...)
 #endif
 
+static void pci_free_resources(struct pci_dev *dev);
 
 #ifdef CONFIG_HOTPLUG
 int pci_hotplug (struct device *dev, char **envp, int num_envp,
@@ -185,7 +186,13 @@
 {
 	if (pci_dev_driver(dev))
 		return -EBUSY;
-	pci_remove_device(dev);
+	device_unregister(&dev->dev);
+	list_del(&dev->bus_list);
+	list_del(&dev->global_list);
+	pci_free_resources(dev);
+#ifdef CONFIG_PROC_FS
+	pci_proc_detach_device(dev);
+#endif
 	return 0;
 }
 EXPORT_SYMBOL(pci_remove_device_safe);
@@ -233,15 +240,33 @@
 }
 
 /**
- * pci_remove_device - remove a pci device
+ * pci_remove_bus_device - remove a PCI device and any children
  * @dev: the device to remove
  *
- * Delete the device structure from the device lists,
- * remove the /proc entry, and notify userspace (/sbin/hotplug).
+ * Remove a PCI device from the device lists, informing the drivers
+ * that the device has been removed.  We also remove any subordinate
+ * buses and children in a depth-first manner.
+ *
+ * For each device we remove, delete the device structure from the
+ * device lists, remove the /proc entry, and notify userspace
+ * (/sbin/hotplug).
  */
-void
-pci_remove_device(struct pci_dev *dev)
+void pci_remove_bus_device(struct pci_dev *dev)
 {
+	if (dev->subordinate) {
+		struct pci_bus *b = dev->subordinate;
+
+		pci_remove_behind_bridge(dev);
+
+#ifdef CONFIG_PROC_FS
+		pci_proc_detach_bus(b);
+#endif
+
+		list_del(&b->node);
+		kfree(b);
+		dev->subordinate = NULL;
+	}
+
 	device_unregister(&dev->dev);
 	list_del(&dev->bus_list);
 	list_del(&dev->global_list);
@@ -249,9 +274,33 @@
 #ifdef CONFIG_PROC_FS
 	pci_proc_detach_device(dev);
 #endif
+
+	kfree(dev);
+}
+
+/**
+ * pci_remove_behind_bridge - remove all devices behind a PCI bridge
+ * @dev: PCI bridge device
+ *
+ * Remove all devices on the bus, except for the parent bridge.
+ * This also removes any child buses, and any devices they may
+ * contain in a depth-first manner.
+ */
+void pci_remove_behind_bridge(struct pci_dev *dev)
+{
+	struct list_head *l, *n;
+
+	if (dev->subordinate) {
+		list_for_each_safe(l, n, &dev->subordinate->devices) {
+			struct pci_dev *dev = pci_dev_b(l);
+
+			pci_remove_bus_device(dev);
+		}
+	}
 }
 
 #ifdef CONFIG_HOTPLUG
 EXPORT_SYMBOL(pci_insert_device);
-EXPORT_SYMBOL(pci_remove_device);
+EXPORT_SYMBOL(pci_remove_bus_device);
+EXPORT_SYMBOL(pci_remove_behind_bridge);
 #endif
include/linux/pci.h +2 -1
diff -Nru a/include/linux/pci.h b/include/linux/pci.h
@@ -645,7 +645,8 @@
 int pci_register_driver(struct pci_driver *);
 void pci_unregister_driver(struct pci_driver *);
 void pci_insert_device(struct pci_dev *, struct pci_bus *);
-void pci_remove_device(struct pci_dev *);
+void pci_remove_bus_device(struct pci_dev *);
+void pci_remove_behind_bridge(struct pci_dev *);
 struct pci_driver *pci_dev_driver(const struct pci_dev *);
 const struct pci_device_id *pci_match_device(const struct pci_device_id *ids, const struct pci_dev *dev);
 unsigned int pci_do_scan_bus(struct pci_bus *bus);
author
#9 lore raw

ChangeSet 1.1022.1.9, 2003/02/24 16:29:53-08:00, [email protected]

[PATCH] Compaq PCI Hotplug: convert to use pci_remove_bus_device instead of custom code.

drivers/hotplug/cpqphp_pci.c +3 -101
diff -Nru a/drivers/hotplug/cpqphp_pci.c b/drivers/hotplug/cpqphp_pci.c
@@ -117,94 +117,11 @@
 }
 
 
-static int unconfigure_visit_pci_dev_phase2 (struct pci_dev_wrapped *wrapped_dev, struct pci_bus_wrapped *wrapped_bus) 
-{
-	struct pci_dev* dev = wrapped_dev->dev;
-
-	struct pci_func *temp_func;
-	int i=0;
-
-	//We need to remove the hotplug function representation with the linux representation
-	do {
-		temp_func = cpqhp_slot_find(dev->bus->number, dev->devfn >> 3, i++);
-		if (temp_func) {
-			dbg("temp_func->function = %d\n", temp_func->function);
-		}
-	} while (temp_func && (temp_func->function != (dev->devfn & 0x07)));
-
-	//Now, remove the Linux Representation
-	if (dev) {
-		if (pci_remove_device_safe(dev) == 0) {
-			kfree(dev); //Now, remove
-		} else {
-			return -1; // problems while freeing, abort visitation
-		}
-	}
-
-	if (temp_func) {
-		temp_func->pci_dev = NULL;
-	} else {
-		dbg("No pci_func representation for bus, devfn = %d, %x\n", dev->bus->number, dev->devfn);
-	}
-
-	return 0;
-}
-
-
-static int unconfigure_visit_pci_bus_phase2 (struct pci_bus_wrapped *wrapped_bus, struct pci_dev_wrapped *wrapped_dev) 
-{
-	struct pci_bus* bus = wrapped_bus->bus;
-
-	//The cleanup code for proc entries regarding buses should be in the kernel...
-	if (bus->procdir)
-		dbg("detach_pci_bus %s\n", bus->procdir->name);
-	pci_proc_detach_bus(bus);
-	// The cleanup code should live in the kernel...
-	bus->self->subordinate = NULL;
-	// unlink from parent bus
-	list_del(&bus->node);
-
-	// Now, remove
-	if (bus)
-		kfree(bus);
-
-	return 0;
-}
-
-
-static int unconfigure_visit_pci_dev_phase1 (struct pci_dev_wrapped *wrapped_dev, struct pci_bus_wrapped *wrapped_bus) 
-{
-	struct pci_dev* dev = wrapped_dev->dev;
-
-	dbg("attempting removal of driver for device (%x, %x, %x)\n", dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
-	//Now, remove the Linux Driver Representation 
-	if (dev->driver) {
-		if (dev->driver->remove) {
-			dev->driver->remove(dev);
-			dbg("driver was properly removed\n");
-		}
-		dev->driver = NULL;
-	}
-
-	return (pci_dev_driver(dev) != NULL);
-}
-
-
 static struct pci_visit configure_functions = {
 	.visit_pci_dev =	configure_visit_pci_dev,
 };
 
 
-static struct pci_visit unconfigure_functions_phase1 = {
-	.post_visit_pci_dev =	unconfigure_visit_pci_dev_phase1
-};
-
-static struct pci_visit unconfigure_functions_phase2 = {
-	.post_visit_pci_bus =	unconfigure_visit_pci_bus_phase2,               
-	.post_visit_pci_dev =	unconfigure_visit_pci_dev_phase2
-};
-
-
 int cpqhp_configure_device (struct controller* ctrl, struct pci_func* func)  
 {
 	unsigned char bus;
@@ -258,31 +175,16 @@
 
 int cpqhp_unconfigure_device(struct pci_func* func) 
 {
-	int rc = 0;
 	int j;
-	struct pci_dev_wrapped wrapped_dev;
-	struct pci_bus_wrapped wrapped_bus;
 	
-	memset(&wrapped_dev, 0, sizeof(struct pci_dev_wrapped));
-	memset(&wrapped_bus, 0, sizeof(struct pci_bus_wrapped));
-
 	dbg("%s: bus/dev/func = %x/%x/%x\n", __FUNCTION__, func->bus, func->device, func->function);
 
 	for (j=0; j<8 ; j++) {
 		struct pci_dev* temp = pci_find_slot(func->bus, (func->device << 3) | j);
-		if (temp) {
-			wrapped_dev.dev = temp;
-			wrapped_bus.bus = temp->bus;
-			rc = pci_visit_dev(&unconfigure_functions_phase1, &wrapped_dev, &wrapped_bus);
-			if (rc)
-				break;
-
-			rc = pci_visit_dev(&unconfigure_functions_phase2, &wrapped_dev, &wrapped_bus);
-			if (rc)
-				break;
-		}
+		if (temp)
+			pci_remove_bus_device(temp);
 	}
-	return rc;
+	return 0;
 }
 
 static int PCI_RefinedAccessConfig(struct pci_bus *bus, unsigned int devfn, u8 offset, u32 *value)
author
#10 lore raw

ChangeSet 1.1022.1.10, 2003/02/24 16:30:40-08:00, [email protected]

[PATCH] Compaq PCI Hotplug: remove unused walk of the device on insertion.

drivers/hotplug/cpqphp_pci.c +0 -54
diff -Nru a/drivers/hotplug/cpqphp_pci.c b/drivers/hotplug/cpqphp_pci.c
@@ -80,61 +80,14 @@
 	return fp;
 }
 
-static int configure_visit_pci_dev (struct pci_dev_wrapped *wrapped_dev, struct pci_bus_wrapped *wrapped_bus) 
-{
-	struct pci_bus* bus = wrapped_bus->bus;
-	struct pci_dev* dev = wrapped_dev->dev;
-	struct pci_func *temp_func;
-	int i=0;
-
-	//We need to fix up the hotplug function representation with the linux representation
-	do {
-		temp_func = cpqhp_slot_find(dev->bus->number, dev->devfn >> 3, i++);
-	} while (temp_func && (temp_func->function != (dev->devfn & 0x07)));
-
-	if (temp_func) {
-		temp_func->pci_dev = dev;
-	} else {
-		//We did not even find a hotplug rep of the function, create it
-		//This code might be taken out if we can guarantee the creation of functions
-		//in parallel (hotplug and Linux at the same time).
-		dbg("@@@@@@@@@@@ cpqhp_slot_create in %s\n", __FUNCTION__);
-		temp_func = cpqhp_slot_create(bus->number);
-		if (temp_func == NULL)
-			return -ENOMEM;
-		temp_func->pci_dev = dev;
-	}
-
-	//Create /proc/bus/pci proc entry for this device and bus device is on
-	//Notify the drivers of the change
-	if (temp_func->pci_dev) {
-//		pci_insert_device (temp_func->pci_dev, bus);
-//		pci_proc_attach_device(temp_func->pci_dev);
-//		pci_announce_device_to_drivers(temp_func->pci_dev);
-	}
-
-	return 0;
-}
-
-
-static struct pci_visit configure_functions = {
-	.visit_pci_dev =	configure_visit_pci_dev,
-};
-
 
 int cpqhp_configure_device (struct controller* ctrl, struct pci_func* func)  
 {
 	unsigned char bus;
 	struct pci_dev dev0;
 	struct pci_bus *child;
-	struct pci_dev* temp;
 	int rc = 0;
 
-	struct pci_dev_wrapped wrapped_dev;
-	struct pci_bus_wrapped wrapped_bus;
-	memset(&wrapped_dev, 0, sizeof(struct pci_dev_wrapped));
-	memset(&wrapped_bus, 0, sizeof(struct pci_bus_wrapped));
-
 	memset(&dev0, 0, sizeof(struct pci_dev));
 
 	if (func->pci_dev == NULL)
@@ -162,13 +115,6 @@
 
 	}
 
-	temp = func->pci_dev;
-
-	if (temp) {
-		wrapped_dev.dev = temp;
-		wrapped_bus.bus = temp->bus;
-		rc = pci_visit_dev(&configure_functions, &wrapped_dev, &wrapped_bus);
-	}
 	return rc;
 }
 
author
#11 lore raw

ChangeSet 1.1022.1.11, 2003/02/24 16:31:00-08:00, [email protected]

[PATCH] ACPI PCI hotplug: convert to use pci_remove_bus_device()

Also got rid of some unneeded bus walking on device init and shutdown.

drivers/hotplug/acpiphp_pci.c +3 -143
diff -Nru a/drivers/hotplug/acpiphp_pci.c b/drivers/hotplug/acpiphp_pci.c
@@ -194,92 +194,6 @@
 	return 0;
 }
 
-
-/* enable pci_dev */
-static int configure_pci_dev (struct pci_dev_wrapped *wrapped_dev, struct pci_bus_wrapped *wrapped_bus)
-{
-	struct acpiphp_func *func;
-	struct acpiphp_bridge *bridge;
-	struct pci_dev *dev;
-
-	func = (struct acpiphp_func *)wrapped_dev->data;
-	bridge = (struct acpiphp_bridge *)wrapped_bus->data;
-	dev = wrapped_dev->dev;
-
-	/* TBD: support PCI-to-PCI bridge case */
-	if (!func || !bridge)
-		return 0;
-
-	//pci_proc_attach_device(dev);
-	//pci_announce_device_to_drivers(dev);
-	info("Device %s configured\n", dev->slot_name);
-
-	return 0;
-}
-
-/* remove device driver */
-static int unconfigure_pci_dev_driver (struct pci_dev_wrapped *wrapped_dev, struct pci_bus_wrapped *wrapped_bus)
-{
-	struct pci_dev *dev = wrapped_dev->dev;
-
-	dbg("attempting removal of driver for device %s\n", dev->slot_name);
-
-	/* Now, remove the Linux Driver Representation */
-	if (dev->driver) {
-		if (dev->driver->remove) {
-			dev->driver->remove(dev);
-			dbg("driver was properly removed\n");
-		}
-		dev->driver = NULL;
-	}
-
-	return (pci_dev_driver(dev) != NULL);
-}
-
-
-/* remove pci_dev itself from system */
-static int unconfigure_pci_dev (struct pci_dev_wrapped *wrapped_dev, struct pci_bus_wrapped *wrapped_bus)
-{
-	struct pci_dev *dev = wrapped_dev->dev;
-
-	/* Now, remove the Linux Representation */
-	if (dev) {
-		if (pci_remove_device_safe(dev) == 0) {
-			info("Device %s removed\n", dev->slot_name);
-			kfree(dev); /* Now, remove */
-		} else {
-			return -1; /* problems while freeing, abort visitation */
-		}
-	}
-
-	return 0;
-}
-
-
-/* remove pci_bus itself from system */
-static int unconfigure_pci_bus (struct pci_bus_wrapped *wrapped_bus, struct pci_dev_wrapped *wrapped_dev)
-{
-	struct pci_bus *bus = wrapped_bus->bus;
-
-#ifdef CONFIG_PROC_FS
-	/* Now, remove the Linux Representation */
-	if (bus->procdir) {
-		pci_proc_detach_bus(bus);
-	}
-#endif
-	/* the cleanup code should live in the kernel ... */
-	bus->self->subordinate = NULL;
-	/* unlink from parent bus */
-	list_del(&bus->node);
-
-	/* Now, remove */
-	if (bus)
-		kfree(bus);
-
-	return 0;
-}
-
-
 /* detect_used_resource - subtract resource under dev from bridge */
 static int detect_used_resource (struct acpiphp_bridge *bridge, struct pci_dev *dev)
 {
@@ -551,22 +465,6 @@
 	return retval;
 }
 
-
-/* for pci_visit_dev() */
-static struct pci_visit configure_functions = {
-	.post_visit_pci_dev =	configure_pci_dev
-};
-
-static struct pci_visit unconfigure_functions_phase1 = {
-	.post_visit_pci_dev =	unconfigure_pci_dev_driver
-};
-
-static struct pci_visit unconfigure_functions_phase2 = {
-	.post_visit_pci_bus =	unconfigure_pci_bus,
-	.post_visit_pci_dev =	unconfigure_pci_dev
-};
-
-
 /**
  * acpiphp_configure_function - configure PCI function
  * @func: function to be configured
@@ -577,33 +475,10 @@
  */
 int acpiphp_configure_function (struct acpiphp_func *func)
 {
-	int retval = 0;
-	struct pci_dev_wrapped wrapped_dev;
-	struct pci_bus_wrapped wrapped_bus;
-	struct acpiphp_bridge *bridge;
-
-	/* if pci_dev is NULL, ignore it */
-	if (!func->pci_dev)
-		goto err_exit;
-
-	bridge = func->slot->bridge;
-
-	memset(&wrapped_dev, 0, sizeof(struct pci_dev_wrapped));
-	memset(&wrapped_bus, 0, sizeof(struct pci_bus_wrapped));
-	wrapped_dev.dev = func->pci_dev;
-	wrapped_dev.data = func;
-	wrapped_bus.bus = bridge->pci_bus;
-	wrapped_bus.data = bridge;
-
-	retval = pci_visit_dev(&configure_functions, &wrapped_dev, &wrapped_bus);
-	if (retval)
-		goto err_exit;
-
- err_exit:
-	return retval;
+	/* all handled by the pci core now */
+	return 0;
 }
 
-
 /**
  * acpiphp_unconfigure_function - unconfigure PCI function
  * @func: function to be unconfigured
@@ -612,28 +487,13 @@
 int acpiphp_unconfigure_function (struct acpiphp_func *func)
 {
 	struct acpiphp_bridge *bridge;
-	struct pci_dev_wrapped wrapped_dev;
-	struct pci_bus_wrapped wrapped_bus;
 	int retval = 0;
 
 	/* if pci_dev is NULL, ignore it */
 	if (!func->pci_dev)
 		goto err_exit;
 
-	memset(&wrapped_dev, 0, sizeof(struct pci_dev_wrapped));
-	memset(&wrapped_bus, 0, sizeof(struct pci_bus_wrapped));
-	wrapped_dev.dev = func->pci_dev;
-	//wrapped_dev.data = func;
-	wrapped_bus.bus = func->slot->bridge->pci_bus;
-	//wrapped_bus.data = func->slot->bridge;
-
-	retval = pci_visit_dev(&unconfigure_functions_phase1, &wrapped_dev, &wrapped_bus);
-	if (retval)
-		goto err_exit;
-
-	retval = pci_visit_dev(&unconfigure_functions_phase2, &wrapped_dev, &wrapped_bus);
-	if (retval)
-		goto err_exit;
+	pci_remove_bus_device(func->pci_dev);
 
 	/* free all resources */
 	bridge = func->slot->bridge;
author
#12 lore raw

ChangeSet 1.1022.1.12, 2003/02/24 16:32:16-08:00, [email protected]

[PATCH] IBM PCI Hotplug: convert driver to use pci_bus_remove_device()

Also cleaned up a lot of unnecessary bus walking on device startup and shutdown.

drivers/hotplug/ibmphp_core.c +3 -133
diff -Nru a/drivers/hotplug/ibmphp_core.c b/drivers/hotplug/ibmphp_core.c
@@ -781,141 +781,23 @@
 	debug ("%s -- exit\n", __FUNCTION__);
 }
 
-static int ibm_unconfigure_visit_pci_dev_phase2 (struct pci_dev_wrapped *wrapped_dev, struct pci_bus_wrapped *wrapped_bus)
-{
-	struct pci_dev *dev = wrapped_dev->dev;
-	struct pci_func *temp_func;
-	int i = 0;
-
-	do {
-		temp_func = ibm_slot_find (dev->bus->number, dev->devfn >> 3, i++);
-	} while (temp_func && (temp_func->function != (dev->devfn & 0x07)));
-
-	if (dev) {
-		if (pci_remove_device_safe(dev) == 0)
-			kfree (dev);    /* Now, remove */
-		else
-			return -1;
-	}
-
-	if (temp_func)
-		temp_func->dev = NULL;
-	else
-		debug ("No pci_func representation for bus, devfn = %d, %x\n", dev->bus->number, dev->devfn);
-
-	return 0;
-}
-
-static int ibm_unconfigure_visit_pci_bus_phase2 (struct pci_bus_wrapped *wrapped_bus, struct pci_dev_wrapped *wrapped_dev)
-{
-	struct pci_bus *bus = wrapped_bus->bus;
-
-	pci_proc_detach_bus (bus);
-	/* The cleanup code should live in the kernel... */
-	bus->self->subordinate = NULL;
-	/* unlink from parent bus */
-	list_del (&bus->node);
-
-	/* Now, remove */
-	if (bus)
-		kfree (bus);
-
-	return 0;
-}
-
-static int ibm_unconfigure_visit_pci_dev_phase1 (struct pci_dev_wrapped *wrapped_dev, struct pci_bus_wrapped *wrapped_bus)
-{
-	struct pci_dev *dev = wrapped_dev->dev;
-
-	debug ("attempting removal of driver for device (%x, %x, %x)\n", dev->bus->number, PCI_SLOT (dev->devfn), PCI_FUNC (dev->devfn));
-
-	/* Now, remove the Linux Driver Representation */
-	if (dev->driver) {
-		debug ("is there a driver?\n");
-		if (dev->driver->remove) {
-			dev->driver->remove (dev);
-			debug ("driver was properly removed\n");
-		}
-		dev->driver = NULL;
-	}
-
-	return (pci_dev_driver(dev) != NULL);
-}
-
-static struct pci_visit ibm_unconfigure_functions_phase1 = {
-	.post_visit_pci_dev =	ibm_unconfigure_visit_pci_dev_phase1,
-};
-
-static struct pci_visit ibm_unconfigure_functions_phase2 = {
-	.post_visit_pci_bus =	ibm_unconfigure_visit_pci_bus_phase2,
-	.post_visit_pci_dev =	ibm_unconfigure_visit_pci_dev_phase2,
-};
-
 static int ibm_unconfigure_device (struct pci_func *func)
 {
-	int rc = 0;
-	struct pci_dev_wrapped wrapped_dev;
-	struct pci_bus_wrapped wrapped_bus;
 	struct pci_dev *temp;
 	u8 j;
 
-	memset (&wrapped_dev, 0, sizeof (struct pci_dev_wrapped));
-	memset (&wrapped_bus, 0, sizeof (struct pci_bus_wrapped));
-
-	debug ("inside ibm_unconfigure_device\n");
+	debug ("inside %s\n", __FUNCTION__);
 	debug ("func->device = %x, func->function = %x\n", func->device, func->function);
 	debug ("func->device << 3 | 0x0  = %x\n", func->device << 3 | 0x0);
 
 	for (j = 0; j < 0x08; j++) {
 		temp = pci_find_slot (func->busno, (func->device << 3) | j);
-		if (temp) {
-			wrapped_dev.dev = temp;
-			wrapped_bus.bus = temp->bus;
-			rc = pci_visit_dev (&ibm_unconfigure_functions_phase1, &wrapped_dev, &wrapped_bus);
-			if (rc)
-				break;
-
-			rc = pci_visit_dev (&ibm_unconfigure_functions_phase2, &wrapped_dev, &wrapped_bus);
-			if (rc)
-				break;
-		}
+		if (temp)
+			pci_remove_bus_device(temp);
 	}
-	debug ("rc in ibm_unconfigure_device b4 returning is %d \n", rc);
-	return rc;
-}
-
-static int configure_visit_pci_dev (struct pci_dev_wrapped *wrapped_dev, struct pci_bus_wrapped *wrapped_bus)
-{
-	//      struct pci_bus *bus = wrapped_bus->bus; /* We don't need this, since we don't create in the else statement */
-	struct pci_dev *dev = wrapped_dev->dev;
-	struct pci_func *temp_func;
-	int i = 0;
-
-	do {
-		temp_func = ibm_slot_find (dev->bus->number, dev->devfn >> 3, i++);
-	} while (temp_func && (temp_func->function != (dev->devfn & 0x07)));
-
-	if (temp_func)
-		temp_func->dev = dev;
-	else {
-		/* This should not really happen, since we create functions
-		   first and then call to configure */
-		debug (" We shouldn't come here \n");
-	}
-
-	if (temp_func->dev) {
-//		pci_proc_attach_device (temp_func->dev);
-//		pci_announce_device_to_drivers (temp_func->dev);
-	}
-
 	return 0;
 }
 
-static struct pci_visit configure_functions = {
-	.visit_pci_dev =configure_visit_pci_dev,
-};
-
-
 /*
  * The following function is to fix kernel bug regarding 
  * getting bus entries, here we manually add those primary 
@@ -965,15 +847,9 @@
 	unsigned char bus;
 	struct pci_dev dev0;
 	struct pci_bus *child;
-	struct pci_dev *temp;
 	int rc = 0;
 	int flag = 0;	/* this is to make sure we don't double scan the bus, for bridged devices primarily */
 
-	struct pci_dev_wrapped wrapped_dev;
-	struct pci_bus_wrapped wrapped_bus;
-
-	memset (&wrapped_dev, 0, sizeof (struct pci_dev_wrapped));
-	memset (&wrapped_bus, 0, sizeof (struct pci_bus_wrapped));
 	memset (&dev0, 0, sizeof (struct pci_dev));
 
 	if (!(bus_structure_fixup (func->busno)))
@@ -1001,12 +877,6 @@
 		pci_do_scan_bus (child);
 	}
 
-	temp = func->dev;
-	if (temp) {
-		wrapped_dev.dev = temp;
-		wrapped_bus.bus = temp->bus;
-		rc = pci_visit_dev (&configure_functions, &wrapped_dev, &wrapped_bus);
-	}
 	return rc;
 }
 
author
#13 lore raw

ChangeSet 1.1022.1.13, 2003/02/24 16:33:09-08:00, [email protected]

[PATCH] PCI: export pci_scan_bus_parented which is needed by the IBM pci hotplug driver.

drivers/pci/probe.c +1 -0
diff -Nru a/drivers/pci/probe.c b/drivers/pci/probe.c
@@ -609,6 +609,7 @@
 	}
 	return b;
 }
+EXPORT_SYMBOL(pci_scan_bus_parented);
 
 EXPORT_SYMBOL(pci_devices);
 EXPORT_SYMBOL(pci_root_buses);
author
#14 lore raw

ChangeSet 1.1022.1.14, 2003/02/24 16:35:48-08:00, [email protected]

[PATCH] CPCI core: remove unneeded visit device on unconfigure.

The driver now links properly, but this is untested due to my lack of cPCI hardware.

drivers/hotplug/cpci_hotplug_pci.c +0 -34
diff -Nru a/drivers/hotplug/cpci_hotplug_pci.c b/drivers/hotplug/cpci_hotplug_pci.c
@@ -483,29 +483,6 @@
 	return 0;
 }
 
-static int unconfigure_visit_pci_dev_phase1(struct pci_dev_wrapped *wrapped_dev,
-				 struct pci_bus_wrapped *wrapped_bus)
-{
-	struct pci_dev *dev = wrapped_dev->dev;
-
-	dbg("%s - enter", __FUNCTION__);
-
-	dbg("attempting removal of driver for device %02x:%02x.%x",
-	    dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
-
-	/* Now, remove the Linux Driver representation */
-	if(dev->driver) {
-		dbg("device is attached to a driver");
-		if(dev->driver->remove) {
-			dev->driver->remove(dev);
-			dbg("driver was removed");
-		}
-		dev->driver = NULL;
-	}
-	dbg("%s - exit", __FUNCTION__);
-	return pci_is_dev_in_use(dev);
-}
-
 static int unconfigure_visit_pci_dev_phase2(struct pci_dev_wrapped *wrapped_dev,
 					    struct pci_bus_wrapped *wrapped_bus)
 {
@@ -577,10 +554,6 @@
 	.visit_pci_dev = configure_visit_pci_dev,
 };
 
-static struct pci_visit unconfigure_functions_phase1 = {
-	.post_visit_pci_dev = unconfigure_visit_pci_dev_phase1
-};
-
 static struct pci_visit unconfigure_functions_phase2 = {
 	.post_visit_pci_bus = unconfigure_visit_pci_bus_phase2,
 	.post_visit_pci_dev = unconfigure_visit_pci_dev_phase2
@@ -668,13 +641,6 @@
 		if(dev) {
 			wrapped_dev.dev = dev;
 			wrapped_bus.bus = dev->bus;
-			dbg("%s - unconfigure phase 1", __FUNCTION__);
-			rc = pci_visit_dev(&unconfigure_functions_phase1,
-					   &wrapped_dev, &wrapped_bus);
-			if(rc) {
-				break;
-			}
-
 			dbg("%s - unconfigure phase 2", __FUNCTION__);
 			rc = pci_visit_dev(&unconfigure_functions_phase2,
 					   &wrapped_dev, &wrapped_bus);
author
#15 lore raw
In reply to Greg KH
Quoted 9 lines · Greg KH

Hi,

Here's some patches that clean up the remove logic a lot for the PCI hotplug drivers. The main PCI patches were done by Russell King and Christoph Hellwig, and then I went and cleaned up the PCI Hotplug drivers a lot based on their changes. I also fixed up some exit logic in the IBM PCI hotplug driver, as it was a mess.

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

I've merged with your latest tree again, and it's available at the above place. Could you please pull these changes?

thanks,

greg k-h

#16 lore raw
Quoted 3 lines · Greg KH

I've merged with your latest tree again, and it's available at the above place. Could you please pull these changes?

This causes

	drivers/built-in.o(.text+0xedc7e): In function `cb_free':
	: undefined reference to `pci_remove_device'
	make: *** [.tmp_vmlinux1] Error 1

Ehh?

Linus

author
#17 lore raw
Quoted 6 lines · Linus Torvalds
Quoted 3 lines · Greg KH

I've merged with your latest tree again, and it's available at the above place. Could you please pull these changes?

Quoted 7 lines

This causes

	drivers/built-in.o(.text+0xedc7e): In function `cb_free':
	: undefined reference to `pci_remove_device'
	make: *** [.tmp_vmlinux1] Error 1

Ehh?

Oops, looks like Russell and I didn't test on a cardbus machine :) I've made the following change to the repository, so you can just pull it if you want to (from bk://kernel.bkbits.net/gregkh/linux/pci-2.5 ) or you can just apply this patch.

It looks right to me, but I don't have a working cardbus machine at the moment, so I can't test it, sorry.

Again, sorry about this.

greg k-h

# Cardbus: change cb_free to use pci_remove_device_safe()

drivers/pcmcia/cardbus.c +1 -1
diff -Nru a/drivers/pcmcia/cardbus.c b/drivers/pcmcia/cardbus.c
@@ -313,7 +313,7 @@
 
 		s->cb_config = NULL;
 		for (i = 0 ; i < s->functions ; i++)
-			pci_remove_device(&c[i].dev);
+			pci_remove_device_safe(&c[i].dev);
 
 		kfree(c);
 		printk(KERN_INFO "cs: cb_free(bus %d)\n", s->cap.cb_dev->subordinate->number);
#18 lore raw
Quoted 3 lines · Greg KH

It looks right to me, but I don't have a working cardbus machine at the moment, so I can't test it, sorry.

I don't think this is right. When we unplug a device, we're unplugging it whether it is unused or not, and pci_remove_device_safe() is the wrong thing. It should use the "remove_behind_bridge()" thing, so I think Russell's patch is closer to working, but that one looked like it will certainly corrupt memory with any multi-function device, so I really would want to see something that has actually been tested too.

Linus

author
#19 lore raw
Quoted 6 lines · Linus Torvalds
Quoted 3 lines · Greg KH

It looks right to me, but I don't have a working cardbus machine at the moment, so I can't test it, sorry.

Quoted 6 lines

I don't think this is right. When we unplug a device, we're unplugging it whether it is unused or not, and pci_remove_device_safe() is the wrong thing. It should use the "remove_behind_bridge()" thing, so I think Russell's patch is closer to working, but that one looked like it will certainly corrupt memory with any multi-function device, so I really would want to see something that has actually been tested too.

Fair enough, I'll try to get my laptop up and running this evening and test these changes out on it.

thanks,

greg k-h