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

📄 ata.c

📁 PDA上的包含NANDFlash和FAT文件系统的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*************************************************************
File Name: ATA.C
Last Modified Date: 2002/06/26
Programmer: Johnson (Huang Giun-Haur)
Compiler: ???
Platform: X86 protection mode without any function support,
          Dragonball, MIPS, ARM7, AR2000
Usage:
        1. WAIT_COMMAND_AVAILABLE(not in SMC)
        2. WAIT_COMMAND_RESULT(not in SMC)
        3. ATA_GET_PARAMETER(not in SMC)
        4. ATA_READ
        5. ATA_WRITE

Other Information :

990614  IO with a loop is used instead of 'rep' so that slower
        HD can work correctly.

        Timeout is used to wait till the disk is ready instead
        of looping N times. More machine independent now.

History : Arti Engineer Huang TzeHeng updated(2002/6/26)
	  1. Added SMC option ( FAT_USE_SMC defined )
	  2. SMC option uses {driver/nflash} driver
	  Himark Engineer Huang TzeHeng updated(2002/11/19)
	  1. Added MMC option ( FAT_USE_MMC defined )

**************************************************************/
#include <sys/syscall.h>

/**** added by chilong 11/11/2001 ****/
#include <stdio.h>

#include "filesys/include/FileSys.h"
#include "../include/fat1x.h"
/**** added by chilong 11/11/2001 ****/

//#include "../include/fat1x.h"

/**** added by chilong temporarily 11/11/2001 ****/
#define TICK_HZ 32
/**** added by chilong temporarily 11/11/2001 ****/

#ifdef FAT_USE_PCMCIA
  //#include "../../pcmcia/include/cf_typedef.h"
  #include "../include/ata_pcc.h"
  
//  #include "pcmcia/include/pcmcia.h"//thhuang added it
#ifdef __WIN32__
 #include"../../diskEmu/include/cf_emu.h"
#else
  #include "pcmcia/include/pcm_io.h"  
  #include "pcmcia/include/pcmcia.h"
#endif

#elif defined(FAT_USE_SMC)
  #include "../../nflash/include/nflash.h"
  #include "../include/ata_pcc.h"
#else
  #include "../../../../../driver/mmc/include/mmc_drv.h"
  #include "../include/ata_pcc.h"
#endif

#ifdef FAT_ID
///* marked by chilong 11/11/2001
#ifdef FAT_ATA_CACHE_ON
// ATA cache
struct FAT_sectorCache FATAtaCache[FAT1X_ATA_TAG_NO][FAT1X_ATA_BLOCK_PER_TAG];
#ifdef FAT1X_DEBUG
extern unsigned long FATAtaReadHit;     // ATA read hit count
extern unsigned long FATAtaReadMiss;    // ATA read miss count
extern unsigned long FATAtaWriteHit;    // ATA write hit count
extern unsigned long FATAtaWriteMiss;   // ATA write miss count
extern unsigned long FATAtaSwap;        // ATA cache swap count
extern unsigned long FATAtaFlush;       //  ATA cache flush count
#endif
#endif
//   marked by chilong 11/11/2001 */

/* init.c */
extern int FATIsLBA;
extern int FATHdDriver;
extern int FATAtaSemaphoreID;

#ifdef FAT_USE_PCMCIA//thhuang added it
#if (PCB_V >= 5 )
  extern U16   gCFCardStatus;
#endif
#endif

/**** added by chilong 11/11/2001 ****/
#ifdef PCMCIA_DEBUG
extern unsigned char debugString[80];

#endif

// this line needs to be deleted after the test on rtos is ok
//unsigned char debugString[80];

/**** added by chilong 11/11/2001 ****/

/*************************************************************
Fuction: WAIT_COMMAND_AVAILABLE
**************************************************************/
#ifdef FAT_USE_PCMCIA
unsigned short WAIT_COMMAND_AVAILABLE(int driver, unsigned long howLong)
{
  unsigned short result;
  unsigned long timeout;

  /**** added by chilong temporaily 11/11/2001 ****/
//  unsigned int i = 0;
  /**** added by chilong temporaily 11/11/2001 ****/

/**** added by chilong 11/11/2001 ****/
#ifdef PCMCIA_DEBUG
  printString("WAIT_COMMAND_AVAILABLE\n\r");
#endif

  timeout = howLong + sc_getTimeStamp();

  /**** added by chilong 11/11/2001 ****/
//  timeout = howLong + 1000;
  /**** added by chilong 11/11/2001 ****/

  /* Wait until BSY = 0 */
  #ifdef FAT_USE_PCMCIA
        result = pcmInport(driver + STATUS_REG);
  #else
        result = inportb(driver + STATUS_REG);
        result = result & 0x00FF;

  #endif

  while ((result & ATA_COMMAND_BUSY) == ATA_COMMAND_BUSY)
  {
        if (timeout < sc_getTimeStamp())
                break;

#if( PCB_V >=5 )
        // if card removed , break of the wait loop immediately
        if( gCFCardStatus != CF_CARD_IN )
                break;
#endif

        #ifdef FAT_USE_PCMCIA
                result = pcmInport(driver + STATUS_REG);

        #else
                result = inportb(driver + STATUS_REG);
                result = result & 0x00FF;

        #endif

  }

  return result;
}
#endif
/*************************************************************
Fuction: GET_ERROR_RESULT
          Get the error status reg.
return value: ATA_OK, ATA_FAILURE, ATA_FAIL_BBK, ATA_FAIL_UNC, ATA_FAIL_IDNF
              ATA_FAIL_ABRT, ATA_FAIL_AMNF
**************************************************************/
#ifdef FAT_USE_PCMCIA
unsigned short GET_ERROR_RESULT(int driver)
{
  unsigned short status;

  status = WAIT_COMMAND_AVAILABLE(driver, FAT_TIMEOUT * TICK_HZ);

  if (((status & ATA_COMMAND_BUSY) == ATA_COMMAND_BUSY) || ((status & ATA_DRIVE_READY) != ATA_DRIVE_READY))
  {
#ifdef PCMCIA_DEBUG
	printString("GET_ERROR_RESULT error\n\r");
#endif
        return ATA_FAILURE;
  }

  #ifdef FAT_USE_PCMCIA
        status = pcmInport(driver + DUP_ERROR_REG);
//        status = (status & 0xFF00) >> 8;
        status = status & 0x00FF;
  #else
        status = inportb(driver + DUP_ERROR_REG);
        status = status & 0x00FF;
  #endif

  if (status & ERR_ALL)
  {
        if (status& ERR_BBK)
                return ATA_FAIL_BBK;
        if (status & ERR_UNC)
                return ATA_FAIL_UNC;
#if 0//2003.3.24, don't know why be setted on sandisk 64MB
        if (status & ERR_IDNF)
                return ATA_FAIL_IDNF;
#endif
        if (status & ERR_ABRT)
                return ATA_FAIL_ABRT;
        if (status & ERR_AMNF)
                return ATA_FAIL_AMNF;
  }

  return ATA_OK;
}
#endif
/*************************************************************
Function: WAIT_COMMAND_RESULT
**************************************************************/
#ifdef FAT_USE_PCMCIA
unsigned short WAIT_COMMAND_RESULT(int driver, unsigned long howLong)
{
  unsigned short result;
  unsigned long timeout;

  timeout = howLong + sc_getTimeStamp();

  /* Wait until BSY = 0 & DRDY = 1 */
  #ifdef FAT_USE_PCMCIA
        result = pcmInport(driver + STATUS_REG);
  #else
        result = inportb(driver + STATUS_REG);
        result = result & 0x00FF;

  #endif

  while (((result & ATA_COMMAND_BUSY) == ATA_COMMAND_BUSY) || ((result & ATA_DATA_READY) != ATA_DATA_READY))
  {
        if ((result & ATA_DATA_ERROR_AND_READY) == ATA_DATA_ERROR_AND_READY)
        {
                break;
        }
        else
        {
                if (timeout < sc_getTimeStamp())
                        break;
        }

#if( PCB_V >= 5)
        // if card removed , break of the wait loop immediately
        if( gCFCardStatus != CF_CARD_IN )
                break;
#endif

        #ifdef FAT_USE_PCMCIA
                result = pcmInport(driver + STATUS_REG);
        #else
                result = inportb(driver + STATUS_REG);
                result = result & 0x00FF;

        #endif
  }

  return result;
}
#endif


/*************************************************************
Function: ATA_GET_PARAMETER
**************************************************************/
#ifdef FAT_USE_PCMCIA
unsigned short ATA_GET_PARAMETER(int driver, unsigned short *buf)
{
  unsigned short status;
  short i;
  unsigned short temp;

#ifdef PCMCIA_DEBUG
  printString("ATA_GET_PARAMETER\n\r");
#endif

/**** added by chilong 11/11/2001 ****/
  /* 0. Soft reset */
//  outportb(driver + CONTROL_REG, 0x04);
//  outportb(driver + CONTROL_REG, 0x00);

  /* 1. Wait for the time ATA-Register can accept COMMAND */
  status = WAIT_COMMAND_AVAILABLE(driver, FAT_TIMEOUT * TICK_HZ);

  if ((status & ATA_COMMAND_BUSY) == ATA_COMMAND_BUSY)
  {
  #ifdef PCMCIA_DEBUG
  	printString("ATA_GET_PARAMETER: 1st step error\n\r");
  #endif

        return ATA_FAILURE;
  }

  #ifdef FAT_USE_PCMCIA
	//#ifdef BIG_ENDIAN
        //	temp = (unsigned short)ATA_MASTER_DRV;
        //	if (FATIsLBA != FALSE)
        //        	temp |= (unsigned short)ATA_LBA_MODE;

        //	temp = temp << 8;
        //	temp |= (unsigned short)ID_ATA_CMD;
	//#else
        	temp = (unsigned short)ID_ATA_CMD;
        	temp = temp << 8;
        	temp |= (unsigned short)ATA_MASTER_DRV;
        	if (FATIsLBA != FALSE)
                	temp |= (unsigned short)ATA_LBA_MODE;

        //#endif

        pcmOutport(driver + DEV_HEADER_REG, temp);

  #else
        // 2. SELECT THE DISK-CONTROLLER
        if (FATIsLBA == FALSE)
                outportb(driver + DEV_HEADER_REG, ATA_MASTER_DRV);
        else
                outportb(driver + DEV_HEADER_REG, ATA_MASTER_DRV | ATA_LBA_MODE);

        // 3. Wait for the time ATA-Register can accept COMMAND
        status = WAIT_COMMAND_AVAILABLE(driver, FAT_TIMEOUT * TICK_HZ);
        status = inportb(driver + STATUS_REG);
        if (((status & ATA_COMMAND_BUSY) == ATA_COMMAND_BUSY) || ((status & ATA_DRIVE_READY) != ATA_DRIVE_READY))
        {
  	#ifdef PCMCIA_DEBUG
  		printString("3th step error\n\r");
  	#endif

                return ATA_FAILURE;
        }

        // 4. send identify ATA command
        outportb(driver + COMMAND_REG, ID_ATA_CMD);

  #endif

  /* 5. Wait command executed completely */
  status = WAIT_COMMAND_AVAILABLE(driver, FAT_TIMEOUT * TICK_HZ);

  #ifdef FAT_USE_PCMCIA
        status = pcmInport(driver + STATUS_REG);
  #else
        status = inportb(driver + STATUS_REG);
        status = result & 0x00FF;

  #endif

  if (((status & ATA_COMMAND_BUSY) == ATA_COMMAND_BUSY) || ((status & ATA_DATA_READY) != ATA_DATA_READY))
  {
        if (((status & ATA_COMMAND_BUSY) == ATA_COMMAND_BUSY) || ((status & ATA_COMMAND_ERROR) == ATA_COMMAND_ERROR))
        {
  	#ifdef PCMCIA_DEBUG
  		printString("5th step error\n\r");
  	#endif

                return ATA_FAILURE;
        }
  }

  /* 6. Move the parameter to caller's dataBuffer */
  for (i = 0; i < WORDS_PER_SECTOR; i++)
  {
        #ifdef FAT_USE_PCMCIA
                temp = pcmInport(driver + DATA_REG);
	#ifdef BIG_ENDIAN
                if ((i < 23) && (i > 46))
	#else                
                if ((i >= 23) && (i <= 46))
        #endif
                        *(buf + i) = ((temp & 0xFF00) >> 8) | ((temp & 0x00FF) << 8);
                else
                        *(buf + i) = temp;

		/**** added by chilong 11/11/2001 ****/
#ifdef PCMCIA_DEBUG
		if (i % 8 == 0)
			printString("\n\r");

		sprintf(debugString, "%.2x ", (*(buf+i) >> 8) & 0xFF);
		printString(debugString);

		sprintf(debugString, "%.2x ", *(buf+i) & 0xFF);
		printString(debugString);
#endif
		/**** added by chilong 11/11/2001 ****/
        #else
                *(buf + i) = inportw(driver + DATA_REG);

        #endif
  }

  return ATA_OK;
}
#endif
/*************************************************************
Function: ATA_READ_SECTOR
        Read N sectors from drive
**************************************************************/
unsigned short ATA_READ_SECTOR(int driver, unsigned char secCount, unsigned long startSec, unsigned short *buf)
{
#ifdef FAT_USE_SMC
	unsigned char i;

	for ( i=0 ; i<secCount; i++ )
	{
		if ( LG_ReadFrame( (startSec+i)*SECTOR_SIZE, (unsigned char *) (buf+i*WORDS_PER_SECTOR) ) == NFLASH_FAIL )
			return ATA_FAILURE;
	}
	return ATA_OK;
#elif defined FAT_USE_MMC
	unsigned char i;

	for ( i=0 ; i<secCount; i++ )
	{
		if ( MMC_ReadSector( (unsigned int *) (buf+i*WORDS_PER_SECTOR), startSec+i ) != SM_OK )
			return ATA_FAILURE;
	}
	return ATA_OK;
#else
  struct FAT_C_H_S readSec;
  unsigned short status;
  int i;
  unsigned short* base;

  if( secCount <= 0 )
    return ATA_OK;

  // read the sector from disk
  FAT_logical_sector_to_chs(startSec, &readSec);

  // 0. Wait for the time ATA-Register can accept COMMAND
  status = WAIT_COMMAND_AVAILABLE(driver, FAT_TIMEOUT * TICK_HZ);

  if ((status & ATA_COMMAND_BUSY) == ATA_COMMAND_BUSY)

⌨️ 快捷键说明

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