/*
 * 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/gfp.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;

	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);
