hall@nosc.NOSC.MIL (Robert R. Hall) (11/08/88)
I now have the MINIX xt_wini driver working with my RRL disk drive. I am using the seagate ST2238 disk with Western WD-27x controller. The previous problem which the xt_xini.c version 1.3c+ was giving was error message the the hard drive won't reset status: $C0 and error message cant read partition parameters. Then after overcomming these message it then would refuse to mount any file system built on the hard drive. I dissasembled the BIOS ROM at location C800:0000 for examples where correction may be need. The following patch is what I ended up with. You MFM owner check it out for your drives to see if any of my patches cause trouble with you. It would be nice to have only one xt_wini version. --------------------- xt_wini.cdif ----------------------------- *** xt_wini.v3c Thu Oct 13 08:14:22 1988 --- xt_wini.c Mon Nov 7 07:07:40 1988 *************** *** 32,38 #include "type.h" #include "proc.h" ! /*#define AUTO_BIOS TRUE /* TRUE: use Western's autoconfig BIOS */ #define DEBUG FALSE /* TRUE: enable debug messages */ #define MONITOR TRUE /* TRUE: monitor performance of busy loops */ #define MAX_DRIVES 1 --- 32,38 ----- #include "type.h" #include "proc.h" ! #define AUTO_BIOS FALSE /* TRUE: use Western's autoconfig BIOS */ #define DEBUG FALSE /* TRUE: enable debug messages */ #define MONITOR FALSE /* TRUE: monitor performance of busy loops */ #define RRL TRUE /* MFM owners need to set this false */ *************** *** 34,40 /*#define AUTO_BIOS TRUE /* TRUE: use Western's autoconfig BIOS */ #define DEBUG FALSE /* TRUE: enable debug messages */ ! #define MONITOR TRUE /* TRUE: monitor performance of busy loops */ #define MAX_DRIVES 1 /* I/O Ports used by winchester disk task. */ --- 34,41 ----- #define AUTO_BIOS FALSE /* TRUE: use Western's autoconfig BIOS */ #define DEBUG FALSE /* TRUE: enable debug messages */ ! #define MONITOR FALSE /* TRUE: monitor performance of busy loops */ ! #define RRL TRUE /* MFM owners need to set this false */ #define MAX_DRIVES 1 /* I/O Ports used by winchester disk task. */ *************** *** 72,78 /* Parameters for the disk drive. */ #define SECTOR_SIZE 512 /* physical sector size in bytes */ ! #define NR_SECTORS 0x11 /* number of sectors per track */ /* Error codes */ #define ERR -1 /* general error */ --- 73,79 ----- /* Parameters for the disk drive. */ #define SECTOR_SIZE 512 /* physical sector size in bytes */ ! #define NR_SECTORS 26 /* number of sectors per track */ /* Error codes */ #define ERR -1 /* general error */ *************** *** 87,92 #if AUTO_BIOS #define AUTO_PARAM 0x1AD /* drive parameter table starts here in sect 0 */ #define AUTO_ENABLE 0x10 /* auto bios enabled bit from status reg */ /* some start up parameters in order to extract the drive parameter table */ /* from the winchester. these should not need changed. */ #define AUTO_CYLS 306 /* default number of cylinders */ --- 88,94 ----- #if AUTO_BIOS #define AUTO_PARAM 0x1AD /* drive parameter table starts here in sect 0 */ #define AUTO_ENABLE 0x10 /* auto bios enabled bit from status reg */ + #endif /* some start up parameters in order to extract the drive parameter table */ /* from the winchester. these should not need changed. */ #define AUTO_CYLS 613 /* default number of cylinders */ *************** *** 89,95 #define AUTO_ENABLE 0x10 /* auto bios enabled bit from status reg */ /* some start up parameters in order to extract the drive parameter table */ /* from the winchester. these should not need changed. */ ! #define AUTO_CYLS 306 /* default number of cylinders */ #define AUTO_HEADS 4 /* default number of heads */ #define AUTO_RWC 307 /* default reduced write cylinder */ #define AUTO_WPC 307 /* default write precomp cylinder */ --- 91,97 ----- #endif /* some start up parameters in order to extract the drive parameter table */ /* from the winchester. these should not need changed. */ ! #define AUTO_CYLS 613 /* default number of cylinders */ #define AUTO_HEADS 4 /* default number of heads */ #define AUTO_RWC 616 /* default reduced write cylinder */ #define AUTO_WPC 616 /* default write precomp cylinder */ *************** *** 91,98 /* from the winchester. these should not need changed. */ #define AUTO_CYLS 306 /* default number of cylinders */ #define AUTO_HEADS 4 /* default number of heads */ ! #define AUTO_RWC 307 /* default reduced write cylinder */ ! #define AUTO_WPC 307 /* default write precomp cylinder */ #define AUTO_ECC 11 /* default ecc burst */ #define AUTO_CTRL 5 /* default winchester stepping speed byte */ #endif --- 93,100 ----- /* from the winchester. these should not need changed. */ #define AUTO_CYLS 613 /* default number of cylinders */ #define AUTO_HEADS 4 /* default number of heads */ ! #define AUTO_RWC 616 /* default reduced write cylinder */ ! #define AUTO_WPC 616 /* default write precomp cylinder */ #define AUTO_ECC 11 /* default ecc burst */ #define AUTO_CTRL 7 /* default winchester stepping speed byte */ *************** *** 94,101 #define AUTO_RWC 307 /* default reduced write cylinder */ #define AUTO_WPC 307 /* default write precomp cylinder */ #define AUTO_ECC 11 /* default ecc burst */ ! #define AUTO_CTRL 5 /* default winchester stepping speed byte */ ! #endif /* Variables. */ PRIVATE struct wini { /* main drive struct, one entry per drive */ --- 96,102 ----- #define AUTO_RWC 616 /* default reduced write cylinder */ #define AUTO_WPC 616 /* default write precomp cylinder */ #define AUTO_ECC 11 /* default ecc burst */ ! #define AUTO_CTRL 7 /* default winchester stepping speed byte */ /* Variables. */ PRIVATE struct wini { /* main drive struct, one entry per drive */ *************** *** 390,396 /* Strobe reset bit low. */ port_out(WIN_STATUS, 0); ! for(i = MAX_WIN_RETRY/10; i; --i) ; /* Spin loop for a while */ port_out(WIN_SELECT, 0); /* Issue select pulse */ --- 391,397 ----- /* Strobe reset bit low. */ port_out(WIN_STATUS, 0); ! for(i = 0x0584; i; i--) ; /* Spin loop for a while */ for (i = 500; i; i--) { *************** *** 393,400 for(i = MAX_WIN_RETRY/10; i; --i) ; /* Spin loop for a while */ ! port_out(WIN_SELECT, 0); /* Issue select pulse */ ! for (i = 0; i < MAX_WIN_RETRY; i++) { port_in(WIN_STATUS, &r); if(r & 0x30) /* What is 10? 20 = INTERRUPT */ return (ERR); --- 394,401 ----- for(i = 0x0584; i; i--) ; /* Spin loop for a while */ ! for (i = 500; i; i--) { ! port_out(WIN_SELECT, 0); /* Issue select pulse */ port_in(WIN_STATUS, &r); if(r & 0x30) /* What is 10? 20 = INTERRUPT */ return (ERR); *************** *** 404,410 break; } ! if (i == MAX_WIN_RETRY) { printf("Hard disk won't reset, status = %x\n", r); return(ERR); } --- 405,411 ----- break; } ! if (!i) { printf("Hard disk won't reset, status = %x\n", r); return(ERR); } *************** *** 447,453 { /*DEBUG: loop looking for 0x20 in status (I don't know what that is!!) */ /* 10-Apr-87. G. Oliver */ ! int r, i; /* Some local storage */ receive(HARDWARE, &w_mess); --- 448,455 ----- { /*DEBUG: loop looking for 0x20 in status (I don't know what that is!!) */ /* 10-Apr-87. G. Oliver */ ! int r; /* Some local storage */ ! long i; receive(HARDWARE, &w_mess); *************** *** 453,459 port_out(DMA_INIT, 0x07); /* Disable int from DMA */ ! for(i=0; i<MAX_WIN_RETRY; ++i) { port_in(WIN_STATUS, &r); if(r & WST_INTERRUPT) break; /* Exit if end of int */ --- 455,461 ----- port_out(DMA_INIT, 0x07); /* Disable int from DMA */ ! for(i=64000 * 75; i; i--) { port_in(WIN_STATUS, &r); if(r & WST_INTERRUPT) break; /* Exit if end of int */ *************** *** 460,467 } #if MONITOR ! if(i > 10) { /* Some arbitrary limit below which we don't really care */ ! if(i == MAX_WIN_RETRY) printf("wini: timeout waiting for INTERRUPT status\n"); else printf("wini: %d loops waiting for INTERRUPT status\n", i); --- 462,469 ----- } #if MONITOR ! if(i < 64000 * 70) { /* Some arbitrary limit below which we don't really care */ ! if(!i) printf("wini: timeout waiting for INTERRUPT status\n"); else printf("wini: %ld loops waiting for INTERRUPT status\n", *************** *** 464,470 if(i == MAX_WIN_RETRY) printf("wini: timeout waiting for INTERRUPT status\n"); else ! printf("wini: %d loops waiting for INTERRUPT status\n", i); } #endif /* MONITOR */ } --- 466,473 ----- if(!i) printf("wini: timeout waiting for INTERRUPT status\n"); else ! printf("wini: %ld loops waiting for INTERRUPT status\n", ! 64000 * 75 - i); } #endif /* MONITOR */ } *************** *** 660,671 /* Read the switches from the controller */ port_in(WIN_SELECT, &i); - #if AUTO_BIOS - /* Get the drive parameters from sector zero of the drive if the */ - /* autoconfig mode of the controller has been selected */ - - if(i & AUTO_ENABLE) { - /* set up some phoney parameters so that we can read the first sector */ /* from the winchester. all drives will have one cylinder and one head */ /* but set up initially to the mini scribe drives from ibm */ --- 663,668 ----- /* Read the switches from the controller */ port_in(WIN_SELECT, &i); /* set up some phoney parameters so that we can read the first sector */ /* from the winchester. all drives will have one cylinder and one head */ /* but set up initially to the mini scribe drives from ibm */ *************** *** 679,684 wini[DEV_PER_DRIVE].wn_low = wini[0].wn_low = 0L; wini[DEV_PER_DRIVE].wn_size = wini[0].wn_size = (long)AUTO_CYLS * (long)AUTO_HEADS * (long)NR_SECTORS; if(w_reset() != OK) panic("cannot setup for reading winchester parameter tables",0); --- 676,687 ----- wini[DEV_PER_DRIVE].wn_low = wini[0].wn_low = 0L; wini[DEV_PER_DRIVE].wn_size = wini[0].wn_size = (long)AUTO_CYLS * (long)AUTO_HEADS * (long)NR_SECTORS; + #if AUTO_BIOS + /* Get the drive parameters from sector zero of the drive if the */ + /* autoconfig mode of the controller has been selected */ + + if(i & AUTO_ENABLE) { + if(w_reset() != OK) panic("cannot setup for reading winchester parameter tables",0); *************** *** 695,701 panic("cannot read drive parameters from winchester",DEV_PER_DRIVE); /* copy the parameter tables into the structures for later use */ ! copy_param(&buf[AUTO_PARAM], ¶m1); } --- 698,704 ----- panic("cannot read drive parameters from winchester",DEV_PER_DRIVE); /* copy the parameter tables into the structures for later use */ ! copy_params(&buf[AUTO_PARAM], ¶m1); } *************** *** 710,716 panic("cannot read drive parameters from winchester", 0); /* copy the parameter tables into the structures for later use */ ! copy_param(&buf[AUTO_PARAM], ¶m0); /* whoever compiled the kernel wanted the auto bios code included. if it --- 713,719 ----- panic("cannot read drive parameters from winchester", 0); /* copy the parameter tables into the structures for later use */ ! copy_params(&buf[AUTO_PARAM], ¶m0); /* whoever compiled the kernel wanted the auto bios code included. if it *************** *** 720,725 #endif /* Calculate the drive types */ type_0 = i & 3; type_1 = (i >> 2) & 3; --- 723,732 ----- #endif /* Calculate the drive types */ + #if RRL + type_0 = ((~i) >> 4) & 3; + type_1 = type_0; + #else type_0 = i & 3; type_1 = (i >> 2) & 3; #endif *************** *** 722,727 /* Calculate the drive types */ type_0 = i & 3; type_1 = (i >> 2) & 3; /* Copy the parameter vector from the saved vector table */ offset = vec_table[2 * 0x41]; --- 729,735 ----- #else type_0 = i & 3; type_1 = (i >> 2) & 3; + #endif /* Copy the parameter vector from the saved vector table */ offset = vec_table[2 * 0x41]; --------------------------- xt_wini.cdif END ---------------------- Robert R. Hall hall@nosc.mil
ncoverby@ndsuvax.UUCP (Glen Overby) (11/09/88)
In article <803@nosc.NOSC.MIL> hall@nosc.NOSC.MIL (Robert R. Hall) writes: >I now have the MINIX xt_wini driver working with my RRL disk drive. >I am using the seagate ST2238 disk with Western WD-27x controller. >--- 73,79 ----- > > /* Parameters for the disk drive. */ > #define SECTOR_SIZE 512 /* physical sector size in bytes */ >! #define NR_SECTORS 26 /* number of sectors per track */ Caveat: If you have an Adaptec RLL controler, this should be 25 because the controler apparently uses one sector per track for bad-block mapping (yes, one sector per track does seem a bit excessive, but that appears to be the way they're doing it!)