*/
compile_dev_ops(ops);
- devfs_dev = devfs_new_cdev(ops, minor);
+ devfs_dev = devfs_new_cdev(ops, minor, NULL);
__va_start(ap, fmt);
kvsnrprintf(devfs_dev->si_name, sizeof(devfs_dev->si_name),
32, fmt, ap);
return (devfs_dev);
}
+/*
+ * make_dev_covering has equivalent functionality to make_dev, except that it
+ * also takes the cdev of the underlying device. Hence this function should
+ * only be used by systems and drivers which create devices covering others
+ */
+cdev_t
+make_dev_covering(struct dev_ops *ops, cdev_t rdev, int minor, uid_t uid,
+ gid_t gid, int perms, const char *fmt, ...)
+{
+ cdev_t devfs_dev;
+ __va_list ap;
+
+ /*
+ * compile the cdevsw and install the device
+ */
+ compile_dev_ops(ops);
+
+ devfs_dev = devfs_new_cdev(ops, minor, rdev);
+ __va_start(ap, fmt);
+ kvsnrprintf(devfs_dev->si_name, sizeof(devfs_dev->si_name),
+ 32, fmt, ap);
+ __va_end(ap);
+
+ devfs_debug(DEVFS_DEBUG_INFO,
+ "make_dev called for %s\n",
+ devfs_dev->si_name);
+ devfs_create_dev(devfs_dev, uid, gid, perms);
+
+ return (devfs_dev);
+}
+
+
cdev_t
make_only_devfs_dev(struct dev_ops *ops, int minor, uid_t uid, gid_t gid,
* compile the cdevsw and install the device
*/
compile_dev_ops(ops);
- devfs_dev = devfs_new_cdev(ops, minor);
+ devfs_dev = devfs_new_cdev(ops, minor, NULL);
/*
* Set additional fields (XXX DEVFS interface goes here)
* compile the cdevsw and install the device
*/
compile_dev_ops(ops);
- devfs_dev = devfs_new_cdev(ops, minor);
+ devfs_dev = devfs_new_cdev(ops, minor, NULL);
devfs_dev->si_perms = perms;
devfs_dev->si_uid = uid;
devfs_dev->si_gid = gid;
uid_t si_uid;
gid_t si_gid;
int si_perms;
+ cdev_t si_rdev;
TAILQ_ENTRY(cdev) link;
int si_uminor;
int si_umajor;
int devfs_destroy_dev_by_ops(struct dev_ops *, int);
struct devfs_node *devfs_find_device_node_by_name(struct devfs_node *, char *);
-cdev_t devfs_new_cdev(struct dev_ops *, int);
+cdev_t devfs_new_cdev(struct dev_ops *, int, cdev_t);
cdev_t devfs_find_device_by_name(const char *, ...);
cdev_t devfs_find_device_by_udev(udev_t);
cdev_t make_dev(struct dev_ops *ops, int minor, uid_t uid, gid_t gid,
int perms, const char *fmt, ...) __printflike(6, 7);
+cdev_t make_dev_covering(struct dev_ops *ops, cdev_t rdev, int minor, uid_t uid,
+ gid_t gid, int perms, const char *fmt, ...) __printflike(7, 8);
cdev_t make_only_dev(struct dev_ops *ops, int minor, uid_t uid, gid_t gid,
int perms, const char *fmt, ...) __printflike(6, 7);
cdev_t make_only_devfs_dev(struct dev_ops *ops, int minor, uid_t uid, gid_t gid,
* fields.
*/
cdev_t
-devfs_new_cdev(struct dev_ops *ops, int minor)
+devfs_new_cdev(struct dev_ops *ops, int minor, cdev_t rdev)
{
cdev_t dev = sysref_alloc(&cdev_sysref_class);
dev->si_flags = 0;
dev->si_umajor = 0;
dev->si_uminor = minor;
- dev->si_inode = makeudev(devfs_reference_ops(ops), minor);
+ dev->si_rdev = rdev;
+ /* If there is a backing device, we reference its ops */
+ dev->si_inode = makeudev(
+ devfs_reference_ops((rdev)?(rdev->si_ops):(ops)),
+ minor );
return dev;
}
if (locked)
lockmgr(&devfs_lock, LK_RELEASE);
- devfs_release_ops(dev->si_ops);
+ /* If there is a backing device, we release the backing device's ops */
+ devfs_release_ops((dev->si_rdev)?(dev->si_rdev->si_ops):(dev->si_ops));
/* Finally destroy the device */
sysref_put(&dev->si_sysref);