home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / ddkx86v5.zip / DDKX86 / SRC / DEV / PCMCIA / CLSAMPLE / CLSAMPLE.C < prev    next >
Encoding:
C/C++ Source or Header  |  1995-04-14  |  30.2 KB  |  996 lines

  1. /*DDK*************************************************************************/
  2. /*                                                                           */
  3. /* COPYRIGHT    Copyright (C) 1995 IBM Corporation                           */
  4. /*                                                                           */
  5. /*    The following IBM OS/2 WARP source code is provided to you solely for  */
  6. /*    the purpose of assisting you in your development of OS/2 WARP device   */
  7. /*    drivers. You may use this code in accordance with the IBM License      */
  8. /*    Agreement provided in the IBM Device Driver Source Kit for OS/2. This  */
  9. /*    Copyright statement may not be removed.                                */
  10. /*                                                                           */
  11. /*****************************************************************************/
  12. /*****************************************************************************/
  13. /*                                                                           */
  14. /*                                                                           */
  15. /*    The following IBM OS/2 2.1 source code is provided to you solely for   */
  16. /*    the purpose of assisting you in your development of OS/2 2.x device    */
  17. /*    drivers. You may use this code in accordance with the IBM License      */
  18. /*    Agreement provided in the IBM Device Driver Source Kit for OS/2. This  */
  19. /*    Copyright statement may not be removed.                                */
  20. /*                                                                           */
  21. /*****************************************************************************/
  22. /**************************************************************************
  23.  *
  24.  * SOURCE FILE NAME = CLSAMPLE.C
  25.  *
  26.  * DESCRIPTIVE NAME = PCMCIA Client Services Sample Code
  27.  *
  28.  *
  29.  *
  30.  *
  31.  * The following IBM OS/2 2.1 source code is provided to you solely for
  32.  * the purpose of assisting you in your development of OS/2 2.x device
  33.  * drivers. You may use this code in accordance with the IBM License
  34.  * Agreement provided in the IBM Device Driver Source Kit for OS/2. This
  35.  * Copyright statement may not be removed.
  36.  *
  37.  *
  38.  *
  39.  * VERSION =
  40.  *
  41.  * DATE        6/22/93
  42.  *
  43.  * DESCRIPTION This is PCMCIA client services driver skeleton.
  44.  *
  45.  * FUNCTIONS   This driver supports the following strategy commands.
  46.  *
  47.  *              0x00  INIT
  48.  *              0x0d  OPEN DEVICE
  49.  *              0x0e  CLOSE DEVICE
  50.  *              0x10  GENERIC IOCtl
  51.  *              0x1F  INIT COMPLETE
  52.  *
  53.  * ENTRY POINTS:
  54.  *
  55.  * DEPENDENCIES:
  56.  *
  57.  * NOTES
  58.  *
  59.  *
  60.  * STRUCTURES
  61.  *
  62.  * EXTERNAL REFERENCES
  63.  *
  64.  * EXTERNAL FUNCTIONS
  65.  *
  66.  ***************************************************************************/
  67.  
  68. #define  INCL_DOSMISC
  69. #define  INCL_DOSINFOSEG
  70. #define  INCL_16
  71.  
  72. #include "os2.h"
  73. #include "error.h"
  74. #include "devhdr.h"
  75. #include "dhcalls.h"
  76. #include "client.h"
  77. #include "clsample.h"
  78. #include "string.h"
  79.  
  80. #ifdef WAT
  81. /* Pragmas for MSC Calling Convention */
  82. #pragma aux (cdecl) CBHandler;
  83. #pragma aux (cdecl) CBMTDHandler;
  84. #pragma aux (cdecl) CSCall;
  85. #pragma aux (cdecl) CBEntry;
  86. #pragma aux (cdecl) STRENTRY;
  87. #pragma aux (cdecl) StrProc;
  88. #endif
  89.  
  90. extern void  far  CBEntry();
  91. extern ULONG      CSCall();
  92.  
  93. extern void   STRENTRY();
  94. USHORT StrProc(PREQPACKET);
  95. int    far  Init(PREQPACKET);
  96. int    far  InitComp(PREQPACKET);
  97. int    far  Open(PREQPACKET);
  98. int    far  Close(PREQPACKET);
  99. int    far  IOCtl(PREQPACKET);
  100. int    far  DeInstall(PREQPACKET);
  101. ULONG  far  f_CSCall_Wait(USHORT, USHORT, ULONG, USHORT, PUCHAR);
  102. ULONG  near CSCall_Wait(USHORT, USHORT, ULONG, USHORT, PUCHAR);
  103. void   far  TimerHandler();
  104. void   far  CardRemoval(USHORT, USHORT, USHORT, USHORT, USHORT, USHORT, PUCHAR);
  105. BOOL   near WaitArgPkt();
  106. BOOL   near ReleaseArgPkt();
  107.  
  108. /*
  109. ** pragma definition
  110. */
  111. #pragma alloc_text(InitCode, Init)
  112. #pragma alloc_text(SwapCode, InitComp)
  113. #pragma alloc_text(SwapCode, Open)
  114. #pragma alloc_text(SwapCode, Close)
  115. #pragma alloc_text(SwapCode, IOCtl)
  116. #pragma alloc_text(SwapCode, DeInstall)
  117. #pragma alloc_text(SwapCode, CardRemoval)
  118. #pragma alloc_text(SwapCode, WaitArgPkt)
  119. #pragma alloc_text(SwapCode, ReleaseArgPkt)
  120.  
  121. DEVICEHDR devhdr = {
  122.         (void far *) 0xFFFFFFFF,                             /* link         */
  123.         (DEV_CHAR_DEV | DEV_SHARE | DEV_30| DEVLEV_3 ),      /* attr         */
  124.         (PUSHORT) STRENTRY,                                  /* &strategy    */
  125.         (USHORT)0,                                           /* &IDCroutine  */
  126.         "SAMPLEDD",
  127.         {0},
  128.         DEV_INITCOMPLETE
  129. };
  130.  
  131. /*
  132. ** global data
  133. */
  134. PFN         Device_Help = 0;               /* storage area for DevHlp calls   */
  135. PFN         CSEntry     = 0;               /* storage area for Card Services  */
  136. USHORT      opencount = 0;                 /* count of DosOpens               */
  137. USHORT      savepid = 0;                   /* save the caller's PID           */
  138. UCHAR       PCMCIA_DD[]="PCMCIA$ ";        /* name of card services driver    */
  139. ATTACHAREA  AttachArea = {0};              /* data area to hold address       */
  140. USHORT      hClient = 0;                   /* client handle                   */
  141. USHORT      hMemory = 0;                   /* memory handle                   */
  142. USHORT      status = 0;                    /* status from CSCall              */
  143. USHORT      devType = 0;                   /* device type                     */
  144. USHORT      CL_status = 0;                 /* swappable code seg lock status  */
  145. USHORT      cntWaiting = 0;                /* waiting request from app.       */
  146. ULONG       lockhandle = 0;                /* handle for locked segment       */
  147. UCHAR       ArgPacket[100] = {0};          /* argument packet buffer          */
  148.  
  149. UCHAR    MainMsg[]  = "\r\nOS/2 PCMCIA Client Sample Device Driver installed.\r\n";
  150.  
  151.  
  152. /****************************************************************************
  153.  *
  154.  * FUNCTION NAME = StrProc
  155.  *
  156.  * DESCRIPTION   = Strategy commands process routine
  157.  *
  158.  * INPUT         = the pointer to the requesst packet
  159.  *
  160.  * OUTPUT        = status
  161.  *
  162.  * RETURN-NORMAL =
  163.  * RETURN-ERROR  =
  164.  *
  165.  ****************************************************************************/
  166.  
  167. USHORT StrProc(PREQPACKET rp)          /* Pks near */
  168. {
  169.     PFN       pFunction = 0;
  170.     USHORT    rc;
  171.  
  172.     if (rp->RPcommand == RPINIT)  /* 0x00 */
  173.         /*
  174.         ** init called by kernel in protected mode ring 3 with IOPL
  175.         */
  176.        {
  177.         return Init(rp);
  178.        }
  179.     else
  180.     {
  181.  
  182.         /* ********************
  183.         ** * Development Tips *
  184.         ** ********************
  185.         **
  186.         ** When the version of card services does not match this client
  187.         ** driver or when "Register Client" request fails, INIT_FAIURE
  188.         ** flag is set.  Return with error code to the application
  189.         ** without proceeding anything.  Make sure that all swappable
  190.         ** segments are all swapped out.
  191.         **
  192.         */
  193.  
  194.         if (CL_status & INIT_FAILURE)
  195.         {
  196.            return (RPDONE | RPERR | ERROR_I24_GEN_FAILURE);
  197.         }
  198.  
  199.         /* ********************
  200.         ** * Development Tips *
  201.         ** ********************
  202.         **
  203.         ** For the information of multiple code segment support,
  204.         ** When the allocation of each procedure is considered, it is
  205.         ** necessary to try to make each segment size close to a 4K
  206.         ** boundary,  becuase the unit swap size is in 4KB memory pages.
  207.         **
  208.         ** Basically all public entry points, Strategy entry routine,
  209.         ** Callback entry routine, Timer handler, and Event procedures
  210.         ** for some events, those with very high frequency of usage,
  211.         ** should be in the main (resident) code segment.
  212.         **
  213.         ** Those routines not needed during interrupt context (timer
  214.         ** or HW) should be moved into the swappable segments.
  215.         **
  216.         ** If IOCtl routine and Event Procedure 2 does not have any
  217.         ** relation, and it is possible to make two swappable code
  218.         ** segments.  In this code, only one swappable code segment
  219.         ** exists.
  220.         **
  221.         ** +----Client Services Driver----------------------------+
  222.         ** | +-------------------------------------------------+  |
  223.         ** | |                                     +---------+ |  |
  224.         ** | | +---------+ +---------+ +---------+ |INIT     | |  |
  225.         ** | | |         | |         | |         | |  Routine| |  |
  226.         ** | | |Strategy | |Callback | |Event    | +---------+ |  |
  227.         ** | | |  Routine| |   Entry | |  Procs 1| +---------+ |  |
  228.         ** | | |         | |         | |         | |Timer    | |  |
  229.         ** | | +---------+ +---------+ +---------+ |  Handler| |  |
  230.         ** | |                                     +---------+ |  |
  231.         ** | +------- Resident Code segement  -----------------+  |
  232.         ** |                                                      |
  233.         ** |   +-----------------------------------------+        |
  234.         ** |   | +---------+ | +---------+ | +---------+ |        |
  235.         ** |   | |         | | |         | | |         | |        |
  236.         ** |   | | IOCtl   | | | Work sub| | |Event    | |        |
  237.         ** |   | |  Routine| | | routins | | |  Procs 2| |        |
  238.         ** |   | |         | | |         | | |         | |        |
  239.         ** |   | +---------+ | +---------+ | +---------+ |        |
  240.         ** |   +------ Swappable Code Segment(s) --------+        |
  241.         ** |                                                      |
  242.         ** +------------------------------------------------------+
  243.         **
  244.         */
  245.  
  246.         if (!(CL_status & CODE_LOCKED))    /* code is not locked             */
  247.         {
  248.            pFunction = (PFN) Open;
  249.                                            /* lock SwapCode code segment     */
  250.            if (!DevHelp_Lock(SELECTOROF(pFunction),
  251.                              LOCKTYPE_LONG_ANYMEM,
  252.                              0,
  253.                              &lockhandle))
  254.               CL_status |= CODE_LOCKED;    /* set locked status              */
  255.            else
  256.            {
  257.               CL_status &= (~CODE_LOCKED); /* clear locked status            */
  258.               return (RPDONE | RPERR | ERROR_I24_GEN_FAILURE);
  259.            }
  260.         }
  261.  
  262.         switch(rp->RPcommand)
  263.         {
  264.             case RPINITCOMP:  /* 0x1F */
  265.  
  266.                 rc = InitComp(rp);
  267.                 break;
  268.  
  269.             case RPOPEN:      /* 0x0d */
  270.  
  271.                 rc = Open(rp);
  272.                 break;
  273.  
  274.             case RPCLOSE:     /* 0x0e */
  275.  
  276.                 rc = Close(rp);
  277.                 break;
  278.  
  279.             case RPIOCTL:     /* 0x10 */
  280.  
  281.                 rc = IOCtl(rp);
  282.                 break;
  283.  
  284.             case RPDEINSTALL: /* 0x14 */
  285.  
  286.                 rc = DeInstall(rp);
  287.                 break;
  288.  
  289.                 /*
  290.                 ** all other commands are ignored
  291.                 */
  292.             default:
  293.                 rc = RPDONE;
  294.                 break;
  295.         }
  296.  
  297.             /*
  298.             ** If no requests is queueing, unlock the segment.
  299.             */
  300.         if (!cntWaiting)
  301.         {
  302.             if (!DevHelp_UnLock (lockhandle))
  303.                 CL_status &= (~CODE_LOCKED);
  304.         }
  305.         return(rc);
  306.     }
  307. }
  308.  
  309. /****************************************************************************
  310.  *
  311.  * FUNCTION NAME = Init
  312.  *
  313.  * DESCRIPTION   = Initialization routine
  314.  *
  315.  * INPUT         = the pointer to the request packet
  316.  *
  317.  * OUTPUT        = the status
  318.  *
  319.  * RETURN_NORMAL =
  320.  * RETURN-ERROR  =
  321.  *
  322.  ****************************************************************************/
  323.  
  324. int far Init(PREQPACKET rp)
  325. {
  326.     USHORT lid;
  327.     USHORT ReturnValue;       /* pks */
  328.     register char far *p;
  329.  
  330.     /*
  331.     ** store DevHlp entry point
  332.     */
  333.     Device_Help = rp->s.Init.DevHlp;       /* save DevHlp entry point        */
  334.  
  335.     /*
  336.     ** get entry to card services driver PCMCIA$
  337.     */
  338.     if (DevHelp_AttachDD(PCMCIA_DD, (NPBYTE)&AttachArea))
  339.       {
  340.         ReturnValue = (RPDONE | RPERR  | ERROR_I24_GEN_FAILURE);  /* pks */
  341.         return(ReturnValue);
  342.       }
  343.                       /*           */
  344.     OFFSETOF(CSEntry)   = AttachArea.offEPProt;
  345.     SELECTOROF(CSEntry) = AttachArea.selEPProt;
  346.  
  347.     DosPutMessage(1, 56, MainMsg);
  348.     /*
  349.     ** send back our cs and ds end values to os/2
  350.     */
  351.     rp->s.InitExit.finalCS = (USHORT)Init;
  352.     rp->s.InitExit.finalDS = (USHORT)(MainMsg + (sizeof(MainMsg)));
  353.  
  354.     return (RPDONE);
  355.  
  356. }
  357.  
  358.  
  359.  
  360. /****************************************************************************
  361.  *
  362.  * FUNCTION NAME = InitComp
  363.  *
  364.  * DESCRIPTION   = InitComp process routine
  365.  *
  366.  * INPUT         = the pointer to the request packet
  367.  *
  368.  * OUTPUT        = the status
  369.  *
  370.  * RETURN_NORMAL =
  371.  * RETURN-ERROR  =
  372.  *
  373.  ****************************************************************************/
  374.  
  375. int far InitComp(PREQPACKET rp)
  376. {
  377.     ULONG     rc;
  378.     ULONG     addr;
  379.     USHORT    ReturnValue;       /* modified by pks */
  380.     int       i;
  381.  
  382.     ReturnValue= (RPDONE) | (RPERR | ERROR_I24_GEN_FAILURE);
  383.     /*
  384.     ** check Card Services version
  385.     */
  386.  
  387.     /* ********************
  388.     ** * Development Tips *
  389.     ** ********************
  390.     **
  391.     ** If the driver expects that Callback entry point is always called
  392.     ** from Card Services at task time, the following version check
  393.     ** will be required.  Earlier versions of Card Services allowed
  394.     ** callbacks at task and interrupt time.
  395.     **
  396.     */
  397.  
  398.     CLEAR_ARGPACKET;                   /* clear argument buffer          */
  399.  
  400.     rc = f_CSCall_Wait(GET_CARDSERVICES_INFO,
  401.                        NULL,
  402.                        NULL,
  403.                        sizeof(GET_CSINFO),
  404.                        (PUCHAR)ArgPacket);
  405.  
  406.     if (((PGET_CSINFO)ArgPacket)->usCSLevel < CS_LEVEL)
  407.     {
  408.         CL_status |= INIT_FAILURE;
  409.         return(ReturnValue);
  410.     }
  411.  
  412.     if ((((PGET_CSINFO)ArgPacket)->usCSLevel == CS_LEVEL) &&
  413.         (((PGET_CSINFO)ArgPacket)->usRevision < CS_REVISION))
  414.     {
  415.         CL_status |= INIT_FAILURE;
  416.         return(ReturnValue);  /* modified by pks */
  417.     }
  418.  
  419.     /*
  420.     ** issue RegisterClient function to CS
  421.     */
  422.     CLEAR_ARGPACKET;                   /* clear argument buffer          */
  423.     addr = (ULONG) ArgPacket;
  424.  
  425.     ((PREG_CLIENT)ArgPacket)->usAttributes    =
  426.                                         RCA_MEMORY_CDD | RCA_CI_SHARABLE;
  427.     ((PREG_CLIENT)ArgPacket)->usEventMask     = EM_ALL_EVENTS;
  428.     ((PREG_CLIENT)ArgPacket)->usClientData[1] = SELECTOROF(addr);
  429.     ((PREG_CLIENT)ArgPacket)->usVersion       = 0x0200;
  430.  
  431.     rc = f_CSCall_Wait(REGISTER_CLIENT,
  432.                        NULL,
  433.                        (ULONG)CBEntry,
  434.                        sizeof(REG_CLIENT),
  435.                        (PUCHAR)ArgPacket);
  436.  
  437.     status  = *((PUSHORT)(&rc));       /* save status from CSCall        */
  438.     hClient = *((PUSHORT)(&rc)+1);     /* save client handle             */
  439.  
  440.     if (status)
  441.     {
  442.         CL_status |= INIT_FAILURE;
  443.         return(ReturnValue); /* modified PKS */
  444.     }
  445.  
  446.     return (RPDONE);
  447.  
  448. }
  449.  
  450. /****************************************************************************
  451.  *
  452.  * FUNCTION NAME = Open
  453.  *
  454.  * DESCRIPTION   = Open process routine
  455.  *
  456.  * INPUT         = the pointer to the request packet
  457.  *
  458.  * OUTPUT        = the status
  459.  *
  460.  * RETURN_NORMAL =
  461.  * RETURN-ERROR  =
  462.  *
  463.  ****************************************************************************/
  464.  
  465. int far Open(PREQPACKET rp)
  466. {
  467.     return (RPDONE);
  468.  
  469. }
  470.  
  471. /****************************************************************************
  472.  *
  473.  * FUNCTION NAME = Close
  474.  *
  475.  * DESCRIPTION   = Close process routine
  476.  *
  477.  * INPUT         = the pointer to the request packet
  478.  *
  479.  * OUTPUT        = the status
  480.  *
  481.  * RETURN_NORMAL =
  482.  * RETURN-ERROR  =
  483.  *
  484.  ****************************************************************************/
  485.  
  486. int far Close(PREQPACKET rp)
  487. {
  488.     return (RPDONE);                   /* return 'done' status to caller */
  489.  
  490. }
  491.  
  492. /****************************************************************************
  493.  *
  494.  * FUNCTION NAME = IOCtl
  495.  *
  496.  * DESCRIPTION   = IOCtl process routine
  497.  *
  498.  * INPUT         = the pointer to the request packet
  499.  *
  500.  * OUTPUT        = the status
  501.  *
  502.  * RETURN_NORMAL =
  503.  * RETURN-ERROR  =
  504.  *
  505.  ****************************************************************************/
  506.  
  507. int far IOCtl(PREQPACKET rp)
  508. {
  509.     ULONG     rc;
  510.     int       i;
  511.     USHORT    ReturnValue; /* pks */
  512.  
  513.     /* ********************
  514.     ** * Development Tips *
  515.     ** ********************
  516.     **
  517.     ** To support multiple threads, if the buffer for Argument Packet
  518.     ** is not available, block the thread and wait until the buffer is
  519.     ** availble.
  520.     */
  521.     ReturnValue=(RPDONE | RPERR | ERROR_I24_GEN_FAILURE); /* PKS */
  522.     if (!WaitArgPkt())
  523.        return(ReturnValue);  /* PKS */
  524.  
  525.     /*
  526.     ** please add your unique process here..
  527.     **
  528.     ** for example....   issue OpenMemory to CS
  529.     */
  530.  
  531.     CLEAR_ARGPACKET;                   /* clear argument buffer          */
  532.  
  533.     ((POPN_MEMORY)ArgPacket)->usSocket     = 1;
  534.     ((POPN_MEMORY)ArgPacket)->usAttributes = OMA_EXCLUSIVE;
  535.     ((POPN_MEMORY)ArgPacket)->ulOffset     = 0;
  536.  
  537.     rc = f_CSCall_Wait(OPEN_MEMORY,
  538.                        hClient,
  539.                        (ULONG)NULL,
  540.                        sizeof(OPN_MEMORY),
  541.                        (PUCHAR)ArgPacket);
  542.  
  543.     status  = *((PUSHORT)(&rc));       /* save status from CSCall        */
  544.     hMemory = *((PUSHORT)(&rc)+1);     /* save memory handle             */
  545.  
  546.  
  547.     if (!ReleaseArgPkt())
  548.        rc = ReturnValue;      /* pks */
  549.  
  550.     return (RPDONE);
  551.  
  552. }
  553.  
  554. /****************************************************************************
  555.  *
  556.  * FUNCTION NAME = DeInstall
  557.  *
  558.  * DESCRIPTION   = DeInstall process routine
  559.  *
  560.  * INPUT         = the pointer to the request packet
  561.  *
  562.  * OUTPUT        = the status
  563.  *
  564.  * RETURN_NORMAL =
  565.  * RETURN-ERROR  =
  566.  *
  567.  ****************************************************************************/
  568.  
  569. int far DeInstall(PREQPACKET rp)
  570. {
  571.     USHORT ReturnValue;
  572.     ReturnValue = RPDONE | RPERR | ERROR_I24_BAD_COMMAND ;
  573.     return(ReturnValue);
  574.  
  575. }
  576.  
  577.  
  578. /***************************************************************************
  579.  *
  580.  * FUNCTION NAME = CSCall_Wait
  581.  *
  582.  * DESCRIPTION   = This routine calls to Card Services.   If CS returns
  583.  *                 "BUSY" return code, it will retry 10 times.
  584.  *
  585.  * INPUT         = function argument
  586.  *                 handle argument
  587.  *                 pointer argument
  588.  *                 Arglength argument
  589.  *                 ArgPointer argument
  590.  *
  591.  * OUTPUT        = Status argument
  592.  *                 handle
  593.  *
  594.  * RETURN-NORMAL =
  595.  * RETURN-ERROR  =
  596.  *
  597.  **************************************************************************/
  598.  
  599. ULONG FAR f_CSCall_Wait(USHORT function, USHORT clHandle,
  600.                         ULONG  ptrArg,   USHORT lnArg,  PUCHAR argPtrArg)
  601. {
  602.     return(CSCall_Wait(function, clHandle, ptrArg,
  603.                        lnArg, argPtrArg));
  604. }
  605.  
  606.  
  607. ULONG near CSCall_Wait(USHORT function, USHORT clHandle,    /* pks near */
  608.                   ULONG  ptrArg,   USHORT lnArg,  PUCHAR argPtrArg)
  609. {
  610.     int    i;
  611.     ULONG  rc;
  612.  
  613.     /* ********************
  614.     ** * Development Tips *
  615.     ** ********************
  616.     **
  617.     ** When Card Sevice returns BUSY status, this driver starts the timer
  618.     ** and retry certain times.  Temporally it tries 10 time.  This value
  619.     ** should be adjusted.
  620.     */
  621.  
  622.     for (i = 0; i < 10; i++)         /* It is just sample                  */
  623.     {                                /* It will retry maximum 10 times     */
  624.         rc = CSCall(function,
  625.                     clHandle,
  626.                     ptrArg,
  627.                     lnArg,
  628.                     argPtrArg);
  629.  
  630.         if (*((PUSHORT)(&rc)) == BUSY)    /* check r/c BUSY or not         */
  631.         {
  632.             /* ********************
  633.             ** * Development Tips *
  634.             ** ********************
  635.             **
  636.             ** Currenly TIMERCOUNT is 2 ticks.
  637.             ** TIMERCOUNT should be adjusted when you debug the code.
  638.             **
  639.             */
  640.  
  641.             if (!DevHelp_TickCount ((NPFN)TimerHandler,
  642.                                     TIMERCOUNT))
  643.             {
  644.                 DISABLE;
  645.                 CL_status |= TIMER_START;
  646.                                           /* until timer expired           */
  647.                                           /*   it block this thread        */
  648.                 while (CL_status & TIMER_START)
  649.                 {
  650.                     DevHelp_ProcBlock ((ULONG)(&CL_status), -1L, 0);
  651.                     DISABLE;
  652.                 }
  653.             }
  654.             else
  655.                 return(rc);
  656.         }
  657.         else
  658.         {
  659.             return(rc);
  660.         }
  661.  
  662.     }
  663.     return(rc);
  664.  
  665. }
  666.  
  667.  
  668. /***************************************************************************
  669.  *
  670.  * FUNCTION NAME = TimerHandler
  671.  *
  672.  * DESCRIPTION   = This routine is called from Kernel.
  673.  *
  674.  * INPUT         =
  675.  *
  676.  * OUTPUT        =
  677.  *
  678.  * RETURN-NORMAL =
  679.  * RETURN-ERROR  =
  680.  *
  681.  **************************************************************************/
  682.  
  683. void far TimerHandler()
  684. {
  685.     USHORT   Awakecount;
  686.  
  687.     DevHelp_ResetTimer((NPFN)TimerHandler);
  688.  
  689.     CL_status &= (~TIMER_START);
  690.  
  691.         /*
  692.         ** It let the thread run and try to call CS again
  693.         */
  694.     DevHelp_ProcRun ((ULONG)(&CL_status), (PUSHORT)(&Awakecount));
  695.  
  696.     return;
  697.  
  698. }
  699.  
  700. /****************************************************************************
  701.  *
  702.  * FUNCTION NAME = CBHandler
  703.  *
  704.  * DESCRIPTION   = callback handler
  705.  *
  706.  * INPUT         = function
  707.  *                 socket
  708.  *                 card status, socket status information
  709.  *                 ClientVal field from ClientData structure
  710.  *                 ClientDS field from ClientData structure
  711.  *                 ClientOff field from ClientData structure
  712.  *                 pointer to buffer
  713.  *
  714.  * OUTPUT        = the status
  715.  *
  716.  * RETURN_NORMAL =
  717.  * RETURN-ERROR  =
  718.  *
  719.  ****************************************************************************/
  720.  
  721. int CBHandler(USHORT function, USHORT socket, USHORT info,
  722.               USHORT clientVal, USHORT clientDS, USHORT clientOff,
  723.               PUCHAR Buffer)
  724. {
  725.     int       i;
  726.     ULONG     rc;
  727.     PFN       pFunction = 0;
  728.  
  729.     switch (function)
  730.     {
  731.  
  732.     /*
  733.     ** please add your unique event process here..
  734.     **
  735.     ** just example....
  736.     */
  737.  
  738.     /* ********************
  739.     ** * Development Tips *
  740.     ** ********************
  741.     **
  742.     ** It is possible to get the following events from Card Services
  743.     ** when the PC card is not present.
  744.     **
  745.     **   - CARD_INSERTION
  746.     **   - CLIENT_INFO
  747.     **   - INSERTION_REQUEST
  748.     **   - INSERTION_COMPLETE
  749.     **   - REGISTRATION_COMPLETE
  750.     **   - SS_UPDATED
  751.     **
  752.     ** For the information of multiple code segment support,
  753.     ** the code for the events in the above should be in the resident
  754.     ** code segment if still it has a space.
  755.     **
  756.     ** The space means that space to 4K boundary.  The unit of swap
  757.     ** is 4K.  When the allocation of each procedure is considered
  758.     ** it is necessary to try to make each segment size close to
  759.     ** 4K boundary.
  760.     **
  761.     ** The code for the other events should be in the swappable code
  762.     ** segment, and when CARD_INSERTION event is gotten, the segment
  763.     ** should be locked.  When CARD_REMOVAL event is sent, the locked
  764.     ** segment should be released.
  765.     **
  766.     */
  767.  
  768.     case CARD_INSERTION:
  769.  
  770.         /* ********************
  771.         ** * Development Tips *
  772.         ** ********************
  773.         **
  774.         ** The fax/modem driver will call COM.SYS IDC entry to register
  775.         ** COM port for the requested card in CARD_INSERTION.
  776.         **
  777.         ** COM.SYS must be called at task time.
  778.         */
  779.  
  780.         /*
  781.         ** please add your card initialize process here ....
  782.         */
  783.         CLEAR_ARGPACKET;                   /* clear argument packet buffer   */
  784.  
  785.         ((PGET_CONFGINFO)ArgPacket)->usSocket = socket;
  786.  
  787.         rc = CSCall_Wait(GET_CONFIGURATIONINFO,
  788.                          NULL,
  789.                          (ULONG)NULL,
  790.                          sizeof(GET_CONFGINFO),
  791.                          (PUCHAR)ArgPacket);
  792.  
  793.         status  = *((PUSHORT)(&rc));       /* save status from CSCall        */
  794.                                            /* save the first device type     */
  795.         devType = (USHORT)(((PGET_CONFGINFO)ArgPacket)->ucFirstDevType);
  796.  
  797.  
  798.            /* ********************
  799.            ** * Development Tips *
  800.            ** ********************
  801.            **
  802.            ** When this client driver suppots requested card,
  803.            ** and this card is only one which this driver recognizes,
  804.            ** lock the segment which has the events procedures.
  805.            **
  806.            */
  807.  
  808.            if (!(CL_status & CODE_LOCKED))    /* code is not locked           */
  809.            {
  810.               pFunction = (PFN) Open;
  811.                                               /* lock SwapCode code segment   */
  812.               if (!DevHelp_Lock(SELECTOROF(pFunction),
  813.                                 LOCKTYPE_LONG_ANYMEM,
  814.                                 0,
  815.                                 &lockhandle))
  816.                  CL_status |= CODE_LOCKED;    /* set locked status            */
  817.               else
  818.               {
  819.                  CL_status &= (~CODE_LOCKED); /* clear locked status          */
  820.               }
  821.            }
  822.  
  823.         return(SUCCESS);                   /* always SUCCESS must be returned */
  824.  
  825.  
  826.     case CARD_REMOVAL:
  827.  
  828.         /* ********************
  829.         ** * Development Tips *
  830.         ** ********************
  831.         **
  832.         ** The fax/modem driver will call COM.SYS IDC entry to deregister
  833.         ** COM port for the requested card in CARD_REMOVAL.
  834.         **
  835.         ** COM.SYS must be called at task time.
  836.         */
  837.  
  838.         CardRemoval(function, socket, info,
  839.                     clientVal, clientDS,
  840.                     clientOff, Buffer);
  841.  
  842.            /* ********************
  843.            ** * Development Tips *
  844.            ** ********************
  845.            **
  846.            ** When there is no more cards that this driver supports
  847.            ** in the sockets, and there is no request to wait for
  848.            ** process, the locked segment should be unlocked.
  849.            */
  850.  
  851.            if (!cntWaiting)
  852.            {
  853.                if (!DevHelp_UnLock (lockhandle))
  854.                    CL_status &= (~CODE_LOCKED);
  855.            }
  856.  
  857.         return(SUCCESS);                   /* always SUCCESS must be returned */
  858.  
  859.     default:
  860.         return(SUCCESS);
  861.  
  862.     } /* endswitch */
  863. }
  864.  
  865.  
  866. /****************************************************************************
  867.  *
  868.  * FUNCTION NAME = CBMTDHandler
  869.  *
  870.  * DESCRIPTION   = MTD request callback handler
  871.  *
  872.  * INPUT         = function
  873.  *                 socket
  874.  *                 ClientVal field from ClientData structure
  875.  *                 ClientDS field from ClientData structure
  876.  *                 ClientOff field from ClientData structure
  877.  *                 pointer to MTD request packet
  878.  *                 pointer to buffer
  879.  *
  880.  * OUTPUT        = the status
  881.  *
  882.  * RETURN_NORMAL =
  883.  * RETURN-ERROR  =
  884.  *
  885.  ****************************************************************************/
  886.  
  887. int CBMTDHandler(USHORT function, USHORT socket,
  888.                  USHORT clientVal, USHORT clientDS, USHORT clientOff,
  889.                  PMTD_REQPKT pMTDReqPkt, PUCHAR Buffer)
  890. {
  891.  
  892.     /*
  893.     **
  894.     ** please add your unique MTD event process here...
  895.     **
  896.     */
  897.  
  898.     return(SUCCESS);
  899. }
  900.  
  901. /****************************************************************************
  902.  *
  903.  * FUNCTION NAME = CardRemoval
  904.  *
  905.  * DESCRIPTION   = CARD_REMOVAL event routine.
  906.  *
  907.  * INPUT         = function
  908.  *                 socket
  909.  *                 card status, socket status information
  910.  *                 ClientVal field from ClientData structure
  911.  *                 ClientDS field from ClientData structure
  912.  *                 ClientOff field from ClientData structure
  913.  *                 pointer to buffer
  914.  *
  915.  * OUTPUT        = N/A
  916.  *
  917.  * RETURN_NORMAL =
  918.  * RETURN-ERROR  =
  919.  *
  920.  ****************************************************************************/
  921.  
  922. void far CardRemoval(USHORT function, USHORT socket, USHORT info,
  923.                      USHORT clientVal, USHORT clientDS, USHORT clientOff,
  924.                      PUCHAR Buffer)
  925. {
  926.     return;
  927. }
  928.  
  929.  
  930. /****************************************************************************
  931.  *
  932.  * FUNCTION NAME = WaitArgPkt
  933.  *
  934.  * DESCRIPTION   = Waiting until ArgPacket buffer is availble
  935.  *
  936.  * INPUT         = None
  937.  *
  938.  * OUTPUT        =
  939.  *
  940.  * RETURN_NORMAL = TRUE
  941.  * RETURN-ERROR  = FALSE
  942.  *
  943.  ****************************************************************************/
  944.  
  945. BOOL near WaitArgPkt()     /* pks near */
  946. {
  947.     USHORT   rc;
  948.  
  949.     while (CL_status & ARGPKT_BUSY) /* until buffer is available block thread */
  950.     {
  951.        rc = DevHelp_ProcBlock ((ULONG)(&ArgPacket), -1L, 0);
  952.        DISABLE;
  953.     }
  954.  
  955.     if (rc)
  956.       return(FALSE);
  957.  
  958.     CL_status |= ARGPKT_BUSY;       /* set busy flag                          */
  959.     cntWaiting++;                   /* increment waiting count                */
  960.  
  961.     return(TRUE);
  962. }
  963.  
  964.  
  965. /****************************************************************************
  966.  *
  967.  * FUNCTION NAME = ReleaseArgPkt
  968.  *
  969.  * DESCRIPTION   = Relese ArgPacket buffer
  970.  *
  971.  * INPUT         = None
  972.  *
  973.  * OUTPUT        =
  974.  *
  975.  * RETURN_NORMAL = TRUE
  976.  * RETURN-ERROR  = FALSE
  977.  *
  978.  ****************************************************************************/
  979.  
  980. BOOL near ReleaseArgPkt()
  981. {
  982.     USHORT   Awakecount;
  983.     USHORT   rc;
  984.                                     /* let the other thread run               */
  985.     rc = DevHelp_ProcRun ((ULONG)(&ArgPacket), (PUSHORT)(&Awakecount));
  986.  
  987.     if (rc)
  988.       return(FALSE);
  989.  
  990.     CL_status &= (~ARGPKT_BUSY);    /* reset busy flag                        */
  991.     cntWaiting--;                   /* decrement waiting count                */
  992.  
  993.     return(TRUE);
  994. }
  995.  
  996.