doch_api.c

来自「电子盘DEMO板程序」· C语言 代码 · 共 1,849 行 · 第 1/5 页

C
1,849
字号
		/*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			*/
/*                                                                      */
/* 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,

⌨️ 快捷键说明

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