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> | |
2bace8b9 CT |
19 | #include <sys/mman.h> |
20 | #include <sched.h> | |
ef2cfc79 PM |
21 | |
22 | void write_int(char *path, int i) | |
23 | { | |
24 | char buf[1024]; | |
25 | int fd = open(path, O_RDWR); | |
26 | if (fd < 0) { | |
27 | perror("open"); | |
28 | exit(1); | |
29 | } | |
30 | sprintf(buf, "%d", i); | |
31 | if (write(fd, buf, strlen(buf)) != strlen(buf)) { | |
32 | perror("write"); | |
33 | exit(1); | |
34 | } | |
35 | close(fd); | |
36 | } | |
37 | ||
38 | void set_led(int on) | |
39 | { | |
40 | write_int("/sys/class/leds/hp::hddprotect/brightness", on); | |
41 | } | |
42 | ||
43 | void protect(int seconds) | |
44 | { | |
45 | write_int("/sys/block/sda/device/unload_heads", seconds*1000); | |
46 | } | |
47 | ||
48 | int on_ac(void) | |
49 | { | |
50 | // /sys/class/power_supply/AC0/online | |
51 | } | |
52 | ||
53 | int lid_open(void) | |
54 | { | |
55 | // /proc/acpi/button/lid/LID/state | |
56 | } | |
57 | ||
58 | void ignore_me(void) | |
59 | { | |
60 | protect(0); | |
61 | set_led(0); | |
ef2cfc79 PM |
62 | } |
63 | ||
b519c15d | 64 | int main(int argc, char *argv[]) |
ef2cfc79 | 65 | { |
b519c15d | 66 | int fd, ret; |
2bace8b9 | 67 | struct sched_param param; |
ef2cfc79 | 68 | |
b519c15d FP |
69 | fd = open("/dev/freefall", O_RDONLY); |
70 | if (fd < 0) { | |
71 | perror("open"); | |
72 | return EXIT_FAILURE; | |
73 | } | |
ef2cfc79 | 74 | |
2bace8b9 CT |
75 | daemon(0, 0); |
76 | param.sched_priority = sched_get_priority_max(SCHED_FIFO); | |
77 | sched_setscheduler(0, SCHED_FIFO, ¶m); | |
78 | mlockall(MCL_CURRENT|MCL_FUTURE); | |
79 | ||
ef2cfc79 PM |
80 | signal(SIGALRM, ignore_me); |
81 | ||
b519c15d FP |
82 | for (;;) { |
83 | unsigned char count; | |
84 | ||
85 | ret = read(fd, &count, sizeof(count)); | |
86 | alarm(0); | |
87 | if ((ret == -1) && (errno == EINTR)) { | |
88 | /* Alarm expired, time to unpark the heads */ | |
89 | continue; | |
90 | } | |
91 | ||
92 | if (ret != sizeof(count)) { | |
93 | perror("read"); | |
94 | break; | |
95 | } | |
96 | ||
97 | protect(21); | |
98 | set_led(1); | |
99 | if (1 || on_ac() || lid_open()) | |
100 | alarm(2); | |
101 | else | |
102 | alarm(20); | |
103 | } | |
ef2cfc79 | 104 | |
b519c15d FP |
105 | close(fd); |
106 | return EXIT_SUCCESS; | |
ef2cfc79 | 107 | } |