/*
 * $Id: cu3088.c,v 1.35 2005/03/30 19:28:52 richtera Exp $
 *
 * CTC / LCS ccw_device driver
 *
 * Copyright (C) 2002 IBM Deutschland Entwicklung GmbH, IBM Corporation
 * Author(s): Arnd Bergmann <arndb@de.ibm.com>
 *            Cornelia Huck <cohuck@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/init.h>
#include <linux/module.h>
#include <linux/err.h>

#include <asm/ccwdev.h>
#include <asm/ccwgroup.h>

#include "cu3088.h"

const char *cu3088_type[] = {
	"not a channel",
	"CTC/A",
	"ESCON channel",
	"FICON channel",
	"P390 LCS card",
	"OSA LCS card",
	"CLAW channel device",
	"unknown channel type",
	"unsupported channel type",
};

/* static definitions */

static struct ccw_device_id cu3088_ids[] = {
	{ CCW_DEVICE(0x3088, 0x08), .driver_info = channel_type_parallel },
	{ CCW_DEVICE(0x3088, 0x1f), .driver_info = channel_type_escon },
	{ CCW_DEVICE(0x3088, 0x1e), .driver_info = channel_type_ficon },
	{ CCW_DEVICE(0x3088, 0x01), .driver_info = channel_type_p390 },
	{ CCW_DEVICE(0x3088, 0x60), .driver_info = channel_type_osa2 },
	{ CCW_DEVICE(0x3088, 0x61), .driver_info = channel_type_claw },
	{ /* end of list */ }
};

static struct ccw_driver cu3088_driver;

struct device *cu3088_root_dev;

static ssize_t
group_write(struct device_driver *drv, const char *buf, size_t count)
{
	const char *start, *end;
	char bus_ids[2][BUS_ID_SIZE], *argv[2];
	int i;
	int ret;
	struct ccwgroup_driver *cdrv;

	cdrv = to_ccwgroupdrv(drv);
	if (!cdrv)
		return -EINVAL;
	start = buf;
	for (i=0; i<2; i++) {
		static const char delim[] = {',', '\n'};
		int len;

		if (!(end = strchr(start, delim[i])))
			return count;
		len = min_t(ptrdiff_t, BUS_ID_SIZE, end - start + 1);
		strlcpy (bus_ids[i], start, len);
		argv[i] = bus_ids[i];
		start = end + 1;
	}

	ret = ccwgroup_create(cu3088_root_dev, cdrv->driver_id,
			      &cu3088_driver, 2, argv);

	return (ret == 0) ? count : ret;
}

static DRIVER_ATTR(group, 0200, NULL, group_write);

/* Register-unregister for ctc&lcs */
int
register_cu3088_discipline(struct ccwgroup_driver *dcp) 
{
	int rc;

	if (!dcp)
		return -EINVAL;

	/* Register discipline.*/
	rc = ccwgroup_driver_register(dcp);
	if (rc)
		return rc;

	rc = driver_create_file(&dcp->driver, &driver_attr_group);
	if (rc)
		ccwgroup_driver_unregister(dcp);
		
	return rc;

}

void
unregister_cu3088_discipline(struct ccwgroup_driver *dcp)
{
	if (!dcp)
		return;

	driver_remove_file(&dcp->driver, &driver_attr_group);
	ccwgroup_driver_unregister(dcp);
}

static struct ccw_driver cu3088_driver = {
	.owner	     = THIS_MODULE,
	.ids	     = cu3088_ids,
	.name        = "cu3088",
	.probe	     = ccwgroup_probe_ccwdev,
	.remove	     = ccwgroup_remove_ccwdev,
};

/* module setup */
static int __init
cu3088_init (void)
{
	int rc;
	
	cu3088_root_dev = s390_root_dev_register("cu3088");
	if (IS_ERR(cu3088_root_dev))
		return PTR_ERR(cu3088_root_dev);
	rc = ccw_driver_register(&cu3088_driver);
	if (rc)
		s390_root_dev_unregister(cu3088_root_dev);

	return rc;
}

static void __exit
cu3088_exit (void)
{
	ccw_driver_unregister(&cu3088_driver);
	s390_root_dev_unregister(cu3088_root_dev);
}

MODULE_DEVICE_TABLE(ccw,cu3088_ids);
MODULE_AUTHOR("Arnd Bergmann <arndb@de.ibm.com>");
MODULE_LICENSE("GPL");

module_init(cu3088_init);
module_exit(cu3088_exit);

EXPORT_SYMBOL_GPL(cu3088_type);
EXPORT_SYMBOL_GPL(register_cu3088_discipline);
EXPORT_SYMBOL_GPL(unregister_cu3088_discipline);
