home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 10 / mycd10.iso / share / os2 / utilidad / ext2fl / e2iocmd.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-07-31  |  8.0 KB  |  214 lines

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