[2475] in linux-scsi channel archive
AHA-152X Command-Phase hung..?
daemon@ATHENA.MIT.EDU (Jukka Tapani Santala)
Wed Sep 17 08:42:53 1997
Date: Wed, 17 Sep 1997 11:32:14 +0300 (EET DST)
From: Jukka Tapani Santala <e75644@UWasa.Fi>
To: linux-scsi@vger.rutgers.edu
cc: fischer@et-inf.fho-emden.de
Using AHA-1520 on 486/50Mhz with 2.1.55 (Driver-version 1.7), I've been
continuously annoyed by getphase() making itself on the top of the
profile-list, usualyl taking more than half of the kernel CPU etc. So, I
finally started looking for solution - I didn't find one, but I did find
various tips that may tell something to those better versed in SCSI
technology. Basically, the CPU-hog traces into...
// drivers/scsi/aha152x.c:aha152x_intr() :
/* wait for data latch to become ready or a phase change */
while(TESTLO(DMASTAT, INTSTAT))
barrier();
for(i=0; i<CURRENT_SC->cmd_len && TESTLO(SSTAT1, PHASEMIS); i++) {
SETPORT(SCSIDAT, CURRENT_SC->cmnd[i]);
make_acklow(shpnt);
getphase(shpnt); /* <--- Here! */
}
...and to be even more specific, this "hung" happens on the last
recursion thru the loop, and we can even point out the specific
instruction. (In other words, it takes _ages_ for the condition to be met).
// drivers/scsi/aha152x.c:getphase() :
while(1) { /* There... */
do { /* v v v v v v v v */
while(!((sstat1 = GETPORT(SSTAT1)) & (BUSFREE|SCSIRSTI|REQINIT)))
barrier();
if(sstat1 & BUSFREE)
return P_BUSFREE;
if(sstat1 & SCSIRSTI) {
printk("aha152x: RESET IN\n");
SETPORT(SSTAT1, SCSIRSTI);
}
} while(TESTHI(SCSISIG, ACKI) || TESTLO(SSTAT1, REQINIT));
...my personal solution to this problem was removing the last getphase()
check altogether [if(i<(CURRENT_SC->cmd_len-1)) getphase(shpnt);],
however I'm well aware this is not the _right_ solution and leads into
severe risk of data-loss etc. but I'm not so sure the original code is
neccessarily much better either, so I'm enjoying the _hugely_ improved
responsiveness during disk-operations and actually _working_ swap this
little fix provided on my machine. Not recommended for others, though ;)
However, being the perfectionsit that I am, I'm looking into finding out
what would be the right fix/solution to this problem. Unfortunately, I
couldn't get my hands on any SCSI-specs, so I'm throwing the problem out
to the folks on this list in hopes that somebody has the right solution.
Oh, and by the way, yes the assumption of the problem is correct, as
proven by the fact that my "quick fix" worked (Actually I used
kernel-profiler with inlined functions & branched execution to find out
where the kernel was spending it's time, but that's neither here or
there;). Thanks in advance.
-Donwulff
Our cause is a secret within a secret,
a secret that only another secret can explain;
it is a secret about a secret veiled by a secret.