summaryrefslogtreecommitdiff
path: root/Documentation/hwmon/hpfall.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2009-02-22 22:05:19 +0300
committerIngo Molnar <mingo@elte.hu>2009-02-22 22:05:19 +0300
commitfc6fc7f1b1095b92d4834e69b385b91e412a7ce5 (patch)
tree2ad451d5dac4d460830536944cef1de93be36b2a /Documentation/hwmon/hpfall.c
parentef1f87aa7ba6224bef1b750b3272ba281d8f43ed (diff)
parent770824bdc421ff58a64db608294323571c949f4c (diff)
downloadlinux-fc6fc7f1b1095b92d4834e69b385b91e412a7ce5.tar.xz
Merge branch 'linus' into x86/apic
Conflicts: arch/x86/mach-default/setup.c Semantic conflict resolution: arch/x86/kernel/setup.c Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'Documentation/hwmon/hpfall.c')
-rw-r--r--Documentation/hwmon/hpfall.c101
1 files changed, 101 insertions, 0 deletions
diff --git a/Documentation/hwmon/hpfall.c b/Documentation/hwmon/hpfall.c
new file mode 100644
index 000000000000..bbea1ccfd46a
--- /dev/null
+++ b/Documentation/hwmon/hpfall.c
@@ -0,0 +1,101 @@
+/* Disk protection for HP machines.
+ *
+ * Copyright 2008 Eric Piel
+ * Copyright 2009 Pavel Machek <pavel@suse.cz>
+ *
+ * GPLv2.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <string.h>
+#include <stdint.h>
+#include <errno.h>
+#include <signal.h>
+
+void write_int(char *path, int i)
+{
+ char buf[1024];
+ int fd = open(path, O_RDWR);
+ if (fd < 0) {
+ perror("open");
+ exit(1);
+ }
+ sprintf(buf, "%d", i);
+ if (write(fd, buf, strlen(buf)) != strlen(buf)) {
+ perror("write");
+ exit(1);
+ }
+ close(fd);
+}
+
+void set_led(int on)
+{
+ write_int("/sys/class/leds/hp::hddprotect/brightness", on);
+}
+
+void protect(int seconds)
+{
+ write_int("/sys/block/sda/device/unload_heads", seconds*1000);
+}
+
+int on_ac(void)
+{
+// /sys/class/power_supply/AC0/online
+}
+
+int lid_open(void)
+{
+// /proc/acpi/button/lid/LID/state
+}
+
+void ignore_me(void)
+{
+ protect(0);
+ set_led(0);
+
+}
+
+int main(int argc, char* argv[])
+{
+ int fd, ret;
+
+ fd = open("/dev/freefall", O_RDONLY);
+ if (fd < 0) {
+ perror("open");
+ return EXIT_FAILURE;
+ }
+
+ signal(SIGALRM, ignore_me);
+
+ for (;;) {
+ unsigned char count;
+
+ ret = read(fd, &count, sizeof(count));
+ alarm(0);
+ if ((ret == -1) && (errno == EINTR)) {
+ /* Alarm expired, time to unpark the heads */
+ continue;
+ }
+
+ if (ret != sizeof(count)) {
+ perror("read");
+ break;
+ }
+
+ protect(21);
+ set_led(1);
+ if (1 || on_ac() || lid_open()) {
+ alarm(2);
+ } else {
+ alarm(20);
+ }
+ }
+
+ close(fd);
+ return EXIT_SUCCESS;
+}