⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usbh_hcds_urb.c

📁 epson usb2.0 控制芯片 S1R72V05 固件程序。
💻 C
📖 第 1 页 / 共 2 页
字号:
// Function_Name: URBListEndpointSearchCancel
//
// description	: URB of Endpoint of the corresponding device is canceled from the URB list
//
//				  Corresponding URB is serched from the link list on passed USB device information structure
//				  and Endpoint address, and be canceled.
//
// argument 	: *psSearchList				(in)Pointer to URB list
//				  psRootDev					(in)Pointer of USB device information structure of route hub
//				  devNum					(in)USB device address
//				  epAddress					(in)Endpoint address(Direction+EP number)
//
// return		: None
===============================================================================================*/
Inline void URBListEndpointSearchCancel( USBH_HCD_LIST_HEAD *psSearchList, USBH_HCD_USBDEV *psRootDev,
											unsigned char devNum, unsigned char epAddress )
{
	USBH_HCD_URB *psUrb;
	USBH_HCD_LIST_HEAD *psListEnd, *psList;
	unsigned char usbAddress;
	unsigned long pipe;


	if( USBH_HCDS_ListEmpty(psSearchList) == 0 ){
		/* There is URB in Queuing */

		/*===================================================/
		Finish search if the first list header becomes the tail and reach there /
		/ because it is a link list 						 /
		/===================================================*/
		psListEnd = psSearchList;
		psList = psSearchList->psNext;
		do{
			psUrb = USBH_HCDS_ListEntry(psList, USBH_HCD_URB, sList);
			pipe = psUrb->pipe;

			usbAddress = USBH_HCDS_GetPipeUSBDevAdrs(pipe);
			if( usbAddress == devNum ){
				/* Corresponding USB device */

				pipe = psUrb->pipe;
				if( USBH_HCDS_GetPipeEndpointAdrs(pipe) == epAddress ){
					/* Corresponding Endpoint*/

					/*===============/
					Cancel process/
					/===============*/
					USBH_HCDS_URBUnlink(psUrb, psRootDev);

					/* Because connection situation of the list changes by the cancel process, return to the head */
					if( USBH_HCDS_ListEmpty(psSearchList) == 1 ){
						/* case of list empty */

						return;
					}
					psList = psSearchList;
				}
			}
			psList = psList->psNext;
		}while( psList != psListEnd );
	}
}

/*=============================================================================================
// Function_Name: URBTranCmpCallback
//
// description	: Callback process when URB is completed
//
//				  When URB is completed, it is called
//
// argument 	: chNum								(in)Channel number
//				  urbStatus							(in)URB status
//				  *pParam							(in)Pointer of URB structure
//
// return		: None
===============================================================================================*/
static long URBTranCmpCallback( unsigned long chNum, unsigned long urbStatus, void *pParam	)
{
	USBH_HCD_URB *psUrb;
	CH_INFO *psCHInfo;


	psUrb = pParam;

	/*============================/
	Delete from URB active queue/
	/============================*/
	psCHInfo = (CH_INFO *)psUrb->pHCPriv;
	if( (psCHInfo->chType == USBH_HCDS_CH_TYPE_CTRL) || (psCHInfo->chType == USBH_HCDS_CH_TYPE_BULK)
		|| (psCHInfo->chType == USBH_HCDS_CH_TYPE_STRG) ){

		USBH_HCDS_ListDel(&(psUrb->sList));
		psUrb->pHCPriv = NULL;

		/*==============================/
		Call the URB Completion callback /
		/==============================*/
		ExecURBCallback(psUrb, urbStatus);

		/* Check for queueing of URB */

		CheckQueuedURB(psCHInfo);
	} else {

		/*==============================/
		Call the URB Completion callback /
		/==============================*/
		ExecURBCallback(psUrb, urbStatus);
	}


	return STATUS_SUCCESS;
}

/*=============================================================================================
// Function_Name: CheckQueuedURB
//
// description	: Check the queueing URB
//
//				  Check the queueing URB of execution waiting, and execute it if existing.
//
// argument 	: *psUrb							(in)Pointer of URB structure
//
// return		: None

===============================================================================================*/
Inline void CheckQueuedURB( CH_INFO *psCHInfo )
{
	USBH_HCD_LIST_HEAD *psList;
	USBH_HCD_URB *psNextUrb;
	unsigned int skip, allocCH;
	unsigned char nextCHNum, chType;
	unsigned long fifoSize;
	long retValue;


	psList = NULL;		// Countermeasure against warning of optimizing
	chType = 0;			// Countermeasure against warning of optimizing

	allocCH = 0;

	if( psCHInfo->chType == USBH_HCDS_CH_TYPE_CTRL ){
		/* When channel used by control transfer is released */

		if( USBH_HCDS_ListEmpty(&(URBStatus.sCtrlURBList)) == 0 ){
			/* There is URB in queueing */

			psList = &(URBStatus.sCtrlURBList);
			allocCH = 1;
			chType = USBH_HCDS_CH_TYPE_CTRL;
		}
	} else if( psCHInfo->chType == USBH_HCDS_CH_TYPE_STRG ){
		/* When channel used by Bulk-Only transfer is released */

		if( USBH_HCDS_ListEmpty(&(URBStatus.sStrgURBList)) == 0 ){
			/* There is URB in queueing */

			psList = &(URBStatus.sStrgURBList);
			allocCH = 1;
			chType = USBH_HCDS_CH_TYPE_STRG;
		}
	} else {
		/* When channel used by Bulk-Only transfer is released */

		if( URBStatus.pendingAsyncSetupCount != 0 ){
			/* Synchronous transfer(Interrupt/Isochronous)setting is being reserved */

			skip = 0;
			if( USBH_HCDS_ListEmpty(&(URBStatus.sIsoURBList)) == 0 ){
				/* There is URB of Isochronous transfer in queueing */

				psList = &(URBStatus.sIsoURBList);
				allocCH = 1;
				chType = USBH_HCDS_CH_TYPE_ISO;
				URBStatus.pendingAsyncSetupCount--;	/* Update the synchronous transfer(Interrupt/Isochronous) setting reservation counter */
				skip = 1;
			}
			if( (skip == 0) && (USBH_HCDS_ListEmpty(&(URBStatus.sIntURBList)) == 0) ){
				/* There is URB of Interrupt transfer in queueing */

				psList = &(URBStatus.sIntURBList);
				allocCH = 1;
				chType = USBH_HCDS_CH_TYPE_INT;
				URBStatus.pendingAsyncSetupCount--;	/* Update the synchronous transfer(Interrupt/Isochronous) setting reservation counter */
			}
		}
		if( allocCH == 0 ){
			/* When the other allocated factor doesn't exist */

			if( USBH_HCDS_ListEmpty(&(URBStatus.sBulkURBList)) == 0 ){
				/* There is URB of Bulk transfer in queueing */

				psList = &(URBStatus.sBulkURBList);
				allocCH = 1;
				chType = USBH_HCDS_CH_TYPE_BULK;
			}
		}
	}
	if( allocCH != 0 ){
		psNextUrb = USBH_HCDS_ListEntry(psList->psNext, USBH_HCD_URB, sList);
		psCHInfo = (CH_INFO *)psNextUrb->pHCPriv;
		fifoSize = GetFIFOSize(psNextUrb, chType);
		retValue = USBH_HCDS_CHAlloc(&nextCHNum, chType, fifoSize);
		if( retValue == STATUS_SUCCESS ){
			/* Channel allocation success */

			/*=================/
			Channel information update /
			/=================*/
			psNextUrb->pHCPriv = &URBStatus.sCHInfo[nextCHNum];
			URBStatus.sCHInfo[nextCHNum].chNum = nextCHNum;
			URBStatus.sCHInfo[nextCHNum].chType = chType;

			/*==============================================================/
			Remove from the waiting queue, put into URB active queue, and execute the channel/
			/==============================================================*/
			USBH_HCDS_InterruptDisable();
			USBH_HCDS_ListDel(&(psNextUrb->sList));
			USBH_HCDS_ListAddTail(&(psNextUrb->sList), &(URBStatus.sActiveURBList));
			USBH_HCDS_InterruptEnable();
			USBH_HCDS_CHTranGo(psNextUrb, nextCHNum, URBTranCmpCallback);
		}
	}
}

/*=============================================================================================
// Function_Name: CheckStorageModeURB
//
// description	: URB parameter check at storage mode
//
//				  Check to see whether the URB structure at the storage mode is appropriate
//
// argument 	: *psUrb							(in)Pointer of URB structure
//
// return		: None
===============================================================================================*/
Inline long CheckStorageModeURB( USBH_HCD_URB *psUrb )
{
	USBH_HCD_URB *psCBWURB, *psCSWURB, *psDataURB;
	unsigned char *pCBWDataTransferLength;
	unsigned long dataLength;


	if( psUrb->psNext == NULL ){
		/* CSW doesn't exsit */

		return STATUS_INVALID_PARAMETER;
	}
	psCBWURB = psUrb;

	if( psCBWURB->psNext->psNext == NULL ){
		/* CBW + CSW */

		psCSWURB = psUrb->psNext;
		psDataURB = NULL;
	} else {
		/* CBW + DATA + CSW */

		psDataURB = psUrb->psNext;
		psCSWURB = psDataURB->psNext;
		if( psCSWURB->psNext != NULL ){
			/* Unnecessary URB is connected */

			return STATUS_INVALID_PARAMETER;
		}
	}

	if( psCBWURB->transBufLength != BO_CBW_SIZE ){
		/* Differ from the data size of CBW */

		return STATUS_INVALID_PARAMETER;
	}

	if( USBH_HCDS_GetPipeType(psCBWURB->pipe) != USBH_HCD_PIPE_BULK ){
		/* Excluding the pipe for the Bulk transfer */

		return STATUS_INVALID_PARAMETER;
	}

	if( USBH_HCDS_CheckPipeIN(psCBWURB->pipe) != 0 ){
		/* Endpoint of IN direction */

		return STATUS_INVALID_PARAMETER;
	}

	pCBWDataTransferLength = psCBWURB->pTransBuf;
	dataLength = pCBWDataTransferLength[OFFSET_BO_CBW_DATA_LENGTH];
	dataLength |= (pCBWDataTransferLength[OFFSET_BO_CBW_DATA_LENGTH + 1] << 8) & 0x0000FF00;
	dataLength |= (pCBWDataTransferLength[OFFSET_BO_CBW_DATA_LENGTH + 2] << 16) & 0x00FF0000;
	dataLength |= (pCBWDataTransferLength[OFFSET_BO_CBW_DATA_LENGTH + 3] << 24) & 0xFF000000;
	if( dataLength == 0 ){

		if( psDataURB != NULL ){
			/* There should be no URB for Data, but there is */

			return STATUS_INVALID_PARAMETER;
		}
	} else {
		if( psDataURB == NULL ){
			/* There should be URB for Data, but there isn't */

			return STATUS_INVALID_PARAMETER;
		}
	}


	if( psCSWURB->transBufLength != BO_CSW_SIZE ){
		/* Differ from the data size of CSW */

		return STATUS_INVALID_PARAMETER;
	}

	if( psCSWURB->pTransBuf == NULL ){
		/* The pointer in the data buffer of CSW is NULL */

		return STATUS_INVALID_PARAMETER;
	}

	if( USBH_HCDS_GetPipeType(psCSWURB->pipe) != USBH_HCD_PIPE_BULK ){
		/* Excluding the pipe for the Bulk transfer */

		return STATUS_INVALID_PARAMETER;
	}

	if( USBH_HCDS_CheckPipeOUT(psCSWURB->pipe) != 0 ){
		/* Endpoint of OUT direction */

		return STATUS_INVALID_PARAMETER;
	}

	if( psDataURB != NULL ){
		/* When there is data URB */

		if( USBH_HCDS_GetPipeType(psDataURB->pipe) != USBH_HCD_PIPE_BULK ){
			/* Excluding the pipe for the Bulk transfer */

			return STATUS_INVALID_PARAMETER;
		}

		if( psDataURB->transBufLength != 0 ){
			/* Transfer data length is except 0*/

			if( psDataURB->pTransBuf == NULL && (psCBWURB->transFlag & USBH_HCD_URB_DIRECT_COPY) == 0 ){
				/* The pointer in the data buffer of Data is NULL excluding a direct copy */

				return STATUS_INVALID_PARAMETER;
			}
		}
	}
	return STATUS_SUCCESS;
}

/*=============================================================================================
// Function_Name: NotifyStatusChanged
//
// description	: Status change notification of virtual route hub
//
//				  The status of hub/port of the virtual route hub is notified when changed
//
// argument 	: param0							(in)Not used
//				  param1							(in)Not used
//				  *pParam							(in)Not used
//
// return		: None

===============================================================================================*/
long NotifyStatusChanged( unsigned long param0, unsigned long param1, void *pParam )
{
	unsigned long vhubStatus;


	vhubStatus = param0;

	if( (vhubStatus & USBH_HCDS_VHUB_HUB_STATUS) != 0 ){
		*((UCHAR *)URBStatus.psRootIntUrb->pTransBuf) = HUB_BIT;
	}
	if( (vhubStatus & USBH_HCDS_VHUB_PORT_STATUS) != 0 ){
		*((UCHAR *)URBStatus.psRootIntUrb->pTransBuf) = HUB_PORT_BIT;
	}

	if( vhubStatus != 0 ){
		/*=====================================================/
		The port status changing is notified with Interrupt IN of the route hub/
		/=====================================================*/
		ExecURBCallback(URBStatus.psRootIntUrb, USBH_HCD_URBSTS_SUCCESS);
	}

	return STATUS_SUCCESS;
}

/*=============================================================================================
// Function_Name: ExecURBCallback
//
// description	: URB completion callback processing
//
//				  The completion callback function of URB is called
//
// argument 	: *psUrb							(in)Pointer of URB structure
//				  usbStatus							(in)URB status
//
// return		: None
===============================================================================================*/
Inline void ExecURBCallback( USBH_HCD_URB *psUrb, unsigned long urbStatus )
{
	USBH_HCD_URB *psExecUrb;

	psExecUrb = psUrb;

	if( psUrb->transFlag & USBH_HCD_URB_STRG_MODE ){
		/* When the Bulk-Only support function of Mass Storage Class is used */

		if( urbStatus == USBH_HCD_URBSTS_SUCCESS ){
			/* All URB terminated successfully	*/

			while(1){
				if( psExecUrb->psNext == NULL ){
					break;
				}
				psExecUrb = psExecUrb->psNext;
			}
		} else {
			while(1){
				if( psExecUrb->status != USBH_HCD_URBSTS_SUCCESS ){
					/* URB structure be found when terminated unsuccessfully */

					break;
				}
				/* For URB list check Next when URB terminated abnormally, changed in order to not check the NULL */
				if( psExecUrb->psNext == NULL ){
					break;
				}
				psExecUrb = psExecUrb->psNext;
			}
		}
	}


	/*=========================/
	Call the completion callback /
	/=========================*/
	if( psExecUrb->status != USBH_HCD_URBSTS_NOENT ){
		/* The callback is called excluding the cancellation by USBH_HCD_UnlinkURB(). */

		if( psExecUrb->pfnComplete != NULL ){
			/* When the callback function is registered */

			/* The callback function is called. (URB passed as argument is a pointer of the URB structure
			 passed with USBH_HCD_SubmitURB(). ) */
			(psExecUrb->pfnComplete)(psUrb);
		}
	}
}

/*=============================================================================================
// Function_Name: GetFIFOSize
//
// description	: Returned the allocated FIFO size
//
//				  Return the FIFO size allocated by the passed channel type
//
// argument 	: *psUrb							(in)Pointer of URB structure
//				  chType							(in)Channel type
//
// return		: None
===============================================================================================*/
Inline unsigned long GetFIFOSize( USBH_HCD_URB *psUrb, unsigned char chType )
{
	unsigned long fifoSize;

	USBH_HCDS_GetPipeMaxPacketSize(psUrb->psDev, psUrb->pipe, fifoSize);
	switch( chType ){
		case USBH_HCDS_CH_TYPE_BULK:
		case USBH_HCDS_CH_TYPE_STRG:
			/* Use Double Buffer in Bulk or Storage transfer */

			fifoSize *= 2;
			break;
		default:
			/* Use Single Buffer excluding Bulk and Storage transfer */
			;
	}
	return fifoSize;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -