public BusMasterDma(IdeConfig !ideConfig) { ideConfigHandle = ideConfig; // Set up BusMaster ports for this controller // <command, status, PRD table> commandPort = ideConfig.DmaBase.PortAtOffset(0, 1, Access.ReadWrite); statusPort = ideConfig.DmaBase.PortAtOffset(2, 1, Access.ReadWrite); prdPort = ideConfig.DmaBase.PortAtOffset(4, 4, Access.ReadWrite); // PRD needs to be 4-byte aligned and within one 4k page. prdRegion = IoMemory.AllocatePhysical(PRD_MAX_ENTRIES * PRD_BYTES_PER_ENTRY, PRD_ALIGNMENT); } // BusMasterInitialize
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); }