Here is a short patch for actually letting dma_cache_inv use
invalidate. As it might happen if we are not cache-line aligned
we need to flush the non-aligned start and end. To take that decision
might actually take longer than just flush it thus we simply do it.
This would make the case for size<=dc_lsize slower by the factor
of a cache_flush on a non-dirty line. I would consider this the
non common case because using DMA for something <= dc_lsize is also
a not very optimal decision.
Currently i am unsure about interlocking/timing on 2 cache instructions on
the same cache line and i have no documentation at hand. Probably
its better to put the flush_dcache behind the while loop. I would
be happy to hear comments on this.
I am currently running my test again although it might be as Ralf
pointed out that this only might lead to problems on devices like
tape streamers. If anyone has a streamer handy i would be happy
to hear experiences.
If i would have known how to interpret HPC3 documentation you would not
have to apply the other attached patch - But as life goes i was able
to detect my own disability by filesystem corruption :)
Index: arch/mips/mm/c-r4k.c
===================================================================
RCS file: /cvs/linux/arch/mips/mm/c-r4k.c,v
retrieving revision 1.3
diff -u -r1.3 c-r4k.c
--- arch/mips/mm/c-r4k.c 2001/11/30 13:28:06 1.3
+++ arch/mips/mm/c-r4k.c 2001/12/14 02:20:20
@@ -1211,9 +1211,14 @@
a = addr & ~(dc_lsize - 1);
end = (addr + size) & ~(dc_lsize - 1);
- while (1) {
- flush_dcache_line(a); /* Hit_Writeback_Inv_D */
- if (a == end) break;
+
+ flush_dcache_line(a); /* Hit_Writeback_Inv_D */
+ flush_dcache_line(end);
+
+ a+=dc_lsize;
+
+ while (a<end) {
+ invalidate_dcache_line(a); /* Hit_Invalidate_D */
a += dc_lsize;
}
__restore_flags(flags);
@@ -1234,9 +1239,14 @@
a = addr & ~(sc_lsize - 1);
end = (addr + size) & ~(sc_lsize - 1);
- while (1) {
- flush_scache_line(a); /* Hit_Writeback_Inv_SD */
- if (a == end) break;
+
+ flush_scache_line(a); /* Hit_Writeback_Inv_SD */
+ flush_scache_line(end);
+
+ a+=sc_lsize;
+
+ while (a<end) {
+ invalidate_scache_line(a); /* Hit_Invalidate_SD */
a += sc_lsize;
}
}
Index: drivers/scsi/sgiwd93.c
===================================================================
RCS file: /cvs/linux/drivers/scsi/sgiwd93.c,v
retrieving revision 1.28.2.2
diff -u -r1.28.2.2 sgiwd93.c
--- drivers/scsi/sgiwd93.c 2001/12/13 20:08:36 1.28.2.2
+++ drivers/scsi/sgiwd93.c 2001/12/14 03:33:36
@@ -142,10 +142,10 @@
/* Start up the HPC. */
hregs->ndptr = PHYSADDR(hdata->dma_bounce_buffer);
if(datainp) {
- dma_cache_wback_inv((unsigned long) cmd->SCp.ptr, cmd->SCp.this_residual);
+ dma_cache_inv((unsigned long) cmd->SCp.ptr, cmd->SCp.this_residual);
hregs->ctrl = (HPC3_SCTRL_ACTIVE);
} else {
- dma_cache_inv((unsigned long) cmd->SCp.ptr, cmd->SCp.this_residual);
+ dma_cache_wback_inv((unsigned long) cmd->SCp.ptr, cmd->SCp.this_residual);
hregs->ctrl = (HPC3_SCTRL_ACTIVE | HPC3_SCTRL_DIR);
}
--
Florian Lohoff flo@rfc822.org +49-5201-669912
Nine nineth on september the 9th Welcome to the new billenium
PGP signature