summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Farrugia <mark.farrugia@fiberdyne.com.au>2019-04-04 10:32:06 +1100
committerMark Farrugia <mark.farrugia@fiberdyne.com.au>2019-04-04 10:32:52 +1100
commit3fdd59a91136e04809d6870a25a47534d7acb311 (patch)
treea708bd082939b703d8e56aae9bca88001e0c2b4d
parent2f73499dd43cc9f27c30f8267d14281beec6a785 (diff)
Add ability to cleanup avirt
- Add reset all function for streams - Add checks for empty /config dir, to avoid remount of configfs Signed-off-by: Mark Farrugia <mark.farrugia@fiberdyne.com.au>
-rw-r--r--include/avirt/avirt.h2
-rw-r--r--src/avirt-config.c107
2 files changed, 102 insertions, 7 deletions
diff --git a/include/avirt/avirt.h b/include/avirt/avirt.h
index 9389f47..afd856f 100644
--- a/include/avirt/avirt.h
+++ b/include/avirt/avirt.h
@@ -112,6 +112,8 @@ int snd_avirt_audiopaths(struct snd_avirt_audiopath **audiopaths, int *count);
*/
int snd_avirt_card_configure();
+int snd_avirt_card_unconfigure();
+
/**
* snd_avirt_pcm_info - Get PCM info for a given PCM name
* @pcm_name: The PCM name of which to retrieve the PCM info
diff --git a/src/avirt-config.c b/src/avirt-config.c
index 6f1391c..a52ef0a 100644
--- a/src/avirt-config.c
+++ b/src/avirt-config.c
@@ -134,9 +134,29 @@ static bool configfs_mounted = false;
static bool card_configured = false;
static int card_index = -1;
+bool check_dir_empty(char *dirname)
+{
+ int n = 0;
+ struct dirent *d;
+
+ DIR *dir = opendir(dirname);
+ if (dir == NULL) // Not a directory or doesn't exist
+ return 1;
+ while ((d = readdir(dir)) != NULL) {
+ if (++n > 2) // Ignore the '.' and '..' directories
+ break;
+ }
+
+ closedir(dir);
+ if (n <= 2) // Directory Empty
+ return true;
+
+ return false;
+}
+
static int mount_configfs()
{
- int err;
+ int err = 0;
char fsline[100];
bool configfs_supported = false;
FILE *procfs;
@@ -164,14 +184,18 @@ static int mount_configfs()
if (stat("/config", &st) == -1)
mkdir("/config", S_IRWXU | S_IRWXG | S_IRWXO);
- err = mount("none", "/config", "configfs", 0, NULL);
- if (!err)
+ // Check whether configfs is mounted, if not, mount it
+ if (check_dir_empty("/config"))
{
- AVIRT_DEBUG("Successfully mounted configfs");
- configfs_mounted = true;
+ err = mount("none", "/config", "configfs", 0, NULL);
+ if (!err)
+ {
+ AVIRT_DEBUG("Successfully mounted configfs");
+ configfs_mounted = true;
+ }
+ else
+ AVIRT_ERROR("Failed to mount configfs filesystem!");
}
- else
- AVIRT_ERROR("Failed to mount configfs filesystem!");
return err;
}
@@ -409,6 +433,48 @@ close_handle:
return retval;
}
+static int snd_avirt_stream_reset_all()
+{
+ int err;
+ DIR *d;
+ struct dirent *dir;
+ char path[AVIRT_CONFIGFS_PATH_MAXLEN];
+
+ d = opendir(AVIRT_CONFIGFS_PATH_STREAMS);
+ if (d)
+ {
+ while ((dir = readdir(d)) != NULL)
+ {
+ // Ignore the directory . and ..
+ if ((!strcmp(dir->d_name, ".")) || (!strcmp(dir->d_name, "..")))
+ continue;
+
+ memset(path, 0, AVIRT_CONFIGFS_PATH_MAXLEN);
+ strcpy(path, AVIRT_CONFIGFS_PATH_STREAMS);
+ strcat(path, dir->d_name);
+
+ // If not a directory, continue
+ struct stat path_stat;
+ stat(path, &path_stat);
+ if (S_ISREG(path_stat.st_mode))
+ continue;
+
+ err = rmdir(path);
+ if (err < 0)
+ {
+ AVIRT_ERROR_V("Cannot remove config item '%s' at directory '%s'", dir->d_name, path);
+ return err;
+ }
+ }
+
+ AVIRT_DEBUG("Reset streams!");
+
+ return 0;
+ }
+
+ return -EPERM;
+}
+
int snd_avirt_stream_new(const char *name, unsigned int channels, int direction,
const char *map, bool internal)
{
@@ -526,6 +592,33 @@ int snd_avirt_card_configure()
AVIRT_DEBUG_V("Running router: '%s'", cmd);
}
+
+ return 0;
+}
+
+int snd_avirt_card_unconfigure()
+{
+ // Check if card is already configured
+ if (!card_configured)
+ {
+ AVIRT_ERROR("Card is already unconfigured!");
+ return -EPERM;
+ }
+
+ IS_CONFIGFS_MOUNTED();
+
+ snd_avirt_stream_reset_all();
+
+ WRITE_ATTR_TO_DIR(AVIRT_CONFIGFS_PATH_STREAMS, "configured", "%d", 0);
+
+ AVIRT_DEBUG("Card unconfigured!");
+ card_configured = false;
+
+ if (card_index < 0)
+ card_index = snd_avirt_card_index_get(0);
+ if (card_index < 0)
+ return card_index;
+
return 0;
}