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

📄 ata_cmds.c

📁 电子盘DEMO板程序
💻 C
📖 第 1 页 / 共 5 页
字号:
	DOCH_SimSocket* simSocket = getSimSocket();

	if((items & CHECK_PARTITION) == CHECK_PARTITION)
	{
		if(simDev->partitions[partNum].wActive == 0)
		{
			DBG_PRINT_FLOW_PRM(FLZONE_MTD, (FLTXT("Partition #%d not formatted\r\n"),partNum));
			rc |= CHECK_PARTITION;
		}
	}

	if((items & CHECK_SIZE) == CHECK_SIZE)
	{
		if( ((FLDword)requiredSize) > /*(partNum==DOCH_IPL_PARTITION?simDev->dwXIPMaxSize : */simDev->partitions[partNum].dwSize/*)*/)
		{
			DBG_PRINT_FLOW_PRM(FLZONE_MTD, (FLTXT("Not enough space...\r\n")));
			rc |= CHECK_SIZE;
		}
	}

	if((items & CHECK_LIMITS) == CHECK_LIMITS)
	{
		if( ((FLDword)endSector) > simDev->partitions[partNum].dwSize)
		{
			DBG_PRINT_FLOW_PRM(FLZONE_MTD, (FLTXT("Request overflows partition limits\r\n")));
			rc |= CHECK_LIMITS;
		}
	}

	if((items & CHECK_AUTHENTICATION) == CHECK_AUTHENTICATION)
	{
		if(!simDev->partitions[partNum].wAuthenticated)
		{
			DBG_PRINT_FLOW_PRM(FLZONE_MTD, (FLTXT("Partition NOT authenticated\r\n")));
			rc |= CHECK_AUTHENTICATION;
		}
	}

	if((items & CHECK_READ_ACCESS) == CHECK_READ_ACCESS)
	{
		if((!simDev->partitions[partNum].wAuthenticated) &&
			(((simDev->partitions[partNum].info.partitionAttributes2 & DOCH_PA2B_GUEST_MODE) >> DOCH_PA2O_GUEST_MODE)
			== DOCH_PART_ACCESS_MODE_NONE))
		{
			DBG_PRINT_FLOW_PRM(FLZONE_MTD, (FLTXT("No Read Access\r\n")));
			rc |= CHECK_READ_ACCESS;
		}
	}

	if((items & CHECK_WRITE_ACCESS) == CHECK_WRITE_ACCESS)
	{
		if((!simDev->partitions[partNum].wAuthenticated) &&
			(((simDev->partitions[partNum].info.partitionAttributes2 & DOCH_PA2B_GUEST_MODE) >> DOCH_PA2O_GUEST_MODE)
			!= DOCH_PART_ACCESS_MODE_FULL))
		{
			DBG_PRINT_FLOW_PRM(FLZONE_MTD, (FLTXT("No Write Access\r\n")));
			rc |= CHECK_WRITE_ACCESS;
		}
	}

	if((items & CHECK_OTP) == CHECK_OTP)
	{
		if((simDev->partitions[partNum].info.dwCommandFlagsOrStatuses & DOCH_CFSB_PERM_LOCKED) == DOCH_CFSB_PERM_LOCKED)
		{
			DBG_PRINT_FLOW_PRM(FLZONE_MTD, (FLTXT("OTP Bit Active!\r\n")));
			rc |= CHECK_OTP;
		}
	}

	if((items & CHECK_SLOCK) == CHECK_SLOCK)
	{
		if((simSocket->config_regs.wSWLock & 0x1) == 0x01)
		{
			DBG_PRINT_FLOW_PRM(FLZONE_MTD, (FLTXT("SLock active!\r\n")));
			rc |= CHECK_SLOCK;
		}
	}

	if(rc != 0)
	{
		simSocket->out_regs.bStatusCommand |= DOCH_ERROR;

		if((rc & CHECK_PARTITION) == CHECK_PARTITION)
		{
			simSocket->out_regs.bErrorFeature = (DOCH_ATA_ERROR_ABORT);
			return (simATANotFormatted);
		}
		else if((rc & CHECK_SIZE) == CHECK_SIZE)
		{
			simSocket->out_regs.bErrorFeature = (DOCH_ATA_ERROR_ABORT | DOCH_ATA_ERROR_WRITE_PROTECTED);
			return (simATANoSpace);
		}
		else if((rc & CHECK_LIMITS) == CHECK_LIMITS)
		{
			simSocket->out_regs.bErrorFeature = (DOCH_ATA_ERROR_ABORT | DOCH_ATA_ERROR_ID_NOT_FOUND);
			return (simATAExcLimit);
		}
		else if((rc & CHECK_AUTHENTICATION) == CHECK_AUTHENTICATION)
		{
			simSocket->out_regs.bErrorFeature = (DOCH_ATA_ERROR_ABORT | DOCH_ATA_ERROR_TRACK_0_NOT_FOUND);
			return (simATANotAuth);
		}
		else if((rc & CHECK_READ_ACCESS) == CHECK_READ_ACCESS)
		{
			simSocket->out_regs.bErrorFeature = (DOCH_ATA_ERROR_ABORT | DOCH_ATA_ERROR_TRACK_0_NOT_FOUND);
			return (simATANoReadAccess);
		}
		else if((rc & CHECK_WRITE_ACCESS) == CHECK_WRITE_ACCESS)
		{
			simSocket->out_regs.bErrorFeature = (DOCH_ATA_ERROR_ABORT | DOCH_ATA_ERROR_TRACK_0_NOT_FOUND);
			return (simATANoWriteAccess);
		}
		else if((rc & CHECK_OTP) == CHECK_OTP)
		{
			simSocket->out_regs.bErrorFeature = (DOCH_ATA_ERROR_ABORT | DOCH_ATA_ERROR_TRACK_0_NOT_FOUND);
			return (simATANoWriteAccess);
		}
		else if((rc & CHECK_SLOCK) == CHECK_SLOCK)
		{
			simSocket->out_regs.bErrorFeature = (DOCH_ATA_ERROR_ABORT | DOCH_ATA_ERROR_TRACK_0_NOT_FOUND);
			return (simATASlockActive);
		}
	}

	return rc;
}

/*Simulation static routines implementations*/
/*==========================================*/
static FLSNative simReadPartition(DOCH_SimDevice* simDev)
{
	FLSNative  rc = 0;
	DOCH_SimSocket* simSocket = getSimSocket();
	FLNative requiredSize = simSocket->in_regs.bSectorCount;
	FLNative startSector;
	FLNative endSector;
	if(requiredSize == 0)
		requiredSize = 0x100;
	startSector  = simSocket->in_regs.bLBALow + (simSocket->in_regs.bLBAMid << 8) + (simSocket->in_regs.bLBAHigh << 16);
	endSector	 = startSector + requiredSize;

	simSocket->out_regs.bStatusCommand |= DOCH_BUSY;
	simSocket->out_regs.bStatusCommand &= ~(DOCH_READY | DOCH_DRQ | DOCH_ERROR);

	/*Sanity checks*/
	rc = sanityCheck(simDev,
					 CHECK_PARTITION | CHECK_SIZE | CHECK_LIMITS | CHECK_READ_ACCESS,
					 simSocket->in_regs.bErrorFeature,
					 requiredSize,
					 startSector,
					 endSector);
	if(rc != 0)
	{
		simSocket->out_regs.bStatusCommand &= ~DOCH_BUSY;
		return rc;
	}

#ifdef DOCH_MEMMAP_FILE

	if(simFileIO(simSocket, SIM_ITEM_STORAGE, simSocket->selDevNum, FALSE, NULL))
	{
		simSocket->out_regs.bStatusCommand |= DOCH_ERROR;
		simSocket->out_regs.bErrorFeature = (DOCH_ATA_ERROR_ABORT);
		simSocket->out_regs.bStatusCommand &= ~DOCH_BUSY;
		return -1;
	}

#endif /*DOCH_MEMMAP_FILE*/

	simSocket->cmdBuffer.sbBuffer = choosePartition(simSocket, simSocket->in_regs.bErrorFeature);
	simSocket->cmdBuffer.nBufferLen = requiredSize * DOCH_SECTOR_SIZE;
	simSocket->cmdBuffer.sbCurrentPosition = simSocket->cmdBuffer.sbBuffer + (startSector * DOCH_SECTOR_SIZE);
	simSocket->cmdBuffer.sbPositionToReach = (simSocket->cmdBuffer.sbCurrentPosition + simSocket->cmdBuffer.nBufferLen);
	simSocket->cmdBuffer.nDirection = SIM_READ;

	/* Now that data is ready, set DRQ and clear BSY*/
	simSocket->out_regs.bStatusCommand |= (DOCH_DRQ | DOCH_READY);
	simSocket->out_regs.bStatusCommand &= ~DOCH_BUSY;
	
	return rc;

}

static FLSNative simWritePartition(DOCH_SimDevice* simDev)
{
	FLSNative  rc = 0;
	DOCH_SimSocket* simSocket = getSimSocket();
	FLNative requiredSize = simSocket->in_regs.bSectorCount;
	FLNative startSector;
	FLNative endSector;
	if(requiredSize == 0)
		requiredSize = 0x100;
	startSector  = simSocket->in_regs.bLBALow + (simSocket->in_regs.bLBAMid << 8) + (simSocket->in_regs.bLBAHigh << 16);
	endSector	 = startSector + requiredSize;

	simSocket->out_regs.bStatusCommand |= DOCH_BUSY;
	simSocket->out_regs.bStatusCommand &= ~(DOCH_READY | DOCH_DRQ | DOCH_ERROR);

	/*Sanity checks*/
	rc = sanityCheck(simDev,
					 CHECK_PARTITION | CHECK_SIZE | CHECK_LIMITS | CHECK_WRITE_ACCESS | CHECK_OTP,
					 simSocket->in_regs.bErrorFeature,
					 requiredSize,
					 startSector,
					 endSector);
	if(rc != 0)
	{
		simSocket->out_regs.bStatusCommand &= ~DOCH_BUSY;
		return rc;
	}

#ifdef DOCH_MEMMAP_FILE

	if(simFileIO(simSocket, SIM_ITEM_STORAGE, simSocket->selDevNum, FALSE, NULL))
	{
		simSocket->out_regs.bStatusCommand |= DOCH_ERROR;
		simSocket->out_regs.bErrorFeature = (DOCH_ATA_ERROR_ABORT);
		simSocket->out_regs.bStatusCommand &= ~DOCH_BUSY;
		return -1;
	}

#endif /*DOCH_MEMMAP_FILE*/

	simSocket->cmdBuffer.sbBuffer = choosePartition(simSocket, simSocket->in_regs.bErrorFeature);
	simSocket->cmdBuffer.nBufferLen = requiredSize * DOCH_SECTOR_SIZE;
	simSocket->cmdBuffer.sbCurrentPosition = simSocket->cmdBuffer.sbBuffer + (startSector * DOCH_SECTOR_SIZE);
	simSocket->cmdBuffer.sbPositionToReach = (simSocket->cmdBuffer.sbCurrentPosition + simSocket->cmdBuffer.nBufferLen);
	simSocket->cmdBuffer.nDirection = SIM_WRITE;

	/* Now that data is ready, set DRQ and clear BSY*/
	simSocket->out_regs.bStatusCommand |= (DOCH_DRQ | DOCH_READY);
	simSocket->out_regs.bStatusCommand &= ~DOCH_BUSY;
	
#if 0
	if( simSocket->in_regs.bErrorFeature == DOCH_IPL_PARTITION )
	{
		if( ((FLDword)endSector)==simDev->dwXIPMaxSize )
		{
			simDev->partitions[DOCH_IPL_PARTITION].dwSize = simDev->dwXIPMaxSize; /* update the IPL partition size, when last sector written */
			simDev->partitions[DOCH_IPL_PARTITION].dwRequestedSize = simDev->dwXIPMaxSize; /* update the IPL partition size, when last sector written */
			simDev->partitions[DOCH_IPL_PARTITION].info.nPartitionSize = simDev->dwXIPMaxSize; /* update the IPL partition size, when last sector written */
		}
	}
#endif /*0*/

	return rc;
}

static FLSNative simWriteFlexi(DOCH_SimDevice* simDev)
{
	/*TBD*/
	return 0;
}

static FLSNative simErasePartition(DOCH_SimDevice* simDev)
{
	FLSNative  rc = 0;
	FLNative i;

	DOCH_SimSocket* simSocket = getSimSocket();
	FLNative requiredSize = simSocket->in_regs.bSectorCount;
	FLNative startSector  = simSocket->in_regs.bLBALow + (simSocket->in_regs.bLBAMid << 8) + (simSocket->in_regs.bLBAHigh << 16);
	FLNative endSector	  = startSector + requiredSize;

	simSocket->out_regs.bStatusCommand |= DOCH_BUSY;
	simSocket->out_regs.bStatusCommand &= ~(DOCH_READY | DOCH_ERROR);

	/*Sanity checks*/
	rc = sanityCheck(simDev,
					 CHECK_PARTITION | CHECK_SIZE | CHECK_LIMITS | CHECK_WRITE_ACCESS | CHECK_OTP,
					 simSocket->in_regs.bErrorFeature,
					 requiredSize,
					 startSector,
					 endSector);
	if(rc != 0)
	{
		simSocket->out_regs.bStatusCommand &= ~DOCH_BUSY;
		return rc;
	}

#ifdef DOCH_MEMMAP_FILE
	{
		FLWord writeLen = 0;
		FLByte dummy[DOCH_SECTOR_SIZE];

		if(simFileIO(simSocket, SIM_ITEM_STORAGE, simSocket->selDevNum, FALSE, NULL))
		{
			simSocket->out_regs.bStatusCommand |= DOCH_ERROR;
			simSocket->out_regs.bErrorFeature = (DOCH_ATA_ERROR_ABORT);
			simSocket->out_regs.bStatusCommand &= ~DOCH_BUSY;
			return -1;
		}

		for(i=0; i<requiredSize; i++)
		{
			/* Fill partition with "0" */
			writeLen = fwrite( (void*)&(dummy), 1, 
							DOCH_SECTOR_SIZE, simSocket->pSimFile );
			if( writeLen != DOCH_SECTOR_SIZE )
			{
				simSocket->out_regs.bStatusCommand |= DOCH_ERROR;
				simSocket->out_regs.bErrorFeature = (DOCH_ATA_ERROR_ABORT);
				simSocket->out_regs.bStatusCommand &= ~DOCH_BUSY;
				return -1;
			}
		}

	}

#else /*DOCH_MEMMAP_FILE*/

	simSocket->cmdBuffer.sbBuffer = choosePartition(simSocket, simSocket->in_regs.bErrorFeature);
	simSocket->cmdBuffer.nBufferLen = 0;

	for(i=0; i<(requiredSize * DOCH_SECTOR_SIZE); i++)
	{
		simSocket->cmdBuffer.sbBuffer[(startSector * DOCH_SECTOR_SIZE) + i] = 0;
	}

#endif /*DOCH_MEMMAP_FILE*/

	/* Now that data is ready, clear BSY*/
	simSocket->out_regs.bStatusCommand |= (DOCH_READY);
	simSocket->out_regs.bStatusCommand &= ~DOCH_BUSY;
	
	return rc;
}

static FLSNative simSecureErase(DOCH_SimDevice* simDev)
{
	DOCH_SimSocket* simSocket = getSimSocket();

	simSocket->out_regs.bStatusCommand |= DOCH_BUSY;
	simSocket->out_regs.bStatusCommand &= ~(DOCH_READY | DOCH_DRQ | DOCH_ERROR);

	simSocket->cmdBuffer.sbBuffer = getSandBox();
	simSocket->cmdBuffer.nBufferLen = (simSocket->in_regs.bLBALow<<DOCH_SECTOR_SIZE_BITS);
	simSocket->cmdBuffer.sbCurrentPosition = simSocket->cmdBuffer.sbBuffer;
	simSocket->cmdBuffer.sbPositionToReach = (simSocket->cmdBuffer.sbCurrentPosition + simSocket->cmdBuffer.nBufferLen);
	simSocket->cmdBuffer.nDirection = SIM_READ;

	/* Now that data is ready, clear BSY*/
	simSocket->out_regs.bStatusCommand |= (DOCH_DRQ | DOCH_READY);
	simSocket->out_regs.bStatusCommand &= ~DOCH_BUSY;

	return 0;
}

static FLSNative simDeletePartitions(DOCH_SimDevice* simDev)
{
	register FLSNative i = 0;
	DOCH_SimSocket* simSocket = getSimSocket();
	DOCH_DeviceInfo* diskOnChipDeviceInfo = (DOCH_DeviceInfo*)getDiskOnChipDeviceInfo(simSocket->selDevNum);
	FLByte firstPartToRemove = simSocket->in_regs.bSectorCount;
	FLByte lastPartToRemove  = TFFSMIN(simSocket->in_regs.bLBALow, (diskOnChipDeviceInfo->wTotalNumOfPartitions-1));

	simSocket->out_regs.bStatusCommand |= DOCH_BUSY;
	simSocket->out_regs.bStatusCommand &= ~(DOCH_READY | DOCH_ERROR);

	/* (lastPartToRemove + 1) must be >= last partition number */
	if((lastPartToRemove+1) < diskOnChipDeviceInfo->wTotalNumOfPartitions)
	{
		simSocket->out_regs.bStatusCommand |= DOCH_ERROR;
		simSocket->out_regs.bErrorFeature = (DOCH_ATA_ERROR_ABORT);
		simSocket->out_regs.bStatusCommand &= ~DOCH_BUSY;
		return -1;
	}

	/* (firstPartToRemove+1) must be <= total number of partitions */
    if( ((firstPartToRemove+1) > diskOnChipDeviceInfo->wTotalNumOfPartitions) &&
        (diskOnChipDeviceInfo->wTotalNumOfPartitions != 0))
    {
		simSocket->out_regs.bStatusCommand |= DOCH_ERROR;
        simSocket->out_regs.bErrorFeature = (DOCH_ATA_ERROR_ABORT);
        simSocket->out_regs.bStatusCommand &= ~DOCH_BUSY;
        return -1;
	}

	/* If no partition exist - FAIL */
	if((diskOnChipDeviceInfo->wTotalNumOfPartitions == 0) &&
		(! ((firstPartToRemove == 0) && (lastPartToRemove == 0xFF))) )
	{
		simSocket->out_regs.bStatusCommand |= DOCH_ERROR;
		simSocket->out_regs.bErrorFeature = (DOCH_ATA_ERROR_ABORT | DOCH_ATA_ERROR_WRITE_PROTECTED);
		simSocket->out_regs.bStatusCommand &= ~DOCH_BUSY;
		return -1;

⌨️ 快捷键说明

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