dev: implement generic devices

generic devices don't have a type (char, block, etc) and are created
by bus drivers to represent the device until a suitable driver is found.

generic devices are registered by the bus driver. once a more suitable
driver is found, that driver will re-register the device under itself.
This commit is contained in:
2023-06-10 13:21:42 +01:00
parent 4a2c5de5b6
commit c5edce612d
8 changed files with 122 additions and 8 deletions

View File

@@ -115,6 +115,7 @@ struct device {
struct btree_node dev_driverent;
char dev_name[DEV_NAME_MAX];
void *dev_bus_priv;
void *dev_priv;
union {
@@ -130,7 +131,12 @@ struct device {
struct driver;
struct driver_ops {
/* called when a bus driver finds a device for this driver to manage. */
kern_status_t(*bind)(struct driver *, struct device *, struct device *);
/* called when driver is registered. */
kern_status_t(*install)(struct driver *);
/* called when driver is unregistered. */
kern_status_t(*uninstall)(struct driver *);
};
struct driver {
@@ -184,6 +190,13 @@ extern struct input_device *input_device_create(void);
extern struct bus_device *bus_device_create(void);
extern struct framebuffer_device *framebuffer_device_create(void);
extern struct char_device *char_device_from_generic(struct device *dev);
extern struct block_device *block_device_from_generic(struct device *dev);
extern struct net_device *net_device_from_generic(struct device *dev);
extern struct input_device *input_device_from_generic(struct device *dev);
extern struct bus_device *bus_device_from_generic(struct device *dev);
extern struct framebuffer_device *framebuffer_device_from_generic(struct device *dev);
static inline struct device *char_device_base(struct char_device *dev)
{
return (struct device *)((char *)dev - offsetof(struct device, chr));
@@ -221,14 +234,20 @@ extern kern_status_t input_device_read(struct device *dev, void *buf, size_t siz
extern struct driver *driver_create(struct kext *self, const char *name);
extern kern_status_t driver_destroy(struct driver *driver);
extern kern_status_t driver_init(struct driver *driver, struct kext *self, const char *name);
extern kern_status_t driver_deinit(struct driver *driver);
extern kern_status_t driver_register(struct driver *driver);
extern kern_status_t driver_unregister(struct driver *driver);
extern unsigned int driver_alloc_minor(struct driver *driver);
extern void driver_free_minor(struct driver *driver, unsigned int minor);
extern struct device *driver_get_device(struct driver *driver, unsigned int minor);
extern kern_status_t driver_add_device(struct driver *driver, struct device *dev);
extern kern_status_t driver_remove_device(struct driver *driver, struct device *dev);
extern struct driver *system_driver(void);
extern kern_status_t framebuffer_get_varinfo(struct device *dev, struct framebuffer_varinfo *varinfo);
extern kern_status_t framebuffer_set_varinfo(struct device *dev, const struct framebuffer_varinfo *varinfo);
static inline void driver_lock(struct driver *driver)
{
spin_lock(&driver->drv_lock);