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

📄 usbtarglib.c

📁 This the USB source code for vxworks5.5. It has OSS library source code and also the complete targ
💻 C
📖 第 1 页 / 共 5 页
字号:
    pUSB_TARG_PIPE pPipeHandle		/* returned pipe handle */    )    {    pTARG_TCD pTcd;    pUSB_TARG_ENDPOINT_INFO pEndpoint = NULL;    pUSB_TARG_ENDPOINT_INFO pEndpoint2 = NULL;    pTARG_PIPE pPipe = NULL;    UINT16 direction2 = NULL;    STATUS status;    UINT16 i;    OSS_MUTEX_TAKE (targMutex, OSS_BLOCK);    /* Validate parameters */    if (pPipeHandle == NULL)	status = S_usbTargLib_BAD_PARAM;    else	status = validateTarg (targChannel, &pTcd);    if (transferType == USB_XFRTYPE_CONTROL)	{	/* Must validate both endpoints.  pEndpointId must be OUT endpoint	 * and pEndpointId2 must be IN endpoint.	 */	direction = USB_DIR_OUT;	direction2 = USB_DIR_IN;	if ((status = validateEndpoint (pTcd, endpointId, USB_XFRTYPE_CONTROL,	    direction, &pEndpoint)) == OK)	    {	    status = validateEndpoint (pTcd, endpointId2, USB_XFRTYPE_CONTROL,		direction2, &pEndpoint2);	    }	}    else	{	/* Validate only the first endpointId. */	status = validateEndpoint (pTcd, endpointId, transferType,	    direction, &pEndpoint);	}    if (status == OK)	{	/* See if the requested endpoint number is valid */	if (endpointNum > USB_MAX_ENDPOINT_NUM)	    status = S_usbTargLib_BAD_PARAM;	}    if (status == OK)	{	/* See if the endpointNum is in use (for the same direction) */	for (i = 0; i < pTcd->numEndpoints; i++)	    {	    if ((pTcd->pEndpoints [i].flags & TCD_ENDPOINT_IN_USE) != 0 &&		pTcd->pEndpoints [i].direction == direction &&		pTcd->pEndpoints [i].endpointNum == endpointNum)		{		status = S_usbTargLib_ENDPOINT_IN_USE;		break;		}	    }	}    if (status == OK)	{	/* All of the parameters check out OK.	Create a pipe to manage	 * this endpoint. */	if ((pPipe = OSS_CALLOC (sizeof (*pPipe))) == NULL)	    status = S_usbTargLib_OUT_OF_MEMORY;	else	    {	    /* Initialize pipe */	    pPipe->pTcd = pTcd;	    pPipe->configuration = configuration;	    pPipe->interface = interface;	    pPipe->dataToggle = USB_DATA0;	    if (usbHandleCreate (TARG_PIPE_SIG, pPipe, &pPipe->pipeHandle) != OK)		status = S_usbTargLib_OUT_OF_RESOURCES;	    }	}    if (status == OK)	{	/* Ask the TCD to assign endpointId to the pipe. */	if (usbTcdEndpointAssign (&pTcd->tcdNexus, endpointId, endpointNum,	    configuration, interface, transferType, direction) != OK)	    status = S_usbTargLib_TCD_FAULT;	else	    pPipe->pEndpoint = pEndpoint;	}    if (status == OK && pEndpoint2 != NULL)	{	/* Ask the TCD to assign endpointId2 to the pipe. */	if (usbTcdEndpointAssign (&pTcd->tcdNexus, endpointId2, endpointNum,	    configuration, interface, transferType, direction2) != OK)	    status = S_usbTargLib_TCD_FAULT;	else	    pPipe->pEndpoint2 = pEndpoint2;	}    /* If we failed to create the pipe, release any partially created pipe.     * Otherwise, link the pipe to the list of pipes on this target channel. */    if (status != OK)	destroyPipe (pPipe);    else	{	usbListLink (&pTcd->pipes, pPipe, &pPipe->pipeLink, LINK_TAIL);		*pPipeHandle = pPipe->pipeHandle;	}    OSS_MUTEX_RELEASE (targMutex);    return ossStatus (status);    }/***************************************************************************** usbTargPipeDestroy - Destroys an endpoint pipe** This function tears down a pipe previously created by calling* usbTargPipeCreate().	Any pending transfers on the pipe are canceled* and all resources allocated to the pipe are released.** RETURNS: OK, or ERROR if unable to destroy pipe.*/STATUS usbTargPipeDestroy    (    USB_TARG_PIPE pipeHandle		/* pipe to be destroyed */    )    {    pTARG_PIPE pPipe;    STATUS status;    OSS_MUTEX_TAKE (targMutex, OSS_BLOCK);    /* Validate parameters */    if ((status = validatePipe (pipeHandle, &pPipe)) == OK)	{	/* Destroy pipe */	destroyPipe (pPipe);	}    OSS_MUTEX_RELEASE (targMutex);    return status;    }/***************************************************************************** usbTargTransfer - Submits a USB_ERP for transfer through a pipe** A client uses this function to initiate an transfer on the pipe indicated * by <pipeHandle>.  The transfer is described by an ERP, or endpoint request * packet, which must be allocated and initialized by the caller prior to * invoking usbdTargTransfer().** The USB_ERP structure is defined in usb.h as:** .CS* typedef struct usb_bfr_list*     {*     UINT16 pid;*     pUINT8 pBfr;*     UINT32 bfrLen;*     UINT32 actLen;*     } USB_BFR_LIST;** typedef struct usb_erp*     {*     LINK targLink;		    // used by usbTargLib*     pVOID targPtr;		    // used by usbTargLib*     LINK tcdLink;		    // used by TCD*     pVOID tcdPtr;		    // used by TCD*     pVOID userPtr;	*     UINT16 erpLen;		    *     int result;		    // returned by usbTargLib/TCD*     ERP_CALLBACK targCallback;    // used by usbTargLib*     ERP_CALLBACK userCallback;*     UINT16 endpointId;	    // filled in by usbTargLib*     UINT16 transferType;	    // filled in by usbTargLib*     UINT16 dataToggle;	    // filled in by usbTargLib*     UINT16 bfrCount;	    *     USB_BFR_LIST bfrList [1];*     } USB_ERP, *pUSB_ERP;* .CE** The length of the USB_ERP structure must be stored in <erpLen> and varies * depending on the number of <bfrList> elements allocated at the end of the * structure.  By default, the default structure contains a single <bfrList>* element, but clients may allocate a longer structure to accommodate a larger * number of <bfrList> elements.  ** <endpointId> and <transferType> are filled in automatically * by the usbTargLib using values recorded when the pipe was created.  ** <dataToggle> is filled in automatically except for control pipes.  For these* pipes, the caller is required to store the next data toggle as USB_DATA0* or USB_DATA1.  The Setup packet is always a DATA0.  The first packet of the* data phase is always DATA1, with data packets alternating thereafter, and * the Status phase packet is always DATA1.  When using the functions* usbTargLibResponseSend() and usbTargLibPayloadRcv(), usbTargLib handles the* <dataToggle> value automatically.** <bfrList> is an array of buffer descriptors which describe data buffers to * be associated with this ERP.	If more than the one <bfrList> element is * required then the caller must allocate the ERP by calculating the size as ** .CS* erpLen = sizeof (USB_ERP) + (sizeof (USB_BFR_DESCR) * (bfrCount - 1))* .CE** <pid> specifies the packet type to use for the indicated buffer and is* specified as USB_PID_xxxx.  Note that packet types are specified from the* perspective of the host.  For example, USB_PID_IN indicates a transfer from* the device (target) to the host.** The ERP <userCallback> routine must point to a client-supplied ERP_CALLBACK* routine.  The usbdTargTransfer() function returns as soon as the ERP has been* successfully enqueued.  If there is a failure in delivering the ERP to the* TCD, then usbdTargTransfer() returns an error.  The actual result of the ERP* should be checked after the <userCallback> routine has been invoked.** RETURNS: OK, or ERROR if unable to submit USB_ERP for execution** ERRNO:*   S_usbTargLib_BAD_PARAM*   S_usbTargLib_TCD_FAULT*/STATUS usbTargTransfer    (    USB_TARG_PIPE pipeHandle,		/* pipe for transfer */    pUSB_ERP pErp			/* ERP describing transfer */    )    {    pTARG_PIPE pPipe;    STATUS status;    OSS_MUTEX_TAKE (targMutex, OSS_BLOCK);    /* Validate parameters */    if (pErp == NULL)	status = S_usbTargLib_BAD_PARAM;    else if ((status = validatePipe (pipeHandle, &pPipe)) == OK)	{	/* Fill in fields in ERP. */	pErp->targPtr = pPipe;	pErp->targCallback = usbTargErpCallback;	pErp->transferType = pPipe->pEndpoint->transferType;	/* If this is a control pipe and with a direction of USB_PID_IN,	 * then use the second endpoint for the pipe.	 */	if (pErp->transferType == USB_XFRTYPE_CONTROL &&	    pErp->bfrList [0].pid == USB_PID_IN)	    pErp->endpointId = pPipe->pEndpoint2->endpointId;	else	    pErp->endpointId = pPipe->pEndpoint->endpointId;	/* The caller must specify DATA0/DATA1 for control pipes */	if (pErp->transferType != USB_XFRTYPE_CONTROL)	    pErp->dataToggle = pPipe->dataToggle;	usbListLink (&pPipe->erps, pErp, &pErp->targLink, LINK_HEAD);	/* Submit ERP to TCD */	if (usbTcdErpSubmit (&pPipe->pTcd->tcdNexus, pErp) != OK)	    {	    status = S_usbTargLib_TCD_FAULT;	    usbListUnlink (&pErp->targLink);	    }	}    OSS_MUTEX_RELEASE (targMutex);    return ossStatus (status);    }/***************************************************************************** usbTargTransferAbort - Cancels a previously submitted USB_ERP** This function aborts an ERP which was previously submitted through* a call to usbdTargTransfer().  ** RETURNS: OK, or ERROR if unable to cancel USB_ERP** ERRNO:*   S_usbTargLib_BAD_PARAM*/STATUS usbTargTransferAbort    (    USB_TARG_PIPE pipeHandle,		/* pipe for transfer to abort */    pUSB_ERP pErp			/* ERP to be aborted */    )    {    pTARG_PIPE pPipe;    STATUS status;    OSS_MUTEX_TAKE (targMutex, OSS_BLOCK);    /* Validate parameters */    if (pErp == NULL)	status = S_usbTargLib_BAD_PARAM;    else if ((status = validatePipe (pipeHandle, &pPipe)) == OK)	{	/* cancel the ERP */	status = cancelErp (pPipe, pErp);	}    OSS_MUTEX_RELEASE (targMutex);    return ossStatus (status);    }/***************************************************************************** usbTargControlResponseSend - Sends a response on the control pipe** usbTargLib automatically creates a pipe to manage communication on the* default control endpoint (#0) defined by the USB.  Certain application* callbacks (e.g., the USB_TARG_VENDOR_SPECIFIC callback) may need to* formulate a response and send it to the host.  This function allows a* caller to respond to a host control pipe request.** There are two kinds of responses, those that involve a data phase and* those that do not.  This function may be used to handle both types.  If* a data phase is required, the caller passes a non-NULL <pBfr> for the * usbTargTransfer() function.  The usbTargControlResponseSend() function* sends the data described by the USB_ERP and then automatically* accepts the "status phase" transfer sent the by the host to acknowledge* the transfer.  If there is no data phase, the <pBfr> parameter should be* NULL, in which case usbTargLib generates just the Status phase* automatically.** The contents of the <pBfr> passed by the caller are copied into a * private usbTargLib buffer.  <bfrLen> must not exceed USB_MAX_DESCR_LEN.** This function returns as soon as the transfer is enqueued.  ** RETURNS: OK, or ERROR if unable to submit response to host.** ERRNO:*   S_usbTargLib_GENERAL_FAULT*   S_usbTargLib_BAD_PARAM*/STATUS usbTargControlResponseSend    (    USB_TARG_CHANNEL targChannel,	/* target channel */    UINT16 bfrLen,			/* length of response, or 0 */    pUINT8 pBfr 			/* ptr to bfr or NULL */    )    {    pTARG_TCD pTcd;    STATUS status;    OSS_MUTEX_TAKE (targMutex, OSS_BLOCK);    /* Validate parameters */    if ((status = validateTarg (targChannel, &pTcd)) == OK)	{	/* If <pErp> is NULL, then just do a Status packet.  Otherwise,	 * submit the caller's ERP. 	 */	if (pBfr == NULL)	    {	    if (initStatusErp (pTcd, USB_PID_IN) != OK)		status = S_usbTargLib_GENERAL_FAULT;	    }	else	    {	    /* Transfer the caller's data. */	    if (bfrLen > sizeof (pTcd->dataBfr))		status = S_usbTargLib_BAD_PARAM;	    else		{		memcpy (pTcd->dataBfr, pBfr, bfrLen);		if (initDataErpForResponse (pTcd, bfrLen) != OK)		    status = S_usbTargLib_GENERAL_FAULT;		}	    }	}        OSS_MUTEX_RELEASE (targMutex);    return ossStatus (status);    }/***************************************************************************** usbTargControlPayloadRcv - Receives data on the default control pipe** usbTargLib automatically creates a pipe to manage communication on the* default control pipe (#0) defined by the USB.  Certain application* callbacks (e.g., USB_TARG_VENDOR_SPECIFIC or USB_TARG_DESCRIPTOR_SET)* may need to receive additional data on the control OUT endpoint in order* to complete processing of the control pipe request.  This function allows* a caller to receive data on a control pipe.** The <pErp> parameter must point to an ERP which will receive the* additional data. ** This function returns as soon as the USB_ERP is enqueued.  Completion of* the USB_ERP is indicated when the ERP's callback is invoked.	After the* ERP completes, the application should terminate the USB request by* invoking the usbTargControlResponseSend() function with a NULL <pBfr>* parameter.  This will direct usbTargLib to generate a Status IN phase,* signalling the end of the transaction.** NOTE: The caller must ensure that the ERP remains valid until the ERP* userCallback has been invoked - signalling completion of the ERP.** RETURNS: OK, or ERROR if unable to submit ERP to receive additional data*/STATUS usbTargControlPayloadRcv    (    USB_TARG_CHANNEL targChannel,    pUSB_ERP pErp    )    {    pTARG_TCD pTcd;    STATUS status;    OSS_MUTEX_TAKE (targMutex, OSS_BLOCK);    /* Validate parameters */    if ((status = validateTarg (targChannel, &pTcd)) == OK)	{	status = usbTargTransfer (pTcd->controlPipe, pErp);	}        OSS_MUTEX_RELEASE (targMutex);    return ossStatus (status);    }/***************************************************************************** usbTargPipeStatusSet - sets pipe stalled/unstalled status** If the target application detects an error while servicing a pipe,* including the default control pipe, it may choose to stall the endpoint(s)* associated with that pipe.  This function allows the caller to set the* state of a p

⌨️ 快捷键说明

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