summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2009-11-29 17:03:54 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2009-11-29 17:03:54 +0000
commitee8f82e280f39d9319a0bb7063d0412c8125b76d (patch)
treeed381401dcb98709a3d283ae535611800855c3aa /sys/arch
parentf8b7a80e30517a2fe4374ede254d41d594b271f4 (diff)
Send a powerdown command to L1 on IP35 if powerdown is requested.
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/sgi/sgi/ip27_machdep.c27
-rw-r--r--sys/arch/sgi/sgi/l1.c67
-rw-r--r--sys/arch/sgi/sgi/l1.h3
3 files changed, 88 insertions, 9 deletions
diff --git a/sys/arch/sgi/sgi/ip27_machdep.c b/sys/arch/sgi/sgi/ip27_machdep.c
index 05297863789..cec3d107e73 100644
--- a/sys/arch/sgi/sgi/ip27_machdep.c
+++ b/sys/arch/sgi/sgi/ip27_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip27_machdep.c,v 1.39 2009/11/25 22:25:37 jsing Exp $ */
+/* $OpenBSD: ip27_machdep.c,v 1.40 2009/11/29 17:03:53 miod Exp $ */
/*
* Copyright (c) 2008, 2009 Miodrag Vallat.
@@ -40,6 +40,7 @@
#include <uvm/uvm_extern.h>
#include <sgi/sgi/ip27.h>
+#include <sgi/sgi/l1.h>
#include <sgi/xbow/hub.h>
#include <sgi/xbow/widget.h>
#include <sgi/xbow/xbow.h>
@@ -47,6 +48,8 @@
#include <sgi/pci/iofreg.h>
#include <dev/ic/comvar.h>
+#include <dev/cons.h>
+
extern char *hw_prod;
extern void (*md_halt)(int);
@@ -529,11 +532,23 @@ ip27_halt(int howto)
else
promop = GDA_PROMOP_EIM;
#else
- if (howto & RB_POWERDOWN)
- printf("Software powerdown not supported, "
- "please switch off power manually.\n");
- for (;;) ;
- /* NOTREACHED */
+ if (howto & RB_POWERDOWN) {
+ if (ip35) {
+ l1_exec_command(masternasid, "pwr d");
+ delay(1000000);
+ printf("Powerdown failed, "
+ "please switch off power manually.\n");
+ } else {
+ printf("Software powerdown not supported, "
+ "please switch off power manually.\n");
+ }
+ for (;;) ;
+ } else {
+ printf("System halted.\n"
+ "Press any key to restart\n");
+ cngetc();
+ promop = GDA_PROMOP_REBOOT;
+ }
#endif
} else
promop = GDA_PROMOP_REBOOT;
diff --git a/sys/arch/sgi/sgi/l1.c b/sys/arch/sgi/sgi/l1.c
index a5a6e23b133..c3d1eafe496 100644
--- a/sys/arch/sgi/sgi/l1.c
+++ b/sys/arch/sgi/sgi/l1.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: l1.c,v 1.2 2009/11/09 16:58:55 miod Exp $ */
+/* $OpenBSD: l1.c,v 1.3 2009/11/29 17:03:53 miod Exp $ */
/*
* Copyright (c) 2009 Miodrag Vallat.
@@ -557,7 +557,8 @@ l1_read_board_ia(int16_t nasid, u_char **ria, size_t *rialen)
L1_ARG_INT, (uint32_t)0); /* size */
if (pktlen > sizeof pkt) {
#ifdef DIAGNOSTIC
- panic("L1 command packet too large (%zu) for buffer", pktlen);
+ panic("%s: L1 command packet too large (%zu) for buffer",
+ __func__, pktlen);
#endif
return ENOMEM;
}
@@ -874,3 +875,65 @@ out:
free(ia, M_DEVBUF);
return rc;
}
+
+int
+l1_exec_command(int16_t nasid, const char *cmd)
+{
+ u_char pkt[64 + 64]; /* command and response packet buffer */
+ size_t pktlen;
+ uint32_t data;
+
+ /*
+ * Build the command packet.
+ */
+ pktlen = l1_command_build(pkt, sizeof pkt,
+ L1_ADDRESS(L1_TYPE_L1, L1_ADDRESS_LOCAL | L1_TASK_COMMAND),
+ L1_REQ_EXEC_CMD, 1,
+ L1_ARG_ASCII, cmd);
+ if (pktlen > sizeof pkt) {
+#ifdef DIAGNOSTIC
+ panic("%s: L1 command packet too large (%zu) for buffer",
+ __func__, pktlen);
+#endif
+ return ENOMEM;
+ }
+
+ if (l1_packet_put(nasid, pkt, pktlen) != 0)
+ return EWOULDBLOCK;
+
+ pktlen = sizeof pkt;
+ if (l1_receive_response(nasid, pkt, &pktlen) != 0)
+ return EWOULDBLOCK;
+
+ if (pktlen <= 6) {
+#ifdef L1_DEBUG
+ printf("truncated response (length %d)\n", pktlen);
+#endif
+ return ENXIO;
+ }
+
+ /*
+ * Check the response code.
+ */
+
+ data = l1_packet_get_be32(&pkt[1]);
+ if (data != L1_RESP_OK) {
+#ifdef L1_DEBUG
+ printf("unexpected L1 response code: %08x\n", data);
+#endif
+ return ENXIO;
+ }
+
+ /*
+ * We do not expect anything in return.
+ */
+
+ if (pkt[5] != 0) {
+#ifdef L1_DEBUG
+ printf("unexpected L1 response: %d values\n", pkt[5]);
+#endif
+ return ENXIO;
+ }
+
+ return 0;
+}
diff --git a/sys/arch/sgi/sgi/l1.h b/sys/arch/sgi/sgi/l1.h
index db400ed7370..1766bd53c94 100644
--- a/sys/arch/sgi/sgi/l1.h
+++ b/sys/arch/sgi/sgi/l1.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: l1.h,v 1.1 2009/11/08 22:44:16 miod Exp $ */
+/* $OpenBSD: l1.h,v 1.2 2009/11/29 17:03:53 miod Exp $ */
/*
* Copyright (c) 2009 Miodrag Vallat.
@@ -71,3 +71,4 @@
int l1_read_board_ia(int16_t, u_char **, size_t *);
int l1_get_brick_ethernet_address(int16_t, uint8_t *);
+int l1_exec_command(int16_t, const char *);