LSI53C895A: Handle empty SCRIPTS opcode
PATCH 2/2 LSI53C895A: Handle empty SCRIPTS opcode
Well I've finally sorted out what Openserver is doing. Basically after each DMA transfer the Openserver driver would issue an empty (0) SCRIPTS opcode. As the opcode is essentially a NOP it has no second DWORD and therefore the DSP should only be incremented by 4 bytes instead of the 8 bytes we currently do.
Here's a snippet of the log:
lsi_scsi: Data ready tag=0x100d9 len=16384
...lsi_scsi: SCRIPTS dsp=068c5e50 opcode 01000400 arg 07a09000lsi_scsi: DMA addr=0x07a09000 len=1024lsi_scsi: SCRIPTS dsp=068c5e58 opcode 00000000 arg 01000400lsi_scsi: Wrong phase got 1 expected 0
Note the 2nd DWORD after the empty opcode; the next opcode in the DMA transfer sequence. As can be expected the address after that has the next DMA address to use.
After the attached patch the DMA transfer is able to complete successfully:
lsi_scsi: SCRIPTS dsp=068c5e50 opcode 01000400 arg 07a0d000lsi_scsi: DMA addr=0x07a0d000 len=1024lsi_scsi: SCRIPTS dsp=068c5e5c opcode 01000400 arg 07a0d400lsi_scsi: DMA addr=0x07a0d400 len=1024
...
Tested againsted Openserver 5.0.5 and Debian ARM.
Changelog:
Handle empty SCRIPTS opcode
lsi53c895a.c +6 -0
@@ -867,6 +867,12 @@ again: insn_processed++; insn =read_dword (s, s->dsp); +if (!insn) { +/* If we receive an empty opcode increment the DSP by 4 bytes +instead of 8 and execute the next opcode at that location */ + s->dsp +=4 ; + goto again; + } addr =read_dword (s, s->dsp +4 ); addr_high =0 ;DPRINTF ("SCRIPTS dsp=%08x opcode %08x arg %08x\n" , s->dsp, insn, addr);
Quoted 5 lines · Justin Chevrier
Well I've finally sorted out what Openserver is doing. Basically after each DMA transfer the Openserver driver would issue an empty (0) SCRIPTS opcode. As the opcode is essentially a NOP it has no second DWORD and therefore the DSP should only be incremented by 4 bytes instead of the 8 bytes we currently do.
Nice catch!
Quoted 22 lines
Here's a snippet of the log:
lsi_scsi: Data ready tag=0x100d9 len=16384
...lsi_scsi: SCRIPTS dsp=068c5e50 opcode 01000400 arg07a09000lsi_scsi: DMA addr=0x07a09000 len=1024lsi_scsi: SCRIPTS dsp=068c5e58 opcode 00000000 arg 01000400lsi_scsi: Wrong phase got 1 expected 0Note the 2nd DWORD after the empty opcode; the next opcode in the DMA transfer sequence. As can be expected the address after that has the next DMA address to use.
After the attached patch the DMA transfer is able to complete successfully:
lsi_scsi: SCRIPTS dsp=068c5e50 opcode 01000400 arg07a0d000lsi_scsi: DMA addr=0x07a0d000 len=1024lsi_scsi: SCRIPTS dsp=068c5e5c opcode 01000400 arg07a0d400lsi_scsi: DMA addr=0x07a0d400 len=1024
...
Quoted 7 lines
Tested againsted Openserver 5.0.5 and Debian ARM.
Changelog:
Handle empty SCRIPTS opcode
Signed-off-by Justin Chevrier <address@hidden>
Tested XP 32-bit, Linux 2.6.27 in 40-bit DMA mode. I don't seen any issues with the patch applied.
Quoted 20 lines
Index:
hw/lsi53c895a.c
===================================================================lsi53c895a.c +6
-0@@ -867,6 +867,12 @@ again: insn_processed++; insn =read_dword (s, s->dsp); +if (!insn) { +/* If we receive an empty opcode increment the DSP by 4 bytes +instead of 8 and execute the next opcode at that location */ + s->dsp +=4 ; + goto again; + } addr =read_dword (s, s->dsp +4 ); addr_high =0 ;DPRINTF ("SCRIPTS dsp=%08x opcode %08x arg %08x\n" , s->dsp, insn, addr);
Signature · 4 lines
Ryan Harper Software Engineer; Linux Technology Center IBM Corp., Austin, Tx [email protected]