Module Name: src Committed By: nisimura Date: Mon Apr 16 14:30:42 UTC 2012
Modified Files: src/sys/arch/sandpoint/sandpoint: satmgr.c Log Message: Preliminary support of TS-TGL/KBT4 power down operation. To generate a diff of this commit: cvs rdiff -u -r1.18 -r1.19 src/sys/arch/sandpoint/sandpoint/satmgr.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/sandpoint/sandpoint/satmgr.c diff -u src/sys/arch/sandpoint/sandpoint/satmgr.c:1.18 src/sys/arch/sandpoint/sandpoint/satmgr.c:1.19 --- src/sys/arch/sandpoint/sandpoint/satmgr.c:1.18 Mon Apr 9 13:26:37 2012 +++ src/sys/arch/sandpoint/sandpoint/satmgr.c Mon Apr 16 14:30:42 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: satmgr.c,v 1.18 2012/04/09 13:26:37 nisimura Exp $ */ +/* $NetBSD: satmgr.c,v 1.19 2012/04/16 14:30:42 nisimura Exp $ */ /*- * Copyright (c) 2010 The NetBSD Foundation, Inc. @@ -120,26 +120,30 @@ static void rxintr(struct satmgr_softc * static void txintr(struct satmgr_softc *); static void startoutput(struct satmgr_softc *); static void swintr(void *); +static void minit(struct satmgr_softc *); static void sinit(struct satmgr_softc *); static void qinit(struct satmgr_softc *); static void iinit(struct satmgr_softc *); static void kreboot(struct satmgr_softc *); +static void mreboot(struct satmgr_softc *); static void sreboot(struct satmgr_softc *); static void qreboot(struct satmgr_softc *); static void ireboot(struct satmgr_softc *); static void kpwroff(struct satmgr_softc *); +static void mpwroff(struct satmgr_softc *); static void spwroff(struct satmgr_softc *); static void qpwroff(struct satmgr_softc *); static void dpwroff(struct satmgr_softc *); static void ipwroff(struct satmgr_softc *); static void kbutton(struct satmgr_softc *, int); +static void mbutton(struct satmgr_softc *, int); static void sbutton(struct satmgr_softc *, int); static void qbutton(struct satmgr_softc *, int); static void dbutton(struct satmgr_softc *, int); static void ibutton(struct satmgr_softc *, int); static void idosync(void *); static void iprepcmd(struct satmgr_softc *, int, int, int, int, int, int); -static void mbutton(struct satmgr_softc *, int); +static int mbtnintr(void *); static void guarded_pbutton(void *); static void sched_sysmon_pbutton(void *); @@ -155,7 +159,7 @@ static struct satops satmodel[] = { { "dlink", NULL, NULL, dpwroff, dbutton }, { "iomega", iinit, ireboot, ipwroff, ibutton }, { "kurobox", NULL, kreboot, kpwroff, kbutton }, - { "kurot4", NULL, NULL, NULL, mbutton }, + { "kurot4", minit, mreboot, mpwroff, mbutton }, { "qnap", qinit, qreboot, qpwroff, qbutton }, { "synology", sinit, sreboot, spwroff, sbutton } }; @@ -302,6 +306,10 @@ satmgr_attach(device_t parent, device_t satmgr_sysctl_fanhigh, 0, NULL, 0, CTL_CREATE, CTL_EOL); } + else if (strcmp(ops->family, "kurot4") == 0) { + intr_establish(2 + I8259_ICU, + IST_LEVEL, IPL_SERIAL, mbtnintr, sc); + } md_reboot = satmgr_reboot; /* cpu_reboot() hook */ if (ops->init != NULL) @@ -438,6 +446,24 @@ send_sat_len(struct satmgr_softc *sc, co goto again; } +static void +recv_sat_len(struct satmgr_softc *sc, char *buf, int len) +{ + int lsr; + + lsr = CSR_READ(sc, LSR); + while (len > 0 && (lsr & LSR_RXRDY)) { + if (lsr & (LSR_BI | LSR_FE | LSR_PE)) { + (void) CSR_READ(sc, RBR); + lsr = CSR_READ(sc, LSR); + continue; + } + *buf++ = CSR_READ(sc, RBR); + len -= 1; + lsr = CSR_READ(sc, LSR); + } +} + static int satopen(dev_t dev, int flags, int fmt, struct lwp *l) { @@ -721,14 +747,14 @@ static void kreboot(struct satmgr_softc *sc) { - send_sat(sc, "CCGG"); + send_sat(sc, "CCGG"); /* perform reboot */ } static void kpwroff(struct satmgr_softc *sc) { - send_sat(sc, "EEGG"); + send_sat(sc, "EEGG"); /* force power off */ } static void @@ -951,10 +977,77 @@ iprepcmd(struct satmgr_softc *sc, int po */ } +static void msattalk(struct satmgr_softc *, const char *, char *, int); + +static void +msattalk(struct satmgr_softc *sc, const char *cmd, char *rep, int n) +{ + int len, i; + uint8_t pa; + + if (cmd[0] != 0x80) + len = 2 + cmd[0]; /* cmd[0] is data portion length */ + else + len = 2; /* read report */ + + for (i = 0, pa = 0; i < len; i++) + pa += cmd[i]; + pa = 0 - pa; /* parity formula */ + + CSR_WRITE(sc, IER, 0); + send_sat_len(sc, cmd, len); + send_sat_len(sc, &pa, 1); + recv_sat_len(sc, rep, n); + CSR_WRITE(sc, IER, 0x7f); +} + +static void +minit(struct satmgr_softc *sc) +{ + char report[4]; + + msattalk(sc, "\x00\x03", report, 4); /* boot has completed */ +} + +static void +mreboot(struct satmgr_softc *sc) +{ + char report[4]; + + msattalk(sc, "\x01\x35\x00", report, 4); /* stop watchdog timer */ + msattalk(sc, "\x00\x0c", report, 4); /* shutdown in progress */ + msattalk(sc, "\x00\x03", report, 4); /* boot has completed */ + msattalk(sc, "\x00\x0e", report, 4); /* perform reboot */ +} + +static void +mpwroff(struct satmgr_softc *sc) +{ + char report[4]; + + msattalk(sc, "\x01\x35\x00", report, 4); /* stop watchdog timer */ + msattalk(sc, "\x00\x0c", report, 4); /* shutdown in progress */ + msattalk(sc, "\x00\x03", report, 4); /* boot has completed */ + msattalk(sc, "\x00\x06", report, 4); /* force power off */ +} + static void mbutton(struct satmgr_softc *sc, int ch) { - /* do nothing */ + /* can do nothing */ +} + +static int +mbtnintr(void *arg) +{ + /* notified after 3 seconds guard time */ + struct satmgr_softc *sc = arg; + char report[2]; + + msattalk(sc, "\x80\x36", report, 2); + if ((report[0] & 01) == 0) /* power button depressed */ + sysmon_task_queue_sched(0, sched_sysmon_pbutton, sc); + return 1; } static void @@ -964,7 +1057,7 @@ guarded_pbutton(void *arg) /* we're now in callout(9) context */ sysmon_task_queue_sched(0, sched_sysmon_pbutton, sc); - send_sat(sc, "UU"); + send_sat(sc, "UU"); /* make front panel LED flashing */ } static void