[comp.os.minix] at_wini.c fixes: can't read partition table/can't reset winchester

matt@LOCUS.UCLA.EDU (05/10/87)

Keywords:


-------

This message includes some minor bugfixes to the controller initialization 
code in ``at_wini.c''.  In the system I'm running currently (IBM AT 6MHz
w/70MB Maxtor & 0.5 MB memory), Minix was not able to properly reset the
disk (``couldn't reset winchester 0''), nor was it able to access any 
blocks on the disk (the controller indicated it couldn't find the
appropriate address marks on the disk).

The changes involved problems with the precompensation settings, and I
suspect the 'i<<4' statement in the win_init().  I was able to boot my
wini the first time by simply commenting out the body of the winchester
init routine (and using the BIOS defaults left behind at boot time).

Some of the changes noted below may be unnecessary; I went through a lot
of iterations, and didn't take out all of the changes that might not
have contributed, like a few precomp assignments, etc.

I hope these help those having problems.

					- Matt Weinstein
					  matt @ locus.ucla.edu
					  {backbone}!ucla-cs!matt

The following annotations should provide some help:

Line		Meaning
-------		-------
200c200		The 'ctlbyte' value in the BIOS ROM is supposed to be 
		used for setting the upper wini control register. 

268a269		Delay to allow for reset to complete.  Not sure if this
		is necessary.

294c295,296	Using 'ctlbyte', as noted above.  Also, precomp added,
310c312,313	though may be unnecessary.

297c299		This are the changes posted earlier by Larry Hubble.
313c316

325,327c328,331	'ctlbyte' being used; 'i << 4' may be wrong without any
		drive parameters specified (the 0xA0 that's or'd in
		everywhere specifies sector size and enables ECC);
		RECALIBRATE doesn't want any argument bits (ST607
		drives will run with very fast pulsing); precomp added
		(may be unnecessary).

391d394		style change only; embedded initializer into for loop.
394c397

479c482		error in computing precompensation cylinder.  0xFFFF is
		recorded in the BIOS if no precompensation is required;
		a value of 0xFF is likewise used by the WD controller 
		to indicate no precomp is required.  However, division 
		by 4 turns 0xFFFF (-1) into 0, which is wrong (starts 
		precomp on cylinder 0).

----- diff at_wini.c.old at_wini.c.new -----
200c200
<   command[0] = wn->wn_head & 8;
---
>   command[0] = wn->wn_ctlbyte;
268a269
>   for (i = 0; i < 10000; i++) /*delay added for slow drive -- MJW*/; 
294c295,296
<   command[0] = wini[0].wn_heads & 8;
---
>   command[0] = wini[0].wn_ctlbyte;
>   command[1] = wini[0].wn_precomp;
297c299
<   command[6] = wini[0].wn_heads || 0xA0;
---
>   command[6] = (wini[0].wn_heads - 1) | 0xA0;
310c312,313
< 	command[0] = wini[5].wn_heads & 8;
---
> 	command[0] = wini[5].wn_ctlbyte;
> 	command[1] = wini[5].wn_precomp;
313c316
< 	command[6] = wini[5].wn_heads || 0xA1;
---
> 	command[6] = (wini[5].wn_heads - 1) | 0xB0;
325,327c328,331
< 	command[0] = wini[i*5].wn_heads & 8;
< 	command[6] = i << 4;
< 	command[7] = WIN_RECALIBRATE | (wini[i*5].wn_ctlbyte & 0x0F);
---
> 	command[0] = wini[i*5].wn_ctlbyte;
> 	command[1] = wini[i*5].wn_precomp;
> 	command[6] = i << 4 | 0xA0;
> 	command[7] = WIN_RECALIBRATE;
391d394
< 	r = WIN_REG2;
394c397
< 	for (i=1; i<8; i++, r++)
---
> 	for (i=1, r = WIN_REG2; i<8; i++, r++)
479c482
< 	dest[i].wn_precomp = *(int *)&src[5] / 4;
---
> 	dest[i].wn_precomp = *(int *)&src[5] >> 2;