📄 diskmain.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
#include <atamain.h>
static HANDLE g_hTestUnitReadyThread = NULL;
/*------------------------------------------------------------------------------------------*/
BOOL CDisk::Init(HKEY hActiveKey)
{
DWORD dwOption = 0;
BOOL bEnableInterrupts = FALSE;
BOOL bRet = TRUE;
//
// Read in the registry settings first.
//
dwOption = 0;
if (AtaGetRegistryValue(m_hDevKey, REG_VALUE_DMAENABLE, &dwOption) && (dwOption == 1))
{
m_fDMAActive = TRUE;
}
dwOption = 0;
if (AtaGetRegistryValue(m_hDevKey, REG_VALUE_UDMAENABLE, &dwOption) && (dwOption == 1))
{
m_fUDMAActive = TRUE;
}
dwOption = 0;
if (AtaGetRegistryValue(m_hDevKey, REG_VALUE_MDMA_MODE, &dwOption) )
{
m_ulBestMwDmaModeReg = dwOption;
}
dwOption = 0;
if (AtaGetRegistryValue(m_hDevKey, REG_VALUE_UDMA_MODE, &dwOption) )
{
m_ulBestUDmaModeReg = dwOption;
}
dwOption = 0;
if (AtaGetRegistryValue(m_hDevKey, REG_VALUE_DVD, &dwOption) && (dwOption == 1))
{
m_dwDeviceFlags |= DFLAGS_DEVICE_ISDVD;
}
TakeCS();
if (m_dwDeviceFlags & DFLAGS_DEVICE_INITIALIZED) {
DEBUGMSG( ZONE_INIT, (TEXT("ATAPI:ResetController Skipped - Device !!!\r\n")));
} else {
SelectDevice();
if (!(bRet = ResetController(FALSE)))
{
if (!(bRet = ResetController(TRUE))) {
DEBUGMSG( ZONE_INIT, (TEXT("ATAPI:AtaInitDevice: ResetController failed!!")));
ReleaseCS();
goto Exit;
}
}
WaitOnBusy(TRUE);
bEnableInterrupts = TRUE;
m_dwDeviceFlags |= DFLAGS_DEVICE_INITIALIZED;
}
ReleaseCS();
//
// Issue Identify Command and process received data.
//
if (!(bRet = Identify())) {
DEBUGMSG( ZONE_INIT, (TEXT("ATAPI:Identify Command failed !!!\r\n")));
goto Exit;
}
if (bEnableInterrupts)
{
// Enable interrupts
SelectDevice();
WriteDriveController( ATA_CTRL_ENABLE_INTR);
SelectDevice();
WriteAltDriveController(ATA_CTRL_ENABLE_INTR);
EnableInterrupt();
}
#if 0
if (IsAtapiDevice()) {
DEBUGMSG( ZONE_INIT, (TEXT("ATAPI:Atapi Device ...performing soft reset !\r\n")));
AtapiSoftReset();
}
#endif
// Get MediaCheckTime if it is removable device.
if (IsRemoveableDevice()) {
if (!AtaGetRegistryValue(m_hDevKey, REG_VALUE_MEDIACHECKTIME, &m_dwUnitReadyTime)) {
m_dwUnitReadyTime = DEFAULT_MEDIA_CHECK_TIME;
DEBUGMSG( ZONE_INIT, (TEXT("ATAPI:ConfigureDisk MediaCheckTime using default value of %ld\r\n"), m_dwUnitReadyTime));
}
}
DEBUGMSG(ZONE_INIT, (TEXT("ATAPI:Init Device Ready!!!( DevceId; %x )\r\n"), m_dwDeviceId));
//dwOption = 0;
//if (AtaGetRegistryValue(m_hDevKey, REG_VALUE_SETTINGS, &dwOption))
//{
// if (IsAtapiDevice())
// {
// if (dwOption & ATA_SETTINGS_CDDMA)
// {
// m_fDMAActive = TRUE;
// }
// else
// {
// m_fDMAActive = FALSE;
// }
// }
// else
// {
// if (dwOption & ATA_SETTINGS_HDDMA)
// {
// m_fDMAActive = TRUE;
// }
// else
// {
// m_fDMAActive = FALSE;
// }
// }
// }
Exit:
return bRet;
}
/*------------------------------------------------------------------------------------------*/
BOOL CDisk::ResetController(BOOL bSoftReset)
{
DWORD dwAttempts;
BYTE bStatus;
DEBUGMSG(ZONE_INIT, (TEXT("ATAPI:ResetController entered\r\n")));
// WriteAltDriveController( 0x8);
// Read the status first
bStatus = GetBaseStatus();
// DEBUGMSG(ZONE_INIT, (TEXT("ATADISK:ResetController - ATA_STATUS = %02X Error=%x!\r\n"), bStatus, GetError()));
//
// We select the secondary device , that way we will get a response through the shadow
// if only the master is connected. Otherwise we will get a response from
// the secondary device
//
WriteAltDriveController(ATA_CTRL_RESET | ATA_CTRL_DISABLE_INTR);
WaitForDisc( WAIT_TYPE_BUSY, 500);
WriteAltDriveController(ATA_CTRL_DISABLE_INTR);
WaitForDisc( WAIT_TYPE_READY, 400);
if (bSoftReset) {
DEBUGMSG( ZONE_INIT, (TEXT("ATAPI:ResetController ...performing soft reset !\r\n")));
AtapiSoftReset();
} else {
StallExecution(5000);
}
for (dwAttempts = 0; dwAttempts < MAX_RESET_ATTEMPTS; dwAttempts++)
{
bStatus = GetBaseStatus();
if ((bStatus != ATA_STATUS_IDLE) && (bStatus != 0x0))
{
DEBUGMSG( ZONE_INIT, (TEXT("ATAPI::ResetController: Current drive status = 0x%2.2X\r\n"), bStatus));
if (bStatus == 0xFF)
{
SetDriveHead( ATA_HEAD_DRIVE_2);
bStatus = GetBaseStatus();
if ((bStatus != ATA_STATUS_IDLE) && (bStatus != 0x0))
{
DEBUGMSG(ZONE_INIT, (TEXT("ATAPI::ResetController Drive 2 status = 0x%2.2X\r\n"), bStatus));
if (bStatus == 0xFF)
{
DEBUGMSG(ZONE_INIT, (TEXT("ATAPI::ResetController no second device\r\n")));
return FALSE;
}
}
else
{
break;
}
}
StallExecution(5000);
} else {
break;
}
}
if (dwAttempts == MAX_RESET_ATTEMPTS)
{
DEBUGMSG( ZONE_INIT, (TEXT("ATAPIPCI:AtaResetController no response after %ld reset attempts\r\n"), MAX_RESET_ATTEMPTS));
return FALSE;
}
DEBUGMSG( ZONE_INIT, (TEXT("ATAPI:ResetController: Controller reset done\r\n")));
return TRUE;
}
/*------------------------------------------------------------------------------------------*/
BOOL CDisk::Identify()
{
DWORD dwBlockSize;
WORD wDevType;
TakeCS();
WaitOnBusy(FALSE);
SelectDevice();
WriteCommand(ATA_CMD_IDENTIFY);
if (WaitOnBusy(FALSE) & ATA_STATUS_ERROR)
{
// Not ATA Device. Try ATAPI !!!.
if (GetError() & ATA_ERROR_ABORTED)
{
//
// Try ATAPI!!
//
SelectDevice();
WriteCommand(ATAPI_CMD_IDENTIFY);
if (WaitOnBusy(FALSE) & ATA_STATUS_ERROR)
{
DEBUGMSG( ZONE_ERROR, (TEXT("ATAPI:Identify failed (Device: %x)\r\n"),m_dwDeviceId));
ReleaseCS();
return(FALSE);
}
}
m_fAtapiDevice = TRUE;
}
dwBlockSize = sizeof(IDENTIFY_DATA);
ASSERT( dwBlockSize <= BYTES_PER_SECTOR);
if (m_f16Bit) {
dwBlockSize /= 2;
ReadWordBuffer( (PWORD)&m_Id, dwBlockSize);
} else {
ReadByteBuffer( (PBYTE)&m_Id, dwBlockSize);
}
//
// Read the rest of data if available !!! And throw it away !!!
//
while (GetAltStatus() & ATA_STATUS_DATA_REQ ) {
if (m_f16Bit)
ReadWord();
else
ReadByte();
}
ReleaseCS(); //
ATAPRINTIDENTIFY(&m_Id); // Macro'd out for debug
if ((m_Id.GeneralConfiguration == 0) ||
(m_Id.GeneralConfiguration == 0xffff)||
(m_Id.GeneralConfiguration == 0xff7f)||
(m_Id.GeneralConfiguration == 0x7fff)||
((m_Id.GeneralConfiguration == m_Id.IntegrityWord) && (m_Id.NumberOfCurrentCylinders == m_Id.IntegrityWord)))
{
DEBUGMSG( ZONE_INIT | ZONE_ERROR, (TEXT("ATAPI:Identify General Configuration %04X is not valid !!!\r\n"), m_Id.GeneralConfiguration));
return (FALSE);
}
//
// Convert ATA Configuration to the ATAPI Configuration.
// Clear ATAPI Device Bit (8).
if (!m_fAtapiDevice)
{
m_Id.GeneralConfiguration &= ~IDE_IDDATA_REMOVABLE;
}
wDevType = (m_Id.GeneralConfiguration>>8) & 0x1F;
DEBUGMSG(ZONE_INIT, (TEXT("ATAPI:Identify DevId (%x ) wDevType (%x) \r\n"), m_dwDeviceId, wDevType));
if (wDevType == ATA_IDDEVICE_UNKNOWN) // Unknown Type or no device type
return(FALSE); // Or Device not present!!!
if (!((wDevType == ATA_IDDEVICE_DISK) || // Direct Access Device
(wDevType == ATA_IDDEVICE_CDROM) || // CD-ROM
(wDevType == ATA_IDDEVICE_OPTICAL_MEM))) // Optical Memory
{
DEBUGMSG(ZONE_INIT, (TEXT("ATAPI:Identify Not a supported device ???\r\n")));
#if 0
return (FALSE);
#else
DEBUGMSG(ZONE_INIT, (TEXT("ATAPI:Identify Assuming hard disk device\r\n")));
#endif
}
if (wDevType == ATA_IDDEVICE_CDROM) // CD-ROM
{
DEBUGMSG( ZONE_INIT, (TEXT("ATAPI:Identify CD-ROM Device\r\n")));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -