/*
 * IEEE 1394 for Linux
 *
 * Core support: hpsb_packet management, packet handling and forwarding to
 *               highlevel or lowlevel code
 *
 * Copyright (C) 1999, 2000 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>
 *        loopback functionality in hpsb_send_packet
 *        allow highlevel drivers to disable automatic response generation
 *              and to generate responses themselves (deferred)
 *
 */

#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/string.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/bitops.h>
#include <linux/kdev_t.h>
#include <linux/suspend.h>
#include <linux/kthread.h>
#include <linux/preempt.h>
#include <linux/time.h>

#include <asm/system.h>
#include <asm/byteorder.h>

#include "ieee1394_types.h"
#include "ieee1394.h"
#include "hosts.h"
#include "ieee1394_core.h"
#include "highlevel.h"
#include "ieee1394_transactions.h"
#include "csr.h"
#include "nodemgr.h"
#include "dma.h"
#include "iso.h"
#include "config_roms.h"

/*
 * Disable the nodemgr detection and config rom reading functionality.
 */
static int disable_nodemgr;
module_param(disable_nodemgr, int, 0444);
MODULE_PARM_DESC(disable_nodemgr, "Disable nodemgr functionality.");

/* Disable Isochronous Resource Manager functionality */
int hpsb_disable_irm = 0;
module_param_named(disable_irm, hpsb_disable_irm, bool, 0444);
MODULE_PARM_DESC(disable_irm,
		 "Disable Isochronous Resource Manager functionality.");

/* We are GPL, so treat us special */
MODULE_LICENSE("GPL");

/* Some globals used */
const char *hpsb_speedto_str[] = { "S100", "S200", "S400", "S800", "S1600", "S3200" };
struct class *hpsb_protocol_class;

#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
static void dump_packet(const char *text, quadlet_t *data, int size, int speed)
{
	int i;

	size /= 4;
	size = (size > 4 ? 4 : size);

	printk(KERN_DEBUG "ieee1394: %s", text);
	if (speed > -1 && speed < 6)
		printk(" at %s", hpsb_speedto_str[speed]);
	printk(":");
	for (i = 0; i < size; i++)
		printk(" %08x", data[i]);
	printk("\n");
}
#else
#define dump_packet(a,b,c,d) do {} while (0)
#endif

static void abort_requests(struct hpsb_host *host);
static void queue_packet_complete(struct hpsb_packet *packet);


/**
 * hpsb_set_packet_complete_task - set task that runs when a packet completes
 * @packet: the packet whose completion we want the task added to
 * @routine: function to call
 * @data: data (if any) to pass to the above function
 *
 * Set the task that runs when a packet completes. You cannot call this more
 * than once on a single packet before it is sent.
 *
 * Typically, the complete @routine is responsible to call hpsb_free_packet().
 */
void hpsb_set_packet_complete_task(struct hpsb_packet *packet,
				   void (*routine)(void *), void *data)
{
	WARN_ON(packet->complete_routine != NULL);
	packet->complete_routine = routine;
	packet->complete_data = data;
	return;
}

/**
 * hpsb_alloc_packet - allocate new packet structure
 * @data_size: size of the data block to be allocated, in bytes
 *
 * This function allocates, initializes and returns a new &struct hpsb_packet.
 * It can be used in interrupt context.  A header block is always included and
 * initialized with zeros.  Its size is big enough to contain all possible 1394
 * headers.  The data block is only allocated if @data_size is not zero.
 *
 * For packets for which responses will be received the @data_size has to be big
 * enough to contain the response's data block since no further allocation
 * occurs at response matching time.
 *
 * The packet's generation value will be set to the current generation number
 * for ease of use.  Remember to overwrite it with your own recorded generation
 * number if you can not be sure that your code will not race with a bus reset.
 *
 * Return value: A pointer to a &struct hpsb_packet or NULL on allocation
 * failure.
 */
struct hpsb_packet *hpsb_alloc_packet(size_t data_size)
{
	struct hpsb_packet *packet;

	data_size = ((data_size + 3) & ~3);

	packet = kzalloc(sizeof(*packet) + data_size, GFP_ATOMIC);
	if (!packet)
		return NULL;

	packet->state = hpsb_unused;
	packet->generation = -1;
	INIT_LIST_HEAD(&packet->driver_list);
	INIT_LIST_HEAD(&packet->queue);
	atomic_set(&packet->refcnt, 1);

	if (data_size) {
		packet->data = packet->embedded_data;
		packet->allocated_data_size = data_size;
	}
	return packet;
}

/**
 * hpsb_free_packet - free packet and data associated with it
 * @packet: packet to free (is NULL safe)
 *
 * Frees @packet->data only if it was allocated through hpsb_alloc_packet().
 */
void hpsb_free_packet(struct hpsb_packet *packet)
{
	if (packet && atomic_dec_and_test(&packet->refcnt)) {
		BUG_ON(!list_empty(&packet->driver_list) ||
		       !list_empty(&packet->queue));
		kfree(packet);
	}
}

/**
 * hpsb_reset_bus - initiate bus reset on the given host
 * @host: host controller whose bus to reset
 * @type: one of enum reset_types
 *
 * Returns 1 if bus reset already in progress, 0 otherwise.
 */
int hpsb_reset_bus(struct hpsb_host *host, int type)
{
	if (!host->in_bus_reset) {
		host->driver->devctl(host, RESET_BUS, type);
		return 0;
	} else {
		return 1;
	}
}

/**
 * hpsb_read_cycle_timer - read cycle timer register and system time
 * @host: host whose isochronous cycle timer register is read
 * @cycle_timer: address of bitfield to return the register contents
 * @local_time: address to return the system time
 *
 * The format of * @cycle_timer, is described in OHCI 1.1 clause 5.13. This
 * format is also read from non-OHCI controllers. * @local_time contains the
 * system time in microseconds since the Epoch, read at the moment when the
 * cycle timer was read.
 *
 * Return value: 0 for success or error number otherwise.
 */
int hpsb_read_cycle_timer(struct hpsb_host *host, u32 *cycle_timer,
			  u64 *local_time)
{
	int ctr;
	struct timeval tv;
	unsigned long flags;

	if (!host || !cycle_timer || !local_time)
		return -EINVAL;

	preempt_disable();
	local_irq_save(flags);

	ctr = host->driver->devctl(host, GET_CYCLE_COUNTER, 0);
	if (ctr)
		do_gettimeofday(&tv);

	local_irq_restore(flags);
	preempt_enable();

	if (!ctr)
		return -EIO;
	*cycle_timer = ctr;
	*local_time = tv.tv_sec * 1000000ULL + tv.tv_usec;
	return 0;
}

/**
 * hpsb_bus_reset - notify a bus reset to the core
 *
 * For host driver module usage.  Safe to use in interrupt context, although
 * quite complex; so you may want to run it in the bottom rather than top half.
 *
 * Returns 1 if bus reset already in progress, 0 otherwise.
 */
int hpsb_bus_reset(struct hpsb_host *host)
{
	if (host->in_bus_reset) {
		HPSB_NOTICE("%s called while bus reset already in progress",
			    __FUNCTION__);
		return 1;
	}

	abort_requests(host);
	host->in_bus_reset = 1;
	host->irm_id = -1;
	host->is_irm = 0;
	host->busmgr_id = -1;
	host->is_busmgr = 0;
	host->is_cycmst = 0;
	host->node_count = 0;
	host->selfid_count = 0;

	return 0;
}


/*
 * Verify num_of_selfids SelfIDs and return number of nodes.  Return zero in
 * case verification failed.
 */
static int check_selfids(struct hpsb_host *host)
{
	int nodeid = -1;
	int rest_of_selfids = host->selfid_count;
	struct selfid *sid = (struct selfid *)host->topology_map;
	struct ext_selfid *esid;
	int esid_seq = 23;

	host->nodes_active = 0;

	while (rest_of_selfids--) {
		if (!sid->extended) {
			nodeid++;
			esid_seq = 0;

			if (sid->phy_id != nodeid) {
				HPSB_INFO("SelfIDs failed monotony check with "
					  "%d", sid->phy_id);
				return 0;
			}

			if (sid->link_active) {
				host->nodes_active++;
				if (sid->contender)
					host->irm_id = LOCAL_BUS | sid->phy_id;
			}
		} else {
			esid = (struct ext_selfid *)sid;

			if ((esid->phy_id != nodeid)
			    || (esid->seq_nr != esid_seq)) {
				HPSB_INFO("SelfIDs failed monotony check with "
					  "%d/%d", esid->phy_id, esid->seq_nr);
				return 0;
			}
			esid_seq++;
		}
		sid++;
	}

	esid = (struct ext_selfid *)(sid - 1);
	while (esid->extended) {
		if ((esid->porta == SELFID_PORT_PARENT) ||
		    (esid->portb == SELFID_PORT_PARENT) ||
		    (esid->portc == SELFID_PORT_PARENT) ||
		    (esid->portd == SELFID_PORT_PARENT) ||
		    (esid->porte == SELFID_PORT_PARENT) ||
		    (esid->portf == SELFID_PORT_PARENT) ||
		    (esid->portg == SELFID_PORT_PARENT) ||
		    (esid->porth == SELFID_PORT_PARENT)) {
			HPSB_INFO("SelfIDs failed root check on "
				  "extended SelfID");
			return 0;
		}
		esid--;
	}

	sid = (struct selfid *)esid;
	if ((sid->port0 == SELFID_PORT_PARENT) ||
	    (sid->port1 == SELFID_PORT_PARENT) ||
	    (sid->port2 == SELFID_PORT_PARENT)) {
		HPSB_INFO("SelfIDs failed root check");
		return 0;
	}

	host->node_count = nodeid + 1;
	return 1;
}

static void build_speed_map(struct hpsb_host *host, int nodecount)
{
	u8 cldcnt[nodecount];
	u8 *map = host->speed_map;
	u8 *speedcap = host->speed;
	struct selfid *sid;
	struct ext_selfid *esid;
	int i, j, n;

	for (i = 0; i < (nodecount * 64); i += 64) {
		for (j = 0; j < nodecount; j++) {
			map[i+j] = IEEE1394_SPEED_MAX;
		}
	}

	for (i = 0; i < nodecount; i++) {
		cldcnt[i] = 0;
	}

	/* find direct children count and speed */
	for (sid = (struct selfid *)&host->topology_map[host->selfid_count-1],
		     n = nodecount - 1;
	     (void *)sid >= (void *)host->topology_map; sid--) {
		if (sid->extended) {
			esid = (struct ext_selfid *)sid;

			if (esid->porta == SELFID_PORT_CHILD) cldcnt[n]++;
			if (esid->portb == SELFID_PORT_CHILD) cldcnt[n]++;
			if (esid->portc == SELFID_PORT_CHILD) cldcnt[n]++;
			if (esid->portd == SELFID_PORT_CHILD) cldcnt[n]++;
			if (esid->porte == SELFID_PORT_CHILD) cldcnt[n]++;
			if (esid->portf == SELFID_PORT_CHILD) cldcnt[n]++;
			if (esid->portg == SELFID_PORT_CHILD) cldcnt[n]++;
			if (esid->porth == SELFID_PORT_CHILD) cldcnt[n]++;
                } else {
			if (sid->port0 == SELFID_PORT_CHILD) cldcnt[n]++;
			if (sid->port1 == SELFID_PORT_CHILD) cldcnt[n]++;
			if (sid->port2 == SELFID_PORT_CHILD) cldcnt[n]++;

			speedcap[n] = sid->speed;
			n--;
		}
	}

	/* set self mapping */
	for (i = 0; i < nodecount; i++) {
		map[64*i + i] = speedcap[i];
	}

	/* fix up direct children count to total children count;
	 * also fix up speedcaps for sibling and parent communication */
	for (i = 1; i < nodecount; i++) {
		for (j = cldcnt[i], n = i - 1; j > 0; j--) {
			cldcnt[i] += cldcnt[n];
			speedcap[n] = min(speedcap[n], speedcap[i]);
			n -= cldcnt[n] + 1;
		}
	}

	for (n = 0; n < nodecount; n++) {
		for (i = n - cldcnt[n]; i <= n; i++) {
			for (j = 0; j < (n - cldcnt[n]); j++) {
				map[j*64 + i] = map[i*64 + j] =
					min(map[i*64 + j], speedcap[n]);
			}
			for (j = n + 1; j < nodecount; j++) {
				map[j*64 + i] = map[i*64 + j] =
					min(map[i*64 + j], speedcap[n]);
			}
		}
	}

#if SELFID_SPEED_UNKNOWN != IEEE1394_SPEED_MAX
	/* assume maximum speed for 1394b PHYs, nodemgr will correct it */
	for (n = 0; n < nodecount; n++)
		if (speedcap[n] == SELFID_SPEED_UNKNOWN)
			speedcap[n] = IEEE1394_SPEED_MAX;
#endif
}


/**
 * hpsb_selfid_received - hand over received selfid packet to the core
 *
 * For host driver module usage.  Safe to use in interrupt context.
 *
 * The host driver should have done a successful complement check (second
 * quadlet is complement of first) beforehand.
 */
void hpsb_selfid_received(struct hpsb_host *host, quadlet_t sid)
{
	if (host->in_bus_reset) {
		HPSB_VERBOSE("Including SelfID 0x%x", sid);
		host->topology_map[host->selfid_count++] = sid;
	} else {
		HPSB_NOTICE("Spurious SelfID packet (0x%08x) received from bus %d",
			    sid, NODEID_TO_BUS(host->node_id));
	}
}

/**
 * hpsb_selfid_complete - notify completion of SelfID stage to the core
 *
 * For host driver module usage.  Safe to use in interrupt context, although
 * quite complex; so you may want to run it in the bottom rather than top half.
 *
 * Notify completion of SelfID stage to the core and report new physical ID
 * and whether host is root now.
 */
void hpsb_selfid_complete(struct hpsb_host *host, int phyid, int isroot)
{
	if (!host->in_bus_reset)
		HPSB_NOTICE("SelfID completion called outside of bus reset!");

	host->node_id = LOCAL_BUS | phyid;
	host->is_root = isroot;

	if (!check_selfids(host)) {
		if (host->reset_retries++ < 20) {
			/* selfid stage did not complete without error */
			HPSB_NOTICE("Error in SelfID stage, resetting");
			host->in_bus_reset = 0;
			/* this should work from ohci1394 now... */
			hpsb_reset_bus(host, LONG_RESET);
			return;
		} else {
			HPSB_NOTICE("Stopping out-of-control reset loop");
			HPSB_NOTICE("Warning - topology map and speed map will not be valid");
			host->reset_retries = 0;
		}
	} else {
		host->reset_retries = 0;
		build_speed_map(host, host->node_count);
	}

	HPSB_VERBOSE("selfid_complete called with successful SelfID stage "
		     "... irm_id: 0x%X node_id: 0x%X",host->irm_id,host->node_id);

	/* irm_id is kept up to date by check_selfids() */
	if (host->irm_id == host->node_id) {
		host->is_irm = 1;
	} else {
		host->is_busmgr = 0;
		host->is_irm = 0;
	}

	if (isroot) {
		host->driver->devctl(host, ACT_CYCLE_MASTER, 1);
		host->is_cycmst = 1;
	}
	atomic_inc(&host->generation);
	host->in_bus_reset = 0;
	highlevel_host_reset(host);
}

static spinlock_t pending_packets_lock = SPIN_LOCK_UNLOCKED;

/**
 * hpsb_packet_sent - notify core of sending a packet
 *
 * For host driver module usage.  Safe to call from within a transmit packet
 * routine.
 *
 * Notify core of sending a packet.  Ackcode is the ack code returned for async
 * transmits or ACKX_SEND_ERROR if the transmission failed completely; ACKX_NONE
 * for other cases (internal errors that don't justify a panic).
 */
void hpsb_packet_sent(struct hpsb_host *host, struct hpsb_packet *packet,
		      int ackcode)
{
	unsigned long flags;

	spin_lock_irqsave(&pending_packets_lock, flags);

	packet->ack_code = ackcode;

	if (packet->no_waiter || packet->state == hpsb_complete) {
		/* if packet->no_waiter, must not have a tlabel allocated */
		spin_unlock_irqrestore(&pending_packets_lock, flags);
		hpsb_free_packet(packet);
		return;
	}

	atomic_dec(&packet->refcnt);	/* drop HC's reference */
	/* here the packet must be on the host->pending_packets queue */

	if (ackcode != ACK_PENDING || !packet->expect_response) {
		packet->state = hpsb_complete;
		list_del_init(&packet->queue);
		spin_unlock_irqrestore(&pending_packets_lock, flags);
		queue_packet_complete(packet);
		return;
	}

	packet->state = hpsb_pending;
	packet->sendtime = jiffies;

	spin_unlock_irqrestore(&pending_packets_lock, flags);

	mod_timer(&host->timeout, jiffies + host->timeout_interval);
}

/**
 * hpsb_send_phy_config - transmit a PHY configuration packet on the bus
 * @host: host that PHY config packet gets sent through
 * @rootid: root whose force_root bit should get set (-1 = don't set force_root)
 * @gapcnt: gap count value to set (-1 = don't set gap count)
 *
 * This function sends a PHY config packet on the bus through the specified
 * host.
 *
 * Return value: 0 for success or negative error number otherwise.
 */
int hpsb_send_phy_config(struct hpsb_host *host, int rootid, int gapcnt)
{
	struct hpsb_packet *packet;
	quadlet_t d = 0;
	int retval = 0;

	if (rootid >= ALL_NODES || rootid < -1 || gapcnt > 0x3f || gapcnt < -1 ||
	   (rootid == -1 && gapcnt == -1)) {
		HPSB_DEBUG("Invalid Parameter: rootid = %d   gapcnt = %d",
			   rootid, gapcnt);
		return -EINVAL;
	}

	if (rootid != -1)
		d |= PHYPACKET_PHYCONFIG_R | rootid << PHYPACKET_PORT_SHIFT;
	if (gapcnt != -1)
		d |= PHYPACKET_PHYCONFIG_T | gapcnt << PHYPACKET_GAPCOUNT_SHIFT;

	packet = hpsb_make_phypacket(host, d);
	if (!packet)
		return -ENOMEM;

	packet->generation = get_hpsb_generation(host);
	retval = hpsb_send_packet_and_wait(packet);
	hpsb_free_packet(packet);

	return retval;
}

/**
 * hpsb_send_packet - transmit a packet on the bus
 * @packet: packet to send
 *
 * The packet is sent through the host specified in the packet->host field.
 * Before sending, the packet's transmit speed is automatically determined
 * using the local speed map when it is an async, non-broadcast packet.
 *
 * Possibilities for failure are that host is either not initialized, in bus
 * reset, the packet's generation number doesn't match the current generation
 * number or the host reports a transmit error.
 *
 * Return value: 0 on success, negative errno on failure.
 */
int hpsb_send_packet(struct hpsb_packet *packet)
{
	struct hpsb_host *host = packet->host;

	if (host->is_shutdown)
		return -EINVAL;
	if (host->in_bus_reset ||
	    (packet->generation != get_hpsb_generation(host)))
		return -EAGAIN;

	packet->state = hpsb_queued;

	/* This just seems silly to me */
	WARN_ON(packet->no_waiter && packet->expect_response);

	if (!packet->no_waiter || packet->expect_response) {
		unsigned long flags;

		atomic_inc(&packet->refcnt);
		/* Set the initial "sendtime" to 10 seconds from now, to
		   prevent premature expiry.  If a packet takes more than
		   10 seconds to hit the wire, we have bigger problems :) */
		packet->sendtime = jiffies + 10 * HZ;
		spin_lock_irqsave(&pending_packets_lock, flags);
		list_add_tail(&packet->queue, &host->pending_packets);
		spin_unlock_irqrestore(&pending_packets_lock, flags);
	}

	if (packet->node_id == host->node_id) {
		/* it is a local request, so handle it locally */

		quadlet_t *data;
		size_t size = packet->data_size + packet->header_size;

		data = kmalloc(size, GFP_ATOMIC);
		if (!data) {
			HPSB_ERR("unable to allocate memory for concatenating header and data");
			return -ENOMEM;
		}

		memcpy(data, packet->header, packet->header_size);

		if (packet->data_size)
			memcpy(((u8*)data) + packet->header_size, packet->data, packet->data_size);

		dump_packet("send packet local", packet->header, packet->header_size, -1);

		hpsb_packet_sent(host, packet, packet->expect_response ? ACK_PENDING : ACK_COMPLETE);
		hpsb_packet_received(host, data, size, 0);

		kfree(data);

		return 0;
	}

	if (packet->type == hpsb_async &&
	    NODEID_TO_NODE(packet->node_id) != ALL_NODES)
		packet->speed_code =
			host->speed[NODEID_TO_NODE(packet->node_id)];

	dump_packet("send packet", packet->header, packet->header_size, packet->speed_code);

	return host->driver->transmit_packet(host, packet);
}

/* We could just use complete() directly as the packet complete
 * callback, but this is more typesafe, in the sense that we get a
 * compiler error if the prototype for complete() changes. */

static void complete_packet(void *data)
{
	complete((struct completion *) data);
}

/**
 * hpsb_send_packet_and_wait - enqueue packet, block until transaction completes
 * @packet: packet to send
 *
 * Return value: 0 on success, negative errno on failure.
 */
int hpsb_send_packet_and_wait(struct hpsb_packet *packet)
{
	struct completion done;
	int retval;

	init_completion(&done);
	hpsb_set_packet_complete_task(packet, complete_packet, &done);
	retval = hpsb_send_packet(packet);
	if (retval == 0)
		wait_for_completion(&done);

	return retval;
}

static void send_packet_nocare(struct hpsb_packet *packet)
{
	if (hpsb_send_packet(packet) < 0) {
		hpsb_free_packet(packet);
	}
}

static size_t packet_size_to_data_size(size_t packet_size, size_t header_size,
				       size_t buffer_size, int tcode)
{
	size_t ret = packet_size <= header_size ? 0 : packet_size - header_size;

	if (unlikely(ret > buffer_size))
		ret = buffer_size;

	if (unlikely(ret + header_size != packet_size))
		HPSB_ERR("unexpected packet size %zd (tcode %d), bug?",
			 packet_size, tcode);
	return ret;
}

static void handle_packet_response(struct hpsb_host *host, int tcode,
				   quadlet_t *data, size_t size)
{
	struct hpsb_packet *packet;
	int tlabel = (data[0] >> 10) & 0x3f;
	size_t header_size;
	unsigned long flags;

	spin_lock_irqsave(&pending_packets_lock, flags);

	list_for_each_entry(packet, &host->pending_packets, queue)
		if (packet->tlabel == tlabel &&
		    packet->node_id == (data[1] >> 16))
			goto found;

	spin_unlock_irqrestore(&pending_packets_lock, flags);
	HPSB_DEBUG("unsolicited response packet received - %s",
		   "no tlabel match");
	dump_packet("contents", data, 16, -1);
	return;

found:
	switch (packet->tcode) {
	case TCODE_WRITEQ:
	case TCODE_WRITEB:
		if (unlikely(tcode != TCODE_WRITE_RESPONSE))
			break;
		header_size = 12;
		size = 0;
		goto dequeue;

	case TCODE_READQ:
		if (unlikely(tcode != TCODE_READQ_RESPONSE))
			break;
		header_size = 16;
		size = 0;
		goto dequeue;

	case TCODE_READB:
		if (unlikely(tcode != TCODE_READB_RESPONSE))
			break;
		header_size = 16;
		size = packet_size_to_data_size(size, header_size,
						packet->allocated_data_size,
						tcode);
		goto dequeue;

	case TCODE_LOCK_REQUEST:
		if (unlikely(tcode != TCODE_LOCK_RESPONSE))
			break;
		header_size = 16;
		size = packet_size_to_data_size(min(size, (size_t)(16 + 8)),
						header_size,
						packet->allocated_data_size,
						tcode);
		goto dequeue;
	}

	spin_unlock_irqrestore(&pending_packets_lock, flags);
	HPSB_DEBUG("unsolicited response packet received - %s",
		   "tcode mismatch");
	dump_packet("contents", data, 16, -1);
	return;

dequeue:
	list_del_init(&packet->queue);
	spin_unlock_irqrestore(&pending_packets_lock, flags);

	if (packet->state == hpsb_queued) {
		packet->sendtime = jiffies;
		packet->ack_code = ACK_PENDING;
	}
	packet->state = hpsb_complete;

	memcpy(packet->header, data, header_size);
	if (size)
		memcpy(packet->data, data + 4, size);

	queue_packet_complete(packet);
}


static struct hpsb_packet *create_reply_packet(struct hpsb_host *host,
					       quadlet_t *data, size_t dsize)
{
	struct hpsb_packet *p;

	p = hpsb_alloc_packet(dsize);
	if (unlikely(p == NULL)) {
		/* FIXME - send data_error response */
		HPSB_ERR("out of memory, cannot send response packet");
		return NULL;
	}

	p->type = hpsb_async;
	p->state = hpsb_unused;
	p->host = host;
	p->node_id = data[1] >> 16;
	p->tlabel = (data[0] >> 10) & 0x3f;
	p->no_waiter = 1;

	p->generation = get_hpsb_generation(host);

	if (dsize % 4)
		p->data[dsize / 4] = 0;

	return p;
}

#define PREP_ASYNC_HEAD_RCODE(tc) \
	packet->tcode = tc; \
	packet->header[0] = (packet->node_id << 16) | (packet->tlabel << 10) \
		| (1 << 8) | (tc << 4); \
	packet->header[1] = (packet->host->node_id << 16) | (rcode << 12); \
	packet->header[2] = 0

static void fill_async_readquad_resp(struct hpsb_packet *packet, int rcode,
			      quadlet_t data)
{
	PREP_ASYNC_HEAD_RCODE(TCODE_READQ_RESPONSE);
	packet->header[3] = data;
	packet->header_size = 16;
	packet->data_size = 0;
}

static void fill_async_readblock_resp(struct hpsb_packet *packet, int rcode,
			       int length)
{
	if (rcode != RCODE_COMPLETE)
		length = 0;

	PREP_ASYNC_HEAD_RCODE(TCODE_READB_RESPONSE);
	packet->header[3] = length << 16;
	packet->header_size = 16;
	packet->data_size = length + (length % 4 ? 4 - (length % 4) : 0);
}

static void fill_async_write_resp(struct hpsb_packet *packet, int rcode)
{
	PREP_ASYNC_HEAD_RCODE(TCODE_WRITE_RESPONSE);
	packet->header_size = 12;
	packet->data_size = 0;
}

static void fill_async_lock_resp(struct hpsb_packet *packet, int rcode, int extcode,
			  int length)
{
	if (rcode != RCODE_COMPLETE)
		length = 0;

	PREP_ASYNC_HEAD_RCODE(TCODE_LOCK_RESPONSE);
	packet->header[3] = (length << 16) | extcode;
	packet->header_size = 16;
	packet->data_size = length;
}

static void handle_incoming_packet(struct hpsb_host *host, int tcode,
				   quadlet_t *data, size_t size,
				   int write_acked)
{
	struct hpsb_packet *packet;
	int length, rcode, extcode;
	quadlet_t buffer;
	nodeid_t source = data[1] >> 16;
	nodeid_t dest = data[0] >> 16;
	u16 flags = (u16) data[0];
	u64 addr;

	/* FIXME?
	 * Out-of-bounds lengths are left for highlevel_read|write to cap. */

	switch (tcode) {
	case TCODE_WRITEQ:
		addr = (((u64)(data[1] & 0xffff)) << 32) | data[2];
		rcode = highlevel_write(host, source, dest, data + 3,
					addr, 4, flags);
		goto handle_write_request;

	case TCODE_WRITEB:
		addr = (((u64)(data[1] & 0xffff)) << 32) | data[2];
		rcode = highlevel_write(host, source, dest, data + 4,
					addr, data[3] >> 16, flags);
handle_write_request:
		if (rcode < 0 || write_acked ||
		    NODEID_TO_NODE(data[0] >> 16) == NODE_MASK)
			return;
		/* not a broadcast write, reply */
		packet = create_reply_packet(host, data, 0);
		if (packet) {
			fill_async_write_resp(packet, rcode);
			send_packet_nocare(packet);
		}
		return;

	case TCODE_READQ:
		addr = (((u64)(data[1] & 0xffff)) << 32) | data[2];
		rcode = highlevel_read(host, source, &buffer, addr, 4, flags);
		if (rcode < 0)
			return;

		packet = create_reply_packet(host, data, 0);
		if (packet) {
			fill_async_readquad_resp(packet, rcode, buffer);
			send_packet_nocare(packet);
		}
		return;

	case TCODE_READB:
		length = data[3] >> 16;
		packet = create_reply_packet(host, data, length);
		if (!packet)
			return;

		addr = (((u64)(data[1] & 0xffff)) << 32) | data[2];
		rcode = highlevel_read(host, source, packet->data, addr,
				       length, flags);
		if (rcode < 0) {
			hpsb_free_packet(packet);
			return;
		}
		fill_async_readblock_resp(packet, rcode, length);
		send_packet_nocare(packet);
		return;

	case TCODE_LOCK_REQUEST:
		length = data[3] >> 16;
		extcode = data[3] & 0xffff;
		addr = (((u64)(data[1] & 0xffff)) << 32) | data[2];

		packet = create_reply_packet(host, data, 8);
		if (!packet)
			return;

		if (extcode == 0 || extcode >= 7) {
			/* let switch default handle error */
			length = 0;
		}

		switch (length) {
		case 4:
			rcode = highlevel_lock(host, source, packet->data, addr,
					       data[4], 0, extcode, flags);
			fill_async_lock_resp(packet, rcode, extcode, 4);
			break;
		case 8:
			if (extcode != EXTCODE_FETCH_ADD &&
			    extcode != EXTCODE_LITTLE_ADD) {
				rcode = highlevel_lock(host, source,
						       packet->data, addr,
						       data[5], data[4],
						       extcode, flags);
				fill_async_lock_resp(packet, rcode, extcode, 4);
			} else {
				rcode = highlevel_lock64(host, source,
					     (octlet_t *)packet->data, addr,
					     *(octlet_t *)(data + 4), 0ULL,
					     extcode, flags);
				fill_async_lock_resp(packet, rcode, extcode, 8);
			}
			break;
		case 16:
			rcode = highlevel_lock64(host, source,
						 (octlet_t *)packet->data, addr,
						 *(octlet_t *)(data + 6),
						 *(octlet_t *)(data + 4),
						 extcode, flags);
			fill_async_lock_resp(packet, rcode, extcode, 8);
			break;
		default:
			rcode = RCODE_TYPE_ERROR;
			fill_async_lock_resp(packet, rcode, extcode, 0);
		}

		if (rcode < 0)
			hpsb_free_packet(packet);
		else
			send_packet_nocare(packet);
		return;
	}
}

/**
 * hpsb_packet_received - hand over received packet to the core
 *
 * For host driver module usage.
 *
 * The contents of data are expected to be the full packet but with the CRCs
 * left out (data block follows header immediately), with the header (i.e. the
 * first four quadlets) in machine byte order and the data block in big endian.
 * *@data can be safely overwritten after this call.
 *
 * If the packet is a write request, @write_acked is to be set to true if it was
 * ack_complete'd already, false otherwise.  This argument is ignored for any
 * other packet type.
 */
void hpsb_packet_received(struct hpsb_host *host, quadlet_t *data, size_t size,
			  int write_acked)
{
	int tcode;

	if (unlikely(host->in_bus_reset)) {
		HPSB_DEBUG("received packet during reset; ignoring");
		return;
	}

	dump_packet("received packet", data, size, -1);

	tcode = (data[0] >> 4) & 0xf;

	switch (tcode) {
	case TCODE_WRITE_RESPONSE:
	case TCODE_READQ_RESPONSE:
	case TCODE_READB_RESPONSE:
	case TCODE_LOCK_RESPONSE:
		handle_packet_response(host, tcode, data, size);
		break;

	case TCODE_WRITEQ:
	case TCODE_WRITEB:
	case TCODE_READQ:
	case TCODE_READB:
	case TCODE_LOCK_REQUEST:
		handle_incoming_packet(host, tcode, data, size, write_acked);
		break;


	case TCODE_ISO_DATA:
		highlevel_iso_receive(host, data, size);
		break;

	case TCODE_CYCLE_START:
		/* simply ignore this packet if it is passed on */
		break;

	default:
		HPSB_DEBUG("received packet with bogus transaction code %d",
			   tcode);
		break;
	}
}

static void abort_requests(struct hpsb_host *host)
{
	struct hpsb_packet *packet, *p;
	struct list_head tmp;
	unsigned long flags;

	host->driver->devctl(host, CANCEL_REQUESTS, 0);

	INIT_LIST_HEAD(&tmp);
	spin_lock_irqsave(&pending_packets_lock, flags);
	list_splice_init(&host->pending_packets, &tmp);
	spin_unlock_irqrestore(&pending_packets_lock, flags);

	list_for_each_entry_safe(packet, p, &tmp, queue) {
		list_del_init(&packet->queue);
		packet->state = hpsb_complete;
		packet->ack_code = ACKX_ABORTED;
		queue_packet_complete(packet);
	}
}

void abort_timedouts(unsigned long __opaque)
{
	struct hpsb_host *host = (struct hpsb_host *)__opaque;
	struct hpsb_packet *packet, *p;
	struct list_head tmp;
	unsigned long flags, expire, j;

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

	j = jiffies;
	INIT_LIST_HEAD(&tmp);
	spin_lock_irqsave(&pending_packets_lock, flags);

	list_for_each_entry_safe(packet, p, &host->pending_packets, queue) {
		if (time_before(packet->sendtime + expire, j))
			list_move_tail(&packet->queue, &tmp);
		else
			/* Since packets are added to the tail, the oldest
			 * ones are first, always. When we get to one that
			 * isn't timed out, the rest aren't either. */
			break;
	}
	if (!list_empty(&host->pending_packets))
		mod_timer(&host->timeout, j + host->timeout_interval);

	spin_unlock_irqrestore(&pending_packets_lock, flags);

	list_for_each_entry_safe(packet, p, &tmp, queue) {
		list_del_init(&packet->queue);
		packet->state = hpsb_complete;
		packet->ack_code = ACKX_TIMEOUT;
		queue_packet_complete(packet);
	}
}

static struct task_struct *khpsbpkt_thread;
static LIST_HEAD(hpsbpkt_queue);

static void queue_packet_complete(struct hpsb_packet *packet)
{
	unsigned long flags;

	if (packet->no_waiter) {
		hpsb_free_packet(packet);
		return;
	}
	if (packet->complete_routine != NULL) {
		spin_lock_irqsave(&pending_packets_lock, flags);
		list_add_tail(&packet->queue, &hpsbpkt_queue);
		spin_unlock_irqrestore(&pending_packets_lock, flags);
		wake_up_process(khpsbpkt_thread);
	}
	return;
}

/*
 * Kernel thread which handles packets that are completed.  This way the
 * packet's "complete" function is asynchronously run in process context.
 * Only packets which have a "complete" function may be sent here.
 */
static int hpsbpkt_thread(void *__hi)
{
	struct hpsb_packet *packet, *p;
	struct list_head tmp;
	int may_schedule;

	current->flags |= PF_NOFREEZE;

	while (!kthread_should_stop()) {

		INIT_LIST_HEAD(&tmp);
		spin_lock_irq(&pending_packets_lock);
		list_splice_init(&hpsbpkt_queue, &tmp);
		spin_unlock_irq(&pending_packets_lock);

		list_for_each_entry_safe(packet, p, &tmp, queue) {
			list_del_init(&packet->queue);
			packet->complete_routine(packet->complete_data);
		}

		set_current_state(TASK_INTERRUPTIBLE);
		spin_lock_irq(&pending_packets_lock);
		may_schedule = list_empty(&hpsbpkt_queue);
		spin_unlock_irq(&pending_packets_lock);
		if (may_schedule)
			schedule();
		__set_current_state(TASK_RUNNING);
	}
	return 0;
}

static int __init ieee1394_init(void)
{
	int i, ret;

	/* non-fatal error */
	if (hpsb_init_config_roms()) {
		HPSB_ERR("Failed to initialize some config rom entries.\n");
		HPSB_ERR("Some features may not be available\n");
	}

	khpsbpkt_thread = kthread_run(hpsbpkt_thread, NULL, "khpsbpkt");
	if (IS_ERR(khpsbpkt_thread)) {
		HPSB_ERR("Failed to start hpsbpkt thread!\n");
		ret = PTR_ERR(khpsbpkt_thread);
		goto exit_cleanup_config_roms;
	}

	if (register_chrdev_region(IEEE1394_CORE_DEV, 256, "ieee1394")) {
		HPSB_ERR("unable to register character device major %d!\n", IEEE1394_MAJOR);
		ret = -ENODEV;
		goto exit_release_kernel_thread;
	}

	ret = bus_register(&ieee1394_bus_type);
	if (ret < 0) {
		HPSB_INFO("bus register failed");
		goto release_chrdev;
	}

	for (i = 0; fw_bus_attrs[i]; i++) {
		ret = bus_create_file(&ieee1394_bus_type, fw_bus_attrs[i]);
		if (ret < 0) {
			while (i >= 0) {
				bus_remove_file(&ieee1394_bus_type,
						fw_bus_attrs[i--]);
			}
			bus_unregister(&ieee1394_bus_type);
			goto release_chrdev;
		}
	}

	ret = class_register(&hpsb_host_class);
	if (ret < 0)
		goto release_all_bus;

	hpsb_protocol_class = class_create(THIS_MODULE, "ieee1394_protocol");
	if (IS_ERR(hpsb_protocol_class)) {
		ret = PTR_ERR(hpsb_protocol_class);
		goto release_class_host;
	}

	ret = init_csr();
	if (ret) {
		HPSB_INFO("init csr failed");
		ret = -ENOMEM;
		goto release_class_protocol;
	}

	if (disable_nodemgr) {
		HPSB_INFO("nodemgr and IRM functionality disabled");
		/* We shouldn't contend for IRM with nodemgr disabled, since
		   nodemgr implements functionality required of ieee1394a-2000
		   IRMs */
		hpsb_disable_irm = 1;

		return 0;
	}

	if (hpsb_disable_irm) {
		HPSB_INFO("IRM functionality disabled");
	}

	ret = init_ieee1394_nodemgr();
	if (ret < 0) {
		HPSB_INFO("init nodemgr failed");
		goto cleanup_csr;
	}

	return 0;

cleanup_csr:
	cleanup_csr();
release_class_protocol:
	class_destroy(hpsb_protocol_class);
release_class_host:
	class_unregister(&hpsb_host_class);
release_all_bus:
	for (i = 0; fw_bus_attrs[i]; i++)
		bus_remove_file(&ieee1394_bus_type, fw_bus_attrs[i]);
	bus_unregister(&ieee1394_bus_type);
release_chrdev:
	unregister_chrdev_region(IEEE1394_CORE_DEV, 256);
exit_release_kernel_thread:
	kthread_stop(khpsbpkt_thread);
exit_cleanup_config_roms:
	hpsb_cleanup_config_roms();
	return ret;
}

static void __exit ieee1394_cleanup(void)
{
	int i;

	if (!disable_nodemgr)
		cleanup_ieee1394_nodemgr();

	cleanup_csr();

	class_destroy(hpsb_protocol_class);
	class_unregister(&hpsb_host_class);
	for (i = 0; fw_bus_attrs[i]; i++)
		bus_remove_file(&ieee1394_bus_type, fw_bus_attrs[i]);
	bus_unregister(&ieee1394_bus_type);

	kthread_stop(khpsbpkt_thread);

	hpsb_cleanup_config_roms();

	unregister_chrdev_region(IEEE1394_CORE_DEV, 256);
}

fs_initcall(ieee1394_init); /* same as ohci1394 */
module_exit(ieee1394_cleanup);

/* Exported symbols */

/** hosts.c **/
EXPORT_SYMBOL(hpsb_alloc_host);
EXPORT_SYMBOL(hpsb_add_host);
EXPORT_SYMBOL(hpsb_resume_host);
EXPORT_SYMBOL(hpsb_remove_host);
EXPORT_SYMBOL(hpsb_update_config_rom_image);

/** ieee1394_core.c **/
EXPORT_SYMBOL(hpsb_speedto_str);
EXPORT_SYMBOL(hpsb_protocol_class);
EXPORT_SYMBOL(hpsb_set_packet_complete_task);
EXPORT_SYMBOL(hpsb_alloc_packet);
EXPORT_SYMBOL(hpsb_free_packet);
EXPORT_SYMBOL(hpsb_send_packet);
EXPORT_SYMBOL(hpsb_reset_bus);
EXPORT_SYMBOL(hpsb_read_cycle_timer);
EXPORT_SYMBOL(hpsb_bus_reset);
EXPORT_SYMBOL(hpsb_selfid_received);
EXPORT_SYMBOL(hpsb_selfid_complete);
EXPORT_SYMBOL(hpsb_packet_sent);
EXPORT_SYMBOL(hpsb_packet_received);
EXPORT_SYMBOL_GPL(hpsb_disable_irm);

/** ieee1394_transactions.c **/
EXPORT_SYMBOL(hpsb_get_tlabel);
EXPORT_SYMBOL(hpsb_free_tlabel);
EXPORT_SYMBOL(hpsb_make_readpacket);
EXPORT_SYMBOL(hpsb_make_writepacket);
EXPORT_SYMBOL(hpsb_make_streampacket);
EXPORT_SYMBOL(hpsb_make_lockpacket);
EXPORT_SYMBOL(hpsb_make_lock64packet);
EXPORT_SYMBOL(hpsb_make_phypacket);
EXPORT_SYMBOL(hpsb_make_isopacket);
EXPORT_SYMBOL(hpsb_read);
EXPORT_SYMBOL(hpsb_write);
EXPORT_SYMBOL(hpsb_packet_success);

/** highlevel.c **/
EXPORT_SYMBOL(hpsb_register_highlevel);
EXPORT_SYMBOL(hpsb_unregister_highlevel);
EXPORT_SYMBOL(hpsb_register_addrspace);
EXPORT_SYMBOL(hpsb_unregister_addrspace);
EXPORT_SYMBOL(hpsb_allocate_and_register_addrspace);
EXPORT_SYMBOL(hpsb_listen_channel);
EXPORT_SYMBOL(hpsb_unlisten_channel);
EXPORT_SYMBOL(hpsb_get_hostinfo);
EXPORT_SYMBOL(hpsb_create_hostinfo);
EXPORT_SYMBOL(hpsb_destroy_hostinfo);
EXPORT_SYMBOL(hpsb_set_hostinfo_key);
EXPORT_SYMBOL(hpsb_get_hostinfo_bykey);
EXPORT_SYMBOL(hpsb_set_hostinfo);

/** nodemgr.c **/
EXPORT_SYMBOL(hpsb_node_fill_packet);
EXPORT_SYMBOL(hpsb_node_write);
EXPORT_SYMBOL(__hpsb_register_protocol);
EXPORT_SYMBOL(hpsb_unregister_protocol);

/** csr.c **/
EXPORT_SYMBOL(hpsb_update_config_rom);

/** dma.c **/
EXPORT_SYMBOL(dma_prog_region_init);
EXPORT_SYMBOL(dma_prog_region_alloc);
EXPORT_SYMBOL(dma_prog_region_free);
EXPORT_SYMBOL(dma_region_init);
EXPORT_SYMBOL(dma_region_alloc);
EXPORT_SYMBOL(dma_region_free);
EXPORT_SYMBOL(dma_region_sync_for_cpu);
EXPORT_SYMBOL(dma_region_sync_for_device);
EXPORT_SYMBOL(dma_region_mmap);
EXPORT_SYMBOL(dma_region_offset_to_bus);

/** iso.c **/
EXPORT_SYMBOL(hpsb_iso_xmit_init);
EXPORT_SYMBOL(hpsb_iso_recv_init);
EXPORT_SYMBOL(hpsb_iso_xmit_start);
EXPORT_SYMBOL(hpsb_iso_recv_start);
EXPORT_SYMBOL(hpsb_iso_recv_listen_channel);
EXPORT_SYMBOL(hpsb_iso_recv_unlisten_channel);
EXPORT_SYMBOL(hpsb_iso_recv_set_channel_mask);
EXPORT_SYMBOL(hpsb_iso_stop);
EXPORT_SYMBOL(hpsb_iso_shutdown);
EXPORT_SYMBOL(hpsb_iso_xmit_queue_packet);
EXPORT_SYMBOL(hpsb_iso_xmit_sync);
EXPORT_SYMBOL(hpsb_iso_recv_release_packets);
EXPORT_SYMBOL(hpsb_iso_n_ready);
EXPORT_SYMBOL(hpsb_iso_packet_sent);
EXPORT_SYMBOL(hpsb_iso_packet_received);
EXPORT_SYMBOL(hpsb_iso_wake);
EXPORT_SYMBOL(hpsb_iso_recv_flush);

/** csr1212.c **/
EXPORT_SYMBOL(csr1212_attach_keyval_to_directory);
EXPORT_SYMBOL(csr1212_detach_keyval_from_directory);
EXPORT_SYMBOL(csr1212_get_keyval);
EXPORT_SYMBOL(csr1212_new_directory);
EXPORT_SYMBOL(csr1212_parse_keyval);
EXPORT_SYMBOL(csr1212_read);
EXPORT_SYMBOL(csr1212_release_keyval);
