📄 statapi.c
字号:
/************************************************************************COPYRIGHT (C) STMicroelectronics 2000Source file name : statapi.cATA/ATAPI driver.************************************************************************//* Includes --------------------------------------------------------------*/#include <stdio.h>#include <string.h>#include "stlite.h"#include "sttbx.h"#include "stevt.h"#include "statapi.h"#include "hal_atapi.h"#include "ata.h"/* Defines */#define STATAPI_HARD_RESET_ID 0 /* Offsets for events array */#define STATAPI_SOFT_RESET_ID 1#define STATAPI_CMD_COMPLETE_ID 2#define STATAPI_PKT_COMPLETE_ID 3/* Bus Access Task defines */#define BAT_STACK_SIZE 4096#define BAT_PRIORITY MIN_USER_PRIORITY#define CLOSING_TIMEOUT 20000#define SET_MULTIPLE_MODE 0xC6/*Private Types--------------------------------------------------------*//*Private Constants----------------------------------------------------*/static const ST_Revision_t Revision = "STATAPI-REL_1.3.0";/*Private Variables----------------------------------------------------*/static ata_ControlBlock_t *ATAHandle;/* For bus access task */static tdesc_t BusTaskDesc;static unsigned char *BusTaskStack; /* 0 1 2 3 4 5 6 7 8 9 */static U8 CmdCodes[49]={0xC0,0x03,0x87,0xCD,0x38,0xE5,0x08,0x90,0xE7,0xEC, 0xA1,0xE3,0xE1,0x91,0xED,0x00,0xA0,0xE4,0xC8,0xC7, 0xC4,0x20,0x40,0x70,0xEF,0xC6,0xE6,0xE2,0xE0,0xE8, 0xCA,0xCC,0xC5,0x30,0xF1,0xF6,0xF2,0x24,0x25,0x26, 0x27,0x29,0x34,0x35,0x36,0x37,0x39,0x42,0xEA}; /* 0 1 2 3 4 5 6 7 8 9 */ static U8 PktCodes[62]={ 0xA1,0x5B,0x39,0x2C,0x35,0x04,0x46,0x4A,0xAC,0x12, 0xA6,0x36,0x4C,0x4D,0xBD,0x55,0x5A,0x4B,0x45,0x47, 0xBC,0x34,0x1E,0x28,0xA8,0x3C,0x25,0xBE,0xB9,0x51, 0xAD,0x23,0x44,0x42,0x43,0x52,0x1C,0x17,0x57,0x58, 0xA4,0x03,0x16,0x56,0x53,0xBA,0x2B,0x5D,0x1D,0xBF, 0xA2,0xA3,0x54,0xA7,0xB6,0x1B,0x4E,0x00,0x2F,0x2A, 0x2E,0x3B};/* DMA/PIO timing values, specified in 10ns units. These will be rescaled * at init (for 5514). Taken from Table 10, HDDI functional spec, * ADCS #7180863. */#if defined(ST_5514)/* U32 InitSequenceDelay; U32 IoRdySetupDelay; U32 WaitTime; U32 WriteDelay; U32 ReadDelay; U32 AddressHoldDelay; U32 WriteEnableOutDelay; U32 WriteRecoverDelay; U32 ReadRecoverDelay;*/static STATAPI_PioTiming_t PioTimingDefaults[5] = { /* Mode 0 */ { 7, 4, WAIT, 24, 24, 2, 1, 22, 22 }, /* Mode 1 */ { 5, 4, WAIT, 24, 24, 2, 0, 3, 3 }, /* Mode 2 *//* { 3, 4, WAIT, 24, 24, 1, 1, 0, 1 }, */ { 3, 4, WAIT, 5, 5, 1, 1, 10, 11 }, /* Mode 3 */ { 3, 4, WAIT, 3, 3, 1, 0, 7, 7 }, /* Mode 4 */ { 3, 4, WAIT, 2, 2, 1, 0, 4, 4 } };/* U32 NotDIoRwAssertedT; U32 WriteDataHoldT; U32 DIoRwToDMAckHoldT; U32 NotDIoRNegatedT; U32 NotDIoWNegatedT; U32 CsToNotDIoRwT; U32 CsHoldT;*/static STATAPI_MwDmaTiming_t MwDmaTimingDefaults[3] = { /* Mode 0 */ { 25, 2, 2, 23, 23, 5, 2 }, /* Mode 1 */ { 9, 2, 1, 7, 7, 3, 3 }, /* Mode 2 */ { 7, 1, 1, 5, 5, 3, 3 } };/* U32 AckT; U32 InitEnvelopeT; U32 MinAssertStopNegateT; U32 MinInterlockT; U32 LimitedInterlockT; U32 DataOutSetupT; U32 DataOutHoldT; U32 HostStrobeToStopSetupT; U32 ReadyToFinalStrobeT;*/ /* Timing values from Stephane Cattaneo, 28/11/01, for 5514 cut 3. */ /* May need changing for other cuts. */static STATAPI_UltraDmaTiming_t UltraDmaTimingDefaults[5] = { /* Mode 0 */ { 3, 3, 16, 2, 15, 11, 1, 5, 0 }, /* Mode 1 */ { 3, 3, 13, 2, 15, 7, 1, 5, 0 }, /* Mode 2 */ { 3, 3, 10, 2, 15, 5, 1, 5, 0 }, /* Mode 3 */ { 3, 3, 10, 2, 10, 3, 1, 5, 0 }, /* Mode 4 */ { 3, 3, 10, 2, 10, 2, 1, 5, 0 } };#endif/* In Packet Transfers 4 K per DRQ assertion */ #define BYTE_COUNT_LOW 0x00#define BYTE_COUNT_HIGH 0x10/*Private Macros-------------------------------------------------------*//*Private functions prototypes-----------------------------------------*/static ST_ErrorCode_t RegisterATAEvents(const ST_DeviceName_t EvtHandlerName, STEVT_Handle_t *EvtHndl);static ST_ErrorCode_t GetDeviceCapabilities(STATAPI_DeviceAddr_t DevAddress); static ST_ErrorCode_t UnregisterATAEvents( STEVT_Handle_t EvtHndl );static BOOL IsOutsideRange( U32 ValuePassed, U32 LowerBound, U32 UpperBound );static BOOL ParseIdentifyBlock(STATAPI_DeviceAddr_t DevNo, U8 *Data, STATAPI_Params_t *Params, ata_DevCtrlBlock_t *DevHndl);static U8 ChooseProtocolCmd(U16 CommandCode, ata_DevCtrlBlock_t *Dev);#if defined(ST_5514)static void CalculateTiming(U32 Mult, U32 Div);#endif /* Bus Access Task */static void BusAccessTask(void);/******************************************************************************* PUBLIC DRIVER FUNCTIONS******************************************************************************//****************************************************************************Name : STATAPI Init()Description : Initializes the ATAPI driver and the devices connected in the busParameters : ST_DeviceName_t DeviceName ATAPI driver name STATAPI_InitParams_t InitParams Params structure Return Value : ST_NO_ERROR No error. ST_ERROR_ALREADY_INITIALIZED The device name has already been initialized. ST_ERROR_BAD_PARAMETER One or more of the parameters are invalid. ST_ERROR_INTERRUPT_INSTALL Unable to install interrupts. ST_ERROR_NO_MEMORY Unable to allocate required memory. ****************************************************************************/ST_ErrorCode_t STATAPI_Init(const ST_DeviceName_t DeviceName, const STATAPI_InitParams_t *InitParams){ ST_ErrorCode_t rVal= ST_NO_ERROR; volatile S32 TaskReturn; /* Check parameters */ if( ATAHandle != NULL ) /* prior Init w/o Term? */ { return( ST_ERROR_ALREADY_INITIALIZED ); } if( ( DeviceName == NULL ) || /* NULL Name ptr? */ ( InitParams == NULL ) || /* NULL structure ptr? */ ( DeviceName[0] == '\0' ) || /* Device Name undefined? */ ( strlen( DeviceName ) >= ST_MAX_DEVICE_NAME ) ) /* string too long? */ { return( ST_ERROR_BAD_PARAMETER ); } if ((InitParams->DriverPartition == NULL) || (InitParams->BaseAddress == NULL) || (InitParams->HW_ResetAddress == NULL)) { return( ST_ERROR_BAD_PARAMETER ); } if(IsOutsideRange( InitParams->DeviceType, STATAPI_EMI_PIO4, STATAPI_HDD_UDMA4)) { return( ST_ERROR_BAD_PARAMETER ); } /*--------------End of parameters check -------------------*/ /*Allocate High level Handle*/ ATAHandle=(ata_ControlBlock_t*)memory_allocate(InitParams->DriverPartition,sizeof(ata_ControlBlock_t)); if(ATAHandle==NULL) { return ST_ERROR_NO_MEMORY; } /* Allocate memory for bus access task stack */ BusTaskStack = memory_allocate(InitParams->DriverPartition, BAT_STACK_SIZE); if (BusTaskStack == NULL) { memory_deallocate(InitParams->DriverPartition, ATAHandle); return ST_ERROR_NO_MEMORY; } /*Init hal*/ if( hal_Init(InitParams,&ATAHandle->HalHndl)) { memory_deallocate(InitParams->DriverPartition, ATAHandle); return ST_ERROR_INTERRUPT_INSTALL; } /* Setup initial values */ strcpy( ATAHandle->DeviceName,DeviceName); strcpy( ATAHandle->EvtDeviceName,InitParams->EVTDeviceName); ATAHandle->DriverPartition = InitParams->DriverPartition; ATAHandle->UsedHandles = 0; ATAHandle->DeviceSelected = DEVICE_0; ATAHandle->BusBusy = FALSE; ATAHandle->Terminate = FALSE; ATAHandle->LastExtendedErrorCode = 0x00; ATAHandle->Handles[0].Opened= FALSE; ATAHandle->Handles[1].Opened= FALSE; /* Register the ATA events*/ rVal= RegisterATAEvents(InitParams->EVTDeviceName,&ATAHandle->EvtHndl); if(rVal != ST_NO_ERROR) { hal_Term(ATAHandle->HalHndl); memory_deallocate(InitParams->DriverPartition, ATAHandle); ATAHandle=NULL; return ST_ERROR_BAD_PARAMETER; } semaphore_init_fifo_timeout(&ATAHandle->BusMutexSemaphore,1); semaphore_init_fifo_timeout(&ATAHandle->BATSemaphore,0); /* Init interface */ if(ata_ctrl_HardReset(ATAHandle)) { /* Clean and exit */ UnregisterATAEvents( ATAHandle->EvtHndl ); semaphore_delete(&ATAHandle->BusMutexSemaphore); semaphore_delete(&ATAHandle->BATSemaphore); hal_Term(ATAHandle->HalHndl); memory_deallocate(InitParams->DriverPartition, ATAHandle); memory_deallocate(InitParams->DriverPartition, BusTaskStack); ATAHandle= NULL; return STATAPI_ERROR_DEVICE_NOT_PRESENT; } /* Detect devices */ ata_ctrl_Probe(ATAHandle); /* Check that at least there is one */ if( (ATAHandle->DevInBus[0]==NONE_DEVICE)&& (ATAHandle->DevInBus[1]==NONE_DEVICE) ) { /* Clean and exit */ UnregisterATAEvents( ATAHandle->EvtHndl ); semaphore_delete(&ATAHandle->BusMutexSemaphore); semaphore_delete(&ATAHandle->BATSemaphore); hal_Term(ATAHandle->HalHndl); memory_deallocate(InitParams->DriverPartition, ATAHandle); memory_deallocate(InitParams->DriverPartition, BusTaskStack); ATAHandle= NULL; return STATAPI_ERROR_DEVICE_NOT_PRESENT; } ata_ctrl_HardReset(ATAHandle); /* 0 success, anything else failure */ TaskReturn = task_init( (void(*)(void *))BusAccessTask, NULL, BusTaskStack, BAT_STACK_SIZE, &ATAHandle->BAT, &BusTaskDesc, BAT_PRIORITY, "Bus Access Task", 0); if (TaskReturn != 0) { /* Clean and exit */ UnregisterATAEvents( ATAHandle->EvtHndl ); semaphore_delete(&ATAHandle->BusMutexSemaphore); semaphore_delete(&ATAHandle->BATSemaphore); hal_Term(ATAHandle->HalHndl); memory_deallocate(InitParams->DriverPartition, ATAHandle); memory_deallocate(InitParams->DriverPartition, BusTaskStack); ATAHandle= NULL; return ST_ERROR_NO_MEMORY; } /* Create semaphores to signal the end of internal command issuing; they * have to be created here, because functions such as softreset use them. */ semaphore_init_fifo_timeout(&ATAHandle->Handles[STATAPI_DEVICE_0].EndCmdSem, 0); semaphore_init_fifo_timeout(&ATAHandle->Handles[STATAPI_DEVICE_1].EndCmdSem, 0);#if defined(ST_5514) /* Calculate the timing frequencies for 5514. */ if (InitParams->DeviceType == STATAPI_HDD_UDMA4) { U32 Mult; Mult = InitParams->ClockFrequency; Mult /= 1000000; CalculateTiming(Mult, 100); } /* Start up in PIO mode 2 */ hal_SetPioMode(ATAHandle->HalHndl, STATAPI_PIO_MODE_2); hal_SetPioTiming(ATAHandle->HalHndl, &PioTimingDefaults[2]);#endif return ST_NO_ERROR; }/****************************************************************************Name : STATAPI Term()Description : Terminates the ATAPI driver and deallocate all the driver control structuresParameters : ST_DeviceName_t DeviceName ATAPI driver name STATAPI_InitParams_t InitParams Params structure Return Value : ST_NO_ERROR No error. ST_ERROR_OPEN_HANDLE Could not terminate the driver; not all handles have not been closed. ST_ERROR_INTERRUPT_UNINSTALL Unable to uninstall interrupts. ST_ERROR_UNKNOWN_DEVICE Invalid DeviceName. STATAPI_ERROR_TERMINATE_BAT Could not delete the Bus Access Task ****************************************************************************/ST_ErrorCode_t STATAPI_Term(const ST_DeviceName_t DeviceName, const STATAPI_TermParams_t *TermParams){ ST_ErrorCode_t rVal=ST_NO_ERROR; clock_t TO; task_t *TaskList[1]; ata_ControlBlock_t *Clean_p; if (strcmp(DeviceName, ATAHandle->DeviceName)) { return ST_ERROR_UNKNOWN_DEVICE; } if (TermParams == NULL) { return ST_ERROR_BAD_PARAMETER; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -