📄 hal4ata.c
字号:
} /* end IssueIdentify()*/
BOOLEAN
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);
}
BOOLEAN
Hal4ATA_IsLBAmode(void)
{
// if( ATADevExt_IDData.CurrentSectorCapacity.u0 >= ((INT32) 63<<14) ) /*63* 1024 * 16*/
// {
Hal4ATA_DevReg_LBA = 1;
// }
// else
// {
// Hal4ATA_DevReg_LBA = 0;
// }
return(Hal4ATA_DevReg_LBA);
}
BOOLEAN
Hal4ATA_IsModeOK(void)
{
/*
// This hideous hack is to deal with ESDI devices that return
// garbage geometry in the IDENTIFY data.
// This is ONLY for the crashdump environment as
// these are ESDI devices.
*/
ATABF_IsSkipSetParameters = FALSE;
if (Hal4ATA_DevExt.IdentifyData.SectorsPerTrack == 0x35 &&
ATADevExt_IDData.NumberOfHeads == 0x07)
{
/*
// Change these values to something reasonable.
*/
ATADevExt_IDData.SectorsPerTrack = 0x34;
ATADevExt_IDData.NumberOfHeads = 0x0E;
}
if (ATADevExt_IDData.SectorsPerTrack == 0x35 &&
ATADevExt_IDData.NumberOfHeads == 0x0F)
{
/*
// Change these values to something reasonable.
*/
ATADevExt_IDData.SectorsPerTrack = 0x34;
ATADevExt_IDData.NumberOfHeads = 0x0F;
}
if (ATADevExt_IDData.SectorsPerTrack == 0x36 &&
ATADevExt_IDData.NumberOfHeads == 0x07)
{
/*
// Change these values to something reasonable.
*/
ATADevExt_IDData.SectorsPerTrack = 0x3F;
ATADevExt_IDData.NumberOfHeads = 0x10;
ATABF_IsSkipSetParameters = TRUE;
}
return ATABF_IsSkipSetParameters;
}
BOOLEAN
Hal4ATA_SetFeature(void)
{
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);
}
BOOLEAN
Hal4ATA_SetDriveParameters(void)
{
BOOLEAN retStatus = FALSE;
if(Hal4ATA_WaitOnBusy())
{
/*
// Set up registers for SET PARAMETER command.
*/
//Hal4Sys_ATAPortOutB(ATAREG4OUT_DEVICE_HEAD,Hal4ATA_DevReg|(ATADevExt_IDData.NumberOfHeads-1) );
Hal4Sys_ATAPortOutB(ATAREG4OUT_DEVICE_HEAD,0xef );
//Hal4Sys_ATAPortOutB(ATAREG4OUT_SECTOR_COUNT,ATADevExt_IDData.SectorsPerTrack);
Hal4Sys_ATAPortOutB(ATAREG4OUT_SECTOR_COUNT,0x20);
if(Hal4ATA_WaitOnBusyNDrdy())
{
/*
// Send SET PARAMETER command.
// IDE_COMMAND_SET_DRIVE_PARAMETERS 0x91 (Init Device Parameter)
*/
Hal4Sys_ATAPortOutB(ATAREG4OUT_COMMAND,IDE_COMMAND_SET_DRIVE_PARAMETERS);
retStatus = Hal4ATA_WaitOnBusy();
}
}
return retStatus;
} /* end Hal4ATA_SetDriveParameters()*/
BOOLEAN
Hal4ATA_SetMultipleMode(void) //IDE_COMMAND_SET_MULTIPLE=0xC6
{
BOOLEAN retStatus = FALSE;
if ( ATABF_IsAttached && Hal4ATA_SelDevice() )
{
if(ATADevExt_IDData.MaximumBlockTransfer > MULTI_BLOCK_1 )
{
// Hal4Sys_ATAPortOutB(ATAREG4OUT_SECTOR_COUNT, ATADevExt_IDData.MaximumBlockTransfer);
// Hal4Sys_ATAPortOutB(ATAREG4OUT_COMMAND, IDE_COMMAND_SET_MULTIPLE);
if( Hal4ATA_WaitOnBusy())
{
ATABF_IsSupportMultiSector = TRUE;
retStatus = TRUE;
}
else
{
ATABF_IsSupportMultiSector = FALSE;
}
}
else
{
ATABF_IsSupportMultiSector = FALSE;
}
if(ATABF_IsSupportMultiSector == FALSE)
{
retStatus = Hal4ATA_IdeSoftReset();
}
}
return retStatus;
}
/*
//*************************************************************************
// Subroutines -- level 5 ATA transaction
//*************************************************************************
*/
BOOLEAN
Hal4ATA_IdeHardReset(void)
{
INT8 c,a,b,d,e;
BOOLEAN retStatus = FALSE;
ATA_RST_N = 0;
Hal4Sys_WaitInUS(320); // >25 US
ATA_RST_N = 1;
/*
while (TRUE)
{ a= Hal4Sys_ATAPortInB(ATAREG4IN_SECTOR_COUNT);
b = Hal4Sys_ATAPortInB(ATAREG4IN_SECTOR_NUMBER);
d = Hal4Sys_ATAPortInB(ATAREG4IN_CYLINDER_LOW);
e = Hal4Sys_ATAPortInB(ATAREG4IN_CYLINDER_HIGH);
if ( (d+e >0) && (a+b >2))
{ATA_RST_N = 0;
Hal4Sys_WaitInUS(320); // >25 US
ATA_RST_N = 1;
}
else
break;
}
*/
for(c = 20; c != 0; c--)
Hal4Sys_WaitInUS(50000); // 50MS
if(Hal4ATA_SelDevice())
{
Hal4ATA_DevReg_DEV = FALSE;
Hal4Sys_ATAPortOutB(ATAREG4OUT_DEVICE_HEAD,Hal4ATA_DevReg);
}
#ifndef DEBUG
for(c = 31; c!=0; c--) // 31 Seconds time out
#else
while(TRUE)
#endif
{
if(Hal4ATA_WaitOnBusyNDrdy())
{
retStatus = TRUE;
break;
}
}
// MCU_P1 = D12REG_ONLY;
return retStatus;
}
BOOLEAN
Hal4ATA_FindIDEDevice(void)
{
INT8 c;
ATABF_IsAttached = FALSE;
Hal4ATA_DevReg_DEV = FALSE;
if(Hal4ATA_IdeHardReset())
{
// Hal4Sys_ATAPortOutB(ATAREG4OUT_CONTROL,0xFA);
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();
if(!Hal4ATA_DevReg_LBA)
{
// Being cautious,
// CHS Harddisk set block=1
ATADevExt_IDData.MaximumBlockTransfer = 1;
}
if( Hal4ATA_IsModeOK() == FALSE)
{
ATABF_IsAttached = Hal4ATA_SetDriveParameters();
}
if(ATABF_IsAttached)
{
ATABF_IsAttached = Hal4ATA_SetMultipleMode();
}
} // IDE HD is found
//Hal4Sys_ATAPortOutB(ATAREG4OUT_CONTROL,0xFA);
} // IDE Reset OK
// MCU_P1 = D12REG_ONLY; //D12REG_ONLY =0xB8
return ATABF_IsAttached;
} /*end Hal4ATA_FindIDEDevice()*/
BOOLEAN
Hal4ATA_ReadWriteSetting(void)
{
BOOLEAN retStatus = FALSE;
/*
// Select device .
*/
if(Hal4ATA_SelDevice())
//if(TRUE)
{
//Assume Sector Counter <256
Hal4Sys_ATAPortOutB(ATAREG4OUT_SECTOR_COUNT, RBC_CDB.RbcCdb_Read.XferLength_0);
if(Hal4ATA_DevReg_LBA )
/* IN LBA mode */
{
/*
// Set up sector number register.
*/
/* From Read Card Capacity()
cdbReadCap.tmpVar.CapData.LBA_3 =cdbReadCap.tmpVar.l0[1].chars0.c3;
cdbReadCap.tmpVar.CapData.LBA_2 =cdbReadCap.tmpVar.l0[1].chars0.c2;
cdbReadCap.tmpVar.CapData.LBA_1 =cdbReadCap.tmpVar.l0[1].chars0.c1;
cdbReadCap.tmpVar.CapData.LBA_0 =cdbReadCap.tmpVar.l0[1].chars0.c0;
*/
//-----------------------------------------
if( ATABF_IDEXfer_dir ) // ATABF_Xfer_dir==1 Read(from Dev to Host)
{
Hal4Sys_ATAPortOutB(ATAREG4OUT_SECTOR_NUMBER,RBC_CDB.RbcCdb_Read.LBA.LBA_W8.LBA_0);
Hal4Sys_ATAPortOutB(ATAREG4OUT_CYLINDER_LOW,RBC_CDB.RbcCdb_Read.LBA.LBA_W8.LBA_1);
Hal4Sys_ATAPortOutB(ATAREG4OUT_CYLINDER_HIGH,RBC_CDB.RbcCdb_Read.LBA.LBA_W8.LBA_2);
Hal4Sys_ATAPortOutB(ATAREG4OUT_DEVICE_HEAD, (RBC_CDB.RbcCdb_Read.LBA.LBA_W8.LBA_3&0x0f) | Hal4ATA_DevReg );
}
else
{
// write command.
Hal4Sys_ATAPortOutB(ATAREG4OUT_SECTOR_NUMBER,RBC_CDB.RbcCdb_Write.LBA.LBA_W8.LBA_0);
Hal4Sys_ATAPortOutB(ATAREG4OUT_CYLINDER_LOW,RBC_CDB.RbcCdb_Write.LBA.LBA_W8.LBA_1);
Hal4Sys_ATAPortOutB(ATAREG4OUT_CYLINDER_HIGH,RBC_CDB.RbcCdb_Write.LBA.LBA_W8.LBA_2);
Hal4Sys_ATAPortOutB(ATAREG4OUT_DEVICE_HEAD, (RBC_CDB.RbcCdb_Write.LBA.LBA_W8.LBA_3&0x0f) | Hal4ATA_DevReg );
}
//----------------------------------------
}
else
/* CHS mode */
{
/*
// Set up sector number register.
*/
Hal4Sys_ATAPortOutB(ATAREG4OUT_SECTOR_NUMBER,(INT8) ((RBC_CDB.RbcCdb_Read.LBA.LBA_W32 % ATADevExt_IDData.SectorsPerTrack) + 1));
/*
// Caculate Hal4ATA_Track & Hal4ATA_drvSelect
*/
Hal4ATA_Track.u0 = RBC_CDB.RbcCdb_Read.LBA.LBA_W32/((INT32)(ATADevExt_IDData.SectorsPerTrack));
Hal4ATA_drvSelect = (INT8)(Hal4ATA_Track.u0%ATADevExt_IDData.NumberOfHeads);
Hal4ATA_Track.u0 /= ((INT32)(ATADevExt_IDData.NumberOfHeads));
/*
// Set up cylinder low register.
*/
Hal4Sys_ATAPortOutB(ATAREG4OUT_CYLINDER_LOW,Hal4ATA_Track.chars0.c0);
Hal4Sys_ATAPortOutB(ATAREG4OUT_CYLINDER_HIGH,Hal4ATA_Track.chars0.c1);
/*
// Set up head and drive select register.
*/
Hal4Sys_ATAPortOutB(ATAREG4OUT_DEVICE_HEAD, Hal4ATA_DevReg|Hal4ATA_drvSelect);
}
if( ATABF_IDEXfer_dir ) // ATABF_Xfer_dir==1 Read(from Dev to Host)
{
/*
// Send read command.
*/
// if (ATABF_IsSupportMultiSector)
// Hal4Sys_ATAPortOutB(ATAREG4OUT_COMMAND, IDE_COMMAND_READ_MULTIPLE);
// else
Hal4Sys_ATAPortOutB(ATAREG4OUT_COMMAND, IDE_COMMAND_READ);
}
else
{
/*
// Send write command.
*/
// if (ATABF_IsSupportMultiSector)
// Hal4Sys_ATAPortOutB(ATAREG4OUT_COMMAND,IDE_COMMAND_WRITE_MULTIPLE);
// else
Hal4Sys_ATAPortOutB(ATAREG4OUT_COMMAND,IDE_COMMAND_WRITE);
}
retStatus = Hal4ATA_WaitOnBusyNDrq();
}
// MCU_P1 = D12REG_ONLY;
return retStatus;
} /* end Hal4ATA_ReadWriteSetting()*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -