📄 usbh_storage_if.c
字号:
if(result != STATUS_SUCCESS) {
return STATUS_UNSUCCESSFUL;
}
for(i = 0; i < REQSENSE_LENGTH; i++) {
devicePara[deviceNo].reqSenseData[i] = 0x00;
}
devicePara[deviceNo].deviceStatus = DRV_FUNC_CMD_EXEC;
devicePara[deviceNo].commandStatus = URB_LINK;
/* Issue URB */
result = USBH_USBD_SubmitURB(pUrb, classid, USBH_STRG_SubmitURBCallback);
if(result != STATUS_SUCCESS) {
return STATUS_UNSUCCESSFUL;
}
/* Waiting for the completion of URB registration*/
OS_WaiFlg(FLGID_USBH_SAMPLE, FLG_EVENT_SUBMITURB_CMP_USBH_SAMPLE, OS_TWF_ORW, &flgPtn);
OS_ClrFlg(FLGID_USBH_SAMPLE, ~(FLG_EVENT_SUBMITURB_CMP_USBH_SAMPLE));
if(callbackPara.event != USBH_USBD_MSG_SUBMIT_OK) {
return STATUS_UNSUCCESSFUL;
}
/* It loops until CSW URB ends normally. */
do {
/* Waiting for URB completion */
OS_WaiFlg(FLGID_USBH_SAMPLE, FLG_EVENT_URB_CMP_USBH_SAMPLE, OS_TWF_ORW, &flgPtn);
OS_ClrFlg(FLGID_USBH_SAMPLE, ~(FLG_EVENT_URB_CMP_USBH_SAMPLE));
switch(devicePara[deviceNo].commandStatus) {
/* It makes an error in CBW URB */
case CBW_CMP:
/* Terminate when Transfer error occur */
if(cbwUrb[deviceNo].status == URBSTS_PROTO) {
result = USBH_USBD_UnlinkURB(&cbwUrb[deviceNo], classid, USBH_STRG_UnlinkURBCallback);
if(result != STATUS_SUCCESS) {
return STATUS_UNSUCCESSFUL;
}
/* Waiting for the completion of UnlinkURB */
OS_WaiFlg(FLGID_USBH_SAMPLE, FLG_EVENT_UNLINKURB_CMP_USBH_SAMPLE, OS_TWF_ORW, &flgPtn);
OS_ClrFlg(FLGID_USBH_SAMPLE, ~(FLG_EVENT_UNLINKURB_CMP_USBH_SAMPLE));
devicePara[deviceNo].commandStatus = NO_OP;
result = STATUS_UNSUCCESSFUL;
} else {
/* Execute ClearFeature of Bulk Out EP when the protocol error. */
pSetupData = &setupData[deviceNo];
pSetupData->bmRequestType = CLEAR_FEATURE_EP;
/* Specify EP */
endpointAdrs = pSetupData->wIndex = USBH_HCDS_GetPipeEndpointAdrs(cbwUrb[deviceNo].pipe);
result = USBH_STRG_MakeCtlURB(deviceNo, pSetupData, NULL, pUrb);
if(result != STATUS_SUCCESS) {
return STATUS_UNSUCCESSFUL;
}
result = USBH_USBD_SubmitURB(pUrb, classid, USBH_STRG_SubmitURBCallback);
if(result != STATUS_SUCCESS) {
return STATUS_UNSUCCESSFUL;
}
/* Waiting for the completion of URB registration*/
OS_WaiFlg(FLGID_USBH_SAMPLE, FLG_EVENT_URB_CMP_USBH_SAMPLE, OS_TWF_ORW, &flgPtn);
OS_ClrFlg(FLGID_USBH_SAMPLE, ~(FLG_EVENT_URB_CMP_USBH_SAMPLE));
if(callbackPara.event != USBH_USBD_MSG_SUBMIT_OK) {
return STATUS_UNSUCCESSFUL;
}
/* Waiting for URB completion */
OS_WaiFlg(FLGID_USBH_SAMPLE, FLG_EVENT_URB_CMP_USBH_SAMPLE, OS_TWF_ORW, &flgPtn);
OS_ClrFlg(FLGID_USBH_SAMPLE, ~(FLG_EVENT_URB_CMP_USBH_SAMPLE));
USBH_USBD_SetOUTToggle(pUrb->psDev, (endpointAdrs & MASK_EP_NUMBER), 0);
/* Execute CBW Transport again */
result = USBH_USBD_SubmitURB(&cbwUrb[deviceNo], classid, USBH_STRG_SubmitURBCallback);
if(result != STATUS_SUCCESS) {
return STATUS_UNSUCCESSFUL;
}
/* Waiting for the completion of URB registration*/
OS_WaiFlg(FLGID_USBH_SAMPLE, FLG_EVENT_SUBMITURB_CMP_USBH_SAMPLE, OS_TWF_ORW, &flgPtn);
OS_ClrFlg(FLGID_USBH_SAMPLE, ~(FLG_EVENT_SUBMITURB_CMP_USBH_SAMPLE));
if(callbackPara.event != USBH_USBD_MSG_SUBMIT_OK) {
return STATUS_UNSUCCESSFUL;
}
}
break;
/* It makes an error in Data URB */
case DATA_CMP:
/* Terminate when transfer error occur */
if( (dataUrb[deviceNo].status == URBSTS_OVERFLOW) || (dataUrb[deviceNo].status == URBSTS_REMOTEIO) ||
(dataUrb[deviceNo].status == URBSTS_PROTO) ) {
result = USBH_USBD_UnlinkURB(&cbwUrb[deviceNo], classid, USBH_STRG_UnlinkURBCallback);
if(result != STATUS_SUCCESS) {
return STATUS_UNSUCCESSFUL;
}
/* Waiting for the completion of UnlinkURB */
OS_WaiFlg(FLGID_USBH_SAMPLE, FLG_EVENT_UNLINKURB_CMP_USBH_SAMPLE, OS_TWF_ORW, &flgPtn);
OS_ClrFlg(FLGID_USBH_SAMPLE, ~(FLG_EVENT_UNLINKURB_CMP_USBH_SAMPLE));
devicePara[deviceNo].commandStatus = NO_OP;
result = STATUS_UNSUCCESSFUL;
} else {
/* Execute ClearFeature of Bulk Out(In) EP when the protocol error. */
pSetupData = &setupData[deviceNo];
pSetupData->bmRequestType = CLEAR_FEATURE_EP;
/* Specify the EP */
endpointAdrs = pSetupData->wIndex = USBH_HCDS_GetPipeEndpointAdrs(dataUrb[deviceNo].pipe);
pUrb = &ctlUrb[deviceNo];
result = USBH_STRG_MakeCtlURB(deviceNo, pSetupData, NULL, pUrb);
if(result != STATUS_SUCCESS) {
return STATUS_UNSUCCESSFUL;
}
pUrb->pfnComplete = USBH_STRG_CtlCompCallback;
result = USBH_USBD_SubmitURB(pUrb, classid, USBH_STRG_SubmitURBCallback);
if(result != STATUS_SUCCESS) {
return STATUS_UNSUCCESSFUL;
}
/* Waiting for the completion of URB registration*/
OS_WaiFlg(FLGID_USBH_SAMPLE, FLG_EVENT_SUBMITURB_CMP_USBH_SAMPLE, OS_TWF_ORW, &flgPtn);
OS_ClrFlg(FLGID_USBH_SAMPLE, ~(FLG_EVENT_SUBMITURB_CMP_USBH_SAMPLE));
if(callbackPara.event != USBH_USBD_MSG_SUBMIT_OK) {
return STATUS_UNSUCCESSFUL;
}
/* Waiting for the completion of URB */
OS_WaiFlg(FLGID_USBH_SAMPLE, FLG_EVENT_URB_CMP_USBH_SAMPLE, OS_TWF_ORW, &flgPtn);
OS_ClrFlg(FLGID_USBH_SAMPLE, ~(FLG_EVENT_URB_CMP_USBH_SAMPLE));
if( pTranPara->direction == DRV_FUNC_IN ){
USBH_USBD_SetINToggle(pUrb->psDev, (endpointAdrs & MASK_EP_NUMBER), 0);
} else {
USBH_USBD_SetOUTToggle(pUrb->psDev, (endpointAdrs & MASK_EP_NUMBER), 0);
}
/* Execute CSW Transport again */
result = USBH_USBD_SubmitURB(&cswUrb[deviceNo], classid, USBH_STRG_SubmitURBCallback);
if(result != STATUS_SUCCESS) {
return STATUS_UNSUCCESSFUL;
}
/* Waiting for the completion of URB registration*/
OS_WaiFlg(FLGID_USBH_SAMPLE, FLG_EVENT_SUBMITURB_CMP_USBH_SAMPLE, OS_TWF_ORW, &flgPtn);
OS_ClrFlg(FLGID_USBH_SAMPLE, ~(FLG_EVENT_SUBMITURB_CMP_USBH_SAMPLE));
if(callbackPara.event != USBH_USBD_MSG_SUBMIT_OK) {
return STATUS_UNSUCCESSFUL;
}
}
break;
/* The completion of CSW URB */
case CSW_CMP:
/* Check the CSW Status when the CSW transfer is completed successfully. */
if(cswUrb[deviceNo].status == URBSTS_SUCCESS) {
if(bulkCsw[deviceNo].status == CSW_OK) {
/* Complete when CSW OK. */
devicePara[deviceNo].commandStatus = NO_OP;
result = STATUS_SUCCESS;
} else if(bulkCsw[deviceNo].status == CSW_ERR) {
/* Execute RequestSense command when the command makes an error. */
devicePara[deviceNo].commandStatus = URB_LINK;
pTranPara->transferSize = dataUrb[deviceNo].actualLength;
/* Execute RequestSense command */
pRQSenseCmdBlock = &sRQSenseCmdBlock;
result = USBH_STRG_PutCmd(deviceNo, pRQSenseCmdBlock, REQUEST_SENSE);
if(result != STATUS_SUCCESS) {
return STATUS_UNSUCCESSFUL;
}
pTranParaLocal = &sTranParaLocal;
pTranParaLocal->direction = DRV_FUNC_IN;
pTranParaLocal->dataSize = REQSENSE_LENGTH;
pTranParaLocal->dataPointer = (ULONG) &devicePara[deviceNo].reqSenseData[0];
pUrb = &cbwUrb[deviceNo];
result = USBH_STRG_MakeStorageURB(deviceNo, transferMode, pRQSenseCmdBlock, pTranParaLocal, pUrb);
if(result != STATUS_SUCCESS) {
return STATUS_UNSUCCESSFUL;
}
result = USBH_USBD_SubmitURB(pUrb, classid, USBH_STRG_SubmitURBCallback);
if(result != STATUS_SUCCESS) {
return STATUS_UNSUCCESSFUL;
}
/* Waiting for the completion of URB registration*/
OS_WaiFlg(FLGID_USBH_SAMPLE, FLG_EVENT_SUBMITURB_CMP_USBH_SAMPLE, OS_TWF_ORW, &flgPtn);
OS_ClrFlg(FLGID_USBH_SAMPLE, ~(FLG_EVENT_SUBMITURB_CMP_USBH_SAMPLE));
if(callbackPara.event != USBH_USBD_MSG_SUBMIT_OK) {
return STATUS_UNSUCCESSFUL;
}
/* Tentative measures of bug that RequestSense command doesn't operate correctly immediately after start of filesystem */
/* Waiting for the completion of URB */
OS_WaiFlg(FLGID_USBH_SAMPLE, FLG_EVENT_URB_CMP_USBH_SAMPLE, OS_TWF_ORW, &flgPtn);
OS_ClrFlg(FLGID_USBH_SAMPLE, ~(FLG_EVENT_URB_CMP_USBH_SAMPLE));
if(bulkCsw[deviceNo].status == CSW_OK) {
/* End in case of CSW OK */
devicePara[deviceNo].commandStatus = NO_OP;
result = STATUS_SUCCESS;
}
} else {
/* Execute reset recovery when phase error occur */
result = USBH_STRG_ResetRecovery(deviceNo);
if(result != STATUS_SUCCESS) {
return STATUS_UNSUCCESSFUL;
}
result = STATUS_SUCCESS;
}
} else {
/* Execute ClearFeature of Bulk In EP when the CSW transfer error. */
pSetupData = &setupData[deviceNo];
pSetupData->bmRequestType = CLEAR_FEATURE_EP;
/* Specify EP */
endpointAdrs = pSetupData->wIndex = USBH_HCDS_GetPipeEndpointAdrs(cswUrb[deviceNo].pipe);
pUrb = &ctlUrb[deviceNo];
result = USBH_STRG_MakeCtlURB(deviceNo, pSetupData, NULL, pUrb);
if(result != STATUS_SUCCESS) {
return STATUS_UNSUCCESSFUL;
}
result = USBH_USBD_SubmitURB(pUrb, classid, USBH_STRG_SubmitURBCallback);
if(result != STATUS_SUCCESS) {
return STATUS_UNSUCCESSFUL;
}
/* Waiting for the completion of URB registration*/
OS_WaiFlg(FLGID_USBH_SAMPLE, FLG_EVENT_SUBMITURB_CMP_USBH_SAMPLE, OS_TWF_ORW, &flgPtn);
OS_ClrFlg(FLGID_USBH_SAMPLE, ~(FLG_EVENT_SUBMITURB_CMP_USBH_SAMPLE));
if(callbackPara.event != USBH_USBD_MSG_SUBMIT_OK) {
return STATUS_UNSUCCESSFUL;
}
/* Waiting for the completion of URB */
OS_WaiFlg(FLGID_USBH_SAMPLE, FLG_EVENT_URB_CMP_USBH_SAMPLE, OS_TWF_ORW, &flgPtn);
OS_ClrFlg(FLGID_USBH_SAMPLE, ~(FLG_EVENT_URB_CMP_USBH_SAMPLE));
USBH_USBD_SetINToggle(pUrb->psDev, (endpointAdrs & MASK_EP_NUMBER), 0);
/* Execute CSW Transport again */
result = USBH_USBD_SubmitURB(&cswUrb[deviceNo], classid, USBH_STRG_SubmitURBCallback);
if(result != STATUS_SUCCESS) {
return STATUS_UNSUCCESSFUL;
}
/* Waiting for the completion of URB registration*/
OS_WaiFlg(FLGID_USBH_SAMPLE, FLG_EVENT_SUBMITURB_CMP_USBH_SAMPLE, OS_TWF_ORW, &flgPtn);
OS_ClrFlg(FLGID_USBH_SAMPLE, ~(FLG_EVENT_SUBMITURB_CMP_USBH_SAMPLE));
if(callbackPara.event != USBH_USBD_MSG_SUBMIT_OK) {
return STATUS_UNSUCCESSFUL;
}
}
break;
default:
/* It doese not run here */
break;
}
} while(devicePara[deviceNo].commandStatus != NO_OP);
/* Set ReqSenseData */
for(i = 0; i < REQSENSE_LENGTH; i++) {
*pSenseData = devicePara[deviceNo].reqSenseData[i];
pSenseData++;
}
/* Set the status that corresponds to the Sence Key */
switch( (devicePara[deviceNo].reqSenseData[2] & 0x0F) ) {
case MEDIUM_ERROR:
*pStatus = DRV_FUNC_NM_ERR;
result = STATUS_UNSUCCESSFUL;
break;
case HARDWARE_ERROR:
*pStatus = DRV_FUNC_DEVICE_ERR;
result = STATUS_UNSUCCESSFUL;
break;
case UNIT_ATTENTION:
*pStatus = DRV_FUNC_MC_ERR;
result = STATUS_UNSUCCESSFUL;
break;
default:
break;
}
#ifdef USBH_STRG_IF_COMMAND_PRINT
DBG_FlowStrPrint("[Status[USB]:", 1);
DBG_FlowValPrint(PRINT_HEXA_MODE, DBG_STORE_BYTE, *pStatus, 1);
DBG_FlowStrPrint("]\r\n", 1);
#endif
return result;
}
/*=============================================================================================
// Function_Name: USBH_STRG_IFRegisterCBRDMAComp
//
// description : Register the CallBack for the completion of the asynchronous data transfer
//
// After the completion of the asynchronous data transfer,register the notify function.
//
// argument : deviceNo (in)Device No.
// pfnNotifyDMAComp (in)The pointer of the CallBack function.
//
// return : STATUS_SUCCESS Completed successfully
// STATUS_UNSUCCESSFUL Completed with error
// STATUS_UNABLE_TO_REGISTER Can not register
===============================================================================================*/
LONG USBH_STRG_IFRegisterCBRDMAComp( USHORT deviceNo, CALLBACK_PROC pfnNotifyDMAComp )
{
/* Check the registration of CALLBACK */
if(USBH_STRG_IFDMACompCBR[deviceNo] != NULL){
/* The CALL BACK is already registered */
return STATUS_UNABLE_TO_REGISTER;
}
/* Register the CALL BACK */
USBH_STRG_IFDMACompCBR[deviceNo] = pfnNotifyDMAComp;
return STATUS_SUCCESS;
}
/*=============================================================================================
// Function_Name: USBH_STRG_IFUnregisterCBRDMAComp
//
// description : Delete the CallBack after the completion of the asynchronous data transfer
//
// Delete the notify function after the completion of the asynchronous data transfer
//
// argument : deviceNo (in)Device No.
// pfnNotifyDMAComp (in)The pointer of the CallBack function.
//
// return : STATUS_SUCCESS Completed successfully
// STATUS_UNSUCCESSFUL Completed with error
// STATUS_UNREGISTERED Not registered
===============================================================================================*/
LONG USBH_STRG_IFUnregisterCBRDMAComp( USHORT deviceNo, CALLBACK_PROC pfnNotifyDMAComp )
{
/* Check the registration of CALL BACK */
if(USBH_STRG_IFDMACompCBR[deviceNo] != pfnNotifyDMAComp){
/* The CALL BACK is not registered */
return STATUS_UNREGISTERED;
}
/* Delete the CALL BACK */
USBH_STRG_IFDMACompCBR[deviceNo] = NULL;
return STATUS_SUCCESS;
}
/*=============================================================================================
// Function_Name: USBH_STRG_IFRegisterCBRIntrqComp
//
// description : Register the CallBack for the completion of the asynchronous data transfer
//
// Register the notify function after the completion of the asynchronous command.
//
// argument : deviceNo (in)Device No.
// pfnNotifyDMAComp (in)The pointer of the CallBack function.
//
// return : STATUS_SUCCESS Completed successfully
// STATUS_UNSUCCESSFUL Completed with error
// STATUS_UNABLE_TO_REGISTER Can not register
===============================================================================================*/
LONG USBH_STRG_IFRegisterCBRIntrqComp( USHORT deviceNo, CALLBACK_PROC pfnNotifyIntrqComp )
{
/* Check the registration of CALL BACK */
if(USBH_STRG_IFIntrqCompCBR[deviceNo] != NULL){
/* The CALL BACK already registered */
return STATUS_UNABLE_TO_REGISTER;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -