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

📄 doch_api.c

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