Re[2]: Отключается режим DMA для IDE контроллера (драйвер фи
От: Srv  
Дата: 27.04.06 07:15
Оценка:
Здравствуйте, Alter_, Вы писали:

A_>1. как именно вы шлете команды ?


вот так шлю


BOOL CheckHDDState(ULONG StateReg, ULONG TimeOut, UCHAR SetFlags, UCHAR ClearFlags, ULONG msFreq)
{
    UINT64    Ticks = QueryTickCount(msFreq);
    UCHAR    Value, V, IsFirst = TRUE;
    UCHAR    Flags = SetFlags | ClearFlags;

    do
    {
        Value = _INP(StateReg);
        if ((Value & Flags) == SetFlags)
            return TRUE;
    }
    while ((QueryTickCount(msFreq) - Ticks) <= TimeOut);

    return FALSE;
}

BOOL WaitForDeviceReady(ULONG BasePort, ULONG Disk, ULONG msFreq)
{
    if (!CheckHDDState(BasePort + 7, 3 * 1000, 0, BSY, msFreq))
        return FALSE;
    _OUTP(BasePort + 6, CB_DH_SELECT | (Disk << 4));
    if (CheckHDDState(BasePort + 7, 3, DRDY, BSY|DF, msFreq))
        return TRUE; 
    return FALSE;
}


VOID DELAY400NS(ULONG CtrlPort)
{
    _INP(CtrlPort);
    _INP(CtrlPort);
    _INP(CtrlPort);
    _INP(CtrlPort);
}

VOID ReadDataFromDevice(ULONG BasePort, VOID* DeviceData, ULONG Len)
{
    _asm
    {
        push edi
        mov  edi, DeviceData
        mov  ecx, Len
        mov  edx, BasePort
        cld
        rep  insw
        pop  edi
    }
}

BOOL DO_SMART_RCV_DRIVE_DATA(PDEVICE_EXTENSION pDevExt, PSENDCMDINPARAMS SCIP, PSENDCMDOUTPARAMS SCOP)
{
    PIDEREGS    IDERegs;
    ULONG        BasePort = 0, CtrlPort = 0;
    ULONG        BasePort_ = 0;
    BOOL        Result;
    ULONG        i;

    BasePort = pDevExt->portconf.BasePort;
    CtrlPort = pDevExt->portconf.CtrlPort;

    if ((BasePort == 0) || (CtrlPort == 0))
        return FALSE;

    if (SCIP->bDriveNumber >= pDevExt->DisksCount)// Проверить номер переданного диска
        return FALSE;

    if (!WaitForDeviceReady(BasePort, SCIP->bDriveNumber, pDevExt->msFreq))// Ждать пока контроллер не освободится
        return FALSE;

    _OUTP(CtrlPort, CB_DC_NIEN);// Запретить прерывания

    IDERegs = &SCIP->irDriveRegs;// Записать параметры переданной команды
    BasePort_ = BasePort;
    _OUTP(++BasePort_, IDERegs->bFeaturesReg);
    _OUTP(++BasePort_, IDERegs->bSectorCountReg);
    _OUTP(++BasePort_, IDERegs->bSectorNumberReg);
    _OUTP(++BasePort_, IDERegs->bCylLowReg);
    _OUTP(++BasePort_, IDERegs->bCylHighReg);
    _OUTP(++BasePort_, IDERegs->bDriveHeadReg);
    _OUTP(++BasePort_, IDERegs->bCommandReg);// Послать переданную команду

    Result = CheckHDDState(BasePort_, CMD_TIMEOUT, DRDY|DRQ, BSY|DF|ERR, pDevExt->msFreq);// Ждать готовности команды
    if (Result)
        ReadDataFromDevice(BasePort, &SCOP->bBuffer, SECTOR_SIZE/2);// Считать результат выполнения команды
    _OUTP(CtrlPort, 0);// Разрешить прерывания

    return Result;
}


Думаю из исходника понятно как это происходит вызываю DO_SMART_RCV_DRIVE_DATA...
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.