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.");
}
}
}
}