Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/sandpoint/sandpoint Add Iomega support (init, reboo...



details:   https://anonhg.NetBSD.org/src/rev/b9c003d0e6f6
branches:  trunk
changeset: 771155:b9c003d0e6f6
user:      phx <phx%NetBSD.org@localhost>
date:      Sat Nov 12 23:57:55 2011 +0000

description:
Add Iomega support (init, reboot, poweroff).
Make new sysctl-nodes for Iomega fan control in machdep.satmgr.

diffstat:

 sys/arch/sandpoint/sandpoint/satmgr.c |  216 +++++++++++++++++++++++++++++++--
 1 files changed, 201 insertions(+), 15 deletions(-)

diffs (truncated from 344 to 300 lines):

diff -r d6db38cac61a -r b9c003d0e6f6 sys/arch/sandpoint/sandpoint/satmgr.c
--- a/sys/arch/sandpoint/sandpoint/satmgr.c     Sat Nov 12 23:52:54 2011 +0000
+++ b/sys/arch/sandpoint/sandpoint/satmgr.c     Sat Nov 12 23:57:55 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: satmgr.c,v 1.12 2011/07/01 19:16:06 dyoung Exp $ */
+/* $NetBSD: satmgr.c,v 1.13 2011/11/12 23:57:55 phx Exp $ */
 
 /*-
  * Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -65,6 +65,7 @@
        struct selinfo          sc_rsel;
        callout_t               sc_ch_wdog;
        callout_t               sc_ch_pbutton;
+       callout_t               sc_ch_sync;
        struct sysmon_pswitch   sc_sm_pbutton;
        int                     sc_open;
        void                    *sc_si;
@@ -79,6 +80,10 @@
        struct satops           *sc_ops;
        char                    sc_btn_buf[8];
        int                     sc_btn_cnt;
+       char                    sc_cmd_buf[8];
+       int                     sc_sysctl_wdog;
+       int                     sc_sysctl_fanlow;
+       int                     sc_sysctl_fanhigh;
 };
 
 static int  satmgr_match(device_t, cfdata_t, void *);
@@ -105,8 +110,11 @@
 
 static void satmgr_reboot(int);
 static int satmgr_sysctl_wdogenable(SYSCTLFN_PROTO);
+static int satmgr_sysctl_fanlow(SYSCTLFN_PROTO);
+static int satmgr_sysctl_fanhigh(SYSCTLFN_PROTO);
 static void wdog_tickle(void *);
 static void send_sat(struct satmgr_softc *, const char *);
+static void send_sat_len(struct satmgr_softc *, const char *, int);
 static int hwintr(void *);
 static void rxintr(struct satmgr_softc *);
 static void txintr(struct satmgr_softc *);
@@ -114,17 +122,23 @@
 static void swintr(void *);
 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 sreboot(struct satmgr_softc *);
 static void qreboot(struct satmgr_softc *);
+static void ireboot(struct satmgr_softc *);
 static void kpwroff(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 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 guarded_pbutton(void *);
 static void sched_sysmon_pbutton(void *);
 
@@ -137,8 +151,9 @@
 };
 
 static struct satops satmodel[] = {
-    { "dlink",    NULL, NULL, dpwroff, dbutton },
-    { "kurobox",  NULL, kreboot, kpwroff, kbutton },
+    { "dlink",    NULL,  NULL,    dpwroff, dbutton },
+    { "iomega",   iinit, ireboot, ipwroff, ibutton },
+    { "kurobox",  NULL,  kreboot, kpwroff, kbutton },
     { "qnap",     qinit, qreboot, qpwroff, qbutton },
     { "synology", sinit, sreboot, spwroff, sbutton }
 };
@@ -155,8 +170,6 @@
 #define CSR_READ(t,r)  bus_space_read_1((t)->sc_iot, (t)->sc_ioh, (r))
 #define CSR_WRITE(t,r,v) bus_space_write_1((t)->sc_iot, (t)->sc_ioh, (r), (v))
 
-static int satmgr_wdog;
-
 static int
 satmgr_match(device_t parent, cfdata_t match, void *aux)
 {
@@ -210,6 +223,7 @@
        selinit(&sc->sc_rsel);
        callout_init(&sc->sc_ch_wdog, 0);
        callout_init(&sc->sc_ch_pbutton, 0);
+       callout_init(&sc->sc_ch_sync, 0);
        mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_HIGH);
        cv_init(&sc->sc_rdcv, "satrd");
        cv_init(&sc->sc_wrcv, "satwr");
@@ -233,11 +247,11 @@
                aprint_error_dev(sc->sc_dev,
                    "unable to register power button with sysmon\n");
 
+       /* create machdep.satmgr subtree for those models which support it */
        if (strcmp(ops->family, "kurobox") == 0) {
                const struct sysctlnode *rnode;
                struct sysctllog *clog;
 
-               /* create machdep.satmgr.* subtree */
                clog = NULL;
                sysctl_createv(&clog, 0, NULL, &rnode,
                        CTLFLAG_PERMANENT,
@@ -256,6 +270,34 @@
                        satmgr_sysctl_wdogenable, 0, NULL, 0,
                        CTL_CREATE, CTL_EOL);
        }
+       else if (strcmp(ops->family, "iomega") == 0) {
+               const struct sysctlnode *rnode;
+               struct sysctllog *clog;
+
+               clog = NULL;
+               sysctl_createv(&clog, 0, NULL, &rnode,
+                       CTLFLAG_PERMANENT,
+                       CTLTYPE_NODE, "machdep", NULL,
+                       NULL, 0, NULL, 0,
+                       CTL_MACHDEP, CTL_EOL);
+               sysctl_createv(&clog, 0, &rnode, &rnode,
+                       CTLFLAG_PERMANENT,
+                       CTLTYPE_NODE, "satmgr", NULL,
+                       NULL, 0, NULL, 0,
+                       CTL_CREATE, CTL_EOL);
+               sysctl_createv(&clog, 0, &rnode, NULL,
+                       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
+                       CTLTYPE_INT, "fan_low_temp",
+                       SYSCTL_DESCR("Turn off fan below this temperature"),
+                       satmgr_sysctl_fanlow, 0, NULL, 0,
+                       CTL_CREATE, CTL_EOL);
+               sysctl_createv(&clog, 0, &rnode, NULL,
+                       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
+                       CTLTYPE_INT, "fan_high_temp",
+                       SYSCTL_DESCR("Turn on fan above this temperature"),
+                       satmgr_sysctl_fanhigh, 0, NULL, 0,
+                       CTL_CREATE, CTL_EOL);
+       }
 
        md_reboot = satmgr_reboot;      /* cpu_reboot() hook */
        if (ops->init != NULL)
@@ -287,21 +329,21 @@
 static int
 satmgr_sysctl_wdogenable(SYSCTLFN_ARGS)
 {
-       int error, t;
        struct sysctlnode node;
        struct satmgr_softc *sc;
+       int error, t;
 
+       sc = device_lookup_private(&satmgr_cd, 0);
        node = *rnode;
-       t = satmgr_wdog;
+       t = sc->sc_sysctl_wdog;
        node.sysctl_data = &t;
        error = sysctl_lookup(SYSCTLFN_CALL(&node));
        if (error || newp == NULL)
                return error;
-
        if (t < 0 || t > 1)
                return EINVAL;
 
-       sc = device_lookup_private(&satmgr_cd, 0);
+       sc->sc_sysctl_wdog = t;
        if (t == 1) {
                callout_setfunc(&sc->sc_ch_wdog, wdog_tickle, sc);
                callout_schedule(&sc->sc_ch_wdog, 90 * hz);
@@ -323,20 +365,72 @@
        callout_schedule(&sc->sc_ch_wdog, 90 * hz);
 }
 
+static int
+satmgr_sysctl_fanlow(SYSCTLFN_ARGS)
+{
+       struct sysctlnode node;
+       struct satmgr_softc *sc;
+       int error, t;
+
+       sc = device_lookup_private(&satmgr_cd, 0);
+       node = *rnode;
+       t = sc->sc_sysctl_fanlow;
+       node.sysctl_data = &t;
+       error = sysctl_lookup(SYSCTLFN_CALL(&node));
+       if (error || newp == NULL)
+               return error;
+       if (t < 0 || t > 99)
+               return EINVAL;
+       sc->sc_sysctl_fanlow = t;
+       iprepcmd(sc, 'b', 'b', 10, 'a',
+           sc->sc_sysctl_fanhigh, sc->sc_sysctl_fanlow);
+       return 0;
+}
+
+static int
+satmgr_sysctl_fanhigh(SYSCTLFN_ARGS)
+{
+       struct sysctlnode node;
+       struct satmgr_softc *sc;
+       int error, t;
+
+       sc = device_lookup_private(&satmgr_cd, 0);
+       node = *rnode;
+       t = sc->sc_sysctl_fanhigh;
+       node.sysctl_data = &t;
+       error = sysctl_lookup(SYSCTLFN_CALL(&node));
+       if (error || newp == NULL)
+               return error;
+       if (t < 0 || t > 99)
+               return EINVAL;
+       sc->sc_sysctl_fanhigh = t;
+       iprepcmd(sc, 'b', 'b', 10, 'a',
+           sc->sc_sysctl_fanhigh, sc->sc_sysctl_fanlow);
+       return 0;
+}
+
 static void
 send_sat(struct satmgr_softc *sc, const char *msg)
 {
-       unsigned lsr, ch, n;
+
+       send_sat_len(sc, msg, strlen(msg));
+}
+
+
+static void
+send_sat_len(struct satmgr_softc *sc, const char *msg, int len)
+{
+       unsigned lsr;
+       int n;
 
  again:
        do {
                lsr = CSR_READ(sc, LSR);
        } while ((lsr & LSR_TXRDY) == 0);
        n = 16; /* FIFO depth */
-       while ((ch = *msg++) != '\0' && n-- > 0) {
-               CSR_WRITE(sc, THR, ch);
-       }
-       if (ch != '\0')
+       while (len-- > 0 && n-- > 0)
+               CSR_WRITE(sc, THR, *msg++);
+       if (len > 0)
                goto again;
 }
 
@@ -762,6 +856,98 @@
 }
 
 static void
+iinit(struct satmgr_softc *sc)
+{
+
+       /* LED blue, auto-fan, turn on at 50C, turn off at 45C */
+       sc->sc_sysctl_fanhigh = 50;
+       sc->sc_sysctl_fanlow = 45;
+       iprepcmd(sc, 'b', 'b', 10, 'a',
+           sc->sc_sysctl_fanhigh, sc->sc_sysctl_fanlow);
+}
+
+static void
+ireboot(struct satmgr_softc *sc)
+{
+
+       iprepcmd(sc, 'g', 0, 0, 0, 0, 0);
+}
+
+static void
+ipwroff(struct satmgr_softc *sc)
+{
+
+       iprepcmd(sc, 'c', 0, 0, 0, 0, 0);
+}
+
+static void
+ibutton(struct satmgr_softc *sc, int ch)
+{
+       int i;
+       char cksum;
+
+       sc->sc_btn_buf[sc->sc_btn_cnt++] = ch;
+
+       if (sc->sc_btn_cnt >= 8) {
+               sc->sc_btn_cnt = 0;
+
+               if (callout_active(&sc->sc_ch_sync) == true) {
+                       /* now we can send a pending command packet */
+                       callout_stop(&sc->sc_ch_sync);
+                       for (i = 0, cksum = 0; i < 7; i++)
+                               cksum += sc->sc_cmd_buf[i];
+                       sc->sc_cmd_buf[7] = cksum & 0x7f;
+                       send_sat_len(sc, sc->sc_cmd_buf, 8);
+               }
+       }
+}
+
+static void
+idosync(void *arg)
+{
+       /*
+        * Send 0-bytes until the 68HC908 sends a reply packet.



Home | Main Index | Thread Index | Old Index