diff options
Diffstat (limited to 'hw/s390x')
-rw-r--r-- | hw/s390x/event-facility.c | 17 | ||||
-rw-r--r-- | hw/s390x/sclpquiesce.c | 29 |
2 files changed, 37 insertions, 9 deletions
diff --git a/hw/s390x/event-facility.c b/hw/s390x/event-facility.c index a3aceef8f5..25951a020a 100644 --- a/hw/s390x/event-facility.c +++ b/hw/s390x/event-facility.c @@ -120,7 +120,7 @@ static uint16_t handle_write_event_buf(SCLPEventFacility *ef, ec = SCLP_EVENT_GET_CLASS(event); if (ec->write_event_data && - ec->event_type() == event_buf->type) { + ec->can_handle_event(event_buf->type)) { rc = ec->write_event_data(event, event_buf); break; } @@ -183,7 +183,7 @@ static uint16_t handle_sccb_read_events(SCLPEventFacility *ef, SCCB *sccb, { uint16_t rc; int slen; - unsigned elen = 0; + unsigned elen; BusChild *kid; SCLPEvent *event; SCLPEventClass *ec; @@ -203,11 +203,11 @@ static uint16_t handle_sccb_read_events(SCLPEventFacility *ef, SCCB *sccb, if (mask & ec->get_send_mask()) { if (ec->read_event_data(event, event_buf, &slen)) { + elen = be16_to_cpu(event_buf->length); + event_buf = (EventBufferHeader *) ((char *)event_buf + elen); rc = SCLP_RC_NORMAL_COMPLETION; } } - elen = be16_to_cpu(event_buf->length); - event_buf = (void *) event_buf + elen; } if (sccb->h.control_mask[2] & SCLP_VARIABLE_LENGTH_RESPONSE) { @@ -338,10 +338,19 @@ static int init_event_facility(S390SCLPDevice *sdev) return 0; } +static void reset_event_facility(DeviceState *dev) +{ + S390SCLPDevice *sdev = SCLP_S390_DEVICE(dev); + + sdev->ef->receive_mask = 0; +} + static void init_event_facility_class(ObjectClass *klass, void *data) { + DeviceClass *dc = DEVICE_CLASS(klass); S390SCLPDeviceClass *k = SCLP_S390_DEVICE_CLASS(klass); + dc->reset = reset_event_facility; k->init = init_event_facility; } diff --git a/hw/s390x/sclpquiesce.c b/hw/s390x/sclpquiesce.c index 5fadc86d42..a3c4bd6272 100644 --- a/hw/s390x/sclpquiesce.c +++ b/hw/s390x/sclpquiesce.c @@ -22,9 +22,9 @@ typedef struct SignalQuiesce { uint8_t unit; } QEMU_PACKED SignalQuiesce; -static int event_type(void) +static bool can_handle_event(uint8_t type) { - return SCLP_EVENT_SIGNAL_QUIESCE; + return type == SCLP_EVENT_SIGNAL_QUIESCE; } static unsigned int send_mask(void) @@ -65,6 +65,17 @@ static int read_event_data(SCLPEvent *event, EventBufferHeader *evt_buf_hdr, return 1; } +static const VMStateDescription vmstate_sclpquiesce = { + .name = "sclpquiesce", + .version_id = 0, + .minimum_version_id = 0, + .minimum_version_id_old = 0, + .fields = (VMStateField[]) { + VMSTATE_BOOL(event_pending, SCLPEvent), + VMSTATE_END_OF_LIST() + } +}; + typedef struct QuiesceNotifier QuiesceNotifier; static struct QuiesceNotifier { @@ -84,8 +95,6 @@ static void quiesce_powerdown_req(Notifier *n, void *opaque) static int quiesce_init(SCLPEvent *event) { - event->event_type = SCLP_EVENT_SIGNAL_QUIESCE; - qn.notifier.notify = quiesce_powerdown_req; qn.event = event; @@ -94,15 +103,25 @@ static int quiesce_init(SCLPEvent *event) return 0; } +static void quiesce_reset(DeviceState *dev) +{ + SCLPEvent *event = SCLP_EVENT(dev); + + event->event_pending = false; +} + static void quiesce_class_init(ObjectClass *klass, void *data) { + DeviceClass *dc = DEVICE_CLASS(klass); SCLPEventClass *k = SCLP_EVENT_CLASS(klass); + dc->reset = quiesce_reset; + dc->vmsd = &vmstate_sclpquiesce; k->init = quiesce_init; k->get_send_mask = send_mask; k->get_receive_mask = receive_mask; - k->event_type = event_type; + k->can_handle_event = can_handle_event; k->read_event_data = read_event_data; k->write_event_data = NULL; } |