/*
 * Legacy iSeries specific vio initialisation
 * that needs to be built in (not a module).
 *
 * © Copyright 2007 IBM Corporation
 *	Author: Stephen Rothwell
 *	Some parts collected from various other files
 *
 * 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.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */
#include <linux/of.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/completion.h>
#include <linux/proc_fs.h>
#include <linux/module.h>

#include <asm/firmware.h>
#include <asm/vio.h>
#include <asm/iseries/vio.h>
#include <asm/iseries/iommu.h>
#include <asm/iseries/hv_types.h>
#include <asm/iseries/hv_lp_event.h>

#define FIRST_VTY	0
#define NUM_VTYS	1
#define FIRST_VSCSI	(FIRST_VTY + NUM_VTYS)
#define NUM_VSCSIS	1
#define FIRST_VLAN	(FIRST_VSCSI + NUM_VSCSIS)
#define NUM_VLANS	HVMAXARCHITECTEDVIRTUALLANS
#define FIRST_VIODASD	(FIRST_VLAN + NUM_VLANS)
#define NUM_VIODASDS	HVMAXARCHITECTEDVIRTUALDISKS
#define FIRST_VIOCD	(FIRST_VIODASD + NUM_VIODASDS)
#define NUM_VIOCDS	HVMAXARCHITECTEDVIRTUALCDROMS
#define FIRST_VIOTAPE	(FIRST_VIOCD + NUM_VIOCDS)
#define NUM_VIOTAPES	HVMAXARCHITECTEDVIRTUALTAPES

struct vio_waitevent {
	struct completion	com;
	int			rc;
	u16			sub_result;
};

struct vio_resource {
	char	rsrcname[10];
	char	type[4];
	char	model[3];
};

static struct property *new_property(const char *name, int length,
		const void *value)
{
	struct property *np = kzalloc(sizeof(*np) + strlen(name) + 1 + length,
			GFP_KERNEL);

	if (!np)
		return NULL;
	np->name = (char *)(np + 1);
	np->value = np->name + strlen(name) + 1;
	strcpy(np->name, name);
	memcpy(np->value, value, length);
	np->length = length;
	return np;
}

static void free_property(struct property *np)
{
	kfree(np);
}

static struct device_node *new_node(const char *path,
		struct device_node *parent)
{
	struct device_node *np = kzalloc(sizeof(*np), GFP_KERNEL);

	if (!np)
		return NULL;
	np->full_name = kmalloc(strlen(path) + 1, GFP_KERNEL);
	if (!np->full_name) {
		kfree(np);
		return NULL;
	}
	strcpy(np->full_name, path);
	of_node_set_flag(np, OF_DYNAMIC);
	kref_init(&np->kref);
	np->parent = of_node_get(parent);
	return np;
}

static void free_node(struct device_node *np)
{
	struct property *next;
	struct property *prop;

	next = np->properties;
	while (next) {
		prop = next;
		next = prop->next;
		free_property(prop);
	}
	of_node_put(np->parent);
	kfree(np->full_name);
	kfree(np);
}

static int add_string_property(struct device_node *np, const char *name,
		const char *value)
{
	struct property *nprop = new_property(name, strlen(value) + 1, value);

	if (!nprop)
		return 0;
	prom_add_property(np, nprop);
	return 1;
}

static int add_raw_property(struct device_node *np, const char *name,
		int length, const void *value)
{
	struct property *nprop = new_property(name, length, value);

	if (!nprop)
		return 0;
	prom_add_property(np, nprop);
	return 1;
}

static struct device_node *do_device_node(struct device_node *parent,
		const char *name, u32 reg, u32 unit, const char *type,
		const char *compat, struct vio_resource *res)
{
	struct device_node *np;
	char path[32];

	snprintf(path, sizeof(path), "/vdevice/%s@%08x", name, reg);
	np = new_node(path, parent);
	if (!np)
		return NULL;
	if (!add_string_property(np, "name", name) ||
		!add_string_property(np, "device_type", type) ||
		!add_string_property(np, "compatible", compat) ||
		!add_raw_property(np, "reg", sizeof(reg), &reg) ||
		!add_raw_property(np, "linux,unit_address",
			sizeof(unit), &unit)) {
		goto node_free;
	}
	if (res) {
		if (!add_raw_property(np, "linux,vio_rsrcname",
				sizeof(res->rsrcname), res->rsrcname) ||
			!add_raw_property(np, "linux,vio_type",
				sizeof(res->type), res->type) ||
			!add_raw_property(np, "linux,vio_model",
				sizeof(res->model), res->model))
			goto node_free;
	}
	np->name = of_get_property(np, "name", NULL);
	np->type = of_get_property(np, "device_type", NULL);
	of_attach_node(np);
#ifdef CONFIG_PROC_DEVICETREE
	if (parent->pde) {
		struct proc_dir_entry *ent;

		ent = proc_mkdir(strrchr(np->full_name, '/') + 1, parent->pde);
		if (ent)
			proc_device_tree_add_node(np, ent);
	}
#endif
	return np;

 node_free:
	free_node(np);
	return NULL;
}

/*
 * This is here so that we can dynamically add viodasd
 * devices without exposing all the above infrastructure.
 */
struct vio_dev *vio_create_viodasd(u32 unit)
{
	struct device_node *vio_root;
	struct device_node *np;
	struct vio_dev *vdev = NULL;

	vio_root = of_find_node_by_path("/vdevice");
	if (!vio_root)
		return NULL;
	np = do_device_node(vio_root, "viodasd", FIRST_VIODASD + unit, unit,
			"block", "IBM,iSeries-viodasd", NULL);
	of_node_put(vio_root);
	if (np) {
		vdev = vio_register_device_node(np);
		if (!vdev)
			free_node(np);
	}
	return vdev;
}
EXPORT_SYMBOL_GPL(vio_create_viodasd);

static void __init handle_block_event(struct HvLpEvent *event)
{
	struct vioblocklpevent *bevent = (struct vioblocklpevent *)event;
	struct vio_waitevent *pwe;

	if (event == NULL)
		/* Notification that a partition went away! */
		return;
	/* First, we should NEVER get an int here...only acks */
	if (hvlpevent_is_int(event)) {
		printk(KERN_WARNING "handle_viod_request: "
		       "Yikes! got an int in viodasd event handler!\n");
		if (hvlpevent_need_ack(event)) {
			event->xRc = HvLpEvent_Rc_InvalidSubtype;
			HvCallEvent_ackLpEvent(event);
		}
		return;
	}

	switch (event->xSubtype & VIOMINOR_SUBTYPE_MASK) {
	case vioblockopen:
		/*
		 * Handle a response to an open request.  We get all the
		 * disk information in the response, so update it.  The
		 * correlation token contains a pointer to a waitevent
		 * structure that has a completion in it.  update the
		 * return code in the waitevent structure and post the
		 * completion to wake up the guy who sent the request
		 */
		pwe = (struct vio_waitevent *)event->xCorrelationToken;
		pwe->rc = event->xRc;
		pwe->sub_result = bevent->sub_result;
		complete(&pwe->com);
		break;
	case vioblockclose:
		break;
	default:
		printk(KERN_WARNING "handle_viod_request: unexpected subtype!");
		if (hvlpevent_need_ack(event)) {
			event->xRc = HvLpEvent_Rc_InvalidSubtype;
			HvCallEvent_ackLpEvent(event);
		}
	}
}

static void __init probe_disk(struct device_node *vio_root, u32 unit)
{
	HvLpEvent_Rc hvrc;
	struct vio_waitevent we;
	u16 flags = 0;

retry:
	init_completion(&we.com);

	/* Send the open event to OS/400 */
	hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
			HvLpEvent_Type_VirtualIo,
			viomajorsubtype_blockio | vioblockopen,
			HvLpEvent_AckInd_DoAck, HvLpEvent_AckType_ImmediateAck,
			viopath_sourceinst(viopath_hostLp),
			viopath_targetinst(viopath_hostLp),
			(u64)(unsigned long)&we, VIOVERSION << 16,
			((u64)unit << 48) | ((u64)flags<< 32),
			0, 0, 0);
	if (hvrc != 0) {
		printk(KERN_WARNING "probe_disk: bad rc on HV open %d\n",
			(int)hvrc);
		return;
	}

	wait_for_completion(&we.com);

	if (we.rc != 0) {
		if (flags != 0)
			return;
		/* try again with read only flag set */
		flags = vioblockflags_ro;
		goto retry;
	}

	/* Send the close event to OS/400.  We DON'T expect a response */
	hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
			HvLpEvent_Type_VirtualIo,
			viomajorsubtype_blockio | vioblockclose,
			HvLpEvent_AckInd_NoAck, HvLpEvent_AckType_ImmediateAck,
			viopath_sourceinst(viopath_hostLp),
			viopath_targetinst(viopath_hostLp),
			0, VIOVERSION << 16,
			((u64)unit << 48) | ((u64)flags << 32),
			0, 0, 0);
	if (hvrc != 0) {
		printk(KERN_WARNING "probe_disk: "
		       "bad rc sending event to OS/400 %d\n", (int)hvrc);
		return;
	}

	do_device_node(vio_root, "viodasd", FIRST_VIODASD + unit, unit,
			"block", "IBM,iSeries-viodasd", NULL);
}

static void __init get_viodasd_info(struct device_node *vio_root)
{
	int rc;
	u32 unit;

	rc = viopath_open(viopath_hostLp, viomajorsubtype_blockio, 2);
	if (rc) {
		printk(KERN_WARNING "get_viodasd_info: "
		       "error opening path to host partition %d\n",
		       viopath_hostLp);
		return;
	}

	/* Initialize our request handler */
	vio_setHandler(viomajorsubtype_blockio, handle_block_event);

	for (unit = 0; unit < HVMAXARCHITECTEDVIRTUALDISKS; unit++)
		probe_disk(vio_root, unit);

	vio_clearHandler(viomajorsubtype_blockio);
	viopath_close(viopath_hostLp, viomajorsubtype_blockio, 2);
}

static void __init handle_cd_event(struct HvLpEvent *event)
{
	struct viocdlpevent *bevent;
	struct vio_waitevent *pwe;

	if (!event)
		/* Notification that a partition went away! */
		return;

	/* First, we should NEVER get an int here...only acks */
	if (hvlpevent_is_int(event)) {
		printk(KERN_WARNING "handle_cd_event: got an unexpected int\n");
		if (hvlpevent_need_ack(event)) {
			event->xRc = HvLpEvent_Rc_InvalidSubtype;
			HvCallEvent_ackLpEvent(event);
		}
		return;
	}

	bevent = (struct viocdlpevent *)event;

	switch (event->xSubtype & VIOMINOR_SUBTYPE_MASK) {
	case viocdgetinfo:
		pwe = (struct vio_waitevent *)event->xCorrelationToken;
		pwe->rc = event->xRc;
		pwe->sub_result = bevent->sub_result;
		complete(&pwe->com);
		break;

	default:
		printk(KERN_WARNING "handle_cd_event: "
			"message with unexpected subtype %0x04X!\n",
			event->xSubtype & VIOMINOR_SUBTYPE_MASK);
		if (hvlpevent_need_ack(event)) {
			event->xRc = HvLpEvent_Rc_InvalidSubtype;
			HvCallEvent_ackLpEvent(event);
		}
	}
}

static void __init get_viocd_info(struct device_node *vio_root)
{
	HvLpEvent_Rc hvrc;
	u32 unit;
	struct vio_waitevent we;
	struct vio_resource *unitinfo;
	dma_addr_t unitinfo_dmaaddr;
	int ret;

	ret = viopath_open(viopath_hostLp, viomajorsubtype_cdio, 2);
	if (ret) {
		printk(KERN_WARNING
			"get_viocd_info: error opening path to host partition %d\n",
			viopath_hostLp);
		return;
	}

	/* Initialize our request handler */
	vio_setHandler(viomajorsubtype_cdio, handle_cd_event);

	unitinfo = iseries_hv_alloc(
			sizeof(*unitinfo) * HVMAXARCHITECTEDVIRTUALCDROMS,
			&unitinfo_dmaaddr, GFP_ATOMIC);
	if (!unitinfo) {
		printk(KERN_WARNING
			"get_viocd_info: error allocating unitinfo\n");
		goto clear_handler;
	}

	memset(unitinfo, 0, sizeof(*unitinfo) * HVMAXARCHITECTEDVIRTUALCDROMS);

	init_completion(&we.com);

	hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
			HvLpEvent_Type_VirtualIo,
			viomajorsubtype_cdio | viocdgetinfo,
			HvLpEvent_AckInd_DoAck, HvLpEvent_AckType_ImmediateAck,
			viopath_sourceinst(viopath_hostLp),
			viopath_targetinst(viopath_hostLp),
			(u64)&we, VIOVERSION << 16, unitinfo_dmaaddr, 0,
			sizeof(*unitinfo) * HVMAXARCHITECTEDVIRTUALCDROMS, 0);
	if (hvrc != HvLpEvent_Rc_Good) {
		printk(KERN_WARNING
			"get_viocd_info: cdrom error sending event. rc %d\n",
			(int)hvrc);
		goto hv_free;
	}

	wait_for_completion(&we.com);

	if (we.rc) {
		printk(KERN_WARNING "get_viocd_info: bad rc %d:0x%04X\n",
			we.rc, we.sub_result);
		goto hv_free;
	}

	for (unit = 0; (unit < HVMAXARCHITECTEDVIRTUALCDROMS) &&
			unitinfo[unit].rsrcname[0]; unit++) {
		if (!do_device_node(vio_root, "viocd", FIRST_VIOCD + unit, unit,
				"block", "IBM,iSeries-viocd", &unitinfo[unit]))
			break;
	}

 hv_free:
	iseries_hv_free(sizeof(*unitinfo) * HVMAXARCHITECTEDVIRTUALCDROMS,
			unitinfo, unitinfo_dmaaddr);
 clear_handler:
	vio_clearHandler(viomajorsubtype_cdio);
	viopath_close(viopath_hostLp, viomajorsubtype_cdio, 2);
}

/* Handle interrupt events for tape */
static void __init handle_tape_event(struct HvLpEvent *event)
{
	struct vio_waitevent *we;
	struct viotapelpevent *tevent = (struct viotapelpevent *)event;

	if (event == NULL)
		/* Notification that a partition went away! */
		return;

	we = (struct vio_waitevent *)event->xCorrelationToken;
	switch (event->xSubtype & VIOMINOR_SUBTYPE_MASK) {
	case viotapegetinfo:
		we->rc = tevent->sub_type_result;
		complete(&we->com);
		break;
	default:
		printk(KERN_WARNING "handle_tape_event: weird ack\n");
	}
}

static void __init get_viotape_info(struct device_node *vio_root)
{
	HvLpEvent_Rc hvrc;
	u32 unit;
	struct vio_resource *unitinfo;
	dma_addr_t unitinfo_dmaaddr;
	size_t len = sizeof(*unitinfo) * HVMAXARCHITECTEDVIRTUALTAPES;
	struct vio_waitevent we;
	int ret;

	init_completion(&we.com);

	ret = viopath_open(viopath_hostLp, viomajorsubtype_tape, 2);
	if (ret) {
		printk(KERN_WARNING "get_viotape_info: "
			"error on viopath_open to hostlp %d\n", ret);
		return;
	}

	vio_setHandler(viomajorsubtype_tape, handle_tape_event);

	unitinfo = iseries_hv_alloc(len, &unitinfo_dmaaddr, GFP_ATOMIC);
	if (!unitinfo)
		goto clear_handler;

	memset(unitinfo, 0, len);

	hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
			HvLpEvent_Type_VirtualIo,
			viomajorsubtype_tape | viotapegetinfo,
			HvLpEvent_AckInd_DoAck, HvLpEvent_AckType_ImmediateAck,
			viopath_sourceinst(viopath_hostLp),
			viopath_targetinst(viopath_hostLp),
			(u64)(unsigned long)&we, VIOVERSION << 16,
			unitinfo_dmaaddr, len, 0, 0);
	if (hvrc != HvLpEvent_Rc_Good) {
		printk(KERN_WARNING "get_viotape_info: hv error on op %d\n",
				(int)hvrc);
		goto hv_free;
	}

	wait_for_completion(&we.com);

	for (unit = 0; (unit < HVMAXARCHITECTEDVIRTUALTAPES) &&
			unitinfo[unit].rsrcname[0]; unit++) {
		if (!do_device_node(vio_root, "viotape", FIRST_VIOTAPE + unit,
				unit, "byte", "IBM,iSeries-viotape",
				&unitinfo[unit]))
			break;
	}

 hv_free:
	iseries_hv_free(len, unitinfo, unitinfo_dmaaddr);
 clear_handler:
	vio_clearHandler(viomajorsubtype_tape);
	viopath_close(viopath_hostLp, viomajorsubtype_tape, 2);
}

static int __init iseries_vio_init(void)
{
	struct device_node *vio_root;
	int ret = -ENODEV;

	if (!firmware_has_feature(FW_FEATURE_ISERIES))
		goto out;

	iommu_vio_init();

	vio_root = of_find_node_by_path("/vdevice");
	if (!vio_root)
		goto out;

	if (viopath_hostLp == HvLpIndexInvalid) {
		vio_set_hostlp();
		/* If we don't have a host, bail out */
		if (viopath_hostLp == HvLpIndexInvalid)
			goto put_node;
	}

	get_viodasd_info(vio_root);
	get_viocd_info(vio_root);
	get_viotape_info(vio_root);

	ret = 0;

 put_node:
	of_node_put(vio_root);
 out:
	return ret;
}
arch_initcall(iseries_vio_init);
