#include "hw/usb.h"
#include "hw/baum.h"
#include "hw/msmouse.h"
+#include "qemu-objects.h"
#include <unistd.h>
#include <fcntl.h>
#include <sys/select.h>
#ifdef CONFIG_BSD
#include <sys/stat.h>
-#ifdef __FreeBSD__
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
#include <libutil.h>
#include <dev/ppbus/ppi.h>
#include <dev/ppbus/ppbconf.h>
+#if defined(__GLIBC__)
+#include <pty.h>
+#endif
#elif defined(__DragonFly__)
#include <libutil.h>
#include <dev/misc/ppi/ppi.h>
#else
#include <util.h>
#endif
-#elif defined (__GLIBC__) && defined (__FreeBSD_kernel__)
-#include <freebsd/stdlib.h>
#else
#ifdef __linux__
#include <pty.h>
#include "qemu_socket.h"
+#define READ_BUF_LEN 4096
+
/***********************************************************/
/* character device */
s->chr_event(s->handler_opaque, event);
}
-static void qemu_chr_reset_bh(void *opaque)
+static void qemu_chr_generic_open_bh(void *opaque)
{
CharDriverState *s = opaque;
qemu_chr_event(s, CHR_EVENT_OPENED);
s->bh = NULL;
}
-void qemu_chr_reset(CharDriverState *s)
+void qemu_chr_generic_open(CharDriverState *s)
{
if (s->bh == NULL) {
- s->bh = qemu_bh_new(qemu_chr_reset_bh, s);
+ s->bh = qemu_bh_new(qemu_chr_generic_open_bh, s);
qemu_bh_schedule(s->bh);
}
}
-void qemu_chr_initial_reset(void)
-{
- CharDriverState *chr;
-
- QTAILQ_FOREACH(chr, &chardevs, next) {
- qemu_chr_reset(chr);
- }
-}
-
int qemu_chr_write(CharDriverState *s, const uint8_t *buf, int len)
{
return s->chr_write(s, buf, len);
void qemu_chr_printf(CharDriverState *s, const char *fmt, ...)
{
- char buf[4096];
+ char buf[READ_BUF_LEN];
va_list ap;
va_start(ap, fmt);
vsnprintf(buf, sizeof(buf), fmt, ap);
CharDriverState *chr = opaque;
FDCharDriver *s = chr->opaque;
int size, len;
- uint8_t buf[1024];
+ uint8_t buf[READ_BUF_LEN];
len = sizeof(buf);
if (len > s->max_size)
chr->chr_update_read_handler = fd_chr_update_read_handler;
chr->chr_close = fd_chr_close;
- qemu_chr_reset(chr);
+ qemu_chr_generic_open(chr);
return chr;
}
{
int fd_out;
- TFR(fd_out = open(qemu_opt_get(opts, "path"),
+ TFR(fd_out = qemu_open(qemu_opt_get(opts, "path"),
O_WRONLY | O_TRUNC | O_CREAT | O_BINARY, 0666));
if (fd_out < 0)
return NULL;
snprintf(filename_in, 256, "%s.in", filename);
snprintf(filename_out, 256, "%s.out", filename);
- TFR(fd_in = open(filename_in, O_RDWR | O_BINARY));
- TFR(fd_out = open(filename_out, O_RDWR | O_BINARY));
+ TFR(fd_in = qemu_open(filename_in, O_RDWR | O_BINARY));
+ TFR(fd_out = qemu_open(filename_out, O_RDWR | O_BINARY));
if (fd_in < 0 || fd_out < 0) {
if (fd_in >= 0)
close(fd_in);
#endif
#if defined(__linux__) || defined(__sun__) || defined(__FreeBSD__) \
- || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
+ || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) \
+ || defined(__GLIBC__)
typedef struct {
int fd;
CharDriverState *chr = opaque;
PtyCharDriver *s = chr->opaque;
int size, len;
- uint8_t buf[1024];
+ uint8_t buf[READ_BUF_LEN];
len = sizeof(buf);
if (len > s->read_bytes)
qemu_mod_timer(s->timer, qemu_get_clock(rt_clock) + 1000);
} else {
if (!s->connected)
- qemu_chr_reset(chr);
+ qemu_chr_generic_open(chr);
s->connected = 1;
}
}
#endif
tcgetattr (fd, &tty);
-#define MARGIN 1.1
- if (speed <= 50 * MARGIN)
- spd = B50;
- else if (speed <= 75 * MARGIN)
- spd = B75;
- else if (speed <= 300 * MARGIN)
- spd = B300;
- else if (speed <= 600 * MARGIN)
- spd = B600;
- else if (speed <= 1200 * MARGIN)
- spd = B1200;
- else if (speed <= 2400 * MARGIN)
- spd = B2400;
- else if (speed <= 4800 * MARGIN)
- spd = B4800;
- else if (speed <= 9600 * MARGIN)
- spd = B9600;
- else if (speed <= 19200 * MARGIN)
- spd = B19200;
- else if (speed <= 38400 * MARGIN)
- spd = B38400;
- else if (speed <= 57600 * MARGIN)
- spd = B57600;
- else if (speed <= 115200 * MARGIN)
- spd = B115200;
- else
+#define check_speed(val) if (speed <= val) { spd = B##val; break; }
+ speed = speed * 10 / 11;
+ do {
+ check_speed(50);
+ check_speed(75);
+ check_speed(110);
+ check_speed(134);
+ check_speed(150);
+ check_speed(200);
+ check_speed(300);
+ check_speed(600);
+ check_speed(1200);
+ check_speed(1800);
+ check_speed(2400);
+ check_speed(4800);
+ check_speed(9600);
+ check_speed(19200);
+ check_speed(38400);
+ /* Non-Posix values follow. They may be unsupported on some systems. */
+ check_speed(57600);
+ check_speed(115200);
+#ifdef B230400
+ check_speed(230400);
+#endif
+#ifdef B460800
+ check_speed(460800);
+#endif
+#ifdef B500000
+ check_speed(500000);
+#endif
+#ifdef B576000
+ check_speed(576000);
+#endif
+#ifdef B921600
+ check_speed(921600);
+#endif
+#ifdef B1000000
+ check_speed(1000000);
+#endif
+#ifdef B1152000
+ check_speed(1152000);
+#endif
+#ifdef B1500000
+ check_speed(1500000);
+#endif
+#ifdef B2000000
+ check_speed(2000000);
+#endif
+#ifdef B2500000
+ check_speed(2500000);
+#endif
+#ifdef B3000000
+ check_speed(3000000);
+#endif
+#ifdef B3500000
+ check_speed(3500000);
+#endif
+#ifdef B4000000
+ check_speed(4000000);
+#endif
spd = B115200;
+ } while (0);
cfsetispeed(&tty, spd);
cfsetospeed(&tty, spd);
return NULL;
}
chr->chr_ioctl = tty_serial_ioctl;
- qemu_chr_reset(chr);
+ qemu_chr_generic_open(chr);
return chr;
}
#else /* ! __linux__ && ! __sun__ */
chr->chr_close = pp_close;
chr->opaque = drv;
- qemu_chr_reset(chr);
+ qemu_chr_generic_open(chr);
return chr;
}
#endif /* __linux__ */
-#if defined(__FreeBSD__) || defined(__DragonFly__)
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
static int pp_ioctl(CharDriverState *chr, int cmd, void *arg)
{
int fd = (int)chr->opaque;
{
WinCharState *s = chr->opaque;
int ret, err;
- uint8_t buf[1024];
+ uint8_t buf[READ_BUF_LEN];
DWORD size;
ZeroMemory(&s->orecv, sizeof(s->orecv));
free(chr);
return NULL;
}
- qemu_chr_reset(chr);
+ qemu_chr_generic_open(chr);
return chr;
}
free(chr);
return NULL;
}
- qemu_chr_reset(chr);
+ qemu_chr_generic_open(chr);
return chr;
}
s->hcom = fd_out;
chr->opaque = s;
chr->chr_write = win_chr_write;
- qemu_chr_reset(chr);
+ qemu_chr_generic_open(chr);
return chr;
}
typedef struct {
int fd;
- uint8_t buf[1024];
+ uint8_t buf[READ_BUF_LEN];
int bufcnt;
int bufptr;
int max_size;
{
CharDriverState *chr = opaque;
TCPCharDriver *s = chr->opaque;
- uint8_t buf[1024];
+ uint8_t buf[READ_BUF_LEN];
int len, size;
if (!s->connected || s->max_size <= 0)
s->connected = 1;
qemu_set_fd_handler2(s->fd, tcp_chr_read_poll,
tcp_chr_read, NULL, chr);
- qemu_chr_reset(chr);
+ qemu_chr_generic_open(chr);
}
#define IACSET(x,a,b,c) x[0] = a; x[1] = b; x[2] = c;
len = sizeof(saddr);
addr = (struct sockaddr *)&saddr;
}
- fd = accept(s->listen_fd, addr, &len);
+ fd = qemu_accept(s->listen_fd, addr, &len);
if (fd < 0 && errno != EINTR) {
return;
} else if (fd >= 0) {
return NULL;
}
-static QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename)
+QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename)
{
char host[65], port[33], width[8], height[8];
int pos;
{ .name = "braille", .open = chr_baum_init },
#endif
#if defined(__linux__) || defined(__sun__) || defined(__FreeBSD__) \
- || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
+ || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) \
+ || defined(__FreeBSD_kernel__)
{ .name = "tty", .open = qemu_chr_open_tty },
#endif
-#if defined(__linux__) || defined(__FreeBSD__) || defined(__DragonFly__)
+#if defined(__linux__) || defined(__FreeBSD__) || defined(__DragonFly__) \
+ || defined(__FreeBSD_kernel__)
{ .name = "parport", .open = qemu_chr_open_pp },
#endif
};
qemu_free(chr);
}
-void qemu_chr_info(Monitor *mon)
+static void qemu_chr_qlist_iter(QObject *obj, void *opaque)
+{
+ QDict *chr_dict;
+ Monitor *mon = opaque;
+
+ chr_dict = qobject_to_qdict(obj);
+ monitor_printf(mon, "%s: filename=%s\n", qdict_get_str(chr_dict, "label"),
+ qdict_get_str(chr_dict, "filename"));
+}
+
+void qemu_chr_info_print(Monitor *mon, const QObject *ret_data)
+{
+ qlist_iter(qobject_to_qlist(ret_data), qemu_chr_qlist_iter, mon);
+}
+
+/**
+ * qemu_chr_info(): Character devices information
+ *
+ * Each device is represented by a QDict. The returned QObject is a QList
+ * of all devices.
+ *
+ * The QDict contains the following:
+ *
+ * - "label": device's label
+ * - "filename": device's file
+ *
+ * Example:
+ *
+ * [ { "label": "monitor", "filename", "stdio" },
+ * { "label": "serial0", "filename": "vc" } ]
+ */
+void qemu_chr_info(Monitor *mon, QObject **ret_data)
{
+ QList *chr_list;
CharDriverState *chr;
+ chr_list = qlist_new();
+
QTAILQ_FOREACH(chr, &chardevs, next) {
- monitor_printf(mon, "%s: filename=%s\n", chr->label, chr->filename);
+ QObject *obj = qobject_from_jsonf("{ 'label': %s, 'filename': %s }",
+ chr->label, chr->filename);
+ qlist_append_obj(chr_list, obj);
}
+
+ *ret_data = QOBJECT(chr_list);
}
CharDriverState *qemu_chr_find(const char *name)