On Wed, 28 Feb 2024 at 21:12, Sven Schnelle <sv...@stackframe.org> wrote: > > 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;
I see we already have a hacky workaround for other OSes that do something similar. The ideal fix for both of these I think would be for lsi_execute_script() to, instead of stopping, arrange to defer executing more script instructions until after the guest has had a chance to run a bit more. I think setting a timer that calls lsi_resume_script() after a while would have that effect. -- PMM