mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging
* SCSI max_transfer support for scsi-generic (Eric) * x86 SMI broadcast (Laszlo) * Character device QOMification (Marc-André) * Record/replay improvements (Pavel) * iscsi fixes (Peter L.) * "info mtree -f" command (Peter Xu) * TSC clock rate reporting (Phil) * DEVICE_CATEGORY_CPU (Thomas) * Memory sign-extension fix (Ladi) # gpg: Signature made Fri 27 Jan 2017 17:08:51 GMT # gpg: using RSA key 0xBFFBD25F78C7AE83 # gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" # gpg: aka "Paolo Bonzini <pbonzini@redhat.com>" # Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4 E2F7 7E15 100C CD36 69B1 # Subkey fingerprint: F133 3857 4B66 2389 866C 7682 BFFB D25F 78C7 AE83 * remotes/bonzini/tags/for-upstream: (41 commits) memory: don't sign-extend 32-bit writes chardev: qom-ify vc: use a common prefix for chr callbacks baum: use a common prefix for chr callbacks gtk: overwrite the console.c char driver char: use error_report() spice-char: improve error reporting char: rename TCPChardev and NetChardev char: rename CharDriverState Chardev bt: use qemu_chr_alloc() char: allocate CharDriverState as a single object char: use a feature bit for replay char: introduce generic qemu_chr_get_kind() char: fold single-user functions in caller char: move callbacks in CharDriver char: use a static array for backends char: use a const CharDriver doc: fix spelling char: add qemu_chr_fe_add_watch() Returns description qemu-options: stdio is available on win32 ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
@@ -1642,6 +1642,7 @@ M: Peter Lieven <pl@kamp.de>
|
||||
L: qemu-block@nongnu.org
|
||||
S: Supported
|
||||
F: block/iscsi.c
|
||||
F: block/iscsi-opts.c
|
||||
|
||||
NFS
|
||||
M: Jeff Cody <jcody@redhat.com>
|
||||
|
||||
+55
-51
@@ -85,7 +85,7 @@
|
||||
#define BUF_SIZE 256
|
||||
|
||||
typedef struct {
|
||||
CharDriverState *chr;
|
||||
Chardev parent;
|
||||
|
||||
brlapi_handle_t *brlapi;
|
||||
int brlapi_fd;
|
||||
@@ -98,7 +98,10 @@ typedef struct {
|
||||
uint8_t out_buf_used, out_buf_ptr;
|
||||
|
||||
QEMUTimer *cellCount_timer;
|
||||
} BaumDriverState;
|
||||
} BaumChardev;
|
||||
|
||||
#define TYPE_CHARDEV_BRAILLE "chardev-braille"
|
||||
#define BAUM_CHARDEV(obj) OBJECT_CHECK(BaumChardev, (obj), TYPE_CHARDEV_BRAILLE)
|
||||
|
||||
/* Let's assume NABCC by default */
|
||||
enum way {
|
||||
@@ -223,7 +226,7 @@ static const uint8_t nabcc_translation[2][256] = {
|
||||
};
|
||||
|
||||
/* The guest OS has started discussing with us, finish initializing BrlAPI */
|
||||
static int baum_deferred_init(BaumDriverState *baum)
|
||||
static int baum_deferred_init(BaumChardev *baum)
|
||||
{
|
||||
int tty = BRLAPI_TTY_DEFAULT;
|
||||
QemuConsole *con;
|
||||
@@ -253,9 +256,9 @@ static int baum_deferred_init(BaumDriverState *baum)
|
||||
}
|
||||
|
||||
/* The serial port can receive more of our data */
|
||||
static void baum_accept_input(struct CharDriverState *chr)
|
||||
static void baum_chr_accept_input(struct Chardev *chr)
|
||||
{
|
||||
BaumDriverState *baum = chr->opaque;
|
||||
BaumChardev *baum = BAUM_CHARDEV(chr);
|
||||
int room, first;
|
||||
|
||||
if (!baum->out_buf_used)
|
||||
@@ -279,24 +282,25 @@ static void baum_accept_input(struct CharDriverState *chr)
|
||||
}
|
||||
|
||||
/* We want to send a packet */
|
||||
static void baum_write_packet(BaumDriverState *baum, const uint8_t *buf, int len)
|
||||
static void baum_write_packet(BaumChardev *baum, const uint8_t *buf, int len)
|
||||
{
|
||||
Chardev *chr = CHARDEV(baum);
|
||||
uint8_t io_buf[1 + 2 * len], *cur = io_buf;
|
||||
int room;
|
||||
*cur++ = ESC;
|
||||
while (len--)
|
||||
if ((*cur++ = *buf++) == ESC)
|
||||
*cur++ = ESC;
|
||||
room = qemu_chr_be_can_write(baum->chr);
|
||||
room = qemu_chr_be_can_write(chr);
|
||||
len = cur - io_buf;
|
||||
if (len <= room) {
|
||||
/* Fits */
|
||||
qemu_chr_be_write(baum->chr, io_buf, len);
|
||||
qemu_chr_be_write(chr, io_buf, len);
|
||||
} else {
|
||||
int first;
|
||||
uint8_t out;
|
||||
/* Can't fit all, send what can be, and store the rest. */
|
||||
qemu_chr_be_write(baum->chr, io_buf, room);
|
||||
qemu_chr_be_write(chr, io_buf, room);
|
||||
len -= room;
|
||||
cur = io_buf + room;
|
||||
if (len > BUF_SIZE - baum->out_buf_used) {
|
||||
@@ -321,14 +325,14 @@ static void baum_write_packet(BaumDriverState *baum, const uint8_t *buf, int len
|
||||
/* Called when the other end seems to have a wrong idea of our display size */
|
||||
static void baum_cellCount_timer_cb(void *opaque)
|
||||
{
|
||||
BaumDriverState *baum = opaque;
|
||||
BaumChardev *baum = BAUM_CHARDEV(opaque);
|
||||
uint8_t cell_count[] = { BAUM_RSP_CellCount, baum->x * baum->y };
|
||||
DPRINTF("Timeout waiting for DisplayData, sending cell count\n");
|
||||
baum_write_packet(baum, cell_count, sizeof(cell_count));
|
||||
}
|
||||
|
||||
/* Try to interpret a whole incoming packet */
|
||||
static int baum_eat_packet(BaumDriverState *baum, const uint8_t *buf, int len)
|
||||
static int baum_eat_packet(BaumChardev *baum, const uint8_t *buf, int len)
|
||||
{
|
||||
const uint8_t *cur = buf;
|
||||
uint8_t req = 0;
|
||||
@@ -469,9 +473,9 @@ static int baum_eat_packet(BaumDriverState *baum, const uint8_t *buf, int len)
|
||||
}
|
||||
|
||||
/* The other end is writing some data. Store it and try to interpret */
|
||||
static int baum_write(CharDriverState *chr, const uint8_t *buf, int len)
|
||||
static int baum_chr_write(Chardev *chr, const uint8_t *buf, int len)
|
||||
{
|
||||
BaumDriverState *baum = chr->opaque;
|
||||
BaumChardev *baum = BAUM_CHARDEV(chr);
|
||||
int tocopy, cur, eaten, orig_len = len;
|
||||
|
||||
if (!len)
|
||||
@@ -510,14 +514,16 @@ static int baum_write(CharDriverState *chr, const uint8_t *buf, int len)
|
||||
}
|
||||
|
||||
/* Send the key code to the other end */
|
||||
static void baum_send_key(BaumDriverState *baum, uint8_t type, uint8_t value) {
|
||||
static void baum_send_key(BaumChardev *baum, uint8_t type, uint8_t value)
|
||||
{
|
||||
uint8_t packet[] = { type, value };
|
||||
DPRINTF("writing key %x %x\n", type, value);
|
||||
baum_write_packet(baum, packet, sizeof(packet));
|
||||
}
|
||||
|
||||
static void baum_send_key2(BaumDriverState *baum, uint8_t type, uint8_t value,
|
||||
uint8_t value2) {
|
||||
static void baum_send_key2(BaumChardev *baum, uint8_t type, uint8_t value,
|
||||
uint8_t value2)
|
||||
{
|
||||
uint8_t packet[] = { type, value, value2 };
|
||||
DPRINTF("writing key %x %x\n", type, value);
|
||||
baum_write_packet(baum, packet, sizeof(packet));
|
||||
@@ -526,7 +532,7 @@ static void baum_send_key2(BaumDriverState *baum, uint8_t type, uint8_t value,
|
||||
/* We got some data on the BrlAPI socket */
|
||||
static void baum_chr_read(void *opaque)
|
||||
{
|
||||
BaumDriverState *baum = opaque;
|
||||
BaumChardev *baum = BAUM_CHARDEV(opaque);
|
||||
brlapi_keyCode_t code;
|
||||
int ret;
|
||||
if (!baum->brlapi)
|
||||
@@ -610,41 +616,25 @@ static void baum_chr_read(void *opaque)
|
||||
}
|
||||
}
|
||||
|
||||
static void baum_free(struct CharDriverState *chr)
|
||||
static void baum_chr_free(Chardev *chr)
|
||||
{
|
||||
BaumDriverState *baum = chr->opaque;
|
||||
BaumChardev *baum = BAUM_CHARDEV(chr);
|
||||
|
||||
timer_free(baum->cellCount_timer);
|
||||
if (baum->brlapi) {
|
||||
brlapi__closeConnection(baum->brlapi);
|
||||
g_free(baum->brlapi);
|
||||
}
|
||||
g_free(baum);
|
||||
}
|
||||
|
||||
static CharDriverState *chr_baum_init(const char *id,
|
||||
ChardevBackend *backend,
|
||||
ChardevReturn *ret,
|
||||
bool *be_opened,
|
||||
Error **errp)
|
||||
static void baum_chr_open(Chardev *chr,
|
||||
ChardevBackend *backend,
|
||||
bool *be_opened,
|
||||
Error **errp)
|
||||
{
|
||||
ChardevCommon *common = backend->u.braille.data;
|
||||
BaumDriverState *baum;
|
||||
CharDriverState *chr;
|
||||
BaumChardev *baum = BAUM_CHARDEV(chr);
|
||||
brlapi_handle_t *handle;
|
||||
|
||||
chr = qemu_chr_alloc(common, errp);
|
||||
if (!chr) {
|
||||
return NULL;
|
||||
}
|
||||
baum = g_malloc0(sizeof(BaumDriverState));
|
||||
baum->chr = chr;
|
||||
|
||||
chr->opaque = baum;
|
||||
chr->chr_write = baum_write;
|
||||
chr->chr_accept_input = baum_accept_input;
|
||||
chr->chr_free = baum_free;
|
||||
|
||||
handle = g_malloc0(brlapi_getHandleSize());
|
||||
baum->brlapi = handle;
|
||||
|
||||
@@ -652,27 +642,41 @@ static CharDriverState *chr_baum_init(const char *id,
|
||||
if (baum->brlapi_fd == -1) {
|
||||
error_setg(errp, "brlapi__openConnection: %s",
|
||||
brlapi_strerror(brlapi_error_location()));
|
||||
goto fail_handle;
|
||||
g_free(handle);
|
||||
return;
|
||||
}
|
||||
baum->deferred_init = 0;
|
||||
|
||||
baum->cellCount_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, baum_cellCount_timer_cb, baum);
|
||||
|
||||
qemu_set_fd_handler(baum->brlapi_fd, baum_chr_read, NULL, baum);
|
||||
|
||||
return chr;
|
||||
|
||||
fail_handle:
|
||||
g_free(handle);
|
||||
g_free(chr);
|
||||
g_free(baum);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void char_braille_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
ChardevClass *cc = CHARDEV_CLASS(oc);
|
||||
|
||||
cc->open = baum_chr_open;
|
||||
cc->chr_write = baum_chr_write;
|
||||
cc->chr_accept_input = baum_chr_accept_input;
|
||||
cc->chr_free = baum_chr_free;
|
||||
}
|
||||
|
||||
static const TypeInfo char_braille_type_info = {
|
||||
.name = TYPE_CHARDEV_BRAILLE,
|
||||
.parent = TYPE_CHARDEV,
|
||||
.instance_size = sizeof(BaumChardev),
|
||||
.class_init = char_braille_class_init,
|
||||
};
|
||||
|
||||
static void register_types(void)
|
||||
{
|
||||
register_char_driver("braille", CHARDEV_BACKEND_KIND_BRAILLE, NULL,
|
||||
chr_baum_init);
|
||||
static const CharDriver driver = {
|
||||
.kind = CHARDEV_BACKEND_KIND_BRAILLE,
|
||||
};
|
||||
|
||||
register_char_driver(&driver);
|
||||
type_register_static(&char_braille_type_info);
|
||||
}
|
||||
|
||||
type_init(register_types);
|
||||
|
||||
+45
-36
@@ -31,18 +31,23 @@
|
||||
#define MSMOUSE_HI2(n) (((n) & 0xc0) >> 6)
|
||||
|
||||
typedef struct {
|
||||
CharDriverState *chr;
|
||||
Chardev parent;
|
||||
|
||||
QemuInputHandlerState *hs;
|
||||
int axis[INPUT_AXIS__MAX];
|
||||
bool btns[INPUT_BUTTON__MAX];
|
||||
bool btnc[INPUT_BUTTON__MAX];
|
||||
uint8_t outbuf[32];
|
||||
int outlen;
|
||||
} MouseState;
|
||||
} MouseChardev;
|
||||
|
||||
static void msmouse_chr_accept_input(CharDriverState *chr)
|
||||
#define TYPE_CHARDEV_MSMOUSE "chardev-msmouse"
|
||||
#define MOUSE_CHARDEV(obj) \
|
||||
OBJECT_CHECK(MouseChardev, (obj), TYPE_CHARDEV_MSMOUSE)
|
||||
|
||||
static void msmouse_chr_accept_input(Chardev *chr)
|
||||
{
|
||||
MouseState *mouse = chr->opaque;
|
||||
MouseChardev *mouse = MOUSE_CHARDEV(chr);
|
||||
int len;
|
||||
|
||||
len = qemu_chr_be_can_write(chr);
|
||||
@@ -60,7 +65,7 @@ static void msmouse_chr_accept_input(CharDriverState *chr)
|
||||
}
|
||||
}
|
||||
|
||||
static void msmouse_queue_event(MouseState *mouse)
|
||||
static void msmouse_queue_event(MouseChardev *mouse)
|
||||
{
|
||||
unsigned char bytes[4] = { 0x40, 0x00, 0x00, 0x00 };
|
||||
int dx, dy, count = 3;
|
||||
@@ -97,7 +102,7 @@ static void msmouse_queue_event(MouseState *mouse)
|
||||
static void msmouse_input_event(DeviceState *dev, QemuConsole *src,
|
||||
InputEvent *evt)
|
||||
{
|
||||
MouseState *mouse = (MouseState *)dev;
|
||||
MouseChardev *mouse = MOUSE_CHARDEV(dev);
|
||||
InputMoveEvent *move;
|
||||
InputBtnEvent *btn;
|
||||
|
||||
@@ -121,24 +126,24 @@ static void msmouse_input_event(DeviceState *dev, QemuConsole *src,
|
||||
|
||||
static void msmouse_input_sync(DeviceState *dev)
|
||||
{
|
||||
MouseState *mouse = (MouseState *)dev;
|
||||
MouseChardev *mouse = MOUSE_CHARDEV(dev);
|
||||
Chardev *chr = CHARDEV(dev);
|
||||
|
||||
msmouse_queue_event(mouse);
|
||||
msmouse_chr_accept_input(mouse->chr);
|
||||
msmouse_chr_accept_input(chr);
|
||||
}
|
||||
|
||||
static int msmouse_chr_write (struct CharDriverState *s, const uint8_t *buf, int len)
|
||||
static int msmouse_chr_write(struct Chardev *s, const uint8_t *buf, int len)
|
||||
{
|
||||
/* Ignore writes to mouse port */
|
||||
return len;
|
||||
}
|
||||
|
||||
static void msmouse_chr_free(struct CharDriverState *chr)
|
||||
static void msmouse_chr_free(struct Chardev *chr)
|
||||
{
|
||||
MouseState *mouse = chr->opaque;
|
||||
MouseChardev *mouse = MOUSE_CHARDEV(chr);
|
||||
|
||||
qemu_input_handler_unregister(mouse->hs);
|
||||
g_free(mouse);
|
||||
}
|
||||
|
||||
static QemuInputHandler msmouse_handler = {
|
||||
@@ -148,39 +153,43 @@ static QemuInputHandler msmouse_handler = {
|
||||
.sync = msmouse_input_sync,
|
||||
};
|
||||
|
||||
static CharDriverState *qemu_chr_open_msmouse(const char *id,
|
||||
ChardevBackend *backend,
|
||||
ChardevReturn *ret,
|
||||
bool *be_opened,
|
||||
Error **errp)
|
||||
static void msmouse_chr_open(Chardev *chr,
|
||||
ChardevBackend *backend,
|
||||
bool *be_opened,
|
||||
Error **errp)
|
||||
{
|
||||
ChardevCommon *common = backend->u.msmouse.data;
|
||||
MouseState *mouse;
|
||||
CharDriverState *chr;
|
||||
MouseChardev *mouse = MOUSE_CHARDEV(chr);
|
||||
|
||||
chr = qemu_chr_alloc(common, errp);
|
||||
if (!chr) {
|
||||
return NULL;
|
||||
}
|
||||
chr->chr_write = msmouse_chr_write;
|
||||
chr->chr_free = msmouse_chr_free;
|
||||
chr->chr_accept_input = msmouse_chr_accept_input;
|
||||
*be_opened = false;
|
||||
|
||||
mouse = g_new0(MouseState, 1);
|
||||
mouse->hs = qemu_input_handler_register((DeviceState *)mouse,
|
||||
&msmouse_handler);
|
||||
|
||||
mouse->chr = chr;
|
||||
chr->opaque = mouse;
|
||||
|
||||
return chr;
|
||||
}
|
||||
|
||||
static void char_msmouse_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
ChardevClass *cc = CHARDEV_CLASS(oc);
|
||||
|
||||
cc->open = msmouse_chr_open;
|
||||
cc->chr_write = msmouse_chr_write;
|
||||
cc->chr_accept_input = msmouse_chr_accept_input;
|
||||
cc->chr_free = msmouse_chr_free;
|
||||
}
|
||||
|
||||
static const TypeInfo char_msmouse_type_info = {
|
||||
.name = TYPE_CHARDEV_MSMOUSE,
|
||||
.parent = TYPE_CHARDEV,
|
||||
.instance_size = sizeof(MouseChardev),
|
||||
.class_init = char_msmouse_class_init,
|
||||
};
|
||||
|
||||
static void register_types(void)
|
||||
{
|
||||
register_char_driver("msmouse", CHARDEV_BACKEND_KIND_MSMOUSE, NULL,
|
||||
qemu_chr_open_msmouse);
|
||||
static const CharDriver driver = {
|
||||
.kind = CHARDEV_BACKEND_KIND_MSMOUSE,
|
||||
};
|
||||
|
||||
register_char_driver(&driver);
|
||||
type_register_static(&char_msmouse_type_info);
|
||||
}
|
||||
|
||||
type_init(register_types);
|
||||
|
||||
+2
-2
@@ -86,7 +86,7 @@ static void rng_egd_chr_read(void *opaque, const uint8_t *buf, int size)
|
||||
static void rng_egd_opened(RngBackend *b, Error **errp)
|
||||
{
|
||||
RngEgd *s = RNG_EGD(b);
|
||||
CharDriverState *chr;
|
||||
Chardev *chr;
|
||||
|
||||
if (s->chr_name == NULL) {
|
||||
error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
|
||||
@@ -125,7 +125,7 @@ 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);
|
||||
CharDriverState *chr = qemu_chr_fe_get_driver(&s->chr);
|
||||
Chardev *chr = qemu_chr_fe_get_driver(&s->chr);
|
||||
|
||||
if (chr && chr->label) {
|
||||
return g_strdup(chr->label);
|
||||
|
||||
+25
-28
@@ -30,13 +30,18 @@
|
||||
#define BUF_SIZE 32
|
||||
|
||||
typedef struct {
|
||||
CharDriverState *chr;
|
||||
Chardev parent;
|
||||
|
||||
uint8_t in_buf[32];
|
||||
int in_buf_used;
|
||||
} TestdevCharState;
|
||||
} TestdevChardev;
|
||||
|
||||
#define TYPE_CHARDEV_TESTDEV "chardev-testdev"
|
||||
#define TESTDEV_CHARDEV(obj) \
|
||||
OBJECT_CHECK(TestdevChardev, (obj), TYPE_CHARDEV_TESTDEV)
|
||||
|
||||
/* Try to interpret a whole incoming packet */
|
||||
static int testdev_eat_packet(TestdevCharState *testdev)
|
||||
static int testdev_eat_packet(TestdevChardev *testdev)
|
||||
{
|
||||
const uint8_t *cur = testdev->in_buf;
|
||||
int len = testdev->in_buf_used;
|
||||
@@ -77,9 +82,9 @@ static int testdev_eat_packet(TestdevCharState *testdev)
|
||||
}
|
||||
|
||||
/* The other end is writing some data. Store it and try to interpret */
|
||||
static int testdev_write(CharDriverState *chr, const uint8_t *buf, int len)
|
||||
static int testdev_chr_write(Chardev *chr, const uint8_t *buf, int len)
|
||||
{
|
||||
TestdevCharState *testdev = chr->opaque;
|
||||
TestdevChardev *testdev = TESTDEV_CHARDEV(chr);
|
||||
int tocopy, eaten, orig_len = len;
|
||||
|
||||
while (len) {
|
||||
@@ -102,36 +107,28 @@ static int testdev_write(CharDriverState *chr, const uint8_t *buf, int len)
|
||||
return orig_len;
|
||||
}
|
||||
|
||||
static void testdev_free(struct CharDriverState *chr)
|
||||
static void char_testdev_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
TestdevCharState *testdev = chr->opaque;
|
||||
ChardevClass *cc = CHARDEV_CLASS(oc);
|
||||
|
||||
g_free(testdev);
|
||||
cc->chr_write = testdev_chr_write;
|
||||
}
|
||||
|
||||
static CharDriverState *chr_testdev_init(const char *id,
|
||||
ChardevBackend *backend,
|
||||
ChardevReturn *ret,
|
||||
bool *be_opened,
|
||||
Error **errp)
|
||||
{
|
||||
TestdevCharState *testdev;
|
||||
CharDriverState *chr;
|
||||
|
||||
testdev = g_new0(TestdevCharState, 1);
|
||||
testdev->chr = chr = g_new0(CharDriverState, 1);
|
||||
|
||||
chr->opaque = testdev;
|
||||
chr->chr_write = testdev_write;
|
||||
chr->chr_free = testdev_free;
|
||||
|
||||
return chr;
|
||||
}
|
||||
static const TypeInfo char_testdev_type_info = {
|
||||
.name = TYPE_CHARDEV_TESTDEV,
|
||||
.parent = TYPE_CHARDEV,
|
||||
.instance_size = sizeof(TestdevChardev),
|
||||
.class_init = char_testdev_class_init,
|
||||
};
|
||||
|
||||
static void register_types(void)
|
||||
{
|
||||
register_char_driver("testdev", CHARDEV_BACKEND_KIND_TESTDEV, NULL,
|
||||
chr_testdev_init);
|
||||
static const CharDriver driver = {
|
||||
.kind = CHARDEV_BACKEND_KIND_TESTDEV,
|
||||
};
|
||||
|
||||
register_char_driver(&driver);
|
||||
type_register_static(&char_testdev_type_info);
|
||||
}
|
||||
|
||||
type_init(register_types);
|
||||
|
||||
@@ -14,6 +14,7 @@ block-obj-y += throttle-groups.o
|
||||
|
||||
block-obj-y += nbd.o nbd-client.o sheepdog.o
|
||||
block-obj-$(CONFIG_LIBISCSI) += iscsi.o
|
||||
block-obj-$(if $(CONFIG_LIBISCSI),y,n) += iscsi-opts.o
|
||||
block-obj-$(CONFIG_LIBNFS) += nfs.o
|
||||
block-obj-$(CONFIG_CURL) += curl.o
|
||||
block-obj-$(CONFIG_RBD) += rbd.o
|
||||
|
||||
+11
-8
@@ -651,12 +651,15 @@ static void raw_reopen_abort(BDRVReopenState *state)
|
||||
state->opaque = NULL;
|
||||
}
|
||||
|
||||
static int hdev_get_max_transfer_length(int fd)
|
||||
static int hdev_get_max_transfer_length(BlockDriverState *bs, int fd)
|
||||
{
|
||||
#ifdef BLKSECTGET
|
||||
int max_sectors = 0;
|
||||
if (ioctl(fd, BLKSECTGET, &max_sectors) == 0) {
|
||||
return max_sectors;
|
||||
int max_bytes = 0;
|
||||
short max_sectors = 0;
|
||||
if (bs->sg && ioctl(fd, BLKSECTGET, &max_bytes) == 0) {
|
||||
return max_bytes;
|
||||
} else if (!bs->sg && ioctl(fd, BLKSECTGET, &max_sectors) == 0) {
|
||||
return max_sectors << BDRV_SECTOR_BITS;
|
||||
} else {
|
||||
return -errno;
|
||||
}
|
||||
@@ -671,10 +674,10 @@ static void raw_refresh_limits(BlockDriverState *bs, Error **errp)
|
||||
struct stat st;
|
||||
|
||||
if (!fstat(s->fd, &st)) {
|
||||
if (S_ISBLK(st.st_mode)) {
|
||||
int ret = hdev_get_max_transfer_length(s->fd);
|
||||
if (ret > 0 && ret <= BDRV_REQUEST_MAX_SECTORS) {
|
||||
bs->bl.max_transfer = pow2floor(ret << BDRV_SECTOR_BITS);
|
||||
if (S_ISBLK(st.st_mode) || S_ISCHR(st.st_mode)) {
|
||||
int ret = hdev_get_max_transfer_length(bs, s->fd);
|
||||
if (ret > 0 && ret <= BDRV_REQUEST_MAX_BYTES) {
|
||||
bs->bl.max_transfer = pow2floor(ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* QEMU Block driver for iSCSI images (static options)
|
||||
*
|
||||
* Copyright (c) 2017 Peter Lieven <pl@kamp.de>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu-common.h"
|
||||
#include "qemu/config-file.h"
|
||||
|
||||
static QemuOptsList qemu_iscsi_opts = {
|
||||
.name = "iscsi",
|
||||
.head = QTAILQ_HEAD_INITIALIZER(qemu_iscsi_opts.head),
|
||||
.desc = {
|
||||
{
|
||||
.name = "user",
|
||||
.type = QEMU_OPT_STRING,
|
||||
.help = "username for CHAP authentication to target",
|
||||
},{
|
||||
.name = "password",
|
||||
.type = QEMU_OPT_STRING,
|
||||
.help = "password for CHAP authentication to target",
|
||||
},{
|
||||
.name = "password-secret",
|
||||
.type = QEMU_OPT_STRING,
|
||||
.help = "ID of the secret providing password for CHAP "
|
||||
"authentication to target",
|
||||
},{
|
||||
.name = "header-digest",
|
||||
.type = QEMU_OPT_STRING,
|
||||
.help = "HeaderDigest setting. "
|
||||
"{CRC32C|CRC32C-NONE|NONE-CRC32C|NONE}",
|
||||
},{
|
||||
.name = "initiator-name",
|
||||
.type = QEMU_OPT_STRING,
|
||||
.help = "Initiator iqn name to use when connecting",
|
||||
},{
|
||||
.name = "timeout",
|
||||
.type = QEMU_OPT_NUMBER,
|
||||
.help = "Request timeout in seconds (default 0 = no timeout)",
|
||||
},
|
||||
{ /* end of list */ }
|
||||
},
|
||||
};
|
||||
|
||||
static void iscsi_block_opts_init(void)
|
||||
{
|
||||
qemu_add_opts(&qemu_iscsi_opts);
|
||||
}
|
||||
|
||||
block_init(iscsi_block_opts_init);
|
||||
+6
-2
@@ -499,14 +499,18 @@ iscsi_allocmap_update(IscsiLun *iscsilun, int64_t sector_num,
|
||||
if (allocated) {
|
||||
bitmap_set(iscsilun->allocmap, cl_num_expanded, nb_cls_expanded);
|
||||
} else {
|
||||
bitmap_clear(iscsilun->allocmap, cl_num_shrunk, nb_cls_shrunk);
|
||||
if (nb_cls_shrunk > 0) {
|
||||
bitmap_clear(iscsilun->allocmap, cl_num_shrunk, nb_cls_shrunk);
|
||||
}
|
||||
}
|
||||
|
||||
if (iscsilun->allocmap_valid == NULL) {
|
||||
return;
|
||||
}
|
||||
if (valid) {
|
||||
bitmap_set(iscsilun->allocmap_valid, cl_num_shrunk, nb_cls_shrunk);
|
||||
if (nb_cls_shrunk > 0) {
|
||||
bitmap_set(iscsilun->allocmap_valid, cl_num_shrunk, nb_cls_shrunk);
|
||||
}
|
||||
} else {
|
||||
bitmap_clear(iscsilun->allocmap_valid, cl_num_expanded,
|
||||
nb_cls_expanded);
|
||||
|
||||
+1
-1
@@ -508,8 +508,8 @@ static inline void cpu_handle_interrupt(CPUState *cpu,
|
||||
True when it is, and we should restart on a new TB,
|
||||
and via longjmp via cpu_loop_exit. */
|
||||
else {
|
||||
replay_interrupt();
|
||||
if (cc->cpu_exec_interrupt(cpu, interrupt_request)) {
|
||||
replay_interrupt();
|
||||
*last_tb = NULL;
|
||||
}
|
||||
/* The target hook may have updated the 'cpu->interrupt_request';
|
||||
|
||||
@@ -196,6 +196,22 @@ is recorded to the log. In replay phase the queue is matched with
|
||||
events read from the log. Therefore block devices requests are processed
|
||||
deterministically.
|
||||
|
||||
Snapshotting
|
||||
------------
|
||||
|
||||
New VM snapshots may be created in replay mode. They can be used later
|
||||
to recover the desired VM state. All VM states created in replay mode
|
||||
are associated with the moment of time in the replay scenario.
|
||||
After recovering the VM state replay will start from that position.
|
||||
|
||||
Default starting snapshot name may be specified with icount field
|
||||
rrsnapshot as follows:
|
||||
-icount shift=7,rr=record,rrfile=replay.bin,rrsnapshot=snapshot_name
|
||||
|
||||
This snapshot is created at start of recording and restored at start
|
||||
of replaying. It also can be loaded while replaying to roll back
|
||||
the execution.
|
||||
|
||||
Network devices
|
||||
---------------
|
||||
|
||||
|
||||
@@ -2630,7 +2630,7 @@ static MemTxResult address_space_write_continue(AddressSpace *as, hwaddr addr,
|
||||
break;
|
||||
case 4:
|
||||
/* 32 bit write access */
|
||||
val = ldl_p(buf);
|
||||
val = (uint32_t)ldl_p(buf);
|
||||
result |= memory_region_dispatch_write(mr, addr1, val, 4,
|
||||
attrs);
|
||||
break;
|
||||
|
||||
@@ -305,7 +305,7 @@ typedef struct GDBState {
|
||||
int running_state;
|
||||
#else
|
||||
CharBackend chr;
|
||||
CharDriverState *mon_chr;
|
||||
Chardev *mon_chr;
|
||||
#endif
|
||||
char syscall_buf[256];
|
||||
gdb_syscall_complete_cb current_syscall_cb;
|
||||
@@ -1473,7 +1473,7 @@ void gdb_exit(CPUArchState *env, int code)
|
||||
GDBState *s;
|
||||
char buf[4];
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
CharDriverState *chr;
|
||||
Chardev *chr;
|
||||
#endif
|
||||
|
||||
s = gdbserver_state;
|
||||
@@ -1698,7 +1698,7 @@ static void gdb_monitor_output(GDBState *s, const char *msg, int len)
|
||||
put_packet(s, buf);
|
||||
}
|
||||
|
||||
static int gdb_monitor_write(CharDriverState *chr, const uint8_t *buf, int len)
|
||||
static int gdb_monitor_write(Chardev *chr, const uint8_t *buf, int len)
|
||||
{
|
||||
const char *p = (const char *)buf;
|
||||
int max_sz;
|
||||
@@ -1725,13 +1725,35 @@ static void gdb_sigterm_handler(int signal)
|
||||
}
|
||||
#endif
|
||||
|
||||
static void gdb_monitor_open(Chardev *chr, ChardevBackend *backend,
|
||||
bool *be_opened, Error **errp)
|
||||
{
|
||||
*be_opened = false;
|
||||
}
|
||||
|
||||
static void char_gdb_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
ChardevClass *cc = CHARDEV_CLASS(oc);
|
||||
|
||||
cc->internal = true;
|
||||
cc->open = gdb_monitor_open;
|
||||
cc->chr_write = gdb_monitor_write;
|
||||
}
|
||||
|
||||
#define TYPE_CHARDEV_GDB "chardev-gdb"
|
||||
|
||||
static const TypeInfo char_gdb_type_info = {
|
||||
.name = TYPE_CHARDEV_GDB,
|
||||
.parent = TYPE_CHARDEV,
|
||||
.class_init = char_gdb_class_init,
|
||||
};
|
||||
|
||||
int gdbserver_start(const char *device)
|
||||
{
|
||||
GDBState *s;
|
||||
char gdbstub_device_name[128];
|
||||
CharDriverState *chr = NULL;
|
||||
CharDriverState *mon_chr;
|
||||
ChardevCommon common = { 0 };
|
||||
Chardev *chr = NULL;
|
||||
Chardev *mon_chr;
|
||||
|
||||
if (!first_cpu) {
|
||||
error_report("gdbstub: meaningless to attach gdb to a "
|
||||
@@ -1770,8 +1792,8 @@ int gdbserver_start(const char *device)
|
||||
qemu_add_vm_change_state_handler(gdb_vm_state_change, NULL);
|
||||
|
||||
/* Initialize a monitor terminal for gdb */
|
||||
mon_chr = qemu_chr_alloc(&common, &error_abort);
|
||||
mon_chr->chr_write = gdb_monitor_write;
|
||||
mon_chr = qemu_chardev_new(NULL, TYPE_CHARDEV_GDB,
|
||||
NULL, &error_abort);
|
||||
monitor_init(mon_chr, 0);
|
||||
} else {
|
||||
if (qemu_chr_fe_get_driver(&s->chr)) {
|
||||
@@ -1794,4 +1816,11 @@ int gdbserver_start(const char *device)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void register_types(void)
|
||||
{
|
||||
type_register_static(&char_gdb_type_info);
|
||||
}
|
||||
|
||||
type_init(register_types);
|
||||
#endif
|
||||
|
||||
@@ -249,9 +249,9 @@ ETEXI
|
||||
|
||||
{
|
||||
.name = "mtree",
|
||||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show memory tree",
|
||||
.args_type = "flatview:-f",
|
||||
.params = "[-f]",
|
||||
.help = "show memory tree (-f: dump flat view for address spaces)",
|
||||
.cmd = hmp_info_mtree,
|
||||
},
|
||||
|
||||
|
||||
+1
-1
@@ -118,7 +118,7 @@ static void fsl_imx25_realize(DeviceState *dev, Error **errp)
|
||||
};
|
||||
|
||||
if (i < MAX_SERIAL_PORTS) {
|
||||
CharDriverState *chr;
|
||||
Chardev *chr;
|
||||
|
||||
chr = serial_hds[i];
|
||||
|
||||
|
||||
+1
-1
@@ -107,7 +107,7 @@ static void fsl_imx31_realize(DeviceState *dev, Error **errp)
|
||||
};
|
||||
|
||||
if (i < MAX_SERIAL_PORTS) {
|
||||
CharDriverState *chr;
|
||||
Chardev *chr;
|
||||
|
||||
chr = serial_hds[i];
|
||||
|
||||
|
||||
+1
-1
@@ -187,7 +187,7 @@ static void fsl_imx6_realize(DeviceState *dev, Error **errp)
|
||||
};
|
||||
|
||||
if (i < MAX_SERIAL_PORTS) {
|
||||
CharDriverState *chr;
|
||||
Chardev *chr;
|
||||
|
||||
chr = serial_hds[i];
|
||||
|
||||
|
||||
+1
-1
@@ -786,7 +786,7 @@ static void n8x0_cbus_setup(struct n800_s *s)
|
||||
|
||||
static void n8x0_uart_setup(struct n800_s *s)
|
||||
{
|
||||
CharDriverState *radio = uart_hci_init();
|
||||
Chardev *radio = uart_hci_init();
|
||||
|
||||
qdev_connect_gpio_out(s->mpu->gpio, N8X0_BT_RESET_GPIO,
|
||||
csrhci_pins_get(radio)[csrhci_pin_reset]);
|
||||
|
||||
+1
-1
@@ -792,7 +792,7 @@ static const MemoryRegionOps omap_sti_fifo_ops = {
|
||||
static struct omap_sti_s *omap_sti_init(struct omap_target_agent_s *ta,
|
||||
MemoryRegion *sysmem,
|
||||
hwaddr channel_base, qemu_irq irq, omap_clk clk,
|
||||
CharDriverState *chr)
|
||||
Chardev *chr)
|
||||
{
|
||||
struct omap_sti_s *s = g_new0(struct omap_sti_s, 1);
|
||||
|
||||
|
||||
+1
-1
@@ -2024,7 +2024,7 @@ static PXA2xxFIrState *pxa2xx_fir_init(MemoryRegion *sysmem,
|
||||
hwaddr base,
|
||||
qemu_irq irq, qemu_irq rx_dma,
|
||||
qemu_irq tx_dma,
|
||||
CharDriverState *chr)
|
||||
Chardev *chr)
|
||||
{
|
||||
DeviceState *dev;
|
||||
SysBusDevice *sbd;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user