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

📄 doch_api.c

📁 H3 M-system NAND flash driver in Linux OS, M-DOC driver
💻 C
📖 第 1 页 / 共 5 页
字号:
    else
    {
		/*Prevent invoking Dev1 if it was not detected!!!*/
		tffsset(&pdev->sSpanData, 0, sizeof(pdev->sSpanData));

        /*DBG_PRINT_ERR(FLZONE_API, "DOCHIdentifyDiskOnChipDevice(): Dev1 not found\r\n");*/
    }
    return DOCH_GeneralFailure;
}

DOCH_Error DOCHIdentifyDiskOnChipDevice(IOreq* ioreq)
{
	DOCH_Error rc = DOCH_OK;
	IOreq ioreq2;
	DOCH_Socket* pdev;
	DOCH_DeviceInfo* tempDiskOnChipDeviceInfo;
	FLByte requestedDevice;
	
	DOCH_get_socket(pdev, DOCH_GET_SOCKET_FROM_IOREQ_HANDLE(ioreq));

	/*If socket is not registered, return error*/
	if(pdev == NULL)
		return DOCH_DiskNotFound;

	requestedDevice = pdev->bAtaDevNum;

	/*Identify Dev0*/
	tempDiskOnChipDeviceInfo = (DOCH_DeviceInfo*)(ioreq->irData);
	pdev->bAtaDevNum = 0;

	/*Identify command should have a short timeout*/
	gUseShortWaitOnBusy = DOCH_LONG_IDENTIFY_TIMEOUT;
	rc = DOCHIdentifyDiskOnChipDeviceSingleFloor(ioreq);
	gUseShortWaitOnBusy = 0;

	pdev->bAtaDevNum = requestedDevice;
	if(rc != DOCH_OK)
		return rc;

	/*If only 1 device is present, return*/
	if(pdev->wNumOfDevices > 1)
	{
		/*Identify Dev1*/
		tffscpy(&ioreq2, ioreq, sizeof(ioreq2));
		ioreq2.irData = &diskOnChipDeviceInfo2;

		pdev->bAtaDevNum = 1;
		/*Identify command should have a short timeout*/
		gUseShortWaitOnBusy = DOCH_LONG_IDENTIFY_TIMEOUT;
		rc = DOCHIdentifyDiskOnChipDeviceSingleFloor(&ioreq2);
		gUseShortWaitOnBusy = 0;
		pdev->bAtaDevNum = requestedDevice;
		if(rc != DOCH_OK)
			return rc;

		/*Combine data*/
		tempDiskOnChipDeviceInfo->dwUnformattedCapacity += diskOnChipDeviceInfo2.dwUnformattedCapacity;

		tempDiskOnChipDeviceInfo->wTotalNumOfPartitions += diskOnChipDeviceInfo2.wTotalNumOfPartitions;

		if(diskOnChipDeviceInfo2.wTotalNumOfPartitions > 1)
		{
			if((pdev->sSpanData.bLastDev0PartSpanned))
				tempDiskOnChipDeviceInfo->wTotalNumOfPartitions -= 2;
			else
				tempDiskOnChipDeviceInfo->wTotalNumOfPartitions -= 1;
		}
		else if(diskOnChipDeviceInfo2.wTotalNumOfPartitions == 1)
			tempDiskOnChipDeviceInfo->wTotalNumOfPartitions -= 1;
	}

	return DOCH_OK;
}

/*----------------------------------------------------------------------*/
/*            D O C H G e t R e s e t S t a t u s						*/
/*                                                                      */
/* Parameters:                                                          */
/*      irHandle        : Socket number (zero based)                    */
/*                                                                      */
/* ATA command:															*/
/*			DOCH_VSCMD_EXT_DEVICE_CTRL									*/
/* ATA sub-command:														*/
/*			DOCH_GET_RESET_STATUS										*/
/*																		*/
/* Returns:                                                             */
/*        irCount	      : 0	=	No reset since last query			*/
/*							1	=	The device has been reset since last*/
/*									query								*/
/*        DOCH_Error      : 0 on success, otherwise failed              */
/*----------------------------------------------------------------------*/
DOCH_Error DOCHGetResetStatus(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;

	dochEnableATAInterrupt(DOCH_GET_SOCKET_FROM_IOREQ_HANDLE(ioreq),
						   FALSE,
						   0);

	/*Update ATA register values*/
	/*--------------------------*/
	in_regs.bFeaturesError = DOCH_GET_RESET_STATUS;
	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,
					    NULL,
						0);

	/*Update device structure*/
	/*=======================*/
	if(rc == DOCH_OK)
	{
		/*Return reset status*/
		ioreq->irCount = out_regs.bSectorCount;

		return DOCH_OK;
	}
	else
	{
		DBG_PRINT_ERR(FLZONE_API, "DOCHGetResetStatus(): failed with status: ");
		DBG_PRINT_ERR_PRM(FLZONE_API, (FLTXT("0x%x \r\n"), rc));

		return DOCH_GeneralFailure;
	}
}

/*----------------------------------------------------------------------*/
/*            D O C H N o t i f y R e s e t								*/
/*																		*/
/*	Notify the Device on an upcoming reset initiated by the Host.		*/
/*	Host should NOT perform actual reset before this command completes	*/
/*                                                                      */
/* Parameters:                                                          */
/*      irHandle        : Socket number (zero based)                    */
/*                                                                      */
/* ATA command:															*/
/*			DOCH_VSCMD_EXT_DEVICE_CTRL									*/
/* ATA sub-command:														*/
/*			DOCH_NOTIFY_RESET											*/
/*																		*/
/* Returns:                                                             */
/*        DOCH_Error        : 0 on success, otherwise failed            */
/*----------------------------------------------------------------------*/
DOCH_Error DOCHNotifyResetSingleFloor(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_NOTIFY_RESET;
	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), 
						0,
						&in_regs,
						&out_regs,
					    NULL,
						0);

	/*Update device structure*/
	/*=======================*/
	if(rc != DOCH_OK)
	{
		DBG_PRINT_ERR(FLZONE_API, "DOCHNotifyReset(): failed with status: ");
		DBG_PRINT_ERR_PRM(FLZONE_API, (FLTXT("0x%x \r\n"), rc));

		return DOCH_GeneralFailure;
	}

	return DOCH_OK;
}

DOCH_Error DOCHNotifyReset(IOreq* ioreq)
{
	DOCH_Error rc = DOCH_OK;
	DOCH_Socket* pdev;
	FLByte origDevNum;

	DOCH_get_socket(pdev, DOCH_GET_SOCKET_FROM_IOREQ_HANDLE(ioreq));

	/*If socket is not registered, return error*/
	if(pdev == NULL)
		return DOCH_DiskNotFound;

	origDevNum = pdev->bAtaDevNum;

	pdev->bAtaDevNum = 0;
	rc = DOCHNotifyResetSingleFloor(ioreq);
	if(rc != DOCH_OK)
	{
		pdev->bAtaDevNum = origDevNum;
		return rc;
	}

	if(pdev->wNumOfDevices > 1)
	{
		pdev->bAtaDevNum = 1;
		rc = DOCHNotifyResetSingleFloor(ioreq);
		pdev->bAtaDevNum = origDevNum;
	}

	return rc;
}

/*----------------------------------------------------------------------*/
/*          D O C H N o t i f y P l a t f o r m R e s u m e d			*/
/*																		*/
/*	Notify the Device that there was a reset,							*/
/*                                                                      */
/* Parameters:                                                          */
/*      irHandle        : Socket number (zero based)                    */
/*                                                                      */
/* ATA command:															*/
/*			DOCH_VSCMD_EXT_DEVICE_CTRL									*/
/* ATA sub-command:														*/
/*			DOCH_NOTIFY_PLATFORM_RESUMED								*/
/*																		*/
/* Returns:                                                             */
/*        DOCH_Error        : 0 on success, otherwise failed            */
/*----------------------------------------------------------------------*/
DOCH_Error DOCHNotifyPlatformResumedSingleFloor(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;

	/*Update ATA register values*/
	/*--------------------------*/
	in_regs.bFeaturesError = DOCH_NOTIFY_PLATFORM_RESUMED;
	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), 
						0,
						&in_regs,
						&out_regs,
					    NULL,
						0);

	/*Update device structure*/
	/*=======================*/
	if(rc != DOCH_OK)
	{
		DBG_PRINT_ERR(FLZONE_API, "DOCHNotifyPlatformResumed(): failed with status: ");
		DBG_PRINT_ERR_PRM(FLZONE_API, (FLTXT("0x%x \r\n"), rc));

		return DOCH_GeneralFailure;
	}

    /*Restore DPD settings */
    /*=====================*/
    tffsset(&ioreq2, 0, sizeof(ioreq2));

    ioreq2.irFlags  = (DOCH_PM_SET_BOTH_MODES | DOCH_PM_WORK_MODE);
    ioreq2.irCount  = (gDpdSettings.activeMode | gDpdSettings.inActiveMode);
	ioreq2.irLength = gDpdSettings.timeOut;

	rc = DOCHSetPowerMode(&ioreq2);
	if(rc != DOCH_OK)
		return rc;

	/*Restore transfer mode */
	/*======================*/
	tffsset(&ioreq2, 0, sizeof(ioreq));

	ioreq2.irCount  = pdev->device[pdev->bAtaDevNum].dataTransferMode;
	ioreq2.irLength = pdev->device[pdev->bAtaDevNum].dwMulti_Current;

	rc = DOCHSetDataTransferModeSingleFloor(&ioreq2);
	if(rc != DOCH_OK)
		return rc;


	return DOCH_OK;
}

DOCH_Error DOCHNotifyPlatformResumed(IOreq* ioreq)
{
	DOCH_Error rc = DOCH_OK;
	DOCH_Socket* pdev;
	FLByte origDevNum;

	DOCH_get_socket(pdev, DOCH_GET_SOCKET_FROM_IOREQ_HANDLE(ioreq));

	/*If socket is not registered, return error*/
	if(pdev == NULL)
		return DOCH_DiskNotFound;

	origDevNum = pdev->bAtaDevNum;

	pdev->bAtaDevNum = 0;
	rc = DOCHNotifyPlatformResumedSingleFloor(ioreq);
	if(rc != DOCH_OK)
	{
		pdev->bAtaDevNum = origDevNum;
		return rc;
	}

	if(pdev->wNumOfDevices > 1)
	{
		pdev->bAtaDevNum = 1;
		rc = DOCHNotifyPlatformResumedSingleFloor(ioreq);
		pdev->bAtaDevNum = origDevNum;
	}

	return rc;
}

/*----------------------------------------------------------------------*/
/*	    f l D O C H S e t D i s k U s e r A t t r i b u t e s			*/
/*                                                                      */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -