// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * VME Bridge Framework
 *
 * Author: Martyn Welch <martyn.welch@ge.com>
 * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc.
 *
 * Based on work by Tom Armistead and Ajit Prem
 * Copyright 2004 Motorola Inc.
 */

#include <linux/init.h>
#include <linux/export.h>
#include <linux/mm.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/pci.h>
#include <linux/poll.h>
#include <linux/highmem.h>
#include <linux/interrupt.h>
#include <linux/pagemap.h>
#include <linux/device.h>
#include <linux/dma-mapping.h>
#include <linux/syscalls.h>
#include <linux/mutex.h>
#include <linux/spinlock.h>
#include <linux/slab.h>
#include <linux/vme.h>

#include "vme_bridge.h"

/* Bitmask and list of registered buses both protected by common mutex */
static unsigned int vme_bus_numbers;
static LIST_HEAD(vme_bus_list);
static DEFINE_MUTEX(vme_buses_lock);

static int __init vme_init(void);

static struct vme_dev *dev_to_vme_dev(struct device *dev)
{
	return container_of(dev, struct vme_dev, dev);
}

/*
 * Find the bridge that the resource is associated with.
 */
static struct vme_bridge *find_bridge(struct vme_resource *resource)
{
	/* Get list to search */
	switch (resource->type) {
	case VME_MASTER:
		return list_entry(resource->entry, struct vme_master_resource,
			list)->parent;
		break;
	case VME_SLAVE:
		return list_entry(resource->entry, struct vme_slave_resource,
			list)->parent;
		break;
	case VME_DMA:
		return list_entry(resource->entry, struct vme_dma_resource,
			list)->parent;
		break;
	case VME_LM:
		return list_entry(resource->entry, struct vme_lm_resource,
			list)->parent;
		break;
	default:
		printk(KERN_ERR "Unknown resource type\n");
		return NULL;
		break;
	}
}

/**
 * vme_free_consistent - Allocate contiguous memory.
 * @resource: Pointer to VME resource.
 * @size: Size of allocation required.
 * @dma: Pointer to variable to store physical address of allocation.
 *
 * Allocate a contiguous block of memory for use by the driver. This is used to
 * create the buffers for the slave windows.
 *
 * Return: Virtual address of allocation on success, NULL on failure.
 */
void *vme_alloc_consistent(struct vme_resource *resource, size_t size,
	dma_addr_t *dma)
{
	struct vme_bridge *bridge;

	if (!resource) {
		printk(KERN_ERR "No resource\n");
		return NULL;
	}

	bridge = find_bridge(resource);
	if (!bridge) {
		printk(KERN_ERR "Can't find bridge\n");
		return NULL;
	}

	if (!bridge->parent) {
		printk(KERN_ERR "Dev entry NULL for bridge %s\n", bridge->name);
		return NULL;
	}

	if (!bridge->alloc_consistent) {
		printk(KERN_ERR "alloc_consistent not supported by bridge %s\n",
		       bridge->name);
		return NULL;
	}

	return bridge->alloc_consistent(bridge->parent, size, dma);
}
EXPORT_SYMBOL(vme_alloc_consistent);

/**
 * vme_free_consistent - Free previously allocated memory.
 * @resource: Pointer to VME resource.
 * @size: Size of allocation to free.
 * @vaddr: Virtual address of allocation.
 * @dma: Physical address of allocation.
 *
 * Free previously allocated block of contiguous memory.
 */
void vme_free_consistent(struct vme_resource *resource, size_t size,
	void *vaddr, dma_addr_t dma)
{
	struct vme_bridge *bridge;

	if (!resource) {
		printk(KERN_ERR "No resource\n");
		return;
	}

	bridge = find_bridge(resource);
	if (!bridge) {
		printk(KERN_ERR "Can't find bridge\n");
		return;
	}

	if (!bridge->parent) {
		printk(KERN_ERR "Dev entry NULL for bridge %s\n", bridge->name);
		return;
	}

	if (!bridge->free_consistent) {
		printk(KERN_ERR "free_consistent not supported by bridge %s\n",
		       bridge->name);
		return;
	}

	bridge->free_consistent(bridge->parent, size, vaddr, dma);
}
EXPORT_SYMBOL(vme_free_consistent);

/**
 * vme_get_size - Helper function returning size of a VME window
 * @resource: Pointer to VME slave or master resource.
 *
 * Determine the size of the VME window provided. This is a helper
 * function, wrappering the call to vme_master_get or vme_slave_get
 * depending on the type of window resource handed to it.
 *
 * Return: Size of the window on success, zero on failure.
 */
size_t vme_get_size(struct vme_resource *resource)
{
	int enabled, retval;
	unsigned long long base, size;
	dma_addr_t buf_base;
	u32 aspace, cycle, dwidth;

	switch (resource->type) {
	case VME_MASTER:
		retval = vme_master_get(resource, &enabled, &base, &size,
			&aspace, &cycle, &dwidth);
		if (retval)
			return 0;

		return size;
		break;
	case VME_SLAVE:
		retval = vme_slave_get(resource, &enabled, &base, &size,
			&buf_base, &aspace, &cycle);
		if (retval)
			return 0;

		return size;
		break;
	case VME_DMA:
		return 0;
		break;
	default:
		printk(KERN_ERR "Unknown resource type\n");
		return 0;
		break;
	}
}
EXPORT_SYMBOL(vme_get_size);

int vme_check_window(u32 aspace, unsigned long long vme_base,
		     unsigned long long size)
{
	int retval = 0;

	if (vme_base + size < size)
		return -EINVAL;

	switch (aspace) {
	case VME_A16:
		if (vme_base + size > VME_A16_MAX)
			retval = -EFAULT;
		break;
	case VME_A24:
		if (vme_base + size > VME_A24_MAX)
			retval = -EFAULT;
		break;
	case VME_A32:
		if (vme_base + size > VME_A32_MAX)
			retval = -EFAULT;
		break;
	case VME_A64:
		/* The VME_A64_MAX limit is actually U64_MAX + 1 */
		break;
	case VME_CRCSR:
		if (vme_base + size > VME_CRCSR_MAX)
			retval = -EFAULT;
		break;
	case VME_USER1:
	case VME_USER2:
	case VME_USER3:
	case VME_USER4:
		/* User Defined */
		break;
	default:
		printk(KERN_ERR "Invalid address space\n");
		retval = -EINVAL;
		break;
	}

	return retval;
}
EXPORT_SYMBOL(vme_check_window);

static u32 vme_get_aspace(int am)
{
	switch (am) {
	case 0x29:
	case 0x2D:
		return VME_A16;
	case 0x38:
	case 0x39:
	case 0x3A:
	case 0x3B:
	case 0x3C:
	case 0x3D:
	case 0x3E:
	case 0x3F:
		return VME_A24;
	case 0x8:
	case 0x9:
	case 0xA:
	case 0xB:
	case 0xC:
	case 0xD:
	case 0xE:
	case 0xF:
		return VME_A32;
	case 0x0:
	case 0x1:
	case 0x3:
		return VME_A64;
	}

	return 0;
}

/**
 * vme_slave_request - Request a VME slave window resource.
 * @vdev: Pointer to VME device struct vme_dev assigned to driver instance.
 * @address: Required VME address space.
 * @cycle: Required VME data transfer cycle type.
 *
 * Request use of a VME window resource capable of being set for the requested
 * address space and data transfer cycle.
 *
 * Return: Pointer to VME resource on success, NULL on failure.
 */
struct vme_resource *vme_slave_request(struct vme_dev *vdev, u32 address,
	u32 cycle)
{
	struct vme_bridge *bridge;
	struct list_head *slave_pos = NULL;
	struct vme_slave_resource *allocated_image = NULL;
	struct vme_slave_resource *slave_image = NULL;
	struct vme_resource *resource = NULL;

	bridge = vdev->bridge;
	if (!bridge) {
		printk(KERN_ERR "Can't find VME bus\n");
		goto err_bus;
	}

	/* Loop through slave resources */
	list_for_each(slave_pos, &bridge->slave_resources) {
		slave_image = list_entry(slave_pos,
			struct vme_slave_resource, list);

		if (!slave_image) {
			printk(KERN_ERR "Registered NULL Slave resource\n");
			continue;
		}

		/* Find an unlocked and compatible image */
		mutex_lock(&slave_image->mtx);
		if (((slave_image->address_attr & address) == address) &&
			((slave_image->cycle_attr & cycle) == cycle) &&
			(slave_image->locked == 0)) {

			slave_image->locked = 1;
			mutex_unlock(&slave_image->mtx);
			allocated_image = slave_image;
			break;
		}
		mutex_unlock(&slave_image->mtx);
	}

	/* No free image */
	if (!allocated_image)
		goto err_image;

	resource = kmalloc(sizeof(*resource), GFP_KERNEL);
	if (!resource)
		goto err_alloc;

	resource->type = VME_SLAVE;
	resource->entry = &allocated_image->list;

	return resource;

err_alloc:
	/* Unlock image */
	mutex_lock(&slave_image->mtx);
	slave_image->locked = 0;
	mutex_unlock(&slave_image->mtx);
err_image:
err_bus:
	return NULL;
}
EXPORT_SYMBOL(vme_slave_request);

/**
 * vme_slave_set - Set VME slave window configuration.
 * @resource: Pointer to VME slave resource.
 * @enabled: State to which the window should be configured.
 * @vme_base: Base address for the window.
 * @size: Size of the VME window.
 * @buf_base: Based address of buffer used to provide VME slave window storage.
 * @aspace: VME address space for the VME window.
 * @cycle: VME data transfer cycle type for the VME window.
 *
 * Set configuration for provided VME slave window.
 *
 * Return: Zero on success, -EINVAL if operation is not supported on this
 *         device, if an invalid resource has been provided or invalid
 *         attributes are provided. Hardware specific errors may also be
 *         returned.
 */
int vme_slave_set(struct vme_resource *resource, int enabled,
	unsigned long long vme_base, unsigned long long size,
	dma_addr_t buf_base, u32 aspace, u32 cycle)
{
	struct vme_bridge *bridge = find_bridge(resource);
	struct vme_slave_resource *image;
	int retval;

	if (resource->type != VME_SLAVE) {
		printk(KERN_ERR "Not a slave resource\n");
		return -EINVAL;
	}

	image = list_entry(resource->entry, struct vme_slave_resource, list);

	if (!bridge->slave_set) {
		printk(KERN_ERR "Function not supported\n");
		return -ENOSYS;
	}

	if (!(((image->address_attr & aspace) == aspace) &&
		((image->cycle_attr & cycle) == cycle))) {
		printk(KERN_ERR "Invalid attributes\n");
		return -EINVAL;
	}

	retval = vme_check_window(aspace, vme_base, size);
	if (retval)
		return retval;

	return bridge->slave_set(image, enabled, vme_base, size, buf_base,
		aspace, cycle);
}
EXPORT_SYMBOL(vme_slave_set);

/**
 * vme_slave_get - Retrieve VME slave window configuration.
 * @resource: Pointer to VME slave resource.
 * @enabled: Pointer to variable for storing state.
 * @vme_base: Pointer to variable for storing window base address.
 * @size: Pointer to variable for storing window size.
 * @buf_base: Pointer to variable for storing slave buffer base address.
 * @aspace: Pointer to variable for storing VME address space.
 * @cycle: Pointer to variable for storing VME data transfer cycle type.
 *
 * Return configuration for provided VME slave window.
 *
 * Return: Zero on success, -EINVAL if operation is not supported on this
 *         device or if an invalid resource has been provided.
 */
int vme_slave_get(struct vme_resource *resource, int *enabled,
	unsigned long long *vme_base, unsigned long long *size,
	dma_addr_t *buf_base, u32 *aspace, u32 *cycle)
{
	struct vme_bridge *bridge = find_bridge(resource);
	struct vme_slave_resource *image;

	if (resource->type != VME_SLAVE) {
		printk(KERN_ERR "Not a slave resource\n");
		return -EINVAL;
	}

	image = list_entry(resource->entry, struct vme_slave_resource, list);

	if (!bridge->slave_get) {
		printk(KERN_ERR "vme_slave_get not supported\n");
		return -EINVAL;
	}

	return bridge->slave_get(image, enabled, vme_base, size, buf_base,
		aspace, cycle);
}
EXPORT_SYMBOL(vme_slave_get);

/**
 * vme_slave_free - Free VME slave window
 * @resource: Pointer to VME slave resource.
 *
 * Free the provided slave resource so that it may be reallocated.
 */
void vme_slave_free(struct vme_resource *resource)
{
	struct vme_slave_resource *slave_image;

	if (resource->type != VME_SLAVE) {
		printk(KERN_ERR "Not a slave resource\n");
		return;
	}

	slave_image = list_entry(resource->entry, struct vme_slave_resource,
		list);
	if (!slave_image) {
		printk(KERN_ERR "Can't find slave resource\n");
		return;
	}

	/* Unlock image */
	mutex_lock(&slave_image->mtx);
	if (slave_image->locked == 0)
		printk(KERN_ERR "Image is already free\n");

	slave_image->locked = 0;
	mutex_unlock(&slave_image->mtx);

	/* Free up resource memory */
	kfree(resource);
}
EXPORT_SYMBOL(vme_slave_free);

/**
 * vme_master_request - Request a VME master window resource.
 * @vdev: Pointer to VME device struct vme_dev assigned to driver instance.
 * @address: Required VME address space.
 * @cycle: Required VME data transfer cycle type.
 * @dwidth: Required VME data transfer width.
 *
 * Request use of a VME window resource capable of being set for the requested
 * address space, data transfer cycle and width.
 *
 * Return: Pointer to VME resource on success, NULL on failure.
 */
struct vme_resource *vme_master_request(struct vme_dev *vdev, u32 address,
	u32 cycle, u32 dwidth)
{
	struct vme_bridge *bridge;
	struct list_head *master_pos = NULL;
	struct vme_master_resource *allocated_image = NULL;
	struct vme_master_resource *master_image = NULL;
	struct vme_resource *resource = NULL;

	bridge = vdev->bridge;
	if (!bridge) {
		printk(KERN_ERR "Can't find VME bus\n");
		goto err_bus;
	}

	/* Loop through master resources */
	list_for_each(master_pos, &bridge->master_resources) {
		master_image = list_entry(master_pos,
			struct vme_master_resource, list);

		if (!master_image) {
			printk(KERN_WARNING "Registered NULL master resource\n");
			continue;
		}

		/* Find an unlocked and compatible image */
		spin_lock(&master_image->lock);
		if (((master_image->address_attr & address) == address) &&
			((master_image->cycle_attr & cycle) == cycle) &&
			((master_image->width_attr & dwidth) == dwidth) &&
			(master_image->locked == 0)) {

			master_image->locked = 1;
			spin_unlock(&master_image->lock);
			allocated_image = master_image;
			break;
		}
		spin_unlock(&master_image->lock);
	}

	/* Check to see if we found a resource */
	if (!allocated_image) {
		printk(KERN_ERR "Can't find a suitable resource\n");
		goto err_image;
	}

	resource = kmalloc(sizeof(*resource), GFP_KERNEL);
	if (!resource)
		goto err_alloc;

	resource->type = VME_MASTER;
	resource->entry = &allocated_image->list;

	return resource;

err_alloc:
	/* Unlock image */
	spin_lock(&master_image->lock);
	master_image->locked = 0;
	spin_unlock(&master_image->lock);
err_image:
err_bus:
	return NULL;
}
EXPORT_SYMBOL(vme_master_request);

/**
 * vme_master_set - Set VME master window configuration.
 * @resource: Pointer to VME master resource.
 * @enabled: State to which the window should be configured.
 * @vme_base: Base address for the window.
 * @size: Size of the VME window.
 * @aspace: VME address space for the VME window.
 * @cycle: VME data transfer cycle type for the VME window.
 * @dwidth: VME data transfer width for the VME window.
 *
 * Set configuration for provided VME master window.
 *
 * Return: Zero on success, -EINVAL if operation is not supported on this
 *         device, if an invalid resource has been provided or invalid
 *         attributes are provided. Hardware specific errors may also be
 *         returned.
 */
int vme_master_set(struct vme_resource *resource, int enabled,
	unsigned long long vme_base, unsigned long long size, u32 aspace,
	u32 cycle, u32 dwidth)
{
	struct vme_bridge *bridge = find_bridge(resource);
	struct vme_master_resource *image;
	int retval;

	if (resource->type != VME_MASTER) {
		printk(KERN_ERR "Not a master resource\n");
		return -EINVAL;
	}

	image = list_entry(resource->entry, struct vme_master_resource, list);

	if (!bridge->master_set) {
		printk(KERN_WARNING "vme_master_set not supported\n");
		return -EINVAL;
	}

	if (!(((image->address_attr & aspace) == aspace) &&
		((image->cycle_attr & cycle) == cycle) &&
		((image->width_attr & dwidth) == dwidth))) {
		printk(KERN_WARNING "Invalid attributes\n");
		return -EINVAL;
	}

	retval = vme_check_window(aspace, vme_base, size);
	if (retval)
		return retval;

	return bridge->master_set(image, enabled, vme_base, size, aspace,
		cycle, dwidth);
}
EXPORT_SYMBOL(vme_master_set);

/**
 * vme_master_get - Retrieve VME master window configuration.
 * @resource: Pointer to VME master resource.
 * @enabled: Pointer to variable for storing state.
 * @vme_base: Pointer to variable for storing window base address.
 * @size: Pointer to variable for storing window size.
 * @aspace: Pointer to variable for storing VME address space.
 * @cycle: Pointer to variable for storing VME data transfer cycle type.
 * @dwidth: Pointer to variable for storing VME data transfer width.
 *
 * Return configuration for provided VME master window.
 *
 * Return: Zero on success, -EINVAL if operation is not supported on this
 *         device or if an invalid resource has been provided.
 */
int vme_master_get(struct vme_resource *resource, int *enabled,
	unsigned long long *vme_base, unsigned long long *size, u32 *aspace,
	u32 *cycle, u32 *dwidth)
{
	struct vme_bridge *bridge = find_bridge(resource);
	struct vme_master_resource *image;

	if (resource->type != VME_MASTER) {
		printk(KERN_ERR "Not a master resource\n");
		return -EINVAL;
	}

	image = list_entry(resource->entry, struct vme_master_resource, list);

	if (!bridge->master_get) {
		printk(KERN_WARNING "%s not supported\n", __func__);
		return -EINVAL;
	}

	return bridge->master_get(image, enabled, vme_base, size, aspace,
		cycle, dwidth);
}
EXPORT_SYMBOL(vme_master_get);

/**
 * vme_master_write - Read data from VME space into a buffer.
 * @resource: Pointer to VME master resource.
 * @buf: Pointer to buffer where data should be transferred.
 * @count: Number of bytes to transfer.
 * @offset: Offset into VME master window at which to start transfer.
 *
 * Perform read of count bytes of data from location on VME bus which maps into
 * the VME master window at offset to buf.
 *
 * Return: Number of bytes read, -EINVAL if resource is not a VME master
 *         resource or read operation is not supported. -EFAULT returned if
 *         invalid offset is provided. Hardware specific errors may also be
 *         returned.
 */
ssize_t vme_master_read(struct vme_resource *resource, void *buf, size_t count,
	loff_t offset)
{
	struct vme_bridge *bridge = find_bridge(resource);
	struct vme_master_resource *image;
	size_t length;

	if (!bridge->master_read) {
		printk(KERN_WARNING "Reading from resource not supported\n");
		return -EINVAL;
	}

	if (resource->type != VME_MASTER) {
		printk(KERN_ERR "Not a master resource\n");
		return -EINVAL;
	}

	image = list_entry(resource->entry, struct vme_master_resource, list);

	length = vme_get_size(resource);

	if (offset > length) {
		printk(KERN_WARNING "Invalid Offset\n");
		return -EFAULT;
	}

	if ((offset + count) > length)
		count = length - offset;

	return bridge->master_read(image, buf, count, offset);

}
EXPORT_SYMBOL(vme_master_read);

/**
 * vme_master_write - Write data out to VME space from a buffer.
 * @resource: Pointer to VME master resource.
 * @buf: Pointer to buffer holding data to transfer.
 * @count: Number of bytes to transfer.
 * @offset: Offset into VME master window at which to start transfer.
 *
 * Perform write of count bytes of data from buf to location on VME bus which
 * maps into the VME master window at offset.
 *
 * Return: Number of bytes written, -EINVAL if resource is not a VME master
 *         resource or write operation is not supported. -EFAULT returned if
 *         invalid offset is provided. Hardware specific errors may also be
 *         returned.
 */
ssize_t vme_master_write(struct vme_resource *resource, void *buf,
	size_t count, loff_t offset)
{
	struct vme_bridge *bridge = find_bridge(resource);
	struct vme_master_resource *image;
	size_t length;

	if (!bridge->master_write) {
		printk(KERN_WARNING "Writing to resource not supported\n");
		return -EINVAL;
	}

	if (resource->type != VME_MASTER) {
		printk(KERN_ERR "Not a master resource\n");
		return -EINVAL;
	}

	image = list_entry(resource->entry, struct vme_master_resource, list);

	length = vme_get_size(resource);

	if (offset > length) {
		printk(KERN_WARNING "Invalid Offset\n");
		return -EFAULT;
	}

	if ((offset + count) > length)
		count = length - offset;

	return bridge->master_write(image, buf, count, offset);
}
EXPORT_SYMBOL(vme_master_write);

/**
 * vme_master_rmw - Perform read-modify-write cycle.
 * @resource: Pointer to VME master resource.
 * @mask: Bits to be compared and swapped in operation.
 * @compare: Bits to be compared with data read from offset.
 * @swap: Bits to be swapped in data read from offset.
 * @offset: Offset into VME master window at which to perform operation.
 *
 * Perform read-modify-write cycle on provided location:
 * - Location on VME bus is read.
 * - Bits selected by mask are compared with compare.
 * - Where a selected bit matches that in compare and are selected in swap,
 * the bit is swapped.
 * - Result written back to location on VME bus.
 *
 * Return: Bytes written on success, -EINVAL if resource is not a VME master
 *         resource or RMW operation is not supported. Hardware specific
 *         errors may also be returned.
 */
unsigned int vme_master_rmw(struct vme_resource *resource, unsigned int mask,
	unsigned int compare, unsigned int swap, loff_t offset)
{
	struct vme_bridge *bridge = find_bridge(resource);
	struct vme_master_resource *image;

	if (!bridge->master_rmw) {
		printk(KERN_WARNING "Writing to resource not supported\n");
		return -EINVAL;
	}

	if (resource->type != VME_MASTER) {
		printk(KERN_ERR "Not a master resource\n");
		return -EINVAL;
	}

	image = list_entry(resource->entry, struct vme_master_resource, list);

	return bridge->master_rmw(image, mask, compare, swap, offset);
}
EXPORT_SYMBOL(vme_master_rmw);

/**
 * vme_master_mmap - Mmap region of VME master window.
 * @resource: Pointer to VME master resource.
 * @vma: Pointer to definition of user mapping.
 *
 * Memory map a region of the VME master window into user space.
 *
 * Return: Zero on success, -EINVAL if resource is not a VME master
 *         resource or -EFAULT if map exceeds window size. Other generic mmap
 *         errors may also be returned.
 */
int vme_master_mmap(struct vme_resource *resource, struct vm_area_struct *vma)
{
	struct vme_master_resource *image;
	phys_addr_t phys_addr;
	unsigned long vma_size;

	if (resource->type != VME_MASTER) {
		pr_err("Not a master resource\n");
		return -EINVAL;
	}

	image = list_entry(resource->entry, struct vme_master_resource, list);
	phys_addr = image->bus_resource.start + (vma->vm_pgoff << PAGE_SHIFT);
	vma_size = vma->vm_end - vma->vm_start;

	if (phys_addr + vma_size > image->bus_resource.end + 1) {
		pr_err("Map size cannot exceed the window size\n");
		return -EFAULT;
	}

	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);

	return vm_iomap_memory(vma, phys_addr, vma->vm_end - vma->vm_start);
}
EXPORT_SYMBOL(vme_master_mmap);

/**
 * vme_master_free - Free VME master window
 * @resource: Pointer to VME master resource.
 *
 * Free the provided master resource so that it may be reallocated.
 */
void vme_master_free(struct vme_resource *resource)
{
	struct vme_master_resource *master_image;

	if (resource->type != VME_MASTER) {
		printk(KERN_ERR "Not a master resource\n");
		return;
	}

	master_image = list_entry(resource->entry, struct vme_master_resource,
		list);
	if (!master_image) {
		printk(KERN_ERR "Can't find master resource\n");
		return;
	}

	/* Unlock image */
	spin_lock(&master_image->lock);
	if (master_image->locked == 0)
		printk(KERN_ERR "Image is already free\n");

	master_image->locked = 0;
	spin_unlock(&master_image->lock);

	/* Free up resource memory */
	kfree(resource);
}
EXPORT_SYMBOL(vme_master_free);

/**
 * vme_dma_request - Request a DMA controller.
 * @vdev: Pointer to VME device struct vme_dev assigned to driver instance.
 * @route: Required src/destination combination.
 *
 * Request a VME DMA controller with capability to perform transfers bewteen
 * requested source/destination combination.
 *
 * Return: Pointer to VME DMA resource on success, NULL on failure.
 */
struct vme_resource *vme_dma_request(struct vme_dev *vdev, u32 route)
{
	struct vme_bridge *bridge;
	struct list_head *dma_pos = NULL;
	struct vme_dma_resource *allocated_ctrlr = NULL;
	struct vme_dma_resource *dma_ctrlr = NULL;
	struct vme_resource *resource = NULL;

	/* XXX Not checking resource attributes */
	printk(KERN_ERR "No VME resource Attribute tests done\n");

	bridge = vdev->bridge;
	if (!bridge) {
		printk(KERN_ERR "Can't find VME bus\n");
		goto err_bus;
	}

	/* Loop through DMA resources */
	list_for_each(dma_pos, &bridge->dma_resources) {
		dma_ctrlr = list_entry(dma_pos,
			struct vme_dma_resource, list);
		if (!dma_ctrlr) {
			printk(KERN_ERR "Registered NULL DMA resource\n");
			continue;
		}

		/* Find an unlocked and compatible controller */
		mutex_lock(&dma_ctrlr->mtx);
		if (((dma_ctrlr->route_attr & route) == route) &&
			(dma_ctrlr->locked == 0)) {

			dma_ctrlr->locked = 1;
			mutex_unlock(&dma_ctrlr->mtx);
			allocated_ctrlr = dma_ctrlr;
			break;
		}
		mutex_unlock(&dma_ctrlr->mtx);
	}

	/* Check to see if we found a resource */
	if (!allocated_ctrlr)
		goto err_ctrlr;

	resource = kmalloc(sizeof(*resource), GFP_KERNEL);
	if (!resource)
		goto err_alloc;

	resource->type = VME_DMA;
	resource->entry = &allocated_ctrlr->list;

	return resource;

err_alloc:
	/* Unlock image */
	mutex_lock(&dma_ctrlr->mtx);
	dma_ctrlr->locked = 0;
	mutex_unlock(&dma_ctrlr->mtx);
err_ctrlr:
err_bus:
	return NULL;
}
EXPORT_SYMBOL(vme_dma_request);

/**
 * vme_new_dma_list - Create new VME DMA list.
 * @resource: Pointer to VME DMA resource.
 *
 * Create a new VME DMA list. It is the responsibility of the user to free
 * the list once it is no longer required with vme_dma_list_free().
 *
 * Return: Pointer to new VME DMA list, NULL on allocation failure or invalid
 *         VME DMA resource.
 */
struct vme_dma_list *vme_new_dma_list(struct vme_resource *resource)
{
	struct vme_dma_list *dma_list;

	if (resource->type != VME_DMA) {
		printk(KERN_ERR "Not a DMA resource\n");
		return NULL;
	}

	dma_list = kmalloc(sizeof(*dma_list), GFP_KERNEL);
	if (!dma_list)
		return NULL;

	INIT_LIST_HEAD(&dma_list->entries);
	dma_list->parent = list_entry(resource->entry,
				      struct vme_dma_resource,
				      list);
	mutex_init(&dma_list->mtx);

	return dma_list;
}
EXPORT_SYMBOL(vme_new_dma_list);

/**
 * vme_dma_pattern_attribute - Create "Pattern" type VME DMA list attribute.
 * @pattern: Value to use used as pattern
 * @type: Type of pattern to be written.
 *
 * Create VME DMA list attribute for pattern generation. It is the
 * responsibility of the user to free used attributes using
 * vme_dma_free_attribute().
 *
 * Return: Pointer to VME DMA attribute, NULL on failure.
 */
struct vme_dma_attr *vme_dma_pattern_attribute(u32 pattern, u32 type)
{
	struct vme_dma_attr *attributes;
	struct vme_dma_pattern *pattern_attr;

	attributes = kmalloc(sizeof(*attributes), GFP_KERNEL);
	if (!attributes)
		goto err_attr;

	pattern_attr = kmalloc(sizeof(*pattern_attr), GFP_KERNEL);
	if (!pattern_attr)
		goto err_pat;

	attributes->type = VME_DMA_PATTERN;
	attributes->private = (void *)pattern_attr;

	pattern_attr->pattern = pattern;
	pattern_attr->type = type;

	return attributes;

err_pat:
	kfree(attributes);
err_attr:
	return NULL;
}
EXPORT_SYMBOL(vme_dma_pattern_attribute);

/**
 * vme_dma_pci_attribute - Create "PCI" type VME DMA list attribute.
 * @address: PCI base address for DMA transfer.
 *
 * Create VME DMA list attribute pointing to a location on PCI for DMA
 * transfers. It is the responsibility of the user to free used attributes
 * using vme_dma_free_attribute().
 *
 * Return: Pointer to VME DMA attribute, NULL on failure.
 */
struct vme_dma_attr *vme_dma_pci_attribute(dma_addr_t address)
{
	struct vme_dma_attr *attributes;
	struct vme_dma_pci *pci_attr;

	/* XXX Run some sanity checks here */

	attributes = kmalloc(sizeof(*attributes), GFP_KERNEL);
	if (!attributes)
		goto err_attr;

	pci_attr = kmalloc(sizeof(*pci_attr), GFP_KERNEL);
	if (!pci_attr)
		goto err_pci;

	attributes->type = VME_DMA_PCI;
	attributes->private = (void *)pci_attr;

	pci_attr->address = address;

	return attributes;

err_pci:
	kfree(attributes);
err_attr:
	return NULL;
}
EXPORT_SYMBOL(vme_dma_pci_attribute);

/**
 * vme_dma_vme_attribute - Create "VME" type VME DMA list attribute.
 * @address: VME base address for DMA transfer.
 * @aspace: VME address space to use for DMA transfer.
 * @cycle: VME bus cycle to use for DMA transfer.
 * @dwidth: VME data width to use for DMA transfer.
 *
 * Create VME DMA list attribute pointing to a location on the VME bus for DMA
 * transfers. It is the responsibility of the user to free used attributes
 * using vme_dma_free_attribute().
 *
 * Return: Pointer to VME DMA attribute, NULL on failure.
 */
struct vme_dma_attr *vme_dma_vme_attribute(unsigned long long address,
	u32 aspace, u32 cycle, u32 dwidth)
{
	struct vme_dma_attr *attributes;
	struct vme_dma_vme *vme_attr;

	attributes = kmalloc(sizeof(*attributes), GFP_KERNEL);
	if (!attributes)
		goto err_attr;

	vme_attr = kmalloc(sizeof(*vme_attr), GFP_KERNEL);
	if (!vme_attr)
		goto err_vme;

	attributes->type = VME_DMA_VME;
	attributes->private = (void *)vme_attr;

	vme_attr->address = address;
	vme_attr->aspace = aspace;
	vme_attr->cycle = cycle;
	vme_attr->dwidth = dwidth;

	return attributes;

err_vme:
	kfree(attributes);
err_attr:
	return NULL;
}
EXPORT_SYMBOL(vme_dma_vme_attribute);

/**
 * vme_dma_free_attribute - Free DMA list attribute.
 * @attributes: Pointer to DMA list attribute.
 *
 * Free VME DMA list attribute. VME DMA list attributes can be safely freed
 * once vme_dma_list_add() has returned.
 */
void vme_dma_free_attribute(struct vme_dma_attr *attributes)
{
	kfree(attributes->private);
	kfree(attributes);
}
EXPORT_SYMBOL(vme_dma_free_attribute);

/**
 * vme_dma_list_add - Add enty to a VME DMA list.
 * @list: Pointer to VME list.
 * @src: Pointer to DMA list attribute to use as source.
 * @dest: Pointer to DMA list attribute to use as destination.
 * @count: Number of bytes to transfer.
 *
 * Add an entry to the provided VME DMA list. Entry requires pointers to source
 * and destination DMA attributes and a count.
 *
 * Please note, the attributes supported as source and destinations for
 * transfers are hardware dependent.
 *
 * Return: Zero on success, -EINVAL if operation is not supported on this
 *         device or if the link list has already been submitted for execution.
 *         Hardware specific errors also possible.
 */
int vme_dma_list_add(struct vme_dma_list *list, struct vme_dma_attr *src,
	struct vme_dma_attr *dest, size_t count)
{
	struct vme_bridge *bridge = list->parent->parent;
	int retval;

	if (!bridge->dma_list_add) {
		printk(KERN_WARNING "Link List DMA generation not supported\n");
		return -EINVAL;
	}

	if (!mutex_trylock(&list->mtx)) {
		printk(KERN_ERR "Link List already submitted\n");
		return -EINVAL;
	}

	retval = bridge->dma_list_add(list, src, dest, count);

	mutex_unlock(&list->mtx);

	return retval;
}
EXPORT_SYMBOL(vme_dma_list_add);

/**
 * vme_dma_list_exec - Queue a VME DMA list for execution.
 * @list: Pointer to VME list.
 *
 * Queue the provided VME DMA list for execution. The call will return once the
 * list has been executed.
 *
 * Return: Zero on success, -EINVAL if operation is not supported on this
 *         device. Hardware specific errors also possible.
 */
int vme_dma_list_exec(struct vme_dma_list *list)
{
	struct vme_bridge *bridge = list->parent->parent;
	int retval;

	if (!bridge->dma_list_exec) {
		printk(KERN_ERR "Link List DMA execution not supported\n");
		return -EINVAL;
	}

	mutex_lock(&list->mtx);

	retval = bridge->dma_list_exec(list);

	mutex_unlock(&list->mtx);

	return retval;
}
EXPORT_SYMBOL(vme_dma_list_exec);

/**
 * vme_dma_list_free - Free a VME DMA list.
 * @list: Pointer to VME list.
 *
 * Free the provided DMA list and all its entries.
 *
 * Return: Zero on success, -EINVAL on invalid VME resource, -EBUSY if resource
 *         is still in use. Hardware specific errors also possible.
 */
int vme_dma_list_free(struct vme_dma_list *list)
{
	struct vme_bridge *bridge = list->parent->parent;
	int retval;

	if (!bridge->dma_list_empty) {
		printk(KERN_WARNING "Emptying of Link Lists not supported\n");
		return -EINVAL;
	}

	if (!mutex_trylock(&list->mtx)) {
		printk(KERN_ERR "Link List in use\n");
		return -EBUSY;
	}

	/*
	 * Empty out all of the entries from the DMA list. We need to go to the
	 * low level driver as DMA entries are driver specific.
	 */
	retval = bridge->dma_list_empty(list);
	if (retval) {
		printk(KERN_ERR "Unable to empty link-list entries\n");
		mutex_unlock(&list->mtx);
		return retval;
	}
	mutex_unlock(&list->mtx);
	kfree(list);

	return retval;
}
EXPORT_SYMBOL(vme_dma_list_free);

/**
 * vme_dma_free - Free a VME DMA resource.
 * @resource: Pointer to VME DMA resource.
 *
 * Free the provided DMA resource so that it may be reallocated.
 *
 * Return: Zero on success, -EINVAL on invalid VME resource, -EBUSY if resource
 *         is still active.
 */
int vme_dma_free(struct vme_resource *resource)
{
	struct vme_dma_resource *ctrlr;

	if (resource->type != VME_DMA) {
		printk(KERN_ERR "Not a DMA resource\n");
		return -EINVAL;
	}

	ctrlr = list_entry(resource->entry, struct vme_dma_resource, list);

	if (!mutex_trylock(&ctrlr->mtx)) {
		printk(KERN_ERR "Resource busy, can't free\n");
		return -EBUSY;
	}

	if (!(list_empty(&ctrlr->pending) && list_empty(&ctrlr->running))) {
		printk(KERN_WARNING "Resource still processing transfers\n");
		mutex_unlock(&ctrlr->mtx);
		return -EBUSY;
	}

	ctrlr->locked = 0;

	mutex_unlock(&ctrlr->mtx);

	kfree(resource);

	return 0;
}
EXPORT_SYMBOL(vme_dma_free);

void vme_bus_error_handler(struct vme_bridge *bridge,
			   unsigned long long address, int am)
{
	struct list_head *handler_pos = NULL;
	struct vme_error_handler *handler;
	int handler_triggered = 0;
	u32 aspace = vme_get_aspace(am);

	list_for_each(handler_pos, &bridge->vme_error_handlers) {
		handler = list_entry(handler_pos, struct vme_error_handler,
				     list);
		if ((aspace == handler->aspace) &&
		    (address >= handler->start) &&
		    (address < handler->end)) {
			if (!handler->num_errors)
				handler->first_error = address;
			if (handler->num_errors != UINT_MAX)
				handler->num_errors++;
			handler_triggered = 1;
		}
	}

	if (!handler_triggered)
		dev_err(bridge->parent,
			"Unhandled VME access error at address 0x%llx\n",
			address);
}
EXPORT_SYMBOL(vme_bus_error_handler);

struct vme_error_handler *vme_register_error_handler(
	struct vme_bridge *bridge, u32 aspace,
	unsigned long long address, size_t len)
{
	struct vme_error_handler *handler;

	handler = kmalloc(sizeof(*handler), GFP_ATOMIC);
	if (!handler)
		return NULL;

	handler->aspace = aspace;
	handler->start = address;
	handler->end = address + len;
	handler->num_errors = 0;
	handler->first_error = 0;
	list_add_tail(&handler->list, &bridge->vme_error_handlers);

	return handler;
}
EXPORT_SYMBOL(vme_register_error_handler);

void vme_unregister_error_handler(struct vme_error_handler *handler)
{
	list_del(&handler->list);
	kfree(handler);
}
EXPORT_SYMBOL(vme_unregister_error_handler);

void vme_irq_handler(struct vme_bridge *bridge, int level, int statid)
{
	void (*call)(int, int, void *);
	void *priv_data;

	call = bridge->irq[level - 1].callback[statid].func;
	priv_data = bridge->irq[level - 1].callback[statid].priv_data;
	if (call)
		call(level, statid, priv_data);
	else
		printk(KERN_WARNING "Spurious VME interrupt, level:%x, vector:%x\n",
		       level, statid);
}
EXPORT_SYMBOL(vme_irq_handler);

/**
 * vme_irq_request - Request a specific VME interrupt.
 * @vdev: Pointer to VME device struct vme_dev assigned to driver instance.
 * @level: Interrupt priority being requested.
 * @statid: Interrupt vector being requested.
 * @callback: Pointer to callback function called when VME interrupt/vector
 *            received.
 * @priv_data: Generic pointer that will be passed to the callback function.
 *
 * Request callback to be attached as a handler for VME interrupts with provided
 * level and statid.
 *
 * Return: Zero on success, -EINVAL on invalid vme device, level or if the
 *         function is not supported, -EBUSY if the level/statid combination is
 *         already in use. Hardware specific errors also possible.
 */
int vme_irq_request(struct vme_dev *vdev, int level, int statid,
	void (*callback)(int, int, void *),
	void *priv_data)
{
	struct vme_bridge *bridge;

	bridge = vdev->bridge;
	if (!bridge) {
		printk(KERN_ERR "Can't find VME bus\n");
		return -EINVAL;
	}

	if ((level < 1) || (level > 7)) {
		printk(KERN_ERR "Invalid interrupt level\n");
		return -EINVAL;
	}

	if (!bridge->irq_set) {
		printk(KERN_ERR "Configuring interrupts not supported\n");
		return -EINVAL;
	}

	mutex_lock(&bridge->irq_mtx);

	if (bridge->irq[level - 1].callback[statid].func) {
		mutex_unlock(&bridge->irq_mtx);
		printk(KERN_WARNING "VME Interrupt already taken\n");
		return -EBUSY;
	}

	bridge->irq[level - 1].count++;
	bridge->irq[level - 1].callback[statid].priv_data = priv_data;
	bridge->irq[level - 1].callback[statid].func = callback;

	/* Enable IRQ level */
	bridge->irq_set(bridge, level, 1, 1);

	mutex_unlock(&bridge->irq_mtx);

	return 0;
}
EXPORT_SYMBOL(vme_irq_request);

/**
 * vme_irq_free - Free a VME interrupt.
 * @vdev: Pointer to VME device struct vme_dev assigned to driver instance.
 * @level: Interrupt priority of interrupt being freed.
 * @statid: Interrupt vector of interrupt being freed.
 *
 * Remove previously attached callback from VME interrupt priority/vector.
 */
void vme_irq_free(struct vme_dev *vdev, int level, int statid)
{
	struct vme_bridge *bridge;

	bridge = vdev->bridge;
	if (!bridge) {
		printk(KERN_ERR "Can't find VME bus\n");
		return;
	}

	if ((level < 1) || (level > 7)) {
		printk(KERN_ERR "Invalid interrupt level\n");
		return;
	}

	if (!bridge->irq_set) {
		printk(KERN_ERR "Configuring interrupts not supported\n");
		return;
	}

	mutex_lock(&bridge->irq_mtx);

	bridge->irq[level - 1].count--;

	/* Disable IRQ level if no more interrupts attached at this level*/
	if (bridge->irq[level - 1].count == 0)
		bridge->irq_set(bridge, level, 0, 1);

	bridge->irq[level - 1].callback[statid].func = NULL;
	bridge->irq[level - 1].callback[statid].priv_data = NULL;

	mutex_unlock(&bridge->irq_mtx);
}
EXPORT_SYMBOL(vme_irq_free);

/**
 * vme_irq_generate - Generate VME interrupt.
 * @vdev: Pointer to VME device struct vme_dev assigned to driver instance.
 * @level: Interrupt priority at which to assert the interrupt.
 * @statid: Interrupt vector to associate with the interrupt.
 *
 * Generate a VME interrupt of the provided level and with the provided
 * statid.
 *
 * Return: Zero on success, -EINVAL on invalid vme device, level or if the
 *         function is not supported. Hardware specific errors also possible.
 */
int vme_irq_generate(struct vme_dev *vdev, int level, int statid)
{
	struct vme_bridge *bridge;

	bridge = vdev->bridge;
	if (!bridge) {
		printk(KERN_ERR "Can't find VME bus\n");
		return -EINVAL;
	}

	if ((level < 1) || (level > 7)) {
		printk(KERN_WARNING "Invalid interrupt level\n");
		return -EINVAL;
	}

	if (!bridge->irq_generate) {
		printk(KERN_WARNING "Interrupt generation not supported\n");
		return -EINVAL;
	}

	return bridge->irq_generate(bridge, level, statid);
}
EXPORT_SYMBOL(vme_irq_generate);

/**
 * vme_lm_request - Request a VME location monitor
 * @vdev: Pointer to VME device struct vme_dev assigned to driver instance.
 *
 * Allocate a location monitor resource to the driver. A location monitor
 * allows the driver to monitor accesses to a contiguous number of
 * addresses on the VME bus.
 *
 * Return: Pointer to a VME resource on success or NULL on failure.
 */
struct vme_resource *vme_lm_request(struct vme_dev *vdev)
{
	struct vme_bridge *bridge;
	struct list_head *lm_pos = NULL;
	struct vme_lm_resource *allocated_lm = NULL;
	struct vme_lm_resource *lm = NULL;
	struct vme_resource *resource = NULL;

	bridge = vdev->bridge;
	if (!bridge) {
		printk(KERN_ERR "Can't find VME bus\n");
		goto err_bus;
	}

	/* Loop through LM resources */
	list_for_each(lm_pos, &bridge->lm_resources) {
		lm = list_entry(lm_pos,
			struct vme_lm_resource, list);
		if (!lm) {
			printk(KERN_ERR "Registered NULL Location Monitor resource\n");
			continue;
		}

		/* Find an unlocked controller */
		mutex_lock(&lm->mtx);
		if (lm->locked == 0) {
			lm->locked = 1;
			mutex_unlock(&lm->mtx);
			allocated_lm = lm;
			break;
		}
		mutex_unlock(&lm->mtx);
	}

	/* Check to see if we found a resource */
	if (!allocated_lm)
		goto err_lm;

	resource = kmalloc(sizeof(*resource), GFP_KERNEL);
	if (!resource)
		goto err_alloc;

	resource->type = VME_LM;
	resource->entry = &allocated_lm->list;

	return resource;

err_alloc:
	/* Unlock image */
	mutex_lock(&lm->mtx);
	lm->locked = 0;
	mutex_unlock(&lm->mtx);
err_lm:
err_bus:
	return NULL;
}
EXPORT_SYMBOL(vme_lm_request);

/**
 * vme_lm_count - Determine number of VME Addresses monitored
 * @resource: Pointer to VME location monitor resource.
 *
 * The number of contiguous addresses monitored is hardware dependent.
 * Return the number of contiguous addresses monitored by the
 * location monitor.
 *
 * Return: Count of addresses monitored or -EINVAL when provided with an
 *	   invalid location monitor resource.
 */
int vme_lm_count(struct vme_resource *resource)
{
	struct vme_lm_resource *lm;

	if (resource->type != VME_LM) {
		printk(KERN_ERR "Not a Location Monitor resource\n");
		return -EINVAL;
	}

	lm = list_entry(resource->entry, struct vme_lm_resource, list);

	return lm->monitors;
}
EXPORT_SYMBOL(vme_lm_count);

/**
 * vme_lm_set - Configure location monitor
 * @resource: Pointer to VME location monitor resource.
 * @lm_base: Base address to monitor.
 * @aspace: VME address space to monitor.
 * @cycle: VME bus cycle type to monitor.
 *
 * Set the base address, address space and cycle type of accesses to be
 * monitored by the location monitor.
 *
 * Return: Zero on success, -EINVAL when provided with an invalid location
 *	   monitor resource or function is not supported. Hardware specific
 *	   errors may also be returned.
 */
int vme_lm_set(struct vme_resource *resource, unsigned long long lm_base,
	u32 aspace, u32 cycle)
{
	struct vme_bridge *bridge = find_bridge(resource);
	struct vme_lm_resource *lm;

	if (resource->type != VME_LM) {
		printk(KERN_ERR "Not a Location Monitor resource\n");
		return -EINVAL;
	}

	lm = list_entry(resource->entry, struct vme_lm_resource, list);

	if (!bridge->lm_set) {
		printk(KERN_ERR "vme_lm_set not supported\n");
		return -EINVAL;
	}

	return bridge->lm_set(lm, lm_base, aspace, cycle);
}
EXPORT_SYMBOL(vme_lm_set);

/**
 * vme_lm_get - Retrieve location monitor settings
 * @resource: Pointer to VME location monitor resource.
 * @lm_base: Pointer used to output the base address monitored.
 * @aspace: Pointer used to output the address space monitored.
 * @cycle: Pointer used to output the VME bus cycle type monitored.
 *
 * Retrieve the base address, address space and cycle type of accesses to
 * be monitored by the location monitor.
 *
 * Return: Zero on success, -EINVAL when provided with an invalid location
 *	   monitor resource or function is not supported. Hardware specific
 *	   errors may also be returned.
 */
int vme_lm_get(struct vme_resource *resource, unsigned long long *lm_base,
	u32 *aspace, u32 *cycle)
{
	struct vme_bridge *bridge = find_bridge(resource);
	struct vme_lm_resource *lm;

	if (resource->type != VME_LM) {
		printk(KERN_ERR "Not a Location Monitor resource\n");
		return -EINVAL;
	}

	lm = list_entry(resource->entry, struct vme_lm_resource, list);

	if (!bridge->lm_get) {
		printk(KERN_ERR "vme_lm_get not supported\n");
		return -EINVAL;
	}

	return bridge->lm_get(lm, lm_base, aspace, cycle);
}
EXPORT_SYMBOL(vme_lm_get);

/**
 * vme_lm_attach - Provide callback for location monitor address
 * @resource: Pointer to VME location monitor resource.
 * @monitor: Offset to which callback should be attached.
 * @callback: Pointer to callback function called when triggered.
 * @data: Generic pointer that will be passed to the callback function.
 *
 * Attach a callback to the specificed offset into the location monitors
 * monitored addresses. A generic pointer is provided to allow data to be
 * passed to the callback when called.
 *
 * Return: Zero on success, -EINVAL when provided with an invalid location
 *	   monitor resource or function is not supported. Hardware specific
 *	   errors may also be returned.
 */
int vme_lm_attach(struct vme_resource *resource, int monitor,
	void (*callback)(void *), void *data)
{
	struct vme_bridge *bridge = find_bridge(resource);
	struct vme_lm_resource *lm;

	if (resource->type != VME_LM) {
		printk(KERN_ERR "Not a Location Monitor resource\n");
		return -EINVAL;
	}

	lm = list_entry(resource->entry, struct vme_lm_resource, list);

	if (!bridge->lm_attach) {
		printk(KERN_ERR "vme_lm_attach not supported\n");
		return -EINVAL;
	}

	return bridge->lm_attach(lm, monitor, callback, data);
}
EXPORT_SYMBOL(vme_lm_attach);

/**
 * vme_lm_detach - Remove callback for location monitor address
 * @resource: Pointer to VME location monitor resource.
 * @monitor: Offset to which callback should be removed.
 *
 * Remove the callback associated with the specificed offset into the
 * location monitors monitored addresses.
 *
 * Return: Zero on success, -EINVAL when provided with an invalid location
 *	   monitor resource or function is not supported. Hardware specific
 *	   errors may also be returned.
 */
int vme_lm_detach(struct vme_resource *resource, int monitor)
{
	struct vme_bridge *bridge = find_bridge(resource);
	struct vme_lm_resource *lm;

	if (resource->type != VME_LM) {
		printk(KERN_ERR "Not a Location Monitor resource\n");
		return -EINVAL;
	}

	lm = list_entry(resource->entry, struct vme_lm_resource, list);

	if (!bridge->lm_detach) {
		printk(KERN_ERR "vme_lm_detach not supported\n");
		return -EINVAL;
	}

	return bridge->lm_detach(lm, monitor);
}
EXPORT_SYMBOL(vme_lm_detach);

/**
 * vme_lm_free - Free allocated VME location monitor
 * @resource: Pointer to VME location monitor resource.
 *
 * Free allocation of a VME location monitor.
 *
 * WARNING: This function currently expects that any callbacks that have
 *          been attached to the location monitor have been removed.
 *
 * Return: Zero on success, -EINVAL when provided with an invalid location
 *	   monitor resource.
 */
void vme_lm_free(struct vme_resource *resource)
{
	struct vme_lm_resource *lm;

	if (resource->type != VME_LM) {
		printk(KERN_ERR "Not a Location Monitor resource\n");
		return;
	}

	lm = list_entry(resource->entry, struct vme_lm_resource, list);

	mutex_lock(&lm->mtx);

	/* XXX
	 * Check to see that there aren't any callbacks still attached, if
	 * there are we should probably be detaching them!
	 */

	lm->locked = 0;

	mutex_unlock(&lm->mtx);

	kfree(resource);
}
EXPORT_SYMBOL(vme_lm_free);

/**
 * vme_slot_num - Retrieve slot ID
 * @vdev: Pointer to VME device struct vme_dev assigned to driver instance.
 *
 * Retrieve the slot ID associated with the provided VME device.
 *
 * Return: The slot ID on success, -EINVAL if VME bridge cannot be determined
 *         or the function is not supported. Hardware specific errors may also
 *         be returned.
 */
int vme_slot_num(struct vme_dev *vdev)
{
	struct vme_bridge *bridge;

	bridge = vdev->bridge;
	if (!bridge) {
		printk(KERN_ERR "Can't find VME bus\n");
		return -EINVAL;
	}

	if (!bridge->slot_get) {
		printk(KERN_WARNING "vme_slot_num not supported\n");
		return -EINVAL;
	}

	return bridge->slot_get(bridge);
}
EXPORT_SYMBOL(vme_slot_num);

/**
 * vme_bus_num - Retrieve bus number
 * @vdev: Pointer to VME device struct vme_dev assigned to driver instance.
 *
 * Retrieve the bus enumeration associated with the provided VME device.
 *
 * Return: The bus number on success, -EINVAL if VME bridge cannot be
 *         determined.
 */
int vme_bus_num(struct vme_dev *vdev)
{
	struct vme_bridge *bridge;

	bridge = vdev->bridge;
	if (!bridge) {
		pr_err("Can't find VME bus\n");
		return -EINVAL;
	}

	return bridge->num;
}
EXPORT_SYMBOL(vme_bus_num);

/* - Bridge Registration --------------------------------------------------- */

static void vme_dev_release(struct device *dev)
{
	kfree(dev_to_vme_dev(dev));
}

/* Common bridge initialization */
struct vme_bridge *vme_init_bridge(struct vme_bridge *bridge)
{
	INIT_LIST_HEAD(&bridge->vme_error_handlers);
	INIT_LIST_HEAD(&bridge->master_resources);
	INIT_LIST_HEAD(&bridge->slave_resources);
	INIT_LIST_HEAD(&bridge->dma_resources);
	INIT_LIST_HEAD(&bridge->lm_resources);
	mutex_init(&bridge->irq_mtx);

	return bridge;
}
EXPORT_SYMBOL(vme_init_bridge);

int vme_register_bridge(struct vme_bridge *bridge)
{
	int i;
	int ret = -1;

	mutex_lock(&vme_buses_lock);
	for (i = 0; i < sizeof(vme_bus_numbers) * 8; i++) {
		if ((vme_bus_numbers & (1 << i)) == 0) {
			vme_bus_numbers |= (1 << i);
			bridge->num = i;
			INIT_LIST_HEAD(&bridge->devices);
			list_add_tail(&bridge->bus_list, &vme_bus_list);
			ret = 0;
			break;
		}
	}
	mutex_unlock(&vme_buses_lock);

	return ret;
}
EXPORT_SYMBOL(vme_register_bridge);

void vme_unregister_bridge(struct vme_bridge *bridge)
{
	struct vme_dev *vdev;
	struct vme_dev *tmp;

	mutex_lock(&vme_buses_lock);
	vme_bus_numbers &= ~(1 << bridge->num);
	list_for_each_entry_safe(vdev, tmp, &bridge->devices, bridge_list) {
		list_del(&vdev->drv_list);
		list_del(&vdev->bridge_list);
		device_unregister(&vdev->dev);
	}
	list_del(&bridge->bus_list);
	mutex_unlock(&vme_buses_lock);
}
EXPORT_SYMBOL(vme_unregister_bridge);

/* - Driver Registration --------------------------------------------------- */

static int __vme_register_driver_bus(struct vme_driver *drv,
	struct vme_bridge *bridge, unsigned int ndevs)
{
	int err;
	unsigned int i;
	struct vme_dev *vdev;
	struct vme_dev *tmp;

	for (i = 0; i < ndevs; i++) {
		vdev = kzalloc(sizeof(*vdev), GFP_KERNEL);
		if (!vdev) {
			err = -ENOMEM;
			goto err_devalloc;
		}
		vdev->num = i;
		vdev->bridge = bridge;
		vdev->dev.platform_data = drv;
		vdev->dev.release = vme_dev_release;
		vdev->dev.parent = bridge->parent;
		vdev->dev.bus = &vme_bus_type;
		dev_set_name(&vdev->dev, "%s.%u-%u", drv->name, bridge->num,
			vdev->num);

		err = device_register(&vdev->dev);
		if (err)
			goto err_reg;

		if (vdev->dev.platform_data) {
			list_add_tail(&vdev->drv_list, &drv->devices);
			list_add_tail(&vdev->bridge_list, &bridge->devices);
		} else
			device_unregister(&vdev->dev);
	}
	return 0;

err_reg:
	put_device(&vdev->dev);
err_devalloc:
	list_for_each_entry_safe(vdev, tmp, &drv->devices, drv_list) {
		list_del(&vdev->drv_list);
		list_del(&vdev->bridge_list);
		device_unregister(&vdev->dev);
	}
	return err;
}

static int __vme_register_driver(struct vme_driver *drv, unsigned int ndevs)
{
	struct vme_bridge *bridge;
	int err = 0;

	mutex_lock(&vme_buses_lock);
	list_for_each_entry(bridge, &vme_bus_list, bus_list) {
		/*
		 * This cannot cause trouble as we already have vme_buses_lock
		 * and if the bridge is removed, it will have to go through
		 * vme_unregister_bridge() to do it (which calls remove() on
		 * the bridge which in turn tries to acquire vme_buses_lock and
		 * will have to wait).
		 */
		err = __vme_register_driver_bus(drv, bridge, ndevs);
		if (err)
			break;
	}
	mutex_unlock(&vme_buses_lock);
	return err;
}

/**
 * vme_register_driver - Register a VME driver
 * @drv: Pointer to VME driver structure to register.
 * @ndevs: Maximum number of devices to allow to be enumerated.
 *
 * Register a VME device driver with the VME subsystem.
 *
 * Return: Zero on success, error value on registration failure.
 */
int vme_register_driver(struct vme_driver *drv, unsigned int ndevs)
{
	int err;

	drv->driver.name = drv->name;
	drv->driver.bus = &vme_bus_type;
	INIT_LIST_HEAD(&drv->devices);

	err = driver_register(&drv->driver);
	if (err)
		return err;

	err = __vme_register_driver(drv, ndevs);
	if (err)
		driver_unregister(&drv->driver);

	return err;
}
EXPORT_SYMBOL(vme_register_driver);

/**
 * vme_unregister_driver - Unregister a VME driver
 * @drv: Pointer to VME driver structure to unregister.
 *
 * Unregister a VME device driver from the VME subsystem.
 */
void vme_unregister_driver(struct vme_driver *drv)
{
	struct vme_dev *dev, *dev_tmp;

	mutex_lock(&vme_buses_lock);
	list_for_each_entry_safe(dev, dev_tmp, &drv->devices, drv_list) {
		list_del(&dev->drv_list);
		list_del(&dev->bridge_list);
		device_unregister(&dev->dev);
	}
	mutex_unlock(&vme_buses_lock);

	driver_unregister(&drv->driver);
}
EXPORT_SYMBOL(vme_unregister_driver);

/* - Bus Registration ------------------------------------------------------ */

static int vme_bus_match(struct device *dev, struct device_driver *drv)
{
	struct vme_driver *vme_drv;

	vme_drv = container_of(drv, struct vme_driver, driver);

	if (dev->platform_data == vme_drv) {
		struct vme_dev *vdev = dev_to_vme_dev(dev);

		if (vme_drv->match && vme_drv->match(vdev))
			return 1;

		dev->platform_data = NULL;
	}
	return 0;
}

static int vme_bus_probe(struct device *dev)
{
	struct vme_driver *driver;
	struct vme_dev *vdev = dev_to_vme_dev(dev);

	driver = dev->platform_data;
	if (driver->probe)
		return driver->probe(vdev);

	return -ENODEV;
}

static int vme_bus_remove(struct device *dev)
{
	struct vme_driver *driver;
	struct vme_dev *vdev = dev_to_vme_dev(dev);

	driver = dev->platform_data;
	if (driver->remove)
		return driver->remove(vdev);

	return -ENODEV;
}

struct bus_type vme_bus_type = {
	.name = "vme",
	.match = vme_bus_match,
	.probe = vme_bus_probe,
	.remove = vme_bus_remove,
};
EXPORT_SYMBOL(vme_bus_type);

static int __init vme_init(void)
{
	return bus_register(&vme_bus_type);
}
subsys_initcall(vme_init);
