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

📄 cmmd_ata.c

📁 STi5518机顶盒ATAPI源代码!绝对超值!
💻 C
📖 第 1 页 / 共 2 页
字号:
/************************************************************************Source file name : cmmd_ata.cDescription: Implementation of the ATA Command Interface intermediate module            following the API Design Document v0.9.0 of the ATAPI driver.COPYRIGHT (C) STMicroelectronics  200031-08-00  Added an extra 400 ns delay at the end of the PIO in protocol           to allow slow drives as CD-ROM's to update their status           registers. (MV)          ************************************************************************//*Includes-------------------------------------------------------------*/#include <stdio.h>#include <string.h>#include "stlite.h"#include "statapi.h"#include "stsys.h"#include "hal_atapi.h"#include "ata.h"#include "stcommon.h"#include "sttbx.h"/*Private Types--------------------------------------------------------*//*Private Constants----------------------------------------------------*//*Private Variables----------------------------------------------------*/extern U32 intcount;extern U32 inttrace[15];/* Kind of messy, but since we need to get status differently for  * an extended command, and we can't expect the user to tell us what type * a command was... */BOOL LastCommandExtended = FALSE;/*Private Macros-------------------------------------------------------*/#if defined(ST_5512)     #define ATAPI_DATA 0x60080000 #elif defined(ST_5508) || defined(ST_5518)     #define ATAPI_DATA 0x50200000 #endif/*Private functions prototypes-----------------------------------------*/static void GetCmdStatus(ata_ControlBlock_t *Ata_p,                         STATAPI_CmdStatus_t *Stat_p);static void ata_cmd_WriteRegs(ata_ControlBlock_t *Ata_p,                                        ata_Cmd_t *Cmd_p);extern BOOL Trace;/*Functions------------------------------------------------------------*//************************************************************************Name: ata_cmd_WriteRegsDescription: Programs registers for sector count/number, cylinder, etc.Parameters: Two params:            Ata_p : Pointer to the ATA control block            Cmd_p : Pointer to a command structureReturn: none           ************************************************************************/static void ata_cmd_WriteRegs(ata_ControlBlock_t *Ata_p,                                        ata_Cmd_t *Cmd_p){    /* Feature is reserved with extended commands, so don't write. */    if ((Cmd_p->CmdType & ATA_EXT_BIT) == 0)           hal_RegOutByte(Ata_p->HalHndl, ATA_REG_FEATURE, Cmd_p->Feature);#if defined(STTBX_PRINT)    if (Trace == TRUE)    {        STTBX_Print(("Feature: %i\n", Cmd_p->Feature));        STTBX_Print(("SC: 0x%x\nSN: %i\nCL: %i\nCH: %i\n", Cmd_p->SecCount,                 Cmd_p->SecNum, Cmd_p->CylLow, Cmd_p->CylHigh));        STTBX_Print(("DH: %i\n", Cmd_p->DevHead));        STTBX_Print(("CC: 0x%02x\n", Cmd_p->CommandCode));    }#endif    hal_RegOutByte(Ata_p->HalHndl, ATA_REG_SECCOUNT, Cmd_p->SecCount);    hal_RegOutByte(Ata_p->HalHndl, ATA_REG_SECNUM, Cmd_p->SecNum);    hal_RegOutByte(Ata_p->HalHndl, ATA_REG_CYLLOW, Cmd_p->CylLow);    hal_RegOutByte(Ata_p->HalHndl, ATA_REG_CYLHIGH, Cmd_p->CylHigh);        /* "first" write of devhead is also reserved */    if ((Cmd_p->CmdType & ATA_EXT_BIT) == 0)           hal_RegOutByte(Ata_p->HalHndl, ATA_REG_DEVHEAD, Cmd_p->DevHead);    /* If it's an extended command, now write the other bits and head. */    if ((Cmd_p->CmdType & ATA_EXT_BIT) != 0)    {        LastCommandExtended = TRUE;                hal_RegOutByte(Ata_p->HalHndl, ATA_REG_SECCOUNT, Cmd_p->SecCount2);        hal_RegOutByte(Ata_p->HalHndl, ATA_REG_SECNUM, Cmd_p->SecNum2);        hal_RegOutByte(Ata_p->HalHndl, ATA_REG_CYLLOW, Cmd_p->CylLow2);        hal_RegOutByte(Ata_p->HalHndl, ATA_REG_CYLHIGH, Cmd_p->CylHigh2);        hal_RegOutByte(Ata_p->HalHndl, ATA_REG_DEVHEAD, Cmd_p->DevHead);    }    else        LastCommandExtended = FALSE;}/************************************************************************Name: ata_cmd_NoDataDescription: executes a non data command. The device is already selected              no parameters check is performed. We totally trust on the caller Parameters: Two params:            Ata_p : Pointer to the ATA control block            Cmd_p : Pointer to a command structureReturn:     TRUE:  Extended error is set            FALSE: No error                     ************************************************************************/BOOL ata_cmd_NoData(ata_ControlBlock_t *Ata_p, ata_Cmd_t *Cmd_p){    DU8 status;        /* First we write the registers */    ata_cmd_WriteRegs(Ata_p, Cmd_p);       if(WaitForBit(Ata_p->HalHndl, ATA_REG_ALTSTAT, DRDY_BIT_MASK, DRDY_BIT_MASK))    {        STTBX_Print(("Device not ready 0x26\n"));        Ata_p->LastExtendedErrorCode= 0x26;          GetCmdStatus(Ata_p,Cmd_p->Stat.CmdStat);        return TRUE;    }    /* Finally write the command */    hal_RegOutByte(Ata_p->HalHndl,ATA_REG_COMMAND, Cmd_p->CommandCode);    #if  ATAPI_USING_INTERRUPTS    if(hal_AwaitInt(Ata_p->HalHndl,INT_TIMEOUT))    {        STTBX_Print(("Not interrupt 0x22\n"));        Ata_p->LastExtendedErrorCode= 0x22;        GetCmdStatus(Ata_p,Cmd_p->Stat.CmdStat);        return TRUE;    }#else    WAIT400NS;    if(WaitForBit(Ata_p->HalHndl,ATA_REG_ALTSTAT,BSY_BIT_MASK,0))    {        STTBX_Print(("BSY not set, 0x23\n"));        Ata_p->LastExtendedErrorCode= 0x23;        GetCmdStatus(Ata_p,Cmd_p->Stat.CmdStat);        return TRUE;    }#endif /* ATAPI_USING_INTERRUPTS */         /* Now Check the Status */    status= hal_RegInByte(Ata_p->HalHndl,ATA_REG_STATUS);        if( status & (BSY_BIT_MASK | DRQ_BIT_MASK| DF_BIT_MASK | ERR_BIT_MASK))    {        STTBX_Print(("Unwanted bit 0x21\n"));        Ata_p->LastExtendedErrorCode= 0x21;        GetCmdStatus(Ata_p,Cmd_p->Stat.CmdStat);        return TRUE;     }        GetCmdStatus(Ata_p,Cmd_p->Stat.CmdStat);    Ata_p->LastExtendedErrorCode= 0x00;    return FALSE;}/************************************************************************Name: ata_cmd_PioInDescription: executes a command with data transfer from the device              to the host via PIO.             The device is already selected, no parameters check             is performed. We totally trust on the caller               Parameters: Two params:            Ata_p : Pointer to the ATA control block            Cmd_p : Pointer to a command structureReturn:     TRUE:  Extended error is set            FALSE: No error                     ************************************************************************/BOOL ata_cmd_PioIn(ata_ControlBlock_t *Ata_p, ata_Cmd_t *Cmd_p){    volatile U8 status;    BOOL Error=FALSE;    U16* Data_p;      U32 loopcount = 0;    *Cmd_p->BytesRW =0;    Data_p= (U16*) Cmd_p->DataBuffer;       /* First we write the registers */     ata_cmd_WriteRegs(Ata_p, Cmd_p);        if(WaitForBit(Ata_p->HalHndl,ATA_REG_ALTSTAT,DRDY_BIT_MASK,DRDY_BIT_MASK))    {        STTBX_Print(("Device not ready 0x36\n"));        Ata_p->LastExtendedErrorCode= 0x36;          GetCmdStatus(Ata_p,Cmd_p->Stat.CmdStat);                   return TRUE;    }        /* Finally write the command */    hal_RegOutByte(Ata_p->HalHndl, ATA_REG_COMMAND, Cmd_p->CommandCode);    WAIT400NS;     /* Transfering Data: Read Loop*/    while (TRUE)    {   #if  ATAPI_USING_INTERRUPTS        if(hal_AwaitInt(Ata_p->HalHndl, INT_TIMEOUT))        {            STTBX_Print(("No interrupt 0x34\n"));            GetCmdStatus(Ata_p, Cmd_p->Stat.CmdStat);            STTBX_Print(("intcount: %i\n", intcount));            STTBX_Print(("loopcount: %i\n", loopcount));            STTBX_Print(("Sectors remaining: %i\n", Cmd_p->SecCount));            if (1)            {                U32 i;                for (i = 0; i < intcount; i++)                    STTBX_Print(("%i %04x\n", i, inttrace[i]));            }            Ata_p->LastExtendedErrorCode= 0x34;            Error= TRUE;            break;        }        intcount = 0;   #endif        if(WaitForBit(Ata_p->HalHndl, ATA_REG_ALTSTAT, BSY_BIT_MASK, 0))        {            Ata_p->LastExtendedErrorCode= 0x35;              Error= TRUE;            break;        }        /* Now check the status*/        status=hal_RegInByte(Ata_p->HalHndl,ATA_REG_STATUS);        /* Checking if Busy =0 and DRQ=1 in order to           enter into the transfer phase                    */        if ((status & (BSY_BIT_MASK | DRQ_BIT_MASK)) == DRQ_BIT_MASK)        {               /* Read one DRQ sector*/#ifdef BMDMA_ENABLE                                                                 ATA_BMDMA((U8*)ATAPI_DATA,                       (U8*)Data_p,                      Cmd_p->MultiCnt * SECTOR_BSIZE);            *Cmd_p->BytesRW += (Cmd_p->MultiCnt * SECTOR_BSIZE);            Data_p += (Cmd_p->MultiCnt * SECTOR_WSIZE);#else            hal_RegInBlock(Ata_p->HalHndl,                           Data_p,                           SECTOR_BSIZE * Cmd_p->MultiCnt,                           Cmd_p->UseDMA);            Data_p += SECTOR_WSIZE * Cmd_p->MultiCnt;            *Cmd_p->BytesRW += SECTOR_BSIZE * Cmd_p->MultiCnt;#endif            Cmd_p->SecCount = Cmd_p->SecCount - Cmd_p->MultiCnt;            }        else        {            /* BSY 0, DRQ 0 => error */            status=hal_RegInByte(Ata_p->HalHndl,ATA_REG_STATUS);            if((status & (ERR_BIT_MASK | DF_BIT_MASK)) != 0)            {                STTBX_Print(("Unwanted bits; 0x%02x; 0x31\n", status));                STTBX_Print(("Feature: %i\n", Cmd_p->Feature));                STTBX_Print(("SC: 0x%x\nSN: %i\nCL: %i\nCH: %i\n", Cmd_p->SecCount,                     Cmd_p->SecNum, Cmd_p->CylLow, Cmd_p->CylHigh));                STTBX_Print(("DH: %i\n", Cmd_p->DevHead));                STTBX_Print(("CC: 0x%02x\n", Cmd_p->CommandCode));                Ata_p->LastExtendedErrorCode= 0x31;                  Error= TRUE;                break;            }        }                if(Cmd_p->SecCount<1)        {               /* Since the drive has transferred all of the requested sectors               without error, the drive should not have BUSY, DEVICE FAULT,               DATA REQUEST or ERROR active now.*/            WAIT400NS;            status = hal_RegInByte(Ata_p->HalHndl,ATA_REG_STATUS);            if (status & (BSY_BIT_MASK | ERR_BIT_MASK | DF_BIT_MASK | DRQ_BIT_MASK))            {                STTBX_Print(("Unwanted bits; 0x%02x; 0x33\n", status));                Ata_p->LastExtendedErrorCode= 0x33;                  Error= TRUE;                break;            }            /* All sectors have been read without error, exit */            Ata_p->LastExtendedErrorCode= 0x00;            break;        }        /*End of read loop*/        loopcount++;    }    /*read the output registers and store them in the cmd status structure*/    GetCmdStatus(Ata_p, Cmd_p->Stat.CmdStat);    return Error;    }   /************************************************************************Name: ata_cmd_PioOutDescription: executes a command with data transfer from the host              to the device via PIO.             The device is already selected, no parameters check             is performed. We totally trust on the caller               Parameters: Two params:            Ata_p : Pointer to the ATA control block            Cmd_p : Pointer to a command structureReturn:     TRUE:  Extended error is set            FALSE: No error                     ************************************************************************/BOOL ata_cmd_PioOut(ata_ControlBlock_t *Ata_p, ata_Cmd_t *Cmd_p){    volatile U8 status;    BOOL Error=FALSE;    U16* Data_p;       *Cmd_p->BytesRW =0;    Data_p= (U16*) Cmd_p->DataBuffer;    /* First we write the registers */     ata_cmd_WriteRegs(Ata_p, Cmd_p);       if(WaitForBit(Ata_p->HalHndl,ATA_REG_ALTSTAT,DRDY_BIT_MASK,DRDY_BIT_MASK))    {        STTBX_Print(("Device not ready 0x46\n"));        Ata_p->LastExtendedErrorCode= 0x46;          GetCmdStatus(Ata_p,Cmd_p->Stat.CmdStat);        return TRUE;    }    /* Finally write the command */    hal_RegOutByte(Ata_p->HalHndl,ATA_REG_COMMAND, Cmd_p->CommandCode);        WAIT400NS;            if(WaitForBit(Ata_p->HalHndl,ATA_REG_STATUS,BSY_BIT_MASK,0))    {        STTBX_Print(("Device busy 0x45\n"));        Ata_p->LastExtendedErrorCode= 0x45;          return  TRUE;    }    /* Transfering Data: Write Loop*/    while (TRUE)    {                intcount = 0;           /* Check the status*/                status=hal_RegInByte(Ata_p->HalHndl,ATA_REG_STATUS);                /* Checking if Busy =0 and DRQ=1 in order to           enter into the transfer phase                    */        if((status & ( BSY_BIT_MASK | DRQ_BIT_MASK))== DRQ_BIT_MASK)        {   /* Write one DRQ sector*/            #ifdef BMDMA_ENABLE                                  ATA_BMDMA((U8*)Data_p,                      (U8*)ATAPI_DATA,                      Cmd_p->MultiCnt * SECTOR_BSIZE);            *Cmd_p->BytesRW += (Cmd_p->MultiCnt * SECTOR_BSIZE);            Data_p += (Cmd_p->MultiCnt * SECTOR_WSIZE);#else            hal_RegOutBlock(Ata_p->HalHndl,                            Data_p,                            SECTOR_BSIZE * Cmd_p->MultiCnt,                            Cmd_p->UseDMA);            Data_p += SECTOR_WSIZE * Cmd_p->MultiCnt;			               *Cmd_p->BytesRW += SECTOR_BSIZE * Cmd_p->MultiCnt;            #endif                             Cmd_p->SecCount = Cmd_p->SecCount - Cmd_p->MultiCnt;        }        if (Cmd_p->SecCount < 1)        {   #if  ATAPI_USING_INTERRUPTS            if(hal_AwaitInt(Ata_p->HalHndl, INT_TIMEOUT))            {                status = hal_RegInByte(Ata_p->HalHndl, ATA_REG_STATUS);                STTBX_Print(("int timeout; status: 0x%02x; 0x44\n", status));                Ata_p->LastExtendedErrorCode = 0x44;                Error = TRUE;                break;            }#else            WAIT400NS;            if (WaitForBit(Ata_p->HalHndl, ATA_REG_ALTSTAT, BSY_BIT_MASK, 0))            {                Ata_p->LastExtendedErrorCode= 0x45;                  Error= TRUE;                break;            }#endif /* ATAPI_USING_INTERRUPTS */                        /*Since the drive has transferred all of the requested sectors              without error, the drive should not have BUSY, DEVICE FAULT,              DATA REQUEST or ERROR active now.*/            WAIT400NS;            status= hal_RegInByte(Ata_p->HalHndl,ATA_REG_STATUS);            if(status & (BSY_BIT_MASK | ERR_BIT_MASK | DF_BIT_MASK | DRQ_BIT_MASK))            {                STTBX_Print(("Unwanted bits; 0x%02x; 0x43\n", status));                Ata_p->LastExtendedErrorCode= 0x43;                  Error= TRUE;

⌨️ 快捷键说明

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