?? usbtransunitdata.c
字號:
pUSBTU_IRP tempIrp; pUSBTU_IRP prevIrp; if(pIrp == NULL) return ERROR; /* Check if the pipe handle is valid */ if (pipeInfo == NULL) return ERROR; /* remove the IRP from the list maintained - start */ /* Take the mutex before accessing the list */ OSS_MUTEX_TAKE (usbtuMutex, OSS_BLOCK); tempIrp = pipeInfo->irpList; prevIrp = pipeInfo->irpList; while(tempIrp != NULL ) { if(tempIrp->pIrp == pIrp ) break; else { prevIrp = tempIrp; tempIrp = tempIrp->nextIrp; } } if (tempIrp == NULL) { OSS_MUTEX_RELEASE (usbtuMutex); return ERROR; } if(tempIrp == prevIrp) pipeInfo->irpList = pipeInfo->irpList->nextIrp; else { prevIrp->nextIrp = tempIrp->nextIrp; if(tempIrp->nextIrp != NULL) tempIrp->nextIrp->prevIrp = prevIrp; } OSS_FREE (tempIrp); /* remove the IRP from the list maintained - End */ /* Release the mutex after accessing the list */ OSS_MUTEX_RELEASE (usbtuMutex); pIrpContext = pIrp->usbdPtr; /* Check for NULL Pointer */ if (pIrpContext == NULL) { USBTU_LOG ("IRP context is NULL\n"); return ERROR; } if(pIrpContext->urbPtr == NULL) return ERROR; pUrb = pIrpContext->urbPtr; /* Wind View Instrumentation */ if ((usbtuInitWvFilter & USBTU_WV_FILTER) == TRUE) { char evLog[USBTU_WV_LOGSIZE]; strncpy ((char*)evLog, (char *)pDriver->clientName,USBD_NAME_LEN ); strcat(evLog, " : USBD Transfer Abort "); USB_HCD_LOG_EVENT(USBTU_WV_CLIENT_TRANSFER, evLog, USBTU_WV_FILTER); } USBTU_LOG ( "usbdTransferAbort entered \n "); /* if all the URB's are completed , there is nothing to abort */ if (pIrpContext->urbCompleteCount == pIrp->bfrCount) { USBTU_LOG ( "Transfer Completed! \n "); return OK; } /* abort the URB's and release URB specific resources */ for ( i = 0 ; i < pIrp->bfrCount ; i++ ) { status = usbHstURBCancel( &(pUrb[i])); if ((status == USBHST_TRANSFER_COMPLETED) || (status == USBHST_INVALID_PARAMETER) || (status == USBHST_INVALID_REQUEST)) { USBTU_LOG ( "usbdTransferAbort CancelURB failed \n "); s = ERROR; break; } /* This will be freed by the callback */ if ( pUrb[i].pTransferSpecificData) OSS_FREE (pUrb[i].pTransferSpecificData); } /* Call callback if the cancelling is successful */ if ( s!= ERROR) { pIrp->result = S_usbHcdLib_IRP_CANCELED; (*pIrp->userCallback)(pIrp); /* Release resources */ OSS_FREE(pUrb); OSS_FREE(pIrpContext); pIrp->usbdPtr = NULL; } if ( s == OK) { USBTU_LOG ( "usbdTransferAbort return OK \n "); } else { USBTU_LOG ( "usbdTransferAbort return ERROR \n "); } return s; }/***************************************************************************** usbdVendorSpecific - Allows clients to issue vendor-specific USB requests** Certain devices may implement vendor-specific USB requests which cannot* be generated using the standard functions described elsewhere. This* function allows a client to specify directly the exact parameters for a* USB control pipe request.** <requestType>, <request>, <value>, <index>, and <length> correspond* exactly to the bmRequestType, bRequest, wValue, wIndex, and wLength fields* defined by the USB Specfication. If <length> is greater than zero, then* <pBfr> must be a non-NULL pointer to a data buffer which will provide or* accept data, depending on the direction of the transfer.** Vendor specific requests issued through this function are always directed* to the control pipe of the device specified by <nodeId>. This function* formats and sends a Setup packet based on the parameters provided. If a* non-NULL <pBfr> is also provided, then additional IN or OUT transfers* will be performed following the Setup packet. The direction of these* transfers is inferred from the direction bit in the <requestType> param.* For IN transfers, the actual length of the data transferred will be* stored in <pActLen> if <pActLen> is not NULL.** RETURNS: OK, or ERROR if unable to execute vendor-specific request.** ERRNO: N/A*/STATUS usbdVendorSpecific ( USBD_CLIENT_HANDLE clientHandle, /* Client handle */ USBD_NODE_ID nodeId, /* Node Id of device/hub */ UINT8 requestType, /* bmRequestType in USB spec. */ UINT8 request, /* bRequest in USB spec. */ UINT16 value, /* wValue in USB spec. */ UINT16 index, /* wIndex in USB spec. */ UINT16 length, /* wLength in USB spec. */ pUINT8 pBfr, /* ptr to data buffer */ pUINT16 pActLen /* actual length of IN */ ) { pUSBHST_URB pUrb; pUSBHST_SETUP_PACKET pSetupPacket; SEM_ID semMutex; STATUS s = OK; pUSBTU_DEVICE_DRIVER pDriver = (pUSBTU_DEVICE_DRIVER) clientHandle; /* Wind View Instrumentation */ if ((usbtuInitWvFilter & USBTU_WV_FILTER) == TRUE) { char evLog[USBTU_WV_LOGSIZE]; strncpy ((char*)evLog,(char *)pDriver->clientName,USBD_NAME_LEN ); strcat(evLog, " : Vendor Specific Transfer "); USB_HCD_LOG_EVENT(USBTU_WV_CLIENT_TRANSFER, evLog, USBTU_WV_FILTER); } USBTU_LOG ( "usbdVendorSpecific entered \n "); if (pActLen != NULL) *pActLen = 0; /* allocate a URB structure */ if ( !(pUrb = OSS_CALLOC ( sizeof (USBHST_URB )))) { USBTU_LOG ( "usbdVendorSpecific returns ERROR: malloc failed \n "); return ERROR; } /* allocate a setup packet structure */ if ( !(pSetupPacket = OSS_CALLOC ( sizeof (USBHST_SETUP_PACKET)))) { OSS_FREE (pUrb); USBTU_LOG ( "usbdVendorSpecific returns ERROR: malloc1 failed \n "); return ERROR; } /* initialize the setup packet structure */ USBHST_FILL_SETUP_PACKET(pSetupPacket,requestType,request,value, index,length); /* since the call has to block, create a semaphore */ if ( !(semMutex = semBCreate (SEM_Q_FIFO,SEM_EMPTY))) { OSS_FREE (pUrb); OSS_FREE (pSetupPacket); USBTU_LOG ( "usbdVendorSpecific returns ERROR: sem create failed \n "); return ERROR; } /* initialize the URB structure */ USBHST_FILL_CONTROL_URB (pUrb, (UINT32)nodeId, 0, pBfr, length, USBHST_SHORT_TRANSFER_OK, (PVOID)pSetupPacket, usbtuDataVendorSpecificCallback, (PVOID)semMutex, USBHST_SUCCESS ); /* submit the URB */ if ( usbHstURBSubmit (pUrb) != USBHST_SUCCESS) { /* failed to submit the URB */ OSS_FREE (pUrb); OSS_FREE (pSetupPacket); semDelete (semMutex); USBTU_LOG ( "usbdVendorSpecific returns ERROR: SubmitURB failed \n "); return ERROR; } /* block till vendor specific callback releases the semaphore */ USBTU_LOG(" waiting for transfer to complete \n "); semTake (semMutex, WAIT_FOREVER); USBTU_LOG(" transfer completed \n "); /* URB completed, callback released the semaphore */ if (pUrb->nStatus != USBHST_SUCCESS ) { USBTU_LOG("usbdVendorSpecific returns ERROR:URB status!=USBHST_SUCCESS\n"); s = ERROR; } /* update length fo data transfer */ if (pActLen != NULL) *pActLen = pUrb->uTransferLength; /* release resources allocated */ OSS_FREE (pUrb); OSS_FREE (pSetupPacket); semDelete (semMutex); /* return status */ if ( s == OK) { USBTU_LOG ( "usbdVendorSpecific returns OK \n "); } else { USBTU_LOG ( "usbdVendorSpecific returns ERROR \n "); } return s; }/***************************************************************************** usbtuDataUrbCompleteCallback - Callback called on URB completeion** This function is called from interrupt context by the USBD on a* URB completion.* RETURNS: USBHST_SUCCESS , or USBHST_FAILURE on failure** ERRNO: N/A*/USBHST_STATUS usbtuDataUrbCompleteCallback ( pUSBHST_URB urbPtr /* URB pointer */ ) { pUSBHST_URB pUrb = (pUSBHST_URB) urbPtr; pUSB_IRP pIrp = (pUSB_IRP)pUrb->pContext; pUSBTU_IRPCONTEXT pIrpContext = pIrp->usbdPtr; MSG_Q_ID msgQid; pUSBTU_IRP tempIrp; pUSBTU_IRP prevIrp; USBTU_LOG ( "usbtuDataUrbCompleteCallback entered \n "); /* map the error codes */ if ( pUrb->nStatus != USBHST_SUCCESS ) { switch (pUrb->nStatus) { case USBHST_TRANSFER_CANCELLED : pIrp->result = S_usbHcdLib_IRP_CANCELED; break; case USBHST_DATA_UNDERRUN_ERROR : pIrp->result = S_usbHcdLib_DATA_BFR_FAULT; break; case USBHST_TIMEOUT : pIrp->result = S_usbHcdLib_CRC_TIMEOUT; break; case USBHST_STALL_ERROR : pIrp->result = S_usbHcdLib_STALLED; break; case USBHST_DEVICE_NOT_RESPONDING_ERROR : pIrp->result = S_usbHcdLib_IRP_CANCELED; break; default: pIrp->result = ERROR; } } else pIrp->result = OK; /* release URB specific resources */ if (pUrb->pTransferSpecificData) OSS_FREE(pUrb->pTransferSpecificData); /* Update the number of bytes transferred */ pIrp->bfrList[pIrpContext->urbCompleteCount].actLen = pUrb->uTransferLength; /* increment the URB completion count */ (pIrpContext->urbCompleteCount)++; /* if all URB's have completed , call the callback */ if ( pIrpContext->urbCompleteCount == pIrp->bfrCount) { /* get the message queue id */ msgQid = pIrpContext->msgQid; if ( msgQSend(msgQid,(char *) &pIrp , sizeof(char *) , NO_WAIT, MSG_PRI_NORMAL) != OK) { USBTU_LOG ( "usbtuDataUrbCompleteCallback msgQSend failed \n "); } /* Take the mutex before accessing the list */ OSS_MUTEX_TAKE (usbtuMutex, OSS_BLOCK); tempIrp =pIrpContext->pipeInfo->irpList; prevIrp =pIrpContext->pipeInfo->irpList; /* unlink the irp from pipe info structure */ while(tempIrp != NULL ) { if(tempIrp->pIrp == pIrp ) break; else { prevIrp = tempIrp; tempIrp = tempIrp->nextIrp; } } /* If the IRP is present, unlink it from the pipe's * request list */ if (tempIrp != NULL) { if(tempIrp == prevIrp) pIrpContext->pipeInfo->irpList = pIrpContext->pipeInfo->irpList->nextIrp; else { prevIrp->nextIrp = tempIrp->nextIrp; if( tempIrp->nextIrp) tempIrp->nextIrp->prevIrp = prevIrp; } OSS_FREE (tempIrp); } /* If the pipe is marked for deletion and the list is empty, * signal the semaphore so that the pipe can be safely deleted */ if ((pIrpContext->pipeInfo->markedForDeletion == 1) && (pIrpContext->pipeInfo->irpList == NULL) && (pIrpContext->pipeInfo->PipeDelete != NULL)) { semGive(pIrpContext->pipeInfo->PipeDelete); } /* Release the semaphore */ OSS_MUTEX_RELEASE (usbtuMutex); /* release IRP context resources */ OSS_FREE ( pIrpContext->urbPtr); OSS_FREE ( pIrpContext); } USBTU_LOG ( "usbtuDataUrbCompleteCallback left \n "); return USBHST_SUCCESS; }/***************************************************************************** usbtuDataVendorSpecificCallback - Callback called on Vendor Specific Request* completeion** This function is called from interrupt context by the USBD on a* Vendor Specific request completion.** RETURNS: USBHST_SUCCESS** ERRNO: N/A*/USBHST_STATUS usbtuDataVendorSpecificCallback ( pUSBHST_URB urbPtr /* URB pointer */ ) { pUSBHST_URB pUrb = (pUSBHST_URB) urbPtr; USBTU_LOG ( "usbtuDataVendorSpecificCallback entered \n "); /* release the semaphore */ semGive (pUrb->pContext); USBTU_LOG ( "usbtuDataVendorSpecificCallback left \n "); return USBHST_SUCCESS; }/* End of file. */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -