📄 tmfat32ide.c
字号:
/* * Copyright (C) 2003 Koninklijke Philips Electronics N.V., * All Rights Reserved. * * This source code and any compilation or derivative thereof is the * proprietary information of Koninklijke Philips Electronics N.V. * and is confidential in nature. * Under no circumstances is this software to be exposed to or placed * under an Open Source License of any type without the expressed * written permission of Koninklijke Philips Electronics N.V. * *----------------------------------------------------------*//*! * \file tmFat32Ide.c * * This file implements the IDE tmFat32 device driver API. * *//*----------------------------------------------------------- * * %version: ds08#8 % * instance: DS_4 * %date_created: Sun Nov 12 15:05:44 2006 % * */ //-----------------------------------------------------------------------------//-----------------------------------------------------------------------------// Standard include files://-----------------------------------------------------------------------------//#include <tmStdLib.h>#include <tmNxTypes.h>#include <tmDbg.h>#include <stdio.h>//-----------------------------------------------------------------------------// Project include files://-----------------------------------------------------------------------------//#include <stdlib.h>#include <tmml.h>#include <tmbslIde.h> // Ide BSL header#include <tmdlIde.h> // Ide DevLib header#include <tmosal.h>#include <tmArith.h>#include <tmSGList.h>#include <tmFat32.h>#include <tmFat32Debug.h>#include <tmFat32Device.h>#include <tmFat32Ide.h>//-----------------------------------------------------------------------------// Types and defines://-----------------------------------------------------------------------------#define SCRATCH_SECTORS 256 /* Optimized for IDE. */#define IDE_MAX_UNITS 4 /* TMDL_IDE_MAX_UNITS */#define TMFAT32_IDE_CACHE_ALIGN 64// Based on SCRATCH_SECTORS=256 use the following SGList sizes#define INPUT_SG_LIST_SIZE 44#define OUTPUT_SG_LISTG_SIZE 180#define MY_BUFSIZE (SCRATCH_SECTORS * TMBSL_IDE_SECTORSIZE + \ INPUT_SG_LIST_SIZE + OUTPUT_SG_LISTG_SIZE + \ TMFAT32_IDE_CACHE_ALIGN)//-----------------------------------------------------------------------------// Global data://-----------------------------------------------------------------------------//static tmFat32_Ide_t ide_device[IDE_MAX_UNITS];static UInt8 myBuffer[MY_BUFSIZE];static UInt8 *pScratchPad; // Cache-aligned scratch buffer//-----------------------------------------------------------------------------// Internal Prototypes://-----------------------------------------------------------------------------//static void get_ata_string(char *s, char *d, int len);static tmErrorCode_t tmFat32_Ide_Init (ptmFat32_Dev_t p);static tmErrorCode_t tmFat32_Ide_Term (ptmFat32_Dev_t p);static tmErrorCode_t tmFat32_Ide_Read_Sectors ( ptmFat32_Dev_t p, // I: Pointer to tmFat32_Dev_t structure UInt64 sector, // I: Starting sector number UInt32 count, // I: Number of sectors UInt8 * buffer // 0: Pointer to buffer to receive data );static tmErrorCode_t tmFat32_Ide_Write_Sectors ( ptmFat32_Dev_t p, // I: Pointer to tmFat32_Dev_t structure UInt64 sector, // I: Starting sector number UInt32 count, // I: Number of sectors UInt8 * buffer // I: Pointer to buffer containing data );static void ideCallbackFunction(UInt32 events, void* pData, UInt32 userData);static tmErrorCode_t CreateSGLists( ptmFat32_Ide_t p, tmutilSGList_t *pSGListInput, // I: The input SG List to be created tmutilSGList_t *pSGListOutput, // I: The output SG List to be created UInt32 nrSectors, UInt8* Buffer );static tmErrorCode_t DestroySGLists( ptmFat32_Ide_t p, tmutilSGList_t *pSGListInput, // I: The input SG List to be destroyd tmutilSGList_t *pSGListOutput // I: The input SG List to be destroyd );//-----------------------------------------------------------------------------// Internal Functions//-----------------------------------------------------------------------------//// Get string data from ATA IDENTIFY DEVICE results. Length must be// even. The data is byte-swapped.static void get_ata_string(char *s, char *d, int len){ int i; if (len & 1) { *d = 0; return; } for (i = 0; i < len; i++) { if (i & 1) *d++ = s[i - 1]; else *d++ = s[i + 1]; } *d = 0;}static void ideCallbackFunction( UInt32 events, void* pData, UInt32 userData){ tmErrorCode_t errorCode; ptmFat32_Ide_t p = (ptmFat32_Ide_t) userData; (void) events; (void) pData; // Now release the semaphore which the main program is waiting for errorCode = tmosalSemRelease(p->semHandle); if ( errorCode ) { TMFAT_DEBUG1("Semaphore Release Err 0x%x\n",errorCode); }} // ideCallbackFunctionstatic tmErrorCode_tCreateSGLists( ptmFat32_Ide_t p, tmutilSGList_t *pSGListInput, // I: The input SG List to be created tmutilSGList_t *pSGListOutput, // I: The output SG List to be created UInt32 nrSectors, UInt8* Buffer){ tmErrorCode_t errorCode = TM_OK; memset(p->pMemorySGListInput, 0, p->inputSGListSize); tmutilSGListCreate( p->pMemorySGListInput, 1, pSGListInput ); memset(p->pMemorySGListOutput, 0, p->outputSListGSize); tmutilSGListCreate( p->pMemorySGListOutput, p->nrUnitsOutputSGList, pSGListOutput ); tmutilSGListAppend( *pSGListInput, Buffer, nrSectors * TMBSL_IDE_SECTORSIZE); return errorCode;}//-----------------------------------------------------------------------------// FUNCTION: DestroySGLists://// DESCRIPTION: This function destroys the SG lists for the test.//// RETURN: None//// NOTES: None//-----------------------------------------------------------------------------static tmErrorCode_tDestroySGLists( ptmFat32_Ide_t p, tmutilSGList_t *pSGListInput, // I: The input SG List to be destroyd tmutilSGList_t *pSGListOutput // I: The input SG List to be destroyd){ tmErrorCode_t errorCode = TM_OK; // Clear the input SG list tmutilSGListClear( *pSGListInput ); // Destroy the input SG list tmutilSGListDestroy( *pSGListInput, &p->pMemorySGListInput); // Clear the output SG list tmutilSGListClear( *pSGListOutput ); // Destroy the output SG list tmutilSGListDestroy( *pSGListOutput, &p->pMemorySGListOutput); return errorCode;} // DestroySGLists//-----------------------------------------------------------------------------// FUNCTION: tmFat32_Ide_Init//// DESCRIPTION://// RETURN: tmErrorCode_t: Status of operation (TM_OK = PASS)//// NOTES://-----------------------------------------------------------------------------//static tmErrorCode_ttmFat32_Ide_Init ( ptmFat32_Dev_t d // IO: Pointer to tmFat32_Dev_t structure ){ tmErrorCode_t errorCode; ptmdlIdeInstanceSetup_t pideDevSetup; UInt32 userData; UInt8 *data_ptr; UInt16 *p16; tmdlIdeDeviceInfo IdeDeviceInfo; ptmFat32_Ide_t p; Bool supportsLBA; char serial_number[20+1]; char firmware_rev[8+1]; char model[40+1]; Bool supportsWriteCache; Bool supportsReadLookAhead; Bool supportsPowerManagement; Bool supportsPowerupInStandby; Bool supportsMediaStatusNotification; TMFAT_ASSERT (d != Null); p = &ide_device[d->unit]; p->syncIO = d->syncIO; TMFAT_DEBUG2("Using %ssynchronous I/O for unit %d\n", (d->syncIO == False) ? "a" : "", d->unit); if (p->init_count > 0) { d->type = p->common.type; d->lbaMax = p->common.lbaMax; d->bytesPerSector = p->common.bytesPerSector; d->devInstance = p->common.devInstance; p->init_count++; return TM_OK; }// TMFAT_DEBUG0("ATA_init_Driver\n"); pScratchPad = (pVoid)(((UInt32)&myBuffer[0] / TMFAT32_IDE_CACHE_ALIGN) * TMFAT32_IDE_CACHE_ALIGN + TMFAT32_IDE_CACHE_ALIGN); p->pMemorySGListInput = pScratchPad + SCRATCH_SECTORS * TMBSL_IDE_SECTORSIZE; p->pMemorySGListOutput = (pVoid) ((UInt32) p->pMemorySGListInput + p->inputSGListSize);// TMFAT_DEBUG2("Trying tmdlIdeOpenM for unit %d, p->init_count=%d\n", d->unit, p->init_count); errorCode = tmdlIdeOpenM(&p->ideInstance, d->unit); CHECK(tmdlIdeOpenM, errorCode); p->common.devInstance = (UInt32) &p->ideInstance;// TMFAT_DEBUG1("\n\n*** IDE Instance = %x\n\n", p->ideInstance);// TMFAT_DEBUG0("ATA_init_Driver4\n"); // Get some information about the device errorCode = tmdlIdeGetDeviceInfo(p->ideInstance, &IdeDeviceInfo); CHECK(tmdlIdeGetDeviceInfo, errorCode); data_ptr = (UInt8 *) IdeDeviceInfo;// TMFAT_DEBUG0("Contents of IdeDeviceInfo.\n");// UTIL_dump_buffer(data_ptr, sizeof(IdeDeviceInfo)); p16 = (UInt16 *) data_ptr; get_ata_string((char *) &p16[10], serial_number, sizeof(serial_number) - 1); get_ata_string((char *) &p16[23], firmware_rev, sizeof(firmware_rev) - 1); get_ata_string((char *) &p16[27], model, sizeof(model) - 1); TMFAT_DEBUG1("Serial number: '%s'\n", serial_number); TMFAT_DEBUG1("Firmware revision: '%s'\n", firmware_rev); TMFAT_DEBUG1("Model number: '%s'\n", model); strcpy(d->serial,serial_number); supportsWriteCache = (data_ptr[82*2] & 0x20) ? True : False; supportsReadLookAhead = (data_ptr[82*2] & 0x40) ? True : False; supportsPowerManagement = (data_ptr[82*2] & 0x08) ? True : False; supportsPowerupInStandby = (data_ptr[83*2] & 0x20) ? True : False; supportsMediaStatusNotification = (data_ptr[83*2] & 0x10) ? True : False; TMFAT_DEBUG1("supportsPowerManagement: %d\n", supportsPowerManagement); TMFAT_DEBUG1("supportsWriteCache: %d\n", supportsWriteCache); TMFAT_DEBUG1("supportsReadLookAhead: %d\n", supportsReadLookAhead); TMFAT_DEBUG1("supportsPowerupInStandby: %d\n", supportsPowerupInStandby); TMFAT_DEBUG1("supportsMediaStatusNotification: %d\n", supportsMediaStatusNotification); errorCode = tmdlIdeGetInstanceSetup (p->ideInstance, &pideDevSetup); CHECK(tmdlIdeGetInstanceSetup, errorCode); pideDevSetup->bEnableMediaStatusNotification = False; // supportsMediaStatusNotification pideDevSetup->bEnableWriteCache = supportsWriteCache; pideDevSetup->bEnableReadLookAhead = supportsReadLookAhead; pideDevSetup->bEnablePowerManagement = False; // supportsPowerManagement pideDevSetup->bEnablePowerupInStandby = False; // supportsPowerupInStandby pideDevSetup->bEnableRevertToDefaultAtPowerOn = False; pideDevSetup->transferMode.transferType = (tmdlIdeTransferType_t)tmbslIdePioFlowControl; pideDevSetup->transferMode.transferSubMode = (tmdlIdeTransferSubMode_t)tmbslIdeSubMode4; errorCode = tmdlIdeInstanceSetup (p->ideInstance, pideDevSetup); CHECK(tmdlIdeInstanceSetup, errorCode);/* ideDevSetupGet.transferMode.transferSubMode = (tmdlIdeTransferSubMode_t)tmbslIdeSubMode0; ideDevSetupGet.transferMode.transferType = (tmdlIdeTransferType_t)tmbslIdePioDefault; pIdeDevSetupGet = &ideDevSetupGet; errorCode = tmdlIdeGetInstanceSetup (p->ideInstance, &pIdeDevSetupGet); CHECK(tmdlIdeGetInstanceSetup, errorCode);*/ // Prepare for asynchronous I/O. It may be needed by other partitions for this unit // First register the callback userData = (UInt32) p; errorCode = tmdlIdeRegisterCallback(p->ideInstance, ideCallbackFunction, userData); CHECK(tmdlIdeRegisterCallback, errorCode); // Set Event Mask for callback errorCode = tmdlIdeSetEventMask(p->ideInstance, TMDL_IDE_FUNCTION_COMPLETED); CHECK(tmdlIdeSetEventMask, errorCode); /* --- initialization of the ATA semaphore --- */// TMFAT_DEBUG0("ATA_init_Driver9\n"); errorCode = tmosalTaskSleep(10); // Milliseconds CHECK(tmosalTaskSleep, errorCode);/* { UInt16 NoOfCyls; UInt16 NoOfHeads; UInt16 SectorsPerTrack; NoOfCyls = (UInt16) ((*(data_ptr + 3) << 8) | (*(data_ptr + 2))); NoOfHeads = (UInt16) ((*(data_ptr + 7) << 8) | (*(data_ptr + 6))); SectorsPerTrack = (UInt16) ((*(data_ptr + 13) << 8) | (*(data_ptr + 12))); TMFAT_DEBUG1("Cylinders: %u\n", NoOfCyls); TMFAT_DEBUG1("Heads: %u\n", NoOfHeads); TMFAT_DEBUG1("Sectors per track: %u\n", SectorsPerTrack); }*/ /* determine if inserted card is of type CompactFlash */ if ((*data_ptr == 0x8A) && (*(data_ptr + 1) == 0x84)) { TMFAT_DEBUG2("CompactFlash card found %#x %#x\n", *data_ptr, *(data_ptr + 1)); } else { TMFAT_DEBUG2("Other card found %#x %#x\n", *data_ptr, *(data_ptr + 1)); } supportsLBA = (Bool) ((*(data_ptr + 99) >> 1) & 0x01); if (supportsLBA) { p->common.lbaMax = (p16[60] + (p16[61] << 16)) - 1; TMFAT_DEBUG1("Total sectors: %llu\n", p->common.lbaMax + 1); } else { TMFAT_DEBUG0("Device does not support Logical Block Addressing.\n"); } if (supportsLBA) { d->type = p->common.type; d->lbaMax = p->common.lbaMax; d->bytesPerSector = p->common.bytesPerSector; d->devInstance = p->common.devInstance; p->init_count = 1; errorCode = TM_OK; } else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -