/*
 * iSeries_pci.c
 *
 * Copyright (C) 2001 Allan Trautman, IBM Corporation
 *
 * iSeries specific routines for PCI.
 * 
 * Based on code from pci.c and iSeries_pci.c 32bit
 *
 * 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.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 */
#include <linux/kernel.h>
#include <linux/list.h> 
#include <linux/string.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/ide.h>
#include <linux/pci.h>

#include <asm/io.h>
#include <asm/irq.h>
#include <asm/prom.h>
#include <asm/machdep.h>
#include <asm/pci-bridge.h>
#include <asm/ppcdebug.h>
#include <asm/iommu.h>

#include <asm/iSeries/HvCallPci.h>
#include <asm/iSeries/HvCallXm.h>
#include <asm/iSeries/iSeries_irq.h>
#include <asm/iSeries/iSeries_pci.h>
#include <asm/iSeries/mf.h>

#include "pci.h"

extern unsigned long io_page_mask;

/*
 * Forward declares of prototypes. 
 */
static struct iSeries_Device_Node *find_Device_Node(int bus, int devfn);
static void scan_PHB_slots(struct pci_controller *Phb);
static void scan_EADS_bridge(HvBusNumber Bus, HvSubBusNumber SubBus, int IdSel);
static int scan_bridge_slot(HvBusNumber Bus, struct HvCallPci_BridgeInfo *Info);

LIST_HEAD(iSeries_Global_Device_List);

static int DeviceCount;

/* Counters and control flags. */
static long Pci_Io_Read_Count;
static long Pci_Io_Write_Count;
#if 0
static long Pci_Cfg_Read_Count;
static long Pci_Cfg_Write_Count;
#endif
static long Pci_Error_Count;

static int Pci_Retry_Max = 3;	/* Only retry 3 times  */	
static int Pci_Error_Flag = 1;	/* Set Retry Error on. */

static struct pci_ops iSeries_pci_ops;

/*
 * Table defines
 * Each Entry size is 4 MB * 1024 Entries = 4GB I/O address space.
 */
#define IOMM_TABLE_MAX_ENTRIES	1024
#define IOMM_TABLE_ENTRY_SIZE	0x0000000000400000UL
#define BASE_IO_MEMORY		0xE000000000000000UL

static unsigned long max_io_memory = 0xE000000000000000UL;
static long current_iomm_table_entry;

/*
 * Lookup Tables.
 */
static struct iSeries_Device_Node **iomm_table;
static u8 *iobar_table;

/*
 * Static and Global variables
 */
static char *pci_io_text = "iSeries PCI I/O";
static DEFINE_SPINLOCK(iomm_table_lock);

/*
 * iomm_table_initialize
 *
 * Allocates and initalizes the Address Translation Table and Bar
 * Tables to get them ready for use.  Must be called before any
 * I/O space is handed out to the device BARs.
 */
static void iomm_table_initialize(void)
{
	spin_lock(&iomm_table_lock);
	iomm_table = kmalloc(sizeof(*iomm_table) * IOMM_TABLE_MAX_ENTRIES,
			GFP_KERNEL);
	iobar_table = kmalloc(sizeof(*iobar_table) * IOMM_TABLE_MAX_ENTRIES,
			GFP_KERNEL);
	spin_unlock(&iomm_table_lock);
	if ((iomm_table == NULL) || (iobar_table == NULL))
		panic("PCI: I/O tables allocation failed.\n");
}

/*
 * iomm_table_allocate_entry
 *
 * Adds pci_dev entry in address translation table
 *
 * - Allocates the number of entries required in table base on BAR
 *   size.
 * - Allocates starting at BASE_IO_MEMORY and increases.
 * - The size is round up to be a multiple of entry size.
 * - CurrentIndex is incremented to keep track of the last entry.
 * - Builds the resource entry for allocated BARs.
 */
static void iomm_table_allocate_entry(struct pci_dev *dev, int bar_num)
{
	struct resource *bar_res = &dev->resource[bar_num];
	long bar_size = pci_resource_len(dev, bar_num);

	/*
	 * No space to allocate, quick exit, skip Allocation.
	 */
	if (bar_size == 0)
		return;
	/*
	 * Set Resource values.
	 */
	spin_lock(&iomm_table_lock);
	bar_res->name = pci_io_text;
	bar_res->start =
		IOMM_TABLE_ENTRY_SIZE * current_iomm_table_entry;
	bar_res->start += BASE_IO_MEMORY;
	bar_res->end = bar_res->start + bar_size - 1;
	/*
	 * Allocate the number of table entries needed for BAR.
	 */
	while (bar_size > 0 ) {
		iomm_table[current_iomm_table_entry] = dev->sysdata;
		iobar_table[current_iomm_table_entry] = bar_num;
		bar_size -= IOMM_TABLE_ENTRY_SIZE;
		++current_iomm_table_entry;
	}
	max_io_memory = BASE_IO_MEMORY +
		(IOMM_TABLE_ENTRY_SIZE * current_iomm_table_entry);
	spin_unlock(&iomm_table_lock);
}

/*
 * allocate_device_bars
 *
 * - Allocates ALL pci_dev BAR's and updates the resources with the
 *   BAR value.  BARS with zero length will have the resources
 *   The HvCallPci_getBarParms is used to get the size of the BAR
 *   space.  It calls iomm_table_allocate_entry to allocate
 *   each entry.
 * - Loops through The Bar resources(0 - 5) including the ROM
 *   is resource(6).
 */
static void allocate_device_bars(struct pci_dev *dev)
{
	struct resource *bar_res;
	int bar_num;

	for (bar_num = 0; bar_num <= PCI_ROM_RESOURCE; ++bar_num) {
		bar_res = &dev->resource[bar_num];
		iomm_table_allocate_entry(dev, bar_num);
    	}
}

/*
 * Log error information to system console.
 * Filter out the device not there errors.
 * PCI: EADs Connect Failed 0x18.58.10 Rc: 0x00xx
 * PCI: Read Vendor Failed 0x18.58.10 Rc: 0x00xx
 * PCI: Connect Bus Unit Failed 0x18.58.10 Rc: 0x00xx
 */
static void pci_Log_Error(char *Error_Text, int Bus, int SubBus,
		int AgentId, int HvRc)
{
	if (HvRc == 0x0302)
		return;
	printk(KERN_ERR "PCI: %s Failed: 0x%02X.%02X.%02X Rc: 0x%04X",
	       Error_Text, Bus, SubBus, AgentId, HvRc);
}

/*
 * build_device_node(u16 Bus, int SubBus, u8 DevFn)
 */
static struct iSeries_Device_Node *build_device_node(HvBusNumber Bus,
		HvSubBusNumber SubBus, int AgentId, int Function)
{
	struct iSeries_Device_Node *node;

	PPCDBG(PPCDBG_BUSWALK,
			"-build_device_node 0x%02X.%02X.%02X Function: %02X\n",
			Bus, SubBus, AgentId, Function);

	node = kmalloc(sizeof(struct iSeries_Device_Node), GFP_KERNEL);
	if (node == NULL)
		return NULL;

	memset(node, 0, sizeof(struct iSeries_Device_Node));
	list_add_tail(&node->Device_List, &iSeries_Global_Device_List);
#if 0
	node->DsaAddr = ((u64)Bus << 48) + ((u64)SubBus << 40) + ((u64)0x10 << 32);
#endif
	node->DsaAddr.DsaAddr = 0;
	node->DsaAddr.Dsa.busNumber = Bus;
	node->DsaAddr.Dsa.subBusNumber = SubBus;
	node->DsaAddr.Dsa.deviceId = 0x10;
	node->DevFn = PCI_DEVFN(ISERIES_ENCODE_DEVICE(AgentId), Function);
	return node;
}

/*
 * unsigned long __init find_and_init_phbs(void)
 *
 * Description:
 *   This function checks for all possible system PCI host bridges that connect
 *   PCI buses.  The system hypervisor is queried as to the guest partition
 *   ownership status.  A pci_controller is built for any bus which is partially
 *   owned or fully owned by this guest partition.
 */
unsigned long __init find_and_init_phbs(void)
{
	struct pci_controller *phb;
	HvBusNumber bus;

	PPCDBG(PPCDBG_BUSWALK, "find_and_init_phbs Entry\n");

	/* Check all possible buses. */
	for (bus = 0; bus < 256; bus++) {
		int ret = HvCallXm_testBus(bus);
		if (ret == 0) {
			printk("bus %d appears to exist\n", bus);

			phb = (struct pci_controller *)kmalloc(sizeof(struct pci_controller), GFP_KERNEL);
			if (phb == NULL)
				return -ENOMEM;
			pci_setup_pci_controller(phb);

			phb->pci_mem_offset = phb->local_number = bus;
			phb->first_busno = bus;
			phb->last_busno = bus;
			phb->ops = &iSeries_pci_ops;

			PPCDBG(PPCDBG_BUSWALK, "PCI:Create iSeries pci_controller(%p), Bus: %04X\n",
					phb, bus);

			/* Find and connect the devices. */
			scan_PHB_slots(phb);
		}
		/*
		 * Check for Unexpected Return code, a clue that something
		 * has gone wrong.
		 */
		else if (ret != 0x0301)
			printk(KERN_ERR "Unexpected Return on Probe(0x%04X): 0x%04X",
			       bus, ret);
	}
	return 0;
}

/*
 * iSeries_pcibios_init
 *  
 * Chance to initialize and structures or variable before PCI Bus walk.
 */
void iSeries_pcibios_init(void)
{
	PPCDBG(PPCDBG_BUSWALK, "iSeries_pcibios_init Entry.\n"); 
	iomm_table_initialize();
	find_and_init_phbs();
	io_page_mask = -1;
	PPCDBG(PPCDBG_BUSWALK, "iSeries_pcibios_init Exit.\n"); 
}

/*
 * iSeries_pci_final_fixup(void)  
 */
void __init iSeries_pci_final_fixup(void)
{
	struct pci_dev *pdev = NULL;
	struct iSeries_Device_Node *node;
    	int DeviceCount = 0;

	PPCDBG(PPCDBG_BUSWALK, "iSeries_pcibios_fixup Entry.\n"); 

	/* Fix up at the device node and pci_dev relationship */
	mf_display_src(0xC9000100);

	printk("pcibios_final_fixup\n");
	for_each_pci_dev(pdev) {
		node = find_Device_Node(pdev->bus->number, pdev->devfn);
		printk("pci dev %p (%x.%x), node %p\n", pdev,
		       pdev->bus->number, pdev->devfn, node);

		if (node != NULL) {
			++DeviceCount;
			pdev->sysdata = (void *)node;
			node->PciDev = pdev;
			PPCDBG(PPCDBG_BUSWALK,
					"pdev 0x%p <==> DevNode 0x%p\n",
					pdev, node);
			allocate_device_bars(pdev);
			iSeries_Device_Information(pdev, DeviceCount);
			iommu_devnode_init_iSeries(node);
		} else
			printk("PCI: Device Tree not found for 0x%016lX\n",
					(unsigned long)pdev);
		pdev->irq = node->Irq;
	}
	iSeries_activate_IRQs();
	mf_display_src(0xC9000200);
}

void pcibios_fixup_bus(struct pci_bus *PciBus)
{
	PPCDBG(PPCDBG_BUSWALK, "iSeries_pcibios_fixup_bus(0x%04X) Entry.\n",
			PciBus->number); 
}

void pcibios_fixup_resources(struct pci_dev *pdev)
{
	PPCDBG(PPCDBG_BUSWALK, "fixup_resources pdev %p\n", pdev);
}   

/*
 * Loop through each node function to find usable EADs bridges.  
 */
static void scan_PHB_slots(struct pci_controller *Phb)
{
	struct HvCallPci_DeviceInfo *DevInfo;
	HvBusNumber bus = Phb->local_number;	/* System Bus */	
	const HvSubBusNumber SubBus = 0;	/* EADs is always 0. */
	int HvRc = 0;
	int IdSel;	
	const int MaxAgents = 8;

	DevInfo = (struct HvCallPci_DeviceInfo*)
		kmalloc(sizeof(struct HvCallPci_DeviceInfo), GFP_KERNEL);
	if (DevInfo == NULL)
		return;

	/*
	 * Probe for EADs Bridges      
	 */
	for (IdSel = 1; IdSel < MaxAgents; ++IdSel) {
    		HvRc = HvCallPci_getDeviceInfo(bus, SubBus, IdSel,
				ISERIES_HV_ADDR(DevInfo),
				sizeof(struct HvCallPci_DeviceInfo));
		if (HvRc == 0) {
			if (DevInfo->deviceType == HvCallPci_NodeDevice)
				scan_EADS_bridge(bus, SubBus, IdSel);
			else
				printk("PCI: Invalid System Configuration(0x%02X)"
				       " for bus 0x%02x id 0x%02x.\n",
				       DevInfo->deviceType, bus, IdSel);
		}
		else
			pci_Log_Error("getDeviceInfo", bus, SubBus, IdSel, HvRc);
	}
	kfree(DevInfo);
}

static void scan_EADS_bridge(HvBusNumber bus, HvSubBusNumber SubBus,
		int IdSel)
{
	struct HvCallPci_BridgeInfo *BridgeInfo;
	HvAgentId AgentId;
	int Function;
	int HvRc;

	BridgeInfo = (struct HvCallPci_BridgeInfo *)
		kmalloc(sizeof(struct HvCallPci_BridgeInfo), GFP_KERNEL);
	if (BridgeInfo == NULL)
		return;

	/* Note: hvSubBus and irq is always be 0 at this level! */
	for (Function = 0; Function < 8; ++Function) {
	  	AgentId = ISERIES_PCI_AGENTID(IdSel, Function);
		HvRc = HvCallXm_connectBusUnit(bus, SubBus, AgentId, 0);
 		if (HvRc == 0) {
			printk("found device at bus %d idsel %d func %d (AgentId %x)\n",
			       bus, IdSel, Function, AgentId);
  			/*  Connect EADs: 0x18.00.12 = 0x00 */
			PPCDBG(PPCDBG_BUSWALK,
					"PCI:Connect EADs: 0x%02X.%02X.%02X\n",
					bus, SubBus, AgentId);
	    		HvRc = HvCallPci_getBusUnitInfo(bus, SubBus, AgentId,
					ISERIES_HV_ADDR(BridgeInfo),
					sizeof(struct HvCallPci_BridgeInfo));
	 		if (HvRc == 0) {
				printk("bridge info: type %x subbus %x maxAgents %x maxsubbus %x logslot %x\n",
					BridgeInfo->busUnitInfo.deviceType,
					BridgeInfo->subBusNumber,
					BridgeInfo->maxAgents,
					BridgeInfo->maxSubBusNumber,
					BridgeInfo->logicalSlotNumber);
				PPCDBG(PPCDBG_BUSWALK,
					"PCI: BridgeInfo, Type:0x%02X, SubBus:0x%02X, MaxAgents:0x%02X, MaxSubBus: 0x%02X, LSlot: 0x%02X\n",
					BridgeInfo->busUnitInfo.deviceType,
					BridgeInfo->subBusNumber,
					BridgeInfo->maxAgents,
					BridgeInfo->maxSubBusNumber,
					BridgeInfo->logicalSlotNumber);

				if (BridgeInfo->busUnitInfo.deviceType ==
						HvCallPci_BridgeDevice)  {
					/* Scan_Bridge_Slot...: 0x18.00.12 */
					scan_bridge_slot(bus, BridgeInfo);
				} else
					printk("PCI: Invalid Bridge Configuration(0x%02X)",
						BridgeInfo->busUnitInfo.deviceType);
			}
    		} else if (HvRc != 0x000B)
			pci_Log_Error("EADs Connect",
					bus, SubBus, AgentId, HvRc);
	}
	kfree(BridgeInfo);
}

/*
 * This assumes that the node slot is always on the primary bus!
 */
static int scan_bridge_slot(HvBusNumber Bus,
		struct HvCallPci_BridgeInfo *BridgeInfo)
{
	struct iSeries_Device_Node *node;
	HvSubBusNumber SubBus = BridgeInfo->subBusNumber;
	u16 VendorId = 0;
	int HvRc = 0;
	u8 Irq = 0;
	int IdSel = ISERIES_GET_DEVICE_FROM_SUBBUS(SubBus);
	int Function = ISERIES_GET_FUNCTION_FROM_SUBBUS(SubBus);
	HvAgentId EADsIdSel = ISERIES_PCI_AGENTID(IdSel, Function);

	/* iSeries_allocate_IRQ.: 0x18.00.12(0xA3) */
  	Irq = iSeries_allocate_IRQ(Bus, 0, EADsIdSel);
	PPCDBG(PPCDBG_BUSWALK,
		"PCI:- allocate and assign IRQ 0x%02X.%02X.%02X = 0x%02X\n",
		Bus, 0, EADsIdSel, Irq);

	/*
	 * Connect all functions of any device found.  
	 */
  	for (IdSel = 1; IdSel <= BridgeInfo->maxAgents; ++IdSel) {
    		for (Function = 0; Function < 8; ++Function) {
			HvAgentId AgentId = ISERIES_PCI_AGENTID(IdSel, Function);
			HvRc = HvCallXm_connectBusUnit(Bus, SubBus,
					AgentId, Irq);
			if (HvRc != 0) {
				pci_Log_Error("Connect Bus Unit",
					      Bus, SubBus, AgentId, HvRc);
				continue;
			}

			HvRc = HvCallPci_configLoad16(Bus, SubBus, AgentId,
						      PCI_VENDOR_ID, &VendorId);
			if (HvRc != 0) {
				pci_Log_Error("Read Vendor",
					      Bus, SubBus, AgentId, HvRc);
				continue;
			}
			printk("read vendor ID: %x\n", VendorId);

			/* FoundDevice: 0x18.28.10 = 0x12AE */
			PPCDBG(PPCDBG_BUSWALK,
			       "PCI:- FoundDevice: 0x%02X.%02X.%02X = 0x%04X, irq %d\n",
			       Bus, SubBus, AgentId, VendorId, Irq);
			HvRc = HvCallPci_configStore8(Bus, SubBus, AgentId,
						      PCI_INTERRUPT_LINE, Irq);  
			if (HvRc != 0)
				pci_Log_Error("PciCfgStore Irq Failed!",
					      Bus, SubBus, AgentId, HvRc);

			++DeviceCount;
			node = build_device_node(Bus, SubBus, EADsIdSel, Function);
			node->Irq = Irq;
			node->LogicalSlot = BridgeInfo->logicalSlotNumber;

		} /* for (Function = 0; Function < 8; ++Function) */
	} /* for (IdSel = 1; IdSel <= MaxAgents; ++IdSel) */
	return HvRc;
}

/*
 * I/0 Memory copy MUST use mmio commands on iSeries
 * To do; For performance, include the hv call directly
 */
void iSeries_memset_io(volatile void __iomem *dest, char c, size_t Count)
{
	u8 ByteValue = c;
	long NumberOfBytes = Count;

	while (NumberOfBytes > 0) {
		iSeries_Write_Byte(ByteValue, dest++);
		-- NumberOfBytes;
	}
}
EXPORT_SYMBOL(iSeries_memset_io);

void iSeries_memcpy_toio(volatile void __iomem *dest, void *source, size_t count)
{
	char *src = source;
	long NumberOfBytes = count;

	while (NumberOfBytes > 0) {
		iSeries_Write_Byte(*src++, dest++);
		-- NumberOfBytes;
	}
}
EXPORT_SYMBOL(iSeries_memcpy_toio);

void iSeries_memcpy_fromio(void *dest, const volatile void __iomem *src, size_t count)
{
	char *dst = dest;
	long NumberOfBytes = count;

	while (NumberOfBytes > 0) {
		*dst++ = iSeries_Read_Byte(src++);
		-- NumberOfBytes;
	}
}
EXPORT_SYMBOL(iSeries_memcpy_fromio);

/*
 * Look down the chain to find the matching Device Device
 */
static struct iSeries_Device_Node *find_Device_Node(int bus, int devfn)
{
	struct list_head *pos;

	list_for_each(pos, &iSeries_Global_Device_List) {
		struct iSeries_Device_Node *node =
			list_entry(pos, struct iSeries_Device_Node, Device_List);

		if ((bus == ISERIES_BUS(node)) && (devfn == node->DevFn))
			return node;
	}
	return NULL;
}

#if 0
/*
 * Returns the device node for the passed pci_dev
 * Sanity Check Node PciDev to passed pci_dev
 * If none is found, returns a NULL which the client must handle.
 */
static struct iSeries_Device_Node *get_Device_Node(struct pci_dev *pdev)
{
	struct iSeries_Device_Node *node;

	node = pdev->sysdata;
	if (node == NULL || node->PciDev != pdev)
		node = find_Device_Node(pdev->bus->number, pdev->devfn);
	return node;
}
#endif

/*
 * Config space read and write functions.
 * For now at least, we look for the device node for the bus and devfn
 * that we are asked to access.  It may be possible to translate the devfn
 * to a subbus and deviceid more directly.
 */
static u64 hv_cfg_read_func[4]  = {
	HvCallPciConfigLoad8, HvCallPciConfigLoad16,
	HvCallPciConfigLoad32, HvCallPciConfigLoad32
};

static u64 hv_cfg_write_func[4] = {
	HvCallPciConfigStore8, HvCallPciConfigStore16,
	HvCallPciConfigStore32, HvCallPciConfigStore32
};

/*
 * Read PCI config space
 */
static int iSeries_pci_read_config(struct pci_bus *bus, unsigned int devfn,
		int offset, int size, u32 *val)
{
	struct iSeries_Device_Node *node = find_Device_Node(bus->number, devfn);
	u64 fn;
	struct HvCallPci_LoadReturn ret;

	if (node == NULL)
		return PCIBIOS_DEVICE_NOT_FOUND;
	if (offset > 255) {
		*val = ~0;
		return PCIBIOS_BAD_REGISTER_NUMBER;
	}

	fn = hv_cfg_read_func[(size - 1) & 3];
	HvCall3Ret16(fn, &ret, node->DsaAddr.DsaAddr, offset, 0);

	if (ret.rc != 0) {
		*val = ~0;
		return PCIBIOS_DEVICE_NOT_FOUND;	/* or something */
	}

	*val = ret.value;
	return 0;
}

/*
 * Write PCI config space
 */

static int iSeries_pci_write_config(struct pci_bus *bus, unsigned int devfn,
		int offset, int size, u32 val)
{
	struct iSeries_Device_Node *node = find_Device_Node(bus->number, devfn);
	u64 fn;
	u64 ret;

	if (node == NULL)
		return PCIBIOS_DEVICE_NOT_FOUND;
	if (offset > 255)
		return PCIBIOS_BAD_REGISTER_NUMBER;

	fn = hv_cfg_write_func[(size - 1) & 3];
	ret = HvCall4(fn, node->DsaAddr.DsaAddr, offset, val, 0);

	if (ret != 0)
		return PCIBIOS_DEVICE_NOT_FOUND;

	return 0;
}

static struct pci_ops iSeries_pci_ops = {
	.read = iSeries_pci_read_config,
	.write = iSeries_pci_write_config
};

/*
 * Check Return Code
 * -> On Failure, print and log information.
 *    Increment Retry Count, if exceeds max, panic partition.
 *
 * PCI: Device 23.90 ReadL I/O Error( 0): 0x1234
 * PCI: Device 23.90 ReadL Retry( 1)
 * PCI: Device 23.90 ReadL Retry Successful(1)
 */
static int CheckReturnCode(char *TextHdr, struct iSeries_Device_Node *DevNode,
		int *retry, u64 ret)
{
	if (ret != 0)  {
		++Pci_Error_Count;
		(*retry)++;
		printk("PCI: %s: Device 0x%04X:%02X  I/O Error(%2d): 0x%04X\n",
				TextHdr, DevNode->DsaAddr.Dsa.busNumber, DevNode->DevFn,
				*retry, (int)ret);
		/*
		 * Bump the retry and check for retry count exceeded.
		 * If, Exceeded, panic the system.
		 */
		if (((*retry) > Pci_Retry_Max) &&
				(Pci_Error_Flag > 0)) {
			mf_display_src(0xB6000103);
			panic_timeout = 0;
			panic("PCI: Hardware I/O Error, SRC B6000103, "
					"Automatic Reboot Disabled.\n");
		}
		return -1;	/* Retry Try */
	}
	return 0;
}

/*
 * Translate the I/O Address into a device node, bar, and bar offset.
 * Note: Make sure the passed variable end up on the stack to avoid
 * the exposure of being device global.
 */
static inline struct iSeries_Device_Node *xlate_iomm_address(
		const volatile void __iomem *IoAddress,
		u64 *dsaptr, u64 *BarOffsetPtr)
{
	unsigned long OrigIoAddr;
	unsigned long BaseIoAddr;
	unsigned long TableIndex;
	struct iSeries_Device_Node *DevNode;

	OrigIoAddr = (unsigned long __force)IoAddress;
	if ((OrigIoAddr < BASE_IO_MEMORY) || (OrigIoAddr >= max_io_memory))
		return NULL;
	BaseIoAddr = OrigIoAddr - BASE_IO_MEMORY;
	TableIndex = BaseIoAddr / IOMM_TABLE_ENTRY_SIZE;
	DevNode = iomm_table[TableIndex];

	if (DevNode != NULL) {
		int barnum = iobar_table[TableIndex];
		*dsaptr = DevNode->DsaAddr.DsaAddr | (barnum << 24);
		*BarOffsetPtr = BaseIoAddr % IOMM_TABLE_ENTRY_SIZE;
	} else
		panic("PCI: Invalid PCI IoAddress detected!\n");
	return DevNode;
}

/*
 * Read MM I/O Instructions for the iSeries
 * On MM I/O error, all ones are returned and iSeries_pci_IoError is cal
 * else, data is returned in big Endian format.
 *
 * iSeries_Read_Byte = Read Byte  ( 8 bit)
 * iSeries_Read_Word = Read Word  (16 bit)
 * iSeries_Read_Long = Read Long  (32 bit)
 */
u8 iSeries_Read_Byte(const volatile void __iomem *IoAddress)
{
	u64 BarOffset;
	u64 dsa;
	int retry = 0;
	struct HvCallPci_LoadReturn ret;
	struct iSeries_Device_Node *DevNode =
		xlate_iomm_address(IoAddress, &dsa, &BarOffset);

	if (DevNode == NULL) {
		static unsigned long last_jiffies;
		static int num_printed;

		if ((jiffies - last_jiffies) > 60 * HZ) {
			last_jiffies = jiffies;
			num_printed = 0;
		}
		if (num_printed++ < 10)
			printk(KERN_ERR "iSeries_Read_Byte: invalid access at IO address %p\n", IoAddress);
		return 0xff;
	}
	do {
		++Pci_Io_Read_Count;
		HvCall3Ret16(HvCallPciBarLoad8, &ret, dsa, BarOffset, 0);
	} while (CheckReturnCode("RDB", DevNode, &retry, ret.rc) != 0);

	return (u8)ret.value;
}
EXPORT_SYMBOL(iSeries_Read_Byte);

u16 iSeries_Read_Word(const volatile void __iomem *IoAddress)
{
	u64 BarOffset;
	u64 dsa;
	int retry = 0;
	struct HvCallPci_LoadReturn ret;
	struct iSeries_Device_Node *DevNode =
		xlate_iomm_address(IoAddress, &dsa, &BarOffset);

	if (DevNode == NULL) {
		static unsigned long last_jiffies;
		static int num_printed;

		if ((jiffies - last_jiffies) > 60 * HZ) {
			last_jiffies = jiffies;
			num_printed = 0;
		}
		if (num_printed++ < 10)
			printk(KERN_ERR "iSeries_Read_Word: invalid access at IO address %p\n", IoAddress);
		return 0xffff;
	}
	do {
		++Pci_Io_Read_Count;
		HvCall3Ret16(HvCallPciBarLoad16, &ret, dsa,
				BarOffset, 0);
	} while (CheckReturnCode("RDW", DevNode, &retry, ret.rc) != 0);

	return swab16((u16)ret.value);
}
EXPORT_SYMBOL(iSeries_Read_Word);

u32 iSeries_Read_Long(const volatile void __iomem *IoAddress)
{
	u64 BarOffset;
	u64 dsa;
	int retry = 0;
	struct HvCallPci_LoadReturn ret;
	struct iSeries_Device_Node *DevNode =
		xlate_iomm_address(IoAddress, &dsa, &BarOffset);

	if (DevNode == NULL) {
		static unsigned long last_jiffies;
		static int num_printed;

		if ((jiffies - last_jiffies) > 60 * HZ) {
			last_jiffies = jiffies;
			num_printed = 0;
		}
		if (num_printed++ < 10)
			printk(KERN_ERR "iSeries_Read_Long: invalid access at IO address %p\n", IoAddress);
		return 0xffffffff;
	}
	do {
		++Pci_Io_Read_Count;
		HvCall3Ret16(HvCallPciBarLoad32, &ret, dsa,
				BarOffset, 0);
	} while (CheckReturnCode("RDL", DevNode, &retry, ret.rc) != 0);

	return swab32((u32)ret.value);
}
EXPORT_SYMBOL(iSeries_Read_Long);

/*
 * Write MM I/O Instructions for the iSeries
 *
 * iSeries_Write_Byte = Write Byte (8 bit)
 * iSeries_Write_Word = Write Word(16 bit)
 * iSeries_Write_Long = Write Long(32 bit)
 */
void iSeries_Write_Byte(u8 data, volatile void __iomem *IoAddress)
{
	u64 BarOffset;
	u64 dsa;
	int retry = 0;
	u64 rc;
	struct iSeries_Device_Node *DevNode =
		xlate_iomm_address(IoAddress, &dsa, &BarOffset);

	if (DevNode == NULL) {
		static unsigned long last_jiffies;
		static int num_printed;

		if ((jiffies - last_jiffies) > 60 * HZ) {
			last_jiffies = jiffies;
			num_printed = 0;
		}
		if (num_printed++ < 10)
			printk(KERN_ERR "iSeries_Write_Byte: invalid access at IO address %p\n", IoAddress);
		return;
	}
	do {
		++Pci_Io_Write_Count;
		rc = HvCall4(HvCallPciBarStore8, dsa, BarOffset, data, 0);
	} while (CheckReturnCode("WWB", DevNode, &retry, rc) != 0);
}
EXPORT_SYMBOL(iSeries_Write_Byte);

void iSeries_Write_Word(u16 data, volatile void __iomem *IoAddress)
{
	u64 BarOffset;
	u64 dsa;
	int retry = 0;
	u64 rc;
	struct iSeries_Device_Node *DevNode =
		xlate_iomm_address(IoAddress, &dsa, &BarOffset);

	if (DevNode == NULL) {
		static unsigned long last_jiffies;
		static int num_printed;

		if ((jiffies - last_jiffies) > 60 * HZ) {
			last_jiffies = jiffies;
			num_printed = 0;
		}
		if (num_printed++ < 10)
			printk(KERN_ERR "iSeries_Write_Word: invalid access at IO address %p\n", IoAddress);
		return;
	}
	do {
		++Pci_Io_Write_Count;
		rc = HvCall4(HvCallPciBarStore16, dsa, BarOffset, swab16(data), 0);
	} while (CheckReturnCode("WWW", DevNode, &retry, rc) != 0);
}
EXPORT_SYMBOL(iSeries_Write_Word);

void iSeries_Write_Long(u32 data, volatile void __iomem *IoAddress)
{
	u64 BarOffset;
	u64 dsa;
	int retry = 0;
	u64 rc;
	struct iSeries_Device_Node *DevNode =
		xlate_iomm_address(IoAddress, &dsa, &BarOffset);

	if (DevNode == NULL) {
		static unsigned long last_jiffies;
		static int num_printed;

		if ((jiffies - last_jiffies) > 60 * HZ) {
			last_jiffies = jiffies;
			num_printed = 0;
		}
		if (num_printed++ < 10)
			printk(KERN_ERR "iSeries_Write_Long: invalid access at IO address %p\n", IoAddress);
		return;
	}
	do {
		++Pci_Io_Write_Count;
		rc = HvCall4(HvCallPciBarStore32, dsa, BarOffset, swab32(data), 0);
	} while (CheckReturnCode("WWL", DevNode, &retry, rc) != 0);
}
EXPORT_SYMBOL(iSeries_Write_Long);
