Commit | Line | Data |
---|---|---|
ef2cfc79 PM |
1 | /* Disk protection for HP machines. |
2 | * | |
3 | * Copyright 2008 Eric Piel | |
4 | * Copyright 2009 Pavel Machek <pavel@suse.cz> | |
5 | * | |
6 | * GPLv2. | |
7 | */ | |
8 | ||
9 | #include <stdio.h> | |
10 | #include <stdlib.h> | |
11 | #include <unistd.h> | |
12 | #include <fcntl.h> | |
13 | #include <sys/stat.h> | |
14 | #include <sys/types.h> | |
15 | #include <string.h> | |
16 | #include <stdint.h> | |
17 | #include <errno.h> | |
18 | #include <signal.h> | |
19 | ||
20 | void write_int(char *path, int i) | |
21 | { | |
22 | char buf[1024]; | |
23 | int fd = open(path, O_RDWR); | |
24 | if (fd < 0) { | |
25 | perror("open"); | |
26 | exit(1); | |
27 | } | |
28 | sprintf(buf, "%d", i); | |
29 | if (write(fd, buf, strlen(buf)) != strlen(buf)) { | |
30 | perror("write"); | |
31 | exit(1); | |
32 | } | |
33 | close(fd); | |
34 | } | |
35 | ||
36 | void set_led(int on) | |
37 | { | |
38 | write_int("/sys/class/leds/hp::hddprotect/brightness", on); | |
39 | } | |
40 | ||
41 | void protect(int seconds) | |
42 | { | |
43 | write_int("/sys/block/sda/device/unload_heads", seconds*1000); | |
44 | } | |
45 | ||
46 | int on_ac(void) | |
47 | { | |
48 | // /sys/class/power_supply/AC0/online | |
49 | } | |
50 | ||
51 | int lid_open(void) | |
52 | { | |
53 | // /proc/acpi/button/lid/LID/state | |
54 | } | |
55 | ||
56 | void ignore_me(void) | |
57 | { | |
58 | protect(0); | |
59 | set_led(0); | |
60 | ||
61 | } | |
62 | ||
63 | int main(int argc, char* argv[]) | |
64 | { | |
65 | int fd, ret; | |
66 | ||
67 | fd = open("/dev/freefall", O_RDONLY); | |
68 | if (fd < 0) { | |
69 | perror("open"); | |
70 | return EXIT_FAILURE; | |
71 | } | |
72 | ||
73 | signal(SIGALRM, ignore_me); | |
74 | ||
75 | for (;;) { | |
76 | unsigned char count; | |
77 | ||
78 | ret = read(fd, &count, sizeof(count)); | |
79 | alarm(0); | |
80 | if ((ret == -1) && (errno == EINTR)) { | |
81 | /* Alarm expired, time to unpark the heads */ | |
82 | continue; | |
83 | } | |
84 | ||
85 | if (ret != sizeof(count)) { | |
86 | perror("read"); | |
87 | break; | |
88 | } | |
89 | ||
90 | protect(21); | |
91 | set_led(1); | |
92 | if (1 || on_ac() || lid_open()) { | |
93 | alarm(2); | |
94 | } else { | |
95 | alarm(20); | |
96 | } | |
97 | } | |
98 | ||
99 | close(fd); | |
100 | return EXIT_SUCCESS; | |
101 | } |