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

  1. //
  2. //    SCSI handling routine for ASPI
  3. //      copyright(c) by Tsuru-Zoh, Oct.30,1992
  4. //
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <io.h>
  8. #include <dos.h>
  9. #include <fcntl.h>
  10. #include <ctype.h>
  11. #include <memory.h>
  12. #include <string.h>
  13. #include "aspi.h"
  14.  
  15.  
  16. void ( _far *Aspi )( unsigned char _far * ) = ( void _far * )0;
  17.  
  18.  
  19. //
  20. //    Initialize ASPI routine
  21. //    open "ASPIMGR$", get address of function Aspi(), close "ASPIMGR$"
  22. //        param.    : non
  23. //        return    : 0 if succeed
  24. //                 -1 if failured
  25. //
  26. int AspiInit()
  27. {
  28.     int handle;
  29.     union REGS rg;
  30.     
  31.     if( ( handle = open( "SCSIMGR$", O_RDONLY ) ) == -1 ){
  32.         printf( "Error : ASPI SCSI manager not found.\n" );
  33.         printf( " Please add ASPI SCSI manager to your config.sys.\n" );
  34.         return( -1 );
  35.     }
  36.     rg.x.ax = 0x4402;        /* IOCTL in */
  37.     rg.x.bx = handle;
  38.     rg.x.cx = 4;
  39.     rg.x.dx = (unsigned int)&Aspi;
  40.     intdos( &rg, &rg );
  41.     
  42.     close( handle );
  43.     
  44.     return( 0 );
  45. }
  46.  
  47. void AspiClose( void )
  48. {
  49. }
  50.  
  51.  
  52. //
  53. //    Get Host Adapter Inquiry
  54. //        param.    :
  55. //            int hostNo            : host adapter no.
  56. //            unsigned char *buf    : buffer for host inquiry data ( 24 bytes )
  57. //        return    :
  58. //            returns number of host adapters if succeed
  59. //                inquiry data stored to buf
  60. //            -1 if error occured
  61. //
  62. int HostInquiry( hostNo, buf )
  63.     int hostNo;
  64.     unsigned char *buf;
  65. {
  66.     struct SREGS sr;
  67.     srbInquiry srb;
  68.     
  69.     segread( &sr );
  70.     SrbInit( (unsigned char *)&srb, sizeof( srb ) );
  71.         
  72.     srb.commandCode = 0x00;
  73.     srb.hostAdapterNo = hostNo;
  74.     srb.scsiRequestFlag = 0x00;
  75.     Aspi( (unsigned char _far *)&srb );
  76.     while( !srb.commandStatus ){
  77.         /* wait until command complete */
  78.     }
  79.     if( srb.commandStatus == 0x81 ){
  80.         printf( "ASPI Error at Host adapter inquiry : Invalid host adapter number.\n" );
  81.         return( -1 );
  82.     }
  83.     memcpy( buf, &srb.managerId, 48 );
  84.     return( srb.noOfAdapter );
  85. }
  86.  
  87.  
  88. //
  89. //    Test Unit Ready command
  90. //        param.    :
  91. //            int hostNo        : host adapter no.
  92. //            int targetId    : target SCSI ID
  93. //        return    :
  94. //            0 if no error
  95. //            8 if target is busy
  96. //            -1 if error occured
  97. //
  98. int TestUnitReady( hostNo, targetId )
  99.     int hostNo, targetId;
  100. {
  101.     srbCdb6 srb;
  102.     
  103.     for( ; ; ){
  104.         SrbInit( (unsigned char *)&srb, sizeof( srb ) );
  105.         
  106.         srb.commandCode = 0x02;
  107.         srb.hostAdapterNo = hostNo;
  108.         srb.scsiRequestFlag = 0x00;
  109.         srb.targetId = targetId;
  110.         srb.senseAllocLength = SENSE_LENGTH;
  111.         srb.scsiCdbLength = 6;
  112.         srb.cdb[ 0 ] = 0x00;
  113.         srb.cdb[ 1 ] = 0x00;
  114.         srb.cdb[ 2 ] = 0x00;
  115.         srb.cdb[ 3 ] = 0x00;
  116.         srb.cdb[ 4 ] = 0x00;
  117.         srb.cdb[ 5 ] = 0x00;
  118.     
  119.         Aspi( (unsigned char _far *)&srb );
  120.         while( !srb.commandStatus ){
  121.             /* wait until command complete */
  122.         }
  123.         switch( srb.hostAdapterStatus ){
  124.         case 0x00:
  125.             break;
  126.         default:
  127.             printf( "ASPI Error : Host adapter error %02x.\n", srb.hostAdapterStatus );
  128.             return( -1 );
  129.         }
  130.         switch( srb.commandStatus ){
  131.         case 0x01:            /* completed without error */
  132.             return( 0 );
  133.         case 0x04:            /* completed with error */
  134.             break;
  135.         case 0x80:            /* invalid scsi request */
  136.         case 0x81:            /* invalid host adapter no. */
  137.         case 0x82:            /* SCSI device not installed */
  138.             printf( "ASPI Error : Command error status = %02x.\n", srb.commandStatus );
  139.             return( -1 );
  140.         default:
  141.             printf( "ASPI Error : Command error status = %02x.\n", srb.commandStatus );
  142.             return( -1 );
  143.         }
  144.         switch( srb.targetStatus ){
  145.         case 0x00:
  146.             return( 0 );
  147.         case 0x02:
  148.             if( ( srb.sense[ 12 ] == 0x28 ) || (srb.sense[ 12 ] == 0x29 ) ){
  149.                 /* reset condition */
  150.                 continue;
  151.             }else{
  152.                 return( -1 );
  153.             }
  154.         case 0x08:
  155.             /* target busy */
  156.             return( 8 );
  157.         default:
  158.             return( -1 );
  159.         }
  160.     }
  161. }
  162.  
  163.  
  164. //
  165. //    Inquiry command
  166. //        param.    :
  167. //            int hostNo                : host adapter no.
  168. //            int targetId            : target SCSI ID
  169. //            unsigned char *inqData    : data buffer for inquiry data ( 36 bytes )
  170. //        return    :
  171. //             0 if no error, inquiry data sotred to inqData
  172. //            -1 if error occured
  173. //
  174. int Inquiry( hostNo, targetId, inqData )
  175.     int hostNo, targetId;
  176.     unsigned char *inqData;
  177. {
  178.     struct SREGS sr;
  179.     srbCdb6 srb;
  180.     
  181.     segread( &sr );
  182.     for( ; ; ){
  183.         SrbInit( (unsigned char *)&srb, sizeof( srb ) );
  184.         
  185.         srb.commandCode = 0x02;
  186.         srb.hostAdapterNo = hostNo;
  187.         srb.scsiRequestFlag = 0x00;
  188.         srb.targetId = targetId;
  189.         srb.dataAllocLength = 40;
  190.         srb.senseAllocLength = SENSE_LENGTH;
  191.         srb.dataBufferOffset = (unsigned)inqData;
  192.         srb.dataBufferSegment = sr.ds;
  193.         srb.scsiCdbLength = 6;
  194.         srb.cdb[ 0 ] = 0x12;
  195.         srb.cdb[ 1 ] = 0x00;
  196.         srb.cdb[ 2 ] = 0x00;
  197.         srb.cdb[ 3 ] = 0x00;
  198.         srb.cdb[ 4 ] = 40;
  199.         srb.cdb[ 5 ] = 0x00;
  200.     
  201.         Aspi( (unsigned char _far *)&srb );
  202.         while( !srb.commandStatus ){
  203.             /* wait until command complete */
  204.         }
  205.         switch( srb.hostAdapterStatus ){
  206.         case 0x00:
  207.             break;
  208.         case 0x11:            /* selection timeout */
  209.             inqData[ 0 ] = 0xff;
  210.             return( 0 );
  211.         default:
  212.             printf( "ASPI Error : Host adapter error %02x.\n", srb.hostAdapterStatus );
  213.             return( -1 );
  214.         }
  215.         switch( srb.commandStatus ){
  216.         case 0x01:            /* completed without error */
  217.             return( 0 );
  218.         case 0x04:            /* completed with error */
  219.             break;
  220.         case 0x80:            /* invalid scsi request */
  221.         case 0x81:            /* invalid host adapter no. */
  222.             printf( "ASPI Error : Command error status = %02x.\n", srb.commandStatus );
  223.             return( -1 );
  224.         case 0x82:            /* SCSI device not installed */
  225.             inqData[ 0 ] = 0xff;
  226.             return( 0 );
  227.         default:
  228.             printf( "ASPI Error : Command error status = %02x.\n", srb.commandStatus );
  229.             return( -1 );
  230.         }
  231.         switch( srb.targetStatus ){
  232.         case 0x00:
  233.             return( 0 );
  234.         case 0x02:
  235.             if( ( srb.sense[ 12 ] == 0x28 ) || (srb.sense[ 12 ] == 0x29 ) ){
  236.                 /* reset condition */
  237.                 continue;
  238.             }else{
  239.                 inqData[ 0 ] = 0xff;
  240.                 return( 0 );
  241.             }
  242.         default:
  243.             return( -1 );
  244.         }
  245.     }
  246. }
  247.  
  248.  
  249. //
  250. //    Read Capacity command
  251. //        param.    :
  252. //            int hostNo                : host adapter no.
  253. //            int targetId            : target SCSI ID
  254. //            unsigned char *capBuf    : buffer for capacity data ( 8 bytes )
  255. //        return    :
  256. //             0 if no error, capacity data sotred to *capBuf
  257. //            -1 if error occured
  258. //
  259. int ReadCapacity( hostNo, targetId, capBuf )
  260.     int hostNo, targetId;
  261.     unsigned char *capBuf;
  262. {
  263.     struct SREGS sr;
  264.     srbCdb10 srb;
  265.  
  266.     segread( &sr );
  267.     for( ; ; ){
  268.         SrbInit( (unsigned char *)&srb, sizeof( srb ) );
  269.         
  270.         srb.commandCode = 0x02;
  271.         srb.hostAdapterNo = hostNo;
  272.         srb.scsiRequestFlag = 0x00;
  273.         srb.targetId = targetId;
  274.         srb.dataAllocLength = 8;
  275.         srb.senseAllocLength = SENSE_LENGTH;
  276.         srb.dataBufferOffset = (unsigned)capBuf;
  277.         srb.dataBufferSegment = sr.ds;
  278.         srb.scsiCdbLength = 10;
  279.         srb.cdb[ 0 ] = 0x25;
  280.         srb.cdb[ 1 ] = 0x00;
  281.         srb.cdb[ 2 ] = 0x00;
  282.         srb.cdb[ 3 ] = 0x00;
  283.         srb.cdb[ 4 ] = 0x00;
  284.         srb.cdb[ 5 ] = 0x00;
  285.         srb.cdb[ 6 ] = 0x00;
  286.         srb.cdb[ 7 ] = 0x00;
  287.         srb.cdb[ 8 ] = 0x00;
  288.         srb.cdb[ 9 ] = 0x00;
  289.     
  290.         Aspi( (unsigned char _far *)&srb );
  291.         while( !srb.commandStatus ){
  292.             /* wait until command complete */
  293.         }
  294.         if( srb.hostAdapterStatus ){
  295.             printf( "ASPI Error : Host adapter error %02x.\n", srb.hostAdapterStatus );
  296.             return( -1 );
  297.         }
  298.         switch( srb.commandStatus ){
  299.         case 0x01:            /* completed without error */
  300.             return( 0 );
  301.         case 0x04:            /* completed with error */
  302.             break;
  303.         case 0x80:            /* invalid scsi request */
  304.         case 0x81:            /* invalid host adapter no. */
  305.         case 0x82:            /* SCSI device not installed */
  306.             printf( "ASPI Error : Command error status = %02x.\n", srb.commandStatus );
  307.             return( -1 );
  308.         default:
  309.             printf( "ASPI Error : Command error status = %02x.\n", srb.commandStatus );
  310.             return( -1 );
  311.         }
  312.         switch( srb.targetStatus ){
  313.         case 0x00:
  314.             return( 0 );
  315.         case 0x02:
  316.             if( ( srb.sense[ 12 ] == 0x28 ) || (srb.sense[ 12 ] == 0x29 ) ){
  317.                 /* reset condition */
  318.                 continue;
  319.             }else{
  320.                 printf( "SCSI Error : ID=%d sense key = %02x , sense code = %02x\n",
  321.                     targetId, srb.sense[ 2 ], srb.sense[ 12 ] );
  322.                 return( -1 );
  323.             }
  324.         default:
  325.             return( -1 );
  326.         }
  327.     }
  328. }
  329.  
  330.  
  331. //
  332. //    Seek command
  333. //        param.    :
  334. //            int hostNo                    : host adapter no.
  335. //            int targetId                : target SCSI ID
  336. //            unsigned long logicalAddr    : logical address to seek
  337. //        return    :
  338. //             0 if no error
  339. //            -1 if error occured
  340. //
  341. int ScsiSeek( hostNo, targetId, logicalAddr )
  342.     int hostNo, targetId;
  343.     unsigned long logicalAddr;
  344. {
  345.     srbCdb6 srb;
  346.  
  347.     for( ; ; ){
  348.         SrbInit( (unsigned char *)&srb, sizeof( srb ) );
  349.         
  350.         srb.commandCode = 0x02;
  351.         srb.hostAdapterNo = hostNo;
  352.         srb.scsiRequestFlag = 0x00;    /* no data transfer */
  353.         srb.targetId = targetId;
  354.         srb.senseAllocLength = SENSE_LENGTH;
  355.         srb.scsiCdbLength = 6;
  356.         srb.cdb[ 0 ] = 0x0b;
  357.         srb.cdb[ 1 ] = ( logicalAddr >> 16 ) & 0x00ff;
  358.         srb.cdb[ 2 ] = ( logicalAddr >> 8 ) & 0x00ff;
  359.         srb.cdb[ 3 ] = logicalAddr & 0x00ff;
  360.         srb.cdb[ 4 ] = 0x00;
  361.         srb.cdb[ 5 ] = 0x00;
  362.     
  363.         Aspi( (unsigned char far *)&srb );
  364.         while( !srb.commandStatus ){
  365.             /* wait until command complete */
  366.         }
  367.         if( srb.hostAdapterStatus ){
  368.             printf( "ASPI Error : Host adapter error %02x.\n", srb.hostAdapterStatus );
  369.             return( -1 );
  370.         }
  371.         switch( srb.commandStatus ){
  372.         case 0x01:            /* completed without error */
  373.             return( 0 );
  374.         case 0x04:            /* completed with error */
  375.             break;
  376.         case 0x80:            /* invalid scsi request */
  377.         case 0x81:            /* invalid host adapter no. */
  378.         case 0x82:            /* SCSI device not installed */
  379.             printf( "ASPI Error : Command error status = %02x.\n", srb.commandStatus );
  380.             return( -1 );
  381.         default:
  382.             printf( "ASPI Error : Command error status = %02x.\n", srb.commandStatus );
  383.             return( -1 );
  384.         }
  385.         switch( srb.targetStatus ){
  386.         case 0x00:
  387.             return( 0 );
  388.         case 0x02:
  389.             if( ( srb.sense[ 12 ] == 0x28 ) || (srb.sense[ 12 ] == 0x29 ) ){
  390.                 /* reset condition */
  391.                 continue;
  392.             }else{
  393.                 printf( "SCSI Error : ID=%d sense key = %02x , sense code = %02x\n",
  394.                     targetId, srb.sense[ 2 ], srb.sense[ 12 ] );
  395.                 return( -1 );
  396.             }
  397.         default:
  398.             return( -1 );
  399.         }
  400.     }
  401. }
  402.  
  403.  
  404. //
  405. //    Read command
  406. //        param.    :
  407. //            int hostNo                        : host adapter no.
  408. //            int targetId                    : target SCSI ID
  409. //            unsigned long logicalAddr        : logical address to seek
  410. //            int blockSize                    : logical block size of target
  411. //            int blockCount                    : no. of block to read
  412. //            unsigned char far *dataBuffer    : read data buffer (max.65536)
  413. //        return    :
  414. //             0 if no error
  415. //            -1 if error occured
  416. //
  417. int ScsiRead( hostNo, targetId, logicalAddr, blockSize, blockCount, dataBuffer )
  418.     int hostNo, targetId, blockSize, blockCount;
  419.     unsigned long logicalAddr;
  420.     unsigned char far *dataBuffer;
  421. {
  422.     srbCdb10 srb;
  423.  
  424.     for( ; ; ){
  425.         SrbInit( (unsigned char *)&srb, sizeof( srb ) );
  426.         
  427.         srb.commandCode = 0x02;
  428.         srb.hostAdapterNo = hostNo;
  429.         srb.scsiRequestFlag = 0x08;    /* target to host */
  430.         srb.targetId = targetId;
  431.         srb.dataAllocLength = (long)blockSize * blockCount;
  432.         srb.senseAllocLength = SENSE_LENGTH;
  433.         srb.dataBufferOffset = FP_OFF( dataBuffer );
  434.         srb.dataBufferSegment = FP_SEG( dataBuffer );
  435.         srb.scsiCdbLength = 10;
  436.         srb.cdb[ 0 ] = 0x28;
  437.         srb.cdb[ 1 ] = 0x00;
  438.         srb.cdb[ 2 ] = ( logicalAddr >> 24 ) & 0x00ff;
  439.         srb.cdb[ 3 ] = ( logicalAddr >> 16 ) & 0x00ff;
  440.         srb.cdb[ 4 ] = ( logicalAddr >> 8 ) & 0x00ff;
  441.         srb.cdb[ 5 ] = logicalAddr & 0x00ff;
  442.         srb.cdb[ 6 ] = 0x00;
  443.         srb.cdb[ 7 ] = ( blockCount >> 8 ) & 0x00ff;
  444.         srb.cdb[ 8 ] = blockCount & 0x00ff;
  445.         srb.cdb[ 9 ] = 0x00;
  446.     
  447.         Aspi( (unsigned char _far *)&srb );
  448.         while( !srb.commandStatus ){
  449.             /* wait until command complete */
  450.         }
  451.         if( srb.hostAdapterStatus ){
  452.             printf( "ASPI Error : Host adapter error %02x.\n", srb.hostAdapterStatus );
  453.             return( -1 );
  454.         }
  455.         switch( srb.commandStatus ){
  456.         case 0x01:            /* completed without error */
  457.             return( 0 );
  458.         case 0x04:            /* completed with error */
  459.             break;
  460.         case 0x80:            /* invalid scsi request */
  461.         case 0x81:            /* invalid host adapter no. */
  462.         case 0x82:            /* SCSI device not installed */
  463.             printf( "ASPI Error : Command error status = %02x.\n", srb.commandStatus );
  464.             return( -1 );
  465.         default:
  466.             printf( "ASPI Error : Command error status = %02x.\n", srb.commandStatus );
  467.             return( -1 );
  468.         }
  469.         switch( srb.targetStatus ){
  470.         case 0x00:
  471.             return( 0 );
  472.         case 0x02:
  473.             if( ( srb.sense[ 12 ] == 0x28 ) || (srb.sense[ 12 ] == 0x29 ) ){
  474.                 /* reset condition */
  475.                 continue;
  476.             }else{
  477.                 printf( "SCSI Error : ID=%d sense key = %02x , sense code = %02x\n",
  478.                     targetId, srb.sense[ 2 ], srb.sense[ 12 ] );
  479.                 return( -1 );
  480.             }
  481.         default:
  482.             return( -1 );
  483.         }
  484.     }
  485. }
  486.  
  487.  
  488. //
  489. //    clear SRB
  490. //        param. :
  491. //            unsigned char *srb    : area to fill with '0'
  492. //            int count            : clear up size
  493. //
  494. void SrbInit( srb, count )
  495.     unsigned char *srb;
  496.     int count;
  497. {
  498.     int i;
  499.     
  500.     for( i = 0; i < count; i++ ){
  501.         *srb++ = 0;
  502.     }
  503. }
  504.  
  505.