📄 doch_api.c
字号:
/* Set disk user attributes . */
/* */
/* Parameters: */
/* irHandle : Socket number (zero based) */
/* irData : Pointer to 1 sector of data */
/* */
/* ATA command: */
/* DOCH_VSCMD_EXT_DEVICE_CTRL */
/* ATA sub-command: */
/* DOCH_SET_DISK_USER_ATTR */
/* */
/* Returns: */
/* DOCH_Error : 0 on success, otherwise failed */
/*----------------------------------------------------------------------*/
DOCH_Error DOCHSetDiskUserAttributes(IOreq* ioreq)
{
DOCH_Error rc;
IOreq ioreq2;
DOCH_Registers in_regs;
DOCH_Registers out_regs;
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;
if(!gSDKUpdatesDiskAttributes)
{
/*First retrieve current attributes sector
(for protecting first 0x40 bytes that are SDK specific*/
/*------------------------------------------------------*/
tffscpy(&ioreq2, ioreq, sizeof(ioreq2));
ioreq2.irData = currentAttributes;
DOCHGetDiskUserAttributes(&ioreq2);
/*Use currentAttributes bytes 0x41..0x200 to set requested*/
/*--------------------------------------------------------*/
tffscpy(ioreq->irData, currentAttributes, DOCH_PART_INFO_SDK_RESERVED_BYTES);
}
/*Update ATA register values*/
/*--------------------------*/
in_regs.bFeaturesError = DOCH_SET_DISK_USER_ATTR;
in_regs.bSectorCount = 0;
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 ( DOCH_GET_SOCKET_FROM_IOREQ_HANDLE(ioreq),
pdev->bAtaDevNum,
&in_regs,
&out_regs,
ioreq->irData,
(1));
if(rc == DOCH_OK)
return DOCH_OK;
else
{
DBG_PRINT_ERR(FLZONE_API, "DOCHSetDiskUserAttributes(): failed with status: ");
DBG_PRINT_ERR_PRM(FLZONE_API, (FLTXT("0x%x \r\n"), rc));
if((rc & DOCH_ATA_ERROR_TRACK_0_NOT_FOUND) == DOCH_ATA_ERROR_TRACK_0_NOT_FOUND)
return DOCH_ProtectionFault;
else
return DOCH_GeneralFailure;
}
}
/*----------------------------------------------------------------------*/
/* f l D O C H G e t D i s k U s e r A t t r i b u t e s */
/* */
/* Get disk user attributes . */
/* */
/* Parameters: */
/* irHandle : Socket number (zero based) */
/* irData : Pointer to 1 sector of data */
/* */
/* ATA command: */
/* DOCH_VSCMD_EXT_DEVICE_CTRL */
/* ATA sub-command: */
/* DOCH_GET_DISK_USER_ATTR */
/* */
/* Returns: */
/* DOCH_Error : 0 on success, otherwise failed */
/*----------------------------------------------------------------------*/
DOCH_Error DOCHGetDiskUserAttributes(IOreq* ioreq)
{
DOCH_Error rc;
DOCH_Registers in_regs;
DOCH_Registers out_regs;
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;
/*Update ATA register values*/
/*--------------------------*/
in_regs.bFeaturesError = DOCH_GET_DISK_USER_ATTR;
in_regs.bSectorCount = 0;
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 ( DOCH_GET_SOCKET_FROM_IOREQ_HANDLE(ioreq),
pdev->bAtaDevNum,
&in_regs,
&out_regs,
ioreq->irData,
(1));
if(rc == DOCH_OK)
return DOCH_OK;
else
{
DBG_PRINT_ERR(FLZONE_API, "DOCHGetDiskUserAttributes(): failed with status: ");
DBG_PRINT_ERR_PRM(FLZONE_API, (FLTXT("0x%x \r\n"), rc));
if((rc & DOCH_ATA_ERROR_TRACK_0_NOT_FOUND) == DOCH_ATA_ERROR_TRACK_0_NOT_FOUND)
return DOCH_ProtectionFault;
else
return DOCH_GeneralFailure;
}
}
/*----------------------------------------------------------------------*/
/* f l D O C H G e t C o n f i g u r a t i o n D a t a */
/* */
/* Read the device configuration data. No authentication is required */
/* for calling this command, but the fields containing keys in the */
/* configuration data will be masked by ETFFS using zeros. */
/* */
/* Parameters: */
/* irHandle : Socket number (zero based) */
/* irData : Pointer to 1..3 sector(s) of data. */
/* irCount : Sector offset in the configuration data to start */
/* reading from. */
/* irLength : Number of sectors of configuration data to read. */
/* */
/* ATA command: */
/* DOCH_VSCMD_EXT_DEVICE_CTRL */
/* ATA sub-command: */
/* DOCH_GET_CONFIGURATION_DATA */
/* */
/* Returns: */
/* DOCH_Error : 0 on success, otherwise failed */
/*----------------------------------------------------------------------*/
DOCH_Error DOCHGetConfigurationData(IOreq* ioreq)
{
DOCH_Error rc;
DOCH_Registers in_regs;
DOCH_Registers out_regs;
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;
/*Update ATA register values*/
/*--------------------------*/
in_regs.bFeaturesError = DOCH_GET_CONFIGURATION_DATA;
in_regs.bSectorCount = (FLByte)ioreq->irLength;
in_regs.bSectorNumber = (FLByte)ioreq->irCount;
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 ( DOCH_GET_SOCKET_FROM_IOREQ_HANDLE(ioreq),
pdev->bAtaDevNum,
&in_regs,
&out_regs,
ioreq->irData,
(ioreq->irLength));
if(rc == DOCH_OK)
return DOCH_OK;
else
{
DBG_PRINT_ERR(FLZONE_API, "DOCHGetConfigurationData(): failed with status: ");
DBG_PRINT_ERR_PRM(FLZONE_API, (FLTXT("0x%x \r\n"), rc));
return DOCH_GeneralFailure;
}
}
/*----------------------------------------------------------------------*/
/* f l D O C H S e t C o n f i g u r a t i o n D a t a */
/* */
/* Save the device configuration data. Calling this command will */
/* succeed only if there are no partitions present on the media */
/* (including partition 0). */
/* You should use this command in the process of duplicating DiskOnChip */
/* device to make sure all configuration data of the original device */
/* have been duplicated to the new device. */
/* */
/* Parameters: */
/* irHandle : Socket number (zero based) */
/* irData : Pointer to 1..3 sector(s) of data. */
/* irCount : Sector offset in the configuration data to start */
/* writing from. */
/* irLength : Number of sectors of configuration data to write.*/
/* */
/* ATA command: */
/* DOCH_VSCMD_EXT_DEVICE_CTRL */
/* ATA sub-command: */
/* DOCH_SET_CONFIGURATION_DATA */
/* */
/* Returns: */
/* DOCH_Error : 0 on success, otherwise failed */
/*----------------------------------------------------------------------*/
DOCH_Error DOCHSetConfigurationData(IOreq* ioreq)
{
DOCH_Error rc;
DOCH_Registers in_regs;
DOCH_Registers out_regs;
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;
/*Update ATA register values*/
/*--------------------------*/
in_regs.bFeaturesError = DOCH_SET_CONFIGURATION_DATA;
in_regs.bSectorCount = (FLByte)ioreq->irLength;
in_regs.bSectorNumber = (FLByte)ioreq->irCount;
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 ( DOCH_GET_SOCKET_FROM_IOREQ_HANDLE(ioreq),
pdev->bAtaDevNum,
&in_regs,
&out_regs,
ioreq->irData,
(ioreq->irLength));
if(rc == DOCH_OK)
return DOCH_OK;
else
{
DBG_PRINT_ERR(FLZONE_API, "DOCHSetConfigurationData(): failed with status: ");
DBG_PRINT_ERR_PRM(FLZONE_API, (FLTXT("0x%x \r\n"), rc));
return DOCH_GeneralFailure;
}
}
/*----------------------------------------------------------------------*/
/* D O C H P a r t i t i o n I n f o */
/* */
/* Get information about a specific partition. */
/* */
/* Parameters: */
/* irHandle : Socket number (zero based) */
/* Partition number (zero based) */
/* irData : Address of user buffer to read partition */
/* information into. */
/* ATA command: */
/* DOCH_VSCMD_PARTITION_MANAGEMENT */
/* ATA sub-command: */
/* DOCH_GET_PARTITION_INFO */
/* */
/* Returns: */
/* DOCH_Error : 0 on success, otherwise failed */
/*----------------------------------------------------------------------*/
DOCH_Error DOCHPartitionInfoSingleFloor(IOreq* ioreq)
{
DOCH_Error rc;
DOCH_Socket * pdev;
#ifdef DOCH_BIG_ENDIAN
DOCH_PartitionInfo* partInfo = (DOCH_PartitionInfo*)(ioreq->irData);
DOCH_PartitionInfo* partInfoToBig = partInfo;
#endif /*DOCH_BIG_ENDIAN*/
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;
/*Check if Partition exceeds number of existing partitions*/
/*--------------------------------------------------------*/
if(DOCH_GET_PARTITION_FROM_IOREQ_HANDLE(ioreq) >= pdev->device[pdev->bAtaDevNum].wNumOfPartitions)
return DOCH_PartitionNotFound;
/*Update ATA register values*/
/*--------------------------*/
in_regs.bFeaturesError = DOCH_GET_PARTITION_INFO;
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);
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,
ioreq->irData,
(sizeof(DOCH_PartitionInfo) / DOCH_SECTOR_SIZE));
#ifdef DOCH_BIG_ENDIAN
/*In case of a BIG ENDIAN host CPU, reorder bytes in 16 and 32 Bit variables*/
partInfoToBig->dwCommandFlagsOrStatuses = be_FLDword((FLByte*)&partInfoToBig->dwCommandFlagsOrStatuses);
partInfoToBig->partitionAttributes1 = be_FLDword((FLByte*)&partInfoToBig->partitionAttributes1);
partInfoToBig->partitionAttributes2 = be_FLDword((FLByte*)&partInfoToBig->partitionAttributes2);
partInfoToBig->nPartitionSize = be_FLDword((FLByte*)&partInfoToBig->nPartitionSize);
partInfoToBig->nFastAreaSize = be_FLDword((FLByte*)&partInfoToBig->nFastAreaSize);
partInfoToBig->wFastAreaFactor = be_FLWord((FLByte*)&partInfoToBig->wFastAreaFactor);
partInfoToBig->wPartitionStartSector = be_FLWord((FLByte*)&partInfoToBig->wPartitionStartSector);
partInfoToBig->wCurrentSectorsPerTrack = be_FLWord((FLByte*)&partInfoToBig->wCurrentSectorsPerTrack);
partInfoToBig->wDefaultSectorsPerTrack = be_FLWord((FLByte*)&partInfoToBig->wDefaultSectorsPerTrack);
partInfoToBig->wCurrentCylinders = be_FLWord((FLByte*)&partInfoToBig->wCurrentCylinders);
partInfoToBig->wDefaultCylinders = be_FLWord((FLByte*)&partInfoToBig->wDefaultCylinders);
partInfoToBig->wCurrentHeads = be_FLWord((FLByte*)&partInfoToBig->wCurrentHeads);
partInfoToBig->wDefaultHeads = be_FLWord((FLByte*)&partInfoToBig->wDefaultHeads);
partInfoToBig->wFastAreaSectorsInErasableUnit = be_FLWord((FLByte*)&partInfoToBig->wFastAreaSectorsInErasableUnit);
partInfoToBig->wNormalAreaSectorsInErasableUnit = be_FLWord((FLByte*)&partInfoToBig->wNormalAreaSectorsInErasableUnit);
partInfoToBig->wRecommendedSectorsPerCluster = be_FLWord((FLByte*)&partInfoToBig->wRecommendedSectorsPerCluster);
partInfoToBig->wFastMaxRelatedSectors = be_FLWord((FLByte*)&partInfoToBig->wFastMaxRelatedSectors);
partInfoToBig->wNormalMaxRelatedSectors = be_FLWord((FLByte*)&partInfoToBig->wNormalMaxRelatedSectors);
#endif /*DOCH_BIG_ENDIAN*/
/*Update pdev fields*/
#if 0
pdev->device[pdev->bAtaDevNum].dwMulti_Current =
((partInfo->dwCommandFlags
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -