[comp.os.minix] at_wini patches for 6 and 8 mhz PC-AT

Leisner.Henr@xerox.com (Marty) (08/16/89)

Enclosed are diffs so the 1.3b winchester driver will run successfully on
both 6 and 8 Mhz ATs.  I haven't tried this on any other machines yet, but
I know from experience the AT driver is a problem.  I've looked at the
v1.3c and v1.4a diff packages, and they don't seem to address these
changes.

I initially made these changes to 1.1 -- I guess they never got into the
distribution.

I initially made these changes by looking at the Western Digital specs
(which ain't very clear) and the AT Bios from the Technical Reference --
unfortunately I don't have the Bios listing anymore so I'll try to replay
this from memory.

In com_out() I replaced if(drive_busy()) with a call to a new function:
if(controller_busy())

Drive_busy does the following test on the winchester status register (port
0x1f7)

  for (i = 0, r = 255; i<MAX_WIN_RETRY && (r&0x80) != 0; i++)
	port_in(WIN_REG8, &r);
  if ((r&0x80) != 0 || (r&0x40) == 0 || (r&0x10) == 0) {
	w_need_reset = TRUE;
	return(ERR);
  }
  return(OK);

This in somewhat modified form reduces to (from another at driver I have
lying around)
        if((r & STATUS_BSY) || !(r & STATUS_RDY) || !(r & STATUS_SC))    
which infers a SEEK_COMPLETE.  However, if we haven't seeked, it probably
will fail.

Actually, the 1.3b driver worked once on my 8 Mhz AT (I actually ran
fdisk).  When I rebooted, it wouldn't read the disk anymore.

This seems to be working consistently.  If anyone has any
comments/suggestions, they're welcome.
I'm pretty miffed with the status of the AT driver.


*** at_wini.c	Tue Aug  8 13:29:07 1989
--- my_at_wini.c	Fri Aug 11 15:35:52 1989
***************
*** 359,364 ****
--- 359,385 ----
    return(OK);
  }
  
+ 
+
/*============================================================================*
+  *				controller_busy				      *
+
*============================================================================*/
+ 
+ PRIVATE controller_busy()
+ {
+ 
+   /* test if controller is busy */
+   register int i = 0;
+   int r;
+ 
+   for(i = 0; i < 1000; i++) {
+   	port_in(WIN_REG8, &r);
+ 	if(!(r & 0x80))
+ 		return OK;
+   }
+   
+   return ERR;
+ }
+ 

/*============================================================================*
   *				drive_busy				      *

*============================================================================*/
***************
*** 388,397 ****
  	register int i, old_state;
  	int r;
  
! 	if (drive_busy()) {
  		w_need_reset = TRUE;
  		return(ERR);
  	}
  	r = WIN_REG2;
  	old_state = lock();
  	port_out(WIN_REG9, command[0]);
--- 409,420 ----
  	register int i, old_state;
  	int r;
  
! 	if (controller_busy()) {
! 		printf("controller busy failed in com_out\n");
  		w_need_reset = TRUE;
  		return(ERR);
  	}
+ 	
  	r = WIN_REG2;
  	old_state = lock();
  	port_out(WIN_REG9, command[0]);


marty
ARPA:	leisner.henr@xerox.com
GV:  leisner.henr
NS:  leisner:wbst139:xerox
UUCP:	hplabs!arisia!leisner
 

rbthomas@athos.rutgers.edu (Rick Thomas) (08/16/89)

We built a kernel with the listed patches (bare bonez 1.3PH [Prentice
Hall] except for the patches).  After dealing with complaints from
"patch" that the cdiff file was malformed (it is -- something is not
dealing correctly with the long comment lines.  Marty, did you create
that with Minix cdiff, or something else?) we got it to compile and
make an image.

The image booted and read the disk on the Zenith 286 that we originally
built it on, and on an (allegedly 8MHz) IBM/AT that had been giving us
problems upto now.  On the AT, we ran "dd if=/dev/hd0 of=/dev/null",
and it read fine for a long time but eventually crapped out with an IO
error, which may have been a genuine bad block.  We need to explore
further.

Rick
-- 

Rick Thomas
uucp: {ames, att, harvard}!rutgers!jove.rutgers.edu!rbthomas
internet: rbthomas@JOVE.RUTGERS.EDU
bitnet: rbthomas@zodiac.bitnet
Phone: (201) 932-4301

ast@cs.vu.nl (Andy Tanenbaum) (08/20/89)

In article <21763@louie.udel.EDU> Leisner.Henr@xerox.com (Marty) writes:
>Enclosed are diffs so the 1.3b winchester driver will run successfully on
>both 6 and 8 Mhz ATs.  I haven't tried this on any other machines yet, but
>I know from experience the AT driver is a problem.  

The at_wini.c driver is unfortunately very fragile.  I didn't write it, and
the student who did, has long vanished.  I am very hesitant to tinker with
it any more, since any change may break machines where it did work.  If the
net can collectively come up with a version that is better than the current
one in the sense of working on more machines, I'm certainly interested, but
it has to be thoroughly tested.

On the subject of disk performance, the single-threadedness of MINIX was
mentioned, but that is irrelevant, as MS-DOS is also single threaded.  It
is my suspicion that the performance loss is mostly due to a poor choice
of interleaving.  The drivers actually have a provision for software
interleaving.  Maybe somebody could experiment with it.  Another interesting
test is a large number of random reads to see how MINIX does against
MS-DOS.  If the blocks read are not consecutive, but randomly strewn over
the disk surface, interleaving won't be an issue.

Andy Tanenbaum (ast@cs.vu.nl)