📄 doch_api.c
字号:
/*Check if socket is registered*/
if(pdev != NULL)
{
/*Enter dev0 to DPD mode*/
/*----------------------*/
/*Set device*/
DOCHWRITE_ATA_REG (pdev->bRegBase, DOCH_DRIVE_HEAD_REG, 0);
/*Set device to inactive mode*/
DOCHWRITE_ATA_REG (pdev->bRegBase, DOCH_SECTOR_CNT_REG, (DOCH_PM_SET_NONE | DOCH_PM_INACTIVE_MODE));
/*Invoke command*/
DOCHWRITE_ATA_REG (pdev->bRegBase, DOCH_FEATURES_REG, DOCH_SET_POWER_MODE);
DOCHWRITE_ATA_REG (pdev->bRegBase, DOCH_COMMAND_REG, DOCH_VSCMD_EXT_DEVICE_CTRL);
/*Wait for Dev0 to become ready*/
for(i=0; i<tries; i++)
{
status = DOCHREAD_ATA_REG(pdev->bRegBase, DOCH_STATUS_REG);
if((status & (DOCH_READY | DOCH_BUSY)) == DOCH_READY)
goto doch_Dev0_DPD_OK;
}
doch_Dev0_DPD_OK:
if(pdev->wNumOfDevices > 1)
{
/*Enter dev1 to DPD mode*/
/*----------------------*/
/*Set device*/
DOCHWRITE_ATA_REG (pdev->bRegBase, DOCH_DRIVE_HEAD_REG, DOCH_DEVICE);
/*Set device to inactive mode*/
DOCHWRITE_ATA_REG (pdev->bRegBase, DOCH_SECTOR_CNT_REG, (DOCH_PM_SET_NONE | DOCH_PM_INACTIVE_MODE));
/*Invoke command*/
DOCHWRITE_ATA_REG (pdev->bRegBase, DOCH_FEATURES_REG, DOCH_SET_POWER_MODE);
DOCHWRITE_ATA_REG (pdev->bRegBase, DOCH_COMMAND_REG, DOCH_VSCMD_EXT_DEVICE_CTRL);
/*Wait for Dev1 to become ready*/
for(i=0; i<tries; i++)
{
status = DOCHREAD_ATA_REG(pdev->bRegBase, DOCH_STATUS_REG);
if((status & (DOCH_READY | DOCH_BUSY)) == DOCH_READY)
goto doch_Dev1_DPD_OK;
}
doch_Dev1_DPD_OK:
/*Do Nothing*/;
}
}
}
#endif /*DOCH_AUTO_DPD_BY_HOST*/
/* Free mutex for current device */
dochSetMutex(DOCH_GET_SOCKET_FROM_IOREQ_HANDLE(ioreq),
DOCH_OFF,
DOCH_GET_PARTITION_FROM_IOREQ_HANDLE(ioreq));
#ifdef CHECK_POWER_ON_EVERY_COMMAND
/*In case Power Fail was detected, return DOCH_DeviceTurnedOff*/
if(gDeviceTurnedOff)
{
return DOCH_DeviceTurnedOff;
}
#endif /*CHECK_POWER_ON_EVERY_COMMAND*/
return rc;
}
/*----------------------------------------------------------------------*/
/* D O C H S e t D e f a u l t P a r t i t i o n */
/* */
/* Set default partition for Standard-ATA commands */
/* */
/* Parameters: */
/* irHandle : Socket number (zero based) */
/* Partition number (zero based) */
/* irCount : SET_DEFAULT_PARTITION_TEMP */
/* SET_DEFAULT_PARTITION_PERM */
/* */
/* ATA command: */
/* DOCH_VSCMD_PARTITION_MANAGEMENT */
/* ATA sub-command: */
/* DOCH_SET_DEFAULT_PARTITION */
/* */
/* Returns: */
/* DOCH_Error : 0 on success, otherwise failed */
/*----------------------------------------------------------------------*/
DOCH_Error DOCHSetDefaultPartition(IOreq* ioreq)
{
DOCH_Error rc;
DOCH_Registers in_regs;
DOCH_Registers out_regs;
FLByte dev_head_opt;
DOCH_Socket* pdev;
DOCH_get_socket(pdev, DOCH_GET_SOCKET_FROM_IOREQ_HANDLE(ioreq));
/*If socket is not registered, return error*/
if(pdev == NULL)
return DOCH_DiskNotFound;
/*Check if Partition exceeds number of existing partitions*/
/*--------------------------------------------------------*/
if(DOCH_GET_PARTITION_FROM_IOREQ_HANDLE(ioreq) >= pdev->device[pdev->bAtaDevNum].wNumOfPartitions)
return DOCH_PartitionNotFound;
if(ioreq->irCount == SET_DEFAULT_PARTITION_PERM)
dev_head_opt = PERM_DEFAULT_PART_OP;
else
dev_head_opt = 0;
/*Update ATA register values*/
/*--------------------------*/
in_regs.bFeaturesError = DOCH_SET_DEFAULT_PARTITION;
in_regs.bSectorCount = DOCH_GET_PARTITION_FROM_IOREQ_HANDLE(ioreq);
in_regs.bSectorNumber = 0;
in_regs.bCylLow = 0;
in_regs.bCylHigh = 0;
in_regs.bDriveHead = ((pdev->bAtaDevNum * DOCH_DEVICE) | (dev_head_opt));
in_regs.bCommandStatus = DOCH_VSCMD_PARTITION_MANAGEMENT;
/*Activate ATA command*/
/*--------------------*/
rc = doch_command ( DOCH_GET_SOCKET_FROM_IOREQ_HANDLE(ioreq),
pdev->bAtaDevNum,
&in_regs,
&out_regs,
NULL,
0);
if(rc == DOCH_OK)
return DOCH_OK;
else
{
DBG_PRINT_ERR(FLZONE_API, "DOCHSetDefaultPartition(): failed with status: ");
DBG_PRINT_ERR_PRM(FLZONE_API, (FLTXT("0x%x \r\n"), rc));
return DOCH_GeneralFailure;
}
}
/*----------------------------------------------------------------------*/
/* D O C H S e t D a t a T r a n s f e r M o d e */
/* */
/* Set Data transfer mode */
/* */
/* Parameters: */
/* irHandle : Socket number (zero based) */
/* irCount : Requested data transfer mode: */
/* DOCH_DATA_XFER_MODE_SINGLE */
/* DOCH_DATA_XFER_MODE_MULT */
/* irLength : In case of DOCH_DATA_XFER_MODE_MULT, */
/* specifies DRQ block size */
/* */
/* ATA command: */
/* DOCH_VSCMD_EXT_DEVICE_CTRL */
/* ATA sub-command: */
/* DOCH_SET_DATA_XFER_MODE */
/* */
/* Returns: */
/* DOCH_Error : 0 on success, otherwise failed */
/*----------------------------------------------------------------------*/
DOCH_Error DOCHSetDataTransferModeSingleFloor(IOreq* ioreq)
{
DOCH_Error rc;
DOCH_Registers in_regs;
DOCH_Registers out_regs;
DOCH_TransferMode requstedXferMode = (DOCH_TransferMode)(ioreq->irCount);
FLByte requestedDrqSize = (FLByte)(ioreq->irLength);
FLSNative socketNum = DOCH_GET_SOCKET_FROM_IOREQ_HANDLE(ioreq);
DOCH_Socket* pdev;
DOCH_get_socket(pdev, socketNum);
/*If socket is not registered, return error*/
if(pdev == NULL)
return DOCH_DiskNotFound;
/*Check that Multi-sector transfer mode does not exceed max allowed*/
if((ioreq->irCount == DOCH_DATA_XFER_MODE_MULT) &&
((ioreq->irLength > DOCH_MAX_DRQ_SUPPORTED) ||
(ioreq->irLength > (FLSDword)pdev->device[pdev->bAtaDevNum].dwMulti_MAX))
)
return DOCH_FeatureNotSupported;
/*Update ATA register values*/
/*--------------------------*/
in_regs.bFeaturesError = DOCH_SET_DATA_XFER_MODE;
in_regs.bSectorCount = (FLByte)(ioreq->irCount);
if(ioreq->irCount == DOCH_DATA_XFER_MODE_MULT)
in_regs.bSectorNumber = (FLByte)(ioreq->irLength);
else
in_regs.bSectorNumber = 0;
in_regs.bCylLow = 0;
in_regs.bCylHigh = 0;
in_regs.bDriveHead = (pdev->bAtaDevNum * DOCH_DEVICE);
in_regs.bCommandStatus = DOCH_VSCMD_EXT_DEVICE_CTRL;
/*Activate ATA command*/
/*--------------------*/
rc = doch_command ( socketNum,
pdev->bAtaDevNum,
&in_regs,
&out_regs,
NULL,
0);
if(rc == DOCH_OK)
{
/*If operation succeeded - update transfer mode in SDK as well*/
/*------------------------------------------------------------*/
rc = doch_setTransferMode(socketNum, pdev->bAtaDevNum, requstedXferMode, requestedDrqSize);
return rc;
}
else
{
DBG_PRINT_ERR(FLZONE_API, "DOCHSetDataTransferMode(): failed with status: ");
DBG_PRINT_ERR_PRM(FLZONE_API, (FLTXT("0x%x \r\n"), rc));
return DOCH_GeneralFailure;
}
}
DOCH_Error DOCHSetDataTransferMode(IOreq* ioreq)
{
DOCH_Error rc = DOCH_OK;
DOCH_Socket* pdev;
DOCH_get_socket(pdev, DOCH_GET_SOCKET_FROM_IOREQ_HANDLE(ioreq));
/*If socket is not registered, return error*/
if(pdev == NULL)
return DOCH_DiskNotFound;
pdev->bAtaDevNum = 0;
rc = DOCHSetDataTransferModeSingleFloor(ioreq);
if(rc != DOCH_OK)
return rc;
if(pdev->wNumOfDevices > 1)
{
pdev->bAtaDevNum = 1;
rc = DOCHSetDataTransferModeSingleFloor(ioreq);
pdev->bAtaDevNum = 0;
}
return rc;
}
/*----------------------------------------------------------------------*/
/* D O C H I d e n t i f y D i s k O n C h i p D e v i c e */
/* */
/* Returns general information about the Device */
/* */
/* Parameters: */
/* irHandle : Socket number (zero based) */
/* irCount : DOCH_IDENTIFY_FROM_FLASH */
/* DOCH_IDENTIFY_EXISTANCE */
/* irData : Address of DOCH_DeviceInfo struct */
/* */
/* ATA command: */
/* DOCH_VSCMD_EXT_DEVICE_CTRL */
/* ATA sub-command: */
/* DOCH_IDENTIFY_DISKONCHIP_DEVICE */
/* */
/* Returns: */
/* DOCH_Error : 0 on success, otherwise failed */
/*----------------------------------------------------------------------*/
DOCH_Error DOCHIdentifyDiskOnChipDeviceSingleFloor(IOreq* ioreq)
{
DOCH_Error rc;
DOCH_Socket* pdev;
DOCH_DeviceInfo* localDiskOnChipDeviceInfo = (DOCH_DeviceInfo*)(ioreq->irData);
FLSNative devNum;
DOCH_Registers in_regs;
DOCH_Registers out_regs;
DOCH_get_socket(pdev, DOCH_GET_SOCKET_FROM_IOREQ_HANDLE(ioreq));
/*If socket is not registered, return error*/
if(pdev == NULL)
return DOCH_DiskNotFound;
devNum = pdev->bAtaDevNum;
/*Update ATA register values*/
/*--------------------------*/
in_regs.bFeaturesError = DOCH_IDENTIFY_DISKONCHIP_DEVICE;
in_regs.bSectorCount = 0;
in_regs.bSectorNumber = 0;
in_regs.bCylLow = 0;
in_regs.bCylHigh = 0;
in_regs.bDriveHead = ((pdev->bAtaDevNum * DOCH_DEVICE) | ((FLByte)ioreq->irCount));
in_regs.bCommandStatus = DOCH_VSCMD_EXT_DEVICE_CTRL;
/*Activate ATA command*/
/*--------------------*/
rc = doch_command ( DOCH_GET_SOCKET_FROM_IOREQ_HANDLE(ioreq),
devNum,
&in_regs,
&out_regs,
ioreq->irData,
sizeof(DOCH_DeviceInfo) / DOCH_SECTOR_SIZE);
#ifdef DOCH_BIG_ENDIAN
/*In case of a BIG ENDIAN host CPU, reorder bytes in 16 and 32 Bit variables*/
localDiskOnChipDeviceInfo->wVersion = be_FLWord((FLByte*)&localDiskOnChipDeviceInfo->wVersion);
localDiskOnChipDeviceInfo->dwCommandFlagsOrStatuses = be_FLDword((FLByte*)&localDiskOnChipDeviceInfo->dwCommandFlagsOrStatuses);
localDiskOnChipDeviceInfo->dwDiskAttributes1 = be_FLDword((FLByte*)&localDiskOnChipDeviceInfo->dwDiskAttributes1);
localDiskOnChipDeviceInfo->dwRservedGateKeeperAttr = be_FLDword((FLByte*)&localDiskOnChipDeviceInfo->dwRservedGateKeeperAttr);
localDiskOnChipDeviceInfo->wTotalNumOfPartitions = be_FLWord((FLByte*)&localDiskOnChipDeviceInfo->wTotalNumOfPartitions);
localDiskOnChipDeviceInfo->wDefaultPartitionNumber = be_FLWord((FLByte*)&localDiskOnChipDeviceInfo->wDefaultPartitionNumber);
localDiskOnChipDeviceInfo->dwUnformattedCapacity = be_FLDword((FLByte*)&localDiskOnChipDeviceInfo->dwUnformattedCapacity);
localDiskOnChipDeviceInfo->dwReservedConfigPartitionSize = be_FLDword((FLByte*)&localDiskOnChipDeviceInfo->dwReservedConfigPartitionSize);
localDiskOnChipDeviceInfo->dwUnitSize = be_FLDword((FLByte*)&localDiskOnChipDeviceInfo->dwUnitSize);
localDiskOnChipDeviceInfo->dwConfigurationPartitionExistsSign = be_FLDword((FLByte*)&localDiskOnChipDeviceInfo->dwConfigurationPartitionExistsSign);
#endif /*DOCH_BIG_ENDIAN*/
/*Update device structure*/
/*=======================*/
if(rc == DOCH_OK)
{
/*ETFFS detected*/
pdev->device[devNum].ETFFS_Identified = TRUE;
/*Extract MAX DRQ size from the Disk Attributes field*/
pdev->device[devNum].dwMulti_MAX = (1 <<
((localDiskOnChipDeviceInfo->dwDiskAttributes1 & DOCH_DA1B_MAX_MULTI_SEC_XFER_SIZE) >> DOCH_DA1O_MAX_MULTI_SEC_XFER_SIZE));
if((localDiskOnChipDeviceInfo->dwUnformattedCapacity != 0) &&
(localDiskOnChipDeviceInfo->wVersionCompatability == 0)
#ifndef DOCH_DONT_CHECK_EXISTANCE_SIGN
&& (localDiskOnChipDeviceInfo->dwConfigurationPartitionExistsSign == DOCH_CONFIGURATION_EXISTS_SIGN)
#endif /*DOCH_DONT_CHECK_EXISTANCE_SIGN*/
)
{
rc = update_device_info(pdev, localDiskOnChipDeviceInfo, devNum);
#ifdef CHECK_POWER_ON_EVERY_COMMAND
{
IOreq ioreq2;
/*Make sure next calls to DOCHGetResetStatus() will reflect actual reset*/
tffsset(&ioreq2, 0, sizeof(ioreq2));
ioreq2.irHandle = ioreq->irHandle;
DOCHGetResetStatus(&ioreq2);
}
#endif /*CHECK_POWER_ON_EVERY_COMMAND*/
return DOCH_OK;
}
DBG_PRINT_ERR(FLZONE_API, "ERROR: DOCHIdentifyDiskOnChipDevice(): read incorrect data\r\n");
}
if(devNum == 0)
{
DBG_PRINT_ERR(FLZONE_API, "ERROR: DOCHIdentifyDiskOnChipDevice(): failed with status: ");
DBG_PRINT_ERR_PRM(FLZONE_API, (FLTXT("0x%x \r\n"), rc));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -