📄 doch_ata.c
字号:
* *
* d o c h _ c o m m a n d *
* *
* Sends 'cmd' command to DOCH device. *
* *
* Parameters : *
* socketNo : Socket # (0...DOCH_MAX_SOCKETS-1) *
* in_regs : DOCH input registers values *
* out_regs : DOCH output registers values *
* buf : user buffer *
* secNum : # of sectors (for data transfer commands) *
* *
* Returns : *
* DOCH_OK in success, otherwise respective error code. *
* *
******************************************************************************/
DOCH_Error doch_command ( FLSNative socketNo,
FLSNative devNum,
DOCH_Registers* in_regs,
DOCH_Registers* out_regs,
void * buf,
FLNative secNum)
{
DOCH_Socket* pdev;
DOCH_Error rc;
DOCH_Error rc2;
/* Sanity Check*/
/*=============*/
if(socketNo > DOCH_MAX_SOCKETS - 1)
return DOCH_BadParameter;
pdev = &sockets[socketNo];
#ifdef CHECK_POWER_ON_EVERY_COMMAND
/* Check if device was reset */
rc = dochCheckPFSymptom(socketNo, pdev->bAtaDevNum, TRUE);
if(rc != DOCH_OK)
return rc;
#endif /*CHECK_POWER_ON_EVERY_COMMAND*/
#ifdef DOCH_DMA_CONFIG
{
DMA_Params_S dmaParams;
if(pdev->bUseDMA && (gDMAChannelOpen == 0))
{
dmaParams.bOpType = DOCH_DMA_OPEN_CHANNEL;
DOCH_DMA_CONFIG(&dmaParams);
if(dmaParams.fDmaStatus != 0)
{
DBG_PRINT_ERR(FLZONE_API, "doch_command(): DOCH_DMA_OPEN_CHANNEL Failed\r\n");
return DOCH_GeneralFailure;
}
gDMAChannelOpen = DOCH_GLOBAL_BOOL_PATTERN;
DBG_PRINT_FLOW(FLZONE_ATA, "\r\nDMA Channel opened\r\n");
}
}
#endif /*DOCH_DMA_CONFIG*/
/*Branch to proper IO routine according to ATA command*/
switch ((DOCH_Command)(in_regs->bCommandStatus))
{
/* Vendor-Specific ATA commands */
case DOCH_VSCMD_READ_PARTITION:
case DOCH_VSCMD_READ_CALCULATED_HASH:
case DOCH_VSCMD_READ_ORIGINAL_HASH:
rc = io_input (pdev, devNum, in_regs, buf, secNum);
break;
case DOCH_VSCMD_WRITE_PARTITION:
case DOCH_VSCMD_WRITE_FLEXI:
case DOCH_VSCMD_WRITE_GIVEN_HASH:
rc = io_output (pdev, devNum, in_regs, buf, secNum);
break;
case DOCH_VSCMD_OPTIMIZE_PARTITION_SECTORS:
case DOCH_VSCMD_ERASE_PARTITION_SECTORS:
case DOCH_VSCMD_WRITE_CALCULATED_HASH:
rc = io_ctrl (pdev, devNum, in_regs);
break;
case DOCH_VSCMD_PARTITION_MANAGEMENT:
switch((DOCH_DeviceCtrlOp)(in_regs->bFeaturesError))
{
case DOCH_SET_DEFAULT_PARTITION:
case DOCH_DELETE_PARTITIONS:
rc = io_ctrl (pdev, devNum, in_regs);
break;
case DOCH_GET_PARTITION_INFO:
case DOCH_GET_PARTITION_USER_ATTR:
rc = io_input (pdev, devNum, in_regs, buf, secNum);
break;
case DOCH_SET_PARTITION_PROTECTION:
case DOCH_SET_PARTITION_USER_ATTR:
case DOCH_ADD_PARTITION:
case DOCH_SECURE_ERASE:
rc = io_output (pdev, devNum, in_regs, buf, secNum);
break;
default:
return DOCH_UnknownCmd;
}
break;
case DOCH_VSCMD_ACCESS_CONTROL:
switch((DOCH_SecurityCtrlOp)(in_regs->bFeaturesError))
{
case DOCH_DISABLE_ACCESS:
rc = io_ctrl (pdev, devNum, in_regs);
break;
case DOCH_RX_DOCH_PUBLICKEY:
case DOCH_VERIFY_HOST_KEY:
rc = io_input (pdev, devNum, in_regs, buf, secNum);
break;
case DOCH_EN_ACCESS_WPWD:
case DOCH_TX_HOST_PUBLICKEY:
rc = io_output (pdev, devNum, in_regs, buf, secNum);
break;
default:
return DOCH_UnknownCmd;
}
break;
case DOCH_VSCMD_EXT_DEVICE_CTRL:
switch((DOCH_DeviceCtrlOp)(in_regs->bFeaturesError))
{
case DOCH_SET_DATA_XFER_MODE:
case DOCH_ATOMIC_WRITE_SEQUENCE:
case DOCH_OPTIMIZE_MEDIA:
case DOCH_GET_RESET_STATUS:
case DOCH_NOTIFY_RESET:
case DOCH_NOTIFY_PLATFORM_RESUMED:
case DOCH_GET_CUSTOM_PARAM:
case DOCH_SET_CUSTOM_PARAM:
case DOCH_SET_POWER_MODE:
case DOCH_GET_POWER_MODE:
case DOCH_ACTIVATE_DEBUG_MODE:
case DOCH_SET_ALERT_LEVEL:
rc = io_ctrl (pdev, devNum, in_regs);
break;
case DOCH_IDENTIFY_DISKONCHIP_DEVICE:
case DOCH_GET_EXTENDED_DEVICE_INFO:
case DOCH_GET_DISK_USER_ATTR:
case DOCH_GET_CONFIGURATION_DATA:
rc = io_input (pdev, devNum, in_regs, buf, secNum);
break;
case DOCH_SET_DISK_USER_ATTR:
case DOCH_SET_CONFIGURATION_DATA:
rc = io_output (pdev, devNum, in_regs, buf, secNum);
break;
default:
return DOCH_UnknownCmd;
}
break;
case DOCH_VSCMD_EXT_SECURITY_CTRL:
switch((DOCH_SecurityCtrlOp)(in_regs->bFeaturesError))
{
case DOCH_SET_ALGORITHM_MODE:
case DOCH_AUTO_HASH_CONTROL:
case DOCH_SET_KEYS:
case DOCH_START_HASH_STREAM_CALC:
case DOCH_READ_STOP_HASH_STREAM_CALC:
rc = io_ctrl (pdev, devNum, in_regs);
break;
case DOCH_REPORT_SUPPORTED_ALGORITHMS:
case DOCH_GET_ALGORITHM_CAPABILITIES:
case DOCH_RETURN_RANDOM_NUMBERS:
rc = io_input (pdev, devNum, in_regs, buf, secNum);
break;
default:
return DOCH_UnknownCmd;
}
break;
default:
return DOCH_UnknownCmd;
}
/*If IO operation succeeded, retrieve device response from ATA registers
(calling routine might need some data back from the device)
Common IO Read/Write routines are excluded */
switch( rc )
{
case DOCH_OK:
if((in_regs->bCommandStatus != DOCH_VSCMD_READ_PARTITION) &&
(in_regs->bCommandStatus != DOCH_VSCMD_WRITE_PARTITION) &&
(in_regs->bCommandStatus != DOCH_VSCMD_WRITE_FLEXI))
rc = get_out_registers(pdev, devNum, out_regs);
break;
case DOCH_ATAErrorDetected:
rc = get_out_registers(pdev, devNum, out_regs);
break;
default:
break;
}
#ifdef CHECK_POWER_ON_EVERY_COMMAND
/* Check if device was reset */
rc2 = dochCheckPFSymptom(socketNo, pdev->bAtaDevNum, FALSE);
if(rc2 != DOCH_OK)
return rc2;
#endif /*CHECK_POWER_ON_EVERY_COMMAND*/
/* If ATA debug was requested - retrieve and print buffer from Device */
if(gDochAtaDebug == DOCH_GLOBAL_BOOL_PATTERN)
{
rc2 = retrieveAndPrintAtaDebug(pdev);
if(rc2 != DOCH_OK)
return rc2;
}
return rc;
}
/******************************************************************************
* *
* d o c h _ a t a _ p a s s t h r u *
* *
* Pass-thru routine for ATA commands *
* *
* Parameters : *
* socketNo : Socket # (0...DOCH_MAX_SOCKETS-1) *
* ptOP : Data transfer type (In/Out/No) *
* in_regs : DOCH input registers values *
* out_regs : DOCH output registers values *
* buf : user buffer *
* secNum : Number of sectors (in case of data transfer) *
* *
* Returns : *
* DOCH_OK in success, otherwise respective error code. *
* *
******************************************************************************/
DOCH_Error doch_ata_passthru ( FLSNative socketNo,
FLSNative devNum,
DOCH_PassThru_Op ptOP,
DOCH_Registers * in_regs,
DOCH_Registers * out_regs,
void * buf,
FLNative secNum)
{
DOCH_Socket* pdev;
DOCH_Error rc = DOCH_OK;
DOCH_Error rc2;
/* Sanity Check*/
/*=============*/
if(socketNo > DOCH_MAX_SOCKETS - 1)
return DOCH_BadParameter;
pdev = &sockets[socketNo];
switch(ptOP)
{
case DOCH_PASSTHRU_NO_DATA:
rc = io_ctrl (pdev, devNum, in_regs);
break;
case DOCH_PASSTHRU_DATA_IN:
rc = io_input (pdev, devNum, in_regs, buf, secNum);
break;
case DOCH_PASSTHRU_DATA_OUT:
rc = io_output (pdev, devNum, in_regs, buf, secNum);
break;
default:
return DOCH_UnknownCmd;
}
/*If IO operation succeeded, retrieve device response from ATA registers
(calling routine might need some data back from the device)*/
if(rc == DOCH_OK)
rc = get_out_registers(pdev, devNum, out_regs);
else
return rc;
/* If ATA debug was requested - retrieve and print buffer from Device */
if(gDochAtaDebug == DOCH_GLOBAL_BOOL_PATTERN)
{
rc2 = retrieveAndPrintAtaDebug(pdev);
if(rc2 != DOCH_OK)
return rc2;
}
return rc;
}
/******************************************************************************
* *
* c l e a r A T A I n t e r r u p t *
* *
* Clear ATA interrupt by simply reading the ATA status register *
* *
* Parameters : *
* pdev : device to perform operation on *
* *
* Returns : *
* DOCH_OK in success, otherwise respective error code. *
* *
******************************************************************************/
DOCH_Error clearATAInterrupt(FLSNative socketNo)
{
#ifdef DOCH_USE_FUNC
DOCH_Socket* pdev;
if(socketNo > DOCH_MAX_SOCKETS - 1)
return DOCH_BadParameter;
pdev = &sockets[socketNo];
DOCHREAD_ATA_REG(pdev->bRegBase, DOCH_STATUS_REG);
#else /*DOCH_USE_FUNC*/
DOCHREAD_ATA_REG((&sockets[socketNo])->bRegBase, DOCH_STATUS_REG);
#endif /*DOCH_USE_FUNC*/
return DOCH_OK;
}
/******************************************************************************
* *
* g e t _ o u t _ r e g i s t e r s *
* *
* Retrieve ATA output registers values *
* *
* Parameters : *
* pdev : device to perform operation on *
* out_regs : DOCH output registers values *
* *
* Returns : *
* DOCH_OK in success, otherwise respective error code. *
* *
******************************************************************************/
DOCH_Error get_out_registers(DOCH_Socket* pdev, FLSNative devNum, DOCH_Registers* out_regs)
{
DOCH_Error err
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -