Driver-Core: extend devnode callbacks to provide permissions
This allows subsytems to provide devtmpfs with non-default permissions for the device node. Instead of the default mode of 0600, null, zero, random, urandom, full, tty, ptmx now have a mode of 0666, which allows non-privileged processes to access standard device nodes in case no other userspace process applies the expected permissions. This also fixes a wrong assignment in pktcdvd and a checkpatch.pl complain. Signed-off-by: Kay Sievers <kay.sievers@vrfy.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
parent
78f28b7c55
commit
e454cea20b
|
@ -182,7 +182,7 @@ static struct notifier_block __refdata cpuid_class_cpu_notifier =
|
|||
.notifier_call = cpuid_class_cpu_callback,
|
||||
};
|
||||
|
||||
static char *cpuid_nodename(struct device *dev)
|
||||
static char *cpuid_devnode(struct device *dev, mode_t *mode)
|
||||
{
|
||||
return kasprintf(GFP_KERNEL, "cpu/%u/cpuid", MINOR(dev->devt));
|
||||
}
|
||||
|
@ -203,7 +203,7 @@ static int __init cpuid_init(void)
|
|||
err = PTR_ERR(cpuid_class);
|
||||
goto out_chrdev;
|
||||
}
|
||||
cpuid_class->nodename = cpuid_nodename;
|
||||
cpuid_class->devnode = cpuid_devnode;
|
||||
for_each_online_cpu(i) {
|
||||
err = cpuid_device_create(i);
|
||||
if (err != 0)
|
||||
|
|
|
@ -236,7 +236,7 @@ static const struct file_operations microcode_fops = {
|
|||
static struct miscdevice microcode_dev = {
|
||||
.minor = MICROCODE_MINOR,
|
||||
.name = "microcode",
|
||||
.devnode = "cpu/microcode",
|
||||
.nodename = "cpu/microcode",
|
||||
.fops = µcode_fops,
|
||||
};
|
||||
|
||||
|
|
|
@ -241,7 +241,7 @@ static struct notifier_block __refdata msr_class_cpu_notifier = {
|
|||
.notifier_call = msr_class_cpu_callback,
|
||||
};
|
||||
|
||||
static char *msr_nodename(struct device *dev)
|
||||
static char *msr_devnode(struct device *dev, mode_t *mode)
|
||||
{
|
||||
return kasprintf(GFP_KERNEL, "cpu/%u/msr", MINOR(dev->devt));
|
||||
}
|
||||
|
@ -262,7 +262,7 @@ static int __init msr_init(void)
|
|||
err = PTR_ERR(msr_class);
|
||||
goto out_chrdev;
|
||||
}
|
||||
msr_class->nodename = msr_nodename;
|
||||
msr_class->devnode = msr_devnode;
|
||||
for_each_online_cpu(i) {
|
||||
err = msr_device_create(i);
|
||||
if (err != 0)
|
||||
|
|
|
@ -1062,7 +1062,7 @@ EXPORT_SYMBOL_GPL(bsg_register_queue);
|
|||
|
||||
static struct cdev bsg_cdev;
|
||||
|
||||
static char *bsg_nodename(struct device *dev)
|
||||
static char *bsg_devnode(struct device *dev, mode_t *mode)
|
||||
{
|
||||
return kasprintf(GFP_KERNEL, "bsg/%s", dev_name(dev));
|
||||
}
|
||||
|
@ -1087,7 +1087,7 @@ static int __init bsg_init(void)
|
|||
ret = PTR_ERR(bsg_class);
|
||||
goto destroy_kmemcache;
|
||||
}
|
||||
bsg_class->nodename = bsg_nodename;
|
||||
bsg_class->devnode = bsg_devnode;
|
||||
|
||||
ret = alloc_chrdev_region(&devid, 0, BSG_MAX_DEVS, "bsg");
|
||||
if (ret)
|
||||
|
|
|
@ -998,12 +998,12 @@ struct class block_class = {
|
|||
.name = "block",
|
||||
};
|
||||
|
||||
static char *block_nodename(struct device *dev)
|
||||
static char *block_devnode(struct device *dev, mode_t *mode)
|
||||
{
|
||||
struct gendisk *disk = dev_to_disk(dev);
|
||||
|
||||
if (disk->nodename)
|
||||
return disk->nodename(disk);
|
||||
if (disk->devnode)
|
||||
return disk->devnode(disk, mode);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -1011,7 +1011,7 @@ static struct device_type disk_type = {
|
|||
.name = "disk",
|
||||
.groups = disk_attr_groups,
|
||||
.release = disk_release,
|
||||
.nodename = block_nodename,
|
||||
.devnode = block_devnode,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
|
|
|
@ -166,13 +166,16 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj,
|
|||
if (MAJOR(dev->devt)) {
|
||||
const char *tmp;
|
||||
const char *name;
|
||||
mode_t mode = 0;
|
||||
|
||||
add_uevent_var(env, "MAJOR=%u", MAJOR(dev->devt));
|
||||
add_uevent_var(env, "MINOR=%u", MINOR(dev->devt));
|
||||
name = device_get_nodename(dev, &tmp);
|
||||
name = device_get_devnode(dev, &mode, &tmp);
|
||||
if (name) {
|
||||
add_uevent_var(env, "DEVNAME=%s", name);
|
||||
kfree(tmp);
|
||||
if (mode)
|
||||
add_uevent_var(env, "DEVMODE=%#o", mode & 0777);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1148,8 +1151,9 @@ static struct device *next_device(struct klist_iter *i)
|
|||
}
|
||||
|
||||
/**
|
||||
* device_get_nodename - path of device node file
|
||||
* device_get_devnode - path of device node file
|
||||
* @dev: device
|
||||
* @mode: returned file access mode
|
||||
* @tmp: possibly allocated string
|
||||
*
|
||||
* Return the relative path of a possible device node.
|
||||
|
@ -1157,21 +1161,22 @@ static struct device *next_device(struct klist_iter *i)
|
|||
* a name. This memory is returned in tmp and needs to be
|
||||
* freed by the caller.
|
||||
*/
|
||||
const char *device_get_nodename(struct device *dev, const char **tmp)
|
||||
const char *device_get_devnode(struct device *dev,
|
||||
mode_t *mode, const char **tmp)
|
||||
{
|
||||
char *s;
|
||||
|
||||
*tmp = NULL;
|
||||
|
||||
/* the device type may provide a specific name */
|
||||
if (dev->type && dev->type->nodename)
|
||||
*tmp = dev->type->nodename(dev);
|
||||
if (dev->type && dev->type->devnode)
|
||||
*tmp = dev->type->devnode(dev, mode);
|
||||
if (*tmp)
|
||||
return *tmp;
|
||||
|
||||
/* the class may provide a specific name */
|
||||
if (dev->class && dev->class->nodename)
|
||||
*tmp = dev->class->nodename(dev);
|
||||
if (dev->class && dev->class->devnode)
|
||||
*tmp = dev->class->devnode(dev, mode);
|
||||
if (*tmp)
|
||||
return *tmp;
|
||||
|
||||
|
|
|
@ -6,9 +6,10 @@
|
|||
* During bootup, before any driver core device is registered,
|
||||
* devtmpfs, a tmpfs-based filesystem is created. Every driver-core
|
||||
* device which requests a device node, will add a node in this
|
||||
* filesystem. The node is named after the the name of the device,
|
||||
* or the susbsytem can provide a custom name. All devices are
|
||||
* owned by root and have a mode of 0600.
|
||||
* filesystem.
|
||||
* By default, all devices are named after the the name of the
|
||||
* device, owned by root and have a default mode of 0600. Subsystems
|
||||
* can overwrite the default setting if needed.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
|
@ -20,6 +21,7 @@
|
|||
#include <linux/fs.h>
|
||||
#include <linux/shmem_fs.h>
|
||||
#include <linux/cred.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/init_task.h>
|
||||
|
||||
static struct vfsmount *dev_mnt;
|
||||
|
@ -134,7 +136,7 @@ int devtmpfs_create_node(struct device *dev)
|
|||
const char *tmp = NULL;
|
||||
const char *nodename;
|
||||
const struct cred *curr_cred;
|
||||
mode_t mode;
|
||||
mode_t mode = 0;
|
||||
struct nameidata nd;
|
||||
struct dentry *dentry;
|
||||
int err;
|
||||
|
@ -142,14 +144,16 @@ int devtmpfs_create_node(struct device *dev)
|
|||
if (!dev_mnt)
|
||||
return 0;
|
||||
|
||||
nodename = device_get_nodename(dev, &tmp);
|
||||
nodename = device_get_devnode(dev, &mode, &tmp);
|
||||
if (!nodename)
|
||||
return -ENOMEM;
|
||||
|
||||
if (mode == 0)
|
||||
mode = 0600;
|
||||
if (is_blockdev(dev))
|
||||
mode = S_IFBLK|0600;
|
||||
mode |= S_IFBLK;
|
||||
else
|
||||
mode = S_IFCHR|0600;
|
||||
mode |= S_IFCHR;
|
||||
|
||||
curr_cred = override_creds(&init_cred);
|
||||
err = vfs_path_lookup(dev_mnt->mnt_root, dev_mnt,
|
||||
|
@ -165,8 +169,12 @@ int devtmpfs_create_node(struct device *dev)
|
|||
|
||||
dentry = lookup_create(&nd, 0);
|
||||
if (!IS_ERR(dentry)) {
|
||||
int umask;
|
||||
|
||||
umask = sys_umask(0000);
|
||||
err = vfs_mknod(nd.path.dentry->d_inode,
|
||||
dentry, mode, dev->devt);
|
||||
sys_umask(umask);
|
||||
/* mark as kernel created inode */
|
||||
if (!err)
|
||||
dentry->d_inode->i_private = &dev_mnt;
|
||||
|
@ -271,7 +279,7 @@ int devtmpfs_delete_node(struct device *dev)
|
|||
if (!dev_mnt)
|
||||
return 0;
|
||||
|
||||
nodename = device_get_nodename(dev, &tmp);
|
||||
nodename = device_get_devnode(dev, NULL, &tmp);
|
||||
if (!nodename)
|
||||
return -ENOMEM;
|
||||
|
||||
|
|
|
@ -266,7 +266,7 @@ static const struct file_operations aoe_fops = {
|
|||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static char *aoe_nodename(struct device *dev)
|
||||
static char *aoe_devnode(struct device *dev, mode_t *mode)
|
||||
{
|
||||
return kasprintf(GFP_KERNEL, "etherd/%s", dev_name(dev));
|
||||
}
|
||||
|
@ -288,7 +288,7 @@ aoechr_init(void)
|
|||
unregister_chrdev(AOE_MAJOR, "aoechr");
|
||||
return PTR_ERR(aoe_class);
|
||||
}
|
||||
aoe_class->nodename = aoe_nodename;
|
||||
aoe_class->devnode = aoe_devnode;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(chardevs); ++i)
|
||||
device_create(aoe_class, NULL,
|
||||
|
|
|
@ -2857,7 +2857,7 @@ static struct block_device_operations pktcdvd_ops = {
|
|||
.media_changed = pkt_media_changed,
|
||||
};
|
||||
|
||||
static char *pktcdvd_nodename(struct gendisk *gd)
|
||||
static char *pktcdvd_devnode(struct gendisk *gd, mode_t *mode)
|
||||
{
|
||||
return kasprintf(GFP_KERNEL, "pktcdvd/%s", gd->disk_name);
|
||||
}
|
||||
|
@ -2914,7 +2914,7 @@ static int pkt_setup_dev(dev_t dev, dev_t* pkt_dev)
|
|||
disk->fops = &pktcdvd_ops;
|
||||
disk->flags = GENHD_FL_REMOVABLE;
|
||||
strcpy(disk->disk_name, pd->name);
|
||||
disk->nodename = pktcdvd_nodename;
|
||||
disk->devnode = pktcdvd_devnode;
|
||||
disk->private_data = pd;
|
||||
disk->queue = blk_alloc_queue(GFP_KERNEL);
|
||||
if (!disk->queue)
|
||||
|
@ -3070,7 +3070,7 @@ static const struct file_operations pkt_ctl_fops = {
|
|||
static struct miscdevice pkt_misc = {
|
||||
.minor = MISC_DYNAMIC_MINOR,
|
||||
.name = DRIVER_NAME,
|
||||
.name = "pktcdvd/control",
|
||||
.nodename = "pktcdvd/control",
|
||||
.fops = &pkt_ctl_fops
|
||||
};
|
||||
|
||||
|
|
|
@ -153,7 +153,7 @@ static const struct file_operations rng_chrdev_ops = {
|
|||
static struct miscdevice rng_miscdev = {
|
||||
.minor = RNG_MISCDEV_MINOR,
|
||||
.name = RNG_MODULE_NAME,
|
||||
.devnode = "hwrng",
|
||||
.nodename = "hwrng",
|
||||
.fops = &rng_chrdev_ops,
|
||||
};
|
||||
|
||||
|
|
|
@ -866,24 +866,25 @@ static const struct file_operations kmsg_fops = {
|
|||
|
||||
static const struct memdev {
|
||||
const char *name;
|
||||
mode_t mode;
|
||||
const struct file_operations *fops;
|
||||
struct backing_dev_info *dev_info;
|
||||
} devlist[] = {
|
||||
[ 1] = { "mem", &mem_fops, &directly_mappable_cdev_bdi },
|
||||
[1] = { "mem", 0, &mem_fops, &directly_mappable_cdev_bdi },
|
||||
#ifdef CONFIG_DEVKMEM
|
||||
[ 2] = { "kmem", &kmem_fops, &directly_mappable_cdev_bdi },
|
||||
[2] = { "kmem", 0, &kmem_fops, &directly_mappable_cdev_bdi },
|
||||
#endif
|
||||
[ 3] = {"null", &null_fops, NULL },
|
||||
[3] = { "null", 0666, &null_fops, NULL },
|
||||
#ifdef CONFIG_DEVPORT
|
||||
[ 4] = { "port", &port_fops, NULL },
|
||||
[4] = { "port", 0, &port_fops, NULL },
|
||||
#endif
|
||||
[ 5] = { "zero", &zero_fops, &zero_bdi },
|
||||
[ 7] = { "full", &full_fops, NULL },
|
||||
[ 8] = { "random", &random_fops, NULL },
|
||||
[ 9] = { "urandom", &urandom_fops, NULL },
|
||||
[11] = { "kmsg", &kmsg_fops, NULL },
|
||||
[5] = { "zero", 0666, &zero_fops, &zero_bdi },
|
||||
[7] = { "full", 0666, &full_fops, NULL },
|
||||
[8] = { "random", 0666, &random_fops, NULL },
|
||||
[9] = { "urandom", 0666, &urandom_fops, NULL },
|
||||
[11] = { "kmsg", 0, &kmsg_fops, NULL },
|
||||
#ifdef CONFIG_CRASH_DUMP
|
||||
[12] = { "oldmem", &oldmem_fops, NULL },
|
||||
[12] = { "oldmem", 0, &oldmem_fops, NULL },
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -920,6 +921,13 @@ static const struct file_operations memory_fops = {
|
|||
.open = memory_open,
|
||||
};
|
||||
|
||||
static char *mem_devnode(struct device *dev, mode_t *mode)
|
||||
{
|
||||
if (mode && devlist[MINOR(dev->devt)].mode)
|
||||
*mode = devlist[MINOR(dev->devt)].mode;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct class *mem_class;
|
||||
|
||||
static int __init chr_dev_init(void)
|
||||
|
@ -935,6 +943,7 @@ static int __init chr_dev_init(void)
|
|||
printk("unable to get major %d for memory devs\n", MEM_MAJOR);
|
||||
|
||||
mem_class = class_create(THIS_MODULE, "mem");
|
||||
mem_class->devnode = mem_devnode;
|
||||
for (minor = 1; minor < ARRAY_SIZE(devlist); minor++) {
|
||||
if (!devlist[minor].name)
|
||||
continue;
|
||||
|
|
|
@ -263,12 +263,14 @@ int misc_deregister(struct miscdevice *misc)
|
|||
EXPORT_SYMBOL(misc_register);
|
||||
EXPORT_SYMBOL(misc_deregister);
|
||||
|
||||
static char *misc_nodename(struct device *dev)
|
||||
static char *misc_devnode(struct device *dev, mode_t *mode)
|
||||
{
|
||||
struct miscdevice *c = dev_get_drvdata(dev);
|
||||
|
||||
if (c->devnode)
|
||||
return kstrdup(c->devnode, GFP_KERNEL);
|
||||
if (mode && c->mode)
|
||||
*mode = c->mode;
|
||||
if (c->nodename)
|
||||
return kstrdup(c->nodename, GFP_KERNEL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -287,7 +289,7 @@ static int __init misc_init(void)
|
|||
err = -EIO;
|
||||
if (register_chrdev(MISC_MAJOR,"misc",&misc_fops))
|
||||
goto fail_printk;
|
||||
misc_class->nodename = misc_nodename;
|
||||
misc_class->devnode = misc_devnode;
|
||||
return 0;
|
||||
|
||||
fail_printk:
|
||||
|
|
|
@ -261,7 +261,7 @@ static const struct file_operations raw_ctl_fops = {
|
|||
|
||||
static struct cdev raw_cdev;
|
||||
|
||||
static char *raw_nodename(struct device *dev)
|
||||
static char *raw_devnode(struct device *dev, mode_t *mode)
|
||||
{
|
||||
return kasprintf(GFP_KERNEL, "raw/%s", dev_name(dev));
|
||||
}
|
||||
|
@ -289,7 +289,7 @@ static int __init raw_init(void)
|
|||
ret = PTR_ERR(raw_class);
|
||||
goto error_region;
|
||||
}
|
||||
raw_class->nodename = raw_nodename;
|
||||
raw_class->devnode = raw_devnode;
|
||||
device_create(raw_class, NULL, MKDEV(RAW_MAJOR, 0), NULL, "rawctl");
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -3056,11 +3056,22 @@ void __init console_init(void)
|
|||
}
|
||||
}
|
||||
|
||||
static char *tty_devnode(struct device *dev, mode_t *mode)
|
||||
{
|
||||
if (!mode)
|
||||
return NULL;
|
||||
if (dev->devt == MKDEV(TTYAUX_MAJOR, 0) ||
|
||||
dev->devt == MKDEV(TTYAUX_MAJOR, 2))
|
||||
*mode = 0666;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int __init tty_class_init(void)
|
||||
{
|
||||
tty_class = class_create(THIS_MODULE, "tty");
|
||||
if (IS_ERR(tty_class))
|
||||
return PTR_ERR(tty_class);
|
||||
tty_class->devnode = tty_devnode;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -76,7 +76,7 @@ static ssize_t version_show(struct class *dev, char *buf)
|
|||
CORE_MINOR, CORE_PATCHLEVEL, CORE_DATE);
|
||||
}
|
||||
|
||||
static char *drm_nodename(struct device *dev)
|
||||
static char *drm_devnode(struct device *dev, mode_t *mode)
|
||||
{
|
||||
return kasprintf(GFP_KERNEL, "dri/%s", dev_name(dev));
|
||||
}
|
||||
|
@ -112,7 +112,7 @@ struct class *drm_sysfs_create(struct module *owner, char *name)
|
|||
if (err)
|
||||
goto err_out_class;
|
||||
|
||||
class->nodename = drm_nodename;
|
||||
class->devnode = drm_devnode;
|
||||
|
||||
return class;
|
||||
|
||||
|
|
|
@ -852,14 +852,14 @@ static const struct file_operations hiddev_fops = {
|
|||
#endif
|
||||
};
|
||||
|
||||
static char *hiddev_nodename(struct device *dev)
|
||||
static char *hiddev_devnode(struct device *dev, mode_t *mode)
|
||||
{
|
||||
return kasprintf(GFP_KERNEL, "usb/%s", dev_name(dev));
|
||||
}
|
||||
|
||||
static struct usb_class_driver hiddev_class = {
|
||||
.name = "hiddev%d",
|
||||
.nodename = hiddev_nodename,
|
||||
.devnode = hiddev_devnode,
|
||||
.fops = &hiddev_fops,
|
||||
.minor_base = HIDDEV_MINOR_BASE,
|
||||
};
|
||||
|
|
|
@ -1265,14 +1265,14 @@ static struct device_type input_dev_type = {
|
|||
.uevent = input_dev_uevent,
|
||||
};
|
||||
|
||||
static char *input_nodename(struct device *dev)
|
||||
static char *input_devnode(struct device *dev, mode_t *mode)
|
||||
{
|
||||
return kasprintf(GFP_KERNEL, "input/%s", dev_name(dev));
|
||||
}
|
||||
|
||||
struct class input_class = {
|
||||
.name = "input",
|
||||
.nodename = input_nodename,
|
||||
.devnode = input_devnode,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(input_class);
|
||||
|
||||
|
|
|
@ -1532,7 +1532,7 @@ static const struct file_operations _ctl_fops = {
|
|||
static struct miscdevice _dm_misc = {
|
||||
.minor = MISC_DYNAMIC_MINOR,
|
||||
.name = DM_NAME,
|
||||
.devnode = "mapper/control",
|
||||
.nodename = "mapper/control",
|
||||
.fops = &_ctl_fops
|
||||
};
|
||||
|
||||
|
|
|
@ -447,7 +447,7 @@ static int dvb_uevent(struct device *dev, struct kobj_uevent_env *env)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static char *dvb_nodename(struct device *dev)
|
||||
static char *dvb_devnode(struct device *dev, mode_t *mode)
|
||||
{
|
||||
struct dvb_device *dvbdev = dev_get_drvdata(dev);
|
||||
|
||||
|
@ -478,7 +478,7 @@ static int __init init_dvbdev(void)
|
|||
goto error;
|
||||
}
|
||||
dvb_class->dev_uevent = dvb_uevent;
|
||||
dvb_class->nodename = dvb_nodename;
|
||||
dvb_class->devnode = dvb_devnode;
|
||||
return 0;
|
||||
|
||||
error:
|
||||
|
|
|
@ -1370,7 +1370,7 @@ static const struct file_operations tun_fops = {
|
|||
static struct miscdevice tun_miscdev = {
|
||||
.minor = TUN_MINOR,
|
||||
.name = "tun",
|
||||
.devnode = "net/tun",
|
||||
.nodename = "net/tun",
|
||||
.fops = &tun_fops,
|
||||
};
|
||||
|
||||
|
|
|
@ -1057,14 +1057,14 @@ static const struct file_operations usblp_fops = {
|
|||
.release = usblp_release,
|
||||
};
|
||||
|
||||
static char *usblp_nodename(struct device *dev)
|
||||
static char *usblp_devnode(struct device *dev, mode_t *mode)
|
||||
{
|
||||
return kasprintf(GFP_KERNEL, "usb/%s", dev_name(dev));
|
||||
}
|
||||
|
||||
static struct usb_class_driver usblp_class = {
|
||||
.name = "lp%d",
|
||||
.nodename = usblp_nodename,
|
||||
.devnode = usblp_devnode,
|
||||
.fops = &usblp_fops,
|
||||
.minor_base = USBLP_MINOR_BASE,
|
||||
};
|
||||
|
|
|
@ -67,14 +67,14 @@ static struct usb_class {
|
|||
struct class *class;
|
||||
} *usb_class;
|
||||
|
||||
static char *usb_nodename(struct device *dev)
|
||||
static char *usb_devnode(struct device *dev, mode_t *mode)
|
||||
{
|
||||
struct usb_class_driver *drv;
|
||||
|
||||
drv = dev_get_drvdata(dev);
|
||||
if (!drv || !drv->nodename)
|
||||
if (!drv || !drv->devnode)
|
||||
return NULL;
|
||||
return drv->nodename(dev);
|
||||
return drv->devnode(dev, mode);
|
||||
}
|
||||
|
||||
static int init_usb_class(void)
|
||||
|
@ -100,7 +100,7 @@ static int init_usb_class(void)
|
|||
kfree(usb_class);
|
||||
usb_class = NULL;
|
||||
}
|
||||
usb_class->class->nodename = usb_nodename;
|
||||
usb_class->class->devnode = usb_devnode;
|
||||
|
||||
exit:
|
||||
return result;
|
||||
|
|
|
@ -311,7 +311,7 @@ static struct dev_pm_ops usb_device_pm_ops = {
|
|||
#endif /* CONFIG_PM */
|
||||
|
||||
|
||||
static char *usb_nodename(struct device *dev)
|
||||
static char *usb_devnode(struct device *dev, mode_t *mode)
|
||||
{
|
||||
struct usb_device *usb_dev;
|
||||
|
||||
|
@ -324,7 +324,7 @@ struct device_type usb_device_type = {
|
|||
.name = "usb_device",
|
||||
.release = usb_release_dev,
|
||||
.uevent = usb_dev_uevent,
|
||||
.nodename = usb_nodename,
|
||||
.devnode = usb_devnode,
|
||||
.pm = &usb_device_pm_ops,
|
||||
};
|
||||
|
||||
|
|
|
@ -727,7 +727,7 @@ static const struct file_operations iowarrior_fops = {
|
|||
.poll = iowarrior_poll,
|
||||
};
|
||||
|
||||
static char *iowarrior_nodename(struct device *dev)
|
||||
static char *iowarrior_devnode(struct device *dev, mode_t *mode)
|
||||
{
|
||||
return kasprintf(GFP_KERNEL, "usb/%s", dev_name(dev));
|
||||
}
|
||||
|
@ -738,7 +738,7 @@ static char *iowarrior_nodename(struct device *dev)
|
|||
*/
|
||||
static struct usb_class_driver iowarrior_class = {
|
||||
.name = "iowarrior%d",
|
||||
.nodename = iowarrior_nodename,
|
||||
.devnode = iowarrior_devnode,
|
||||
.fops = &iowarrior_fops,
|
||||
.minor_base = IOWARRIOR_MINOR_BASE,
|
||||
};
|
||||
|
|
|
@ -266,7 +266,7 @@ static const struct file_operations tower_fops = {
|
|||
.llseek = tower_llseek,
|
||||
};
|
||||
|
||||
static char *legousbtower_nodename(struct device *dev)
|
||||
static char *legousbtower_devnode(struct device *dev, mode_t *mode)
|
||||
{
|
||||
return kasprintf(GFP_KERNEL, "usb/%s", dev_name(dev));
|
||||
}
|
||||
|
@ -277,7 +277,7 @@ static char *legousbtower_nodename(struct device *dev)
|
|||
*/
|
||||
static struct usb_class_driver tower_class = {
|
||||
.name = "legousbtower%d",
|
||||
.nodename = legousbtower_nodename,
|
||||
.devnode = legousbtower_devnode,
|
||||
.fops = &tower_fops,
|
||||
.minor_base = LEGO_USB_TOWER_MINOR_BASE,
|
||||
};
|
||||
|
|
|
@ -193,7 +193,7 @@ struct class {
|
|||
struct kobject *dev_kobj;
|
||||
|
||||
int (*dev_uevent)(struct device *dev, struct kobj_uevent_env *env);
|
||||
char *(*nodename)(struct device *dev);
|
||||
char *(*devnode)(struct device *dev, mode_t *mode);
|
||||
|
||||
void (*class_release)(struct class *class);
|
||||
void (*dev_release)(struct device *dev);
|
||||
|
@ -298,7 +298,7 @@ struct device_type {
|
|||
const char *name;
|
||||
const struct attribute_group **groups;
|
||||
int (*uevent)(struct device *dev, struct kobj_uevent_env *env);
|
||||
char *(*nodename)(struct device *dev);
|
||||
char *(*devnode)(struct device *dev, mode_t *mode);
|
||||
void (*release)(struct device *dev);
|
||||
|
||||
const struct dev_pm_ops *pm;
|
||||
|
@ -487,7 +487,8 @@ extern struct device *device_find_child(struct device *dev, void *data,
|
|||
extern int device_rename(struct device *dev, char *new_name);
|
||||
extern int device_move(struct device *dev, struct device *new_parent,
|
||||
enum dpm_order dpm_order);
|
||||
extern const char *device_get_nodename(struct device *dev, const char **tmp);
|
||||
extern const char *device_get_devnode(struct device *dev,
|
||||
mode_t *mode, const char **tmp);
|
||||
extern void *dev_get_drvdata(const struct device *dev);
|
||||
extern void dev_set_drvdata(struct device *dev, void *data);
|
||||
|
||||
|
|
|
@ -142,7 +142,7 @@ struct gendisk {
|
|||
* disks that can't be partitioned. */
|
||||
|
||||
char disk_name[DISK_NAME_LEN]; /* name of major driver */
|
||||
char *(*nodename)(struct gendisk *gd);
|
||||
char *(*devnode)(struct gendisk *gd, mode_t *mode);
|
||||
/* Array of pointers to partitions indexed by partno.
|
||||
* Protected with matching bdev lock but stat and other
|
||||
* non-critical accesses use RCU. Always access through
|
||||
|
|
|
@ -41,7 +41,8 @@ struct miscdevice {
|
|||
struct list_head list;
|
||||
struct device *parent;
|
||||
struct device *this_device;
|
||||
const char *devnode;
|
||||
const char *nodename;
|
||||
mode_t mode;
|
||||
};
|
||||
|
||||
extern int misc_register(struct miscdevice * misc);
|
||||
|
|
|
@ -922,7 +922,7 @@ extern struct bus_type usb_bus_type;
|
|||
/**
|
||||
* struct usb_class_driver - identifies a USB driver that wants to use the USB major number
|
||||
* @name: the usb class device name for this driver. Will show up in sysfs.
|
||||
* @nodename: Callback to provide a naming hint for a possible
|
||||
* @devnode: Callback to provide a naming hint for a possible
|
||||
* device node to create.
|
||||
* @fops: pointer to the struct file_operations of this driver.
|
||||
* @minor_base: the start of the minor range for this driver.
|
||||
|
@ -933,7 +933,7 @@ extern struct bus_type usb_bus_type;
|
|||
*/
|
||||
struct usb_class_driver {
|
||||
char *name;
|
||||
char *(*nodename)(struct device *dev);
|
||||
char *(*devnode)(struct device *dev, mode_t *mode);
|
||||
const struct file_operations *fops;
|
||||
int minor_base;
|
||||
};
|
||||
|
|
|
@ -29,7 +29,7 @@ MODULE_DESCRIPTION("Core sound module");
|
|||
MODULE_AUTHOR("Alan Cox");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
static char *sound_nodename(struct device *dev)
|
||||
static char *sound_devnode(struct device *dev, mode_t *mode)
|
||||
{
|
||||
if (MAJOR(dev->devt) == SOUND_MAJOR)
|
||||
return NULL;
|
||||
|
@ -50,7 +50,7 @@ static int __init init_soundcore(void)
|
|||
return PTR_ERR(sound_class);
|
||||
}
|
||||
|
||||
sound_class->nodename = sound_nodename;
|
||||
sound_class->devnode = sound_devnode;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue