[net.bugs.4bsd] 4.1bsd/up.c bug

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