home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / ddkx86v5.zip / DDKX86 / SRC / DEV / DASD / OS2SCSI / SCGIOCTL.C < prev    next >
Encoding:
C/C++ Source or Header  |  1995-04-14  |  35.6 KB  |  836 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. /*static char *SCCSID = "src/dev/dasd/os2scsi/scgioctl.c, scsy, ddk_subset, b_bdd.032 93/10/25";*/
  13. /**************************************************************************
  14.  *
  15.  * SOURCE FILE NAME = SCGIOCTL.C
  16.  *
  17.  * DESCRIPTIVE NAME = OS2SCSI.DMD - OS/2 SCSI.SYS Emulation
  18.  *
  19.  *
  20.  *
  21.  * VERSION = V2.0
  22.  *
  23.  * DATE
  24.  *
  25.  * DESCRIPTION : OS2SCSI (SCSI.SYS) IOCTL processing
  26.  *
  27.  *
  28.  *
  29. */
  30. #define INCL_NOBASEAPI
  31. #define INCL_NOPMAPI
  32. #include "os2.h"
  33. #include "error.h"
  34. #include "strat2.h"
  35. #include "reqpkt.h"
  36. #include "dhcalls.h"
  37. #include "scb.h"
  38. #include "iorb.h"
  39. #include "scsi.h"
  40. #include "scscsi.h"
  41. #include "scgen.h"
  42. #include "scproto.h"
  43. #include "abios.h"
  44.  
  45.  
  46. extern UNITCB     UnitCB[1];               /* First UnitCB allocated here    */
  47. extern USHORT     NumUnitCBs;              /* number of unit control blocks  */
  48. extern UCHAR      ScratchBuffer1[512];     /* Scratch buffer for I/O         */
  49. extern USHORT     vTimeout_buff;           /* timeout value buffer           */
  50. extern UCHAR      ControllerClass[];       /* Controller Class ID for IORB   */
  51.  
  52.  
  53. /********************** START OF SPECIFICATIONS *****************************
  54. *                                                                           *
  55. * SUBROUTINE NAME:  f_DriveGenIOCtl                                         *
  56. *                                                                           *
  57. * DESCRIPTIVE NAME: Far General I/O Control                                 *
  58. *                                                                           *
  59. * FUNCTION:         This routine handles Generic I/O Control request.       *
  60. *                   It checks the function in the parameter packet, and     *
  61. *                   call to the appropriate subroutine to process it.       *
  62. *                                                                           *
  63. * ENTRY POINT:      f_DriveGenIOCtl                                         *
  64. *                                                                           *
  65. * LINKAGE:          Call Far                                                *
  66. *                                                                           *
  67. * INPUT:            pGenioctl Pointer to General I/O Control Request Packet *
  68. *                                                                           *
  69. * EXIT-NORMAL:                                                              *
  70. *                                                                           *
  71. * EXIT-ERROR:                                                               *
  72. *                                                                           *
  73. *********************** END OF SPECIFICATIONS *******************************/
  74.  
  75. USHORT far f_DriveGenIOCtl(EntryType, pRPH)
  76. USHORT EntryType;
  77. PRPH   pRPH;
  78. {
  79.   PRP_GENIOCTL   pGenioctl = (PRP_GENIOCTL)pRPH;
  80.   PSCSI_IN       pParm = (PSCSI_IN) (pGenioctl->ParmPacket);
  81.   PSCSI_OUT      pData = (PSCSI_OUT)(pGenioctl->DataPacket);
  82.   USHORT         iUnit;
  83.   USHORT         rc = STDON | STERR | ERROR_I24_BAD_COMMAND;
  84.   NPUCB          npUCB;
  85.  
  86.   if (pGenioctl->Category == ABIOS_SERVICE)
  87.   {
  88.      if ((pGenioctl->Function != (ABFC_SCSIP_ALLOC_SCSI_DEV | SCSI_PLUS_VALUE)) &&
  89.          (pGenioctl->Function != (ABFC_SCSIP_RET_TYPE_COUNT | SCSI_PLUS_VALUE)))
  90.      {
  91.         iUnit = pParm->hDev;
  92.                                            /* Device Handle Check */
  93.         if ( iUnit > (NumUnitCBs - 1))
  94.         {
  95.            rc = STDON + STERR + ERROR_I24_INVALID_PARAMETER;
  96.            return ( rc );
  97.         }
  98.         npUCB = &UnitCB[iUnit];
  99.                                            /* Already allocated or not */
  100.         if (!(npUCB->IntUnitFlags & IUF_ALLOCATED))
  101.         {
  102.            rc = STDON + STERR + ERROR_I24_BAD_UNIT;
  103.            return ( rc );
  104.         }
  105.      }
  106.                                            /* Distribute function */
  107.      switch (pGenioctl->Function)
  108.      {
  109.         case (ABFC_READ_DEVICE_PARMS | SCSI_PLUS_VALUE):
  110.            /*****************************************/
  111.            /* Read Device Parameters                */
  112.            /*****************************************/
  113.  
  114.            WaitOtherIORB( npUCB );
  115.            rc = ReadDevParms(pGenioctl);
  116.            ReleaseOtherIORB( npUCB );
  117.  
  118.            break;
  119.  
  120.  
  121.         case (ABFC_RESET_DEVICE | SCSI_PLUS_VALUE):
  122.            /*****************************************/
  123.            /* Reset / Initialize                    */
  124.            /*****************************************/
  125.                                            /* Queueing Command */
  126.            if((rc = WaitIORB(pGenioctl,EntryType)) == TRUE)
  127.            {
  128.               rc = Reset_Init(pGenioctl);
  129.               ReleaseIORB(pGenioctl);
  130.               return(rc);
  131.            }
  132.            else
  133.               if (rc == REQ_FLUSHED)
  134.                  return(STDON + STERR + ERROR_I24_UNCERTAIN_MEDIA);
  135.               else if (rc == REQ_INTERRUPTED)
  136.                  return(STDON + STERR + SCSI_ERR_UNUSUAL_WAKEUP);
  137.               else
  138.                  return(STDON + STERR + SCSI_ERR_DEVHELP);
  139.  
  140.  
  141.         case (ABFC_SCSIA_ENABLE_CACHE | SCSI_PLUS_VALUE):
  142.            /*****************************************/
  143.            /* Enable Intelligent Buffer             */
  144.            /*****************************************/
  145.  
  146.            return(STDON + STERR + SCSI_ERR_INT_BUFF_NOT_SUPPORT);
  147.  
  148.  
  149.         case (ABFC_SCSIA_DISABLE_CACHE | SCSI_PLUS_VALUE):
  150.            /*****************************************/
  151.            /* Disable Intelligent Buffer            */
  152.            /*****************************************/
  153.  
  154.            return(STDON + STERR + SCSI_ERR_INT_BUFF_NOT_SUPPORT);
  155.  
  156.  
  157.         case (ABFC_SCSIA_CACHE_STATUS | SCSI_PLUS_VALUE):
  158.            /*****************************************/
  159.            /* Return Intelligent Buffer Status      */
  160.            /*****************************************/
  161.  
  162.            return(STDON + STERR + SCSI_ERR_INT_BUFF_NOT_SUPPORT);
  163.  
  164.  
  165.         case (ABFC_SCSIP_SET_DEV_TIMEOUT | SCSI_PLUS_VALUE):
  166.            /*****************************************/
  167.            /* Set Device Timeout                    */
  168.            /*****************************************/
  169.  
  170.                                            /* Immediate Command */
  171.            return(SetTimeout(pGenioctl));
  172.  
  173.  
  174.         case (ABFC_SCSIP_READ_DEV_TIMEOUT | SCSI_PLUS_VALUE):
  175.            /*****************************************/
  176.            /* Read Device Timeout                   */
  177.            /*****************************************/
  178.  
  179.                                            /* Immediate Command */
  180.            return(ReadTimeout(pGenioctl));
  181.  
  182.  
  183.         case (ABFC_SCSIP_TRANSFER_SCB | SCSI_PLUS_VALUE):
  184.            /*****************************************/
  185.            /* Transfer SCB                          */
  186.            /*****************************************/
  187.  
  188.            if ((rc = WaitIORB(pGenioctl, EntryType)) == TRUE )
  189.            {
  190.               rc = XferSCB(pGenioctl);
  191.               ReleaseIORB(pGenioctl);
  192.            }
  193.            else
  194.               if (rc == REQ_FLUSHED)
  195.                  rc = STDON + STERR + ERROR_I24_UNCERTAIN_MEDIA;
  196.               else if (rc == REQ_INTERRUPTED)
  197.                  rc = STDON + STERR + SCSI_ERR_UNUSUAL_WAKEUP;
  198.               else
  199.                  rc = STDON + STERR + SCSI_ERR_DEVHELP;
  200.  
  201.            break;
  202.  
  203.  
  204.         case (ABFC_SCSIP_DEALLOC_SCSI_DEV | SCSI_PLUS_VALUE):
  205.            /*****************************************/
  206.            /* Deallocate Device                     */
  207.            /*****************************************/
  208.  
  209.            WaitOtherIORB( npUCB );
  210.            rc = DeallocDev(pGenioctl);
  211.            ReleaseOtherIORB( npUCB );
  212.  
  213.            break;
  214.  
  215.  
  216.         case (ABFC_SCSIP_ALLOC_SCSI_DEV | SCSI_PLUS_VALUE):
  217.            /*****************************************/
  218.            /* Allocate Device                       */
  219.            /*****************************************/
  220.  
  221.            /*---------------------------------------------------*/
  222.            /* Note: This routine requires the 'OtherIORB'       */
  223.            /*       however we do not know which UCB will be    */
  224.            /*       addressed. WaitOtherIORB() is called within */
  225.            /*       this routine when a UCB has been selected.  */
  226.            /*---------------------------------------------------*/
  227.  
  228.            rc = AllocDev(pGenioctl);
  229.  
  230.            break;
  231.  
  232.         case (ABFC_SCSIP_RET_TYPE_COUNT | SCSI_PLUS_VALUE):
  233.            /*****************************************/
  234.            /* Return Peripheral Type Count          */
  235.            /*****************************************/
  236.                                            /* Immediate Command */
  237.            rc = RetTypeCnt(pGenioctl);
  238.  
  239.            break;
  240.  
  241.  
  242.         case (ABFC_SCSIP_ABORT | SCSI_PLUS_VALUE):
  243.            /*****************************************/
  244.            /* Send Abort                            */
  245.            /*****************************************/
  246.  
  247.            WaitOtherIORB( npUCB );
  248.            rc =  SendAbort(pGenioctl, EntryType);
  249.            ReleaseOtherIORB( npUCB );
  250.  
  251.            break;
  252.  
  253.         default:
  254.            /*****************************************/
  255.            /* Invalid Function                      */
  256.            /*****************************************/
  257.            ;
  258.      }
  259.   }
  260.   return( rc );
  261.  
  262. }
  263.  
  264. /********************** START OF SPECIFICATIONS *****************************
  265. *                                                                           *
  266. * SUBROUTINE NAME:  AllocDev                                                *
  267. *                                                                           *
  268. * DESCRIPTIVE NAME: Allocate Device                                         *
  269. *                                                                           *
  270. * FUNCTION:         This routine looks for the unit which fits to the       *
  271. *                   request from Device-Class driver and issue Allocate     *
  272. *                   command to it and returns the uniqur device handle to   *
  273. *                   Device-Class Driver.                                    *
  274. *                                                                           *
  275. * ENTRY POINT:      AllocDev                                                *
  276. *                                                                           *
  277. * LINKAGE:          Call Near                                               *
  278. *                                                                           *
  279. * INPUT:            pParm         Pointer to parameter packet               *
  280. *                   pData         Pointer to data packet                    *
  281. *                                                                           *
  282. * EXIT-NORMAL:      Status                                                  *
  283. *                                                                           *
  284. * EXIT-ERROR:       Status                                                  *
  285. *                                                                           *
  286. *********************** END OF SPECIFICATIONS *******************************/
  287.  
  288. USHORT near AllocDev(pGenioctl)
  289.  
  290. PRP_GENIOCTL pGenioctl;
  291. {
  292.   PSCSI_IN_ALLOCDEV    pParm = (PSCSI_IN_ALLOCDEV) (pGenioctl->ParmPacket);
  293.   PSCSI_OUT_ALLOCDEV   pData = (PSCSI_OUT_ALLOCDEV)(pGenioctl->DataPacket);
  294.  
  295.   NPIORB               npIORB;
  296.  
  297.   NPUCB                npUCB         = UnitCB;
  298.  
  299.   USHORT               iUnit         = 0;
  300.   USHORT               nth_available = 0;
  301.   USHORT               nAvailable    = pParm->nAvailable;
  302.   USHORT               UnitRemovable;
  303.   USHORT               AllocRemovable;
  304.   USHORT               Status;                                       /*@V74951*/
  305.   USHORT               i;
  306.  
  307.  
  308.   AllocRemovable = (pParm->fDevType & SCSI_REMOVABLE) ? 1 : 0;
  309.  
  310.   for ( ; iUnit < NumUnitCBs; iUnit++, npUCB++)
  311.   {
  312.      UnitRemovable  = (npUCB->UnitInfo.UnitFlags & UF_REMOVABLE) ? 1 : 0;
  313.  
  314.      if ((pParm->DevType == npUCB->UnitInfo.UnitType) &&
  315.                                       (AllocRemovable == UnitRemovable) )
  316.      {
  317.         nth_available++;
  318.  
  319.         if (!(npUCB->IntUnitFlags & IUF_ALLOCATED))
  320.         {
  321.            if ((nAvailable == nth_available) || !nAvailable)         /*@V74951*/
  322.            {
  323.               WaitOtherIORB( npUCB );
  324.  
  325.               npIORB = &npUCB->Other_IORB;
  326.               CLEAR_IORB_BUFF;
  327.  
  328.               npIORB->Length                = sizeof(IORB_UNIT_CONTROL);
  329.               npIORB->UnitHandle            = npUCB->UnitInfo.UnitHandle;
  330.               npIORB->CommandCode           = IOCC_UNIT_CONTROL;
  331.               npIORB->CommandModifier       = IOCM_ALLOCATE_UNIT;
  332.               npIORB->RequestControl        = IORB_ASYNC_POST;
  333.               npIORB->NotifyAddress         = NotifyIORBDone;
  334.  
  335.               (*(npUCB->AdapterDriverEP))((PIORB) npIORB);
  336.  
  337.               DISABLE;
  338.               while ( !(npIORB->Status & IORB_DONE) )
  339.               {
  340.                  DevHelp_ProcBlock ((ULONG)((PIORB) npIORB), -1L, 0);
  341.                  DISABLE;
  342.               }
  343.               ENABLE;
  344.  
  345.               Status = npIORB->Status;                               /*@V74951*/
  346.  
  347.               ReleaseOtherIORB( npUCB );
  348.  
  349.               if (!(Status & IORB_ERROR))                            /*@V74951*/
  350.               {
  351.                  pData->hDev          = iUnit;
  352.                  npUCB->IntUnitFlags |= IUF_ALLOCATED;
  353.                  return( STDON );
  354.               }
  355.               else if ( nAvailable )                                 /*@V74951*/
  356.               {                                                      /*@V74951*/
  357.                 break;                                               /*@V74951*/
  358.               }                                                      /*@V74951*/
  359.            }
  360.  
  361.         }
  362.      }
  363.   }
  364.  
  365.   return(STDON + STERR + SCSI_ERR_DEV_NOT_AVAILABLE);
  366.  
  367. }
  368.  
  369. /********************** START OF SPECIFICATIONS *****************************
  370. *                                                                           *
  371. * SUBROUTINE NAME:  ReadDevParms                                            *
  372. *                                                                           *
  373. * DESCRIPTIVE NAME: Read Device Parameters                                  *
  374. *                                                                           *
  375. * FUNCTION:         This routine returns device information for particular  *
  376. *                   unit specified by device handle.  It issues  Unit Status*
  377. *                   IORB to ADD to get some information like power-on/off.  *
  378. *                                                                           *
  379. * ENTRY POINT:      ReadDevParms                                            *
  380. *                                                                           *
  381. * LINKAGE:          Call Near                                               *
  382. *                                                                           *
  383. * INPUT:            pParm         Pointer to parameter packet               *
  384. *                   pData         Pointer to data packet                    *
  385. *                                                                           *
  386. * EXIT-NORMAL:      Status                                                  *
  387. *                                                                           *
  388. * EXIT-ERROR:       Status                                                  *
  389. *                                                                           *
  390. *********************** END OF SPECIFICATIONS *******************************/
  391.  
  392.  
  393. USHORT near ReadDevParms(pGenioctl)
  394.  
  395. PRP_GENIOCTL pGenioctl;
  396. {
  397.   PSCSI_OUT_READPARM   pData = (PSCSI_OUT_READPARM) pGenioctl->DataPacket;
  398.   NPIORB               npIORB;
  399.   NPIORB_UNIT_STATUS   npIORBUS;
  400.   NPUCB                npUCB;
  401.  
  402.   USHORT               sUnit;
  403.   USHORT               sFlag = 0;
  404.   USHORT               i;
  405.  
  406.   npUCB    = &UnitCB[((PSCSI_IN)(pGenioctl->ParmPacket))->hDev];
  407.  
  408.   npIORB   =                      &npUCB->Other_IORB;
  409.   npIORBUS = (NPIORB_UNIT_STATUS) npIORB;
  410.   CLEAR_IORB_BUFF;
  411.  
  412.   npIORB->Length          = sizeof(IORB_UNIT_STATUS);
  413.   npIORB->UnitHandle      = npUCB->UnitInfo.UnitHandle;
  414.   npIORB->CommandCode     = IOCC_UNIT_STATUS;
  415.   npIORB->CommandModifier = IOCM_GET_UNIT_STATUS;
  416.   npIORB->Timeout         = npUCB->Timeout;
  417.   npIORB->RequestControl  = IORB_ASYNC_POST;
  418.   npIORB->NotifyAddress   = NotifyIORBDone;
  419.  
  420.   npIORBUS->UnitStatus    = 0;
  421.  
  422.   (*(npUCB->AdapterDriverEP))((PIORB)npIORB);
  423.  
  424.   DISABLE;
  425.   while ( !(npIORB->Status & IORB_DONE) )
  426.   {
  427.      DevHelp_ProcBlock ((ULONG)((PIORB) npIORB), -1L, 0);
  428.      DISABLE;
  429.   }
  430.   ENABLE;
  431.  
  432.   sUnit = npUCB->UnitStatus = npIORBUS->UnitStatus;
  433.  
  434.   if (!(sUnit & US_POWER))
  435.      sFlag |= DEVICE_POWER_OFF;
  436.  
  437.   if (sUnit & US_DEFECTIVE)
  438.      sFlag |= DEVICE_DEFECTIVE;
  439.  
  440.   pData->indexDeviceKey  = 0;
  441.   pData->levelSCBArcCard = 0;
  442.   pData->indexAdapter    = npUCB->UnitInfo.AdapterIndex;
  443.   pData->fDevice         = sFlag;
  444.   pData->LUN             = npUCB->UnitInfo.UnitSCSILUN;
  445.   pData->PUN             = npUCB->UnitInfo.UnitSCSITargetID;
  446.  
  447.   return(STDON);
  448. }
  449.  
  450.  
  451. /********************** START OF SPECIFICATIONS *****************************
  452. *                                                                           *
  453. * SUBROUTINE NAME:  Reset_Init                                              *
  454. *                                                                           *
  455. * DESCRIPTIVE NAME: Reset / Initialize                                      *
  456. *                                                                           *
  457. * FUNCTION:         This routine issues Reset IORB to ADD.                  *
  458. *                                                                           *
  459. * ENTRY POINT:      Reset_Init                                              *
  460. *                                                                           *
  461. * LINKAGE:          Call Near                                               *
  462. *                                                                           *
  463. * INPUT:            pParm         Pointer to parameter packet               *
  464. *                   pData         Pointer to data packet                    *
  465. *                                                                           *
  466. * EXIT-NORMAL:      Status                                                  *
  467. *                                                                           *
  468. * EXIT-ERROR:       Status                                                  *
  469. *                                                                           *
  470. *********************** END OF SPECIFICATIONS *******************************/
  471.  
  472. USHORT near Reset_Init(pGenioctl)
  473.  
  474. PRP_GENIOCTL        pGenioctl;
  475. {
  476.   PSCSI_IN_RESET_INIT    pParm = (PSCSI_IN_RESET_INIT) (pGenioctl->ParmPacket);
  477.   PSCSI_OUT              pData = (PSCSI_OUT)           (pGenioctl->DataPacket);
  478.  
  479.   NPUCB                  npUCB;
  480.   NPIORB                 npIORB;
  481.   NPSCSI_STATUS_BLOCK    npSSB;
  482.  
  483.   USHORT                  i;
  484.  
  485.   npUCB    = &UnitCB[((PSCSI_IN)(pGenioctl->ParmPacket))->hDev];
  486.  
  487.   npIORB = &npUCB->Other_IORB;
  488.   CLEAR_IORB_BUFF;
  489.  
  490.   npSSB = &npUCB->Other_SSB;
  491.   CLEAR_SSB_BUFF;
  492.  
  493.   npIORB->Length                = sizeof(IORB_DEVICE_CONTROL);
  494.   npIORB->UnitHandle            = npUCB->UnitInfo.UnitHandle;
  495.   npIORB->CommandCode           = IOCC_DEVICE_CONTROL;
  496.   npIORB->CommandModifier       = IOCM_RESET;
  497.   npIORB->RequestControl       |= (IORB_ASYNC_POST | IORB_REQ_STATUSBLOCK);
  498.   npIORB->Timeout               = npUCB->Timeout;
  499.   npIORB->StatusBlockLen        = sizeof(SCSI_STATUS_BLOCK);
  500.   npIORB->pStatusBlock          = (NPBYTE)npSSB;
  501.   npIORB->NotifyAddress         = NotifyIORBDone;                    /*@V61008*/
  502.   *(NPUCB *)(npIORB->DMWorkSpace)  = npUCB;
  503.  
  504.                                             /* set sense data length & addr. */
  505.   npSSB->ReqSenseLen = pParm->lnSenseData;
  506.   npSSB->SenseData   = npUCB->pSenseData;
  507.  
  508.   (*(npUCB->AdapterDriverEP))((PIORB) npIORB);
  509.  
  510.   DISABLE;
  511.   while ( !(npIORB->Status & IORB_DONE) )
  512.   {
  513.      DevHelp_ProcBlock ((ULONG)(PIORB) npIORB, -1L, 0);
  514.      DISABLE;
  515.   }
  516.   ENABLE;
  517.  
  518.   return( CheckIORBError( npUCB, npIORB) );
  519.  
  520. }
  521.  
  522.  
  523. /********************** START OF SPECIFICATIONS *****************************
  524. *                                                                           *
  525. * SUBROUTINE NAME:  SetTimeout                                              *
  526. *                                                                           *
  527. * DESCRIPTIVE NAME: Set Timeout value                                       *
  528. *                                                                           *
  529. * FUNCTION:         This routine set the value of timeout into Unit CB.     *
  530. *                                                                           *
  531. * ENTRY POINT:      SetTimeout                                              *
  532. *                                                                           *
  533. * LINKAGE:          Call Near                                               *
  534. *                                                                           *
  535. * INPUT:            pParm         Pointer to parameter packet               *
  536. *                   pData         Pointer to data packet                    *
  537. *                                                                           *
  538. * EXIT-NORMAL:      Status                                                  *
  539. *                                                                           *
  540. * EXIT-ERROR:       Status                                                  *
  541. *                                                                           *
  542. *********************** END OF SPECIFICATIONS *******************************/
  543.  
  544.  
  545. USHORT near SetTimeout(pGenioctl)
  546.  
  547. PRP_GENIOCTL           pGenioctl;
  548. {
  549.   PSCSI_IN_SETTIMEOUT pParm = (PSCSI_IN_SETTIMEOUT) (pGenioctl->ParmPacket);
  550.   USHORT              iUnit;
  551.  
  552.   iUnit = pParm->hDev;
  553.  
  554.   UnitCB[iUnit].Timeout = MS_to_S(pParm->vTimeout);
  555.  
  556.   return(STDON);
  557.  
  558. }
  559.  
  560. /********************** START OF SPECIFICATIONS *****************************
  561. *                                                                           *
  562. * SUBROUTINE NAME:  ReadTimeout                                             *
  563. *                                                                           *
  564. * DESCRIPTIVE NAME: Read Timeout Value                                      *
  565. *                                                                           *
  566. * FUNCTION:         This routine read the value of timeout from Unit CB.    *
  567. *                   If the value is not set, return the default value.      *
  568. *                                                                           *
  569. * ENTRY POINT:      ReadTimeout                                             *
  570. *                                                                           *
  571. * LINKAGE:          Call Near                                               *
  572. *                                                                           *
  573. * INPUT:            pParm         Pointer to parameter packet               *
  574. *                   pData         Pointer to data packet                    *
  575. *                                                                           *
  576. * EXIT-NORMAL:      Status                                                  *
  577. *                                                                           *
  578. * EXIT-ERROR:       Status                                                  *
  579. *                                                                           *
  580. *********************** END OF SPECIFICATIONS *******************************/
  581.  
  582.  
  583. USHORT near ReadTimeout(pGenioctl)
  584.  
  585. PRP_GENIOCTL           pGenioctl;
  586. {
  587.   PSCSI_IN               pParm = (PSCSI_IN)              (pGenioctl->ParmPacket);
  588.   PSCSI_OUT_READTIMEOUT  pData = (PSCSI_OUT_READTIMEOUT) (pGenioctl->DataPacket);
  589.  
  590.   USHORT                 iUnit = pParm->hDev;
  591.  
  592.   pData->vTimeout = S_to_MS(UnitCB[iUnit].Timeout);
  593.  
  594.   return(STDON);
  595.  
  596. }
  597.  
  598.  
  599.  
  600. /********************** START OF SPECIFICATIONS *****************************
  601. *                                                                           *
  602. * SUBROUTINE NAME:  DeallocDev                                              *
  603. *                                                                           *
  604. * DESCRIPTIVE NAME: Deallocate Device                                       *
  605. *                                                                           *
  606. * FUNCTION:         This routine issues Deallocate Unit IORB to ADD.        *
  607. *                                                                           *
  608. * ENTRY POINT:      DeallocDev                                              *
  609. *                                                                           *
  610. * LINKAGE:          Call Near                                               *
  611. *                                                                           *
  612. * INPUT:            pParm         Pointer to parameter packet               *
  613. *                   pData         Pointer to data packet                    *
  614. *                                                                           *
  615. * EXIT-NORMAL:      Status                                                  *
  616. *                                                                           *
  617. * EXIT-ERROR:       Status                                                  *
  618. *                                                                           *
  619. *********************** END OF SPECIFICATIONS *******************************/
  620.  
  621. USHORT near DeallocDev(pGenioctl)
  622.  
  623. PRP_GENIOCTL    pGenioctl;
  624. {
  625.   NPUCB                 npUCB;
  626.   NPIORB                npIORB;
  627.   USHORT                i;
  628.  
  629.   npUCB    = &UnitCB[((PSCSI_IN)(pGenioctl->ParmPacket))->hDev];
  630.  
  631.   npIORB = &npUCB->Other_IORB;
  632.   CLEAR_IORB_BUFF;
  633.  
  634.   npIORB->Length                = sizeof(IORB_UNIT_CONTROL);
  635.   npIORB->UnitHandle            = npUCB->UnitInfo.UnitHandle;
  636.   npIORB->CommandCode           = IOCC_UNIT_CONTROL;
  637.   npIORB->CommandModifier       = IOCM_DEALLOCATE_UNIT;
  638.   npIORB->Timeout               = npUCB->Timeout;
  639.   npIORB->RequestControl        = IORB_ASYNC_POST;
  640.   npIORB->NotifyAddress         = NotifyIORBDone;
  641.  
  642.   (*(npUCB->AdapterDriverEP))((PIORB) npIORB);
  643.  
  644.   DISABLE;
  645.   while ( !(npIORB->Status & IORB_DONE) )
  646.   {
  647.      DevHelp_ProcBlock ((ULONG)((PIORB) npIORB), -1L, 0);
  648.      DISABLE;
  649.   }
  650.   ENABLE;
  651.  
  652.   if (!(npIORB->Status & IORB_ERROR))
  653.   {
  654.      npUCB->IntUnitFlags &= (~IUF_ALLOCATED);
  655.   }
  656.   return( CheckIORBError(npUCB, npIORB) );
  657. }
  658.  
  659.  
  660. /********************** START OF SPECIFICATIONS *****************************
  661. *                                                                           *
  662. * SUBROUTINE NAME:  RetTypeCnt                                              *
  663. *                                                                           *
  664. * DESCRIPTIVE NAME: Return Peripheral Type Count                            *
  665. *                                                                           *
  666. * FUNCTION:         This routine returns a count of the number of device of *
  667. *                   a particular type which specified by Device-Class Driver*
  668. *                                                                           *
  669. * ENTRY POINT:      RetTypeCnt                                              *
  670. *                                                                           *
  671. * LINKAGE:          Call Near                                               *
  672. *                                                                           *
  673. * INPUT:            pParm         Pointer to parameter packet               *
  674. *                   pData         Pointer to data packet                    *
  675. *                                                                           *
  676. * EXIT-NORMAL:      Status                                                  *
  677. *                                                                           *
  678. * EXIT-ERROR:       Status                                                  *
  679. *                                                                           *
  680. *********************** END OF SPECIFICATIONS *******************************/
  681.  
  682. USHORT near RetTypeCnt(pGenioctl)
  683.  
  684. PRP_GENIOCTL    pGenioctl;
  685. {
  686.   PSCSI_IN_RTNDEVCNT    pParm =(PSCSI_IN_RTNDEVCNT) (pGenioctl->ParmPacket);
  687.   PSCSI_OUT_RTNDEVCNT   pData =(PSCSI_OUT_RTNDEVCNT)(pGenioctl->DataPacket);
  688.  
  689.   NPUCB         npUCB = UnitCB;
  690.  
  691.   USHORT        iUnit  = 0;
  692.   USHORT        cntDev = 0;
  693.   USHORT        DeviceType;
  694.   USHORT        UnitRemovable;
  695.   USHORT        FindRemovable;
  696.  
  697.   DeviceType    =  (USHORT)(pParm->DevType);
  698.   FindRemovable =  (pParm->fDevType & SCSI_REMOVABLE) ? 1 : 0;
  699.  
  700.   for ( ; iUnit < NumUnitCBs; iUnit++, npUCB++)
  701.   {
  702.      UnitRemovable = (npUCB->UnitInfo.UnitFlags & UF_REMOVABLE)   ? 1 : 0;
  703.  
  704.      if ((npUCB->UnitInfo.UnitType == DeviceType) &&
  705.                                       (FindRemovable == UnitRemovable) )
  706.      {
  707.         cntDev++;
  708.      }
  709.   }
  710.  
  711.   pData->numDev = cntDev;
  712.   return(STDON);
  713.  
  714. }
  715.  
  716.  
  717. /********************** START OF SPECIFICATIONS *****************************
  718. *                                                                           *
  719. * SUBROUTINE NAME:  SendAbort                                               *
  720. *                                                                           *
  721. * DESCRIPTIVE NAME: Send Abort                                              *
  722. *                                                                           *
  723. * FUNCTION:         This routine issues to ABORT IORB to ADD.               *
  724. *                                                                           *
  725. * ENTRY POINT:      SendAbort                                               *
  726. *                                                                           *
  727. * LINKAGE:          Call Near                                               *
  728. *                                                                           *
  729. * INPUT:            pParm         Pointer to parameter packet               *
  730. *                   pData         Pointer to data packet                    *
  731. *                                                                           *
  732. * EXIT-NORMAL:      Status                                                  *
  733. *                                                                           *
  734. * EXIT-ERROR:       Status                                                  *
  735. *                                                                           *
  736. *********************** END OF SPECIFICATIONS *******************************/
  737.  
  738. USHORT near SendAbort(pGenioctl, EntryType)
  739.  
  740. PRP_GENIOCTL           pGenioctl;
  741. USHORT                 EntryType;
  742. {
  743.   PSCSI_IN_SENDABORT   pParm = (PSCSI_IN_SENDABORT)(pGenioctl->ParmPacket);
  744.   PSCSI_OUT            pData = (PSCSI_OUT)         (pGenioctl->DataPacket);
  745.  
  746.   NPIORB               npIORB;
  747.   NPSCSI_STATUS_BLOCK  npSSB;
  748.   NPUCB                npUCB = &UnitCB[pParm->hDev];
  749.  
  750.   USHORT               i;
  751.  
  752.   if ( ValidateUserPacket(pGenioctl, npUCB, EntryType) )             /*@V55360*/
  753.   {                                                                  /*@V55360*/
  754.                                             /* get IORB buffer address */
  755.     npIORB = &npUCB->Other_IORB;
  756.     CLEAR_IORB_BUFF;
  757.                                             /* get SSB buffer address  */
  758.     npSSB = &npUCB->Other_SSB;
  759.     CLEAR_SSB_BUFF;
  760.  
  761.     npIORB->Length                = sizeof(IORB_DEVICE_CONTROL);
  762.     npIORB->UnitHandle            = npUCB->UnitInfo.UnitHandle;
  763.  
  764.     npIORB->CommandCode           = IOCC_DEVICE_CONTROL;
  765.     npIORB->CommandModifier       = IOCM_ABORT;
  766.     npIORB->RequestControl        = IORB_REQ_STATUSBLOCK | IORB_ASYNC_POST;
  767.  
  768.     npIORB->Timeout               = npUCB->Timeout;
  769.  
  770.     npIORB->StatusBlockLen        = sizeof(SCSI_STATUS_BLOCK);
  771.     npIORB->pStatusBlock          = (NPBYTE)npSSB;
  772.  
  773.     npIORB->NotifyAddress         = NotifyIORBDone;
  774.  
  775.                                              /* set sense data length & addr. */
  776.     npSSB->ReqSenseLen = pParm->lnSenseData;
  777.     npSSB->SenseData   = npUCB->pSenseData;
  778.  
  779.     (*(npUCB->AdapterDriverEP))((PIORB)npIORB);
  780.  
  781.     DISABLE;
  782.     while ( !(npIORB->Status & IORB_DONE) )
  783.     {
  784.        DevHelp_ProcBlock ((ULONG)((PIORB) npIORB), -1L, 0);
  785.        DISABLE;
  786.     }
  787.     ENABLE;
  788.  
  789.     npUCB->LastStatus    = npIORB->Status;
  790.     npUCB->LastErrCode   = npIORB->ErrorCode;
  791.     npUCB->LastSSB       = *(NPSCSI_STATUS_BLOCK) npIORB->pStatusBlock;
  792.     npUCB->ppLastSCB     = 0;
  793.  
  794.     return( CheckIORBError(npUCB, npIORB) );
  795.   }                                                                  /*@V55360*/
  796.   else                                                               /*@V55360*/
  797.   {                                                                  /*@V55360*/
  798.     return( STDON + STERR + ERROR_I24_INVALID_PARAMETER );           /*@V55360*/
  799.   }                                                                  /*@V55360*/
  800. }
  801.  
  802. /********************** START OF SPECIFICATIONS *****************************
  803. *                                                                           *
  804. * SUBROUTINE NAME:  NotifyIORBDone                                          *
  805. *                                                                           *
  806. * DESCRIPTIVE NAME: IORB Notification routine                               *
  807. *                                                                           *
  808. * FUNCTION:         Does a DevHelp_ProcRun on the completed IORB address.   *
  809. *                   This routine is used by sections of the OS2SCSI that    *
  810. *                   need an in-line wait for an IORB completion.            *
  811. *                                                                           *
  812. * ENTRY POINT:                                                              *
  813. *                                                                           *
  814. * LINKAGE:          Call FAR                                                *
  815. *                                                                           *
  816. * INPUT:            pIORB                                                   *
  817. *                                                                           *
  818. * EXIT-NORMAL:                                                              *
  819. *                                                                           *
  820. * EXIT-ERROR:                                                               *
  821. *                                                                           *
  822. *********************** END OF SPECIFICATIONS *******************************/
  823.  
  824. void _loadds far
  825. NotifyIORBDone(pIORB)
  826.  
  827. PIORBH           pIORB;
  828. {
  829.   USHORT         AwakeCount;
  830.  
  831.   DevHelp_ProcRun((ULONG)(pIORB), &AwakeCount);
  832.  
  833.   return;
  834.  
  835. }
  836.