?? usbehcdtransfermanagement.c
字號:
{ OS_LOG_MESSAGE_HIGH(EHCD,"usbEhcdIsBandwidthAvailable - Current descriptor should be NULL\n",0,0,0,0); return USBHST_INVALID_PARAMETER; } /* Get the current configuration descriptor */ pCurrentConfigDesc = (pUSBHST_CONFIG_DESCRIPTOR)pCurrentDescriptor; /* Get the new configuration descriptor */ pNewConfigDesc = (pUSBHST_CONFIG_DESCRIPTOR)pNewDescriptor; } /* * If it is not an interface or configuration descriptor, * then it is an error */ else { OS_LOG_MESSAGE_HIGH(EHCD,"Descriptor type is not valid\n",0,0,0,0); return USBHST_INVALID_PARAMETER; } OS_LOG_MESSAGE_LOW(EHCD,"usbEhcdIsBandwidthAvailable - Exit\n",0,0,0,0);#endif /* Return success */ return USBHST_SUCCESS; }/* End of usbEhcdIsBandwidthAvailable() *//***************************************************************************** usbEhcdSubmitURB - submits a request to a pipe.** This function is used to submit a request to the pipe. <uBusIndex> specifies* the host controller bus index. <uPipeHandle> holds the pipe handle. <pURB>* is the pointer to the URB holding the request details.** RETURNS: * USBHST_SUCCESS - Returned if the URB is submitted successfully.* USBHST_INVALID_PARAMETER - Returned if the parameters are not valid.* USBHST_INSUFFICIENT_BANDWIDTH - Returned if memory is insufficient for the* request.** ERRNO:* None.** \NOMANUAL*/USBHST_STATUS usbEhcdSubmitURB ( UINT8 uBusIndex, /* Index of the host controller */ UINT32 uPipeHandle, /* Pipe handle */ pUSBHST_URB pURB /* Pointer to the URB */ ) { /* To hold the pointer to the data structure */ pUSB_EHCD_DATA pHCDData = NULL; /* To hold the PID value */ UINT32 pId; /* Pointer to the HCD maintained pipe */ pUSB_EHCD_PIPE pHCDPipe = NULL; /* To hold the request information */ pUSB_EHCD_REQUEST_INFO pRequestInfo = NULL; /* To hold the status of the request */ USBHST_STATUS Status = USBHST_FAILURE; /* To hold the status of the function call */ BOOLEAN bStatus = FALSE; /* Pointer to the QTD */ pUSB_EHCD_QTD pQTD = NULL; /* To hold the current frame index */ UINT32 uFrameNumber = 0; /* WindView Instrumentation */ USB_HCD_LOG_EVENT( USB_EHCI_WV_TRANSFER, "usbEhcdSubmitURB() starts", USB_EHCD_WV_FILTER); OS_LOG_MESSAGE_LOW(EHCD,"usbEhcdSubmitURB - Entry\n",0,0,0,0); /* Check the validity of the parameters */ if ((g_EHCDControllerCount <= uBusIndex) || (0 == uPipeHandle) || (NULL == pURB)) { OS_LOG_MESSAGE_HIGH(EHCD,"usbEhcdSubmitURB - parameters are not valid\n",0,0,0,0); return USBHST_INVALID_PARAMETER; } /* Extract the global data structure */ pHCDData = g_pEHCDData[uBusIndex]; /* Assert if the global pointer is not valid */ OS_ASSERT(NULL != pHCDData); /* Extract the USB_EHCD_PIPE data structure */ pHCDPipe = (pUSB_EHCD_PIPE)uPipeHandle; /* Check if the request is for the Root hub and route it */ if ((pHCDData->RHData.pInterruptPipe == pHCDPipe) || (pHCDData->RHData.pControlPipe == pHCDPipe) || ((pHCDData->pDefaultPipe == pHCDPipe) && (0 == pHCDData->RHData.uDeviceAddress))) { Status = usbEhcdRHSubmitURB(pHCDData, uPipeHandle, pURB); return Status; } /* Exclusively access the list */ OS_WAIT_FOR_EVENT(pHCDData->RequestSynchEventID,OS_WAIT_INFINITE); /* It is of the assumption that the USBD always gives a valid pipe handle. * This also includes not giving a submit URB request while the pipe * is being deleted. */ /* Allocate the request information structure */ pRequestInfo = (pUSB_EHCD_REQUEST_INFO)OS_MALLOC(sizeof(USB_EHCD_REQUEST_INFO)); /* Check if memory allocation is successful */ if (NULL == pRequestInfo) { OS_LOG_MESSAGE_HIGH(EHCD,"usbEhcdSubmitURB - Memory not allocated for the request info\n",0,0,0,0); /* Release the event */ OS_RELEASE_EVENT(pHCDData->RequestSynchEventID); return USBHST_MEMORY_NOT_ALLOCATED; } /* Initialize the fields of the data structure */ OS_MEMSET(pRequestInfo, 0, sizeof(USB_EHCD_REQUEST_INFO)); /* Copy the URB pointer */ pRequestInfo->pUrb = pURB; /* Store the USB_EHCD_PIPE pointer */ pRequestInfo->pHCDPipe = pHCDPipe; /* Check if it is a control transfer request */ if (USBHST_CONTROL_TRANSFER == pHCDPipe->uEndpointType) { /* To hold the number of bytes to be transferred */ UINT32 uNumBytes = 0; /* Pointer to the setup packet */ pUSBHST_SETUP_PACKET pSetup = NULL; /* Retrieve the setup packet information */ pSetup = (pUSBHST_SETUP_PACKET)(pURB->pTransferSpecificData); /* Swap the 16 bit values */ pSetup->wValue = OS_UINT16_LE_TO_CPU(pSetup->wValue); pSetup->wIndex = OS_UINT16_LE_TO_CPU(pSetup->wIndex); pSetup->wLength = OS_UINT16_LE_TO_CPU(pSetup->wLength); /* create TD for the SETUP TRANSACTION */ pQTD = usbEhcdFormEmptyQTD(); /* Check if QTD is created successfully */ if (NULL == pQTD) { OS_LOG_MESSAGE_HIGH(EHCD,"usbEhcdSubmitURB - Head TD is not created\n",0,0,0,0); /* Release memory allocated for the request element */ OS_FREE(pRequestInfo); /* Release the event */ OS_RELEASE_EVENT(pHCDData->RequestSynchEventID); return USBHST_INSUFFICIENT_BANDWIDTH; } /* Update the buffer pointer fields of the TD */ uNumBytes = usbEhcdFillQTDBuffer(pQTD, pURB->pTransferSpecificData, sizeof(USBHST_SETUP_PACKET), pHCDPipe->uMaximumPacketSize); /* Check if the buffer pointer fields are updated */ if (0 == uNumBytes) { OS_LOG_MESSAGE_HIGH(EHCD,"usbEhcdSubmitURB - Head TD is not created\n",0,0,0,0); /* Add the QH to the free list * Nothing can be done with return value */ usbEhcdAddToFreeQTDList(pQTD); /* Release memory allocated for the request element */ OS_FREE(pRequestInfo); /* Release the event */ OS_RELEASE_EVENT(pHCDData->RequestSynchEventID); return USBHST_FAILURE; } /* Update the data toggle bit */ USB_EHCD_SET_BITFIELD(QTD, pQTD->uTransferInfo, 0, TOKEN_DT); /* Indicate that it is a SETUP token */ USB_EHCD_SET_BITFIELD(QTD, pQTD->uTransferInfo, USB_EHCD_SETUP_PID, TOKEN_PID_CODE); /* Copy the TD to the head of the request */ pRequestInfo->pHead = (VOID *)pQTD; /* create qTD for the STATUS TRANSACTION */ pQTD = usbEhcdFormEmptyQTD(); /* Check if QTD is created successfully */ if (NULL == pQTD) { OS_LOG_MESSAGE_HIGH(EHCD,"usbEhcdSubmitURB - Status TD is not created\n",0,0,0,0); /* Add the head TD to the free list */ usbEhcdAddToFreeQTDList((pUSB_EHCD_QTD)pRequestInfo->pHead); /* Release memory allocated for the request element */ OS_FREE(pRequestInfo); /* Release the event */ OS_RELEASE_EVENT(pHCDData->RequestSynchEventID); return USBHST_INSUFFICIENT_BANDWIDTH; } /* Update the buffer pointer fields of the TD */ usbEhcdFillQTDBuffer(pQTD, (VOID *) NULL, 0, pHCDPipe->uMaximumPacketSize); /* update the data toggle field */ USB_EHCD_SET_BITFIELD(QTD, pQTD->uTransferInfo, 1, TOKEN_DT); /* Indicate that an interrupt is to be * generated on completion of the status stage */ USB_EHCD_SET_BITFIELD(QTD, pQTD->uTransferInfo, 1, TOKEN_IOC); /* Indicate that there are no elements after the status stage */ pQTD->pNext = NULL; /* Based on the direction of data transfer, update the status * stage direction. The status stage would be in a direction * opposite to the data stage direction. */ pId = (0 != (pSetup->bmRequestType & USB_EHCD_DIR_IN))? USB_EHCD_OUT_PID:USB_EHCD_IN_PID; USB_EHCD_SET_BITFIELD(QTD, pQTD->uTransferInfo, pId, TOKEN_PID_CODE); /* Make this as the tail */ pRequestInfo->pTail = (VOID *)pQTD; /* Flush the contents of the cache to the RAM */ CACHE_DMA_FLUSH(pQTD, sizeof(USB_EHCD_QTD)); /* Invalidate the cache */ CACHE_DMA_INVALIDATE(pQTD, sizeof(USB_EHCD_QTD)); /* Create TDs for the DATA TRANSACTION */ if (0 != pURB->uTransferLength) { /* Pointer to the head of the data TD list */ pUSB_EHCD_QTD pDataHead = NULL; /* Pointer to the tail of the data TD list */ pUSB_EHCD_QTD pDataTail = NULL; /* To hold the PID value */ UINT8 uPid = (0 != (pSetup->bmRequestType & USB_EHCD_DIR_IN))? USB_EHCD_IN_PID:USB_EHCD_OUT_PID; /* Create the TD chain for the data stage */ bStatus = usbEhcdCreateQTDs(&pDataHead, &pDataTail, pURB->pTransferBuffer, pURB->uTransferLength, pHCDPipe->uMaximumPacketSize, 1, uPid); /* Check if the TDs are not created successfully */ if (FALSE == bStatus) { OS_LOG_MESSAGE_HIGH(EHCD,"usbEhcdSubmitURB - Data TDs not created\n",0,0,0,0); /* Add the head TD to the free list */ usbEhcdAddToFreeQTDList((pUSB_EHCD_QTD)pRequestInfo->pHead); /* Add the tail TD to the free list */ usbEhcdAddToFreeQTDList((pUSB_EHCD_QTD)pRequestInfo->pTail); /* Release memory allocated for the request element */ OS_FREE(pRequestInfo); /* Release the event */ OS_RELEASE_EVENT(pHCDData->RequestSynchEventID); return USBHST_FAILURE; } /* Store the head of the Request list */ pQTD = (pUSB_EHCD_QTD)pRequestInfo->pHead; /* Update the next element of the head of the request */ pQTD->pNext = pDataHead; /* Update the HC's link pointers */ USB_EHCD_SET_BITFIELD(QTD, pQTD->uNextQTDPointer, (((unsigned)USB_EHCD_CONVERT_TO_PCI(pDataHead)) >> 5), NEXTQTD_POINTER); /* Indicate that the head element of * the request is not the last element in the list */ USB_EHCD_SET_BITFIELD(QTD, pQTD->uNextQTDPoint
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -