blob: a3cfe1a5f964aedf1b4e83ec0f62dd34f8b51a8c [file] [log] [blame]
Pavel Machekef2cfc72009-02-18 14:48:23 -08001/* 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>
Christian Thaeter2bace8b2009-07-25 20:55:15 +020019#include <sys/mman.h>
20#include <sched.h>
Pavel Machekef2cfc72009-02-18 14:48:23 -080021
22void 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
38void set_led(int on)
39{
40 write_int("/sys/class/leds/hp::hddprotect/brightness", on);
41}
42
43void protect(int seconds)
44{
45 write_int("/sys/block/sda/device/unload_heads", seconds*1000);
46}
47
48int on_ac(void)
49{
50// /sys/class/power_supply/AC0/online
51}
52
53int lid_open(void)
54{
55// /proc/acpi/button/lid/LID/state
56}
57
58void ignore_me(void)
59{
60 protect(0);
61 set_led(0);
Pavel Machekef2cfc72009-02-18 14:48:23 -080062}
63
Frans Popb519c152009-06-22 11:08:36 +020064int main(int argc, char *argv[])
Pavel Machekef2cfc72009-02-18 14:48:23 -080065{
Frans Popb519c152009-06-22 11:08:36 +020066 int fd, ret;
Christian Thaeter2bace8b2009-07-25 20:55:15 +020067 struct sched_param param;
Pavel Machekef2cfc72009-02-18 14:48:23 -080068
Frans Popb519c152009-06-22 11:08:36 +020069 fd = open("/dev/freefall", O_RDONLY);
70 if (fd < 0) {
71 perror("open");
72 return EXIT_FAILURE;
73 }
Pavel Machekef2cfc72009-02-18 14:48:23 -080074
Christian Thaeter2bace8b2009-07-25 20:55:15 +020075 daemon(0, 0);
76 param.sched_priority = sched_get_priority_max(SCHED_FIFO);
77 sched_setscheduler(0, SCHED_FIFO, &param);
78 mlockall(MCL_CURRENT|MCL_FUTURE);
79
Pavel Machekef2cfc72009-02-18 14:48:23 -080080 signal(SIGALRM, ignore_me);
81
Frans Popb519c152009-06-22 11:08:36 +020082 for (;;) {
83 unsigned char count;
Pavel Machekef2cfc72009-02-18 14:48:23 -080084
Frans Popb519c152009-06-22 11:08:36 +020085 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 }
Pavel Machekef2cfc72009-02-18 14:48:23 -080091
Frans Popb519c152009-06-22 11:08:36 +020092 if (ret != sizeof(count)) {
93 perror("read");
94 break;
95 }
Pavel Machekef2cfc72009-02-18 14:48:23 -080096
Frans Popb519c152009-06-22 11:08:36 +020097 protect(21);
98 set_led(1);
99 if (1 || on_ac() || lid_open())
100 alarm(2);
101 else
102 alarm(20);
103 }
Pavel Machekef2cfc72009-02-18 14:48:23 -0800104
Frans Popb519c152009-06-22 11:08:36 +0200105 close(fd);
106 return EXIT_SUCCESS;
Pavel Machekef2cfc72009-02-18 14:48:23 -0800107}