18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci#ifndef _BCACHE_SYSFS_H_ 38c2ecf20Sopenharmony_ci#define _BCACHE_SYSFS_H_ 48c2ecf20Sopenharmony_ci 58c2ecf20Sopenharmony_ci#define KTYPE(type) \ 68c2ecf20Sopenharmony_cistruct kobj_type type ## _ktype = { \ 78c2ecf20Sopenharmony_ci .release = type ## _release, \ 88c2ecf20Sopenharmony_ci .sysfs_ops = &((const struct sysfs_ops) { \ 98c2ecf20Sopenharmony_ci .show = type ## _show, \ 108c2ecf20Sopenharmony_ci .store = type ## _store \ 118c2ecf20Sopenharmony_ci }), \ 128c2ecf20Sopenharmony_ci .default_attrs = type ## _files \ 138c2ecf20Sopenharmony_ci} 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_ci#define SHOW(fn) \ 168c2ecf20Sopenharmony_cistatic ssize_t fn ## _show(struct kobject *kobj, struct attribute *attr,\ 178c2ecf20Sopenharmony_ci char *buf) \ 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci#define STORE(fn) \ 208c2ecf20Sopenharmony_cistatic ssize_t fn ## _store(struct kobject *kobj, struct attribute *attr,\ 218c2ecf20Sopenharmony_ci const char *buf, size_t size) \ 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ci#define SHOW_LOCKED(fn) \ 248c2ecf20Sopenharmony_ciSHOW(fn) \ 258c2ecf20Sopenharmony_ci{ \ 268c2ecf20Sopenharmony_ci ssize_t ret; \ 278c2ecf20Sopenharmony_ci mutex_lock(&bch_register_lock); \ 288c2ecf20Sopenharmony_ci ret = __ ## fn ## _show(kobj, attr, buf); \ 298c2ecf20Sopenharmony_ci mutex_unlock(&bch_register_lock); \ 308c2ecf20Sopenharmony_ci return ret; \ 318c2ecf20Sopenharmony_ci} 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ci#define STORE_LOCKED(fn) \ 348c2ecf20Sopenharmony_ciSTORE(fn) \ 358c2ecf20Sopenharmony_ci{ \ 368c2ecf20Sopenharmony_ci ssize_t ret; \ 378c2ecf20Sopenharmony_ci mutex_lock(&bch_register_lock); \ 388c2ecf20Sopenharmony_ci ret = __ ## fn ## _store(kobj, attr, buf, size); \ 398c2ecf20Sopenharmony_ci mutex_unlock(&bch_register_lock); \ 408c2ecf20Sopenharmony_ci return ret; \ 418c2ecf20Sopenharmony_ci} 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci#define __sysfs_attribute(_name, _mode) \ 448c2ecf20Sopenharmony_ci static struct attribute sysfs_##_name = \ 458c2ecf20Sopenharmony_ci { .name = #_name, .mode = _mode } 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_ci#define write_attribute(n) __sysfs_attribute(n, 0200) 488c2ecf20Sopenharmony_ci#define read_attribute(n) __sysfs_attribute(n, 0444) 498c2ecf20Sopenharmony_ci#define rw_attribute(n) __sysfs_attribute(n, 0644) 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_ci#define sysfs_printf(file, fmt, ...) \ 528c2ecf20Sopenharmony_cido { \ 538c2ecf20Sopenharmony_ci if (attr == &sysfs_ ## file) \ 548c2ecf20Sopenharmony_ci return snprintf(buf, PAGE_SIZE, fmt "\n", __VA_ARGS__); \ 558c2ecf20Sopenharmony_ci} while (0) 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_ci#define sysfs_print(file, var) \ 588c2ecf20Sopenharmony_cido { \ 598c2ecf20Sopenharmony_ci if (attr == &sysfs_ ## file) \ 608c2ecf20Sopenharmony_ci return snprint(buf, PAGE_SIZE, var); \ 618c2ecf20Sopenharmony_ci} while (0) 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_ci#define sysfs_hprint(file, val) \ 648c2ecf20Sopenharmony_cido { \ 658c2ecf20Sopenharmony_ci if (attr == &sysfs_ ## file) { \ 668c2ecf20Sopenharmony_ci ssize_t ret = bch_hprint(buf, val); \ 678c2ecf20Sopenharmony_ci strcat(buf, "\n"); \ 688c2ecf20Sopenharmony_ci return ret + 1; \ 698c2ecf20Sopenharmony_ci } \ 708c2ecf20Sopenharmony_ci} while (0) 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ci#define var_printf(_var, fmt) sysfs_printf(_var, fmt, var(_var)) 738c2ecf20Sopenharmony_ci#define var_print(_var) sysfs_print(_var, var(_var)) 748c2ecf20Sopenharmony_ci#define var_hprint(_var) sysfs_hprint(_var, var(_var)) 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_ci#define sysfs_strtoul(file, var) \ 778c2ecf20Sopenharmony_cido { \ 788c2ecf20Sopenharmony_ci if (attr == &sysfs_ ## file) \ 798c2ecf20Sopenharmony_ci return strtoul_safe(buf, var) ?: (ssize_t) size; \ 808c2ecf20Sopenharmony_ci} while (0) 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_ci#define sysfs_strtoul_bool(file, var) \ 838c2ecf20Sopenharmony_cido { \ 848c2ecf20Sopenharmony_ci if (attr == &sysfs_ ## file) { \ 858c2ecf20Sopenharmony_ci unsigned long v = strtoul_or_return(buf); \ 868c2ecf20Sopenharmony_ci \ 878c2ecf20Sopenharmony_ci var = v ? 1 : 0; \ 888c2ecf20Sopenharmony_ci return size; \ 898c2ecf20Sopenharmony_ci } \ 908c2ecf20Sopenharmony_ci} while (0) 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_ci#define sysfs_strtoul_clamp(file, var, min, max) \ 938c2ecf20Sopenharmony_cido { \ 948c2ecf20Sopenharmony_ci if (attr == &sysfs_ ## file) { \ 958c2ecf20Sopenharmony_ci unsigned long v = 0; \ 968c2ecf20Sopenharmony_ci ssize_t ret; \ 978c2ecf20Sopenharmony_ci ret = strtoul_safe_clamp(buf, v, min, max); \ 988c2ecf20Sopenharmony_ci if (!ret) { \ 998c2ecf20Sopenharmony_ci var = v; \ 1008c2ecf20Sopenharmony_ci return size; \ 1018c2ecf20Sopenharmony_ci } \ 1028c2ecf20Sopenharmony_ci return ret; \ 1038c2ecf20Sopenharmony_ci } \ 1048c2ecf20Sopenharmony_ci} while (0) 1058c2ecf20Sopenharmony_ci 1068c2ecf20Sopenharmony_ci#define strtoul_or_return(cp) \ 1078c2ecf20Sopenharmony_ci({ \ 1088c2ecf20Sopenharmony_ci unsigned long _v; \ 1098c2ecf20Sopenharmony_ci int _r = kstrtoul(cp, 10, &_v); \ 1108c2ecf20Sopenharmony_ci if (_r) \ 1118c2ecf20Sopenharmony_ci return _r; \ 1128c2ecf20Sopenharmony_ci _v; \ 1138c2ecf20Sopenharmony_ci}) 1148c2ecf20Sopenharmony_ci 1158c2ecf20Sopenharmony_ci#define strtoi_h_or_return(cp, v) \ 1168c2ecf20Sopenharmony_cido { \ 1178c2ecf20Sopenharmony_ci int _r = strtoi_h(cp, &v); \ 1188c2ecf20Sopenharmony_ci if (_r) \ 1198c2ecf20Sopenharmony_ci return _r; \ 1208c2ecf20Sopenharmony_ci} while (0) 1218c2ecf20Sopenharmony_ci 1228c2ecf20Sopenharmony_ci#define sysfs_hatoi(file, var) \ 1238c2ecf20Sopenharmony_cido { \ 1248c2ecf20Sopenharmony_ci if (attr == &sysfs_ ## file) \ 1258c2ecf20Sopenharmony_ci return strtoi_h(buf, &var) ?: (ssize_t) size; \ 1268c2ecf20Sopenharmony_ci} while (0) 1278c2ecf20Sopenharmony_ci 1288c2ecf20Sopenharmony_ci#endif /* _BCACHE_SYSFS_H_ */ 129