/** * @file devicefs.h * @brief Device filesystem (devicefs) subsystem. * * Provides a VFS interface at /dev for exposing block and character devices. * Drivers register devices through the devicefs API, and each device is * assigned a sequential number by device class (e.g., hdd1, hdd2, cd1). * * The devicefs owns device naming — drivers specify a class name (e.g., "hdd") * and the devicefs appends a sequential number. */ #ifndef DEVICEFS_H #define DEVICEFS_H #include #include /** Maximum number of registered devices. */ #define DEVICEFS_MAX_DEVICES 32 /** Maximum length of a device class name (e.g., "hdd", "cd", "floppy"). */ #define DEVICEFS_MAX_CLASS_NAME 16 /** Maximum length of a full device name (class + number, e.g., "hdd1"). */ #define DEVICEFS_MAX_DEV_NAME 32 /** Device types. */ #define DEVICEFS_BLOCK 0x01 /**< Block device (e.g., hard drives, CDs). */ #define DEVICEFS_CHAR 0x02 /**< Character device (e.g., serial ports). */ /** * Block device operations. * * Block devices transfer data in fixed-size sectors. */ typedef struct devicefs_block_ops { /** Read `count` sectors starting at `lba` into `buf`. Returns 0 on success. */ int (*read_sectors)(void *dev_data, uint32_t lba, uint32_t count, void *buf); /** Write `count` sectors from `buf` starting at `lba`. Returns 0 on success. */ int (*write_sectors)(void *dev_data, uint32_t lba, uint32_t count, const void *buf); /** Get the sector size in bytes. */ uint32_t (*sector_size)(void *dev_data); /** Get total number of sectors. */ uint32_t (*sector_count)(void *dev_data); } devicefs_block_ops_t; /** * Character device operations. * * Character devices transfer data as byte streams. */ typedef struct devicefs_char_ops { /** Read up to `size` bytes into `buf`. Returns bytes read, or -1. */ int32_t (*read)(void *dev_data, uint32_t size, void *buf); /** Write `size` bytes from `buf`. Returns bytes written, or -1. */ int32_t (*write)(void *dev_data, uint32_t size, const void *buf); } devicefs_char_ops_t; /** * Registered device entry. */ typedef struct devicefs_device { char name[DEVICEFS_MAX_DEV_NAME]; /**< Full device name (e.g., "hdd1"). */ char class_name[DEVICEFS_MAX_CLASS_NAME]; /**< Device class (e.g., "hdd"). */ uint8_t type; /**< DEVICEFS_BLOCK or DEVICEFS_CHAR. */ uint32_t number; /**< Assigned device number within class. */ int active; /**< 1 if registered, 0 if free. */ /** Device-specific operations (union of block/char). */ union { devicefs_block_ops_t *block_ops; devicefs_char_ops_t *char_ops; }; /** Opaque driver-specific data passed to operation callbacks. */ void *dev_data; } devicefs_device_t; /** * Initialize the devicefs subsystem and mount at /dev. * * @return 0 on success, -1 on failure. */ int init_devicefs(void); /** * Register a new block device. * * The devicefs assigns a sequential number within the class. For example, * registering class "hdd" twice yields "hdd1" and "hdd2". * * @param class_name Device class name (e.g., "hdd", "cd"). * @param ops Block device operations. * @param dev_data Opaque data passed to operation callbacks. * @return Pointer to the device entry, or NULL on failure. */ devicefs_device_t *devicefs_register_block(const char *class_name, devicefs_block_ops_t *ops, void *dev_data); /** * Register a new character device. * * @param class_name Device class name (e.g., "tty", "serial"). * @param ops Character device operations. * @param dev_data Opaque data passed to operation callbacks. * @return Pointer to the device entry, or NULL on failure. */ devicefs_device_t *devicefs_register_char(const char *class_name, devicefs_char_ops_t *ops, void *dev_data); /** * Find a device by its full name (e.g., "hdd1"). * * @param name Device name. * @return Pointer to the device entry, or NULL if not found. */ devicefs_device_t *devicefs_find(const char *name); /** * Get the next device number for a given class. * This is called internally but may be useful for drivers. * * @param class_name Device class name. * @return Next sequential number (starting from 1). */ uint32_t devicefs_next_number(const char *class_name); #endif /* DEVICEFS_H */