home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 8 Other / 08-Other.zip / e2fltsrc.zip / e2iocmd.c < prev    next >
C/C++ Source or Header  |  1995-07-25  |  7KB  |  203 lines

  1. /************************************************************************/
  2. /*  Linux partition filter (C) Deon van der Westhuysen.                 */
  3. /*                                                                      */
  4. /*  Dedicated to Jesus Christ, my Lord and Saviour.                     */
  5. /*                                                                      */
  6. /*  Permission is granted to freely use and modify this code for non-   */
  7. /*  profit use on the condition that this notice is not removed. All    */
  8. /*  other rights are reserved. No warranty, etc.                        */
  9. /*                                                                      */
  10. /*  This code is still under development; expect some rough edges.      */
  11. /*                                                                      */
  12. /************************************************************************/
  13.  
  14. #include "debug.h"
  15. #include "e2data.h"
  16. #include "e2router.h"
  17. #include "e2part.h"
  18. #include "e2iocmd.h"
  19. #include "e2virtio.h"
  20. #include "e2wrap.h"
  21.  
  22. /* Command thats called when we receive an unknown/unsupported IORB command */
  23. void BadCommand (NPVirtUnitRec pUnitRec, PIORB pIORB)
  24. {
  25.  IORBError(pIORB,IOERR_CMD_NOT_SUPPORTED);    /* Set error */
  26.  PartCommandDone (pUnitRec,pIORB);        /* Send it away. */
  27. }
  28.  
  29. /* Macro to compute the length of the device table that we will create */
  30. #define DEVICE_TABLE_LEN    sizeof(DEVICETABLE)+\
  31.                 sizeof(ADAPTERINFO)*(MountCount)+\
  32.                 sizeof(NPADAPTERINFO)*(MountCount-1)
  33.  
  34. /* Command to create a device table. */
  35. void PartGetDeviceTable (NPVirtUnitRec pUnitRec, PIORB pIORB)
  36. {
  37. #define pIOCFG        ((PIORB_CONFIGURATION) pIORB)
  38.  
  39.  NPVirtUnitRec        pCurrentUnitRec;    /* Ptr to UnitRec current */
  40.                         /* entry in the device table */
  41.  PDEVICETABLE        pDevTable;        /* Where to build dev table */
  42.  PADAPTERINFO        pAdapter;        /* Ptr to adapter entry */
  43.  UNITINFO        UnitInfo;        /* Default UnitInfo returned */
  44.  int            Count;
  45.  
  46.  if (pIOCFG->DeviceTableLen<DEVICE_TABLE_LEN)    /* Check table not too big */
  47.   IORBError(pIORB,IOERR_CMD_SYNTAX);
  48.  else
  49.  {
  50.   /* Static unit information... */
  51.   UnitInfo.UnitIndex= 0;
  52.   UnitInfo.UnitFlags= UF_NOSCSI_SUPT;
  53.   UnitInfo.FilterADDHandle= 0;
  54.   UnitInfo.UnitType= UIB_TYPE_DISK;
  55.   UnitInfo.QueuingCount= 1;
  56.   UnitInfo.UnitSCSITargetID= 0;
  57.   UnitInfo.UnitSCSILUN= 0;
  58.  
  59.   /* Fill in device section... */
  60.   pDevTable= pIOCFG->pDeviceTable;
  61.   pDevTable->ADDLevelMajor= ADD_LEVEL_MAJOR;
  62.   pDevTable->ADDLevelMinor= ADD_LEVEL_MINOR;
  63.   pDevTable->ADDHandle= ADDHandle;
  64.   pDevTable->TotalAdapters= MountCount;    /* One adapter for each unit */
  65.  
  66.   for (Count= 0,pAdapter=(PADAPTERINFO) &(pDevTable->pAdapter[MountCount]);
  67.        Count<MountCount;
  68.        Count++,pAdapter++)
  69.   {
  70.    /* Get pointer to the next mounted unit. */
  71.    pCurrentUnitRec= VirtUnits+MountTable[Count];
  72.    /* Fill in pointer to the this adapter */
  73.    pDevTable->pAdapter[Count]= (NPADAPTERINFO) pAdapter;
  74.    /* Fill in adapter section for each linux partition... */
  75.    memcpy (pAdapter,&(pCurrentUnitRec->pSourceUnitRec->AdapterInfo),
  76.            sizeof(ADAPTERINFO)-sizeof(UNITINFO));
  77.    /* Fill in unit information for this unit... */
  78.    UnitInfo.AdapterIndex= Count;
  79.    UnitInfo.UnitHandle= (USHORT) pCurrentUnitRec;
  80.    if (pCurrentUnitRec->pUnitInfo)        /* If UnitInfo was changed */
  81.     memcpy (pAdapter->UnitInfo,
  82.             pCurrentUnitRec->pUnitInfo,
  83.             pCurrentUnitRec->UnitInfoLen);
  84.    else                        /* Else use default */
  85.     memcpy (pAdapter->UnitInfo,&UnitInfo,sizeof(UnitInfo));
  86.   }
  87.  }
  88.  PartCommandDone (pUnitRec,pIORB);
  89.  
  90. #undef pIOCFG
  91. }
  92.  
  93. /* Command to change default unit information */
  94. void PartChangeUnitInfo (NPVirtUnitRec pUnitRec, PIORB pIORB)
  95. {
  96. #define pIOUC        ((PIORB_UNIT_CONTROL) pIORB)
  97.  
  98.  pUnitRec->pUnitInfo= pIOUC->pUnitInfo;        /* Store ptr to new UnitInfo */
  99.  pUnitRec->UnitInfoLen= pIOUC->UnitInfoLen;
  100.  PartCommandDone (pUnitRec,pIORB);
  101.  
  102. #undef pIOUC
  103. }
  104.  
  105. /* Command to return the geometry of the virtual unit */
  106. void PartGetGeometry (NPVirtUnitRec pUnitRec, PIORB pIORB)
  107. {
  108. #define pIOG        ((PIORB_GEOMETRY) pIORB)
  109.  
  110.  USHORT    NumHeads=    pUnitRec->pSourceUnitRec->GeoNumHeads;
  111.                         /* Num heads of base unit */
  112.  USHORT    TrackSectors=    pUnitRec->pSourceUnitRec->GeoTrackSec;
  113.                         /* Num sectors/track of base */
  114.  ULONG    SectorsPerCylinder= NumHeads*TrackSectors;
  115.  ULONG    DiskSize;
  116.  
  117.  if (pIOG->GeometryLen!=sizeof(GEOMETRY))    /* Check storage size */
  118.   IORBError(pIORB,IOERR_CMD_SYNTAX);
  119.  else
  120.  {
  121.   DiskSize= pUnitRec->NumSectors+pUnitRec->NumExtraSectors;
  122.                         /* Compute disk size needed */
  123.   pIOG->pGeometry->BytesPerSector= SECTOR_SIZE;    /* Fill in sector size */
  124.   pIOG->pGeometry->NumHeads= NumHeads;        /* Fill in geometry info... */
  125.   pIOG->pGeometry->SectorsPerTrack= TrackSectors;
  126.   pIOG->pGeometry->TotalCylinders= ((DiskSize-1)/SectorsPerCylinder)+1;
  127.                         /* Compute num cylinders */
  128.   pIOG->pGeometry->TotalSectors= pIOG->pGeometry->NumHeads*
  129.                                  pIOG->pGeometry->TotalCylinders*
  130.                                  pIOG->pGeometry->SectorsPerTrack;
  131.  }
  132.  PartCommandDone (pUnitRec,pIORB);
  133.  
  134. #undef pIOG
  135. }
  136.  
  137. /* Command to execute IO related IORBs. */
  138. void PartDoIO (NPVirtUnitRec pUnitRec, PIORB pIORB)
  139. {
  140. #define pIOXIO        ((PIORB_EXECUTEIO) pIORB)
  141.  
  142.  ULONG    SectorCount;
  143.  USHORT    Result;
  144.  
  145.  /* Check write permission flag for write operations... */
  146.  if ((!(pUnitRec->Hdr.Flags&F_ALLOW_WRITE))&&
  147.      ((pIORB->CommandModifier==IOCM_WRITE)||
  148.       (pIORB->CommandModifier==IOCM_WRITE_VERIFY)))
  149.  {
  150.   IORBError(pIORB,IOERR_MEDIA_WRITE_PROTECT);
  151.   PartCommandDone (pUnitRec,pIORB);
  152.   return;
  153.  }
  154.  
  155. /*BREAK*/
  156.  
  157.  /* Do IO on virtual sectors... */
  158.  for (SectorCount= pIOXIO->RBA;
  159.       (SectorCount<pUnitRec->NumVirtualSectors)&&
  160.       ((SectorCount-pIOXIO->RBA)<pIOXIO->BlockCount);
  161.       SectorCount++)
  162.  {
  163.   Result= DoVirtualIO (pIORB->CommandModifier,pUnitRec,SectorCount,
  164.                        pIOXIO->pSGList,pIOXIO->cSGList,
  165.                        (SectorCount-pIOXIO->RBA)*SECTOR_SIZE);
  166.   if (Result)
  167.   {
  168.    IORBError(pIORB,Result);
  169.    PartCommandDone (pUnitRec,pIORB);
  170.    return;  
  171.   }
  172.   pIOXIO->BlocksXferred++;            /* Increase num transerfered */
  173.  }
  174.  
  175.  /* 'Transfer' left-over sectors between the end of the partition and unit */
  176.  if ((pIOXIO->RBA+pIOXIO->BlockCount)>
  177.      (pUnitRec->NumSectors+pUnitRec->NumExtraSectors))
  178.  {                        /* Just increase xfer count */
  179.   BREAK
  180.   if (pIOXIO->RBA>(pUnitRec->NumSectors+pUnitRec->NumExtraSectors))
  181.    pIOXIO->BlocksXferred= pIOXIO->BlockCount;    /* Doesn't for for partitions */
  182.                         /* with less than the number */
  183.                         /* of virtual sectors... ! */
  184.   else
  185.    pIOXIO->BlocksXferred+= (pIOXIO->RBA+pIOXIO->BlockCount)-
  186.                           (pUnitRec->NumSectors+pUnitRec->NumExtraSectors);
  187.  }
  188.  
  189.  /* If we need some real sectors, call original driver, else done... */
  190.  if ((pIOXIO->RBA+pIOXIO->BlockCount)>pUnitRec->NumVirtualSectors)
  191.   PartFilterIORB (pUnitRec,pIORB);        /* Call driver */
  192.  else
  193.   PartCommandDone (pUnitRec,pIORB);        /* Done! */
  194.  
  195. #undef pIOXIO
  196. }
  197.  
  198. /* Command to get unit status: simply send request to original driver. */
  199. void PartGetUnitStatus (NPVirtUnitRec pUnitRec, PIORB pIORB)
  200. {
  201.  PartFilterIORB (pUnitRec,pIORB);
  202. }
  203.