/*
 * arch/v850/kernel/mb_a_pci.c -- PCI support for Midas lab RTE-MOTHER-A board
 *
 *  Copyright (C) 2001,02,03,05  NEC Electronics Corporation
 *  Copyright (C) 2001,02,03,05  Miles Bader <miles@gnu.org>
 *
 * This file is subject to the terms and conditions of the GNU General
 * Public License.  See the file COPYING in the main directory of this
 * archive for more details.
 *
 * Written by Miles Bader <miles@gnu.org>
 */

#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/pci.h>

#include <asm/machdep.h>

/* __nomods_init is like __devinit, but is a no-op when modules are enabled.
   This is used by some routines that can be called either during boot
   or by a module.  */
#ifdef CONFIG_MODULES
#define __nomods_init /*nothing*/
#else
#define __nomods_init __devinit
#endif

/* PCI devices on the Mother-A board can only do DMA to/from the MB SRAM
   (the RTE-V850E/MA1-CB cpu board doesn't support PCI access to
   CPU-board memory), and since linux DMA buffers are allocated in
   normal kernel memory, we basically have to copy DMA blocks around
   (this is like a `bounce buffer').  When a DMA block is `mapped', we
   allocate an identically sized block in MB SRAM, and if we're doing
   output to the device, copy the CPU-memory block to the MB-SRAM block.
   When an active block is `unmapped', we will copy the block back to
   CPU memory if necessary, and then deallocate the MB SRAM block.
   Ack.  */

/* Where the motherboard SRAM is in the PCI-bus address space (the
   first 512K of it is also mapped at PCI address 0).  */
#define PCI_MB_SRAM_ADDR 0x800000

/* Convert CPU-view MB SRAM address to/from PCI-view addresses of the
   same memory.  */
#define MB_SRAM_TO_PCI(mb_sram_addr) \
   ((dma_addr_t)mb_sram_addr - MB_A_SRAM_ADDR + PCI_MB_SRAM_ADDR)
#define PCI_TO_MB_SRAM(pci_addr)     \
   (void *)(pci_addr - PCI_MB_SRAM_ADDR + MB_A_SRAM_ADDR)

static void pcibios_assign_resources (void);

struct mb_pci_dev_irq {
	unsigned dev;		/* PCI device number */
	unsigned irq_base;	/* First IRQ  */
	unsigned query_pin;	/* True if we should read the device's
				   Interrupt Pin info, and allocate
				   interrupt IRQ_BASE + PIN.  */
};

/* PCI interrupts are mapped statically to GBUS interrupts.  */
static struct mb_pci_dev_irq mb_pci_dev_irqs[] = {
	/* Motherboard SB82558 ethernet controller */
	{ 10,	IRQ_MB_A_LAN,		0 },
	/* PCI slot 1 */
	{ 8, 	IRQ_MB_A_PCI1(0),	1 },
	/* PCI slot 2 */
	{ 9, 	IRQ_MB_A_PCI2(0),	1 }
};
#define NUM_MB_PCI_DEV_IRQS \
  (sizeof mb_pci_dev_irqs / sizeof mb_pci_dev_irqs[0])


/* PCI configuration primitives.  */

#define CONFIG_DMCFGA(bus, devfn, offs)					\
   (0x80000000								\
    | ((offs) & ~0x3)							\
    | ((devfn) << 8)							\
    | ((bus)->number << 16))

static int
mb_pci_read (struct pci_bus *bus, unsigned devfn, int offs, int size, u32 *rval)
{
	u32 addr;
	int flags;

	local_irq_save (flags);

	MB_A_PCI_PCICR = 0x7;
	MB_A_PCI_DMCFGA = CONFIG_DMCFGA (bus, devfn, offs);

	addr = MB_A_PCI_IO_ADDR + (offs & 0x3);

	switch (size) {
	case 1:	*rval = *(volatile  u8 *)addr; break;
	case 2:	*rval = *(volatile u16 *)addr; break;
	case 4:	*rval = *(volatile u32 *)addr; break;
	}

        if (MB_A_PCI_PCISR & 0x2000) {
		MB_A_PCI_PCISR = 0x2000;
		*rval = ~0;
        }

	MB_A_PCI_DMCFGA = 0;

	local_irq_restore (flags);

	return PCIBIOS_SUCCESSFUL;
}

static int
mb_pci_write (struct pci_bus *bus, unsigned devfn, int offs, int size, u32 val)
{
	u32 addr;
	int flags;

	local_irq_save (flags);

	MB_A_PCI_PCICR = 0x7;
	MB_A_PCI_DMCFGA = CONFIG_DMCFGA (bus, devfn, offs);

	addr = MB_A_PCI_IO_ADDR + (offs & 0x3);

	switch (size) {
	case 1: *(volatile  u8 *)addr = val; break;
	case 2: *(volatile u16 *)addr = val; break;
	case 4: *(volatile u32 *)addr = val; break;
	}

        if (MB_A_PCI_PCISR & 0x2000)
		MB_A_PCI_PCISR = 0x2000;

	MB_A_PCI_DMCFGA = 0;

	local_irq_restore (flags);

	return PCIBIOS_SUCCESSFUL;
}

static struct pci_ops mb_pci_config_ops = {
	.read	= mb_pci_read,
	.write	= mb_pci_write,
};


/* PCI Initialization.  */

static struct pci_bus *mb_pci_bus = 0;

/* Do initial PCI setup.  */
static int __devinit pcibios_init (void)
{
	u32 id = MB_A_PCI_PCIHIDR;
	u16 vendor = id & 0xFFFF;
	u16 device = (id >> 16) & 0xFFFF;

	if (vendor == PCI_VENDOR_ID_PLX && device == PCI_DEVICE_ID_PLX_9080) {
		printk (KERN_INFO
			"PCI: PLX Technology PCI9080 HOST/PCI bridge\n");

		MB_A_PCI_PCICR = 0x147;

		MB_A_PCI_PCIBAR0 = 0x007FFF00;
		MB_A_PCI_PCIBAR1 = 0x0000FF00;
		MB_A_PCI_PCIBAR2 = 0x00800000;

		MB_A_PCI_PCILTR = 0x20;

		MB_A_PCI_PCIPBAM |= 0x3;

		MB_A_PCI_PCISR =  ~0; /* Clear errors.  */

		/* Reprogram the motherboard's IO/config address space,
		   as we don't support the GCS7 address space that the
		   default uses.  */

		/* Significant address bits used for decoding PCI GCS5 space
		   accessess.  */
		MB_A_PCI_DMRR = ~(MB_A_PCI_MEM_SIZE - 1);

		/* I don't understand this, but the SolutionGear example code
		   uses such an offset, and it doesn't work without it.  XXX */
#if GCS5_SIZE == 0x00800000
#define GCS5_CFG_OFFS 0x00800000
#else
#define GCS5_CFG_OFFS 0
#endif

		/* Address bit values for matching.  Note that we have to give
		   the address from the motherboard's point of view, which is
		   different than the CPU's.  */
		/* PCI memory space.  */
		MB_A_PCI_DMLBAM = GCS5_CFG_OFFS + 0x0;
		/* PCI I/O space.  */
		MB_A_PCI_DMLBAI =
			GCS5_CFG_OFFS + (MB_A_PCI_IO_ADDR - GCS5_ADDR);

		mb_pci_bus = pci_scan_bus (0, &mb_pci_config_ops, 0);

		pcibios_assign_resources ();
	} else
		printk (KERN_ERR "PCI: HOST/PCI bridge not found\n");

	return 0;
}

subsys_initcall (pcibios_init);

char __devinit *pcibios_setup (char *option)
{
	/* Don't handle any options. */
	return option;
}


int __nomods_init pcibios_enable_device (struct pci_dev *dev, int mask)
{
	u16 cmd, old_cmd;
	int idx;
	struct resource *r;

	pci_read_config_word(dev, PCI_COMMAND, &cmd);
	old_cmd = cmd;
	for (idx = 0; idx < 6; idx++) {
		r = &dev->resource[idx];
		if (!r->start && r->end) {
			printk(KERN_ERR "PCI: Device %s not available because "
			       "of resource collisions\n", pci_name(dev));
			return -EINVAL;
		}
		if (r->flags & IORESOURCE_IO)
			cmd |= PCI_COMMAND_IO;
		if (r->flags & IORESOURCE_MEM)
			cmd |= PCI_COMMAND_MEMORY;
	}
	if (cmd != old_cmd) {
		printk("PCI: Enabling device %s (%04x -> %04x)\n",
		       pci_name(dev), old_cmd, cmd);
		pci_write_config_word(dev, PCI_COMMAND, cmd);
	}
	return 0;
}


/* Resource allocation.  */
static void __devinit pcibios_assign_resources (void)
{
	struct pci_dev *dev = NULL;
	struct resource *r;

	for_each_pci_dev(dev) {
		unsigned di_num;
		unsigned class = dev->class >> 8;

		if (class && class != PCI_CLASS_BRIDGE_HOST) {
			unsigned r_num;
			for(r_num = 0; r_num < 6; r_num++) {
				r = &dev->resource[r_num];
				if (!r->start && r->end)
					pci_assign_resource (dev, r_num);
			}
		}

		/* Assign interrupts.  */
		for (di_num = 0; di_num < NUM_MB_PCI_DEV_IRQS; di_num++) {
			struct mb_pci_dev_irq *di = &mb_pci_dev_irqs[di_num];

			if (di->dev == PCI_SLOT (dev->devfn)) {
				unsigned irq = di->irq_base;

				if (di->query_pin) {
					/* Find out which interrupt pin
					   this device uses (each PCI
					   slot has 4).  */
					u8 irq_pin;

					pci_read_config_byte (dev,
							     PCI_INTERRUPT_PIN,
							      &irq_pin);

					if (irq_pin == 0)
						/* Doesn't use interrupts.  */ 
						continue;
					else
						irq += irq_pin - 1;
				}

				pcibios_update_irq (dev, irq);
			}
		}
	}
}

void __devinit pcibios_update_irq (struct pci_dev *dev, int irq)
{
	dev->irq = irq;
	pci_write_config_byte (dev, PCI_INTERRUPT_LINE, irq);
}

void __devinit
pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
			struct resource *res)
{
	unsigned long offset = 0;

	if (res->flags & IORESOURCE_IO) {
		offset = MB_A_PCI_IO_ADDR;
	} else if (res->flags & IORESOURCE_MEM) {
		offset = MB_A_PCI_MEM_ADDR;
	}

	region->start = res->start - offset;
	region->end = res->end - offset;
}


/* Stubs for things we don't use.  */

/* Called after each bus is probed, but before its children are examined. */
void pcibios_fixup_bus(struct pci_bus *b)
{
}

void
pcibios_align_resource (void *data, struct resource *res,
			unsigned long size, unsigned long align)
{
}

void pcibios_set_master (struct pci_dev *dev)
{
}


/* Mother-A SRAM memory allocation.  This is a simple first-fit allocator.  */

/* A memory free-list node.  */
struct mb_sram_free_area {
	void *mem;
	unsigned long size;
	struct mb_sram_free_area *next;
};

/* The tail of the free-list, which starts out containing all the SRAM.  */
static struct mb_sram_free_area mb_sram_free_tail = {
	(void *)MB_A_SRAM_ADDR, MB_A_SRAM_SIZE, 0
};

/* The free-list.  */
static struct mb_sram_free_area *mb_sram_free_areas = &mb_sram_free_tail;

/* The free-list of free free-list nodes. (:-)  */
static struct mb_sram_free_area *mb_sram_free_free_areas = 0;

/* Spinlock protecting the above globals.  */
static DEFINE_SPINLOCK(mb_sram_lock);

/* Allocate a memory block at least SIZE bytes long in the Mother-A SRAM
   space.  */
static void *alloc_mb_sram (size_t size)
{
	struct mb_sram_free_area *prev, *fa;
	int flags;
	void *mem = 0;

	spin_lock_irqsave (mb_sram_lock, flags);

	/* Look for a free area that can contain SIZE bytes.  */
	for (prev = 0, fa = mb_sram_free_areas; fa; prev = fa, fa = fa->next)
		if (fa->size >= size) {
			/* Found one!  */
			mem = fa->mem;

			if (fa->size == size) {
				/* In fact, it fits exactly, so remove
				   this node from the free-list.  */
				if (prev)
					prev->next = fa->next;
				else
					mb_sram_free_areas = fa->next;
				/* Put it on the free-list-entry-free-list. */
				fa->next = mb_sram_free_free_areas;
				mb_sram_free_free_areas = fa;
			} else {
				/* FA is bigger than SIZE, so just
				   reduce its size to account for this
				   allocation.  */
				fa->mem += size;
				fa->size -= size;
			}

			break;
		}

	spin_unlock_irqrestore (mb_sram_lock, flags);

	return mem;
}

/* Return the memory area MEM of size SIZE to the MB SRAM free pool.  */
static void free_mb_sram (void *mem, size_t size)
{
	struct mb_sram_free_area *prev, *fa, *new_fa;
	int flags;
	void *end = mem + size;

	spin_lock_irqsave (mb_sram_lock, flags);

 retry:
	/* Find an adjacent free-list entry.  */
	for (prev = 0, fa = mb_sram_free_areas; fa; prev = fa, fa = fa->next)
		if (fa->mem == end) {
			/* FA is just after MEM, grow down to encompass it. */
			fa->mem = mem;
			fa->size += size;
			goto done;
		} else if (fa->mem + fa->size == mem) {
			struct mb_sram_free_area *next_fa = fa->next;

			/* FA is just before MEM, expand to encompass it. */
			fa->size += size;

			/* See if FA can now be merged with its successor. */
			if (next_fa && fa->mem + fa->size == next_fa->mem) {
				/* Yup; merge NEXT_FA's info into FA.  */
				fa->size += next_fa->size;
				fa->next = next_fa->next;
				/* Free NEXT_FA.  */
				next_fa->next = mb_sram_free_free_areas;
				mb_sram_free_free_areas = next_fa;
			}
			goto done;
		} else if (fa->mem > mem)
			/* We've reached the right spot in the free-list
			   without finding an adjacent free-area, so add
			   a new free area to hold mem. */
			break;

	/* Make a new free-list entry.  */

	/* First, get a free-list entry.  */
	if (! mb_sram_free_free_areas) {
		/* There are none, so make some.  */
		void *block;
		size_t block_size = sizeof (struct mb_sram_free_area) * 8;

		/* Don't hold the lock while calling kmalloc (I'm not
		   sure whether it would be a problem, since we use
		   GFP_ATOMIC, but it makes me nervous).  */
		spin_unlock_irqrestore (mb_sram_lock, flags);

		block = kmalloc (block_size, GFP_ATOMIC);
		if (! block)
			panic ("free_mb_sram: can't allocate free-list entry");

		/* Now get the lock back.  */
		spin_lock_irqsave (mb_sram_lock, flags);

		/* Add the new free free-list entries.  */
		while (block_size > 0) {
			struct mb_sram_free_area *nfa = block;
			nfa->next = mb_sram_free_free_areas;
			mb_sram_free_free_areas = nfa;
			block += sizeof *nfa;
			block_size -= sizeof *nfa;
		}

		/* Since we dropped the lock to call kmalloc, the
		   free-list could have changed, so retry from the
		   beginning.  */
		goto retry;
	}

	/* Remove NEW_FA from the free-list of free-list entries.  */
	new_fa = mb_sram_free_free_areas;
	mb_sram_free_free_areas = new_fa->next;

	/* NEW_FA initially holds only MEM.  */
	new_fa->mem = mem;
	new_fa->size = size;

	/* Insert NEW_FA in the free-list between PREV and FA. */
	new_fa->next = fa;
	if (prev)
		prev->next = new_fa;
	else
		mb_sram_free_areas = new_fa;

 done:
	spin_unlock_irqrestore (mb_sram_lock, flags);
}


/* Maintainence of CPU -> Mother-A DMA mappings.  */

struct dma_mapping {
	void *cpu_addr;
	void *mb_sram_addr;
	size_t size;
	struct dma_mapping *next;
};

/* A list of mappings from CPU addresses to MB SRAM addresses for active
   DMA blocks (that have been `granted' to the PCI device).  */
static struct dma_mapping *active_dma_mappings = 0;

/* A list of free mapping objects.  */
static struct dma_mapping *free_dma_mappings = 0;

/* Spinlock protecting the above globals.  */
static DEFINE_SPINLOCK(dma_mappings_lock);

static struct dma_mapping *new_dma_mapping (size_t size)
{
	int flags;
	struct dma_mapping *mapping;
	void *mb_sram_block = alloc_mb_sram (size);

	if (! mb_sram_block)
		return 0;

	spin_lock_irqsave (dma_mappings_lock, flags);

	if (! free_dma_mappings) {
		/* We're out of mapping structures, make more.  */
		void *mblock;
		size_t mblock_size = sizeof (struct dma_mapping) * 8;

		/* Don't hold the lock while calling kmalloc (I'm not
		   sure whether it would be a problem, since we use
		   GFP_ATOMIC, but it makes me nervous).  */
		spin_unlock_irqrestore (dma_mappings_lock, flags);

		mblock = kmalloc (mblock_size, GFP_ATOMIC);
		if (! mblock) {
			free_mb_sram (mb_sram_block, size);
			return 0;
		}

		/* Get the lock back.  */
		spin_lock_irqsave (dma_mappings_lock, flags);

		/* Add the new mapping structures to the free-list.  */
		while (mblock_size > 0) {
			struct dma_mapping *fm = mblock;
			fm->next = free_dma_mappings;
			free_dma_mappings = fm;
			mblock += sizeof *fm;
			mblock_size -= sizeof *fm;
		}
	}

	/* Get a mapping struct from the freelist.  */
	mapping = free_dma_mappings;
	free_dma_mappings = mapping->next;

	/* Initialize the mapping.  Other fields should be filled in by
	   caller.  */
	mapping->mb_sram_addr = mb_sram_block;
	mapping->size = size;

	/* Add it to the list of active mappings.  */
	mapping->next = active_dma_mappings;
	active_dma_mappings = mapping;

	spin_unlock_irqrestore (dma_mappings_lock, flags);

	return mapping;
}

static struct dma_mapping *find_dma_mapping (void *mb_sram_addr)
{
	int flags;
	struct dma_mapping *mapping;

	spin_lock_irqsave (dma_mappings_lock, flags);

	for (mapping = active_dma_mappings; mapping; mapping = mapping->next)
		if (mapping->mb_sram_addr == mb_sram_addr) {
			spin_unlock_irqrestore (dma_mappings_lock, flags);
			return mapping;
		}

	panic ("find_dma_mapping: unmapped PCI DMA addr 0x%x",
	       MB_SRAM_TO_PCI (mb_sram_addr));
}

static struct dma_mapping *deactivate_dma_mapping (void *mb_sram_addr)
{
	int flags;
	struct dma_mapping *mapping, *prev;

	spin_lock_irqsave (dma_mappings_lock, flags);

	for (prev = 0, mapping = active_dma_mappings;
	     mapping;
	     prev = mapping, mapping = mapping->next)
	{
		if (mapping->mb_sram_addr == mb_sram_addr) {
			/* This is the MAPPING; deactivate it.  */
			if (prev)
				prev->next = mapping->next;
			else
				active_dma_mappings = mapping->next;

			spin_unlock_irqrestore (dma_mappings_lock, flags);

			return mapping;
		}
	}

	panic ("deactivate_dma_mapping: unmapped PCI DMA addr 0x%x",
	       MB_SRAM_TO_PCI (mb_sram_addr));
}

/* Return MAPPING to the freelist.  */
static inline void
free_dma_mapping (struct dma_mapping *mapping)
{
	int flags;

	free_mb_sram (mapping->mb_sram_addr, mapping->size);

	spin_lock_irqsave (dma_mappings_lock, flags);

	mapping->next = free_dma_mappings;
	free_dma_mappings = mapping;

	spin_unlock_irqrestore (dma_mappings_lock, flags);
}


/* Single PCI DMA mappings.  */

/* `Grant' to PDEV the memory block at CPU_ADDR, for doing DMA.  The
   32-bit PCI bus mastering address to use is returned.  the device owns
   this memory until either pci_unmap_single or pci_dma_sync_single is
   performed.  */
dma_addr_t
pci_map_single (struct pci_dev *pdev, void *cpu_addr, size_t size, int dir)
{
	struct dma_mapping *mapping = new_dma_mapping (size);

	if (! mapping)
		return 0;

	mapping->cpu_addr = cpu_addr;

	if (dir == PCI_DMA_BIDIRECTIONAL || dir == PCI_DMA_TODEVICE)
		memcpy (mapping->mb_sram_addr, cpu_addr, size);

	return MB_SRAM_TO_PCI (mapping->mb_sram_addr);
}

/* Return to the CPU the PCI DMA memory block previously `granted' to
   PDEV, at DMA_ADDR.  */
void pci_unmap_single (struct pci_dev *pdev, dma_addr_t dma_addr, size_t size,
		       int dir)
{
	void *mb_sram_addr = PCI_TO_MB_SRAM (dma_addr);
	struct dma_mapping *mapping = deactivate_dma_mapping (mb_sram_addr);

	if (size != mapping->size)
		panic ("pci_unmap_single: size (%d) doesn't match"
		       " size of mapping at PCI DMA addr 0x%x (%d)\n",
		       size, dma_addr, mapping->size);

	/* Copy back the DMA'd contents if necessary.  */
	if (dir == PCI_DMA_BIDIRECTIONAL || dir == PCI_DMA_FROMDEVICE)
		memcpy (mapping->cpu_addr, mb_sram_addr, size);

	/* Return mapping to the freelist.  */
	free_dma_mapping (mapping);
}

/* Make physical memory consistent for a single streaming mode DMA
   translation after a transfer.

   If you perform a pci_map_single() but wish to interrogate the
   buffer using the cpu, yet do not wish to teardown the PCI dma
   mapping, you must call this function before doing so.  At the next
   point you give the PCI dma address back to the card, you must first
   perform a pci_dma_sync_for_device, and then the device again owns
   the buffer.  */
void
pci_dma_sync_single_for_cpu (struct pci_dev *pdev, dma_addr_t dma_addr, size_t size,
		     int dir)
{
	void *mb_sram_addr = PCI_TO_MB_SRAM (dma_addr);
	struct dma_mapping *mapping = find_dma_mapping (mb_sram_addr);

	/* Synchronize the DMA buffer with the CPU buffer if necessary.  */
	if (dir == PCI_DMA_FROMDEVICE)
		memcpy (mapping->cpu_addr, mb_sram_addr, size);
	else if (dir == PCI_DMA_TODEVICE)
		; /* nothing to do */
	else
		panic("pci_dma_sync_single: unsupported sync dir: %d", dir);
}

void
pci_dma_sync_single_for_device (struct pci_dev *pdev, dma_addr_t dma_addr, size_t size,
				int dir)
{
	void *mb_sram_addr = PCI_TO_MB_SRAM (dma_addr);
	struct dma_mapping *mapping = find_dma_mapping (mb_sram_addr);

	/* Synchronize the DMA buffer with the CPU buffer if necessary.  */
	if (dir == PCI_DMA_FROMDEVICE)
		; /* nothing to do */
	else if (dir == PCI_DMA_TODEVICE)
		memcpy (mb_sram_addr, mapping->cpu_addr, size);
	else
		panic("pci_dma_sync_single: unsupported sync dir: %d", dir);
}


/* Scatter-gather PCI DMA mappings.  */

/* Do multiple DMA mappings at once.  */
int
pci_map_sg (struct pci_dev *pdev, struct scatterlist *sg, int sg_len, int dir)
{
	BUG ();
	return 0;
}

/* Unmap multiple DMA mappings at once.  */
void
pci_unmap_sg (struct pci_dev *pdev, struct scatterlist *sg, int sg_len,int dir)
{
	BUG ();
}

/* Make physical memory consistent for a set of streaming mode DMA
   translations after a transfer.  The same as pci_dma_sync_single_* but
   for a scatter-gather list, same rules and usage.  */

void
pci_dma_sync_sg_for_cpu (struct pci_dev *dev,
			 struct scatterlist *sg, int sg_len,
			 int dir)
{
	BUG ();
}

void
pci_dma_sync_sg_for_device (struct pci_dev *dev,
			    struct scatterlist *sg, int sg_len,
			    int dir)
{
	BUG ();
}


/* PCI mem mapping.  */

/* Allocate and map kernel buffer using consistent mode DMA for PCI
   device.  Returns non-NULL cpu-view pointer to the buffer if
   successful and sets *DMA_ADDR to the pci side dma address as well,
   else DMA_ADDR is undefined.  */
void *
pci_alloc_consistent (struct pci_dev *pdev, size_t size, dma_addr_t *dma_addr)
{
	void *mb_sram_mem = alloc_mb_sram (size);
	if (mb_sram_mem)
		*dma_addr = MB_SRAM_TO_PCI (mb_sram_mem);
	return mb_sram_mem;
}

/* Free and unmap a consistent DMA buffer.  CPU_ADDR and DMA_ADDR must
   be values that were returned from pci_alloc_consistent.  SIZE must be
   the same as what as passed into pci_alloc_consistent.  References to
   the memory and mappings assosciated with CPU_ADDR or DMA_ADDR past
   this call are illegal.  */
void
pci_free_consistent (struct pci_dev *pdev, size_t size, void *cpu_addr,
		     dma_addr_t dma_addr)
{
	void *mb_sram_mem = PCI_TO_MB_SRAM (dma_addr);
	free_mb_sram (mb_sram_mem, size);
}


/* iomap/iomap */

void __iomem *pci_iomap (struct pci_dev *dev, int bar, unsigned long max)
{
	unsigned long start = pci_resource_start (dev, bar);
	unsigned long len = pci_resource_len (dev, bar);

	if (!start || len == 0)
		return 0;

	/* None of the ioremap functions actually do anything, other than
	   re-casting their argument, so don't bother differentiating them.  */
	return ioremap (start, len);
}

void pci_iounmap (struct pci_dev *dev, void __iomem *addr)
{
	/* nothing */
}


/* symbol exports (for modules) */

EXPORT_SYMBOL (pci_map_single);
EXPORT_SYMBOL (pci_unmap_single);
EXPORT_SYMBOL (pci_alloc_consistent);
EXPORT_SYMBOL (pci_free_consistent);
EXPORT_SYMBOL (pci_dma_sync_single_for_cpu);
EXPORT_SYMBOL (pci_dma_sync_single_for_device);
EXPORT_SYMBOL (pci_iomap);
EXPORT_SYMBOL (pci_iounmap);
