From 34d2c2e0137b3ad637a3cfa9c7afbdf636fc6384 Mon Sep 17 00:00:00 2001 From: Marcin Chrzanowski Date: Mon, 28 May 2018 22:50:44 +0200 Subject: Allocate minor numbers sensibly --- char.c | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/char.c b/char.c index 90bd16c..cdf4029 100644 --- a/char.c +++ b/char.c @@ -121,6 +121,23 @@ struct file_operations doomdev_fops = { struct class *doom_class; +int alloc_minor(void) { + int i; + + for (i = 0; i < DOOMDEV_COUNT; i++) { + if (!minors[i]) { + minors[i] = true; + return i; + } + } + + return -EOVERFLOW; +} + +void free_minor(int minor) { + minors[minor] = false; +} + int new_doomdev(struct pci_dev *dev) { int err = 0; @@ -128,16 +145,13 @@ int new_doomdev(struct pci_dev *dev) struct doom_data *doom_data; dev_t devt; - if (next_minor >= DOOMDEV_COUNT) { - return -EOVERFLOW; - } - doom_data = pci_get_drvdata(dev); cdev_init(&doom_data->cdev, &doomdev_fops); ORFAIL(cdev_add(&doom_data->cdev, first, 1), error_add); - minor = next_minor++; + minor = alloc_minor(); + ORFAIL(minor, error_minor); devt = MKDEV(major, minor); doom_data->device = device_create(doom_class, &dev->dev, devt, NULL, "doom%d", minor); @@ -146,6 +160,8 @@ int new_doomdev(struct pci_dev *dev) return 0; error_create: + free_minor(minor); +error_minor: cdev_del(&doom_data->cdev); error_add: return err; @@ -153,6 +169,7 @@ error_add: void destroy_doomdev(struct doom_data *doom_data) { + free_minor(MINOR(doom_data->device->devt)); device_destroy(doom_class, doom_data->device->devt); cdev_del(&doom_data->cdev); } -- cgit v1.2.3