Esempio n. 1
0
        /// <summary>
        /// This method discover the current ATA device and try to read all its configurations
        /// </summary>
        private void Discover()
        {
            DriveInfo.Device     = Device.IDE_None;
            DriveInfo.BufferSize = 0;

            Status xStatus;
            bool   Error = false;

            //Select Drive
            SelectDrive();

            //Send Identify command
            CommandReg.Byte = (byte)Cmd.ATA_CMD_IDENTIFY;
            Wait();

            if (StatusReg.Byte == 0)
            {
                return; //No Device
            }
            while (true)
            {
                xStatus = (Status)StatusReg.Byte;
                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();
            }

            DriveInfo.Device     = Device.IDE_ATA;
            DriveInfo.BufferSize = 512;

            // (IV) Probe for ATAPI Devices:
            if (Error)
            {
                ushort xTypeID = (ushort)(LBA2.Byte << 8 | LBA1.Byte);
                if (xTypeID == 0xEB14 || xTypeID == 0x9669)
                {
                    DriveInfo.Device     = Device.IDE_ATAPI;
                    DriveInfo.BufferSize = 2048;
                }
                else
                {
                    DriveInfo.Device     = Device.IDE_None;
                    DriveInfo.BufferSize = 0;
                    return;
                }

                //Send Identify packet command
                CommandReg.Byte = (byte)Cmd.ATA_CMD_IDENTIFY_PACKET;
                Wait();
            }

            var xBuff = new ushort[256];

            DataReg.Read16(xBuff);

            //ATA/ATAPI COnfig
            DriveInfo.IsRemovable = (xBuff[(int)Identify.ATA_IDENT_DEVICETYPE] & (1 << 7)) > 0;

            //CHS configurations
            DriveInfo.Cylinder        = xBuff.ToUInt32((int)Identify.ATA_IDENT_CYLINDERS);
            DriveInfo.Heads           = xBuff.ToUInt32((int)Identify.ATA_IDENT_HEADS);
            DriveInfo.SectorsPerTrack = xBuff.ToUInt32((int)Identify.ATA_IDENT_SECTORS);
            DriveInfo.CommandSet      = xBuff.ToUInt32((int)Identify.ATA_IDENT_COMMANDSETS);

            ushort xFieldValid = xBuff[(int)Identify.ATA_IDENT_FIELDVALID];

            //1st bit determine weather it support LBA or not
            DriveInfo.LBASupport = (bool)((xFieldValid & 1) == 1);

            if ((DriveInfo.CommandSet & (1 << 26)) != 0)
            {
                // Device uses 48-Bit Addressing:
                DriveInfo.Size = xBuff.ToUInt48((int)Identify.ATA_IDENT_MAX_LBA_EXT);
            }
            else
            {
                // Device uses CHS or 28-bit Addressing:
                DriveInfo.Size = xBuff.ToUInt32((int)Identify.ATA_IDENT_MAX_LBA);
            }

            //Read Model, Firmware, SerialNo.
            DriveInfo.Model    = xBuff.GetString((int)Identify.ATA_IDENT_MODEL, 40);
            DriveInfo.SerialNo = xBuff.GetString((int)Identify.ATA_IDENT_SERIAL, 20);
        }