/*
* RapidIO enumeration and discovery support
*
* Copyright 2005 MontaVista Software, Inc.
* Matt Porter <mporter@kernel.crashing.org>
*
* Copyright 2009 Integrated Device Technology, Inc.
* Alex Bounine <alexandre.bounine@idt.com>
* - Added Port-Write/Error Management initialization and handling
*
* Copyright 2009 Sysgo AG
* Thomas Moll <thomas.moll@sysgo.com>
* - Added Input- Output- enable functionality, to allow full communication
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/dma-mapping.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/timer.h>
#include <linux/jiffies.h>
#include <linux/slab.h>
#include "rio.h"
LIST_HEAD(rio_devices);
static LIST_HEAD(rio_switches);
static void rio_enum_timeout(unsigned long);
static void rio_init_em(struct rio_dev *rdev);
DEFINE_SPINLOCK(rio_global_list_lock);
static int next_destid = 0;
static int next_switchid = 0;
static int next_net = 0;
static int next_comptag = 1;
static struct timer_list rio_enum_timer =
TIMER_INITIALIZER(rio_enum_timeout, 0, 0);
static int rio_mport_phys_table[] = {
RIO_EFB_PAR_EP_ID,
RIO_EFB_PAR_EP_REC_ID,
RIO_EFB_SER_EP_ID,
RIO_EFB_SER_EP_REC_ID,
-1,
};
/**
* rio_get_device_id - Get the base/extended device id for a device
* @port: RIO master port
* @destid: Destination ID of device
* @hopcount: Hopcount to device
*
* Reads the base/extended device id from a device. Returns the
* 8/16-bit device ID.
*/
static u16 rio_get_device_id(struct rio_mport *port, u16 destid, u8 hopcount)
{
u32 result;
rio_mport_read_config_32(port, destid, hopcount, RIO_DID_CSR, &result);
return RIO_GET_DID(port->sys_size, result);
}
/**
* rio_set_device_id - Set the base/extended device id for a device
* @port: RIO master port
* @destid: Destination ID of device
* @hopcount: Hopcount to device
* @did: Device ID value to be written
*
* Writes the base/extended device id from a device.
*/
static void rio_set_device_id(struct rio_mport *port, u16 destid, u8 hopcount, u16 did)
{
rio_mport_write_config_32(port, destid, hopcount, RIO_DID_CSR,
RIO_SET_DID(port->sys_size, did));
}
/**
* 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.
*/
static 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));
}
/**
* rio_clear_locks- Release all host locks and signal enumeration complete
* @port: Master port to issue transaction
*
* Marks the component tag CSR on each device with the enumeration
* complete flag. When complete, it then release the host locks on
* e