diff options
-rw-r--r-- | files/device_table-openslug.txt | 41 | ||||
-rw-r--r-- | packages/openslug-init/openslug-init-0.10/leds.c | 190 | ||||
-rw-r--r-- | packages/openslug-init/openslug-init-0.10/leds.h | 21 |
3 files changed, 252 insertions, 0 deletions
diff --git a/files/device_table-openslug.txt b/files/device_table-openslug.txt index e69de29bb2..b3ee0cb4dc 100644 --- a/files/device_table-openslug.txt +++ b/files/device_table-openslug.txt @@ -0,0 +1,41 @@ +# <path> <type> <mode> <uid> <gid> <major> <minor> <start> <inc> <count> +# /dev/mem c 640 0 0 1 1 0 0 - +# f A regular file +# d Directory +# c Character special device file +# b Block special device file +# p Fifo (named pipe) +/dev d 755 0 0 - - - - - +/dev/buzzer c 660 0 0 62 0 - - - +/dev/console c 622 0 0 5 1 - - - +/dev/cua c 622 0 0 5 64 0 1 2 +/dev/flash d 755 0 0 - - - - - +/dev/flash/config c 644 0 0 90 6 - - - +/dev/ipsec c 644 0 0 36 10 - - - +/dev/kmem c 640 0 0 1 2 - - - +/dev/leds c 660 0 0 126 0 - - - +/dev/mem c 640 0 0 1 1 - - - +/dev/mtd c 664 0 0 90 0 0 2 4 +/dev/mtdblock b 644 0 0 31 0 0 1 4 +/dev/mtdr c 664 0 0 90 0 1 2 4 +/dev/null c 666 0 0 1 3 - - - +/dev/pbuttons c 660 0 0 61 0 - - - +/dev/ppp c 644 0 0 108 0 - - - +/dev/ptyp c 644 0 0 2 0 0 1 10 +/dev/ram b 644 0 0 1 0 0 1 4 +/dev/random c 644 0 0 1 8 - - - +/dev/rbuttons c 660 0 0 60 0 - - - +/dev/rtc c 644 0 0 10 135 - - - +/dev/sda b 664 0 0 8 0 - - - +/dev/sda b 664 0 0 8 1 1 1 5 +/dev/sdb b 664 0 0 8 16 - - - +/dev/sdb b 664 0 0 8 17 1 1 5 +/dev/sdc b 664 0 0 8 32 - - - +/dev/sdc b 664 0 0 8 33 1 1 5 +/dev/tty c 666 0 0 5 0 - - - +/dev/tty c 644 0 0 4 0 0 1 10 +/dev/ttyS c 644 0 0 4 64 0 1 2 +/dev/ttyp c 644 0 0 3 0 0 1 10 +/dev/urandom c 644 0 0 1 9 - - - +/dev/zero c 666 0 0 1 5 - - - +/bin/tinylogin f 6755 0 0 - - - - - diff --git a/packages/openslug-init/openslug-init-0.10/leds.c b/packages/openslug-init/openslug-init-0.10/leds.c index e69de29bb2..e2120ae5d6 100644 --- a/packages/openslug-init/openslug-init-0.10/leds.c +++ b/packages/openslug-init/openslug-init-0.10/leds.c @@ -0,0 +1,190 @@ + #include <stdio.h> + #include <stdlib.h> + #include <math.h> + #include <errno.h> + #include <string.h> + #include <endian.h> + #include <unistd.h> + #include <fcntl.h> + #include <sys/ioctl.h> + #include "leds.h" + + static int leds; + static int reset; + static int verbose = 0; + enum { + off=0, on=1, blink, unknown, transition=unknown + }; + + + void init_leds(void) + { + int i; + if ((leds = open("/dev/leds", O_RDWR)) < 0) { + int e1 = errno; + if (e1 != ENOENT) { + + fprintf(stderr,"Error: Could not open LEDS device file '/dev/leds' : %s\n", + strerror(e1)); + if(e1 == EACCES) + fprintf(stderr,"Run as root\n"); + exit(1); + } + } + + if (verbose) + printf("leds: initialized.\n"); + } + + void led_ioctl( int cmd, int num ) + { + int i, st; + + if (ioctl(leds, cmd, num) < 0) { + int e1 = errno; + fprintf(stderr, "leds: ioctl(%d,%d): failed to set leds: %s\n", + cmd, num, strerror(e1)); + exit(1); + } + } + + void led_set( int led, int state ) + { + switch (state) { + case off: if (!reset) led_ioctl(N2_LM_OFF, led); break; + case on: led_ioctl(N2_LM_ON, led); break; + case blink: /* Ensure any previous timer gets deleted first and that + * the LED is in a well known state. + */ + if (!reset) led_ioctl(N2_LM_OFF, led); + led_ioctl(N2_LM_BLINK, led); break; + } + } + + int led( int ch ) { + switch (ch) { + case 'r': return LED_RS_RED; + case 'g': return LED_RS_GRN; + case '1': return LED_DISK1; + case '2': return LED_DISK2; + case 'A': reset = 1; return LED_ALL; + default: fprintf(stderr, "leds: %c: unknown LED (use r,g,0,1 or A)\n", ch); + exit(1); + } + } + + int main( int argc, char **argv ) + { + /* Default: switch green on, red off (-A +g). */ + if (argc == 1) { + verbose = 1; + init_leds(); + led_ioctl(N2_LM_ALL_OFF, 0); + led_ioctl(N2_LM_ON, LED_RS_GRN); + } else { + int i, alt=0, state[PHYS_LEDS]; + for(i=0; i<PHYS_LEDS; ++i) + state[i] = unknown; + reset = 0; + + while (--argc > 0) { + char *arg = *++argv; + int st; + if (strcmp(arg, "-v") == 0) { + ++verbose; + continue; + } + + switch (*arg) { + case '+': st = on; break; + case '-': st = off; break; + case '!': st = blink; break; + case '/': st = transition; break; + default: fprintf(stderr, "leds: %c: unknown option\n", *arg); + exit(1); + } + + if (st != transition) { + while (*++arg) { + i = led(*arg); + if (i == LED_ALL) + for (i=0; i<PHYS_LEDS; ++i) state[i] = st; + else + state[i] = st; + } + } else { + int done, newstate[PHYS_LEDS]; + for(i=0; i<PHYS_LEDS; ++i) + newstate[i] = off; + while (*++arg) { + i = led(*arg); + if (i == LED_ALL) + for (i=0; i<PHYS_LEDS; ++i) newstate[i] = on; + else + newstate[i] = on; + } + + /* Merge the newstate back in. This sets 'alt' if going + * from an old state of just red to a new of just green + * or vice versa (and this is the only way of getting + * 'alt') + */ + /* Blink anything which changes from off to on or from + * on to off (this ignores anything already blinking). + */ + for (done=i=0; i<PHYS_LEDS; ++i) { + if (state[i] == !newstate[i]) { + done = 1; + state[i] = blink; + } + } + + /* Is anything (new) blinking? If it is then deal + * with the red/green case - blinking red,green is + * amber, is that what we want? This could be + * improved by a better kernel interface - it would + * be nice just to specify on/off times and a start + * time for each LED. + */ + if (done) { + if (state[LED_RS_RED] == blink && state[LED_RS_GRN] == blink && + newstate[LED_RS_RED] == !newstate[LED_RS_GRN]) { + /* Kernel bug: must switch off r and g first. */ + alt = 1; + } + } else { + for (i=0; i<PHYS_LEDS; ++i) { + if (newstate[i] == on) { + state[i] = blink; + } + } + } + } + } + + /* Go through the list making the required settings. 'alt' is + * special. 'reset' means A was given and all the settings are + * known. + */ + init_leds(); + if (reset) + led_ioctl(N2_LM_ALL_OFF, 0); + if (alt) { + /* Turn the leds off first to get to a known state. */ + led_set(LED_RS_GRN, off); + led_set(LED_RS_RED, off); + led_ioctl(N2_LM_ALT, LED_RS_RED); + } else { + /* KERNEL BUG: setting the green timer zaps the red behaviour + * to toggle the green, therefore if red blink is set before + * green blink no blink will happen! + */ + led_set(LED_RS_GRN, state[LED_RS_GRN]); + led_set(LED_RS_RED, state[LED_RS_RED]); + } + led_set(LED_DISK1, state[LED_DISK1]); + led_set(LED_DISK2, state[LED_DISK2]); + } + + return 0; + } diff --git a/packages/openslug-init/openslug-init-0.10/leds.h b/packages/openslug-init/openslug-init-0.10/leds.h index e69de29bb2..0b236dd6c0 100644 --- a/packages/openslug-init/openslug-init-0.10/leds.h +++ b/packages/openslug-init/openslug-init-0.10/leds.h @@ -0,0 +1,21 @@ + void init_leds(void); + void led_on(int); + void led_off( int ); + void led_toggle(int num); + + // ioctls -- 'M" is used for sound cards...we don't got one so it seems safe + #define N2_LM_OFF _IOW('M',32,long) + #define N2_LM_ON _IOW('M',33,long) + #define N2_LM_BLINK _IOW('M',34,long) + #define N2_LM_ALT _IOW('M',35,long) + #define N2_LM_ALL_ON _IO('M',36) + #define N2_LM_ALL_OFF _IO('M',37) + + // The LED names for switches + #define LED_RS_RED 0 + #define LED_RS_GRN 1 + #define LED_DISK1 2 + #define LED_DISK2 3 + #define LED_ALL 4 + + #define PHYS_LEDS 4 |