Exemplo n.º 1
0
        /// <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);
        }