#include "chardev.h" #include "internal.h" #include #include #include #include #include static struct vfs_dir_entry_t *chardev_folder_dentry = NULL; extern struct vfs_dir_entry_t *devfs_root_dentry; /** * @brief 字符设备名称前缀 * */ static char chardev_name_prefix[CHAR_DEV_STYPE_END + 1][32] = { [CHAR_DEV_STYPE_START] = "", [CHAR_DEV_STYPE_PS2_KEYBOARD] = "ps2.kb", [CHAR_DEV_STYPE_PS2_MOUSE] = "ps2.mse", [CHAR_DEV_STYPE_USB_MOUSE] = "usb.mse", [CHAR_DEV_STYPE_USB_KEYBOARD] = "usb.kb", [CHAR_DEV_STYPE_BLUETOOTH_MOUSE] = "bt.mse", [CHAR_DEV_STYPE_BLUETOOTH_KEYBOARD] = "bt.kb", [CHAR_DEV_STYPE_TTY] = "vdev.tty", [CHAR_DEV_STYPE_END] = "", }; /** * @brief 为不同类型的字符设备分配的管理信息结构体 * */ static struct chardev_manage_info_t { mutex_t lock; // 操作互斥锁 int count; } chardev_manage_info[CHAR_DEV_STYPE_END + 1]; /** * @brief 在devfs中注册字符设备(该函数只应被devfs调用) * * @param private_info inode私有信息 * @param target_dentry 返回的dentry的指针 * @return int 错误码 */ int __devfs_chardev_register(struct devfs_private_inode_info_t *private_info, struct vfs_dir_entry_t **target_dentry) { // 检测subtype是否合法 if (private_info->sub_type <= CHAR_DEV_STYPE_START || private_info->sub_type >= CHAR_DEV_STYPE_END) return -EINVAL; mutex_lock(&chardev_manage_info[private_info->sub_type].lock); // 拷贝名称 char devname[64] = {0}; strcpy(devname, chardev_name_prefix[private_info->sub_type]); char *ptr = devname + strlen(chardev_name_prefix[private_info->sub_type]); sprintk(ptr, "%d", chardev_manage_info[private_info->sub_type].count); int namelen = strlen(devname); struct vfs_dir_entry_t *dentry = vfs_alloc_dentry(namelen + 1); __devfs_fill_dentry(dentry, devname); __devfs_fill_inode(dentry, vfs_alloc_inode(), VFS_IF_DEVICE, private_info); // 将dentry挂载到char文件夹下 __devfs_dentry_bind_parent(chardev_folder_dentry, dentry); ++chardev_manage_info[private_info->sub_type].count; mutex_unlock(&chardev_manage_info[private_info->sub_type].lock); *target_dentry = dentry; return 0; } /** * @brief 初始化chardev管理机制 * */ void __devfs_chardev_init() { // 初始化管理信息结构体 for (int i = CHAR_DEV_STYPE_START + 1; i < CHAR_DEV_STYPE_END; ++i) { mutex_init(&chardev_manage_info[i].lock); chardev_manage_info[i].count = 0; } vfs_mkdir("/dev/char", 0, false); // 获取char dev的dentry chardev_folder_dentry = __devfs_find_dir(devfs_root_dentry, "char"); }