📄 ide_ata.c
字号:
ATA_REG_STATUS
);
// Device is not busy, check DRQ
if ( !(status & ATA_STATUS_BSY) &&
((status & ATA_STATUS_DRDY) == ATA_STATUS_DRDY) )
{
/* BSY = 0, DRQ = ATA_STATUS_DRDY */
break;
}
// Check for timeout
if ( (tickGet() - tickCnt) > HD_WAIT_TIMEOUT )
{
TRACE_ERROR("<ide_command_media> Timeout Waiting For Drive Drdy 2\n");
//soft_assert(0);
ATA_WriteRegister(driveID, ATA_REG_DEVICE_CONTROL, ATA_DEVICE_CTRL_SRT_BIT | ATA_DEVICE_CTRL_nIEN_BIT);
ATA_ReleaseDevice(driveID);
ATA_ReleaseBus (driveID);
return (IDE_ERRORCODE_TIMEOUT);
}
}
if ((status & ATA_STATUS_ERR) == ATA_STATUS_ERR)
{
retVal = ATA_ReadRegister(driveID, ATA_REG_ERROR);
}
else
{
retVal = ATA_SUCCESS;
}
ATA_ReleaseDevice(driveID);
ATA_ReleaseBus (driveID);
return retVal;
}
#else
Int32 ide_command_media(Uint8 driveID)
{
IDE_Cmd cmd;
cmd.cmdCode = IDE_CMD_MEDIA;
cmd.sectorCntReg = 0;
cmd.lba = 0;
cmd.driveID = driveID;
if( diskDesc[driveID].MediaDeviceBrand == MEDIADEVICE_BRAND_ONSPEC)
{
cmd.featureReg = 0;
}else
{
cmd.featureReg = 1;
}
cmd.pktCmd = NULL;
cmd.pktCmdSize = 0;
cmd.data = NULL;
cmd.deviceReg = 0;
cmd.readWrite = 0;
cmd.maxDataSize = 0;
cmd.ext_cmd = FALSE;
return IDE_SendCmd(&cmd);
}
#endif
static Int32 ide_initial_devices(Uint8 current_driveID)
{
Int32 retVal = SUCCESS;
if ( diskDesc[current_driveID].IsRemovableMediaDevice)
retVal = ide_command_enable_msns(current_driveID);
return retVal;
}
Int32 ide_change_status(Uint8 driveID, IDE_STATE status)
{
switch (status)
{
case IDE_STATE_UPGRADE_FIRMWARE:
diskDesc[driveID].state= IDE_STATE_UPGRADE_FIRMWARE;
break;
case IDE_STATE_IDLE:
diskDesc[driveID].state= IDE_STATE_IDLE;
break;
default :
break;
}
return SUCCESS;
}
Int32 ide_inquire_media(Uint8 driveID)
{
Int32 retVal;
if (diskDesc[driveID].state == IDE_STATE_UPGRADE_FIRMWARE)
{
retVal = MEDIA_NO_MEDIA;
}
else if ( diskDesc[driveID].mediaChanged)
{
retVal = MEDIA_CHANGED;
}
else if ( diskDesc[driveID].IsRemovableMediaDevice)
{
if(ATA_reseted(driveID))
{
ide_initial_devices(driveID);
retVal = MEDIA_NO_MEDIA;
}
else
{
retVal = ide_command_media (driveID);
if (retVal == MEDIA_READING)
{
ide_initial_devices(driveID);
retVal = ide_command_media (driveID);
}
}
}
else
{
retVal = MEDIA_UNREMOVALBE;
}
diskDesc[driveID].mediaChanged = FALSE;
return retVal;
}
Int32 ide_command_enable_msns(Uint8 driveID)
{
IDE_Cmd cmd;
if ( diskDesc[driveID].MediaDeviceBrand == MEDIADEVICE_BRAND_SAIN)
{
return SUCCESS;
}
cmd.cmdCode = IDE_CMD_MSNS;
cmd.sectorCntReg = 0;
cmd.lba = 0;
cmd.driveID = driveID;
cmd.featureReg = 0x95;
cmd.pktCmd = NULL;
cmd.pktCmdSize = 0;
cmd.data = NULL;
cmd.deviceReg = 0;
cmd.readWrite = 0;
cmd.maxDataSize = 0;
cmd.ext_cmd = FALSE;
return IDE_SendCmd(&cmd);
}
Int32 ide_command_disable_msns(Uint8 driveID)
{
IDE_Cmd cmd;
if ( diskDesc[driveID].MediaDeviceBrand == MEDIADEVICE_BRAND_SAIN)
{
return SUCCESS;
}
cmd.cmdCode = IDE_CMD_MSNS;
cmd.sectorCntReg = 0;
cmd.lba = 0;
cmd.driveID = driveID;
cmd.featureReg = 0x31;
cmd.pktCmd = NULL;
cmd.pktCmdSize = 0;
cmd.data = NULL;
cmd.deviceReg = 0;
cmd.readWrite = 0;
cmd.maxDataSize = 0;
cmd.ext_cmd = FALSE;
return IDE_SendCmd(&cmd);
}
int ide_invalidate(Uint8 driveID)
{
Uint32 i;
for (i = 0; i < (NDISKS * NDRIVES); i++)
{
if ((driveDesc[i].fat_type != 0) &&
(driveDesc[i].phys_disk == driveID))
{
if (driveDesc[i].open_count > 0)
return IDE_BADDRIVE;
driveDesc[i].fat_type = 0;
driveDesc[i].drv_start = 0L;
driveDesc[i].drv_end = 0L;
driveDesc[i].open_count= 0;
driveDesc[i].phys_disk = 0; // we'll need to change that if we want to support several HD
driveDesc[i].part_no = 0;
}
}
if (diskDesc[driveID].IsRemovableMediaDevice)
{
diskDesc[driveID].driveID = 0;
diskDesc[driveID].maxLBA = 0;
diskDesc[driveID].maxMultipleTransfer = 0;
diskDesc[driveID].currentMultipleTransfer = 0;
diskDesc[driveID].supports48bitAddFeatureSet = FALSE;
diskDesc[driveID].initialized = FALSE;
diskDesc[driveID].mediaChanged = FALSE;
}
else
{
diskDesc[driveID].driveID = 0;
diskDesc[driveID].maxLBA = 0;
diskDesc[driveID].maxMultipleTransfer = 0;
diskDesc[driveID].currentMultipleTransfer = 0;
diskDesc[driveID].IsRemovableMediaDevice = FALSE;
diskDesc[driveID].supports48bitAddFeatureSet = FALSE;
diskDesc[driveID].initialized = FALSE;
diskDesc[driveID].mediaChanged = FALSE;
}
// Close the ide
closeCache(&ide_cache[driveID]);
return SUCCESS;
}
Int32 ide_reset_MBR(Uint8 driveID)
{
// Disk must be invalidated after reset MBR
Int32 ret = SUCCESS;
diskDesc[driveID].driveID = driveID;
TRACE_48BIT("ide_reset_MBR - calling ide_controller_init on phys_disk: %d\n", driveID);
if (ide_controller_init(&(diskDesc[driveID])))
{
ret = IDE_INTERNAL;
goto IDE_RESET_MBR_EXIT;
}
// Now reset the MBR
soft_assert(writeMBR(driveID, 0, diskDesc[driveID].maxLBA) == SUCCESS);
IDE_RESET_MBR_EXIT:
soft_assert(ide_invalidate(driveID) == SUCCESS);
return ret;
}
//-----------------------------------------------------------------------------
// Function: ide_open
//
// Description:
// Open function. This is pointed to by the bdevsw[] table
//
//
// Returns: Uint8
//
//
//-----------------------------------------------------------------------------
#ifdef FORCE_FORMAT
static Boolean force_format_flag = TRUE;
#endif
int ide_open(Uint8 driveID, Uint8 partno, Boolean force_format, Uint8 *driveno)
{
Int32 ret = SUCCESS;
Uint32 i, index;
Uint32 part_count;
DEBUG_OUT("ide_open1 driverId %d\n",driveID);
if (!ide_initialized) // Nothing has been initialized yet...
{
for (index = 0; index < NDISKS; index++)
{
diskDesc[index].driveID = 0;
diskDesc[index].maxLBA = 0;
diskDesc[index].maxMultipleTransfer = 0;
diskDesc[index].currentMultipleTransfer = 0;
diskDesc[index].initialized = FALSE;
diskDesc[index].IsRemovableMediaDevice = FALSE;
diskDesc[index].supports48bitAddFeatureSet = FALSE;
diskDesc[index].state = IDE_STATE_IDLE;
ide_cache[index].pages = NULL;
ide_cache[index].data = NULL;
}
for (index = 0; index < (NDRIVES * NDISKS); index++)
{
driveDesc[index].fat_type = 0;
driveDesc[index].drv_start = 0L;
driveDesc[index].drv_end = 0L;
driveDesc[index].open_count= 0;
driveDesc[index].phys_disk = 0; // we'll need to change that if we want to support several HD
driveDesc[index].part_no = 0;
}
ide_initialized = TRUE;
}
if (diskDesc[driveID].initialized == FALSE)
{
Boolean reset_mbr = FALSE;
for (i = 0; i < (NDISKS * NDRIVES); i++)
{
// Any thing corresponding to this phys_disk needs to be erased
// Nothing must be pointing to the physical disk it must have been invalidated previously
if ((driveDesc[i].fat_type != 0) && (driveDesc[i].phys_disk == driveID))
{
soft_assert(0);
}
}
// Reset the current variable
soft_assert(diskDesc[driveID].driveID == 0);
soft_assert(diskDesc[driveID].maxLBA == 0);
soft_assert(diskDesc[driveID].maxMultipleTransfer == 0);
soft_assert(diskDesc[driveID].currentMultipleTransfer == 0);
//soft_assert(diskDesc[driveID].initialized == FALSE);
//soft_assert(diskDesc[driveID].IsRemovableMediaDevice == FALSE);
soft_assert(diskDesc[driveID].supports48bitAddFeatureSet == FALSE);
part_count = 0;
ret = ide_init_drive(driveID, &part_count);
#ifdef FORCE_FORMAT
if (force_format_flag == TRUE)
{
ret = IDE_BADMBR;
soft_assert(ide_invalidate(driveID) == SUCCESS);
}
#endif
// Handle error codes
switch(ret)
{
case IDE_BADMBR:
if (force_format == TRUE)
reset_mbr = TRUE;
break;
case SUCCESS:
case IDE_IO_ERROR:
break;
default:
soft_assert(0);
break;
}
// Handle 0 partition
if ((part_count == 0) && (force_format == TRUE))
{
if (force_format == TRUE)
reset_mbr = TRUE;
else
ret = IDE_BADMBR;
}
// We don't check for multiple partition and if the single
// partition does not span entire HDD here
// This is because opening a drive should not make any assumption
// When the user decides to format, we will give the option
// to wipe the MBR and not just the partition
if (reset_mbr == TRUE)
{
//soft_assert(ide_invalidate(driveID) == SUCCESS);
soft_assert(ide_reset_MBR(driveID) == SUCCESS);
soft_assert(ide_init_drive(driveID, &part_count) == SUCCESS);
soft_assert(part_count == 1);
ret = IDE_MBR_RESET;
#ifdef FORCE_FORMAT
force_format_flag = FALSE;
#endif
}
DEBUG_OUT("ide init drive returning ret: %d containing: %d partitions driverID %d\n", ret, part_count,driveID);
}
else
{
/*
if ( diskDesc[driveID].IsRemovableMediaDevice)
{
if (ide_command_media (driveID))
{
return FAIL;
}
}
*/
}
//soft_assert(diskDesc[driveID].initialized == TRUE);
// If this partition does not exist then return fail
if (ret == SUCCESS)
{
Boolean drive_found = FALSE;
Uint8 drive_wanted, i;
drive_wanted = 0;
for (i = 0; i < (NDISKS * NDRIVES); i++)
{
if ((driveDesc[i].fat_type != 0) &&
(driveDesc[i].phys_disk == driveID) &&
(driveDesc[i].part_no == partno))
{
drive_wanted = i;
drive_found = TRUE;
}
}
if (drive_found == FALSE)
{
// Reset this to false for next time
diskDesc[driveID].initialized = FALSE;
LOG_DIAG_ERROR("ide_diag_open requested partition %d for disk: %d is invalid\n", partno, driveID);
return IDE_BADDRIVE;
}
else
{
(*driveno) = drive_wanted;
driveDesc[drive_wanted].open_count += 1;
}
soft_assert(diskDesc[driveID].initialized == TRUE);
}
else
{
LOG_DIAG_ERROR("ide_diag_open ide_init_drive failed with error code: %d\n", ret);
}
DEBUG_OUT("ide_open returns: %d driverID %d\n", ret,driveID);
return ret;
}
#if 0
int ide_open (Uint8 driveno, Boolean force_format)
{
STATUS ret = SUCCESS;
DEBUG_OUT("ide_open1\n");
//if (!ide_initialized) // Nothing has been initialized yet...
{
DEBUG_OUT("ide_open2\n");
ret = ide_init_drives(force_format);
}
if ((ret == SUCCESS) || (ret == IDE_REFORMAT_NEEDED))
{
DEBUG_OUT("ide_open4\n");
/* This just counts the number of calls after the initial Open ! */
driveDesc[driveno].open_count += 1;
}
return ret;
}
#endif
//-----------------------------------------------------------------------------
// Function:
//
// Description:
// Close function. This is pointed to by the bdevsw[] table
//
//
// Returns: Uint8
//
//
//-----------------------------------------------------------------------------
int ide_close(Uint8 driveno)
{
if (!driveDesc[driveno].open_count)
return IDE_BADDRIVE;
driveDesc[driveno].open_count -= 1;
return SUCCESS;
}
Int32 ide_init_media(Uint8 driveID)
{
Uint32 index;
if (!ide_initialized) // Nothing has been initialized yet...
{
for (index = 0; index < NDISKS; index++)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -