Subject: Problems writing back dirty data from the SA-110 data cache

From: <[email-masked]>
Date: Wed, 7 Jun 2000 11:03:20 -0700

We are trying to port linux/drivers/scsi/advansys.c to a StrongArm platform
running Linux 2.2.13. We are experiencing cache coherency problems between
the SA-110 and a PCI master (AdvanSys SCSI chip). We have attempted to
implement the cache write back and invalidate functions in
linux/arch/arm/mm/proc-sa110.s to achieve cache coherency, but every attempt
has resulted in memory corruption and memory violations.

To help diagnose the problem, we simplified our strategy to rely primarily
on the "_sa110_flush_cache_all" function which does a 16K read from the
Footbridge SA-110 Cache Flush area followed by an SA-110 Coprocessor "Drain
Write Buffer" instruction. Attaching an analyzer to the processor bus and
the PCI bus we can see the following sequence for a particular command the
driver queues to the SCSI chip. (Note: the command structures are cache line
aligned and are exactly three cache lines in length.)

1. The driver calls "_sa110_flush_cache_all" to write back and invalidate
the command structure from the cache. During the 16K read loop, two of the
three cache lines belonging to the command structure are successfully
written to the processor bus. The third cache line is not written even
though it was modified by the processor.

2. The driver updates command queue linkage and calls
"_sa110_cache_wback_area" to write back the modified linkage. This function
also includes an 
SA-110 Coprocessor "Drain Write Buffer" instruction.

3. The processor performs an unbuffered write to the SCSI chip to inform the
chip of the new command.

4. The SCSI chip reads the command structure from processor memory.

5. The third cache line is finally written to the processor bus (75 us after
step 3, 14 us after step 4) the next time "_sa110_flush_cache_all" is called
(apparently by the kernel).

6. The SCSI chip returns the corrupted command structure to the driver.

unsubscribe: body of `unsubscribe linux-arm-kernel' to [email-masked]