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); | |
ef2cfc79 PM |
60 | } |
61 | ||
b519c15d | 62 | int main(int argc, char *argv[]) |
ef2cfc79 | 63 | { |
b519c15d | 64 | int fd, ret; |
ef2cfc79 | 65 | |
b519c15d FP |
66 | fd = open("/dev/freefall", O_RDONLY); |
67 | if (fd < 0) { | |
68 | perror("open"); | |
69 | return EXIT_FAILURE; | |
70 | } | |
ef2cfc79 PM |
71 | |
72 | signal(SIGALRM, ignore_me); | |
73 | ||
b519c15d FP |
74 | for (;;) { |
75 | unsigned char count; | |
76 | ||
77 | ret = read(fd, &count, sizeof(count)); | |
78 | alarm(0); | |
79 | if ((ret == -1) && (errno == EINTR)) { | |
80 | /* Alarm expired, time to unpark the heads */ | |
81 | continue; | |
82 | } | |
83 | ||
84 | if (ret != sizeof(count)) { | |
85 | perror("read"); | |
86 | break; | |
87 | } | |
88 | ||
89 | protect(21); | |
90 | set_led(1); | |
91 | if (1 || on_ac() || lid_open()) | |
92 | alarm(2); | |
93 | else | |
94 | alarm(20); | |
95 | } | |
ef2cfc79 | 96 | |
b519c15d FP |
97 | close(fd); |
98 | return EXIT_SUCCESS; | |
ef2cfc79 | 99 | } |