/*
 *  drivers/s390/cio/device.c
 *  bus driver for ccw devices
 *
 *    Copyright (C) 2002 IBM Deutschland Entwicklung GmbH,
 *			 IBM Corporation
 *    Author(s): Arnd Bergmann (arndb@de.ibm.com)
 *		 Cornelia Huck (cornelia.huck@de.ibm.com)
 *		 Martin Schwidefsky (schwidefsky@de.ibm.com)
 */
#include <linux/module.h>
#include <linux/init.h>
#include <linux/spinlock.h>
#include <linux/errno.h>
#include <linux/err.h>
#include <linux/slab.h>
#include <linux/list.h>
#include <linux/device.h>
#include <linux/workqueue.h>

#include <asm/ccwdev.h>
#include <asm/cio.h>
#include <asm/param.h>		/* HZ */

#include "cio.h"
#include "css.h"
#include "device.h"
#include "ioasm.h"

/******************* bus type handling ***********************/

/* The Linux driver model distinguishes between a bus type and
 * the bus itself. Of course we only have one channel
 * subsystem driver and one channel system per machine, but
 * we still use the abstraction. T.R. says it's a good idea. */
static int
ccw_bus_match (struct device * dev, struct device_driver * drv)
{
	struct ccw_device *cdev = to_ccwdev(dev);
	struct ccw_driver *cdrv = to_ccwdrv(drv);
	const struct ccw_device_id *ids = cdrv->ids, *found;

	if (!ids)
		return 0;

	found = ccw_device_id_match(ids, &cdev->id);
	if (!found)
		return 0;

	cdev->id.driver_info = found->driver_info;

	return 1;
}

/* Store modalias string delimited by prefix/suffix string into buffer with
 * specified size. Return length of resulting string (excluding trailing '\0')
 * even if string doesn't fit buffer (snprintf semantics). */
static int snprint_alias(char *buf, size_t size, const char *prefix,
			 struct ccw_device_id *id, const char *suffix)
{
	int len;

	len = snprintf(buf, size, "%sccw:t%04Xm%02X", prefix, id->cu_type,
		       id->cu_model);
	if (len > size)
		return len;
	buf += len;
	size -= len;

	if (id->dev_type != 0)
		len += snprintf(buf, size, "dt%04Xdm%02X%s", id->dev_type,
				id->dev_model, suffix);
	else
		len += snprintf(buf, size, "dtdm%s", suffix);

	return len;
}

/* Set up environment variables for ccw device uevent. Return 0 on success,
 * non-zero otherwise. */
static int ccw_uevent(struct device *dev, char **envp, int num_envp,
		      char *buffer, int buffer_size)
{
	struct ccw_device *cdev = to_ccwdev(dev);
	struct ccw_device_id *id = &(cdev->id);
	int i = 0;
	int len;

	/* CU_TYPE= */
	len = snprintf(buffer, buffer_size, "CU_TYPE=%04X", id->cu_type) + 1;
	if (len > buffer_size || i >= num_envp)
		return -ENOMEM;
	envp[i++] = buffer;
	buffer += len;
	buffer_size -= len;

	/* CU_MODEL= */
	len = snprintf(buffer, buffer_size, "CU_MODEL=%02X", id->cu_model) + 1;
	if (len > buffer_size || i >= num_envp)
		return -ENOMEM;
	envp[i++] = buffer;
	buffer += len;
	buffer_size -= len;

	/* The next two can be zero, that's ok for us */
	/* DEV_TYPE= */
	len = snprintf(buffer, buffer_size, "DEV_TYPE=%04X", id->dev_type) + 1;
	if (len > buffer_size || i >= num_envp)
		return -ENOMEM;
	envp[i++] = buffer;
	buffer += len;
	buffer_size -= len;

	/* DEV_MODEL= */
	len = snprintf(buffer, buffer_size, "DEV_MODEL=%02X",
			(unsigned char) id->dev_model) + 1;
	if (len > buffer_size || i >= num_envp)
		return -ENOMEM;
	envp[i++] = buffer;
	buffer += len;
	buffer_size -= len;

	/* MODALIAS=  */
	len = snprint_alias(buffer, buffer_size, "MODALIAS=", id, "") + 1;
	if (len > buffer_size || i >= num_envp)
		return -ENOMEM;
	envp[i++] = buffer;
	buffer += len;
	buffer_size -= len;

	envp[i] = NULL;

	return 0;
}

struct bus_type ccw_bus_type;

static int io_subchannel_probe (struct subchannel *);
static int io_subchannel_remove (struct subchannel *);
void io_subchannel_irq (struct device *);
static int io_subchannel_notify(struct device *, int);
static void io_subchannel_verify(struct device *);
static void io_subchannel_ioterm(struct device *);
static void io_subchannel_shutdown(struct subchannel *);

struct css_driver io_subchannel_driver = {
	.subchannel_type = SUBCHANNEL_TYPE_IO,
	.drv = {
		.name = "io_subchannel",
		.bus  = &css_bus_type,
	},
	.irq = io_subchannel_irq,
	.notify = io_subchannel_notify,
	.verify = io_subchannel_verify,
	.termination = io_subchannel_ioterm,
	.probe = io_subchannel_probe,
	.remove = io_subchannel_remove,
	.shutdown = io_subchannel_shutdown,
};

struct workqueue_struct *ccw_device_work;
struct workqueue_struct *ccw_device_notify_work;
wait_queue_head_t ccw_device_init_wq;
atomic_t ccw_device_init_count;

static int __init
init_ccw_bus_type (void)
{
	int ret;

	init_waitqueue_head(&ccw_device_init_wq);
	atomic_set(&ccw_device_init_count, 0);

	ccw_device_work = create_singlethread_workqueue("cio");
	if (!ccw_device_work)
		return -ENOMEM; /* FIXME: better errno ? */
	ccw_device_notify_work = create_singlethread_workqueue("cio_notify");
	if (!ccw_device_notify_work) {
		ret = -ENOMEM; /* FIXME: better errno ? */
		goto out_err;
	}
	slow_path_wq = create_singlethread_workqueue("kslowcrw");
	if (!slow_path_wq) {
		ret = -ENOMEM; /* FIXME: better errno ? */
		goto out_err;
	}
	if ((ret = bus_register (&ccw_bus_type)))
		goto out_err;

	if ((ret = driver_register(&io_subchannel_driver.drv)))
		goto out_err;

	wait_event(ccw_device_init_wq,
		   atomic_read(&ccw_device_init_count) == 0);
	flush_workqueue(ccw_device_work);
	return 0;
out_err:
	if (ccw_device_work)
		destroy_workqueue(ccw_device_work);
	if (ccw_device_notify_work)
		destroy_workqueue(ccw_device_notify_work);
	if (slow_path_wq)
		destroy_workqueue(slow_path_wq);
	return ret;
}

static void __exit
cleanup_ccw_bus_type (void)
{
	driver_unregister(&io_subchannel_driver.drv);
	bus_unregister(&ccw_bus_type);
	destroy_workqueue(ccw_device_notify_work);
	destroy_workqueue(ccw_device_work);
}

subsys_initcall(init_ccw_bus_type);
module_exit(cleanup_ccw_bus_type);

/************************ device handling **************************/

/*
 * A ccw_device has some interfaces in sysfs in addition to the
 * standard ones.
 * The following entries are designed to export the information which
 * resided in 2.4 in /proc/subchannels. Subchannel and device number
 * are obvious, so they don't have an entry :)
 * TODO: Split chpids and pimpampom up? Where is "in use" in the tree?
 */
static ssize_t
chpids_show (struct device * dev, struct device_attribute *attr, char * buf)
{
	struct subchannel *sch = to_subchannel(dev);
	struct ssd_info *ssd = &sch->ssd_info;
	ssize_t ret = 0;
	int chp;

	for (chp = 0; chp < 8; chp++)
		ret += sprintf (buf+ret, "%02x ", ssd->chpid[chp]);

	ret += sprintf (buf+ret, "\n");
	return min((ssize_t)PAGE_SIZE, ret);
}

static ssize_t
pimpampom_show (struct device * dev, struct device_attribute *attr, char * buf)
{
	struct subchannel *sch = to_subchannel(dev);
	struct pmcw *pmcw = &sch->schib.pmcw;

	return sprintf (buf, "%02x %02x %02x\n",
			pmcw->pim, pmcw->pam, pmcw->pom);
}

static ssize_t
devtype_show (struct device *dev, struct device_attribute *attr, char *buf)
{
	struct ccw_device *cdev = to_ccwdev(dev);
	struct ccw_device_id *id = &(cdev->id);

	if (id->dev_type != 0)
		return sprintf(buf, "%04x/%02x\n",
				id->dev_type, id->dev_model);
	else
		return sprintf(buf, "n/a\n");
}

static ssize_t
cutype_show (struct device *dev, struct device_attribute *attr, char *buf)
{
	struct ccw_device *cdev = to_ccwdev(dev);
	struct ccw_device_id *id = &(cdev->id);

	return sprintf(buf, "%04x/%02x\n",
		       id->cu_type, id->cu_model);
}

static ssize_t
modalias_show (struct device *dev, struct device_attribute *attr, char *buf)
{
	struct ccw_device *cdev = to_ccwdev(dev);
	struct ccw_device_id *id = &(cdev->id);
	int len;

	len = snprint_alias(buf, PAGE_SIZE, "", id, "\n") + 1;

	return len > PAGE_SIZE ? PAGE_SIZE : len;
}

static ssize_t
online_show (struct device *dev, struct device_attribute *attr, char *buf)
{
	struct ccw_device *cdev = to_ccwdev(dev);

	return sprintf(buf, cdev->online ? "1\n" : "0\n");
}

static void
ccw_device_remove_disconnected(struct ccw_device *cdev)
{
	struct subchannel *sch;
	/*
	 * Forced offline in disconnected state means
	 * 'throw away device'.
	 */
	sch = to_subchannel(cdev->dev.parent);
	css_sch_device_unregister(sch);
	/* Reset intparm to zeroes. */
	sch->schib.pmcw.intparm = 0;
	cio_modify(sch);
	put_device(&sch->dev);
}

int
ccw_device_set_offline(struct ccw_device *cdev)
{
	int ret;

	if (!cdev)
		return -ENODEV;
	if (!cdev->online || !cdev->drv)
		return -EINVAL;

	if (cdev->drv->set_offline) {
		ret = cdev->drv->set_offline(cdev);
		if (ret != 0)
			return ret;
	}
	cdev->online = 0;
	spin_lock_irq(cdev->ccwlock);
	ret = ccw_device_offline(cdev);
	if (ret == -ENODEV) {
		if (cdev->private->state != DEV_STATE_NOT_OPER) {
			cdev->private->state = DEV_STATE_OFFLINE;
			dev_fsm_event(cdev, DEV_EVENT_NOTOPER);
		}
		spin_unlock_irq(cdev->ccwlock);
		return ret;
	}
	spin_unlock_irq(cdev->ccwlock);
	if (ret == 0)
		wait_event(cdev->private->wait_q, dev_fsm_final_state(cdev));
	else {
		pr_debug("ccw_device_offline returned %d, device %s\n",
			 ret, cdev->dev.bus_id);
		cdev->online = 1;
	}
 	return ret;
}

int
ccw_device_set_online(struct ccw_device *cdev)
{
	int ret;

	if (!cdev)
		return -ENODEV;
	if (cdev->online || !cdev->drv)
		return -EINVAL;

	spin_lock_irq(cdev->ccwlock);
	ret = ccw_device_online(cdev);
	spin_unlock_irq(cdev->ccwlock);
	if (ret == 0)
		wait_event(cdev->private->wait_q, dev_fsm_final_state(cdev));
	else {
		pr_debug("ccw_device_online returned %d, device %s\n",
			 ret, cdev->dev.bus_id);
		return ret;
	}
	if (cdev->private->state != DEV_STATE_ONLINE)
		return -ENODEV;
	if (!cdev->drv->set_online || cdev->drv->set_online(cdev) == 0) {
		cdev->online = 1;
		return 0;
	}
	spin_lock_irq(cdev->ccwlock);
	ret = ccw_device_offline(cdev);
	spin_unlock_irq(cdev->ccwlock);
	if (ret == 0)
		wait_event(cdev->private->wait_q, dev_fsm_final_state(cdev));
	else 
		pr_debug("ccw_device_offline returned %d, device %s\n",
			 ret, cdev->dev.bus_id);
	return (ret == 0) ? -ENODEV : ret;
}

static ssize_t
online_store (struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
	struct ccw_device *cdev = to_ccwdev(dev);
	int i, force, ret;
	char *tmp;

	if (atomic_cmpxchg(&cdev->private->onoff, 0, 1) != 0)
		return -EAGAIN;

	if (cdev->drv && !try_module_get(cdev->drv->owner)) {
		atomic_set(&cdev->private->onoff, 0);
		return -EINVAL;
	}
	if (!strncmp(buf, "force\n", count)) {
		force = 1;
		i = 1;
	} else {
		force = 0;
		i = simple_strtoul(buf, &tmp, 16);
	}
	if (i == 1) {
		/* Do device recognition, if needed. */
		if (cdev->id.cu_type == 0) {
			ret = ccw_device_recognition(cdev);
			if (ret) {
				printk(KERN_WARNING"Couldn't start recognition "
				       "for device %s (ret=%d)\n",
				       cdev->dev.bus_id, ret);
				goto out;
			}
			wait_event(cdev->private->wait_q,
				   cdev->private->flags.recog_done);
		}
		if (cdev->drv && cdev->drv->set_online)
			ccw_device_set_online(cdev);
	} else if (i == 0) {
		if (cdev->private->state == DEV_STATE_DISCONNECTED)
			ccw_device_remove_disconnected(cdev);
		else if (cdev->drv && cdev->drv->set_offline)
			ccw_device_set_offline(cdev);
	}
	if (force && cdev->private->state == DEV_STATE_BOXED) {
		ret = ccw_device_stlck(cdev);
		if (ret) {
			printk(KERN_WARNING"ccw_device_stlck for device %s "
			       "returned %d!\n", cdev->dev.bus_id, ret);
			goto out;
		}
		/* Do device recognition, if needed. */
		if (cdev->id.cu_type == 0) {
			cdev->private->state = DEV_STATE_NOT_OPER;
			ret = ccw_device_recognition(cdev);
			if (ret) {
				printk(KERN_WARNING"Couldn't start recognition "
				       "for device %s (ret=%d)\n",
				       cdev->dev.bus_id, ret);
				goto out;
			}
			wait_event(cdev->private->wait_q,
				   cdev->private->flags.recog_done);
		}
		if (cdev->drv && cdev->drv->set_online)
			ccw_device_set_online(cdev);
	}
	out:
	if (cdev->drv)
		module_put(cdev->drv->owner);
	atomic_set(&cdev->private->onoff, 0);
	return count;
}

static ssize_t
available_show (struct device *dev, struct device_attribute *attr, char *buf)
{
	struct ccw_device *cdev = to_ccwdev(dev);
	struct subchannel *sch;

	switch (cdev->private->state) {
	case DEV_STATE_BOXED:
		return sprintf(buf, "boxed\n");
	case DEV_STATE_DISCONNECTED:
	case DEV_STATE_DISCONNECTED_SENSE_ID:
	case DEV_STATE_NOT_OPER:
		sch = to_subchannel(dev->parent);
		if (!sch->lpm)
			return sprintf(buf, "no path\n");
		else
			return sprintf(buf, "no device\n");
	default:
		/* All other states considered fine. */
		return sprintf(buf, "good\n");
	}
}

static DEVICE_ATTR(chpids, 0444, chpids_show, NULL);
static DEVICE_ATTR(pimpampom, 0444, pimpampom_show, NULL);
static DEVICE_ATTR(devtype, 0444, devtype_show, NULL);
static DEVICE_ATTR(cutype, 0444, cutype_show, NULL);
static DEVICE_ATTR(modalias, 0444, modalias_show, NULL);
static DEVICE_ATTR(online, 0644, online_show, online_store);
extern struct device_attribute dev_attr_cmb_enable;
static DEVICE_ATTR(availability, 0444, available_show, NULL);

static struct attribute * subch_attrs[] = {
	&dev_attr_chpids.attr,
	&dev_attr_pimpampom.attr,
	NULL,
};

static struct attribute_group subch_attr_group = {
	.attrs = subch_attrs,
};

static inline int
subchannel_add_files (struct device *dev)
{
	return sysfs_create_group(&dev->kobj, &subch_attr_group);
}

static struct attribute * ccwdev_attrs[] = {
	&dev_attr_devtype.attr,
	&dev_attr_cutype.attr,
	&dev_attr_modalias.attr,
	&dev_attr_online.attr,
	&dev_attr_cmb_enable.attr,
	&dev_attr_availability.attr,
	NULL,
};

static struct attribute_group ccwdev_attr_group = {
	.attrs = ccwdev_attrs,
};

static inline int
device_add_files (struct device *dev)
{
	return sysfs_create_group(&dev->kobj, &ccwdev_attr_group);
}

static inline void
device_remove_files(struct device *dev)
{
	sysfs_remove_group(&dev->kobj, &ccwdev_attr_group);
}

/* this is a simple abstraction for device_register that sets the
 * correct bus type and adds the bus specific files */
int
ccw_device_register(struct ccw_device *cdev)
{
	struct device *dev = &cdev->dev;
	int ret;

	dev->bus = &ccw_bus_type;

	if ((ret = device_add(dev)))
		return ret;

	set_bit(1, &cdev->private->registered);
	if ((ret = device_add_files(dev))) {
		if (test_and_clear_bit(1, &cdev->private->registered))
			device_del(dev);
	}
	return ret;
}

struct match_data {
	struct ccw_dev_id dev_id;
	struct ccw_device * sibling;
};

static int
match_devno(struct device * dev, void * data)
{
	struct match_data * d = data;
	struct ccw_device * cdev;

	cdev = to_ccwdev(dev);
	if ((cdev->private->state == DEV_STATE_DISCONNECTED) &&
	    ccw_dev_id_is_equal(&cdev->private->dev_id, &d->dev_id) &&
	    (cdev != d->sibling)) {
		cdev->private->state = DEV_STATE_NOT_OPER;
		return 1;
	}
	return 0;
}

static struct ccw_device * get_disc_ccwdev_by_dev_id(struct ccw_dev_id *dev_id,
						     struct ccw_device *sibling)
{
	struct device *dev;
	struct match_data data;

	data.dev_id = *dev_id;
	data.sibling = sibling;
	dev = bus_find_device(&ccw_bus_type, NULL, &data, match_devno);

	return dev ? to_ccwdev(dev) : NULL;
}

static void
ccw_device_add_changed(void *data)
{

	struct ccw_device *cdev;

	cdev = data;
	if (device_add(&cdev->dev)) {
		put_device(&cdev->dev);
		return;
	}
	set_bit(1, &cdev->private->registered);
	if (device_add_files(&cdev->dev)) {
		if (test_and_clear_bit(1, &cdev->private->registered))
			device_unregister(&cdev->dev);
	}
}

extern int css_get_ssd_info(struct subchannel *sch);

void
ccw_device_do_unreg_rereg(void *data)
{
	struct ccw_device *cdev;
	struct subchannel *sch;
	int need_rename;

	cdev = data;
	sch = to_subchannel(cdev->dev.parent);
	if (cdev->private->dev_id.devno != sch->schib.pmcw.dev) {
		/*
		 * The device number has changed. This is usually only when
		 * a device has been detached under VM and then re-appeared
		 * on another subchannel because of a different attachment
		 * order than before. Ideally, we should should just switch
		 * subchannels, but unfortunately, this is not possible with
		 * the current implementation.
		 * Instead, we search for the old subchannel for this device
		 * number and deregister so there are no collisions with the
		 * newly registered ccw_device.
		 * FIXME: Find another solution so the block layer doesn't
		 *        get possibly sick...
		 */
		struct ccw_device *other_cdev;
		struct ccw_dev_id dev_id;

		need_rename = 1;
		dev_id.devno = sch->schib.pmcw.dev;
		dev_id.ssid = sch->schid.ssid;
		other_cdev = get_disc_ccwdev_by_dev_id(&dev_id, cdev);
		if (other_cdev) {
			struct subchannel *other_sch;

			other_sch = to_subchannel(other_cdev->dev.parent);
			if (get_device(&other_sch->dev)) {
				stsch(other_sch->schid, &other_sch->schib);
				if (other_sch->schib.pmcw.dnv) {
					other_sch->schib.pmcw.intparm = 0;
					cio_modify(other_sch);
				}
				css_sch_device_unregister(other_sch);
			}
		}
		/* Update ssd info here. */
		css_get_ssd_info(sch);
		cdev->private->dev_id.devno = sch->schib.pmcw.dev;
	} else
		need_rename = 0;
	device_remove_files(&cdev->dev);
	if (test_and_clear_bit(1, &cdev->private->registered))
		device_del(&cdev->dev);
	if (need_rename)
		snprintf (cdev->dev.bus_id, BUS_ID_SIZE, "0.%x.%04x",
			  sch->schid.ssid, sch->schib.pmcw.dev);
	PREPARE_WORK(&cdev->private->kick_work,
		     ccw_device_add_changed, cdev);
	queue_work(ccw_device_work, &cdev->private->kick_work);
}

static void
ccw_device_release(struct device *dev)
{
	struct ccw_device *cdev;

	cdev = to_ccwdev(dev);
	kfree(cdev->private);
	kfree(cdev);
}

/*
 * Register recognized device.
 */
static void
io_subchannel_register(void *data)
{
	struct ccw_device *cdev;
	struct subchannel *sch;
	int ret;
	unsigned long flags;

	cdev = data;
	sch = to_subchannel(cdev->dev.parent);

	if (klist_node_attached(&cdev->dev.knode_parent)) {
		bus_rescan_devices(&ccw_bus_type);
		goto out;
	}
	/* make it known to the system */
	ret = ccw_device_register(cdev);
	if (ret) {
		printk (KERN_WARNING "%s: could not register %s\n",
			__func__, cdev->dev.bus_id);
		put_device(&cdev->dev);
		spin_lock_irqsave(&sch->lock, flags);
		sch->dev.driver_data = NULL;
		spin_unlock_irqrestore(&sch->lock, flags);
		kfree (cdev->private);
		kfree (cdev);
		put_device(&sch->dev);
		if (atomic_dec_and_test(&ccw_device_init_count))
			wake_up(&ccw_device_init_wq);
		return;
	}

	ret = subchannel_add_files(cdev->dev.parent);
	if (ret)
		printk(KERN_WARNING "%s: could not add attributes to %s\n",
		       __func__, sch->dev.bus_id);
	put_device(&cdev->dev);
out:
	cdev->private->flags.recog_done = 1;
	put_device(&sch->dev);
	wake_up(&cdev->private->wait_q);
	if (atomic_dec_and_test(&ccw_device_init_count))
		wake_up(&ccw_device_init_wq);
}

void
ccw_device_call_sch_unregister(void *data)
{
	struct ccw_device *cdev = data;
	struct subchannel *sch;

	sch = to_subchannel(cdev->dev.parent);
	css_sch_device_unregister(sch);
	/* Reset intparm to zeroes. */
	sch->schib.pmcw.intparm = 0;
	cio_modify(sch);
	put_device(&cdev->dev);
	put_device(&sch->dev);
}

/*
 * subchannel recognition done. Called from the state machine.
 */
void
io_subchannel_recog_done(struct ccw_device *cdev)
{
	struct subchannel *sch;

	if (css_init_done == 0) {
		cdev->private->flags.recog_done = 1;
		return;
	}
	switch (cdev->private->state) {
	case DEV_STATE_NOT_OPER:
		cdev->private->flags.recog_done = 1;
		/* Remove device found not operational. */
		if (!get_device(&cdev->dev))
			break;
		sch = to_subchannel(cdev->dev.parent);
		PREPARE_WORK(&cdev->private->kick_work,
			     ccw_device_call_sch_unregister, cdev);
		queue_work(slow_path_wq, &cdev->private->kick_work);
		if (atomic_dec_and_test(&ccw_device_init_count))
			wake_up(&ccw_device_init_wq);
		break;
	case DEV_STATE_BOXED:
		/* Device did not respond in time. */
	case DEV_STATE_OFFLINE:
		/* 
		 * We can't register the device in interrupt context so
		 * we schedule a work item.
		 */
		if (!get_device(&cdev->dev))
			break;
		PREPARE_WORK(&cdev->private->kick_work,
			     io_subchannel_register, cdev);
		queue_work(slow_path_wq, &cdev->private->kick_work);
		break;
	}
}

static int
io_subchannel_recog(struct ccw_device *cdev, struct subchannel *sch)
{
	int rc;
	struct ccw_device_private *priv;

	sch->dev.driver_data = cdev;
	sch->driver = &io_subchannel_driver;
	cdev->ccwlock = &sch->lock;

	/* Init private data. */
	priv = cdev->private;
	priv->dev_id.devno = sch->schib.pmcw.dev;
	priv->dev_id.ssid = sch->schid.ssid;
	priv->schid = sch->schid;
	priv->state = DEV_STATE_NOT_OPER;
	INIT_LIST_HEAD(&priv->cmb_list);
	init_waitqueue_head(&priv->wait_q);
	init_timer(&priv->timer);

	/* Set an initial name for the device. */
	snprintf (cdev->dev.bus_id, BUS_ID_SIZE, "0.%x.%04x",
		  sch->schid.ssid, sch->schib.pmcw.dev);

	/* Increase counter of devices currently in recognition. */
	atomic_inc(&ccw_device_init_count);

	/* Start async. device sensing. */
	spin_lock_irq(&sch->lock);
	rc = ccw_device_recognition(cdev);
	spin_unlock_irq(&sch->lock);
	if (rc) {
		if (atomic_dec_and_test(&ccw_device_init_count))
			wake_up(&ccw_device_init_wq);
	}
	return rc;
}

static int
io_subchannel_probe (struct subchannel *sch)
{
	struct ccw_device *cdev;
	int rc;
	unsigned long flags;

	if (sch->dev.driver_data) {
		/*
		 * This subchannel already has an associated ccw_device.
		 * Register it and exit. This happens for all early
		 * device, e.g. the console.
		 */
		cdev = sch->dev.driver_data;
		device_initialize(&cdev->dev);
		ccw_device_register(cdev);
		subchannel_add_files(&sch->dev);
		/*
		 * Check if the device is already online. If it is
		 * the reference count needs to be corrected
		 * (see ccw_device_online and css_init_done for the
		 * ugly details).
		 */
		if (cdev->private->state != DEV_STATE_NOT_OPER &&
		    cdev->private->state != DEV_STATE_OFFLINE &&
		    cdev->private->state != DEV_STATE_BOXED)
			get_device(&cdev->dev);
		return 0;
	}
	cdev = kzalloc (sizeof(*cdev), GFP_KERNEL);
	if (!cdev)
		return -ENOMEM;
	cdev->private = kzalloc(sizeof(struct ccw_device_private),
				GFP_KERNEL | GFP_DMA);
	if (!cdev->private) {
		kfree(cdev);
		return -ENOMEM;
	}
	atomic_set(&cdev->private->onoff, 0);
	cdev->dev.parent = &sch->dev;
	cdev->dev.release = ccw_device_release;
	INIT_LIST_HEAD(&cdev->private->kick_work.entry);
	/* Do first half of device_register. */
	device_initialize(&cdev->dev);

	if (!get_device(&sch->dev)) {
		if (cdev->dev.release)
			cdev->dev.release(&cdev->dev);
		return -ENODEV;
	}

	rc = io_subchannel_recog(cdev, sch);
	if (rc) {
		spin_lock_irqsave(&sch->lock, flags);
		sch->dev.driver_data = NULL;
		spin_unlock_irqrestore(&sch->lock, flags);
		if (cdev->dev.release)
			cdev->dev.release(&cdev->dev);
	}

	return rc;
}

static void
ccw_device_unregister(void *data)
{
	struct ccw_device *cdev;

	cdev = (struct ccw_device *)data;
	if (test_and_clear_bit(1, &cdev->private->registered))
		device_unregister(&cdev->dev);
	put_device(&cdev->dev);
}

static int
io_subchannel_remove (struct subchannel *sch)
{
	struct ccw_device *cdev;
	unsigned long flags;

	if (!sch->dev.driver_data)
		return 0;
	cdev = sch->dev.driver_data;
	/* Set ccw device to not operational and drop reference. */
	spin_lock_irqsave(cdev->ccwlock, flags);
	sch->dev.driver_data = NULL;
	cdev->private->state = DEV_STATE_NOT_OPER;
	spin_unlock_irqrestore(cdev->ccwlock, flags);
	/*
	 * Put unregistration on workqueue to avoid livelocks on the css bus
	 * semaphore.
	 */
	if (get_device(&cdev->dev)) {
		PREPARE_WORK(&cdev->private->kick_work,
			     ccw_device_unregister, cdev);
		queue_work(ccw_device_work, &cdev->private->kick_work);
	}
	return 0;
}

static int
io_subchannel_notify(struct device *dev, int event)
{
	struct ccw_device *cdev;

	cdev = dev->driver_data;
	if (!cdev)
		return 0;
	if (!cdev->drv)
		return 0;
	if (!cdev->online)
		return 0;
	return cdev->drv->notify ? cdev->drv->notify(cdev, event) : 0;
}

static void
io_subchannel_verify(struct device *dev)
{
	struct ccw_device *cdev;

	cdev = dev->driver_data;
	if (cdev)
		dev_fsm_event(cdev, DEV_EVENT_VERIFY);
}

static void
io_subchannel_ioterm(struct device *dev)
{
	struct ccw_device *cdev;

	cdev = dev->driver_data;
	if (!cdev)
		return;
	cdev->private->state = DEV_STATE_CLEAR_VERIFY;
	if (cdev->handler)
		cdev->handler(cdev, cdev->private->intparm,
			      ERR_PTR(-EIO));
}

static void
io_subchannel_shutdown(struct subchannel *sch)
{
	struct ccw_device *cdev;
	int ret;

	cdev = sch->dev.driver_data;

	if (cio_is_console(sch->schid))
		return;
	if (!sch->schib.pmcw.ena)
		/* Nothing to do. */
		return;
	ret = cio_disable_subchannel(sch);
	if (ret != -EBUSY)
		/* Subchannel is disabled, we're done. */
		return;
	cdev->private->state = DEV_STATE_QUIESCE;
	if (cdev->handler)
		cdev->handler(cdev, cdev->private->intparm,
			      ERR_PTR(-EIO));
	ret = ccw_device_cancel_halt_clear(cdev);
	if (ret == -EBUSY) {
		ccw_device_set_timeout(cdev, HZ/10);
		wait_event(cdev->private->wait_q, dev_fsm_final_state(cdev));
	}
	cio_disable_subchannel(sch);
}

#ifdef CONFIG_CCW_CONSOLE
static struct ccw_device console_cdev;
static struct ccw_device_private console_private;
static int console_cdev_in_use;

static int
ccw_device_console_enable (struct ccw_device *cdev, struct subchannel *sch)
{
	int rc;

	/* Initialize the ccw_device structure. */
	cdev->dev.parent= &sch->dev;
	rc = io_subchannel_recog(cdev, sch);
	if (rc)
		return rc;

	/* Now wait for the async. recognition to come to an end. */
	spin_lock_irq(cdev->ccwlock);
	while (!dev_fsm_final_state(cdev))
		wait_cons_dev();
	rc = -EIO;
	if (cdev->private->state != DEV_STATE_OFFLINE)
		goto out_unlock;
	ccw_device_online(cdev);
	while (!dev_fsm_final_state(cdev))
		wait_cons_dev();
	if (cdev->private->state != DEV_STATE_ONLINE)
		goto out_unlock;
	rc = 0;
out_unlock:
	spin_unlock_irq(cdev->ccwlock);
	return 0;
}

struct ccw_device *
ccw_device_probe_console(void)
{
	struct subchannel *sch;
	int ret;

	if (xchg(&console_cdev_in_use, 1) != 0)
		return ERR_PTR(-EBUSY);
	sch = cio_probe_console();
	if (IS_ERR(sch)) {
		console_cdev_in_use = 0;
		return (void *) sch;
	}
	memset(&console_cdev, 0, sizeof(struct ccw_device));
	memset(&console_private, 0, sizeof(struct ccw_device_private));
	console_cdev.private = &console_private;
	ret = ccw_device_console_enable(&console_cdev, sch);
	if (ret) {
		cio_release_console();
		console_cdev_in_use = 0;
		return ERR_PTR(ret);
	}
	console_cdev.online = 1;
	return &console_cdev;
}
#endif

/*
 * get ccw_device matching the busid, but only if owned by cdrv
 */
static int
__ccwdev_check_busid(struct device *dev, void *id)
{
	char *bus_id;

	bus_id = id;

	return (strncmp(bus_id, dev->bus_id, BUS_ID_SIZE) == 0);
}


struct ccw_device *
get_ccwdev_by_busid(struct ccw_driver *cdrv, const char *bus_id)
{
	struct device *dev;
	struct device_driver *drv;

	drv = get_driver(&cdrv->driver);
	if (!drv)
		return NULL;

	dev = driver_find_device(drv, NULL, (void *)bus_id,
				 __ccwdev_check_busid);
	put_driver(drv);

	return dev ? to_ccwdev(dev) : NULL;
}

/************************** device driver handling ************************/

/* This is the implementation of the ccw_driver class. The probe, remove
 * and release methods are initially very similar to the device_driver
 * implementations, with the difference that they have ccw_device
 * arguments.
 *
 * A ccw driver also contains the information that is needed for
 * device matching.
 */
static int
ccw_device_probe (struct device *dev)
{
	struct ccw_device *cdev = to_ccwdev(dev);
	struct ccw_driver *cdrv = to_ccwdrv(dev->driver);
	int ret;

	cdev->drv = cdrv; /* to let the driver call _set_online */

	ret = cdrv->probe ? cdrv->probe(cdev) : -ENODEV;

	if (ret) {
		cdev->drv = NULL;
		return ret;
	}

	return 0;
}

static int
ccw_device_remove (struct device *dev)
{
	struct ccw_device *cdev = to_ccwdev(dev);
	struct ccw_driver *cdrv = cdev->drv;
	int ret;

	pr_debug("removing device %s\n", cdev->dev.bus_id);
	if (cdrv->remove)
		cdrv->remove(cdev);
	if (cdev->online) {
		cdev->online = 0;
		spin_lock_irq(cdev->ccwlock);
		ret = ccw_device_offline(cdev);
		spin_unlock_irq(cdev->ccwlock);
		if (ret == 0)
			wait_event(cdev->private->wait_q,
				   dev_fsm_final_state(cdev));
		else
			//FIXME: we can't fail!
			pr_debug("ccw_device_offline returned %d, device %s\n",
				 ret, cdev->dev.bus_id);
	}
	ccw_device_set_timeout(cdev, 0);
	cdev->drv = NULL;
	return 0;
}

struct bus_type ccw_bus_type = {
	.name   = "ccw",
	.match  = ccw_bus_match,
	.uevent = ccw_uevent,
	.probe  = ccw_device_probe,
	.remove = ccw_device_remove,
};

int
ccw_driver_register (struct ccw_driver *cdriver)
{
	struct device_driver *drv = &cdriver->driver;

	drv->bus = &ccw_bus_type;
	drv->name = cdriver->name;

	return driver_register(drv);
}

void
ccw_driver_unregister (struct ccw_driver *cdriver)
{
	driver_unregister(&cdriver->driver);
}

/* Helper func for qdio. */
struct subchannel_id
ccw_device_get_subchannel_id(struct ccw_device *cdev)
{
	struct subchannel *sch;

	sch = to_subchannel(cdev->dev.parent);
	return sch->schid;
}

MODULE_LICENSE("GPL");
EXPORT_SYMBOL(ccw_device_set_online);
EXPORT_SYMBOL(ccw_device_set_offline);
EXPORT_SYMBOL(ccw_driver_register);
EXPORT_SYMBOL(ccw_driver_unregister);
EXPORT_SYMBOL(get_ccwdev_by_busid);
EXPORT_SYMBOL(ccw_bus_type);
EXPORT_SYMBOL(ccw_device_work);
EXPORT_SYMBOL(ccw_device_notify_work);
EXPORT_SYMBOL_GPL(ccw_device_get_subchannel_id);
