/*
 * FireDTV driver -- firewire I/O backend
 */

#include <linux/device.h>
#include <linux/errno.h>
#include <linux/firewire.h>
#include <linux/firewire-constants.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/types.h>

#include <asm/page.h>

#include <dvb_demux.h>

#include "firedtv.h"

static LIST_HEAD(node_list);
static DEFINE_SPINLOCK(node_list_lock);

static inline struct fw_device *device_of(struct firedtv *fdtv)
{
	return fw_device(fdtv->device->parent);
}

static int node_req(struct firedtv *fdtv, u64 addr, void *data, size_t len,
		    int tcode)
{
	struct fw_device *device = device_of(fdtv);
	int rcode, generation = device->generation;

	smp_rmb(); /* node_id vs. generation */

	rcode = fw_run_transaction(device->card, tcode, device->node_id,
			generation, device->max_speed, addr, data, len);

	return rcode != RCODE_COMPLETE ? -EIO : 0;
}

static int node_lock(struct firedtv *fdtv, u64 addr, __be32 data[])
{
	return node_req(fdtv, addr, data, 8, TCODE_LOCK_COMPARE_SWAP);
}

static int node_read(struct firedtv *fdtv, u64 addr, void *data)
{
	return node_req(fdtv, addr, data, 4, TCODE_READ_QUADLET_REQUEST);
}

static int node_write(struct firedtv *fdtv, u64 addr, void *data, size_t len)
{
	return node_req(fdtv, addr, data, len, TCODE_WRITE_BLOCK_REQUEST);
}

#define ISO_HEADER_SIZE			4
#define CIP_HEADER_SIZE			8
#define MPEG2_TS_HEADER_SIZE		4
#define MPEG2_TS_SOURCE_PACKET_SIZE	(4 + 188)

#define MAX_PACKET_SIZE		1024  /* 776, rounded up to 2^n */
#define PACKETS_PER_PAGE	(PAGE_SIZE / MAX_PACKET_SIZE)
#define N_PACKETS		64    /* buffer size */
#define N_PAGES			DIV_ROUND_UP(N_PACKETS, PACKETS_PER_PAGE)
#define IRQ_INTERVAL		16

struct firedtv_receive_context {
	struct fw_iso_context *context;
	struct fw_iso_buffer buffer;
	int interrupt_packet;
	int current_packet;
	char *pages[N_PAGES];
};

static int queue_iso(struct firedtv_receive_context *ctx, int index)
{
	struct fw_iso_packet p;

	p.payload_length = MAX_PACKET_SIZE;
	p.interrupt = !(++ctx->interrupt_packet & (IRQ_INTERVAL - 1));
	p.skip = 0;
	p.header_length = ISO_HEADER_SIZE;

	return fw_iso_context_queue(ctx->context, &p, &ctx->buffer,
				    index * MAX_PACKET_SIZE);
}

static void handle_iso(struct fw_iso_context *context, u32 cycle,
		       size_t header_length, void *header, void *data)
{
	struct firedtv *fdtv = data;
	struct firedtv_receive_context *ctx = fdtv->backend_data;
	__be32 *h, *h_end;
	int length, err, i = ctx->current_packet;
	char *p, *p_end;

	for (h = header, h_end = h + header_length / 4; h < h_end; h++) {
		length = be32_to_cpup(h) >> 16;
		if (unlikely(length > MAX_PACKET_SIZE)) {
			dev_err(fdtv->device, "length = %d\n", length);
			length = MAX_PACKET_SIZE;
		}

		p = ctx->pages[i / PACKETS_PER_PAGE]
				+ (i % PACKETS_PER_PAGE) * MAX_PACKET_SIZE;
		p_end = p + length;

		for (p += CIP_HEADER_SIZE + MPEG2_TS_HEADER_SIZE; p < p_end;
		     p += MPEG2_TS_SOURCE_PACKET_SIZE)
			dvb_dmx_swfilter_packets(&fdtv->demux, p, 1);

		err = queue_iso(ctx, i);
		if (unlikely(err))
			dev_err(fdtv->device, "requeue failed\n");

		i = (i + 1) & (N_PACKETS - 1);
	}
	ctx->current_packet = i;
}

static int start_iso(struct firedtv *fdtv)
{
	struct firedtv_receive_context *ctx;
	struct fw_device *device = device_of(fdtv);
	int i, err;

	ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
	if (!ctx)
		return -ENOMEM;

	ctx->context = fw_iso_context_create(device->card,
			FW_ISO_CONTEXT_RECEIVE, fdtv->isochannel,
			device->max_speed, ISO_HEADER_SIZE, handle_iso, fdtv);
	if (IS_ERR(ctx->context)) {
		err = PTR_ERR(ctx->context);
		goto fail_free;
	}

	err = fw_iso_buffer_init(&ctx->buffer, device->card,
				 N_PAGES, DMA_FROM_DEVICE);
	if (err)
		goto fail_context_destroy;

	ctx->interrupt_packet = 0;
	ctx->current_packet = 0;

	for (i = 0; i < N_PAGES; i++)
		ctx->pages[i] = page_address(ctx->buffer.pages[i]);

	for (i = 0; i < N_PACKETS; i++) {
		err = queue_iso(ctx, i);
		if (err)
			goto fail;
	}

	err = fw_iso_context_start(ctx->context, -1, 0,
				   FW_ISO_CONTEXT_MATCH_ALL_TAGS);
	if (err)
		goto fail;

	fdtv->backend_data = ctx;

	return 0;
fail:
	fw_iso_buffer_destroy(&ctx->buffer, device->card);
fail_context_destroy:
	fw_iso_context_destroy(ctx->context);
fail_free:
	kfree(ctx);

	return err;
}

static void stop_iso(struct firedtv *fdtv)
{
	struct firedtv_receive_context *ctx = fdtv->backend_data;

	fw_iso_context_stop(ctx->context);
	fw_iso_buffer_destroy(&ctx->buffer, device_of(fdtv)->card);
	fw_iso_context_destroy(ctx->context);
	kfree(ctx);
}

static const struct firedtv_backend backend = {
	.lock		= node_lock,
	.read		= node_read,
	.write		= node_write,
	.start_iso	= start_iso,
	.stop_iso	= stop_iso,
};

static void handle_fcp(struct fw_card *card, struct fw_request *request,
		       int tcode, int destination, int source, int generation,
		       int speed, unsigned long long offset,
		       void *payload, size_t length, void *callback_data)
{
	struct firedtv *f, *fdtv = NULL;
	struct fw_device *device;
	unsigned long flags;
	int su;

	if ((tcode != TCODE_WRITE_QUADLET_REQUEST &&
	     tcode != TCODE_WRITE_BLOCK_REQUEST) ||
	    offset != CSR_REGISTER_BASE + CSR_FCP_RESPONSE ||
	    length == 0 ||
	    (((u8 *)payload)[0] & 0xf0) != 0) {
		fw_send_response(card, request, RCODE_TYPE_ERROR);
		return;
	}

	su = ((u8 *)payload)[1] & 0x7;

	spin_lock_irqsave(&node_list_lock, flags);
	list_for_each_entry(f, &node_list, list) {
		device = device_of(f);
		if (device->generation != generation)
			continue;

		smp_rmb(); /* node_id vs. generation */

		if (device->card == card &&
		    device->node_id == source &&
		    (f->subunit == su || (f->subunit == 0 && su == 0x7))) {
			fdtv = f;
			break;
		}
	}
	spin_unlock_irqrestore(&node_list_lock, flags);

	if (fdtv) {
		avc_recv(fdtv, payload, length);
		fw_send_response(card, request, RCODE_COMPLETE);
	}
}

static struct fw_address_handler fcp_handler = {
	.length           = CSR_FCP_END - CSR_FCP_RESPONSE,
	.address_callback = handle_fcp,
};

static const struct fw_address_region fcp_region = {
	.start	= CSR_REGISTER_BASE + CSR_FCP_RESPONSE,
	.end	= CSR_REGISTER_BASE + CSR_FCP_END,
};

/* Adjust the template string if models with longer names appear. */
#define MAX_MODEL_NAME_LEN ((int)DIV_ROUND_UP(sizeof("FireDTV ????"), 4))

static size_t model_name(u32 *directory, __be32 *buffer)
{
	struct fw_csr_iterator ci;
	int i, length, key, value, last_key = 0;
	u32 *block = NULL;

	fw_csr_iterator_init(&ci, directory);
	while (fw_csr_iterator_next(&ci, &key, &value)) {
		if (last_key == CSR_MODEL &&
		    key == (CSR_DESCRIPTOR | CSR_LEAF))
			block = ci.p - 1 + value;
		last_key = key;
	}

	if (block == NULL)
		return 0;

	length = min((int)(block[0] >> 16) - 2, MAX_MODEL_NAME_LEN);
	if (length <= 0)
		return 0;

	/* fast-forward to text string */
	block += 3;

	for (i = 0; i < length; i++)
		buffer[i] = cpu_to_be32(block[i]);

	return length * 4;
}

static int node_probe(struct device *dev)
{
	struct firedtv *fdtv;
	__be32 name[MAX_MODEL_NAME_LEN];
	int name_len, err;

	name_len = model_name(fw_unit(dev)->directory, name);

	fdtv = fdtv_alloc(dev, &backend, (char *)name, name_len);
	if (!fdtv)
		return -ENOMEM;

	err = fdtv_register_rc(fdtv, dev);
	if (err)
		goto fail_free;

	spin_lock_irq(&node_list_lock);
	list_add_tail(&fdtv->list, &node_list);
	spin_unlock_irq(&node_list_lock);

	err = avc_identify_subunit(fdtv);
	if (err)
		goto fail;

	err = fdtv_dvb_register(fdtv);
	if (err)
		goto fail;

	avc_register_remote_control(fdtv);

	return 0;
fail:
	spin_lock_irq(&node_list_lock);
	list_del(&fdtv->list);
	spin_unlock_irq(&node_list_lock);
	fdtv_unregister_rc(fdtv);
fail_free:
	kfree(fdtv);

	return err;
}

static int node_remove(struct device *dev)
{
	struct firedtv *fdtv = dev_get_drvdata(dev);

	fdtv_dvb_unregister(fdtv);

	spin_lock_irq(&node_list_lock);
	list_del(&fdtv->list);
	spin_unlock_irq(&node_list_lock);

	fdtv_unregister_rc(fdtv);

	kfree(fdtv);
	return 0;
}

static void node_update(struct fw_unit *unit)
{
	struct firedtv *fdtv = dev_get_drvdata(&unit->device);

	if (fdtv->isochannel >= 0)
		cmp_establish_pp_connection(fdtv, fdtv->subunit,
					    fdtv->isochannel);
}

static struct fw_driver fdtv_driver = {
	.driver   = {
		.owner  = THIS_MODULE,
		.name   = "firedtv",
		.bus    = &fw_bus_type,
		.probe  = node_probe,
		.remove = node_remove,
	},
	.update   = node_update,
	.id_table = fdtv_id_table,
};

int __init fdtv_fw_init(void)
{
	int ret;

	ret = fw_core_add_address_handler(&fcp_handler, &fcp_region);
	if (ret < 0)
		return ret;

	return driver_register(&fdtv_driver.driver);
}

void fdtv_fw_exit(void)
{
	driver_unregister(&fdtv_driver.driver);
	fw_core_remove_address_handler(&fcp_handler);
}
