BarryServer : Git

All the code for all my projects
// BarryServer : Git / Nucleus / commit / 7864e7f8ed319f380849d97675be53f53c953f9d / drivers / driver.c

// Related

Nucleus

Barry Device driver interface 7864e7f (3 years, 2 months ago)
diff --git a/drivers/driver.c b/drivers/driver.c
new file mode 100644
index 0000000..5309c1a
--- /dev/null
+++ b/drivers/driver.c
@@ -0,0 +1,70 @@
+/*
+ * This file controls the Device Driver Interface.  It allows a driver to
+ * register a set of file operations and a major number.  This number can later
+ * be used to find the correct operations for a device file.
+ */
+
+#include <nucleus/driver.h>
+#include <nucleus/object.h>
+#include <nucleus/vfs.h>
+
+/* Structure for a Driver object */
+struct Driver {
+	Object obj;
+	unsigned short major;
+	FileOps *ops;
+};
+
+/* Driver object type */
+ObjectType driverType = {
+	.name = "DRIVER",
+	.size = sizeof(Driver),
+};
+
+static ObjectList *drivers;
+
+/* Compare the major numbers of two Drivers */
+static int
+compare_driver(void *a, void *b)
+{
+	Driver *da = a, *db = b;
+	return (da->major - db->major);
+}
+
+/* Register a driver */
+unsigned short
+register_driver(unsigned short major, FileOps *ops)
+{
+	if (!drivers)
+		drivers = create_list(&driverType, LIST_ORDERED,
+		                      compare_driver);
+	Driver *driver = new(&driverType);
+	driver->major = major;
+	driver->ops = ops;
+
+	/* Ensure major is unique */
+	if (!driver->major)
+		driver->major = 1;
+	Driver *collision;
+	foreach (drivers, collision) {
+		if (driver->major == collision->major)
+			driver->major++;
+		else if (driver->major < collision->major)
+			break;
+	}
+
+	add(drivers, driver);
+	return driver->major;
+}
+
+/* Find a driver from a major number */
+FileOps *
+find_driver(unsigned short major)
+{
+	Driver *driver;
+	foreach (drivers, driver) {
+		if (driver->major == major)
+			break;
+	}
+	return driver->ops;
+}