Exemple #1
0
        IdentifyDeviceInformation GetDeviceIdentification(IdeController !controller,
                                                          int devsel, bool atapi)
        {
            ushort[] identifyData = new ushort[256];

            if (!controller.PollBSY(false))
            {
                // should fail here.
            }
            controller.SelectDevice(devsel, atapi);

            //DebugStub.Print(" IDE GetDeviceIdentification starting\n");
            bool iflag = PrivilegedGate.DisableInterrupts();

            try {
                controller.SetIdentifyInProgress(true);
                controller.PollDRDY(true);
                byte cmd = (atapi)? (byte)IdeCommand.IdentifyPacketDevice:
                           (byte)IdeCommand.IdentifyDevice;
                controller.WriteCommandPort(cmd); //will post interrupt
                controller.Delay400ns();
                Tracing.Log(Tracing.Debug, "status={0}", (UIntPtr)controller.ReadFullStatus());
                controller.PollDRDY(true); // Device indicates ready.
            }
            finally {
                PrivilegedGate.RestoreInterrupts(iflag);
            }

            IdeConfig config  = controller.GetConfig();
            bool      success = (config != null) && config.IdentifyEndEvent.WaitOne(TimeSpan.FromMilliseconds(250));

            if (!success)
            {
                //DebugStub.Break();
                Tracing.Log(Tracing.Debug, " IDE GetDeviceIdentification did NOT receive  interrupt\n");
                controller.SetIdentifyInProgress(false);
            }

            //DebugStub.Print(" IDE GetDeviceIdentification received interrupt\n");

            // XXX: We should check for an Error condition here.
            // XXX: We should check for the ATAPI signature here.

            byte statusBits = controller.ReadAlternateStatusPort();

            if ((statusBits & (byte)ATA6.IdeStatus.ERR) > 0)
            {
                Tracing.Log(Tracing.Debug, "ERR reported in status after IdentifyDevice!\n");
                DebugStub.Break();
            }

            for (int i = 0; i < 256; i++)
            {
                identifyData[i] = controller.ReadDataPort();
            }

            IdentifyDeviceInformation ident = ParseIdentifyInformation(identifyData);

////        if (atapi)
            if (ident.ModelNumber == "Virtual CD") // SECTOR_SIZE is actually 2048
            {
                ident.MaxLBASectors = 650 * 1024 * 1024 / IdeRequest.SECTOR_SIZE;
            }
            // for IdeDisk::ReadWrite tests
            return(ident);
        }
Exemple #2
0
        //public static uint    MAX_SUPPORTED_SECTORS = 2048 * 128;
        //public static uint    MAX_SUPPORTED_SECTORS = 16383 * 16 * 63;

        public static IdentifyDeviceInformation ParseIdentifyInformation(ushort[] !DriveData)
        {
            IdentifyDeviceInformation temp = new IdentifyDeviceInformation();

            temp.RemovableMediaDevice = (DriveData[0] & (1 << 7)) > 0;
            temp.CylinderCount        = DriveData[1];
            temp.HeadCount            = DriveData[3];
            temp.SectorCountPerTrack  = DriveData[6];
            temp.SerialNumber         = WordsToString(DriveData, 10, 19);
            temp.NumberOfBytesAvailInVendorCommand = DriveData[22];
            temp.FirmwareRevision = WordsToString(DriveData, 23, 26);
            temp.ModelNumber      = WordsToString(DriveData, 27, 46);
            if ((DriveData[47] & (0xFF)) == 0)
            {
                temp.SupportsMultiple = false;
            }
            else
            {
                temp.SupportsMultiple           = true;
                temp.MaximumMultipleSectorCount = (ushort)(DriveData[47] & 0xFF);
            }

            temp.StandbyTimer     = ((DriveData[49] & (1 << 13))) > 0;
            temp.IORDYSupported   = ((DriveData[49] & (1 << 11))) > 0;
            temp.IORDYDisableable = ((DriveData[49] & (1 << 10))) > 0;
            temp.LBASupported     = ((DriveData[49] & (1 << 9))) > 0;
            temp.DMASupported     = ((DriveData[49] & (1 << 8))) > 0;
            //UltraDMA supported
            temp.Word88Valid       = ((DriveData[53] & (1 << 2))) > 0;
            temp.UltraDmaSupported = temp.Word88Valid;
            //this bit should always be true unless device is CFA or PCMCIA
            temp.Words64to70Valid = ((DriveData[53] & (1 << 1))) > 0;
            //obsolete
            temp.Words54to58Valid = ((DriveData[53] & (1 << 0))) > 0;

            // word 59:  multiple sector setting
            temp.MultipleSectorSettingValid     = (DriveData[59] & (1 << 8)) > 0;
            temp.CurrentSectorCountPerInterrupt = (ushort)(DriveData[59] & 0xFF);

            // words 60,61: Total # of addressable sectors (+1)
            temp.TotalAddressableSectors = ((uint)DriveData[61] << 16) | (uint)DriveData[60];
#if obsolete
            if (temp.TotalAddressableSectors > MAX_SUPPORTED_SECTORS)
            {
                temp.TotalAddressableSectors = MAX_SUPPORTED_SECTORS;
            }
#endif
            // word 63:  should be 0 if UltraDMA is supported
            // bit 10: MDMA mode 2 selected
            // bit 09: MDMA mode 1 selected
            // bit 08: MDMA mode 0 selected

            // bit 02: MDMA mode 2 supported
            // bit 01: MDMA mode 1 supported
            // bit 00: MDMA mode 0 supported

            temp.MultiwordDMATransferMode  = (ushort)((DriveData[63] & 0xFF00) >> 8);
            temp.MultiwordDMATransferModes = (ushort)(DriveData[63] & 0xFF);

            temp.PIODMATransferModes                = (ushort)(DriveData[64] & 0xFF);
            temp.MinimumMultiwordDMACycleTime       = DriveData[65];
            temp.RecommendedMultiwordDMACycleTime   = DriveData[66];
            temp.MinimumPIOCycleTimeWithFlowControl = DriveData[67];
            temp.MinimumPIOCycleTimeWithIORDY       = DriveData[68];

            // value == maximum queue depth -1  (max = 31 +1)
            temp.QueueDepth = (ushort)(DriveData[75] & 0x1F);

            temp.MajorVersion = DriveData[80];
            temp.MinorVersion = DriveData[81];

            //Feature sets
            temp.FeatureSet1Supported = DriveData[82];
            temp.FeatureSet2Supported = DriveData[83];
            temp.FeatureSet3Supported = DriveData[84];
            temp.FeatureSet1Enabled   = DriveData[85];
            temp.FeatureSet2Enabled   = DriveData[86];
            temp.FeatureSet3Enabled   = DriveData[87];

            temp.LBA48Supported = ((DriveData[83] & (1 << 10))) > 0;
            temp.LBA48Enabled   = ((DriveData[86] & (1 << 10))) > 0;

            temp.QueuedDMASupported = ((DriveData[83] & (1 << 1))) > 0;
            temp.QueuedDMAEnabled   = ((DriveData[86] & (1 << 1))) > 0;

            if (temp.UltraDmaSupported)
            {
                temp.UltraDmaModes       = DriveData[88];
                temp.HighestUltraDmaMode =
                    (byte)(HighestBitSet((ushort)(temp.UltraDmaModes & 0x3f)) - (byte)1);
            }

            if (temp.LBA48Supported)
            {
                temp.MaxLBASectors = ((ulong)DriveData[103] << 48)
                                     | ((ulong)DriveData[102] << 32)
                                     | ((ulong)DriveData[101] << 16)
                                     | (ulong)DriveData[100];
                DebugStub.WriteLine("Disk Device supports LBA 48\n");
                DebugStub.WriteLine("Total LBA sectors ={0}", __arglist(temp.MaxLBASectors));
                //controller.WriteCommandPort( (byte) ATA6.IdeCommand.ReadNativeMaxAddressExt);
                //controller.Delay400ns();
                //DebugStub.WriteLine("ReadNativeMaxAddressExt:");
                //ShowOffsetAndCount();
            }
            else
            {
                temp.MaxLBASectors = temp.TotalAddressableSectors;
            }

            if (temp.UltraDmaSupported)
            {
                DebugStub.WriteLine("Disk Device supports Ultra DMA modes={0:x4},highest={1}",
                                    __arglist(temp.UltraDmaModes, temp.HighestUltraDmaMode));
            }

            return(temp);
        }