diskio.c
来自「WinCE 3.0 BSP, 包含Inter SA1110, Intel_815」· C语言 代码 · 共 1,552 行 · 第 1/3 页
C
1,552 行
}
if(ATAPI_errcode != NO_ERROR) { // Error ?
pSgr->sr_status = ATAPI_errcode; // return ATAPI_errcode;
return FALSE;
}
pDisk->d_ReadEvent = CreateEvent(NULL, TRUE, FALSE, NULL);//ready for next read interrupput process
pSgr->sr_status = ERROR_SUCCESS;
return TRUE;
} // CDRead
//
// ATAWrite
//
DWORD
ATAWrite(
PDISK pDisk,
PSG_REQ pSgr
)
{
DWORD i;
DWORD num_sg;
DWORD bytes_this_int;
DWORD bytes_this_sg;
PSG_BUF pSg;
PUSHORT pBuf16;
PUSHORT pTmp16;
volatile PUSHORT pData16;
PUCHAR pBuf;
volatile PUCHAR pData;
DWORD sectno;
DWORD endsect;
DWORD error;
num_sg = pSgr->sr_num_sg;
pSg = &(pSgr->sr_sglist[0]);
bytes_this_sg = pSg->sb_len;
bytes_this_int = pDisk->d_DiskInfo.di_bytes_per_sect;
pBuf = (PUCHAR)pBuf16 = MapPtrToProcess((LPVOID)pSg->sb_buf, GetCallerProcess());
pData = (volatile PUCHAR)pData16 = pDisk->d_pATAReg;
sectno = pSgr->sr_start;
endsect = sectno + pSgr->sr_num_sec;
error = ERROR_SUCCESS;
//
// This loop writes data from multiple scatter/gather buffers to multiple
// sectors.
//
while (num_sg) {
DEBUGMSG(ATAPI_IO,
(TEXT("ATAPI:ATAWrite - writing sector %d\r\n"), sectno));
try {
error = ATASetSector(pDisk, sectno, ATA_CMD_WRITE);
} except (GetExceptionCode() == STATUS_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
DEBUGMSG(ATAPI_IO|ATAPI_ERROR, (TEXT("ATAPI:ATAWrite - exception 1\r\n")));
error = ERROR_WRITE_FAULT;
}
if (error != ERROR_SUCCESS) {
return GetDiskStateError(pDisk->d_DiskCardState);
}
if (ATAWaitForDisk(
pDisk,
WAIT_TIME_NORMAL,
WAIT_TYPE_DRQ) != CERR_SUCCESS) {
return GetDiskStateError(pDisk->d_DiskCardState);
}
sectno++;
bytes_this_int = pDisk->d_DiskInfo.di_bytes_per_sect;
aw_continue_sector:
i = (bytes_this_sg < bytes_this_int) ? bytes_this_sg : bytes_this_int;
bytes_this_sg -= i;
bytes_this_int -= i;
try {
if (pDisk->d_f16Bit) {
i = (i+1) / 2;
if ((DWORD)pBuf16 & 1) {
//
// ("Son, this hurts me worse than it hurts you.")
// If the user's buffer is not 16 bit aligned then use the
// 16 bit aligned buffer to write the sector to the card.
//
memcpy(pDisk->d_AlignBuf, pBuf16, i * 2);
pTmp16 = pDisk->d_AlignBuf;
pBuf16 += i;
while (i) {
ATA_WRITE_USHORT(pData16, *pTmp16);
i--;
pTmp16++;
}
} else {
while (i) {
ATA_WRITE_USHORT(pData16, *pBuf16);
i--;
pBuf16++;
}
}
} else {
while (i) {
ATA_WRITE_UCHAR(pData, *pBuf);
i--;
pBuf++;
}
}
} except (GetExceptionCode() == STATUS_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
DEBUGMSG(ATAPI_IO|ATAPI_ERROR, (TEXT("ATAPI:ATAWrite - exception 2\r\n")));
error = GetDiskStateError(pDisk->d_DiskCardState);
}
if (error != ERROR_SUCCESS) {
return error;
}
if (bytes_this_int == 0) {
if (pDisk->d_DiskCardState != STATE_OPENED) {
return GetDiskStateError(pDisk->d_DiskCardState);
}
if (sectno < endsect) {
continue; // next sector
}
}
//
// Use the next scatter/gather buffer
//
num_sg--;
if (num_sg == 0) {
break;
}
pSg++;
pBuf = MapPtrToProcess((LPVOID)pSg->sb_buf, GetCallerProcess());
bytes_this_sg = pSg->sb_len;
if (bytes_this_int) {
goto aw_continue_sector;
}
} // while
//
// Finish writing to last sector if the last buffer was not a sector multiple.
//
if (pDisk->d_f16Bit) {
bytes_this_int = (bytes_this_int + 1) /2;
while (bytes_this_int) {
*pData16 = 0xDDDD;
bytes_this_int--;
}
} else {
while (bytes_this_int) {
*pData = 0xDD;
bytes_this_int--;
}
}
ATAWaitForDisk(pDisk, WAIT_TIME_NORMAL, WAIT_TYPE_NOT_BUSY);
return 0;
} // ATAWrite
//
// DoDiskIO - fulfill I/O requests
//
DWORD
DoDiskIO(
PDISK pDisk,
DWORD Opcode,
PSG_REQ pSgr
)
{
DWORD status;
DWORD dwlength;
DWORD dwmin;
DWORD dwsec;
DWORD dwframe;
DWORD dwmap;
PSG_REQ pSG;
//
// Covert Scatter/gather structure to CD-ROM structure
//
EnterCriticalSection(&(pDisk->d_DiskCardCrit));
pSG = (PSG_REQ)pSgr;
dwmin = pSgr->sr_start;
dwsec = pSgr->sr_num_sec;
dwframe = pSgr->sr_num_sg;
dwlength = pSgr->sr_status;
dwmap = (DWORD)ATAPI_WORK;
dwmin = (dwmin >>8 )*100 + (((dwmin >> 2)>>2 ) & 0x0000000f )*10 + ( dwmin & 0x0000000f );
dwsec = ((dwsec >> 2)>>2 )*10 + ( dwsec & 0x0000000f );
dwframe = ((dwframe >> 2)>>2 )*10 + ( dwframe & 0x0000000f );
LBaddress.lword = (ULONG)( 4500 * dwmin + 75 * dwsec + dwframe-150 );
if(dwlength>255){
pSgr->sr_status = ERROR_BAD_LENGTH;
status = FALSE;
goto ddi_leave;
}
// Byte SWAP Logical Block Address
dwHighLBA = LBaddress.word.hi;
dwHighLBA = (dwHighLBA<<8) | (dwHighLBA>>8);
dwLowLBA = LBaddress.word.low;
dwLowLBA = (dwLowLBA<<8) | (dwLowLBA>>8);
// Byte SWAP Transfer Length
datasize.byte.hi = (BYTE)dwlength;
datasize.byte.low = 0;
// Set Store Address
CD_ROM_STA.count = (unsigned long) dwmap ;
if (Opcode == DISK_IOCTL_READ) {
status = CDRead(pDisk, pSG); // status = FALSE or TRUE
} else {
status = ATAWrite(pDisk, pSG);
}
ddi_leave:
LeaveCriticalSection(&(pDisk->d_DiskCardCrit));
//ddi_exit:
return status; // FALSE or TRUE
} // DoDiskIO
#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 PUSHORT pData16;
PUCHAR pBuf;
volatile PUCHAR 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(ATAPI_IO, (TEXT("ATDISK:ATAIssueIdentify entered\r\n")));
ret = TRUE;
//
// Send IDENTIFY command.
//
try {
ATA_WRITE_UCHAR(pDisk->d_pATAReg + ATA_REG_COMMAND, ATA_CMD_IDENTIFY);
} except (GetExceptionCode() == STATUS_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
DEBUGMSG(ATAPI_IO|ATAPI_ERROR, (TEXT("ATAPI:ATAIssueIdentify - exception 1\r\n")));
ret = FALSE;
}
if (ret == FALSE) {
return ret;
}
//
// Wait for DRQ or ERROR.
//
DEBUGMSG(ATAPI_IO, (TEXT("ATDISK:ATAIssueIdentify waiting for DRQ\r\n")));
if (ATAWaitForDisk(pDisk, WAIT_TIME_LONG, WAIT_TYPE_DRQ)) {
DEBUGMSG(ATAPI_IO, (TEXT("ATDISK:ATAIssueIdentify - ATAWaitForDisk failed\r\n")));
return FALSE;
}
//
// Read the identify information
//
DEBUGMSG(ATAPI_IO, (TEXT("ATDISK:ATAIssueIdentify reading data\r\n")));
pBuf = (PUCHAR)pBuf16 = (PUCHAR)pId;
pData = (volatile PUCHAR)pData16 = pDisk->d_pATAReg;
try {
if (pDisk->d_f16Bit) {
i = (sizeof(IDENTIFY_DATA) + 1) / 2;
while (i) {
*pBuf16 = ATA_READ_USHORT(pData16);
i--;
pBuf16++;
}
} else {
i = sizeof(IDENTIFY_DATA);
while (i) {
*pBuf = ATA_READ_UCHAR(pData);
i--;
pBuf++;
}
}
} except (GetExceptionCode() == STATUS_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
DEBUGMSG(ATAPI_IO|ATAPI_ERROR, (TEXT("ATAPI:ATAIssueIdentify - exception 2\r\n")));
ret = FALSE;
}
if (ret == FALSE) {
return ret;
}
#ifdef DEBUG
if (!(ATAPI_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(ATAPI_IO,(TEXT("%s\r\n"), OutBuf));
i -= k;
pCh += k;
}
DEBUGMSG(ATAPI_IO, (TEXT("ATDISK: Identify Data -\r\n")));
if (pId->GeneralConfiguration & 0x8000) {
DEBUGMSG(ATAPI_IO, (TEXT("non-magnetic media\r\n")));
}
if (pId->GeneralConfiguration & 0x4000) {
DEBUGMSG(ATAPI_IO, (TEXT("format speed tolerance gap required\r\n")));
}
if (pId->GeneralConfiguration & 0x2000) {
DEBUGMSG(ATAPI_IO, (TEXT("track offset option available\r\n")));
}
if (pId->GeneralConfiguration & 0x1000) {
DEBUGMSG(ATAPI_IO, (TEXT("data strobe offset option available\r\n")));
}
if (pId->GeneralConfiguration & 0x0800) {
DEBUGMSG(ATAPI_IO, (TEXT("rotational speed tolerance is > 0,5%\r\n")));
}
if (pId->GeneralConfiguration & 0x0400) {
DEBUGMSG(ATAPI_IO, (TEXT("disk transfer rate > 10Mbs\r\n")));
}
if (pId->GeneralConfiguration & 0x0200) {
DEBUGMSG(ATAPI_IO, (TEXT("disk transfer rate > 5Mbs but <= 10Mbs\r\n")));
}
if (pId->GeneralConfiguration & 0x0100) {
DEBUGMSG(ATAPI_IO, (TEXT("disk transfer rate <= 5Mbs\r\n")));
}
if (pId->GeneralConfiguration & 0x0080) {
DEBUGMSG(ATAPI_IO, (TEXT("removeable cartridge drive\r\n")));
}
if (pId->GeneralConfiguration & 0x0040) {
DEBUGMSG(ATAPI_IO, (TEXT("fixed drive\r\n")));
}
if (pId->GeneralConfiguration & 0x0020) {
DEBUGMSG(ATAPI_IO, (TEXT("spindle motor control option implemented\r\n")));
}
if (pId->GeneralConfiguration & 0x0010) {
DEBUGMSG(ATAPI_IO, (TEXT("head switch time > 15us\r\n")));
}
if (pId->GeneralConfiguration & 0x0008) {
DEBUGMSG(ATAPI_IO, (TEXT("not MFM encoded\r\n")));
}
if (pId->GeneralConfiguration & 0x0004) {
DEBUGMSG(ATAPI_IO, (TEXT("soft sectored\r\n")));
}
if (pId->GeneralConfiguration & 0x0002) {
DEBUGMSG(ATAPI_IO, (TEXT("hard sectored\r\n")));
}
DEBUGMSG(ATAPI_IO, (TEXT("Number of Cylinders: %d\r\n"), pId->NumberOfCylinders));
DEBUGMSG(ATAPI_IO, (TEXT("Number of heads: %d\r\n"),pId->NumberOfHeads));
DEBUGMSG(ATAPI_IO, (TEXT("Unformatted bytes per track: %d\r\n"),pId->UnformattedBytesPerTrack));
DEBUGMSG(ATAPI_IO, (TEXT("Unformatted bytes per sector: %d\r\n"),pId->UnformattedBytesPerSector));
DEBUGMSG(ATAPI_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(ATAPI_IO, (TEXT("Serial number: %s\r\n"), tch));
if (pId->BufferType == 0) {
DEBUGMSG(ATAPI_IO, (TEXT("Buffer type unspecified\r\n")));
}
if (pId->BufferType == 1) {
DEBUGMSG(ATAPI_IO, (TEXT("Buffer type single port - no simultaneous transfer\r\n")));
}
if (pId->BufferType == 2) {
DEBUGMSG(ATAPI_IO, (TEXT("Buffer type dual port - simultaneous transfer capable\r\n")));
}
if (pId->BufferType == 3) {
DEBUGMSG(ATAPI_IO, (TEXT("Buffer type dual port - simultaneous transfer capable - read cache\r\n")));
}
if (pId->BufferType >= 4) {
DEBUGMSG(ATAPI_IO, (TEXT("Buffer type reserved\r\n")));
}
if (pId->BufferSectorSize == 0) {
DEBUGMSG(ATAPI_IO, (TEXT("Unspecified buffer size\r\n")));
} else {
DEBUGMSG(ATAPI_IO, (TEXT("Buffer size in sectors: %d\r\n"),pId->BufferSectorSize));
}
if (pId->NumberOfEccBytes == 0) {
DEBUGMSG(ATAPI_IO, (TEXT("Number of Ecc bytes is unspecified\r\n")));
} else {
DEBUGMSG(ATAPI_IO, (TEXT("Number of Ecc bytes or r/w long: %d\r\n"),pId->NumberOfEccBytes));
}
FormatSBCS((PUCHAR)&pId->FirmwareRevision[0], tch, 8);
DEBUGMSG(ATAPI_IO, (TEXT("Firmware revision: %s\r\n"), tch));
FormatSBCS((PUCHAR)&pId->ModelNumber[0], tch, 40);
DEBUGMSG(ATAPI_IO, (TEXT("Model number: %s\r\n"), tch));
if (pId->MaximumBlockTransfer == 0) {
DEBUGMSG(ATAPI_IO, (TEXT("Read/Write multiple not implmeneted\r\n")));
} else {
DEBUGMSG(ATAPI_IO, (TEXT("Maximum sectors/interrupt on read/write multiple: %d\r\n"),
pId->MaximumBlockTransfer));
}
if (pId->DoubleWordIo == 0) {
DEBUGMSG(ATAPI_IO, (TEXT("Can not perform double word IO\r\n")));
} else if (pId->DoubleWordIo == 1) {
DEBUGMSG(ATAPI_IO, (TEXT("Can perform double word IO\r\n")));
} else {
DEBUGMSG(ATAPI_IO, (TEXT("Unknown doubleword specifier\r\n")));
}
if (pId->Capabilities & 0x0200) {
DEBUGMSG(ATAPI_IO, (TEXT("LBA mode supported\r\n")));
} else {
DEBUGMSG(ATAPI_IO, (TEXT("LBA mode NOT supported\r\n")));
}
if (pId->Capabilities & 0x0100) {
DEBUGMSG(ATAPI_IO, (TEXT("DMA supported\r\n")));
} else {
DEBUGMSG(ATAPI_IO, (TEXT("DMA NOT supported\r\n")));
}
DEBUGMSG(ATAPI_IO, (TEXT("PIO cycle timing mode: %x\r\n"),
pId->PioCycleTimingMode));
DEBUGMSG(ATAPI_IO, (TEXT("DMA cycle timing mode: %x\r\n"),
pId->DmaCycleTimingMode));
if ((pId->TranslationFieldsValid & 1) == 0) {
DEBUGMSG(ATAPI_IO, (TEXT("Current size fields MAY be valid\r\n")));
} else {
DEBUGMSG(ATAPI_IO, (TEXT("Current size fields ARE valid\r\n")));
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?