diff options
Diffstat (limited to 'Documentation/hwmon/hpfall.c')
-rw-r--r-- | Documentation/hwmon/hpfall.c | 115 |
1 files changed, 80 insertions, 35 deletions
diff --git a/Documentation/hwmon/hpfall.c b/Documentation/hwmon/hpfall.c index bbea1ccfd46a..681ec22b9d0e 100644 --- a/Documentation/hwmon/hpfall.c +++ b/Documentation/hwmon/hpfall.c | |||
@@ -16,6 +16,34 @@ | |||
16 | #include <stdint.h> | 16 | #include <stdint.h> |
17 | #include <errno.h> | 17 | #include <errno.h> |
18 | #include <signal.h> | 18 | #include <signal.h> |
19 | #include <sys/mman.h> | ||
20 | #include <sched.h> | ||
21 | |||
22 | char unload_heads_path[64]; | ||
23 | |||
24 | int set_unload_heads_path(char *device) | ||
25 | { | ||
26 | char devname[64]; | ||
27 | |||
28 | if (strlen(device) <= 5 || strncmp(device, "/dev/", 5) != 0) | ||
29 | return -EINVAL; | ||
30 | strncpy(devname, device + 5, sizeof(devname)); | ||
31 | |||
32 | snprintf(unload_heads_path, sizeof(unload_heads_path), | ||
33 | "/sys/block/%s/device/unload_heads", devname); | ||
34 | return 0; | ||
35 | } | ||
36 | int valid_disk(void) | ||
37 | { | ||
38 | int fd = open(unload_heads_path, O_RDONLY); | ||
39 | if (fd < 0) { | ||
40 | perror(unload_heads_path); | ||
41 | return 0; | ||
42 | } | ||
43 | |||
44 | close(fd); | ||
45 | return 1; | ||
46 | } | ||
19 | 47 | ||
20 | void write_int(char *path, int i) | 48 | void write_int(char *path, int i) |
21 | { | 49 | { |
@@ -40,7 +68,7 @@ void set_led(int on) | |||
40 | 68 | ||
41 | void protect(int seconds) | 69 | void protect(int seconds) |
42 | { | 70 | { |
43 | write_int("/sys/block/sda/device/unload_heads", seconds*1000); | 71 | write_int(unload_heads_path, seconds*1000); |
44 | } | 72 | } |
45 | 73 | ||
46 | int on_ac(void) | 74 | int on_ac(void) |
@@ -57,45 +85,62 @@ void ignore_me(void) | |||
57 | { | 85 | { |
58 | protect(0); | 86 | protect(0); |
59 | set_led(0); | 87 | set_led(0); |
60 | |||
61 | } | 88 | } |
62 | 89 | ||
63 | int main(int argc, char* argv[]) | 90 | int main(int argc, char **argv) |
64 | { | 91 | { |
65 | int fd, ret; | 92 | int fd, ret; |
93 | struct sched_param param; | ||
94 | |||
95 | if (argc == 1) | ||
96 | ret = set_unload_heads_path("/dev/sda"); | ||
97 | else if (argc == 2) | ||
98 | ret = set_unload_heads_path(argv[1]); | ||
99 | else | ||
100 | ret = -EINVAL; | ||
101 | |||
102 | if (ret || !valid_disk()) { | ||
103 | fprintf(stderr, "usage: %s <device> (default: /dev/sda)\n", | ||
104 | argv[0]); | ||
105 | exit(1); | ||
106 | } | ||
107 | |||
108 | fd = open("/dev/freefall", O_RDONLY); | ||
109 | if (fd < 0) { | ||
110 | perror("/dev/freefall"); | ||
111 | return EXIT_FAILURE; | ||
112 | } | ||
66 | 113 | ||
67 | fd = open("/dev/freefall", O_RDONLY); | 114 | daemon(0, 0); |
68 | if (fd < 0) { | 115 | param.sched_priority = sched_get_priority_max(SCHED_FIFO); |
69 | perror("open"); | 116 | sched_setscheduler(0, SCHED_FIFO, ¶m); |
70 | return EXIT_FAILURE; | 117 | mlockall(MCL_CURRENT|MCL_FUTURE); |
71 | } | ||
72 | 118 | ||
73 | signal(SIGALRM, ignore_me); | 119 | signal(SIGALRM, ignore_me); |
74 | 120 | ||
75 | for (;;) { | 121 | for (;;) { |
76 | unsigned char count; | 122 | unsigned char count; |
77 | 123 | ||
78 | ret = read(fd, &count, sizeof(count)); | 124 | ret = read(fd, &count, sizeof(count)); |
79 | alarm(0); | 125 | alarm(0); |
80 | if ((ret == -1) && (errno == EINTR)) { | 126 | if ((ret == -1) && (errno == EINTR)) { |
81 | /* Alarm expired, time to unpark the heads */ | 127 | /* Alarm expired, time to unpark the heads */ |
82 | continue; | 128 | continue; |
83 | } | 129 | } |
84 | 130 | ||
85 | if (ret != sizeof(count)) { | 131 | if (ret != sizeof(count)) { |
86 | perror("read"); | 132 | perror("read"); |
87 | break; | 133 | break; |
88 | } | 134 | } |
89 | 135 | ||
90 | protect(21); | 136 | protect(21); |
91 | set_led(1); | 137 | set_led(1); |
92 | if (1 || on_ac() || lid_open()) { | 138 | if (1 || on_ac() || lid_open()) |
93 | alarm(2); | 139 | alarm(2); |
94 | } else { | 140 | else |
95 | alarm(20); | 141 | alarm(20); |
96 | } | 142 | } |
97 | } | 143 | |
98 | 144 | close(fd); | |
99 | close(fd); | 145 | return EXIT_SUCCESS; |
100 | return EXIT_SUCCESS; | ||
101 | } | 146 | } |