drivers/s390/char/monreader.c

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

File Facts

System
Linux kernel
Corpus path
drivers/s390/char/monreader.c
Extension
.c
Size
13644 bytes
Lines
531
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 file_operations mon_fops = {
	.owner   = THIS_MODULE,
	.open    = &mon_open,
	.release = &mon_close,
	.read    = &mon_read,
	.poll    = &mon_poll,
	.llseek  = noop_llseek,
};

static struct miscdevice mon_dev = {
	.name       = "monreader",
	.fops       = &mon_fops,
	.minor      = MISC_DYNAMIC_MINOR,
};

/******************************************************************************
 *                              module init/exit                              *
 *****************************************************************************/
static int __init mon_init(void)
{
	int rc;

	if (!machine_is_vm()) {
		pr_err("The z/VM *MONITOR record device driver cannot be "
		       "loaded without z/VM\n");
		return -ENODEV;
	}

	/*
	 * Register with IUCV and connect to *MONITOR service
	 */
	rc = iucv_register(&monreader_iucv_handler, 1);
	if (rc) {
		pr_err("The z/VM *MONITOR record device driver failed to "
		       "register with IUCV\n");
		return rc;
	}

	rc = segment_type(mon_dcss_name);
	if (rc < 0) {
		segment_warning(rc, mon_dcss_name);
		goto out_iucv;
	}
	if (rc != SEG_TYPE_SC) {
		pr_err("The specified *MONITOR DCSS %s does not have the "
		       "required type SC\n", mon_dcss_name);
		rc = -EINVAL;
		goto out_iucv;
	}

	rc = segment_load(mon_dcss_name, SEGMENT_SHARED,
			  &mon_dcss_start, &mon_dcss_end);
	if (rc < 0) {
		segment_warning(rc, mon_dcss_name);
		rc = -EINVAL;
		goto out_iucv;
	}
	dcss_mkname(mon_dcss_name, &user_data_connect[8]);

	/*
	 * misc_register() has to be the last action in module_init(), because
	 * file operations will be available right after this.
	 */
	rc = misc_register(&mon_dev);
	if (rc < 0 )
		goto out;
	return 0;

out:
	segment_unload(mon_dcss_name);
out_iucv:
	iucv_unregister(&monreader_iucv_handler, 1);
	return rc;
}

static void __exit mon_exit(void)
{
	segment_unload(mon_dcss_name);
	misc_deregister(&mon_dev);
	iucv_unregister(&monreader_iucv_handler, 1);
	return;
}


module_init(mon_init);
module_exit(mon_exit);

module_param_string(mondcss, mon_dcss_name, 9, 0444);
MODULE_PARM_DESC(mondcss, "Name of DCSS segment to be used for *MONITOR "
		 "service, max. 8 chars. Default is MONDCSS");

Annotation

Implementation Notes