[parisc-linux-cvs] [DIFF] 2.4.0 PCI rework

Grant Grundler grundler@puffin.external.hp.com
Sun, 11 Mar 2001 00:13:44 -0700


Since Code is already committed, I expect folks will already
have my commit msg. If not, let me know and I'll send a copy.

Index: arch/parisc/kernel/lba_pci.c
===================================================================
RCS file: /home/cvs/parisc/linux/arch/parisc/kernel/lba_pci.c,v
retrieving revision 1.23
diff -u -p -r1.23 lba_pci.c
--- lba_pci.c	2001/03/02 10:31:49	1.23
+++ lba_pci.c	2001/03/11 05:56:22
@@ -62,6 +62,15 @@
 #undef DEBUG_LBA_CFG	/* debug Config Space Access (ie PCI Bus walk) */
 #undef DEBUG_LBA_PAT	/* debug PCI Resource Mgt code - PDC PAT only */
 
+#undef FBB_SUPPORT	/* Fast Back-Back xfers - NOT READY YET */
+
+#ifdef __LP64__
+/* workarounds for brokeness in PAT PDC
+** Hopefully these can/will go away as new PDC revs become available.
+*/
+#define PDC_PAT_BUG
+#endif
+
 #ifdef DEBUG_LBA
 #define DBG(x...)	printk(x)
 #else
@@ -137,6 +146,9 @@ static struct pa_iodc_driver lba_drivers
 #define LBA_MOD_ID	0x0100	/* Module ID. PDC_PAT_CELL reports 4 */
 
 #define LBA_STAT_CTL	0x0108	/* Status & Control */
+#define   LBA_BUS_RESET		0x01	/*  Deassert PCI Bus Reset Signal */
+#define   CLEAR_ERRLOG		0x10	/*  "Clear Error Log" cmd */
+#define   CLEAR_ERRLOG_ENABLE	0x20	/*  "Clear Error Log" Enable */
 #define   HF_ENABLE	0x40	/*    enable HF mode (default is -1 mode) */
 
 #define LBA_LMMIO_BASE	0x0200	/* < 4GB I/O address range */
@@ -170,7 +182,9 @@ static struct pa_iodc_driver lba_drivers
 
 /* ERROR regs are needed for config cycle kluges */
 #define LBA_ERROR_CONFIG 0x0680
+#define     LBA_SMART_MODE 0x20
 #define LBA_ERROR_STATUS 0x0688
+#define LBA_ROPE_CTL     0x06A0
 
 #define LBA_IOSAPIC_BASE	0x800 /* Offset of IRQ logic */
 
@@ -242,6 +256,9 @@ static u32 lba_t32;
 #define READ_REG8(addr)  gsc_readb(addr)
 #define READ_REG16(addr) le16_to_cpu(gsc_readw((u16 *) (addr)))
 #define READ_REG32(addr) le32_to_cpu(gsc_readl((u32 *) (addr)))
+#ifdef __LP64__
+#define READ_REG64(addr) le64_to_cpu(gsc_readq((u64 *) (addr)))
+#endif
 #define WRITE_REG8(value, addr) gsc_writeb(value, addr)
 #define WRITE_REG16(value, addr) gsc_writew(cpu_to_le16(value), (u16 *) (addr))
 #define WRITE_REG32(value, addr) gsc_writel(cpu_to_le32(value), (u32 *) (addr))
@@ -371,7 +388,7 @@ lba_device_present( u8 bus, u8 dfn, stru
      * Set the smart mode bit so that master aborts don't cause		\
      * LBA to go into PCI fatal mode (required).			\
      */									\
-    WRITE_REG32(error_config | 0x20, d->hba.base_addr + LBA_ERROR_CONFIG);	\
+    WRITE_REG32(error_config | LBA_SMART_MODE, d->hba.base_addr + LBA_ERROR_CONFIG);	\
 }
 
 
@@ -432,7 +449,7 @@ lba_device_present( u8 bus, u8 dfn, stru
      * Set clear enable (CE) bit. Unset by HW when new			\
      * errors are logged -- LBA HW ERS section 14.3.3).		\
      */									\
-    WRITE_REG32(status_control | 0x20, base + LBA_STAT_CTL);	\
+    WRITE_REG32(status_control | CLEAR_ERRLOG_ENABLE, base + LBA_STAT_CTL); \
     error_status = READ_REG32(base + LBA_ERROR_STATUS);		\
     if ((error_status & 0x1f) != 0) {					\
 	/*								\
@@ -444,7 +461,7 @@ lba_device_present( u8 bus, u8 dfn, stru
 	     * Clear error status (if fatal bit not set) by setting	\
 	     * clear error log bit (CL).				\
 	     */								\
-	    WRITE_REG32(status_control | 0x10, base + LBA_STAT_CTL);	\
+	    WRITE_REG32(status_control | CLEAR_ERRLOG, base + LBA_STAT_CTL); \
 	}								\
     }									\
 }
@@ -714,9 +731,10 @@ static void
 lba_fixup_bus(struct pci_bus *bus)
 {
 	struct list_head *ln;
-        struct pci_dev *dev;
+#ifdef FBB_SUPPORT
 	u16 fbb_enable = PCI_STATUS_FAST_BACK;
 	u16 status;
+#endif
 	struct lba_device *ldev = LBA_DEV(bus->sysdata);
 #ifdef __LP64__
 	int i;
@@ -733,13 +751,11 @@ lba_fixup_bus(struct pci_bus *bus)
 
 		DBG("lba_fixup_bus() %s [%lx/%lx]/%x\n",
 			ldev->hba.io_space.name,
-			ldev->hba.io_space.start,
-			ldev->hba.io_space.end,
+			ldev->hba.io_space.start, ldev->hba.io_space.end,
 			(int) ldev->hba.io_space.flags);
 		DBG("lba_fixup_bus() %s [%lx/%lx]/%x\n",
 			ldev->hba.mem_space.name,
-			ldev->hba.mem_space.start,
-			ldev->hba.mem_space.end,
+			ldev->hba.mem_space.start, ldev->hba.mem_space.end,
 			(int) ldev->hba.mem_space.flags);
 
 		err = request_resource(&ioport_resource, &(ldev->hba.io_space));
@@ -755,20 +771,61 @@ lba_fixup_bus(struct pci_bus *bus)
 
 		bus->resource[0] = &(ldev->hba.io_space);
 		bus->resource[1] = &(ldev->hba.mem_space);
+	} else {
+		/* KLUGE ALERT!
+		** PCI-PCI Bridge resource munging.
+		** This hack should go away in the near future.
+		** It's based on the Alpha port.
+		*/
+		int i;
+		u16 cmd;
+
+		for(i=0; i<4; i++) {
+			bus->resource[i] =
+				&bus->self->resource[PCI_BRIDGE_RESOURCES+i];
+			bus->resource[i]->name = bus->name;
+		}
+		bus->resource[0]->flags |= pci_bridge_check_io(bus->self);
+		bus->resource[1]->flags |= IORESOURCE_MEM;
+		bus->resource[2]->flags = 0;	/* Don't support prefetchable */
+		bus->resource[3]->flags = 0;	/* not used */
+
+		/* 
+		** If the PPB is enabled (ie already configured) then
+		** just read those values.
+		*/
+		(void) lba_cfg_read16(bus->self, PCI_COMMAND, &cmd);
+		if (cmd & (PCI_COMMAND_MEMORY | PCI_COMMAND_IO)) {
+			pci_read_bridge_bases(bus);
+		} else {
+			/* Not configured.
+			** For now, propogate HBA limits to the bus;
+			**	PCI will adjust them later.
+			*/
+			bus->resource[0]->end = ldev->hba.io_space.end;
+			bus->resource[1]->end = ldev->hba.mem_space.end;
+		}
+
+		/* Turn off downstream PF memory address range by default */
+		bus->resource[2]->start = 1024*1024;
+		bus->resource[2]->end = bus->resource[2]->start - 1;
 	}
 
-	list_for_each(ln, &bus->devices) {
 
-		dev = pci_dev_b(ln);
+	list_for_each(ln, &bus->devices) {
+		struct pci_dev *dev = pci_dev_b(ln);
 
 #ifdef __LP64__
 		/*
-		** 0-5 are the "standard PCI regions"
-		** (see comments near PCI_NUM_RESOURCES in include/linux/pci.h)
+		** Virtualize Device/Bridge Resources.
 		*/
-		for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
+		for (i = 0; i < PCI_NUM_RESOURCES; i++) {
 			struct resource *res = &(dev->resource[i]);
 
+			/* If resource not allocated - skip it */
+			if (!res->start)
+				continue;
+
 			if (res->flags & IORESOURCE_MEM) {
 				/* "Globalize" PCI address */
 				res->start |= ldev->lmmio_base;
@@ -777,12 +834,14 @@ lba_fixup_bus(struct pci_bus *bus)
 		}
 #endif
 
+#ifdef FBB_SUPPORT
 		/*
 		** If one device does not support FBB transfers,
 		** No one on the bus can be allowed to use them.
 		*/
 		(void) lba_cfg_read16(dev, PCI_STATUS, &status);
 		fbb_enable &= status;
+#endif
 
 #ifdef __LP64__
 		if (is_pdc_pat()) {
@@ -801,7 +860,7 @@ lba_fixup_bus(struct pci_bus *bus)
 		iosapic_fixup_irq(LBA_DEV(bus->sysdata)->iosapic_obj, dev);
 	}
 
-#if 0
+#ifdef FBB_SUPPORT
 /* FIXME/REVISIT - finish figuring out to set FBB on both
 ** pci_setup_bridge() clobbers PCI_BRIDGE_CONTROL.
 ** Can't fixup here anyway....garr...
@@ -1167,20 +1226,80 @@ lba_legacy_resources( struct hp_device *
 **
 **************************************************************************/
 
-static void
+static int
 lba_hw_init(struct lba_device *d)
 {
 	u32 stat;
+#ifdef PDC_PAT_BUG
+	u32 bus_reset;
+#endif
 
+#ifdef DEBUG_LBA_PAT
+printk("LBA %p  STAT_CTL %Lx  ERROR_CFG %Lx  STATUS %Lx DMA_CTL %Lx\n",
+	d->hba.base_addr,
+        READ_REG64(d->hba.base_addr + LBA_STAT_CTL),
+        READ_REG64(d->hba.base_addr + LBA_ERROR_CONFIG),
+        READ_REG64(d->hba.base_addr + LBA_ERROR_STATUS),
+        READ_REG64(d->hba.base_addr + LBA_DMA_CTL)
+	);
+printk("	ARB mask %Lx  pri %Lx  mode %Lx  mtlt %Lx\n",
+        READ_REG64(d->hba.base_addr + LBA_ARB_MASK),
+        READ_REG64(d->hba.base_addr + LBA_ARB_PRI),
+        READ_REG64(d->hba.base_addr + LBA_ARB_MODE),
+        READ_REG64(d->hba.base_addr + LBA_ARB_MTLT)
+	);
+#endif	/* DEBUG_LBA_PAT */
+
+#ifdef __LP64__
+#warning Need to add support for PDC_PAT_IO "Get slot status" - OLAR support
+#endif
+
+	/*
+	**
+	*/
+	stat = READ_REG32(d->hba.base_addr + LBA_ERROR_CONFIG);
+	WRITE_REG32(stat | LBA_SMART_MODE, d->hba.base_addr + LBA_ERROR_CONFIG);
+
+#ifdef PDC_PAT_BUG
+	/* Bug exhibited with PDC rev 40.48  on L2000 */
+	if (bus_reset = (READ_REG32(d->hba.base_addr + LBA_STAT_CTL + 4) & 1)) {
+		BUG();
+	}
+#endif
+
 	/* Set HF mode as the default (vs. -1 mode). */
         stat = READ_REG32(d->hba.base_addr + LBA_STAT_CTL);
 	WRITE_REG32(stat | HF_ENABLE, d->hba.base_addr + LBA_STAT_CTL);
 
+#ifdef PDC_PAT_BUG
+	/*
+	** Writing a zero to STAT_CTL.rf (bit 0) will clear reset signal
+	** if it's not already set. If we just cleared the PCI Bus Reset
+	** signal, wait a bit for the PCI devices to recover and setup.
+	*/
+	if (bus_reset)
+		mdelay(pci_post_reset_delay);
+
+	if (0 == READ_REG32(d->hba.base_addr + LBA_ARB_MASK)) {
+		/*
+		** Bug exhibited with PDC rev 40.48 on L2000.
+		** 
+		** Elroys with hot pluggable slots don't get configured
+		** correctly if the slot is empty.  ARB_MASK is set to 0
+		** and we can't master transactions on the bus if it's
+		** not at least one. 0x3 enables elroy and first slot.
+		*/
+		BUG();
+		WRITE_REG32(0x3, d->hba.base_addr + LBA_ARB_MASK);
+	}
+#endif
+
 	/*
 	** FIXME: Hint registers are programmed with default hint
 	** values by firmware. Hints should be sane even if we
 	** can't reprogram them the way drivers want.
 	*/
+	return 0;
 }
 
 
@@ -1215,9 +1334,6 @@ lba_driver_callback(struct hp_device *d,
 	u32 func_class;
 	void *tmp_obj;
 
-	/* from drivers/pci/setup-bus.c */
-	extern void __init pci_setup_bridge(struct pci_bus *);
-
 	/* Read HW Rev First */
 	func_class = READ_REG32(d->hpa + LBA_FCLASS);
 	func_class &= 0xf;
@@ -1278,7 +1394,9 @@ lba_driver_callback(struct hp_device *d,
 
 	/* ------------ Second : initialize common stuff ---------- */
 	lba_common_init(lba_dev);
-	lba_hw_init(lba_dev);
+
+	if (lba_hw_init(lba_dev))
+		return(1);
 
 	/* ---------- Third : setup I/O Port and MMIO resources  --------- */
 
@@ -1309,11 +1427,6 @@ lba_driver_callback(struct hp_device *d,
 
 #ifdef __LP64__
 	if (is_pdc_pat()) {
-
-		/* determine window sizes needed by PCI-PCI bridges */
-		DBG_PAT("LBA pcibios_size_bridge()\n");
-		pcibios_size_bridge(lba_bus, NULL);
-
 		/* assign resources to un-initialized devices */
 		DBG_PAT("LBA pcibios_assign_unassigned_resources()\n");
 		pcibios_assign_unassigned_resources(lba_bus);
Index: arch/parisc/kernel/pci.c
===================================================================
RCS file: /home/cvs/parisc/linux/arch/parisc/kernel/pci.c,v
retrieving revision 1.19
diff -u -p -r1.19 pci.c
--- pci.c	2001/03/02 10:31:49	1.19
+++ pci.c	2001/03/11 05:56:22
@@ -125,11 +125,6 @@ void pcibios_fixup_bus(struct pci_bus *b
 {
 	ASSERT(pci_bios != NULL);
 
-        /* If this is a PCI-PCI bridge, get the current bases */
-	if (bus->self && !is_pdc_pat()) {
-		pci_read_bridge_bases(bus);
-	}
-
 	if (pci_bios->fixup_bus) {
 		(*pci_bios->fixup_bus)(bus);
 	} else {
@@ -200,19 +195,11 @@ void __devinit pcibios_update_irq(struct
 ** ------------------------------------
 ** PAT PDC systems need this routine. PA legacy PDC does not.
 **
-** Used by alpha/arm: 
-** alpha/kernel/pci.c:common_init_pci()
-** (or arm/kernel/pci.c:pcibios_init())
-**    drivers/pci/setup.c:pci_assign_unassigned_resources()
-**        drivers/pci/setup.c:pdev_assign_unassigned_resources()
-**            arch/<foo>/kernel/pci.c:pcibios_update_resource()
-**
-** When BAR's are configured by linux, this routine
-** will update configuration space with the "normalized"
-** address. "root" indicates where the range starts and res
-** is some portion of that range.
+** When BAR's are configured by linux, this routine will update
+** configuration space with the "normalized" address. "root" indicates
+** where the range starts and res is some portion of that range.
 **
-** For all PA-RISC systems except V-class, root->start would be zero.
+** VCLASS: For all PA-RISC systems except V-class, root->start would be zero.
 **
 ** 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.
@@ -301,6 +288,30 @@ pcibios_set_master(struct pci_dev *dev)
 
 
 /*
+** 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(
@@ -308,6 +319,7 @@ void pcibios_fixup_pbus_ranges(
 	struct pbus_set_ranges_data *ranges
 	)
 {
+
 	/*
 	** I/O space may see busnumbers here. Something
 	** in the form of 0xbbxxxx where bb is the bus num
@@ -318,9 +330,23 @@ void pcibios_fixup_pbus_ranges(
 	ranges->io_start = PCI_PORT_ADDR(ranges->io_start);
 	ranges->io_end   = PCI_PORT_ADDR(ranges->io_end);
 
+#ifdef __LP64__
+	/* Convert MMIO addr to PCI addr (undo global virtualization) */
+	ranges->mem_start &= 0xffffffffUL;
+	ranges->mem_end   &= 0xffffffffUL;
+#endif
+
 	DBG_RES("pcibios_fixup_pbus_ranges(%02x, [%lx,%lx %lx,%lx])\n", bus->number,
 		ranges->io_start, ranges->io_end,
 		ranges->mem_start, ranges->mem_end);
+
+	/* KLUGE ALERT
+	** if this resource isn't linked to a "parent", then it seems
+	** to be a child of the HBA - lets link it in.
+	*/
+	pcibios_link_hba_resources(&((struct pci_hba_data *)bus->sysdata)->io_space, bus->resource[0]);
+
+	pcibios_link_hba_resources(&((struct pci_hba_data *)bus->sysdata)->mem_space, bus->resource[1]);
 }
 
 #define MAX(val1, val2)   ((val1) > (val2) ? (val1) : (val2))
@@ -359,103 +385,11 @@ pcibios_align_resource(void *data, struc
 	/*
 	** WARNING : caller is expected to update "end" field.
 	** We can't since it might really represent the *size*.
-	** The difference is "end = start + size" vs "end += size".
+	** The difference is "end = start + size" vs "end += start".
 	*/
 }
 
 
-#define ROUND_UP(x, a)		(((x) + (a) - 1) & ~((a) - 1))
-
-void __devinit
-pcibios_size_bridge(struct pci_bus *bus, struct pbus_set_ranges_data *outer)
-{
-	struct pbus_set_ranges_data inner;
-	struct pci_dev *dev;
-	struct pci_dev *bridge = bus->self;
-	struct list_head *ln;
-
-	/* set reasonable default "window" for pcibios_align_resource */
-	inner.io_start  = inner.io_end  = 0;
-	inner.mem_start = inner.mem_end = 0;
-
-	/* Collect information about how our direct children are layed out. */
-	for (ln=bus->devices.next; ln != &bus->devices; ln=ln->next) {
-		int i;
-		dev = pci_dev_b(ln);
-
-		/* Skip bridges here - we'll catch them below */
-		if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI)
-			continue;
-
-		for (i = 0; i < PCI_NUM_RESOURCES; i++) {
-			struct resource res;
-			unsigned long size;
-
-			if (dev->resource[i].flags == 0)
-				continue;
-
-			memcpy(&res, &dev->resource[i], sizeof(res));
-			size = res.end - res.start + 1;
-
-			if (res.flags & IORESOURCE_IO) {
-				res.start = inner.io_end;
-				pcibios_align_resource(dev, &res, size);
-				inner.io_end += res.start + size;
-			} else if (res.flags & IORESOURCE_MEM) {
-				res.start = inner.mem_end;
-				pcibios_align_resource(dev, &res, size);
-				inner.mem_end = res.start + size;
-			}
-
-		DBG_RES("    %s  inner size %lx/%x IO %lx MEM %lx\n",
-			dev->slot_name,
-			size, res.flags, inner.io_end, inner.mem_end);
-		}
-	}
-
-	/* And for all of the subordinate busses. */
-	for (ln=bus->children.next; ln != &bus->children; ln=ln->next)
-		pcibios_size_bridge(pci_bus_b(ln), &inner);
-
-	/* turn the ending locations into sizes (subtract start) */
-	inner.io_end -= inner.io_start - 1;
-	inner.mem_end -= inner.mem_start - 1;
-
-	/* Align the sizes up by PPB rules (4KB for IO, 1MB for MEM) */
-	inner.io_end = ROUND_UP(inner.io_end, 4*1024) - 1;
-	inner.mem_end = ROUND_UP(inner.mem_end, 1*1024*1024) - 1;
-
-	/* PPB - PCI bridge Device will normaller also have "outer" != NULL. */
-	if (bridge) {
-		/* Adjust the bus' allocation requirements */
-		/* PPB's pci device Bridge resources */
-
-		bus->resource[0] = &bridge->resource[PCI_BRIDGE_RESOURCES];
-		bus->resource[1] = &bridge->resource[PCI_BRIDGE_RESOURCES + 1];
-		
-		bus->resource[0]->start = bus->resource[1]->start  = 0;
-		bus->resource[0]->parent= bus->resource[1]->parent = NULL;
-
-		bus->resource[0]->end    = inner.io_end;
-		bus->resource[0]->flags  = IORESOURCE_IO;
-
-		bus->resource[1]->end    = inner.mem_end;
-		bus->resource[1]->flags  = IORESOURCE_MEM;
-	}
-
-	/* adjust parent's resource requirements */
-	if (outer) {
-		outer->io_end = ROUND_UP(outer->io_end, 4*1024);
-		outer->io_end += inner.io_end;
-
-		outer->mem_end = ROUND_UP(outer->mem_end, 1*1024*1024);
-		outer->mem_end += inner.mem_end;
-	}
-}
-
-#undef ROUND_UP
-
-
 int __devinit
 pcibios_enable_device(struct pci_dev *dev)
 {
@@ -501,6 +435,9 @@ pcibios_enable_device(struct pci_dev *de
 
 
 #ifdef __LP64__
+/*
+** Mostly copied from drivers/pci/setup-bus.c:pci_assign_unassigned_resources()
+*/
 void __devinit
 pcibios_assign_unassigned_resources(struct pci_bus *bus)
 {
@@ -510,9 +447,9 @@ pcibios_assign_unassigned_resources(stru
 	struct pbus_set_ranges_data ranges;
 
 	ranges.io_end = ranges.io_start
-				= bus->resource[0]->start;
+				= bus->resource[0]->start + PCIBIOS_MIN_IO;
 	ranges.mem_end = ranges.mem_start
-				= bus->resource[1]->start;
+				= bus->resource[1]->start + PCIBIOS_MIN_MEM;
 	ranges.found_vga = 0;
 	pbus_assign_resources(bus, &ranges);
 }
Index: drivers/gsc/dino.c
===================================================================
RCS file: /home/cvs/parisc/linux/drivers/gsc/dino.c,v
retrieving revision 1.25
diff -u -p -r1.25 dino.c
--- dino.c	2001/03/01 05:22:46	1.25
+++ dino.c	2001/03/11 05:56:22
@@ -665,6 +665,10 @@ dino_fixup_bus(struct pci_bus *bus)
 	DBG(KERN_WARNING __FUNCTION__ "(0x%p) bus %d sysdata 0x%p\n",
 				bus, bus->secondary, bus->sysdata);
 
+	/* If this is a PCI-PCI Bridge, read the window registers etc */
+	if (bus->self)
+		pci_read_bridge_bases(bus);
+
 	list_for_each(ln, &bus->devices) {
 	        int i;
 
Index: drivers/pci/Makefile
===================================================================
RCS file: /home/cvs/parisc/linux/drivers/pci/Makefile,v
retrieving revision 1.6
diff -u -p -r1.6 Makefile
--- Makefile	2001/02/02 15:35:25	1.6
+++ Makefile	2001/03/11 05:56:22
@@ -21,7 +21,7 @@ obj-$(CONFIG_PROC_FS) += proc.o
 #
 obj-$(CONFIG_ALPHA) += setup-bus.o setup-irq.o
 obj-$(CONFIG_ARM) += setup-bus.o setup-irq.o
-obj-$(CONFIG_PARISC64) += setup-bus.o
+obj-$(CONFIG_PARISC) += setup-bus.o
 
 ifndef CONFIG_X86
 obj-y += syscall.o
Index: drivers/pci/pci.c
===================================================================
RCS file: /home/cvs/parisc/linux/drivers/pci/pci.c,v
retrieving revision 1.11
diff -u -p -r1.11 pci.c
--- pci.c	2001/02/22 01:11:47	1.11
+++ pci.c	2001/03/11 05:56:22
@@ -645,16 +645,15 @@ void __init pci_read_bridge_bases(struct
 		res->end = limit + 0xfff;
 		res->name = child->name;
 	} else {
-		
 		/*
-		 * Either this is not a PCI-PCI bridge or it's not
-		 * configured yet. Since this code only supports PCI-PCI
-		 * bridge, we better not be called for any other type.
-		 * Don't muck the resources since it will confuse the
-		 * platform specific code which does that.
-		 */
-		printk("PCI : ignoring %s PCI-PCI bridge (I/O BASE not configured)\n", child->self->slot_name);
-		return;
+		** resource has been either disabled (base > limit) or not
+		** configured.  Any devices downstream are SOL.
+		** Seen on Intel 82443BX (device #1) host-AGP bridge which
+		** attempts to "emulate" a PCI-PCI bridge.
+		*/
+		memset(res, 0, sizeof(*res));
+		DBG("PCI : %s bridge IO BASE/LIMIT disabled? (0x%x, 0x%x)\n",
+			child->self->slot_name, base, limit);
 	}
 
 	res = child->resource[1];
@@ -668,9 +667,10 @@ void __init pci_read_bridge_bases(struct
 		res->end = limit + 0xfffff;
 		res->name = child->name;
 	} else {
-		/* See comment above. Same thing */
-		printk("PCI : ignoring %s PCI-PCI bridge (MMIO base not configured)\n", child->self->slot_name);
-		return;
+		/* See comment about 82443BX. */
+		memset(res, 0, sizeof(*res));
+		DBG("PCI : %s bridge MEM BASE/LIMIT disabled? (0x%x, 0x%x)\n",
+			child->self->slot_name, base, limit);
 	}
 
 	res = child->resource[2];
@@ -695,7 +695,13 @@ void __init pci_read_bridge_bases(struct
 		res->end = limit + 0xfffff;
 		res->name = child->name;
 	} else {
-		/* Base > limit means the prefetchable mem is disabled.*/
+		/* See comment about 82443BX.
+		** parisc arch doesn't support cachable memory in I/O space
+		** This will always be disabled for parisc.
+		*/
+		memset(res, 0, sizeof(*res));
+		DBG("PCI : %s bridge PREF_MEM BASE/LIMIT disabled? (0x%x, 0x%x)\n",
+			child->self->slot_name, base, limit);
 	}
 }
 
Index: drivers/pci/setup-bus.c
===================================================================
RCS file: /home/cvs/parisc/linux/drivers/pci/setup-bus.c,v
retrieving revision 1.5
diff -u -p -r1.5 setup-bus.c
--- setup-bus.c	2001/02/22 01:11:47	1.5
+++ setup-bus.c	2001/03/11 05:56:22
@@ -12,6 +12,8 @@
 /*
  * Nov 2000, Ivan Kokshaysky <ink@jurassic.park.msu.ru>
  *	     PCI-PCI bridges cleanup, sorted resource allocation
+ * Feb 2001, Grant Grundler <grundler@puffin.external.hp.com>
+ *           add __hppa__ klu^H^H^Hsupport.
  */
 
 #include <linux/init.h>
@@ -243,9 +245,14 @@ pbus_assign_resources(struct pci_bus *bu
 	for (ln=bus->children.next; ln != &bus->children; ln=ln->next) {
 		struct pci_bus *b = pci_bus_b(ln);
 
-		ranges->io_start = ranges->io_end;
-		ranges->mem_start = ranges->mem_end;
+		b->resource[0]->start = ranges->io_start = ranges->io_end;
+		b->resource[1]->start = ranges->mem_start = ranges->mem_end;
+
 		pbus_assign_resources(b, ranges);
+
+		b->resource[0]->end = ranges->io_end - 1;
+		b->resource[1]->end = ranges->mem_end - 1;
+
 		pci_setup_bridge(b);
 	}
 }
Index: drivers/pci/setup-res.c
===================================================================
RCS file: /home/cvs/parisc/linux/drivers/pci/setup-res.c,v
retrieving revision 1.7
diff -u -p -r1.7 setup-res.c
--- setup-res.c	2001/02/22 01:11:47	1.7
+++ setup-res.c	2001/03/11 05:56:22
@@ -14,8 +14,6 @@
 /*
  * Nov 2000, Ivan Kokshaysky <ink@jurassic.park.msu.ru>
  *	     Resource sorting
- * Feb 2001, Grant Grundler <gurndler@puffin.external.hp.com>
- *           Fix PCI-PCI bridge support and add __hppa__ support
  */
 
 #include <linux/init.h>
@@ -140,13 +138,11 @@ pdev_sort_resources(struct pci_dev *dev,
 		struct resource_list *list, *tmp;
 		unsigned long r_size;
 
-#ifndef __hppa__
 		/* PCI-PCI bridges may have I/O ports or
 		   memory on the primary bus */
 		if (dev->class >> 8 == PCI_CLASS_BRIDGE_PCI &&
 						i >= PCI_BRIDGE_RESOURCES)
 			continue;
-#endif
 
 		r = &dev->resource[i];
 		r_size = r->end - r->start;