📄 ata.c
字号:
{
#ifdef PCMCIA_DEBUG
printString("ATA_READ_SECTOR: step 0 error\n\r");
#endif
return ATA_FAILURE;
}
// 1. SELECT THE DISK-CONTROLLER
#ifdef FAT_USE_PCMCIA
//#ifdef BIG_ENDIAN
// status = (unsigned short)secCount;
// status = status << 8;
// status |= (unsigned short)readSec.Sector;
//#else
status = (unsigned short)readSec.Sector;
status = status << 8;
status |= (unsigned short)secCount;
//#endif
pcmOutport(driver + COUNT_REG, status);
#else
outportb(driver + COUNT_REG, secCount); // if secCount = 0, then it means 256 sectors
outportb(driver + SECTOR_REG, readSec.Sector);
#endif
#ifdef FAT_USE_PCMCIA
//#ifdef BIG_ENDIAN
// status = (unsigned short)readSec.CylLow;
// status = status << 8;
// status |= (unsigned short)readSec.CylHigh;
//#else
status = (unsigned short)readSec.CylHigh;
status = status << 8;
status |= (unsigned short)readSec.CylLow;
//#endif
pcmOutport(driver + CYLINDER_L_REG, status);
#else
outportb(driver + CYLINDER_L_REG, readSec.CylLow);
outportb(driver + CYLINDER_H_REG, readSec.CylHigh);
#endif
// 2. 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) || ((status & ATA_DRIVE_READY) != ATA_DRIVE_READY))
{
#ifdef PCMCIA_DEBUG
printString("ATA_READ_SECTOR: step 2 error\n\r");
#endif
return ATA_FAILURE;
}
// 3. Send Read command to ata-controller
#ifdef FAT_USE_PCMCIA
//#ifdef BIG_ENDIAN
// status = ((unsigned short)ATA_MASTER_DRV | (unsigned short)readSec.Head);
// if (FATIsLBA != FALSE)
// status |= (unsigned short)ATA_LBA_MODE;
// status = status << 8;
// status |= (unsigned short)READ_ATA_CMD;
//#else
status = (unsigned short)READ_ATA_CMD;
status = status << 8;
status |= ((unsigned short)ATA_MASTER_DRV | (unsigned short)readSec.Head);
if (FATIsLBA != FALSE)
status |= (unsigned short)ATA_LBA_MODE;
//#endif
pcmOutport(driver + DEV_HEADER_REG, status);
#else
if (FATIsLBA == FALSE)
outportb(driver + DEV_HEADER_REG, (readSec.Head | ATA_MASTER_DRV));
else
outportb(driver + DEV_HEADER_REG, (readSec.Head | (ATA_MASTER_DRV | ATA_LBA_MODE)));
outportb(driver + COMMAND_REG, READ_ATA_CMD);
#endif
base = (unsigned short*)CF_TASK_FILE_ADDR;
base += ((driver + DATA_REG)&0xFFFE);
base = (unsigned short*)((int)base | 0x00000002);
// 4. Looping for reading "secCount" sectors
while (secCount != 0)
{
status = WAIT_COMMAND_RESULT(driver, FAT_TIMEOUT * TICK_HZ);
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("ATA_READ_SECTOR: step 4 error\n\r");
#endif
return ATA_FAILURE;
}
}
// Move one sector (512 bytes) to caller's dataBuffer
pcmMoveDataFixSrc( base , buf , WORDS_PER_SECTOR );
secCount--;
buf += WORDS_PER_SECTOR;
}
return GET_ERROR_RESULT(driver);
#endif
}
/*************************************************************
Function: ATA_WRITE_SECTOR
Write N sectors to drive
**************************************************************/
unsigned short ATA_WRITE_SECTOR(int driver, unsigned char secCount, unsigned long startSec, unsigned short *buf)
{
#ifdef FAT_USE_SMC//thhuang added
unsigned long i;
unsigned short status;
if( secCount <= 0 )
return ATA_OK;
if ( (startSec & (NFLASH_FRAMES_OF_BLOCK-1)) != 0 )
{
if ( (startSec | (NFLASH_FRAMES_OF_BLOCK-1)) < (startSec+secCount-1) )
{
status = LG_write_block( startSec, startSec | (NFLASH_FRAMES_OF_BLOCK-1), buf );//not over
if ( status == NFLASH_FAIL )
return ATA_FAILURE;//failure, so it's over...
secCount -= (startSec | (NFLASH_FRAMES_OF_BLOCK-1)) - startSec + 1;
buf += WORDS_PER_SECTOR*((startSec | (NFLASH_FRAMES_OF_BLOCK-1)) - startSec + 1);
startSec = (startSec | (NFLASH_FRAMES_OF_BLOCK-1)) + 1;//next block.
}
else
{
if ( LG_write_block( startSec, startSec+secCount-1 , buf ) == NFLASH_OK )
return ATA_OK;//end
else
return ATA_FAILURE;//end
}
}
/* Now the startSec points to the start of a block */
for ( i = startSec; i < (startSec+secCount); i+=NFLASH_FRAMES_OF_BLOCK )
{
if ( (i+NFLASH_FRAMES_OF_BLOCK) < (startSec+secCount) )
{
status = LG_write_block( i, i | (NFLASH_FRAMES_OF_BLOCK-1), buf );//not over
if ( status == NFLASH_FAIL )
return ATA_FAILURE;//failure, so it's over...
}
else
{
if ( LG_write_block( i, startSec+secCount-1, buf ) == NFLASH_OK )
return ATA_OK;//end
else
return ATA_FAILURE;//end
}
buf += WORDS_PER_SECTOR*NFLASH_FRAMES_OF_BLOCK;
}
return ATA_OK;
#elif defined FAT_USE_MMC
unsigned char i;
for ( i=0 ; i<secCount; i++ )
{
if ( MMC_EraseSector( startSec+i, startSec+i ) != SM_OK )
return ATA_FAILURE;
if ( MMC_WriteSector( (unsigned int *) (buf+i*WORDS_PER_SECTOR), startSec+i ) != SM_OK )
return ATA_FAILURE;
}
return ATA_OK;
#else
struct FAT_C_H_S writeSec;
unsigned short status;
unsigned short* base;
int i;
if( secCount <= 0 )
return ATA_OK;
FAT_logical_sector_to_chs(startSec, &writeSec);
/* 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)
{
#ifdef PCMCIA_DEBUG
printString("ATA_WRITE_SECTOR: step 0 error\n\r");
#endif
return ATA_FAILURE;
}
/* 1. SELECT THE DISK-CONTROLLER */
#ifdef FAT_USE_PCMCIA
//#ifdef BIG_ENDIAN
// status = (unsigned short)secCount;
// status = status << 8;
// status |= (unsigned short)writeSec.Sector;
//#else
status = (unsigned short)writeSec.Sector;
status = status << 8;
status |= (unsigned short)secCount;
//#endif
#ifdef PCMCIA_DEBUG
sprintf(debugString, "W_COUNT_REG: %x", status);
printStringLn(debugString);
#endif
pcmOutport(driver + COUNT_REG, status);
#else
outportb(driver + COUNT_REG, secCount); // if secCount = 0, then it means 256 sectors
outportb(driver + SECTOR_REG, writeSec.Sector);
#endif
#ifdef FAT_USE_PCMCIA
//#ifdef BIG_ENDIAN
// status = (unsigned short)writeSec.CylLow;
// status = status << 8;
// status |= (unsigned short)writeSec.CylHigh;
//#else
status = (unsigned short)writeSec.CylHigh;
status = status << 8;
status |= (unsigned short)writeSec.CylLow;
//#endif
#ifdef PCMCIA_DEBUG
sprintf(debugString, "W_CYL_L_REG: %x", status);
printStringLn(debugString);
#endif
pcmOutport(driver + CYLINDER_L_REG, status);
#ifdef PCMCIA_DEBUG
sprintf(debugString, "R_CYL_L_REG: %x",
pcmInport(driver + CYLINDER_L_REG));
printStringLn(debugString);
#endif
#else
outportb(driver + CYLINDER_L_REG, writeSec.CylLow);
outportb(driver + CYLINDER_H_REG, writeSec.CylHigh);
#endif
/* 2. 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) || ((status & ATA_DRIVE_READY) != ATA_DRIVE_READY))
{
#ifdef PCMCIA_DEBUG
printString("ATA_WRITE_SECTOR: step 2 error\n\r");
#endif
return ATA_FAILURE;
}
/* 3. Send Write command to ata-controller */
#ifdef FAT_USE_PCMCIA
//#ifdef BIG_ENDIAN
// status = ((unsigned short)ATA_MASTER_DRV | (unsigned short)writeSec.Head);
// if (FATIsLBA != FALSE)
// status |= (unsigned short)ATA_LBA_MODE;
// status = status << 8;
// status |= (unsigned short)WRITE_ATA_CMD;
//#else
status = (unsigned short)WRITE_ATA_CMD;
status = status << 8;
status |= ((unsigned short)ATA_MASTER_DRV | (unsigned short)writeSec.Head);
if (FATIsLBA != FALSE)
status |= (unsigned short)ATA_LBA_MODE;
//#endif
#ifdef PCMCIA_DEBUG
sprintf(debugString, "W_DEV_HEADER_REG: %x", status);
printStringLn(debugString);
#endif
pcmOutport(driver + DEV_HEADER_REG, status);
#ifdef PCMCIA_DEBUG
sprintf(debugString, "R_DEV_HEADER_REG: %x",
pcmInport(driver + DEV_HEADER_REG));
printStringLn(debugString);
#endif
#else
if (FATIsLBA == FALSE)
outportb(driver + DEV_HEADER_REG, (writeSec.Head | ATA_MASTER_DRV));
else
outportb(driver + DEV_HEADER_REG, (writeSec.Head | (ATA_MASTER_DRV | ATA_LBA_MODE)));
outportb(driver + COMMAND_REG, WRITE_ATA_CMD);
#endif
base = (unsigned short*)CF_TASK_FILE_ADDR;
base += ((driver + DATA_REG)&0xFFFE);
//base = (unsigned short*)((int)base | 0x00000002);
/* 4. Looping for writing "secCount" sectors */
while (secCount != 0)
{
status = WAIT_COMMAND_RESULT(driver, FAT_TIMEOUT * TICK_HZ);
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("ATA_WRITE_SECTOR: step 4 error\n\r");
#endif
return ATA_FAILURE;
}
}
pcmMoveDataFixDest( buf , base , WORDS_PER_SECTOR );
secCount--;
buf += WORDS_PER_SECTOR;
}
return GET_ERROR_RESULT(driver);
#endif //not SMC
}
/*************************************************************
Function: ATA_ERASE_SECTOR
Erase N sectors to drive
**************************************************************/
unsigned short ATA_ERASE_SECTOR(int driver, unsigned char secCount, unsigned long startSec, unsigned short *buf)
{
#ifdef FAT_USE_PCMCIA
struct FAT_C_H_S writeSec;
unsigned short status;
unsigned short* base;
int i;
if( secCount <= 0 )
return ATA_OK;
FAT_logical_sector_to_chs(startSec, &writeSec);
/* 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)
{
return ATA_FAILURE;
}
/* 1. SELECT THE DISK-CONTROLLER */
status = (unsigned short)writeSec.Sector;
status = status << 8;
status |= (unsigned short)secCount;
pcmOutport(driver + COUNT_REG, status);
status = (unsigned short)writeSec.CylHigh;
status = status << 8;
status |= (unsigned short)writeSec.CylLow;
pcmOutport(driver + CYLINDER_L_REG, status);
/* 2. 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) || ((status & ATA_DRIVE_READY) != ATA_DRIVE_READY))
{
return ATA_FAILURE;
}
/* 3. Send Write command to ata-controller */
status = (unsigned short)0x00c0;//Erase
status = status << 8;
status |= ((unsigned short)ATA_MASTER_DRV | (unsigned short)writeSec.Head);
if (FATIsLBA != FALSE)
status |= (unsigned short)ATA_LBA_MODE;
pcmOutport(driver + DEV_HEADER_REG, status);
return GET_ERROR_RESULT(driver);
#endif
}
/*************************************************************
Function: ATA_READ
**************************************************************/
unsigned short ATA_READ(int driver, unsigned char secCount, unsigned long startSec, unsigned short *buf)
{
unsigned short status;
/* Kevin, change SDRAM hold time for CF access */
#if defined(PR2001B)||defined(AR2001)
*(unsigned char *) 0xbfbf001c |= 0x20;
#endif
status = ATA_READ_SECTOR(driver, secCount, startSec, buf);
#if defined(PR2001B)||defined(AR2001)
*(unsigned char *) 0xbfbf001c &= ~(0x20);
#endif
return status;
}
/*************************************************************
Function: ATA_WRITE
**************************************************************/
unsigned short ATA_WRITE(int driver, unsigned char secCount, unsigned long startSec, unsigned short *buf)
{
unsigned short status;
/* Kevin, change SDRAM hold time for CF access */
#if defined(PR2001B)||defined(AR2001)
*(unsigned char *) 0xbfbf001c |= 0x20;
#endif
status = ATA_WRITE_SECTOR(driver, secCount, startSec, buf);
#if defined(PR2001B)||defined(AR2001)
*(unsigned char *) 0xbfbf001c &= ~(0x20);
#endif
return status;
}
#endif //FAT_ID
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -