summary refs log tree commit diff stats
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-rw-r--r--hw/alpha/dp264.c3
-rw-r--r--hw/audio/es1370.c10
-rw-r--r--hw/char/serial.c4
-rw-r--r--hw/char/sh_serial.c20
-rw-r--r--hw/char/virtio-serial-bus.c6
-rw-r--r--hw/core/loader.c5
-rw-r--r--hw/hppa/machine.c2
-rw-r--r--hw/i386/kvm/clock.c17
-rw-r--r--hw/i386/pc.c7
-rw-r--r--hw/ide/core.c3
-rw-r--r--hw/input/ps2.c8
-rw-r--r--hw/mips/mips_fulong2e.c6
-rw-r--r--hw/mips/mips_malta.c6
-rw-r--r--hw/mips/mips_mipssim.c3
-rw-r--r--hw/mips/mips_r4k.c6
-rw-r--r--hw/misc/debugexit.c6
-rw-r--r--hw/misc/edu.c5
-rw-r--r--hw/misc/hyperv_testdev.c10
-rw-r--r--hw/misc/pc-testdev.c20
-rw-r--r--hw/moxie/moxiesim.c2
-rw-r--r--hw/nvram/fw_cfg.c13
-rw-r--r--hw/scsi/lsi53c895a.c214
-rw-r--r--hw/scsi/mptendian.c163
-rw-r--r--hw/scsi/scsi-disk.c6
-rw-r--r--hw/scsi/trace-events62
-rw-r--r--hw/virtio/virtio.c8
26 files changed, 376 insertions, 239 deletions
diff --git a/hw/alpha/dp264.c b/hw/alpha/dp264.c
index 80b987f7fb..dd62f2a405 100644
--- a/hw/alpha/dp264.c
+++ b/hw/alpha/dp264.c
@@ -150,7 +150,8 @@ static void clipper_init(MachineState *machine)
         }
 
         if (initrd_filename) {
-            long initrd_base, initrd_size;
+            long initrd_base;
+            int64_t initrd_size;
 
             initrd_size = get_image_size(initrd_filename);
             if (initrd_size < 0) {
diff --git a/hw/audio/es1370.c b/hw/audio/es1370.c
index dd75c9e8f5..4f980a598b 100644
--- a/hw/audio/es1370.c
+++ b/hw/audio/es1370.c
@@ -506,10 +506,13 @@ static void es1370_write(void *opaque, hwaddr addr, uint64_t val, unsigned size)
                 d - &s->chan[0], val >> 16, (val & 0xffff));
         break;
 
+    case ES1370_REG_ADC_FRAMEADR:
+        d += 2;
+        goto frameadr;
     case ES1370_REG_DAC1_FRAMEADR:
     case ES1370_REG_DAC2_FRAMEADR:
-    case ES1370_REG_ADC_FRAMEADR:
         d += (addr - ES1370_REG_DAC1_FRAMEADR) >> 3;
+    frameadr:
         d->frame_addr = val;
         ldebug ("chan %td frame address %#x\n", d - &s->chan[0], val);
         break;
@@ -521,10 +524,13 @@ static void es1370_write(void *opaque, hwaddr addr, uint64_t val, unsigned size)
         lwarn ("writing to phantom frame address %#x\n", val);
         break;
 
+    case ES1370_REG_ADC_FRAMECNT:
+        d += 2;
+        goto framecnt;
     case ES1370_REG_DAC1_FRAMECNT:
     case ES1370_REG_DAC2_FRAMECNT:
-    case ES1370_REG_ADC_FRAMECNT:
         d += (addr - ES1370_REG_DAC1_FRAMECNT) >> 3;
+    framecnt:
         d->frame_cnt = val;
         d->leftover = 0;
         ldebug ("chan %td frame count %d, buffer size %d\n",
diff --git a/hw/char/serial.c b/hw/char/serial.c
index 251f40fdac..02463e3388 100644
--- a/hw/char/serial.c
+++ b/hw/char/serial.c
@@ -345,9 +345,9 @@ static void serial_ioport_write(void *opaque, hwaddr addr, uint64_t val,
     default:
     case 0:
         if (s->lcr & UART_LCR_DLAB) {
-            if (size == 2) {
+            if (size == 1) {
                 s->divider = (s->divider & 0xff00) | val;
-            } else if (size == 4) {
+            } else {
                 s->divider = val;
             }
             serial_update_parameters(s);
diff --git a/hw/char/sh_serial.c b/hw/char/sh_serial.c
index 373a40595f..12831561a6 100644
--- a/hw/char/sh_serial.c
+++ b/hw/char/sh_serial.c
@@ -29,6 +29,7 @@
 #include "hw/sh4/sh.h"
 #include "chardev/char-fe.h"
 #include "qapi/error.h"
+#include "qemu/timer.h"
 
 //#define DEBUG_SERIAL
 
@@ -63,6 +64,8 @@ typedef struct {
     int rtrg;
 
     CharBackend chr;
+    QEMUTimer *fifo_timeout_timer;
+    uint64_t etu; /* Elementary Time Unit (ns) */
 
     qemu_irq eri;
     qemu_irq rxi;
@@ -314,6 +317,16 @@ static int sh_serial_can_receive1(void *opaque)
     return sh_serial_can_receive(s);
 }
 
+static void sh_serial_timeout_int(void *opaque)
+{
+    sh_serial_state *s = opaque;
+
+    s->flags |= SH_SERIAL_FLAG_RDF;
+    if (s->scr & (1 << 6) && s->rxi) {
+        qemu_set_irq(s->rxi, 1);
+    }
+}
+
 static void sh_serial_receive1(void *opaque, const uint8_t *buf, int size)
 {
     sh_serial_state *s = opaque;
@@ -330,8 +343,12 @@ static void sh_serial_receive1(void *opaque, const uint8_t *buf, int size)
                 if (s->rx_cnt >= s->rtrg) {
                     s->flags |= SH_SERIAL_FLAG_RDF;
                     if (s->scr & (1 << 6) && s->rxi) {
+                        timer_del(s->fifo_timeout_timer);
                         qemu_set_irq(s->rxi, 1);
                     }
+                } else {
+                    timer_mod(s->fifo_timeout_timer,
+                        qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + 15 * s->etu);
                 }
             }
         }
@@ -402,6 +419,9 @@ void sh_serial_init(MemoryRegion *sysmem,
                                  sh_serial_event, NULL, s, NULL, true);
     }
 
+    s->fifo_timeout_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
+                                         sh_serial_timeout_int, s);
+    s->etu = NANOSECONDS_PER_SECOND / 9600;
     s->eri = eri_source;
     s->rxi = rxi_source;
     s->txi = txi_source;
diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c
index d2dd8ab502..04e3ebe352 100644
--- a/hw/char/virtio-serial-bus.c
+++ b/hw/char/virtio-serial-bus.c
@@ -667,9 +667,9 @@ static void virtio_serial_save_device(VirtIODevice *vdev, QEMUFile *f)
 
     /* The config space (ignored on the far end in current versions) */
     get_config(vdev, (uint8_t *)&config);
-    qemu_put_be16s(f, &config.cols);
-    qemu_put_be16s(f, &config.rows);
-    qemu_put_be32s(f, &config.max_nr_ports);
+    qemu_put_be16(f, config.cols);
+    qemu_put_be16(f, config.rows);
+    qemu_put_be32(f, config.max_nr_ports);
 
     /* The ports map */
     max_nr_ports = s->serial.max_virtserial_ports;
diff --git a/hw/core/loader.c b/hw/core/loader.c
index 390987a05c..aa0b3fc867 100644
--- a/hw/core/loader.c
+++ b/hw/core/loader.c
@@ -61,9 +61,10 @@
 static int roms_loaded;
 
 /* return the size or -1 if error */
-int get_image_size(const char *filename)
+int64_t get_image_size(const char *filename)
 {
-    int fd, size;
+    int fd;
+    int64_t size;
     fd = open(filename, O_RDONLY | O_BINARY);
     if (fd < 0)
         return -1;
diff --git a/hw/hppa/machine.c b/hw/hppa/machine.c
index 0fb8fb877e..ac6dd7f6ab 100644
--- a/hw/hppa/machine.c
+++ b/hw/hppa/machine.c
@@ -191,7 +191,7 @@ static void machine_hppa_init(MachineState *machine)
 
         if (initrd_filename) {
             ram_addr_t initrd_base;
-            long initrd_size;
+            int64_t initrd_size;
 
             initrd_size = get_image_size(initrd_filename);
             if (initrd_size < 0) {
diff --git a/hw/i386/kvm/clock.c b/hw/i386/kvm/clock.c
index 0bf1c60a06..25ea783bec 100644
--- a/hw/i386/kvm/clock.c
+++ b/hw/i386/kvm/clock.c
@@ -147,6 +147,15 @@ static void kvm_update_clock(KVMClockState *s)
     s->clock_is_reliable = kvm_has_adjust_clock_stable();
 }
 
+static void do_kvmclock_ctrl(CPUState *cpu, run_on_cpu_data data)
+{
+    int ret = kvm_vcpu_ioctl(cpu, KVM_KVMCLOCK_CTRL, 0);
+
+    if (ret && ret != -EINVAL) {
+        fprintf(stderr, "%s: %s\n", __func__, strerror(-ret));
+    }
+}
+
 static void kvmclock_vm_state_change(void *opaque, int running,
                                      RunState state)
 {
@@ -183,13 +192,7 @@ static void kvmclock_vm_state_change(void *opaque, int running,
             return;
         }
         CPU_FOREACH(cpu) {
-            ret = kvm_vcpu_ioctl(cpu, KVM_KVMCLOCK_CTRL, 0);
-            if (ret) {
-                if (ret != -EINVAL) {
-                    fprintf(stderr, "%s: %s\n", __func__, strerror(-ret));
-                }
-                return;
-            }
+            run_on_cpu(cpu, do_kvmclock_ctrl, RUN_ON_CPU_NULL);
         }
     } else {
 
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 03148450c8..cd5029c149 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -838,7 +838,8 @@ static void load_linux(PCMachineState *pcms,
                        FWCfgState *fw_cfg)
 {
     uint16_t protocol;
-    int setup_size, kernel_size, initrd_size = 0, cmdline_size;
+    int setup_size, kernel_size, cmdline_size;
+    int64_t initrd_size = 0;
     int dtb_size, setup_data_offset;
     uint32_t initrd_max;
     uint8_t header[8192], *setup, *kernel, *initrd_data;
@@ -974,6 +975,10 @@ static void load_linux(PCMachineState *pcms,
             fprintf(stderr, "qemu: error reading initrd %s: %s\n",
                     initrd_filename, strerror(errno));
             exit(1);
+        } else if (initrd_size >= initrd_max) {
+            fprintf(stderr, "qemu: initrd is too large, cannot support."
+                    "(max: %"PRIu32", need %"PRId64")\n", initrd_max, initrd_size);
+            exit(1);
         }
 
         initrd_addr = (initrd_max-initrd_size) & ~4095;
diff --git a/hw/ide/core.c b/hw/ide/core.c
index 2c62efc536..04e22e751d 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -35,6 +35,7 @@
 #include "sysemu/block-backend.h"
 #include "qapi/error.h"
 #include "qemu/cutils.h"
+#include "sysemu/replay.h"
 
 #include "hw/ide/internal.h"
 #include "trace.h"
@@ -479,7 +480,7 @@ static void ide_issue_trim_cb(void *opaque, int ret)
 done:
     iocb->aiocb = NULL;
     if (iocb->bh) {
-        qemu_bh_schedule(iocb->bh);
+        replay_bh_schedule_event(iocb->bh);
     }
 }
 
diff --git a/hw/input/ps2.c b/hw/input/ps2.c
index fdfcadf9a1..6c43fc2912 100644
--- a/hw/input/ps2.c
+++ b/hw/input/ps2.c
@@ -914,7 +914,12 @@ static void ps2_common_post_load(PS2State *s)
     uint8_t tmp_data[PS2_QUEUE_SIZE];
 
     /* set the useful data buffer queue size, < PS2_QUEUE_SIZE */
-    size = (q->count < 0 || q->count > PS2_QUEUE_SIZE) ? 0 : q->count;
+    size = q->count;
+    if (q->count < 0) {
+        size = 0;
+    } else if (q->count > PS2_QUEUE_SIZE) {
+        size = PS2_QUEUE_SIZE;
+    }
 
     /* move the queue elements to the start of data array */
     for (i = 0; i < size; i++) {
@@ -929,7 +934,6 @@ static void ps2_common_post_load(PS2State *s)
     q->rptr = 0;
     q->wptr = (size == PS2_QUEUE_SIZE) ? 0 : size;
     q->count = size;
-    s->update_irq(s->update_arg, q->count != 0);
 }
 
 static void ps2_kbd_reset(void *opaque)
diff --git a/hw/mips/mips_fulong2e.c b/hw/mips/mips_fulong2e.c
index c1694c8254..2fbba32c48 100644
--- a/hw/mips/mips_fulong2e.c
+++ b/hw/mips/mips_fulong2e.c
@@ -104,9 +104,9 @@ static void GCC_FMT_ATTR(3, 4) prom_set(uint32_t* prom_buf, int index,
 
 static int64_t load_kernel (CPUMIPSState *env)
 {
-    int64_t kernel_entry, kernel_low, kernel_high;
+    int64_t kernel_entry, kernel_low, kernel_high, initrd_size;
     int index = 0;
-    long kernel_size, initrd_size;
+    long kernel_size;
     ram_addr_t initrd_offset;
     uint32_t *prom_buf;
     long prom_size;
@@ -150,7 +150,7 @@ static int64_t load_kernel (CPUMIPSState *env)
 
     prom_set(prom_buf, index++, "%s", loaderparams.kernel_filename);
     if (initrd_size > 0) {
-        prom_set(prom_buf, index++, "rd_start=0x%" PRIx64 " rd_size=%li %s",
+        prom_set(prom_buf, index++, "rd_start=0x%" PRIx64 " rd_size=%" PRId64 " %s",
                  cpu_mips_phys_to_kseg0(NULL, initrd_offset), initrd_size,
                  loaderparams.kernel_cmdline);
     } else {
diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
index 40041d5ec0..29b90bacf3 100644
--- a/hw/mips/mips_malta.c
+++ b/hw/mips/mips_malta.c
@@ -995,8 +995,8 @@ static void GCC_FMT_ATTR(3, 4) prom_set(uint32_t* prom_buf, int index,
 /* Kernel */
 static int64_t load_kernel (void)
 {
-    int64_t kernel_entry, kernel_high;
-    long kernel_size, initrd_size;
+    int64_t kernel_entry, kernel_high, initrd_size;
+    long kernel_size;
     ram_addr_t initrd_offset;
     int big_endian;
     uint32_t *prom_buf;
@@ -1070,7 +1070,7 @@ static int64_t load_kernel (void)
 
     prom_set(prom_buf, prom_index++, "%s", loaderparams.kernel_filename);
     if (initrd_size > 0) {
-        prom_set(prom_buf, prom_index++, "rd_start=0x%" PRIx64 " rd_size=%li %s",
+        prom_set(prom_buf, prom_index++, "rd_start=0x%" PRIx64 " rd_size=%" PRId64 " %s",
                  xlate_to_kseg0(NULL, initrd_offset), initrd_size,
                  loaderparams.kernel_cmdline);
     } else {
diff --git a/hw/mips/mips_mipssim.c b/hw/mips/mips_mipssim.c
index 241faa1d0f..f665752a2f 100644
--- a/hw/mips/mips_mipssim.c
+++ b/hw/mips/mips_mipssim.c
@@ -58,9 +58,8 @@ typedef struct ResetData {
 
 static int64_t load_kernel(void)
 {
-    int64_t entry, kernel_high;
+    int64_t entry, kernel_high, initrd_size;
     long kernel_size;
-    long initrd_size;
     ram_addr_t initrd_offset;
     int big_endian;
 
diff --git a/hw/mips/mips_r4k.c b/hw/mips/mips_r4k.c
index d5725d0555..3e852e98cf 100644
--- a/hw/mips/mips_r4k.c
+++ b/hw/mips/mips_r4k.c
@@ -81,8 +81,8 @@ typedef struct ResetData {
 static int64_t load_kernel(void)
 {
     const size_t params_size = 264;
-    int64_t entry, kernel_high;
-    long kernel_size, initrd_size;
+    int64_t entry, kernel_high, initrd_size;
+    long kernel_size;
     ram_addr_t initrd_offset;
     uint32_t *params_buf;
     int big_endian;
@@ -136,7 +136,7 @@ static int64_t load_kernel(void)
     params_buf[1] = tswap32(0x12345678);
 
     if (initrd_size > 0) {
-        snprintf((char *)params_buf + 8, 256, "rd_start=0x%" PRIx64 " rd_size=%li %s",
+        snprintf((char *)params_buf + 8, 256, "rd_start=0x%" PRIx64 " rd_size=%" PRId64 " %s",
                  cpu_mips_phys_to_kseg0(NULL, initrd_offset),
                  initrd_size, loaderparams.kernel_cmdline);
     } else {
diff --git a/hw/misc/debugexit.c b/hw/misc/debugexit.c
index 84fa1a5b9d..bed293247e 100644
--- a/hw/misc/debugexit.c
+++ b/hw/misc/debugexit.c
@@ -23,6 +23,11 @@ typedef struct ISADebugExitState {
     MemoryRegion io;
 } ISADebugExitState;
 
+static uint64_t debug_exit_read(void *opaque, hwaddr addr, unsigned size)
+{
+    return 0;
+}
+
 static void debug_exit_write(void *opaque, hwaddr addr, uint64_t val,
                              unsigned width)
 {
@@ -30,6 +35,7 @@ static void debug_exit_write(void *opaque, hwaddr addr, uint64_t val,
 }
 
 static const MemoryRegionOps debug_exit_ops = {
+    .read = debug_exit_read,
     .write = debug_exit_write,
     .valid.min_access_size = 1,
     .valid.max_access_size = 4,
diff --git a/hw/misc/edu.c b/hw/misc/edu.c
index df26a4d046..0687ffd343 100644
--- a/hw/misc/edu.c
+++ b/hw/misc/edu.c
@@ -30,7 +30,8 @@
 #include "qemu/main-loop.h" /* iothread mutex */
 #include "qapi/visitor.h"
 
-#define EDU(obj)        OBJECT_CHECK(EduState, obj, "edu")
+#define TYPE_PCI_EDU_DEVICE "edu"
+#define EDU(obj)        OBJECT_CHECK(EduState, obj, TYPE_PCI_EDU_DEVICE)
 
 #define FACT_IRQ        0x00000001
 #define DMA_IRQ         0x00000100
@@ -414,7 +415,7 @@ static void pci_edu_register_types(void)
         { },
     };
     static const TypeInfo edu_info = {
-        .name          = "edu",
+        .name          = TYPE_PCI_EDU_DEVICE,
         .parent        = TYPE_PCI_DEVICE,
         .instance_size = sizeof(EduState),
         .instance_init = edu_instance_init,
diff --git a/hw/misc/hyperv_testdev.c b/hw/misc/hyperv_testdev.c
index bf6bbfa8cf..7549f470b1 100644
--- a/hw/misc/hyperv_testdev.c
+++ b/hw/misc/hyperv_testdev.c
@@ -105,7 +105,12 @@ static void hv_synic_test_dev_control(HypervTestDev *dev, uint32_t ctl,
     }
 }
 
-static void hv_test_dev_control(void *opaque, hwaddr addr, uint64_t data,
+static uint64_t hv_test_dev_read(void *opaque, hwaddr addr, unsigned size)
+{
+    return 0;
+}
+
+static void hv_test_dev_write(void *opaque, hwaddr addr, uint64_t data,
                                 uint32_t len)
 {
     HypervTestDev *dev = HYPERV_TEST_DEV(opaque);
@@ -127,7 +132,8 @@ static void hv_test_dev_control(void *opaque, hwaddr addr, uint64_t data,
 }
 
 static const MemoryRegionOps synic_test_sint_ops = {
-    .write = hv_test_dev_control,
+    .read = hv_test_dev_read,
+    .write = hv_test_dev_write,
     .valid.min_access_size = 4,
     .valid.max_access_size = 4,
     .endianness = DEVICE_LITTLE_ENDIAN,
diff --git a/hw/misc/pc-testdev.c b/hw/misc/pc-testdev.c
index b81d820084..697eb88c97 100644
--- a/hw/misc/pc-testdev.c
+++ b/hw/misc/pc-testdev.c
@@ -58,7 +58,12 @@ typedef struct PCTestdev {
 #define TESTDEV(obj) \
      OBJECT_CHECK(PCTestdev, (obj), TYPE_TESTDEV)
 
-static void test_irq_line(void *opaque, hwaddr addr, uint64_t data,
+static uint64_t test_irq_line_read(void *opaque, hwaddr addr, unsigned size)
+{
+    return 0;
+}
+
+static void test_irq_line_write(void *opaque, hwaddr addr, uint64_t data,
                           unsigned len)
 {
     PCTestdev *dev = opaque;
@@ -68,7 +73,8 @@ static void test_irq_line(void *opaque, hwaddr addr, uint64_t data,
 }
 
 static const MemoryRegionOps test_irq_ops = {
-    .write = test_irq_line,
+    .read = test_irq_line_read,
+    .write = test_irq_line_write,
     .valid.min_access_size = 1,
     .valid.max_access_size = 1,
     .endianness = DEVICE_LITTLE_ENDIAN,
@@ -110,7 +116,12 @@ static const MemoryRegionOps test_ioport_byte_ops = {
     .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
-static void test_flush_page(void *opaque, hwaddr addr, uint64_t data,
+static uint64_t test_flush_page_read(void *opaque, hwaddr addr, unsigned size)
+{
+    return 0;
+}
+
+static void test_flush_page_write(void *opaque, hwaddr addr, uint64_t data,
                             unsigned len)
 {
     hwaddr page = 4096;
@@ -126,7 +137,8 @@ static void test_flush_page(void *opaque, hwaddr addr, uint64_t data,
 }
 
 static const MemoryRegionOps test_flush_ops = {
-    .write = test_flush_page,
+    .read = test_flush_page_read,
+    .write = test_flush_page_write,
     .valid.min_access_size = 4,
     .valid.max_access_size = 4,
     .endianness = DEVICE_LITTLE_ENDIAN,
diff --git a/hw/moxie/moxiesim.c b/hw/moxie/moxiesim.c
index d41247dbdc..4b0ce09c5e 100644
--- a/hw/moxie/moxiesim.c
+++ b/hw/moxie/moxiesim.c
@@ -54,8 +54,8 @@ typedef struct {
 static void load_kernel(MoxieCPU *cpu, LoaderParams *loader_params)
 {
     uint64_t entry, kernel_low, kernel_high;
+    int64_t initrd_size;
     long kernel_size;
-    long initrd_size;
     ram_addr_t initrd_offset;
 
     kernel_size = load_elf(loader_params->kernel_filename,  NULL, NULL,
diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c
index d79a568f54..946f765f7f 100644
--- a/hw/nvram/fw_cfg.c
+++ b/hw/nvram/fw_cfg.c
@@ -434,6 +434,11 @@ static bool fw_cfg_data_mem_valid(void *opaque, hwaddr addr,
     return addr == 0;
 }
 
+static uint64_t fw_cfg_ctl_mem_read(void *opaque, hwaddr addr, unsigned size)
+{
+    return 0;
+}
+
 static void fw_cfg_ctl_mem_write(void *opaque, hwaddr addr,
                                  uint64_t value, unsigned size)
 {
@@ -468,6 +473,7 @@ static bool fw_cfg_comb_valid(void *opaque, hwaddr addr,
 }
 
 static const MemoryRegionOps fw_cfg_ctl_mem_ops = {
+    .read = fw_cfg_ctl_mem_read,
     .write = fw_cfg_ctl_mem_write,
     .endianness = DEVICE_BIG_ENDIAN,
     .valid.accepts = fw_cfg_ctl_mem_valid,
@@ -1109,12 +1115,7 @@ static void fw_cfg_mem_realize(DeviceState *dev, Error **errp)
     sysbus_init_mmio(sbd, &s->ctl_iomem);
 
     if (s->data_width > data_ops->valid.max_access_size) {
-        /* memberwise copy because the "old_mmio" member is const */
-        s->wide_data_ops.read       = data_ops->read;
-        s->wide_data_ops.write      = data_ops->write;
-        s->wide_data_ops.endianness = data_ops->endianness;
-        s->wide_data_ops.valid      = data_ops->valid;
-        s->wide_data_ops.impl       = data_ops->impl;
+        s->wide_data_ops = *data_ops;
 
         s->wide_data_ops.valid.max_access_size = s->data_width;
         s->wide_data_ops.impl.max_access_size  = s->data_width;
diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c
index 996b40650d..d1e6534311 100644
--- a/hw/scsi/lsi53c895a.c
+++ b/hw/scsi/lsi53c895a.c
@@ -20,20 +20,7 @@
 #include "hw/scsi/scsi.h"
 #include "sysemu/dma.h"
 #include "qemu/log.h"
-
-//#define DEBUG_LSI
-//#define DEBUG_LSI_REG
-
-#ifdef DEBUG_LSI
-#define DPRINTF(fmt, ...) \
-do { printf("lsi_scsi: " fmt , ## __VA_ARGS__); } while (0)
-#define BADF(fmt, ...) \
-do { fprintf(stderr, "lsi_scsi: error: " fmt , ## __VA_ARGS__); exit(1);} while (0)
-#else
-#define DPRINTF(fmt, ...) do {} while(0)
-#define BADF(fmt, ...) \
-do { fprintf(stderr, "lsi_scsi: error: " fmt , ## __VA_ARGS__);} while (0)
-#endif
+#include "trace.h"
 
 static const char *names[] = {
     "SCNTL0", "SCNTL1", "SCNTL2", "SCNTL3", "SCID", "SXFER", "SDID", "GPREG",
@@ -313,7 +300,7 @@ static inline int lsi_irq_on_rsl(LSIState *s)
 
 static void lsi_soft_reset(LSIState *s)
 {
-    DPRINTF("Reset\n");
+    trace_lsi_reset();
     s->carry = 0;
 
     s->msg_action = 0;
@@ -484,15 +471,13 @@ static void lsi_update_irq(LSIState *s)
         level = 1;
 
     if (level != last_level) {
-        DPRINTF("Update IRQ level %d dstat %02x sist %02x%02x\n",
-                level, s->dstat, s->sist1, s->sist0);
+        trace_lsi_update_irq(level, s->dstat, s->sist1, s->sist0);
         last_level = level;
     }
     lsi_set_irq(s, level);
 
     if (!level && lsi_irq_on_rsl(s) && !(s->scntl1 & LSI_SCNTL1_CON)) {
-        DPRINTF("Handled IRQs & disconnected, looking for pending "
-                "processes\n");
+        trace_lsi_update_irq_disconnected();
         QTAILQ_FOREACH(p, &s->queue, next) {
             if (p->pending) {
                 lsi_reselect(s, p);
@@ -508,8 +493,7 @@ static void lsi_script_scsi_interrupt(LSIState *s, int stat0, int stat1)
     uint32_t mask0;
     uint32_t mask1;
 
-    DPRINTF("SCSI Interrupt 0x%02x%02x prev 0x%02x%02x\n",
-            stat1, stat0, s->sist1, s->sist0);
+    trace_lsi_script_scsi_interrupt(stat1, stat0, s->sist1, s->sist0);
     s->sist0 |= stat0;
     s->sist1 |= stat1;
     /* Stop processor on fatal or unmasked interrupt.  As a special hack
@@ -527,7 +511,7 @@ static void lsi_script_scsi_interrupt(LSIState *s, int stat0, int stat1)
 /* Stop SCRIPTS execution and raise a DMA interrupt.  */
 static void lsi_script_dma_interrupt(LSIState *s, int stat)
 {
-    DPRINTF("DMA Interrupt 0x%x prev 0x%x\n", stat, s->dstat);
+    trace_lsi_script_dma_interrupt(stat, s->dstat);
     s->dstat |= stat;
     lsi_update_irq(s);
     lsi_stop_script(s);
@@ -547,9 +531,9 @@ static void lsi_bad_phase(LSIState *s, int out, int new_phase)
         } else {
             s->dsp = (s->scntl2 & LSI_SCNTL2_WSR ? s->pmjad2 : s->pmjad1);
         }
-        DPRINTF("Data phase mismatch jump to %08x\n", s->dsp);
+        trace_lsi_bad_phase_jump(s->dsp);
     } else {
-        DPRINTF("Phase mismatch interrupt\n");
+        trace_lsi_bad_phase_interrupt();
         lsi_script_scsi_interrupt(s, LSI_SIST0_MA, 0);
         lsi_stop_script(s);
     }
@@ -576,7 +560,7 @@ static void lsi_disconnect(LSIState *s)
 
 static void lsi_bad_selection(LSIState *s, uint32_t id)
 {
-    DPRINTF("Selected absent target %d\n", id);
+    trace_lsi_bad_selection(id);
     lsi_script_scsi_interrupt(s, 0, LSI_SIST1_STO);
     lsi_disconnect(s);
 }
@@ -591,7 +575,7 @@ static void lsi_do_dma(LSIState *s, int out)
     assert(s->current);
     if (!s->current->dma_len) {
         /* Wait until data is available.  */
-        DPRINTF("DMA no data available\n");
+        trace_lsi_do_dma_unavailable();
         return;
     }
 
@@ -611,7 +595,7 @@ static void lsi_do_dma(LSIState *s, int out)
     else if (s->sbms)
         addr |= ((uint64_t)s->sbms << 32);
 
-    DPRINTF("DMA addr=0x" DMA_ADDR_FMT " len=%d\n", addr, count);
+    trace_lsi_do_dma(addr, count);
     s->csbc += count;
     s->dnad += count;
     s->dbc -= count;
@@ -640,7 +624,7 @@ static void lsi_queue_command(LSIState *s)
 {
     lsi_request *p = s->current;
 
-    DPRINTF("Queueing tag=0x%x\n", p->tag);
+    trace_lsi_queue_command(p->tag);
     assert(s->current != NULL);
     assert(s->current->dma_len == 0);
     QTAILQ_INSERT_TAIL(&s->queue, s->current, next);
@@ -654,9 +638,9 @@ static void lsi_queue_command(LSIState *s)
 static void lsi_add_msg_byte(LSIState *s, uint8_t data)
 {
     if (s->msg_len >= LSI_MAX_MSGIN_LEN) {
-        BADF("MSG IN data too long\n");
+        trace_lsi_add_msg_byte_error();
     } else {
-        DPRINTF("MSG IN 0x%02x\n", data);
+        trace_lsi_add_msg_byte(data);
         s->msg[s->msg_len++] = data;
     }
 }
@@ -676,7 +660,7 @@ static void lsi_reselect(LSIState *s, lsi_request *p)
     if (!(s->dcntl & LSI_DCNTL_COM)) {
         s->sfbr = 1 << (id & 0x7);
     }
-    DPRINTF("Reselected target %d\n", id);
+    trace_lsi_reselect(id);
     s->scntl1 |= LSI_SCNTL1_CON;
     lsi_set_phase(s, PHASE_MI);
     s->msg_action = p->out ? 2 : 3;
@@ -732,7 +716,7 @@ static int lsi_queue_req(LSIState *s, SCSIRequest *req, uint32_t len)
     lsi_request *p = req->hba_private;
 
     if (p->pending) {
-        BADF("Multiple IO pending for request %p\n", p);
+        trace_lsi_queue_req_error(p);
     }
     p->pending = len;
     /* Reselect if waiting for it, or if reselection triggers an IRQ
@@ -747,7 +731,7 @@ static int lsi_queue_req(LSIState *s, SCSIRequest *req, uint32_t len)
         lsi_reselect(s, p);
         return 0;
     } else {
-        DPRINTF("Queueing IO tag=0x%x\n", p->tag);
+        trace_lsi_queue_req(p->tag);
         p->pending = len;
         return 1;
     }
@@ -760,7 +744,7 @@ static void lsi_command_complete(SCSIRequest *req, uint32_t status, size_t resid
     int out;
 
     out = (s->sstat1 & PHASE_MASK) == PHASE_DO;
-    DPRINTF("Command complete status=%d\n", (int)status);
+    trace_lsi_command_complete(status);
     s->status = status;
     s->command_complete = 2;
     if (s->waiting && s->dbc != 0) {
@@ -795,7 +779,7 @@ static void lsi_transfer_data(SCSIRequest *req, uint32_t len)
     out = (s->sstat1 & PHASE_MASK) == PHASE_DO;
 
     /* host adapter (re)connected */
-    DPRINTF("Data ready tag=0x%x len=%d\n", req->tag, len);
+    trace_lsi_transfer_data(req->tag, len);
     s->current->dma_len = len;
     s->command_complete = 1;
     if (s->waiting) {
@@ -814,7 +798,7 @@ static void lsi_do_command(LSIState *s)
     uint32_t id;
     int n;
 
-    DPRINTF("Send command len=%d\n", s->dbc);
+    trace_lsi_do_command(s->dbc);
     if (s->dbc > 16)
         s->dbc = 16;
     pci_dma_read(PCI_DEVICE(s), s->dnad, buf, s->dbc);
@@ -862,9 +846,10 @@ static void lsi_do_command(LSIState *s)
 static void lsi_do_status(LSIState *s)
 {
     uint8_t status;
-    DPRINTF("Get status len=%d status=%d\n", s->dbc, s->status);
-    if (s->dbc != 1)
-        BADF("Bad Status move\n");
+    trace_lsi_do_status(s->dbc, s->status);
+    if (s->dbc != 1) {
+        trace_lsi_do_status_error();
+    }
     s->dbc = 1;
     status = s->status;
     s->sfbr = status;
@@ -877,7 +862,7 @@ static void lsi_do_status(LSIState *s)
 static void lsi_do_msgin(LSIState *s)
 {
     int len;
-    DPRINTF("Message in len=%d/%d\n", s->dbc, s->msg_len);
+    trace_lsi_do_msgin(s->dbc, s->msg_len);
     s->sfbr = s->msg[0];
     len = s->msg_len;
     if (len > s->dbc)
@@ -942,36 +927,36 @@ static void lsi_do_msgout(LSIState *s)
         current_req = lsi_find_by_tag(s, current_tag);
     }
 
-    DPRINTF("MSG out len=%d\n", s->dbc);
+    trace_lsi_do_msgout(s->dbc);
     while (s->dbc) {
         msg = lsi_get_msgbyte(s);
         s->sfbr = msg;
 
         switch (msg) {
         case 0x04:
-            DPRINTF("MSG: Disconnect\n");
+            trace_lsi_do_msgout_disconnect();
             lsi_disconnect(s);
             break;
         case 0x08:
-            DPRINTF("MSG: No Operation\n");
+            trace_lsi_do_msgout_noop();
             lsi_set_phase(s, PHASE_CMD);
             break;
         case 0x01:
             len = lsi_get_msgbyte(s);
             msg = lsi_get_msgbyte(s);
             (void)len; /* avoid a warning about unused variable*/
-            DPRINTF("Extended message 0x%x (len %d)\n", msg, len);
+            trace_lsi_do_msgout_extended(msg, len);
             switch (msg) {
             case 1:
-                DPRINTF("SDTR (ignored)\n");
+                trace_lsi_do_msgout_ignored("SDTR");
                 lsi_skip_msgbytes(s, 2);
                 break;
             case 3:
-                DPRINTF("WDTR (ignored)\n");
+                trace_lsi_do_msgout_ignored("WDTR");
                 lsi_skip_msgbytes(s, 1);
                 break;
             case 4:
-                DPRINTF("PPR (ignored)\n");
+                trace_lsi_do_msgout_ignored("PPR");
                 lsi_skip_msgbytes(s, 5);
                 break;
             default:
@@ -980,19 +965,20 @@ static void lsi_do_msgout(LSIState *s)
             break;
         case 0x20: /* SIMPLE queue */
             s->select_tag |= lsi_get_msgbyte(s) | LSI_TAG_VALID;
-            DPRINTF("SIMPLE queue tag=0x%x\n", s->select_tag & 0xff);
+            trace_lsi_do_msgout_simplequeue(s->select_tag & 0xff);
             break;
         case 0x21: /* HEAD of queue */
-            BADF("HEAD queue not implemented\n");
+            qemu_log_mask(LOG_UNIMP, "lsi_scsi: HEAD queue not implemented\n");
             s->select_tag |= lsi_get_msgbyte(s) | LSI_TAG_VALID;
             break;
         case 0x22: /* ORDERED queue */
-            BADF("ORDERED queue not implemented\n");
+            qemu_log_mask(LOG_UNIMP,
+                          "lsi_scsi: ORDERED queue not implemented\n");
             s->select_tag |= lsi_get_msgbyte(s) | LSI_TAG_VALID;
             break;
         case 0x0d:
             /* The ABORT TAG message clears the current I/O process only. */
-            DPRINTF("MSG: ABORT TAG tag=0x%x\n", current_tag);
+            trace_lsi_do_msgout_abort(current_tag);
             if (current_req) {
                 scsi_req_cancel(current_req->req);
             }
@@ -1004,17 +990,17 @@ static void lsi_do_msgout(LSIState *s)
             /* The ABORT message clears all I/O processes for the selecting
                initiator on the specified logical unit of the target. */
             if (msg == 0x06) {
-                DPRINTF("MSG: ABORT tag=0x%x\n", current_tag);
+                trace_lsi_do_msgout_abort(current_tag);
             }
             /* The CLEAR QUEUE message clears all I/O processes for all
                initiators on the specified logical unit of the target. */
             if (msg == 0x0e) {
-                DPRINTF("MSG: CLEAR QUEUE tag=0x%x\n", current_tag);
+                trace_lsi_do_msgout_clearqueue(current_tag);
             }
             /* The BUS DEVICE RESET message clears all I/O processes for all
                initiators on all logical units of the target. */
             if (msg == 0x0c) {
-                DPRINTF("MSG: BUS DEVICE RESET tag=0x%x\n", current_tag);
+                trace_lsi_do_msgout_busdevicereset(current_tag);
             }
 
             /* clear the current I/O process */
@@ -1042,14 +1028,14 @@ static void lsi_do_msgout(LSIState *s)
                 goto bad;
             }
             s->current_lun = msg & 7;
-            DPRINTF("Select LUN %d\n", s->current_lun);
+            trace_lsi_do_msgout_select(s->current_lun);
             lsi_set_phase(s, PHASE_CMD);
             break;
         }
     }
     return;
 bad:
-    BADF("Unimplemented message 0x%02x\n", msg);
+    qemu_log_mask(LOG_UNIMP, "Unimplemented message 0x%02x\n", msg);
     lsi_set_phase(s, PHASE_MI);
     lsi_add_msg_byte(s, 7); /* MESSAGE REJECT */
     s->msg_action = 0;
@@ -1061,7 +1047,7 @@ static void lsi_memcpy(LSIState *s, uint32_t dest, uint32_t src, int count)
     int n;
     uint8_t buf[LSI_BUF_SIZE];
 
-    DPRINTF("memcpy dest 0x%08x src 0x%08x count %d\n", dest, src, count);
+    trace_lsi_memcpy(dest, src, count);
     while (count) {
         n = (count > LSI_BUF_SIZE) ? LSI_BUF_SIZE : count;
         lsi_mem_read(s, src, buf, n);
@@ -1076,7 +1062,7 @@ static void lsi_wait_reselect(LSIState *s)
 {
     lsi_request *p;
 
-    DPRINTF("Wait Reselect\n");
+    trace_lsi_wait_reselect();
 
     QTAILQ_FOREACH(p, &s->queue, next) {
         if (p->pending) {
@@ -1109,14 +1095,14 @@ again:
     }
     addr = read_dword(s, s->dsp + 4);
     addr_high = 0;
-    DPRINTF("SCRIPTS dsp=%08x opcode %08x arg %08x\n", s->dsp, insn, addr);
+    trace_lsi_execute_script(s->dsp, insn, addr);
     s->dsps = addr;
     s->dcmd = insn >> 24;
     s->dsp += 8;
     switch (insn >> 30) {
     case 0: /* Block move.  */
         if (s->sist1 & LSI_SIST1_STO) {
-            DPRINTF("Delayed select timeout\n");
+            trace_lsi_execute_script_blockmove_delayed();
             lsi_stop_script(s);
             break;
         }
@@ -1171,8 +1157,9 @@ again:
                     addr_high = s->dbms;
                     break;
                 default:
-                    BADF("Illegal selector specified (0x%x > 0x15)"
-                         " for 64-bit DMA block move", selector);
+                    qemu_log_mask(LOG_GUEST_ERROR,
+                          "lsi_scsi: Illegal selector specified (0x%x > 0x15) "
+                          "for 64-bit DMA block move", selector);
                     break;
                 }
             }
@@ -1184,8 +1171,8 @@ again:
             s->ia = s->dsp - 12;
         }
         if ((s->sstat1 & PHASE_MASK) != ((insn >> 24) & 7)) {
-            DPRINTF("Wrong phase got %d expected %d\n",
-                    s->sstat1 & PHASE_MASK, (insn >> 24) & 7);
+            trace_lsi_execute_script_blockmove_badphase(s->sstat1 & PHASE_MASK,
+                                                        (insn >> 24) & 7);
             lsi_script_scsi_interrupt(s, LSI_SIST0_MA, 0);
             break;
         }
@@ -1217,8 +1204,8 @@ again:
             lsi_do_msgin(s);
             break;
         default:
-            BADF("Unimplemented phase %d\n", s->sstat1 & PHASE_MASK);
-            exit(1);
+            qemu_log_mask(LOG_UNIMP, "lsi_scsi: Unimplemented phase %d\n",
+                          s->sstat1 & PHASE_MASK);
         }
         s->dfifo = s->dbc & 0xff;
         s->ctest5 = (s->ctest5 & 0xfc) | ((s->dbc >> 8) & 3);
@@ -1246,7 +1233,7 @@ again:
             case 0: /* Select */
                 s->sdid = id;
                 if (s->scntl1 & LSI_SCNTL1_CON) {
-                    DPRINTF("Already reselected, jumping to alternative address\n");
+                    trace_lsi_execute_script_io_alreadyreselected();
                     s->dsp = s->dnad;
                     break;
                 }
@@ -1256,8 +1243,8 @@ again:
                     lsi_bad_selection(s, id);
                     break;
                 }
-                DPRINTF("Selected target %d%s\n",
-                        id, insn & (1 << 3) ? " ATN" : "");
+                trace_lsi_execute_script_io_selected(id,
+                                             insn & (1 << 3) ? " ATN" : "");
                 /* ??? Linux drivers compain when this is set.  Maybe
                    it only applies in low-level mode (unimplemented).
                 lsi_script_scsi_interrupt(s, LSI_SIST0_CMP, 0); */
@@ -1269,7 +1256,7 @@ again:
                 lsi_set_phase(s, PHASE_MO);
                 break;
             case 1: /* Disconnect */
-                DPRINTF("Wait Disconnect\n");
+                trace_lsi_execute_script_io_disconnect();
                 s->scntl1 &= ~LSI_SCNTL1_CON;
                 break;
             case 2: /* Wait Reselect */
@@ -1278,7 +1265,7 @@ again:
                 }
                 break;
             case 3: /* Set */
-                DPRINTF("Set%s%s%s%s\n",
+                trace_lsi_execute_script_io_set(
                         insn & (1 << 3) ? " ATN" : "",
                         insn & (1 << 6) ? " ACK" : "",
                         insn & (1 << 9) ? " TM" : "",
@@ -1288,14 +1275,14 @@ again:
                     lsi_set_phase(s, PHASE_MO);
                 }
                 if (insn & (1 << 9)) {
-                    BADF("Target mode not implemented\n");
-                    exit(1);
+                    qemu_log_mask(LOG_UNIMP,
+                        "lsi_scsi: Target mode not implemented\n");
                 }
                 if (insn & (1 << 10))
                     s->carry = 1;
                 break;
             case 4: /* Clear */
-                DPRINTF("Clear%s%s%s%s\n",
+                trace_lsi_execute_script_io_clear(
                         insn & (1 << 3) ? " ATN" : "",
                         insn & (1 << 6) ? " ACK" : "",
                         insn & (1 << 9) ? " TM" : "",
@@ -1313,18 +1300,17 @@ again:
             uint8_t data8;
             int reg;
             int operator;
-#ifdef DEBUG_LSI
+
             static const char *opcode_names[3] =
                 {"Write", "Read", "Read-Modify-Write"};
             static const char *operator_names[8] =
                 {"MOV", "SHL", "OR", "XOR", "AND", "SHR", "ADD", "ADC"};
-#endif
 
             reg = ((insn >> 16) & 0x7f) | (insn & 0x80);
             data8 = (insn >> 8) & 0xff;
             opcode = (insn >> 27) & 7;
             operator = (insn >> 24) & 7;
-            DPRINTF("%s reg 0x%x %s data8=0x%02x sfbr=0x%02x%s\n",
+            trace_lsi_execute_script_io_opcode(
                     opcode_names[opcode - 5], reg,
                     operator_names[operator], data8, s->sfbr,
                     (insn & (1 << 23)) ? " SFBR" : "");
@@ -1404,21 +1390,21 @@ again:
             int jmp;
 
             if ((insn & 0x002e0000) == 0) {
-                DPRINTF("NOP\n");
+                trace_lsi_execute_script_tc_nop();
                 break;
             }
             if (s->sist1 & LSI_SIST1_STO) {
-                DPRINTF("Delayed select timeout\n");
+                trace_lsi_execute_script_tc_delayedselect_timeout();
                 lsi_stop_script(s);
                 break;
             }
             cond = jmp = (insn & (1 << 19)) != 0;
             if (cond == jmp && (insn & (1 << 21))) {
-                DPRINTF("Compare carry %d\n", s->carry == jmp);
+                trace_lsi_execute_script_tc_compc(s->carry == jmp);
                 cond = s->carry != 0;
             }
             if (cond == jmp && (insn & (1 << 17))) {
-                DPRINTF("Compare phase %d %c= %d\n",
+                trace_lsi_execute_script_tc_compp(
                         (s->sstat1 & PHASE_MASK),
                         jmp ? '=' : '!',
                         ((insn >> 24) & 7));
@@ -1428,7 +1414,7 @@ again:
                 uint8_t mask;
 
                 mask = (~insn >> 8) & 0xff;
-                DPRINTF("Compare data 0x%x & 0x%x %c= 0x%x\n",
+                trace_lsi_execute_script_tc_compd(
                         s->sfbr, mask, jmp ? '=' : '!', insn & mask);
                 cond = (s->sfbr & mask) == (insn & mask);
             }
@@ -1439,21 +1425,21 @@ again:
                 }
                 switch ((insn >> 27) & 7) {
                 case 0: /* Jump */
-                    DPRINTF("Jump to 0x%08x\n", addr);
+                    trace_lsi_execute_script_tc_jump(addr);
                     s->adder = addr;
                     s->dsp = addr;
                     break;
                 case 1: /* Call */
-                    DPRINTF("Call 0x%08x\n", addr);
+                    trace_lsi_execute_script_tc_call(addr);
                     s->temp = s->dsp;
                     s->dsp = addr;
                     break;
                 case 2: /* Return */
-                    DPRINTF("Return to 0x%08x\n", s->temp);
+                    trace_lsi_execute_script_tc_return(s->temp);
                     s->dsp = s->temp;
                     break;
                 case 3: /* Interrupt */
-                    DPRINTF("Interrupt 0x%08x\n", s->dsps);
+                    trace_lsi_execute_script_tc_interrupt(s->dsps);
                     if ((insn & (1 << 20)) != 0) {
                         s->istat0 |= LSI_ISTAT0_INTF;
                         lsi_update_irq(s);
@@ -1462,12 +1448,12 @@ again:
                     }
                     break;
                 default:
-                    DPRINTF("Illegal transfer control\n");
+                    trace_lsi_execute_script_tc_illegal();
                     lsi_script_dma_interrupt(s, LSI_DSTAT_IID);
                     break;
                 }
             } else {
-                DPRINTF("Control condition failed\n");
+                trace_lsi_execute_script_tc_cc_failed();
             }
         }
         break;
@@ -1495,13 +1481,12 @@ again:
             reg = (insn >> 16) & 0xff;
             if (insn & (1 << 24)) {
                 pci_dma_read(pci_dev, addr, data, n);
-                DPRINTF("Load reg 0x%x size %d addr 0x%08x = %08x\n", reg, n,
-                        addr, *(int *)data);
+                trace_lsi_execute_script_mm_load(reg, n, addr, *(int *)data);
                 for (i = 0; i < n; i++) {
                     lsi_reg_writeb(s, reg + i, data[i]);
                 }
             } else {
-                DPRINTF("Store reg 0x%x size %d addr 0x%08x\n", reg, n, addr);
+                trace_lsi_execute_script_mm_store(reg, n, addr);
                 for (i = 0; i < n; i++) {
                     data[i] = lsi_reg_readb(s, reg + i);
                 }
@@ -1515,8 +1500,10 @@ again:
            assume this is the case and force an unexpected device disconnect.
            This is apparently sufficient to beat the drivers into submission.
          */
-        if (!(s->sien0 & LSI_SIST0_UDC))
-            fprintf(stderr, "inf. loop with UDC masked\n");
+        if (!(s->sien0 & LSI_SIST0_UDC)) {
+            qemu_log_mask(LOG_GUEST_ERROR,
+                          "lsi_scsi: inf. loop with UDC masked");
+        }
         lsi_script_scsi_interrupt(s, LSI_SIST0_UDC, 0);
         lsi_disconnect(s);
     } else if (s->istat1 & LSI_ISTAT1_SRUN && !s->waiting) {
@@ -1526,7 +1513,7 @@ again:
             goto again;
         }
     }
-    DPRINTF("SCRIPTS execution stopped\n");
+    trace_lsi_execute_script_stop();
 }
 
 static uint8_t lsi_reg_readb(LSIState *s, int offset)
@@ -1761,10 +1748,8 @@ static uint8_t lsi_reg_readb(LSIState *s, int offset)
 #undef CASE_GET_REG24
 #undef CASE_GET_REG32
 
-#ifdef DEBUG_LSI_REG
-    DPRINTF("Read reg %s %x = %02x\n",
-            offset < ARRAY_SIZE(names) ? names[offset] : "???", offset, ret);
-#endif
+    trace_lsi_reg_read(offset < ARRAY_SIZE(names) ? names[offset] : "???",
+                       offset, ret);
 
     return ret;
 }
@@ -1782,21 +1767,22 @@ static void lsi_reg_writeb(LSIState *s, int offset, uint8_t val)
     case addr + 2: s->name &= 0xff00ffff; s->name |= val << 16; break; \
     case addr + 3: s->name &= 0x00ffffff; s->name |= val << 24; break;
 
-#ifdef DEBUG_LSI_REG
-    DPRINTF("Write reg %s %x = %02x\n",
-            offset < ARRAY_SIZE(names) ? names[offset] : "???", offset, val);
-#endif
+    trace_lsi_reg_write(offset < ARRAY_SIZE(names) ? names[offset] : "???",
+                        offset, val);
+
     switch (offset) {
     case 0x00: /* SCNTL0 */
         s->scntl0 = val;
         if (val & LSI_SCNTL0_START) {
-            BADF("Start sequence not implemented\n");
+            qemu_log_mask(LOG_UNIMP,
+                          "lsi_scsi: Start sequence not implemented\n");
         }
         break;
     case 0x01: /* SCNTL1 */
         s->scntl1 = val & ~LSI_SCNTL1_SST;
         if (val & LSI_SCNTL1_IARB) {
-            BADF("Immediate Arbritration not implemented\n");
+            qemu_log_mask(LOG_UNIMP,
+                      "lsi_scsi: Immediate Arbritration not implemented\n");
         }
         if (val & LSI_SCNTL1_RST) {
             if (!(s->sstat0 & LSI_SSTAT0_RST)) {
@@ -1823,7 +1809,8 @@ static void lsi_reg_writeb(LSIState *s, int offset, uint8_t val)
         break;
     case 0x06: /* SDID */
         if ((s->ssid & 0x80) && (val & 0xf) != (s->ssid & 0xf)) {
-            BADF("Destination ID does not match SSID\n");
+            qemu_log_mask(LOG_GUEST_ERROR,
+                          "lsi_scsi: Destination ID does not match SSID\n");
         }
         s->sdid = val & 0xf;
         break;
@@ -1851,7 +1838,7 @@ static void lsi_reg_writeb(LSIState *s, int offset, uint8_t val)
             lsi_update_irq(s);
         }
         if (s->waiting == 1 && val & LSI_ISTAT0_SIGP) {
-            DPRINTF("Woken by SIGP\n");
+            trace_lsi_awoken();
             s->waiting = 0;
             s->dsp = s->dnad;
             lsi_execute_script(s);
@@ -1878,13 +1865,15 @@ static void lsi_reg_writeb(LSIState *s, int offset, uint8_t val)
     CASE_SET_REG32(temp, 0x1c)
     case 0x21: /* CTEST4 */
         if (val & 7) {
-           BADF("Unimplemented CTEST4-FBL 0x%x\n", val);
+            qemu_log_mask(LOG_UNIMP,
+                          "lsi_scsi: Unimplemented CTEST4-FBL 0x%x\n", val);
         }
         s->ctest4 = val;
         break;
     case 0x22: /* CTEST5 */
         if (val & (LSI_CTEST5_ADCK | LSI_CTEST5_BBCK)) {
-            BADF("CTEST5 DMA increment not implemented\n");
+            qemu_log_mask(LOG_UNIMP,
+                          "lsi_scsi: CTEST5 DMA increment not implemented\n");
         }
         s->ctest5 = val;
         break;
@@ -1941,7 +1930,8 @@ static void lsi_reg_writeb(LSIState *s, int offset, uint8_t val)
         break;
     case 0x49: /* STIME1 */
         if (val & 0xf) {
-            DPRINTF("General purpose timer not implemented\n");
+            qemu_log_mask(LOG_UNIMP,
+                          "lsi_scsi: General purpose timer not implemented\n");
             /* ??? Raising the interrupt immediately seems to be sufficient
                to keep the FreeBSD driver happy.  */
             lsi_script_scsi_interrupt(s, 0, LSI_SIST1_GEN);
@@ -1958,13 +1948,15 @@ static void lsi_reg_writeb(LSIState *s, int offset, uint8_t val)
         break;
     case 0x4e: /* STEST2 */
         if (val & 1) {
-            BADF("Low level mode not implemented\n");
+            qemu_log_mask(LOG_UNIMP,
+                          "lsi_scsi: Low level mode not implemented\n");
         }
         s->stest2 = val;
         break;
     case 0x4f: /* STEST3 */
         if (val & 0x41) {
-            BADF("SCSI FIFO test mode not implemented\n");
+            qemu_log_mask(LOG_UNIMP,
+                          "lsi_scsi: SCSI FIFO test mode not implemented\n");
         }
         s->stest3 = val;
         break;
diff --git a/hw/scsi/mptendian.c b/hw/scsi/mptendian.c
index 8ae39a76f4..79f99734d2 100644
--- a/hw/scsi/mptendian.c
+++ b/hw/scsi/mptendian.c
@@ -35,152 +35,155 @@
 
 static void mptsas_fix_sgentry_endianness(MPISGEntry *sge)
 {
-    le32_to_cpus(&sge->FlagsLength);
+    sge->FlagsLength = le32_to_cpu(sge->FlagsLength);
     if (sge->FlagsLength & MPI_SGE_FLAGS_64_BIT_ADDRESSING) {
-       le64_to_cpus(&sge->u.Address64);
+        sge->u.Address64 = le64_to_cpu(sge->u.Address64);
     } else {
-       le32_to_cpus(&sge->u.Address32);
+        sge->u.Address32 = le32_to_cpu(sge->u.Address32);
     }
 }
 
 static void mptsas_fix_sgentry_endianness_reply(MPISGEntry *sge)
 {
     if (sge->FlagsLength & MPI_SGE_FLAGS_64_BIT_ADDRESSING) {
-       cpu_to_le64s(&sge->u.Address64);
+        sge->u.Address64 = cpu_to_le64(sge->u.Address64);
     } else {
-       cpu_to_le32s(&sge->u.Address32);
+        sge->u.Address32 = cpu_to_le32(sge->u.Address32);
     }
-    cpu_to_le32s(&sge->FlagsLength);
+    sge->FlagsLength = cpu_to_le32(sge->FlagsLength);
 }
 
 void mptsas_fix_scsi_io_endianness(MPIMsgSCSIIORequest *req)
 {
-    le32_to_cpus(&req->MsgContext);
-    le32_to_cpus(&req->Control);
-    le32_to_cpus(&req->DataLength);
-    le32_to_cpus(&req->SenseBufferLowAddr);
+    req->MsgContext = le32_to_cpu(req->MsgContext);
+    req->Control = le32_to_cpu(req->Control);
+    req->DataLength = le32_to_cpu(req->DataLength);
+    req->SenseBufferLowAddr = le32_to_cpu(req->SenseBufferLowAddr);
 }
 
 void mptsas_fix_scsi_io_reply_endianness(MPIMsgSCSIIOReply *reply)
 {
-    cpu_to_le32s(&reply->MsgContext);
-    cpu_to_le16s(&reply->IOCStatus);
-    cpu_to_le32s(&reply->IOCLogInfo);
-    cpu_to_le32s(&reply->TransferCount);
-    cpu_to_le32s(&reply->SenseCount);
-    cpu_to_le32s(&reply->ResponseInfo);
-    cpu_to_le16s(&reply->TaskTag);
+    reply->MsgContext = cpu_to_le32(reply->MsgContext);
+    reply->IOCStatus = cpu_to_le16(reply->IOCStatus);
+    reply->IOCLogInfo = cpu_to_le32(reply->IOCLogInfo);
+    reply->TransferCount = cpu_to_le32(reply->TransferCount);
+    reply->SenseCount = cpu_to_le32(reply->SenseCount);
+    reply->ResponseInfo = cpu_to_le32(reply->ResponseInfo);
+    reply->TaskTag = cpu_to_le16(reply->TaskTag);
 }
 
 void mptsas_fix_scsi_task_mgmt_endianness(MPIMsgSCSITaskMgmt *req)
 {
-    le32_to_cpus(&req->MsgContext);
-    le32_to_cpus(&req->TaskMsgContext);
+    req->MsgContext = le32_to_cpu(req->MsgContext);
+    req->TaskMsgContext = le32_to_cpu(req->TaskMsgContext);
 }
 
 void mptsas_fix_scsi_task_mgmt_reply_endianness(MPIMsgSCSITaskMgmtReply *reply)
 {
-    cpu_to_le32s(&reply->MsgContext);
-    cpu_to_le16s(&reply->IOCStatus);
-    cpu_to_le32s(&reply->IOCLogInfo);
-    cpu_to_le32s(&reply->TerminationCount);
+    reply->MsgContext = cpu_to_le32(reply->MsgContext);
+    reply->IOCStatus = cpu_to_le16(reply->IOCStatus);
+    reply->IOCLogInfo = cpu_to_le32(reply->IOCLogInfo);
+    reply->TerminationCount = cpu_to_le32(reply->TerminationCount);
 }
 
 void mptsas_fix_ioc_init_endianness(MPIMsgIOCInit *req)
 {
-    le32_to_cpus(&req->MsgContext);
-    le16_to_cpus(&req->ReplyFrameSize);
-    le32_to_cpus(&req->HostMfaHighAddr);
-    le32_to_cpus(&req->SenseBufferHighAddr);
-    le32_to_cpus(&req->ReplyFifoHostSignalingAddr);
+    req->MsgContext = le32_to_cpu(req->MsgContext);
+    req->ReplyFrameSize = le16_to_cpu(req->ReplyFrameSize);
+    req->HostMfaHighAddr = le32_to_cpu(req->HostMfaHighAddr);
+    req->SenseBufferHighAddr = le32_to_cpu(req->SenseBufferHighAddr);
+    req->ReplyFifoHostSignalingAddr =
+        le32_to_cpu(req->ReplyFifoHostSignalingAddr);
     mptsas_fix_sgentry_endianness(&req->HostPageBufferSGE);
-    le16_to_cpus(&req->MsgVersion);
-    le16_to_cpus(&req->HeaderVersion);
+    req->MsgVersion = le16_to_cpu(req->MsgVersion);
+    req->HeaderVersion = le16_to_cpu(req->HeaderVersion);
 }
 
 void mptsas_fix_ioc_init_reply_endianness(MPIMsgIOCInitReply *reply)
 {
-    cpu_to_le32s(&reply->MsgContext);
-    cpu_to_le16s(&reply->IOCStatus);
-    cpu_to_le32s(&reply->IOCLogInfo);
+    reply->MsgContext = cpu_to_le32(reply->MsgContext);
+    reply->IOCStatus = cpu_to_le16(reply->IOCStatus);
+    reply->IOCLogInfo = cpu_to_le32(reply->IOCLogInfo);
 }
 
 void mptsas_fix_ioc_facts_endianness(MPIMsgIOCFacts *req)
 {
-    le32_to_cpus(&req->MsgContext);
+    req->MsgContext = le32_to_cpu(req->MsgContext);
 }
 
 void mptsas_fix_ioc_facts_reply_endianness(MPIMsgIOCFactsReply *reply)
 {
-    cpu_to_le16s(&reply->MsgVersion);
-    cpu_to_le16s(&reply->HeaderVersion);
-    cpu_to_le32s(&reply->MsgContext);
-    cpu_to_le16s(&reply->IOCExceptions);
-    cpu_to_le16s(&reply->IOCStatus);
-    cpu_to_le32s(&reply->IOCLogInfo);
-    cpu_to_le16s(&reply->ReplyQueueDepth);
-    cpu_to_le16s(&reply->RequestFrameSize);
-    cpu_to_le16s(&reply->ProductID);
-    cpu_to_le32s(&reply->CurrentHostMfaHighAddr);
-    cpu_to_le16s(&reply->GlobalCredits);
-    cpu_to_le32s(&reply->CurrentSenseBufferHighAddr);
-    cpu_to_le16s(&reply->CurReplyFrameSize);
-    cpu_to_le32s(&reply->FWImageSize);
-    cpu_to_le32s(&reply->IOCCapabilities);
-    cpu_to_le16s(&reply->HighPriorityQueueDepth);
+    reply->MsgVersion = cpu_to_le16(reply->MsgVersion);
+    reply->HeaderVersion = cpu_to_le16(reply->HeaderVersion);
+    reply->MsgContext = cpu_to_le32(reply->MsgContext);
+    reply->IOCExceptions = cpu_to_le16(reply->IOCExceptions);
+    reply->IOCStatus = cpu_to_le16(reply->IOCStatus);
+    reply->IOCLogInfo = cpu_to_le32(reply->IOCLogInfo);
+    reply->ReplyQueueDepth = cpu_to_le16(reply->ReplyQueueDepth);
+    reply->RequestFrameSize = cpu_to_le16(reply->RequestFrameSize);
+    reply->ProductID = cpu_to_le16(reply->ProductID);
+    reply->CurrentHostMfaHighAddr = cpu_to_le32(reply->CurrentHostMfaHighAddr);
+    reply->GlobalCredits = cpu_to_le16(reply->GlobalCredits);
+    reply->CurrentSenseBufferHighAddr =
+        cpu_to_le32(reply->CurrentSenseBufferHighAddr);
+    reply->CurReplyFrameSize = cpu_to_le16(reply->CurReplyFrameSize);
+    reply->FWImageSize = cpu_to_le32(reply->FWImageSize);
+    reply->IOCCapabilities = cpu_to_le32(reply->IOCCapabilities);
+    reply->HighPriorityQueueDepth = cpu_to_le16(reply->HighPriorityQueueDepth);
     mptsas_fix_sgentry_endianness_reply(&reply->HostPageBufferSGE);
-    cpu_to_le32s(&reply->ReplyFifoHostSignalingAddr);
+    reply->ReplyFifoHostSignalingAddr =
+        cpu_to_le32(reply->ReplyFifoHostSignalingAddr);
 }
 
 void mptsas_fix_config_endianness(MPIMsgConfig *req)
 {
-    le16_to_cpus(&req->ExtPageLength);
-    le32_to_cpus(&req->MsgContext);
-    le32_to_cpus(&req->PageAddress);
+    req->ExtPageLength = le16_to_cpu(req->ExtPageLength);
+    req->MsgContext = le32_to_cpu(req->MsgContext);
+    req->PageAddress = le32_to_cpu(req->PageAddress);
     mptsas_fix_sgentry_endianness(&req->PageBufferSGE);
 }
 
 void mptsas_fix_config_reply_endianness(MPIMsgConfigReply *reply)
 {
-    cpu_to_le16s(&reply->ExtPageLength);
-    cpu_to_le32s(&reply->MsgContext);
-    cpu_to_le16s(&reply->IOCStatus);
-    cpu_to_le32s(&reply->IOCLogInfo);
+    reply->ExtPageLength = cpu_to_le16(reply->ExtPageLength);
+    reply->MsgContext = cpu_to_le32(reply->MsgContext);
+    reply->IOCStatus = cpu_to_le16(reply->IOCStatus);
+    reply->IOCLogInfo = cpu_to_le32(reply->IOCLogInfo);
 }
 
 void mptsas_fix_port_facts_endianness(MPIMsgPortFacts *req)
 {
-    le32_to_cpus(&req->MsgContext);
+    req->MsgContext = le32_to_cpu(req->MsgContext);
 }
 
 void mptsas_fix_port_facts_reply_endianness(MPIMsgPortFactsReply *reply)
 {
-    cpu_to_le32s(&reply->MsgContext);
-    cpu_to_le16s(&reply->IOCStatus);
-    cpu_to_le32s(&reply->IOCLogInfo);
-    cpu_to_le16s(&reply->MaxDevices);
-    cpu_to_le16s(&reply->PortSCSIID);
-    cpu_to_le16s(&reply->ProtocolFlags);
-    cpu_to_le16s(&reply->MaxPostedCmdBuffers);
-    cpu_to_le16s(&reply->MaxPersistentIDs);
-    cpu_to_le16s(&reply->MaxLanBuckets);
+    reply->MsgContext = cpu_to_le32(reply->MsgContext);
+    reply->IOCStatus = cpu_to_le16(reply->IOCStatus);
+    reply->IOCLogInfo = cpu_to_le32(reply->IOCLogInfo);
+    reply->MaxDevices = cpu_to_le16(reply->MaxDevices);
+    reply->PortSCSIID = cpu_to_le16(reply->PortSCSIID);
+    reply->ProtocolFlags = cpu_to_le16(reply->ProtocolFlags);
+    reply->MaxPostedCmdBuffers = cpu_to_le16(reply->MaxPostedCmdBuffers);
+    reply->MaxPersistentIDs = cpu_to_le16(reply->MaxPersistentIDs);
+    reply->MaxLanBuckets = cpu_to_le16(reply->MaxLanBuckets);
 }
 
 void mptsas_fix_port_enable_endianness(MPIMsgPortEnable *req)
 {
-    le32_to_cpus(&req->MsgContext);
+    req->MsgContext = le32_to_cpu(req->MsgContext);
 }
 
 void mptsas_fix_port_enable_reply_endianness(MPIMsgPortEnableReply *reply)
 {
-    cpu_to_le32s(&reply->MsgContext);
-    cpu_to_le16s(&reply->IOCStatus);
-    cpu_to_le32s(&reply->IOCLogInfo);
+    reply->MsgContext = cpu_to_le32(reply->MsgContext);
+    reply->IOCStatus = cpu_to_le16(reply->IOCStatus);
+    reply->IOCLogInfo = cpu_to_le32(reply->IOCLogInfo);
 }
 
 void mptsas_fix_event_notification_endianness(MPIMsgEventNotify *req)
 {
-    le32_to_cpus(&req->MsgContext);
+    req->MsgContext = le32_to_cpu(req->MsgContext);
 }
 
 void mptsas_fix_event_notification_reply_endianness(MPIMsgEventNotifyReply *reply)
@@ -188,16 +191,16 @@ void mptsas_fix_event_notification_reply_endianness(MPIMsgEventNotifyReply *repl
     int length = reply->EventDataLength;
     int i;
 
-    cpu_to_le16s(&reply->EventDataLength);
-    cpu_to_le32s(&reply->MsgContext);
-    cpu_to_le16s(&reply->IOCStatus);
-    cpu_to_le32s(&reply->IOCLogInfo);
-    cpu_to_le32s(&reply->Event);
-    cpu_to_le32s(&reply->EventContext);
+    reply->EventDataLength = cpu_to_le16(reply->EventDataLength);
+    reply->MsgContext = cpu_to_le32(reply->MsgContext);
+    reply->IOCStatus = cpu_to_le16(reply->IOCStatus);
+    reply->IOCLogInfo = cpu_to_le32(reply->IOCLogInfo);
+    reply->Event = cpu_to_le32(reply->Event);
+    reply->EventContext = cpu_to_le32(reply->EventContext);
 
     /* Really depends on the event kind.  This will do for now.  */
     for (i = 0; i < length; i++) {
-        cpu_to_le32s(&reply->Data[i]);
+        reply->Data[i] = cpu_to_le32(reply->Data[i]);
     }
 }
 
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index 5ae7baa082..c43163cef4 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -2610,6 +2610,12 @@ static void scsi_block_realize(SCSIDevice *dev, Error **errp)
         return;
     }
 
+    if (s->rotation_rate) {
+        error_report_once("rotation_rate is specified for scsi-block but is "
+                          "not implemented. This option is deprecated and will "
+                          "be removed in a future version");
+    }
+
     /* check we are using a driver managing SG_IO (version 3 and after) */
     rc = blk_ioctl(s->qdev.conf.blk, SG_GET_VERSION_NUM, &sg_version);
     if (rc < 0) {
diff --git a/hw/scsi/trace-events b/hw/scsi/trace-events
index 6e299d0338..0fb6a99616 100644
--- a/hw/scsi/trace-events
+++ b/hw/scsi/trace-events
@@ -229,3 +229,65 @@ spapr_vscsi_process_login(void) "Got login, sending response !"
 spapr_vscsi_queue_cmd_no_drive(uint64_t lun) "Command for lun 0x%08" PRIx64 " with no drive"
 spapr_vscsi_queue_cmd(uint32_t qtag, unsigned cdb, const char *cmd, int lun, int ret) "Queued command tag 0x%"PRIx32" CMD 0x%x=%s LUN %d ret: %d"
 spapr_vscsi_do_crq(unsigned c0, unsigned c1) "crq: %02x %02x ..."
+
+# hw/scsi/lsi53c895a.c
+lsi_reset(void) "Reset"
+lsi_update_irq(int level, uint8_t dstat, uint8_t sist1, uint8_t sist0) "Update IRQ level %d dstat 0x%02x sist 0x%02x0x%02x"
+lsi_update_irq_disconnected(void) "Handled IRQs & disconnected, looking for pending processes"
+lsi_script_scsi_interrupt(uint8_t stat1, uint8_t stat0, uint8_t sist1, uint8_t sist0) "SCSI Interrupt 0x%02x0x%02x prev 0x%02x0x%02x"
+lsi_script_dma_interrupt(uint8_t stat, uint8_t dstat) "DMA Interrupt 0x%x prev 0x%x"
+lsi_bad_phase_jump(uint32_t dsp) "Data phase mismatch jump to 0x%"PRIX32
+lsi_bad_phase_interrupt(void) "Phase mismatch interrupt"
+lsi_bad_selection(uint32_t id) "Selected absent target %"PRIu32
+lsi_do_dma_unavailable(void) "DMA no data available"
+lsi_do_dma(uint64_t addr, int len) "DMA addr=0x%"PRIx64" len=%d"
+lsi_queue_command(uint32_t tag) "Queueing tag=0x%"PRId32
+lsi_add_msg_byte_error(void) "MSG IN data too long"
+lsi_add_msg_byte(uint8_t data) "MSG IN 0x%02x"
+lsi_reselect(int id) "Reselected target %d"
+lsi_queue_req_error(void *p) "Multiple IO pending for request %p"
+lsi_queue_req(uint32_t tag) "Queueing IO tag=0x%"PRIx32
+lsi_command_complete(uint32_t status) "Command complete status=%"PRId32
+lsi_transfer_data(uint32_t tag, uint32_t len) "Data ready tag=0x%"PRIx32" len=%"PRId32
+lsi_do_command(uint32_t dbc) "Send command len=%"PRId32
+lsi_do_status(uint32_t dbc, uint8_t status) "Get status len=%"PRId32" status=%d"
+lsi_do_status_error(void) "Bad Status move"
+lsi_do_msgin(uint32_t dbc, int len) "Message in len=%"PRId32" %d"
+lsi_do_msgout(uint32_t dbc) "MSG out len=%"PRId32
+lsi_do_msgout_disconnect(void) "MSG: Disconnect"
+lsi_do_msgout_noop(void) "MSG: No Operation"
+lsi_do_msgout_extended(uint8_t msg, uint8_t len) "Extended message 0x%x (len %d)"
+lsi_do_msgout_ignored(const char *msg) "%s (ignored)"
+lsi_do_msgout_simplequeue(uint8_t select_tag) "SIMPLE queue tag=0x%x"
+lsi_do_msgout_abort(uint32_t tag) "MSG: ABORT TAG tag=0x%"PRId32
+lsi_do_msgout_clearqueue(uint32_t tag) "MSG: CLEAR QUEUE tag=0x%"PRIx32
+lsi_do_msgout_busdevicereset(uint32_t tag) "MSG: BUS DEVICE RESET tag=0x%"PRIx32
+lsi_do_msgout_select(int id) "Select LUN %d"
+lsi_memcpy(uint32_t dest, uint32_t src, int count) "memcpy dest 0x%"PRIx32" src 0x%"PRIx32" count %d"
+lsi_wait_reselect(void) "Wait Reselect"
+lsi_execute_script(uint32_t dsp, uint32_t insn, uint32_t addr) "SCRIPTS dsp=0x%"PRIx32" opcode 0x%"PRIx32" arg 0x%"PRIx32
+lsi_execute_script_blockmove_delayed(void) "Delayed select timeout"
+lsi_execute_script_blockmove_badphase(uint8_t phase, uint8_t expected) "Wrong phase got %d expected %d"
+lsi_execute_script_io_alreadyreselected(void) "Already reselected, jumping to alternative address"
+lsi_execute_script_io_selected(uint8_t id, const char *atn) "Selected target %d%s"
+lsi_execute_script_io_disconnect(void) "Wait Disconnect"
+lsi_execute_script_io_set(const char *atn, const char *ack, const char *tm, const char *cc) "Set%s%s%s%s"
+lsi_execute_script_io_clear(const char *atn, const char *ack, const char *tm, const char *cc) "Clear%s%s%s%s"
+lsi_execute_script_io_opcode(const char *opcode, int reg, const char *opname, uint8_t data8, uint32_t sfbr, const char *ssfbr) "%s reg 0x%x %s data8=0x%02x sfbr=0x%02x%s"
+lsi_execute_script_tc_nop(void) "NOP"
+lsi_execute_script_tc_delayedselect_timeout(void) "Delayed select timeout"
+lsi_execute_script_tc_compc(int result) "Compare carry %d"
+lsi_execute_script_tc_compp(uint8_t phase, int op, uint8_t insn_phase) "Compare phase %d %c= %d"
+lsi_execute_script_tc_compd(uint32_t sfbr, uint8_t mask, int op, int result) "Compare data 0x%"PRIx32" & 0x%x %c= 0x%x"
+lsi_execute_script_tc_jump(uint32_t addr) "Jump to 0x%"PRIx32
+lsi_execute_script_tc_call(uint32_t addr) "Call 0x%"PRIx32
+lsi_execute_script_tc_return(uint32_t addr) "Return to 0x%"PRIx32
+lsi_execute_script_tc_interrupt(uint32_t addr) "Interrupt 0x%"PRIx32
+lsi_execute_script_tc_illegal(void) "Illegal transfer control"
+lsi_execute_script_tc_cc_failed(void) "Control condition failed"
+lsi_execute_script_mm_load(int reg, int n, uint32_t addr, int data) "Load reg 0x%x size %d addr 0x%"PRIx32" = 0x%08x"
+lsi_execute_script_mm_store(int reg, int n, uint32_t addr) "Store reg 0x%x size %d addr 0x%"PRIx32
+lsi_execute_script_stop(void) "SCRIPTS execution stopped"
+lsi_awoken(void) "Woken by SIGP"
+lsi_reg_read(const char *name, int offset, uint8_t ret) "Read reg %s 0x%x = 0x%02x"
+lsi_reg_write(const char *name, int offset, uint8_t val) "Write reg %s 0x%x = 0x%02x"
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index f6a588ab57..94f5c8e52a 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -358,6 +358,10 @@ int virtio_queue_ready(VirtQueue *vq)
  * Called within rcu_read_lock().  */
 static int virtio_queue_empty_rcu(VirtQueue *vq)
 {
+    if (unlikely(vq->vdev->broken)) {
+        return 1;
+    }
+
     if (unlikely(!vq->vring.avail)) {
         return 1;
     }
@@ -373,6 +377,10 @@ int virtio_queue_empty(VirtQueue *vq)
 {
     bool empty;
 
+    if (unlikely(vq->vdev->broken)) {
+        return 1;
+    }
+
     if (unlikely(!vq->vring.avail)) {
         return 1;
     }