summaryrefslogtreecommitdiffstats
path: root/src/tuning/tuningsysfs.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/tuning/tuningsysfs.cpp')
-rw-r--r--src/tuning/tuningsysfs.cpp130
1 files changed, 130 insertions, 0 deletions
diff --git a/src/tuning/tuningsysfs.cpp b/src/tuning/tuningsysfs.cpp
new file mode 100644
index 0000000..631e9fd
--- /dev/null
+++ b/src/tuning/tuningsysfs.cpp
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2010, Intel Corporation
+ *
+ * This file is part of PowerTOP
+ *
+ * This program file is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program in a file named COPYING; if not, write to the
+ * Free Software Foundation, Inc,
+ * 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ * or just google for it.
+ *
+ * Authors:
+ * Arjan van de Ven <arjan@linux.intel.com>
+ */
+
+#include "tuning.h"
+#include "tunable.h"
+#include "unistd.h"
+#include "tuningsysfs.h"
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <utility>
+#include <iostream>
+#include <fstream>
+#include <unistd.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <limits.h>
+
+
+#include "../lib.h"
+
+sysfs_tunable::sysfs_tunable(const char *str, const char *_sysfs_path, const char *_target_content) : tunable(str, 1.0, _("Good"), _("Bad"), _("Unknown"))
+{
+ pt_strcpy(sysfs_path, _sysfs_path);
+ pt_strcpy(target_value, _target_content);
+ bad_value[0] = 0;
+ snprintf(toggle_good, sizeof(toggle_good), "echo '%s' > '%s';", target_value, sysfs_path);
+ snprintf(toggle_bad, sizeof(toggle_bad), "echo '%s' > '%s';", bad_value, sysfs_path);
+}
+
+int sysfs_tunable::good_bad(void)
+{
+ char current_value[4096], *c;
+ ifstream file;
+
+ file.open(sysfs_path, ios::in);
+ if (!file)
+ return TUNE_NEUTRAL;
+ file.getline(current_value, 4096);
+ file.close();
+
+ c = strchr(current_value, '\n');
+ if (c)
+ *c = 0;
+
+ if (strcmp(current_value, target_value) == 0)
+ return TUNE_GOOD;
+
+ pt_strcpy(bad_value, current_value);
+ return TUNE_BAD;
+}
+
+void sysfs_tunable::toggle(void)
+{
+ int good;
+ good = good_bad();
+
+ if (good == TUNE_GOOD) {
+ if (strlen(bad_value) > 0)
+ write_sysfs(sysfs_path, bad_value);
+ return;
+ }
+
+ write_sysfs(sysfs_path, target_value);
+}
+
+const char *sysfs_tunable::toggle_script(void) {
+ int good;
+ good = good_bad();
+
+ if (good == TUNE_GOOD) {
+ if (strlen(bad_value) > 0)
+ return toggle_bad;
+ return NULL;
+ }
+
+ return toggle_good;
+}
+
+
+void add_sysfs_tunable(const char *str, const char *_sysfs_path, const char *_target_content)
+{
+ class sysfs_tunable *tunable;
+
+ if (access(_sysfs_path, R_OK) != 0)
+ return;
+
+ tunable = new class sysfs_tunable(str, _sysfs_path, _target_content);
+
+
+ all_tunables.push_back(tunable);
+}
+
+static void add_sata_tunables_callback(const char *d_name)
+{
+ char filename[PATH_MAX];
+ char msg[4096];
+
+ snprintf(filename, sizeof(filename), "/sys/class/scsi_host/%s/link_power_management_policy", d_name);
+ snprintf(msg, sizeof(msg), _("Enable SATA link power management for %s"), d_name);
+ add_sysfs_tunable(msg, filename, "med_power_with_dipm");
+}
+
+void add_sata_tunables(void)
+{
+ process_directory("/sys/class/scsi_host", add_sata_tunables_callback);
+}