mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 17:47:41 +02:00
driver core: Allow the constification of device attributes
Allow device attribute to reside in read-only memory. Both const and non-const attributes are handled by the utility macros and attributes can be migrated one-by-one. Signed-off-by: Thomas Weißschuh <linux@weissschuh.net> Link: https://patch.msgid.link/20260512-sysfs-const-attr-device_attr-prep-v3-4-cb7c17b34d52@weissschuh.net Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
13443fbf62
commit
434506b86a
|
|
@ -2485,9 +2485,11 @@ static ssize_t dev_attr_show(struct kobject *kobj, struct attribute *attr,
|
|||
|
||||
if (dev_attr->show)
|
||||
ret = dev_attr->show(dev, dev_attr, buf);
|
||||
else if (dev_attr->show_const)
|
||||
ret = dev_attr->show_const(dev, dev_attr, buf);
|
||||
if (ret >= (ssize_t)PAGE_SIZE) {
|
||||
printk("dev_attr_show: %pS returned bad count\n",
|
||||
dev_attr->show);
|
||||
printk("dev_attr_show: %pS/%pS returned bad count\n",
|
||||
dev_attr->show, dev_attr->show_const);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -2501,6 +2503,8 @@ static ssize_t dev_attr_store(struct kobject *kobj, struct attribute *attr,
|
|||
|
||||
if (dev_attr->store)
|
||||
ret = dev_attr->store(dev, dev_attr, buf, count);
|
||||
else if (dev_attr->store_const)
|
||||
ret = dev_attr->store_const(dev, dev_attr, buf, count);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -3113,10 +3117,10 @@ int device_create_file(struct device *dev,
|
|||
int error = 0;
|
||||
|
||||
if (dev) {
|
||||
WARN(((attr->attr.mode & S_IWUGO) && !attr->store),
|
||||
WARN(((attr->attr.mode & S_IWUGO) && !(attr->store || attr->store_const)),
|
||||
"Attribute %s: write permission without 'store'\n",
|
||||
attr->attr.name);
|
||||
WARN(((attr->attr.mode & S_IRUGO) && !attr->show),
|
||||
WARN(((attr->attr.mode & S_IRUGO) && !(attr->show || attr->show_const)),
|
||||
"Attribute %s: read permission without 'show'\n",
|
||||
attr->attr.name);
|
||||
error = sysfs_create_file(&dev->kobj, &attr->attr);
|
||||
|
|
|
|||
|
|
@ -103,10 +103,18 @@ struct device_type {
|
|||
*/
|
||||
struct device_attribute {
|
||||
struct attribute attr;
|
||||
ssize_t (*show)(struct device *dev, struct device_attribute *attr,
|
||||
char *buf);
|
||||
ssize_t (*store)(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count);
|
||||
__SYSFS_FUNCTION_ALTERNATIVE(
|
||||
ssize_t (*show)(struct device *dev, struct device_attribute *attr,
|
||||
char *buf);
|
||||
ssize_t (*show_const)(struct device *dev, const struct device_attribute *attr,
|
||||
char *buf);
|
||||
);
|
||||
__SYSFS_FUNCTION_ALTERNATIVE(
|
||||
ssize_t (*store)(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count);
|
||||
ssize_t (*store_const)(struct device *dev, const struct device_attribute *attr,
|
||||
const char *buf, size_t count);
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -134,11 +142,50 @@ ssize_t device_store_bool(struct device *dev, struct device_attribute *attr,
|
|||
ssize_t device_show_string(struct device *dev, struct device_attribute *attr,
|
||||
char *buf);
|
||||
|
||||
typedef ssize_t __device_show_handler_const(struct device *dev, const struct device_attribute *attr,
|
||||
char *buf);
|
||||
typedef ssize_t __device_store_handler_const(struct device *dev, const struct device_attribute *attr,
|
||||
const char *buf, size_t count);
|
||||
|
||||
#ifdef CONFIG_CFI
|
||||
|
||||
#define __DEVICE_ATTR_SHOW_STORE(_show, _store) \
|
||||
.show = _Generic(_show, \
|
||||
__device_show_handler_const * : NULL, \
|
||||
default : _show \
|
||||
), \
|
||||
.show_const = _Generic(_show, \
|
||||
__device_show_handler_const * : _show, \
|
||||
default : NULL \
|
||||
), \
|
||||
.store = _Generic(_store, \
|
||||
__device_store_handler_const * : NULL, \
|
||||
default : _store \
|
||||
), \
|
||||
.store_const = _Generic(_store, \
|
||||
__device_store_handler_const * : _store, \
|
||||
default : NULL \
|
||||
),
|
||||
|
||||
#else
|
||||
|
||||
#define __DEVICE_ATTR_SHOW_STORE(_show, _store) \
|
||||
.show = _Generic(_show, \
|
||||
__device_show_handler_const * : (void *)_show, \
|
||||
default : _show \
|
||||
), \
|
||||
.store = _Generic(_store, \
|
||||
__device_store_handler_const * : (void *)_store, \
|
||||
default : _store \
|
||||
), \
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#define __DEVICE_ATTR(_name, _mode, _show, _store) { \
|
||||
.attr = {.name = __stringify(_name), \
|
||||
.mode = VERIFY_OCTAL_PERMISSIONS(_mode) }, \
|
||||
.show = _show, \
|
||||
.store = _store, \
|
||||
__DEVICE_ATTR_SHOW_STORE(_show, _store) \
|
||||
}
|
||||
|
||||
#define __DEVICE_ATTR_RO_MODE(_name, _mode) \
|
||||
|
|
@ -160,8 +207,7 @@ ssize_t device_show_string(struct device *dev, struct device_attribute *attr,
|
|||
#define __DEVICE_ATTR_IGNORE_LOCKDEP(_name, _mode, _show, _store) { \
|
||||
.attr = {.name = __stringify(_name), .mode = _mode, \
|
||||
.ignore_lockdep = true }, \
|
||||
.show = _show, \
|
||||
.store = _store, \
|
||||
__DEVICE_ATTR_SHOW_STORE(_show, _store) \
|
||||
}
|
||||
#else
|
||||
#define __DEVICE_ATTR_IGNORE_LOCKDEP __DEVICE_ATTR
|
||||
|
|
@ -220,8 +266,7 @@ ssize_t device_show_string(struct device *dev, struct device_attribute *attr,
|
|||
#define DEVICE_ATTR_RW_NAMED(_name, _attrname) \
|
||||
struct device_attribute dev_attr_##_name = { \
|
||||
.attr = { .name = _attrname, .mode = 0644 }, \
|
||||
.show = _name##_show, \
|
||||
.store = _name##_store, \
|
||||
__DEVICE_ATTR_SHOW_STORE(_name##_show, _name##_store) \
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -254,7 +299,7 @@ ssize_t device_show_string(struct device *dev, struct device_attribute *attr,
|
|||
#define DEVICE_ATTR_RO_NAMED(_name, _attrname) \
|
||||
struct device_attribute dev_attr_##_name = { \
|
||||
.attr = { .name = _attrname, .mode = 0444 }, \
|
||||
.show = _name##_show, \
|
||||
__DEVICE_ATTR_SHOW_STORE(_name##_show, NULL) \
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -278,7 +323,7 @@ ssize_t device_show_string(struct device *dev, struct device_attribute *attr,
|
|||
#define DEVICE_ATTR_WO_NAMED(_name, _attrname) \
|
||||
struct device_attribute dev_attr_##_name = { \
|
||||
.attr = { .name = _attrname, .mode = 0200 }, \
|
||||
.store = _name##_store, \
|
||||
__DEVICE_ATTR_SHOW_STORE(NULL, _name##_store) \
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user