home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / aspisrc.zip / IOCTL.C < prev    next >
C/C++ Source or Header  |  1998-11-29  |  9KB  |  216 lines

  1. #include <devhelp.h>
  2. #include <devdebug.h>
  3. #include <devtype.h>
  4. #include <devrp.h>
  5. #include "AspiRout.h"
  6. #include <i86.h>
  7.  
  8.  
  9. static WORD32 aspiIDC;
  10. BYTE FAR* SRBPtr;                       // SRBPtr2 added 6.7.97 for v. 1.01 (abort SRB)
  11. WORD32 SRBPhys, SRBPtr2, SRBPhys2;      // SRBPhys2 added 6.7.97 for v. 1.01 (abort SRB)
  12. static WORD32 DATAPtr, DATAPhys;
  13. WORD32 aspiPostAddr;
  14. WORD16 codeseg, dataseg, bufseg, result;
  15. BYTE   SRBCommand;
  16. extern "C" BYTE   postInProgress=0;     // determines wheter post routine is currently active
  17.  
  18. #if defined(DEBUG)
  19.  
  20. static const char* MSG_IOCTL              = "Watcom Sample Device Driver IOCtl";
  21. static const char* MSG_CATEGORY           = " Category = ";
  22. static const char* MSG_FUNCTION           = " Function = ";
  23.  
  24. #else
  25.  
  26. #define            MSG_IOCTL              0
  27. #define            MSG_CATEGORY           0
  28. #define            MSG_FUNCTION           0
  29.  
  30. #endif // DEBUG
  31.  
  32. #define IOCTLCAT  0x92
  33.  
  34. // Dispatch IOCtl requests received from the Strategy routine
  35. short data;
  36.  
  37. // IDC to OS2ASPI.DMD with SRB pushed on stack first
  38. void callAspi(void);
  39. #pragma aux callAspi = \
  40.    "push SRBPtr" \
  41.    "push AspiData" \
  42.    "call dword ptr AspiEntry" \
  43.    "add  sp,6";
  44.  
  45. // Get data segment
  46. WORD16 getDataSeg(void);
  47. #pragma aux getDataSeg = "mov ax,ds" value [ax] modify [ax];
  48.  
  49. // Context hook called from posting routine to post semaphore
  50. VOID __far __saveregs __loadds ctx_hand(void)   // this is our context hook
  51. {
  52.   DevEventPost(postSema);
  53. }
  54.  
  55. // posting routine called from OS2ASPI.DMD to notify that SRB is completed.
  56. // See POST.ASM
  57. extern "C" void __cdecl aspiPost(WORD32 SRBPointer)
  58. {
  59. #if defined(DEBUG)
  60.   cdbg << "aspiPost called." << endl;
  61.   cdbg << "SRBPtr: " << SRBPointer << endl;
  62. #endif
  63.   DevCtxArm(Hook1, (WORD32) 0);         // call our hook which will trigger back to app
  64. }
  65.  
  66. // Entry code for aspiPost. Located in POST.ASM
  67. extern "C" void __far postEntry(WORD16, WORD32);
  68.  
  69. WORD16 StratIOCtl(RP FAR* _rp)
  70.   {
  71.   RPIOCtl FAR* rp = (RPIOCtl FAR*)_rp;
  72.   // Print a message to the debug terminal saying which IOCtl we just
  73.   // received.  Of course, if DEBUG is not defined, then the following
  74.   // instructions will generate _NO_ code!
  75.   cdbg << SKELETON;
  76.   cdbg << MSG_IOCTL << hex << setw(4);
  77.   cdbg << MSG_CATEGORY << rp->Category;
  78.   cdbg << MSG_FUNCTION << rp->Function;
  79.   cdbg << setw() << setb() << endl;
  80.  
  81.   if(rp->Category != IOCTLCAT)
  82.      return RPDONE;// | RPERR_COMMAND;
  83.   switch (rp->Function)
  84.      {
  85.      case 0x02:
  86.      // This function 'sends' a SRB to OS2ASPI after converting and completing
  87.      // address fields
  88.        DATAPtr=0;                                               // initialization
  89.        SRBPtr = rp->ParmPacket;                                 // get pointer of SRB
  90.        SRBCommand=*((BYTE FAR*)((WORD32)SRBPtr));               // get SRB command code
  91.        switch (SRBCommand)
  92.        {
  93.          case SRB_Command:
  94. #if defined(DEBUG)
  95.            cdbg << "SRBPtr: " << hex << (WORD32)SRBPtr << endl;
  96.            cdbg << "aspiPost: " << hex << (WORD32)&aspiPost << endl;
  97. #endif
  98.            codeseg=FP_SEG(aspiPost);                                // get code segment
  99.            dataseg=getDataSeg();                                    // get data segment
  100. #if defined(DEBUG)
  101.            cdbg << "code segment: " << hex << codeseg << endl;
  102.            cdbg << "data segment: " << hex << dataseg << endl;
  103. #endif
  104.            DevVirtToPhys(SRBPtr, &SRBPhys);                         // convert address
  105.            aspiPostAddr=(WORD32)(void _far *)postEntry;
  106.            aspiPostAddr=(aspiPostAddr) + (codeseg << 16);   // build address of post routine
  107.            *((WORD32 FAR*)(((WORD32)SRBPtr)+0x26))=SRBPhys; // insert phys. address of SRB
  108.            *((WORD32 FAR*)(((WORD32)SRBPtr)+0x20))=aspiPostAddr; // insert addr of post routine
  109.            *((WORD16 FAR*)(((WORD32)SRBPtr)+0x24))=dataseg; // insert data segment
  110. #if defined(DEBUG)
  111.            cdbg << "SRBPhys: " << (WORD32)SRBPhys << endl;
  112. #endif
  113.            DATAPtr=*((WORD32 FAR*)(((WORD32)SRBPtr)+0x0F)); // get pointer of data buffer
  114. #if defined(DEBUG)
  115.            cdbg << "DATAPtr= " << hex << DATAPtr << endl;
  116.            DevInt3();
  117. #endif
  118.            *((WORD32 FAR*)(((WORD32)SRBPtr)+0x0F))=DATAPhys; // insert in SRB
  119. #if defined(DEBUG)
  120. //         cdbg << "DATAPhys= " << hex << setw(8) << DATAPhys << setw() << dec << 'h' << endl;
  121. #endif
  122. #if defined(DEBUG)
  123.            DevInt3();
  124. #endif
  125.            callAspi();                                      // call OS2ASPI.DMD (IDC)
  126.            break;
  127.          case SRB_Inquiry:
  128.            SRBPtr = rp->ParmPacket;                                 // get pointer of SRB
  129.                                                                     // added 6.7.97
  130.            callAspi();                                      // call OS2ASPI.DMD (IDC)
  131.            break;
  132.          case SRB_Device:
  133.            SRBPtr = rp->ParmPacket;                                 // get pointer of SRB
  134.                                                                     // added 6.7.97
  135.            callAspi();                                      // call OS2ASPI.DMD (IDC)
  136.            break;
  137.          // Abort added 7.6.97 for version 1.01
  138.          case SRB_Abort:
  139.            while (postInProgress) {}                    // wait for post routine to complete
  140.            SRBPtr = rp->ParmPacket;                                 // get pointer of SRB
  141.                                                                     // added 6.7.97
  142.            SRBPtr2=*((WORD32 FAR*)(((WORD32)SRBPtr)+0x08)); // get address of SRB to abort
  143. #if defined(DEBUG)
  144.            cdbg << "SRB to abort address: " << hex << (WORD32)SRBPtr2 << endl;
  145. #endif
  146.            DevVirtToPhys((BYTE FAR*)SRBPtr2, &SRBPhys2);               // convert address
  147. #if defined(DEBUG)
  148.            cdbg << "SRB to abort address (phys): " << hex << (WORD32)SRBPhys2 << endl;
  149. #endif
  150.                                                             // (assume its locked by DosDevIOCtl)
  151.            *((WORD32 FAR*)(((WORD32)SRBPtr)+0x08))=SRBPhys2; // insert addr of SRB to abort
  152.            callAspi();                                      // call OS2ASPI.DMD (IDC)
  153.            break;
  154.          case SRB_Reset:
  155.            SRBPtr = rp->ParmPacket;                                 // get pointer of SRB
  156.                                                                     // added 6.7.97
  157.            codeseg=FP_SEG(aspiPost);                                // get code segment
  158.            dataseg=getDataSeg();                                    // get data segment
  159.            aspiPostAddr=(WORD32)(void _far *)postEntry;
  160.            aspiPostAddr=(aspiPostAddr) + (codeseg << 16);   // build address of post routine
  161.            *((WORD32 FAR*)(((WORD32)SRBPtr)+0x20))=aspiPostAddr; // insert addr of post routine
  162.            *((WORD16 FAR*)(((WORD32)SRBPtr)+0x24))=dataseg; // insert data segment
  163.            callAspi();                                      // call OS2ASPI.DMD (IDC)
  164.            break;
  165.          default:
  166.            break;
  167.        }
  168.        break;
  169.      case 0x03:
  170.      // This function is to hand over an event semaphore handle to the device driver
  171.  
  172.        //Get handle of semaphore from app
  173.        *((WORD32 *) &postSema) = *((WORD32 FAR*)rp->ParmPacket);
  174.  
  175.        //Open Event Semaphore and return error to app
  176.        result = DevEventOpen(postSema);
  177. #if defined(DEBUG)
  178.        cdbg << "DevEventOpen returned with: " << result << endl;
  179. #endif
  180.        *((WORD16 FAR*)rp->DataPacket) = *((WORD16 *) &result);  // return result to app
  181.        break;
  182.      case 0x04:
  183.        //Get buffer pointer from app
  184.        *((WORD32 *) &DATAPtr) = (WORD32)(WORD32 FAR*)rp->ParmPacket;
  185.        bufseg=FP_SEG(DATAPtr);
  186. #if defined(DEBUG)
  187.        cdbg << "Buffer segment: " << hex << bufseg << endl;
  188.        cdbg << "Bufer: " << hex << DATAPtr << endl;
  189. #endif
  190.        result=DevSegLock((SEL)bufseg, 1, 0, &LockHandle);     // lock segment
  191.        *((WORD16 FAR*)rp->DataPacket) = *((WORD16 *) &result);  // return result to app
  192. #if defined(DEBUG)
  193.        if (result)
  194.        {
  195.          cdbg << "DevSegLock failed!" << endl;
  196.        }
  197.        else
  198.        {
  199.          cdbg << "DevSegLock succeeded." << endl;
  200.        }
  201. #endif
  202.        DevVirtToPhys((BYTE FAR*) DATAPtr, &DATAPhys);   // convert ptr to data buffer
  203. #if defined(DEBUG)
  204.        cdbg << "DATAPhys: (hi) " << hex << (DATAPhys >> 16) << endl;
  205.        cdbg << "DATAPhys: (lo) " << hex << (DATAPhys & 0xFFFF) << endl;
  206.        cdbg << "LockHandle: " << hex << (WORD32)LockHandle << endl;
  207. #endif
  208.        break;
  209.      default:
  210.        break;
  211.      }
  212.   return RPDONE; // | RPERR_COMMAND;
  213.   }
  214.  
  215.  
  216.