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

📄 diskio.c

📁 WinCE下的ATADISK驱动
💻 C
📖 第 1 页 / 共 4 页
字号:
            if (pDisk->d_f16Bit) {
                if (nextbyte != 0xFFFF) {
                    // Update the first byte.
                    *pBuf++ = (BYTE) nextbyte;
                    i--; 
                    nextbyte = 0xFFFF;
                }
                if ((DWORD)pBuf & 1) {
                    //
                    // If the user's buffer is not 16 bit aligned then use the
                    // 16 bit aligned buffer to read the sector from the card.
                    //
                    while (i > 1) {
                        unisc.us = ATA_READ_USHORT(pDisk->d_Flags, (PUSHORT)pData16);
                        *pBuf++= unisc.uc[0];
                        *pBuf++= unisc.uc[1];
                        i -= 2;
                    }
                } else {
                    while (i > 1) {
                        *(WORD *)pBuf = ATA_READ_USHORT(pDisk->d_Flags, (PUSHORT)pData16);
                        i -= 2;
                        pBuf +=2;
                    }
                }
                if (i == 1) {
                    unisc.us = ATA_READ_USHORT(pDisk->d_Flags, (PUSHORT)pData16);
                    *pBuf++=   unisc.uc[0];
                    nextbyte = (WORD)unisc.uc[1];    // Save byte for the next SG if 
                }
            } else {
                while (i) {
                    *pBuf++ = ATA_READ_UCHAR(pDisk->d_Flags, (PUCHAR)pData);
                    i--;
                }
            }
        } except (GetExceptionCode() == STATUS_ACCESS_VIOLATION ?
            EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
            DEBUGMSG(ZONE_IO|ZONE_ERROR, (TEXT("ATADISK:ATARead - exception 2\r\n")));
            error = ERROR_READ_FAULT;
        }
        if (error != ERROR_SUCCESS) {
            return error;
        }

        if (bytes_this_int == 0) {
            if (sectno < endsect) {
                continue;       // next sector
            }
        }

        //
        // Use the next scatter/gather buffer
        //
        num_sg--;
        if (num_sg == 0) {
            break;
        }
        pSg++;

        // Map address and check for security violation
        pBuf = (LPBYTE)MapCallerPtr((LPVOID)pSg->sb_buf, pSg->sb_len);
        if (pSg->sb_buf != NULL && pBuf == NULL) {
            // Security violation
            DEBUGMSG(ZONE_ERROR, (TEXT(
                "ATARead>Failed to map pointer to caller\r\n"
                )));
            return ERROR_ACCESS_DENIED;
        }

        bytes_this_sg = pSg->sb_len;
        if (bytes_this_int) {
            goto ar_continue_sector;
        }

    }   // while 
    return 0;
}    // ATARead


//
// ATAWrite
//
DWORD
ATAWrite(
    PDISK pDisk,
    PSG_REQ pSgr
    )
{
    DWORD i;
    DWORD num_sg;
    DWORD bytes_this_int;
    DWORD bytes_this_sg;
    PSG_BUF pSg;
    volatile USHORT *pData16;
    PUCHAR pBuf;
    volatile UCHAR *pData;
    DWORD sectno;
    DWORD nextsec; 
    DWORD endsect;
    DWORD error;
    WORD  nextbyte=0xFFFF;

    union {
        WORD us;
        BYTE  uc[2];
    }unisc;

    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;

    // Map address and check for security violation
    pBuf = (LPBYTE)MapCallerPtr((LPVOID)pSg->sb_buf, pSg->sb_len);
    if (pSg->sb_buf != NULL && pBuf == NULL) {
        // Security violation
        DEBUGMSG(ZONE_ERROR, (TEXT(
            "ATAWrite>Failed to map pointer to caller\r\n"
            )));
        return ERROR_ACCESS_DENIED;
    }

    pData = (volatile UCHAR*)pData16 = pDisk->d_pATAReg;
    sectno = pSgr->sr_start;
    endsect = sectno + pSgr->sr_num_sec;
    error = ERROR_SUCCESS;
    nextsec = 0;

    //
    // This loop writes data from multiple scatter/gather buffers to multiple
    // sectors.
    //
    while (num_sg) {
        DEBUGMSG(ZONE_IO, 
            (TEXT("ATADISK:ATAWrite - writing sector %d\r\n"), sectno));

        if (!nextsec) {
            nextsec = MIN(MAX_SECT_CNT, endsect - sectno);
            try {
                error = ATASetSector(pDisk, sectno, nextsec, ATA_CMD_WRITE);
            } except (GetExceptionCode() == STATUS_ACCESS_VIOLATION ?
                EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
                DEBUGMSG(ZONE_IO|ZONE_ERROR, (TEXT("ATADISK:ATAWrite - exception 1\r\n")));
                error = ERROR_WRITE_FAULT;
            }
            if (error != ERROR_SUCCESS) {
                return error;
            }
        }
        
        error = ATAWaitForDisk(pDisk, WAIT_TIME_NORMAL, WAIT_TYPE_DRQ_NOERR);
        if (error != ERROR_SUCCESS) {
            return error;
        }
        sectno++;
        nextsec--;
        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) {
                if (nextbyte != 0xFFFF) {
                    // Update the first byte
                    unisc.uc[0] = (BYTE) nextbyte;
                    unisc.uc[1] = *pBuf++;
                    i--; 
                    nextbyte = 0xFFFF;
                    ATA_WRITE_USHORT(pDisk->d_Flags, (PUSHORT)pData16, unisc.us);
                }
                if ((DWORD)pBuf & 1) {
                    //
                    // If the user's buffer is not 16 bit aligned then use the
                    // 16 bit aligned buffer to write the sector to the card.
                    //
                    while (i > 1) {
                        unisc.uc[0] = *pBuf++;
                        unisc.uc[1] = *pBuf++;
                        ATA_WRITE_USHORT(pDisk->d_Flags, (PUSHORT)pData16, unisc.us);
                        i -= 2;
                    }
                } else {
                    while (i > 1) {
                        ATA_WRITE_USHORT(pDisk->d_Flags, (PUSHORT)pData16, *(WORD *)pBuf);
                        i -= 2;
                        pBuf +=2;
                    }
                }
                if (i == 1) {
                    nextbyte = *(WORD *)pBuf;  // Save byte for the next SG if 
                    pBuf += 2;
                }
            } else {
                while (i) {
                    ATA_WRITE_UCHAR(pDisk->d_Flags, (PUCHAR)pData, *pBuf);
                    i--;
                    pBuf++;
                }
            }
        } except (GetExceptionCode() == STATUS_ACCESS_VIOLATION ?
            EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
            DEBUGMSG(ZONE_IO|ZONE_ERROR, (TEXT("ATADISK:ATAWrite - exception 2\r\n")));
            error = ERROR_WRITE_FAULT;
        }
        if (error != ERROR_SUCCESS) {
            return error;
        }

        if (bytes_this_int == 0) {
            if (sectno < endsect) {
                continue;       // next sector
            }
        }

        //
        // Use the next scatter/gather buffer
        //
        num_sg--;
        if (num_sg == 0) {
            break;
        }
        pSg++;

        // Map address and check for security violation
        pBuf = (LPBYTE)MapCallerPtr((LPVOID)pSg->sb_buf, pSg->sb_len);
        if (pSg->sb_buf != NULL && pBuf == NULL) {
            // Security violation
            DEBUGMSG(ZONE_ERROR, (TEXT(
                "ATAWrite>Failed to map pointer to caller\r\n"
                )));
            return ERROR_ACCESS_DENIED;
        }

        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) {
            ATA_WRITE_USHORT(pDisk->d_Flags, (PUSHORT)pData16, 0xDDDD);
            //*pData16 = 0xDDDD;
            bytes_this_int--;
        }
    } else {
        while (bytes_this_int) {
            ATA_WRITE_UCHAR(pDisk->d_Flags, (PUCHAR)pData, 0xDD);
            //*pData = 0xDD;
            bytes_this_int--;
        }
    }

    return ATAWaitForDisk(pDisk, WAIT_TIME_NORMAL, WAIT_TYPE_READY);
}   // ATAWrite



//
// DoDiskIO - fulfill I/O requests
//
DWORD
DoDiskIO(
    PDISK pDisk,
    DWORD Opcode,
    PSG_REQ pSgr
    )
{
    DWORD status;
    unsigned int i;

    DEBUGMSG(ZONE_IO, (TEXT("ATDISK:DoDiskIO entered\r\n")));

    pSgr->sr_status = ERROR_IO_PENDING;

    if (pSgr->sr_num_sg > MAX_SG_BUF || pSgr->sr_num_sg <= 0) {
        status = ERROR_INVALID_PARAMETER;
        goto ddi_exit;
    }

    for (i = 0; i < pSgr->sr_num_sg; i++) {
        if (pSgr->sr_sglist[i].sb_len <= 0 ||
            pSgr->sr_sglist[i].sb_buf == NULL) {
            status = ERROR_INVALID_PARAMETER;
            goto ddi_exit;
        }
    }

    //
    // Make sure request doesn't exceed the disk size or ask for 0 sectors.
    //
    if (pSgr->sr_num_sec == 0) {
        status = ERROR_INVALID_PARAMETER;
        goto ddi_exit;
    }
    if ((pSgr->sr_start + pSgr->sr_num_sec) > pDisk->d_DiskInfo.di_total_sectors) {
        status = ERROR_SECTOR_NOT_FOUND;
        goto ddi_exit;
    }

    EnterCriticalSection(&pDisk->d_DiskCardCrit);
    while(pDisk->lPwrOff) {
        HANDLE hEvent = pDisk->hPwrEvent;
        LeaveCriticalSection(&pDisk->d_DiskCardCrit);
        WaitForSingleObject( pDisk->hPwrEvent, INFINITE);
        if (pDisk->lPwrOff == -1) {
            goto ddi_exit;
        }    
        EnterCriticalSection(&pDisk->d_DiskCardCrit);
        ATAInitController(pDisk);
    }

    DEBUGMSG(ZONE_IO, 
        (TEXT("ATADISK:DoDiskIO - working on request @ 0x%x from sector %d to %d\r\n"),
        pSgr, pSgr->sr_start, pSgr->sr_start + pSgr->sr_num_sec - 1));

    if (Opcode == DISK_IOCTL_READ) {
        status = ATARead(pDisk, pSgr);
    } else {
        status = ATAWrite(pDisk, pSgr);
    }

    LeaveCriticalSection(&(pDisk->d_DiskCardCrit));

ddi_exit:
    DEBUGMSG(ZONE_IO, (TEXT("ATDISK:DoDiskIO done - status=%d\r\n"), status));
    if (pDisk->lPwrOff == -1) {
        status = ERROR_DEVICE_NOT_AVAILABLE;
    }    
    pSgr->sr_status = status;
    return status;
}   // DoDiskIO



VOID
PcmciaIntr(
    DWORD Context
    )
{
    DWORD error;
    UCHAR ATAStatus;
    UCHAR AltStatus;
#ifdef DEBUG
    TCHAR szStatus[70];
#endif
    PDISK pDisk = (PDISK)Context;
    if (IsValidDisk(pDisk) == FALSE) {
        DEBUGMSG(ZONE_IO|ZONE_PCMCIA,
            (TEXT("ATADISK: PcmciaIntr - Invalid PDISK\r\n")));
        return;
    }

    error = ERROR_SUCCESS;
    ATAStatus = AltStatus = 0;

    //
    // Acknowledge the interrupt by reading the status register
    //
    try {
        ATAStatus = ATA_READ_UCHAR(pDisk->d_Flags, (UCHAR*)pDisk->d_pATAReg + ATA_REG_STATUS);
        AltStatus = ATA_READ_UCHAR(pDisk->d_Flags, (UCHAR*)pDisk->d_pATARegAlt + ATA_REG_ALT_STATUS);
    } except (GetExceptionCode() == STATUS_ACCESS_VIOLATION ?
            EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
        DEBUGMSG(ZONE_IO|ZONE_ERROR, (TEXT("ATADISK:PcmciaIntr - exception!\r\n")));
        error = ERROR_GEN_FAILURE;
    }
    if (error != ERROR_SUCCESS) {
        return;
    }

    if (ATAStatus != AltStatus) {
        DEBUGMSG(ZONE_IO|ZONE_PCMCIA,
            (TEXT("ATADISK:PcmciaIntr - ATAStatus(0x%x) != AltStatus(0x%x)\r\n"),
            ATAStatus, AltStatus));
    }

    if (ATAStatus != pDisk->d_DiskStatus) {
        pDisk->d_DiskStatus = ATAStatus;

#ifdef DEBUG
    if (ZONE_IO) {
        szStatus[0] = 0;
        //
        // Display ATA status register
        //
        if (ATAStatus & ATA_STATUS_ERROR) {
            _tcscat(szStatus, TEXT("ERROR "));
        }
        if (ATAStatus & ATA_STATUS_CORRECTED_ERROR) {
            _tcscat(szStatus, TEXT("CORRECTED_ERROR "));
        }
        if (ATAStatus & ATA_STATUS_DATA_REQ) {
            _tcscat(szStatus, TEXT("DATA_REQ "));
        }
        if (ATAStatus & ATA_STATUS_SEEK_DONE) {
            _tcscat(szStatus, TEXT("SEEK_DONE "));
        }
        if (ATAStatus & ATA_STATUS_WRITE_FAULT) {
            _tcscat(szStatus, TEXT("WRITE_FAULT "));
        }
        if (ATAStatus & ATA_STATUS_READY) {
            _tcscat(szStatus, TEXT("READY "));
        }
        if (ATAStatus & ATA_STATUS_BUSY) {
            _tcscat(szStatus, TEXT("BUSY "));
        }
        DEBUGMSG(ZONE_IO, (TEXT("ATADISK:PcmciaIntr - ATA Status = %s\r\n"),

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -