diff options
Diffstat (limited to 'hw')
-rw-r--r-- | hw/acpi/tco.c | 11 | ||||
-rw-r--r-- | hw/acpi/trace-events | 4 | ||||
-rw-r--r-- | hw/core/qdev.c | 32 | ||||
-rw-r--r-- | hw/i386/pc.c | 7 | ||||
-rw-r--r-- | hw/ide/core.c | 1 | ||||
-rw-r--r-- | hw/ide/qdev.c | 1 | ||||
-rw-r--r-- | hw/scsi/scsi-disk.c | 28 |
7 files changed, 71 insertions, 13 deletions
diff --git a/hw/acpi/tco.c b/hw/acpi/tco.c index 05b9d7ba36..a9143963ab 100644 --- a/hw/acpi/tco.c +++ b/hw/acpi/tco.c @@ -12,6 +12,7 @@ #include "hw/i386/ich9.h" #include "hw/acpi/tco.h" +#include "trace.h" //#define DEBUG @@ -41,8 +42,11 @@ enum { static inline void tco_timer_reload(TCOIORegs *tr) { - tr->expire_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + - ((int64_t)(tr->tco.tmr & TCO_TMR_MASK) * TCO_TICK_NSEC); + int ticks = tr->tco.tmr & TCO_TMR_MASK; + int64_t nsec = (int64_t)ticks * TCO_TICK_NSEC; + + trace_tco_timer_reload(ticks, nsec / 1000000); + tr->expire_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + nsec; timer_mod(tr->tco_timer, tr->expire_time); } @@ -59,6 +63,9 @@ static void tco_timer_expired(void *opaque) ICH9LPCState *lpc = container_of(pm, ICH9LPCState, pm); uint32_t gcs = pci_get_long(lpc->chip_config + ICH9_CC_GCS); + trace_tco_timer_expired(tr->timeouts_no, + lpc->pin_strap.spkr_hi, + !!(gcs & ICH9_CC_GCS_NO_REBOOT)); tr->tco.rld = 0; tr->tco.sts1 |= TCO_TIMEOUT; if (++tr->timeouts_no == 2) { diff --git a/hw/acpi/trace-events b/hw/acpi/trace-events index e3b41e9df4..df0024f8b2 100644 --- a/hw/acpi/trace-events +++ b/hw/acpi/trace-events @@ -30,3 +30,7 @@ cpuhp_acpi_ejecting_invalid_cpu(uint32_t idx) "0x%"PRIx32 cpuhp_acpi_ejecting_cpu(uint32_t idx) "0x%"PRIx32 cpuhp_acpi_write_ost_ev(uint32_t slot, uint32_t ev) "idx[0x%"PRIx32"] OST EVENT: 0x%"PRIx32 cpuhp_acpi_write_ost_status(uint32_t slot, uint32_t st) "idx[0x%"PRIx32"] OST STATUS: 0x%"PRIx32 + +# hw/acpi/tco.c +tco_timer_reload(int ticks, int msec) "ticks=%d (%d ms)" +tco_timer_expired(int timeouts_no, bool strap, bool no_reboot) "timeouts_no=%d no_reboot=%d/%d" diff --git a/hw/core/qdev.c b/hw/core/qdev.c index 606ab53c42..11112951a5 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -928,6 +928,13 @@ static void device_set_realized(Object *obj, bool value, Error **errp) goto post_realize_fail; } + /* + * always free/re-initialize here since the value cannot be cleaned up + * in device_unrealize due to its usage later on in the unplug path + */ + g_free(dev->canonical_path); + dev->canonical_path = object_get_canonical_path(OBJECT(dev)); + if (qdev_get_vmsd(dev)) { if (vmstate_register_with_alias_id(dev, -1, qdev_get_vmsd(dev), dev, dev->instance_id_alias, @@ -984,6 +991,8 @@ child_realize_fail: } post_realize_fail: + g_free(dev->canonical_path); + dev->canonical_path = NULL; if (dc->unrealize) { dc->unrealize(dev, NULL); } @@ -1070,6 +1079,18 @@ static void device_finalize(Object *obj) * here */ } + + /* Only send event if the device had been completely realized */ + if (dev->pending_deleted_event) { + g_assert(dev->canonical_path); + + qapi_event_send_device_deleted(!!dev->id, dev->id, dev->canonical_path, + &error_abort); + g_free(dev->canonical_path); + dev->canonical_path = NULL; + } + + qemu_opts_del(dev->opts); } static void device_class_base_init(ObjectClass *class, void *data) @@ -1099,17 +1120,6 @@ static void device_unparent(Object *obj) object_unref(OBJECT(dev->parent_bus)); dev->parent_bus = NULL; } - - /* Only send event if the device had been completely realized */ - if (dev->pending_deleted_event) { - gchar *path = object_get_canonical_path(OBJECT(dev)); - - qapi_event_send_device_deleted(!!dev->id, dev->id, path, &error_abort); - g_free(path); - } - - qemu_opts_del(dev->opts); - dev->opts = NULL; } static void device_class_init(ObjectClass *class, void *data) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 05985d4927..8e307f7aff 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1876,8 +1876,15 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev, CPUArchId *cpu_slot; X86CPUTopoInfo topo; X86CPU *cpu = X86_CPU(dev); + MachineState *ms = MACHINE(hotplug_dev); PCMachineState *pcms = PC_MACHINE(hotplug_dev); + if(!object_dynamic_cast(OBJECT(cpu), ms->cpu_type)) { + error_setg(errp, "Invalid CPU type, expected cpu type: '%s'", + ms->cpu_type); + return; + } + /* if APIC ID is not set, set it based on socket/core/thread properties */ if (cpu->apic_id == UNASSIGNED_APIC_ID) { int max_socket = (max_cpus - 1) / smp_threads / smp_cores; diff --git a/hw/ide/core.c b/hw/ide/core.c index 5f1cd3b91f..a04766aee7 100644 --- a/hw/ide/core.c +++ b/hw/ide/core.c @@ -208,6 +208,7 @@ static void ide_identify(IDEState *s) if (dev && dev->conf.discard_granularity) { put_le16(p + 169, 1); /* TRIM support */ } + put_le16(p + 217, dev->rotation_rate); /* Nominal media rotation rate */ ide_identify_size(s); s->identify_set = 1; diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c index d60ac25be0..a5181b4448 100644 --- a/hw/ide/qdev.c +++ b/hw/ide/qdev.c @@ -299,6 +299,7 @@ static Property ide_hd_properties[] = { DEFINE_BLOCK_CHS_PROPERTIES(IDEDrive, dev.conf), DEFINE_PROP_BIOS_CHS_TRANS("bios-chs-trans", IDEDrive, dev.chs_trans, BIOS_ATA_TRANSLATION_AUTO), + DEFINE_PROP_UINT16("rotation_rate", IDEDrive, dev.rotation_rate, 0), DEFINE_PROP_END_OF_LIST(), }; diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c index 6e841fb5ff..12431177a7 100644 --- a/hw/scsi/scsi-disk.c +++ b/hw/scsi/scsi-disk.c @@ -104,6 +104,14 @@ typedef struct SCSIDiskState char *product; bool tray_open; bool tray_locked; + /* + * 0x0000 - rotation rate not reported + * 0x0001 - non-rotating medium (SSD) + * 0x0002-0x0400 - reserved + * 0x0401-0xffe - rotations per minute + * 0xffff - reserved + */ + uint16_t rotation_rate; } SCSIDiskState; static bool scsi_handle_rw_error(SCSIDiskReq *r, int error, bool acct_failed); @@ -605,6 +613,7 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf) outbuf[buflen++] = 0x83; // device identification if (s->qdev.type == TYPE_DISK) { outbuf[buflen++] = 0xb0; // block limits + outbuf[buflen++] = 0xb1; /* block device characteristics */ outbuf[buflen++] = 0xb2; // thin provisioning } break; @@ -747,6 +756,15 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf) outbuf[43] = max_io_sectors & 0xff; break; } + case 0xb1: /* block device characteristics */ + { + buflen = 8; + outbuf[4] = (s->rotation_rate >> 8) & 0xff; + outbuf[5] = s->rotation_rate & 0xff; + outbuf[6] = 0; + outbuf[7] = 0; + break; + } case 0xb2: /* thin provisioning */ { buflen = 8; @@ -2329,6 +2347,14 @@ static void scsi_realize(SCSIDevice *dev, Error **errp) blkconf_serial(&s->qdev.conf, &s->serial); blkconf_blocksizes(&s->qdev.conf); + + if (s->qdev.conf.logical_block_size > + s->qdev.conf.physical_block_size) { + error_setg(errp, + "logical_block_size > physical_block_size not supported"); + return; + } + if (dev->type == TYPE_DISK) { blkconf_geometry(&dev->conf, NULL, 65535, 255, 255, &err); if (err) { @@ -2911,6 +2937,7 @@ static Property scsi_hd_properties[] = { DEFAULT_MAX_UNMAP_SIZE), DEFINE_PROP_UINT64("max_io_size", SCSIDiskState, max_io_size, DEFAULT_MAX_IO_SIZE), + DEFINE_PROP_UINT16("rotation_rate", SCSIDiskState, rotation_rate, 0), DEFINE_BLOCK_CHS_PROPERTIES(SCSIDiskState, qdev.conf), DEFINE_PROP_END_OF_LIST(), }; @@ -2982,6 +3009,7 @@ static const TypeInfo scsi_cd_info = { static Property scsi_block_properties[] = { DEFINE_BLOCK_ERROR_PROPERTIES(SCSIDiskState, qdev.conf), \ DEFINE_PROP_DRIVE("drive", SCSIDiskState, qdev.conf.blk), + DEFINE_PROP_UINT16("rotation_rate", SCSIDiskState, rotation_rate, 0), DEFINE_PROP_END_OF_LIST(), }; |