Abstract
- Allocating and freeing device numbers
> register_chrdev_region
> alloc_chrdev_region
- Best way to allocate device numbers
- The disadvantage of dynamic assignment of device numbers
- Allocating device numbers to SCULL device driver
Allocating and freeing device numbers
register_chrdev_region — register a range of device numbers
Synopsis
int register_chrdev_region ( dev_t from, unsigned count, const char * name);
Arguments
from
the first in the desired range of device numbers; must include the major number.
First is the beginning device number of the range you would like to allocate.
count
the number of consecutive device numbers required
name
the name of the device or driver. This should be associated with this number range: it will appear in /proc/devices and sysfs
Return
The return value of this function will be 0 on success. In case of error, a negative error code will be returned and obviously, you will not have access to the requested region.
int alloc_chrdev_region(dev_t *dev, unsigned int firstminor, unsigned int count, char *name);
where,
With this function,
dev is an output-only parameter that will, on successful completion, hold the first number in your allocated range.
firstminor should be the requested first minor number to use; it is usually 0. The count and name parameters work like those given to request_chrdev_region.
The usual place to call these functions would be in your module's init function.
Regardless of how you allocate your device numbers, you should free them when they are no longer in use. Device numbers are freed with:
void unregister_chrdev_region(dev_t first, unsigned int count);
The usual place to call unregister_chrdev_region would be in your module’s cleanup function.
Best way to allocate device numbers
As a device driver programmer, we have two choices to pick Major number for a device.
> Pick a random number that appears to unused
> Allocate major numbers in a Dynamic manner
Your drivers should almost certainly be using alloc_chrdev_region rather than register_chrdev_region to dynamically allocate major numbers for a new driver.
The disadvantage of dynamic assignment is that you can’t create the device nodes in advance, because the major number assigned to your module will vary. For normal use of the driver, this is hardly a problem, because once the number has been assigned, you can read it from /proc/devices.*
if (scull_major) { dev = MKDEV(scull_major, scull_minor); result = register_chrdev_region(dev, scull_nr_devs, "scull"); } else { result = alloc_chrdev_region(&dev, scull_minor, scull_nr_devs, "scull"); scull_major = MAJOR(dev); } if (result < 0) { printk(KERN_WARNING "scull: can't get major %d ", scull_major); return result; }
References:
- Linux Device Drivers 3rd Edition source code, https://resources.oreilly.com/examples/9780596005900.git