/// <summary> /// This method discover the current ATA device and try to read all its configurations /// </summary> private void Discover() { mDevice = Device.IDE_None; mBufferSize = 0; Status xStatus; bool Error = false; // Select Drive SelectDrive(); // Send Identify command PortIO.Out8(CommandReg, (byte)Cmd.ATA_CMD_IDENTIFY); Wait(); if (PortIO.In8(StatusReg) == 0) { return; // No Device } while (true) { xStatus = (Status)PortIO.In8(StatusReg); if ((xStatus & Status.ATA_SR_ERR) != 0) { Error = true; // If Err, Device is not ATA. break; } if (((xStatus & Status.ATA_SR_BSY) == 0) && ((xStatus & Status.ATA_SR_DRQ) != 0)) { break; // Everything is fine } Wait(); } mDevice = Device.IDE_ATA; mBufferSize = 512; // (IV) Probe for ATAPI Devices: if (Error) { ushort xTypeID = (ushort)(PortIO.In8(LBA2) << 8 | PortIO.In8(LBA1)); if (xTypeID == 0xEB14 || xTypeID == 0x9669) { mDevice = Device.IDE_ATAPI; mBufferSize = 2048; mATAPI_Packet = new byte[12]; } else { mDevice = Device.IDE_None; mBufferSize = 0; return; } // Send Identify packet command PortIO.Out8(CommandReg, (byte)Cmd.ATA_CMD_IDENTIFY_PACKET); Wait(); } var xBuff = new ushort[256]; PortIO.Read16(DataReg, xBuff); // ATA/ATAPI COnfig mIsRemovable = (xBuff[(int)Identify.ATA_IDENT_DEVICETYPE] & (1 << 7)) > 0; // CHS configurations mCylinder = xBuff.ToUInt32((int)Identify.ATA_IDENT_CYLINDERS); mHeads = xBuff.ToUInt32((int)Identify.ATA_IDENT_HEADS); mSectorsPerTrack = xBuff.ToUInt32((int)Identify.ATA_IDENT_SECTORS); mCommandSet = xBuff.ToUInt32((int)Identify.ATA_IDENT_COMMANDSETS); ushort xFieldValid = xBuff[(int)Identify.ATA_IDENT_FIELDVALID]; // 1st bit determine weather it support LBA or not mLBASupport = (bool)((xFieldValid & 1) == 1); if ((mCommandSet & (1 << 26)) != 0) { // Device uses 48-Bit Addressing: throw new Exception("48bit addresssing not supported"); } //mSize = xBuff.ToUInt48((int)Identify.ATA_IDENT_MAX_LBA_EXT); else { // Device uses CHS or 28-bit Addressing: mSize = xBuff.ToUInt32((int)Identify.ATA_IDENT_MAX_LBA); } // Read Model, Firmware, SerialNo. mModel = xBuff.GetString((int)Identify.ATA_IDENT_MODEL, 40); mSerialNo = xBuff.GetString((int)Identify.ATA_IDENT_SERIAL, 20); }