using System; using System.Collections.Generic; namespace Cosmos.HAL.BlockDevice { // This class should not support selecting a device or sub device. // Each instance must control exactly one device. For example with ATA // master/slave, each one needs its own device instance. For ATA // this complicates things a bit because they share IO ports, but this // is an intentional decision. /// /// BlockDevice abstract class. See also: . /// public abstract class BlockDevice : Device { // TODO: Need to protect this from changes except by Hardware ring /// /// Devices list. /// static public List Devices = new List(); /// /// Create new block array. /// /// Number of blocks to alloc. /// byte array. public byte[] NewBlockArray(UInt32 aBlockCount) { return new byte[aBlockCount * mBlockSize]; } /// /// Block count. /// protected UInt64 mBlockCount = 0; /// /// Get block count. /// public UInt64 BlockCount => mBlockCount; /// /// Block size. /// protected UInt64 mBlockSize = 0; /// /// Get block size. /// public UInt64 BlockSize => mBlockSize; // Only allow reading and writing whole blocks because many of the hardware // command work that way and we dont want to add complexity at the BlockDevice level. // public abstract void ReadBlock(UInt64 aBlockNo, UInt32 aBlockCount, byte[] aData); /// /// Read block from partition. /// /// A block to read from. /// A number of blocks in the partition. /// A data that been read. /// Thrown when data lenght is greater then Int32.MaxValue. /// Thrown when data size invalid. public abstract void ReadBlock(UInt64 aBlockNo, UInt64 aBlockCount, ref byte[] aData); /// /// Write block to partition. /// /// A block number to write to. /// A number of blocks in the partition. /// A data to write. /// Thrown when data lenght is greater then Int32.MaxValue. /// Thrown when data size invalid. public abstract void WriteBlock(UInt64 aBlockNo, UInt64 aBlockCount, ref byte[] aData); /// /// Check data size. /// /// A data to check the size of. /// Number of blocks used to store the data. /// Thrown when data lenght is greater then Int32.MaxValue. /// Thrown when data size invalid. protected void CheckDataSize(byte[] aData, UInt64 aBlockCount) { if ((ulong)aData.Length != aBlockCount * mBlockSize) { throw new Exception("Invalid data size."); } } /// /// Check block number. /// Not implemented. /// /// A block number to be checked. /// A block count. protected void CheckBlockNo(UInt64 aBlockNo, UInt64 aBlockCount) { if (aBlockNo + aBlockCount >= mBlockCount) { //throw new Exception("Invalid block number."); } } } }