⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 diskio.c

📁 WinCE下的ATADISK驱动
💻 C
📖 第 1 页 / 共 4 页
字号:
            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 + -