diff options
Diffstat (limited to 'include/sysemu/char.h')
-rw-r--r-- | include/sysemu/char.h | 155 |
1 files changed, 92 insertions, 63 deletions
diff --git a/include/sysemu/char.h b/include/sysemu/char.h index 0a14942..da0e7dd 100644 --- a/include/sysemu/char.h +++ b/include/sysemu/char.h @@ -10,6 +10,7 @@ #include "qapi/qmp/qstring.h" #include "qemu/main-loop.h" #include "qemu/bitmap.h" +#include "qom/object.h" /* character device */ @@ -69,14 +70,16 @@ typedef enum { /* Whether it is possible to send/recv file descriptors * over the data channel */ QEMU_CHAR_FEATURE_FD_PASS, + /* Whether replay or record mode is enabled */ + QEMU_CHAR_FEATURE_REPLAY, QEMU_CHAR_FEATURE_LAST, } CharDriverFeature; /* This is the backend as seen by frontend, the actual backend is - * CharDriverState */ + * Chardev */ typedef struct CharBackend { - CharDriverState *chr; + Chardev *chr; IOEventHandler *chr_event; IOCanReadHandler *chr_can_read; IOReadHandler *chr_read; @@ -85,49 +88,23 @@ typedef struct CharBackend { int fe_open; } CharBackend; -struct CharDriverState { +typedef struct CharDriver CharDriver; + +struct Chardev { + Object parent_obj; + QemuMutex chr_write_lock; - int (*chr_write)(struct CharDriverState *s, const uint8_t *buf, int len); - int (*chr_sync_read)(struct CharDriverState *s, - const uint8_t *buf, int len); - GSource *(*chr_add_watch)(struct CharDriverState *s, GIOCondition cond); - void (*chr_update_read_handler)(struct CharDriverState *s, - GMainContext *context); - int (*chr_ioctl)(struct CharDriverState *s, int cmd, void *arg); - int (*get_msgfds)(struct CharDriverState *s, int* fds, int num); - int (*set_msgfds)(struct CharDriverState *s, int *fds, int num); - int (*chr_add_client)(struct CharDriverState *chr, int fd); - int (*chr_wait_connected)(struct CharDriverState *chr, Error **errp); - void (*chr_free)(struct CharDriverState *chr); - void (*chr_disconnect)(struct CharDriverState *chr); - void (*chr_accept_input)(struct CharDriverState *chr); - void (*chr_set_echo)(struct CharDriverState *chr, bool echo); - void (*chr_set_fe_open)(struct CharDriverState *chr, int fe_open); CharBackend *be; - void *opaque; char *label; char *filename; int logfd; int be_open; - int is_mux; guint fd_in_tag; - bool replay; DECLARE_BITMAP(features, QEMU_CHAR_FEATURE_LAST); - QTAILQ_ENTRY(CharDriverState) next; + QTAILQ_ENTRY(Chardev) next; }; /** - * qemu_chr_alloc: - * @backend: the common backend config - * @errp: pointer to a NULL-initialized error object - * - * Allocate and initialize a new CharDriverState. - * - * Returns: a newly allocated CharDriverState, or NULL on error. - */ -CharDriverState *qemu_chr_alloc(ChardevCommon *backend, Error **errp); - -/** * @qemu_chr_new_from_opts: * * Create a new character backend from a QemuOpts list. @@ -136,8 +113,8 @@ CharDriverState *qemu_chr_alloc(ChardevCommon *backend, Error **errp); * * Returns: a new character backend */ -CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts, - Error **errp); +Chardev *qemu_chr_new_from_opts(QemuOpts *opts, + Error **errp); /** * @qemu_chr_parse_common: @@ -159,7 +136,7 @@ void qemu_chr_parse_common(QemuOpts *opts, ChardevCommon *backend); * * Returns: a new character backend */ -CharDriverState *qemu_chr_new(const char *label, const char *filename); +Chardev *qemu_chr_new(const char *label, const char *filename); /** @@ -197,7 +174,7 @@ int qemu_chr_fe_wait_connected(CharBackend *be, Error **errp); * * Returns: a new character backend */ -CharDriverState *qemu_chr_new_noreplay(const char *label, const char *filename); +Chardev *qemu_chr_new_noreplay(const char *label, const char *filename); /** * @qemu_chr_delete: @@ -205,14 +182,14 @@ CharDriverState *qemu_chr_new_noreplay(const char *label, const char *filename); * Destroy a character backend and remove it from the list of * identified character backends. */ -void qemu_chr_delete(CharDriverState *chr); +void qemu_chr_delete(Chardev *chr); /** * @qemu_chr_free: * * Destroy a character backend. */ -void qemu_chr_free(CharDriverState *chr); +void qemu_chr_free(Chardev *chr); /** * @qemu_chr_fe_set_echo: @@ -258,6 +235,8 @@ void qemu_chr_fe_printf(CharBackend *be, const char *fmt, ...) * @cond the condition to poll for * @func the function to call when the condition happens * @user_data the opaque pointer to pass to @func + * + * Returns: the source tag */ guint qemu_chr_fe_add_watch(CharBackend *be, GIOCondition cond, GIOFunc func, void *user_data); @@ -366,7 +345,7 @@ int qemu_chr_fe_set_msgfds(CharBackend *be, int *fds, int num); * * Returns: the number of bytes the front end can receive via @qemu_chr_be_write */ -int qemu_chr_be_can_write(CharDriverState *s); +int qemu_chr_be_can_write(Chardev *s); /** * @qemu_chr_be_write: @@ -378,7 +357,7 @@ int qemu_chr_be_can_write(CharDriverState *s); * @buf a buffer to receive data from the front end * @len the number of bytes to receive from the front end */ -void qemu_chr_be_write(CharDriverState *s, uint8_t *buf, int len); +void qemu_chr_be_write(Chardev *s, uint8_t *buf, int len); /** * @qemu_chr_be_write_impl: @@ -388,7 +367,7 @@ void qemu_chr_be_write(CharDriverState *s, uint8_t *buf, int len); * @buf a buffer to receive data from the front end * @len the number of bytes to receive from the front end */ -void qemu_chr_be_write_impl(CharDriverState *s, uint8_t *buf, int len); +void qemu_chr_be_write_impl(Chardev *s, uint8_t *buf, int len); /** * @qemu_chr_be_event: @@ -397,7 +376,7 @@ void qemu_chr_be_write_impl(CharDriverState *s, uint8_t *buf, int len); * * @event the event to send */ -void qemu_chr_be_event(CharDriverState *s, int event); +void qemu_chr_be_event(Chardev *s, int event); /** * @qemu_chr_fe_init: @@ -408,7 +387,7 @@ void qemu_chr_be_event(CharDriverState *s, int event); * * Returns: false on error. */ -bool qemu_chr_fe_init(CharBackend *b, CharDriverState *s, Error **errp); +bool qemu_chr_fe_init(CharBackend *b, Chardev *s, Error **errp); /** * @qemu_chr_fe_get_driver: @@ -416,7 +395,7 @@ bool qemu_chr_fe_init(CharBackend *b, CharDriverState *s, Error **errp); * Returns the driver associated with a CharBackend or NULL if no * associated CharDriver. */ -CharDriverState *qemu_chr_fe_get_driver(CharBackend *be); +Chardev *qemu_chr_fe_get_driver(CharBackend *be); /** * @qemu_chr_fe_deinit: @@ -461,33 +440,83 @@ void qemu_chr_fe_set_handlers(CharBackend *b, */ void qemu_chr_fe_take_focus(CharBackend *b); -void qemu_chr_be_generic_open(CharDriverState *s); +void qemu_chr_be_generic_open(Chardev *s); void qemu_chr_fe_accept_input(CharBackend *be); -int qemu_chr_add_client(CharDriverState *s, int fd); -CharDriverState *qemu_chr_find(const char *name); -bool chr_is_ringbuf(const CharDriverState *chr); +int qemu_chr_add_client(Chardev *s, int fd); +Chardev *qemu_chr_find(const char *name); -bool qemu_chr_has_feature(CharDriverState *chr, +bool qemu_chr_has_feature(Chardev *chr, CharDriverFeature feature); -void qemu_chr_set_feature(CharDriverState *chr, +void qemu_chr_set_feature(Chardev *chr, CharDriverFeature feature); QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename); -typedef void CharDriverParse(QemuOpts *opts, ChardevBackend *backend, - Error **errp); -typedef CharDriverState *CharDriverCreate(const char *id, - ChardevBackend *backend, - ChardevReturn *ret, bool *be_opened, - Error **errp); +#define TYPE_CHARDEV "chardev" +#define CHARDEV(obj) OBJECT_CHECK(Chardev, (obj), TYPE_CHARDEV) +#define CHARDEV_CLASS(klass) \ + OBJECT_CLASS_CHECK(ChardevClass, (klass), TYPE_CHARDEV) +#define CHARDEV_GET_CLASS(obj) \ + OBJECT_GET_CLASS(ChardevClass, (obj), TYPE_CHARDEV) + +#define TYPE_CHARDEV_NULL "chardev-null" +#define TYPE_CHARDEV_MUX "chardev-mux" +#define TYPE_CHARDEV_RINGBUF "chardev-ringbuf" +#define TYPE_CHARDEV_PTY "chardev-pty" +#define TYPE_CHARDEV_CONSOLE "chardev-console" +#define TYPE_CHARDEV_STDIO "chardev-stdio" +#define TYPE_CHARDEV_PIPE "chardev-pipe" +#define TYPE_CHARDEV_MEMORY "chardev-memory" +#define TYPE_CHARDEV_PARALLEL "chardev-parallel" +#define TYPE_CHARDEV_FILE "chardev-file" +#define TYPE_CHARDEV_SERIAL "chardev-serial" +#define TYPE_CHARDEV_SOCKET "chardev-socket" +#define TYPE_CHARDEV_UDP "chardev-udp" + +#define CHARDEV_IS_MUX(chr) \ + object_dynamic_cast(OBJECT(chr), TYPE_CHARDEV_MUX) +#define CHARDEV_IS_RINGBUF(chr) \ + object_dynamic_cast(OBJECT(chr), TYPE_CHARDEV_RINGBUF) +#define CHARDEV_IS_PTY(chr) \ + object_dynamic_cast(OBJECT(chr), TYPE_CHARDEV_PTY) + +typedef struct ChardevClass { + ObjectClass parent_class; + + bool internal; /* TODO: eventually use TYPE_USER_CREATABLE */ + + void (*open)(Chardev *chr, ChardevBackend *backend, + bool *be_opened, Error **errp); + + int (*chr_write)(Chardev *s, const uint8_t *buf, int len); + int (*chr_sync_read)(Chardev *s, const uint8_t *buf, int len); + GSource *(*chr_add_watch)(Chardev *s, GIOCondition cond); + void (*chr_update_read_handler)(Chardev *s, GMainContext *context); + int (*chr_ioctl)(Chardev *s, int cmd, void *arg); + int (*get_msgfds)(Chardev *s, int* fds, int num); + int (*set_msgfds)(Chardev *s, int *fds, int num); + int (*chr_add_client)(Chardev *chr, int fd); + int (*chr_wait_connected)(Chardev *chr, Error **errp); + void (*chr_free)(Chardev *chr); + void (*chr_disconnect)(Chardev *chr); + void (*chr_accept_input)(Chardev *chr); + void (*chr_set_echo)(Chardev *chr, bool echo); + void (*chr_set_fe_open)(Chardev *chr, int fe_open); +} ChardevClass; + +struct CharDriver { + ChardevBackendKind kind; + const char *alias; + void (*parse)(QemuOpts *opts, ChardevBackend *backend, Error **errp); +}; -void register_char_driver(const char *name, ChardevBackendKind kind, - CharDriverParse *parse, CharDriverCreate *create); +Chardev *qemu_chardev_new(const char *id, const char *typename, + ChardevBackend *backend, Error **errp); -extern int term_escape_char; +void register_char_driver(const CharDriver *driver); +extern int term_escape_char; /* console.c */ -typedef CharDriverState *(VcHandler)(ChardevVC *vc, Error **errp); -void register_vc_handler(VcHandler *handler); +void qemu_chr_parse_vc(QemuOpts *opts, ChardevBackend *backend, Error **errp); #endif |