// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * RapidIO interconnect services
 * (RapidIO Interconnect Specification, http://www.rapidio.org)
 *
 * Copyright 2005 MontaVista Software, Inc.
 * Matt Porter <mporter@kernel.crashing.org>
 *
 * Copyright 2009 - 2013 Integrated Device Technology, Inc.
 * Alex Bounine <alexandre.bounine@idt.com>
 */

#include <linux/types.h>
#include <linux/kernel.h>

#include <linux/delay.h>
#include <linux/init.h>
#include <linux/rio.h>
#include <linux/rio_drv.h>
#include <linux/rio_ids.h>
#include <linux/rio_regs.h>
#include <linux/module.h>
#include <linux/spinlock.h>
#include <linux/slab.h>
#include <linux/interrupt.h>

#include "rio.h"

/*
 * struct rio_pwrite - RIO portwrite event
 * @node:    Node in list of doorbell events
 * @pwcback: Doorbell event callback
 * @context: Handler specific context to pass on event
 */
struct rio_pwrite {
	struct list_head node;

	int (*pwcback)(struct rio_mport *mport, void *context,
		       union rio_pw_msg *msg, int step);
	void *context;
};

MODULE_DESCRIPTION("RapidIO Subsystem Core");
MODULE_AUTHOR("Matt Porter <mporter@kernel.crashing.org>");
MODULE_AUTHOR("Alexandre Bounine <alexandre.bounine@idt.com>");
MODULE_LICENSE("GPL");

static int hdid[RIO_MAX_MPORTS];
static int ids_num;
module_param_array(hdid, int, &ids_num, 0);
MODULE_PARM_DESC(hdid,
	"Destination ID assignment to local RapidIO controllers");

static LIST_HEAD(rio_devices);
static LIST_HEAD(rio_nets);
static DEFINE_SPINLOCK(rio_global_list_lock);

static LIST_HEAD(rio_mports);
static LIST_HEAD(rio_scans);
static DEFINE_MUTEX(rio_mport_list_lock);
static unsigned char next_portid;
static DEFINE_SPINLOCK(rio_mmap_lock);

/**
 * rio_local_get_device_id - Get the base/extended device id for a port
 * @port: RIO master port from which to get the deviceid
 *
 * Reads the base/extended device id from the local device
 * implementing the master port. Returns the 8/16-bit device
 * id.
 */
u16 rio_local_get_device_id(struct rio_mport *port)
{
	u32 result;

	rio_local_read_config_32(port, RIO_DID_CSR, &result);

	return (RIO_GET_DID(port->sys_size, result));
}
EXPORT_SYMBOL_GPL(rio_local_get_device_id);

/**
 * rio_query_mport - Query mport device attributes
 * @port: mport device to query
 * @mport_attr: mport attributes data structure
 *
 * Returns attributes of specified mport through the
 * pointer to attributes data structure.
 */
int rio_query_mport(struct rio_mport *port,
		    struct rio_mport_attr *mport_attr)
{
	if (!port->ops->query_mport)
		return -ENODATA;
	return port->ops->query_mport(port, mport_attr);
}
EXPORT_SYMBOL(rio_query_mport);

/**
 * rio_alloc_net- Allocate and initialize a new RIO network data structure
 * @mport: Master port associated with the RIO network
 *
 * Allocates a RIO network structure, initializes per-network
 * list heads, and adds the associated master port to the
 * network list of associated master ports. Returns a
 * RIO network pointer on success or %NULL on failure.
 */
struct rio_net *rio_alloc_net(struct rio_mport *mport)
{
	struct rio_net *net = kzalloc(sizeof(*net), GFP_KERNEL);

	if (net) {
		INIT_LIST_HEAD(&net->node);
		INIT_LIST_HEAD(&net->devices);
		INIT_LIST_HEAD(&net->switches);
		INIT_LIST_HEAD(&net->mports);
		mport->net = net;
	}
	return net;
}
EXPORT_SYMBOL_GPL(rio_alloc_net);

int rio_add_net(struct rio_net *net)
{
	int err;

	err = device_register(&net->dev);
	if (err)
		return err;
	spin_lock(&rio_global_list_lock);
	list_add_tail(&net->node, &rio_nets);
	spin_unlock(&rio_global_list_lock);

	return 0;
}
EXPORT_SYMBOL_GPL(rio_add_net);

void rio_free_net(struct rio_net *net)
{
	spin_lock(&rio_global_list_lock);
	if (!list_empty(&net->node))
		list_del(&net->node);
	spin_unlock(&rio_global_list_lock);
	if (net->release)
		net->release(net);
	device_unregister(&net->dev);
}
EXPORT_SYMBOL_GPL(rio_free_net);

/**
 * rio_local_set_device_id - Set the base/extended device id for a port
 * @port: RIO master port
 * @did: Device ID value to be written
 *
 * Writes the base/extended device id from a device.
 */
void rio_local_set_device_id(struct rio_mport *port, u16 did)
{
	rio_local_write_config_32(port, RIO_DID_CSR,
				  RIO_SET_DID(port->sys_size, did));
}
EXPORT_SYMBOL_GPL(rio_local_set_device_id);

/**
 * rio_add_device- Adds a RIO device to the device model
 * @rdev: RIO device
 *
 * Adds the RIO device to the global device list and adds the RIO
 * device to the RIO device list.  Creates the generic sysfs nodes
 * for an RIO device.
 */
int rio_add_device(struct rio_dev *rdev)
{
	int err;

	atomic_set(&rdev->state, RIO_DEVICE_RUNNING);
	err = device_register(&rdev->dev);
	if (err)
		return err;

	spin_lock(&rio_global_list_lock);
	list_add_tail(&rdev->global_list, &rio_devices);
	if (rdev->net) {
		list_add_tail(&rdev->net_list, &rdev->net->devices);
		if (rdev->pef & RIO_PEF_SWITCH)
			list_add_tail(&rdev->rswitch->node,
				      &rdev->net->switches);
	}
	spin_unlock(&rio_global_list_lock);

	return 0;
}
EXPORT_SYMBOL_GPL(rio_add_device);

/*
 * rio_del_device - removes a RIO device from the device model
 * @rdev: RIO device
 * @state: device state to set during removal process
 *
 * Removes the RIO device to the kernel device list and subsystem's device list.
 * Clears sysfs entries for the removed device.
 */
void rio_del_device(struct rio_dev *rdev, enum rio_device_state state)
{
	pr_debug("RIO: %s: removing %s\n", __func__, rio_name(rdev));
	atomic_set(&rdev->state, state);
	spin_lock(&rio_global_list_lock);
	list_del(&rdev->global_list);
	if (rdev->net) {
		list_del(&rdev->net_list);
		if (rdev->pef & RIO_PEF_SWITCH) {
			list_del(&rdev->rswitch->node);
			kfree(rdev->rswitch->route_table);
		}
	}
	spin_unlock(&rio_global_list_lock);
	device_unregister(&rdev->dev);
}
EXPORT_SYMBOL_GPL(rio_del_device);

/**
 * rio_request_inb_mbox - request inbound mailbox service
 * @mport: RIO master port from which to allocate the mailbox resource
 * @dev_id: Device specific pointer to pass on event
 * @mbox: Mailbox number to claim
 * @entries: Number of entries in inbound mailbox queue
 * @minb: Callback to execute when inbound message is received
 *
 * Requests ownership of an inbound mailbox resource and binds
 * a callback function to the resource. Returns %0 on success.
 */
int rio_request_inb_mbox(struct rio_mport *mport,
			 void *dev_id,
			 int mbox,
			 int entries,
			 void (*minb) (struct rio_mport * mport, void *dev_id, int mbox,
				       int slot))
{
	int rc = -ENOSYS;
	struct resource *res;

	if (!mport->ops->open_inb_mbox)
		goto out;

	res = kzalloc(sizeof(*res), GFP_KERNEL);
	if (res) {
		rio_init_mbox_res(res, mbox, mbox);

		/* Make sure this mailbox isn't in use */
		rc = request_resource(&mport->riores[RIO_INB_MBOX_RESOURCE],
				      res);
		if (rc < 0) {
			kfree(res);
			goto out;
		}

		mport->inb_msg[mbox].res = res;

		/* Hook the inbound message callback */
		mport->inb_msg[mbox].mcback = minb;

		rc = mport->ops->open_inb_mbox(mport, dev_id, mbox, entries);
		if (rc) {
			mport->inb_msg[mbox].mcback = NULL;
			mport->inb_msg[mbox].res = NULL;
			release_resource(res);
			kfree(res);
		}
	} else
		rc = -ENOMEM;

      out:
	return rc;
}
EXPORT_SYMBOL_GPL(rio_request_inb_mbox);

/**
 * rio_release_inb_mbox - release inbound mailbox message service
 * @mport: RIO master port from which to release the mailbox resource
 * @mbox: Mailbox number to release
 *
 * Releases ownership of an inbound mailbox resource. Returns 0
 * if the request has been satisfied.
 */
int rio_release_inb_mbox(struct rio_mport *mport, int mbox)
{
	int rc;

	if (!mport->ops->close_inb_mbox || !mport->inb_msg[mbox].res)
		return -EINVAL;

	mport->ops->close_inb_mbox(mport, mbox);
	mport->inb_msg[mbox].mcback = NULL;

	rc = release_resource(mport->inb_msg[mbox].res);
	if (rc)
		return rc;

	kfree(mport->inb_msg[mbox].res);
	mport->inb_msg[mbox].res = NULL;

	return 0;
}
EXPORT_SYMBOL_GPL(rio_release_inb_mbox);

/**
 * rio_request_outb_mbox - request outbound mailbox service
 * @mport: RIO master port from which to allocate the mailbox resource
 * @dev_id: Device specific pointer to pass on event
 * @mbox: Mailbox number to claim
 * @entries: Number of entries in outbound mailbox queue
 * @moutb: Callback to execute when outbound message is sent
 *
 * Requests ownership of an outbound mailbox resource and binds
 * a callback function to the resource. Returns 0 on success.
 */
int rio_request_outb_mbox(struct rio_mport *mport,
			  void *dev_id,
			  int mbox,
			  int entries,
			  void (*moutb) (struct rio_mport * mport, void *dev_id, int mbox, int slot))
{
	int rc = -ENOSYS;
	struct resource *res;

	if (!mport->ops->open_outb_mbox)
		goto out;

	res = kzalloc(sizeof(*res), GFP_KERNEL);
	if (res) {
		rio_init_mbox_res(res, mbox, mbox);

		/* Make sure this outbound mailbox isn't in use */
		rc = request_resource(&mport->riores[RIO_OUTB_MBOX_RESOURCE],
				      res);
		if (rc < 0) {
			kfree(res);
			goto out;
		}

		mport->outb_msg[mbox].res = res;

		/* Hook the inbound message callback */
		mport->outb_msg[mbox].mcback = moutb;

		rc = mport->ops->open_outb_mbox(mport, dev_id, mbox, entries);
		if (rc) {
			mport->outb_msg[mbox].mcback = NULL;
			mport->outb_msg[mbox].res = NULL;
			release_resource(res);
			kfree(res);
		}
	} else
		rc = -ENOMEM;

      out:
	return rc;
}
EXPORT_SYMBOL_GPL(rio_request_outb_mbox);

/**
 * rio_release_outb_mbox - release outbound mailbox message service
 * @mport: RIO master port from which to release the mailbox resource
 * @mbox: Mailbox number to release
 *
 * Releases ownership of an inbound mailbox resource. Returns 0
 * if the request has been satisfied.
 */
int rio_release_outb_mbox(struct rio_mport *mport, int mbox)
{
	int rc;

	if (!mport->ops->close_outb_mbox || !mport->outb_msg[mbox].res)
		return -EINVAL;

	mport->ops->close_outb_mbox(mport, mbox);
	mport->outb_msg[mbox].mcback = NULL;

	rc = release_resource(mport->outb_msg[mbox].res);
	if (rc)
		return rc;

	kfree(mport->outb_msg[mbox].res);
	mport->outb_msg[mbox].res = NULL;

	return 0;
}
EXPORT_SYMBOL_GPL(rio_release_outb_mbox);

/**
 * rio_setup_inb_dbell - bind inbound doorbell callback
 * @mport: RIO master port to bind the doorbell callback
 * @dev_id: Device specific pointer to pass on event
 * @res: Doorbell message resource
 * @dinb: Callback to execute when doorbell is received
 *
 * Adds a doorbell resource/callback pair into a port's
 * doorbell event list. Returns 0 if the request has been
 * satisfied.
 */
static int
rio_setup_inb_dbell(struct rio_mport *mport, void *dev_id, struct resource *res,
		    void (*dinb) (struct rio_mport * mport, void *dev_id, u16 src, u16 dst,
				  u16 info))
{
	struct rio_dbell *dbell = kmalloc(sizeof(*dbell), GFP_KERNEL);

	if (!dbell)
		return -ENOMEM;

	dbell->res = res;
	dbell->dinb = dinb;
	dbell->dev_id = dev_id;

	mutex_lock(&mport->lock);
	list_add_tail(&dbell->node, &mport->dbells);
	mutex_unlock(&mport->lock);
	return 0;
}

/**
 * rio_request_inb_dbell - request inbound doorbell message service
 * @mport: RIO master port from which to allocate the doorbell resource
 * @dev_id: Device specific pointer to pass on event
 * @start: Doorbell info range start
 * @end: Doorbell info range end
 * @dinb: Callback to execute when doorbell is received
 *
 * Requests ownership of an inbound doorbell resource and binds
 * a callback function to the resource. Returns 0 if the request
 * has been satisfied.
 */
int rio_request_inb_dbell(struct rio_mport *mport,
			  void *dev_id,
			  u16 start,
			  u16 end,
			  void (*dinb) (struct rio_mport * mport, void *dev_id, u16 src,
					u16 dst, u16 info))
{
	int rc;
	struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL);

	if (res) {
		rio_init_dbell_res(res, start, end);

		/* Make sure these doorbells aren't in use */
		rc = request_resource(&mport->riores[RIO_DOORBELL_RESOURCE],
				      res);
		if (rc < 0) {
			kfree(res);
			goto out;
		}

		/* Hook the doorbell callback */
		rc = rio_setup_inb_dbell(mport, dev_id, res, dinb);
	} else
		rc = -ENOMEM;

      out:
	return rc;
}
EXPORT_SYMBOL_GPL(rio_request_inb_dbell);

/**
 * rio_release_inb_dbell - release inbound doorbell message service
 * @mport: RIO master port from which to release the doorbell resource
 * @start: Doorbell info range start
 * @end: Doorbell info range end
 *
 * Releases ownership of an inbound doorbell resource and removes
 * callback from the doorbell event list. Returns 0 if the request
 * has been satisfied.
 */
int rio_release_inb_dbell(struct rio_mport *mport, u16 start, u16 end)
{
	int rc = 0, found = 0;
	struct rio_dbell *dbell;

	mutex_lock(&mport->lock);
	list_for_each_entry(dbell, &mport->dbells, node) {
		if ((dbell->res->start == start) && (dbell->res->end == end)) {
			list_del(&dbell->node);
			found = 1;
			break;
		}
	}
	mutex_unlock(&mport->lock);

	/* If we can't find an exact match, fail */
	if (!found) {
		rc = -EINVAL;
		goto out;
	}

	/* Release the doorbell resource */
	rc = release_resource(dbell->res);

	/* Free the doorbell event */
	kfree(dbell);

      out:
	return rc;
}
EXPORT_SYMBOL_GPL(rio_release_inb_dbell);

/**
 * rio_request_outb_dbell - request outbound doorbell message range
 * @rdev: RIO device from which to allocate the doorbell resource
 * @start: Doorbell message range start
 * @end: Doorbell message range end
 *
 * Requests ownership of a doorbell message range. Returns a resource
 * if the request has been satisfied or %NULL on failure.
 */
struct resource *rio_request_outb_dbell(struct rio_dev *rdev, u16 start,
					u16 end)
{
	struct resource *res = kzalloc(sizeof(struct resource), GFP_KERNEL);

	if (res) {
		rio_init_dbell_res(res, start, end);

		/* Make sure these doorbells aren't in use */
		if (request_resource(&rdev->riores[RIO_DOORBELL_RESOURCE], res)
		    < 0) {
			kfree(res);
			res = NULL;
		}
	}

	return res;
}
EXPORT_SYMBOL_GPL(rio_request_outb_dbell);

/**
 * rio_release_outb_dbell - release outbound doorbell message range
 * @rdev: RIO device from which to release the doorbell resource
 * @res: Doorbell resource to be freed
 *
 * Releases ownership of a doorbell message range. Returns 0 if the
 * request has been satisfied.
 */
int rio_release_outb_dbell(struct rio_dev *rdev, struct resource *res)
{
	int rc = release_resource(res);

	kfree(res);

	return rc;
}
EXPORT_SYMBOL_GPL(rio_release_outb_dbell);

/**
 * rio_add_mport_pw_handler - add port-write message handler into the list
 *                            of mport specific pw handlers
 * @mport:   RIO master port to bind the portwrite callback
 * @context: Handler specific context to pass on event
 * @pwcback: Callback to execute when portwrite is received
 *
 * Returns 0 if the request has been satisfied.
 */
int rio_add_mport_pw_handler(struct rio_mport *mport, void *context,
			     int (*pwcback)(struct rio_mport *mport,
			     void *context, union rio_pw_msg *msg, int step))
{
	struct rio_pwrite *pwrite = kzalloc(sizeof(*pwrite), GFP_KERNEL);

	if (!pwrite)
		return -ENOMEM;

	pwrite->pwcback = pwcback;
	pwrite->context = context;
	mutex_lock(&mport->lock);
	list_add_tail(&pwrite->node, &mport->pwrites);
	mutex_unlock(&mport->lock);
	return 0;
}
EXPORT_SYMBOL_GPL(rio_add_mport_pw_handler);

/**
 * rio_del_mport_pw_handler - remove port-write message handler from the list
 *                            of mport specific pw handlers
 * @mport:   RIO master port to bind the portwrite callback
 * @context: Registered handler specific context to pass on event
 * @pwcback: Registered callback function
 *
 * Returns 0 if the request has been satisfied.
 */
int rio_del_mport_pw_handler(struct rio_mport *mport, void *context,
			     int (*pwcback)(struct rio_mport *mport,
			     void *context, union rio_pw_msg *msg, int step))
{
	int rc = -EINVAL;
	struct rio_pwrite *pwrite;

	mutex_lock(&mport->lock);
	list_for_each_entry(pwrite, &mport->pwrites, node) {
		if (pwrite->pwcback == pwcback && pwrite->context == context) {
			list_del(&pwrite->node);
			kfree(pwrite);
			rc = 0;
			break;
		}
	}
	mutex_unlock(&mport->lock);

	return rc;
}
EXPORT_SYMBOL_GPL(rio_del_mport_pw_handler);

/**
 * rio_request_inb_pwrite - request inbound port-write message service for
 *                          specific RapidIO device
 * @rdev: RIO device to which register inbound port-write callback routine
 * @pwcback: Callback routine to execute when port-write is received
 *
 * Binds a port-write callback function to the RapidIO device.
 * Returns 0 if the request has been satisfied.
 */
int rio_request_inb_pwrite(struct rio_dev *rdev,
	int (*pwcback)(struct rio_dev *rdev, union rio_pw_msg *msg, int step))
{
	int rc = 0;

	spin_lock(&rio_global_list_lock);
	if (rdev->pwcback)
		rc = -ENOMEM;
	else
		rdev->pwcback = pwcback;

	spin_unlock(&rio_global_list_lock);
	return rc;
}
EXPORT_SYMBOL_GPL(rio_request_inb_pwrite);

/**
 * rio_release_inb_pwrite - release inbound port-write message service
 *                          associated with specific RapidIO device
 * @rdev: RIO device which registered for inbound port-write callback
 *
 * Removes callback from the rio_dev structure. Returns 0 if the request
 * has been satisfied.
 */
int rio_release_inb_pwrite(struct rio_dev *rdev)
{
	int rc = -ENOMEM;

	spin_lock(&rio_global_list_lock);
	if (rdev->pwcback) {
		rdev->pwcback = NULL;
		rc = 0;
	}

	spin_unlock(&rio_global_list_lock);
	return rc;
}
EXPORT_SYMBOL_GPL(rio_release_inb_pwrite);

/**
 * rio_pw_enable - Enables/disables port-write handling by a master port
 * @mport: Master port associated with port-write handling
 * @enable:  1=enable,  0=disable
 */
void rio_pw_enable(struct rio_mport *mport, int enable)
{
	if (mport->ops->pwenable) {
		mutex_lock(&mport->lock);

		if ((enable && ++mport->pwe_refcnt == 1) ||
		    (!enable && mport->pwe_refcnt && --mport->pwe_refcnt == 0))
			mport->ops->pwenable(mport, enable);
		mutex_unlock(&mport->lock);
	}
}
EXPORT_SYMBOL_GPL(rio_pw_enable);

/**
 * rio_map_inb_region -- Map inbound memory region.
 * @mport: Master port.
 * @local: physical address of memory region to be mapped
 * @rbase: RIO base address assigned to this window
 * @size: Size of the memory region
 * @rflags: Flags for mapping.
 *
 * Return: 0 -- Success.
 *
 * This function will create the mapping from RIO space to local memory.
 */
int rio_map_inb_region(struct rio_mport *mport, dma_addr_t local,
			u64 rbase, u32 size, u32 rflags)
{
	int rc;
	unsigned long flags;

	if (!mport->ops->map_inb)
		return -1;
	spin_lock_irqsave(&rio_mmap_lock, flags);
	rc = mport->ops->map_inb(mport, local, rbase, size, rflags);
	spin_unlock_irqrestore(&rio_mmap_lock, flags);
	return rc;
}
EXPORT_SYMBOL_GPL(rio_map_inb_region);

/**
 * rio_unmap_inb_region -- Unmap the inbound memory region
 * @mport: Master port
 * @lstart: physical address of memory region to be unmapped
 */
void rio_unmap_inb_region(struct rio_mport *mport, dma_addr_t lstart)
{
	unsigned long flags;
	if (!mport->ops->unmap_inb)
		return;
	spin_lock_irqsave(&rio_mmap_lock, flags);
	mport->ops->unmap_inb(mport, lstart);
	spin_unlock_irqrestore(&rio_mmap_lock, flags);
}
EXPORT_SYMBOL_GPL(rio_unmap_inb_region);

/**
 * rio_map_outb_region -- Map outbound memory region.
 * @mport: Master port.
 * @destid: destination id window points to
 * @rbase: RIO base address window translates to
 * @size: Size of the memory region
 * @rflags: Flags for mapping.
 * @local: physical address of memory region mapped
 *
 * Return: 0 -- Success.
 *
 * This function will create the mapping from RIO space to local memory.
 */
int rio_map_outb_region(struct rio_mport *mport, u16 destid, u64 rbase,
			u32 size, u32 rflags, dma_addr_t *local)
{
	int rc;
	unsigned long flags;

	if (!mport->ops->map_outb)
		return -ENODEV;

	spin_lock_irqsave(&rio_mmap_lock, flags);
	rc = mport->ops->map_outb(mport, destid, rbase, size,
		rflags, local);
	spin_unlock_irqrestore(&rio_mmap_lock, flags);

	return rc;
}
EXPORT_SYMBOL_GPL(rio_map_outb_region);

/**
 * rio_unmap_inb_region -- Unmap the inbound memory region
 * @mport: Master port
 * @destid: destination id mapping points to
 * @rstart: RIO base address window translates to
 */
void rio_unmap_outb_region(struct rio_mport *mport, u16 destid, u64 rstart)
{
	unsigned long flags;

	if (!mport->ops->unmap_outb)
		return;

	spin_lock_irqsave(&rio_mmap_lock, flags);
	mport->ops->unmap_outb(mport, destid, rstart);
	spin_unlock_irqrestore(&rio_mmap_lock, flags);
}
EXPORT_SYMBOL_GPL(rio_unmap_outb_region);

/**
 * rio_mport_get_physefb - Helper function that returns register offset
 *                      for Physical Layer Extended Features Block.
 * @port: Master port to issue transaction
 * @local: Indicate a local master port or remote device access
 * @destid: Destination ID of the device
 * @hopcount: Number of switch hops to the device
 * @rmap: pointer to location to store register map type info
 */
u32
rio_mport_get_physefb(struct rio_mport *port, int local,
		      u16 destid, u8 hopcount, u32 *rmap)
{
	u32 ext_ftr_ptr;
	u32 ftr_header;

	ext_ftr_ptr = rio_mport_get_efb(port, local, destid, hopcount, 0);

	while (ext_ftr_ptr)  {
		if (local)
			rio_local_read_config_32(port, ext_ftr_ptr,
						 &ftr_header);
		else
			rio_mport_read_config_32(port, destid, hopcount,
						 ext_ftr_ptr, &ftr_header);

		ftr_header = RIO_GET_BLOCK_ID(ftr_header);
		switch (ftr_header) {

		case RIO_EFB_SER_EP_ID:
		case RIO_EFB_SER_EP_REC_ID:
		case RIO_EFB_SER_EP_FREE_ID:
		case RIO_EFB_SER_EP_M1_ID:
		case RIO_EFB_SER_EP_SW_M1_ID:
		case RIO_EFB_SER_EPF_M1_ID:
		case RIO_EFB_SER_EPF_SW_M1_ID:
			*rmap = 1;
			return ext_ftr_ptr;

		case RIO_EFB_SER_EP_M2_ID:
		case RIO_EFB_SER_EP_SW_M2_ID:
		case RIO_EFB_SER_EPF_M2_ID:
		case RIO_EFB_SER_EPF_SW_M2_ID:
			*rmap = 2;
			return ext_ftr_ptr;

		default:
			break;
		}

		ext_ftr_ptr = rio_mport_get_efb(port, local, destid,
						hopcount, ext_ftr_ptr);
	}

	return ext_ftr_ptr;
}
EXPORT_SYMBOL_GPL(rio_mport_get_physefb);

/**
 * rio_get_comptag - Begin or continue searching for a RIO device by component tag
 * @comp_tag: RIO component tag to match
 * @from: Previous RIO device found in search, or %NULL for new search
 *
 * Iterates through the list of known RIO devices. If a RIO device is
 * found with a matching @comp_tag, a pointer to its device
 * structure is returned. Otherwise, %NULL is returned. A new search
 * is initiated by passing %NULL to the @from argument. Otherwise, if
 * @from is not %NULL, searches continue from next device on the global
 * list.
 */
struct rio_dev *rio_get_comptag(u32 comp_tag, struct rio_dev *from)
{
	struct list_head *n;
	struct rio_dev *rdev;

	spin_lock(&rio_global_list_lock);
	n = from ? from->global_list.next : rio_devices.next;

	while (n && (n != &rio_devices)) {
		rdev = rio_dev_g(n);
		if (rdev->comp_tag == comp_tag)
			goto exit;
		n = n->next;
	}
	rdev = NULL;
exit:
	spin_unlock(&rio_global_list_lock);
	return rdev;
}
EXPORT_SYMBOL_GPL(rio_get_comptag);

/**
 * rio_set_port_lockout - Sets/clears LOCKOUT bit (RIO EM 1.3) for a switch port.
 * @rdev: Pointer to RIO device control structure
 * @pnum: Switch port number to set LOCKOUT bit
 * @lock: Operation : set (=1) or clear (=0)
 */
int rio_set_port_lockout(struct rio_dev *rdev, u32 pnum, int lock)
{
	u32 regval;

	rio_read_config_32(rdev,
		RIO_DEV_PORT_N_CTL_CSR(rdev, pnum),
		&regval);
	if (lock)
		regval |= RIO_PORT_N_CTL_LOCKOUT;
	else
		regval &= ~RIO_PORT_N_CTL_LOCKOUT;

	rio_write_config_32(rdev,
		RIO_DEV_PORT_N_CTL_CSR(rdev, pnum),
		regval);
	return 0;
}
EXPORT_SYMBOL_GPL(rio_set_port_lockout);

/**
 * rio_enable_rx_tx_port - enable input receiver and output transmitter of
 * given port
 * @port: Master port associated with the RIO network
 * @local: local=1 select local port otherwise a far device is reached
 * @destid: Destination ID of the device to check host bit
 * @hopcount: Number of hops to reach the target
 * @port_num: Port (-number on switch) to enable on a far end device
 *
 * Returns 0 or 1 from on General Control Command and Status Register
 * (EXT_PTR+0x3C)
 */
int rio_enable_rx_tx_port(struct rio_mport *port,
			  int local, u16 destid,
			  u8 hopcount, u8 port_num)
{
#ifdef CONFIG_RAPIDIO_ENABLE_RX_TX_PORTS
	u32 regval;
	u32 ext_ftr_ptr;
	u32 rmap;

	/*
	* enable rx input tx output port
	*/
	pr_debug("rio_enable_rx_tx_port(local = %d, destid = %d, hopcount = "
		 "%d, port_num = %d)\n", local, destid, hopcount, port_num);

	ext_ftr_ptr = rio_mport_get_physefb(port, local, destid,
					    hopcount, &rmap);

	if (local) {
		rio_local_read_config_32(port,
				ext_ftr_ptr + RIO_PORT_N_CTL_CSR(0, rmap),
				&regval);
	} else {
		if (rio_mport_read_config_32(port, destid, hopcount,
			ext_ftr_ptr + RIO_PORT_N_CTL_CSR(port_num, rmap),
				&regval) < 0)
			return -EIO;
	}

	regval = regval | RIO_PORT_N_CTL_EN_RX | RIO_PORT_N_CTL_EN_TX;

	if (local) {
		rio_local_write_config_32(port,
			ext_ftr_ptr + RIO_PORT_N_CTL_CSR(0, rmap), regval);
	} else {
		if (rio_mport_write_config_32(port, destid, hopcount,
			ext_ftr_ptr + RIO_PORT_N_CTL_CSR(port_num, rmap),
				regval) < 0)
			return -EIO;
	}
#endif
	return 0;
}
EXPORT_SYMBOL_GPL(rio_enable_rx_tx_port);


/**
 * rio_chk_dev_route - Validate route to the specified device.
 * @rdev:  RIO device failed to respond
 * @nrdev: Last active device on the route to rdev
 * @npnum: nrdev's port number on the route to rdev
 *
 * Follows a route to the specified RIO device to determine the last available
 * device (and corresponding RIO port) on the route.
 */
static int
rio_chk_dev_route(struct rio_dev *rdev, struct rio_dev **nrdev, int *npnum)
{
	u32 result;
	int p_port, rc = -EIO;
	struct rio_dev *prev = NULL;

	/* Find switch with failed RIO link */
	while (rdev->prev && (rdev->prev->pef & RIO_PEF_SWITCH)) {
		if (!rio_read_config_32(rdev->prev, RIO_DEV_ID_CAR, &result)) {
			prev = rdev->prev;
			break;
		}
		rdev = rdev->prev;
	}

	if (!prev)
		goto err_out;

	p_port = prev->rswitch->route_table[rdev->destid];

	if (p_port != RIO_INVALID_ROUTE) {
		pr_debug("RIO: link failed on [%s]-P%d\n",
			 rio_name(prev), p_port);
		*nrdev = prev;
		*npnum = p_port;
		rc = 0;
	} else
		pr_debug("RIO: failed to trace route to %s\n", rio_name(rdev));
err_out:
	return rc;
}

/**
 * rio_mport_chk_dev_access - Validate access to the specified device.
 * @mport: Master port to send transactions
 * @destid: Device destination ID in network
 * @hopcount: Number of hops into the network
 */
int
rio_mport_chk_dev_access(struct rio_mport *mport, u16 destid, u8 hopcount)
{
	int i = 0;
	u32 tmp;

	while (rio_mport_read_config_32(mport, destid, hopcount,
					RIO_DEV_ID_CAR, &tmp)) {
		i++;
		if (i == RIO_MAX_CHK_RETRY)
			return -EIO;
		mdelay(1);
	}

	return 0;
}
EXPORT_SYMBOL_GPL(rio_mport_chk_dev_access);

/**
 * rio_chk_dev_access - Validate access to the specified device.
 * @rdev: Pointer to RIO device control structure
 */
static int rio_chk_dev_access(struct rio_dev *rdev)
{
	return rio_mport_chk_dev_access(rdev->net->hport,
					rdev->destid, rdev->hopcount);
}

/**
 * rio_get_input_status - Sends a Link-Request/Input-Status control symbol and
 *                        returns link-response (if requested).
 * @rdev: RIO devive to issue Input-status command
 * @pnum: Device port number to issue the command
 * @lnkresp: Response from a link partner
 */
static int
rio_get_input_status(struct rio_dev *rdev, int pnum, u32 *lnkresp)
{
	u32 regval;
	int checkcount;

	if (lnkresp) {
		/* Read from link maintenance response register
		 * to clear valid bit */
		rio_read_config_32(rdev,
			RIO_DEV_PORT_N_MNT_RSP_CSR(rdev, pnum),
			&regval);
		udelay(50);
	}

	/* Issue Input-status command */
	rio_write_config_32(rdev,
		RIO_DEV_PORT_N_MNT_REQ_CSR(rdev, pnum),
		RIO_MNT_REQ_CMD_IS);

	/* Exit if the response is not expected */
	if (!lnkresp)
		return 0;

	checkcount = 3;
	while (checkcount--) {
		udelay(50);
		rio_read_config_32(rdev,
			RIO_DEV_PORT_N_MNT_RSP_CSR(rdev, pnum),
			&regval);
		if (regval & RIO_PORT_N_MNT_RSP_RVAL) {
			*lnkresp = regval;
			return 0;
		}
	}

	return -EIO;
}

/**
 * rio_clr_err_stopped - Clears port Error-stopped states.
 * @rdev: Pointer to RIO device control structure
 * @pnum: Switch port number to clear errors
 * @err_status: port error status (if 0 reads register from device)
 *
 * TODO: Currently this routine is not compatible with recovery process
 * specified for idt_gen3 RapidIO switch devices. It has to be reviewed
 * to implement universal recovery process that is compatible full range
 * off available devices.
 * IDT gen3 switch driver now implements HW-specific error handler that
 * issues soft port reset to the port to reset ERR_STOP bits and ackIDs.
 */
static int rio_clr_err_stopped(struct rio_dev *rdev, u32 pnum, u32 err_status)
{
	struct rio_dev *nextdev = rdev->rswitch->nextdev[pnum];
	u32 regval;
	u32 far_ackid, far_linkstat, near_ackid;

	if (err_status == 0)
		rio_read_config_32(rdev,
			RIO_DEV_PORT_N_ERR_STS_CSR(rdev, pnum),
			&err_status);

	if (err_status & RIO_PORT_N_ERR_STS_OUT_ES) {
		pr_debug("RIO_EM: servicing Output Error-Stopped state\n");
		/*
		 * Send a Link-Request/Input-Status control symbol
		 */
		if (rio_get_input_status(rdev, pnum, &regval)) {
			pr_debug("RIO_EM: Input-status response timeout\n");
			goto rd_err;
		}

		pr_debug("RIO_EM: SP%d Input-status response=0x%08x\n",
			 pnum, regval);
		far_ackid = (regval & RIO_PORT_N_MNT_RSP_ASTAT) >> 5;
		far_linkstat = regval & RIO_PORT_N_MNT_RSP_LSTAT;
		rio_read_config_32(rdev,
			RIO_DEV_PORT_N_ACK_STS_CSR(rdev, pnum),
			&regval);
		pr_debug("RIO_EM: SP%d_ACK_STS_CSR=0x%08x\n", pnum, regval);
		near_ackid = (regval & RIO_PORT_N_ACK_INBOUND) >> 24;
		pr_debug("RIO_EM: SP%d far_ackID=0x%02x far_linkstat=0x%02x" \
			 " near_ackID=0x%02x\n",
			pnum, far_ackid, far_linkstat, near_ackid);

		/*
		 * If required, synchronize ackIDs of near and
		 * far sides.
		 */
		if ((far_ackid != ((regval & RIO_PORT_N_ACK_OUTSTAND) >> 8)) ||
		    (far_ackid != (regval & RIO_PORT_N_ACK_OUTBOUND))) {
			/* Align near outstanding/outbound ackIDs with
			 * far inbound.
			 */
			rio_write_config_32(rdev,
				RIO_DEV_PORT_N_ACK_STS_CSR(rdev, pnum),
				(near_ackid << 24) |
					(far_ackid << 8) | far_ackid);
			/* Align far outstanding/outbound ackIDs with
			 * near inbound.
			 */
			far_ackid++;
			if (!nextdev) {
				pr_debug("RIO_EM: nextdev pointer == NULL\n");
				goto rd_err;
			}

			rio_write_config_32(nextdev,
				RIO_DEV_PORT_N_ACK_STS_CSR(nextdev,
					RIO_GET_PORT_NUM(nextdev->swpinfo)),
				(far_ackid << 24) |
				(near_ackid << 8) | near_ackid);
		}
rd_err:
		rio_read_config_32(rdev, RIO_DEV_PORT_N_ERR_STS_CSR(rdev, pnum),
				   &err_status);
		pr_debug("RIO_EM: SP%d_ERR_STS_CSR=0x%08x\n", pnum, err_status);
	}

	if ((err_status & RIO_PORT_N_ERR_STS_INP_ES) && nextdev) {
		pr_debug("RIO_EM: servicing Input Error-Stopped state\n");
		rio_get_input_status(nextdev,
				     RIO_GET_PORT_NUM(nextdev->swpinfo), NULL);
		udelay(50);

		rio_read_config_32(rdev, RIO_DEV_PORT_N_ERR_STS_CSR(rdev, pnum),
				   &err_status);
		pr_debug("RIO_EM: SP%d_ERR_STS_CSR=0x%08x\n", pnum, err_status);
	}

	return (err_status & (RIO_PORT_N_ERR_STS_OUT_ES |
			      RIO_PORT_N_ERR_STS_INP_ES)) ? 1 : 0;
}

/**
 * rio_inb_pwrite_handler - inbound port-write message handler
 * @mport:  mport device associated with port-write
 * @pw_msg: pointer to inbound port-write message
 *
 * Processes an inbound port-write message. Returns 0 if the request
 * has been satisfied.
 */
int rio_inb_pwrite_handler(struct rio_mport *mport, union rio_pw_msg *pw_msg)
{
	struct rio_dev *rdev;
	u32 err_status, em_perrdet, em_ltlerrdet;
	int rc, portnum;
	struct rio_pwrite *pwrite;

#ifdef DEBUG_PW
	{
		u32 i;

		pr_debug("%s: PW to mport_%d:\n", __func__, mport->id);
		for (i = 0; i < RIO_PW_MSG_SIZE / sizeof(u32); i = i + 4) {
			pr_debug("0x%02x: %08x %08x %08x %08x\n",
				i * 4, pw_msg->raw[i], pw_msg->raw[i + 1],
				pw_msg->raw[i + 2], pw_msg->raw[i + 3]);
		}
	}
#endif

	rdev = rio_get_comptag((pw_msg->em.comptag & RIO_CTAG_UDEVID), NULL);
	if (rdev) {
		pr_debug("RIO: Port-Write message from %s\n", rio_name(rdev));
	} else {
		pr_debug("RIO: %s No matching device for CTag 0x%08x\n",
			__func__, pw_msg->em.comptag);
	}

	/* Call a device-specific handler (if it is registered for the device).
	 * This may be the service for endpoints that send device-specific
	 * port-write messages. End-point messages expected to be handled
	 * completely by EP specific device driver.
	 * For switches rc==0 signals that no standard processing required.
	 */
	if (rdev && rdev->pwcback) {
		rc = rdev->pwcback(rdev, pw_msg, 0);
		if (rc == 0)
			return 0;
	}

	mutex_lock(&mport->lock);
	list_for_each_entry(pwrite, &mport->pwrites, node)
		pwrite->pwcback(mport, pwrite->context, pw_msg, 0);
	mutex_unlock(&mport->lock);

	if (!rdev)
		return 0;

	/*
	 * FIXME: The code below stays as it was before for now until we decide
	 * how to do default PW handling in combination with per-mport callbacks
	 */

	portnum = pw_msg->em.is_port & 0xFF;

	/* Check if device and route to it are functional:
	 * Sometimes devices may send PW message(s) just before being
	 * powered down (or link being lost).
	 */
	if (rio_chk_dev_access(rdev)) {
		pr_debug("RIO: device access failed - get link partner\n");
		/* Scan route to the device and identify failed link.
		 * This will replace device and port reported in PW message.
		 * PW message should not be used after this point.
		 */
		if (rio_chk_dev_route(rdev, &rdev, &portnum)) {
			pr_err("RIO: Route trace for %s failed\n",
				rio_name(rdev));
			return -EIO;
		}
		pw_msg = NULL;
	}

	/* For End-point devices processing stops here */
	if (!(rdev->pef & RIO_PEF_SWITCH))
		return 0;

	if (rdev->phys_efptr == 0) {
		pr_err("RIO_PW: Bad switch initialization for %s\n",
			rio_name(rdev));
		return 0;
	}

	/*
	 * Process the port-write notification from switch
	 */
	if (rdev->rswitch->ops && rdev->rswitch->ops->em_handle)
		rdev->rswitch->ops->em_handle(rdev, portnum);

	rio_read_config_32(rdev, RIO_DEV_PORT_N_ERR_STS_CSR(rdev, portnum),
			   &err_status);
	pr_debug("RIO_PW: SP%d_ERR_STS_CSR=0x%08x\n", portnum, err_status);

	if (err_status & RIO_PORT_N_ERR_STS_PORT_OK) {

		if (!(rdev->rswitch->port_ok & (1 << portnum))) {
			rdev->rswitch->port_ok |= (1 << portnum);
			rio_set_port_lockout(rdev, portnum, 0);
			/* Schedule Insertion Service */
			pr_debug("RIO_PW: Device Insertion on [%s]-P%d\n",
			       rio_name(rdev), portnum);
		}

		/* Clear error-stopped states (if reported).
		 * Depending on the link partner state, two attempts
		 * may be needed for successful recovery.
		 */
		if (err_status & (RIO_PORT_N_ERR_STS_OUT_ES |
				  RIO_PORT_N_ERR_STS_INP_ES)) {
			if (rio_clr_err_stopped(rdev, portnum, err_status))
				rio_clr_err_stopped(rdev, portnum, 0);
		}
	}  else { /* if (err_status & RIO_PORT_N_ERR_STS_PORT_UNINIT) */

		if (rdev->rswitch->port_ok & (1 << portnum)) {
			rdev->rswitch->port_ok &= ~(1 << portnum);
			rio_set_port_lockout(rdev, portnum, 1);

			if (rdev->phys_rmap == 1) {
			rio_write_config_32(rdev,
				RIO_DEV_PORT_N_ACK_STS_CSR(rdev, portnum),
				RIO_PORT_N_ACK_CLEAR);
			} else {
				rio_write_config_32(rdev,
					RIO_DEV_PORT_N_OB_ACK_CSR(rdev, portnum),
					RIO_PORT_N_OB_ACK_CLEAR);
				rio_write_config_32(rdev,
					RIO_DEV_PORT_N_IB_ACK_CSR(rdev, portnum),
					0);
			}

			/* Schedule Extraction Service */
			pr_debug("RIO_PW: Device Extraction on [%s]-P%d\n",
			       rio_name(rdev), portnum);
		}
	}

	rio_read_config_32(rdev,
		rdev->em_efptr + RIO_EM_PN_ERR_DETECT(portnum), &em_perrdet);
	if (em_perrdet) {
		pr_debug("RIO_PW: RIO_EM_P%d_ERR_DETECT=0x%08x\n",
			 portnum, em_perrdet);
		/* Clear EM Port N Error Detect CSR */
		rio_write_config_32(rdev,
			rdev->em_efptr + RIO_EM_PN_ERR_DETECT(portnum), 0);
	}

	rio_read_config_32(rdev,
		rdev->em_efptr + RIO_EM_LTL_ERR_DETECT, &em_ltlerrdet);
	if (em_ltlerrdet) {
		pr_debug("RIO_PW: RIO_EM_LTL_ERR_DETECT=0x%08x\n",
			 em_ltlerrdet);
		/* Clear EM L/T Layer Error Detect CSR */
		rio_write_config_32(rdev,
			rdev->em_efptr + RIO_EM_LTL_ERR_DETECT, 0);
	}

	/* Clear remaining error bits and Port-Write Pending bit */
	rio_write_config_32(rdev, RIO_DEV_PORT_N_ERR_STS_CSR(rdev, portnum),
			    err_status);

	return 0;
}
EXPORT_SYMBOL_GPL(rio_inb_pwrite_handler);

/**
 * rio_mport_get_efb - get pointer to next extended features block
 * @port: Master port to issue transaction
 * @local: Indicate a local master port or remote device access
 * @destid: Destination ID of the device
 * @hopcount: Number of switch hops to the device
 * @from: Offset of  current Extended Feature block header (if 0 starts
 * from	ExtFeaturePtr)
 */
u32
rio_mport_get_efb(struct rio_mport *port, int local, u16 destid,
		      u8 hopcount, u32 from)
{
	u32 reg_val;

	if (from == 0) {
		if (local)
			rio_local_read_config_32(port, RIO_ASM_INFO_CAR,
						 &reg_val);
		else
			rio_mport_read_config_32(port, destid, hopcount,
						 RIO_ASM_INFO_CAR, &reg_val);
		return reg_val & RIO_EXT_FTR_PTR_MASK;
	} else {
		if (local)
			rio_local_read_config_32(port, from, &reg_val);
		else
			rio_mport_read_config_32(port, destid, hopcount,
						 from, &reg_val);
		return RIO_GET_BLOCK_ID(reg_val);
	}
}
EXPORT_SYMBOL_GPL(rio_mport_get_efb);

/**
 * rio_mport_get_feature - query for devices' extended features
 * @port: Master port to issue transaction
 * @local: Indicate a local master port or remote device access
 * @destid: Destination ID of the device
 * @hopcount: Number of switch hops to the device
 * @ftr: Extended feature code
 *
 * Tell if a device supports a given RapidIO capability.
 * Returns the offset of the requested extended feature
 * block within the device's RIO configuration space or
 * 0 in case the device does not support it.
 */
u32
rio_mport_get_feature(struct rio_mport * port, int local, u16 destid,
		      u8 hopcount, int ftr)
{
	u32 asm_info, ext_ftr_ptr, ftr_header;

	if (local)
		rio_local_read_config_32(port, RIO_ASM_INFO_CAR, &asm_info);
	else
		rio_mport_read_config_32(port, destid, hopcount,
					 RIO_ASM_INFO_CAR, &asm_info);

	ext_ftr_ptr = asm_info & RIO_EXT_FTR_PTR_MASK;

	while (ext_ftr_ptr) {
		if (local)
			rio_local_read_config_32(port, ext_ftr_ptr,
						 &ftr_header);
		else
			rio_mport_read_config_32(port, destid, hopcount,
						 ext_ftr_ptr, &ftr_header);
		if (RIO_GET_BLOCK_ID(ftr_header) == ftr)
			return ext_ftr_ptr;

		ext_ftr_ptr = RIO_GET_BLOCK_PTR(ftr_header);
		if (!ext_ftr_ptr)
			break;
	}

	return 0;
}
EXPORT_SYMBOL_GPL(rio_mport_get_feature);

/**
 * rio_std_route_add_entry - Add switch route table entry using standard
 *   registers defined in RIO specification rev.1.3
 * @mport: Master port to issue transaction
 * @destid: Destination ID of the device
 * @hopcount: Number of switch hops to the device
 * @table: routing table ID (global or port-specific)
 * @route_destid: destID entry in the RT
 * @route_port: destination port for specified destID
 */
static int
rio_std_route_add_entry(struct rio_mport *mport, u16 destid, u8 hopcount,
			u16 table, u16 route_destid, u8 route_port)
{
	if (table == RIO_GLOBAL_TABLE) {
		rio_mport_write_config_32(mport, destid, hopcount,
				RIO_STD_RTE_CONF_DESTID_SEL_CSR,
				(u32)route_destid);
		rio_mport_write_config_32(mport, destid, hopcount,
				RIO_STD_RTE_CONF_PORT_SEL_CSR,
				(u32)route_port);
	}

	udelay(10);
	return 0;
}

/**
 * rio_std_route_get_entry - Read switch route table entry (port number)
 *   associated with specified destID using standard registers defined in RIO
 *   specification rev.1.3
 * @mport: Master port to issue transaction
 * @destid: Destination ID of the device
 * @hopcount: Number of switch hops to the device
 * @table: routing table ID (global or port-specific)
 * @route_destid: destID entry in the RT
 * @route_port: returned destination port for specified destID
 */
static int
rio_std_route_get_entry(struct rio_mport *mport, u16 destid, u8 hopcount,
			u16 table, u16 route_destid, u8 *route_port)
{
	u32 result;

	if (table == RIO_GLOBAL_TABLE) {
		rio_mport_write_config_32(mport, destid, hopcount,
				RIO_STD_RTE_CONF_DESTID_SEL_CSR, route_destid);
		rio_mport_read_config_32(mport, destid, hopcount,
				RIO_STD_RTE_CONF_PORT_SEL_CSR, &result);

		*route_port = (u8)result;
	}

	return 0;
}

/**
 * rio_std_route_clr_table - Clear swotch route table using standard registers
 *   defined in RIO specification rev.1.3.
 * @mport: Master port to issue transaction
 * @destid: Destination ID of the device
 * @hopcount: Number of switch hops to the device
 * @table: routing table ID (global or port-specific)
 */
static int
rio_std_route_clr_table(struct rio_mport *mport, u16 destid, u8 hopcount,
			u16 table)
{
	u32 max_destid = 0xff;
	u32 i, pef, id_inc = 1, ext_cfg = 0;
	u32 port_sel = RIO_INVALID_ROUTE;

	if (table == RIO_GLOBAL_TABLE) {
		rio_mport_read_config_32(mport, destid, hopcount,
					 RIO_PEF_CAR, &pef);

		if (mport->sys_size) {
			rio_mport_read_config_32(mport, destid, hopcount,
						 RIO_SWITCH_RT_LIMIT,
						 &max_destid);
			max_destid &= RIO_RT_MAX_DESTID;
		}

		if (pef & RIO_PEF_EXT_RT) {
			ext_cfg = 0x80000000;
			id_inc = 4;
			port_sel = (RIO_INVALID_ROUTE << 24) |
				   (RIO_INVALID_ROUTE << 16) |
				   (RIO_INVALID_ROUTE << 8) |
				   RIO_INVALID_ROUTE;
		}

		for (i = 0; i <= max_destid;) {
			rio_mport_write_config_32(mport, destid, hopcount,
					RIO_STD_RTE_CONF_DESTID_SEL_CSR,
					ext_cfg | i);
			rio_mport_write_config_32(mport, destid, hopcount,
					RIO_STD_RTE_CONF_PORT_SEL_CSR,
					port_sel);
			i += id_inc;
		}
	}

	udelay(10);
	return 0;
}

/**
 * rio_lock_device - Acquires host device lock for specified device
 * @port: Master port to send transaction
 * @destid: Destination ID for device/switch
 * @hopcount: Hopcount to reach switch
 * @wait_ms: Max wait time in msec (0 = no timeout)
 *
 * Attepts to acquire host device lock for specified device
 * Returns 0 if device lock acquired or EINVAL if timeout expires.
 */
int rio_lock_device(struct rio_mport *port, u16 destid,
		    u8 hopcount, int wait_ms)
{
	u32 result;
	int tcnt = 0;

	/* Attempt to acquire device lock */
	rio_mport_write_config_32(port, destid, hopcount,
				  RIO_HOST_DID_LOCK_CSR, port->host_deviceid);
	rio_mport_read_config_32(port, destid, hopcount,
				 RIO_HOST_DID_LOCK_CSR, &result);

	while (result != port->host_deviceid) {
		if (wait_ms != 0 && tcnt == wait_ms) {
			pr_debug("RIO: timeout when locking device %x:%x\n",
				destid, hopcount);
			return -EINVAL;
		}

		/* Delay a bit */
		mdelay(1);
		tcnt++;
		/* Try to acquire device lock again */
		rio_mport_write_config_32(port, destid,
			hopcount,
			RIO_HOST_DID_LOCK_CSR,
			port->host_deviceid);
		rio_mport_read_config_32(port, destid,
			hopcount,
			RIO_HOST_DID_LOCK_CSR, &result);
	}

	return 0;
}
EXPORT_SYMBOL_GPL(rio_lock_device);

/**
 * rio_unlock_device - Releases host device lock for specified device
 * @port: Master port to send transaction
 * @destid: Destination ID for device/switch
 * @hopcount: Hopcount to reach switch
 *
 * Returns 0 if device lock released or EINVAL if fails.
 */
int rio_unlock_device(struct rio_mport *port, u16 destid, u8 hopcount)
{
	u32 result;

	/* Release device lock */
	rio_mport_write_config_32(port, destid,
				  hopcount,
				  RIO_HOST_DID_LOCK_CSR,
				  port->host_deviceid);
	rio_mport_read_config_32(port, destid, hopcount,
		RIO_HOST_DID_LOCK_CSR, &result);
	if ((result & 0xffff) != 0xffff) {
		pr_debug("RIO: badness when releasing device lock %x:%x\n",
			 destid, hopcount);
		return -EINVAL;
	}

	return 0;
}
EXPORT_SYMBOL_GPL(rio_unlock_device);

/**
 * rio_route_add_entry- Add a route entry to a switch routing table
 * @rdev: RIO device
 * @table: Routing table ID
 * @route_destid: Destination ID to be routed
 * @route_port: Port number to be routed
 * @lock: apply a hardware lock on switch device flag (1=lock, 0=no_lock)
 *
 * If available calls the switch specific add_entry() method to add a route
 * entry into a switch routing table. Otherwise uses standard RT update method
 * as defined by RapidIO specification. A specific routing table can be selected
 * using the @table argument if a switch has per port routing tables or
 * the standard (or global) table may be used by passing
 * %RIO_GLOBAL_TABLE in @table.
 *
 * Returns %0 on success or %-EINVAL on failure.
 */
int rio_route_add_entry(struct rio_dev *rdev,
			u16 table, u16 route_destid, u8 route_port, int lock)
{
	int rc = -EINVAL;
	struct rio_switch_ops *ops = rdev->rswitch->ops;

	if (lock) {
		rc = rio_lock_device(rdev->net->hport, rdev->destid,
				     rdev->hopcount, 1000);
		if (rc)
			return rc;
	}

	spin_lock(&rdev->rswitch->lock);

	if (!ops || !ops->add_entry) {
		rc = rio_std_route_add_entry(rdev->net->hport, rdev->destid,
					     rdev->hopcount, table,
					     route_destid, route_port);
	} else if (try_module_get(ops->owner)) {
		rc = ops->add_entry(rdev->net->hport, rdev->destid,
				    rdev->hopcount, table, route_destid,
				    route_port);
		module_put(ops->owner);
	}

	spin_unlock(&rdev->rswitch->lock);

	if (lock)
		rio_unlock_device(rdev->net->hport, rdev->destid,
				  rdev->hopcount);

	return rc;
}
EXPORT_SYMBOL_GPL(rio_route_add_entry);

/**
 * rio_route_get_entry- Read an entry from a switch routing table
 * @rdev: RIO device
 * @table: Routing table ID
 * @route_destid: Destination ID to be routed
 * @route_port: Pointer to read port number into
 * @lock: apply a hardware lock on switch device flag (1=lock, 0=no_lock)
 *
 * If available calls the switch specific get_entry() method to fetch a route
 * entry from a switch routing table. Otherwise uses standard RT read method
 * as defined by RapidIO specification. A specific routing table can be selected
 * using the @table argument if a switch has per port routing tables or
 * the standard (or global) table may be used by passing
 * %RIO_GLOBAL_TABLE in @table.
 *
 * Returns %0 on success or %-EINVAL on failure.
 */
int rio_route_get_entry(struct rio_dev *rdev, u16 table,
			u16 route_destid, u8 *route_port, int lock)
{
	int rc = -EINVAL;
	struct rio_switch_ops *ops = rdev->rswitch->ops;

	if (lock) {
		rc = rio_lock_device(rdev->net->hport, rdev->destid,
				     rdev->hopcount, 1000);
		if (rc)
			return rc;
	}

	spin_lock(&rdev->rswitch->lock);

	if (!ops || !ops->get_entry) {
		rc = rio_std_route_get_entry(rdev->net->hport, rdev->destid,
					     rdev->hopcount, table,
					     route_destid, route_port);
	} else if (try_module_get(ops->owner)) {
		rc = ops->get_entry(rdev->net->hport, rdev->destid,
				    rdev->hopcount, table, route_destid,
				    route_port);
		module_put(ops->owner);
	}

	spin_unlock(&rdev->rswitch->lock);

	if (lock)
		rio_unlock_device(rdev->net->hport, rdev->destid,
				  rdev->hopcount);
	return rc;
}
EXPORT_SYMBOL_GPL(rio_route_get_entry);

/**
 * rio_route_clr_table - Clear a switch routing table
 * @rdev: RIO device
 * @table: Routing table ID
 * @lock: apply a hardware lock on switch device flag (1=lock, 0=no_lock)
 *
 * If available calls the switch specific clr_table() method to clear a switch
 * routing table. Otherwise uses standard RT write method as defined by RapidIO
 * specification. A specific routing table can be selected using the @table
 * argument if a switch has per port routing tables or the standard (or global)
 * table may be used by passing %RIO_GLOBAL_TABLE in @table.
 *
 * Returns %0 on success or %-EINVAL on failure.
 */
int rio_route_clr_table(struct rio_dev *rdev, u16 table, int lock)
{
	int rc = -EINVAL;
	struct rio_switch_ops *ops = rdev->rswitch->ops;

	if (lock) {
		rc = rio_lock_device(rdev->net->hport, rdev->destid,
				     rdev->hopcount, 1000);
		if (rc)
			return rc;
	}

	spin_lock(&rdev->rswitch->lock);

	if (!ops || !ops->clr_table) {
		rc = rio_std_route_clr_table(rdev->net->hport, rdev->destid,
					     rdev->hopcount, table);
	} else if (try_module_get(ops->owner)) {
		rc = ops->clr_table(rdev->net->hport, rdev->destid,
				    rdev->hopcount, table);

		module_put(ops->owner);
	}

	spin_unlock(&rdev->rswitch->lock);

	if (lock)
		rio_unlock_device(rdev->net->hport, rdev->destid,
				  rdev->hopcount);

	return rc;
}
EXPORT_SYMBOL_GPL(rio_route_clr_table);

#ifdef CONFIG_RAPIDIO_DMA_ENGINE

static bool rio_chan_filter(struct dma_chan *chan, void *arg)
{
	struct rio_mport *mport = arg;

	/* Check that DMA device belongs to the right MPORT */
	return mport == container_of(chan->device, struct rio_mport, dma);
}

/**
 * rio_request_mport_dma - request RapidIO capable DMA channel associated
 *   with specified local RapidIO mport device.
 * @mport: RIO mport to perform DMA data transfers
 *
 * Returns pointer to allocated DMA channel or NULL if failed.
 */
struct dma_chan *rio_request_mport_dma(struct rio_mport *mport)
{
	dma_cap_mask_t mask;

	dma_cap_zero(mask);
	dma_cap_set(DMA_SLAVE, mask);
	return dma_request_channel(mask, rio_chan_filter, mport);
}
EXPORT_SYMBOL_GPL(rio_request_mport_dma);

/**
 * rio_request_dma - request RapidIO capable DMA channel that supports
 *   specified target RapidIO device.
 * @rdev: RIO device associated with DMA transfer
 *
 * Returns pointer to allocated DMA channel or NULL if failed.
 */
struct dma_chan *rio_request_dma(struct rio_dev *rdev)
{
	return rio_request_mport_dma(rdev->net->hport);
}
EXPORT_SYMBOL_GPL(rio_request_dma);

/**
 * rio_release_dma - release specified DMA channel
 * @dchan: DMA channel to release
 */
void rio_release_dma(struct dma_chan *dchan)
{
	dma_release_channel(dchan);
}
EXPORT_SYMBOL_GPL(rio_release_dma);

/**
 * rio_dma_prep_xfer - RapidIO specific wrapper
 *   for device_prep_slave_sg callback defined by DMAENGINE.
 * @dchan: DMA channel to configure
 * @destid: target RapidIO device destination ID
 * @data: RIO specific data descriptor
 * @direction: DMA data transfer direction (TO or FROM the device)
 * @flags: dmaengine defined flags
 *
 * Initializes RapidIO capable DMA channel for the specified data transfer.
 * Uses DMA channel private extension to pass information related to remote
 * target RIO device.
 *
 * Returns: pointer to DMA transaction descriptor if successful,
 *          error-valued pointer or NULL if failed.
 */
struct dma_async_tx_descriptor *rio_dma_prep_xfer(struct dma_chan *dchan,
	u16 destid, struct rio_dma_data *data,
	enum dma_transfer_direction direction, unsigned long flags)
{
	struct rio_dma_ext rio_ext;

	if (!dchan->device->device_prep_slave_sg) {
		pr_err("%s: prep_rio_sg == NULL\n", __func__);
		return NULL;
	}

	rio_ext.destid = destid;
	rio_ext.rio_addr_u = data->rio_addr_u;
	rio_ext.rio_addr = data->rio_addr;
	rio_ext.wr_type = data->wr_type;

	return dmaengine_prep_rio_sg(dchan, data->sg, data->sg_len,
				     direction, flags, &rio_ext);
}
EXPORT_SYMBOL_GPL(rio_dma_prep_xfer);

/**
 * rio_dma_prep_slave_sg - RapidIO specific wrapper
 *   for device_prep_slave_sg callback defined by DMAENGINE.
 * @rdev: RIO device control structure
 * @dchan: DMA channel to configure
 * @data: RIO specific data descriptor
 * @direction: DMA data transfer direction (TO or FROM the device)
 * @flags: dmaengine defined flags
 *
 * Initializes RapidIO capable DMA channel for the specified data transfer.
 * Uses DMA channel private extension to pass information related to remote
 * target RIO device.
 *
 * Returns: pointer to DMA transaction descriptor if successful,
 *          error-valued pointer or NULL if failed.
 */
struct dma_async_tx_descriptor *rio_dma_prep_slave_sg(struct rio_dev *rdev,
	struct dma_chan *dchan, struct rio_dma_data *data,
	enum dma_transfer_direction direction, unsigned long flags)
{
	return rio_dma_prep_xfer(dchan,	rdev->destid, data, direction, flags);
}
EXPORT_SYMBOL_GPL(rio_dma_prep_slave_sg);

#endif /* CONFIG_RAPIDIO_DMA_ENGINE */

/**
 * rio_find_mport - find RIO mport by its ID
 * @mport_id: number (ID) of mport device
 *
 * Given a RIO mport number, the desired mport is located
 * in the global list of mports. If the mport is found, a pointer to its
 * data structure is returned.  If no mport is found, %NULL is returned.
 */
struct rio_mport *rio_find_mport(int mport_id)
{
	struct rio_mport *port;

	mutex_lock(&rio_mport_list_lock);
	list_for_each_entry(port, &rio_mports, node) {
		if (port->id == mport_id)
			goto found;
	}
	port = NULL;
found:
	mutex_unlock(&rio_mport_list_lock);

	return port;
}

/**
 * rio_register_scan - enumeration/discovery method registration interface
 * @mport_id: mport device ID for which fabric scan routine has to be set
 *            (RIO_MPORT_ANY = set for all available mports)
 * @scan_ops: enumeration/discovery operations structure
 *
 * Registers enumeration/discovery operations with RapidIO subsystem and
 * attaches it to the specified mport device (or all available mports
 * if RIO_MPORT_ANY is specified).
 *
 * Returns error if the mport already has an enumerator attached to it.
 * In case of RIO_MPORT_ANY skips mports with valid scan routines (no error).
 */
int rio_register_scan(int mport_id, struct rio_scan *scan_ops)
{
	struct rio_mport *port;
	struct rio_scan_node *scan;
	int rc = 0;

	pr_debug("RIO: %s for mport_id=%d\n", __func__, mport_id);

	if ((mport_id != RIO_MPORT_ANY && mport_id >= RIO_MAX_MPORTS) ||
	    !scan_ops)
		return -EINVAL;

	mutex_lock(&rio_mport_list_lock);

	/*
	 * Check if there is another enumerator already registered for
	 * the same mport ID (including RIO_MPORT_ANY). Multiple enumerators
	 * for the same mport ID are not supported.
	 */
	list_for_each_entry(scan, &rio_scans, node) {
		if (scan->mport_id == mport_id) {
			rc = -EBUSY;
			goto err_out;
		}
	}

	/*
	 * Allocate and initialize new scan registration node.
	 */
	scan = kzalloc(sizeof(*scan), GFP_KERNEL);
	if (!scan) {
		rc = -ENOMEM;
		goto err_out;
	}

	scan->mport_id = mport_id;
	scan->ops = scan_ops;

	/*
	 * Traverse the list of registered mports to attach this new scan.
	 *
	 * The new scan with matching mport ID overrides any previously attached
	 * scan assuming that old scan (if any) is the default one (based on the
	 * enumerator registration check above).
	 * If the new scan is the global one, it will be attached only to mports
	 * that do not have their own individual operations already attached.
	 */
	list_for_each_entry(port, &rio_mports, node) {
		if (port->id == mport_id) {
			port->nscan = scan_ops;
			break;
		} else if (mport_id == RIO_MPORT_ANY && !port->nscan)
			port->nscan = scan_ops;
	}

	list_add_tail(&scan->node, &rio_scans);

err_out:
	mutex_unlock(&rio_mport_list_lock);

	return rc;
}
EXPORT_SYMBOL_GPL(rio_register_scan);

/**
 * rio_unregister_scan - removes enumeration/discovery method from mport
 * @mport_id: mport device ID for which fabric scan routine has to be
 *            unregistered (RIO_MPORT_ANY = apply to all mports that use
 *            the specified scan_ops)
 * @scan_ops: enumeration/discovery operations structure
 *
 * Removes enumeration or discovery method assigned to the specified mport
 * device. If RIO_MPORT_ANY is specified, removes the specified operations from
 * all mports that have them attached.
 */
int rio_unregister_scan(int mport_id, struct rio_scan *scan_ops)
{
	struct rio_mport *port;
	struct rio_scan_node *scan;

	pr_debug("RIO: %s for mport_id=%d\n", __func__, mport_id);

	if (mport_id != RIO_MPORT_ANY && mport_id >= RIO_MAX_MPORTS)
		return -EINVAL;

	mutex_lock(&rio_mport_list_lock);

	list_for_each_entry(port, &rio_mports, node)
		if (port->id == mport_id ||
		    (mport_id == RIO_MPORT_ANY && port->nscan == scan_ops))
			port->nscan = NULL;

	list_for_each_entry(scan, &rio_scans, node) {
		if (scan->mport_id == mport_id) {
			list_del(&scan->node);
			kfree(scan);
			break;
		}
	}

	mutex_unlock(&rio_mport_list_lock);

	return 0;
}
EXPORT_SYMBOL_GPL(rio_unregister_scan);

/**
 * rio_mport_scan - execute enumeration/discovery on the specified mport
 * @mport_id: number (ID) of mport device
 */
int rio_mport_scan(int mport_id)
{
	struct rio_mport *port = NULL;
	int rc;

	mutex_lock(&rio_mport_list_lock);
	list_for_each_entry(port, &rio_mports, node) {
		if (port->id == mport_id)
			goto found;
	}
	mutex_unlock(&rio_mport_list_lock);
	return -ENODEV;
found:
	if (!port->nscan) {
		mutex_unlock(&rio_mport_list_lock);
		return -EINVAL;
	}

	if (!try_module_get(port->nscan->owner)) {
		mutex_unlock(&rio_mport_list_lock);
		return -ENODEV;
	}

	mutex_unlock(&rio_mport_list_lock);

	if (port->host_deviceid >= 0)
		rc = port->nscan->enumerate(port, 0);
	else
		rc = port->nscan->discover(port, RIO_SCAN_ENUM_NO_WAIT);

	module_put(port->nscan->owner);
	return rc;
}

static struct workqueue_struct *rio_wq;

struct rio_disc_work {
	struct work_struct	work;
	struct rio_mport	*mport;
};

static void disc_work_handler(struct work_struct *_work)
{
	struct rio_disc_work *work;

	work = container_of(_work, struct rio_disc_work, work);
	pr_debug("RIO: discovery work for mport %d %s\n",
		 work->mport->id, work->mport->name);
	if (try_module_get(work->mport->nscan->owner)) {
		work->mport->nscan->discover(work->mport, 0);
		module_put(work->mport->nscan->owner);
	}
}

int rio_init_mports(void)
{
	struct rio_mport *port;
	struct rio_disc_work *work;
	int n = 0;

	if (!next_portid)
		return -ENODEV;

	/*
	 * First, run enumerations and check if we need to perform discovery
	 * on any of the registered mports.
	 */
	mutex_lock(&rio_mport_list_lock);
	list_for_each_entry(port, &rio_mports, node) {
		if (port->host_deviceid >= 0) {
			if (port->nscan && try_module_get(port->nscan->owner)) {
				port->nscan->enumerate(port, 0);
				module_put(port->nscan->owner);
			}
		} else
			n++;
	}
	mutex_unlock(&rio_mport_list_lock);

	if (!n)
		goto no_disc;

	/*
	 * If we have mports that require discovery schedule a discovery work
	 * for each of them. If the code below fails to allocate needed
	 * resources, exit without error to keep results of enumeration
	 * process (if any).
	 * TODO: Implement restart of discovery process for all or
	 * individual discovering mports.
	 */
	rio_wq = alloc_workqueue("riodisc", 0, 0);
	if (!rio_wq) {
		pr_err("RIO: unable allocate rio_wq\n");
		goto no_disc;
	}

	work = kcalloc(n, sizeof *work, GFP_KERNEL);
	if (!work) {
		destroy_workqueue(rio_wq);
		goto no_disc;
	}

	n = 0;
	mutex_lock(&rio_mport_list_lock);
	list_for_each_entry(port, &rio_mports, node) {
		if (port->host_deviceid < 0 && port->nscan) {
			work[n].mport = port;
			INIT_WORK(&work[n].work, disc_work_handler);
			queue_work(rio_wq, &work[n].work);
			n++;
		}
	}

	flush_workqueue(rio_wq);
	mutex_unlock(&rio_mport_list_lock);
	pr_debug("RIO: destroy discovery workqueue\n");
	destroy_workqueue(rio_wq);
	kfree(work);

no_disc:
	return 0;
}
EXPORT_SYMBOL_GPL(rio_init_mports);

static int rio_get_hdid(int index)
{
	if (ids_num == 0 || ids_num <= index || index >= RIO_MAX_MPORTS)
		return -1;

	return hdid[index];
}

int rio_mport_initialize(struct rio_mport *mport)
{
	if (next_portid >= RIO_MAX_MPORTS) {
		pr_err("RIO: reached specified max number of mports\n");
		return -ENODEV;
	}

	atomic_set(&mport->state, RIO_DEVICE_INITIALIZING);
	mport->id = next_portid++;
	mport->host_deviceid = rio_get_hdid(mport->id);
	mport->nscan = NULL;
	mutex_init(&mport->lock);
	mport->pwe_refcnt = 0;
	INIT_LIST_HEAD(&mport->pwrites);

	return 0;
}
EXPORT_SYMBOL_GPL(rio_mport_initialize);

int rio_register_mport(struct rio_mport *port)
{
	struct rio_scan_node *scan = NULL;
	int res = 0;

	mutex_lock(&rio_mport_list_lock);

	/*
	 * Check if there are any registered enumeration/discovery operations
	 * that have to be attached to the added mport.
	 */
	list_for_each_entry(scan, &rio_scans, node) {
		if (port->id == scan->mport_id ||
		    scan->mport_id == RIO_MPORT_ANY) {
			port->nscan = scan->ops;
			if (port->id == scan->mport_id)
				break;
		}
	}

	list_add_tail(&port->node, &rio_mports);
	mutex_unlock(&rio_mport_list_lock);

	dev_set_name(&port->dev, "rapidio%d", port->id);
	port->dev.class = &rio_mport_class;
	atomic_set(&port->state, RIO_DEVICE_RUNNING);

	res = device_register(&port->dev);
	if (res)
		dev_err(&port->dev, "RIO: mport%d registration failed ERR=%d\n",
			port->id, res);
	else
		dev_dbg(&port->dev, "RIO: registered mport%d\n", port->id);

	return res;
}
EXPORT_SYMBOL_GPL(rio_register_mport);

static int rio_mport_cleanup_callback(struct device *dev, void *data)
{
	struct rio_dev *rdev = to_rio_dev(dev);

	if (dev->bus == &rio_bus_type)
		rio_del_device(rdev, RIO_DEVICE_SHUTDOWN);
	return 0;
}

static int rio_net_remove_children(struct rio_net *net)
{
	/*
	 * Unregister all RapidIO devices residing on this net (this will
	 * invoke notification of registered subsystem interfaces as well).
	 */
	device_for_each_child(&net->dev, NULL, rio_mport_cleanup_callback);
	return 0;
}

int rio_unregister_mport(struct rio_mport *port)
{
	pr_debug("RIO: %s %s id=%d\n", __func__, port->name, port->id);

	/* Transition mport to the SHUTDOWN state */
	if (atomic_cmpxchg(&port->state,
			   RIO_DEVICE_RUNNING,
			   RIO_DEVICE_SHUTDOWN) != RIO_DEVICE_RUNNING) {
		pr_err("RIO: %s unexpected state transition for mport %s\n",
			__func__, port->name);
	}

	if (port->net && port->net->hport == port) {
		rio_net_remove_children(port->net);
		rio_free_net(port->net);
	}

	/*
	 * Unregister all RapidIO devices attached to this mport (this will
	 * invoke notification of registered subsystem interfaces as well).
	 */
	mutex_lock(&rio_mport_list_lock);
	list_del(&port->node);
	mutex_unlock(&rio_mport_list_lock);
	device_unregister(&port->dev);

	return 0;
}
EXPORT_SYMBOL_GPL(rio_unregister_mport);
