📄 usbh_storage_if.c
字号:
}
/* Register the CALL BACK */
USBH_STRG_IFIntrqCompCBR[deviceNo] = pfnNotifyIntrqComp;
return STATUS_SUCCESS;
}
/*=============================================================================================
// Function_Name: USBH_STRG_IFUnregisterCBRIntrqComp
//
// description : Delete the CallBack for the completion of the asynchronous data transfer
//
// Delete 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_UNREGISTERED Not registered
===============================================================================================*/
LONG USBH_STRG_IFUnregisterCBRIntrqComp( USHORT deviceNo, CALLBACK_PROC pfnNotifyIntrqComp )
{
/* Check the registration of CALL BACK */
if(USBH_STRG_IFIntrqCompCBR[deviceNo] != pfnNotifyIntrqComp){
/* The CALL BACK is not registered */
return STATUS_UNREGISTERED;
}
/* Delete the CALL BACK */
USBH_STRG_IFIntrqCompCBR[deviceNo] = NULL;
return STATUS_SUCCESS;
}
/*=============================================================================================
// Function_Name: USBH_STRG_PutCmd
//
// description : Set the the specified SCSI command
//
// The specified SCSI command is set to the command block parameter.
//
// argument : deviceNo (in)Device No.
// *pCmdBlock (in)Pointer that points to the command parameter
// OpCode (in)command operation code
//
// return : STATUS_SUCCESS Completed successfully
// STATUS_UNSUCCESSFUL Completed with error
===============================================================================================*/
LONG USBH_STRG_PutCmd( USHORT deviceNo, DRIVEACCESS_FUNCCMDPARA *pCmdBlock, UCHAR opCode)
{
UCHAR i;
LONG result;
/* Command Block Initialize */
for(i=0; i < 12; i++){
pCmdBlock->commandBlock[i] = 0;
}
switch(opCode) {
case TEST_UNIT_READY:
pCmdBlock->commandBlock[0] = TEST_UNIT_READY;
pCmdBlock->commandBlock[1] = devicePara[deviceNo].lun << 5;
result = STATUS_SUCCESS;
break;
case REQUEST_SENSE:
pCmdBlock->commandBlock[0] = REQUEST_SENSE;
pCmdBlock->commandBlock[1] = devicePara[deviceNo].lun << 5;
pCmdBlock->commandBlock[4] = REQSENSE_LENGTH; /* get the 18bytes of SenseData */
result = STATUS_SUCCESS;
break;
case INQUIRY:
pCmdBlock->commandBlock[0] = INQUIRY;
pCmdBlock->commandBlock[1] = devicePara[deviceNo].lun << 5;
pCmdBlock->commandBlock[4] = INQUIRY_LENGTH; /* Get 36Byte Inquiry Data */
result = STATUS_SUCCESS;
break;
case READ_FORMAT_CAPACITY:
pCmdBlock->commandBlock[0] = READ_FORMAT_CAPACITY;
pCmdBlock->commandBlock[1] = devicePara[deviceNo].lun << 5;
pCmdBlock->commandBlock[8] = RDFORMCAPA_LENGTH; /* Allocation Length */
result = STATUS_SUCCESS;
break;
case READ_CAPACITY:
pCmdBlock->commandBlock[0] = READ_CAPACITY;
pCmdBlock->commandBlock[1] = devicePara[deviceNo].lun << 5;
result = STATUS_SUCCESS;
break;
default:
result = STATUS_UNSUCCESSFUL;
break;
}
return result;
}
/*=============================================================================================
// Function_Name: USBH_STRG_MakeStorageURB
//
// description : Create the BulkOnly Transport URB that corresponding to the device.
//
// Create URB that conrresponding to the device from the passed SCSI command block
//
// argument : deviceNo (in)Device No.
// transferMode (in)Transfer mode of the command
// *pCmdBlock (in)Pointer that points to the command parameter
// *pTranPara (in)Pointer that points to the data transfer parameter
// *pUrb (out)The pointer that points to the URB
//
// return : STATUS_SUCCESS Completed successfully
// STATUS_UNSUCCESSFUL Completed with error
===============================================================================================*/
LONG USBH_STRG_MakeStorageURB( USHORT deviceNo, UCHAR transferMode, DRIVEACCESS_FUNCCMDPARA *pCmdBlock, DRIVEACCESS_FUNCTRANPARA *pTranPara, USBH_USBD_URB *pUrb )
{
UCHAR i;
/* Generate CBW Data */
bulkCbw[deviceNo].tag++;
if(transferMode == FOR_HARD_DIRECTCOPY) {
/* Calculate the number of transfer and the direction of transfer from the Command Block when DirectCopy */
bulkCbw[deviceNo].transferLength = MAKEWORD(pCmdBlock->commandBlock[8], pCmdBlock->commandBlock[7]) * 512;
if(pCmdBlock->commandBlock[0] == READ10) {
bulkCbw[deviceNo].flag = CBW_IN;
}
else {
bulkCbw[deviceNo].flag = CBW_OUT;
}
} else {
bulkCbw[deviceNo].transferLength = pTranPara->dataSize;
if(pTranPara->direction == DRV_FUNC_IN) {
bulkCbw[deviceNo].flag = CBW_IN;
}
else {
bulkCbw[deviceNo].flag = CBW_OUT;
}
}
#ifndef LITTLE_ENDIAN_C
bulkCbw[deviceNo].transferLength = SWAP32(bulkCbw[deviceNo].transferLength);
#endif /* #ifndef LITTLE_ENDIAN_C */
bulkCbw[deviceNo].lun = devicePara[deviceNo].lun;
if(devicePara[deviceNo].commandMode == SCSI) {
/* SCSI Command */
switch(pCmdBlock->commandBlock[0]) {
case TEST_UNIT_READY:
bulkCbw[deviceNo].cbdLength = 6;
break;
case REQUEST_SENSE:
bulkCbw[deviceNo].cbdLength = 6;
break;
case INQUIRY:
bulkCbw[deviceNo].cbdLength = 6;
break;
case READ_FORMAT_CAPACITY:
bulkCbw[deviceNo].cbdLength = 10;
break;
case READ_CAPACITY:
bulkCbw[deviceNo].cbdLength = 10;
break;
case READ10:
bulkCbw[deviceNo].cbdLength = 10;
break;
case WRITE10:
bulkCbw[deviceNo].cbdLength = 10;
break;
default:
/* It doese not come here */
break;
}
} else {
/* ATAPI Command */
bulkCbw[deviceNo].cbdLength = 12;
}
for(i = 0; i < 12; i++) {
bulkCbw[deviceNo].cbd[i] = pCmdBlock->commandBlock[i];
}
/* Create CBW URB */
cbwUrb[deviceNo].pipe = (ULONG)USBH_USBD_SetPipeType(USBH_USBD_PIPE_BULK, devicePara[deviceNo].bulkOutEP , devicePara[deviceNo].devAdr, USBH_USBD_DIR_OUT);
cbwUrb[deviceNo].psNext = &dataUrb[deviceNo];
if(transferMode == FOR_HARD_DIRECTCOPY) {
cbwUrb[deviceNo].transFlag = USBH_HCD_URB_STRG_MODE | USBH_HCD_URB_DIRECT_COPY;
} else {
cbwUrb[deviceNo].transFlag = USBH_HCD_URB_STRG_MODE | USBH_HCD_URB_REQ_DMA;
}
cbwUrb[deviceNo].pTransBuf = &bulkCbw[deviceNo];
cbwUrb[deviceNo].transBufLength = CBW_LENGTH;
cbwUrb[deviceNo].pfnComplete = USBH_STRG_CBWCompCallback;
/* Create Data URB */
/* Process when there is no Data transfer */
if(bulkCbw[deviceNo].transferLength != 0x00000000) {
dataUrb[deviceNo].psNext = &cswUrb[deviceNo];
if(bulkCbw[deviceNo].flag == CBW_IN) {
dataUrb[deviceNo].pipe = (ULONG)USBH_USBD_SetPipeType(USBH_USBD_PIPE_BULK, devicePara[deviceNo].bulkInEP , devicePara[deviceNo].devAdr, USBH_USBD_DIR_IN);
} else {
dataUrb[deviceNo].pipe = (ULONG)USBH_USBD_SetPipeType(USBH_USBD_PIPE_BULK, devicePara[deviceNo].bulkOutEP , devicePara[deviceNo].devAdr, USBH_USBD_DIR_OUT);
}
dataUrb[deviceNo].transFlag = 0;
dataUrb[deviceNo].pTransBuf = (void *)pTranPara->dataPointer;
if(transferMode == FOR_HARD_DIRECTCOPY) {
/* The number of transfering is calculated from Command Block when DirectCopy */
dataUrb[deviceNo].transBufLength = MAKEWORD(pCmdBlock->commandBlock[8], pCmdBlock->commandBlock[7]) * 512;
} else {
dataUrb[deviceNo].transBufLength = pTranPara->dataSize;
}
dataUrb[deviceNo].pfnComplete = USBH_STRG_DataCompCallback;
} else {
cbwUrb[deviceNo].psNext = &cswUrb[deviceNo];
}
/* Create CSW URB */
cswUrb[deviceNo].pipe = (ULONG)USBH_USBD_SetPipeType(USBH_USBD_PIPE_BULK, devicePara[deviceNo].bulkInEP , devicePara[deviceNo].devAdr, USBH_USBD_DIR_IN);
cswUrb[deviceNo].transFlag = 0;
cswUrb[deviceNo].pTransBuf = &bulkCsw[deviceNo];
cswUrb[deviceNo].transBufLength = CSW_LENGTH;
cswUrb[deviceNo].pfnComplete = USBH_STRG_CSWCompCallback;
return STATUS_SUCCESS;
}
/*=============================================================================================
// Function_Name: USBH_STRG_MakeCtlURB
//
// description : Create URBof Control transfer
//
// Create the URB of the specified Control transfer
//
// argument : deviceNo (in)Device No.
// *pSetup (in)The pointer of the SETUP packet
// *pTranPara (in)Point of the Data transfer buffer
// *pUrb (out)Pointer that points to the URB
//
// return : STATUS_SUCCESS Completed successfully
// STATUS_UNSUCCESSFUL Completed with error
===============================================================================================*/
LONG USBH_STRG_MakeCtlURB( USHORT deviceNo, USBH_STRG_CTL_SETUP *pSetup, UCHAR *ptranData, USBH_USBD_URB *pUrb )
{
/* Create Setup Packet */
switch(pSetup->bmRequestType) {
case MASS_STORAGE_RESET:
pSetup->bRequest = 0xFF;
pSetup->wValue = 0x0000;
pSetup->wIndex = devicePara[deviceNo].interface;
pSetup->wLength = 0x0000;
break;
case GET_MAX_LUN:
pSetup->bRequest = 0xFE;
pSetup->wValue = 0x0000;
pSetup->wIndex = devicePara[deviceNo].interface;
pSetup->wLength = 0x0001;
break;
case CLEAR_FEATURE_EP:
pSetup->bRequest = 0x01;
pSetup->wValue = 0x0000;
pSetup->wLength = 0x0000;
break;
default:
break;
}
#ifndef LITTLE_ENDIAN_C
pSetup->wValue = SWAP16(pSetup->wValue);
pSetup->wIndex = SWAP16(pSetup->wIndex);
pSetup->wLength = SWAP16(pSetup->wLength);
#endif /* #ifndef LITTLE_ENDIAN_C */
/* Create URB */
pUrb->pipe = (ULONG)USBH_USBD_SetPipeType(USBH_USBD_PIPE_CONTROL, 0, devicePara[deviceNo].devAdr, USBH_USBD_DIR_IN);
pUrb->transFlag = USBH_HCD_URB_SHORT_NOT_OK;
pUrb->pSetupPacket = (UCHAR *)pSetup;
pUrb->pTransBuf = ptranData;
pUrb->transBufLength = pSetup->wLength;
pUrb->pfnComplete = USBH_STRG_CtlCompCallback;
return STATUS_SUCCESS;
}
/*=============================================================================================
// Function_Name: USBH_STRG_ResetRecovery
//
// description : Execute reset recovery of Bulk Only Transport Protocol
//
// The reset recovery is done to the specified device.
//
// argument : deviceNo (in)Device No.
//
// return : STATUS_SUCCESS Completed successfully
// STATUS_UNSUCCESSFUL Completed with error
===============================================================================================*/
LONG USBH_STRG_ResetRecovery( USHORT deviceNo )
{
LONG result;
USBH_USBD_URB *pUrb;
USBH_STRG_CTL_SETUP *pSetupData;
OS_FLGPTN flgPtn;
/* Issue Mass Storage Reset. */
pSetupData = &setupData[deviceNo];
pSetupData->bmRequestType = MASS_STORAGE_RESET;
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));
/* Execute ClearFeature of Bulk In EP */
pSetupData->bmRequestType = CLEAR_FEATURE_EP;
/* Specify EP */
pSetupData->wIndex = USBH_HCDS_GetPipeEndpointAdrs(cswUrb[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_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));
/* Execute ClearFeature of Bulk Out EP */
pSetupData->bmRequestType = CLEAR_FEATURE_EP;
/* Specify EP */
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_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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -