home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / ddkx86v5.zip / DDKX86 / SRC / DEV / DASD / OS2DASD / DMIORB.C < prev    next >
Encoding:
C/C++ Source or Header  |  1995-04-14  |  20.0 KB  |  630 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/os2dasd/dmiorb.c, dsdm, ddk_subset, b_bdd.032 93/07/14";*/
  13. #define SCCSID  "src/dev/dasd/os2dasd/dmiorb.c, dsdm, ddk_subset, b_bdd.032 93/07/14"
  14.  
  15. /**************************************************************************
  16.  *
  17.  * SOURCE FILE NAME = DMIORB.C
  18.  *
  19.  * DESCRIPTIVE NAME = OS2DASD.DMD - OS/2 DASD Device Manager
  20.  *                    IORB managment routines for OS/2 DASD Manager
  21.  *
  22.  *
  23.  * VERSION = V2.0
  24.  *
  25.  * DATE
  26.  *
  27.  * DESCRIPTION    Handles allocation, initialization, and freeing of
  28.  *                I/O request blocks (IORBs) used to communicate with
  29.  *                Adapter Device Drivers (ADDs).
  30.  *
  31.  *
  32.  *
  33. */
  34. #include "dmh.h"
  35. #include "dmfault.h"
  36.  
  37.  
  38. /*------------------------------------------------------------------------
  39. ;
  40. ;** InitCBPool - Initialize the control block pool
  41. ;
  42. ;   Initializes the control block pool which is used for IORB,
  43. ;   CWA and FTDB allocation.
  44. ;
  45. ;   USHORT InitCBPool ()
  46. ;
  47. ;   ENTRY:
  48. ;
  49. ;   RETURN:
  50. ;
  51. ;   EFFECTS:
  52. ;
  53. ------------------------------------------------------------------------*/
  54. VOID InitCBPool ()
  55. {
  56.    NPUNITCB pUnitCB;
  57.    NPBYTE   pCB;
  58.    NPIORBH  pIORB;
  59.    USHORT   NumCBs, CBSize, i;
  60.    USHORT   NumIORBs = 0;
  61.  
  62.    /*--------------------------------*/
  63.    /* Calculate the size of the Pool */
  64.    /*--------------------------------*/
  65.  
  66.    /* The size of a control block is the max size of an IORB, CWA and FTDB */
  67.  
  68.    CBSize = MAX_IORB_SIZE;
  69.    if (CBSize < sizeof(CWA))
  70.       CBSize = sizeof(CWA);
  71.  
  72.  
  73.    /* Calculate the number of IORBs to allocate by summing the */
  74.    /* Queuing Counts in each UnitCB.                           */
  75.  
  76.    for (pUnitCB = UnitCB_Head, i = 0; i < NumUnitCBs; i++, pUnitCB++)
  77.    {
  78.      if ( (pUnitCB->UnitInfo.QueuingCount > MAX_QUEUING_COUNT) ||
  79.           (pUnitCB->UnitInfo.QueuingCount == 0) )
  80.         NumIORBs += MAX_QUEUING_COUNT;
  81.      else
  82.         NumIORBs += pUnitCB->UnitInfo.QueuingCount;
  83.    }
  84.  
  85.    NumCBs = NumIORBs + NUM_DEFAULT_CWAS;   /* add in room for CWAs */
  86.  
  87.    FreePoolSpace = (USHORT) &InitData - (USHORT) pNextFreeCB;
  88.  
  89.    /*  Make sure Pool Size isnt greater than available space left in */
  90.    /*  the data segment.                                             */
  91.  
  92.    if ( ((ULONG)NumCBs * CBSize) < (ULONG)FreePoolSpace)
  93.       PoolSize = NumCBs * CBSize;
  94.    else
  95.    {
  96.       NumCBs = FreePoolSpace / CBSize;
  97.       PoolSize = NumCBs * CBSize;
  98.    }
  99.  
  100.    /*-----------------------------------*/
  101.    /* Initialize the Control Block Pool */
  102.    /*-----------------------------------*/
  103.  
  104.    CB_FreeList = pNextFreeCB;
  105.  
  106.    pCB = CB_FreeList;
  107.  
  108.    for (i = 0; i < NumCBs; i++)
  109.    {
  110.  
  111.       ((NPIORBH) pCB)->pNxtIORB = (PIORBH) (pCB + CBSize);
  112.       pCB += CBSize;
  113.    }
  114.  
  115.    ((NPIORBH) (pCB - CBSize))->pNxtIORB = 0;    /* Zero terminate list */
  116.  
  117.    pNextFreeCB = pCB;
  118.  
  119.  
  120.    /*------------------------------------------*/
  121.    /* Allocate one dedicated IORB to each Unit */
  122.    /*------------------------------------------*/
  123.  
  124.    pCB = CB_FreeList;
  125.  
  126.    for (pUnitCB = UnitCB_Head, i = 0; i < NumUnitCBs; i++, pUnitCB++)
  127.    {
  128.       pUnitCB->pDedicatedIORB = (NPIORBH) pCB;
  129.       ((NPIORBH) pCB)->pNxtIORB = 0;
  130.       pCB += CBSize;
  131.    }
  132.  
  133.    CB_FreeList = pCB;            /* Free List now starts past dedicated IORBs */
  134.  
  135.  
  136. }
  137.  
  138.  
  139.  
  140. typedef struct _ReqToIORB_CmdEntry
  141. {
  142.    UCHAR  PktCommand;
  143.    UCHAR  PktFunction;
  144.    USHORT IORBCommandCode;
  145.    USHORT IORBCommandModifier;
  146. } ReqToIORB_CmdEntry;
  147.  
  148. /*------------------------------------------------------------------------
  149. ;
  150. ;** SetupIORB - Setup an IORB
  151. ;
  152. ;   Sets ups an IORB from the input Request Packet or Request List Entry
  153. ;
  154. ;   VOID SetupIORB  (NPUNITCB pUnitCB, PBYTE pReq, pIORB)
  155. ;
  156. ;   ENTRY:    pUnitCB          - Pointer to UnitCB
  157. ;             pReq             - Pointer to Request Packet or Request List Entry
  158. ;             pIORB            - Pointer to IORB
  159. ;
  160. ;   RETURN:
  161. ;
  162. ;   EFFECTS:
  163. ;
  164. ------------------------------------------------------------------------*/
  165. typedef NPIORB_EXECUTEIO NPXIO;
  166. typedef NPIORB_FORMAT    NPFIO;
  167.  
  168. VOID   SetupIORB (pUnitCB, pReqIn, pIORB)
  169.  
  170. NPUNITCB pUnitCB;
  171. PBYTE    pReqIn;
  172. NPIORBH  pIORB;
  173.  
  174. {
  175.  
  176. static ReqToIORB_CmdEntry ReqToIORB_CmdTable[] = {
  177.  
  178. {PB_REQ_LIST, PB_READ_X,     IOCC_EXECUTE_IO, IOCM_READ},
  179. {PB_REQ_LIST, PB_WRITE_X,    IOCC_EXECUTE_IO, IOCM_WRITE},
  180. {PB_REQ_LIST, PB_WRITEV_X,   IOCC_EXECUTE_IO, IOCM_WRITE_VERIFY},
  181. {PB_REQ_LIST, PB_PREFETCH_X, IOCC_EXECUTE_IO, IOCM_READ_PREFETCH},
  182.  
  183. {CMDINPUT,         0,        IOCC_EXECUTE_IO, IOCM_READ},
  184. {CMDOUTPUT,        0,        IOCC_EXECUTE_IO, IOCM_WRITE},
  185. {CMDOUTPUTV,       0,        IOCC_EXECUTE_IO, IOCM_WRITE_VERIFY},
  186. {CMDInputBypass,   0,        IOCC_EXECUTE_IO, IOCM_READ},
  187. {CMDOutputBypass,  0,        IOCC_EXECUTE_IO, IOCM_WRITE},
  188. {CMDOutputBypassV, 0,        IOCC_EXECUTE_IO, IOCM_WRITE_VERIFY},
  189.  
  190. {CMDInternal, DISKOP_READ_VERIFY,        IOCC_EXECUTE_IO, IOCM_READ_VERIFY},
  191. {CMDInternal, DISKOP_FORMAT,             IOCC_FORMAT,     IOCM_FORMAT_TRACK},
  192. {CMDInternal, DISKOP_FORMAT_VERIFY,      IOCC_FORMAT,     IOCM_FORMAT_TRACK},
  193. {CMDInternal, DISKOP_GET_CHANGELINE_STATE, IOCC_UNIT_STATUS, IOCM_GET_CHANGELINE_STATE},
  194. {CMDInternal, DISKOP_GET_MEDIA_SENSE,    IOCC_UNIT_STATUS, IOCM_GET_MEDIA_SENSE},
  195. {CMDInternal, DISKOP_SUSPEND_DEFERRED,   IOCC_DEVICE_CONTROL, IOCM_SUSPEND},
  196. {CMDInternal, DISKOP_RESUME,             IOCC_DEVICE_CONTROL, IOCM_RESUME},
  197. {CMDInternal, DISKOP_GET_MEDIA_GEOMETRY, IOCC_GEOMETRY, IOCM_GET_MEDIA_GEOMETRY},
  198. {CMDInternal, DISKOP_SET_MEDIA_GEOMETRY, IOCC_GEOMETRY, IOCM_SET_MEDIA_GEOMETRY},
  199. {CMDInternal, DISKOP_SET_LOGICAL_GEOMETRY, IOCC_GEOMETRY, IOCM_SET_LOGICAL_GEOMETRY},
  200. {CMDInternal, DISKOP_LOCKMEDIA,          IOCC_DEVICE_CONTROL, IOCM_LOCK_MEDIA},      /*@V51531*/
  201. {CMDInternal, DISKOP_UNLOCKMEDIA,        IOCC_DEVICE_CONTROL, IOCM_UNLOCK_MEDIA},    /*@V51531*/
  202. {CMDInternal, DISKOP_EJECTMEDIA,         IOCC_DEVICE_CONTROL, IOCM_EJECT_MEDIA},     /*@V51531*/
  203. {CMDInternal, DISKOP_GET_UNIT_STATUS,    IOCC_UNIT_STATUS,    IOCM_GET_UNIT_STATUS}, /*@V51531*/
  204. {CMDInternal, DISKOP_GET_LOCK_STATUS,    IOCC_UNIT_STATUS,    IOCM_GET_LOCK_STATUS}, /*@V51531*/
  205. {CMDInternal, DISKOP_UPDATE_REC_BPB,     IOCC_GEOMETRY, IOCM_GET_MEDIA_GEOMETRY},    /*@V63867*/
  206. {-1}, };                                /* End of Table */
  207.  
  208.  
  209.    UCHAR PktCommand, PktFunction;
  210.    USHORT i;
  211.    NPGEOMETRY pGeometry;
  212.    NPFORMAT_CMD_TRACK pFCT;
  213.    NPVOLCB pVolCB;
  214.    NPIORB_DMWORK pDMWork;
  215.  
  216.    _segment ReqSeg;
  217.    PB_Read_Write _based(ReqSeg)    *pRLE;
  218.    Req_List_Header _based(ReqSeg) *pRLH;
  219.    RP_RWV _based(ReqSeg) *pRP;
  220.  
  221.    ReqSeg = SELECTOROF(pReqIn);
  222.    (USHORT) pRLE = OFFSETOF(pReqIn);
  223.    (USHORT) pRP = OFFSETOF(pReqIn);
  224.  
  225.    pDMWork = (NPIORB_DMWORK) &(pIORB->DMWorkSpace);
  226.  
  227.    /* Setup the IORB header */
  228.  
  229.    pIORB->UnitHandle = pUnitCB->UnitInfo.UnitHandle;
  230.    pIORB->RequestControl = IORB_ASYNC_POST;
  231.    pIORB->NotifyAddress = NotifyDoneIORB;
  232.    pIORB->Status = 0;
  233.    pIORB->ErrorCode = 0;                                             /*@V58430*/
  234.    pDMWork->pUnitCB = pUnitCB;
  235.    pDMWork->pRequest = (PBYTE) pReqIn;
  236.  
  237.    /* Determine the IORB CommandCode/CommandModifier and goto the     */
  238.    /* associate command handler to initialize the rest of the IORB.   */
  239.  
  240.    PktCommand = pRP->rph.Cmd;
  241.    PktFunction = 0;
  242.    if (PktCommand == PB_REQ_LIST)
  243.       PktFunction = pRLE->RqHdr.Command_Code;
  244.    else if (PktCommand == CMDInternal)
  245.       PktFunction = ((PRP_INTERNAL) pRP)->Function;
  246.  
  247.    for (i = 0; ReqToIORB_CmdTable[i].PktCommand != -1; i++)
  248.    {
  249.       if ( (PktCommand == ReqToIORB_CmdTable[i].PktCommand) &&
  250.            (PktFunction == ReqToIORB_CmdTable[i].PktFunction) )
  251.       {
  252.          pIORB->CommandCode = ReqToIORB_CmdTable[i].IORBCommandCode;
  253.          pIORB->CommandModifier = ReqToIORB_CmdTable[i].IORBCommandModifier;
  254.  
  255.          if ( (DDFlags & DDF_DMAReadBack) &&
  256.               (pIORB->CommandCode == IOCC_EXECUTE_IO) &&
  257.               (pIORB->CommandModifier == IOCM_WRITE) &&
  258.               (pUnitCB->UnitInfo.UnitFlags & UF_REMOVABLE) )
  259.  
  260.                  pIORB->CommandModifier = IOCM_WRITE_VERIFY;
  261.  
  262.          break;
  263.       }
  264.    }
  265.  
  266.    switch (pIORB->CommandCode)
  267.    {
  268.       case IOCC_EXECUTE_IO:
  269.  
  270.          if (PktCommand == PB_REQ_LIST)
  271.             goto ExecuteIO_RLE;
  272.          else
  273.             goto ExecuteIO_RP;
  274.  
  275.       case IOCC_FORMAT:
  276.          goto Format_RP;
  277.  
  278.       case IOCC_UNIT_STATUS:
  279.          goto UnitStatus_RP;
  280.  
  281.       case IOCC_DEVICE_CONTROL:
  282.          goto DeviceControl_RP;
  283.  
  284.       case IOCC_GEOMETRY:
  285.          goto Geometry_RP;
  286.  
  287.    }
  288.  
  289.  
  290.    /*----------------------------------------------*/
  291.    /* Setup EXECUTE_IO IORB for Request List Entry */
  292.    /*----------------------------------------------*/
  293.  
  294. ExecuteIO_RLE:
  295.    (USHORT) pRLH = (USHORT) pRLE - pRLE->RqHdr.Head_Offset;
  296.  
  297.    if ( (DDFlags & DDF_FT_ENABLED) &&
  298.         ( ((PRHFT)pRLE)->ftdb.FT_Flags & FTF_FT_REQUEST) )
  299.       Get_VolCB_Addr(((PRHFT)pRLE)->Block_Dev_Unit, (NPVOLCB FAR *) &pVolCB);
  300.    else
  301.       Get_VolCB_Addr(pRLH->Block_Dev_Unit, (NPVOLCB FAR *) &pVolCB);
  302.  
  303.    pIORB->Length = sizeof(IORB_EXECUTEIO);
  304.    ((NPXIO)pIORB)->RBA = pRLE->Start_Block +
  305.                pVolCB->PartitionOffset + pVolCB->MediaBPB.HiddenSectors;
  306.    ((NPXIO)pIORB)->BlockCount = pRLE->Block_Count;
  307.    ((NPXIO)pIORB)->BlockSize = 512;
  308.  
  309.    /* Set up pointers to the scatter/gather list for all commands */
  310.    /* except a read prefetch.                                    */
  311.  
  312.    if (pIORB->CommandModifier != IOCM_READ_PREFETCH)
  313.    {
  314.       ((NPXIO)pIORB)->cSGList = pRLE->SG_Desc_Count;
  315.       SELECTOROF(((NPXIO)pIORB)->pSGList) = ReqSeg;
  316.       OFFSETOF(((NPXIO)pIORB)->pSGList) = (USHORT)pRLE + sizeof(PB_Read_Write);
  317.       ((NPXIO)pIORB)->ppSGList = pRLH->y_PhysAddr +
  318.                           OFFSETOF(((NPXIO)pIORB)->pSGList) - (USHORT)pRLH;
  319.  
  320.       ((NPXIO)pIORB)->Flags = 0;
  321.  
  322.       /* Disable caching if requested */
  323.  
  324.       if (  ( !(pRLE->RW_Flags & RW_Cache_Req) ) ||                  /*@V46569*/
  325.             (pUnitCB->Flags & UCF_REMOVABLE_NON_FLOPPY) )            /*@V46569*/
  326.       {
  327.          ((NPXIO)pIORB)->Flags |=  (XIO_DISABLE_HW_WRITE_CACHE |
  328.                                     XIO_DISABLE_HW_READ_CACHE);
  329.       }
  330.   }
  331.   return;
  332.  
  333.    /*-------------------------------------------*/
  334.    /* Setup EXECUTE_IO IORB for Request Packets */
  335.    /*-------------------------------------------*/
  336.  
  337. ExecuteIO_RP:
  338.    pIORB->Length = sizeof(IORB_EXECUTEIO);
  339.    ((NPXIO)pIORB)->RBA = pRP->rba;
  340.    if (pRP->rph.Flags & RPF_CHS_ADDRESSING)
  341.       pIORB->RequestControl |= IORB_CHS_ADDRESSING;
  342.  
  343.    ((NPXIO)pIORB)->BlockCount = pRP->NumSectors;
  344.    ((NPXIO)pIORB)->BlockSize = 512;
  345.    ((NPXIO)pIORB)->Flags = 0;
  346.  
  347.    if ( (pUnitCB->UnitInfo.UnitFlags & UF_REMOVABLE) &&
  348.         (pRP->rph.Flags & RPF_Internal) &&
  349.         (((PRP_INTERNAL)pRP)->SectorSize != 512) &&
  350.         (((PRP_INTERNAL)pRP)->SectorSize != 0) )
  351.  
  352.         ((NPXIO)pIORB)->BlockSize = ((PRP_INTERNAL)pRP)->SectorSize;
  353.  
  354.    /* Set up pointers to the scatter/gather list for all commands */
  355.    /* except a read verify.  The scatter/gather list for Request  */
  356.    /* Packets is created within a reserved field in the           */
  357.    /* IORB_EXECUTEIO control block.                               */
  358.  
  359.    if (pIORB->CommandModifier != IOCM_READ_VERIFY)
  360.    {
  361.       ((NPXIO)pIORB)->cSGList = 1;
  362.       ((NPXIO)pIORB)->pSGList = (PVOID) pIORB;
  363.       OFFSETOF( ((NPXIO)pIORB)->pSGList) = (USHORT) (&(pDMWork->SGList));
  364.       ((NPXIO)pIORB)->ppSGList =
  365.              (ULONG) (ppDataSeg + (ULONG)((USHORT)&(pDMWork->SGList)));
  366.  
  367.       /* Set up single entry scatter/gather list within IORB */
  368.       (ULONG) (pDMWork->SGList.ppXferBuf) = pRP->XferAddr;
  369.       (ULONG) (pDMWork->SGList.XferBufLen) =
  370.            ((ULONG)((NPXIO)pIORB)->BlockCount)                       /*@V69289*/
  371.                                * ((NPXIO)pIORB)->BlockSize;          /*@V69289*/
  372.    }
  373.  
  374.    /* Disable caching if removable SCSI media */
  375.  
  376.    if (pUnitCB->Flags & UCF_REMOVABLE_NON_FLOPPY)                    /*@V46569*/
  377.    {                                                                 /*@V46569*/
  378.       ((NPXIO)pIORB)->Flags |=  (XIO_DISABLE_HW_WRITE_CACHE |        /*@V46569*/
  379.                                  XIO_DISABLE_HW_READ_CACHE);         /*@V46569*/
  380.    }                                                                 /*@V46569*/
  381.    return;
  382.  
  383.    /*-------------------------------------------*/
  384.    /* Setup FORMAT IORB for Request Packets     */
  385.    /*-------------------------------------------*/
  386. Format_RP:
  387.    pFCT = (NPFORMAT_CMD_TRACK) &( ((NPFIO)pIORB)->Reserved_1[0]);
  388.  
  389.    pIORB->Length = sizeof(IORB_FORMAT);
  390.  
  391.    if (pRP->rph.Flags & RPF_CHS_ADDRESSING)
  392.       pIORB->RequestControl |= IORB_CHS_ADDRESSING;
  393.  
  394.    ((NPFIO)pIORB)->cSGList = 1;
  395.    ((NPFIO)pIORB)->pSGList = (PVOID) pIORB;
  396.    OFFSETOF( ((NPFIO)pIORB)->pSGList) = (USHORT) (&(pDMWork->SGList));
  397.    ((NPFIO)pIORB)->ppSGList =
  398.             (ULONG) (ppDataSeg + (ULONG)((USHORT)&(pDMWork->SGList)));
  399.  
  400.    /* Set up single entry scatter/gather list within IORB */
  401.    (ULONG) (pDMWork->SGList.ppXferBuf) = ((PRP_INTERNAL)pRP)->XferAddr;
  402.    (ULONG) (pDMWork->SGList.XferBufLen) =
  403.            ((PRP_INTERNAL)pRP)->NumSectors * sizeof(FTT);
  404.  
  405.    ((NPFIO)pIORB)->FormatCmdLen = sizeof(FORMAT_CMD_TRACK);
  406.    ((NPFIO)pIORB)->pFormatCmd = (PVOID) pFCT;
  407.  
  408.    pFCT->RBA = ((PRP_INTERNAL)pRP)->rba;
  409.    pFCT->cTrackEntries = ((PRP_INTERNAL)pRP)->NumSectors;
  410.  
  411.    /* If FormatVerify then turn on the verify flag.  */
  412.  
  413.    pFCT->Flags = 0;
  414.    if (PktFunction == DISKOP_FORMAT_VERIFY)
  415.       pFCT->Flags |= FF_VERIFY;
  416.  
  417.    return;
  418.  
  419.    /*------------------------------------------------*/
  420.    /* Setup UNIT STATUS IORB for Request Packets     */
  421.    /*------------------------------------------------*/
  422. UnitStatus_RP:
  423.    pIORB->Length = sizeof(IORB_UNIT_STATUS);
  424.  
  425.    return;
  426.  
  427.    /*---------------------------------------------------*/
  428.    /* Setup DEVICE CONTROL IORB                         */
  429.    /*---------------------------------------------------*/
  430. DeviceControl_RP:
  431.    pIORB->Length = sizeof(IORB_DEVICE_CONTROL);
  432.  
  433.    if (PktFunction == DISKOP_SUSPEND_DEFERRED)
  434.       ((NPIORB_DEVICE_CONTROL)pIORB)->Flags |= DC_SUSPEND_DEFERRED;
  435.  
  436.    return;
  437.  
  438.    /*---------------------------------------------------*/
  439.    /* Setup GEOMETRY IORB                               */
  440.    /*---------------------------------------------------*/
  441. Geometry_RP:
  442.    pVolCB = (NPVOLCB) ((PRP_INTERNAL)pRP)->NumSectors;
  443.    (USHORT) pGeometry = OFFSETOF(pIORB) + sizeof(IORB_GEOMETRY);
  444.  
  445.    pIORB->Length = sizeof(IORB_GEOMETRY);
  446.    ((NPIORB_GEOMETRY)pIORB)->pGeometry = (PVOID) pGeometry;
  447.    ((NPIORB_GEOMETRY)pIORB)->GeometryLen = sizeof(GEOMETRY);
  448.  
  449.    if ( (pIORB->CommandModifier == IOCM_SET_MEDIA_GEOMETRY) ||
  450.         (pIORB->CommandModifier == IOCM_SET_LOGICAL_GEOMETRY) )
  451.    {
  452.       if (pVolCB->MediaBPB.TotalSectors != 0)
  453.          pGeometry->TotalSectors = pVolCB->MediaBPB.TotalSectors;
  454.       else
  455.          pGeometry->TotalSectors = pVolCB->MediaBPB.BigTotalSectors;
  456.  
  457.       pGeometry->BytesPerSector = pVolCB->MediaBPB.BytesPerSector;
  458.       pGeometry->NumHeads = pVolCB->MediaBPB.NumHeads;
  459.       pGeometry->TotalCylinders = pVolCB->NumLogCylinders;
  460.       pGeometry->SectorsPerTrack = pVolCB->MediaBPB.SectorsPerTrack;
  461.    }
  462.  
  463.    return;
  464.  
  465.  
  466. }
  467.  
  468.  
  469. /*------------------------------------------------------------------------
  470. ;
  471. ;** AllocIORB - Allocate an IORB
  472. ;
  473. ;   Allocates an IORB.
  474. ;
  475. ;   USHORT AllocIORB  (NPUNITCB pUnitCB, NPIORB *pIORB)
  476. ;
  477. ;   ENTRY:    pUnitCB           - UnitCB requesting allocation
  478. ;             pIORB             - returned pointer to IORB
  479. ;
  480. ;   RETURN:   USHORT            = 0, IORB allocated
  481. ;                               ! 0 , IORB not allocated
  482. ;
  483. ;   NOTES:
  484. ;
  485. ------------------------------------------------------------------------*/
  486. USHORT  AllocIORB(pUnitCB, pIORB)
  487.  
  488. NPUNITCB pUnitCB;
  489. NPIORBH  FAR *pIORB;
  490.  
  491. {
  492.    USHORT rc = 0;
  493.  
  494.    PUSHFLAGS;
  495.    DISABLE;     /* Make sure interrupts are disabled */
  496.  
  497.    /* Try allocating the dedicated IORB for the requesting unit */
  498.  
  499.    if ( !(pUnitCB->Flags & UCF_IORB_ALLOCATED) )
  500.    {
  501.       pUnitCB->Flags |= UCF_IORB_ALLOCATED;
  502.       *pIORB = pUnitCB->pDedicatedIORB;
  503.    }
  504.    else
  505.    {
  506.      /* Dedicated IORB already allocated, so get an IORB from the pool. */
  507.  
  508.      if (CB_FreeList != 0)
  509.      {
  510.        *pIORB = (NPIORBH) CB_FreeList;           /* Get IORB from free list */
  511.        CB_FreeList = (NPBYTE) (*pIORB)->pNxtIORB; /* Update free list head  */
  512.      }
  513.      else
  514.        rc = 1;
  515.    }
  516.  
  517.    /* Zero fill IORB */
  518.  
  519.    if (rc == 0)
  520.       f_ZeroCB((PBYTE)*pIORB, MAX_IORB_SIZE);
  521.  
  522.    POPFLAGS;
  523.    return(rc);
  524. }
  525.  
  526. /*------------------------------------------------------------------------
  527. ;
  528. ;** AllocIORB_Wait - Allocate an IORB, wait until one is available
  529. ;
  530. ;   Allocates an IORB from the Control Block pool and block if one
  531. ;   is not available.
  532. ;
  533. ;   VOID AllocIORB_Wait  (NPUNITCB pUnitCB, NPIORB *pIORB)
  534. ;
  535. ;   ENTRY:    pUnitCB           - UnitCB requesting allocation
  536. ;             pIORB             - returned pointer to IORB
  537. ;
  538. ;   RETURN:   VOID
  539. ;
  540. ;   EFFECTS:
  541. ;
  542. ------------------------------------------------------------------------*/
  543. VOID  AllocIORB_Wait (pUnitCB, pIORB)
  544.  
  545. NPUNITCB pUnitCB;
  546. NPIORBH  FAR *pIORB;
  547.  
  548. {
  549.    USHORT Allocated = FALSE;
  550.  
  551.    PUSHFLAGS;
  552.    DISABLE;
  553.  
  554.    do
  555.    {
  556.       if (CB_FreeList != 0)             /* Allocate from free list */
  557.       {
  558.          *pIORB = (NPIORBH) CB_FreeList;
  559.          CB_FreeList = (NPBYTE) (*pIORB)->pNxtIORB; /* Update free list head  */
  560.          Allocated = TRUE;
  561.       }
  562.       else                              /* else wait till control block free */
  563.       {
  564.          PoolSem++;                     /* Indicate at least 1 thread blocked */
  565.          DevHelp_ProcBlock((ULONG) ppDataSeg, (ULONG)-1, 0);
  566.          DISABLE;
  567.          PoolSem--;                     /* Indicate at least 1 thread blocked */
  568.       }
  569.    } while (Allocated == FALSE);
  570.  
  571.    ENABLE;
  572.    /* Zero fill the IORB */
  573.  
  574.    f_ZeroCB((PBYTE)*pIORB, MAX_IORB_SIZE);
  575.  
  576.    POPFLAGS;
  577. }
  578. /*------------------------------------------------------------------------
  579. ;
  580. ;** FreeIORB - Free an IORB
  581. ;
  582. ;   Free an IORB.
  583. ;
  584. ;   VOID FreeIORB  (NPUNITCB pUnitCB, NPIORB pIORB)
  585. ;
  586. ;   ENTRY:    pUnitCB           - UnitCB requesting deallocation
  587. ;             pIORB             - IORB to deallocate
  588. ;
  589. ;   RETURN:
  590. ;
  591. ;   EFFECTS:
  592. ;
  593. ------------------------------------------------------------------------*/
  594.  
  595. VOID  FreeIORB (pUnitCB, pIORB)
  596.  
  597. NPUNITCB pUnitCB;
  598. NPIORBH  pIORB;
  599.  
  600. {
  601.    USHORT AwakeCount;
  602.  
  603.    PUSHFLAGS;
  604.    DISABLE;
  605.  
  606.    /* If the IORB being freed is the unit's dedicated IORB, then simply */
  607.    /* clear the UCF_IORB_ALLOCATED flag in the UnitCB, otherwise return */
  608.    /* the IORB to the free pool.                                        */
  609.  
  610.    if (pIORB == pUnitCB->pDedicatedIORB)
  611.       pUnitCB->Flags &= ~UCF_IORB_ALLOCATED;
  612.    else
  613.    {
  614.       pIORB->pNxtIORB = (NPIORBH) CB_FreeList;
  615.       CB_FreeList = (NPBYTE) pIORB;
  616.    }
  617.  
  618.    /* If anyone waiting on the pool, then wake them up */
  619.  
  620.    if (PoolSem)
  621.    {
  622.       DevHelp_ProcRun((ULONG)ppDataSeg, &AwakeCount);
  623.    }
  624.  
  625.    POPFLAGS;
  626. }
  627.  
  628.  
  629.  
  630.