📄 diskmain.cpp
字号:
ReleaseCS(); //
RETAILMSG( 1, (TEXT("ATAPI:Identify VERSION %x --- %x\r\n"), m_Id.MajorVersionNumber, m_Id.MinorVersionNumber ));
//
// Byte flip model number, revision, and serial number string.
//
tempS = m_Id.ModelNumber;
for (k=0; k<20; k++) {
tempByte = (UCHAR)(tempS[k] & 0x00FF);
tempS[k] = tempS[k] >> 8;
tempS[k] |= tempByte << 8;
}
tempS = m_Id.FirmwareRevision;
for (k=0; k<4; k++) {
tempByte = (UCHAR)(tempS[k] & 0x00FF);
tempS[k] = tempS[k] >> 8;
tempS[k] |= tempByte << 8;
}
tempS = m_Id.SerialNumber;
for (k=0; k<10; k++) {
tempByte = (UCHAR)(tempS[k] & 0x00FF);
tempS[k] = tempS[k] >> 8;
tempS[k] |= tempByte << 8;
}
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")));
m_dwDeviceFlags |=DFLAGS_DEVICE_CDROM;
}
DEBUGMSG( ZONE_INIT, (TEXT("ATAPI:Identify Completed Stage 1 Status=%02X\r\n"),GetAltStatus()));
m_dwDeviceFlags |= DFLAGS_DEVICE_PRESENT;
m_dwDeviceFlags |= (IsAtapiDevice()) ? DFLAGS_ATAPI_DEVICE : 0;
m_dwDeviceFlags |= (IsRemoveableDevice()) ? DFLAGS_REMOVABLE_DRIVE : 0;
AnalyzeDeviceCapabilities();
SetBestTransferMode();
if (IsAtapiDevice())
{
// TODO:
// AtapiSetInfo();
} else
{
//
// Set Multiple Mode if ATA Device
//
m_bSectorsPerBlock= 1;
}
m_fLBAMode = (m_Id.Capabilities & 0x0200) ? TRUE : FALSE;
// m_fLBAMode = TRUE;
DWORD dwCHS = 0;
if (AtaGetRegistryValue(m_hDevKey, REG_VALUE_CHS, &dwCHS) && (dwCHS == 1))
{
m_fLBAMode = FALSE;
}
// if (!(m_Id.GeneralConfiguration & 0x8000)) {
if (!IsAtapiDevice())
{
m_bReadCommand = ATA_CMD_READ ;
m_bWriteCommand = ATA_CMD_WRITE ;
if (m_Id.MaximumBlockTransfer > 1) //some CF card with m_Id.MaximumBlockTransfer can't work if going this case
{
SelectDevice();
WriteSectorCount( (BYTE)m_Id.MaximumBlockTransfer) ;
WriteCommand(ATA_CMD_SET_MULTIPLE);
if( WaitForDisc( WAIT_TYPE_BUSY, 500, 1) )
DEBUGMSG( ZONE_INIT, (TEXT("ATADISK:Identify Can't get BUSY %x\r\n"), GetBaseStatus() ));
else
DEBUGMSG( ZONE_INIT, (TEXT("ATADISK:Identify get BUSY successfully %x \r\n"), GetBaseStatus() ));
RETAILMSG( 1, (TEXT("ATADISK:Identify Set Block %d\r\n"), m_Id.MaximumBlockTransfer ));
if (!WaitOnBusy(FALSE) && (GetAltStatus() & ATA_STATUS_READY))
{
m_bReadCommand = ATA_CMD_MULTIPLE_READ ;
m_bWriteCommand = ATA_CMD_MULTIPLE_WRITE ;
m_bSectorsPerBlock = m_Id.MaximumBlockTransfer;
}
}
DEBUGMSG( ZONE_INIT, (TEXT("ATAPI: Idenitfy - MultipleMode Set to= %ld Sectors\r\n"),m_Id.MaximumBlockTransfer));
}
m_DiskInfo.di_bytes_per_sect = BYTES_PER_SECTOR; // Start with 512, then go with SetInfo changes
if (m_Id.NumberOfCurrentCylinders)
{
m_DiskInfo.di_cylinders = m_Id.NumberOfCylinders;
}
else
{
if (!AtaGetRegistryValue(m_hDevKey, TEXT("Cylinders"), &(m_DiskInfo.di_cylinders)))
{
AtaGetRegistryValue(m_hDevKey, TEXT("Cyl"), &(m_DiskInfo.di_cylinders));
}
}
if (m_Id.NumberOfCurrentHeads)
{
m_DiskInfo.di_heads = m_Id.NumberOfCurrentHeads;
}
else
{
AtaGetRegistryValue(m_hDevKey, TEXT("Heads"), &(m_DiskInfo.di_heads));
}
if (m_Id.CurrentSectorsPerTrack)
{
m_DiskInfo.di_sectors = m_Id.CurrentSectorsPerTrack;
}
else
{
if (!AtaGetRegistryValue(m_hDevKey, TEXT("SectorsPerTrack"), &(m_DiskInfo.di_sectors)))
{
AtaGetRegistryValue(m_hDevKey, TEXT("spt"), &(m_DiskInfo.di_sectors)); // Shortcut for dev
}
}
if (m_Id.TotalUserAddressableSectors)
{
m_DiskInfo.di_total_sectors = m_Id.TotalUserAddressableSectors;
}
else
{
// m_DiskInfo.di_total_sectors= m_Id.NumberOfCylinders*m_Id.NumberOfCurrentHeads*m_Id.CurrentSectorsPerTrack;
m_DiskInfo.di_total_sectors= m_DiskInfo.di_cylinders*m_DiskInfo.di_heads*m_DiskInfo.di_sectors;
}
m_DiskInfo.di_flags = DISK_INFO_FLAG_MBR;
if (m_fLBAMode) {
ConfigLBA48(); // set m_fUseLBA48 if applicable
}
RETAILMSG( 1, (TEXT("ATAPI:Identify total sector %d\r\n"), m_DiskInfo.di_total_sectors ));
DEBUGMSG( ZONE_INIT, (TEXT("ATAPI:Identify Completed Stage 2 Status=%02X\r\n"),GetAltStatus()));
return TRUE;
}
void CDisk::ConfigLBA48(void )
{
PIDENTIFY_DATA pId = (PIDENTIFY_DATA)&m_Id;
// Word 87 (CommandSetFeatureDefault):
// bit 14 is set and bit 15 is cleared if config data
// in word 86 (CommandSetFeatureEnabled2) is valid.
// Note that this is only valid for non-ATAPI devices
if ( !IsAtapiDevice() &&
(m_Id.CommandSetFeatureDefault & (1 << 14)) &&
!(m_Id.CommandSetFeatureDefault & (1 << 15)) &&
(m_Id.CommandSetFeatureEnabled2 & (1 << 10)) )
{
DEBUGMSG(ZONE_INIT, (TEXT("Atapi!CDisk::ConfigLBA48> Device supports 48-bit LBA\r\n")));
DEBUGMSG(ZONE_INIT, (TEXT("Atapi!CDisk::ConfigLBA48> Max LBA Address = 0x%08x%08x"),
m_Id.lMaxLBAAddress[1],
m_Id.lMaxLBAAddress[0]));
m_fUseLBA48 = TRUE;
// The CE file system currently supports a maximum of 32-bit sector addresses,
if (pId->lMaxLBAAddress[1] == 0)
m_DiskInfo.di_total_sectors = pId->lMaxLBAAddress[0];
else
m_DiskInfo.di_total_sectors = 0xFFFFFFFF; // Couldn't find MAX_DWORD
ASSERT(m_Id.lMaxLBAAddress[1] <= 0x10000);
// CDisk::Identify has determined whether or not the device supports multi-sector transfers
// Update read/write command to use [READ|WRITE] [SECTORS|MULTIPLE] EXT
/* if (m_bReadCommand == ATA_CMD_READ)
{
m_bReadCommand = ATA_CMD_READ_SECTOR_EXT;
m_bWriteCommand = ATA_CMD_WRITE_SECTOR_EXT;
}
else // CDisk::Identify has determined that the devce supports multi-sector transfers
{
m_bReadCommand = ATA_CMD_READ_MULTIPLE_EXT;
m_bWriteCommand = ATA_CMD_WRITE_MULTIPLE_EXT;
}
m_bDMAReadCommand = ATA_CMD_READ_DMA_EXT;
m_bDMAWriteCommand = ATA_CMD_WRITE_DMA_EXT;
*/
}
else
{
m_fUseLBA48 = FALSE;
}
}
/*------------------------------------------------------------------------------------------*/
void CDisk::AnalyzeDeviceCapabilities ()
{
DWORD dwCycleTime;
DWORD dwXferMode;
DWORD dwBestXferMode;
DWORD dwCurrentMode;
BOOL fIoReadyEnabled;
//
// Figure out who can do DMA and who cannot
//
if (m_dwDeviceFlags & DFLAGS_DEVICE_PRESENT)
{
//
// check LBA capabilities
//
//CLRMASK (m_dwDeviceFlags, DFLAGS_LBA);
dwXferMode = 0;
dwCycleTime = UNINITIALIZED_CYCLE_TIME;
dwBestXferMode = 0;
//
// check for IoReady Line
//
if (m_Id.Capabilities & IDENTIFY_CAPABILITIES_IOREADY_SUPPORTED)
{
fIoReadyEnabled = TRUE;
}
else
{
fIoReadyEnabled = FALSE;
}
//
// Check for PIO mode
//
if ((m_Id.MinimumPIOxferTimeWOFlow & 0x00ff) == 2)
{
dwCycleTime = PIO_MODE2_CYCLE_TIME;
dwXferMode |= PIO_MODE2 | PIO_MODE1 | PIO_MODE0;
dwBestXferMode = 2;
dwCurrentMode = PIO_MODE2;
}
else if ((m_Id.MinimumPIOxferTimeWOFlow & 0x00ff) == 1)
{
dwCycleTime = PIO_MODE1_CYCLE_TIME;
dwXferMode |= PIO_MODE1 | PIO_MODE0;
dwBestXferMode = 1;
dwCurrentMode = PIO_MODE1;
}
else
{
dwCycleTime = PIO_MODE0_CYCLE_TIME;
dwXferMode |= PIO_MODE0;
dwBestXferMode = 0;
dwCurrentMode = PIO_MODE0;
}
DEBUGMSG( ZONE_INIT, (TEXT("ATAPI:AnalyzeDeviceCapabilities target %d IdentifyData PioCycleTimingMode (highest pio mode) = 0x%x\r\n"),
m_dwDevice,
m_Id.MinimumPIOxferTimeWOFlow));
if (m_Id.TranslationFieldsValid & (1 << 1)) {
if (fIoReadyEnabled) {
dwCycleTime = m_Id.MinimumPIOxferTimeIORDYFlow;
} else {
dwCycleTime = m_Id.MinimumPIOxferTimeWOFlow;
}
if (m_Id.AdvancedPIOxferreserved & (1 << 0)) {
dwXferMode |= PIO_MODE3;
dwBestXferMode = 3;
dwCurrentMode = PIO_MODE3;
}
if (m_Id.AdvancedPIOxferreserved & (1 << 1)) {
dwXferMode |= PIO_MODE4;
dwBestXferMode = 4;
dwCurrentMode = PIO_MODE4;
}
DEBUGMSG( ZONE_INIT, (TEXT("ATAPI:AnalyzeDeviceCapabilities target %d IdentifyData AdvancedPIOModes = 0x%x\r\n"),
m_dwDevice,
m_Id.AdvancedPIOxferreserved));
}
ASSERT (dwCycleTime != UNINITIALIZED_CYCLE_TIME);
ASSERT (dwXferMode);
ASSERT (dwCurrentMode);
m_dwBestPioCycleTime = dwCycleTime;
m_dwBestPioMode = dwBestXferMode;
//
// figure out all the DMA transfer mode this device supports
//
dwCurrentMode = 0;
//
// check singleword DMA timing
//
dwCycleTime = UNINITIALIZED_CYCLE_TIME;
dwBestXferMode = UNINITIALIZED_TRANSFER_MODE;
// EP931x rev E1 doesn't support Single word DMA so don't check it.
/*
if (m_Id.SingleDmaModesSupported)
{
DEBUGMSG( ZONE_INIT, (TEXT("ATAPI:AnalyzeDeviceCapabilitiestarget %d IdentifyData SingleDmaModesSupported = 0x%x\r\n"),
m_dwDevice,
m_Id.SingleDmaModesSupported));
DEBUGMSG( ZONE_INIT, (TEXT("ATAPI:AnalyzeDeviceCapabilitiestarget %d IdentifyData SingleWordDMAActive = 0x%x\r\n"),
m_dwDevice,
m_Id.SingleDmaTransferActive));
if (m_Id.SingleDmaModesSupported & (1 << 0))
{
dwCycleTime = SWDMA_MODE0_CYCLE_TIME;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -