home *** CD-ROM | disk | FTP | other *** search
- /* EIDEtest 1.5
- Tests if simultaneous I/O corrupts disk reading. If so, likely causes are the
- PCI RZ-1000 EIDE chip, the CMD PCIO640B EIDE chip or a faulty DMA controller.
- Runs under DOS, DESQview, Windows, NT and OS/2 in DOS emulation mode.
-
- This program may be copied freely and used for any purpose except military.
- (c) copyright 1995 by
- Roedy Green
- Canadian Mind Products
- #601 - 1330 Burrard Street
- Vancouver, BC Canada V6Z 2B8
- (604) 685-8412
- Internet Roedy@bix.com
-
- compiled under SMALL model
-
- It works by writing a file with no I/O interfering, then
- reads it back multiple times with as much DMA as possible
- interfering. It ensures the same pattern written comes back.
-
- This code is written in an extremely pedestrian C-like way. My intent was
- that the widest audience of programmers should understand it,
- and to make it as easy as possible to port to other operating systems.
-
- Version history
-
-
- 1.5 - correct minor typos in the prompts.
- focus on simultaneous floppy/tape I/O.
-
- 1.4 - make mention also of the flawed CMD PCIO640B chip
- - Suggest running modem, mouse, sound card as well.
- - Warning that a pass does not mean a perfect chip.
-
- 1.3 - give different prompts on which background tests to
- use depending on which OS you are using.
- Make clear you must turn on simultaneous I/O in backup.
-
- 1.2 - give proper fail if wrong length read comes back.
- - Formerly code was hidden by an ill-formed comment.
- - lint tidy up.
- - Change prompts to indicate new understanding that
- - simultaneou DMA rather than interrupts trigger the flaw.
- - Allow abort at each prompt.
- - Extra pause at the start.
- - More status messages.
- - Re-order routines top-down.
- - clear screen at various stages to hide previous prompts.
- - ack invalid ignored keystrokes with a beep
-
- 1.1 - get rid of all 8-bit chars in source
- - run test indefinitely, till the user hits ESC
- - more elaborate prompting.
-
- 1.0 - first release beta.
-
- */
-
- /* ***************************************** */
-
- /* D E F I N E S */
-
- /* By redefining these constants, you could create a program to test a
- floppy. You would need to use a smaller file, and turn off caching on
- the floppy. */
-
- #define BufferSizeInWords 15872
- #define BufferSizeInBytes 31744
- /* size of buffer for write/reading the file.
- This size should generate lots of physical I/O.
- Smaller sizes might come out of cache.
- Bigger sizes do only a few big I/Os */
-
- #define NumChunks 240
- /* size of test file in blocks. Size in bytes is 240 * 31744 = 7,618,560.
- File must be bigger than cache, or little physical I/O will occur */
-
- #define WORD unsigned short
-
- #define StartDecorate "\xb0\xb1\xb2\xdb"
- /* line of pretty blobs in oemfont to attract attention */
- #define EndDecorate "\xdb\xb2\xb1\xb0"
-
- #define Esc '\x1b'
-
- /* ***************************************** */
-
- /* I N C L U D E S */
-
- #include <stdlib.h>
- // e.g. exit
-
- #include <stdio.h>
- // e.g. FILE, printf, fopen
-
- #include <conio.h>
- // e.g. getch kbhit crlscr
-
- #include <alloc.h>
- // e.g. malloc free
-
- /* ***************************************** */
-
- /* G L O B A L S */
-
- FILE *TempFile;
- /* temporary Test file */
-
- char TempFileName[] = "C:\\EIDETEST.TMP";
- /* name of the temporary file on an EIDE drive */
-
- WORD *Buffer;
- /* buffer for I/O on TempFile */
-
- /* ***************************************** */
-
- /* P R O T O T Y P E S */
-
- int main( int argc, char *argv[] );
- void banner ( void );
- int Phase1 ( void );
- int Phase2 ( void );
- void DisplayResults( int RetCode );
-
- void beep (void );
- int pause ( void );
- int DoesOSDoSimultaneousIO ( void );
- int CheckForEsc ( void );
-
- /* ***************************************** */
-
- /* F U N C T I O N D E F I N I T I O N S */
-
- int main( int argc, char *argv[] )
-
- {
- int RetCode = 0;
-
- banner();
-
- /* allocate RAM for buffer */
- Buffer = (WORD *) malloc( BufferSizeInBytes );
- if ( Buffer == 0)
- {
- printf("Oops! not enough RAM to run the test.");
- exit (2);
- }
-
- if ( argc != 2 /* 0=EIDEtest.Exe 1=C: */ )
- {
- printf("Oops! usage: EIDEtest C:"
- "\nwhere C: is the EIDE hard drive to test.");
- exit (2);
- }
-
- /* replace first letter of TempFilename with Drive Letter */
- /* e.g. TempFileName might now read: D:\EIDETEST.TMP */
- TempFileName[0] = *argv[1];
-
- printf("\nTesting by writing and reading file %s"
- "\nwhich will need %lu bytes."
- "\nThe test will not prove anything unless this file is on an EIDE hard disk.\n",
- TempFileName, (long) NumChunks * (long) BufferSizeInBytes);
-
- if ( pause() == 2 ) RetCode = 2; /* user ESC abort */
-
- /* Stop processing when non-zero RetCode indicates trouble */
-
- /* do Phase 1 */
- if (RetCode == 0) RetCode = Phase1();
- beep(); /* announce Phase1 over */
-
- /* do Phase 2 */
- if (RetCode == 0) RetCode = Phase2();
- beep(); /* announce Phase2 over */
-
- DisplayResults(RetCode); /* report good or bad news */
-
- /* We are now done without background I/O, so these should be safe. */
- fclose(TempFile);
- unlink(TempFileName);
- free (Buffer);
-
- return RetCode;
-
- } /* end main */
-
- /* ***************************************** */
-
- void banner(void)
- {
- /* display copyright banner. */
-
- clrscr(); /* clear screen */
-
- printf("\n" StartDecorate " EIDEtest 1.5 " EndDecorate
- "\n"
- "\nFreeware to test for the flawed EIDE controllers such as the"
- "\nPC-Tech RZ-1000 and the CMD PCIO640B."
- "\nRuns under DESQview, Windows, Windows For WorkGroups, Windows-95, NT"
- "\nand OS/2 all in DOS emulation mode."
- "\n"
- "\nCopyright (c) 1995 Canadian Mind Products"
- "\n#601 - 1330 Burrard Street, Vancouver BC CANADA V6Z 2B8 (604) 685-8412"
- "\nInternet: Roedy@bix.com <Roedy Green>"
- "\nMay be used freely for non-military use only."
- "\n\n");
-
- } /* end banner */
-
- /* ***************************************** */
-
- int Phase1 ( void )
-
- { /* returns:
- 0 = ok
- 1 = failed
- 2 = could not run test */
-
- WORD Chunk; /* indexing chunks/blocks of file */
- WORD i; /* indexing chars in buffer */
-
-
- clrscr(); /* clear screen */
-
- printf("\n" StartDecorate " PHASE 1 " EndDecorate
- "\n"
- "\nDuring phase 1, do not run any other programs."
- "\nEspecially avoid using the tape or floppy drive."
- "\nShutdown all background programs BEFORE you proceed."
- "\nIf you can't get them all, not to worry;"
- "\nthe test results will still be valid."
- "\n");
-
- if ( pause() == 2 )
- return 2; /* user abort */
-
- printf("\nPhase 1 in progress. Please stand by...\n");
-
- /* create a temporary file */
- TempFile = fopen(TempFileName,"w+b"); /* create binary mode */
- if (TempFile == 0 )
- {
- return 2; /* Failed to create test file */
- }
-
- /* fill buffer with pattern */
- for ( i=0 ; i < BufferSizeInWords ; i++ )
- { Buffer [i] = i;}
-
- /* write a test file full of a set pattern */
-
- for ( Chunk=0 ; Chunk < NumChunks ; Chunk++ )
- {
-
- if (fwrite(Buffer, BufferSizeInBytes , 1, TempFile) != 1)
- {
- return 2; /* could not create test file */
- }
- }
- /* all ok */
- return 0;
-
- } /* end Phase1 */
-
- /* ***************************************** */
-
- int Phase2 ( void )
-
- { /* returns:
- 0 = ok
- 1 = failed
- 2 = could not run test */
-
- WORD Chunk; /* indexing chunks/blocks of file */
- WORD i; /* indexing chars in buffer */
- switch (DoesOSDoSimultaneousIO())
- {
-
- case 0: /* DOS */
- clrscr(); /* clear screen */
- printf( "\n" StartDecorate " PHASE 2 " EndDecorate
- "\n"
- "\nDURING phase 2, do as many of these tests as you can"
- "\nto generate simultaneous I/O:"
- "\n"
- "\n- Backup some files to floppy with MWBackup, MSBackup, Norton Backup"
- "\n or other high performance floppy backup program with fast-mode"
- "\n simultaneous disk I/O configured."
- "\n- Backup a file using your mag tape backup software with fast-mode"
- "\n simultaneous disk I/O configured."
- "\n- Exercise any simultaneous I/O devices e.g. modem, mouse or sound card."
- "\n");
- break;
-
- case 1: /* OS */
- clrscr(); /* clear screen */
- printf( "\n" StartDecorate " PHASE 2 " EndDecorate
- "\n"
- "\nDURING phase 2, do as many of these tests as you can"
- "\nto generate simultaneous I/O:"
- "\n"
- "\n- Format a floppy."
- "\n- Backup some files to floppy with MWBackup, MSBackup, Norton Backup"
- "\n or other high performance floppy backup program with fast-mode"
- "\n simultaneous disk I/O configured."
- "\n- Backup a file using your mag tape backup software with fast-mode"
- "\n simultaneous disk I/O configured."
- "\n- Scan a document with your scanner."
- "\n- Browse some files on other hard disks and CD-ROM."
- "\n- Exercise any simultaneous I/O devices e.g. modem, mouse or sound card."
- "\n");
- break;
-
- case 2: /* esc */
- return 2;
- }
-
-
- printf("\nYour experiments may run slowly because of EIDEtest's disk overhead."
- "\n"
- "\nBEGIN YOUR EXPERIMENTS NOW!"
- "\n"
- "\nTake all the time you want -- days even."
- "\nWhen you have FINISHED your experiments, come back and hit the space bar."
- "\n"
- "\nPhase 2 in progress..."
- "\n");
-
- /* read a test file full of the test pattern, over and over */
- /* keep going till user hits Esc */
-
- while ( 1 )
- {
-
- /* seek to the beginning of the file */
- fseek(TempFile, SEEK_SET, 0);
-
- for ( Chunk=0 ; Chunk < NumChunks ; Chunk++)
- {
- if (CheckForEsc())
- {
- /* all went well, we ran without incident until the user hit space or ESC */
- return 0; /* EXIT */
- }
- if (fread(Buffer, BufferSizeInBytes, 1, TempFile) != 1)
- {
- /* File corrupted */
- return 1; /* EXIT */
- }
- /* check that buffer is same pattern as written */
- for ( i=0 ; i < BufferSizeInWords ; i++ )
- {
- if (Buffer [i] != i)
- {
- /* discrepancy detected */
- return 1; /* EXIT */
- }
- }
- }
- } /* end while forever */
-
- /* never get here */
-
- } /* end Phase2 */
-
- /* ***************************************** */
-
- void DisplayResults( int RetCode )
- {
- /* display results of the test */
- /* 0 = test ok
- 1 = fail
- 2 = could not run test */
-
- clrscr(); /* clear screen */
-
- printf( "\n" StartDecorate " TEST RESULTS " EndDecorate
- "\n\n");
-
- switch (RetCode)
- {
- case 0:
- printf("\n\nEIDEtest passed. No flaws found."
- "\nYou may still have a flawed EIDE controller chip with a"
- "\nsuccessful software bypass."
- "\nKeep in mind, that unless you carefully followed the"
- " instructions on the,"
- "\nscreen, the results of this test are meaningless."
- "\n");
- break;
-
- case 1:
- printf("\n\nEIDEtest failed."
- "\nIf you have a PCI motherboard the failure is probably due to a faultly"
- "\nPC-Tech RZ-1000 or CMD PCIO640B EIDE controller chip."
- "\nIt could also be due to overheating, a faulty DMA controller,"
- "\nor software bugs."
- "\nPlease ensure you have stopped all your experiments that were"
- "\ngenerating background I/O activity.");
- break;
-
- case 2:
- default:
- printf("\n\nEIDEtest could not be run."
- "\nPossibly a user abort or problems creating the test file."
- "\nProbably not enough room on the test disk drive."
- "\n");
- break;
-
- }
- printf("\nPlease admire the test results.\n");
- pause();
-
- } /* end DisplayResults */
-
- /* ***************************************** */
-
- void beep (void)
- {
- /* long beep to attract attention */
- printf("\x07\x07\x07\x07");
-
- } /* end beep */
-
- /* ***************************************** */
-
- int pause (void)
- {
- /*
- returns 1=user hit space
- returns 2=user hit ESC
- */
- int Result = 0;
- /* pause until the user hits the space bar */
- printf ("\nWhen you are ready to proceed, hit the space bar; hit ESC to abort");
-
- while (!Result)
- {
- switch (getch())
- {
- case ' ':
- Result = 1; /* space we are done */
- break;
- case Esc:
- Result = 2; /* Esc, Abort */
- break;
- default:
- printf("\x07" ); /* beep to indicate char ignored. */
- break;
- }
- }
- printf("\r \n\n");
- /* erase the prompt line, to acknowledge the space bar */
- return Result;
-
- } /* end pause */
-
- /* ***************************************** */
-
- int DoesOSDoSimultaneousIO (void)
- {
- /*
- returns 0= no, DESQiew, Windows,...
- returns 1= yes. OS/2, NT...
- returns 2=user hit ESC
- */
- int Result = -1;
-
- printf( "\nDoes your operating system do more than one I/O at a time?"
- "\nAnswer N for DOS, DESQview, Windows, Windows for Workgroups or Windows-95."
- "\nAnswer Y for OS/2, Warp, NT, Linux, SCO XENIX or UNIX.");
- /* don't advertise the ESC possibility */
-
- while (Result == -1)
- {
- switch (getch())
- {
- case 'N':
- case 'n':
- Result = 0; /* No */
- break;
- case 'Y':
- case 'y':
- Result = 1; /* Yes */
- break;
- case Esc:
- Result = 2; /* Esc, Abort */
- break;
- default:
- printf("\x07" ); /* beep to indicate char ignored. */
- break;
- }
- }
-
- return Result;
- } /* end DoesOSDoSimultaneousIO */
-
- /* ***************************************** */
-
- int CheckForEsc (void)
- {
-
- /*
- returns 0=user did nothing. We don't wait for him to hit a key.
- returns 1=user hit space
- returns 2=user hit ESC
- */
- int Result = 0;
-
- if (kbhit())
- {
- switch (getch())
- {
- case ' ':
- Result = 1; /* space we are done */
- break;
- case Esc:
- Result = 2; /* Esc, Abort */
- break;
- default:
- printf("\x07" ); /* beep to indicate char ignored. */
- Result = 0;
- break;
- }
- }
- else
- Result = 0; /* no key hit */
- return Result;
- } /* end CheckForEsc */
-
- /* ***************************************** */
-
- /* -30- */
-
-