📄 diskio.c
字号:
szStatus));
}
if (ZONE_ERROR) {
if (ATAStatus & ATA_STATUS_ERROR) {
AltStatus = ATA_READ_UCHAR(pDisk->d_Flags, (PUCHAR)(pDisk->d_pATAReg + ATA_REG_ERROR));
szStatus[0] = 0;
if (AltStatus & ATA_ERROR_GENERAL) {
_tcscat(szStatus, TEXT("GENERAL "));
}
if (AltStatus & ATA_ERROR_ABORTED) {
_tcscat(szStatus, TEXT("ABORTED "));
}
if (AltStatus & ATA_ERROR_BAD_SECT_NUM) {
_tcscat(szStatus, TEXT("BAD_SECT_NUM "));
}
if (AltStatus & ATA_ERROR_UNCORRECTABLE) {
_tcscat(szStatus, TEXT("UNCORRECTABLE "));
}
if (AltStatus & ATA_ERROR_BAD_BLOCK) {
_tcscat(szStatus, TEXT("BAD_BLOCK "));
}
DEBUGMSG(ZONE_ERROR,
(TEXT("ATADISK:PcmciaIntr - ATA Error = %s\r\n"), szStatus));
}
}
#endif
}
//
// Signal the I/O thread
//
SetEvent(pDisk->d_IRQEvent);
} // PcmciaIntr
#ifdef DEBUG
VOID
FormatSBCS(
PUCHAR p,
LPTSTR pT,
DWORD len
)
{
while (len) {
if ((*p > 0x20) && (*p < 0x7F)) {
*pT = (TCHAR)*p;
} else {
*pT = (TCHAR)'.';
}
pT++;
p++;
len--;
}
*pT = 0; // Terminate the string
} // FormatSBCS
#endif // DEBUG
//
// ATAIssueIdentify - issue a ATA_CMD_IDENTIFY command and put the disk
// information in the caller's buffer.
//
BOOL
ATAIssueIdentify(
PDISK pDisk,
PIDENTIFY_DATA pId
)
{
PUSHORT pBuf16;
volatile USHORT *pData16;
PUCHAR pBuf;
volatile UCHAR *pData;
DWORD i;
BOOL ret;
#ifdef DEBUG
PUCHAR pCh;
TCHAR OutBuf[128];
LPTSTR pOut;
PUSHORT tempS;
UCHAR tempByte;
ULONG j,k;
TCHAR tch[100];
#endif
DEBUGMSG(ZONE_IO, (TEXT("ATDISK:ATAIssueIdentify entered\r\n")));
ret = TRUE;
//
// Send IDENTIFY command.
//
try {
ATA_WRITE_UCHAR(pDisk->d_Flags, (UCHAR*)pDisk->d_pATAReg + ATA_REG_COMMAND, ATA_CMD_IDENTIFY);
} except (GetExceptionCode() == STATUS_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
DEBUGMSG(ZONE_IO|ZONE_ERROR, (TEXT("ATADISK:ATAIssueIdentify - exception 1\r\n")));
ret = FALSE;
}
if (ret == FALSE) {
return ret;
}
//
// Wait for DRQ or ERROR.
//
DEBUGMSG(ZONE_IO, (TEXT("ATDISK:ATAIssueIdentify waiting for DRQ\r\n")));
if (ATAWaitForDisk(pDisk, WAIT_TIME_LONG, WAIT_TYPE_DRQ)) {
DEBUGMSG(ZONE_IO, (TEXT("ATDISK:ATAIssueIdentify - ATAWaitForDisk failed\r\n")));
return FALSE;
}
//
// Read the identify information
//
DEBUGMSG(ZONE_IO, (TEXT("ATDISK:ATAIssueIdentify reading data\r\n")));
pBuf = (PUCHAR)pBuf16 = (PUCHAR)pId;
pData = (volatile UCHAR *)pData16 = pDisk->d_pATAReg;
try {
if (pDisk->d_f16Bit) {
i = (sizeof(IDENTIFY_DATA) - 4 + 1) / 2;
while (i) {
*pBuf16 = ATA_READ_USHORT(pDisk->d_Flags, (PUSHORT)pData16);
i--;
pBuf16++;
}
} else {
i = sizeof(IDENTIFY_DATA) - 4;
while (i) {
*pBuf = ATA_READ_UCHAR(pDisk->d_Flags, (PUCHAR)pData);
i--;
pBuf++;
}
}
} except (GetExceptionCode() == STATUS_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
DEBUGMSG(ZONE_IO|ZONE_ERROR, (TEXT("ATADISK:ATAIssueIdentify - exception 2\r\n")));
ret = FALSE;
}
if (ret == FALSE) {
return ret;
}
#ifdef DEBUG
if (!(ZONE_IO)) {
return TRUE;
}
//
// Display the identify information in hex+ascii
//
i = sizeof(IDENTIFY_DATA);
pCh = (PUCHAR)pId;
while (i) {
pOut = OutBuf;
k = (i < 16) ? i : 16;
for (j = 0; j < k; j++) {
pOut += wsprintf(pOut, TEXT("%2x "), pCh[j]);
}
if (k < 16) { // align last line
for (j = 0; j < 16 - k; j++) {
pOut += wsprintf(pOut, TEXT(" "));
}
}
for (j = 0; j < k; j++) {
if ((pCh[j] < ' ') || (pCh[j] > '~')) {
pOut += wsprintf(pOut, TEXT("."));
} else {
pOut += wsprintf(pOut, TEXT("%c"), pCh[j]);
}
}
DEBUGMSG(ZONE_IO,(TEXT("%s\r\n"), OutBuf));
i -= k;
pCh += k;
}
DEBUGMSG(ZONE_IO, (TEXT("ATDISK: Identify Data -\r\n")));
if (pId->GeneralConfiguration & 0x8000) {
DEBUGMSG(ZONE_IO, (TEXT("non-magnetic media\r\n")));
}
if (pId->GeneralConfiguration & 0x4000) {
DEBUGMSG(ZONE_IO, (TEXT("format speed tolerance gap required\r\n")));
}
if (pId->GeneralConfiguration & 0x2000) {
DEBUGMSG(ZONE_IO, (TEXT("track offset option available\r\n")));
}
if (pId->GeneralConfiguration & 0x1000) {
DEBUGMSG(ZONE_IO, (TEXT("data strobe offset option available\r\n")));
}
if (pId->GeneralConfiguration & 0x0800) {
DEBUGMSG(ZONE_IO, (TEXT("rotational speed tolerance is > 0,5%\r\n")));
}
if (pId->GeneralConfiguration & 0x0400) {
DEBUGMSG(ZONE_IO, (TEXT("disk transfer rate > 10Mbs\r\n")));
}
if (pId->GeneralConfiguration & 0x0200) {
DEBUGMSG(ZONE_IO, (TEXT("disk transfer rate > 5Mbs but <= 10Mbs\r\n")));
}
if (pId->GeneralConfiguration & 0x0100) {
DEBUGMSG(ZONE_IO, (TEXT("disk transfer rate <= 5Mbs\r\n")));
}
if (pId->GeneralConfiguration & 0x0080) {
DEBUGMSG(ZONE_IO, (TEXT("removeable cartridge drive\r\n")));
}
if (pId->GeneralConfiguration & 0x0040) {
DEBUGMSG(ZONE_IO, (TEXT("fixed drive\r\n")));
}
if (pId->GeneralConfiguration & 0x0020) {
DEBUGMSG(ZONE_IO, (TEXT("spindle motor control option implemented\r\n")));
}
if (pId->GeneralConfiguration & 0x0010) {
DEBUGMSG(ZONE_IO, (TEXT("head switch time > 15us\r\n")));
}
if (pId->GeneralConfiguration & 0x0008) {
DEBUGMSG(ZONE_IO, (TEXT("not MFM encoded\r\n")));
}
if (pId->GeneralConfiguration & 0x0004) {
DEBUGMSG(ZONE_IO, (TEXT("soft sectored\r\n")));
}
if (pId->GeneralConfiguration & 0x0002) {
DEBUGMSG(ZONE_IO, (TEXT("hard sectored\r\n")));
}
DEBUGMSG(ZONE_IO, (TEXT("Number of Cylinders: %d\r\n"), pId->NumberOfCylinders));
DEBUGMSG(ZONE_IO, (TEXT("Number of heads: %d\r\n"),pId->NumberOfHeads));
DEBUGMSG(ZONE_IO, (TEXT("Unformatted bytes per track: %d\r\n"),pId->UnformattedBytesPerTrack));
DEBUGMSG(ZONE_IO, (TEXT("Unformatted bytes per sector: %d\r\n"),pId->UnformattedBytesPerSector));
DEBUGMSG(ZONE_IO, (TEXT("Sectors per track: %d\r\n"),pId->SectorsPerTrack));
//
// Byte flip model number, revision, and serial number string.
//
tempS = pId->ModelNumber;
for (k=0; k<20; k++) {
tempByte = (UCHAR)(tempS[k] & 0x00FF);
tempS[k] = tempS[k] >> 8;
tempS[k] |= tempByte << 8;
}
tempS = pId->FirmwareRevision;
for (k=0; k<4; k++) {
tempByte = (UCHAR)(tempS[k] & 0x00FF);
tempS[k] = tempS[k] >> 8;
tempS[k] |= tempByte << 8;
}
tempS = pId->SerialNumber;
for (k=0; k<10; k++) {
tempByte = (UCHAR)(tempS[k] & 0x00FF);
tempS[k] = tempS[k] >> 8;
tempS[k] |= tempByte << 8;
}
FormatSBCS((PUCHAR)&pId->SerialNumber[0], tch, 20);
DEBUGMSG(ZONE_IO, (TEXT("Serial number: %s\r\n"), tch));
if (pId->BufferType == 0) {
DEBUGMSG(ZONE_IO, (TEXT("Buffer type unspecified\r\n")));
}
if (pId->BufferType == 1) {
DEBUGMSG(ZONE_IO, (TEXT("Buffer type single port - no simultaneous transfer\r\n")));
}
if (pId->BufferType == 2) {
DEBUGMSG(ZONE_IO, (TEXT("Buffer type dual port - simultaneous transfer capable\r\n")));
}
if (pId->BufferType == 3) {
DEBUGMSG(ZONE_IO, (TEXT("Buffer type dual port - simultaneous transfer capable - read cache\r\n")));
}
if (pId->BufferType >= 4) {
DEBUGMSG(ZONE_IO, (TEXT("Buffer type reserved\r\n")));
}
if (pId->BufferSectorSize == 0) {
DEBUGMSG(ZONE_IO, (TEXT("Unspecified buffer size\r\n")));
} else {
DEBUGMSG(ZONE_IO, (TEXT("Buffer size in sectors: %d\r\n"),pId->BufferSectorSize));
}
if (pId->NumberOfEccBytes == 0) {
DEBUGMSG(ZONE_IO, (TEXT("Number of Ecc bytes is unspecified\r\n")));
} else {
DEBUGMSG(ZONE_IO, (TEXT("Number of Ecc bytes or r/w long: %d\r\n"),pId->NumberOfEccBytes));
}
FormatSBCS((PUCHAR)&pId->FirmwareRevision[0], tch, 8);
DEBUGMSG(ZONE_IO, (TEXT("Firmware revision: %s\r\n"), tch));
FormatSBCS((PUCHAR)&pId->ModelNumber[0], tch, 40);
DEBUGMSG(ZONE_IO, (TEXT("Model number: %s\r\n"), tch));
if (pId->MaximumBlockTransfer == 0) {
DEBUGMSG(ZONE_IO, (TEXT("Read/Write multiple not implemented\r\n")));
} else {
DEBUGMSG(ZONE_IO, (TEXT("Maximum sectors/interrupt on read/write multiple: %d\r\n"),
pId->MaximumBlockTransfer));
}
if (pId->DoubleWordIo == 0) {
DEBUGMSG(ZONE_IO, (TEXT("Can not perform double word IO\r\n")));
} else if (pId->DoubleWordIo == 1) {
DEBUGMSG(ZONE_IO, (TEXT("Can perform double word IO\r\n")));
} else {
DEBUGMSG(ZONE_IO, (TEXT("Unknown doubleword specifier\r\n")));
}
if (pId->Capabilities & 0x0200) {
DEBUGMSG(ZONE_IO, (TEXT("LBA mode supported\r\n")));
} else {
DEBUGMSG(ZONE_IO, (TEXT("LBA mode NOT supported\r\n")));
}
if (pId->Capabilities & 0x0100) {
DEBUGMSG(ZONE_IO, (TEXT("DMA supported\r\n")));
} else {
DEBUGMSG(ZONE_IO, (TEXT("DMA NOT supported\r\n")));
}
DEBUGMSG(ZONE_IO, (TEXT("PIO cycle timing mode: %x\r\n"),
pId->PioCycleTimingMode));
DEBUGMSG(ZONE_IO, (TEXT("DMA cycle timing mode: %x\r\n"),
pId->DmaCycleTimingMode));
if ((pId->TranslationFieldsValid & 1) == 0) {
DEBUGMSG(ZONE_IO, (TEXT("Current size fields MAY be valid\r\n")));
} else {
DEBUGMSG(ZONE_IO, (TEXT("Current size fields ARE valid\r\n")));
}
DEBUGMSG(ZONE_IO, (TEXT("Current number of cylinders: %d\r\n"),
pId->NumberOfCurrentCylinders));
DEBUGMSG(ZONE_IO, (TEXT("Current number of heads: %d\r\n"),
pId->NumberOfCurrentHeads));
DEBUGMSG(ZONE_IO, (TEXT("Current number of sectors/track: %d\r\n"),
pId->CurrentSectorsPerTrack));
DEBUGMSG(ZONE_IO, (TEXT("Current sector capacity: %d\r\n"),
pId->CurrentSectorCapacity));
DEBUGMSG(ZONE_IO, (TEXT("Sectors per interrupt with r/w multiple: %d\r\n"),
pId->MultiSectorCount));
if (pId->MultiSectorSettingValid & 1) {
DEBUGMSG(ZONE_IO, (TEXT("Multi sector setting valid\r\n")));
} else {
DEBUGMSG(ZONE_IO, (TEXT("Multi sector setting is INVALID\r\n")));
}
DEBUGMSG(ZONE_IO, (TEXT("Total user addressable sectors: %d\r\n"),
pId->TotalUserAddressableSectors));
DEBUGMSG(ZONE_IO, (TEXT("Single word dma modes supported: %x\r\n"),
pId->SingleDmaModesSupported));
DEBUGMSG(ZONE_IO, (TEXT("Single word transfer mode active: %x\r\n"),
pId->SingleDmaTransferActive));
DEBUGMSG(ZONE_IO, (TEXT("Multi word dma modes supported: %x\r\n"),
pId->MultiDmaModesSupported));
DEBUGMSG(ZONE_IO, (TEXT("Multi word transfer mode active: %x\r\n"),
pId->MultiDmaTransferActive));
DEBUGMSG(ZONE_IO, (TEXT("ATDISK:ATAIssueIdentify done\r\n")));
#endif // DEBUG
return TRUE;
} // ATAIssueIdentify
//
// GetDiskInfo - return disk info in response to DISK_IOCTL_GETINFO
//
DWORD
GetDiskInfo(
PDISK pDisk,
PDISK_INFO pInfo
)
{
*pInfo = pDisk->d_DiskInfo;
pInfo->di_flags |= DISK_INFO_FLAG_PAGEABLE;
pInfo->di_flags &= ~DISK_INFO_FLAG_UNFORMATTED;
return ERROR_SUCCESS;
} // GetDiskInfo
//
// SetDiskInfo - store disk info in response to DISK_IOCTL_SETINFO
//
DWORD
SetDiskInfo(
PDISK pDisk,
PDISK_INFO pInfo
)
{
DWORD sectsize;
sectsize = pDisk->d_DiskInfo.di_bytes_per_sect;
pDisk->d_DiskInfo = *pInfo;
return ERROR_SUCCESS;
} // SetDiskInfo
//
// ATAInitController
//
BOOL
ATAInitController(
PDISK pDisk
)
{
BOOL ret = TRUE;
UCHAR status;
DEBUGMSG(ZONE_INIT, (TEXT("ATADISK:ATAInitController entered\r\n")));
try {
status = ATA_READ_UCHAR(pDisk->d_Flags, (UCHAR*)pDisk->d_pATARegAlt + ATA_REG_ALT_STATUS);
if ((status & 0x0f) == 0x0f) {
ret = FALSE;
DEBUGMSG(ZONE_IO|ZONE_ERROR,
(TEXT("ATADISK:ATAInitController - ATA_STATUS = 0x%x!\r\n"),
status));
}
DEBUGMSG(ZONE_INIT,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -