summaryrefslogtreecommitdiff
path: root/packages/sccd/files/sccd.c
diff options
context:
space:
mode:
authorDenys Dmytriyenko <denis@denix.org>2009-03-17 14:32:59 -0400
committerDenys Dmytriyenko <denis@denix.org>2009-03-17 14:32:59 -0400
commit709c4d66e0b107ca606941b988bad717c0b45d9b (patch)
tree37ee08b1eb308f3b2b6426d5793545c38396b838 /packages/sccd/files/sccd.c
parentfa6cd5a3b993f16c27de4ff82b42684516d433ba (diff)
rename packages/ to recipes/ per earlier agreement
See links below for more details: http://thread.gmane.org/gmane.comp.handhelds.openembedded/21326 http://thread.gmane.org/gmane.comp.handhelds.openembedded/21816 Signed-off-by: Denys Dmytriyenko <denis@denix.org> Acked-by: Mike Westerhof <mwester@dls.net> Acked-by: Philip Balister <philip@balister.org> Acked-by: Khem Raj <raj.khem@gmail.com> Acked-by: Marcin Juszkiewicz <hrw@openembedded.org> Acked-by: Koen Kooi <koen@openembedded.org> Acked-by: Frans Meulenbroeks <fransmeulenbroeks@gmail.com>
Diffstat (limited to 'packages/sccd/files/sccd.c')
-rw-r--r--packages/sccd/files/sccd.c523
1 files changed, 0 insertions, 523 deletions
diff --git a/packages/sccd/files/sccd.c b/packages/sccd/files/sccd.c
deleted file mode 100644
index 4f74c1d49c..0000000000
--- a/packages/sccd/files/sccd.c
+++ /dev/null
@@ -1,523 +0,0 @@
-/*
- * Copyright (c) 2006
- * Protium Computing, Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Protium Computing, Inc.
- * 4. The name of Protium Computing, Inc. may not be used to endorse or
- * promote products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY PROTIUM COMPUTING ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL PROTIUM COMPUTING BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-#include <stdio.h>
-#include <fcntl.h>
-#include <time.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <strings.h>
-#include <errno.h>
-#include <utmp.h>
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include <sys/select.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/un.h>
-#include <sys/syslog.h>
-#include <sys/param.h>
-#include <termios.h>
-
-#include "scc.h"
-
-#define HALT "/sbin/halt"
-#define REBOOT "/sbin/reboot"
-
-char * prog;
-int verbose = 0;
-
-extern int scc_die;
-
-void
-usage(void)
-{
- fprintf(stderr, "Usage: %s OPTIONS\n", prog);
- fprintf(stderr,
- "StorCenter Control Daemon manages the StorCenter's LED, fan and soft power.\n\n");
- fprintf(stderr," -?\t\tthis message\n");
- fprintf(stderr," -h\t\tthis message\n");
- fprintf(stderr," -c\t\tallow core files\n");
- fprintf(stderr," -f\t\trun in the foreground\n");
- fprintf(stderr," -v\t\tverbose, show all packets (must be used with -f)\n");
- (void)exit(2);
-}
-
-int
-sendrecv(int fd, int *i, int *j)
-{
- char buf[8];
- int rc;
- fd_set fds;
- struct timeval sec = {1, 0};
- struct timespec tenth_sec = {0, 100000};
-
-
- /* build the buffer */
- *(int *)(buf) = *i;
- *(int *)(buf + 4) = *j;
-
- if (verbose)
- printf("Send: [0x%08x 0x%08x]\n", *i, *j);
-
- if ((rc = write(fd, buf, 8)) != 8) {
- syslog(LOG_ERR, "Write failed to controller");
- return(-1);
- }
-
- /* Wait for data */
- FD_ZERO(&fds);
- FD_SET(fd, &fds);
- rc = select(1024, &fds, NULL, NULL, &sec);
-
- if (rc == -1) {
- syslog(LOG_ERR, "Controller select failed");
- return (-1);
- } else if (!rc) {
- syslog(LOG_ERR, "Controller timeout");
- return (-1);
- }
-
- /* Consume it */
- if ((rc = read(fd, buf, 8)) != 8) {
- syslog(LOG_ERR, "Read from controller failed");
- return(-1);
- }
-
- *i = *(int *)(buf);
- *j = *(int *)(buf + 4);
-
- if (verbose)
- printf("Recv: [0x%08x 0x%08x]\n", *i, *j);
-
- /* Let it rest */
- nanosleep(&tenth_sec, NULL);
-
- return(0);
-}
-
-int
-setup_clnt()
-{
- int s;
- struct sockaddr_un local;
- int len;
-
- if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
- perror("socket");
- return(-1);
- }
-
- local.sun_family = AF_UNIX;
- strcpy(local.sun_path, SCC_SOCKET);
- unlink(local.sun_path);
-
- len = strlen(local.sun_path) + sizeof(local.sun_family);
- if (bind(s, (struct sockaddr *)&local, len) == -1) {
- perror("bind");
- close(s);
- return(-1);
- }
-
- if (listen(s, 5) == -1) {
- perror("listen");
- close(s);
- return(-1);
- }
-
- /* Force the permission on the unix socket */
- if (chmod(SCC_SOCKET, (S_IWUSR | S_IRUSR)) < 0) {
- perror("chmod socket");
- }
-
- return(s);
-}
-
-int
-setup_cntlr()
-{
- int i, j, fd;
- char *dev = SCC_DEVICE;
- struct termios ti;
-
- /* setup the serial connection to 9600, 8n1 */
- if ((fd = open(dev, O_RDWR|O_NOCTTY)) < 0) {
- perror("Open failed");
- return(-1);
- }
-
- if (ioctl(fd, TCGETS, &ti) < 0) {
- perror("TCGETS failed");
- return(-1);
- }
-
- if (ioctl(fd, TCFLSH, 0) < 0) {
- perror("TCFLSH failed");
- return(-1);
- }
-
- ti.c_iflag = IGNPAR;
- ti.c_oflag = 0;
- ti.c_cflag = (B9600 | CS8 | CREAD | CLOCAL);
- ti.c_lflag = 0;
- ti.c_line = N_TTY;
- bzero(ti.c_cc, NCCS);
- ti.c_cc[VMIN] = 0x08;
-
- if (ioctl(fd, TCSETS, &ti) < 0) {
- perror("TCSETS failed");
- return(-1);
- }
-
- if (verbose) printf("Resetting microcontroller\n");
- i = SCC_RESETW1;
- j = SCC_RESETW2;
- scc_setval(&j, SCC_CKSUMMASK, (int)scc_cksum(&i, &j));
- if (sendrecv(fd, &i, &j) < 0) {
- return(-1);
- }
-
- return(fd);
-}
-
-int
-handle_clnt(int clnt, int *w1, int *w2)
-{
- char buf[SCC_PACKETLEN];
- int s, t, i, j, *x, *y;
- struct sockaddr_un remote;
-
- t = sizeof(remote);
- s = accept(clnt, (struct sockaddr *)&remote, &t);
- if (s < 0) {
- syslog(LOG_ERR, "Unable to accept client");
- return(-1);
- }
-
- if (recv(s, buf, SCC_PACKETLEN, 0) != SCC_PACKETLEN) {
- return(-1);
- }
- close(s);
-
- x = (int *)&buf[0];
- y = (int *)&buf[4];
-
- /*
- * Clients only send fields they want enacted. This allows this daemon
- * to keep the other values constant without informing the clients
- * of the current setting. It allows the protocol to unidirectional.
- *
- * Take the data from the client and add it to the current
- * state then validate the resulting state. If valid, return
- * the new state. If not don't corrupt the existing state.
- */
- i = *w1;
- j = *w2;
-
- if (*x & SCC_POWERMASK)
- scc_setval(&i, SCC_POWERMASK, (*x & SCC_POWERMASK));
- if (*x & SCC_LEDMASK)
- scc_setval(&i, SCC_LEDMASK, (*x & SCC_LEDMASK));
- if (*x & SCC_LEDRATEMASK)
- scc_setval(&i, SCC_LEDRATEMASK, (*x & SCC_LEDRATEMASK));
- if (*x & SCC_FANMASK)
- scc_setval(&i, SCC_FANMASK, (*x & SCC_FANMASK));
-
- if (*y & SCC_FANTEMPONMASK)
- scc_setval(&j, SCC_FANTEMPONMASK, (*y & SCC_FANTEMPONMASK));
- if (*y & SCC_FANTEMPOFFMASK)
- scc_setval(&j, SCC_FANTEMPOFFMASK, (*y & SCC_FANTEMPOFFMASK));
- scc_setval(&j, SCC_IDMASK, SCC_HOST);
- scc_setval(&j, SCC_CKSUMMASK, (int)scc_cksum(&i, &j));
-
- if (scc_validate(&i, &j, verbose) < 0) {
- /* log it and return */
- return(-1);
- }
-
- /*
- * If we are here we got a good packet, return it.
- */
- *w1 = i;
- *w2 = j;
- return(0);
-}
-
-#ifdef NOTUSED
-char
-runlevel()
-{
- struct utmp *ut;
- time_t boot;
-
- /*
- * Find last boot time
- */
- time(&boot);
- boot -= (times(NULL) / HZ);
-
- setutent();
- while ((ut = getutent()) != NULL) {
- /*
- * Find runlevel after our last boot
- */
- if (ut->ut_type == RUN_LVL && ut->ut_time > boot)
- return(ut->ut_pid & 0xff);
- }
- endutent();
-
- return(0xff);
-}
-#endif
-
-int
-work_loop(int cntlr, int clnt)
-{
-
- int rc, w1, w2, c1, c2, saverate;
- int shutdown_called = 0;
- pid_t pid;
- fd_set fds;
- struct timeval tv;
-
- /*
- * If we are booting set to red flash and
- * wait for someone to change it.
- * If we are already in runlevel 5 then set it to blue
- */
- scc_defaults(&w1, &w2);
- scc_setval(&w1, SCC_LEDMASK, SCC_LEDREDFLASH);
- scc_setval(&w2, SCC_IDMASK, SCC_HOST);
- scc_setval(&w2, SCC_CKSUMMASK, (int)scc_cksum(&w1, &w2));
-
- if (verbose) {
- printf("New State: \n");
- scc_validate(&w1, &w2, verbose);
- }
-
- if (sendrecv(cntlr, &w1, &w2) < 0) {
- /* log then carry on */
- }
-
- while (!scc_die) {
- /*
- * Wait for data. How long? Well detecting soft power
- * events should happen fairly quickly, 1 second between
- * probes should be enough, but detecting disk activity
- * probably needs to be a little faster. So we try 0.5s or
- * 500,000 micro seconds. If that steals too much CPU
- * then we backoff here.
- */
- FD_ZERO(&fds);
- FD_SET(clnt, &fds);
- tv.tv_sec = 0;
- tv.tv_usec = 500000;
- rc = select(1024, &fds, NULL, NULL, &tv);
-
- if (rc < 0) {
- /* Select failed try again */
- continue;
- } else if (rc) {
- /* Got a clnt request */
- if (handle_clnt(clnt, &w1, &w2) < 0)
- continue;
- } else {
- /* timeout - just fallthrough to refresh ctlr */
- }
-
- /*
- * Here's how we do blinking lights for disk activity.
- * If there is disk activity and the LED is blue, then
- * set the led to blueflash and the rate to io rate.
- * Next time through if there is still activity, the
- * LED is unchanged. If no activity and the led is flashing
- * blue then return it to solid blue and restore the rate.
- */
- if (disk_activity()) {
- if ((w1 & SCC_LEDMASK) == SCC_LEDBLUE) {
- saverate = (w1 & SCC_LEDRATEMASK);
- scc_setval(&w1, SCC_LEDMASK, SCC_LEDBLUEFLASH);
- scc_setrate(&w1, SCC_LEDRATEMASK,
- SCC_LEDRATESHIFT, SCC_LEDIORATE);
- }
- } else {
- if ((w1 & SCC_LEDMASK) == SCC_LEDBLUEFLASH) {
- scc_setval(&w1, SCC_LEDMASK, SCC_LEDBLUE);
- scc_setval(&w1, SCC_LEDRATEMASK, saverate);
- }
- }
-
- /*
- * Getting here because of a timeout or client request
- * in either case refresh the cntlr. Don't use w1 and w2
- * to refresh, cause the daemon should not incorporate
- * the controller's view of the state into the daemon's
- * view. Only a client should alter w1 and w2.
- */
- c1 = w1;
- c2 = w2;
- if (sendrecv(cntlr, &c1, &c2) < 0) {
- continue;
- }
-
- /*
- * Now examine the packet from the controller to see
- * if action needs to be taken.
- * If the power state is either: stop, restart or reset
- * start shutting down the box. Once shutdown (reboot or halt)
- * has beed call don't do it again.
- */
- if (shutdown_called)
- continue;
-
- switch (c1 & SCC_POWERMASK) {
- case SCC_STOP:
- /* exec halt */
- syslog(LOG_INFO, "Halt requested");
- if ((pid = fork()) == -1) {
- break;
- }
-
- if (pid == 0) {
- /* i am child */
- char *argv[] = {HALT, NULL};
- execv(HALT, argv);
- exit(EXIT_FAILURE);
- }
-
- shutdown_called = 1;
- break;
-
- case SCC_RESTART:
- case SCC_RESET:
- /* exec reboot */
- syslog(LOG_INFO, "Reboot requested");
- if ((pid = fork()) == -1) {
- break;
- }
- if (pid == 0) {
- /* i am child */
- char *argv[] = {REBOOT, NULL};
- execv(REBOOT, argv);
- exit(EXIT_FAILURE);
- }
-
- shutdown_called = 1;
- break;
-
- default:
- /* Nothing to do */
- break;
- }
- }
-}
-
-int
-main(int argc, char *argv[])
-{
-
- int cntlr, clnt, w1, w2;
- int c, daemon, cores;
-
- struct stat st;
- extern char *optarg;
- extern int optind, opterr, optopt;
-
- prog = argv[0];
- daemon = 1;
- cores = 0;
-
- while ((c = getopt(argc, argv, "cfhv?")) != EOF) {
- switch (c) {
- case 'h':
- usage();
- break;
- case 'c':
- cores=1;
- break;
- case 'f':
- daemon=0;
- break;
- case 'v':
- verbose=1;
- break;
- case '?':
- usage();
- break;
-
- }
- }
-
- if (verbose && daemon)
- usage();
-
- if (stat(HALT, &st) < 0) {
- perror("Couldn't find halt");
- exit(EXIT_FAILURE);
- }
-
- if (stat(REBOOT, &st) < 0) {
- perror("Couldn't find reboot");
- exit(EXIT_FAILURE);
- }
-
- if (daemon) {
- if (scc_daemonize(cores) < 0)
- exit(EXIT_FAILURE);
- } else {
- /*
- * Open syslog
- */
- openlog("sccd", LOG_PID, LOG_DAEMON);
- syslog(LOG_INFO, "Starting");
- }
-
- /*
- * Setup the controller connection
- */
- if ((cntlr = setup_cntlr()) < 0)
- exit(EXIT_FAILURE);
-
- /*
- * Setup the client connection
- */
- if ((clnt = setup_clnt()) < 0)
- exit(EXIT_FAILURE);
-
- work_loop(cntlr, clnt);
-
- close(cntlr);
- close(clnt);
- unlink(SCC_PIDFILE);
- exit(EXIT_SUCCESS);
-}
-