[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;