[parisc-linux-cvs] Re: 2.4.21-pa4 arch/parisc/kernel/pci.c cleanup

Grant Grundler grundler@parisc-linux.org
Sun, 13 Jul 2003 23:35:41 -0600


On Sun, Jul 13, 2003 at 11:11:54PM -0600, Grant Grundler wrote:
> Log message:
> 2.4.21-pa4 clean __dev_init issues (HOTPLUG=n breakage)
> 
> If CONFIG_HOTPLUG=n, we'd panic modprobe <PCI Driver> when to PCI init
> code is executed that's marked __dev_init. Our implementation doesn't
> actually release __init code segments but hopefully it will someday.
> jejb and I figured out the bug in 2.5 first.


Diff is appended.  Code summary:
o remove __dev_init  or replace with __init as appropriate.
o move pcibios_init_bus() closer to calling function
  (I just realized this didn't buy anything really)
o delete orphaned pcibios_setup_host_bridge()

Tested on a500 with DEC 21154 bridge:
 +-[20]---00.0-[21]--+-04.0  HP Tach TL Fiber Channel Adapter
 |                   \-05.0  HP Tach TL Fiber Channel Adapter


This "mislabeled __devinit" bug really got me thinking about some
sort of validation tool that would catalog symbols found in a vmlinux
based on which section they are in and then do lookup references using
the parents section if it's the __init section. 
eg The lookup for __text+<symbol> would fail if the symbol
were resident in the vmlinux as __init+<symbol>.

I'm not quite sure how to hack this together becuase I don't
know the names of the various kernel sections. If someone
can tell me, I'll try to hack something this coming week
on the laptop...vmlinux is just an ELF file right? :^)

thanks,
grant


Index: Makefile
===================================================================
RCS file: /var/cvs/linux/Makefile,v
retrieving revision 1.401
diff -u -p -r1.401 Makefile
--- Makefile	11 Jul 2003 15:58:10 -0000	1.401
+++ Makefile	14 Jul 2003 04:59:34 -0000
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 4
 SUBLEVEL = 21
-EXTRAVERSION = -pa3
+EXTRAVERSION = -pa4
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
Index: arch/parisc/kernel/pci.c
===================================================================
RCS file: /var/cvs/linux/arch/parisc/kernel/pci.c,v
retrieving revision 1.38
diff -u -p -r1.38 pci.c
--- arch/parisc/kernel/pci.c	17 Nov 2002 20:44:11 -0000	1.38
+++ arch/parisc/kernel/pci.c	14 Jul 2003 04:59:37 -0000
@@ -157,9 +157,9 @@ struct pci_fixup pcibios_fixups[] = { {0
 
 
 /*
-** called by drivers/pci/setup.c:pdev_fixup_irq()
+** called by drivers/pci/setup-irq.c:pdev_fixup_irq()
 */
-void __devinit pcibios_update_irq(struct pci_dev *dev, int irq)
+void __init pcibios_update_irq(struct pci_dev *dev, int irq)
 {
 /*
 ** updates IRQ_LINE cfg register to reflect PCI-PCI bridge skewing.
@@ -207,13 +207,8 @@ void __devinit pcibios_update_irq(struct
 ** PAT PDC can tell us which MMIO ranges are available or already in use.
 ** I/O port space and such are not memory mapped anyway for PA-Risc.
 */
-void __devinit
-pcibios_update_resource(
-	struct pci_dev *dev,
-	struct resource *root,
-	struct resource *res,
-	int barnum
-	)
+void pcibios_update_resource( struct pci_dev *dev, struct resource *root,
+				struct resource *res, int barnum)
 {
 	int where;
 	u32 barval = 0;
@@ -274,8 +269,7 @@ pcibios_update_resource(
 **		bus numbers, bridge control
 **
 */
-void
-pcibios_set_master(struct pci_dev *dev)
+void pcibios_set_master(struct pci_dev *dev)
 {
 	u8 lat;
 
@@ -291,9 +285,31 @@ pcibios_set_master(struct pci_dev *dev)
 				(0x80 << 8) | (L1_CACHE_BYTES / sizeof(u32)));
 }
 
+/*
+** KLUGE: Link the child and parent resources - generic PCI didn't
+*/
+static void pcibios_link_hba_resources( struct resource *hba_res, struct resource *r)
+{
+	if (!r->parent) {
+		r->parent = hba_res;
+
+		/* reverse link is harder *sigh*  */
+		if (r->parent->child) {
+			if (r->parent->sibling) {
+				struct resource *next = r->parent->sibling;
+				while (next->sibling)
+					 next = next->sibling;
+				next->sibling = r;
+			} else {
+				r->parent->sibling = r;
+			}
+		} else
+			r->parent->child = r;
+	}
+}
+
 
-void __init
-pcibios_init_bus(struct pci_bus *bus)
+void __init pcibios_init_bus(struct pci_bus *bus)
 {
 	struct pci_dev *dev = bus->self;
 
@@ -317,36 +333,10 @@ pcibios_init_bus(struct pci_bus *bus)
 
 
 /*
-** KLUGE: Link the child and parent resources - generic PCI didn't
-*/
-static void
-pcibios_link_hba_resources( struct resource *hba_res, struct resource *r)
-{
-	if (!r->parent) {
-		r->parent = hba_res;
-
-		/* reverse link is harder *sigh*  */
-		if (r->parent->child) {
-			if (r->parent->sibling) {
-				struct resource *next = r->parent->sibling;
-				while (next->sibling)
-					 next = next->sibling;
-				next->sibling = r;
-			} else {
-				r->parent->sibling = r;
-			}
-		} else
-			r->parent->child = r;
-	}
-}
-
-/*
 ** called by drivers/pci/setup-res.c:pci_setup_bridge().
 */
-void pcibios_fixup_pbus_ranges(
-	struct pci_bus *bus,
-	struct pbus_set_ranges_data *ranges
-	)
+void __init pcibios_fixup_pbus_ranges( struct pci_bus *bus,
+				struct pbus_set_ranges_data *ranges)
 {
 	struct pci_hba_data *hba = HBA_DATA(bus->sysdata);
 
@@ -374,6 +364,12 @@ void pcibios_fixup_pbus_ranges(
 	*/
 	pcibios_link_hba_resources(&hba->io_space, bus->resource[0]);
 	pcibios_link_hba_resources(&hba->lmmio_space, bus->resource[1]);
+
+	/*
+	 * HACK ALERT: Generic PCI services mixes PPB resource fixups
+	 * with other PPB resource initialization.
+	 */
+	pcibios_init_bus(bus);
 }
 
 #define MAX(val1, val2)   ((val1) > (val2) ? (val1) : (val2))
@@ -388,8 +384,7 @@ void pcibios_fixup_pbus_ranges(
 ** Since we are just checking candidates, don't use any fields other
 ** than res->start.
 */
-void __devinit
-pcibios_align_resource(void *data, struct resource *res,
+void pcibios_align_resource(void *data, struct resource *res,
 			unsigned long size, unsigned long alignment)
 {
 	unsigned long mask, align;
@@ -419,8 +414,7 @@ pcibios_align_resource(void *data, struc
 }
 
 
-int __devinit
-pcibios_enable_device(struct pci_dev *dev, int mask)
+int pcibios_enable_device(struct pci_dev *dev, int mask)
 {
 	u16 cmd;
 	int idx;
@@ -470,23 +464,8 @@ pcibios_enable_device(struct pci_dev *de
 	return 0;
 }
 
-void __init
-pcibios_setup_host_bridge(struct pci_bus *bus)
-{
-	ASSERT(pci_bios != NULL);
-
-#if 0
-	if (pci_bios)
-	{
-		if (pci_bios->setup_host_bridge) {
-			(*pci_bios->setup_host_bridge)(bus);
-		}
-	}
-#endif
-}
 
-static void __devinit
-pcibios_enable_ppb(struct pci_bus *bus)
+static void __init pcibios_enable_ppb(struct pci_bus *bus)
 {
 	struct list_head *list;
 
@@ -502,8 +481,7 @@ pcibios_enable_ppb(struct pci_bus *bus)
 /*
 ** Mostly copied from drivers/pci/setup-bus.c:pci_assign_unassigned_resources()
 */
-void __devinit
-pcibios_assign_unassigned_resources(struct pci_bus *bus)
+void __init pcibios_assign_unassigned_resources(struct pci_bus *bus)
 {
 	/* from drivers/pci/setup-bus.c */
 	extern void pbus_size_bridges(struct pci_bus *bus);