X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=palacios%2Fsrc%2Fdevices%2Fchar_stream.c;h=2bf484142a1263ee62948dd90b2df2135c3549af;hb=22dbf90548cb2ea56a9057a706e3da411dc1b57b;hp=4590cae2c78a09c13e7a59bd3e2f3c9e6d2ea7fd;hpb=4cc7f00cbe637224fb12baaf0e95f8b0040eb7bd;p=palacios.git diff --git a/palacios/src/devices/char_stream.c b/palacios/src/devices/char_stream.c index 4590cae..2bf4841 100644 --- a/palacios/src/devices/char_stream.c +++ b/palacios/src/devices/char_stream.c @@ -35,32 +35,46 @@ struct stream_state { }; +static int serial_event_handler(struct v3_vm_info * vm, + struct v3_serial_event * evt, + void * private_data) { + struct stream_state * state = (struct stream_state *)private_data; -static int stream_write(uint8_t * buf, uint64_t length, void * private_data) -{ - struct stream_state *state = (struct stream_state *)private_data; + if (state->char_ops.push != NULL){ + state->char_ops.push(vm, evt->data, evt->len, state->push_fn_arg); + } + + return 0; +} + +static int stream_write(uint8_t * buf, uint64_t length, void * private_data) { + struct stream_state * state = (struct stream_state *)private_data; return v3_stream_write(state->stream, buf, length); } +static int stream_free(struct stream_state * state) { + v3_stream_close(state->stream); + + // detach host event + + V3_Free(state); + + return 0; +} static struct v3_device_ops dev_ops = { - .free = NULL, - .reset = NULL, - .start = NULL, - .stop = NULL, + .free = (int (*)(void *))stream_free, }; -static int stream_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) -{ +static int stream_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { char * dev_id = v3_cfg_val(cfg, "ID"); char * stream_name = v3_cfg_val(cfg, "name"); struct stream_state * state = NULL; v3_cfg_tree_t * frontend_cfg = v3_cfg_subtree(cfg, "frontend"); - state = (struct stream_state *)V3_Malloc(sizeof(struct stream_state)); if (state == NULL) { @@ -70,41 +84,38 @@ static int stream_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) memset(state, 0, sizeof(struct stream_state)); - state->stream = v3_stream_open(vm, stream_name); - - if (state->stream == NULL) { - PrintError("Could not open stream %s\n", stream_name); - V3_Free(state); - return -1; - } - - state->char_ops.write = stream_write; - - struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, state); + struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, state); if (dev == NULL) { PrintError("Could not allocate device %s\n", dev_id); + V3_Free(state); return -1; } - if (v3_attach_device(vm, dev) == -1) { - PrintError("Could not attach device %s\n", dev_id); - V3_Free(state); + + + state->stream = v3_stream_open(vm, stream_name); + + if (state->stream == NULL) { + PrintError("Could not open stream %s\n", stream_name); + v3_remove_device(dev); return -1; } + state->char_ops.write = stream_write; + if (v3_dev_connect_char(vm, v3_cfg_val(frontend_cfg, "tag"), &(state->char_ops), frontend_cfg, state, &(state->push_fn_arg)) == -1) { PrintError("Could not connect %s to frontend %s\n", dev_id, v3_cfg_val(frontend_cfg, "tag")); + v3_remove_device(dev); return -1; } - + v3_hook_host_event(vm, HOST_SERIAL_EVT, V3_HOST_EVENT_HANDLER(serial_event_handler), state); return 0; } -device_register("CHAR_STREAM", stream_init) - +device_register("CHAR_STREAM", stream_init);