home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 1997 Hardware / HARDWARE.ISO / hardware / asbnch / source / asbench.c next >
Encoding:
C/C++ Source or Header  |  1996-11-27  |  14.0 KB  |  463 lines

  1. //
  2. //  ASBENCH : ASPI SCSI benchmark test for hard-disk / MO / CD-ROM
  3. //      copyright(c) by TsuruZoh Tachibanaya
  4. //
  5. //      V0.1    Oct.30,1992 ;first release
  6. //      V0.2    Nov.23,1992 ;add bar-graph display
  7. //      V0.3    Nov.04,1996 ;test end of disk sequential, Win32 console port
  8. //
  9.  
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #ifndef WIN32
  13. #ifndef _MSC_VER
  14. #include <alloc.h>
  15. #else
  16. #include <malloc.h>
  17. #define farmalloc _fmalloc
  18. #define farfree _ffree
  19. #endif
  20. #else
  21. #define far
  22. #define farmalloc malloc
  23. #define farfree free
  24. int random(int imax);
  25. #pragma warning (disable:4005)
  26. #define putchar(a) (printf("%c",(a)))
  27. #endif
  28. #include <time.h>
  29. #include "aspi.h"
  30.  
  31. #define TESTTIME 5  // measurement length is 5 sec.
  32.  
  33. static int commandRank[ 2 ] = { 25, 35 };
  34. static int seekRank[ 2 ] = { 100, 400 };
  35. static int readRank[ 3 ] = { 20000, 12000,20000 };
  36.  
  37. int main( void );
  38. int GetTarget( void );
  39. int GetHostNo( void );
  40. int GetInquiry( int, unsigned char[7][7][40] );
  41. void DispInquiry( int, int, unsigned char * );
  42. int CommandBench( int, int, int );
  43. int SeekBench( int, int, unsigned long, int );
  44. int ReadBench( int, int, unsigned char far *, int, unsigned long, int );
  45.  
  46.  
  47. int main()
  48. {
  49.     int hostNo, targetId, sectorSize;
  50.     unsigned char far *dataBuffer;
  51.     unsigned char tempBuf[ 80 ];
  52.     unsigned long lbaMax;
  53.  
  54.     printf( "\nASPI SCSI benchmark test V0.4 \n" );
  55.     #ifndef WIN32
  56.     printf( " copyright(c) by Tsuru-Zoh, Nov. 4,1996, modified by Gilles Vollant\n\n" );
  57.     #else
  58.     printf( " copyright(c) by Tsuru-Zoh, Nov. 4,1996, Win32 Version by Gilles Vollant\n\n" );
  59.     #endif    
  60.     if( AspiInit() ){
  61.         return( -1 );
  62.     }
  63.     
  64.     if( ( targetId = GetTarget() ) == -1 ){
  65.         return( 0 );
  66.     }
  67.     hostNo = targetId >> 4;
  68.     targetId = targetId & 0x07;
  69.  
  70.     if( ReadCapacity( hostNo, targetId, tempBuf ) ){
  71.         printf( "Can't get sector size.\n" );
  72.         return( -1L );
  73.     }
  74.     sectorSize = tempBuf[ 6 ] * 256 + tempBuf[ 7 ];
  75.     lbaMax = tempBuf[ 1 ] * 65536L + tempBuf[ 2 ] * 256L + tempBuf[ 3 ];
  76.     printf( "  %d Bytes per sector, capacity is %ld MBytes.\n",
  77.             sectorSize, lbaMax * (sectorSize/16) / 1024L / (1024L/16) );
  78.     printf( "------------------------+-------------+-------+-------+-------+-------+-------+\n" );
  79.     printf( "        Test mode       :    result   |  Poor |   OK  |  Good | Great | Superb|\n" );
  80.  
  81.  
  82.     if( CommandBench( hostNo, targetId, TESTTIME ) ){
  83.         /* command error occured */
  84.         return( -1 );
  85.     }
  86.  
  87.  
  88.     if( SeekBench( hostNo, targetId, lbaMax, TESTTIME ) ){
  89.         /* seek error occured */
  90.         return( -1 );
  91.     }
  92.  
  93.     if( ( dataBuffer = (unsigned char far *)farmalloc( 65536L ) ) == NULL ){
  94.         printf( "Error : Can't allocate buffer.\n" );
  95.         return( -1 );
  96.     }
  97.  
  98.     if( ReadBench( hostNo, targetId, dataBuffer, sectorSize, lbaMax, TESTTIME )  ){
  99.         /* read error occured */
  100.         farfree( dataBuffer );
  101.         return( -1 );
  102.     }
  103.     printf( "------------------------+-------------+-------+-------+-------+-------+-------+\n" );
  104.  
  105.     farfree( dataBuffer );
  106.     AspiClose();
  107.     return( 0 );
  108. }
  109.  
  110.  
  111. //
  112. //  get target device
  113. //      parameter:
  114. //          non
  115. //      return :
  116. //          -1  if error occured
  117. //          else bit 7..4 : host adapter no.
  118. //               bit 3..0 : scsi id
  119. //
  120. int GetTarget()
  121. {
  122.     int hostNo, host, targetId, targetType, selPtr;
  123.     unsigned char inqBuf[ 7 ][ 7 ][ 40 ], buf[ 80 ];
  124.     struct{
  125.         int host;
  126.         int id;
  127.     }selNo[ 49 ];
  128.     
  129.     if( ( hostNo = HostInquiry( 0, buf ) ) == -1 ){
  130.         return( -1 );
  131.     }
  132.     if( GetInquiry( hostNo, inqBuf ) ){
  133.         return( -1 );
  134.     }
  135.     selPtr = 0;
  136.     for( host = 0; host < hostNo; host++ ){
  137.         for( targetId = 0; targetId < 7; targetId++ ){
  138.             targetType = inqBuf[ host ][ targetId ][ 0 ] & 0x1f;
  139.             if( targetType == 0 || targetType == 5 || targetType == 7 ){
  140.                 /* HDD or MO or CD-ROM */
  141.                 selNo[ selPtr ].host = host;
  142.                 selNo[ selPtr ].id = targetId;
  143.                 printf( "Target No.%d : ", selPtr );
  144.                 DispInquiry( host, targetId, inqBuf[ host ][ targetId ] );
  145.                 selPtr++;
  146.             }
  147.         }
  148.     }
  149.     do{
  150.         printf( "\nEnter target number ( 0 to %d ) : ", selPtr - 1 );
  151.         gets( buf );
  152.         targetId = atoi( buf );
  153.         if( targetId == -1 ){
  154.             return( -1 );
  155.         }
  156.     }while( ( targetId < 0 ) || ( targetId >= selPtr ) );
  157.     host = selNo[ targetId ].host;
  158.     targetId = selNo[ targetId ].id;
  159.  
  160.     HostInquiry( host, buf );
  161.     printf( "\n\n  Host Adapter is " );
  162.  
  163.     for( selPtr = 16; selPtr < 32; selPtr++ ){
  164.         if (buf[ selPtr ]=='\0')
  165.             break;
  166.         putchar( buf[ selPtr ] );
  167.     }
  168.  
  169.     printf( "\n  Target device is " );
  170.     DispInquiry( host, targetId, inqBuf[ host ][ targetId ] );
  171.     
  172.     return( host * 16 + targetId );
  173. }
  174.  
  175.  
  176. //
  177. //  scsi command benchmark test
  178. //      parameter :
  179. //          int hostNo              : host adapter no.
  180. //          int targetId            : target scsi id
  181. //          int benchTime           : benchmark measurement time length
  182. //
  183. int CommandBench( hostNo, targetId, benchTime )
  184.     int hostNo, targetId, benchTime;
  185. {
  186.     long commandCount;
  187.     time_t stt;
  188.     int benchMode, rankCount, i;
  189.     static char *commandModeStr[] = {
  190.         " Test Unit Ready command",
  191.         " No Motion Seek command "
  192.     };
  193.  
  194.     printf( "------------------------+-------------+-------+-------+-------+-------+-------+\n" );
  195.     
  196.     for( benchMode = 0; benchMode < 2; benchMode++ ){
  197.         
  198.         printf( "%s|", commandModeStr[ benchMode ] );
  199.         
  200.         commandCount = 0L;
  201.         
  202.         if( ScsiSeek( hostNo, targetId, 0L ) ){
  203.             printf( "Seek error occured.\n" );\
  204.             return( -1 );
  205.         }
  206.         stt = time( NULL );
  207.         while( stt == time( NULL ) ){
  208.             /* wait until time change */
  209.         }
  210.         stt += ( benchTime + 1 );
  211.         while( time( NULL ) < stt ){
  212.             if( benchMode == 0 ){
  213.                 for( i = 0; i < 100; i++ ){
  214.                     if( TestUnitReady( hostNo, targetId ) ){
  215.                         return( -1 );
  216.                     }
  217.                 }
  218.             }else{
  219.                 for( i = 0; i < 100; i++ ){
  220.                     if( ScsiSeek( hostNo, targetId, 0L ) ){
  221.                         printf( "Seek error occured.\n" );\
  222.                         return( -1 );
  223.                     }
  224.                 }
  225.             }
  226.             commandCount++;
  227.         }
  228.         commandCount = (long)benchTime * 100L / commandCount;
  229.         printf( "  %3ld.%1ld[ms]  :",
  230.                      commandCount / 10L, commandCount % 10L );
  231.         rankCount = ( commandRank[ benchMode ] - commandCount ) * 40 / commandRank[ benchMode ] + 1;
  232.         for( i = 0; i < rankCount; i++ ){
  233.             putchar( '*' );
  234.         }
  235.         putchar( '\n' );
  236.     }
  237.     return( 0 );
  238. }
  239.  
  240.  
  241. //
  242. //  seek benchmark test
  243. //      parameter :
  244. //          int hostNo              : host adapter no.
  245. //          int targetId            : target scsi id
  246. //          unsigned long lbaMax    : maximum block number of target device
  247. //          int benchTime           : benchmark measurement time length
  248. //
  249. int SeekBench( hostNo, targetId, lbaMax, benchTime )
  250.     int hostNo, targetId, benchTime;
  251.     unsigned long lbaMax;
  252. {
  253.     long logicalAddr, randomScale, seekCount;
  254.     time_t stt;
  255.     int benchMode, rankCount, i;
  256.     static char *seekModeStr[] = {
  257.         " Sequential Seek command",
  258.         " Random Seek command    "
  259.     };
  260.     
  261.  
  262.     randomScale = lbaMax / 32767L;
  263.     if( randomScale == 0 ){
  264.         randomScale = 1;
  265.     }
  266.     
  267.     printf( "------------------------+-------------+-------+-------+-------+-------+-------+\n" );
  268.     for( benchMode = 0; benchMode < 2; benchMode++ ){
  269.         
  270.         printf( "%s|", seekModeStr[ benchMode ] );
  271.         
  272.         logicalAddr = 0L;
  273.         seekCount = 0L;
  274.         
  275.         stt = time( NULL );
  276.         while( stt == time( NULL ) ){
  277.             /* wait until time change */
  278.         }
  279.         stt += ( benchTime + 1 );
  280.         while( time( NULL ) < stt ){
  281.             if( ScsiSeek( hostNo, targetId, logicalAddr ) ){
  282.                 printf( "Seek error occured.\n" );\
  283.                 return( -1 );
  284.             }
  285.             if( benchMode == 0 ){
  286.                 logicalAddr += 32L;
  287.                 if( logicalAddr > (long)lbaMax ){
  288.                     logicalAddr = 0L;
  289.                 }
  290.             }else{
  291.                 do{
  292.                     logicalAddr = random( 32768 ) * randomScale;
  293.                 }while( logicalAddr > (long)lbaMax );
  294.             }
  295.             seekCount++;
  296.         }
  297.         seekCount = (long)benchTime * 10000L / seekCount;
  298.         printf( "  %3ld.%1ld[ms]  :",
  299.                      seekCount / 10L, seekCount % 10L );
  300.         rankCount = ( seekRank[ benchMode ] - seekCount ) * 40 / seekRank[ benchMode ] + 1;
  301.         for( i = 0; i < rankCount; i++ ){
  302.             putchar( '*' );
  303.         }
  304.         putchar( '\n' );
  305.     }
  306.     return( 0 );
  307. }
  308.  
  309.  
  310. //
  311. //  data read benchmark test
  312. //      parameter :
  313. //          int hostNo                      : host adapter no.
  314. //          int targetId                    : target scsi id
  315. //          unsigned char far *dataBuffer   : data buffer ptr. (65536 bytes)
  316. //          int sectorSize                  : logical block size of target
  317. //          unsigned long lbaMax            : maximum block number of target
  318. //          int benchTime                   : benchmark measurement time length
  319. //
  320. int ReadBench( hostNo, targetId, dataBuffer, sectorSize, lbaMax, benchTime )
  321.     int hostNo, targetId, sectorSize, benchTime;
  322.     unsigned char far *dataBuffer;
  323.     unsigned long lbaMax;
  324. {
  325.     long logicalAddr, randomScale, readCount;
  326.     int benchMode, blockCount, maxBlockCount, rankCount, i;
  327.     time_t stt;
  328.     static char *readModeStr[] = {
  329.         " Seq. Read",
  330.         " Rnd. Read",
  331.         " SeqRd End"
  332.     };
  333.     
  334.     randomScale = ( lbaMax - 65536L / sectorSize ) / 32767L;
  335.     if( randomScale == 0 ){
  336.         randomScale = 1;
  337.     }
  338.     maxBlockCount = 65536L / sectorSize;
  339.  
  340.  
  341.     for( benchMode = 0; benchMode < 3; benchMode++ ){
  342.         printf( "------------------------+-------------+-------+-------+-------+-------+-------+\n" );
  343.  
  344.         for( blockCount = 1; ; ){
  345.             logicalAddr = 0L;
  346.             if (benchMode==2)
  347.                             if (((65536L*1024) / sectorSize) < (long)lbaMax)
  348.                     logicalAddr = lbaMax  - ((65536L*1024) / sectorSize) ;
  349.             readCount = 0L;
  350.  
  351.             printf( "%s  %5ldB/read |",
  352.                 readModeStr[ benchMode ], (long)blockCount * sectorSize );
  353.             stt = time( NULL );
  354.             while( stt == time( NULL ) ){
  355.                 /* wait until time change */
  356.             }
  357.             stt += ( benchTime + 1 );
  358.             while( time( NULL ) < stt ){
  359.                 if( ScsiRead( hostNo, targetId, logicalAddr, sectorSize, blockCount, dataBuffer ) ){
  360.                     printf( "Read error occured.\n" );
  361.                     return( -1 );
  362.                 }
  363.                 if((benchMode  == 0 )||( benchMode  == 2)){
  364.                     logicalAddr += blockCount;
  365.                 }else{
  366.                     do{
  367.                         logicalAddr = random( 32768 ) * randomScale;
  368.                     }while( logicalAddr > (long)lbaMax );
  369.                 }
  370.                 readCount += blockCount;
  371.             }
  372.             readCount = readCount * ((10L * sectorSize)/16) / benchTime / (1024L/16);
  373.             printf( " %4ld.%1ld[KB/s]:",
  374.                  readCount / 10L, readCount % 10L );
  375.             rankCount = readCount * 40 / readRank[ benchMode ] + 1;
  376.             if( rankCount > 40 ){
  377.                 rankCount = 40;
  378.             }
  379.             for( i = 0; i < rankCount; i++ ){
  380.                 putchar( '*' );
  381.             }
  382.             putchar( '\n' );
  383.             if( blockCount == 1 ){
  384.                 blockCount = 16384L / sectorSize;
  385.             }else if( blockCount != maxBlockCount ){
  386.                 blockCount = maxBlockCount;
  387.             }else{
  388.                 break;
  389.             }
  390.         }
  391.     }
  392.     return( 0 );
  393. }
  394.  
  395.  
  396. //
  397. //  get inquiry data from all host adapters, all scsi targets
  398. //      parameter :
  399. //          int hostNo : number of host adapters
  400. //          unsigned char inqbuf[7][7][40] : data buffer for inquiry
  401. //      return :
  402. //           0  if no error
  403. //          -1  if error occured
  404. //
  405. int GetInquiry( hostNo, inqBuf )
  406.     int hostNo;
  407.     unsigned char inqBuf[][ 7 ][ 40 ];
  408. {
  409.     int host, targetId;
  410.     
  411.     for( host = 0; host < hostNo; host++ ){
  412.         for( targetId = 0; targetId < 7; targetId++ ){
  413.             inqBuf[ host ][ targetId ][ 0 ] = 0xff;
  414.             if( Inquiry( host, targetId, inqBuf[ host ][ targetId ] ) == -1 ){
  415.                 printf( "Host adapter error occured.\n" );
  416.                 return( -1 );
  417.             }
  418.         }
  419.     }
  420.     return( 0 );
  421. }
  422.  
  423.  
  424. //
  425. //  display inquiry data
  426. //      parameter :
  427. //          int hostno : host adapter no.
  428. //          int targetid : target scsi is
  429. //          unsigned char *inqdata : inquiry data
  430. //      return :
  431. //          non
  432. //
  433. void DispInquiry( hostNo, targetId, inqData )
  434.     int hostNo, targetId;
  435.     unsigned char *inqData;
  436. {
  437.     int i;
  438.     
  439.     if( inqData[ 0 ] == 0xff ){
  440.         return;
  441.     }
  442.     printf( "HA#%d ID%d ", hostNo, targetId );
  443.     if( inqData[ 4 ] ){
  444.         putchar( ' ' );
  445.         for( i = 8; i < 36; i++ ){
  446.             if( inqData[ i ] == 0x00 ){
  447.                 break;
  448.             }else{
  449.                 putchar( inqData[ i ] );
  450.             }
  451.         }
  452.         putchar( ' ' );
  453.     }else{
  454.         printf( " Device name not available" );
  455.     }
  456.     printf( " CCS%d ",inqData[ 2 ] & 0x03 );
  457.     if( inqData[ 1 ] & 0x80 ){
  458.         printf( "Removable\n" );
  459.     }else{
  460.         printf( "Rigid\n" );
  461.     }
  462. }
  463.