📄 usbehcdutil.c
字号:
pSITD->pNext = NULL; } /* Release the event */ OS_RELEASE_EVENT(g_ListAccessEvent); /* Return the pointer to SITD */ return pSITD; } /* End of usbEhcdGetFreeSITD() *//***************************************************************************** usbEhcdFreeAllLists - releases all the free lists.** This function frees up all the elements in the free list during the HCD* uninitialization.** RETURNS: None.** ERRNO:* None.** \NOMANUAL*/VOID usbEhcdFreeAllLists(VOID) { /* Pointer to the USB_EHCD_QH data structure */ pUSB_EHCD_QH pQH = NULL; /* Pointer to the USB_EHCD_QTD data structure */ pUSB_EHCD_QTD pQTD = NULL; /* Pointer to the USB_EHCD_ITD data structure */ pUSB_EHCD_ITD pITD = NULL; /* Pointer to the USB_EHCD_SITD data structure */ pUSB_EHCD_SITD pSITD = NULL; OS_LOG_MESSAGE_LOW(EHCD,"usbEhcdFreeAllLists - Entry\n",0,0,0,0); /* Assert if the list access event is not valid */ OS_ASSERT(NULL != g_ListAccessEvent); /* Wait on the signalling of the event */ OS_WAIT_FOR_EVENT(g_ListAccessEvent,OS_WAIT_INFINITE); /* Free the elements in the QH list */ for (; pHeadFreeQH != NULL; pHeadFreeQH = pQH) { /* Store the next pointer temporarily */ pQH = pHeadFreeQH->pNext; /* Assert if the allocated memory pointer is invalid */ OS_ASSERT(NULL != pHeadFreeQH->pAllocatedMem); /* Free the Queue head data structure */ OS_FREE(pHeadFreeQH->pAllocatedMem); } /* Update the head and tail pointers to NULL */ pHeadFreeQH = NULL; pTailFreeQH = NULL; /* Free the elements in the QTD list */ for (; pHeadFreeQTD != NULL; pHeadFreeQTD = pQTD) { /* Store the next pointer temporarily */ pQTD = pHeadFreeQTD->pNext; /* Assert if the allocated memory pointer is invalid */ OS_ASSERT(NULL != pHeadFreeQTD->pAllocatedMem); /* Free the Queue element data structure */ OS_FREE(pHeadFreeQTD->pAllocatedMem); } /* Update the head and tail pointers to NULL */ pHeadFreeQTD = NULL; pTailFreeQTD = NULL; /* Free the elements in the ITD list */ for (; pHeadFreeITD != NULL; pHeadFreeITD = pITD) { /* Store the next pointer temporarily */ pITD = pHeadFreeITD->pNext; /* Assert if the allocated memory pointer is invalid */ OS_ASSERT(NULL != pHeadFreeITD->pAllocatedMem); /* Free the iTD data structure */ OS_FREE( pHeadFreeITD->pAllocatedMem); } /* Update the head and tail pointers to NULL */ pHeadFreeITD = NULL; pTailFreeITD = NULL; /* Free the elements in the SITD list */ for (; pHeadFreeSITD != NULL; pHeadFreeSITD = pSITD) { /* Store the next pointer temporarily */ pSITD = pHeadFreeSITD->pNext; /* Assert if the allocated memory pointer is invalid */ OS_ASSERT(NULL != pHeadFreeSITD->pAllocatedMem); /* Free the siTD data structure */ OS_FREE(pHeadFreeSITD->pAllocatedMem); } /* Update the head and tail pointers to NULL */ pHeadFreeSITD = NULL; pTailFreeSITD = NULL; /* Release the event */ OS_RELEASE_EVENT(g_ListAccessEvent); return; } /* End of function usbEhcdFreeAllLists() */ /***************************************************************************** usbEhcdFormEmptyQH - forms an empty QH and populates it.** This function is checks if a QH can be retrieved from the free list. If a* QH cannot be retrieved, creates an empty QH. After retrieving a valid QH,* populates the fields of the QH.** <pHCDData> - Pointer to the USB_EHCD_DATA structure** RETURNS: Pointer to the USB_EHCD_QH data structure.** ERRNO:* None.** \NOMANUAL*/pUSB_EHCD_QH usbEhcdFormEmptyQH ( pUSB_EHCD_DATA pHCDData/* Pointer to the USB_EHCD_DATA structure */ ) { /* To hold the pointer to the Queue Head */ pUSB_EHCD_QH pQH = NULL; /* To hold the pointer to the allocated memory */ VOID * pAllocatedMem = NULL; UINT32 sizeOfAllocMem = 0; /* To hold the HCD bus index */ UINT32 index = pHCDData->uBusIndex; OS_LOG_MESSAGE_LOW(EHCD,"usbEhcdFormEmptyQH - Entry\n",0,0,0,0); /* Default size of memory to be allocated */ sizeOfAllocMem = sizeof(USB_EHCD_QH) + USB_EHCD_HC_DATA_STRUCTURE_ALIGNMENT; /* * If the HC supports 64 bit data structures, then * the size of memory which is to be allocated is different */ if (pHCDData->addressMode64 == 1) sizeOfAllocMem += USB_EHCD_QH_64BIT_ADDITIONAL_SIZE; /* Get a free QH from the free list */ pQH = usbEhcdGetFreeQH(sizeOfAllocMem); /* If the free list is empty, allocate memory and align it */ if (NULL == pQH) { /* Allocate memory considering that the QH is aligned to 32 bytes */ pAllocatedMem = OS_MALLOC (sizeOfAllocMem); /* Check if memory allocation is successful */ if (NULL == pAllocatedMem) { OS_LOG_MESSAGE_HIGH(EHCD,"usbEhcdFormEmptyQH - memory not allocated for \ QH\n",0,0,0,0); return NULL; } /* Align the memory */ pQH = usbEhcdAlign((VOID *)((UINT32)pAllocatedMem + USB_EHCD_QH_HEADER_SIZE), USB_EHCD_HC_DATA_STRUCTURE_ALIGNMENT); /* Decrementing the header size includes the HCD specific info also */ pQH = (pUSB_EHCD_QH)((UINT32)pQH - USB_EHCD_QH_HEADER_SIZE); /* Initialize all the elements of the Queue Head */ OS_MEMSET(pAllocatedMem, 0, sizeOfAllocMem); /* Store the allocated memory in aligned QH */ pQH->pAllocatedMem = pAllocatedMem; /* Store the size of allocated memory */ pQH->uSize = sizeOfAllocMem; } /* Populate the fields of the QH - Start */ /* * This field indicates to the hardware that * the item referenced by the link pointer is a QH */ USB_EHCD_SET_BITFIELD(index, QH, pQH->uQueueHeadHorizontalLinkPointer, USB_EHCD_TYPE_QH, HORIZONTAL_LINK_POINTER_TYPE); /* * Indicate that there are no valid TDs * in this queue as the QH is newly created */ USB_EHCD_SET_BITFIELD(index, QH, pQH->uNextQtdPointer, USB_EHCD_INVALID_LINK, NEXTQTD_POINTER_T); USB_EHCD_SET_BITFIELD(index, QH, pQH->uAlternateNextQtdPointer, USB_EHCD_INVALID_LINK, ALTERNATE_NEXTQTDPOINTER_T); /* Populate the fields of the QH - End */ return pQH; } /* End of function usbEhcdFormEmptyQH() *//***************************************************************************** usbEhcdFormEmptyQTD - forms an empty QTD and populates it.** This function is checks if a QTD can be retrieved from the free list. If a* QTD cannot be retrieved, creates an empty QTD. After retrieving a valid QTD,* populates the fields of the QTD.** <pHCDData> - Pointer to the USB_EHCD_DATA structure** RETURNS: Pointer to the USB_EHCD_QTD data structure.** ERRNO:* None.** \NOMANUAL*/pUSB_EHCD_QTD usbEhcdFormEmptyQTD ( pUSB_EHCD_DATA pHCDData/* Pointer to the USB_EHCD_DATA structure */ ) { /* To hold the pointer to the QTD */ pUSB_EHCD_QTD pQTD = NULL; /* To hold the pointer to the allocated memory */ VOID * pAllocatedMem = NULL; UINT32 sizeOfAllocMem = 0; /* To hold the HCD bus index */ UINT32 index = pHCDData->uBusIndex; /* Default size of memory to be allocated */ sizeOfAllocMem = sizeof(USB_EHCD_QTD) + USB_EHCD_HC_DATA_STRUCTURE_ALIGNMENT; /* * If the HC supports 64 bit data structures, then * the size of memory which is to be allocated is different */ if (pHCDData->addressMode64 == 1) sizeOfAllocMem += USB_EHCD_QTD_64BIT_ADDITIONAL_SIZE; /* Get a free QTD from the free list */ pQTD = usbEhcdGetFreeQTD(sizeOfAllocMem); /* If the free list is empty, allocate memory and align it */ if (NULL == pQTD) { /* Allocate memory considering that the QH is aligned to 32 bytes */ pAllocatedMem = OS_MALLOC (sizeOfAllocMem); /* Check if memory allocation is successful */ if (NULL == pAllocatedMem) { OS_LOG_MESSAGE_HIGH(EHCD,"usbEhcdFormEmptyQTD - memory not allocated for \ QTD\n",0,0,0,0); return NULL; } /* Align the memory */ pQTD = usbEhcdAlign((VOID *)((UINT32)pAllocatedMem + USB_EHCD_QTD_HEADER_SIZE), USB_EHCD_HC_DATA_STRUCTURE_ALIGNMENT); /* Decrementing the header size includes the HCD specific info also */ pQTD = (pUSB_EHCD_QTD)((UINT32)pQTD - USB_EHCD_QTD_HEADER_SIZE); /* Initialize all the elements of the Queue Head */ OS_MEMSET(pAllocatedMem, 0, sizeOfAllocMem); /* Store the allocated memory in aligned QTD */ pQTD->pAllocatedMem = pAllocatedMem; /* Store the size of the allocated memory */ pQTD->uSize = sizeOfAllocMem; } /* Populate the fields of the QTD - Start */ /* Invalidate Link pointer */ USB_EHCD_SET_BITFIELD(index, QTD, pQTD->uNextQTDPointer, USB_EHCD_INVALID_LINK, NEXTQTD_POINTER_T ); USB_EHCD_SET_BITFIELD(index, QTD, pQTD->uAlternateNextQTDPointer, USB_EHCD_INVALID_LINK, ALTERNATE_NEXTQTDPOINTER_T ); /* Indicate that a maximum of 2 errors is acceptable during a transfer */ USB_EHCD_SET_BITFIELD(index, QTD, pQTD->uTransferInfo, USB_EHCD_MAX_ERRORS, TOKEN_CERR ); /* Enable the HC to start executing the Transaction */ USB_EHCD_SET_BITFIELD(index, QTD, pQTD->uTransferInfo, USB_EHCD_QTD_STATUS_ACTIVE, TOKEN_STATUS); /* Populate the fields of the QTD - End */ return pQTD; } /* End of usbEhcdFormEmptyQTD() *//***************************************************************************** usbEhcdFillQTDBuffer - populates the buffer pointers of the QTD.** This function is used to populate the buffer pointer fields of the QTD.** <index> - index of the host controller* <pQTD> - Pointer to the QTD.* <pBuffer> - Pointer to the start of the buffer* <uSize> - Size of the data to be filled.* RETURNS: Returns the number of bytes which were filled in qTD.** ERRNO:* None.** \NOMANUAL*/UINT32 usbEhcdFillQTDBuffer ( UINT8 index, /* index of the host controller */ pUSB_EHCD_QTD pQTD, /* Pointer to the QTD */ VOID * pBuffer, /* Pointer to the start of the buffer */ UINT32 uSize, /* Size of the buffer to be filled */ UINT32 uMaxPacketSize /* Maximum packet size */ ) { /* To hold the index into the buffer pointers of the qTD */ UINT32 uIndex; UINT32 actualSize; /* Check the validity of the parameters */ if(NULL == pQTD || NULL == pBuffer || 0 == uSize) { return 0; } /* Fill qTD's buffer pointer */ USB_EHCD_SET_BITFIELD(index, QTD, pQTD->uBufferPagePointerList[0], (((unsigned)USB_EHCD_CONVERT_TO_BUS_MEM( index,pBuffer)) >> 12), BUFFER_POINTER); /* Fill qTD's current offset into the buffer pointer */ USB_EHCD_SET_BITFIELD(index, QTD, pQTD->uBufferPagePointerList[0], ((unsigned)USB_EHCD_CONVERT_TO_BUS_MEM( index,pBuffer) & 0xFFF), BUFFERPOINTER_CURRENT_OFFSET); /* Fill the number of bytes to transfer - * Totally 5 * 4K bytes can be * transferred using 1 qTD. */ actualSize = (uSize <= (USB_EHCD_QTD_MAX_TRANSFER_SIZE - USB_EHCD_GET_BITFIELD(index, QTD, pQTD->uBufferPagePointerList[0], BUFFERPOINTER_CURRENT_OFFSET))) ? uSize:(USB_EHCD_QTD_MAX_TRANSFER_SIZE - USB_EHCD_GET_BITFIELD(index, QTD, pQTD->uBufferPagePointerList[0], BUFFERPOINTER_CURRENT_OFFSET)); pQTD->uBytesToTransfer = actualSize; /* If uSize is more than BytesToTransfer for this QTD
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -