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

📄 usbtarglib.c

📁 This the USB source code for vxworks5.5. It has OSS library source code and also the complete targ
💻 C
📖 第 1 页 / 共 5 页
字号:
    /* This request isn't supported unless the target application has     * provided a statusGet handler.     */    if (pTcd->pCallbacks->statusGet == NULL)	return ERROR;    if ((*pTcd->pCallbacks->statusGet)	(pTcd->callbackParam, pTcd->targChannel,	pSetup->requestType, index, 	min (length, sizeof (pTcd->dataBfr)), pTcd->dataBfr, 	&actLen) != OK)	{	return ERROR;	}    /* Transmit the descriptor back to the host */    return initDataErpForResponse (pTcd, actLen);    }/***************************************************************************** requestSetAddress - processes a SET_ADDRESS setup packet** RETURNS: OK if setup packet valid, else ERROR if invalid*/LOCAL STATUS requestSetAddress    (    pTARG_TCD pTcd,    pUSB_SETUP pSetup    )    {    UINT16 deviceAddress = FROM_LITTLEW (pSetup->value);    /* If the target application has provided a SetAddress callback,     * then invoke it now.     */    if (pTcd->pCallbacks->addressSet != NULL)	(*pTcd->pCallbacks->addressSet)	    (pTcd->callbackParam, pTcd->targChannel, deviceAddress);    /* The new address goes into effect after the Status phase, if any. */    pTcd->deviceAddress = deviceAddress;    usbTcdAddressSet (&pTcd->tcdNexus, pTcd->deviceAddress);    return initStatusErp (pTcd, USB_PID_IN);    }/***************************************************************************** requestGetSynchFrame - processes a GET_SYNCH_FRAME setup packet** RETURNS: OK if setup packet valid, else ERROR if invalid*/LOCAL STATUS requestGetSynchFrame    (    pTARG_TCD pTcd,    pUSB_SETUP pSetup    )    {    UINT16 endpoint = FROM_LITTLEW (pSetup->index);    /* This request isn't supported unless the target application has     * provided a synchFrameGet handler.     */    if (pTcd->pCallbacks->synchFrameGet == NULL)	return ERROR;    /* Get the synch frame from the target application. */    if ((*pTcd->pCallbacks->synchFrameGet)	(pTcd->callbackParam, pTcd->targChannel, 	endpoint, (pUINT16) pTcd->dataBfr) != OK)	return ERROR;    /* Transmit the synch frame back to the host */    return initDataErpForResponse (pTcd, sizeof (UINT16));    }/***************************************************************************** requestVendorSpecific - processes a "vendor specific" setup packet** RETURNS: OK if setup packet valid, else ERROR if invalid*/LOCAL STATUS requestVendorSpecific    (    pTARG_TCD pTcd,    pUSB_SETUP pSetup    )    {    /* This request isn't supported unless the target application has     * provided a vendorSpecific handler.     */    if (pTcd->pCallbacks->vendorSpecific == NULL)	return ERROR;    return (*pTcd->pCallbacks->vendorSpecific) 	(pTcd->callbackParam, pTcd->targChannel, 	pSetup->requestType, pSetup->request, FROM_LITTLEW (pSetup->value),	FROM_LITTLEW (pSetup->index), FROM_LITTLEW (pSetup->length));    }/***************************************************************************** parseSetupPacket - parse/execute a control pipe request** The TARGET.setupBfr should contain a setup packet.  Validate it.  If* valid, parse and execute it.** RETURNS: OK if setup packet valid, else ERROR if invalid*/LOCAL STATUS parseSetupPacket    (    pTARG_TCD pTcd    )    {    pUSB_SETUP pSetup;    /* Validate the setup packet */    if (pTcd->setupErp.bfrList [0].actLen != sizeof (USB_SETUP))	return ERROR;    pSetup = (pUSB_SETUP) pTcd->setupBfr;    /* Execute based on the type of request. */    if ((pSetup->requestType & USB_RT_CATEGORY_MASK) == USB_RT_STANDARD)	{	switch (pSetup->request)	    {	    case USB_REQ_CLEAR_FEATURE:		return requestClearFeature (pTcd, pSetup);	    case USB_REQ_SET_FEATURE:		return requestSetFeature (pTcd, pSetup);	    case USB_REQ_GET_CONFIGURATION:		return requestGetConfiguration (pTcd, pSetup);	    case USB_REQ_SET_CONFIGURATION:		return requestSetConfiguration (pTcd, pSetup);	    case USB_REQ_GET_DESCRIPTOR:		return requestGetDescriptor (pTcd, pSetup);	    case USB_REQ_SET_DESCRIPTOR:		return requestSetDescriptor (pTcd, pSetup);	    case USB_REQ_GET_INTERFACE:		return requestGetInterface (pTcd, pSetup);	    case USB_REQ_SET_INTERFACE:		return requestSetInterface (pTcd, pSetup);	    case USB_REQ_GET_STATUS:		return requestGetStatus (pTcd, pSetup);	    case USB_REQ_SET_ADDRESS:		return requestSetAddress (pTcd, pSetup);	    case USB_REQ_GET_SYNCH_FRAME:		return requestGetSynchFrame (pTcd, pSetup);	    default:		break;	    }	}    return requestVendorSpecific (pTcd, pSetup);    }/***************************************************************************** setupErpCallback - invoked when Setup ERP completes** This function receives control when a Setup ERP completes.  Examines the* reason for completion, possibly invoking additional control request* handling.** RETURNS: N/A*/LOCAL VOID setupErpCallback    (    pVOID p			    /* ptr to ERP */    )    {    pUSB_ERP pErp = (pUSB_ERP) p;    pTARG_TCD pTcd = (pTARG_TCD) pErp->userPtr;    pTcd->setupErpPending = FALSE;    /* Completion of a setup ERP, whether successful or not, implies that     * any previous control pipe request must be terminated. */    if (pTcd->dataErpPending)	cancelErp ((pTARG_PIPE) pTcd->dataErp.targPtr, &pTcd->dataErp);    if (pTcd->statusErpPending)	cancelErp ((pTARG_PIPE) pTcd->dataErp.targPtr, &pTcd->statusErp);    /* Was the ERP successful? */    if (pErp->result == OK)	{	/* The ERP was successful.  Parse the setup packet. */	if (parseSetupPacket (pTcd) == OK)	    {	    /* The packet can be parsed successfully.  Other code will	     * take care of resubmitting the Setup ERP, so we do nothing.	     */	    return;	    }	else	    {	    /* We cannot process the indicated command.  Stall the	     * control pipe.	     */	    usbTargPipeStatusSet (pTcd->targChannel, pTcd->controlPipe,		TCD_ENDPOINT_STALL);	    }	}    /* Re-submit the ERP unless it was canceled - which indicates that     * the pipe is probably being torn down.     */    if (pErp->result != S_usbTcdLib_ERP_CANCELED)	initSetupErp (pTcd);    }/***************************************************************************** responseErpCallback - invoked when control pipe response ERP completes** This function receives control after the data IN phase of a control pipe* request has completed.** RETURNS: N/A*/LOCAL VOID responseErpCallback    (    pVOID p			    /* ptr to ERP */    )    {    pUSB_ERP pErp = (pUSB_ERP) p;    pTARG_TCD pTcd = (pTARG_TCD) pErp->userPtr;    pTcd->dataErpPending = FALSE;    /* If the ERP was successful, then we prepare the status phase.  The     * status phase is always in the oppposite direction to the data phase.     * Since this callback handles only "responses" (from device to host),     * then the status phase will always be an OUT (from host to device).     *     * If the data phase failed for some reason other than being canceled,     * then we resubmit the Setup phase ERP to ensure that the target     * continues to be responsive on the control pipe.     */    if (pErp->result == OK)	{	initStatusErp (pTcd, USB_PID_OUT);	return;	}    if (pErp->result != S_usbTcdLib_ERP_CANCELED)	initSetupErp (pTcd);    }/***************************************************************************** statusErpCallback - invoked when control pipe status packet completes** This function receives control after the status phase of a control pipe* request has completed.** RETURNS: N/A*/LOCAL VOID statusErpCallback    (    pVOID p			    /* ptr to ERP */    )    {    pUSB_ERP pErp = (pUSB_ERP) p;    pTARG_TCD pTcd = (pTARG_TCD) pErp->userPtr;    pTcd->statusErpPending = FALSE;    /* Re-submit the Setup ERP. */    if (pErp->result != S_usbTcdLib_ERP_CANCELED)	initSetupErp (pTcd);    }/***************************************************************************** usbTargManagementCallback - invoked when TCD detects management event** This function is invoked by a TCD when the TCD detects a "management"* event on a target channel.  Examples of management events include* bus resets, detection of a new or lost connection, etc.** RETURNS: N/A*/LOCAL VOID usbTargManagementCallback    (    pVOID mngmtCallbackParam,	    /* caller-defined param */    TCD_HANDLE handle,		    /* channel */    UINT16 mngmtCode		    /* management code */    )    {    pTARG_TCD pTcd = (pTARG_TCD) mngmtCallbackParam;    switch (mngmtCode)	{	case TCD_MNGMT_VBUS_LOST:	case TCD_MNGMT_BUS_RESET:	    /* Reset the device configuration to the power-on state. */	    pTcd->deviceAddress = 0;	    /* code falls through into following case */	case TCD_MNGMT_VBUS_DETECT:	case TCD_MNGMT_SUSPEND:	case TCD_MNGMT_RESUME:	    /* reflect the management event to the target application */	    mngmtFunc (pTcd, mngmtCode);	    break;	}    }/***************************************************************************** usbTargErpCallback - invoked when ERP completes** The TCD invokes this callback when an ERP completes.	This gives us the* opportunity to monitor ERP execution.  We reflect the callback to the* calling application after we finish our processing.** NOTE: By convention, the targPtr field of the ERP has been initialized* to point to the TARG_PIPE for this ERP.** RETURNS: N/A*/LOCAL VOID usbTargErpCallback    (    pVOID p			    /* ptr to ERP */    )    {    pUSB_ERP pErp = (pUSB_ERP) p;    pTARG_PIPE pPipe = (pTARG_PIPE) pErp->targPtr;    UINT16 packets;    UINT16 i;    OSS_MUTEX_TAKE (targMutex, OSS_BLOCK);    /* Unlink the ERP */    usbListUnlink (&pErp->targLink);    /* Check if this ERP is being deleted.  If so, let the foreground     * thread know the callback has been invoked.     */    if (pErp == pPipe->erpBeingDeleted)	pPipe->erpDeleted = TRUE;    /* Update data toggle for pipe.  Control and isochronous transfers     * always begin with DATA0, which is set at pipe initialization -     * so we don't change it here.  Bulk and interrupt pipes alternate     * between DATA0 and DATA1, and we need to keep a running track of     * the state across ERPs.     */    if (pErp->transferType == USB_XFRTYPE_INTERRUPT ||	pErp->transferType == USB_XFRTYPE_BULK)	{	/* Calculate the number of packets exchanged to determine the	 * next data toggle value.  If the count of packets is odd, then	 * the data toggle needs to switch.	 *	 * NOTE: If the ERP is successful, then at least one packet MUST	 * have been transferred.  However, it may have been a 0-length	 * packet.  This case is handled after the following "for" loop.	 */	packets = 0;	for (i = 0; i < pErp->bfrCount; i++)	    {	    packets += 		(pErp->bfrList [i].actLen + pPipe->pEndpoint->maxPacketSize - 1) /		pPipe->pEndpoint->maxPacketSize;	    }	if (pErp->result == OK)	    packets = max (packets, 1);	if ((packets & 1) != 0)	    pPipe->dataToggle = (pPipe->dataToggle == USB_DATA0) ?		USB_DATA1 : USB_DATA0;	}    /* Invoke the user's callback routine */    if (pErp->userCallback != NULL)	(*pErp->userCallback) (pErp);    OSS_MUTEX_RELEASE (targMutex);    }/***************************************************************************** usbTargVersionGet - Retrieve usbTargLib version** This function returns the usbTargLib version.  If <pVersion> is not NULL, the * usbTargLib returns its version in BCD in <pVersion>.	For example, version * "1.02" would be coded as 01h in the high byte and 02h in the low byte.** If <pMfg> is not NULL it must point to a buffer of at least USBT_NAME_LEN * bytes in length in which the USBD will store the NULL terminated name of* the usbTargLib manufacturer (e.g., "Wind River Systems" + \0).** RETURNS: OK*/ STATUS usbTargVersionGet    (    pUINT16 pVersion,			/* usbTargLib version */    pCHAR pMfg				/* usbTargLib manufacturer */    )    {    /* return version info */    if (pVersion != NULL)	*pVersion = TARG_VERSION;    if (pMfg != NULL)	strncpy (pMfg, TARG_MFG, USBT_NAME_LEN);    return OK;    }/***************************************************************************

⌨️ 快捷键说明

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