Device Driver Core¶
The device driver core facilitates registration and retrieval of devices.
It is implemented in os/drivers/core/device.c.
Implement device registration and retrieval
Initialization¶
The device driver core is initialized by calling
-
void device_init(void)¶
Initialize the device core.
Registering a New Device¶
A new device is allocated and registered by calling
-
int register_device(dev_id_t dev_id, const char *name, const file_operations_t *file_ops, void *priv_data)¶
Register a device.
Mark the major device number as used.
The registered device can later be retrieved via get_device() by its device id.
- Parameters:
dev_id – the (major, minor) pair uniquely identifying the device
name – the name to be used for the device, e.g., in /dev; cannot be NULL or an empty string
file_ops – the file operations, e.g., open(), provided by this device
priv_data – driver specific, private data
- Returns:
0 on sucess
- Returns:
-ENOMEM, if there is no memory to create the device
- Returns:
-EBUSY, if the same
dev_idornamehas already been registered- Returns:
-EINVAL, if
nameis NULL or points to an empty string
For registering the device, the pair of major and minor device id has to be unique. For a single major number, multiple minor numbers can exist. Unique minor device numbers have to be assigned by the driver implementing the device.
A new, still unused major number, can be retrieved and immediately marked as used by calling
-
int device_new_major(void)¶
Query and register a new, i.e., yet unused, major device number.
For dynamic major device number assignment, this function finds and registers a new/free major device number.
- Returns:
a new major number, on success
- Returns:
-ENOMEM, if no free major numbers are available
This function uses the internal helpers
-
static bool __device_major_available(uint8_t major)¶
Check if a device
majornumber still free for use.
-
static void __device_register_major(uint8_t major)¶
Mark a device
majornumber as used.
Which work on the bit mask storing used major numbers
-
static uint8_t __device_majors_used_mask[256 / 8]¶
A bitmask specifying which major numbers are in use.
Retrieving a Device¶
A registered device can be retrieved via its device id, i.e., the (major, minor) pair, by calling
-
const device_t *get_device(dev_id_t dev_id)¶
Retrieve a registered device.
If a device has been registered before a call to this function, the device can be retrieved via its device id passed in
dev_id. The returned device can than be used to determine the required file operations for, e.g., opening the device.- Parameters:
dev_id – the (major, minor) pair uniquely identifying the device
- Returns:
NULLif no such device has been registered.
Iterating Registered Devices¶
Registered devices can be iterated by using the following pair of functions
-
device_t *device_get_first(void)¶
Retrieve the first registered device, e.g., for iteration.
- Returns:
a pointer to the first device
- Returns:
NULL, if there is no registered device
-
device_t *device_get_next(device_t *dev)¶
Given a device
dev, retrieve the next registered device.- Returns:
a pointer to the next device
- Returns:
NULL, if there is no such device
- Returns:
NULL, if
devis NULL ordevhas not yet been registered
Alternatively, the following macro creates the head of a for loop over every registered device:
-
DEVICE_FOR_EACH(d)¶
Provide a for loop over every registered device
d.
Data Structure Provided by the Device Core¶
The device driver core provides the following data structure
-
struct device_t¶
Device information.
Public Members
-
dev_id_t dev_id¶
The device id, i.e., major and minor device number.
-
char name[32]¶
The name of the device, e.g., for the nodes in /dev.
-
const file_operations_tfile_operations_t *file_ops¶
The file operations implemented by the device.
-
void *private_data¶
Driver internal private data, e.g., a gendisk of a block device.
-
dev_id_t dev_id¶