📄 base.c
字号:
if (!S_ISDIR (de->mode) && !is_new) { /* Transmogrifying an old entry */ de->u.dir.first = NULL; de->u.dir.last = NULL; } de->mode = S_IFDIR | S_IRUGO | S_IXUGO; de->info = info; if (!de->registered) de->u.dir.num_removable = 0; de->registered = TRUE; de->show_unreg = (boot_options & OPTION_SHOW) ? TRUE : FALSE; de->hide = FALSE; return de;} /* End Function devfs_mk_dir *//** * devfs_find_handle - Find the handle of a devfs entry. * @dir: The handle to the parent devfs directory entry. If this is %NULL the * name is relative to the root of the devfs. * @name: The name of the entry. * @major: The major number. This is used if @name is %NULL. * @minor: The minor number. This is used if @name is %NULL. * @type: The type of special file to search for. This may be either * %DEVFS_SPECIAL_CHR or %DEVFS_SPECIAL_BLK. * @traverse_symlinks: If %TRUE then symlink entries in the devfs namespace are * traversed. Symlinks pointing out of the devfs namespace will cause a * failure. Symlink traversal consumes stack space. * * Returns a handle which may later be used in a call to devfs_unregister(), * devfs_get_flags(), or devfs_set_flags(). On failure %NULL is returned. */devfs_handle_t devfs_find_handle (devfs_handle_t dir, const char *name, unsigned int major, unsigned int minor, char type, int traverse_symlinks){ devfs_handle_t de; if ( (name != NULL) && (name[0] == '\0') ) name = NULL; de = find_entry (dir, name, 0, major, minor, type, traverse_symlinks); if (de == NULL) return NULL; if (!de->registered) return NULL; return de;} /* End Function devfs_find_handle *//** * devfs_get_flags - Get the flags for a devfs entry. * @de: The handle to the device entry. * @flags: The flags are written here. * * Returns 0 on success, else a negative error code. */int devfs_get_flags (devfs_handle_t de, unsigned int *flags){ unsigned int fl = 0; if (de == NULL) return -EINVAL; if (!de->registered) return -ENODEV; if (de->show_unreg) fl |= DEVFS_FL_SHOW_UNREG; if (de->hide) fl |= DEVFS_FL_HIDE; if ( S_ISCHR (de->mode) || S_ISBLK (de->mode) || S_ISREG (de->mode) ) { if (de->u.fcb.auto_owner) fl |= DEVFS_FL_AUTO_OWNER; if (de->u.fcb.aopen_notify) fl |= DEVFS_FL_AOPEN_NOTIFY; if (de->u.fcb.removable) fl |= DEVFS_FL_REMOVABLE; } *flags = fl; return 0;} /* End Function devfs_get_flags *//* * devfs_set_flags - Set the flags for a devfs entry. * @de: The handle to the device entry. * @flags: The flags to set. Unset flags are cleared. * * Returns 0 on success, else a negative error code. */int devfs_set_flags (devfs_handle_t de, unsigned int flags){ if (de == NULL) return -EINVAL; if (!de->registered) return -ENODEV;#ifdef CONFIG_DEVFS_DEBUG if (devfs_debug & DEBUG_SET_FLAGS) printk ("%s: devfs_set_flags(): de->name: \"%s\"\n", DEVFS_NAME, de->name);#endif de->show_unreg = (flags & DEVFS_FL_SHOW_UNREG) ? TRUE : FALSE; de->hide = (flags & DEVFS_FL_HIDE) ? TRUE : FALSE; if ( S_ISCHR (de->mode) || S_ISBLK (de->mode) || S_ISREG (de->mode) ) { de->u.fcb.auto_owner = (flags & DEVFS_FL_AUTO_OWNER) ? TRUE : FALSE; de->u.fcb.aopen_notify = (flags & DEVFS_FL_AOPEN_NOTIFY) ? TRUE:FALSE; if ( de->u.fcb.removable && !(flags & DEVFS_FL_REMOVABLE) ) { de->u.fcb.removable = FALSE; --de->parent->u.dir.num_removable; } else if ( !de->u.fcb.removable && (flags & DEVFS_FL_REMOVABLE) ) { de->u.fcb.removable = TRUE; ++de->parent->u.dir.num_removable; } } return 0;} /* End Function devfs_set_flags *//** * devfs_get_maj_min - Get the major and minor numbers for a devfs entry. * @de: The handle to the device entry. * @major: The major number is written here. This may be %NULL. * @minor: The minor number is written here. This may be %NULL. * * Returns 0 on success, else a negative error code. */int devfs_get_maj_min (devfs_handle_t de, unsigned int *major, unsigned int *minor){ if (de == NULL) return -EINVAL; if (!de->registered) return -ENODEV; if ( S_ISDIR (de->mode) ) return -EISDIR; if ( !S_ISCHR (de->mode) && !S_ISBLK (de->mode) ) return -EINVAL; if (major != NULL) *major = de->u.fcb.u.device.major; if (minor != NULL) *minor = de->u.fcb.u.device.minor; return 0;} /* End Function devfs_get_maj_min *//** * devfs_get_handle_from_inode - Get the devfs handle for a VFS inode. * @inode: The VFS inode. * * Returns the devfs handle on success, else %NULL. */devfs_handle_t devfs_get_handle_from_inode (struct inode *inode){ if (!inode || !inode->i_sb) return NULL; if (inode->i_sb->s_magic != DEVFS_SUPER_MAGIC) return NULL; return get_devfs_entry_from_vfs_inode (inode);} /* End Function devfs_get_handle_from_inode *//** * devfs_generate_path - Generate a pathname for an entry, relative to the devfs root. * @de: The devfs entry. * @path: The buffer to write the pathname to. The pathname and '\0' * terminator will be written at the end of the buffer. * @buflen: The length of the buffer. * * Returns the offset in the buffer where the pathname starts on success, * else a negative error code. */int devfs_generate_path (devfs_handle_t de, char *path, int buflen){ int pos; if (de == NULL) return -EINVAL; if (de->namelen >= buflen) return -ENAMETOOLONG; /* Must be first */ if (de->parent == NULL) return buflen; /* Don't prepend root */ pos = buflen - de->namelen - 1; memcpy (path + pos, de->name, de->namelen); path[buflen - 1] = '\0'; for (de = de->parent; de->parent != NULL; de = de->parent) { if (pos - de->namelen - 1 < 0) return -ENAMETOOLONG; path[--pos] = '/'; pos -= de->namelen; memcpy (path + pos, de->name, de->namelen); } return pos;} /* End Function devfs_generate_path *//** * devfs_get_ops - Get the device operations for a devfs entry. * @de: The handle to the device entry. * * Returns a pointer to the device operations on success, else NULL. */void *devfs_get_ops (devfs_handle_t de){ if (de == NULL) return NULL; if (!de->registered) return NULL; if ( S_ISCHR (de->mode) || S_ISBLK (de->mode) || S_ISREG (de->mode) ) return de->u.fcb.ops; return NULL;} /* End Function devfs_get_ops *//** * devfs_set_file_size - Set the file size for a devfs regular file. * @de: The handle to the device entry. * @size: The new file size. * * Returns 0 on success, else a negative error code. */int devfs_set_file_size (devfs_handle_t de, unsigned long size){ if (de == NULL) return -EINVAL; if (!de->registered) return -EINVAL; if ( !S_ISREG (de->mode) ) return -EINVAL; if (de->u.fcb.u.file.size == size) return 0; de->u.fcb.u.file.size = size; if (de->inode.dentry == NULL) return 0; if (de->inode.dentry->d_inode == NULL) return 0; de->inode.dentry->d_inode->i_size = size; return 0;} /* End Function devfs_set_file_size *//** * devfs_get_info - Get the info pointer written to private_data of @de upon open. * @de: The handle to the device entry. * * Returns the info pointer. */void *devfs_get_info (devfs_handle_t de){ if (de == NULL) return NULL; if (!de->registered) return NULL; return de->info;} /* End Function devfs_get_info *//** * devfs_set_info - Set the info pointer written to private_data upon open. * @de: The handle to the device entry. * @info: pointer to the data * * Returns 0 on success, else a negative error code. */int devfs_set_info (devfs_handle_t de, void *info){ if (de == NULL) return -EINVAL; if (!de->registered) return -EINVAL; de->info = info; return 0;} /* End Function devfs_set_info *//** * devfs_get_parent - Get the parent device entry. * @de: The handle to the device entry. * * Returns the parent device entry if it exists, else %NULL. */devfs_handle_t devfs_get_parent (devfs_handle_t de){ if (de == NULL) return NULL; if (!de->registered) return NULL; return de->parent;} /* End Function devfs_get_parent *//** * devfs_get_first_child - Get the first leaf node in a directory. * @de: The handle to the device entry. * * Returns the leaf node device entry if it exists, else %NULL. */devfs_handle_t devfs_get_first_child (devfs_handle_t de){ if (de == NULL) return NULL; if (!de->registered) return NULL; if ( !S_ISDIR (de->mode) ) return NULL; return de->u.dir.first;} /* End Function devfs_get_first_child *//** * devfs_get_next_sibling - Get the next sibling leaf node. for a device entry. * @de: The handle to the device entry. * * Returns the leaf node device entry if it exists, else %NULL. */devfs_handle_t devfs_get_next_sibling (devfs_handle_t de){ if (de == NULL) return NULL; if (!de->registered) return NULL; return de->next;} /* End Function devfs_get_next_sibling *//** * devfs_auto_unregister - Configure a devfs entry to be automatically unregistered. * @master: The master devfs entry. Only one slave may be registered. * @slave: The devfs entry which will be automatically unregistered when the * master entry is unregistered. It is illegal to call devfs_unregister() * on this entry. */void devfs_auto_unregister (devfs_handle_t master, devfs_handle_t slave){ if (master == NULL) return; if (master->slave != NULL) { /* Because of the dumbness of the layers above, ignore duplicates */ if (master->slave == slave) return; printk ("%s: devfs_auto_unregister(): only one slave allowed\n", DEVFS_NAME); OOPS (" master: \"%s\" old slave: \"%s\" new slave: \"%s\"\n", master->name, master->slave->name, slave->name); } master->slave = slave;} /* End Function devfs_auto_unregister *//** * devfs_get_unregister_slave - Get the slave entry which will be automatically unregistered. * @master: The master devfs entry. * * Returns the slave which will be unregistered when @master is unregistered. */devfs_handle_t devfs_get_unregister_slave (devfs_handle_t master){ if (master == NULL) return NULL; return master->slave;} /* End Function devfs_get_unregister_slave *//** * devfs_get_name - Get the name for a device entry in its parent directory. * @de: The handle to the device entry. * @namelen: The length of the name is written here. This may be %NULL. * * Returns the name on success, else %NULL. */const char *devfs_get_name (devfs_handle_t de, unsigned int *namelen){ if (de == NULL) return NULL; if (!de->registered) return NULL; if (namelen != NULL) *namelen = de->namelen; return de->name;} /* End Function devfs_get_name *//** * devfs_register_chrdev - Optionally register a conventional character driver. * @major: The major number for the driver. * @name: The name of the driver (as seen in /proc/devices). * @fops: The &file_operations structure pointer. * * This function will register a character driver provided the "devfs=only" * option was not provided at boot time. * Returns 0 on success, else a negative error code on failure. */int devfs_register_chrdev (unsigned int major, const char *name, struct file_operations *fops){ if (boot_options & OPTION_ONLY) return 0; return register_chrdev (major, name, fops);} /* End Function devfs_register_chrdev *//** * devfs_register_blkdev - Optionally register a conventional block driver. * @major: The major number for the driver. * @name: The name of the driver (as seen in /proc/devices). * @bdops: The &block_device_operations structure pointer. * * This function will register a block driver provided the "devfs=only" * option was not provided at boot time. * Returns 0 on success, else a negative error code on failure. */int devfs_register_blkdev (unsigned int major, const char *name, struct block_device_operations *bdops){ if (boot_options & OPTION_ONLY) return 0; return register_blkdev (major, name, bdops);} /* End Function devfs_register_blkdev *//** * devfs_unregister_chrdev - Optionally unregister a conventional character driver. * @major: The major number for the driver. * @name: The name of the driver (a
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -