⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 doch_api.c

📁 H3 M-system NAND flash driver in Linux OS, M-DOC driver
💻 C
📖 第 1 页 / 共 5 页
字号:
/* 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 + -