summaryrefslogtreecommitdiffstats
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-rw-r--r--hw/block/xen_blkif.h167
-rw-r--r--hw/usb/bus.c51
-rw-r--r--hw/usb/dev-storage.c42
-rw-r--r--hw/usb/dev-uas.c5
-rw-r--r--hw/xen/xen_backend.c41
-rw-r--r--hw/xenpv/xen_machine_pv.c40
6 files changed, 196 insertions, 150 deletions
diff --git a/hw/block/xen_blkif.h b/hw/block/xen_blkif.h
index e3b133b9f8..0738684410 100644
--- a/hw/block/xen_blkif.h
+++ b/hw/block/xen_blkif.h
@@ -5,31 +5,41 @@
#include <xen/io/blkif.h>
#include <xen/io/protocols.h>
-/* Not a real protocol. Used to generate ring structs which contain
+/*
+ * Not a real protocol. Used to generate ring structs which contain
* the elements common to all protocols only. This way we get a
* compiler-checkable way to use common struct elements, so we can
- * avoid using switch(protocol) in a number of places. */
+ * avoid using switch(protocol) in a number of places.
+ */
struct blkif_common_request {
- char dummy;
+ char dummy;
};
struct blkif_common_response {
- char dummy;
+ char dummy;
};
/* i386 protocol version */
#pragma pack(push, 4)
struct blkif_x86_32_request {
- uint8_t operation; /* BLKIF_OP_??? */
- uint8_t nr_segments; /* number of segments */
- blkif_vdev_t handle; /* only for read/write requests */
- uint64_t id; /* private guest value, echoed in resp */
- blkif_sector_t sector_number;/* start sector idx on disk (r/w only) */
- struct blkif_request_segment seg[BLKIF_MAX_SEGMENTS_PER_REQUEST];
+ uint8_t operation; /* BLKIF_OP_??? */
+ uint8_t nr_segments; /* number of segments */
+ blkif_vdev_t handle; /* only for read/write requests */
+ uint64_t id; /* private guest value, echoed in resp */
+ blkif_sector_t sector_number; /* start sector idx on disk (r/w only) */
+ struct blkif_request_segment seg[BLKIF_MAX_SEGMENTS_PER_REQUEST];
+};
+struct blkif_x86_32_request_discard {
+ uint8_t operation; /* BLKIF_OP_DISCARD */
+ uint8_t flag; /* nr_segments in request struct */
+ blkif_vdev_t handle; /* only for read/write requests */
+ uint64_t id; /* private guest value, echoed in resp */
+ blkif_sector_t sector_number; /* start sector idx on disk (r/w only) */
+ uint64_t nr_sectors; /* # of contiguous sectors to discard */
};
struct blkif_x86_32_response {
- uint64_t id; /* copied from request */
- uint8_t operation; /* copied from request */
- int16_t status; /* BLKIF_RSP_??? */
+ uint64_t id; /* copied from request */
+ uint8_t operation; /* copied from request */
+ int16_t status; /* BLKIF_RSP_??? */
};
typedef struct blkif_x86_32_request blkif_x86_32_request_t;
typedef struct blkif_x86_32_response blkif_x86_32_response_t;
@@ -37,83 +47,100 @@ typedef struct blkif_x86_32_response blkif_x86_32_response_t;
/* x86_64 protocol version */
struct blkif_x86_64_request {
- uint8_t operation; /* BLKIF_OP_??? */
- uint8_t nr_segments; /* number of segments */
- blkif_vdev_t handle; /* only for read/write requests */
- uint64_t __attribute__((__aligned__(8))) id;
- blkif_sector_t sector_number;/* start sector idx on disk (r/w only) */
- struct blkif_request_segment seg[BLKIF_MAX_SEGMENTS_PER_REQUEST];
+ uint8_t operation; /* BLKIF_OP_??? */
+ uint8_t nr_segments; /* number of segments */
+ blkif_vdev_t handle; /* only for read/write requests */
+ uint64_t __attribute__((__aligned__(8))) id;
+ blkif_sector_t sector_number; /* start sector idx on disk (r/w only) */
+ struct blkif_request_segment seg[BLKIF_MAX_SEGMENTS_PER_REQUEST];
+};
+struct blkif_x86_64_request_discard {
+ uint8_t operation; /* BLKIF_OP_DISCARD */
+ uint8_t flag; /* nr_segments in request struct */
+ blkif_vdev_t handle; /* only for read/write requests */
+ uint64_t __attribute__((__aligned__(8))) id;
+ blkif_sector_t sector_number; /* start sector idx on disk (r/w only) */
+ uint64_t nr_sectors; /* # of contiguous sectors to discard */
};
struct blkif_x86_64_response {
- uint64_t __attribute__((__aligned__(8))) id;
- uint8_t operation; /* copied from request */
- int16_t status; /* BLKIF_RSP_??? */
+ uint64_t __attribute__((__aligned__(8))) id;
+ uint8_t operation; /* copied from request */
+ int16_t status; /* BLKIF_RSP_??? */
};
typedef struct blkif_x86_64_request blkif_x86_64_request_t;
typedef struct blkif_x86_64_response blkif_x86_64_response_t;
-DEFINE_RING_TYPES(blkif_common, struct blkif_common_request, struct blkif_common_response);
-DEFINE_RING_TYPES(blkif_x86_32, struct blkif_x86_32_request, struct blkif_x86_32_response);
-DEFINE_RING_TYPES(blkif_x86_64, struct blkif_x86_64_request, struct blkif_x86_64_response);
+DEFINE_RING_TYPES(blkif_common, struct blkif_common_request,
+ struct blkif_common_response);
+DEFINE_RING_TYPES(blkif_x86_32, struct blkif_x86_32_request,
+ struct blkif_x86_32_response);
+DEFINE_RING_TYPES(blkif_x86_64, struct blkif_x86_64_request,
+ struct blkif_x86_64_response);
union blkif_back_rings {
- blkif_back_ring_t native;
- blkif_common_back_ring_t common;
- blkif_x86_32_back_ring_t x86_32_part;
- blkif_x86_64_back_ring_t x86_64_part;
+ blkif_back_ring_t native;
+ blkif_common_back_ring_t common;
+ blkif_x86_32_back_ring_t x86_32_part;
+ blkif_x86_64_back_ring_t x86_64_part;
};
typedef union blkif_back_rings blkif_back_rings_t;
enum blkif_protocol {
- BLKIF_PROTOCOL_NATIVE = 1,
- BLKIF_PROTOCOL_X86_32 = 2,
- BLKIF_PROTOCOL_X86_64 = 3,
+ BLKIF_PROTOCOL_NATIVE = 1,
+ BLKIF_PROTOCOL_X86_32 = 2,
+ BLKIF_PROTOCOL_X86_64 = 3,
};
-static inline void blkif_get_x86_32_req(blkif_request_t *dst, blkif_x86_32_request_t *src)
+static inline void blkif_get_x86_32_req(blkif_request_t *dst,
+ blkif_x86_32_request_t *src)
{
- int i, n = BLKIF_MAX_SEGMENTS_PER_REQUEST;
+ int i, n = BLKIF_MAX_SEGMENTS_PER_REQUEST;
- dst->operation = src->operation;
- dst->nr_segments = src->nr_segments;
- dst->handle = src->handle;
- dst->id = src->id;
- dst->sector_number = src->sector_number;
- /* Prevent the compiler from using src->... instead. */
- barrier();
- if (dst->operation == BLKIF_OP_DISCARD) {
- struct blkif_request_discard *s = (void *)src;
- struct blkif_request_discard *d = (void *)dst;
- d->nr_sectors = s->nr_sectors;
- return;
- }
- if (n > dst->nr_segments)
- n = dst->nr_segments;
- for (i = 0; i < n; i++)
- dst->seg[i] = src->seg[i];
+ dst->operation = src->operation;
+ dst->nr_segments = src->nr_segments;
+ dst->handle = src->handle;
+ dst->id = src->id;
+ dst->sector_number = src->sector_number;
+ /* Prevent the compiler from using src->... instead. */
+ barrier();
+ if (dst->operation == BLKIF_OP_DISCARD) {
+ struct blkif_x86_32_request_discard *s = (void *)src;
+ struct blkif_request_discard *d = (void *)dst;
+ d->nr_sectors = s->nr_sectors;
+ return;
+ }
+ if (n > dst->nr_segments) {
+ n = dst->nr_segments;
+ }
+ for (i = 0; i < n; i++) {
+ dst->seg[i] = src->seg[i];
+ }
}
-static inline void blkif_get_x86_64_req(blkif_request_t *dst, blkif_x86_64_request_t *src)
+static inline void blkif_get_x86_64_req(blkif_request_t *dst,
+ blkif_x86_64_request_t *src)
{
- int i, n = BLKIF_MAX_SEGMENTS_PER_REQUEST;
+ int i, n = BLKIF_MAX_SEGMENTS_PER_REQUEST;
- dst->operation = src->operation;
- dst->nr_segments = src->nr_segments;
- dst->handle = src->handle;
- dst->id = src->id;
- dst->sector_number = src->sector_number;
- /* Prevent the compiler from using src->... instead. */
- barrier();
- if (dst->operation == BLKIF_OP_DISCARD) {
- struct blkif_request_discard *s = (void *)src;
- struct blkif_request_discard *d = (void *)dst;
- d->nr_sectors = s->nr_sectors;
- return;
- }
- if (n > dst->nr_segments)
- n = dst->nr_segments;
- for (i = 0; i < n; i++)
- dst->seg[i] = src->seg[i];
+ dst->operation = src->operation;
+ dst->nr_segments = src->nr_segments;
+ dst->handle = src->handle;
+ dst->id = src->id;
+ dst->sector_number = src->sector_number;
+ /* Prevent the compiler from using src->... instead. */
+ barrier();
+ if (dst->operation == BLKIF_OP_DISCARD) {
+ struct blkif_x86_64_request_discard *s = (void *)src;
+ struct blkif_request_discard *d = (void *)dst;
+ d->nr_sectors = s->nr_sectors;
+ return;
+ }
+ if (n > dst->nr_segments) {
+ n = dst->nr_segments;
+ }
+ for (i = 0; i < n; i++) {
+ dst->seg[i] = src->seg[i];
+ }
}
#endif /* __XEN_BLKIF_H__ */
diff --git a/hw/usb/bus.c b/hw/usb/bus.c
index 16c3461d99..c28ccb8a96 100644
--- a/hw/usb/bus.c
+++ b/hw/usb/bus.c
@@ -55,9 +55,9 @@ static int usb_device_post_load(void *opaque, int version_id)
USBDevice *dev = opaque;
if (dev->state == USB_STATE_NOTATTACHED) {
- dev->attached = 0;
+ dev->attached = false;
} else {
- dev->attached = 1;
+ dev->attached = true;
}
if (dev->setup_index < 0 ||
dev->setup_len < 0 ||
@@ -533,7 +533,7 @@ void usb_device_attach(USBDevice *dev, Error **errp)
return;
}
- dev->attached++;
+ dev->attached = true;
usb_attach(port);
}
@@ -547,7 +547,7 @@ int usb_device_detach(USBDevice *dev)
trace_usb_port_detach(bus->busnr, port->path);
usb_detach(port);
- dev->attached--;
+ dev->attached = false;
return 0;
}
@@ -736,6 +736,48 @@ USBDevice *usbdevice_create(const char *cmdline)
return dev;
}
+static bool usb_get_attached(Object *obj, Error **errp)
+{
+ USBDevice *dev = USB_DEVICE(obj);
+
+ return dev->attached;
+}
+
+static void usb_set_attached(Object *obj, bool value, Error **errp)
+{
+ USBDevice *dev = USB_DEVICE(obj);
+ Error *err = NULL;
+
+ if (dev->attached == value) {
+ return;
+ }
+
+ if (value) {
+ usb_device_attach(dev, &err);
+ if (err) {
+ error_propagate(errp, err);
+ }
+ } else {
+ usb_device_detach(dev);
+ }
+}
+
+static void usb_device_instance_init(Object *obj)
+{
+ USBDevice *dev = USB_DEVICE(obj);
+ USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev);
+
+ if (klass->attached_settable) {
+ object_property_add_bool(obj, "attached",
+ usb_get_attached, usb_set_attached,
+ NULL);
+ } else {
+ object_property_add_bool(obj, "attached",
+ usb_get_attached, NULL,
+ NULL);
+ }
+}
+
static void usb_device_class_init(ObjectClass *klass, void *data)
{
DeviceClass *k = DEVICE_CLASS(klass);
@@ -749,6 +791,7 @@ static const TypeInfo usb_device_type_info = {
.name = TYPE_USB_DEVICE,
.parent = TYPE_DEVICE,
.instance_size = sizeof(USBDevice),
+ .instance_init = usb_device_instance_init,
.abstract = true,
.class_size = sizeof(USBDeviceClass),
.class_init = usb_device_class_init,
diff --git a/hw/usb/dev-storage.c b/hw/usb/dev-storage.c
index 9fd00dfffc..4d605b8a6a 100644
--- a/hw/usb/dev-storage.c
+++ b/hw/usb/dev-storage.c
@@ -556,21 +556,6 @@ static void usb_msd_handle_data(USBDevice *dev, USBPacket *p)
}
}
-static void usb_msd_password_cb(void *opaque, int err)
-{
- MSDState *s = opaque;
- Error *local_err = NULL;
-
- if (!err) {
- usb_device_attach(&s->dev, &local_err);
- }
-
- if (local_err) {
- error_report_err(local_err);
- qdev_unplug(&s->dev.qdev, NULL);
- }
-}
-
static void *usb_msd_load_request(QEMUFile *f, SCSIRequest *req)
{
MSDState *s = DO_UPCAST(MSDState, dev.qdev, req->bus->qbus.parent);
@@ -616,25 +601,6 @@ static void usb_msd_realize_storage(USBDevice *dev, Error **errp)
return;
}
- if (blk_bs(blk)) {
- bdrv_add_key(blk_bs(blk), NULL, &err);
- if (err) {
- if (monitor_cur_is_qmp()) {
- error_propagate(errp, err);
- return;
- }
- error_free(err);
- err = NULL;
- if (cur_mon) {
- monitor_read_bdrv_key_start(cur_mon, blk_bs(blk),
- usb_msd_password_cb, s);
- s->dev.auto_attach = 0;
- } else {
- autostart = 0;
- }
- }
- }
-
blkconf_serial(&s->conf, &dev->serial);
blkconf_blocksizes(&s->conf);
@@ -668,9 +634,14 @@ static void usb_msd_realize_storage(USBDevice *dev, Error **errp)
static void usb_msd_realize_bot(USBDevice *dev, Error **errp)
{
MSDState *s = USB_STORAGE_DEV(dev);
+ DeviceState *d = DEVICE(dev);
usb_desc_create_serial(dev);
usb_desc_init(dev);
+ if (d->hotplugged) {
+ s->dev.auto_attach = 0;
+ }
+
scsi_bus_new(&s->bus, sizeof(s->bus), DEVICE(dev),
&usb_msd_scsi_info_bot, NULL);
usb_msd_handle_reset(dev);
@@ -840,10 +811,9 @@ static void usb_msd_instance_init(Object *obj)
static void usb_msd_class_initfn_bot(ObjectClass *klass, void *data)
{
USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
- DeviceClass *dc = DEVICE_CLASS(klass);
uc->realize = usb_msd_realize_bot;
- dc->hotpluggable = false;
+ uc->attached_settable = true;
}
static const TypeInfo msd_info = {
diff --git a/hw/usb/dev-uas.c b/hw/usb/dev-uas.c
index 0678b1b05b..3a8ff18b1b 100644
--- a/hw/usb/dev-uas.c
+++ b/hw/usb/dev-uas.c
@@ -900,9 +900,13 @@ static void usb_uas_handle_destroy(USBDevice *dev)
static void usb_uas_realize(USBDevice *dev, Error **errp)
{
UASDevice *uas = USB_UAS(dev);
+ DeviceState *d = DEVICE(dev);
usb_desc_create_serial(dev);
usb_desc_init(dev);
+ if (d->hotplugged) {
+ uas->dev.auto_attach = 0;
+ }
QTAILQ_INIT(&uas->results);
QTAILQ_INIT(&uas->requests);
@@ -940,6 +944,7 @@ static void usb_uas_class_initfn(ObjectClass *klass, void *data)
uc->handle_control = usb_uas_handle_control;
uc->handle_data = usb_uas_handle_data;
uc->handle_destroy = usb_uas_handle_destroy;
+ uc->attached_settable = true;
set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
dc->fw_name = "storage";
dc->vmsd = &vmstate_usb_uas;
diff --git a/hw/xen/xen_backend.c b/hw/xen/xen_backend.c
index e7ce724567..bab79b1912 100644
--- a/hw/xen/xen_backend.c
+++ b/hw/xen/xen_backend.c
@@ -26,12 +26,17 @@
#include <sys/signal.h>
#include "hw/hw.h"
+#include "hw/sysbus.h"
#include "sysemu/char.h"
#include "qemu/log.h"
#include "hw/xen/xen_backend.h"
#include <xen/grant_table.h>
+#define TYPE_XENSYSDEV "xensysdev"
+
+DeviceState *xen_sysdev;
+
/* ------------------------------------------------------------- */
/* public */
@@ -762,6 +767,10 @@ int xen_be_init(void)
/* Check if xen_init() have been called */
goto err;
}
+
+ xen_sysdev = qdev_create(NULL, TYPE_XENSYSDEV);
+ qdev_init_nofail(xen_sysdev);
+
return 0;
err:
@@ -862,3 +871,35 @@ void xen_be_printf(struct XenDevice *xendev, int msg_level, const char *fmt, ...
}
qemu_log_flush();
}
+
+static int xen_sysdev_init(SysBusDevice *dev)
+{
+ return 0;
+}
+
+static Property xen_sysdev_properties[] = {
+ {/* end of property list */},
+};
+
+static void xen_sysdev_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+ k->init = xen_sysdev_init;
+ dc->props = xen_sysdev_properties;
+}
+
+static const TypeInfo xensysdev_info = {
+ .name = TYPE_XENSYSDEV,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(SysBusDevice),
+ .class_init = xen_sysdev_class_init,
+};
+
+static void xenbe_register_types(void)
+{
+ type_register_static(&xensysdev_info);
+}
+
+type_init(xenbe_register_types);
diff --git a/hw/xenpv/xen_machine_pv.c b/hw/xenpv/xen_machine_pv.c
index f68cf48a29..48f725c9cd 100644
--- a/hw/xenpv/xen_machine_pv.c
+++ b/hw/xenpv/xen_machine_pv.c
@@ -25,15 +25,10 @@
#include "qemu/osdep.h"
#include "hw/hw.h"
#include "hw/boards.h"
-#include "hw/sysbus.h"
#include "hw/xen/xen_backend.h"
#include "xen_domainbuild.h"
#include "sysemu/block-backend.h"
-#define TYPE_XENSYSDEV "xensysdev"
-
-DeviceState *xen_sysdev;
-
static void xen_init_pv(MachineState *machine)
{
DriveInfo *dinfo;
@@ -72,9 +67,6 @@ static void xen_init_pv(MachineState *machine)
break;
}
- xen_sysdev = qdev_create(NULL, TYPE_XENSYSDEV);
- qdev_init_nofail(xen_sysdev);
-
xen_be_register("console", &xen_console_ops);
xen_be_register("vkbd", &xen_kbdmouse_ops);
xen_be_register("vfb", &xen_framebuffer_ops);
@@ -112,38 +104,6 @@ static void xen_init_pv(MachineState *machine)
xen_init_display(xen_domid);
}
-static int xen_sysdev_init(SysBusDevice *dev)
-{
- return 0;
-}
-
-static Property xen_sysdev_properties[] = {
- {/* end of property list */},
-};
-
-static void xen_sysdev_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
-
- k->init = xen_sysdev_init;
- dc->props = xen_sysdev_properties;
-}
-
-static const TypeInfo xensysdev_info = {
- .name = TYPE_XENSYSDEV,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(SysBusDevice),
- .class_init = xen_sysdev_class_init,
-};
-
-static void xenpv_register_types(void)
-{
- type_register_static(&xensysdev_info);
-}
-
-type_init(xenpv_register_types);
-
static void xenpv_machine_init(MachineClass *mc)
{
mc->desc = "Xen Para-virtualized PC";