home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / aspio02.zip / aspill.c < prev    next >
C/C++ Source or Header  |  1999-08-17  |  7KB  |  328 lines

  1. /*
  2.  * $Source: r:/source/aspi/RCS/aspill.c,v $
  3.  * $Revision: 1.4 $
  4.  * $Date: 1999/08/18 00:16:26 $
  5.  * $Locker:  $
  6.  *
  7.  *    ASPI Interface Library,
  8.  *    low-level routines to access ASPI Router driver.
  9.  *
  10.  *    Open, Close
  11.  *
  12.  * $Log: aspill.c,v $
  13.  * Revision 1.4  1999/08/18 00:16:26  vitus
  14.  * - updated location of defines.h (moved)
  15.  * - changed function comments to new layout
  16.  *
  17.  * Revision 1.3  1997/09/22 02:28:26  vitus
  18.  * commented
  19.  *
  20.  * Revision 1.2  1997/09/18 01:44:01  vitus
  21.  * copies I/O buffer to/from locked ASPIRouter buffer
  22.  * added public sense data structure
  23.  *
  24.  * Revision 1.1  1997/09/08 02:01:33  vitus
  25.  * Initial revision
  26.  * ----------------------------------------
  27.  * Sample code to demonstrate use of ASPI Interface.
  28.  */
  29. static char const id[]="$Id: aspill.c,v 1.4 1999/08/18 00:16:26 vitus Exp $";
  30.  
  31. #include <stdio.h>
  32. #include <string.h>
  33. #include <stdlib.h>
  34.  
  35. #define INCL_DOS
  36. #define INCL_DOSFILEMGR
  37. #define INCL_DOSDEVICES
  38. #define INCL_DOSDEVIOCTL
  39. #define INCL_DOSSEMAPHORES
  40. #define INCL_ERRORS
  41. #include <os2.h>
  42.  
  43. #include "../lib/defines.h"
  44. #include "scsi.h"
  45. #include "srb.h"
  46. #include "aspio.h"
  47.  
  48. #define BUFFER_SIZE    (62*1024u)
  49.  
  50.  
  51. #if !defined(min)                /* EMX doesn't supply it */
  52. # define min(a,b)    ((a)<(b)?(a):(b))
  53. #endif
  54.  
  55.  
  56. /* Definition to access aspirout.sys */
  57.  
  58. #define IOCTL_ASPIR_CATEGORY    0x92        /* a user-defined category */
  59. #define ASPIR_START_SRB        0x02
  60. #define ASPIR_REGISTER_SEMA    0x03
  61. #define ASPIR_REGISTER_BUFFER    0x04
  62.  
  63.  
  64.  
  65. PUBLIC SCSI_REQSENSE_DATA    strLastSense;
  66.  
  67.  
  68. PRIVATE HFILE    hdAspi = 0;
  69. PRIVATE HEV    semAspi = 0;
  70. PRIVATE PVOID    pAspiBuffer = NULL;
  71.  
  72.  
  73.  
  74.  
  75.  
  76.  
  77. /*# ----------------------------------------------------------------------
  78.  * AspiOpen(reserved)
  79.  *
  80.  * PARAMETER
  81.  *    reserved    0
  82.  *
  83.  * RETURNS
  84.  *    APIRET
  85.  *
  86.  * GLOBAL
  87.  *    hdAspi, semAspi, pAspiBuffer
  88.  *
  89.  * DESPRIPTION
  90.  *    Opens selected ASPI interface (currently only 0: aspirout.sys).
  91.  *
  92.  * REMARKS
  93.  */
  94. PUBLIC APIRET _System
  95. AspiOpen(ULONG reserved)
  96. {
  97.     APIRET    rc;
  98.     ULONG    action;
  99.     ULONG    cbPara;
  100.     ULONG    cbData;
  101.     USHORT    rcDriver;
  102.  
  103.     if( reserved != 0 )
  104.     return ERROR_INVALID_PARAMETER;        /* only 0 supported */
  105.  
  106.     do
  107.     {
  108.     /* Open driver */
  109.  
  110.     rc = DosOpen("ASPIROU$",
  111.              &hdAspi,
  112.              &action,
  113.              0,
  114.              0,
  115.              OPEN_ACTION_FAIL_IF_NEW|OPEN_ACTION_OPEN_IF_EXISTS,
  116.              OPEN_FLAGS_FAIL_ON_ERROR|OPEN_FLAGS_NOINHERIT
  117.              |OPEN_SHARE_DENYREADWRITE|OPEN_ACCESS_READWRITE,
  118.              NULL);
  119.     if( rc != 0 )
  120.         break;
  121.  
  122.     /* Create event semaphore */
  123.  
  124.     rc = DosCreateEventSem(NULL,
  125.                    &semAspi,
  126.                    DC_SEM_SHARED,
  127.                    FALSE);
  128.  
  129.     if( rc )
  130.         break;
  131.  
  132.  
  133.     /* Pass semaphore handle to driver */
  134.  
  135.     cbPara = sizeof(semAspi);
  136.     cbData = sizeof(rcDriver);
  137.     rc = DosDevIOCtl(hdAspi,
  138.              IOCTL_ASPIR_CATEGORY,
  139.              ASPIR_REGISTER_SEMA,
  140.              &semAspi,
  141.              cbPara,
  142.              &cbPara,
  143.              &rcDriver,
  144.              cbData,
  145.              &cbData);
  146.     if( rc != 0  ||  rcDriver != 0 )
  147.     {
  148.         if( rc == 0 )
  149.         rc = rcDriver;
  150.         break;
  151.     }
  152.  
  153.  
  154.     /* Allocate buffer and pass to ASPI Router */
  155.  
  156.     rc = DosAllocMem(&pAspiBuffer,
  157.              BUFFER_SIZE,
  158.              OBJ_TILE | PAG_READ
  159.              | PAG_WRITE | PAG_COMMIT);
  160.     if( rc != 0 )
  161.         break;
  162.  
  163.     cbPara = sizeof(pAspiBuffer);
  164.     cbData = sizeof(rcDriver);
  165.     rc = DosDevIOCtl(hdAspi,
  166.              IOCTL_ASPIR_CATEGORY,
  167.              ASPIR_REGISTER_BUFFER,
  168.              pAspiBuffer,
  169.              cbPara,
  170.              &cbPara,
  171.              &rcDriver,
  172.              cbData,
  173.              &cbData);
  174.     if( rc != 0  ||  rcDriver != 0 )
  175.     {
  176.         if( rc == 0 )
  177.         rc = rcDriver;
  178.         break;
  179.     }
  180.     }
  181.     while( 0 );
  182.  
  183.     if( rc != 0 )
  184.     {
  185.     /* Error, cleanup */
  186.  
  187.     if( semAspi != 0 )
  188.         DosCloseEventSem(semAspi);
  189.     if( hdAspi != 0 )
  190.         DosClose(hdAspi);
  191.     if( pAspiBuffer != NULL )
  192.     {
  193.         DosFreeMem(pAspiBuffer);
  194.         pAspiBuffer = NULL;
  195.     }
  196.     }
  197.     return rc;
  198. }
  199.  
  200.  
  201.  
  202.  
  203. /*# ----------------------------------------------------------------------
  204.  * AspiClose(void)
  205.  *
  206.  * PARAMETER
  207.  *    (none)
  208.  *
  209.  * RETURNS
  210.  *    APIRET
  211.  *
  212.  * GLOBAL
  213.  *    hdAspi, semAspi, pAspiBuffer
  214.  *
  215.  * DESPRIPTION
  216.  *    Closes current ASPI interface.  Don't forget to call as it
  217.  *    may be important to do the cleanup.
  218.  *
  219.  * REMARKS
  220.  *    With aspirout.sys it _is_ important to call AspiClose(): otherwise
  221.  *    the used semaphore might never be freed.
  222.  */
  223. PUBLIC APIRET _System
  224. AspiClose(void)
  225. {
  226.     APIRET    rc;
  227.     APIRET    rcClose;
  228.  
  229.     /* Close semaphore */
  230.  
  231.     rc = DosCloseEventSem(semAspi);
  232.  
  233.     /* Close driver */
  234.  
  235.     rcClose = DosClose(hdAspi);
  236.  
  237.     /* Free memory */
  238.  
  239.     DosFreeMem(pAspiBuffer);
  240.     pAspiBuffer = NULL;
  241.  
  242.     return (rc == 0 ? rcClose : rc);
  243. }
  244.  
  245.  
  246.  
  247.  
  248. /*# ----------------------------------------------------------------------
  249.  * AspiSendSRB(srb,srbsize)
  250.  *
  251.  * PARAMETER
  252.  *    srb        see ASPI spec
  253.  *    srbsize        size of SRB
  254.  *
  255.  * RETURNS
  256.  *    APIRET
  257.  *
  258.  * GLOBAL
  259.  *    hdAspi, semAspi, pAspiBuffer
  260.  *
  261.  * DESPRIPTION
  262.  *    Passes SRB to ASPI interface and waits until SRB is completed.
  263.  *    Does any buffer management that may be needed.
  264.  *
  265.  * REMARKS
  266.  */
  267. PUBLIC APIRET _System
  268. AspiSendSRB(PASPI_SRB_HEADER srb,ULONG srbsize)
  269. {
  270.     APIRET    rc;
  271.     ULONG    cnt;
  272.     ULONG    cbPara = srbsize;
  273.     ULONG    cbData = srbsize;
  274.     PVOID    data = NULL;
  275.     ULONG    datalen = 0;
  276.  
  277.     srb->ASPIStatus = 0;
  278.  
  279.     /* Copy output data to global buffer known by ASPI interface. */
  280.  
  281.     if( srb->CommandCode == ASPI_CMD_EXECUTE_IO )
  282.     {
  283.     data = ((PASPI_SRB_EXECUTE_IO)srb)->pDataBuffer;
  284.     datalen = min(BUFFER_SIZE, ((PASPI_SRB_EXECUTE_IO)srb)->DataXferLen);
  285.  
  286.     if( (srb->ASPIReqFlags
  287.          & ASPI_REQFLAG_DIRECTION_BITS) == ASPI_REQFLAG_DIR_TO_TARGET )
  288.         memcpy(pAspiBuffer, data, datalen);
  289.     }
  290.  
  291.     /* Pass SRB to device driver. */
  292.  
  293.     rc = DosDevIOCtl(hdAspi,
  294.              IOCTL_ASPIR_CATEGORY,
  295.              ASPIR_START_SRB,
  296.              srb,
  297.              cbPara,
  298.              &cbPara,
  299.              srb,
  300.              cbData,
  301.              &cbData);
  302.     if( rc != 0 )
  303.     return rc;
  304.  
  305.     /* Wait for 'semAspi' to be posted by device driver. */
  306.  
  307.     if( (srb->ASPIReqFlags & ASPI_REQFLAG_POST_ENABLE) )
  308.     {
  309.     do
  310.     {
  311.         rc = DosWaitEventSem(semAspi, 1000ul);
  312.     }
  313.     while( srb->ASPIStatus == 0 );
  314.     if( rc == 0 )
  315.         rc = DosResetEventSem(semAspi, &cnt);
  316.     }
  317.  
  318.     /* Copy input data to global buffer known by ASPI interface. */
  319.  
  320.     if( srb->CommandCode == ASPI_CMD_EXECUTE_IO
  321.     && datalen != 0
  322.     &&  (srb->ASPIReqFlags
  323.          & ASPI_REQFLAG_DIRECTION_BITS) == ASPI_REQFLAG_DIR_TO_HOST )
  324.     memcpy(data, pAspiBuffer, datalen);
  325.  
  326.     return rc;
  327. }
  328.