diff options
Diffstat (limited to 'sys/arch')
-rw-r--r-- | sys/arch/sgi/sgi/ip27_machdep.c | 27 | ||||
-rw-r--r-- | sys/arch/sgi/sgi/l1.c | 67 | ||||
-rw-r--r-- | sys/arch/sgi/sgi/l1.h | 3 |
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 *); |