/*
 * IUCV special message driver
 *
 * Copyright IBM Corp. 2003, 2009
 *
 * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
 *
 * 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <linux/module.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/device.h>
#include <linux/slab.h>
#include <net/iucv/iucv.h>
#include <asm/cpcmd.h>
#include <asm/ebcdic.h>
#include "smsgiucv.h"

struct smsg_callback {
	struct list_head list;
	const char *prefix;
	int len;
	void (*callback)(const char *from, char *str);
};

MODULE_AUTHOR
   ("(C) 2003 IBM Corporation by Martin Schwidefsky (schwidefsky@de.ibm.com)");
MODULE_DESCRIPTION ("Linux for S/390 IUCV special message driver");

static struct iucv_path *smsg_path;
/* dummy device used as trigger for PM functions */
static struct device *smsg_dev;

static DEFINE_SPINLOCK(smsg_list_lock);
static LIST_HEAD(smsg_list);
static int iucv_path_connected;

static int smsg_path_pending(struct iucv_path *, u8 ipvmid[8], u8 ipuser[16]);
static void smsg_message_pending(struct iucv_path *, struct iucv_message *);

static struct iucv_handler smsg_handler = {
	.path_pending	 = smsg_path_pending,
	.message_pending = smsg_message_pending,
};

static int smsg_path_pending(struct iucv_path *path, u8 ipvmid[8],
			     u8 ipuser[16])
{
	if (strncmp(ipvmid, "*MSG    ", sizeof(ipvmid)) != 0)
		return -EINVAL;
	/* Path pending from *MSG. */
	return iucv_path_accept(path, &smsg_handler, "SMSGIUCV        ", NULL);
}

static void smsg_message_pending(struct iucv_path *path,
				 struct iucv_message *msg)
{
	struct smsg_callback *cb;
	unsigned char *buffer;
	unsigned char sender[9];
	int rc, i;

	buffer = kmalloc(msg->length + 1, GFP_ATOMIC | GFP_DMA);
	if (!buffer) {
		iucv_message_reject(path, msg);
		return;
	}
	rc = iucv_message_receive(path, msg, 0, buffer, msg->length, NULL);
	if (rc == 0) {
		buffer[msg->length] = 0;
		EBCASC(buffer, msg->length);
		memcpy(sender, buffer, 8);
		sender[8] = 0;
		/* Remove trailing whitespace from the sender name. */
		for (i = 7; i >= 0; i--) {
			if (sender[i] != ' ' && sender[i] != '\t')
				break;
			sender[i] = 0;
		}
		spin_lock(&smsg_list_lock);
		list_for_each_entry(cb, &smsg_list, list)
			if (strncmp(buffer + 8, cb->prefix, cb->len) == 0) {
				cb->callback(sender, buffer + 8);
				break;
			}
		spin_unlock(&smsg_list_lock);
	}
	kfree(buffer);
}

int smsg_register_callback(const char *prefix,
			   void (*callback)(const char *from, char *str))
{
	struct smsg_callback *cb;

	cb = kmalloc(sizeof(struct smsg_callback), GFP_KERNEL);
	if (!cb)
		return -ENOMEM;
	cb->prefix = prefix;
	cb->len = strlen(prefix);
	cb->callback = callback;
	spin_lock_bh(&smsg_list_lock);
	list_add_tail(&cb->list, &smsg_list);
	spin_unlock_bh(&smsg_list_lock);
	return 0;
}

void smsg_unregister_callback(const char *prefix,
			      void (*callback)(const char *from,
					       char *str))
{
	struct smsg_callback *cb, *tmp;

	spin_lock_bh(&smsg_list_lock);
	cb = NULL;
	list_for_each_entry(tmp, &smsg_list, list)
		if (tmp->callback == callback &&
		    strcmp(tmp->prefix, prefix) == 0) {
			cb = tmp;
			list_del(&cb->list);
			break;
		}
	spin_unlock_bh(&smsg_list_lock);
	kfree(cb);
}

static int smsg_pm_freeze(struct device *dev)
{
#ifdef CONFIG_PM_DEBUG
	printk(KERN_WARNING "smsg_pm_freeze\n");
#endif
	if (smsg_path && iucv_path_connected) {
		iucv_path_sever(smsg_path, NULL);
		iucv_path_connected = 0;
	}
	return 0;
}

static int smsg_pm_restore_thaw(struct device *dev)
{
	int rc;

#ifdef CONFIG_PM_DEBUG
	printk(KERN_WARNING "smsg_pm_restore_thaw\n");
#endif
	if (smsg_path && iucv_path_connected) {
		memset(smsg_path, 0, sizeof(*smsg_path));
		smsg_path->msglim = 255;
		smsg_path->flags = 0;
		rc = iucv_path_connect(smsg_path, &smsg_handler, "*MSG    ",
				       NULL, NULL, NULL);
#ifdef CONFIG_PM_DEBUG
		if (rc)
			printk(KERN_ERR
			       "iucv_path_connect returned with rc %i\n", rc);
#endif
		if (!rc)
			iucv_path_connected = 1;
		cpcmd("SET SMSG IUCV", NULL, 0, NULL);
	}
	return 0;
}

static const struct dev_pm_ops smsg_pm_ops = {
	.freeze = smsg_pm_freeze,
	.thaw = smsg_pm_restore_thaw,
	.restore = smsg_pm_restore_thaw,
};

static struct device_driver smsg_driver = {
	.owner = THIS_MODULE,
	.name = SMSGIUCV_DRV_NAME,
	.bus  = &iucv_bus,
	.pm = &smsg_pm_ops,
};

static void __exit smsg_exit(void)
{
	cpcmd("SET SMSG IUCV", NULL, 0, NULL);
	device_unregister(smsg_dev);
	iucv_unregister(&smsg_handler, 1);
	driver_unregister(&smsg_driver);
}

static int __init smsg_init(void)
{
	int rc;

	if (!MACHINE_IS_VM) {
		rc = -EPROTONOSUPPORT;
		goto out;
	}
	rc = driver_register(&smsg_driver);
	if (rc != 0)
		goto out;
	rc = iucv_register(&smsg_handler, 1);
	if (rc)
		goto out_driver;
	smsg_path = iucv_path_alloc(255, 0, GFP_KERNEL);
	if (!smsg_path) {
		rc = -ENOMEM;
		goto out_register;
	}
	rc = iucv_path_connect(smsg_path, &smsg_handler, "*MSG    ",
			       NULL, NULL, NULL);
	if (rc)
		goto out_free_path;
	else
		iucv_path_connected = 1;
	smsg_dev = kzalloc(sizeof(struct device), GFP_KERNEL);
	if (!smsg_dev) {
		rc = -ENOMEM;
		goto out_free_path;
	}
	dev_set_name(smsg_dev, "smsg_iucv");
	smsg_dev->bus = &iucv_bus;
	smsg_dev->parent = iucv_root;
	smsg_dev->release = (void (*)(struct device *))kfree;
	smsg_dev->driver = &smsg_driver;
	rc = device_register(smsg_dev);
	if (rc)
		goto out_put;

	cpcmd("SET SMSG IUCV", NULL, 0, NULL);
	return 0;

out_put:
	put_device(smsg_dev);
out_free_path:
	iucv_path_free(smsg_path);
	smsg_path = NULL;
out_register:
	iucv_unregister(&smsg_handler, 1);
out_driver:
	driver_unregister(&smsg_driver);
out:
	return rc;
}

module_init(smsg_init);
module_exit(smsg_exit);
MODULE_LICENSE("GPL");

EXPORT_SYMBOL(smsg_register_callback);
EXPORT_SYMBOL(smsg_unregister_callback);
