diff options
Diffstat (limited to 'vold/switch.c')
-rw-r--r-- | vold/switch.c | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/vold/switch.c b/vold/switch.c new file mode 100644 index 0000000..ba9ddb3 --- /dev/null +++ b/vold/switch.c @@ -0,0 +1,121 @@ + +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <stdlib.h> +#include <string.h> +#include <dirent.h> +#include <errno.h> + +#include <sys/types.h> + +#include "vold.h" +#include "switch.h" + +#define DEBUG_BOOTSTRAP 0 + +static int mmc_bootstrap_switch(char *sysfs_path); + +int switch_bootstrap() +{ + DIR *d; + struct dirent *de; + + if (!(d = opendir(SYSFS_CLASS_SWITCH_PATH))) { + LOG_ERROR("Unable to open '%s' (%m)", SYSFS_CLASS_SWITCH_PATH); + return -errno; + } + + while ((de = readdir(d))) { + char tmp[255]; + + if (de->d_name[0] == '.') + continue; + + sprintf(tmp, "%s/%s", SYSFS_CLASS_SWITCH_PATH, de->d_name); + if (mmc_bootstrap_switch(tmp)) + LOG_ERROR("Error bootstrapping switch '%s' (%m)", tmp); + } + + closedir(d); + + return 0; +} + +static int mmc_bootstrap_switch(char *sysfs_path) +{ +#if DEBUG_BOOTSTRAP + LOG_VOL("bootstrap_switch(%s):", sysfs_path); +#endif + + char filename[255]; + char name[255]; + char state[255]; + char tmp[255]; + char *uevent_params[3]; + char devpath[255]; + FILE *fp; + + /* + * Read switch name + */ + sprintf(filename, "%s/name", sysfs_path); + if (!(fp = fopen(filename, "r"))) { + LOGE("Error opening switch name path '%s' (%s)", + sysfs_path, strerror(errno)); + return -errno; + } + if (!fgets(name, sizeof(name), fp)) { + LOGE("Unable to read switch name"); + fclose(fp); + return -EIO; + } + fclose(fp); + + name[strlen(name) -1] = '\0'; + sprintf(devpath, "/devices/virtual/switch/%s", name); + sprintf(tmp, "SWITCH_NAME=%s", name); + uevent_params[0] = (char *) strdup(tmp); + + /* + * Read switch state + */ + sprintf(filename, "%s/state", sysfs_path); + if (!(fp = fopen(filename, "r"))) { + LOGE("Error opening switch state path '%s' (%s)", + sysfs_path, strerror(errno)); + return -errno; + } + if (!fgets(state, sizeof(state), fp)) { + LOGE("Unable to read switch state"); + fclose(fp); + return -EIO; + } + fclose(fp); + + state[strlen(state) -1] = '\0'; + sprintf(tmp, "SWITCH_STATE=%s", state); + uevent_params[1] = (char *) strdup(tmp); + + uevent_params[2] = (char *) NULL; + + if (simulate_uevent("switch", devpath, "add", uevent_params) < 0) { + LOGE("Error simulating uevent (%s)", strerror(errno)); + return -errno; + } + + return 0; +} |