#include "qemu/osdep.h"
#include "sysemu/rng.h"
-#include "sysemu/char.h"
+#include "chardev/char-fe.h"
+#include "qapi/error.h"
#include "qapi/qmp/qerror.h"
-#include "hw/qdev.h" /* just for DEFINE_PROP_CHR */
+#include "qemu/module.h"
+#include "qom/object.h"
#define TYPE_RNG_EGD "rng-egd"
+typedef struct RngEgd RngEgd;
#define RNG_EGD(obj) OBJECT_CHECK(RngEgd, (obj), TYPE_RNG_EGD)
-typedef struct RngEgd
-{
+struct RngEgd {
RngBackend parent;
- CharDriverState *chr;
+ CharBackend chr;
char *chr_name;
-} RngEgd;
+};
static void rng_egd_request_entropy(RngBackend *b, RngRequest *req)
{
header[0] = 0x02;
header[1] = len;
- qemu_chr_fe_write(s->chr, header, sizeof(header));
+ /* XXX this blocks entire thread. Rewrite to use
+ * qemu_chr_fe_write and background I/O callbacks */
+ qemu_chr_fe_write_all(&s->chr, header, sizeof(header));
size -= len;
}
static void rng_egd_opened(RngBackend *b, Error **errp)
{
RngEgd *s = RNG_EGD(b);
+ Chardev *chr;
if (s->chr_name == NULL) {
error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
return;
}
- s->chr = qemu_chr_find(s->chr_name);
- if (s->chr == NULL) {
+ chr = qemu_chr_find(s->chr_name);
+ if (chr == NULL) {
error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
"Device '%s' not found", s->chr_name);
return;
}
-
- if (qemu_chr_fe_claim(s->chr) != 0) {
- error_setg(errp, QERR_DEVICE_IN_USE, s->chr_name);
+ if (!qemu_chr_fe_init(&s->chr, chr, errp)) {
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);
+ qemu_chr_fe_set_handlers(&s->chr, rng_egd_chr_can_read,
+ rng_egd_chr_read, NULL, NULL, s, NULL, true);
}
static void rng_egd_set_chardev(Object *obj, const char *value, Error **errp)
static char *rng_egd_get_chardev(Object *obj, Error **errp)
{
RngEgd *s = RNG_EGD(obj);
+ Chardev *chr = qemu_chr_fe_get_driver(&s->chr);
- if (s->chr && s->chr->label) {
- return g_strdup(s->chr->label);
+ if (chr && chr->label) {
+ return g_strdup(chr->label);
}
return NULL;
static void rng_egd_init(Object *obj)
{
object_property_add_str(obj, "chardev",
- rng_egd_get_chardev, rng_egd_set_chardev,
- NULL);
+ rng_egd_get_chardev, rng_egd_set_chardev);
}
static void rng_egd_finalize(Object *obj)
{
RngEgd *s = RNG_EGD(obj);
- if (s->chr) {
- qemu_chr_add_handlers(s->chr, NULL, NULL, NULL, NULL);
- qemu_chr_fe_release(s->chr);
- }
-
+ qemu_chr_fe_deinit(&s->chr, false);
g_free(s->chr_name);
}