/*
 * Interface for Dynamic Logical Partitioning of I/O Slots on
 * RPA-compliant PPC64 platform.
 *
 * John Rose <johnrose@austin.ibm.com>
 * October 2003
 *
 * Copyright (C) 2003 IBM.
 *
 *      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.
 */
#include <linux/kobject.h>
#include <linux/string.h>
#include "pci_hotplug.h"
#include "rpadlpar.h"

#define DLPAR_KOBJ_NAME       "control"
#define ADD_SLOT_ATTR_NAME    "add_slot"
#define REMOVE_SLOT_ATTR_NAME "remove_slot"

#define MAX_DRC_NAME_LEN 64

/* Store return code of dlpar operation in attribute struct */
struct dlpar_io_attr {
	int rc;
	struct attribute attr;
	ssize_t (*store)(struct dlpar_io_attr *dlpar_attr, const char *buf,
		size_t nbytes);
};

/* Common show callback for all attrs, display the return code
 * of the dlpar op */
static ssize_t
dlpar_attr_show(struct kobject * kobj, struct attribute * attr, char * buf)
{
	struct dlpar_io_attr *dlpar_attr = container_of(attr,
						struct dlpar_io_attr, attr);
	return sprintf(buf, "%d\n", dlpar_attr->rc);
}

static ssize_t
dlpar_attr_store(struct kobject * kobj, struct attribute * attr,
		 const char *buf, size_t nbytes)
{
	struct dlpar_io_attr *dlpar_attr = container_of(attr,
						struct dlpar_io_attr, attr);
	return dlpar_attr->store ?
		dlpar_attr->store(dlpar_attr, buf, nbytes) : -EIO;
}

static struct sysfs_ops dlpar_attr_sysfs_ops = {
	.show = dlpar_attr_show,
	.store = dlpar_attr_store,
};

static ssize_t add_slot_store(struct dlpar_io_attr *dlpar_attr,
				const char *buf, size_t nbytes)
{
	char drc_name[MAX_DRC_NAME_LEN];
	char *end;

	if (nbytes >= MAX_DRC_NAME_LEN)
		return 0;

	memcpy(drc_name, buf, nbytes);

	end = strchr(drc_name, '\n');
	if (!end)
		end = &drc_name[nbytes];
	*end = '\0';

	dlpar_attr->rc = dlpar_add_slot(drc_name);

	return nbytes;
}

static ssize_t remove_slot_store(struct dlpar_io_attr *dlpar_attr,
		 		const char *buf, size_t nbytes)
{
	char drc_name[MAX_DRC_NAME_LEN];
	char *end;

	if (nbytes >= MAX_DRC_NAME_LEN)
		return 0;

	memcpy(drc_name, buf, nbytes);

	end = strchr(drc_name, '\n');
	if (!end)
		end = &drc_name[nbytes];
	*end = '\0';

	dlpar_attr->rc = dlpar_remove_slot(drc_name);

	return nbytes;
}

static struct dlpar_io_attr add_slot_attr = {
	.rc = 0,
	.attr = { .name = ADD_SLOT_ATTR_NAME, .mode = 0644, },
	.store = add_slot_store,
};

static struct dlpar_io_attr remove_slot_attr = {
	.rc = 0,
	.attr = { .name = REMOVE_SLOT_ATTR_NAME, .mode = 0644},
	.store = remove_slot_store,
};

static struct attribute *default_attrs[] = {
	&add_slot_attr.attr,
	&remove_slot_attr.attr,
	NULL,
};

static void dlpar_io_release(struct kobject *kobj)
{
	/* noop */
	return;
}

struct kobj_type ktype_dlpar_io = {
	.release = dlpar_io_release,
	.sysfs_ops = &dlpar_attr_sysfs_ops,
	.default_attrs = default_attrs,
};

struct kset dlpar_io_kset = {
	.subsys = &pci_hotplug_slots_subsys,
	.kobj = {.name = DLPAR_KOBJ_NAME, .ktype=&ktype_dlpar_io,},
	.ktype = &ktype_dlpar_io,
};

int dlpar_sysfs_init(void)
{
	if (kset_register(&dlpar_io_kset)) {
		printk(KERN_ERR "rpadlpar_io: cannot register kset for %s\n",
				dlpar_io_kset.kobj.name);
		return -EINVAL;
	}

	return 0;
}

void dlpar_sysfs_exit(void)
{
	kset_unregister(&dlpar_io_kset);
}
