* See the COPYING file in the top-level directory.
*/
-#include "qemu/rng.h"
-#include "qemu-char.h"
-#include "qerror.h"
+#include "sysemu/rng.h"
+#include "sysemu/char.h"
+#include "qapi/qmp/qerror.h"
#include "hw/qdev.h" /* just for DEFINE_PROP_CHR */
#define TYPE_RNG_EGD "rng-egd"
static void rng_egd_chr_read(void *opaque, const uint8_t *buf, int size)
{
RngEgd *s = RNG_EGD(opaque);
+ size_t buf_offset = 0;
while (size > 0 && s->requests) {
RngRequest *req = s->requests->data;
int len = MIN(size, req->size - req->offset);
- memcpy(req->data + req->offset, buf, len);
+ memcpy(req->data + req->offset, buf + buf_offset, len);
+ buf_offset += len;
req->offset += len;
size -= len;
}
}
+static void rng_egd_free_requests(RngEgd *s)
+{
+ GSList *i;
+
+ for (i = s->requests; i; i = i->next) {
+ rng_egd_free_request(i->data);
+ }
+
+ g_slist_free(s->requests);
+ s->requests = NULL;
+}
+
static void rng_egd_cancel_requests(RngBackend *b)
{
RngEgd *s = RNG_EGD(b);
* queue waiting to be read, this is okay, because there will always be
* more data than we requested originally
*/
- g_slist_free_full(s->requests,
- (GDestroyNotify)rng_egd_free_request);
- s->requests = NULL;
+ rng_egd_free_requests(s);
}
static void rng_egd_opened(RngBackend *b, Error **errp)
return;
}
+ if (qemu_chr_fe_claim(s->chr) != 0) {
+ error_set(errp, QERR_DEVICE_IN_USE, s->chr_name);
+ return;
+ }
+
/* FIXME we should resubmit pending requests when the CDS reconnects. */
qemu_chr_add_handlers(s->chr, rng_egd_chr_can_read, rng_egd_chr_read,
NULL, s);
if (b->opened) {
error_set(errp, QERR_PERMISSION_DENIED);
} else {
- g_free(s->chr_name);
s->chr_name = g_strdup(value);
}
}
if (s->chr) {
qemu_chr_add_handlers(s->chr, NULL, NULL, NULL, NULL);
+ qemu_chr_fe_release(s->chr);
}
g_free(s->chr_name);
- g_slist_free_full(s->requests, (GDestroyNotify)rng_egd_free_request);
- s->requests = NULL;
+ rng_egd_free_requests(s);
}
static void rng_egd_class_init(ObjectClass *klass, void *data)
rbc->opened = rng_egd_opened;
}
-static TypeInfo rng_egd_info = {
+static const TypeInfo rng_egd_info = {
.name = TYPE_RNG_EGD,
.parent = TYPE_RNG_BACKEND,
.instance_size = sizeof(RngEgd),