diff options
author | Mark Farrugia <mark.farrugia@fiberdyne.com.au> | 2019-03-01 17:20:29 +1100 |
---|---|---|
committer | Mark Farrugia <mark.farrugia@fiberdyne.com.au> | 2019-03-01 17:20:29 +1100 |
commit | 763bbd2abc251d351746bfddfbac9d39a74e4492 (patch) | |
tree | f412bc93576ccddd26f3c52a2243e2d2cbbd5bac | |
parent | 443bdab5db1cd5494e94aa7031c4a25e33a9c6bb (diff) |
Move sysfs functionality to sysfs.c
Signed-off-by: Mark Farrugia <mark.farrugia@fiberdyne.com.au>
-rw-r--r-- | Makefile | 1 | ||||
-rw-r--r-- | core.c | 183 | ||||
-rw-r--r-- | core.h | 34 | ||||
-rw-r--r-- | sysfs.c | 174 |
4 files changed, 218 insertions, 174 deletions
@@ -3,6 +3,7 @@ obj-$(CONFIG_AVIRT) += snd-avirt-core.o snd-avirt-core-y := core.o snd-avirt-core-y += pcm.o snd-avirt-core-y += configfs.o +snd-avirt-core-y += sysfs.o ifeq ($(CONFIG_AVIRT_BUILDLOCAL),) CCFLAGS_AVIRT := "drivers/staging/" @@ -40,168 +40,6 @@ static struct snd_avirt_core core = { static LIST_HEAD(audiopath_list); -struct snd_avirt_audiopath_obj { - struct kobject kobj; - struct list_head list; - struct snd_avirt_audiopath *path; -}; - -static struct kset *snd_avirt_audiopath_kset; -static struct kobject *kobj; - -#define to_audiopath_obj(d) \ - container_of(d, struct snd_avirt_audiopath_obj, kobj) -#define to_audiopath_attr(a) \ - container_of(a, struct snd_avirt_audiopath_attribute, attr) - -/** - * struct snd_avirt_audiopath_attribute - access the attributes of Audio Path - * @attr: attributes of an Audio Path - * @show: pointer to the show function - * @store: pointer to the store function - */ -struct snd_avirt_audiopath_attribute { - struct attribute attr; - ssize_t (*show)(struct snd_avirt_audiopath_obj *d, - struct snd_avirt_audiopath_attribute *attr, char *buf); - ssize_t (*store)(struct snd_avirt_audiopath_obj *d, - struct snd_avirt_audiopath_attribute *attr, - const char *buf, size_t count); -}; - -/** - * audiopath_attr_show - show function of an Audio Path - * @kobj: pointer to kobject - * @attr: pointer to attribute struct - * @buf: buffer - */ -static ssize_t audiopath_attr_show(struct kobject *kobj, struct attribute *attr, - char *buf) -{ - struct snd_avirt_audiopath_attribute *audiopath_attr; - struct snd_avirt_audiopath_obj *audiopath_obj; - - audiopath_attr = to_audiopath_attr(attr); - audiopath_obj = to_audiopath_obj(kobj); - - if (!audiopath_attr->show) - return -EIO; - - return audiopath_attr->show(audiopath_obj, audiopath_attr, buf); -} - -/** - * audiopath_attr_store - attribute store function of Audio Path object - * @kobj: pointer to kobject - * @attr: pointer to attribute struct - * @buf: buffer - * @len: length of buffer - */ -static ssize_t audiopath_attr_store(struct kobject *kobj, - struct attribute *attr, const char *buf, - size_t len) -{ - struct snd_avirt_audiopath_attribute *audiopath_attr; - struct snd_avirt_audiopath_obj *audiopath_obj; - - audiopath_attr = to_audiopath_attr(attr); - audiopath_obj = to_audiopath_obj(kobj); - - if (!audiopath_attr->store) - return -EIO; - return audiopath_attr->store(audiopath_obj, audiopath_attr, buf, len); -} - -static const struct sysfs_ops snd_avirt_audiopath_sysfs_ops = { - .show = audiopath_attr_show, - .store = audiopath_attr_store, -}; - -/** - * snd_avirt_audiopath_release - Audio Path release function - * @kobj: pointer to Audio Paths's kobject - */ -static void snd_avirt_audiopath_release(struct kobject *kobj) -{ - struct snd_avirt_audiopath_obj *audiopath_obj = to_audiopath_obj(kobj); - - kfree(audiopath_obj); -} - -static ssize_t - audiopath_name_show(struct snd_avirt_audiopath_obj *audiopath_obj, - struct snd_avirt_audiopath_attribute *attr, - char *buf) -{ - return sprintf(buf, "%s\n", audiopath_obj->path->name); -} - -static ssize_t - audiopath_version_show(struct snd_avirt_audiopath_obj *audiopath_obj, - struct snd_avirt_audiopath_attribute *attr, - char *buf) -{ - struct snd_avirt_audiopath *audiopath = audiopath_obj->path; - - return sprintf(buf, "%d.%d.%d\n", audiopath->version[0], - audiopath->version[1], audiopath->version[2]); -} - -static struct snd_avirt_audiopath_attribute snd_avirt_audiopath_attrs[] = { - __ATTR_RO(audiopath_name), - __ATTR_RO(audiopath_version), -}; - -static struct attribute *snd_avirt_audiopath_def_attrs[] = { - &snd_avirt_audiopath_attrs[0].attr, - &snd_avirt_audiopath_attrs[1].attr, - NULL, -}; - -static struct kobj_type snd_avirt_audiopath_ktype = { - .sysfs_ops = &snd_avirt_audiopath_sysfs_ops, - .release = snd_avirt_audiopath_release, - .default_attrs = snd_avirt_audiopath_def_attrs, -}; - -/** - * create_snd_avirt_audiopath_obj - creates an Audio Path object - * @uid: Unique ID of the Audio Path - * - * This creates an Audio Path object and assigns the kset and registers - * it with sysfs. - * @return: Pointer to the Audio Path object or NULL if it failed. - */ -static struct snd_avirt_audiopath_obj * - create_snd_avirt_audiopath_obj(const char *uid) -{ - struct snd_avirt_audiopath_obj *snd_avirt_audiopath; - int retval; - - snd_avirt_audiopath = kzalloc(sizeof(*snd_avirt_audiopath), GFP_KERNEL); - if (!snd_avirt_audiopath) - return NULL; - snd_avirt_audiopath->kobj.kset = snd_avirt_audiopath_kset; - retval = kobject_init_and_add(&snd_avirt_audiopath->kobj, - &snd_avirt_audiopath_ktype, kobj, "%s", - uid); - if (retval) { - kobject_put(&snd_avirt_audiopath->kobj); - return NULL; - } - kobject_uevent(&snd_avirt_audiopath->kobj, KOBJ_ADD); - return snd_avirt_audiopath; -} - -/** - * destroy_snd_avirt_audiopath_obj - destroys an Audio Path object - * @name: the Audio Path object - */ -static void destroy_snd_avirt_audiopath_obj(struct snd_avirt_audiopath_obj *p) -{ - kobject_put(&p->kobj); -} - /** * pcm_private_free - callback function to free private data allocated to pcm * @pcm: the PCM object @@ -375,7 +213,7 @@ int snd_avirt_audiopath_register(struct snd_avirt_audiopath *audiopath) return -EINVAL; } - audiopath_obj = create_snd_avirt_audiopath_obj(audiopath->uid); + audiopath_obj = snd_avirt_audiopath_create_obj(audiopath->uid); if (!audiopath_obj) { D_INFOK("Failed to alloc driver object"); return -ENOMEM; @@ -420,7 +258,7 @@ int snd_avirt_audiopath_deregister(struct snd_avirt_audiopath *audiopath) } list_del(&audiopath_obj->list); - destroy_snd_avirt_audiopath_obj(audiopath_obj); + snd_avirt_audiopath_destroy_obj(audiopath_obj); D_INFOK("Deregistered Audio Path %s", audiopath->uid); return 0; @@ -587,18 +425,15 @@ static int __init snd_avirt_core_init(void) return PTR_ERR(core.class); } - core.dev = device_create(core.class, NULL, 0, NULL, "avirtcore"); + core.dev = device_create(core.class, NULL, 0, NULL, "core"); if (IS_ERR(core.dev)) { err = PTR_ERR(core.dev); goto exit_class; } - snd_avirt_audiopath_kset = - kset_create_and_add("audiopaths", NULL, &core.dev->kobj); - if (!snd_avirt_audiopath_kset) { - err = -ENOMEM; + err = snd_avirt_sysfs_init(&core); + if (err < 0) goto exit_class_container; - } err = snd_card_register(core.card); if (err < 0) { @@ -608,12 +443,12 @@ static int __init snd_avirt_core_init(void) err = snd_avirt_configfs_init(&core); if (err < 0) - goto exit_kset; + goto exit_sysfs; return 0; -exit_kset: - kset_unregister(snd_avirt_audiopath_kset); +exit_sysfs: + snd_avirt_sysfs_exit(&core); exit_class_container: device_destroy(core.class, 0); exit_class: @@ -631,7 +466,7 @@ exit_platform_device: static void __exit snd_avirt_core_exit(void) { snd_avirt_configfs_exit(&core); - kset_unregister(snd_avirt_audiopath_kset); + snd_avirt_sysfs_exit(&core); device_destroy(core.class, 0); class_destroy(core.class); platform_device_unregister(core.plat_dev); @@ -27,6 +27,12 @@ struct snd_avirt_core { bool streams_sealed; }; +struct snd_avirt_audiopath_obj { + struct kobject kobj; + struct list_head list; + struct snd_avirt_audiopath *path; +}; + /** * snd_avirt_configfs_init - Initialise the configfs system * @core: The snd_avirt_core pointer @@ -41,6 +47,34 @@ int __init snd_avirt_configfs_init(struct snd_avirt_core *core); void __exit snd_avirt_configfs_exit(struct snd_avirt_core *core); /** + * snd_avirt_sysfs_init - Initialise the sysfs system + * @core: The snd_avirt_core pointer + * @return: 0 on success, negative ERRNO on failure + */ +int __init snd_avirt_sysfs_init(struct snd_avirt_core *core); + +/** + * snd_avirt_sysfs_exit - Clean up and exit the sysfs system + * @core: The snd_avirt_core pointer + */ +void __exit snd_avirt_sysfs_exit(struct snd_avirt_core *core); + +/** + * snd_avirt_audiopath_obj - creates an Audio Path object, assigns the kset + * and registers it with sysfs. + * @uid: Unique ID of the Audio Path + * @return: Pointer to the Audio Path object or NULL if it failed. + */ +struct snd_avirt_audiopath_obj *snd_avirt_audiopath_create_obj(const char *uid); + +/** + * snd_avirt_audiopath_destroy_obj - destroys an Audio Path object, deregisters + * it with sysfs + * @name: the Audio Path object + */ +void snd_avirt_audiopath_destroy_obj(struct snd_avirt_audiopath_obj *p); + +/** * snd_avirt_streams_seal - Register the sound card to user space * @return: 0 on success, negative ERRNO on failure */ @@ -0,0 +1,174 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * AVIRT - ALSA Virtual Soundcard + * + * Copyright (c) 2010-2019 Fiberdyne Systems Pty Ltd + * + * configfs.c - AVIRT sysfs support + */ + +#include <linux/slab.h> + +#include "core.h" + +#define D_LOGNAME "sysfs" + +#define D_INFOK(fmt, args...) DINFO(D_LOGNAME, fmt, ##args) +#define D_PRINTK(fmt, args...) DDEBUG(D_LOGNAME, fmt, ##args) +#define D_ERRORK(fmt, args...) DERROR(D_LOGNAME, fmt, ##args) + +static struct kset *snd_avirt_audiopath_kset; +static struct kobject *kobj; + +#define to_audiopath_obj(d) \ + container_of(d, struct snd_avirt_audiopath_obj, kobj) +#define to_audiopath_attr(a) \ + container_of(a, struct snd_avirt_audiopath_attribute, attr) + +/** + * struct snd_avirt_audiopath_attribute - access the attributes of Audio Path + * @attr: attributes of an Audio Path + * @show: pointer to the show function + * @store: pointer to the store function + */ +struct snd_avirt_audiopath_attribute { + struct attribute attr; + ssize_t (*show)(struct snd_avirt_audiopath_obj *d, + struct snd_avirt_audiopath_attribute *attr, char *buf); + ssize_t (*store)(struct snd_avirt_audiopath_obj *d, + struct snd_avirt_audiopath_attribute *attr, + const char *buf, size_t count); +}; + +/** + * audiopath_attr_show - show function of an Audio Path + * @kobj: pointer to kobject + * @attr: pointer to attribute struct + * @buf: buffer + */ +static ssize_t audiopath_attr_show(struct kobject *kobj, struct attribute *attr, + char *buf) +{ + struct snd_avirt_audiopath_attribute *audiopath_attr; + struct snd_avirt_audiopath_obj *audiopath_obj; + + audiopath_attr = to_audiopath_attr(attr); + audiopath_obj = to_audiopath_obj(kobj); + + if (!audiopath_attr->show) + return -EIO; + + return audiopath_attr->show(audiopath_obj, audiopath_attr, buf); +} + +/** + * audiopath_attr_store - attribute store function of Audio Path object + * @kobj: pointer to kobject + * @attr: pointer to attribute struct + * @buf: buffer + * @len: length of buffer + */ +static ssize_t audiopath_attr_store(struct kobject *kobj, + struct attribute *attr, const char *buf, + size_t len) +{ + struct snd_avirt_audiopath_attribute *audiopath_attr; + struct snd_avirt_audiopath_obj *audiopath_obj; + + audiopath_attr = to_audiopath_attr(attr); + audiopath_obj = to_audiopath_obj(kobj); + + if (!audiopath_attr->store) + return -EIO; + return audiopath_attr->store(audiopath_obj, audiopath_attr, buf, len); +} + +static const struct sysfs_ops snd_avirt_audiopath_sysfs_ops = { + .show = audiopath_attr_show, + .store = audiopath_attr_store, +}; + +/** + * snd_avirt_audiopath_release - Audio Path release function + * @kobj: pointer to Audio Paths's kobject + */ +static void snd_avirt_audiopath_release(struct kobject *kobj) +{ + struct snd_avirt_audiopath_obj *audiopath_obj = to_audiopath_obj(kobj); + + kfree(audiopath_obj); +} + +static ssize_t name_show(struct snd_avirt_audiopath_obj *audiopath_obj, + struct snd_avirt_audiopath_attribute *attr, char *buf) +{ + return sprintf(buf, "%s\n", audiopath_obj->path->name); +} + +static ssize_t version_show(struct snd_avirt_audiopath_obj *audiopath_obj, + struct snd_avirt_audiopath_attribute *attr, + char *buf) +{ + struct snd_avirt_audiopath *audiopath = audiopath_obj->path; + + return sprintf(buf, "%d.%d.%d\n", audiopath->version[0], + audiopath->version[1], audiopath->version[2]); +} + + +static struct snd_avirt_audiopath_attribute snd_avirt_audiopath_attrs[] = { + __ATTR_RO(name), + __ATTR_RO(version), +}; + +static struct attribute *snd_avirt_audiopath_def_attrs[] = { + &snd_avirt_audiopath_attrs[0].attr, + &snd_avirt_audiopath_attrs[1].attr, + NULL, +}; + +static struct kobj_type snd_avirt_audiopath_ktype = { + .sysfs_ops = &snd_avirt_audiopath_sysfs_ops, + .release = snd_avirt_audiopath_release, + .default_attrs = snd_avirt_audiopath_def_attrs, +}; + +struct snd_avirt_audiopath_obj *snd_avirt_audiopath_create_obj(const char *uid) +{ + struct snd_avirt_audiopath_obj *snd_avirt_audiopath; + int retval; + + snd_avirt_audiopath = kzalloc(sizeof(*snd_avirt_audiopath), GFP_KERNEL); + if (!snd_avirt_audiopath) + return NULL; + snd_avirt_audiopath->kobj.kset = snd_avirt_audiopath_kset; + retval = kobject_init_and_add(&snd_avirt_audiopath->kobj, + &snd_avirt_audiopath_ktype, kobj, "%s", + uid); + if (retval) { + kobject_put(&snd_avirt_audiopath->kobj); + return NULL; + } + kobject_uevent(&snd_avirt_audiopath->kobj, KOBJ_ADD); + return snd_avirt_audiopath; +} + +void snd_avirt_audiopath_destroy_obj(struct snd_avirt_audiopath_obj *p) +{ + kobject_put(&p->kobj); +} + +int __init snd_avirt_sysfs_init(struct snd_avirt_core *core) +{ + snd_avirt_audiopath_kset = + kset_create_and_add("audiopaths", NULL, &core->dev->kobj); + if (!snd_avirt_audiopath_kset) + return -ENOMEM; + + return 0; +} + +void __exit snd_avirt_sysfs_exit(struct snd_avirt_core *core) +{ + kset_unregister(snd_avirt_audiopath_kset); +} |