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 + -
显示快捷键?