/// <summary> /// Performs the LBA28. /// </summary> /// <param name="operation">The operation.</param> /// <param name="drive">The drive NBR.</param> /// <param name="lba">The lba.</param> /// <param name="data">The data.</param> /// <param name="offset">The offset.</param> /// <returns></returns> protected bool PerformLBA28(SectorOperation operation, uint drive, uint lba, byte[] data, uint offset) { if (drive > MaximunDriveCount) { return(false); } FeaturePort.Write8(0); SectorCountPort.Write8(1); LBALowPort.Write8((byte)(lba & 0xFF)); LBAMidPort.Write8((byte)((lba >> 8) & 0xFF)); LBAHighPort.Write8((byte)((lba >> 16) & 0xFF)); DeviceHeadPort.Write8((byte)(0xE0 | (drive << 4) | ((lba >> 24) & 0x0F))); if (operation == SectorOperation.Write) { CommandPort.Write8(IDECommands.WriteSectorsWithRetry); } else { CommandPort.Write8(IDECommands.ReadSectorsWithRetry); } if (!WaitForRegisterReady()) { return(false); } DataBlock sector = new DataBlock(data); //TODO: Don't use PIO if (operation == SectorOperation.Read) { for (uint index = 0; index < 256; index++) { sector.SetUShort(offset + (index * 2), DataPort.Read16()); } } else { for (uint index = 0; index < 256; index++) { DataPort.Write16(sector.GetUShort(offset + (index * 2))); } } return(true); }
private void DoIdentifyDrive(byte index) { //HAL.DebugWriteLine("Device " + index.ToString() + " ID..."); driveInfo[index].Present = false; //Send the identify command to the selected drive DeviceHeadPort.Write8((byte)((index == 0) ? 0xA0 : 0xB0)); SectorCountPort.Write8(0); LBALowPort.Write8(0); LBAMidPort.Write8(0); LBAHighPort.Write8(0); CommandPort.Write8(IDECommand.IdentifyDrive); if (StatusPort.Read8() == 0) { //HAL.DebugWriteLine("Device " + index.ToString() + " doesnt exist..."); //Drive doesn't exist return; } //Wait until a ready status is present if (!WaitForReadyStatus()) { return; //There's no ready status, this drive doesn't exist } if (LBAMidPort.Read8() != 0 && LBAHighPort.Read8() != 0) //Check if the drive is ATA { //In this case the drive is ATAPI, which is not supported //HAL.DebugWriteLine("Device " + index.ToString() + " not ATA"); return; } //Wait until the identify data is present (256x16 bits) if (!WaitForIdentifyData()) { //HAL.DebugWriteLine("Device " + index.ToString() + " ID error"); return; } //Read the identification info var info = new DataBlock(512); for (uint ix = 0; ix < 256; ix++) { info.SetUShort(ix * 2, DataPort.Read16()); } //Find the addressing mode bool lba48Supported = ((info.GetUShort(IdentifyDrive.CommandSetSupported83) & 0x200) == 0x200); driveInfo[index].AddressingMode = (lba48Supported ? AddressingMode.LBA48 : AddressingMode.LBA28); //Find the max LBA count uint lba28SectorCount = info.GetUInt(IdentifyDrive.MaxLBA28); ulong lba48SectorCount = info.GetULong(IdentifyDrive.MaxLBA48); //HAL.DebugWriteLine("LBA48BIT=" + lba48Supported.ToString()); //HAL.DebugWriteLine("LBA28 =" + lba28SectorCount.ToString("X2")); if (!lba48Supported) //No LBA48 { driveInfo[index].MaxLBA = lba28SectorCount; } else //LBA48 supported { if (lba28SectorCount == 0x0FFFFFFF) //Check the limit according to the d1699r3f-ata8-acs.pdf (4.10.4 IDENTIFY DEVICE data) { driveInfo[index].MaxLBA = (uint)lba48SectorCount; } else { driveInfo[index].MaxLBA = lba28SectorCount; } } //An ATA drive is present and ready to use driveInfo[index].Present = true; //HAL.DebugWriteLine("Device " + index.ToString() + " present - MaxLBA=" + driveInfo[index].MaxLBA.ToString()); }
private void DoIdentifyDrive(byte index) { driveInfo[index].Present = false; //Send the identify command to the selected drive DeviceHeadPort.Write8((byte)((index == 0) ? 0xA0 : 0xB0)); SectorCountPort.Write8(0); LBALowPort.Write8(0); LBAMidPort.Write8(0); LBAHighPort.Write8(0); CommandPort.Write8(IDECommand.IdentifyDrive); if (StatusPort.Read8() == 0) { //Drive doesn't exist return; } //Wait until a ready status is present if (!WaitForReadyStatus()) { return; //There's no ready status, this drive doesn't exist } if (LBAMidPort.Read8() != 0 && LBAHighPort.Read8() != 0) //Check if the drive is ATA { //In this case the drive is ATAPI //HAL.DebugWriteLine("Device " + index.ToString() + " not ATA"); return; } //Wait until the identify data is present (256x16 bits) if (!WaitForIdentifyData()) { //HAL.DebugWriteLine("Device " + index.ToString() + " ID error"); return; } //An ATA drive is present driveInfo[index].Present = true; //Read the identification info var info = new DataBlock(512); for (uint ix = 0; ix < 256; ix++) { info.SetUShort(ix * 2, DataPort.Read16()); } //Find the addressing mode var lba28SectorCount = info.GetUInt(IdentifyDrive.MaxLBA28); AddressingMode aMode = AddressingMode.NotSupported; if ((info.GetUShort(IdentifyDrive.CommandSetSupported83) & 0x200) == 0x200) //Check the LBA48 support bit { aMode = AddressingMode.LBA48; driveInfo[index].MaxLBA = info.GetUInt(IdentifyDrive.MaxLBA48); } else if (lba28SectorCount > 0) //LBA48 not supported, check LBA28 { aMode = AddressingMode.LBA28; driveInfo[index].MaxLBA = lba28SectorCount; } driveInfo[index].AddressingMode = aMode; //HAL.DebugWriteLine("Device " + index.ToString() + " present - MaxLBA=" + driveInfo[index].MaxLBA.ToString()); }