/*
 * IEEE 1394 for Linux
 *
 * CSR implementation, iso/bus manager implementation.
 *
 * Copyright (C) 1999 Andreas E. Bombe
 *               2002 Manfred Weihs <weihs@ict.tuwien.ac.at>
 *
 * This code is licensed under the GPL.  See the file COPYING in the root
 * directory of the kernel sources for details.
 *
 *
 * Contributions:
 *
 * Manfred Weihs <weihs@ict.tuwien.ac.at>
 *        configuration ROM manipulation
 *
 */

#include <linux/string.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/param.h>
#include <linux/spinlock.h>

#include "csr1212.h"
#include "ieee1394_types.h"
#include "hosts.h"
#include "ieee1394.h"
#include "highlevel.h"

/* Module Parameters */
/* this module parameter can be used to disable mapping of the FCP registers */

static int fcp = 1;
module_param(fcp, int, 0444);
MODULE_PARM_DESC(fcp, "Map FCP registers (default = 1, disable = 0).");

static struct csr1212_keyval *node_cap = NULL;

static void add_host(struct hpsb_host *host);
static void remove_host(struct hpsb_host *host);
static void host_reset(struct hpsb_host *host);
static int read_maps(struct hpsb_host *host, int nodeid, quadlet_t *buffer,
		     u64 addr, size_t length, u16 fl);
static int write_fcp(struct hpsb_host *host, int nodeid, int dest,
		     quadlet_t *data, u64 addr, size_t length, u16 flags);
static int read_regs(struct hpsb_host *host, int nodeid, quadlet_t *buf,
		     u64 addr, size_t length, u16 flags);
static int write_regs(struct hpsb_host *host, int nodeid, int destid,
		      quadlet_t *data, u64 addr, size_t length, u16 flags);
static int lock_regs(struct hpsb_host *host, int nodeid, quadlet_t *store,
		     u64 addr, quadlet_t data, quadlet_t arg, int extcode, u16 fl);
static int lock64_regs(struct hpsb_host *host, int nodeid, octlet_t * store,
		       u64 addr, octlet_t data, octlet_t arg, int extcode, u16 fl);
static int read_config_rom(struct hpsb_host *host, int nodeid, quadlet_t *buffer,
			   u64 addr, size_t length, u16 fl);
static u64 allocate_addr_range(u64 size, u32 alignment, void *__host);
static void release_addr_range(u64 addr, void *__host);

static struct hpsb_highlevel csr_highlevel = {
	.name =		"standard registers",
	.add_host =	add_host,
	.remove_host =	remove_host,
	.host_reset =	host_reset,
};

static struct hpsb_address_ops map_ops = {
	.read = read_maps,
};

static struct hpsb_address_ops fcp_ops = {
	.write = write_fcp,
};

static struct hpsb_address_ops reg_ops = {
	.read = read_regs,
	.write = write_regs,
	.lock = lock_regs,
	.lock64 = lock64_regs,
};

static struct hpsb_address_ops config_rom_ops = {
	.read = read_config_rom,
};

struct csr1212_bus_ops csr_bus_ops = {
	.allocate_addr_range =	allocate_addr_range,
	.release_addr =		release_addr_range,
};


static u16 csr_crc16(unsigned *data, int length)
{
        int check=0, i;
        int shift, sum, next=0;

        for (i = length; i; i--) {
                for (next = check, shift = 28; shift >= 0; shift -= 4 ) {
                        sum = ((next >> 12) ^ (be32_to_cpu(*data) >> shift)) & 0xf;
                        next = (next << 4) ^ (sum << 12) ^ (sum << 5) ^ (sum);
                }
                check = next & 0xffff;
                data++;
        }

        return check;
}

static void host_reset(struct hpsb_host *host)
{
        host->csr.state &= 0x300;

        host->csr.bus_manager_id = 0x3f;
        host->csr.bandwidth_available = 4915;
	host->csr.channels_available_hi = 0xfffffffe;	/* pre-alloc ch 31 per 1394a-2000 */
        host->csr.channels_available_lo = ~0;
	host->csr.broadcast_channel = 0x80000000 | 31;

	if (host->is_irm) {
		if (host->driver->hw_csr_reg) {
			host->driver->hw_csr_reg(host, 2, 0xfffffffe, ~0);
		}
	}

        host->csr.node_ids = host->node_id << 16;

        if (!host->is_root) {
                /* clear cmstr bit */
                host->csr.state &= ~0x100;
        }

        host->csr.topology_map[1] =
                cpu_to_be32(be32_to_cpu(host->csr.topology_map[1]) + 1);
        host->csr.topology_map[2] = cpu_to_be32(host->node_count << 16
                                                | host->selfid_count);
        host->csr.topology_map[0] =
                cpu_to_be32((host->selfid_count + 2) << 16
                            | csr_crc16(host->csr.topology_map + 1,
                                        host->selfid_count + 2));

        host->csr.speed_map[1] =
                cpu_to_be32(be32_to_cpu(host->csr.speed_map[1]) + 1);
        host->csr.speed_map[0] = cpu_to_be32(0x3f1 << 16
                                             | csr_crc16(host->csr.speed_map+1,
                                                         0x3f1));
}

/*
 * HI == seconds (bits 0:2)
 * LO == fraction units of 1/8000 of a second, as per 1394 (bits 19:31)
 *
 * Convert to units and then to HZ, for comparison to jiffies.
 *
 * By default this will end up being 800 units, or 100ms (125usec per
 * unit).
 *
 * NOTE: The spec says 1/8000, but also says we can compute based on 1/8192
 * like CSR specifies. Should make our math less complex.
 */
static inline void calculate_expire(struct csr_control *csr)
{
	unsigned long units;

	/* Take the seconds, and convert to units */
	units = (unsigned long)(csr->split_timeout_hi & 0x07) << 13;

	/* Add in the fractional units */
	units += (unsigned long)(csr->split_timeout_lo >> 19);

	/* Convert to jiffies */
	csr->expire = (unsigned long)(units * HZ) >> 13UL;

	/* Just to keep from rounding low */
	csr->expire++;

	HPSB_VERBOSE("CSR: setting expire to %lu, HZ=%u", csr->expire, HZ);
}


static void add_host(struct hpsb_host *host)
{
	struct csr1212_keyval *root;
	quadlet_t bus_info[CSR_BUS_INFO_SIZE];

	hpsb_register_addrspace(&csr_highlevel, host, &reg_ops,
				CSR_REGISTER_BASE,
				CSR_REGISTER_BASE + CSR_CONFIG_ROM);
	hpsb_register_addrspace(&csr_highlevel, host, &config_rom_ops,
				CSR_REGISTER_BASE + CSR_CONFIG_ROM,
				CSR_REGISTER_BASE + CSR_CONFIG_ROM_END);
	if (fcp) {
		hpsb_register_addrspace(&csr_highlevel, host, &fcp_ops,
					CSR_REGISTER_BASE + CSR_FCP_COMMAND,
					CSR_REGISTER_BASE + CSR_FCP_END);
	}
	hpsb_register_addrspace(&csr_highlevel, host, &map_ops,
				CSR_REGISTER_BASE + CSR_TOPOLOGY_MAP,
				CSR_REGISTER_BASE + CSR_TOPOLOGY_MAP_END);
	hpsb_register_addrspace(&csr_highlevel, host, &map_ops,
				CSR_REGISTER_BASE + CSR_SPEED_MAP,
				CSR_REGISTER_BASE + CSR_SPEED_MAP_END);

        spin_lock_init(&host->csr.lock);

        host->csr.state                 = 0;
        host->csr.node_ids              = 0;
        host->csr.split_timeout_hi      = 0;
        host->csr.split_timeout_lo      = 800 << 19;
	calculate_expire(&host->csr);
        host->csr.cycle_time            = 0;
        host->csr.bus_time              = 0;
        host->csr.bus_manager_id        = 0x3f;
        host->csr.bandwidth_available   = 4915;
	host->csr.channels_available_hi = 0xfffffffe;	/* pre-alloc ch 31 per 1394a-2000 */
        host->csr.channels_available_lo = ~0;
	host->csr.broadcast_channel = 0x80000000 | 31;

	if (host->is_irm) {
		if (host->driver->hw_csr_reg) {
			host->driver->hw_csr_reg(host, 2, 0xfffffffe, ~0);
		}
	}

	if (host->csr.max_rec >= 9)
		host->csr.max_rom = 2;
	else if (host->csr.max_rec >= 5)
		host->csr.max_rom = 1;
	else
		host->csr.max_rom = 0;

	host->csr.generation = 2;

	bus_info[1] = __constant_cpu_to_be32(0x31333934);
	bus_info[2] = cpu_to_be32((1 << CSR_IRMC_SHIFT) |
				  (1 << CSR_CMC_SHIFT) |
				  (1 << CSR_ISC_SHIFT) |
				  (0 << CSR_BMC_SHIFT) |
				  (0 << CSR_PMC_SHIFT) |
				  (host->csr.cyc_clk_acc << CSR_CYC_CLK_ACC_SHIFT) |
				  (host->csr.max_rec << CSR_MAX_REC_SHIFT) |
				  (host->csr.max_rom << CSR_MAX_ROM_SHIFT) |
				  (host->csr.generation << CSR_GENERATION_SHIFT) |
				  host->csr.lnk_spd);

	bus_info[3] = cpu_to_be32(host->csr.guid_hi);
	bus_info[4] = cpu_to_be32(host->csr.guid_lo);

	/* The hardware copy of the bus info block will be set later when a
	 * bus reset is issued. */

	csr1212_init_local_csr(host->csr.rom, bus_info, host->csr.max_rom);

	root = host->csr.rom->root_kv;

	if(csr1212_attach_keyval_to_directory(root, node_cap) != CSR1212_SUCCESS) {
		HPSB_ERR("Failed to attach Node Capabilities to root directory");
	}

	host->update_config_rom = 1;
}

static void remove_host(struct hpsb_host *host)
{
	quadlet_t bus_info[CSR_BUS_INFO_SIZE];

	bus_info[1] = __constant_cpu_to_be32(0x31333934);
	bus_info[2] = cpu_to_be32((0 << CSR_IRMC_SHIFT) |
				  (0 << CSR_CMC_SHIFT) |
				  (0 << CSR_ISC_SHIFT) |
				  (0 << CSR_BMC_SHIFT) |
				  (0 << CSR_PMC_SHIFT) |
				  (host->csr.cyc_clk_acc << CSR_CYC_CLK_ACC_SHIFT) |
				  (host->csr.max_rec << CSR_MAX_REC_SHIFT) |
				  (0 << CSR_MAX_ROM_SHIFT) |
				  (0 << CSR_GENERATION_SHIFT) |
				  host->csr.lnk_spd);

	bus_info[3] = cpu_to_be32(host->csr.guid_hi);
	bus_info[4] = cpu_to_be32(host->csr.guid_lo);

	csr1212_detach_keyval_from_directory(host->csr.rom->root_kv, node_cap);

	csr1212_init_local_csr(host->csr.rom, bus_info, 0);
	host->update_config_rom = 1;
}


int hpsb_update_config_rom(struct hpsb_host *host, const quadlet_t *new_rom,
	size_t buffersize, unsigned char rom_version)
{
	unsigned long flags;
	int ret;

	HPSB_NOTICE("hpsb_update_config_rom() is deprecated");

        spin_lock_irqsave(&host->csr.lock, flags);
	if (rom_version != host->csr.generation)
                ret = -1;
	else if (buffersize > host->csr.rom->cache_head->size)
		ret = -2;
        else {
		/* Just overwrite the generated ConfigROM image with new data,
		 * it can be regenerated later. */
		memcpy(host->csr.rom->cache_head->data, new_rom, buffersize);
		host->csr.rom->cache_head->len = buffersize;

		if (host->driver->set_hw_config_rom)
			host->driver->set_hw_config_rom(host, host->csr.rom->bus_info_data);
		/* Increment the generation number to keep some sort of sync
		 * with the newer ConfigROM manipulation method. */
		host->csr.generation++;
		if (host->csr.generation > 0xf || host->csr.generation < 2)
			host->csr.generation = 2;
		ret=0;
        }
        spin_unlock_irqrestore(&host->csr.lock, flags);
        return ret;
}


/* Read topology / speed maps and configuration ROM */
static int read_maps(struct hpsb_host *host, int nodeid, quadlet_t *buffer,
                     u64 addr, size_t length, u16 fl)
{
	unsigned long flags;
        int csraddr = addr - CSR_REGISTER_BASE;
        const char *src;

        spin_lock_irqsave(&host->csr.lock, flags);

	if (csraddr < CSR_SPEED_MAP) {
                src = ((char *)host->csr.topology_map) + csraddr
                        - CSR_TOPOLOGY_MAP;
        } else {
                src = ((char *)host->csr.speed_map) + csraddr - CSR_SPEED_MAP;
        }

        memcpy(buffer, src, length);
        spin_unlock_irqrestore(&host->csr.lock, flags);
        return RCODE_COMPLETE;
}


#define out if (--length == 0) break

static int read_regs(struct hpsb_host *host, int nodeid, quadlet_t *buf,
                     u64 addr, size_t length, u16 flags)
{
        int csraddr = addr - CSR_REGISTER_BASE;
        int oldcycle;
        quadlet_t ret;

        if ((csraddr | length) & 0x3)
                return RCODE_TYPE_ERROR;

        length /= 4;

        switch (csraddr) {
        case CSR_STATE_CLEAR:
                *(buf++) = cpu_to_be32(host->csr.state);
                out;
        case CSR_STATE_SET:
                *(buf++) = cpu_to_be32(host->csr.state);
                out;
        case CSR_NODE_IDS:
                *(buf++) = cpu_to_be32(host->csr.node_ids);
                out;

        case CSR_RESET_START:
                return RCODE_TYPE_ERROR;

                /* address gap - handled by default below */

        case CSR_SPLIT_TIMEOUT_HI:
                *(buf++) = cpu_to_be32(host->csr.split_timeout_hi);
                out;
        case CSR_SPLIT_TIMEOUT_LO:
                *(buf++) = cpu_to_be32(host->csr.split_timeout_lo);
                out;

                /* address gap */
                return RCODE_ADDRESS_ERROR;

        case CSR_CYCLE_TIME:
                oldcycle = host->csr.cycle_time;
                host->csr.cycle_time =
                        host->driver->devctl(host, GET_CYCLE_COUNTER, 0);

                if (oldcycle > host->csr.cycle_time) {
                        /* cycle time wrapped around */
                        host->csr.bus_time += 1 << 7;
                }
                *(buf++) = cpu_to_be32(host->csr.cycle_time);
                out;
        case CSR_BUS_TIME:
                oldcycle = host->csr.cycle_time;
                host->csr.cycle_time =
                        host->driver->devctl(host, GET_CYCLE_COUNTER, 0);

                if (oldcycle > host->csr.cycle_time) {
                        /* cycle time wrapped around */
                        host->csr.bus_time += (1 << 7);
                }
                *(buf++) = cpu_to_be32(host->csr.bus_time
                                       | (host->csr.cycle_time >> 25));
                out;

                /* address gap */
                return RCODE_ADDRESS_ERROR;

        case CSR_BUSY_TIMEOUT:
                /* not yet implemented */
                return RCODE_ADDRESS_ERROR;

        case CSR_BUS_MANAGER_ID:
                if (host->driver->hw_csr_reg)
                        ret = host->driver->hw_csr_reg(host, 0, 0, 0);
                else
                        ret = host->csr.bus_manager_id;

                *(buf++) = cpu_to_be32(ret);
                out;
        case CSR_BANDWIDTH_AVAILABLE:
                if (host->driver->hw_csr_reg)
                        ret = host->driver->hw_csr_reg(host, 1, 0, 0);
                else
                        ret = host->csr.bandwidth_available;

                *(buf++) = cpu_to_be32(ret);
                out;
        case CSR_CHANNELS_AVAILABLE_HI:
                if (host->driver->hw_csr_reg)
                        ret = host->driver->hw_csr_reg(host, 2, 0, 0);
                else
                        ret = host->csr.channels_available_hi;

                *(buf++) = cpu_to_be32(ret);
                out;
        case CSR_CHANNELS_AVAILABLE_LO:
                if (host->driver->hw_csr_reg)
                        ret = host->driver->hw_csr_reg(host, 3, 0, 0);
                else
                        ret = host->csr.channels_available_lo;

                *(buf++) = cpu_to_be32(ret);
                out;

	case CSR_BROADCAST_CHANNEL:
		*(buf++) = cpu_to_be32(host->csr.broadcast_channel);
		out;

                /* address gap to end - fall through to default */
        default:
                return RCODE_ADDRESS_ERROR;
        }

        return RCODE_COMPLETE;
}

static int write_regs(struct hpsb_host *host, int nodeid, int destid,
		      quadlet_t *data, u64 addr, size_t length, u16 flags)
{
        int csraddr = addr - CSR_REGISTER_BASE;

        if ((csraddr | length) & 0x3)
                return RCODE_TYPE_ERROR;

        length /= 4;

        switch (csraddr) {
        case CSR_STATE_CLEAR:
                /* FIXME FIXME FIXME */
                printk("doh, someone wants to mess with state clear\n");
                out;
        case CSR_STATE_SET:
                printk("doh, someone wants to mess with state set\n");
                out;

        case CSR_NODE_IDS:
                host->csr.node_ids &= NODE_MASK << 16;
                host->csr.node_ids |= be32_to_cpu(*(data++)) & (BUS_MASK << 16);
                host->node_id = host->csr.node_ids >> 16;
                host->driver->devctl(host, SET_BUS_ID, host->node_id >> 6);
                out;

        case CSR_RESET_START:
                /* FIXME - perform command reset */
                out;

                /* address gap */
                return RCODE_ADDRESS_ERROR;

        case CSR_SPLIT_TIMEOUT_HI:
                host->csr.split_timeout_hi =
                        be32_to_cpu(*(data++)) & 0x00000007;
		calculate_expire(&host->csr);
                out;
        case CSR_SPLIT_TIMEOUT_LO:
                host->csr.split_timeout_lo =
                        be32_to_cpu(*(data++)) & 0xfff80000;
		calculate_expire(&host->csr);
                out;

                /* address gap */
                return RCODE_ADDRESS_ERROR;

        case CSR_CYCLE_TIME:
                /* should only be set by cycle start packet, automatically */
                host->csr.cycle_time = be32_to_cpu(*data);
                host->driver->devctl(host, SET_CYCLE_COUNTER,
                                       be32_to_cpu(*(data++)));
                out;
        case CSR_BUS_TIME:
                host->csr.bus_time = be32_to_cpu(*(data++)) & 0xffffff80;
                out;

                /* address gap */
                return RCODE_ADDRESS_ERROR;

        case CSR_BUSY_TIMEOUT:
                /* not yet implemented */
                return RCODE_ADDRESS_ERROR;

        case CSR_BUS_MANAGER_ID:
        case CSR_BANDWIDTH_AVAILABLE:
        case CSR_CHANNELS_AVAILABLE_HI:
        case CSR_CHANNELS_AVAILABLE_LO:
                /* these are not writable, only lockable */
                return RCODE_TYPE_ERROR;

	case CSR_BROADCAST_CHANNEL:
		/* only the valid bit can be written */
		host->csr.broadcast_channel = (host->csr.broadcast_channel & ~0x40000000)
                        | (be32_to_cpu(*data) & 0x40000000);
		out;

                /* address gap to end - fall through */
        default:
                return RCODE_ADDRESS_ERROR;
        }

        return RCODE_COMPLETE;
}

#undef out


static int lock_regs(struct hpsb_host *host, int nodeid, quadlet_t *store,
                     u64 addr, quadlet_t data, quadlet_t arg, int extcode, u16 fl)
{
        int csraddr = addr - CSR_REGISTER_BASE;
        unsigned long flags;
        quadlet_t *regptr = NULL;

        if (csraddr & 0x3)
		return RCODE_TYPE_ERROR;

        if (csraddr < CSR_BUS_MANAGER_ID || csraddr > CSR_CHANNELS_AVAILABLE_LO
            || extcode != EXTCODE_COMPARE_SWAP)
                goto unsupported_lockreq;

        data = be32_to_cpu(data);
        arg = be32_to_cpu(arg);

	/* Is somebody releasing the broadcast_channel on us? */
	if (csraddr == CSR_CHANNELS_AVAILABLE_HI && (data & 0x1)) {
		/* Note: this is may not be the right way to handle
		 * the problem, so we should look into the proper way
		 * eventually. */
		HPSB_WARN("Node [" NODE_BUS_FMT "] wants to release "
			  "broadcast channel 31.  Ignoring.",
			  NODE_BUS_ARGS(host, nodeid));

		data &= ~0x1;	/* keep broadcast channel allocated */
	}

        if (host->driver->hw_csr_reg) {
                quadlet_t old;

                old = host->driver->
                        hw_csr_reg(host, (csraddr - CSR_BUS_MANAGER_ID) >> 2,
                                   data, arg);

                *store = cpu_to_be32(old);
                return RCODE_COMPLETE;
        }

        spin_lock_irqsave(&host->csr.lock, flags);

        switch (csraddr) {
        case CSR_BUS_MANAGER_ID:
                regptr = &host->csr.bus_manager_id;
		*store = cpu_to_be32(*regptr);
		if (*regptr == arg)
			*regptr = data;
                break;

        case CSR_BANDWIDTH_AVAILABLE:
        {
                quadlet_t bandwidth;
                quadlet_t old;
                quadlet_t new;

                regptr = &host->csr.bandwidth_available;
                old = *regptr;

                /* bandwidth available algorithm adapted from IEEE 1394a-2000 spec */
                if (arg > 0x1fff) {
                        *store = cpu_to_be32(old);	/* change nothing */
			break;
                }
                data &= 0x1fff;
                if (arg >= data) {
                        /* allocate bandwidth */
                        bandwidth = arg - data;
                        if (old >= bandwidth) {
                                new = old - bandwidth;
                                *store = cpu_to_be32(arg);
                                *regptr = new;
                        } else {
                                *store = cpu_to_be32(old);
                        }
                } else {
                        /* deallocate bandwidth */
                        bandwidth = data - arg;
                        if (old + bandwidth < 0x2000) {
                                new = old + bandwidth;
                                *store = cpu_to_be32(arg);
                                *regptr = new;
                        } else {
                                *store = cpu_to_be32(old);
                        }
                }
                break;
        }

        case CSR_CHANNELS_AVAILABLE_HI:
        {
                /* Lock algorithm for CHANNELS_AVAILABLE as recommended by 1394a-2000 */
                quadlet_t affected_channels = arg ^ data;

                regptr = &host->csr.channels_available_hi;

                if ((arg & affected_channels) == (*regptr & affected_channels)) {
                        *regptr ^= affected_channels;
                        *store = cpu_to_be32(arg);
                } else {
                        *store = cpu_to_be32(*regptr);
                }

                break;
        }

        case CSR_CHANNELS_AVAILABLE_LO:
        {
                /* Lock algorithm for CHANNELS_AVAILABLE as recommended by 1394a-2000 */
                quadlet_t affected_channels = arg ^ data;

                regptr = &host->csr.channels_available_lo;

                if ((arg & affected_channels) == (*regptr & affected_channels)) {
                        *regptr ^= affected_channels;
                        *store = cpu_to_be32(arg);
                } else {
                        *store = cpu_to_be32(*regptr);
                }
                break;
        }
        }

        spin_unlock_irqrestore(&host->csr.lock, flags);

        return RCODE_COMPLETE;

 unsupported_lockreq:
        switch (csraddr) {
        case CSR_STATE_CLEAR:
        case CSR_STATE_SET:
        case CSR_RESET_START:
        case CSR_NODE_IDS:
        case CSR_SPLIT_TIMEOUT_HI:
        case CSR_SPLIT_TIMEOUT_LO:
        case CSR_CYCLE_TIME:
        case CSR_BUS_TIME:
	case CSR_BROADCAST_CHANNEL:
                return RCODE_TYPE_ERROR;

        case CSR_BUSY_TIMEOUT:
                /* not yet implemented - fall through */
        default:
                return RCODE_ADDRESS_ERROR;
        }
}

static int lock64_regs(struct hpsb_host *host, int nodeid, octlet_t * store,
		       u64 addr, octlet_t data, octlet_t arg, int extcode, u16 fl)
{
	int csraddr = addr - CSR_REGISTER_BASE;
	unsigned long flags;

	data = be64_to_cpu(data);
	arg = be64_to_cpu(arg);

	if (csraddr & 0x3)
		return RCODE_TYPE_ERROR;

	if (csraddr != CSR_CHANNELS_AVAILABLE
	    || extcode != EXTCODE_COMPARE_SWAP)
		goto unsupported_lock64req;

	/* Is somebody releasing the broadcast_channel on us? */
	if (csraddr == CSR_CHANNELS_AVAILABLE_HI && (data & 0x100000000ULL)) {
		/* Note: this is may not be the right way to handle
		 * the problem, so we should look into the proper way
                 * eventually. */
		HPSB_WARN("Node [" NODE_BUS_FMT "] wants to release "
			  "broadcast channel 31.  Ignoring.",
			  NODE_BUS_ARGS(host, nodeid));

		data &= ~0x100000000ULL;	/* keep broadcast channel allocated */
	}

	if (host->driver->hw_csr_reg) {
		quadlet_t data_hi, data_lo;
		quadlet_t arg_hi, arg_lo;
		quadlet_t old_hi, old_lo;

		data_hi = data >> 32;
		data_lo = data & 0xFFFFFFFF;
		arg_hi = arg >> 32;
		arg_lo = arg & 0xFFFFFFFF;

		old_hi = host->driver->hw_csr_reg(host, (csraddr - CSR_BUS_MANAGER_ID) >> 2,
                                                  data_hi, arg_hi);

		old_lo = host->driver->hw_csr_reg(host, ((csraddr + 4) - CSR_BUS_MANAGER_ID) >> 2,
                                                  data_lo, arg_lo);

		*store = cpu_to_be64(((octlet_t)old_hi << 32) | old_lo);
	} else {
		octlet_t old;
		octlet_t affected_channels = arg ^ data;

		spin_lock_irqsave(&host->csr.lock, flags);

		old = ((octlet_t)host->csr.channels_available_hi << 32) | host->csr.channels_available_lo;

		if ((arg & affected_channels) == (old & affected_channels)) {
			host->csr.channels_available_hi ^= (affected_channels >> 32);
			host->csr.channels_available_lo ^= (affected_channels & 0xffffffff);
			*store = cpu_to_be64(arg);
		} else {
			*store = cpu_to_be64(old);
		}

		spin_unlock_irqrestore(&host->csr.lock, flags);
	}

	/* Is somebody erroneously releasing the broadcast_channel on us? */
	if (host->csr.channels_available_hi & 0x1)
		host->csr.channels_available_hi &= ~0x1;

	return RCODE_COMPLETE;

 unsupported_lock64req:
	switch (csraddr) {
	case CSR_STATE_CLEAR:
	case CSR_STATE_SET:
	case CSR_RESET_START:
	case CSR_NODE_IDS:
	case CSR_SPLIT_TIMEOUT_HI:
	case CSR_SPLIT_TIMEOUT_LO:
	case CSR_CYCLE_TIME:
	case CSR_BUS_TIME:
	case CSR_BUS_MANAGER_ID:
	case CSR_BROADCAST_CHANNEL:
	case CSR_BUSY_TIMEOUT:
	case CSR_BANDWIDTH_AVAILABLE:
		return RCODE_TYPE_ERROR;

	default:
		return RCODE_ADDRESS_ERROR;
	}
}

static int write_fcp(struct hpsb_host *host, int nodeid, int dest,
		     quadlet_t *data, u64 addr, size_t length, u16 flags)
{
        int csraddr = addr - CSR_REGISTER_BASE;

        if (length > 512)
                return RCODE_TYPE_ERROR;

        switch (csraddr) {
        case CSR_FCP_COMMAND:
                highlevel_fcp_request(host, nodeid, 0, (u8 *)data, length);
                break;
        case CSR_FCP_RESPONSE:
                highlevel_fcp_request(host, nodeid, 1, (u8 *)data, length);
                break;
        default:
                return RCODE_TYPE_ERROR;
        }

        return RCODE_COMPLETE;
}

static int read_config_rom(struct hpsb_host *host, int nodeid, quadlet_t *buffer,
			   u64 addr, size_t length, u16 fl)
{
	u32 offset = addr - CSR1212_REGISTER_SPACE_BASE;

	if (csr1212_read(host->csr.rom, offset, buffer, length) == CSR1212_SUCCESS)
		return RCODE_COMPLETE;
	else
		return RCODE_ADDRESS_ERROR;
}

static u64 allocate_addr_range(u64 size, u32 alignment, void *__host)
{
 	struct hpsb_host *host = (struct hpsb_host*)__host;

	return hpsb_allocate_and_register_addrspace(&csr_highlevel,
						    host,
						    &config_rom_ops,
						    size, alignment,
						    CSR1212_UNITS_SPACE_BASE,
						    CSR1212_UNITS_SPACE_END);
}

static void release_addr_range(u64 addr, void *__host)
{
 	struct hpsb_host *host = (struct hpsb_host*)__host;
	hpsb_unregister_addrspace(&csr_highlevel, host, addr);
}


int init_csr(void)
{
	node_cap = csr1212_new_immediate(CSR1212_KV_ID_NODE_CAPABILITIES, 0x0083c0);
	if (!node_cap) {
		HPSB_ERR("Failed to allocate memory for Node Capabilties ConfigROM entry!");
		return -ENOMEM;
	}

	hpsb_register_highlevel(&csr_highlevel);

	return 0;
}

void cleanup_csr(void)
{
	if (node_cap)
		csr1212_release_keyval(node_cap);
        hpsb_unregister_highlevel(&csr_highlevel);
}
