All of lore.kernel.org
 help / color / mirror / Atom feed
From: Greg K-H <gregkh@suse.de>
To: linux-kernel@vger.kernel.org, devel@driverdev.osuosl.org
Cc: Martyn Welch <martyn.welch@gefanuc.com>
Subject: [patch 3/5] Staging: vme: add Universe I/II bridge driver
Date: Mon, 3 Aug 2009 14:01:18 -0700	[thread overview]
Message-ID: <20090803210118.GD28430@kroah.com> (raw)
In-Reply-To: <20090803210054.GA28430@kroah.com>

[-- Attachment #1: staging-vme-add-universe-i-ii-bridge-driver.patch --]
[-- Type: text/plain, Size: 63575 bytes --]

From: Martyn Welch <martyn.welch@gefanuc.com>

Currently this code doesn't compile, so it is disabled.

That should be fixed up...

Signed-off-by: Martyn Welch <martyn.welch@gefanuc.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

---
 drivers/staging/vme/Kconfig                |    2 
 drivers/staging/vme/Makefile               |    2 
 drivers/staging/vme/bridges/Kconfig        |    8 
 drivers/staging/vme/bridges/Makefile       |    1 
 drivers/staging/vme/bridges/vme_ca91cx42.c | 1811 +++++++++++++++++++++++++++++
 drivers/staging/vme/bridges/vme_ca91cx42.h |  403 ++++++
 6 files changed, 2225 insertions(+), 2 deletions(-)

--- /dev/null
+++ b/drivers/staging/vme/bridges/Kconfig
@@ -0,0 +1,8 @@
+comment "VME Bridge Drivers"
+
+config VME_CA91CX42
+	tristate "Universe I/II"
+	depends on BROKEN
+	help
+	 If you say Y here you get support for the Tundra CA91C042 (Universe I)
+	 and CA91C142 (Universe II) VME bridge chips.
--- /dev/null
+++ b/drivers/staging/vme/bridges/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_VME_CA91CX42)	+= vme_ca91cx42.o
--- /dev/null
+++ b/drivers/staging/vme/bridges/vme_ca91cx42.c
@@ -0,0 +1,1811 @@
+/*
+ * Support for the Tundra Universe I/II VME-PCI Bridge Chips
+ *
+ * Author: Martyn Welch <martyn.welch@gefanuc.com>
+ * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc.
+ *
+ * Based on work by Tom Armistead and Ajit Prem
+ * Copyright 2004 Motorola Inc.
+ *
+ * Derived from ca91c042.c by Michael Wyrick
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/proc_fs.h>
+#include <linux/pci.h>
+#include <linux/dma-mapping.h>
+#include <linux/poll.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <asm/time.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+
+#include "../vme.h"
+#include "../vme_bridge.h"
+#include "vme_ca91cx42.h"
+
+extern struct vmeSharedData *vmechip_interboard_data;
+extern dma_addr_t vmechip_interboard_datap;
+extern const int vmechip_revision;
+extern const int vmechip_devid;
+extern const int vmechip_irq;
+extern int vmechip_irq_overhead_ticks;
+extern char *vmechip_baseaddr;
+extern const int vme_slotnum;
+extern int vme_syscon;
+extern unsigned int out_image_va[];
+extern unsigned int vme_irqlog[8][0x100];
+
+static int outCTL[] = { LSI0_CTL, LSI1_CTL, LSI2_CTL, LSI3_CTL,
+	LSI4_CTL, LSI5_CTL, LSI6_CTL, LSI7_CTL
+};
+
+static int outBS[] = { LSI0_BS, LSI1_BS, LSI2_BS, LSI3_BS,
+	LSI4_BS, LSI5_BS, LSI6_BS, LSI7_BS
+};
+
+static int outBD[] = { LSI0_BD, LSI1_BD, LSI2_BD, LSI3_BD,
+	LSI4_BD, LSI5_BD, LSI6_BD, LSI7_BD
+};
+
+static int outTO[] = { LSI0_TO, LSI1_TO, LSI2_TO, LSI3_TO,
+	LSI4_TO, LSI5_TO, LSI6_TO, LSI7_TO
+};
+
+static int inCTL[] = { VSI0_CTL, VSI1_CTL, VSI2_CTL, VSI3_CTL,
+	VSI4_CTL, VSI5_CTL, VSI6_CTL, VSI7_CTL
+};
+
+static int inBS[] = { VSI0_BS, VSI1_BS, VSI2_BS, VSI3_BS,
+	VSI4_BS, VSI5_BS, VSI6_BS, VSI7_BS
+};
+
+static int inBD[] = { VSI0_BD, VSI1_BD, VSI2_BD, VSI3_BD,
+	VSI4_BD, VSI5_BD, VSI6_BD, VSI7_BD
+};
+
+static int inTO[] = { VSI0_TO, VSI1_TO, VSI2_TO, VSI3_TO,
+	VSI4_TO, VSI5_TO, VSI6_TO, VSI7_TO
+};
+static int vmevec[7] = { V1_STATID, V2_STATID, V3_STATID, V4_STATID,
+	V5_STATID, V6_STATID, V7_STATID
+};
+
+struct interrupt_counters {
+	unsigned int acfail;
+	unsigned int sysfail;
+	unsigned int sw_int;
+	unsigned int sw_iack;
+	unsigned int verr;
+	unsigned int lerr;
+	unsigned int lm;
+	unsigned int mbox;
+	unsigned int dma;
+	unsigned int virq[7];
+	unsigned int vown;
+};
+
+extern wait_queue_head_t dma_queue[];
+extern wait_queue_head_t lm_queue;
+extern wait_queue_head_t mbox_queue;
+
+extern int tb_speed;
+
+unsigned int uni_irq_time;
+unsigned int uni_dma_irq_time;
+unsigned int uni_lm_event;
+
+static spinlock_t lm_lock = SPIN_LOCK_UNLOCKED;
+
+static struct interrupt_counters Interrupt_counters = { 0, 0,
+	0, 0, 0, 0,
+	0, 0, 0,
+	{0, 0, 0, 0, 0, 0, 0},
+	0
+};
+
+#define read_register(offset) readl(vmechip_baseaddr + offset)
+#define write_register(value,offset) writel(value, vmechip_baseaddr + offset)
+#define read_register_word(offset) readw(vmechip_baseaddr + offset)
+#define write_register_word(value,offset) writew(value, vmechip_baseaddr + offset)
+
+int uni_procinfo(char *buf)
+{
+	char *p;
+
+	p = buf;
+
+	p += sprintf(p, "\n");
+	{
+		unsigned long misc_ctl;
+
+		misc_ctl = read_register(MISC_CTL);
+		p += sprintf(p, "MISC_CTL:\t\t\t0x%08lx\n", misc_ctl);
+		p += sprintf(p, "VME Bus Time Out:\t\t");
+		switch ((misc_ctl & UNIV_BM_MISC_CTL_VBTO) >>
+			UNIV_OF_MISC_CTL_VBTO) {
+		case 0x0:
+			p += sprintf(p, "Disabled\n");
+			break;
+		case 0x1:
+			p += sprintf(p, "16 us\n");
+			break;
+		case 0x2:
+			p += sprintf(p, "32 us\n");
+			break;
+		case 0x3:
+			p += sprintf(p, "64 us\n");
+			break;
+		case 0x4:
+			p += sprintf(p, "128 us\n");
+			break;
+		case 0x5:
+			p += sprintf(p, "256 us\n");
+			break;
+		case 0x6:
+			p += sprintf(p, "512 us\n");
+			break;
+		case 0x7:
+			p += sprintf(p, "1024 us\n");
+			break;
+		default:
+			p += sprintf(p, "Reserved Value, Undefined\n");
+		}
+		p += sprintf(p, "VME Arbitration Time Out:\t");
+		switch ((misc_ctl & UNIV_BM_MISC_CTL_VARBTO) >>
+			UNIV_OF_MISC_CTL_VARBTO) {
+		case 0x0:
+			p += sprintf(p, "Disabled");
+			break;
+		case 0x1:
+			p += sprintf(p, "16 us");
+			break;
+		case 0x2:
+			p += sprintf(p, "256 us");
+			break;
+		default:
+			p += sprintf(p, "Reserved Value, Undefined");
+		}
+		if (misc_ctl & UNIV_BM_MISC_CTL_VARB)
+			p += sprintf(p, ", Priority Arbitration\n");
+		else
+			p += sprintf(p, ", Round Robin Arbitration\n");
+		p += sprintf(p, "\n");
+	}
+
+	{
+		unsigned int lmisc;
+		unsigned int crt;
+		unsigned int cwt;
+
+		lmisc = read_register(LMISC);
+		p += sprintf(p, "LMISC:\t\t\t\t0x%08x\n", lmisc);
+		crt = (lmisc & UNIV_BM_LMISC_CRT) >> UNIV_OF_LMISC_CRT;
+		cwt = (lmisc & UNIV_BM_LMISC_CWT) >> UNIV_OF_LMISC_CWT;
+		p += sprintf(p, "Coupled Request Timer:\t\t");
+		switch (crt) {
+		case 0x0:
+			p += sprintf(p, "Disabled\n");
+			break;
+		case 0x1:
+			p += sprintf(p, "128 us\n");
+			break;
+		case 0x2:
+			p += sprintf(p, "256 us\n");
+			break;
+		case 0x3:
+			p += sprintf(p, "512 us\n");
+			break;
+		case 0x4:
+			p += sprintf(p, "1024 us\n");
+			break;
+		case 0x5:
+			p += sprintf(p, "2048 us\n");
+			break;
+		case 0x6:
+			p += sprintf(p, "4096 us\n");
+			break;
+		default:
+			p += sprintf(p, "Reserved\n");
+		}
+		p += sprintf(p, "Coupled Window Timer:\t\t");
+		switch (cwt) {
+		case 0x0:
+			p += sprintf(p, "Disabled\n");
+			break;
+		case 0x1:
+			p += sprintf(p, "16 PCI Clocks\n");
+			break;
+		case 0x2:
+			p += sprintf(p, "32 PCI Clocks\n");
+			break;
+		case 0x3:
+			p += sprintf(p, "64 PCI Clocks\n");
+			break;
+		case 0x4:
+			p += sprintf(p, "128 PCI Clocks\n");
+			break;
+		case 0x5:
+			p += sprintf(p, "256 PCI Clocks\n");
+			break;
+		case 0x6:
+			p += sprintf(p, "512 PCI Clocks\n");
+			break;
+		default:
+			p += sprintf(p, "Reserved\n");
+		}
+		p += sprintf(p, "\n");
+	}
+	{
+		unsigned int mast_ctl;
+
+		mast_ctl = read_register(MAST_CTL);
+		p += sprintf(p, "MAST_CTL:\t\t\t0x%08x\n", mast_ctl);
+		{
+			int retries;
+
+			retries = ((mast_ctl & UNIV_BM_MAST_CTL_MAXRTRY)
+				   >> UNIV_OF_MAST_CTL_MAXRTRY) * 64;
+			p += sprintf(p, "Max PCI Master Retries:\t\t");
+			if (retries)
+				p += sprintf(p, "%d\n", retries);
+			else
+				p += sprintf(p, "Forever\n");
+		}
+
+		p += sprintf(p, "Posted Write Transfer Count:\t");
+		switch ((mast_ctl & UNIV_BM_MAST_CTL_PWON) >>
+			UNIV_OF_MAST_CTL_PWON) {
+		case 0x0:
+			p += sprintf(p, "128 Bytes\n");
+			break;
+		case 0x1:
+			p += sprintf(p, "256 Bytes\n");
+			break;
+		case 0x2:
+			p += sprintf(p, "512 Bytes\n");
+			break;
+		case 0x3:
+			p += sprintf(p, "1024 Bytes\n");
+			break;
+		case 0x4:
+			p += sprintf(p, "2048 Bytes\n");
+			break;
+		case 0x5:
+			p += sprintf(p, "4096 Bytes\n");
+			break;
+		default:
+			p += sprintf(p, "Undefined\n");
+		}
+
+		p += sprintf(p, "VMEbus Request Level:\t\t");
+		switch ((mast_ctl & UNIV_BM_MAST_CTL_VRL) >>
+			UNIV_OF_MAST_CTL_VRL) {
+		case 0x0:
+			p += sprintf(p, "Level 0\n");
+		case 0x1:
+			p += sprintf(p, "Level 1\n");
+		case 0x2:
+			p += sprintf(p, "Level 2\n");
+		case 0x3:
+			p += sprintf(p, "Level 3\n");
+		}
+		p += sprintf(p, "VMEbus Request Mode:\t\t");
+		if (mast_ctl & UNIV_BM_MAST_CTL_VRM)
+			p += sprintf(p, "Fair Request Mode\n");
+		else
+			p += sprintf(p, "Demand Request Mode\n");
+		p += sprintf(p, "VMEbus Release Mode:\t\t");
+		if (mast_ctl & UNIV_BM_MAST_CTL_VREL)
+			p += sprintf(p, "Release on Request\n");
+		else
+			p += sprintf(p, "Release when Done\n");
+		p += sprintf(p, "VMEbus Ownership Bit:\t\t");
+		if (mast_ctl & UNIV_BM_MAST_CTL_VOWN)
+			p += sprintf(p, "Acquire and hold VMEbus\n");
+		else
+			p += sprintf(p, "Release VMEbus\n");
+		p += sprintf(p, "VMEbus Ownership Bit Ack:\t");
+		if (mast_ctl & UNIV_BM_MAST_CTL_VOWN_ACK)
+			p += sprintf(p, "Owning VMEbus\n");
+		else
+			p += sprintf(p, "Not Owning VMEbus\n");
+		p += sprintf(p, "\n");
+	}
+	{
+		unsigned int misc_stat;
+
+		misc_stat = read_register(MISC_STAT);
+		p += sprintf(p, "MISC_STAT:\t\t\t0x%08x\n", misc_stat);
+		p += sprintf(p, "Universe BBSY:\t\t\t");
+		if (misc_stat & UNIV_BM_MISC_STAT_MYBBSY)
+			p += sprintf(p, "Negated\n");
+		else
+			p += sprintf(p, "Asserted\n");
+		p += sprintf(p, "Transmit FIFO:\t\t\t");
+		if (misc_stat & UNIV_BM_MISC_STAT_TXFE)
+			p += sprintf(p, "Empty\n");
+		else
+			p += sprintf(p, "Not empty\n");
+		p += sprintf(p, "Receive FIFO:\t\t\t");
+		if (misc_stat & UNIV_BM_MISC_STAT_RXFE)
+			p += sprintf(p, "Empty\n");
+		else
+			p += sprintf(p, "Not Empty\n");
+		p += sprintf(p, "\n");
+	}
+
+	p += sprintf(p, "Latency Timer:\t\t\t%02d Clocks\n\n",
+		     (read_register(UNIV_PCI_MISC0) &
+		      UNIV_BM_PCI_MISC0_LTIMER) >> UNIV_OF_PCI_MISC0_LTIMER);
+
+	{
+		unsigned int lint_en;
+		unsigned int lint_stat;
+
+		lint_en = read_register(LINT_EN);
+		lint_stat = read_register(LINT_STAT);
+
+#define REPORT_IRQ(name,field)     \
+    p += sprintf(p, (lint_en & UNIV_BM_LINT_##name) ? "Enabled" : "Masked"); \
+    p += sprintf(p, ", triggered %d times", Interrupt_counters.field); \
+    p += sprintf(p, (lint_stat & UNIV_BM_LINT_##name) ? ", irq now active\n" : "\n");
+		p += sprintf(p, "ACFAIL Interrupt:\t\t");
+		REPORT_IRQ(ACFAIL, acfail);
+		p += sprintf(p, "SYSFAIL Interrupt:\t\t");
+		REPORT_IRQ(SYSFAIL, sysfail);
+		p += sprintf(p, "SW_INT Interrupt:\t\t");
+		REPORT_IRQ(SW_INT, sw_int);
+		p += sprintf(p, "SW_IACK Interrupt:\t\t");
+		REPORT_IRQ(SW_IACK, sw_iack);
+		p += sprintf(p, "VERR Interrupt:\t\t\t");
+		REPORT_IRQ(VERR, verr);
+		p += sprintf(p, "LERR Interrupt:\t\t\t");
+		REPORT_IRQ(LERR, lerr);
+		p += sprintf(p, "LM Interrupt:\t\t\t");
+		REPORT_IRQ(LM, lm);
+		p += sprintf(p, "MBOX Interrupt:\t\t\t");
+		REPORT_IRQ(MBOX, mbox);
+		p += sprintf(p, "DMA Interrupt:\t\t\t");
+		REPORT_IRQ(DMA, dma);
+		p += sprintf(p, "VIRQ7 Interrupt:\t\t");
+		REPORT_IRQ(VIRQ7, virq[7 - 1]);
+		p += sprintf(p, "VIRQ6 Interrupt:\t\t");
+		REPORT_IRQ(VIRQ6, virq[6 - 1]);
+		p += sprintf(p, "VIRQ5 Interrupt:\t\t");
+		REPORT_IRQ(VIRQ5, virq[5 - 1]);
+		p += sprintf(p, "VIRQ4 Interrupt:\t\t");
+		REPORT_IRQ(VIRQ4, virq[4 - 1]);
+		p += sprintf(p, "VIRQ3 Interrupt:\t\t");
+		REPORT_IRQ(VIRQ3, virq[3 - 1]);
+		p += sprintf(p, "VIRQ2 Interrupt:\t\t");
+		REPORT_IRQ(VIRQ2, virq[2 - 1]);
+		p += sprintf(p, "VIRQ1 Interrupt:\t\t");
+		REPORT_IRQ(VIRQ1, virq[1 - 1]);
+		p += sprintf(p, "VOWN Interrupt:\t\t\t");
+		REPORT_IRQ(VOWN, vown);
+		p += sprintf(p, "\n");
+#undef REPORT_IRQ
+	}
+	{
+		unsigned long vrai_ctl;
+
+		vrai_ctl = read_register(VRAI_CTL);
+		if (vrai_ctl & UNIV_BM_VRAI_CTL_EN) {
+			unsigned int vrai_bs;
+
+			vrai_bs = read_register(VRAI_BS);
+			p += sprintf(p,
+				     "VME Register Image:\t\tEnabled at VME-Address 0x%x\n",
+				     vrai_bs);
+		} else
+			p += sprintf(p, "VME Register Image:\t\tDisabled\n");
+	}
+	{
+		unsigned int slsi;
+
+		slsi = read_register(SLSI);
+		if (slsi & UNIV_BM_SLSI_EN) {
+			/* Not implemented */
+		} else {
+			p += sprintf(p, "Special PCI Slave Image:\tDisabled\n");
+		}
+	}
+	{
+		int i;
+
+		for (i = 0; i < (vmechip_revision > 0 ? 8 : 4); i++) {
+			unsigned int ctl, bs, bd, to, vstart, vend;
+
+			ctl = readl(vmechip_baseaddr + outCTL[i]);
+			bs = readl(vmechip_baseaddr + outBS[i]);
+			bd = readl(vmechip_baseaddr + outBD[i]);
+			to = readl(vmechip_baseaddr + outTO[i]);
+
+			vstart = bs + to;
+			vend = bd + to;
+
+			p += sprintf(p, "PCI Slave Image %d:\t\t", i);
+			if (ctl & UNIV_BM_LSI_CTL_EN) {
+				p += sprintf(p, "Enabled");
+				if (ctl & UNIV_BM_LSI_CTL_PWEN)
+					p += sprintf(p,
+						     ", Posted Write Enabled\n");
+				else
+					p += sprintf(p, "\n");
+				p += sprintf(p,
+					     "\t\t\t\tPCI Addresses from 0x%x to 0x%x\n",
+					     bs, bd);
+				p += sprintf(p,
+					     "\t\t\t\tVME Addresses from 0x%x to 0x%x\n",
+					     vstart, vend);
+			} else
+				p += sprintf(p, "Disabled\n");
+		}
+		p += sprintf(p, "\n");
+	}
+	{
+		int i;
+		for (i = 0; i < (vmechip_revision > 0 ? 8 : 4); i++) {
+			unsigned int ctl, bs, bd, to, vstart, vend;
+
+			ctl = readl(vmechip_baseaddr + inCTL[i]);
+			bs = readl(vmechip_baseaddr + inBS[i]);
+			bd = readl(vmechip_baseaddr + inBD[i]);
+			to = readl(vmechip_baseaddr + inTO[i]);
+			vstart = bs + to;
+			vend = bd + to;
+			p += sprintf(p, "VME Slave Image %d:\t\t", i);
+			if (ctl & UNIV_BM_LSI_CTL_EN) {
+				p += sprintf(p, "Enabled");
+				if (ctl & UNIV_BM_LSI_CTL_PWEN)
+					p += sprintf(p,
+						     ", Posted Write Enabled\n");
+				else
+					p += sprintf(p, "\n");
+				p += sprintf(p,
+					     "\t\t\t\tVME Addresses from 0x%x to 0x%x\n",
+					     bs, bd);
+				p += sprintf(p,
+					     "\t\t\t\tPCI Addresses from 0x%x to 0x%x\n",
+					     vstart, vend);
+			} else
+				p += sprintf(p, "Disabled\n");
+		}
+	}
+
+	return p - buf;
+}
+
+//----------------------------------------------------------------------------
+//  uni_bus_error_chk()
+//----------------------------------------------------------------------------
+int uni_bus_error_chk(int clrflag)
+{
+	int tmp;
+	tmp = readl(vmechip_baseaddr + PCI_COMMAND);
+	if (tmp & 0x08000000) {	// S_TA is Set
+		if (clrflag)
+			writel(tmp | 0x08000000,
+			       vmechip_baseaddr + PCI_COMMAND);
+		return (1);
+	}
+	return (0);
+}
+
+//-----------------------------------------------------------------------------
+// Function   : DMA_uni_irqhandler
+// Inputs     : void
+// Outputs    : void
+// Description: Saves DMA completion timestamp and then wakes up DMA queue
+//-----------------------------------------------------------------------------
+static void DMA_uni_irqhandler(void)
+{
+	uni_dma_irq_time = uni_irq_time;
+	wake_up(&dma_queue[0]);
+}
+
+//-----------------------------------------------------------------------------
+// Function   : LERR_uni_irqhandler
+// Inputs     : void
+// Outputs    : void
+// Description:
+//-----------------------------------------------------------------------------
+static void LERR_uni_irqhandler(void)
+{
+	int val;
+
+	val = readl(vmechip_baseaddr + DGCS);
+
+	if (!(val & 0x00000800)) {
+		printk(KERN_ERR
+		       "ca91c042: LERR_uni_irqhandler DMA Read Error DGCS=%08X\n",
+		       val);
+
+	}
+}
+
+//-----------------------------------------------------------------------------
+// Function   : VERR_uni_irqhandler
+// Inputs     : void
+// Outputs    : void
+// Description:
+//-----------------------------------------------------------------------------
+static void VERR_uni_irqhandler(void)
+{
+	int val;
+
+	val = readl(vmechip_baseaddr + DGCS);
+
+	if (!(val & 0x00000800)) {
+		printk(KERN_ERR
+		       "ca91c042: VERR_uni_irqhandler DMA Read Error DGCS=%08X\n",
+		       val);
+	}
+
+}
+
+//-----------------------------------------------------------------------------
+// Function   : MB_uni_irqhandler
+// Inputs     : void
+// Outputs    : void
+// Description:
+//-----------------------------------------------------------------------------
+static void MB_uni_irqhandler(int mbox_mask)
+{
+	if (vmechip_irq_overhead_ticks != 0) {
+		wake_up(&mbox_queue);
+	}
+}
+
+//-----------------------------------------------------------------------------
+// Function   : LM_uni_irqhandler
+// Inputs     : void
+// Outputs    : void
+// Description:
+//-----------------------------------------------------------------------------
+static void LM_uni_irqhandler(int lm_mask)
+{
+	uni_lm_event = lm_mask;
+	wake_up(&lm_queue);
+}
+
+//-----------------------------------------------------------------------------
+// Function   : VIRQ_uni_irqhandler
+// Inputs     : void
+// Outputs    : void
+// Description:
+//-----------------------------------------------------------------------------
+static void VIRQ_uni_irqhandler(int virq_mask)
+{
+	int iackvec, i;
+
+	for (i = 7; i > 0; i--) {
+		if (virq_mask & (1 << i)) {
+			Interrupt_counters.virq[i - 1]++;
+			iackvec = readl(vmechip_baseaddr + vmevec[i - 1]);
+			vme_irqlog[i][iackvec]++;
+		}
+	}
+}
+
+//-----------------------------------------------------------------------------
+// Function   : uni_irqhandler
+// Inputs     : int irq, void *dev_id, struct pt_regs *regs
+// Outputs    : void
+// Description:
+//-----------------------------------------------------------------------------
+static irqreturn_t uni_irqhandler(int irq, void *dev_id)
+{
+	long stat, enable;
+
+	if (dev_id != vmechip_baseaddr)
+		return IRQ_NONE;
+
+	uni_irq_time = get_tbl();
+
+	stat = readl(vmechip_baseaddr + LINT_STAT);
+	writel(stat, vmechip_baseaddr + LINT_STAT);	// Clear all pending ints
+	enable = readl(vmechip_baseaddr + LINT_EN);
+	stat = stat & enable;
+	if (stat & 0x0100) {
+		Interrupt_counters.dma++;
+		DMA_uni_irqhandler();
+	}
+	if (stat & 0x0200) {
+		Interrupt_counters.lerr++;
+		LERR_uni_irqhandler();
+	}
+	if (stat & 0x0400) {
+		Interrupt_counters.verr++;
+		VERR_uni_irqhandler();
+	}
+	if (stat & 0xF0000) {
+		Interrupt_counters.mbox++;
+		MB_uni_irqhandler((stat & 0xF0000) >> 16);
+	}
+	if (stat & 0xF00000) {
+		Interrupt_counters.lm++;
+		LM_uni_irqhandler((stat & 0xF00000) >> 20);
+	}
+	if (stat & 0x0000FE) {
+		VIRQ_uni_irqhandler(stat & 0x0000FE);
+	}
+	if (stat & UNIV_BM_LINT_ACFAIL) {
+		Interrupt_counters.acfail++;
+	}
+	if (stat & UNIV_BM_LINT_SYSFAIL) {
+		Interrupt_counters.sysfail++;
+	}
+	if (stat & UNIV_BM_LINT_SW_INT) {
+		Interrupt_counters.sw_int++;
+	}
+	if (stat & UNIV_BM_LINT_SW_IACK) {
+		Interrupt_counters.sw_iack++;
+	}
+	if (stat & UNIV_BM_LINT_VOWN) {
+		Interrupt_counters.vown++;
+	}
+
+	return IRQ_HANDLED;
+}
+
+//-----------------------------------------------------------------------------
+// Function   : uni_generate_irq
+// Description:
+//-----------------------------------------------------------------------------
+int uni_generate_irq(virqInfo_t * vmeIrq)
+{
+	int timeout;
+	int looptimeout;
+
+	timeout = vmeIrq->waitTime;
+	if (timeout == 0) {
+		timeout++;	// Wait at least 1 tick...
+	}
+	looptimeout = HZ / 20;	// try for 1/20 second
+
+	vmeIrq->timeOutFlag = 0;
+
+	// Validate & setup vector register.
+	if (vmeIrq->vector & 1) {	// Universe can only generate even vectors
+		return (-EINVAL);
+	}
+	writel(vmeIrq->vector << 24, vmechip_baseaddr + STATID);
+
+	// Assert VMEbus IRQ
+	writel(1 << (vmeIrq->level + 24), vmechip_baseaddr + VINT_EN);
+
+	// Wait for syscon to do iack
+	while (readl(vmechip_baseaddr + VINT_STAT) &
+	       (1 << (vmeIrq->level + 24))) {
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout(looptimeout);
+		timeout = timeout - looptimeout;
+		if (timeout <= 0) {
+			vmeIrq->timeOutFlag = 1;
+			break;
+		}
+	}
+
+	// Clear VMEbus IRQ bit
+	writel(0, vmechip_baseaddr + VINT_EN);
+
+	return (0);
+}
+
+//-----------------------------------------------------------------------------
+// Function   : uni_set_arbiter
+// Description:
+//-----------------------------------------------------------------------------
+int uni_set_arbiter(vmeArbiterCfg_t * vmeArb)
+{
+	int temp_ctl = 0;
+	int vbto = 0;
+
+	temp_ctl = readl(vmechip_baseaddr + MISC_CTL);
+	temp_ctl &= 0x00FFFFFF;
+
+	if (vmeArb->globalTimeoutTimer == 0xFFFFFFFF) {
+		vbto = 7;
+	} else if (vmeArb->globalTimeoutTimer > 1024) {
+		return (-EINVAL);
+	} else if (vmeArb->globalTimeoutTimer == 0) {
+		vbto = 0;
+	} else {
+		vbto = 1;
+		while ((16 * (1 << (vbto - 1))) < vmeArb->globalTimeoutTimer) {
+			vbto += 1;
+		}
+	}
+	temp_ctl |= (vbto << 28);
+
+	if (vmeArb->arbiterMode == VME_PRIORITY_MODE) {
+		temp_ctl |= 1 << 26;
+	}
+
+	if (vmeArb->arbiterTimeoutFlag) {
+		temp_ctl |= 2 << 24;
+	}
+
+	writel(temp_ctl, vmechip_baseaddr + MISC_CTL);
+	return (0);
+}
+
+//-----------------------------------------------------------------------------
+// Function   : uni_get_arbiter
+// Description:
+//-----------------------------------------------------------------------------
+int uni_get_arbiter(vmeArbiterCfg_t * vmeArb)
+{
+	int temp_ctl = 0;
+	int vbto = 0;
+
+	temp_ctl = readl(vmechip_baseaddr + MISC_CTL);
+
+	vbto = (temp_ctl >> 28) & 0xF;
+	if (vbto != 0) {
+		vmeArb->globalTimeoutTimer = (16 * (1 << (vbto - 1)));
+	}
+
+	if (temp_ctl & (1 << 26)) {
+		vmeArb->arbiterMode = VME_PRIORITY_MODE;
+	} else {
+		vmeArb->arbiterMode = VME_R_ROBIN_MODE;
+	}
+
+	if (temp_ctl & (3 << 24)) {
+		vmeArb->arbiterTimeoutFlag = 1;
+	}
+	return (0);
+}
+
+//-----------------------------------------------------------------------------
+// Function   : uni_set_requestor
+// Description:
+//-----------------------------------------------------------------------------
+int uni_set_requestor(vmeRequesterCfg_t * vmeReq)
+{
+	int temp_ctl = 0;
+
+	temp_ctl = readl(vmechip_baseaddr + MAST_CTL);
+	temp_ctl &= 0xFF0FFFFF;
+
+	if (vmeReq->releaseMode == 1) {
+		temp_ctl |= (1 << 20);
+	}
+
+	if (vmeReq->fairMode == 1) {
+		temp_ctl |= (1 << 21);
+	}
+
+	temp_ctl |= (vmeReq->requestLevel << 22);
+
+	writel(temp_ctl, vmechip_baseaddr + MAST_CTL);
+	return (0);
+}
+
+//-----------------------------------------------------------------------------
+// Function   : uni_get_requestor
+// Description:
+//-----------------------------------------------------------------------------
+int uni_get_requestor(vmeRequesterCfg_t * vmeReq)
+{
+	int temp_ctl = 0;
+
+	temp_ctl = readl(vmechip_baseaddr + MAST_CTL);
+
+	if (temp_ctl & (1 << 20)) {
+		vmeReq->releaseMode = 1;
+	}
+
+	if (temp_ctl & (1 << 21)) {
+		vmeReq->fairMode = 1;
+	}
+
+	vmeReq->requestLevel = (temp_ctl & 0xC00000) >> 22;
+
+	return (0);
+}
+
+//-----------------------------------------------------------------------------
+// Function   : uni_set_in_bound
+// Description:
+//-----------------------------------------------------------------------------
+int uni_set_in_bound(vmeInWindowCfg_t * vmeIn)
+{
+	int temp_ctl = 0;
+
+	// Verify input data
+	if (vmeIn->windowNbr > 7) {
+		return (-EINVAL);
+	}
+	if ((vmeIn->vmeAddrU) || (vmeIn->windowSizeU) || (vmeIn->pciAddrU)) {
+		return (-EINVAL);
+	}
+	if ((vmeIn->vmeAddrL & 0xFFF) ||
+	    (vmeIn->windowSizeL & 0xFFF) || (vmeIn->pciAddrL & 0xFFF)) {
+		return (-EINVAL);
+	}
+
+	if (vmeIn->bcastRespond2esst) {
+		return (-EINVAL);
+	}
+	switch (vmeIn->addrSpace) {
+	case VME_A64:
+	case VME_CRCSR:
+	case VME_USER3:
+	case VME_USER4:
+		return (-EINVAL);
+	case VME_A16:
+		temp_ctl |= 0x00000;
+		break;
+	case VME_A24:
+		temp_ctl |= 0x10000;
+		break;
+	case VME_A32:
+		temp_ctl |= 0x20000;
+		break;
+	case VME_USER1:
+		temp_ctl |= 0x60000;
+		break;
+	case VME_USER2:
+		temp_ctl |= 0x70000;
+		break;
+	}
+
+	// Disable while we are mucking around
+	writel(0x00000000, vmechip_baseaddr + inCTL[vmeIn->windowNbr]);
+	writel(vmeIn->vmeAddrL, vmechip_baseaddr + inBS[vmeIn->windowNbr]);
+	writel(vmeIn->vmeAddrL + vmeIn->windowSizeL,
+	       vmechip_baseaddr + inBD[vmeIn->windowNbr]);
+	writel(vmeIn->pciAddrL - vmeIn->vmeAddrL,
+	       vmechip_baseaddr + inTO[vmeIn->windowNbr]);
+
+	// Setup CTL register.
+	if (vmeIn->wrPostEnable)
+		temp_ctl |= 0x40000000;
+	if (vmeIn->prefetchEnable)
+		temp_ctl |= 0x20000000;
+	if (vmeIn->rmwLock)
+		temp_ctl |= 0x00000040;
+	if (vmeIn->data64BitCapable)
+		temp_ctl |= 0x00000080;
+	if (vmeIn->userAccessType & VME_USER)
+		temp_ctl |= 0x00100000;
+	if (vmeIn->userAccessType & VME_SUPER)
+		temp_ctl |= 0x00200000;
+	if (vmeIn->dataAccessType & VME_DATA)
+		temp_ctl |= 0x00400000;
+	if (vmeIn->dataAccessType & VME_PROG)
+		temp_ctl |= 0x00800000;
+
+	// Write ctl reg without enable
+	writel(temp_ctl, vmechip_baseaddr + inCTL[vmeIn->windowNbr]);
+
+	if (vmeIn->windowEnable)
+		temp_ctl |= 0x80000000;
+
+	writel(temp_ctl, vmechip_baseaddr + inCTL[vmeIn->windowNbr]);
+	return (0);
+}
+
+//-----------------------------------------------------------------------------
+// Function   : uni_get_in_bound
+// Description:
+//-----------------------------------------------------------------------------
+int uni_get_in_bound(vmeInWindowCfg_t * vmeIn)
+{
+	int temp_ctl = 0;
+
+	// Verify input data
+	if (vmeIn->windowNbr > 7) {
+		return (-EINVAL);
+	}
+	// Get Window mappings.
+	vmeIn->vmeAddrL = readl(vmechip_baseaddr + inBS[vmeIn->windowNbr]);
+	vmeIn->pciAddrL = vmeIn->vmeAddrL +
+	    readl(vmechip_baseaddr + inTO[vmeIn->windowNbr]);
+	vmeIn->windowSizeL = readl(vmechip_baseaddr + inBD[vmeIn->windowNbr]) -
+	    vmeIn->vmeAddrL;
+
+	temp_ctl = readl(vmechip_baseaddr + inCTL[vmeIn->windowNbr]);
+
+	// Get Control & BUS attributes
+	if (temp_ctl & 0x40000000)
+		vmeIn->wrPostEnable = 1;
+	if (temp_ctl & 0x20000000)
+		vmeIn->prefetchEnable = 1;
+	if (temp_ctl & 0x00000040)
+		vmeIn->rmwLock = 1;
+	if (temp_ctl & 0x00000080)
+		vmeIn->data64BitCapable = 1;
+	if (temp_ctl & 0x00100000)
+		vmeIn->userAccessType |= VME_USER;
+	if (temp_ctl & 0x00200000)
+		vmeIn->userAccessType |= VME_SUPER;
+	if (temp_ctl & 0x00400000)
+		vmeIn->dataAccessType |= VME_DATA;
+	if (temp_ctl & 0x00800000)
+		vmeIn->dataAccessType |= VME_PROG;
+	if (temp_ctl & 0x80000000)
+		vmeIn->windowEnable = 1;
+
+	switch ((temp_ctl & 0x70000) >> 16) {
+	case 0x0:
+		vmeIn->addrSpace = VME_A16;
+		break;
+	case 0x1:
+		vmeIn->addrSpace = VME_A24;
+		break;
+	case 0x2:
+		vmeIn->addrSpace = VME_A32;
+		break;
+	case 0x6:
+		vmeIn->addrSpace = VME_USER1;
+		break;
+	case 0x7:
+		vmeIn->addrSpace = VME_USER2;
+		break;
+	}
+
+	return (0);
+}
+
+//-----------------------------------------------------------------------------
+// Function   : uni_set_out_bound
+// Description:
+//-----------------------------------------------------------------------------
+int uni_set_out_bound(vmeOutWindowCfg_t * vmeOut)
+{
+	int temp_ctl = 0;
+
+	// Verify input data
+	if (vmeOut->windowNbr > 7) {
+		return (-EINVAL);
+	}
+	if ((vmeOut->xlatedAddrU) || (vmeOut->windowSizeU)
+	    || (vmeOut->pciBusAddrU)) {
+		return (-EINVAL);
+	}
+	if ((vmeOut->xlatedAddrL & 0xFFF) ||
+	    (vmeOut->windowSizeL & 0xFFF) || (vmeOut->pciBusAddrL & 0xFFF)) {
+		return (-EINVAL);
+	}
+	if (vmeOut->bcastSelect2esst) {
+		return (-EINVAL);
+	}
+	switch (vmeOut->addrSpace) {
+	case VME_A64:
+	case VME_USER3:
+	case VME_USER4:
+		return (-EINVAL);
+	case VME_A16:
+		temp_ctl |= 0x00000;
+		break;
+	case VME_A24:
+		temp_ctl |= 0x10000;
+		break;
+	case VME_A32:
+		temp_ctl |= 0x20000;
+		break;
+	case VME_CRCSR:
+		temp_ctl |= 0x50000;
+		break;
+	case VME_USER1:
+		temp_ctl |= 0x60000;
+		break;
+	case VME_USER2:
+		temp_ctl |= 0x70000;
+		break;
+	}
+
+	// Disable while we are mucking around
+	writel(0x00000000, vmechip_baseaddr + outCTL[vmeOut->windowNbr]);
+	writel(vmeOut->pciBusAddrL,
+	       vmechip_baseaddr + outBS[vmeOut->windowNbr]);
+	writel(vmeOut->pciBusAddrL + vmeOut->windowSizeL,
+	       vmechip_baseaddr + outBD[vmeOut->windowNbr]);
+	writel(vmeOut->xlatedAddrL - vmeOut->pciBusAddrL,
+	       vmechip_baseaddr + outTO[vmeOut->windowNbr]);
+
+	// Sanity check.
+	if (vmeOut->pciBusAddrL !=
+	    readl(vmechip_baseaddr + outBS[vmeOut->windowNbr])) {
+		printk(KERN_ERR
+		       "ca91c042: out window: %x, failed to configure\n",
+		       vmeOut->windowNbr);
+		return (-EINVAL);
+	}
+
+	if (vmeOut->pciBusAddrL + vmeOut->windowSizeL !=
+	    readl(vmechip_baseaddr + outBD[vmeOut->windowNbr])) {
+		printk(KERN_ERR
+		       "ca91c042: out window: %x, failed to configure\n",
+		       vmeOut->windowNbr);
+		return (-EINVAL);
+	}
+
+	if (vmeOut->xlatedAddrL - vmeOut->pciBusAddrL !=
+	    readl(vmechip_baseaddr + outTO[vmeOut->windowNbr])) {
+		printk(KERN_ERR
+		       "ca91c042: out window: %x, failed to configure\n",
+		       vmeOut->windowNbr);
+		return (-EINVAL);
+	}
+	// Setup CTL register.
+	if (vmeOut->wrPostEnable)
+		temp_ctl |= 0x40000000;
+	if (vmeOut->userAccessType & VME_SUPER)
+		temp_ctl |= 0x001000;
+	if (vmeOut->dataAccessType & VME_PROG)
+		temp_ctl |= 0x004000;
+	if (vmeOut->maxDataWidth == VME_D16)
+		temp_ctl |= 0x00400000;
+	if (vmeOut->maxDataWidth == VME_D32)
+		temp_ctl |= 0x00800000;
+	if (vmeOut->maxDataWidth == VME_D64)
+		temp_ctl |= 0x00C00000;
+	if (vmeOut->xferProtocol & (VME_BLT | VME_MBLT))
+		temp_ctl |= 0x00000100;
+
+	// Write ctl reg without enable
+	writel(temp_ctl, vmechip_baseaddr + outCTL[vmeOut->windowNbr]);
+
+	if (vmeOut->windowEnable)
+		temp_ctl |= 0x80000000;
+
+	writel(temp_ctl, vmechip_baseaddr + outCTL[vmeOut->windowNbr]);
+	return (0);
+}
+
+//-----------------------------------------------------------------------------
+// Function   : uni_get_out_bound
+// Description:
+//-----------------------------------------------------------------------------
+int uni_get_out_bound(vmeOutWindowCfg_t * vmeOut)
+{
+	int temp_ctl = 0;
+
+	// Verify input data
+	if (vmeOut->windowNbr > 7) {
+		return (-EINVAL);
+	}
+	// Get Window mappings.
+	vmeOut->pciBusAddrL =
+	    readl(vmechip_baseaddr + outBS[vmeOut->windowNbr]);
+	vmeOut->xlatedAddrL =
+	    vmeOut->pciBusAddrL + readl(vmechip_baseaddr +
+					outTO[vmeOut->windowNbr]);
+	vmeOut->windowSizeL =
+	    readl(vmechip_baseaddr + outBD[vmeOut->windowNbr]) -
+	    vmeOut->pciBusAddrL;
+
+	temp_ctl = readl(vmechip_baseaddr + outCTL[vmeOut->windowNbr]);
+
+	// Get Control & BUS attributes
+	if (temp_ctl & 0x40000000)
+		vmeOut->wrPostEnable = 1;
+	if (temp_ctl & 0x001000)
+		vmeOut->userAccessType = VME_SUPER;
+	else
+		vmeOut->userAccessType = VME_USER;
+	if (temp_ctl & 0x004000)
+		vmeOut->dataAccessType = VME_PROG;
+	else
+		vmeOut->dataAccessType = VME_DATA;
+	if (temp_ctl & 0x80000000)
+		vmeOut->windowEnable = 1;
+
+	switch ((temp_ctl & 0x00C00000) >> 22) {
+	case 0:
+		vmeOut->maxDataWidth = VME_D8;
+		break;
+	case 1:
+		vmeOut->maxDataWidth = VME_D16;
+		break;
+	case 2:
+		vmeOut->maxDataWidth = VME_D32;
+		break;
+	case 3:
+		vmeOut->maxDataWidth = VME_D64;
+		break;
+	}
+	if (temp_ctl & 0x00000100)
+		vmeOut->xferProtocol = VME_BLT;
+	else
+		vmeOut->xferProtocol = VME_SCT;
+
+	switch ((temp_ctl & 0x70000) >> 16) {
+	case 0x0:
+		vmeOut->addrSpace = VME_A16;
+		break;
+	case 0x1:
+		vmeOut->addrSpace = VME_A24;
+		break;
+	case 0x2:
+		vmeOut->addrSpace = VME_A32;
+		break;
+	case 0x5:
+		vmeOut->addrSpace = VME_CRCSR;
+		break;
+	case 0x6:
+		vmeOut->addrSpace = VME_USER1;
+		break;
+	case 0x7:
+		vmeOut->addrSpace = VME_USER2;
+		break;
+	}
+
+	return (0);
+}
+
+//-----------------------------------------------------------------------------
+// Function   : uni_setup_lm
+// Description:
+//-----------------------------------------------------------------------------
+int uni_setup_lm(vmeLmCfg_t * vmeLm)
+{
+	int temp_ctl = 0;
+
+	if (vmeLm->addrU) {
+		return (-EINVAL);
+	}
+	switch (vmeLm->addrSpace) {
+	case VME_A64:
+	case VME_USER3:
+	case VME_USER4:
+		return (-EINVAL);
+	case VME_A16:
+		temp_ctl |= 0x00000;
+		break;
+	case VME_A24:
+		temp_ctl |= 0x10000;
+		break;
+	case VME_A32:
+		temp_ctl |= 0x20000;
+		break;
+	case VME_CRCSR:
+		temp_ctl |= 0x50000;
+		break;
+	case VME_USER1:
+		temp_ctl |= 0x60000;
+		break;
+	case VME_USER2:
+		temp_ctl |= 0x70000;
+		break;
+	}
+
+	// Disable while we are mucking around
+	writel(0x00000000, vmechip_baseaddr + LM_CTL);
+
+	writel(vmeLm->addr, vmechip_baseaddr + LM_BS);
+
+	// Setup CTL register.
+	if (vmeLm->userAccessType & VME_SUPER)
+		temp_ctl |= 0x00200000;
+	if (vmeLm->userAccessType & VME_USER)
+		temp_ctl |= 0x00100000;
+	if (vmeLm->dataAccessType & VME_PROG)
+		temp_ctl |= 0x00800000;
+	if (vmeLm->dataAccessType & VME_DATA)
+		temp_ctl |= 0x00400000;
+
+	uni_lm_event = 0;
+
+	// Write ctl reg and enable
+	writel(0x80000000 | temp_ctl, vmechip_baseaddr + LM_CTL);
+	temp_ctl = readl(vmechip_baseaddr + LM_CTL);
+
+	return (0);
+}
+
+//-----------------------------------------------------------------------------
+// Function   : uni_wait_lm
+// Description:
+//-----------------------------------------------------------------------------
+int uni_wait_lm(vmeLmCfg_t * vmeLm)
+{
+	unsigned long flags;
+	unsigned int tmp;
+
+	spin_lock_irqsave(&lm_lock, flags);
+	tmp = uni_lm_event;
+	spin_unlock_irqrestore(&lm_lock, flags);
+	if (tmp == 0) {
+		if (vmeLm->lmWait < 10)
+			vmeLm->lmWait = 10;
+		interruptible_sleep_on_timeout(&lm_queue, vmeLm->lmWait);
+	}
+	writel(0x00000000, vmechip_baseaddr + LM_CTL);
+	vmeLm->lmEvents = uni_lm_event;
+
+	return (0);
+}
+
+#define	SWIZZLE(X) ( ((X & 0xFF000000) >> 24) | ((X & 0x00FF0000) >>  8) | ((X & 0x0000FF00) <<  8) | ((X & 0x000000FF) << 24))
+
+//-----------------------------------------------------------------------------
+// Function   : uni_do_rmw
+// Description:
+//-----------------------------------------------------------------------------
+int uni_do_rmw(vmeRmwCfg_t * vmeRmw)
+{
+	int temp_ctl = 0;
+	int tempBS = 0;
+	int tempBD = 0;
+	int tempTO = 0;
+	int vmeBS = 0;
+	int vmeBD = 0;
+	int *rmw_pci_data_ptr = NULL;
+	int *vaDataPtr = NULL;
+	int i;
+	vmeOutWindowCfg_t vmeOut;
+	if (vmeRmw->maxAttempts < 1) {
+		return (-EINVAL);
+	}
+	if (vmeRmw->targetAddrU) {
+		return (-EINVAL);
+	}
+	// Find the PCI address that maps to the desired VME address
+	for (i = 0; i < 8; i++) {
+		temp_ctl = readl(vmechip_baseaddr + outCTL[i]);
+		if ((temp_ctl & 0x80000000) == 0) {
+			continue;
+		}
+		memset(&vmeOut, 0, sizeof(vmeOut));
+		vmeOut.windowNbr = i;
+		uni_get_out_bound(&vmeOut);
+		if (vmeOut.addrSpace != vmeRmw->addrSpace) {
+			continue;
+		}
+		tempBS = readl(vmechip_baseaddr + outBS[i]);
+		tempBD = readl(vmechip_baseaddr + outBD[i]);
+		tempTO = readl(vmechip_baseaddr + outTO[i]);
+		vmeBS = tempBS + tempTO;
+		vmeBD = tempBD + tempTO;
+		if ((vmeRmw->targetAddr >= vmeBS) &&
+		    (vmeRmw->targetAddr < vmeBD)) {
+			rmw_pci_data_ptr =
+			    (int *)(tempBS + (vmeRmw->targetAddr - vmeBS));
+			vaDataPtr =
+			    (int *)(out_image_va[i] +
+				    (vmeRmw->targetAddr - vmeBS));
+			break;
+		}
+	}
+
+	// If no window - fail.
+	if (rmw_pci_data_ptr == NULL) {
+		return (-EINVAL);
+	}
+	// Setup the RMW registers.
+	writel(0, vmechip_baseaddr + SCYC_CTL);
+	writel(SWIZZLE(vmeRmw->enableMask), vmechip_baseaddr + SCYC_EN);
+	writel(SWIZZLE(vmeRmw->compareData), vmechip_baseaddr + SCYC_CMP);
+	writel(SWIZZLE(vmeRmw->swapData), vmechip_baseaddr + SCYC_SWP);
+	writel((int)rmw_pci_data_ptr, vmechip_baseaddr + SCYC_ADDR);
+	writel(1, vmechip_baseaddr + SCYC_CTL);
+
+	// Run the RMW cycle until either success or max attempts.
+	vmeRmw->numAttempts = 1;
+	while (vmeRmw->numAttempts <= vmeRmw->maxAttempts) {
+
+		if ((readl(vaDataPtr) & vmeRmw->enableMask) ==
+		    (vmeRmw->swapData & vmeRmw->enableMask)) {
+
+			writel(0, vmechip_baseaddr + SCYC_CTL);
+			break;
+
+		}
+		vmeRmw->numAttempts++;
+	}
+
+	// If no success, set num Attempts to be greater than max attempts
+	if (vmeRmw->numAttempts > vmeRmw->maxAttempts) {
+		vmeRmw->numAttempts = vmeRmw->maxAttempts + 1;
+	}
+
+	return (0);
+}
+
+//-----------------------------------------------------------------------------
+// Function   : uniSetupDctlReg
+// Description:
+//-----------------------------------------------------------------------------
+int uniSetupDctlReg(vmeDmaPacket_t * vmeDma, int *dctlregreturn)
+{
+	unsigned int dctlreg = 0x80;
+	struct vmeAttr *vmeAttr;
+
+	if (vmeDma->srcBus == VME_DMA_VME) {
+		dctlreg = 0;
+		vmeAttr = &vmeDma->srcVmeAttr;
+	} else {
+		dctlreg = 0x80000000;
+		vmeAttr = &vmeDma->dstVmeAttr;
+	}
+
+	switch (vmeAttr->maxDataWidth) {
+	case VME_D8:
+		break;
+	case VME_D16:
+		dctlreg |= 0x00400000;
+		break;
+	case VME_D32:
+		dctlreg |= 0x00800000;
+		break;
+	case VME_D64:
+		dctlreg |= 0x00C00000;
+		break;
+	}
+
+	switch (vmeAttr->addrSpace) {
+	case VME_A16:
+		break;
+	case VME_A24:
+		dctlreg |= 0x00010000;
+		break;
+	case VME_A32:
+		dctlreg |= 0x00020000;
+		break;
+	case VME_USER1:
+		dctlreg |= 0x00060000;
+		break;
+	case VME_USER2:
+		dctlreg |= 0x00070000;
+		break;
+
+	case VME_A64:		// not supported in Universe DMA
+	case VME_CRCSR:
+	case VME_USER3:
+	case VME_USER4:
+		return (-EINVAL);
+		break;
+	}
+	if (vmeAttr->userAccessType == VME_PROG) {
+		dctlreg |= 0x00004000;
+	}
+	if (vmeAttr->dataAccessType == VME_SUPER) {
+		dctlreg |= 0x00001000;
+	}
+	if (vmeAttr->xferProtocol != VME_SCT) {
+		dctlreg |= 0x00000100;
+	}
+	*dctlregreturn = dctlreg;
+	return (0);
+}
+
+//-----------------------------------------------------------------------------
+// Function   : uni_start_dma
+// Description:
+//-----------------------------------------------------------------------------
+unsigned int
+uni_start_dma(int channel, unsigned int dgcsreg, TDMA_Cmd_Packet * vmeLL)
+{
+	unsigned int val;
+
+	// Setup registers as needed for direct or chained.
+	if (dgcsreg & 0x8000000) {
+		writel(0, vmechip_baseaddr + DTBC);
+		writel((unsigned int)vmeLL, vmechip_baseaddr + DCPP);
+	} else {
+#if	0
+		printk("Starting: DGCS = %08x\n", dgcsreg);
+		printk("Starting: DVA  = %08x\n", readl(&vmeLL->dva));
+		printk("Starting: DLV  = %08x\n", readl(&vmeLL->dlv));
+		printk("Starting: DTBC = %08x\n", readl(&vmeLL->dtbc));
+		printk("Starting: DCTL = %08x\n", readl(&vmeLL->dctl));
+#endif
+		// Write registers
+		writel(readl(&vmeLL->dva), vmechip_baseaddr + DVA);
+		writel(readl(&vmeLL->dlv), vmechip_baseaddr + DLA);
+		writel(readl(&vmeLL->dtbc), vmechip_baseaddr + DTBC);
+		writel(readl(&vmeLL->dctl), vmechip_baseaddr + DCTL);
+		writel(0, vmechip_baseaddr + DCPP);
+	}
+
+	// Start the operation
+	writel(dgcsreg, vmechip_baseaddr + DGCS);
+	val = get_tbl();
+	writel(dgcsreg | 0x8000000F, vmechip_baseaddr + DGCS);
+	return (val);
+}
+
+//-----------------------------------------------------------------------------
+// Function   : uni_setup_dma
+// Description:
+//-----------------------------------------------------------------------------
+TDMA_Cmd_Packet *uni_setup_dma(vmeDmaPacket_t * vmeDma)
+{
+	vmeDmaPacket_t *vmeCur;
+	int maxPerPage;
+	int currentLLcount;
+	TDMA_Cmd_Packet *startLL;
+	TDMA_Cmd_Packet *currentLL;
+	TDMA_Cmd_Packet *nextLL;
+	unsigned int dctlreg = 0;
+
+	maxPerPage = PAGESIZE / sizeof(TDMA_Cmd_Packet) - 1;
+	startLL = (TDMA_Cmd_Packet *) __get_free_pages(GFP_KERNEL, 0);
+	if (startLL == 0) {
+		return (startLL);
+	}
+	// First allocate pages for descriptors and create linked list
+	vmeCur = vmeDma;
+	currentLL = startLL;
+	currentLLcount = 0;
+	while (vmeCur != 0) {
+		if (vmeCur->pNextPacket != 0) {
+			currentLL->dcpp = (unsigned int)(currentLL + 1);
+			currentLLcount++;
+			if (currentLLcount >= maxPerPage) {
+				currentLL->dcpp =
+				    __get_free_pages(GFP_KERNEL, 0);
+				currentLLcount = 0;
+			}
+			currentLL = (TDMA_Cmd_Packet *) currentLL->dcpp;
+		} else {
+			currentLL->dcpp = (unsigned int)0;
+		}
+		vmeCur = vmeCur->pNextPacket;
+	}
+
+	// Next fill in information for each descriptor
+	vmeCur = vmeDma;
+	currentLL = startLL;
+	while (vmeCur != 0) {
+		if (vmeCur->srcBus == VME_DMA_VME) {
+			writel(vmeCur->srcAddr, &currentLL->dva);
+			writel(vmeCur->dstAddr, &currentLL->dlv);
+		} else {
+			writel(vmeCur->srcAddr, &currentLL->dlv);
+			writel(vmeCur->dstAddr, &currentLL->dva);
+		}
+		uniSetupDctlReg(vmeCur, &dctlreg);
+		writel(dctlreg, &currentLL->dctl);
+		writel(vmeCur->byteCount, &currentLL->dtbc);
+
+		currentLL = (TDMA_Cmd_Packet *) currentLL->dcpp;
+		vmeCur = vmeCur->pNextPacket;
+	}
+
+	// Convert Links to PCI addresses.
+	currentLL = startLL;
+	while (currentLL != 0) {
+		nextLL = (TDMA_Cmd_Packet *) currentLL->dcpp;
+		if (nextLL == 0) {
+			writel(1, &currentLL->dcpp);
+		} else {
+			writel((unsigned int)virt_to_bus(nextLL),
+			       &currentLL->dcpp);
+		}
+		currentLL = nextLL;
+	}
+
+	// Return pointer to descriptors list
+	return (startLL);
+}
+
+//-----------------------------------------------------------------------------
+// Function   : uni_free_dma
+// Description:
+//-----------------------------------------------------------------------------
+int uni_free_dma(TDMA_Cmd_Packet * startLL)
+{
+	TDMA_Cmd_Packet *currentLL;
+	TDMA_Cmd_Packet *prevLL;
+	TDMA_Cmd_Packet *nextLL;
+	unsigned int dcppreg;
+
+	// Convert Links to virtual addresses.
+	currentLL = startLL;
+	while (currentLL != 0) {
+		dcppreg = readl(&currentLL->dcpp);
+		dcppreg &= ~6;
+		if (dcppreg & 1) {
+			currentLL->dcpp = 0;
+		} else {
+			currentLL->dcpp = (unsigned int)bus_to_virt(dcppreg);
+		}
+		currentLL = (TDMA_Cmd_Packet *) currentLL->dcpp;
+	}
+
+	// Free all pages associated with the descriptors.
+	currentLL = startLL;
+	prevLL = currentLL;
+	while (currentLL != 0) {
+		nextLL = (TDMA_Cmd_Packet *) currentLL->dcpp;
+		if (currentLL + 1 != nextLL) {
+			free_pages((int)prevLL, 0);
+			prevLL = nextLL;
+		}
+		currentLL = nextLL;
+	}
+
+	// Return pointer to descriptors list
+	return (0);
+}
+
+//-----------------------------------------------------------------------------
+// Function   : uni_do_dma
+// Description:
+//-----------------------------------------------------------------------------
+int uni_do_dma(vmeDmaPacket_t * vmeDma)
+{
+	unsigned int dgcsreg = 0;
+	unsigned int dctlreg = 0;
+	int val;
+	int channel, x;
+	vmeDmaPacket_t *curDma;
+	TDMA_Cmd_Packet *dmaLL;
+
+	// Sanity check the VME chain.
+	channel = vmeDma->channel_number;
+	if (channel > 0) {
+		return (-EINVAL);
+	}
+	curDma = vmeDma;
+	while (curDma != 0) {
+		if (curDma->byteCount == 0) {
+			return (-EINVAL);
+		}
+		if (curDma->byteCount >= 0x1000000) {
+			return (-EINVAL);
+		}
+		if ((curDma->srcAddr & 7) != (curDma->dstAddr & 7)) {
+			return (-EINVAL);
+		}
+		switch (curDma->srcBus) {
+		case VME_DMA_PCI:
+			if (curDma->dstBus != VME_DMA_VME) {
+				return (-EINVAL);
+			}
+			break;
+		case VME_DMA_VME:
+			if (curDma->dstBus != VME_DMA_PCI) {
+				return (-EINVAL);
+			}
+			break;
+		default:
+			return (-EINVAL);
+			break;
+		}
+		if (uniSetupDctlReg(curDma, &dctlreg) < 0) {
+			return (-EINVAL);
+		}
+
+		curDma = curDma->pNextPacket;
+		if (curDma == vmeDma) {	// Endless Loop!
+			return (-EINVAL);
+		}
+	}
+
+	// calculate control register
+	if (vmeDma->pNextPacket != 0) {
+		dgcsreg = 0x8000000;
+	} else {
+		dgcsreg = 0;
+	}
+
+	for (x = 0; x < 8; x++) {	// vme block size
+		if ((256 << x) >= vmeDma->maxVmeBlockSize) {
+			break;
+		}
+	}
+	if (x == 8)
+		x = 7;
+	dgcsreg |= (x << 20);
+
+	if (vmeDma->vmeBackOffTimer) {
+		for (x = 1; x < 8; x++) {	// vme timer
+			if ((16 << (x - 1)) >= vmeDma->vmeBackOffTimer) {
+				break;
+			}
+		}
+		if (x == 8)
+			x = 7;
+		dgcsreg |= (x << 16);
+	}
+	// Setup the dma chain
+	dmaLL = uni_setup_dma(vmeDma);
+
+	// Start the DMA
+	if (dgcsreg & 0x8000000) {
+		vmeDma->vmeDmaStartTick =
+		    uni_start_dma(channel, dgcsreg,
+				  (TDMA_Cmd_Packet *) virt_to_phys(dmaLL));
+	} else {
+		vmeDma->vmeDmaStartTick =
+		    uni_start_dma(channel, dgcsreg, dmaLL);
+	}
+
+	wait_event_interruptible(dma_queue[0],
+				 readl(vmechip_baseaddr + DGCS) & 0x800);
+
+	val = readl(vmechip_baseaddr + DGCS);
+	writel(val | 0xF00, vmechip_baseaddr + DGCS);
+
+	vmeDma->vmeDmaStatus = 0;
+	vmeDma->vmeDmaStopTick = uni_dma_irq_time;
+	if (vmeDma->vmeDmaStopTick < vmeDma->vmeDmaStartTick) {
+		vmeDma->vmeDmaElapsedTime =
+		    (0xFFFFFFFF - vmeDma->vmeDmaStartTick) +
+		    vmeDma->vmeDmaStopTick;
+	} else {
+		vmeDma->vmeDmaElapsedTime =
+		    vmeDma->vmeDmaStopTick - vmeDma->vmeDmaStartTick;
+	}
+	vmeDma->vmeDmaElapsedTime -= vmechip_irq_overhead_ticks;
+	vmeDma->vmeDmaElapsedTime /= (tb_speed / 1000000);
+
+	if (!(val & 0x00000800)) {
+		vmeDma->vmeDmaStatus = val & 0x700;
+		printk(KERN_ERR
+		       "ca91c042: DMA Error in DMA_uni_irqhandler DGCS=%08X\n",
+		       val);
+		val = readl(vmechip_baseaddr + DCPP);
+		printk(KERN_ERR "ca91c042: DCPP=%08X\n", val);
+		val = readl(vmechip_baseaddr + DCTL);
+		printk(KERN_ERR "ca91c042: DCTL=%08X\n", val);
+		val = readl(vmechip_baseaddr + DTBC);
+		printk(KERN_ERR "ca91c042: DTBC=%08X\n", val);
+		val = readl(vmechip_baseaddr + DLA);
+		printk(KERN_ERR "ca91c042: DLA=%08X\n", val);
+		val = readl(vmechip_baseaddr + DVA);
+		printk(KERN_ERR "ca91c042: DVA=%08X\n", val);
+
+	}
+	// Free the dma chain
+	uni_free_dma(dmaLL);
+
+	return (0);
+}
+
+//-----------------------------------------------------------------------------
+// Function   : uni_shutdown
+// Description: Put VME bridge in quiescent state.
+//-----------------------------------------------------------------------------
+void uni_shutdown(void)
+{
+	writel(0, vmechip_baseaddr + LINT_EN);	// Turn off Ints
+
+	// Turn off the windows
+	writel(0x00800000, vmechip_baseaddr + LSI0_CTL);
+	writel(0x00800000, vmechip_baseaddr + LSI1_CTL);
+	writel(0x00800000, vmechip_baseaddr + LSI2_CTL);
+	writel(0x00800000, vmechip_baseaddr + LSI3_CTL);
+	writel(0x00F00000, vmechip_baseaddr + VSI0_CTL);
+	writel(0x00F00000, vmechip_baseaddr + VSI1_CTL);
+	writel(0x00F00000, vmechip_baseaddr + VSI2_CTL);
+	writel(0x00F00000, vmechip_baseaddr + VSI3_CTL);
+	if (vmechip_revision >= 2) {
+		writel(0x00800000, vmechip_baseaddr + LSI4_CTL);
+		writel(0x00800000, vmechip_baseaddr + LSI5_CTL);
+		writel(0x00800000, vmechip_baseaddr + LSI6_CTL);
+		writel(0x00800000, vmechip_baseaddr + LSI7_CTL);
+		writel(0x00F00000, vmechip_baseaddr + VSI4_CTL);
+		writel(0x00F00000, vmechip_baseaddr + VSI5_CTL);
+		writel(0x00F00000, vmechip_baseaddr + VSI6_CTL);
+		writel(0x00F00000, vmechip_baseaddr + VSI7_CTL);
+	}
+}
+
+//-----------------------------------------------------------------------------
+// Function   : uni_init()
+// Description:
+//-----------------------------------------------------------------------------
+int uni_init(void)
+{
+	int result;
+	unsigned int tmp;
+	unsigned int crcsr_addr;
+	unsigned int irqOverHeadStart;
+	int overHeadTicks;
+
+	uni_shutdown();
+
+	// Write to Misc Register
+	// Set VME Bus Time-out
+	//   Arbitration Mode
+	//   DTACK Enable
+	tmp = readl(vmechip_baseaddr + MISC_CTL) & 0x0832BFFF;
+	tmp |= 0x76040000;
+	writel(tmp, vmechip_baseaddr + MISC_CTL);
+	if (tmp & 0x20000) {
+		vme_syscon = 1;
+	} else {
+		vme_syscon = 0;
+	}
+
+	// Clear DMA status log
+	writel(0x00000F00, vmechip_baseaddr + DGCS);
+	// Clear and enable error log
+	writel(0x00800000, vmechip_baseaddr + L_CMDERR);
+	// Turn off location monitor
+	writel(0x00000000, vmechip_baseaddr + LM_CTL);
+
+	// Initialize crcsr map
+	if (vme_slotnum != -1) {
+		writel(vme_slotnum << 27, vmechip_baseaddr + VCSR_BS);
+	}
+	crcsr_addr = readl(vmechip_baseaddr + VCSR_BS) >> 8;
+	writel((unsigned int)vmechip_interboard_datap - crcsr_addr,
+	       vmechip_baseaddr + VCSR_TO);
+	if (vme_slotnum != -1) {
+		writel(0x80000000, vmechip_baseaddr + VCSR_CTL);
+	}
+	// Turn off interrupts
+	writel(0x00000000, vmechip_baseaddr + LINT_EN);	// Disable interrupts in the Universe first
+	writel(0x00FFFFFF, vmechip_baseaddr + LINT_STAT);	// Clear Any Pending Interrupts
+	writel(0x00000000, vmechip_baseaddr + VINT_EN);	// Disable interrupts in the Universe first
+
+	result =
+	    request_irq(vmechip_irq, uni_irqhandler, IRQF_SHARED | IRQF_DISABLED,
+			"VMEBus (ca91c042)", vmechip_baseaddr);
+	if (result) {
+		printk(KERN_ERR
+		       "ca91c042: can't get assigned pci irq vector %02X\n",
+		       vmechip_irq);
+		return (0);
+	} else {
+		writel(0x0000, vmechip_baseaddr + LINT_MAP0);	// Map all ints to 0
+		writel(0x0000, vmechip_baseaddr + LINT_MAP1);	// Map all ints to 0
+		writel(0x0000, vmechip_baseaddr + LINT_MAP2);	// Map all ints to 0
+	}
+
+	// Enable DMA, mailbox, VIRQ & LM Interrupts
+	if (vme_syscon)
+		tmp = 0x00FF07FE;
+	else
+		tmp = 0x00FF0700;
+	writel(tmp, vmechip_baseaddr + LINT_EN);
+
+	// Do a quick sanity test of the bridge
+	if (readl(vmechip_baseaddr + LINT_EN) != tmp) {
+		return (0);
+	}
+	if (readl(vmechip_baseaddr + PCI_CLASS_REVISION) != 0x06800002) {
+		return (0);
+	}
+	for (tmp = 1; tmp < 0x80000000; tmp = tmp << 1) {
+		writel(tmp, vmechip_baseaddr + SCYC_EN);
+		writel(~tmp, vmechip_baseaddr + SCYC_CMP);
+		if (readl(vmechip_baseaddr + SCYC_EN) != tmp) {
+			return (0);
+		}
+		if (readl(vmechip_baseaddr + SCYC_CMP) != ~tmp) {
+			return (0);
+		}
+	}
+
+	// do a mail box interrupt to calibrate the interrupt overhead.
+
+	irqOverHeadStart = get_tbl();
+	writel(0, vmechip_baseaddr + MBOX1);
+	for (tmp = 0; tmp < 10; tmp++) {
+	}
+
+	irqOverHeadStart = get_tbl();
+	writel(0, vmechip_baseaddr + MBOX1);
+	for (tmp = 0; tmp < 10; tmp++) {
+	}
+
+	overHeadTicks = uni_irq_time - irqOverHeadStart;
+	if (overHeadTicks > 0) {
+		vmechip_irq_overhead_ticks = overHeadTicks;
+	} else {
+		vmechip_irq_overhead_ticks = 1;
+	}
+	return (1);
+}
--- /dev/null
+++ b/drivers/staging/vme/bridges/vme_ca91cx42.h
@@ -0,0 +1,403 @@
+/*
+ * ca91c042.h
+ *
+ * Support for the Tundra Universe 1 and Universe II VME bridge chips
+ *
+ * Author: Tom Armistead
+ * Updated and maintained by Ajit Prem
+ * Copyright 2004 Motorola Inc.
+ *
+ * Derived from ca91c042.h by Michael Wyrick
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#ifndef _ca91c042_h
+#define _ca91c042_h
+
+#ifndef	PCI_VENDOR_ID_TUNDRA
+#define	PCI_VENDOR_ID_TUNDRA 0x10e3
+#endif
+
+#ifndef	PCI_DEVICE_ID_TUNDRA_CA91C042
+#define	PCI_DEVICE_ID_TUNDRA_CA91C042 0x0000
+#endif
+
+//-----------------------------------------------------------------------------
+// Public Functions
+//-----------------------------------------------------------------------------
+// This is the typedef for a VmeIrqHandler
+typedef void (*TirqHandler) (int vmeirq, int vector, void *dev_id,
+			     struct pt_regs * regs);
+// This is the typedef for a DMA Transfer Callback function
+typedef void (*TDMAcallback) (int status);
+
+//  Returns the PCI baseaddress of the Universe chip
+char *Universe_BaseAddr(void);
+//  Returns the PCI IRQ That the universe is using
+int Universe_IRQ(void);
+
+char *mapvme(unsigned int pci, unsigned int vme, unsigned int size,
+	     int image, int ctl);
+void unmapvme(char *ptr, int image);
+
+// Interrupt Stuff
+void enable_vmeirq(unsigned int irq);
+void disable_vmeirq(unsigned int irq);
+int request_vmeirq(unsigned int irq, TirqHandler);
+void free_vmeirq(unsigned int irq);
+
+// DMA Stuff
+
+int VME_Bus_Error(void);
+int uni_procinfo(char *);
+
+#define IRQ_VOWN    0x0001
+#define IRQ_VIRQ1   0x0002
+#define IRQ_VIRQ2   0x0004
+#define IRQ_VIRQ3   0x0008
+#define IRQ_VIRQ4   0x0010
+#define IRQ_VIRQ5   0x0020
+#define IRQ_VIRQ6   0x0040
+#define IRQ_VIRQ7   0x0080
+#define IRQ_DMA     0x0100
+#define IRQ_LERR    0x0200
+#define IRQ_VERR    0x0400
+#define IRQ_res     0x0800
+#define IRQ_IACK    0x1000
+#define IRQ_SWINT   0x2000
+#define IRQ_SYSFAIL 0x4000
+#define IRQ_ACFAIL  0x8000
+
+// See Page 2-77 in the Universe User Manual
+typedef struct {
+	unsigned int dctl;	// DMA Control
+	unsigned int dtbc;	// Transfer Byte Count
+	unsigned int dlv;	// PCI Address
+	unsigned int res1;	// Reserved
+	unsigned int dva;	// Vme Address
+	unsigned int res2;	// Reserved
+	unsigned int dcpp;	// Pointer to Numed Cmd Packet with rPN
+	unsigned int res3;	// Reserved
+} TDMA_Cmd_Packet;
+
+/*
+ * Below here is normaly not used by a user module
+ */
+#define  DMATIMEOUT 2*HZ;
+
+// Define for the Universe
+#define SEEK_SET 0
+#define SEEK_CUR 1
+
+#define CONFIG_REG_SPACE        0xA0000000
+
+/* Universe Register Offsets */
+/* general PCI configuration registers */
+#define UNIV_PCI_ID             0x000
+#define UNIV_PCI_CSR            0x004
+#define UNIV_PCI_CLASS          0x008
+#define UNIV_BM_PCI_CLASS_BASE          0xFF000000
+#define UNIV_OF_PCI_CLASS_BASE          24
+#define UNIV_BM_PCI_CLASS_SUB           0x00FF0000
+#define UNIV_OF_PCI_CLASS_SUB           16
+#define UNIV_BM_PCI_CLASS_PROG          0x0000FF00
+#define UNIV_OF_PCI_CLASS_PROG          8
+#define UNIV_BM_PCI_CLASS_RID           0x000000FF
+#define UNIV_OF_PCI_CLASS_RID           0
+
+#define UNIV_OF_PCI_CLASS_RID_UNIVERSE_I 0
+#define UNIV_OF_PCI_CLASS_RID_UNIVERSE_II 1
+
+#define UNIV_PCI_MISC0          0x00C
+#define UNIV_BM_PCI_MISC0_BISTC         0x80000000
+#define UNIV_BM_PCI_MISC0_SBIST         0x60000000
+#define UNIV_BM_PCI_MISC0_CCODE         0x0F000000
+#define UNIV_BM_PCI_MISC0_MFUNCT        0x00800000
+#define UNIV_BM_PCI_MISC0_LAYOUT        0x007F0000
+#define UNIV_BM_PCI_MISC0_LTIMER        0x0000FF00
+#define UNIV_OF_PCI_MISC0_LTIMER        8
+#define UNIV_PCI_BS             0x010
+#define UNIV_PCI_MISC1          0x03C
+
+#define UNIV_BM_LSI_CTL_EN      0x80000000
+#define UNIV_BM_LSI_CTL_PWEN    0x40000000
+#define UNIV_BM_LSI_CTL_VDW     0x00C00000
+#define UNIV_OF_LSI_CTL_VDW     22
+#define UNIV_BM_LSI_CTL_VAS     0x00070000
+#define UNIV_OF_LSI_CTL_VAS     16
+#define UNIV_BM_LSI_CTL_PGM     0x0000C000
+#define UNIV_OF_LSI_CTL_PGM     14
+#define UNIV_BM_LSI_CTL_SUPER   0x00003000
+#define UNIV_OF_LSI_CTL_SUPER   12
+#define UNIV_BM_LSI_CTL_VCT     0x00000100
+#define UNIV_BM_LSI_CTL_LAS     0x00000003
+#define UNIV_OF_LSI_CTL_LAS     0
+#define UNIV_BM_LSI_CTL_RESERVED (~ (UNIV_BM_LSI_CTL_EN | UNIV_BM_LSI_CTL_PWEN | UNIV_BM_LSI_CTL_VDW | UNIV_BM_LSI_CTL_VAS | UNIV_BM_LSI_CTL_PGM | UNIV_BM_LSI_CTL_SUPER | UNIV_BM_LSI_CTL_VCT | UNIV_BM_LSI_CTL_LAS))
+
+#define PCI_SIZE_8	    0x0001
+#define PCI_SIZE_16	    0x0002
+#define PCI_SIZE_32	    0x0003
+
+#define IOCTL_SET_CTL 	0xF001
+#define IOCTL_SET_BS	0xF002
+#define IOCTL_SET_BD	0xF003
+#define IOCTL_SET_TO	0xF004
+#define IOCTL_PCI_SIZE  0xF005
+#define IOCTL_SET_MODE 	0xF006
+#define IOCTL_SET_WINT  0xF007	// Wait for interrupt before read
+
+#define LSI0_CTL	0x0100
+#define LSI0_BS		0x0104
+#define LSI0_BD		0x0108
+#define LSI0_TO		0x010C
+
+#define LSI1_CTL	      0x0114
+#define LSI1_BS		      0x0118
+#define LSI1_BD		      0x011C
+#define LSI1_TO		      0x0120
+
+#define LSI2_CTL	      0x0128
+#define LSI2_BS		      0x012C
+#define LSI2_BD		      0x0130
+#define LSI2_TO		      0x0134
+
+#define LSI3_CTL	      0x013C
+#define LSI3_BS		      0x0140
+#define LSI3_BD		      0x0144
+#define LSI3_TO		      0x0148
+
+#define LSI4_CTL	      0x01A0
+#define LSI4_BS		      0x01A4
+#define LSI4_BD		      0x01A8
+#define LSI4_TO		      0x01AC
+
+#define LSI5_CTL	      0x01B4
+#define LSI5_BS		      0x01B8
+#define LSI5_BD		      0x01BC
+#define LSI5_TO		      0x01C0
+
+#define LSI6_CTL	      0x01C8
+#define LSI6_BS		      0x01CC
+#define LSI6_BD		      0x01D0
+#define LSI6_TO		      0x01D4
+
+#define LSI7_CTL	      0x01DC
+#define LSI7_BS		      0x01E0
+#define LSI7_BD		      0x01E4
+#define LSI7_TO		      0x01E8
+
+#define SCYC_CTL		0x0170
+#define SCYC_ADDR		0x0174
+#define SCYC_EN			0x0178
+#define SCYC_CMP		0x017C
+#define SCYC_SWP		0x0180
+#define LMISC			0x0184
+#define UNIV_BM_LMISC_CRT               0xF0000000
+#define UNIV_OF_LMISC_CRT               28
+#define UNIV_BM_LMISC_CWT               0x0F000000
+#define UNIV_OF_LMISC_CWT               24
+#define SLSI		        0x0188
+#define UNIV_BM_SLSI_EN                 0x80000000
+#define UNIV_BM_SLSI_PWEN               0x40000000
+#define UNIV_BM_SLSI_VDW                0x00F00000
+#define UNIV_OF_SLSI_VDW                20
+#define UNIV_BM_SLSI_PGM                0x0000F000
+#define UNIV_OF_SLSI_PGM                12
+#define UNIV_BM_SLSI_SUPER              0x00000F00
+#define UNIV_OF_SLSI_SUPER              8
+#define UNIV_BM_SLSI_BS                 0x000000F6
+#define UNIV_OF_SLSI_BS                 2
+#define UNIV_BM_SLSI_LAS                0x00000003
+#define UNIV_OF_SLSI_LAS                0
+#define UNIV_BM_SLSI_RESERVED           0x3F0F0000
+#define L_CMDERR		0x018C
+#define LAERR		        0x0190
+
+#define DCTL		        0x0200
+#define DTBC		        0x0204
+#define DLA			0x0208
+#define DVA			0x0210
+#define DCPP		        0x0218
+#define DGCS		        0x0220
+#define D_LLUE			0x0224
+
+#define LINT_EN		      0x0300
+#define UNIV_BM_LINT_ACFAIL             0x00008000
+#define UNIV_BM_LINT_SYSFAIL            0x00004000
+#define UNIV_BM_LINT_SW_INT             0x00002000
+#define UNIV_BM_LINT_SW_IACK            0x00001000
+#define UNIV_BM_LINT_VERR               0x00000400
+#define UNIV_BM_LINT_LERR               0x00000200
+#define UNIV_BM_LINT_DMA                0x00000100
+#define UNIV_BM_LINT_LM                 0x00F00000
+#define UNIV_BM_LINT_MBOX               0x000F0000
+#define UNIV_BM_LINT_VIRQ               0x000000FE
+#define UNIV_BM_LINT_VIRQ7              0x00000080
+#define UNIV_BM_LINT_VIRQ6              0x00000040
+#define UNIV_BM_LINT_VIRQ5              0x00000020
+#define UNIV_BM_LINT_VIRQ4              0x00000010
+#define UNIV_BM_LINT_VIRQ3              0x00000008
+#define UNIV_BM_LINT_VIRQ2              0x00000004
+#define UNIV_BM_LINT_VIRQ1              0x00000002
+#define UNIV_BM_LINT_VOWN               0x00000001
+#define LINT_STAT	      0x0304
+#define LINT_MAP0	      0x0308
+#define LINT_MAP1	      0x030C
+#define VINT_EN		      0x0310
+#define VINT_STAT	      0x0314
+#define VINT_MAP0	      0x0318
+#define VINT_MAP1	      0x031C
+#define STATID		      0x0320
+#define V1_STATID	      0x0324
+#define V2_STATID	      0x0328
+#define V3_STATID	      0x032C
+#define V4_STATID	      0x0330
+#define V5_STATID	      0x0334
+#define V6_STATID	      0x0338
+#define V7_STATID	      0x033C
+#define LINT_MAP2	      0x0340
+#define VINT_MAP2	      0x0344
+
+#define MBOX0	              0x0348
+#define MBOX1	              0x034C
+#define MBOX2		      0x0350
+#define MBOX3		      0x0354
+#define SEMA0		      0x0358
+#define SEMA1		      0x035C
+
+#define MAST_CTL	      0x0400
+#define UNIV_BM_MAST_CTL_MAXRTRY        0xF0000000
+#define UNIV_OF_MAST_CTL_MAXRTRY        28
+#define UNIV_BM_MAST_CTL_PWON           0x0F000000
+#define UNIV_OF_MAST_CTL_PWON           24
+#define UNIV_BM_MAST_CTL_VRL            0x00C00000
+#define UNIV_OF_MAST_CTL_VRL            22
+#define UNIV_BM_MAST_CTL_VRM            0x00200000
+#define UNIV_BM_MAST_CTL_VREL           0x00100000
+#define UNIV_BM_MAST_CTL_VOWN           0x00080000
+#define UNIV_BM_MAST_CTL_VOWN_ACK       0x00040000
+#define UNIV_BM_MAST_CTL_PABS           0x00001000
+#define UNIV_BM_MAST_CTL_BUS_NO         0x0000000F
+#define UNIV_OF_MAST_CTL_BUS_NO         0
+
+#define MISC_CTL	      0x0404
+#define UNIV_BM_MISC_CTL_VBTO           0xF0000000
+#define UNIV_OF_MISC_CTL_VBTO           28
+#define UNIV_BM_MISC_CTL_VARB           0x04000000
+#define UNIV_BM_MISC_CTL_VARBTO         0x03000000
+#define UNIV_OF_MISC_CTL_VARBTO         24
+#define UNIV_BM_MISC_CTL_SW_LRST        0x00800000
+#define UNIV_BM_MISC_CTL_SW_SRST        0x00400000
+#define UNIV_BM_MISC_CTL_BI             0x00100000
+#define UNIV_BM_MISC_CTL_ENGBI          0x00080000
+#define UNIV_BM_MISC_CTL_RESCIND        0x00040000
+#define UNIV_BM_MISC_CTL_SYSCON         0x00020000
+#define UNIV_BM_MISC_CTL_V64AUTO        0x00010000
+#define UNIV_BM_MISC_CTL_RESERVED       0x0820FFFF
+
+#define MISC_STAT	      0x0408
+#define UNIV_BM_MISC_STAT_ENDIAN        0x80000000
+#define UNIV_BM_MISC_STAT_LCLSIZE       0x40000000
+#define UNIV_BM_MISC_STAT_DY4AUTO       0x08000000
+#define UNIV_BM_MISC_STAT_MYBBSY        0x00200000
+#define UNIV_BM_MISC_STAT_DY4DONE       0x00080000
+#define UNIV_BM_MISC_STAT_TXFE          0x00040000
+#define UNIV_BM_MISC_STAT_RXFE          0x00020000
+#define UNIV_BM_MISC_STAT_DY4AUTOID     0x0000FF00
+#define UNIV_OF_MISC_STAT_DY4AUTOID     8
+
+#define USER_AM		      0x040C
+
+#define VSI0_CTL	      0x0F00
+#define VSI0_BS		      0x0F04
+#define VSI0_BD		      0x0F08
+#define VSI0_TO		      0x0F0C
+
+#define VSI1_CTL	      0x0F14
+#define VSI1_BS		      0x0F18
+#define VSI1_BD		      0x0F1C
+#define VSI1_TO		      0x0F20
+
+#define VSI2_CTL	      0x0F28
+#define VSI2_BS		      0x0F2C
+#define VSI2_BD		      0x0F30
+#define VSI2_TO		      0x0F34
+
+#define VSI3_CTL	      0x0F3C
+#define VSI3_BS		      0x0F40
+#define VSI3_BD		      0x0F44
+#define VSI3_TO		      0x0F48
+
+#define LM_CTL		      0x0F64
+#define LM_BS		      0x0F68
+
+#define VRAI_CTL	      0x0F70
+#define UNIV_BM_VRAI_CTL_EN             0x80000000
+#define UNIV_BM_VRAI_CTL_PGM            0x00C00000
+#define UNIV_OF_VRAI_CTL_PGM            22
+#define UNIV_BM_VRAI_CTL_SUPER          0x00300000
+#define UNIV_OF_VRAI_CTL_SUPER          20
+#define UNIV_BM_VRAI_CTL_VAS            0x00030000
+#define UNIV_OF_VRAI_CTL_VAS            16
+
+#define VRAI_BS		      0x0F74
+#define VCSR_CTL	      0x0F80
+#define VCSR_TO		      0x0F84
+#define V_AMERR		      0x0F88
+#define VAERR			0x0F8C
+
+#define VSI4_CTL	      0x0F90
+#define VSI4_BS		      0x0F94
+#define VSI4_BD		      0x0F98
+#define VSI4_TO		      0x0F9C
+
+#define VSI5_CTL	      0x0FA4
+#define VSI5_BS		      0x0FA8
+#define VSI5_BD		      0x0FAC
+#define VSI5_TO		      0x0FB0
+
+#define VSI6_CTL	      0x0FB8
+#define VSI6_BS		      0x0FBC
+#define VSI6_BD		      0x0FC0
+#define VSI6_TO		      0x0FC4
+
+#define VSI7_CTL	      0x0FCC
+#define VSI7_BS		      0x0FD0
+#define VSI7_BD		      0x0FD4
+#define VSI7_TO		      0x0FD8
+
+#define VCSR_CLR	      0x0FF4
+#define VCSR_SET	      0x0FF8
+#define VCSR_BS		      0x0FFC
+
+// DMA General Control/Status Register DGCS (0x220)
+// 32-24 ||  GO   | STOPR | HALTR |   0   || CHAIN |   0   |   0   |   0   ||
+// 23-16 ||              VON              ||             VOFF              ||
+// 15-08 ||  ACT  | STOP  | HALT  |   0   || DONE  | LERR  | VERR  | P_ERR ||
+// 07-00 ||   0   | INT_S | INT_H |   0   || I_DNE | I_LER | I_VER | I_PER ||
+
+// VON - Length Per DMA VMEBus Transfer
+//  0000 = None
+//  0001 = 256 Bytes
+//  0010 = 512
+//  0011 = 1024
+//  0100 = 2048
+//  0101 = 4096
+//  0110 = 8192
+//  0111 = 16384
+
+// VOFF - wait between DMA tenures
+//  0000 = 0    us
+//  0001 = 16
+//  0010 = 32
+//  0011 = 64
+//  0100 = 128
+//  0101 = 256
+//  0110 = 512
+//  0111 = 1024
+
+#endif				/* _ca91c042_h */
--- a/drivers/staging/vme/Kconfig
+++ b/drivers/staging/vme/Kconfig
@@ -10,7 +10,7 @@ menuconfig VME
 
 if VME
 
-#source "drivers/staging/vme/bridges/Kconfig"
+source "drivers/staging/vme/bridges/Kconfig"
 
 source "drivers/staging/vme/devices/Kconfig"
 
--- a/drivers/staging/vme/Makefile
+++ b/drivers/staging/vme/Makefile
@@ -3,5 +3,5 @@
 #
 obj-$(CONFIG_VME)		+= vme.o
 
-#obj-y				+= bridges/
+obj-y				+= bridges/
 obj-y				+= devices/


  parent reply	other threads:[~2009-08-03 21:02 UTC|newest]

Thread overview: 65+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20090803205657.964064732@mini.kroah.org>
2009-08-03 21:00 ` [patch 0/5] [ANNOUNCE] VME Bus drivers and framework for Linux Greg K-H
2009-08-03 21:01   ` [patch 1/5] Staging: VME Framework for the Linux Kernel Greg K-H
2009-08-08 23:01     ` Emilio G. Cota
2009-08-10 12:44       ` Martyn Welch
2009-08-10 14:14         ` Emilio G. Cota
2009-08-10 15:31           ` Emilio G. Cota
2009-08-10 16:40             ` Martyn Welch
2009-08-10 19:50               ` Emilio G. Cota
2009-08-11  8:02                 ` Martyn Welch
2009-08-11  8:43                   ` Emilio G. Cota
2009-08-10 15:53           ` Martyn Welch
2009-08-10 16:26             ` Shawn Bohrer
2009-08-10 19:38             ` Emilio G. Cota
2009-08-11  8:29               ` Martyn Welch
2009-08-11 14:49                 ` Emilio G. Cota
2009-08-11 15:10                   ` Martyn Welch
2009-08-11 15:36                     ` Emilio G. Cota
2009-08-11 15:41                       ` Martyn Welch
2009-08-11 15:42                         ` Emilio G. Cota
2009-08-11 16:38                           ` Martyn Welch
2009-08-11 20:48                             ` Emilio G. Cota
2009-08-12  9:54                             ` Emilio G. Cota
2009-08-12  9:59                               ` Martyn Welch
2009-08-12 10:09                                 ` Emilio G. Cota
2009-08-12 10:19                                   ` Martyn Welch
2009-08-11  4:54         ` Mike Frysinger
2009-08-11  7:48           ` Martyn Welch
2009-08-10 16:30       ` Greg KH
2009-08-10 14:52     ` [PATCH] Staging: vme: fix {master,slave}_get check bug Emilio G. Cota
2009-08-10 16:50       ` Martyn Welch
2009-08-03 21:01   ` [patch 2/5] Staging: vme: add VME userspace driver Greg K-H
2009-08-08 23:22     ` Emilio G. Cota
2009-08-09 12:17       ` Emilio G. Cota
2009-08-10 13:13         ` Martyn Welch
2009-08-10 15:26           ` Emilio G. Cota
2009-08-10 16:29             ` Greg KH
2009-08-10 16:30             ` Martyn Welch
2009-08-10 20:36               ` Emilio G. Cota
2009-08-11  9:03                 ` Martyn Welch
2009-08-11  9:40                   ` Emilio G. Cota
2009-08-11 12:46                     ` Martyn Welch
2009-08-11 21:01                       ` Emilio G. Cota
2009-08-12  8:17                         ` Martyn Welch
2009-08-12  9:39                           ` Emilio G. Cota
2009-08-12  9:57                             ` Martyn Welch
2009-08-12 11:20                               ` Emilio G. Cota
2009-08-12 12:19                                 ` Martyn Welch
2009-08-10 16:28         ` Greg KH
2009-08-10 20:05           ` Emilio G. Cota
2009-08-10 21:09             ` Greg KH
2009-08-11  7:04               ` Emilio G. Cota
2009-08-03 21:01   ` Greg K-H [this message]
2009-08-03 23:00     ` [patch 3/5] Staging: vme: add Universe I/II bridge driver Jiri Slaby
2009-08-03 21:01   ` [patch 4/5] Staging: vme: add Tundra TSI148 VME-PCI Bridge driver Greg K-H
2009-08-03 22:50     ` Jiri Slaby
2009-08-03 22:55       ` Jiri Slaby
2009-08-05 16:33       ` [PATCH] Staging: Correct tsi-148 VME interrupt free routine Martyn Welch
2009-08-05 16:38         ` [PATCH v2] " Martyn Welch
2009-08-05 21:53           ` Jiri Slaby
2009-08-06  7:20             ` Martyn Welch
2009-08-09  0:09     ` [patch 4/5] Staging: vme: add Tundra TSI148 VME-PCI Bridge driver Emilio G. Cota
2009-08-11 14:59       ` [patch 4/5] Staging: vme: add Tundra TSI148 VME-PCI Bridgedriver Martyn Welch
2009-08-03 21:01   ` [patch 5/5] Staging: vme: add TODO file Greg K-H
2009-08-04  7:56   ` [patch 0/5] [ANNOUNCE] VME Bus drivers and framework for Linux Martyn Welch
2009-08-08 22:25   ` Emilio G. Cota

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20090803210118.GD28430@kroah.com \
    --to=gregkh@suse.de \
    --cc=devel@driverdev.osuosl.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=martyn.welch@gefanuc.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.