📄 usbh_ide_if.c
字号:
// description : It informs the status of the specified device to the upper layer.
//
// It informs the status of the specified device to the upper layer.
// Get the request sense data automatically and inform the upper layer.
//
// argument : deviceNo (in)Device No.
// *pStatus (in)Status pointer
// *pTransferSize (in)The pointer that points to the number of bytes
// transfered in the previous executed data transfer
// *pSenseData (in)Pointer of the request sense data
//
// return : STATUS_SUCCESS Complete the process normally
// STATUS_UNSUCCESSFUL Error occured during the process
===============================================================================================*/
LONG USBH_IDE_IFGetStatus( USHORT deviceNo, ULONG *pStatus, ULONG *pTransferSize, UCHAR *pSenseData )
{
*pStatus = devicePara[deviceNo].deviceStatus;
*pTransferSize = devicePara[deviceNo].transferSize;
memcpy( pSenseData, &devicePara[deviceNo].reqSenseData, sizeof(devicePara[deviceNo].reqSenseData) );
return STATUS_SUCCESS;
}
/*=============================================================================================
// Function_Name: USBH_IDE_IFSyncCommand
//
// description : It sends command to the specified device (isochronous process )
//
// It sends command to the specified device (isochronous process )
// Control will not return to the Upper layer until all the processes completed.
//
// argument : deviceNo (in)Device No.
// transferMode (in)The transfer mode of the command
// *pTransferSize (in)The pointer that points to the number of bytes
// transfered in the previous executed data transfer
// *pCmdBlock (in)Pointer of command parameter
// *pTranPara (in)Pointer of data transfer parameter
// *pStatus (in)Status pointer
// *pSenseData (in)Pointer of requesr sense data
//
// return : STATUS_SUCCESS Complete the process normally
// STATUS_UNSUCCESSFUL Error occured during the process
// USBH_IDE_STATUS_DMA_EXEC Specified device is transfering data
===============================================================================================*/
LONG USBH_IDE_IFSyncCommand( USHORT deviceNo, UCHAR transferMode, DRIVEACCESS_FUNCCMDPARA *pCmdBlock, DRIVEACCESS_FUNCTRANPARA *pTranPara, ULONG *pStatus, UCHAR *pSenseData )
{
UCHAR i;
LONG result;
PARAM_MSG_REQ_IDE_CMD IdeCmd; // Command structure sent to IDE
OS_FLGPTN flgPtn;
USBH_SAMPLE_MSG *pMsg;
volatile REG_rxDMAxWindow *prxDMAxWindow;
volatile unsigned short *prsDMAxWindow;
result = STATUS_UNSUCCESSFUL; // For solve the warning based on the optimization
/* Check if the device exists */
if( pUSBH_IDE_DeviceList->deviceType[deviceNo] == NO_DEVICE ){
*pStatus = DRV_FUNC_NM_ERR ;
return STATUS_UNSUCCESSFUL ;
}
#ifdef USBH_IDE_IF_COMMAND_PRINT
DBG_FlowStrPrint("\r\n[CMD[IDE] :", 1);
for( i = 0; i < 12; i++ ){
DBG_FlowStrPrint(" ", 1);
DBG_FlowValPrint(PRINT_HEXA_MODE, DBG_STORE_BYTE, pCmdBlock->commandBlock[i], 1);
}
DBG_FlowStrPrint("]\r\n", 1);
DBG_FlowStrPrint("[BufAdrs : ", 1);
DBG_FlowValPrint(PRINT_HEXA_MODE, DBG_STORE_DWORD, pTranPara->dataPointer, 1);
DBG_FlowStrPrint("]\r\n", 1);
#endif
/* Join MediaFIFO */
RegSet( REG08_MediaFIFO_Join, BIT_JoinIDE );
/* Set direction of IDE */
if(pTranPara->direction == DRV_FUNC_IN) {
RegModify( REG08_IDE_Control, MASK_IDE_Dir, BIT_IDEtoFIFO);
} else {
RegModify( REG08_IDE_Control, MASK_IDE_Dir, BIT_FIFOtoIDE);
}
while(devicePara[deviceNo].commandStatus != COMMAND_OK) {
/* MediaFIFO Clear */
RegSet( REG08_MediaFIFO_Control, BIT_MediaFIFO_Clr );
// generate IDE Command
memcpy( &IdeCmd.IDECmd, pCmdBlock->commandBlock, sizeof(IdeCmd.IDECmd) );
USBH_IDE_MakeIdeCmd(deviceNo, pCmdBlock->commandBlock[0], &IdeCmd);
IdeCmd.reqDataLen = pTranPara->dataSize;
/* Check if DMA is usable */
if( USBH_HCD_USED_DMA_FOR_IDE == 1 ) {
/* In IDE, use the DMA of CPU I/F */
for( i = 0; i < CPU_DMA_NUM; i++ ){
/* Correspondence DMA channel is not being used. */
if(devicePara[deviceNo].usedDMACh == DMA_NOT_USE) {
REG_DMAX_WINDOW_ADDR(prsDMAxWindow, i);
prxDMAxWindow = (volatile REG_rxDMAxWindow *)prsDMAxWindow;
if( ( RegRead( &prxDMAxWindow->rcDMAx_Config ) & MASK_ActiveDMA ) == 0 ){
/* DMA is usable */
RegSet( &prxDMAxWindow->rcDMAx_Config, BIT_ActiveDMA );
devicePara[deviceNo].usedDMACh = i;
break;
}
}
}
}
if(devicePara[deviceNo].usedDMACh != DMA_NOT_USE) {
/* When DMA is usable */
IdeCmd.xferMode = devicePara[deviceNo].xferMode = IDE_XFER_DMA;
IdeCmd.bufferPtr = devicePara[deviceNo].xferStart.bufferPtr = (UCHAR *) pTranPara->dataPointer;
} else {
/* When DAM is unusable */
IdeCmd.xferMode = devicePara[deviceNo].xferMode = IDE_XFER_HPIO;
IdeCmd.bufferPtr = devicePara[deviceNo].xferStart.bufferPtr = (UCHAR *) pTranPara->dataPointer;
}
/* Save the transfer parameter */
devicePara[deviceNo].direction = pTranPara->direction;
RegWrite( REG08_IDE_IntStat, 0xF7 );
RegSet( REG08_MainIntEnb, BIT_EnIDE_IntStat );
/* Send message to IDE Task */
USBH_IDE_SendMessage( MBXID_IDE, MSG_REQ_IDE_CMD, sizeof(IdeCmd), &IdeCmd );
while(devicePara[deviceNo].commandStatus != COMMAND_OK && devicePara[deviceNo].commandStatus != COMMAND_NG) {
/* Waiting for event */
OS_WaiFlg(FLGID_USBH_SAMPLE, (FLG_EVENT_INT_USBH_SAMPLE | FLG_EVENT_MSG_USBH_SAMPLE), OS_TWF_ORW, &flgPtn);
if(flgPtn & FLG_EVENT_INT_USBH_SAMPLE) {
/* Interrupt event */
OS_ClrFlg( FLGID_USBH_SAMPLE, ~(FLG_EVENT_INT_USBH_SAMPLE) );
USBH_IDE_IntEvent(deviceNo);
} else if(flgPtn & FLG_EVENT_MSG_USBH_SAMPLE) {
/* Message event */
OS_ClrFlg( FLGID_USBH_SAMPLE, ~(FLG_EVENT_MSG_USBH_SAMPLE) );
// Receive message from mailbox.
OS_PRcvMbx( FLGID_USBH_SAMPLE, ( T_MSG** )&pMsg );
switch( pMsg->msgHead.msgNo ) {
case MSG_NTFY_IDE_CMP_XFER_READY: // IDE data transfer is ready notification
MsgIdeXferReady(deviceNo, pMsg);
break;
case MSG_NTFY_IDE_XFER_CMP: // Data transfer completion notification
MsgIdeXferCmp(deviceNo, pMsg);
break;
case MSG_NTFY_IDE_CMD: // ATAPI command compeletion notification
MsgIdeCmdCmp(deviceNo, pMsg);
break;
}
// Free the message buffer
OS_RelMpf( pMsg->msgHead.useMpfId, pMsg );
}
}
if(devicePara[deviceNo].commandStatus == COMMAND_OK) {
result = STATUS_SUCCESS;
*pStatus = DRV_FUNC_CMD_COMP;
memset(pSenseData, 0x00, sizeof(REQSENSE_LENGTH));
memset(devicePara[deviceNo].reqSenseData, 0x00, sizeof(REQSENSE_LENGTH));
} else {
/* Send RequestSense when error occured */
/* Execute RequestSense */
USBH_IDE_MakeIdeCmd(deviceNo, REQUEST_SENSE, &IdeCmd);
IdeCmd.xferMode = IDE_XFER_SPIO;
IdeCmd.reqDataLen = REQSENSE_LENGTH;
IdeCmd.bufferPtr = devicePara[deviceNo].reqSenseData;
/* Send message to IDE Task */
USBH_IDE_SendMessage( MBXID_IDE, MSG_REQ_IDE_CMD, sizeof(IdeCmd), &IdeCmd );
/* Waiting for the mesage */
OS_WaiFlg(FLGID_USBH_SAMPLE, FLG_EVENT_MSG_USBH_SAMPLE, OS_TWF_ORW, &flgPtn);
OS_ClrFlg( FLGID_USBH_SAMPLE, ~(FLG_EVENT_MSG_USBH_SAMPLE) );
// Receive message from mailbox.
OS_PRcvMbx( FLGID_USBH_SAMPLE, ( T_MSG** )&pMsg );
if( ((PARAM_MSG_NTFY_IDE_CMD *)pMsg->msgData)->result == IDE_REQ_OK) {
/* Set the SenseData */
memcpy( pSenseData, &devicePara[deviceNo].reqSenseData, sizeof(devicePara[deviceNo].reqSenseData) );
/* Set status */
switch(devicePara[deviceNo].reqSenseData[2]) {
case NO_SENSE:
case RECOVERED_ERROR:
*pStatus = DRV_FUNC_CMD_COMP;
break;
case NOT_READY:
case MEDIUM_ERROR:
case HARDWARE_ERROR:
case ILLEGAL_REQEEST:
*pStatus = DRV_FUNC_DEVICE_ERR;
break;
case UNIT_ATTENTION:
*pStatus = DRV_FUNC_MC_ERR;
break;
case ABORTED_COMMAND:
*pStatus = DRV_FUNC_ABORT_ERR;
break;
case BLANK_CHECK:
case VOLUME_OVERFLOW:
*pStatus = DRV_FUNC_IDNF_ERR;
break;
case DATA_PROTECT:
*pStatus = DRV_FUNC_WP_ERR;
break;
/* Would not run to here */
case COPY_ABORTED:
case EQUAL:
case MISCOMPARE:
default:
break;
}
// Free the message buffer
OS_RelMpf( pMsg->msgHead.useMpfId, pMsg );
/* Retry when UnitAttension */
if(devicePara[deviceNo].reqSenseData[2] != UNIT_ATTENTION) {
result = STATUS_UNSUCCESSFUL;
devicePara[deviceNo].commandStatus = COMMAND_OK;
} else {
devicePara[deviceNo].commandStatus = NO_OP;
}
} else {
// Free the message buffer
OS_RelMpf( pMsg->msgHead.useMpfId, pMsg );
result = STATUS_UNSUCCESSFUL;
*pStatus = DRV_FUNC_DEVICE_ERR;
/* Because RequestSense command failed, initializes SenseData at once. */
memset(pSenseData, 0x00, REQSENSE_LENGTH);
/* Quit the loop */
break;
}
}
}
/* The number of real transfering is set. */
pTranPara->transferSize = devicePara[deviceNo].transferSize;
/* Save the status */
devicePara[deviceNo].deviceStatus = *pStatus;
devicePara[deviceNo].commandStatus = NO_OP;
#ifdef USBH_IDE_IF_COMMAND_PRINT
DBG_FlowStrPrint("[Status[IDE]:", 1);
DBG_FlowValPrint(PRINT_HEXA_MODE, DBG_STORE_BYTE, *pStatus, 1);
DBG_FlowStrPrint("]\r\n", 1);
#endif
return result;
}
/*=============================================================================================
// Function_Name: USBH_IDE_IFRegisterCBRDMAComp
//
// description : Register the asynchronous data transfer completion callback.
//
// It registers the callback when the asynchronous data transfer completed.
//
// argument : deviceNo (in)Device No.
// pfnNotifyDMAComp (in)Pointer of the callback fucntion
//
// return : STATUS_SUCCESS Complete the process normally
// STATUS_UNSUCCESSFUL Error occured during the process
// STATUS_UNABLE_TO_REGISTER It is unable to register.
===============================================================================================*/
LONG USBH_IDE_IFRegisterCBRDMAComp( USHORT deviceNo, CALLBACK_PROC pfnNotifyDMAComp )
{
/* Check callback registration */
if(USBH_IDE_IFDMACompCBR[deviceNo] != NULL){
/* CALLBACK had benn registrated */
return STATUS_UNABLE_TO_REGISTER;
}
/* REgister CALLBACK */
USBH_IDE_IFDMACompCBR[deviceNo] = pfnNotifyDMAComp;
return STATUS_SUCCESS;
}
/*=============================================================================================
// Function_Name: USBH_IDE_IFUnregisterCBRDMAComp
//
// description : Delete the callback when the asynchronous transfer completed.
//
// When the asynchronous transfer completed,delete the callback fucntiont that used for notification.
//
// argument : deviceNo (in)Device No.
// pfnNotifyDMAComp (in)Pointer of the callback function
//
// return : STATUS_SUCCESS Complete the process normally
// STATUS_UNSUCCESSFUL Error occured during the process
// STATUS_UNREGISTERED It is not registered.
===============================================================================================*/
LONG USBH_IDE_IFUnregisterCBRDMAComp( USHORT deviceNo, CALLBACK_PROC pfnNotifyDMAComp )
{
/* Check callback registration */
if(USBH_IDE_IFDMACompCBR[deviceNo] != pfnNotifyDMAComp){
/* CALLBACK had not been registered */
return STATUS_UNREGISTERED;
}
/* Delete CALLBACK */
USBH_IDE_IFDMACompCBR[deviceNo] = NULL;
return STATUS_SUCCESS;
}
/*=============================================================================================
// Function_Name: USBH_IDE_IFRegisterCBRIntrqComp
//
// description : Register the asynchronous data transfer completion callback.
//
// When the asynchronous command completed, register the function that used to notify.
//
// argument : deviceNo (in)Device No.
// pfnNotifyDMAComp (in)Pointer of the callback function
//
// return : STATUS_SUCCESS Complete the process normally
// STATUS_UNSUCCESSFUL Error occured during the process
// STATUS_UNABLE_TO_REGISTER It is not registered.
===============================================================================================*/
LONG USBH_IDE_IFRegisterCBRIntrqComp( USHORT deviceNo, CALLBACK_PROC pfnNotifyIntrqComp )
{
/* Check callback registration */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -