// SPDX-License-Identifier: GPL-2.0
/*
 *  bus driver for ccwgroup
 *
 *  Copyright IBM Corp. 2002, 2012
 *
 *  Author(s): Arnd Bergmann (arndb@de.ibm.com)
 *	       Cornelia Huck (cornelia.huck@de.ibm.com)
 */
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/list.h>
#include <linux/device.h>
#include <linux/init.h>
#include <linux/ctype.h>
#include <linux/dcache.h>

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

#include "device.h"

#define CCW_BUS_ID_SIZE		10

/* In Linux 2.4, we had a channel device layer called "chandev"
 * that did all sorts of obscure stuff for networking devices.
 * This is another driver that serves as a replacement for just
 * one of its functions, namely the translation of single subchannels
 * to devices that use multiple subchannels.
 */

static struct bus_type ccwgroup_bus_type;

static void __ccwgroup_remove_symlinks(struct ccwgroup_device *gdev)
{
	int i;
	char str[16];

	for (i = 0; i < gdev->count; i++) {
		sprintf(str, "cdev%d", i);
		sysfs_remove_link(&gdev->dev.kobj, str);
		sysfs_remove_link(&gdev->cdev[i]->dev.kobj, "group_device");
	}
}

/**
 * ccwgroup_set_online() - enable a ccwgroup device
 * @gdev: target ccwgroup device
 *
 * This function attempts to put the ccwgroup device into the online state.
 * Returns:
 *  %0 on success and a negative error value on failure.
 */
int ccwgroup_set_online(struct ccwgroup_device *gdev)
{
	struct ccwgroup_driver *gdrv = to_ccwgroupdrv(gdev->dev.driver);
	int ret = -EINVAL;

	if (atomic_cmpxchg(&gdev->onoff, 0, 1) != 0)
		return -EAGAIN;
	if (gdev->state == CCWGROUP_ONLINE)
		goto out;
	if (gdrv->set_online)
		ret = gdrv->set_online(gdev);
	if (ret)
		goto out;

	gdev->state = CCWGROUP_ONLINE;
out:
	atomic_set(&gdev->onoff, 0);
	return ret;
}
EXPORT_SYMBOL(ccwgroup_set_online);

/**
 * ccwgroup_set_offline() - disable a ccwgroup device
 * @gdev: target ccwgroup device
 *
 * This function attempts to put the ccwgroup device into the offline state.
 * Returns:
 *  %0 on success and a negative error value on failure.
 */
int ccwgroup_set_offline(struct ccwgroup_device *gdev)
{
	struct ccwgroup_driver *gdrv = to_ccwgroupdrv(gdev->dev.driver);
	int ret = -EINVAL;

	if (atomic_cmpxchg(&gdev->onoff, 0, 1) != 0)
		return -EAGAIN;
	if (gdev->state == CCWGROUP_OFFLINE)
		goto out;
	if (gdrv->set_offline)
		ret = gdrv->set_offline(gdev);
	if (ret)
		goto out;

	gdev->state = CCWGROUP_OFFLINE;
out:
	atomic_set(&gdev->onoff, 0);
	return ret;
}
EXPORT_SYMBOL(ccwgroup_set_offline);

static ssize_t ccwgroup_online_store(struct device *dev,
				     struct device_attribute *attr,
				     const char *buf, size_t count)
{
	struct ccwgroup_device *gdev = to_ccwgroupdev(dev);
	unsigned long value;
	int ret;

	device_lock(dev);
	if (!dev->driver) {
		ret = -EINVAL;
		goto out;
	}

	ret = kstrtoul(buf, 0, &value);
	if (ret)
		goto out;

	if (value == 1)
		ret = ccwgroup_set_online(gdev);
	else if (value == 0)
		ret = ccwgroup_set_offline(gdev);
	else
		ret = -EINVAL;
out:
	device_unlock(dev);
	return (ret == 0) ? count : ret;
}

static ssize_t ccwgroup_online_show(struct device *dev,
				    struct device_attribute *attr,
				    char *buf)
{
	struct ccwgroup_device *gdev = to_ccwgroupdev(dev);
	int online;

	online = (gdev->state == CCWGROUP_ONLINE) ? 1 : 0;

	return scnprintf(buf, PAGE_SIZE, "%d\n", online);
}

/*
 * Provide an 'ungroup' attribute so the user can remove group devices no
 * longer needed or accidentially created. Saves memory :)
 */
static void ccwgroup_ungroup(struct ccwgroup_device *gdev)
{
	mutex_lock(&gdev->reg_mutex);
	if (device_is_registered(&gdev->dev)) {
		__ccwgroup_remove_symlinks(gdev);
		device_unregister(&gdev->dev);
	}
	mutex_unlock(&gdev->reg_mutex);
}

static ssize_t ccwgroup_ungroup_store(struct device *dev,
				      struct device_attribute *attr,
				      const char *buf, size_t count)
{
	struct ccwgroup_device *gdev = to_ccwgroupdev(dev);
	int rc = 0;

	/* Prevent concurrent online/offline processing and ungrouping. */
	if (atomic_cmpxchg(&gdev->onoff, 0, 1) != 0)
		return -EAGAIN;
	if (gdev->state != CCWGROUP_OFFLINE) {
		rc = -EINVAL;
		goto out;
	}

	if (device_remove_file_self(dev, attr))
		ccwgroup_ungroup(gdev);
	else
		rc = -ENODEV;
out:
	if (rc) {
		/* Release onoff "lock" when ungrouping failed. */
		atomic_set(&gdev->onoff, 0);
		return rc;
	}
	return count;
}
static DEVICE_ATTR(ungroup, 0200, NULL, ccwgroup_ungroup_store);
static DEVICE_ATTR(online, 0644, ccwgroup_online_show, ccwgroup_online_store);

static struct attribute *ccwgroup_dev_attrs[] = {
	&dev_attr_online.attr,
	&dev_attr_ungroup.attr,
	NULL,
};
ATTRIBUTE_GROUPS(ccwgroup_dev);

static void ccwgroup_ungroup_workfn(struct work_struct *work)
{
	struct ccwgroup_device *gdev =
		container_of(work, struct ccwgroup_device, ungroup_work);

	ccwgroup_ungroup(gdev);
	put_device(&gdev->dev);
}

static void ccwgroup_release(struct device *dev)
{
	struct ccwgroup_device *gdev = to_ccwgroupdev(dev);
	unsigned int i;

	for (i = 0; i < gdev->count; i++) {
		struct ccw_device *cdev = gdev->cdev[i];
		unsigned long flags;

		if (cdev) {
			spin_lock_irqsave(cdev->ccwlock, flags);
			if (dev_get_drvdata(&cdev->dev) == gdev)
				dev_set_drvdata(&cdev->dev, NULL);
			spin_unlock_irqrestore(cdev->ccwlock, flags);
			put_device(&cdev->dev);
		}
	}

	kfree(gdev);
}

static int __ccwgroup_create_symlinks(struct ccwgroup_device *gdev)
{
	char str[16];
	int i, rc;

	for (i = 0; i < gdev->count; i++) {
		rc = sysfs_create_link(&gdev->cdev[i]->dev.kobj,
				       &gdev->dev.kobj, "group_device");
		if (rc) {
			for (--i; i >= 0; i--)
				sysfs_remove_link(&gdev->cdev[i]->dev.kobj,
						  "group_device");
			return rc;
		}
	}
	for (i = 0; i < gdev->count; i++) {
		sprintf(str, "cdev%d", i);
		rc = sysfs_create_link(&gdev->dev.kobj,
				       &gdev->cdev[i]->dev.kobj, str);
		if (rc) {
			for (--i; i >= 0; i--) {
				sprintf(str, "cdev%d", i);
				sysfs_remove_link(&gdev->dev.kobj, str);
			}
			for (i = 0; i < gdev->count; i++)
				sysfs_remove_link(&gdev->cdev[i]->dev.kobj,
						  "group_device");
			return rc;
		}
	}
	return 0;
}

static int __get_next_id(const char **buf, struct ccw_dev_id *id)
{
	unsigned int cssid, ssid, devno;
	int ret = 0, len;
	char *start, *end;

	start = (char *)*buf;
	end = strchr(start, ',');
	if (!end) {
		/* Last entry. Strip trailing newline, if applicable. */
		end = strchr(start, '\n');
		if (end)
			*end = '\0';
		len = strlen(start) + 1;
	} else {
		len = end - start + 1;
		end++;
	}
	if (len <= CCW_BUS_ID_SIZE) {
		if (sscanf(start, "%2x.%1x.%04x", &cssid, &ssid, &devno) != 3)
			ret = -EINVAL;
	} else
		ret = -EINVAL;

	if (!ret) {
		id->ssid = ssid;
		id->devno = devno;
	}
	*buf = end;
	return ret;
}

/**
 * ccwgroup_create_dev() - create and register a ccw group device
 * @parent: parent device for the new device
 * @gdrv: driver for the new group device
 * @num_devices: number of slave devices
 * @buf: buffer containing comma separated bus ids of slave devices
 *
 * Create and register a new ccw group device as a child of @parent. Slave
 * devices are obtained from the list of bus ids given in @buf.
 * Returns:
 *  %0 on success and an error code on failure.
 * Context:
 *  non-atomic
 */
int ccwgroup_create_dev(struct device *parent, struct ccwgroup_driver *gdrv,
			int num_devices, const char *buf)
{
	struct ccwgroup_device *gdev;
	struct ccw_dev_id dev_id;
	int rc, i;

	if (num_devices < 1)
		return -EINVAL;

	gdev = kzalloc(struct_size(gdev, cdev, num_devices), GFP_KERNEL);
	if (!gdev)
		return -ENOMEM;

	atomic_set(&gdev->onoff, 0);
	mutex_init(&gdev->reg_mutex);
	mutex_lock(&gdev->reg_mutex);
	INIT_WORK(&gdev->ungroup_work, ccwgroup_ungroup_workfn);
	gdev->count = num_devices;
	gdev->dev.bus = &ccwgroup_bus_type;
	gdev->dev.parent = parent;
	gdev->dev.release = ccwgroup_release;
	device_initialize(&gdev->dev);

	for (i = 0; i < num_devices && buf; i++) {
		rc = __get_next_id(&buf, &dev_id);
		if (rc != 0)
			goto error;
		gdev->cdev[i] = get_ccwdev_by_dev_id(&dev_id);
		/*
		 * All devices have to be of the same type in
		 * order to be grouped.
		 */
		if (!gdev->cdev[i] || !gdev->cdev[i]->drv ||
		    gdev->cdev[i]->drv != gdev->cdev[0]->drv ||
		    gdev->cdev[i]->id.driver_info !=
		    gdev->cdev[0]->id.driver_info) {
			rc = -EINVAL;
			goto error;
		}
		/* Don't allow a device to belong to more than one group. */
		spin_lock_irq(gdev->cdev[i]->ccwlock);
		if (dev_get_drvdata(&gdev->cdev[i]->dev)) {
			spin_unlock_irq(gdev->cdev[i]->ccwlock);
			rc = -EINVAL;
			goto error;
		}
		dev_set_drvdata(&gdev->cdev[i]->dev, gdev);
		spin_unlock_irq(gdev->cdev[i]->ccwlock);
	}
	/* Check for sufficient number of bus ids. */
	if (i < num_devices) {
		rc = -EINVAL;
		goto error;
	}
	/* Check for trailing stuff. */
	if (i == num_devices && buf && strlen(buf) > 0) {
		rc = -EINVAL;
		goto error;
	}
	/* Check if the devices are bound to the required ccw driver. */
	if (gdrv && gdrv->ccw_driver &&
	    gdev->cdev[0]->drv != gdrv->ccw_driver) {
		rc = -EINVAL;
		goto error;
	}

	dev_set_name(&gdev->dev, "%s", dev_name(&gdev->cdev[0]->dev));

	if (gdrv) {
		gdev->dev.driver = &gdrv->driver;
		rc = gdrv->setup ? gdrv->setup(gdev) : 0;
		if (rc)
			goto error;
	}
	rc = device_add(&gdev->dev);
	if (rc)
		goto error;
	rc = __ccwgroup_create_symlinks(gdev);
	if (rc) {
		device_del(&gdev->dev);
		goto error;
	}
	mutex_unlock(&gdev->reg_mutex);
	return 0;
error:
	mutex_unlock(&gdev->reg_mutex);
	put_device(&gdev->dev);
	return rc;
}
EXPORT_SYMBOL(ccwgroup_create_dev);

static int ccwgroup_notifier(struct notifier_block *nb, unsigned long action,
			     void *data)
{
	struct ccwgroup_device *gdev = to_ccwgroupdev(data);

	if (action == BUS_NOTIFY_UNBOUND_DRIVER) {
		get_device(&gdev->dev);
		schedule_work(&gdev->ungroup_work);
	}

	return NOTIFY_OK;
}

static struct notifier_block ccwgroup_nb = {
	.notifier_call = ccwgroup_notifier
};

static int __init init_ccwgroup(void)
{
	int ret;

	ret = bus_register(&ccwgroup_bus_type);
	if (ret)
		return ret;

	ret = bus_register_notifier(&ccwgroup_bus_type, &ccwgroup_nb);
	if (ret)
		bus_unregister(&ccwgroup_bus_type);

	return ret;
}

static void __exit cleanup_ccwgroup(void)
{
	bus_unregister_notifier(&ccwgroup_bus_type, &ccwgroup_nb);
	bus_unregister(&ccwgroup_bus_type);
}

module_init(init_ccwgroup);
module_exit(cleanup_ccwgroup);

/************************** driver stuff ******************************/

static void ccwgroup_remove(struct device *dev)
{
	struct ccwgroup_device *gdev = to_ccwgroupdev(dev);
	struct ccwgroup_driver *gdrv = to_ccwgroupdrv(dev->driver);

	if (gdrv->remove)
		gdrv->remove(gdev);
}

static void ccwgroup_shutdown(struct device *dev)
{
	struct ccwgroup_device *gdev = to_ccwgroupdev(dev);
	struct ccwgroup_driver *gdrv = to_ccwgroupdrv(dev->driver);

	if (!dev->driver)
		return;
	if (gdrv->shutdown)
		gdrv->shutdown(gdev);
}

static struct bus_type ccwgroup_bus_type = {
	.name   = "ccwgroup",
	.dev_groups = ccwgroup_dev_groups,
	.remove = ccwgroup_remove,
	.shutdown = ccwgroup_shutdown,
};

bool dev_is_ccwgroup(struct device *dev)
{
	return dev->bus == &ccwgroup_bus_type;
}
EXPORT_SYMBOL(dev_is_ccwgroup);

/**
 * ccwgroup_driver_register() - register a ccw group driver
 * @cdriver: driver to be registered
 *
 * This function is mainly a wrapper around driver_register().
 */
int ccwgroup_driver_register(struct ccwgroup_driver *cdriver)
{
	/* register our new driver with the core */
	cdriver->driver.bus = &ccwgroup_bus_type;

	return driver_register(&cdriver->driver);
}
EXPORT_SYMBOL(ccwgroup_driver_register);

/**
 * ccwgroup_driver_unregister() - deregister a ccw group driver
 * @cdriver: driver to be deregistered
 *
 * This function is mainly a wrapper around driver_unregister().
 */
void ccwgroup_driver_unregister(struct ccwgroup_driver *cdriver)
{
	driver_unregister(&cdriver->driver);
}
EXPORT_SYMBOL(ccwgroup_driver_unregister);

/**
 * get_ccwgroupdev_by_busid() - obtain device from a bus id
 * @gdrv: driver the device is owned by
 * @bus_id: bus id of the device to be searched
 *
 * This function searches all devices owned by @gdrv for a device with a bus
 * id matching @bus_id.
 * Returns:
 *  If a match is found, its reference count of the found device is increased
 *  and it is returned; else %NULL is returned.
 */
struct ccwgroup_device *get_ccwgroupdev_by_busid(struct ccwgroup_driver *gdrv,
						 char *bus_id)
{
	struct device *dev;

	dev = driver_find_device_by_name(&gdrv->driver, bus_id);

	return dev ? to_ccwgroupdev(dev) : NULL;
}
EXPORT_SYMBOL_GPL(get_ccwgroupdev_by_busid);

/**
 * ccwgroup_probe_ccwdev() - probe function for slave devices
 * @cdev: ccw device to be probed
 *
 * This is a dummy probe function for ccw devices that are slave devices in
 * a ccw group device.
 * Returns:
 *  always %0
 */
int ccwgroup_probe_ccwdev(struct ccw_device *cdev)
{
	return 0;
}
EXPORT_SYMBOL(ccwgroup_probe_ccwdev);

/**
 * ccwgroup_remove_ccwdev() - remove function for slave devices
 * @cdev: ccw device to be removed
 *
 * This is a remove function for ccw devices that are slave devices in a ccw
 * group device. It sets the ccw device offline and also deregisters the
 * embedding ccw group device.
 */
void ccwgroup_remove_ccwdev(struct ccw_device *cdev)
{
	struct ccwgroup_device *gdev;

	/* Ignore offlining errors, device is gone anyway. */
	ccw_device_set_offline(cdev);
	/* If one of its devices is gone, the whole group is done for. */
	spin_lock_irq(cdev->ccwlock);
	gdev = dev_get_drvdata(&cdev->dev);
	if (!gdev) {
		spin_unlock_irq(cdev->ccwlock);
		return;
	}
	/* Get ccwgroup device reference for local processing. */
	get_device(&gdev->dev);
	spin_unlock_irq(cdev->ccwlock);
	/* Unregister group device. */
	ccwgroup_ungroup(gdev);
	/* Release ccwgroup device reference for local processing. */
	put_device(&gdev->dev);
}
EXPORT_SYMBOL(ccwgroup_remove_ccwdev);
MODULE_LICENSE("GPL");
