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