donn (02/02/83)
References: rabbit.1079
I think this bug is a common one among the drivers in this family.
Here is my response to someone else's complaint:
From donn Tue Oct 5 17:41:53 1982
To: rusty
Subject: up%d: not ready
Cc: jmcg
If you have two or more drives on one controller, I may have an answer
to your problem. I had similar troubles with the Xylogics driver when
we brought up drive 1 on sdchemc: we would get "xp%d: not ready" errors
by the dozen. This turned out to be due to a queuing goof in the
Xylogics driver -- the driver would have service pending on two drives,
a seek done interrupt would come in on one drive and the driver would
proceed to link in the request queue for the other drive. If the one
drive was still seeking then you would get "not ready" errors. The fix
I put into the xy driver was clumsy but effective: if the seeking bit
in the ds register is still on for a drive when we loop in the
interrupt routine looking for drives to service, then we skip that
drive. (Eventually the seek on that drive will finish and we'll get an
interrupt.) From my casual perusal of the up driver it looks like this
is a possible explanation for its problems -- the difference being that
the up driver checks the ready bit again after printing the "not ready"
message, by which time the seek may have finished, hence the "(flakey)"
addendum. To find out whether the drive is seeking it looks like you
just select the drive and check (ready and) PIP. You can look at the
current xy driver source over here if you want. Hope this helps.
Donn
Here is my attempt at a patch. It does not require disabling
overlapped seeks. THIS IS NOT RUNNING CODE, although the corresponding
part of the Xylogics 211 driver works fine. If my analysis is wrong
I'd appreciate hearing about it... The additions in the following code
in upintr from up.c are marked with !:
doattn:
/*
* Process other units which need attention.
* For each unit which needs attention, call
* the unit start routine to place the slave
* on the controller device queue.
*/
while (unit = ffs(as)) {
unit--; /* was 1 origin */
as &= ~(1<<unit);
! if ( (upaddr->upcs2 & 0x7) != unit )
! upaddr->upcs2 = unit; /* Select drive */
! if (upaddr->upds & UPDS_PIP) /* Seeking? */
! continue; /* Oops! */
upaddr->upas = 1<<unit;
if (upustart(upip[sc21][unit]))
needie = 0;
}
Donn Seeley UCSD Chemistry Dept. RRCF ucbvax!sdcsvax!sdchema!donn
(619) 452-4016 sdamos!donn@nprdc