uint32_t iov_bs; /* offset in buf for char layer read operation */
uint32_t iov_data_len; /* length of byte stream in buffer */
uint32_t iov_sclp_rest; /* length of byte stream not read via SCLP */
- qemu_irq irq_read_vt220;
+ bool notify; /* qemu_notify_event() req'd if true */
} SCLPConsole;
/* character layer call-back functions */
static int chr_can_read(void *opaque)
{
SCLPConsole *scon = opaque;
+ int avail = SIZE_BUFFER_VT220 - scon->iov_data_len;
- return SIZE_BUFFER_VT220 - scon->iov_data_len;
+ if (avail == 0) {
+ scon->notify = true;
+ }
+ return avail;
}
-/* Receive n bytes from character layer, save in iov buffer,
- * and set event pending */
-static void receive_from_chr_layer(SCLPConsole *scon, const uint8_t *buf,
- int size)
+/* Send data from a char device over to the guest */
+static void chr_read(void *opaque, const uint8_t *buf, int size)
{
+ SCLPConsole *scon = opaque;
+
+ assert(scon);
/* read data must fit into current buffer */
assert(size <= SIZE_BUFFER_VT220 - scon->iov_data_len);
scon->iov_sclp_rest += size;
scon->iov_bs += size;
scon->event.event_pending = true;
-}
-
-/* Send data from a char device over to the guest */
-static void chr_read(void *opaque, const uint8_t *buf, int size)
-{
- SCLPConsole *scon = opaque;
-
- assert(scon);
-
- receive_from_chr_layer(scon, buf, size);
- /* trigger SCLP read operation */
- qemu_irq_raise(scon->irq_read_vt220);
+ sclp_service_interrupt(0);
}
/* functions to be called by event facility */
cons->iov_sclp += avail;
/* more data pending */
}
+ if (cons->notify) {
+ cons->notify = false;
+ qemu_notify_event();
+ }
}
static int read_event_data(SCLPEvent *event, EventBufferHeader *evt_buf_hdr,
return rc;
}
-static void trigger_ascii_console_data(void *opaque, int n, int level)
-{
- sclp_service_interrupt(0);
-}
-
static const VMStateDescription vmstate_sclpconsole = {
.name = "sclpconsole",
.version_id = 0,
.minimum_version_id = 0,
- .minimum_version_id_old = 0,
- .fields = (VMStateField[]) {
+ .fields = (VMStateField[]) {
VMSTATE_BOOL(event.event_pending, SCLPConsole),
VMSTATE_UINT8_ARRAY(iov, SCLPConsole, SIZE_BUFFER_VT220),
VMSTATE_UINT32(iov_sclp, SCLPConsole),
qemu_chr_add_handlers(scon->chr, chr_can_read,
chr_read, NULL, scon);
}
- scon->irq_read_vt220 = *qemu_allocate_irqs(trigger_ascii_console_data,
- NULL, 1);
return 0;
}
scon->iov_bs = 0;
scon->iov_data_len = 0;
scon->iov_sclp_rest = 0;
+ scon->notify = false;
}
static int console_exit(SCLPEvent *event)
ec->can_handle_event = can_handle_event;
ec->read_event_data = read_event_data;
ec->write_event_data = write_event_data;
+ set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
}
static const TypeInfo sclp_console_info = {