@@ -83,6 +83,13 @@ struct mon_fd_t {
LIST_ENTRY(mon_fd_t) next;
};
+/* Callback for device info command */
+struct MonDevInfoEntry {
+ const struct MonDevInfo *dev_info;
+ void *dev_opaque;
+ LIST_ENTRY(MonDevInfoEntry) next;
+};
+
struct Monitor {
CharDriverState *chr;
int flags;
@@ -94,6 +101,7 @@ struct Monitor {
BlockDriverCompletionFunc *password_completion_cb;
void *password_opaque;
LIST_HEAD(,mon_fd_t) fds;
+ LIST_HEAD(,MonDevInfoEntry) dev_infos;
LIST_ENTRY(Monitor) entry;
};
@@ -1800,6 +1808,19 @@ int monitor_get_fd(Monitor *mon, const char *fdname)
return -1;
}
+static void do_info_device(Monitor *mon, const QDict *qdict)
+{
+ struct MonDevInfoEntry *entry;
+ const char *name = qdict_get_str(qdict, "devname");
+
+ LIST_FOREACH(entry, &mon->dev_infos, next) {
+ if (strcmp(entry->dev_info->dev_name, name) != 0) {
+ continue;
+ }
+ entry->dev_info->dev_info_cb(mon, entry->dev_opaque);
+ }
+}
+
static const mon_cmd_t mon_cmds[] = {
#include "qemu-monitor.h"
{ NULL, NULL, },
@@ -3045,6 +3066,13 @@ static void monitor_find_completion(const char *cmdline)
for (cmd = mon_cmds; cmd->name != NULL; cmd++) {
cmd_completion(str, cmd->name);
}
+ } else if (!strcmp(cmd->name, "dev_info")) {
+ struct MonDevInfoEntry *entry;
+
+ readline_set_completion_index(cur_mon->rs, strlen(str));
+ LIST_FOREACH(entry, &cur_mon->dev_infos, next) {
+ cmd_completion(str, entry->dev_info->dev_name);
+ }
}
break;
default:
@@ -3209,6 +3237,17 @@ void monitor_read_bdrv_key_start(Monitor *mon,
BlockDriverState *bs,
completion_cb(opaque, err);
}
+void monitor_register_device_info(const struct MonDevInfo *dev_info,
+ void *dev_opaque)
+{
+ struct MonDevInfoEntry *entry;
+
+ entry = qemu_malloc(sizeof(*entry));
+ entry->dev_info = dev_info;
+ entry->dev_opaque = dev_opaque;
+ LIST_INSERT_HEAD(&cur_mon->dev_infos, entry, next);
+}
+
typedef struct QemuErrorSink QemuErrorSink;
struct QemuErrorSink {
enum {
@@ -21,6 +21,16 @@ void monitor_read_bdrv_key_start(Monitor *mon,
BlockDriverState *bs,
BlockDriverCompletionFunc *completion_cb,
void *opaque);
+typedef void DeviceInfoFunc(Monitor *mon, void *opaque);
+
+struct MonDevInfo {
+ const char *dev_name;
+ DeviceInfoFunc *dev_info_cb;
+};
+
+void monitor_register_device_info(const struct MonDevInfo *dev_info,
+ void *dev_opaque);
+
int monitor_get_fd(Monitor *mon, const char *fdname);
void monitor_vprintf(Monitor *mon, const char *fmt, va_list ap);
@@ -645,6 +645,13 @@ Close the file descriptor previously assigned to
@var{fdname} using the
used by another monitor command.
ETEXI
+ { "dev_info", "devname:s", do_info_device,
+ "device name", "show device information" },
+STEXI
+@item device @var{devicename}
+Show information about a device.
+ETEXI
+
STEXI
@end table
ETEXI
@@ -5908,6 +5908,15 @@ int main(int argc, char **argv, char **envp)
}
}
}
+ qemu_chr_initial_reset();
+
+ for (i = 0; i < MAX_MONITOR_DEVICES; i++) {
+ if (monitor_devices[i] && monitor_hds[i]) {
+ monitor_init(monitor_hds[i],
+ MONITOR_USE_READLINE |
+ ((i == 0) ? MONITOR_IS_DEFAULT : 0));
+ }
+ }
for(i = 0; i < MAX_SERIAL_PORTS; i++) {
const char *devname = serial_devices[i];
@@ -6052,15 +6061,6 @@ int main(int argc, char **argv, char **envp)
}
text_consoles_set_display(display_state);
- qemu_chr_initial_reset();
-
- for (i = 0; i < MAX_MONITOR_DEVICES; i++) {
- if (monitor_devices[i] && monitor_hds[i]) {
- monitor_init(monitor_hds[i],
- MONITOR_USE_READLINE |
- ((i == 0) ? MONITOR_IS_DEFAULT : 0));
- }
- }
for(i = 0; i < MAX_SERIAL_PORTS; i++) {
const char *devname = serial_devices[i];
Signed-off-by: Blue Swirl <blauwirbel@gmail.com> --- monitor.c | 39 +++++++++++++++++++++++++++++++++++++++ monitor.h | 10 ++++++++++ qemu-monitor.hx | 7 +++++++ vl.c | 18 +++++++++--------- 4 files changed, 65 insertions(+), 9 deletions(-)