drivers/misc/nsm.c

Source file repositories/reference/linux-study-clean/drivers/misc/nsm.c

File Facts

System
Linux kernel
Corpus path
drivers/misc/nsm.c
Extension
.c
Size
11824 bytes
Lines
506
Domain
Driver Families
Bucket
drivers/misc
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 nsm_dev_fops = {
	.unlocked_ioctl = nsm_dev_ioctl,
	.compat_ioctl = compat_ptr_ioctl,
};

/* Handler for probing the NSM device */
static int nsm_device_probe(struct virtio_device *vdev)
{
	struct device *dev = &vdev->dev;
	struct nsm *nsm;
	int rc;

	nsm = devm_kzalloc(&vdev->dev, sizeof(*nsm), GFP_KERNEL);
	if (!nsm)
		return -ENOMEM;

	vdev->priv = nsm;
	nsm->vdev = vdev;

	rc = nsm_device_init_vq(vdev);
	if (rc) {
		dev_err(dev, "queue failed to initialize: %d.\n", rc);
		goto err_init_vq;
	}

	mutex_init(&nsm->lock);

	/* Register as hwrng provider */
	nsm->hwrng = (struct hwrng) {
		.read = nsm_rng_read,
		.name = "nsm-hwrng",
		.quality = 1000,
	};

	rc = hwrng_register(&nsm->hwrng);
	if (rc) {
		dev_err(dev, "RNG initialization error: %d.\n", rc);
		goto err_hwrng;
	}

	/* Register /dev/nsm device node */
	nsm->misc = (struct miscdevice) {
		.minor	= MISC_DYNAMIC_MINOR,
		.name	= "nsm",
		.fops	= &nsm_dev_fops,
		.mode	= 0666,
	};

	rc = misc_register(&nsm->misc);
	if (rc) {
		dev_err(dev, "misc device registration error: %d.\n", rc);
		goto err_misc;
	}

	return 0;

err_misc:
	hwrng_unregister(&nsm->hwrng);
err_hwrng:
	vdev->config->del_vqs(vdev);
err_init_vq:
	return rc;
}

/* Handler for removing the NSM device */
static void nsm_device_remove(struct virtio_device *vdev)
{
	struct nsm *nsm = vdev->priv;

	hwrng_unregister(&nsm->hwrng);

	vdev->config->del_vqs(vdev);
	misc_deregister(&nsm->misc);
}

/* NSM device configuration structure */
static struct virtio_driver virtio_nsm_driver = {
	.feature_table             = 0,
	.feature_table_size        = 0,
	.feature_table_legacy      = 0,
	.feature_table_size_legacy = 0,
	.driver.name               = KBUILD_MODNAME,
	.id_table                  = id_table,
	.probe                     = nsm_device_probe,
	.remove                    = nsm_device_remove,
};

module_virtio_driver(virtio_nsm_driver);
MODULE_DEVICE_TABLE(virtio, id_table);
MODULE_DESCRIPTION("Virtio NSM driver");

Annotation

Implementation Notes