drivers/s390/char/con3215.c

Source file repositories/reference/linux-study-clean/drivers/s390/char/con3215.c

File Facts

System
Linux kernel
Corpus path
drivers/s390/char/con3215.c
Extension
.c
Size
30361 bytes
Lines
1191
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 ssize_t con_drop_store(struct device_driver *dev, const char *buf, size_t count)
{
	bool drop;
	int rc;

	rc = kstrtobool(buf, &drop);
	if (!rc)
		con3215_drop = drop;
	return rc ?: count;
}

static ssize_t con_drop_show(struct device_driver *dev, char *buf)
{
	return sysfs_emit(buf, "%d\n", con3215_drop ? 1 : 0);
}

static DRIVER_ATTR_RW(con_drop);

static struct attribute *con3215_drv_attrs[] = {
	&driver_attr_con_drop.attr,
	NULL,
};

static struct attribute_group con3215_drv_attr_group = {
	.attrs = con3215_drv_attrs,
};

static const struct attribute_group *con3215_drv_attr_groups[] = {
	&con3215_drv_attr_group,
	NULL,
};

static struct ccw_driver raw3215_ccw_driver = {
	.driver = {
		.name	= "3215",
		.groups = con3215_drv_attr_groups,
		.owner	= THIS_MODULE,
	},
	.ids		= raw3215_id,
	.probe		= &raw3215_probe,
	.remove		= &raw3215_remove,
	.set_online	= &raw3215_set_online,
	.set_offline	= &raw3215_set_offline,
	.int_class	= IRQIO_C15,
};

static void handle_write(struct raw3215_info *raw, const u8 *str, size_t count)
{
	while (count > 0) {
		size_t i = min_t(size_t, count, RAW3215_BUFFER_SIZE - 1);
		raw3215_write(raw, str, i);
		count -= i;
		str += i;
	}
}

#ifdef CONFIG_TN3215_CONSOLE
/*
 * Write a string to the 3215 console
 */
static void con3215_write(struct console *co, const char *str, unsigned int count)
{
	handle_write(raw3215[0], str, count);
}

static struct tty_driver *con3215_device(struct console *c, int *index)
{
	*index = c->index;
	return tty3215_driver;
}

/*
 * The below function is called as a panic/reboot notifier before the
 * system enters a disabled, endless loop.
 *
 * Notice we must use the spin_trylock() alternative, to prevent lockups
 * in atomic context (panic routine runs with secondary CPUs, local IRQs
 * and preemption disabled).
 */
static int con3215_notify(struct notifier_block *self,
			  unsigned long event, void *data)
{
	struct raw3215_info *raw;
	unsigned long flags;

	raw = raw3215[0];  /* console 3215 is the first one */
	if (!spin_trylock_irqsave(get_ccwdev_lock(raw->cdev), flags))
		return NOTIFY_DONE;
	raw3215_make_room(raw, RAW3215_BUFFER_SIZE, false);
	spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);

Annotation

Implementation Notes