Here's an updated patch for 2.4.17 kernel to allow the s390x Linux
kernel to listen for an act on the "SIGNAL SHUTDOWN" condition
(which can occur via z/VM 4.3 #CP SIGNAL SHUTDOWN, #CP SHUTDOWN or
LPAR power-down).
--- ./arch/s390x/kernel/smp.c 2002/06/13 14:28:44 1.1
+++ ./arch/s390x/kernel/smp.c 2002/07/12 18:22:01
@@ -55,10 +55,12 @@
spinlock_t kernel_flag __cacheline_aligned_in_smp =
SPIN_LOCK_UNLOCKED;
unsigned long cpu_online_map;
+static long long quiesce_psw[2] = {0x0002000080000000, 0x0000000000000fff};
+
/*
* Setup routine for controlling SMP activation
*
* Command-line option of "nosmp" or "maxcpus=0" will disable SMP
* activation entirely (the MPS table probe still happens, though).
@@ -275,12 +277,11 @@
{
if (smp_processor_id() == 0) {
smp_send_stop();
if (MACHINE_IS_VM && strlen(vmhalt_cmd) > 0)
cpcmd(vmhalt_cmd, NULL, 0);
- signal_processor(smp_processor_id(),
- sigp_stop_and_store_status);
+ __load_psw(quiesce_psw);
}
for (;;)
enabled_wait();
}
@@ -294,12 +295,11 @@
{
if (smp_processor_id() == 0) {
smp_send_stop();
if (MACHINE_IS_VM && strlen(vmpoff_cmd) > 0)
cpcmd(vmpoff_cmd, NULL, 0);
- signal_processor(smp_processor_id(),
- sigp_stop_and_store_status);
+ __load_psw(quiesce_psw);
}
for (;;)
enabled_wait();
}
--- ./drivers/s390/char/hwc.h 2002/06/13 14:28:44 1.1
+++ ./drivers/s390/char/hwc.h 2002/06/13 14:32:00
@@ -20,17 +20,19 @@
#define ET_Msg 0x02
#define ET_StateChange 0x08
#define ET_PMsgCmd 0x09
#define ET_CntlProgOpCmd 0x20
#define ET_CntlProgIdent 0x0B
+#define ET_EventSigQ 0x1d
#define ET_OpCmd_Mask 0x80000000
#define ET_Msg_Mask 0x40000000
#define ET_StateChange_Mask 0x01000000
#define ET_PMsgCmd_Mask 0x00800000
#define ET_CtlProgOpCmd_Mask 0x00000001
#define ET_CtlProgIdent_Mask 0x00200000
+#define ET_EventSigQ_Mask 0x00000008
#define GMF_DOM 0x8000
#define GMF_SndAlrm 0x4000
#define GMF_HoldMsg 0x2000
@@ -212,11 +214,11 @@
0x00
},
0x0000,
0x0000,
sizeof (_hwcb_mask_t),
- ET_OpCmd_Mask | ET_PMsgCmd_Mask | ET_StateChange_Mask,
+ ET_OpCmd_Mask | ET_PMsgCmd_Mask | ET_StateChange_Mask |
ET_EventSigQ_Mask,
ET_Msg_Mask | ET_PMsgCmd_Mask | ET_CtlProgIdent_Mask
};
typedef struct {
_EBUF_HEADER
@@ -231,10 +233,21 @@
_hwcb_mask_t hwc_send_mask;
u32 read_data_function_mask;
} __attribute__ ((packed))
statechangebuf_t;
+
+typedef struct {
+ _EBUF_HEADER
+ u16 countDown;
+ u8 unitType;
+ #define EVDSQSEC 0
+ #define EVDSQMIN 1
+ #define EVDSQHR 2
+} __attribute__ ((packed))
+
+eventsigqbuf_t;
#define _GDS_VECTOR_HEADER u16 length; \
u16 gds_id;
#define _GDS_SUBVECTOR_HEADER u8 length; \
--- ./drivers/s390/char/hwc_rw.c 2002/06/13 14:29:25 1.1
+++ ./drivers/s390/char/hwc_rw.c 2002/06/13 14:32:01
@@ -1607,10 +1607,24 @@
}
return retval;
}
+int
+eval_eventsigqbuf (eventsigqbuf_t *sigQbuf) {
+ extern void ctrl_alt_del(void);
+ int secsLeft;
+ static short unitVal[3] = {1, 60, 3600};
+
+ secsLeft = sigQbuf->countDown * unitVal[sigQbuf->unitType];
+ printk("Processor has signalled power-down in %d seconds\n"
+ "This system is now shutting down\n",secsLeft);
+ ctrl_alt_del();
+ return 0;
+}
+
+
static int
process_evbufs (void *start, void *end)
{
int retval = 0;
evbuf_t *evbuf;
@@ -1641,10 +1655,13 @@
retval += eval_evbuf (evbuf_data, evbuf_end);
break;
case ET_StateChange:
retval += eval_statechangebuf
((statechangebuf_t *) evbuf);
+ break;
+ case ET_EventSigQ:
+ retval += eval_eventsigqbuf((eventsigqbuf_t *)
evbuf);
break;
default:
internal_print (
DELAYED_WRITE,
HWC_RW_PRINT_HEADER