drivers/s390/cio/ccwgroup.c

Source file repositories/reference/linux-study-clean/drivers/s390/cio/ccwgroup.c

File Facts

System
Linux kernel
Corpus path
drivers/s390/cio/ccwgroup.c
Extension
.c
Size
13507 bytes
Lines
557
Domain
Driver Families
Bucket
drivers/s390
Inferred role
Driver Families: operation-table or driver-model contract
Status
pattern implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

static const 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++) {
		scnprintf(str, sizeof(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
 * @call_gdrv: Call the registered gdrv set_offline function
 *
 * 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, bool call_gdrv)
{
	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 (!call_gdrv) {
		ret = 0;
		goto offline;
	}
	if (gdrv->set_offline)
		ret = gdrv->set_offline(gdev);
	if (ret)
		goto out;

offline:
	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;

Annotation

Implementation Notes