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

  1. //
  2. //    SCSI handling routine for ASPI
  3. //      copyright(c) by Tsuru-Zoh, Oct.30,1992
  4.  
  5. #include <windows.h>
  6. //
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <io.h>
  10. #include <dos.h>
  11. #include <fcntl.h>
  12. #include <ctype.h>
  13. #include <memory.h>
  14. #include <string.h>
  15.  
  16. #include "scsidefs.h"
  17. #include "wnaspi32.h"
  18.  
  19. #include "aspi.h"
  20.  
  21.  
  22.  
  23.  
  24. static HANDLE hEventEnd = NULL;
  25.  
  26.  
  27. /*
  28. void APIENTRY  ASPIPostProc (PSRB_ExecSCSICmd DoneSRB )
  29.    {
  30.  
  31.    //
  32.    // Send POST message
  33.    //
  34.    if (hEventEnd!=NULL)
  35.        SetEvent(hEventEnd);
  36.  
  37.    return;
  38.    }
  39.  
  40. void GetMakePostProc(PSRB_ExecSCSICmd DoneSRB )
  41. {
  42.     if (hEventEnd!=NULL)
  43.         printf("error");
  44.     hEventEnd = CreateEvent(NULL,FALSE,FALSE, NULL);
  45.  
  46.     //DoneSRB->SRB_Flags |=SRB_POSTING;
  47.     //DoneSRB->SRB_PostProc=(void*)ASPIPostProc;
  48.  
  49.     DoneSRB->SRB_Flags |=SRB_EVENT_NOTIFY;
  50.     DoneSRB->SRB_PostProc=hEventEnd;
  51. }
  52.  
  53. void WaitEndAspi()
  54. {
  55.    if (hEventEnd!=NULL)
  56.    {
  57.        WaitForSingleObject(hEventEnd,INFINITE);
  58.        CloseHandle(hEventEnd);
  59.        hEventEnd=NULL;
  60.    }
  61. }
  62. */
  63. //
  64.  
  65.  
  66. void /*APIENTRY*/  ASPIPostProc (PSRB_ExecSCSICmd DoneSRB )
  67.    {
  68.  
  69.    //
  70.    // Send POST message
  71.    //
  72.    if (hEventEnd!=NULL)
  73.        SetEvent(hEventEnd);
  74.  
  75.    return;
  76.    }
  77.  
  78. void GetMakePostProc(PSRB_ExecSCSICmd DoneSRB )
  79. {
  80.     DoneSRB->SRB_Flags |=SRB_POSTING;
  81.     DoneSRB->SRB_PostProc=(void*)ASPIPostProc;
  82. }
  83.  
  84. void WaitEndAspi()
  85. {
  86.    if (hEventEnd!=NULL)
  87.    {
  88.        WaitForSingleObject(hEventEnd,INFINITE);
  89.    }
  90. }
  91.  
  92. int AspiInit()
  93. {
  94.     BYTE  AdapterCount;
  95.     DWORD ASPI32Status;
  96.  
  97.     ASPI32Status             = GetASPI32SupportInfo();
  98.     AdapterCount             = (LOBYTE(LOWORD(ASPI32Status)));
  99.  
  100.     hEventEnd = CreateEvent(NULL,FALSE,FALSE, NULL);
  101.  
  102.     if ((AdapterCount != 0) && (HIBYTE(LOWORD(ASPI32Status)) == SS_COMP))
  103.         return 0;
  104.     else
  105.  
  106.     printf( "Error : ASPI SCSI manager not found.\n" );
  107.     printf( " Please add ASPI SCSI manager to your config.sys.\n" );
  108.     return( -1 );
  109. }
  110.  
  111. void AspiClose( void )
  112. {
  113.        if (hEventEnd!=NULL)
  114.             CloseHandle(hEventEnd);
  115.        hEventEnd=NULL;
  116. }
  117.  
  118. //
  119. //    Get Host Adapter Inquiry
  120. //        param.    :
  121. //            int hostNo            : host adapter no.
  122. //            unsigned char *buf    : buffer for host inquiry data ( 24 bytes )
  123. //        return    :
  124. //            returns number of host adapters if succeed
  125. //                inquiry data stored to buf
  126. //            -1 if error occured
  127. //
  128. int HostInquiry( hostNo, buf )
  129.     int hostNo;
  130.     unsigned char *buf;
  131. {
  132.     SRB_HAInquiry srb;
  133.     
  134.  
  135.     SrbInit( (unsigned char *)&srb, sizeof( srb ) );
  136.     SrbInit( (unsigned char *)buf, 48 );
  137.         
  138.     srb.SRB_Cmd = 0x00;
  139.     srb.SRB_HaId = hostNo;
  140.     srb.SRB_Flags = 0x00;
  141.  
  142.     SendASPI32Command(&srb);
  143.     while( !srb.SRB_Status ){
  144.         /* wait until command complete */
  145.     }
  146.     if( srb.SRB_Status == 0x81 ){
  147.         printf( "ASPI Error at Host adapter inquiry : Invalid host adapter number.\n" );
  148.         return( -1 );
  149.     }
  150.     memcpy( buf, &srb.HA_ManagerId, 48 );
  151.     return( srb.HA_Count );
  152. }
  153.  
  154.  
  155. //
  156. //    Test Unit Ready command
  157. //        param.    :
  158. //            int hostNo        : host adapter no.
  159. //            int targetId    : target SCSI ID
  160. //        return    :
  161. //            0 if no error
  162. //            8 if target is busy
  163. //            -1 if error occured
  164. //
  165. int TestUnitReady( hostNo, targetId )
  166.     int hostNo, targetId;
  167. {
  168.     SRB_ExecSCSICmd srb;
  169.     
  170.     for( ; ; ){
  171.         SrbInit( (unsigned char *)&srb, sizeof( srb ) );
  172.         
  173.         srb.SRB_Cmd = 0x02;
  174.         srb.SRB_HaId = hostNo;
  175.         srb.SRB_Flags = 0x00;
  176.         srb.SRB_Target = targetId;
  177.         srb.SRB_SenseLen = SENSE_LEN;
  178.         srb.SRB_CDBLen = 6;
  179.         srb.CDBByte[ 0 ] = 0x00;
  180.         srb.CDBByte[ 1 ] = 0x00;
  181.         srb.CDBByte[ 2 ] = 0x00;
  182.         srb.CDBByte[ 3 ] = 0x00;
  183.         srb.CDBByte[ 4 ] = 0x00;
  184.         srb.CDBByte[ 5 ] = 0x00;
  185.     
  186.         GetMakePostProc(&srb);
  187.         SendASPI32Command(&srb);
  188.         WaitEndAspi();
  189.  
  190.  
  191.         while( !srb.SRB_Status ){
  192.             /* wait until command complete */
  193.         }
  194.         switch( srb.SRB_HaStat ){
  195.         case 0x00:
  196.             break;
  197.         default:
  198.             printf( "ASPI Error : Host adapter error %02x.\n", srb.SRB_HaStat );
  199.             return( -1 );
  200.         }
  201.         switch( srb.SRB_Status ){
  202.         case 0x01:            /* completed without error */
  203.             return( 0 );
  204.         case 0x04:            /* completed with error */
  205.             break;
  206.         case 0x80:            /* invalid scsi request */
  207.         case 0x81:            /* invalid host adapter no. */
  208.         case 0x82:            /* SCSI device not installed */
  209.             printf( "ASPI Error : Command error status = %02x.\n", srb.SRB_Status );
  210.             return( -1 );
  211.         default:
  212.             printf( "ASPI Error : Command error status = %02x.\n", srb.SRB_Status );
  213.             return( -1 );
  214.         }
  215.         switch( srb.SRB_TargStat ){
  216.         case 0x00:
  217.             return( 0 );
  218.         case 0x02:
  219.             if( ( srb.SenseArea[ 12 ] == 0x28 ) || (srb.SenseArea[ 12 ] == 0x29 ) ){
  220.                 /* reset condition */
  221.                 continue;
  222.             }else{
  223.                 return( -1 );
  224.             }
  225.         case 0x08:
  226.             /* target busy */
  227.             return( 8 );
  228.         default:
  229.             return( -1 );
  230.         }
  231.     }
  232. }
  233.  
  234.  
  235. //
  236. //    Inquiry command
  237. //        param.    :
  238. //            int hostNo                : host adapter no.
  239. //            int targetId            : target SCSI ID
  240. //            unsigned char *inqData    : data buffer for inquiry data ( 36 bytes )
  241. //        return    :
  242. //             0 if no error, inquiry data sotred to inqData
  243. //            -1 if error occured
  244. //
  245. int Inquiry( hostNo, targetId, inqData )
  246.     int hostNo, targetId;
  247.     unsigned char *inqData;
  248. {
  249.  
  250.     SRB_ExecSCSICmd srb;
  251.     
  252.     SrbInit( inqData, 40 );
  253.  
  254.     for( ; ; ){
  255.         SrbInit( (unsigned char *)&srb, sizeof( srb ) );
  256.         
  257.         srb.SRB_Cmd = 0x02;
  258.         srb.SRB_HaId = hostNo;
  259.         srb.SRB_Flags = SRB_DIR_SCSI;//0x00;
  260.         srb.SRB_Target = targetId;
  261.         srb.SRB_BufLen = 40-8;
  262.         srb.SRB_SenseLen = SENSE_LEN;
  263.         srb.SRB_BufPointer = inqData;
  264.         //srb.dataBufferSegment = sr.ds;
  265.         srb.SRB_CDBLen = 6;
  266.         srb.CDBByte[ 0 ] = 0x12;
  267.         srb.CDBByte[ 1 ] = 0x00;
  268.         srb.CDBByte[ 2 ] = 0x00;
  269.         srb.CDBByte[ 3 ] = 0x00;
  270.         srb.CDBByte[ 4 ] = 40-8;
  271.         srb.CDBByte[ 5 ] = 0x00;
  272.  
  273.         
  274.         
  275.         GetMakePostProc(&srb);
  276.         SendASPI32Command(&srb);
  277.         WaitEndAspi();
  278.  
  279.  
  280.  
  281.         while( !srb.SRB_Status ){
  282.             /* wait until command complete */
  283.         }
  284.         switch( srb.SRB_HaStat ){
  285.         case 0x00:
  286.             break;
  287.         case 0x11:            /* selection timeout */
  288.             inqData[ 0 ] = 0xff;
  289.             return( 0 );
  290.         default:
  291.             printf( "ASPI Error : Host adapter error %02x.\n", srb.SRB_HaStat );
  292.             return( -1 );
  293.         }
  294.         switch( srb.SRB_Status ){
  295.         case 0x01:            /* completed without error */
  296.             return( 0 );
  297.         case 0x04:            /* completed with error */
  298.             break;
  299.         case 0x80:            /* invalid scsi request */
  300.         case 0x81:            /* invalid host adapter no. */
  301.             printf( "ASPI Error : Command error status = %02x.\n", srb.SRB_Status );
  302.             return( -1 );
  303.         case 0x82:            /* SCSI device not installed */
  304.             inqData[ 0 ] = 0xff;
  305.             return( 0 );
  306.         default:
  307.             printf( "ASPI Error : Command error status = %02x.\n", srb.SRB_Status );
  308.             return( -1 );
  309.         }
  310.         switch( srb.SRB_TargStat ){
  311.         case 0x00:
  312.             return( 0 );
  313.         case 0x02:
  314.             if( ( srb.SenseArea[ 12 ] == 0x28 ) || (srb.SenseArea[ 12 ] == 0x29 ) ){
  315.                 /* reset condition */
  316.                 continue;
  317.             }else{
  318.                 inqData[ 0 ] = 0xff;
  319.                 return( 0 );
  320.             }
  321.         default:
  322.             return( -1 );
  323.         }
  324.     }
  325. }
  326.  
  327.  
  328. //
  329. //    Read Capacity command
  330. //        param.    :
  331. //            int hostNo                : host adapter no.
  332. //            int targetId            : target SCSI ID
  333. //            unsigned char *capBuf    : buffer for capacity data ( 8 bytes )
  334. //        return    :
  335. //             0 if no error, capacity data sotred to *capBuf
  336. //            -1 if error occured
  337. //
  338. int ReadCapacity( hostNo, targetId, capBuf )
  339.     int hostNo, targetId;
  340.     unsigned char *capBuf;
  341. {
  342.     SRB_ExecSCSICmd srb;
  343.  
  344.     for( ; ; ){
  345.         SrbInit( (unsigned char *)&srb, sizeof( srb ) );
  346.         
  347.         srb.SRB_Cmd = 0x02;
  348.         srb.SRB_HaId = hostNo;
  349.         srb.SRB_Flags = 0x00;
  350.         srb.SRB_Target = targetId;
  351.         srb.SRB_BufLen = 8;
  352.         srb.SRB_SenseLen = SENSE_LEN;
  353.         srb.SRB_BufPointer = capBuf;
  354.         //srb.dataBufferSegment = sr.ds;
  355.         srb.SRB_CDBLen = 10;
  356.         srb.CDBByte[ 0 ] = 0x25;
  357.         srb.CDBByte[ 1 ] = 0x00;
  358.         srb.CDBByte[ 2 ] = 0x00;
  359.         srb.CDBByte[ 3 ] = 0x00;
  360.         srb.CDBByte[ 4 ] = 0x00;
  361.         srb.CDBByte[ 5 ] = 0x00;
  362.         srb.CDBByte[ 6 ] = 0x00;
  363.         srb.CDBByte[ 7 ] = 0x00;
  364.         srb.CDBByte[ 8 ] = 0x00;
  365.         srb.CDBByte[ 9 ] = 0x00;
  366.     
  367.         GetMakePostProc(&srb);
  368.         SendASPI32Command(&srb);
  369.         WaitEndAspi();
  370.  
  371.  
  372.         while( !srb.SRB_Status ){
  373.             /* wait until command complete */
  374.         }
  375.         if( srb.SRB_HaStat ){
  376.             printf( "ASPI Error : Host adapter error %02x.\n", srb.SRB_HaStat );
  377.             return( -1 );
  378.         }
  379.         switch( srb.SRB_Status ){
  380.         case 0x01:            /* completed without error */
  381.             return( 0 );
  382.         case 0x04:            /* completed with error */
  383.             break;
  384.         case 0x80:            /* invalid scsi request */
  385.         case 0x81:            /* invalid host adapter no. */
  386.         case 0x82:            /* SCSI device not installed */
  387.             printf( "ASPI Error : Command error status = %02x.\n", srb.SRB_Status );
  388.             return( -1 );
  389.         default:
  390.             printf( "ASPI Error : Command error status = %02x.\n", srb.SRB_Status );
  391.             return( -1 );
  392.         }
  393.         switch( srb.SRB_TargStat ){
  394.         case 0x00:
  395.             return( 0 );
  396.         case 0x02:
  397.             if( ( srb.SenseArea[ 12 ] == 0x28 ) || (srb.SenseArea[ 12 ] == 0x29 ) ){
  398.                 /* reset condition */
  399.                 continue;
  400.             }else{
  401.                 printf( "SCSI Error : ID=%d sense key = %02x , sense code = %02x\n",
  402.                     targetId, srb.SenseArea[ 2 ], srb.SenseArea[ 12 ] );
  403.                 return( -1 );
  404.             }
  405.         default:
  406.             return( -1 );
  407.         }
  408.     }
  409. }
  410.  
  411.  
  412. //
  413. //    Seek command
  414. //        param.    :
  415. //            int hostNo                    : host adapter no.
  416. //            int targetId                : target SCSI ID
  417. //            unsigned long logicalAddr    : logical address to seek
  418. //        return    :
  419. //             0 if no error
  420. //            -1 if error occured
  421. //
  422. int ScsiSeek( hostNo, targetId, logicalAddr )
  423.     int hostNo, targetId;
  424.     unsigned long logicalAddr;
  425. {
  426.     SRB_ExecSCSICmd srb;
  427.  
  428.     for( ; ; ){
  429.         SrbInit( (unsigned char *)&srb, sizeof( srb ) );
  430.         
  431.         srb.SRB_Cmd = 0x02;
  432.         srb.SRB_HaId = hostNo;
  433.         srb.SRB_Flags = 0x00;    /* no data transfer */
  434.         srb.SRB_Target = targetId;
  435.         srb.SRB_SenseLen = SENSE_LEN;
  436.         srb.SRB_CDBLen = 6;
  437.         srb.CDBByte[ 0 ] = (BYTE)0x0b;
  438.         srb.CDBByte[ 1 ] = (BYTE)(( logicalAddr >> 16 ) & 0x00ff);
  439.         srb.CDBByte[ 2 ] = (BYTE)(( logicalAddr >> 8 ) & 0x00ff);
  440.         srb.CDBByte[ 3 ] = (BYTE)(logicalAddr & 0x00ff);
  441.         srb.CDBByte[ 4 ] = 0x00;
  442.         srb.CDBByte[ 5 ] = 0x00;
  443.     
  444.         
  445.         GetMakePostProc(&srb);
  446.         SendASPI32Command(&srb);
  447.         WaitEndAspi();
  448.  
  449.  
  450.  
  451.         while( !srb.SRB_Status ){
  452.             /* wait until command complete */
  453.         }
  454.         if( srb.SRB_HaStat ){
  455.             printf( "ASPI Error : Host adapter error %02x.\n", srb.SRB_HaStat );
  456.             return( -1 );
  457.         }
  458.         switch( srb.SRB_Status ){
  459.         case 0x01:            /* completed without error */
  460.             return( 0 );
  461.         case 0x04:            /* completed with error */
  462.             break;
  463.         case 0x80:            /* invalid scsi request */
  464.         case 0x81:            /* invalid host adapter no. */
  465.         case 0x82:            /* SCSI device not installed */
  466.             printf( "ASPI Error : Command error status = %02x.\n", srb.SRB_Status );
  467.             return( -1 );
  468.         default:
  469.             printf( "ASPI Error : Command error status = %02x.\n", srb.SRB_Status );
  470.             return( -1 );
  471.         }
  472.         switch( srb.SRB_TargStat ){
  473.         case 0x00:
  474.             return( 0 );
  475.         case 0x02:
  476.             if( ( srb.SenseArea[ 12 ] == 0x28 ) || (srb.SenseArea[ 12 ] == 0x29 ) ){
  477.                 /* reset condition */
  478.                 continue;
  479.             }else{
  480.                 printf( "SCSI Error : ID=%d sense key = %02x , sense code = %02x\n",
  481.                     targetId, srb.SenseArea[ 2 ], srb.SenseArea[ 12 ] );
  482.                 return( -1 );
  483.             }
  484.         default:
  485.             return( -1 );
  486.         }
  487.     }
  488. }
  489.  
  490.  
  491. //
  492. //    Read command
  493. //        param.    :
  494. //            int hostNo                        : host adapter no.
  495. //            int targetId                    : target SCSI ID
  496. //            unsigned long logicalAddr        : logical address to seek
  497. //            int blockSize                    : logical block size of target
  498. //            int blockCount                    : no. of block to read
  499. //            unsigned char far *dataBuffer    : read data buffer (max.65536)
  500. //        return    :
  501. //             0 if no error
  502. //            -1 if error occured
  503. //
  504. int ScsiRead( hostNo, targetId, logicalAddr, blockSize, blockCount, dataBuffer )
  505.     int hostNo, targetId, blockSize, blockCount;
  506.     unsigned long logicalAddr;
  507.     unsigned char far *dataBuffer;
  508. {
  509.     
  510.     SRB_ExecSCSICmd srb;
  511.  
  512.     for( ; ; ){
  513.         SrbInit( (unsigned char *)&srb, sizeof( srb ) );
  514.         
  515.         srb.SRB_Cmd = 0x02;
  516.         srb.SRB_HaId = hostNo;
  517.         srb.SRB_Flags = 0x08;    /* target to host */
  518.         srb.SRB_Target = targetId;
  519.         srb.SRB_BufLen = (long)blockSize * blockCount;
  520.         srb.SRB_SenseLen = SENSE_LEN;
  521.         srb.SRB_BufPointer = ( dataBuffer );
  522.         //srb.dataBufferSegment = FP_SEG( dataBuffer );
  523.         srb.SRB_CDBLen = 10;
  524.         srb.CDBByte[ 0 ] = 0x28;
  525.         srb.CDBByte[ 1 ] = 0x00;
  526.         srb.CDBByte[ 2 ] = (BYTE)(( logicalAddr >> 24 ) & 0x00ff);
  527.         srb.CDBByte[ 3 ] = (BYTE)(( logicalAddr >> 16 ) & 0x00ff);
  528.         srb.CDBByte[ 4 ] = (BYTE)(( logicalAddr >> 8 ) & 0x00ff);
  529.         srb.CDBByte[ 5 ] = (BYTE)(logicalAddr & 0x00ff);
  530.         srb.CDBByte[ 6 ] = 0x00;
  531.         srb.CDBByte[ 7 ] = (BYTE)(( blockCount >> 8 ) & 0x00ff);
  532.         srb.CDBByte[ 8 ] = (BYTE)(blockCount & 0x00ff);
  533.         srb.CDBByte[ 9 ] = 0x00;
  534.  
  535.         
  536.         GetMakePostProc(&srb);
  537.         SendASPI32Command(&srb);
  538.         WaitEndAspi();
  539.  
  540.         while( !srb.SRB_Status ){
  541.             /* wait until command complete */
  542.         }
  543.  
  544.         if( srb.SRB_HaStat ){
  545.             printf( "ASPI Error : Host adapter error %02x.\n", srb.SRB_HaStat );
  546.             return( -1 );
  547.         }
  548.         switch( srb.SRB_Status ){
  549.         case 0x01:            /* completed without error */
  550.             return( 0 );
  551.         case 0x04:            /* completed with error */
  552.             break;
  553.         case 0x80:            /* invalid scsi request */
  554.         case 0x81:            /* invalid host adapter no. */
  555.         case 0x82:            /* SCSI device not installed */
  556.             printf( "ASPI Error : Command error status = %02x.\n", srb.SRB_Status );
  557.             return( -1 );
  558.         default:
  559.             printf( "ASPI Error : Command error status = %02x.\n", srb.SRB_Status );
  560.             return( -1 );
  561.         }
  562.         switch( srb.SRB_TargStat ){
  563.         case 0x00:
  564.             return( 0 );
  565.         case 0x02:
  566.             if( ( srb.SenseArea[ 12 ] == 0x28 ) || (srb.SenseArea[ 12 ] == 0x29 ) ){
  567.                 /* reset condition */
  568.                 continue;
  569.             }else{
  570.                 printf( "SCSI Error : ID=%d sense key = %02x , sense code = %02x\n",
  571.                     targetId, srb.SenseArea[ 2 ], srb.SenseArea[ 12 ] );
  572.                 return( -1 );
  573.             }
  574.         default:
  575.             return( -1 );
  576.         }
  577.     }
  578. }
  579.  
  580.  
  581. //
  582. //    clear SRB
  583. //        param. :
  584. //            unsigned char *srb    : area to fill with '0'
  585. //            int count            : clear up size
  586. //
  587. void SrbInit( srb, count )
  588.     unsigned char *srb;
  589.     int count;
  590. {
  591.     int i;
  592.     
  593.     for( i = 0; i < count; i++ ){
  594.         *srb++ = 0;
  595.     }
  596. }
  597.  
  598.