patch-2.3.16 linux/arch/alpha/kernel/core_mcpcia.c

Next file: linux/arch/alpha/kernel/core_polaris.c
Previous file: linux/arch/alpha/kernel/core_lca.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.15/linux/arch/alpha/kernel/core_mcpcia.c linux/arch/alpha/kernel/core_mcpcia.c
@@ -1,11 +1,11 @@
 /*
  *	linux/arch/alpha/kernel/core_mcpcia.c
  *
- * Code common to all MCbus-PCI Adaptor core logic chipsets
- *
  * Based on code written by David A Rusling (david.rusling@reo.mts.dec.com).
  *
+ * Code common to all MCbus-PCI Adaptor core logic chipsets
  */
+
 #include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
@@ -25,7 +25,7 @@
 #undef __EXTERN_INLINE
 
 #include "proto.h"
-#include "bios32.h"
+#include "pci_impl.h"
 
 /*
  * NOTE: Herein lie back-to-back mb instructions.  They are magic. 
@@ -47,6 +47,11 @@
 
 #define MCPCIA_MAX_HOSES 2
 
+/* Dodge has PCI0 and PCI1 at MID 4 and 5 respectively.  Durango adds
+   PCI2 and PCI3 at MID 6 and 7 respectively.  */
+
+#define hose2mid(h)	((h) + 4)
+
 
 /*
  * Given a bus, device, and function number, compute resulting
@@ -92,10 +97,10 @@
 
 static unsigned int
 conf_read(unsigned long addr, unsigned char type1,
-	  struct linux_hose_info *hose)
+	  struct pci_controler *hose)
 {
 	unsigned long flags;
-	unsigned long hoseno = hose->pci_hose_index;
+	unsigned long mid = hose2mid(hose->index);
 	unsigned int stat0, value, temp, cpu;
 
 	cpu = smp_processor_id();
@@ -103,19 +108,20 @@
 	__save_and_cli(flags);
 
 	DBG_CFG(("conf_read(addr=0x%lx, type1=%d, hose=%d)\n",
-		 addr, type1, hoseno));
+		 addr, type1, mid));
 
 	/* Reset status register to avoid losing errors.  */
-	stat0 = *(vuip)MCPCIA_CAP_ERR(hoseno);
-	*(vuip)MCPCIA_CAP_ERR(hoseno) = stat0; mb();
-	temp = *(vuip)MCPCIA_CAP_ERR(hoseno);
-	DBG_CFG(("conf_read: MCPCIA CAP_ERR(%d) was 0x%x\n", hoseno, stat0));
+	stat0 = *(vuip)MCPCIA_CAP_ERR(mid);
+	*(vuip)MCPCIA_CAP_ERR(mid) = stat0;
+	mb();
+	temp = *(vuip)MCPCIA_CAP_ERR(mid);
+	DBG_CFG(("conf_read: MCPCIA_CAP_ERR(%d) was 0x%x\n", mid, stat0));
 
 	mb();
 	draina();
 	mcheck_expected(cpu) = 1;
 	mcheck_taken(cpu) = 0;
-	mcheck_hose(cpu) = hoseno;
+	mcheck_extra(cpu) = mid;
 	mb();
 
 	/* Access configuration space.  */
@@ -139,10 +145,10 @@
 
 static void
 conf_write(unsigned long addr, unsigned int value, unsigned char type1,
-	   struct linux_hose_info *hose)
+	   struct pci_controler *hose)
 {
 	unsigned long flags;
-	unsigned long hoseno = hose->pci_hose_index;
+	unsigned long mid = hose2mid(hose->index);
 	unsigned int stat0, temp, cpu;
 
 	cpu = smp_processor_id();
@@ -150,21 +156,21 @@
 	__save_and_cli(flags);	/* avoid getting hit by machine check */
 
 	/* Reset status register to avoid losing errors.  */
-	stat0 = *(vuip)MCPCIA_CAP_ERR(hoseno);
-	*(vuip)MCPCIA_CAP_ERR(hoseno) = stat0; mb();
-	temp = *(vuip)MCPCIA_CAP_ERR(hoseno);
-	DBG_CFG(("conf_write: MCPCIA CAP_ERR(%d) was 0x%x\n", hoseno, stat0));
+	stat0 = *(vuip)MCPCIA_CAP_ERR(mid);
+	*(vuip)MCPCIA_CAP_ERR(mid) = stat0; mb();
+	temp = *(vuip)MCPCIA_CAP_ERR(mid);
+	DBG_CFG(("conf_write: MCPCIA CAP_ERR(%d) was 0x%x\n", mid, stat0));
 
 	draina();
 	mcheck_expected(cpu) = 1;
-	mcheck_hose(cpu) = hoseno;
+	mcheck_extra(cpu) = mid;
 	mb();
 
 	/* Access configuration space.  */
 	*((vuip)addr) = value;
 	mb();
 	mb();  /* magic */
-	temp = *(vuip)MCPCIA_CAP_ERR(hoseno); /* read to force the write */
+	temp = *(vuip)MCPCIA_CAP_ERR(mid); /* read to force the write */
 	mcheck_expected(cpu) = 0;
 	mb();
 
@@ -173,71 +179,71 @@
 }
 
 static int
-mk_conf_addr(struct linux_hose_info *hose,
-	     u8 bus, u8 device_fn, u8 where,
+mk_conf_addr(struct pci_dev *dev, int where, struct pci_controler *hose,
 	     unsigned long *pci_addr, unsigned char *type1)
 {
+	u8 bus = dev->bus->number;
+	u8 devfn = dev->devfn;
 	unsigned long addr;
 
-	if (!pci_probe_enabled)
-		return -1;
-
-	DBG_CFG(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x,"
+	DBG_CFG(("mk_conf_addr(bus=%d,devfn=0x%x,hose=%d,where=0x%x,"
 		 " pci_addr=0x%p, type1=0x%p)\n",
-		 bus, device_fn, where, pci_addr, type1));
+		 bus, devfn, hose->index, where, pci_addr, type1));
 
 	/* Type 1 configuration cycle for *ALL* busses.  */
 	*type1 = 1;
 
-	if (hose->pci_first_busno == bus)
+	if (dev->bus->number == hose->first_busno)
 		bus = 0;
-	addr = (bus << 16) | (device_fn << 8) | (where);
+	addr = (bus << 16) | (devfn << 8) | (where);
 	addr <<= 5; /* swizzle for SPARSE */
-	addr |= hose->pci_config_space;
+	addr |= hose->config_space;
 
 	*pci_addr = addr;
 	DBG_CFG(("mk_conf_addr: returning pci_addr 0x%lx\n", addr));
 	return 0;
 }
 
-int
-mcpcia_hose_read_config_byte (u8 bus, u8 device_fn, u8 where, u8 *value,
-			      struct linux_hose_info *hose)
+static int
+mcpcia_read_config_byte(struct pci_dev *dev, int where, u8 *value)
 {
-	unsigned long addr;
+	struct pci_controler *hose = dev->sysdata ? : probing_hose;
+	unsigned long addr, w;
 	unsigned char type1;
 
-	if (mk_conf_addr(hose, bus, device_fn, where, &addr, &type1))
+	if (mk_conf_addr(dev, where, hose, &addr, &type1))
 		return PCIBIOS_DEVICE_NOT_FOUND;
 
 	addr |= 0x00;
-	*value = conf_read(addr, type1, hose) >> ((where & 3) * 8);
+	w = conf_read(addr, type1, hose);
+	*value = __kernel_extbl(w, where & 3);
 	return PCIBIOS_SUCCESSFUL;
 }
 
-int
-mcpcia_hose_read_config_word (u8 bus, u8 device_fn, u8 where, u16 *value,
-			      struct linux_hose_info *hose)
+static int
+mcpcia_read_config_word(struct pci_dev *dev, int where, u16 *value)
 {
-	unsigned long addr;
+	struct pci_controler *hose = dev->sysdata ? : probing_hose;
+	unsigned long addr, w;
 	unsigned char type1;
 
-	if (mk_conf_addr(hose, bus, device_fn, where, &addr, &type1))
+	if (mk_conf_addr(dev, where, hose, &addr, &type1))
 		return PCIBIOS_DEVICE_NOT_FOUND;
 
 	addr |= 0x08;
-	*value = conf_read(addr, type1, hose) >> ((where & 3) * 8);
+	w = conf_read(addr, type1, hose);
+	*value = __kernel_extwl(w, where & 3);
 	return PCIBIOS_SUCCESSFUL;
 }
 
-int
-mcpcia_hose_read_config_dword (u8 bus, u8 device_fn, u8 where, u32 *value,
-			       struct linux_hose_info *hose)
+static int
+mcpcia_read_config_dword(struct pci_dev *dev, int where, u32 *value)
 {
+	struct pci_controler *hose = dev->sysdata ? : probing_hose;
 	unsigned long addr;
 	unsigned char type1;
 
-	if (mk_conf_addr(hose, bus, device_fn, where, &addr, &type1))
+	if (mk_conf_addr(dev, where, hose, &addr, &type1))
 		return PCIBIOS_DEVICE_NOT_FOUND;
 
 	addr |= 0x18;
@@ -245,311 +251,213 @@
 	return PCIBIOS_SUCCESSFUL;
 }
 
-int
-mcpcia_hose_write_config_byte (u8 bus, u8 device_fn, u8 where, u8 value,
-			       struct linux_hose_info *hose)
+static int
+mcpcia_write_config(struct pci_dev *dev, int where, u32 value, long mask)
 {
+	struct pci_controler *hose = dev->sysdata ? : probing_hose;
 	unsigned long addr;
 	unsigned char type1;
 
-	if (mk_conf_addr(hose, bus, device_fn, where, &addr, &type1))
+	if (mk_conf_addr(dev, where, hose, &addr, &type1))
 		return PCIBIOS_DEVICE_NOT_FOUND;
 
-	addr |= 0x00;
-	conf_write(addr, value << ((where & 3) * 8), type1, hose);
+	addr |= mask;
+	value = __kernel_insql(value, where & 3);
+	conf_write(addr, value, type1, hose);
 	return PCIBIOS_SUCCESSFUL;
 }
 
-int
-mcpcia_hose_write_config_word (u8 bus, u8 device_fn, u8 where, u16 value,
-			       struct linux_hose_info *hose)
+static int
+mcpcia_write_config_byte(struct pci_dev *dev, int where, u8 value)
 {
-	unsigned long addr;
-	unsigned char type1;
-
-	if (mk_conf_addr(hose, bus, device_fn, where, &addr, &type1))
-		return PCIBIOS_DEVICE_NOT_FOUND;
-
-	addr |= 0x08;
-	conf_write(addr, value << ((where & 3) * 8), type1, hose);
-	return PCIBIOS_SUCCESSFUL;
+	return mcpcia_write_config(dev, where, value, 0x00);
 }
 
-int
-mcpcia_hose_write_config_dword (u8 bus, u8 device_fn, u8 where, u32 value,
-				struct linux_hose_info *hose)
+static int
+mcpcia_write_config_word(struct pci_dev *dev, int where, u16 value)
 {
-	unsigned long addr;
-	unsigned char type1;
-
-	if (mk_conf_addr(hose, bus, device_fn, where, &addr, &type1))
-		return PCIBIOS_DEVICE_NOT_FOUND;
+	return mcpcia_write_config(dev, where, value, 0x08);
+}
 
-	addr |= 0x18;
-	conf_write(addr, value << ((where & 3) * 8), type1, hose);
-	return PCIBIOS_SUCCESSFUL;
+static int
+mcpcia_write_config_dword(struct pci_dev *dev, int where, u32 value)
+{
+	return mcpcia_write_config(dev, where, value, 0x18);
 }
 
-void __init
-mcpcia_init_arch(unsigned long *mem_start, unsigned long *mem_end)
+struct pci_ops mcpcia_pci_ops = 
 {
-	extern asmlinkage void entInt(void);
-	struct linux_hose_info *hose;
-	unsigned int mcpcia_err;
+	read_byte:	mcpcia_read_config_byte,
+	read_word:	mcpcia_read_config_word,
+	read_dword:	mcpcia_read_config_dword,
+	write_byte:	mcpcia_write_config_byte,
+	write_word:	mcpcia_write_config_word,
+	write_dword:	mcpcia_write_config_dword
+};
+
+static int __init
+mcpcia_probe_hose(int h)
+{
+	int cpu = smp_processor_id();
+	int mid = hose2mid(h);
 	unsigned int pci_rev;
-	int h, cpu;
 
-	/* Ho hum.. init_arch is called before init_IRQ, but we need to be
-	   able to handle machine checks.  So install the handler now.  */
-	wrent(entInt, 0);
-
-	/* Align memory to cache line; we'll be allocating from it.  */
-	*mem_start = (*mem_start | 31) + 1;
+	/* Gotta be REAL careful.  If hose is absent, we get an mcheck.  */
 
-	cpu = smp_processor_id();
-
-	/* First, find how many hoses we have.  */
-	for (h = 0; h < MCPCIA_MAX_HOSES; h++) {
+	mb();
+	mb();
+	draina();
+	mcheck_expected(cpu) = 1;
+	mcheck_taken(cpu) = 0;
+	mcheck_extra(cpu) = mid;
+	mb();
 
-		/* Gotta be REAL careful.  If hose is absent, we get a
-		   machine check.  */
+	/* Access the bus revision word. */
+	pci_rev = *(vuip)MCPCIA_REV(mid);
 
-		mb();
-		mb();
-		draina();
-		mcheck_expected(cpu) = 1;
+	mb();
+	mb();  /* magic */
+	if (mcheck_taken(cpu)) {
 		mcheck_taken(cpu) = 0;
+		pci_rev = 0xffffffff;
 		mb();
+	}
+	mcheck_expected(cpu) = 0;
+	mb();
 
-		/* Access the bus revision word. */
-		pci_rev = *(vuip)MCPCIA_REV(h);
+	return (pci_rev >> 16) == PCI_CLASS_BRIDGE_HOST;
+}
 
-		mb();
-		mb();  /* magic */
-		if (mcheck_taken(cpu)) {
-			mcheck_taken(cpu) = 0;
-			pci_rev = 0xffffffff;
-			mb();
-		}
-		mcheck_expected(cpu) = 0;
-		mb();
+static void __init
+mcpcia_new_hose(unsigned long *mem_start, int h)
+{
+	struct pci_controler *hose;
+	struct resource *io, *mem, *hae_mem;
+	int mid = hose2mid(h);
 
-#if 0
-		printk("mcpcia_init_arch: got 0x%x for PCI_REV for hose %d\n",
-		       pci_rev, h);
-#endif
-		if ((pci_rev >> 16) == PCI_CLASS_BRIDGE_HOST) {
-			hose_count++;
+	hose = alloc_pci_controler(mem_start);
+	io = alloc_resource(mem_start);
+	mem = alloc_resource(mem_start);
+	hae_mem = alloc_resource(mem_start);
+			
+	hose->io_space = io;
+	hose->mem_space = hae_mem;
+	hose->config_space = MCPCIA_CONF(mid);
+	hose->index = h;
 
-			hose = (struct linux_hose_info *)*mem_start;
-			*mem_start = (unsigned long)(hose + 1);
+	io->start = MCPCIA_IO(mid) - MCPCIA_IO_BIAS;
+	io->end = io->start + 0xffff;
+	io->name = pci_io_names[h];
 
-			memset(hose, 0, sizeof(*hose));
+	mem->start = MCPCIA_DENSE(mid) - MCPCIA_MEM_BIAS;
+	mem->end = mem->start + 0xffffffff;
+	mem->name = pci_mem_names[h];
 
-			*hose_tail = hose;
-			hose_tail = &hose->next;
+	hae_mem->start = mem->start;
+	hae_mem->end = mem->start + MCPCIA_MEM_MASK;
+	hae_mem->name = pci_hae0_name;
 
-			hose->pci_io_space = MCPCIA_IO(h);
-			hose->pci_mem_space = MCPCIA_DENSE(h);
-			hose->pci_config_space = MCPCIA_CONF(h);
-			hose->pci_sparse_space = MCPCIA_SPARSE(h);
-			hose->pci_hose_index = h;
-			hose->pci_first_busno = 255;
-			hose->pci_last_busno = 0;
-		}
-	}
+	request_resource(&ioport_resource, io);
+	request_resource(&iomem_resource, mem);
+	request_resource(mem, hae_mem);
+}
 
-#if 1
-	printk("mcpcia_init_arch: found %d hoses\n", hose_count);
-#endif
+static void __init
+mcpcia_startup_hose(struct pci_controler *hose)
+{
+	int mid = hose2mid(hose->index);
+	unsigned int tmp;
 
-	/* Now do init for each hose.  */
-	for (hose = hose_head; hose; hose = hose->next) {
-		h = hose->pci_hose_index;
+	/* 
+	 * Set up error reporting. Make sure CPU_PE is OFF in the mask.
+	 */
 #if 0
-		printk("mcpcia_init_arch: -------- hose %d --------\n",h);
-		printk("MCPCIA_REV 0x%x\n", *(vuip)MCPCIA_REV(h));
-		printk("MCPCIA_WHOAMI 0x%x\n", *(vuip)MCPCIA_WHOAMI(h));
-		printk("MCPCIA_HAE_MEM 0x%x\n", *(vuip)MCPCIA_HAE_MEM(h));
-		printk("MCPCIA_HAE_IO 0x%x\n", *(vuip)MCPCIA_HAE_IO(h));
-		printk("MCPCIA_HAE_DENSE 0x%x\n", *(vuip)MCPCIA_HAE_DENSE(h));
-		printk("MCPCIA_INT_CTL 0x%x\n", *(vuip)MCPCIA_INT_CTL(h));
-		printk("MCPCIA_INT_REQ 0x%x\n", *(vuip)MCPCIA_INT_REQ(h));
-		printk("MCPCIA_INT_TARG 0x%x\n", *(vuip)MCPCIA_INT_TARG(h));
-		printk("MCPCIA_INT_ADR 0x%x\n", *(vuip)MCPCIA_INT_ADR(h));
-		printk("MCPCIA_INT_ADR_EXT 0x%x\n", *(vuip)MCPCIA_INT_ADR_EXT(h));
-		printk("MCPCIA_INT_MASK0 0x%x\n", *(vuip)MCPCIA_INT_MASK0(h));
-		printk("MCPCIA_INT_MASK1 0x%x\n", *(vuip)MCPCIA_INT_MASK1(h));
-		printk("MCPCIA_HBASE 0x%x\n", *(vuip)MCPCIA_HBASE(h));
+	tmp = *(vuip)MCPCIA_ERR_MASK(mid);
+	tmp &= ~4;
+	*(vuip)MCPCIA_ERR_MASK(mid) = tmp;
+	mb();
+	tmp = *(vuip)MCPCIA_ERR_MASK(mid);
 #endif
 
-		/* 
-		 * Set up error reporting. Make sure CPU_PE is OFF in the mask.
-		 */
-#if 0
-		mcpcia_err = *(vuip)MCPCIA_ERR_MASK(h);
-		mcpcia_err &= ~4;   
-		*(vuip)MCPCIA_ERR_MASK(h) = mcpcia_err;
-		mb();
-		mcpcia_err = *(vuip)MCPCIA_ERR_MASK;
-#endif
+	tmp = *(vuip)MCPCIA_CAP_ERR(mid);
+	tmp |= 0x0006;   /* master/target abort */
+	*(vuip)MCPCIA_CAP_ERR(mid) = tmp;
+	mb();
+	tmp = *(vuip)MCPCIA_CAP_ERR(mid);
 
-		mcpcia_err = *(vuip)MCPCIA_CAP_ERR(h);
-		mcpcia_err |= 0x0006;   /* master/target abort */
-		*(vuip)MCPCIA_CAP_ERR(h) = mcpcia_err;
-		mb() ;
-		mcpcia_err = *(vuip)MCPCIA_CAP_ERR(h);
-
-		switch (alpha_use_srm_setup)
-		{
-		default:
-#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_SRM_SETUP)
-			/* Check window 0 for enabled and mapped to 0. */
-			if (((*(vuip)MCPCIA_W0_BASE(h) & 3) == 1)
-			    && (*(vuip)MCPCIA_T0_BASE(h) == 0)
-			    && ((*(vuip)MCPCIA_W0_MASK(h) & 0xfff00000U) > 0x0ff00000U)) {
-				MCPCIA_DMA_WIN_BASE = *(vuip)MCPCIA_W0_BASE(h) & 0xfff00000U;
-				MCPCIA_DMA_WIN_SIZE = *(vuip)MCPCIA_W0_MASK(h) & 0xfff00000U;
-				MCPCIA_DMA_WIN_SIZE += 0x00100000U;
-#if 1
-				printk("mcpcia_init_arch: using Window 0 settings\n");
-				printk("mcpcia_init_arch: BASE 0x%x MASK 0x%x TRANS 0x%x\n",
-				       *(vuip)MCPCIA_W0_BASE(h),
-				       *(vuip)MCPCIA_W0_MASK(h),
-				       *(vuip)MCPCIA_T0_BASE(h));
-#endif
-				break;
-			}
+	/*
+	 * Set up the PCI->physical memory translation windows.
+	 * For now, windows 1,2 and 3 are disabled.  In the
+	 * future, we may want to use them to do scatter/
+	 * gather DMA.
+	 *
+	 * Window 0 goes at 2 GB and is 2 GB large.
+	 */
+
+	*(vuip)MCPCIA_W0_BASE(mid) = 1U | (MCPCIA_DMA_WIN_BASE & 0xfff00000U);
+	*(vuip)MCPCIA_W0_MASK(mid) = (MCPCIA_DMA_WIN_SIZE - 1) & 0xfff00000U;
+	*(vuip)MCPCIA_T0_BASE(mid) = 0;
+
+	*(vuip)MCPCIA_W1_BASE(mid) = 0x0;
+	*(vuip)MCPCIA_W2_BASE(mid) = 0x0;
+	*(vuip)MCPCIA_W3_BASE(mid) = 0x0;
 
-			/* Check window 1 for enabled and mapped to 0.  */
-			if (((*(vuip)MCPCIA_W1_BASE(h) & 3) == 1)
-			    && (*(vuip)MCPCIA_T1_BASE(h) == 0)
-			    && ((*(vuip)MCPCIA_W1_MASK(h) & 0xfff00000U) > 0x0ff00000U)) {
-				MCPCIA_DMA_WIN_BASE = *(vuip)MCPCIA_W1_BASE(h) & 0xfff00000U;
-				MCPCIA_DMA_WIN_SIZE = *(vuip)MCPCIA_W1_MASK(h) & 0xfff00000U;
-				MCPCIA_DMA_WIN_SIZE += 0x00100000U;
-#if 1
-				printk("mcpcia_init_arch: using Window 1 settings\n");
-				printk("mcpcia_init_arch: BASE 0x%x MASK 0x%x TRANS 0x%x\n",
-				       *(vuip)MCPCIA_W1_BASE(h),
-				       *(vuip)MCPCIA_W1_MASK(h),
-				       *(vuip)MCPCIA_T1_BASE(h));
-#endif
-				break;
-			}
+	*(vuip)MCPCIA_HBASE(mid) = 0x0;
+	mb();
 
-			/* Check window 2 for enabled and mapped to 0.  */
-			if (((*(vuip)MCPCIA_W2_BASE(h) & 3) == 1)
-			    && (*(vuip)MCPCIA_T2_BASE(h) == 0)
-			    && ((*(vuip)MCPCIA_W2_MASK(h) & 0xfff00000U) > 0x0ff00000U)) {
-				MCPCIA_DMA_WIN_BASE = *(vuip)MCPCIA_W2_BASE(h) & 0xfff00000U;
-				MCPCIA_DMA_WIN_SIZE = *(vuip)MCPCIA_W2_MASK(h) & 0xfff00000U;
-				MCPCIA_DMA_WIN_SIZE += 0x00100000U;
-#if 1
-				printk("mcpcia_init_arch: using Window 2 settings\n");
-				printk("mcpcia_init_arch: BASE 0x%x MASK 0x%x TRANS 0x%x\n",
-				       *(vuip)MCPCIA_W2_BASE(h),
-				       *(vuip)MCPCIA_W2_MASK(h),
-				       *(vuip)MCPCIA_T2_BASE(h));
+#if 0
+	tmp = *(vuip)MCPCIA_INT_CTL(mid);
+	printk("mcpcia_init_arch: INT_CTL was 0x%x\n", tmp);
+	*(vuip)MCPCIA_INT_CTL(mid) = 1U;
+	mb();
+	tmp = *(vuip)MCPCIA_INT_CTL(mid);
 #endif
-				break;
-			}
 
-			/* Check window 3 for enabled and mapped to 0.  */
-			if (((*(vuip)MCPCIA_W3_BASE(h) & 3) == 1)
-			    && (*(vuip)MCPCIA_T3_BASE(h) == 0)
-			    && ((*(vuip)MCPCIA_W3_MASK(h) & 0xfff00000U) > 0x0ff00000U)) {
-				MCPCIA_DMA_WIN_BASE = *(vuip)MCPCIA_W3_BASE(h) & 0xfff00000U;
-				MCPCIA_DMA_WIN_SIZE = *(vuip)MCPCIA_W3_MASK(h) & 0xfff00000U;
-				MCPCIA_DMA_WIN_SIZE += 0x00100000U;
-#if 1
-				printk("mcpcia_init_arch: using Window 3 settings\n");
-				printk("mcpcia_init_arch: BASE 0x%x MASK 0x%x TRANS 0x%x\n",
-				       *(vuip)MCPCIA_W3_BASE(h),
-				       *(vuip)MCPCIA_W3_MASK(h),
-				       *(vuip)MCPCIA_T3_BASE(h));
-#endif
-				break;
-			}
+	*(vuip)MCPCIA_HAE_MEM(mid) = 0U;
+	mb();
+	*(vuip)MCPCIA_HAE_MEM(mid); /* read it back. */
+	*(vuip)MCPCIA_HAE_IO(mid) = 0;
+	mb();
+	*(vuip)MCPCIA_HAE_IO(mid);  /* read it back. */
+}
 
-			/* Otherwise, we must use our defaults.  */
-			MCPCIA_DMA_WIN_BASE = MCPCIA_DMA_WIN_BASE_DEFAULT;
-			MCPCIA_DMA_WIN_SIZE = MCPCIA_DMA_WIN_SIZE_DEFAULT;
-#endif
-		case 0:
-			/*
-			 * Set up the PCI->physical memory translation windows.
-			 * For now, windows 1,2 and 3 are disabled.  In the
-			 * future, we may want to use them to do scatter/
-			 * gather DMA.
-			 *
-			 * Window 0 goes at 2 GB and is 2 GB large.
-			 */
-
-			*(vuip)MCPCIA_W0_BASE(h) = 1U | (MCPCIA_DMA_WIN_BASE_DEFAULT & 0xfff00000U);
-			*(vuip)MCPCIA_W0_MASK(h) = (MCPCIA_DMA_WIN_SIZE_DEFAULT - 1) & 0xfff00000U;
-			*(vuip)MCPCIA_T0_BASE(h) = 0;
-
-			*(vuip)MCPCIA_W1_BASE(h) = 0x0 ;
-			*(vuip)MCPCIA_W2_BASE(h) = 0x0 ;
-			*(vuip)MCPCIA_W3_BASE(h) = 0x0 ;
+void __init
+mcpcia_init_arch(unsigned long *mem_start, unsigned long *mem_end)
+{
+	extern asmlinkage void entInt(void);
+	struct pci_controler *hose;
+	int h, hose_count = 0;
 
-			*(vuip)MCPCIA_HBASE(h) = 0x0 ;
-			mb();
-			break;
-		}
-#if 0
-		{
-			unsigned int mcpcia_int_ctl = *((vuip)MCPCIA_INT_CTL(h));
-			printk("mcpcia_init_arch: INT_CTL was 0x%x\n", mcpcia_int_ctl);
-			*(vuip)MCPCIA_INT_CTL(h) = 1U; mb();
-			mcpcia_int_ctl = *(vuip)MCPCIA_INT_CTL(h);
-		}
-#endif
+	/* Ho hum.. init_arch is called before init_IRQ, but we need to be
+	   able to handle machine checks.  So install the handler now.  */
+	wrent(entInt, 0);
+
+	/* With multiple PCI busses, we play with I/O as physical addrs.  */
+	ioport_resource.end = ~0UL;
+	iomem_resource.end = ~0UL;
 
-		/*
-		 * Sigh... For the SRM setup, unless we know apriori what the HAE
-		 * contents will be, we need to setup the arbitrary region bases
-		 * so we can test against the range of addresses and tailor the
-		 * region chosen for the SPARSE memory access.
-		 *
-		 * See include/asm-alpha/mcpcia.h for the SPARSE mem read/write.
-		 */
-		if (alpha_use_srm_setup) {
-			unsigned int mcpcia_hae_mem = *(vuip)MCPCIA_HAE_MEM(h);
-
-			alpha_mv.sm_base_r1 = (mcpcia_hae_mem      ) & 0xe0000000UL;
-			alpha_mv.sm_base_r2 = (mcpcia_hae_mem << 16) & 0xf8000000UL;
-			alpha_mv.sm_base_r3 = (mcpcia_hae_mem << 24) & 0xfc000000UL;
-
-			/*
-			 * Set the HAE cache, so that setup_arch() code
-			 * will use the SRM setting always. Our readb/writeb
-			 * code in mcpcia.h expects never to have to change
-			 * the contents of the HAE.
-			 */
-			alpha_mv.hae_cache = mcpcia_hae_mem;
-
-			alpha_mv.mv_readb = mcpcia_srm_readb;
-			alpha_mv.mv_readw = mcpcia_srm_readw;
-			alpha_mv.mv_writeb = mcpcia_srm_writeb;
-			alpha_mv.mv_writew = mcpcia_srm_writew;
-		} else {
-			*(vuip)MCPCIA_HAE_MEM(h) = 0U; mb();
-			*(vuip)MCPCIA_HAE_MEM(h); /* read it back. */
-			*(vuip)MCPCIA_HAE_IO(h) = 0; mb();
-			*(vuip)MCPCIA_HAE_IO(h);  /* read it back. */
+	/* First, find how many hoses we have.  */
+	for (h = 0; h < MCPCIA_MAX_HOSES; ++h) {
+		if (mcpcia_probe_hose(h)) {
+			mcpcia_new_hose(mem_start, h);
+			hose_count++;
 		}
 	}
+
+	printk("mcpcia_init_arch: found %d hoses\n", hose_count);
+
+	/* Now do init for each hose.  */
+	for (hose = hose_head; hose; hose = hose->next)
+		mcpcia_startup_hose(hose);
 }
 
 static void
-mcpcia_pci_clr_err(int hose)
+mcpcia_pci_clr_err(int mid)
 {
-	*(vuip)MCPCIA_CAP_ERR(hose);
-	*(vuip)MCPCIA_CAP_ERR(hose) = 0xffffffff;   /* Clear them all.  */
+	*(vuip)MCPCIA_CAP_ERR(mid);
+	*(vuip)MCPCIA_CAP_ERR(mid) = 0xffffffff;   /* Clear them all.  */
 	mb();
-	*(vuip)MCPCIA_CAP_ERR(hose);  /* Re-read for force write.  */
+	*(vuip)MCPCIA_CAP_ERR(mid);  /* Re-read for force write.  */
 }
 
 static void
@@ -639,19 +547,21 @@
 	mb();  /* magic */
 	draina();
 	if (mcheck_expected(cpu)) {
-		mcpcia_pci_clr_err(mcheck_hose(cpu));
+		mcpcia_pci_clr_err(mcheck_extra(cpu));
 	} else {
 		/* FIXME: how do we figure out which hose the error was on?  */	
-		mcpcia_pci_clr_err(0);
-		mcpcia_pci_clr_err(1);
+		struct pci_controler *hose;
+		for (hose = hose_head; hose; hose = hose->next)
+			mcpcia_pci_clr_err(hose2mid(hose->index));
 	}
 	wrmces(0x7);
 	mb();
 
-	process_mcheck_info(vector, la_ptr, regs, "MCPCIA",
-		            mcheck_expected(cpu));
-
-	if (vector != 0x620 && vector != 0x630) {
-		mcpcia_print_uncorrectable(mchk_logout);
+	if (mcheck_expected(cpu)) {
+		process_mcheck_info(vector, la_ptr, regs, "MCPCIA", 1);
+	} else {
+		process_mcheck_info(vector, la_ptr, regs, "MCPCIA", 0);
+		if (vector != 0x620 && vector != 0x630)
+			mcpcia_print_uncorrectable(mchk_logout);
 	}
 }

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)