Yesterday I managed to coax my hard drive into seeking at maximum
speed. Here are the patches to wd.c and wd.h. They also limit read and
write operations to a single track, because my drive obviously had
trouble with track switching.
*** wd.c	1993/08/02 20:17:07	1.5
--- wd.c	1993/09/08 23:06:42
***************
*** 14,21 ****
  static int wd_cmd(int);
  static void wd_start(), wd_readp(int), wd_cmos(int),
          wd_parseparms(int, char *);
  
! uint first_unit;		/* Lowerst unit # configured */
  
  /*
   * The parameters we read on each disk, and a flag to ask if we've
--- 14,22 ----
  static int wd_cmd(int);
  static void wd_start(), wd_readp(int), wd_cmos(int),
          wd_parseparms(int, char *);
+ static void wd_calibrate (int);
  
! uint first_unit;		/* Lowest unit # configured */
  
  /*
   * The parameters we read on each disk, and a flag to ask if we've
***************
*** 23,28 ****
--- 24,30 ----
   */
  struct wdparms parm[NWD];
  char configed[NWD];
+ char calibrated[NWD];
  
  /*
   * Miscellaneous counters
***************
*** 160,165 ****
--- 162,168 ----
                  if (configed[unit]) {
                          uint s = parm[unit].w_size * SECSZ;
                          const uint m = 1024*1024;
+ 			int	status;
  
                          printf("wd%d: %d.%dM\n", unit,
                                  s / m, (s % m) / (m/10));
***************
*** 167,172 ****
--- 170,176 ----
                          if (unit < first_unit) {
                                  first_unit = unit;
                          }
+ 			wd_calibrate (unit);
                  }
          }
          if (!found_first) {
***************
*** 239,249 ****
          /*
           * Given disk geometry, calculate parameters for next I/O
           */
          cyl =  cur_sec / w->w_secpercyl;
          sect = cur_sec % w->w_secpercyl;
- 	lsect = w->w_secpercyl - sect;
          trk = sect / w->w_secpertrk;
          sect = (sect % w->w_secpertrk) + 1;
  
          /*
           * Transfer size--either the rest, or the remainder of this track
--- 243,255 ----
          /*
           * Given disk geometry, calculate parameters for next I/O
           */
+ 
+ 	if (!calibrated [cur_unit]) wd_calibrate (cur_unit);
          cyl =  cur_sec / w->w_secpercyl;
          sect = cur_sec % w->w_secpercyl;
          trk = sect / w->w_secpertrk;
          sect = (sect % w->w_secpertrk) + 1;
+ 	lsect = w->w_secpertrk + 1 - sect;
  
          /*
           * Transfer size--either the rest, or the remainder of this track
***************
*** 564,566 ****
--- 570,630 ----
          w->w_size = w->w_secpercyl * w->w_cyls;
          configed[unit] = 1;
  }
+ 
+ /* 
+  * specify: part one of drive calibration
+  */
+ 
+ static void wd_specify (int unit) {
+ 
+ 	cur_op = WDC_SPECIFY;
+ 	outportb(WD_PORT+WD_CTLR, 0); 
+ 	outportb(WD_PORT+WD_ERROR, 0xFF); 
+ 	outportb(WD_PORT+WD_SCNT, parm[unit].w_secpertrk);
+ 	outportb(WD_PORT+WD_SNUM, 0);
+ 	outportb(WD_PORT+WD_CYL0, 0);
+ 	outportb(WD_PORT+WD_CYL1, 0);
+ 	outportb(WD_PORT+WD_SDH,
+ 		WDSDH_EXT|WDSDH_512 | parm[unit].w_tracks | (unit << 4));
+ 	outportb(WD_PORT+WD_CMD,
+ 		WDC_SPECIFY);
+ }
+ 
+ /*
+  * calibrate: part two of drive calibration
+  */
+ 
+ static void
+ wd_calibrate (int unit)
+ {
+ 	int	status;
+ 
+ 	cur_op = WDC_CALIBRATE;
+ 	outportb(WD_PORT+WD_CTLR, 0); 
+ 	outportb(WD_PORT+WD_ERROR, 0xFF); 
+ 	outportb(WD_PORT+WD_SCNT, parm[unit].w_secpertrk);
+ 	outportb(WD_PORT+WD_SNUM, 0);
+ 	outportb(WD_PORT+WD_CYL0, 0);
+ 	outportb(WD_PORT+WD_CYL1, 0);
+ 	outportb(WD_PORT+WD_SDH,
+ 		WDSDH_EXT|WDSDH_512 | 0 | (unit << 4));
+ 	outportb(WD_PORT+WD_CMD, WDC_CALIBRATE);
+ 
+ 	while (inportb (WD_PORT+WD_STATUS) & WDS_BUSY);
+ 	status = inportb (WD_PORT+WD_STATUS);
+ 	if (status & WDS_ERROR) {
+ 		printf ("calibrate %d: status %x, error %x\n",	
+ 			unit, status, inportb (WD_PORT+WD_ERROR));
+ 	} else {
+ 		calibrated [unit] = 1;
+ 	}
+ }
+ 
+ char wd_c_rcs_id [] =
+ 	"$Id: wd.c 1.5.1.1 1993/09/08 23:04:51 hjp Exp $";
+ /* $Log: wd.c $
+  * Revision 1.5.1.1  1993/09/08  23:04:51  hjp
+  * Added calibration at start to set step rate to fastest value.
+  * Limited read ops to one track to avoid read errors at start of track.
+  *
+  */
*** wd.h	1993/08/02 20:17:58	1.4
--- wd.h	1993/09/08 23:08:42
***************
*** 2,8 ****
  #define _WD_H
  /*
   * wd.h
!  *	Wester Digital ST-506 type hard disk interface definitions
   */
  #include <sys/types.h>
  #include <sys/perm.h>
--- 2,8 ----
  #define _WD_H
  /*
   * wd.h
!  *	Western Digital ST-506 type hard disk interface definitions
   */
  #include <sys/types.h>
  #include <sys/perm.h>
***************
*** 36,43 ****
--- 36,47 ----
   * Status bits
   */
  #define WDS_ERROR	0x1	/* Error */
+ #define WDS_INDEX	0x2	/* Index pulse */
  #define WDS_ECC		0x4	/* Soft ECC error */
  #define WDS_DRQ		0x8	/* Data request */
+ #define WDS_SEEKCMPL	0x10	/* Seek completed */
+ #define WDS_WRITEFLT	0x20	/* Write fault */
+ #define WDS_READY	0x40	/* Ready (obviously not the same as not busy) */
  #define WDS_BUSY	0x80	/* Busy */
  
  /*
***************
*** 56,65 ****
  /*
   * Commands
   */
! #define WDC_READ	0x20	/* Command: read */
  #define WDC_WRITE	0x30	/*  ...write */
  #define WDC_READP	0xEC	/*  ...read parameters */
- #define WDC_DIAG	0x90	/* Run controller diags */
  
  /*
   * Read parameters command (WDC_READP) returns this.  I think this
--- 60,71 ----
  /*
   * Commands
   */
! #define WDC_CALIBRATE	0x10	/* Command: calibrate */
! #define WDC_READ	0x20	/*  ...read */
  #define WDC_WRITE	0x30	/*  ...write */
+ #define WDC_DIAG	0x90	/*  ...run controller diags */
+ #define WDC_SPECIFY	0x91	/*  ...specify parameters */
  #define WDC_READP	0xEC	/*  ...read parameters */
  
  /*
   * Read parameters command (WDC_READP) returns this.  I think this
***************
*** 159,163 ****
--- 165,176 ----
  extern void wd_init(int, char **);
  extern void iodone();
  extern char configed[];
+ 
+ /* $Id: wd.h 1.4.1.1 1993/09/08 23:08:19 hjp Exp $
+  * $Log: wd.h $
+  * Revision 1.4.1.1  1993/09/08  23:08:19  hjp
+  * add calibrate and specify commands and missing bits from status
+  *
+  */
  
  #endif /* _WD_H */
-- | _ | Peter J. Holzer | Think of it | | |_|_) | Technical University Vienna | as evolution | | | | | Computer Science/Real-Time Systems | in action! | | __/ | hp@vmars.tuwien.ac.at | Tony Rand |Received on Thu Sep 9 04:38:32 1993
This archive was generated by hypermail 2.1.8 : Wed Sep 21 2005 - 19:37:12 PDT