📄 usbd_protstorage.c
字号:
}
}
} else {
/* Request Error */
USBD_FuncSetEPxControl(PRV_EP0IN, USBD_FUNC_CE_STALLMODE, USBD_FUNC_FLAG_SET);
USBD_FuncSetEPxControl(PRV_EP0OUT, USBD_FUNC_CE_STALLMODE, USBD_FUNC_FLAG_SET);
}
}
/* Add for USBCV MSC Test */
if (IS_BIT(PrvInternalStatus,PRV_IR_ALTERNATE_CHANGED) == TRUE) {
CLR_BIT(PrvInternalStatus,PRV_IR_ALTERNATE_CHANGED);
SET_BIT(PrvInternalStatus,PRV_IR_CONFIGURED);
}
/* End of USBCV MSC Test */
if (IS_BIT(PrvInternalStatus,PRV_IR_CONFIGURED) == TRUE) {
CLR_BIT(PrvInternalStatus,PRV_IR_CONFIGURED);
/* Stop the function of BulkOnly CBW,CSW */
/* Stop CBW,CSW Mode */
retValue = USBD_IFSetBulkOnlyMode(USBD_IF_CBWMODE | USBD_IF_CSWMODE,USBD_IF_DISABLE);
/* Set Endpoint which is used by BulkOnly CBW,CSW */
bulkOnlyParam.bLength = sizeof (USBD_FUNC_BULKONLY);
bulkOnlyParam.bType = USBD_FUNC_BULKONLY_PARAM;
bulkOnlyParam.bCBWEPNum = PrvBulkEPInfo[PRV_BULKOUT].bEPNumber;
bulkOnlyParam.bCSWEPNum = PrvBulkEPInfo[PRV_BULKIN].bEPNumber;
tempRet = USBD_FuncSetParameter((UCHAR *)&bulkOnlyParam);
if (tempRet != STATUS_SUCCESS) {
retValue = STATUS_UNSUCCESSFUL;
}
if (PrvStorageEventCallback != NULL) {
/* Call it, if callback had been registered */
lp0 = USBD_PROT_STORAGE_ACTIVECHANGE_EVENT;
lp1 = USBD_PROT_STORAGE_ACTIVE;
pp = NULL;
PrvStorageEventCallback(lp0,lp1,pp);
}
}
if (IS_BIT(PrvInternalStatus,PRV_IR_DECONFIGURED) == TRUE) {
CLR_BIT(PrvInternalStatus,PRV_IR_DECONFIGURED);
/* Stop CBW,CSW Mode */
retValue = USBD_IFSetBulkOnlyMode(USBD_IF_CBWMODE | USBD_IF_CSWMODE,USBD_IF_DISABLE);
/* Call it, if callback had been registered */
lp0 = USBD_PROT_STORAGE_ACTIVECHANGE_EVENT;
lp1 = USBD_PROT_STORAGE_INACTIVE;
pp = NULL;
PrvStorageEventCallback(lp0,lp1,pp);
}
if (IS_BIT(PrvInternalStatus,PRV_IR_EP0_DATAIN_END) == TRUE) {
/* When Data Stage of Control Transfer has finished */
CLR_BIT(PrvInternalStatus,PRV_IR_EP0_DATAIN_END);
/* Do Status Stage */
retValue = USBD_FuncEP0StatusStageReadyA(PrvAllocId);
if (retValue != STATUS_SUCCESS) {
/* Unable to start Status Stage(used for debug) */
break;
}
}
if (IS_BIT(PrvInternalStatus,PRV_IR_EP0_STATUSSTAGE_END) == TRUE) {
/* When Status Stage of Control Transfer has finished */
CLR_BIT(PrvInternalStatus,PRV_IR_EP0_STATUSSTAGE_END);
/* No special process here */
}
/* Check the transmission of CSW */
if (IS_BIT(PrvInternalStatus,PRV_IR_BULKIN_TRANSFER_END) == TRUE) {
if (PrvBulkEPInfo[PRV_BULKIN].bState == PRV_CSW_STATE) {
/* When transfer of Bulk In has finished */
CLR_BIT(PrvInternalStatus,PRV_IR_BULKIN_TRANSFER_END);
/* When transmission of CSW has finished */
PrvBulkEPInfo[PRV_BULKIN].bState = PRV_IDLE_STATE;
}
}
/* Check the receiving of CBW */
if (IS_BIT(PrvInternalStatus,PRV_IR_BULKOUT_TRANSFER_END) == TRUE) {
if (PrvBulkEPInfo[PRV_BULKOUT].bState == PRV_CBW_STATE) {
/* When transfer of Bulk Out has finished */
CLR_BIT(PrvInternalStatus,PRV_IR_BULKOUT_TRANSFER_END);
/* After receiving of CBW */
PrvBulkEPInfo[PRV_BULKOUT].bState = PRV_IDLE_STATE;
if (PrvBulkEPInfo[PRV_BULKIN].bState == PRV_IDLE_STATE) {
/* When CBW has been received after CSW had been sent */
tempRet = PrvCheckCBW();
if (tempRet == STATUS_SUCCESS) {
/* Set TAG of CSW */
PrvCSW[4] = PrvCBW[4];
PrvCSW[5] = PrvCBW[5];
PrvCSW[6] = PrvCBW[6];
PrvCSW[7] = PrvCBW[7];
/* Save the size that is requested to transfer */
size = PrvCBW[11];size <<= 8;
size += PrvCBW[10];size <<= 8;
size += PrvCBW[ 9];size <<= 8;
size += PrvCBW[ 8];
PrvBulkEPInfo[PRV_BULKIN].dwReqXferSize = 0;
PrvBulkEPInfo[PRV_BULKIN].dwTotalXferSize = 0;
PrvBulkEPInfo[PRV_BULKIN].dwActXferSize = 0;
PrvBulkEPInfo[PRV_BULKIN].dwXferedSize = 0;
PrvBulkEPInfo[PRV_BULKOUT].dwReqXferSize = 0;
PrvBulkEPInfo[PRV_BULKOUT].dwTotalXferSize = 0;
PrvBulkEPInfo[PRV_BULKOUT].dwActXferSize = 0;
PrvBulkEPInfo[PRV_BULKOUT].dwXferedSize = 0;
if (size > 0) {
/* If there are data to transfer */
if ((PrvCBW[12] & 0x80) != 0x00) {
/* Bulk IN */
PrvBulkEPInfo[PRV_BULKIN].dwReqXferSize = size;
PrvBulkEPInfo[PRV_BULKIN].dwTotalXferSize = size;
} else {
/* Bulk OUT */
PrvBulkEPInfo[PRV_BULKOUT].dwReqXferSize = size;
PrvBulkEPInfo[PRV_BULKOUT].dwTotalXferSize = size;
}
}
if (PrvStorageEventCallback != NULL) {
/* Call it, if callback had been registered */
lp0 = USBD_PROT_STORAGE_COMMAND_RCVED_EVENT;
lp1 = 0x00;
pp = NULL;
PrvStorageEventCallback(lp0,lp1,pp);
}
} else {
/* Assume it as error */
PrvBulkEPInfo[PRV_BULKIN].bState = PRV_STALL_STATE;
USBD_FuncSetEPxControl(PrvBulkEPInfo[PRV_BULKIN].bEPNumber, USBD_FUNC_CE_STALLMODE, USBD_FUNC_FLAG_SET);
PrvBulkEPInfo[PRV_BULKOUT].bState = PRV_STALL_STATE;
USBD_FuncSetEPxControl(PrvBulkEPInfo[PRV_BULKOUT].bEPNumber, USBD_FUNC_CE_STALLMODE, USBD_FUNC_FLAG_SET);
SET_BIT(PrvInternalStatus,PRV_IR_RESET_RECOVERY);
}
} else {
if (PrvBulkEPInfo[PRV_BULKIN].bState == PRV_CSW_STATE) {
/* If CBW has been received befor the completion fo CSW transmission, assume it as Completion of CSW transfer */
CLR_BIT(PrvInternalStatus,PRV_IR_BULKIN_TRANSFER_END);
/* When transmission of CSW has finished */
PrvBulkEPInfo[PRV_BULKIN].bState = PRV_IDLE_STATE;
}
}
}
}
epx = 0xFF;
if (IS_BIT(PrvInternalStatus,PRV_IR_BULKIN_TRANSFER_END) == TRUE) {
CLR_BIT(PrvInternalStatus,PRV_IR_BULKIN_TRANSFER_END);
epx = PRV_BULKIN;
/* Delete event for detecting completion of flush */
USBD_FuncSetEPxIntEvent(PrvAllocId,PrvBulkEPInfo[epx].bEPNumber,0x00,0x00);
} else if (IS_BIT(PrvInternalStatus,PRV_IR_BULKOUT_TRANSFER_END) == TRUE) {
CLR_BIT(PrvInternalStatus,PRV_IR_BULKOUT_TRANSFER_END);
epx = PRV_BULKOUT;
}
if (epx != 0xFF) {
/* When transfer of Bulk IN or OUT has finished */
if (PrvBulkEPInfo[epx].bState == PRV_DATA_STATE || PrvBulkEPInfo[epx].bState == PRV_ABORT_STATE) {
/* When is is on data transferring, or transfer had been aborted */
PrvBulkEPInfo[epx].dwXferedSize += PrvBulkEPInfo[epx].dwActXferSize;
size = PrvBulkEPInfo[epx].dwActXferSize;
PrvBulkEPInfo[epx].dwActXferSize = 0;
if (PrvBulkEPInfo[epx].bState == PRV_DATA_STATE) {
if (PrvBulkEPInfo[epx].dwXferedSize < PrvBulkEPInfo[epx].dwTotalXferSize && PrvBulkEPInfo[epx].bShortPkt == 0) {
/* When there still are data */
if (PrvStorageXferEventCallback != NULL) {
/* Call it, if callback had been registered */
lp0 = USBD_PROT_STORAGE_BULK_XFER_CMP_EVENT;
lp1 = (PrvBulkEPInfo[epx].dwTotalXferSize - PrvBulkEPInfo[epx].dwXferedSize);
pp = (VOID *)dwParam;
dwParam[0] = size;
USBD_FuncGetEPxPIODataRemain(PrvBulkEPInfo[epx].bEPNumber,&dwParam[1]);
PrvStorageXferEventCallback(lp0,lp1,pp);
}
} else {
/* When data transfer has finished */
PrvBulkEPInfo[epx].bState = PRV_IDLE_STATE;
if (PrvBulkEPInfo[epx].bUseDMA == 1) {
/* Remove the Join */
PrvBulkEPInfo[epx].bUseDMA = 0;
USBD_FuncSetEPxJoinDMA(PrvBulkEPInfo[epx].bEPNumber,PrvBulkEPInfo[epx].bDmaCh,0,0);
USBD_FuncEndEPxDMATransfer(PrvBulkEPInfo[epx].bEPNumber);
}
if (PrvStorageXferEventCallback != NULL) {
/* Call it, if callback had been registered */
lp0 = USBD_PROT_STORAGE_BULK_XFER_CMP_EVENT;
lp1 = 0;
pp = (VOID *)dwParam;
dwParam[0] = size;
USBD_FuncGetEPxPIODataRemain(PrvBulkEPInfo[epx].bEPNumber,&dwParam[1]);
PrvStorageXferEventCallback(lp0,lp1,pp);
}
/*----------------------------------------------------------------
* When the transfer has finished but it is less than dCBWDataTransfer, return STALL.
*/
if (PrvBulkEPInfo[epx].dwReqXferSize != PrvBulkEPInfo[epx].dwXferedSize) {
/* Set to Stall */
PrvBulkEPInfo[epx].bState = PRV_STALL_STATE;
USBD_FuncSetEPxControl(PrvBulkEPInfo[epx].bEPNumber,USBD_FUNC_CE_STALLMODE,USBD_FUNC_FLAG_SET);
}
}
} else if (PrvBulkEPInfo[epx].bState == PRV_ABORT_STATE) {
/* When transfer has been aborted */
PrvBulkEPInfo[epx].bState = PRV_IDLE_STATE;
if (PrvBulkEPInfo[epx].dwXferedSize < PrvBulkEPInfo[epx].dwTotalXferSize) {
/* Set to Stall */
PrvBulkEPInfo[epx].bState = PRV_STALL_STATE;
USBD_FuncSetEPxControl(PrvBulkEPInfo[epx].bEPNumber,USBD_FUNC_CE_STALLMODE,USBD_FUNC_FLAG_SET);
}
if (PrvBulkEPInfo[epx].bUseDMA == 1) {
/* Remove the Join */
PrvBulkEPInfo[epx].bUseDMA = 0;
USBD_FuncSetEPxJoinDMA(PrvBulkEPInfo[epx].bEPNumber,PrvBulkEPInfo[epx].bDmaCh,0,0);
USBD_FuncEndEPxDMATransfer(PrvBulkEPInfo[epx].bEPNumber);
}
if (PrvStorageXferEventCallback != NULL) {
/* Call it, if callback had been registered */
lp0 = USBD_PROT_STORAGE_BULK_XFER_ABORT_EVENT;
lp1 = 0;
pp = (VOID *)dwParam;
dwParam[0] = PrvBulkEPInfo[epx].dwXferedSize;
USBD_FuncGetEPxPIODataRemain(PrvBulkEPInfo[epx].bEPNumber,&dwParam[1]);
PrvStorageXferEventCallback(lp0,lp1,pp);
}
}
}
}
if (IS_BIT(PrvInternalStatus,PRV_IR_CBW_READY) == TRUE
&& PrvBulkEPInfo[PRV_BULKIN].bState == PRV_IDLE_STATE
&& PrvBulkEPInfo[PRV_BULKOUT].bState == PRV_IDLE_STATE) {
/* When preparation of CBW receiving has finished */
CLR_BIT(PrvInternalStatus,PRV_IR_CBW_READY);
tempRet = PrvGoCBW();
if (tempRet != STATUS_SUCCESS) {
PrvBulkEPInfo[PRV_BULKIN].bState = PRV_STALL_STATE;
USBD_FuncSetEPxControl(PrvBulkEPInfo[PRV_BULKIN].bEPNumber, USBD_FUNC_CE_STALLMODE, USBD_FUNC_FLAG_SET);
PrvBulkEPInfo[PRV_BULKOUT].bState = PRV_STALL_STATE;
USBD_FuncSetEPxControl(PrvBulkEPInfo[PRV_BULKOUT].bEPNumber, USBD_FUNC_CE_STALLMODE, USBD_FUNC_FLAG_SET);
SET_BIT(PrvInternalStatus,PRV_IR_RESET_RECOVERY);
break;
}
}
if (IS_BIT(PrvInternalStatus,PRV_IR_CSW_READY) == TRUE
&& PrvBulkEPInfo[PRV_BULKIN].bState == PRV_IDLE_STATE
&& PrvBulkEPInfo[PRV_BULKOUT].bState == PRV_IDLE_STATE) {
/* When preparation of CSW transmission has finished */
if (PrvBulkEPInfo[PRV_BULKIN].dwReqXferSize > 0) {
epx = PRV_BULKIN;
} else if (PrvBulkEPInfo[PRV_BULKOUT].dwReqXferSize > 0) {
epx = PRV_BULKOUT;
} else {
epx = 0xFF;
}
if (PrvCSW[12] != 0x02 && epx != 0xFF) {
PrvCSW[8] = DWORD2BYTE_LL(PrvCSWResidue);
PrvCSW[9] = DWORD2BYTE_LH(PrvCSWResidue);
PrvCSW[10] = DWORD2BYTE_HL(PrvCSWResidue);
PrvCSW[11] = DWORD2BYTE_HH(PrvCSWResidue);
} else {
PrvCSW[8] = 0x00000000;
PrvCSW[9] = 0x00000000;
PrvCSW[10] = 0x00000000;
PrvCSW[11] = 0x00000000;
}
if (epx != 0xFF) {
/* Remove the Join with DMA */
if (PrvBulkEPInfo[epx].bUseDMA == 1) {
PrvBulkEPInfo[epx].bUseDMA = 0;
USBD_FuncSetEPxJoinDMA(PrvBulkEPInfo[epx].bEPNumber,PrvBulkEPInfo[epx].bDmaCh,0,0);
}
}
CLR_BIT(PrvInternalStatus,PRV_IR_CSW_READY);
tempRet = PrvGoCSW();
if (tempRet != STATUS_SUCCESS) {
PrvBulkEPInfo[PRV_BULKIN].bState = PRV_STALL_STATE;
USBD_FuncSetEPxControl(PrvBulkEPInfo[PRV_BULKIN].bEPNumber, USBD_FUNC_CE_STALLMODE, USBD_FUNC_FLAG_SET);
PrvBulkEPInfo[PRV_BULKOUT].bState = PRV_STALL_STATE;
USBD_FuncSetEPxControl(PrvBulkEPInfo[PRV_BULKOUT].bEPNumber, USBD_FUNC_CE_STALLMODE, USBD_FUNC_FLAG_SET);
SET_BIT(PrvInternalStatus,PRV_IR_RESET_RECOVERY);
break;
}
if (PrvStorageXferEventCallback != NULL) {
/* Call it, if callback had been registered */
lp0 = USBD_PROT_STORAGE_COMMANDSTATUS_SENT_EVENT;
lp1 = 0;
pp = NULL;
PrvStorageEventCallback(lp0,lp1,pp);
}
}
/* Finished normally */
retValue = STATUS_SUCCESS;
break;};
return retValue;
}
/* =============================================================================
// Function_Name: PrvDecodeRequest
// description : Analyze the request received
// argument : None
// return : Finished normally STATUS_SUCCESS
// flag :
// global :
// =============================================================================
*/
static LONG PrvDecodeRequest(void)
{
LONG retValue;
USHORT wValue,wIndex,wLength;
retValue = STATUS_UNSUCCESSFUL;
while (1) {
if ((PrvRequest.bmRequestType & PRV_BMREQ_RECIPIENT_MASK) != PRV_RECIPIENT_INTERFACE) {
/* When it is not RECIPIENT_DEVICE */
break;
}
wValue = MAKEWORD(PrvRequest.wValue[0],PrvRequest.wValue[1]);
wIndex = MAKEWORD(PrvRequest.wIndex[0],PrvRequest.wIndex[1]);
wLength = MAKEWORD(PrvRequest.wLength[0],PrvRequest.wLength[1]);
if (PrvRequest.bRequest == PRV_BULKONLYRESET) {
/* Mass Storage Bulk Only Reset Command */
if ((PrvRequest.bmRequestType & PRV_BMREQ_DIR_MASK) != PRV_DIR_HOST_TO_DEVICE) {
/* When it is not OUT direction */
break;
}
if (wValue != 0) {
/* Case of parameter error */
break;
}
if (wIndex != PrvInterfaceNumber) {
/* Case of parameter error */
break;
}
if (wLength != 0) {
/* Case of parameter error */
break;
}
/* Reserve to do Control transfer */
retValue = USBD_FuncReserveControlTransfer();
if (retValue != STATUS_SUCCESS) {
/* Unable to reserve */
break;
}
/* Set status which means that Mass Storage Bulk Only Reset had been received */
SET_BIT(PrvBulkOnlyStatus,USBD_PROT_STORAGE_BULKONLYRESET);
/* Completed normally */
retValue = STATUS_SUCCESS;
}
else if
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -