?? usbtransunitdata.c
字號:
* window for the underlying USB host controller. The frame window specifies* the maximum number of frames into the future (relative to the current frame* number) which may be specified by <startFrame>. <startFrame> should be* specified only for isochronous transfers.** <dataBlockSize> may also be specified for isochronous transfers. If non-0,* the <dataBlockSize> defines the granularity of isochronous data being sent.* When the underlying Host Controller Driver (HCD) breaks up the transfer into* individual frames, it will ensure that the amount of data transferred in* each frame is a multiple of this value.** <timeout> specifies the IRP timeout in milliseconds. If the caller passes* a value of zero, then the USBD sets a default timeout of USB_TIMEOUT_DEFAULT.* If no timeout is desired, then <timeout> should be set to USB_TIMEOUT_NONE.* Timeouts apply only to control and bulk transfers. Isochronous and* interrupt transfers do not time out.** <bfrList> is an array of buffer descriptors which describe data buffers to* be associated with this IRP. If more than the one <bfrList> element is* required then the caller must allocate the IRP by calculating the size as** \cs* irpLen = sizeof (USB_IRP) + (sizeof (USB_BFR_DESCR) * (bfrCount - 1))* \ce** <transferLen> must be the total length of data to be transferred. In other* words, transferLen is the sum of all <bfrLen> entries in the <bfrList>.** <pid> specifies the packet type to use for the indicated buffer and is* specified as USB_PID_xxxx.** The IRP <userCallback> routine must point to a client-supplied IRP_CALLBACK* routine. The usbdTransfer() function returns as soon as the IRP has been* successfully enqueued. If there is a failure in delivering the IRP to the* HCD, then usbdTransfer() returns an error. The actual result of the IRP* should be checked after the <userCallback> routine has been invoked.** RETURNS: OK, or ERROR if unable to submit IRP for transfer.** ERRNO: N/A*/STATUS usbdTransfer ( USBD_CLIENT_HANDLE clientHandle, /* Client handle */ USBD_PIPE_HANDLE pipeHandle, /* Pipe handle */ pUSB_IRP pIrp /* ptr to I/O request packet */ ) { pUSBTU_IRPCONTEXT pIrpContext; pUSBTU_PIPE_INFO pipeInfo = (pUSBTU_PIPE_INFO) pipeHandle; pUSBTU_DEVICE_DRIVER clientInfo = (pUSBTU_DEVICE_DRIVER) clientHandle; pUSBHST_ISO_PACKET_DESC pIsoPacketDesc; pUSBHST_URB pUrb; int no; int i; int bufferlength; int bufferIndex; int transferflag = 0; pUSBTU_DEVICE_DRIVER pDriver = (pUSBTU_DEVICE_DRIVER) clientHandle; pUSBTU_IRP tempIrp = NULL; UINT32 frameCount = 0; UINT32 bytesThroughFrameCount = 0; UINT32 maxLen= 0; UINT32 bytesSoFar = 0; /* 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 "); USB_HCD_LOG_EVENT(USBTU_WV_CLIENT_TRANSFER, evLog, USBTU_WV_FILTER); } USBTU_LOG ( "usbdTransfer entered \n "); /* control transfer type not handled by usbdTransfer */ if (pipeInfo->transferType == USB_XFRTYPE_CONTROL) { USBTU_LOG ( "usbdTransfer returns ERROR : control transfer \n "); return ERROR; } /* If pipe is marked for deletion return ERROR */ if(pipeInfo->markedForDeletion) { USBTU_LOG ( "usbdTransfer returns ERROR : pipe marked for deletion \n "); return ERROR; } /* allocate structure for IRP context */ if ( !(pIrpContext = OSS_CALLOC ( sizeof (USBTU_IRPCONTEXT)))) { USBTU_LOG ( "usbdTransfer returns ERROR : malloc \n "); return ERROR; } /* allocate an array of URB structures one for each buffer */ if (!(pIrpContext->urbPtr = OSS_CALLOC ( pIrp->bfrCount * sizeof(USBHST_URB)))) { OSS_FREE (pIrpContext); USBTU_LOG ( "usbdTransfer returns ERROR : malloc1 failed \n "); return ERROR; } /* set the array index */ pIrpContext->urbIndex = 0; pIrpContext->pipeInfo = pipeInfo; pIrpContext->urbCompleteCount = 0; /* store the IRP context structure in IRP */ pIrp->usbdPtr = pIrpContext; /* set the initial status of IRP to OK */ pIrp->result = OK; /* get the message queue id of client */ pIrpContext->msgQid = clientInfo->msgQidIrpComplete; /* determine the transfer flag */ if (pIrp->flags == USB_FLAG_SHORT_OK) transferflag = USBHST_SHORT_TRANSFER_OK; else { if ( pIrp->flags & USB_FLAG_ISO_ASAP) transferflag = USBHST_START_ISOCHRONOUS_TRANSFER_ASAP; } /* Allocate memory for irp link list element */ if (!(tempIrp = OSS_CALLOC ( sizeof (USBTU_IRP)))) { OSS_FREE(pIrpContext->urbPtr); OSS_FREE (pIrpContext); USBTU_LOG ( "usbdTransfer returns ERROR : malloc1 failed \n "); return ERROR; } tempIrp->pIrp = pIrp; tempIrp->nextIrp = NULL; tempIrp->prevIrp = NULL; /* Take the mutex before accessing the list */ OSS_MUTEX_TAKE (usbtuMutex, OSS_BLOCK); /* Add the request to the list of requests for * the pipe */ if(pipeInfo->irpList == NULL) pipeInfo->irpList = tempIrp; else { tempIrp->nextIrp = pipeInfo->irpList; pipeInfo->irpList->prevIrp = tempIrp; pipeInfo->irpList = tempIrp; } /* Release the mutex */ OSS_MUTEX_RELEASE (usbtuMutex); switch ( pipeInfo->transferType) { case USB_XFRTYPE_ISOCH: /* isochronous transfer type */ for ( bufferIndex= 0; bufferIndex < pIrp->bfrCount ; bufferIndex++) { /* get the length of the buffer */ bufferlength = (pIrp->bfrList[bufferIndex]).bfrLen; /* determine the number of isochronous packet * descriptors required */ if (pipeInfo->bandwidth == 0) { if ( bufferlength % pipeInfo->uMaxPacketSize) no = ( bufferlength / pipeInfo->uMaxPacketSize ) + 1; else no = ( bufferlength / pipeInfo->uMaxPacketSize); pIsoPacketDesc = NULL; /* allocate ischronous packet descriptors */ if (!(pIsoPacketDesc = OSS_CALLOC( no * sizeof (USBHST_ISO_PACKET_DESC)))) { /* cancel already submitted URB's */ usbdTransferAbort(clientHandle, pipeHandle, pIrp); USBTU_LOG ( "usbdTransfer returns ERROR : malloc2 \n "); return ERROR; } /* initialize the isochronous packet descriptors */ for ( i= 0 ; i< no ; i++) { /* update the length */ if ( i == (no - 1) ) { pIsoPacketDesc[i].uLength = (bufferlength % pipeInfo->uMaxPacketSize); } else pIsoPacketDesc[i].uLength = pipeInfo->uMaxPacketSize; /* update the offset */ pIsoPacketDesc[i].uOffset =pipeInfo->uMaxPacketSize * i; } } else { /* Determine the number of packets based on pipeInfo->bandwidth */ bytesSoFar = 0; frameCount = 0; while ((int) bytesSoFar < bufferlength) { frameCount++; bytesThroughFrameCount = (frameCount * pipeInfo->bandwidth) / 1000L; maxLen = min (bytesThroughFrameCount - bytesSoFar, bufferlength - bytesSoFar); maxLen = min (maxLen, pipeInfo->uMaxPacketSize); if (pIrp->dataBlockSize != 0 && maxLen > pIrp->dataBlockSize) maxLen = (maxLen / pIrp->dataBlockSize) * pIrp->dataBlockSize; bytesSoFar += maxLen ; } no = frameCount; pIsoPacketDesc = NULL; /* allocate ischronous packet descriptors */ if (!(pIsoPacketDesc = OSS_CALLOC( no * sizeof (USBHST_ISO_PACKET_DESC)))) { /* cancel already submitted URB's */ usbdTransferAbort(clientHandle, pipeHandle, pIrp); USBTU_LOG ( "usbdTransfer returns ERROR : malloc2 \n "); return ERROR; } /* initialize the isochronous packet descriptors */ bytesSoFar = 0; frameCount = 0; while ((int) bytesSoFar < bufferlength) { frameCount++; bytesThroughFrameCount = (frameCount * pipeInfo->bandwidth) / 1000L; maxLen = min (bytesThroughFrameCount - bytesSoFar, bufferlength - bytesSoFar); maxLen = min (maxLen, pipeInfo->uMaxPacketSize); if (pIrp->dataBlockSize != 0 && maxLen > pIrp->dataBlockSize) maxLen = (maxLen / pIrp->dataBlockSize) * pIrp->dataBlockSize; /* update the offset */ pIsoPacketDesc[frameCount - 1].uOffset =bytesSoFar; /* update the length */ pIsoPacketDesc[frameCount - 1].uLength = maxLen; bytesSoFar += maxLen ; } } /* get the URB structure to be filled from array of URB structures */ pUrb = &(pIrpContext->urbPtr[pIrpContext->urbIndex]); /* initialize the URB structure */#if 1 USBHST_FILL_ISOCHRONOUS_URB(pUrb, pipeInfo->hDevice, pipeInfo->endpointAddress, (pIrp->bfrList[bufferIndex]).pBfr, (pIrp->bfrList[bufferIndex]).bfrLen, transferflag, pIrp->startFrame, no, pIsoPacketDesc, usbtuDataUrbCompleteCallback, (PVOID)pIrp, USBHST_SUCCESS);#else /* WARNING**************Just a patch */ transferflag |= USBHST_START_ISOCHRONOUS_TRANSFER_ASAP; USBHST_FILL_ISOCHRONOUS_URB(pUrb, pipeInfo->hDevice, pipeInfo->endpointAddress, (pIrp->bfrList[bufferIndex]).pBfr, (pIrp->bfrList[bufferIndex]).bfrLen, transferflag, 0, no, pIsoPacketDesc, usbtuDataUrbCompleteCallback, (PVOID)pIrp, USBHST_SUCCESS);#endif /* increment the URB array index */ (pIrpContext->urbIndex)++; /* submit the URB */ if ( usbHstURBSubmit (pUrb) != USBHST_SUCCESS) { /* cancel already submitted URB's */ USBTU_LOG("usbdTransfer returns ERROR : SubmitURB failed\n"); usbdTransferAbort(clientHandle, pipeHandle, pIrp); return ERROR; } } break; case USB_XFRTYPE_BULK : /* Bulk Transfer Type */ for ( bufferIndex= 0; bufferIndex < pIrp->bfrCount ; bufferIndex++) { /* get the URB structure to be filled */ pUrb = &(pIrpContext->urbPtr[ pIrpContext->urbIndex]); /* initialize the URB structure */ USBHST_FILL_BULK_URB(pUrb, pipeInfo->hDevice, pipeInfo->endpointAddress, (pIrp->bfrList[bufferIndex]).pBfr, (pIrp->bfrList[bufferIndex]).bfrLen, transferflag, usbtuDataUrbCompleteCallback, (PVOID)pIrp, USBHST_SUCCESS ); /* increment the URB array index */ (pIrpContext->urbIndex)++; /* submit the URB */ if ( usbHstURBSubmit(pUrb) != USBHST_SUCCESS) { /* cancel already submitted URB's */ USBTU_LOG("usbdTransfer returns ERROR : SubmitURB failed\n"); usbdTransferAbort(clientHandle, pipeHandle, pIrp); return ERROR; } } break; case USB_XFRTYPE_INTERRUPT: /* Interrupt Transfer Type */ for ( bufferIndex= 0; bufferIndex < pIrp->bfrCount ; bufferIndex++) { /* Get the URB structure to be filled */ pUrb = &(pIrpContext->urbPtr[ pIrpContext->urbIndex]); /* initialize the URB structure */ USBHST_FILL_INTERRUPT_URB(pUrb, pipeInfo->hDevice, pipeInfo->endpointAddress, (pIrp->bfrList[bufferIndex]).pBfr, (pIrp->bfrList[bufferIndex]).bfrLen, transferflag, usbtuDataUrbCompleteCallback, (PVOID)pIrp, USBHST_SUCCESS ); /* increment the URB array index */ (pIrpContext->urbIndex)++; /* submit the URB */ if ( usbHstURBSubmit(pUrb) != OK) { /* cancel already submitted URB's */ USBTU_LOG("usbdTransfer returns ERROR : SubmitURB failed\n"); usbdTransferAbort(clientHandle, pipeHandle, pIrp); return ERROR; } } break; default: break; } USBTU_LOG(" usbdTransfer returns OK \n "); return OK; }/***************************************************************************** usbdTransferAbort - Aborts a transfer** This function aborts an IRP which was previously submitted through* a call to usbdTransfer().** RETURNS: OK, or ERROR if unable to abort transfer.** ERRNO: N/A*/STATUS usbdTransferAbort ( USBD_CLIENT_HANDLE clientHandle, /* Client handle */ USBD_PIPE_HANDLE pipeHandle, /* Pipe handle */ pUSB_IRP pIrp /* ptr to I/O to abort */ ) { int i; pUSBTU_IRPCONTEXT pIrpContext; pUSBHST_URB pUrb; STATUS s = OK; pUSBTU_DEVICE_DRIVER pDriver = (pUSBTU_DEVICE_DRIVER) clientHandle; USBHST_STATUS status; pUSBTU_PIPE_INFO pipeInfo = (pUSBTU_PIPE_INFO) pipeHandle;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -