HP-UX 10.20 seems to make the lsi53c895a spinning on a memory location under certain circumstances. As the SCSI controller and CPU are not running at the same time this loop will never finish. After some time, the check loop interrupts with a unexpected device disconnect. This works, but is slow because the kernel resets the scsi controller. Instead of signaling UDC, add an option 'hpux-spin-workaround' which emulates a INTERRUPT 2 script instruction. This instruction tells the kernel that the request was fulfilled. With this change, SCSI speeds improves significantly.
The option can be enabled by adding -global lsi53c895a.hpux-spin-workaround=on to the qemu commandline. Signed-off-by: Sven Schnelle <sv...@stackframe.org> --- hw/scsi/lsi53c895a.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c index d607a5f9fb..20c353f594 100644 --- a/hw/scsi/lsi53c895a.c +++ b/hw/scsi/lsi53c895a.c @@ -304,6 +304,7 @@ struct LSIState { uint32_t adder; uint8_t script_ram[2048 * sizeof(uint32_t)]; + bool hpux_spin_workaround; }; #define TYPE_LSI53C810 "lsi53c810" @@ -1156,8 +1157,17 @@ again: 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); + if (s->hpux_spin_workaround) { + /* + * Workaround for HP-UX 10.20: Instead of disconnecting, which + * causes a long delay, emulate a INTERRUPT 2 instruction. + */ + s->dsps = 2; + lsi_script_dma_interrupt(s, LSI_DSTAT_SIR); + } else { + lsi_script_scsi_interrupt(s, LSI_SIST0_UDC, 0); + lsi_disconnect(s); + } trace_lsi_execute_script_stop(); reentrancy_level--; return; @@ -2339,6 +2349,11 @@ static void lsi_scsi_exit(PCIDevice *dev) address_space_destroy(&s->pci_io_as); } +static Property lsi_props[] = { + DEFINE_PROP_BOOL("hpux-spin-workaround", LSIState, hpux_spin_workaround, + false), +}; + static void lsi_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -2353,6 +2368,7 @@ static void lsi_class_init(ObjectClass *klass, void *data) dc->reset = lsi_scsi_reset; dc->vmsd = &vmstate_lsi_scsi; set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); + device_class_set_props(dc, lsi_props); } static const TypeInfo lsi_info = { -- 2.43.2