|
Packit |
4a16fb |
/*
|
|
Packit |
4a16fb |
* This library is free software; you can redistribute it and/or
|
|
Packit |
4a16fb |
* modify it under the terms of the GNU Lesser General Public
|
|
Packit |
4a16fb |
* License as published by the Free Software Foundation; either
|
|
Packit |
4a16fb |
* version 2 of the License, or (at your option) any later version.
|
|
Packit |
4a16fb |
*
|
|
Packit |
4a16fb |
* This library is distributed in the hope that it will be useful,
|
|
Packit |
4a16fb |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
4a16fb |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
4a16fb |
* Lesser General Public License for more details.
|
|
Packit |
4a16fb |
*
|
|
Packit |
4a16fb |
* You should have received a copy of the GNU Lesser General Public
|
|
Packit |
4a16fb |
* License along with this library; if not, write to the Free Software
|
|
Packit |
4a16fb |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
Packit |
4a16fb |
*
|
|
Packit |
4a16fb |
* Support for the verb/device/modifier core logic and API,
|
|
Packit |
4a16fb |
* command line tool and file parser was kindly sponsored by
|
|
Packit |
4a16fb |
* Texas Instruments Inc.
|
|
Packit |
4a16fb |
* Support for multiple active modifiers and devices,
|
|
Packit |
4a16fb |
* transition sequences, multiple client access and user defined use
|
|
Packit |
4a16fb |
* cases was kindly sponsored by Wolfson Microelectronics PLC.
|
|
Packit |
4a16fb |
*
|
|
Packit |
4a16fb |
* Copyright (C) 2008-2010 SlimLogic Ltd
|
|
Packit |
4a16fb |
* Copyright (C) 2010 Wolfson Microelectronics PLC
|
|
Packit |
4a16fb |
* Copyright (C) 2010 Texas Instruments Inc.
|
|
Packit |
4a16fb |
* Copyright (C) 2010 Red Hat Inc.
|
|
Packit |
4a16fb |
* Authors: Liam Girdwood <lrg@slimlogic.co.uk>
|
|
Packit |
4a16fb |
* Stefan Schmidt <stefan@slimlogic.co.uk>
|
|
Packit |
4a16fb |
* Justin Xu <justinx@slimlogic.co.uk>
|
|
Packit |
4a16fb |
* Jaroslav Kysela <perex@perex.cz>
|
|
Packit |
4a16fb |
*/
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
#include "ucm_local.h"
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
void uc_mgr_error(const char *fmt,...)
|
|
Packit |
4a16fb |
{
|
|
Packit |
4a16fb |
va_list va;
|
|
Packit |
4a16fb |
va_start(va, fmt);
|
|
Packit |
4a16fb |
fprintf(stderr, "ucm: ");
|
|
Packit |
4a16fb |
vfprintf(stderr, fmt, va);
|
|
Packit |
4a16fb |
va_end(va);
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
void uc_mgr_stdout(const char *fmt,...)
|
|
Packit |
4a16fb |
{
|
|
Packit |
4a16fb |
va_list va;
|
|
Packit |
4a16fb |
va_start(va, fmt);
|
|
Packit |
4a16fb |
vfprintf(stdout, fmt, va);
|
|
Packit |
4a16fb |
va_end(va);
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
struct ctl_list *uc_mgr_get_one_ctl(snd_use_case_mgr_t *uc_mgr)
|
|
Packit |
4a16fb |
{
|
|
Packit |
4a16fb |
struct list_head *pos;
|
|
Packit |
4a16fb |
struct ctl_list *ctl_list = NULL;
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
list_for_each(pos, &uc_mgr->ctl_list) {
|
|
Packit |
4a16fb |
if (ctl_list) {
|
|
Packit |
4a16fb |
uc_error("multiple control device names were found!");
|
|
Packit |
4a16fb |
return NULL;
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
ctl_list = list_entry(pos, struct ctl_list, list);
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
return ctl_list;
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
snd_ctl_t *uc_mgr_get_ctl(snd_use_case_mgr_t *uc_mgr)
|
|
Packit |
4a16fb |
{
|
|
Packit |
4a16fb |
struct ctl_list *ctl_list;
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
ctl_list = uc_mgr_get_one_ctl(uc_mgr);
|
|
Packit |
4a16fb |
if (ctl_list)
|
|
Packit |
4a16fb |
return ctl_list->ctl;
|
|
Packit |
4a16fb |
return NULL;
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
static void uc_mgr_free_ctl(struct ctl_list *ctl_list)
|
|
Packit |
4a16fb |
{
|
|
Packit |
4a16fb |
struct list_head *pos, *npos;
|
|
Packit |
4a16fb |
struct ctl_dev *ctl_dev;
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
list_for_each_safe(pos, npos, &ctl_list->dev_list) {
|
|
Packit |
4a16fb |
ctl_dev = list_entry(pos, struct ctl_dev, list);
|
|
Packit |
4a16fb |
free(ctl_dev->device);
|
|
Packit |
4a16fb |
free(ctl_dev);
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
snd_ctl_card_info_free(ctl_list->ctl_info);
|
|
Packit |
4a16fb |
free(ctl_list);
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
void uc_mgr_free_ctl_list(snd_use_case_mgr_t *uc_mgr)
|
|
Packit |
4a16fb |
{
|
|
Packit |
4a16fb |
struct list_head *pos, *npos;
|
|
Packit |
4a16fb |
struct ctl_list *ctl_list;
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
list_for_each_safe(pos, npos, &uc_mgr->ctl_list) {
|
|
Packit |
4a16fb |
ctl_list = list_entry(pos, struct ctl_list, list);
|
|
Packit |
4a16fb |
snd_ctl_close(ctl_list->ctl);
|
|
Packit |
4a16fb |
list_del(&ctl_list->list);
|
|
Packit |
4a16fb |
uc_mgr_free_ctl(ctl_list);
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
static int uc_mgr_ctl_add_dev(struct ctl_list *ctl_list, const char *device)
|
|
Packit |
4a16fb |
{
|
|
Packit |
4a16fb |
struct list_head *pos;
|
|
Packit |
4a16fb |
struct ctl_dev *ctl_dev;
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
/* skip duplicates */
|
|
Packit |
4a16fb |
list_for_each(pos, &ctl_list->dev_list) {
|
|
Packit |
4a16fb |
ctl_dev = list_entry(pos, struct ctl_dev, list);
|
|
Packit |
4a16fb |
if (strcmp(ctl_dev->device, device) == 0)
|
|
Packit |
4a16fb |
return 0;
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
/* allocate new device name */
|
|
Packit |
4a16fb |
ctl_dev = malloc(sizeof(*ctl_dev));
|
|
Packit |
4a16fb |
if (ctl_dev == NULL)
|
|
Packit |
4a16fb |
return -ENOMEM;
|
|
Packit |
4a16fb |
ctl_dev->device = strdup(device);
|
|
Packit |
4a16fb |
if (ctl_dev->device == NULL) {
|
|
Packit |
4a16fb |
free(ctl_dev);
|
|
Packit |
4a16fb |
return -ENOMEM;
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
list_add_tail(&ctl_dev->list, &ctl_list->dev_list);
|
|
Packit |
4a16fb |
return 0;
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
static int uc_mgr_ctl_add(snd_use_case_mgr_t *uc_mgr,
|
|
Packit |
4a16fb |
struct ctl_list *ctl_list,
|
|
Packit |
4a16fb |
snd_ctl_t *ctl, int card,
|
|
Packit |
4a16fb |
snd_ctl_card_info_t *info,
|
|
Packit |
4a16fb |
const char *device)
|
|
Packit |
4a16fb |
{
|
|
Packit |
4a16fb |
struct ctl_list *cl = NULL;
|
|
Packit |
4a16fb |
const char *id = snd_ctl_card_info_get_id(info);
|
|
Packit |
4a16fb |
char dev[MAX_CARD_LONG_NAME];
|
|
Packit |
4a16fb |
int err, hit = 0;
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
if (id == NULL || id[0] == '\0')
|
|
Packit |
4a16fb |
return -ENOENT;
|
|
Packit |
4a16fb |
if (!ctl_list) {
|
|
Packit |
4a16fb |
cl = malloc(sizeof(*cl));
|
|
Packit |
4a16fb |
if (cl == NULL)
|
|
Packit |
4a16fb |
return -ENOMEM;
|
|
Packit |
4a16fb |
INIT_LIST_HEAD(&cl->dev_list);
|
|
Packit |
4a16fb |
cl->ctl = ctl;
|
|
Packit |
4a16fb |
if (snd_ctl_card_info_malloc(&cl->ctl_info) < 0) {
|
|
Packit |
4a16fb |
free(cl);
|
|
Packit |
4a16fb |
return -ENOMEM;
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
snd_ctl_card_info_copy(cl->ctl_info, info);
|
|
Packit |
4a16fb |
ctl_list = cl;
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
if (card >= 0) {
|
|
Packit |
4a16fb |
snprintf(dev, sizeof(dev), "hw:%d", card);
|
|
Packit |
4a16fb |
hit |= !!(device && (strcmp(dev, device) == 0));
|
|
Packit |
4a16fb |
err = uc_mgr_ctl_add_dev(ctl_list, dev);
|
|
Packit |
4a16fb |
if (err < 0)
|
|
Packit |
4a16fb |
goto __nomem;
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
snprintf(dev, sizeof(dev), "hw:%s", id);
|
|
Packit |
4a16fb |
hit |= !!(device && (strcmp(dev, device) == 0));
|
|
Packit |
4a16fb |
err = uc_mgr_ctl_add_dev(ctl_list, dev);
|
|
Packit |
4a16fb |
if (err < 0)
|
|
Packit |
4a16fb |
goto __nomem;
|
|
Packit |
4a16fb |
/* the UCM name not based on the card name / id */
|
|
Packit |
4a16fb |
if (!hit && device) {
|
|
Packit |
4a16fb |
err = uc_mgr_ctl_add_dev(ctl_list, device);
|
|
Packit |
4a16fb |
if (err < 0)
|
|
Packit |
4a16fb |
goto __nomem;
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
list_add_tail(&ctl_list->list, &uc_mgr->ctl_list);
|
|
Packit |
4a16fb |
return 0;
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
__nomem:
|
|
Packit |
4a16fb |
if (ctl_list == cl)
|
|
Packit |
4a16fb |
uc_mgr_free_ctl(cl);
|
|
Packit |
4a16fb |
return -ENOMEM;
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
int uc_mgr_open_ctl(snd_use_case_mgr_t *uc_mgr,
|
|
Packit |
4a16fb |
snd_ctl_t **ctl,
|
|
Packit |
4a16fb |
const char *device)
|
|
Packit |
4a16fb |
{
|
|
Packit |
4a16fb |
struct list_head *pos1, *pos2;
|
|
Packit |
4a16fb |
struct ctl_list *ctl_list;
|
|
Packit |
4a16fb |
struct ctl_dev *ctl_dev;
|
|
Packit |
4a16fb |
snd_ctl_card_info_t *info;
|
|
Packit |
4a16fb |
const char *id;
|
|
Packit |
4a16fb |
int err, card;
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
snd_ctl_card_info_alloca(&info;;
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
/* cache lookup */
|
|
Packit |
4a16fb |
list_for_each(pos1, &uc_mgr->ctl_list) {
|
|
Packit |
4a16fb |
ctl_list = list_entry(pos1, struct ctl_list, list);
|
|
Packit |
4a16fb |
list_for_each(pos2, &ctl_list->dev_list) {
|
|
Packit |
4a16fb |
ctl_dev = list_entry(pos2, struct ctl_dev, list);
|
|
Packit |
4a16fb |
if (strcmp(ctl_dev->device, device) == 0) {
|
|
Packit |
4a16fb |
*ctl = ctl_list->ctl;
|
|
Packit |
4a16fb |
return 0;
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
err = snd_ctl_open(ctl, device, 0);
|
|
Packit |
4a16fb |
if (err < 0)
|
|
Packit |
4a16fb |
return err;
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
id = NULL;
|
|
Packit |
4a16fb |
err = snd_ctl_card_info(*ctl, info);
|
|
Packit |
4a16fb |
if (err == 0)
|
|
Packit |
4a16fb |
id = snd_ctl_card_info_get_id(info);
|
|
Packit |
4a16fb |
if (err < 0 || id == NULL || id[0] == '\0') {
|
|
Packit |
4a16fb |
uc_error("control hardware info (%s): %s", device, snd_strerror(err));
|
|
Packit |
4a16fb |
snd_ctl_close(*ctl);
|
|
Packit |
4a16fb |
*ctl = NULL;
|
|
Packit |
4a16fb |
return err;
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
/* insert to cache, if just name differs */
|
|
Packit |
4a16fb |
list_for_each(pos1, &uc_mgr->ctl_list) {
|
|
Packit |
4a16fb |
ctl_list = list_entry(pos1, struct ctl_list, list);
|
|
Packit |
4a16fb |
if (strcmp(id, snd_ctl_card_info_get_id(ctl_list->ctl_info)) == 0) {
|
|
Packit |
4a16fb |
card = snd_card_get_index(id);
|
|
Packit |
4a16fb |
err = uc_mgr_ctl_add(uc_mgr, ctl_list, *ctl, card, info, device);
|
|
Packit |
4a16fb |
if (err < 0)
|
|
Packit |
4a16fb |
goto __nomem;
|
|
Packit |
4a16fb |
snd_ctl_close(*ctl);
|
|
Packit |
4a16fb |
*ctl = ctl_list->ctl;
|
|
Packit |
4a16fb |
return 0;
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
err = uc_mgr_ctl_add(uc_mgr, NULL, *ctl, -1, info, device);
|
|
Packit |
4a16fb |
if (err < 0)
|
|
Packit |
4a16fb |
goto __nomem;
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
return 0;
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
__nomem:
|
|
Packit |
4a16fb |
snd_ctl_close(*ctl);
|
|
Packit |
4a16fb |
*ctl = NULL;
|
|
Packit |
4a16fb |
return -ENOMEM;
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
int uc_mgr_config_load(int format, const char *file, snd_config_t **cfg)
|
|
Packit |
4a16fb |
{
|
|
Packit |
4a16fb |
FILE *fp;
|
|
Packit |
4a16fb |
snd_input_t *in;
|
|
Packit |
4a16fb |
snd_config_t *top;
|
|
Packit |
4a16fb |
const char *path, *default_paths[2];
|
|
Packit |
4a16fb |
int err;
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
fp = fopen(file, "r");
|
|
Packit |
4a16fb |
if (!fp) {
|
|
Packit |
4a16fb |
err = -errno;
|
|
Packit |
4a16fb |
__err0:
|
|
Packit |
4a16fb |
uc_error("could not open configuration file %s", file);
|
|
Packit |
4a16fb |
return err;
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
err = snd_input_stdio_attach(&in, fp, 1);
|
|
Packit |
4a16fb |
if (err < 0)
|
|
Packit |
4a16fb |
goto __err0;
|
|
Packit |
4a16fb |
err = snd_config_top(&top);
|
|
Packit |
4a16fb |
if (err < 0)
|
|
Packit |
4a16fb |
goto __err1;
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
if (format >= 2) {
|
|
Packit |
4a16fb |
path = getenv(ALSA_CONFIG_UCM2_VAR);
|
|
Packit |
4a16fb |
if (!path || path[0] == '\0')
|
|
Packit |
4a16fb |
path = ALSA_CONFIG_DIR "/ucm2";
|
|
Packit |
4a16fb |
} else {
|
|
Packit |
4a16fb |
path = getenv(ALSA_CONFIG_UCM_VAR);
|
|
Packit |
4a16fb |
if (!path || path[0] == '\0')
|
|
Packit |
4a16fb |
path = ALSA_CONFIG_DIR "/ucm";
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
default_paths[0] = path;
|
|
Packit |
4a16fb |
default_paths[1] = NULL;
|
|
Packit |
4a16fb |
err = _snd_config_load_with_include(top, in, 0, default_paths);
|
|
Packit |
4a16fb |
if (err < 0) {
|
|
Packit |
4a16fb |
uc_error("could not load configuration file %s", file);
|
|
Packit |
4a16fb |
goto __err2;
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
err = snd_input_close(in);
|
|
Packit |
4a16fb |
if (err < 0) {
|
|
Packit |
4a16fb |
in = NULL;
|
|
Packit |
4a16fb |
goto __err2;
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
*cfg = top;
|
|
Packit |
4a16fb |
return 0;
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
__err2:
|
|
Packit |
4a16fb |
snd_config_delete(top);
|
|
Packit |
4a16fb |
__err1:
|
|
Packit |
4a16fb |
if (in)
|
|
Packit |
4a16fb |
snd_input_close(in);
|
|
Packit |
4a16fb |
return err;
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
void uc_mgr_free_value(struct list_head *base)
|
|
Packit |
4a16fb |
{
|
|
Packit |
4a16fb |
struct list_head *pos, *npos;
|
|
Packit |
4a16fb |
struct ucm_value *val;
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
list_for_each_safe(pos, npos, base) {
|
|
Packit |
4a16fb |
val = list_entry(pos, struct ucm_value, list);
|
|
Packit |
4a16fb |
free(val->name);
|
|
Packit |
4a16fb |
free(val->data);
|
|
Packit |
4a16fb |
list_del(&val->list);
|
|
Packit |
4a16fb |
free(val);
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
void uc_mgr_free_dev_list(struct dev_list *dev_list)
|
|
Packit |
4a16fb |
{
|
|
Packit |
4a16fb |
struct list_head *pos, *npos;
|
|
Packit |
4a16fb |
struct dev_list_node *dlist;
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
list_for_each_safe(pos, npos, &dev_list->list) {
|
|
Packit |
4a16fb |
dlist = list_entry(pos, struct dev_list_node, list);
|
|
Packit |
4a16fb |
free(dlist->name);
|
|
Packit |
4a16fb |
list_del(&dlist->list);
|
|
Packit |
4a16fb |
free(dlist);
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
void uc_mgr_free_sequence_element(struct sequence_element *seq)
|
|
Packit |
4a16fb |
{
|
|
Packit |
4a16fb |
if (seq == NULL)
|
|
Packit |
4a16fb |
return;
|
|
Packit |
4a16fb |
switch (seq->type) {
|
|
Packit |
4a16fb |
case SEQUENCE_ELEMENT_TYPE_CDEV:
|
|
Packit |
4a16fb |
free(seq->data.cdev);
|
|
Packit |
4a16fb |
break;
|
|
Packit |
4a16fb |
case SEQUENCE_ELEMENT_TYPE_CSET:
|
|
Packit |
4a16fb |
case SEQUENCE_ELEMENT_TYPE_CSET_BIN_FILE:
|
|
Packit |
4a16fb |
case SEQUENCE_ELEMENT_TYPE_CSET_TLV:
|
|
Packit |
4a16fb |
free(seq->data.cset);
|
|
Packit |
4a16fb |
break;
|
|
Packit |
4a16fb |
case SEQUENCE_ELEMENT_TYPE_EXEC:
|
|
Packit |
4a16fb |
free(seq->data.exec);
|
|
Packit |
4a16fb |
break;
|
|
Packit |
4a16fb |
default:
|
|
Packit |
4a16fb |
break;
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
free(seq);
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
void uc_mgr_free_sequence(struct list_head *base)
|
|
Packit |
4a16fb |
{
|
|
Packit |
4a16fb |
struct list_head *pos, *npos;
|
|
Packit |
4a16fb |
struct sequence_element *seq;
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
list_for_each_safe(pos, npos, base) {
|
|
Packit |
4a16fb |
seq = list_entry(pos, struct sequence_element, list);
|
|
Packit |
4a16fb |
list_del(&seq->list);
|
|
Packit |
4a16fb |
uc_mgr_free_sequence_element(seq);
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
void uc_mgr_free_transition_element(struct transition_sequence *tseq)
|
|
Packit |
4a16fb |
{
|
|
Packit |
4a16fb |
free(tseq->name);
|
|
Packit |
4a16fb |
uc_mgr_free_sequence(&tseq->transition_list);
|
|
Packit |
4a16fb |
free(tseq);
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
void uc_mgr_free_transition(struct list_head *base)
|
|
Packit |
4a16fb |
{
|
|
Packit |
4a16fb |
struct list_head *pos, *npos;
|
|
Packit |
4a16fb |
struct transition_sequence *tseq;
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
list_for_each_safe(pos, npos, base) {
|
|
Packit |
4a16fb |
tseq = list_entry(pos, struct transition_sequence, list);
|
|
Packit |
4a16fb |
list_del(&tseq->list);
|
|
Packit |
4a16fb |
uc_mgr_free_transition_element(tseq);
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
void uc_mgr_free_modifier(struct list_head *base)
|
|
Packit |
4a16fb |
{
|
|
Packit |
4a16fb |
struct list_head *pos, *npos;
|
|
Packit |
4a16fb |
struct use_case_modifier *mod;
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
list_for_each_safe(pos, npos, base) {
|
|
Packit |
4a16fb |
mod = list_entry(pos, struct use_case_modifier, list);
|
|
Packit |
4a16fb |
free(mod->name);
|
|
Packit |
4a16fb |
free(mod->comment);
|
|
Packit |
4a16fb |
uc_mgr_free_sequence(&mod->enable_list);
|
|
Packit |
4a16fb |
uc_mgr_free_sequence(&mod->disable_list);
|
|
Packit |
4a16fb |
uc_mgr_free_transition(&mod->transition_list);
|
|
Packit |
4a16fb |
uc_mgr_free_dev_list(&mod->dev_list);
|
|
Packit |
4a16fb |
uc_mgr_free_value(&mod->value_list);
|
|
Packit |
4a16fb |
list_del(&mod->list);
|
|
Packit |
4a16fb |
free(mod);
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
void uc_mgr_free_device(struct list_head *base)
|
|
Packit |
4a16fb |
{
|
|
Packit |
4a16fb |
struct list_head *pos, *npos;
|
|
Packit |
4a16fb |
struct use_case_device *dev;
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
list_for_each_safe(pos, npos, base) {
|
|
Packit |
4a16fb |
dev = list_entry(pos, struct use_case_device, list);
|
|
Packit |
4a16fb |
free(dev->name);
|
|
Packit |
4a16fb |
free(dev->comment);
|
|
Packit |
4a16fb |
uc_mgr_free_sequence(&dev->enable_list);
|
|
Packit |
4a16fb |
uc_mgr_free_sequence(&dev->disable_list);
|
|
Packit |
4a16fb |
uc_mgr_free_transition(&dev->transition_list);
|
|
Packit |
4a16fb |
uc_mgr_free_dev_list(&dev->dev_list);
|
|
Packit |
4a16fb |
uc_mgr_free_value(&dev->value_list);
|
|
Packit |
4a16fb |
list_del(&dev->list);
|
|
Packit |
4a16fb |
free(dev);
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
void uc_mgr_free_verb(snd_use_case_mgr_t *uc_mgr)
|
|
Packit |
4a16fb |
{
|
|
Packit |
4a16fb |
struct list_head *pos, *npos;
|
|
Packit |
4a16fb |
struct use_case_verb *verb;
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
list_for_each_safe(pos, npos, &uc_mgr->verb_list) {
|
|
Packit |
4a16fb |
verb = list_entry(pos, struct use_case_verb, list);
|
|
Packit |
4a16fb |
free(verb->name);
|
|
Packit |
4a16fb |
free(verb->comment);
|
|
Packit |
4a16fb |
uc_mgr_free_sequence(&verb->enable_list);
|
|
Packit |
4a16fb |
uc_mgr_free_sequence(&verb->disable_list);
|
|
Packit |
4a16fb |
uc_mgr_free_transition(&verb->transition_list);
|
|
Packit |
4a16fb |
uc_mgr_free_value(&verb->value_list);
|
|
Packit |
4a16fb |
uc_mgr_free_device(&verb->device_list);
|
|
Packit |
4a16fb |
uc_mgr_free_device(&verb->cmpt_device_list);
|
|
Packit |
4a16fb |
uc_mgr_free_modifier(&verb->modifier_list);
|
|
Packit |
4a16fb |
list_del(&verb->list);
|
|
Packit |
4a16fb |
free(verb);
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
uc_mgr_free_sequence(&uc_mgr->default_list);
|
|
Packit |
4a16fb |
uc_mgr_free_value(&uc_mgr->value_list);
|
|
Packit |
4a16fb |
free(uc_mgr->comment);
|
|
Packit |
4a16fb |
uc_mgr->comment = NULL;
|
|
Packit |
4a16fb |
uc_mgr->active_verb = NULL;
|
|
Packit |
4a16fb |
INIT_LIST_HEAD(&uc_mgr->active_devices);
|
|
Packit |
4a16fb |
INIT_LIST_HEAD(&uc_mgr->active_modifiers);
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
void uc_mgr_free(snd_use_case_mgr_t *uc_mgr)
|
|
Packit |
4a16fb |
{
|
|
Packit |
4a16fb |
uc_mgr_free_verb(uc_mgr);
|
|
Packit |
4a16fb |
uc_mgr_free_ctl_list(uc_mgr);
|
|
Packit |
4a16fb |
free(uc_mgr->card_name);
|
|
Packit |
4a16fb |
free(uc_mgr);
|
|
Packit |
4a16fb |
}
|