/*
 * RPA Virtual I/O device functions 
 * Copyright (C) 2004 Linda Xie <lxie@us.ibm.com>
 *
 * All rights reserved.
 *
 * 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, GOOD TITLE or
 * NON INFRINGEMENT.  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., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * Send feedback to <lxie@us.ibm.com>
 *
 */
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/kobject.h>
#include <linux/sysfs.h>
#include <linux/pci.h>
#include <linux/string.h>
#include <linux/slab.h>

#include <asm/rtas.h>
#include "rpaphp.h"

static ssize_t address_read_file (struct hotplug_slot *php_slot, char *buf)
{
	int retval;
	struct slot *slot = (struct slot *)php_slot->private;
	struct pci_bus *bus;

	if (!slot)
		return -ENOENT;

	bus = slot->bus;
	if (!bus)
		return -ENOENT;

	if (bus->self)
		retval = sprintf(buf, pci_name(bus->self));
	else
		retval = sprintf(buf, "%04x:%02x:00.0",
		        pci_domain_nr(bus), bus->number);

	return retval;
}

static struct hotplug_slot_attribute php_attr_address = {
	.attr = {.name = "address", .mode = S_IFREG | S_IRUGO},
	.show = address_read_file,
};

/* free up the memory used by a slot */
static void rpaphp_release_slot(struct hotplug_slot *hotplug_slot)
{
	struct slot *slot = (struct slot *) hotplug_slot->private;
	dealloc_slot_struct(slot);
}

void dealloc_slot_struct(struct slot *slot)
{
	kfree(slot->hotplug_slot->info);
	kfree(slot->hotplug_slot->name);
	kfree(slot->hotplug_slot);
	kfree(slot);
}

struct slot *alloc_slot_struct(struct device_node *dn,
                       int drc_index, char *drc_name, int power_domain)
{
	struct slot *slot;
	
	slot = kzalloc(sizeof(struct slot), GFP_KERNEL);
	if (!slot)
		goto error_nomem;
	slot->hotplug_slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL);
	if (!slot->hotplug_slot)
		goto error_slot;	
	slot->hotplug_slot->info = kzalloc(sizeof(struct hotplug_slot_info),
					   GFP_KERNEL);
	if (!slot->hotplug_slot->info)
		goto error_hpslot;
	slot->hotplug_slot->name = kmalloc(strlen(drc_name) + 1, GFP_KERNEL);
	if (!slot->hotplug_slot->name)
		goto error_info;	
	slot->name = slot->hotplug_slot->name;
	strcpy(slot->name, drc_name);
	slot->dn = dn;
	slot->index = drc_index;
	slot->power_domain = power_domain;
	slot->hotplug_slot->private = slot;
	slot->hotplug_slot->ops = &rpaphp_hotplug_slot_ops;
	slot->hotplug_slot->release = &rpaphp_release_slot;
	
	return (slot);

error_info:
	kfree(slot->hotplug_slot->info);
error_hpslot:
	kfree(slot->hotplug_slot);
error_slot:
	kfree(slot);
error_nomem:
	return NULL;
}

static int is_registered(struct slot *slot)
{
	struct slot *tmp_slot;

	list_for_each_entry(tmp_slot, &rpaphp_slot_head, rpaphp_slot_list) {
		if (!strcmp(tmp_slot->name, slot->name))
			return 1;
	}	
	return 0;
}

int rpaphp_deregister_slot(struct slot *slot)
{
	int retval = 0;
	struct hotplug_slot *php_slot = slot->hotplug_slot;

	 dbg("%s - Entry: deregistering slot=%s\n",
		__func__, slot->name);

	list_del(&slot->rpaphp_slot_list);
	
	/* remove "address" file */
	sysfs_remove_file(&php_slot->kobj, &php_attr_address.attr);

	retval = pci_hp_deregister(php_slot);
	if (retval)
		err("Problem unregistering a slot %s\n", slot->name);

	dbg("%s - Exit: rc[%d]\n", __func__, retval);
	return retval;
}
EXPORT_SYMBOL_GPL(rpaphp_deregister_slot);

int rpaphp_register_slot(struct slot *slot)
{
	struct hotplug_slot *php_slot = slot->hotplug_slot;
	int retval;

	dbg("%s registering slot:path[%s] index[%x], name[%s] pdomain[%x] type[%d]\n", 
		__func__, slot->dn->full_name, slot->index, slot->name,
		slot->power_domain, slot->type);

	/* should not try to register the same slot twice */
	if (is_registered(slot)) {
		err("rpaphp_register_slot: slot[%s] is already registered\n", slot->name);
		return -EAGAIN;
	}	

	retval = pci_hp_register(php_slot);
	if (retval) {
		err("pci_hp_register failed with error %d\n", retval);
		return retval;
	}

	/* create "address" file */
	retval = sysfs_create_file(&php_slot->kobj, &php_attr_address.attr);
	if (retval) {
		err("sysfs_create_file failed with error %d\n", retval);
		goto sysfs_fail;
	}

	/* add slot to our internal list */
	list_add(&slot->rpaphp_slot_list, &rpaphp_slot_head);
	info("Slot [%s] registered\n", slot->name);
	return 0;

sysfs_fail:
	pci_hp_deregister(php_slot);
	return retval;
}

