📄 hal4ata.c
字号:
/*
//////////////////////////////////////////////////////////////////////
//
// Copyright (c) 1999 - 2003 PHILIPS Semiconductors - APIC
//
// Module Name:
//
// HAL4ATA.c
//
// Abstract:
//
// This is HAL for IDE controllers.
//
// Author:
//
// Hilbert Zhang ZhenYu
//
// Environment:
//
// kernel mode only
//
// Notes:
//
// Revision History:
// Create Date: Nov. 19 1999
//
//////////////////////////////////////////////////////////////////////////////
// Implementation Notes:
*/
#include "config.h" /* special function register declarations */
#undef GLOBAL_EXT
#include "SysCnfg.h"
#include "BasicTyp.h"
#include "common.h"
#include "Hal4Sys.h"
#include "ATA.h"
#include "RBC.h"
#include "RBCCmd.h"
#include "Hal4ATA.h"
#include "TPBulk.h"
//*************************************************************************
// Public Data
//*************************************************************************
STRUC_EXT TPBLK_STRUC TPBulk_Block;
#define TPBulk_CBW TPBulk_Block.TPBulk_CommandBlock
#define RBC_CDB TPBulk_CBW.cdbRBC
#define RBC_LUN TPBulk_CBW.bCBW_LUN
#define TPBulk_CSW TPBulk_Block.TPBulk_CommandStatus
#define Hal4ATA_Atapi RBC_CDB
STRUC_EXT HW_ATA_DEVICES_EXTENSION Hal4ATA_DevExt;
#define ATADevExt_IDData Hal4ATA_DevExt.IdentifyData
STRUC_EXT BITFLAGS bFlags;
#define MCUBF_Timer bFlags.bits.timer
#define D12BF_SetupOverwritten bFlags.bits.setup_overwritten
#define D12BF_Configuration bFlags.bits.;configuration
#define REQBF_DCPRequest_dir bFlags.bits.DCPRequst_Dir
#define REQBF_DCPRequest_EPdir bFlags.bits.DCPRequst_EPDir
#define REQBF_StallDCPRequest bFlags.bits.Stall_DCPRequest
#define BOTBF_StallAtBulkOut bFlags.bits.BO_Stalled
#define BOTBF_StallAtBulkIn bFlags.bits.BI_Stalled
#define BOTXfer_Abort bFlags.bits.Abort_BOT
#define ATABF_IsAttached bFlags.bits.ATABF_IsAttached
#define ATABF_IsSupportMultiSector bFlags.bits.ATABF_IsSupportMultiSector
#define ATABF_IDEXfer_dir bFlags.bits.ATABF_IDEXfer_dir
#define ATABF_IsSkipSetParameters bFlags.bits.ATABF_IsSkipSetParameters
INT8_EXT Hal4ATA_SectCntInBlk;
//*************************************************************************
// Private Data
//*************************************************************************
// Static
char_bit _Hal4ATA_StatusByte;
#define Hal4ATA_StatusByte _Hal4ATA_StatusByte.char_
#define Hal4ATA_StatusByte_ERR _Hal4ATA_StatusByte.bit_.b0
#define Hal4ATA_StatusByte_IDX _Hal4ATA_StatusByte.bit_.b1
#define Hal4ATA_StatusByte_CORR _Hal4ATA_StatusByte.bit_.b2
#define Hal4ATA_StatusByte_DRQ _Hal4ATA_StatusByte.bit_.b3
#define Hal4ATA_StatusByte_DSC _Hal4ATA_StatusByte.bit_.b4
#define Hal4ATA_StatusByte_DF _Hal4ATA_StatusByte.bit_.b5
#define Hal4ATA_StatusByte_DRDY _Hal4ATA_StatusByte.bit_.b6
#define Hal4ATA_StatusByte_BSY _Hal4ATA_StatusByte.bit_.b7
char_bit _Hal4ATA_DevReg;
#define Hal4ATA_DevReg _Hal4ATA_DevReg.char_ //= 0xA0;
#define Hal4ATA_DevReg_DEV _Hal4ATA_DevReg.bit_.b4
#define Hal4ATA_DevReg_b5 _Hal4ATA_DevReg.bit_.b5
#define Hal4ATA_DevReg_LBA _Hal4ATA_DevReg.bit_.b6
#define Hal4ATA_DevReg_b7 _Hal4ATA_DevReg.bit_.b7
// Temp
FLEXI_INT32 Hal4ATA_Track;
INT8 Hal4ATA_drvSelect;
//*************************************************************************
// Subroutines -- Level 1
//*************************************************************************
void
Hal4ATA_GetStatus(void)
{
Hal4ATA_StatusByte = (uint8)Hal4Sys_ATAPortInB(IDE_ASTATUS);
}
uint8
Hal4ATA_WaitOnBusyNDrdy(void)
{
uint8 retStatus = FALSE;
while(TRUE)
{
Hal4ATA_GetStatus();
// if IDE_STATUS_BUSY && !IDE_STATUS_DRDY
//Hal4ATA_StatusByte_ERR = Hal4ATA_StatusByte^0
if (Hal4ATA_StatusByte_ERR != 0 || Hal4ATA_StatusByte_DF != 0)
{
break;
}
else
if(Hal4ATA_StatusByte_BSY !=0 || Hal4ATA_StatusByte_DRDY !=1)
//if(Hal4ATA_StatusByte_BSY !=0 )
Hal4Sys_Wait4US();
else
{
retStatus = TRUE;
break;
}
}
return retStatus;
}
uint8
Hal4ATA_WaitOnBusyNDrq(void)
{
uint8 retStatus = FALSE;
while(TRUE)
{ Hal4ATA_GetStatus();
if (Hal4ATA_StatusByte_ERR != 0 || Hal4ATA_StatusByte_DF != 0)
{
break;
}
else
if(Hal4ATA_StatusByte_BSY !=0 || Hal4ATA_StatusByte_DRQ !=1)
Hal4Sys_Wait4US();
else
{
retStatus = TRUE;
break;
}
}
return TRUE;
}
uint8
Hal4ATA_WaitOnBusy(void)
{
uint8 retStatus = FALSE;
while(TRUE)
{
Hal4ATA_GetStatus();
if (Hal4ATA_StatusByte_ERR != 0 || Hal4ATA_StatusByte_DF != 0)
{
break;
}
else
if(Hal4ATA_StatusByte_BSY)
{
Hal4Sys_Wait4US();
}
else
{
retStatus = TRUE;
break;
}
}
return retStatus;
}
//*************************************************************************
// Subroutines -- Level 2
//*************************************************************************
uint8
Hal4ATA_SelDevice(void)
{
uint8 retStatus = FALSE;
if(Hal4ATA_WaitOnBusy())
{
// ATAREG4OUT_DEVICE_HEAD = ATAREG_GRP0+6 = 0x56
// ATAREG_GRP0 =0x50
// BUFF_DIR_RD, !D12CS, !BUFF_EN, !IDE_CS1, !IDE_CS0, A2, A1, A0
//0x56 0 1 0 1 0 1 1 0
Hal4Sys_ATAPortOutB(IDE_DEVICE_HEAD,Hal4ATA_DevReg);
retStatus = Hal4ATA_WaitOnBusyNDrdy();
}
return retStatus;
}
//*************************************************************************
// Subroutines -- level 4
//*************************************************************************
uint8
Hal4ATA_IssueIDEIdentify(void)
{
INT16 i;
uint8 retStatus = FALSE;
// Select device.
if(Hal4ATA_SelDevice())
{
// Send IDE IDENTIFY command.
// IDE_COMMAND_IDENTIFY=0xEC ;
Hal4Sys_ATAPortOutB(IDE_COMMAND, IDE_COMMAND_IDENTIFY);
if(Hal4ATA_WaitOnBusyNDrq())
{
// Suck out 256 words. After waiting for one model that asserts busy
// after receiving the Packet Identify command.
if(Hal4ATA_InitDevExt())
retStatus = TRUE;
}
// Work around for some IDE and one model Atapi that will present more than
// 256 words for the Identify data.
for (i=10000; i != 0; i--)
{
Hal4ATA_GetStatus();
if (Hal4ATA_StatusByte_DRQ)
{
// Suck out any remaining bytes and throw away.
Hal4Sys_ATADataPortInW();
}
else
break;
}
}
return retStatus;
} /* end IssueIdentify()*/
uint8
Hal4ATA_InitDevExt(void)
{
INT8 c;
if(Hal4ATA_WaitOnBusyNDrq())
{
ATADevExt_IDData.GeneralConfiguration = Hal4Sys_ATADataPortInW();//INT16 00
ATADevExt_IDData.NumberOfCylinders = Hal4Sys_ATADataPortInW();//INT16 01
Hal4Sys_ATADataPortInW();
ATADevExt_IDData.NumberOfHeads = Hal4Sys_ATADataPortInW();//INT16 03
for(c = 2 ; c != 0; c--)
Hal4Sys_ATADataPortInW();
ATADevExt_IDData.SectorsPerTrack = Hal4Sys_ATADataPortInW();//INT16 06
for(c = 40 ; c != 0; c--) // 7 -47
Hal4Sys_ATADataPortInW();
ATADevExt_IDData.MaximumBlockTransfer = Hal4Sys_ATADataPortInW();//INT8 47
Hal4Sys_ATADataPortInW(); // 48
ATADevExt_IDData.Capabilities = Hal4Sys_ATADataPortInW();//INT16 49
for(c = 4; c != 0; c--)
Hal4Sys_ATADataPortInW();
ATADevExt_IDData.NumberOfCurrentCylinders = Hal4Sys_ATADataPortInW();//INT16 54
ATADevExt_IDData.NumberOfCurrentHeads = Hal4Sys_ATADataPortInW();//INT16 55
ATADevExt_IDData.CurrentSectorsPerTrack = Hal4Sys_ATADataPortInW();//INT16 56
ATADevExt_IDData.CurrentSectorCapacity.ints.i0 = Hal4Sys_ATADataPortInW();//INT32 57
ATADevExt_IDData.CurrentSectorCapacity.ints.i1 = Hal4Sys_ATADataPortInW();//
if(ATADevExt_IDData.CurrentSectorCapacity.u0 == 0)
{
ATADevExt_IDData.NumberOfCurrentCylinders = ATADevExt_IDData.NumberOfCylinders;
ATADevExt_IDData.NumberOfCurrentHeads = ATADevExt_IDData.NumberOfHeads ;//INT16 55
ATADevExt_IDData.CurrentSectorsPerTrack = ATADevExt_IDData.SectorsPerTrack;//INT16 56
ATADevExt_IDData.CurrentSectorCapacity.u0 = (INT32)ATADevExt_IDData.NumberOfCurrentCylinders * ATADevExt_IDData.NumberOfCurrentHeads * ATADevExt_IDData.CurrentSectorsPerTrack;
}
return(TRUE);
}
else
return(FALSE);
}
uint8
Hal4ATA_IsLBAmode(void)
{ Hal4ATA_DevReg_LBA = 1;
return(Hal4ATA_DevReg_LBA);
}
uint8
Hal4ATA_SetFeature(void)
{ /* uint8 retStatus = FALSE;
Hal4Sys_ATAPortOutB(ATAREG4OUT_FEATURE,0x03);
Hal4Sys_ATAPortOutB(ATAREG4OUT_SECTOR_COUNT, 0x08);
Hal4Sys_ATAPortOutB(ATAREG4OUT_SECTOR_NUMBER,0);
Hal4Sys_ATAPortOutB(ATAREG4OUT_CYLINDER_LOW,0);
Hal4Sys_ATAPortOutB(ATAREG4OUT_CYLINDER_HIGH,0);
Hal4Sys_ATAPortOutB(ATAREG4OUT_COMMAND, 0xEF);
while(TRUE)
{
if(Hal4ATA_WaitOnBusyNDrdy())
{
retStatus = TRUE;
break;
}
}
return retStatus;*/
return TRUE;
}
//*************************************************************************
// Subroutines -- level 5 ATA transaction
//*************************************************************************
uint8
Hal4ATA_IdeHardReset(void)
{
//INT8 c;
uint8 retStatus = FALSE;
IOCLR = IDE_RST; // 复位引脚置低
Hal4Sys_WaitInUS(320); // >25 US
IOSET = IDE_RST; // 复位引脚置高
// for(c = 10; c != 0; c--)
Hal4Sys_WaitInUS(500000); // 50MS
if(Hal4ATA_SelDevice())
{
// Hal4ATA_DevReg_DEV = FALSE;
// Hal4Sys_ATAPortOutB(ATAREG4OUT_DEVICE_HEAD,Hal4ATA_DevReg);
// }
while(TRUE)
{
if(Hal4ATA_WaitOnBusyNDrdy())
{
retStatus = TRUE;
break;
}
}
}
return retStatus;
}
uint8
Hal4ATA_FindIDEDevice(void)
{
INT8 c;
ATABF_IsAttached = FALSE;
Hal4ATA_DevReg = 0xA0;
Hal4ATA_DevReg_DEV = FALSE;
if(Hal4ATA_IdeHardReset())
{ Hal4ATA_SetFeature();
for ( c = 2; c != 0; c--, Hal4ATA_DevReg_DEV^=1 )
{ if(Hal4ATA_SelDevice())
{
if ( Hal4ATA_IssueIDEIdentify() )
{ ATABF_IsAttached = TRUE;
break;
}
}
}
if(ATABF_IsAttached)
{ Hal4ATA_IsLBAmode();// 设为LAB模式
} // IDE HD is found
} // IDE Reset OK
return ATABF_IsAttached;
} /*end Hal4ATA_FindIDEDevice()*/
uint8
Hal4ATA_ReadWriteSetting(void)
{
uint8 retStatus = FALSE;
// Select device .
if(Hal4ATA_SelDevice())
{ //Assume Sector Counter <256
Hal4Sys_ATAPortOutB(IDE_SECCNT, RBC_CDB.RbcCdb_Read.XferLength_0);
/* IN LBA mode */
if( ATABF_IDEXfer_dir ) // ATABF_Xfer_dir==1 Read(from Dev to Host)
{
Hal4Sys_ATAPortOutB(IDE_SECTOR,RBC_CDB.RbcCdb_Read.LBA_0);
Hal4Sys_ATAPortOutB(IDE_CYLINDER_LOW,RBC_CDB.RbcCdb_Read.LBA_1);
Hal4Sys_ATAPortOutB(IDE_CYLINDER_HIGH,RBC_CDB.RbcCdb_Read.LBA_2);
Hal4Sys_ATAPortOutB(IDE_DEVICE_HEAD, (RBC_CDB.RbcCdb_Read.LBA_3&0x0f) | Hal4ATA_DevReg );
Hal4Sys_ATAPortOutB(IDE_COMMAND, IDE_COMMAND_READ);
}
else
{ // write command.
Hal4Sys_ATAPortOutB(IDE_SECTOR,RBC_CDB.RbcCdb_Write.LBA_0);
Hal4Sys_ATAPortOutB(IDE_CYLINDER_LOW,RBC_CDB.RbcCdb_Write.LBA_1);
Hal4Sys_ATAPortOutB(IDE_CYLINDER_HIGH,RBC_CDB.RbcCdb_Write.LBA_2);
Hal4Sys_ATAPortOutB(IDE_DEVICE_HEAD, (RBC_CDB.RbcCdb_Write.LBA_3&0x0f) | Hal4ATA_DevReg );
Hal4Sys_ATAPortOutB(IDE_COMMAND,IDE_COMMAND_WRITE);
}
}
retStatus = Hal4ATA_WaitOnBusyNDrq();
return retStatus;
} /* end Hal4ATA_ReadWriteSetting()*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -