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

📄 usbtarglib.c

📁 VxWorks下USB驱动的源代码!
💻 C
📖 第 1 页 / 共 5 页
字号:
/***************************************************************************** usbTargPipeCreate - Creates a pipe for communication on an endpoint** This function creates a pipe attached to a specific target endpoint.* <endpointId> is the TCD-assigned ID of the target endpoint to be used* for this pipe and <endpointNum> is the device endpoint number to which* the endpoint will respond.  Some TCDs allow the flexible assignment of* endpoints to specific endpoint numbers while others do not.  The* endpointNumMask field in the USB_TARG_ENDPOINT_INFO structure is a bit* mask that reveals which endpoint numbers are supported by a given* endpoint.  (e.g., If bit 0 is '1', then the corresponding endpoint can* be assigned to endpoint #0, and so forth).** By convention, each of the endpoints exposed by the TCD is unidirectional.* Control pipes are bidirectional, and therefore logically occupy two* endpoints, one IN endpoint and one OUT endpoint, both with the same* endpointNum.	When creating a control pipe, the caller must specify the* second endpoint Id in <endpointId2>.	In this case, <endpointId> must* specify the OUT endpoint, and <endpointId2> must specify the IN endpoint.* <endpointId2> should be 0 for other types of pipes.** <configuration> and <interface> specify the device configuration and* interface with which the endpoint (and pipe) is associated.  The * usbTargLib uses these values to reset pipes as appropriate when* USB "configuration events" are detected.  (In response to a USB* configuration event, the data toggle for a given endpoint is always* reset to DATA0.)** <transferType> specifies the type of transfers to be performed as* USB_XFRTYPE_xxxx.  <direction> specifies the direction of the pipe as* USB_DIR_xxxx.  Control pipes specify direction as USB_DIR_INOUT.** The caller must be aware that not all endpoints are capable of all types* of transfers.  Prior to assigning an endpoint for a particular purpose,* the caller should interrogate the USB_TARG_ENDPOINT_INFO structure for* the endpoint to ensure that it supports the indicated type of transfer.** RETURNS: OK, or ERROR if unable to create pipe** ERRNO:*   S_usbTargLib_BAD_PARAM*   S_usbTargLib_ENDPOINT_IN_USE*   S_usbTargLib_OUT_OF_MEMORY*   S_usbTargLib_OUT_OF_RESOURCES*   S_usbTargLib_TCD_FAULT*/STATUS usbTargPipeCreate (USB_TARG_CHANNEL targChannel, /* target channel */                          UINT16 endpointId,    /* endpoint ID to use for pipe */                          UINT16 endpointId2,   /* needed for control pipes only */                          UINT16 endpointNum,   /* endpoint number to assign */                          UINT16 configuration, /* associated configuration */                          UINT16 interface, /* associated interface */                          UINT16 transferType,  /* USB_XFRTYPE_xxxx */                          UINT16 direction, /* USB_DIR_xxxx */                          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

⌨️ 快捷键说明

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