📄 usbuhcdschedulequeue.c
字号:
/* Create the QH */ qh = usbUhcdFormEmptyQh(); /* Check if memory allocation is successful */ if (qh == NULL) { OS_LOG_MESSAGE_MEDIUM(UHCD,"memory allocation unsuccessful\n",0,0,0,0); OS_FREE(pHCDData->usbUhcdTable); UHCI_FREE(pHCDData->forFreeing); UHCI_FREE((UCHAR*)pHCDData->usbUhcdCQh - pHCDData->usbUhcdCQh->offsetForFreeing); UHCI_FREE((UCHAR*)pHCDData->usbUhcdBQh - pHCDData->usbUhcdBQh->offsetForFreeing ); UHCI_FREE((UCHAR*)pHCDData->usbUhcdBRQh->td - pHCDData->usbUhcdBRQh->td->offsetForFreeing); UHCI_FREE((UCHAR*)pHCDData->usbUhcdBRQh - pHCDData->usbUhcdBRQh->offsetForFreeing ); while (i) { i--; UHCI_FREE((UCHAR*)pHCDData->usbUhcdTree[i].qh - pHCDData->usbUhcdTree[i].qh->offsetForFreeing ); } OS_FREE(pHCDData->usbUhcdTree); return(FALSE); } /* Make the previous pointer as NULL */ qh->prevQh = NULL; /* Make the tree element's QH point to the allocated QH */ pHCDData->usbUhcdTree[i].qh = qh; /* Initialise the tree element's BW to 0 */ pHCDData->usbUhcdTree[i].bandWidth = 0; /* If the QH is the tip of the tree, make it point to the control QH */ if (i == 0) { OS_LOG_MESSAGE_MEDIUM(UHCD,"QH is the tip of tree\n",0,0,0,0); qh->nextQh = pHCDData->usbUhcdCQh; } /* If it is not the tip of the tree, update the link element index */ else { linkIndex = usbUhcdFindLinkForQh(i); qh->nextQh = (USB_UHCD_QH *) pHCDData->usbUhcdTree[linkIndex].qh; } /* update the link pointers */ qh->dWord0Qh &= ~(USBUHCD_LINK_PTR_MASK); qh->dWord0Qh |= USBUHCD_LINK_PTR_FMT(((unsigned) qh->nextQh) >> 4); /* Indicate that this is not the last element in the schedule */ qh->dWord0Qh &= ~(USBUHCD_LINK_TERMINATE); qh->dWord0Qh = USB_UHCD_CONVERT_TO_BUS_MEM( pHCDData->busIndex, (PVOID)qh->dWord0Qh); /* Indicate that the next element in the schedule is a QH */ qh->dWord0Qh |= USBUHCD_LINK_QH; usbUhcdMakeQDLE ( pHCDData->busIndex, qh); }/* End of for () */ /* Form the static isochronous TDs */ for (i = 0; i < 1024; ++i) { /* Create an empty isochronous TD */ itd = usbUhcdFormEmptyTd ((UINT32)NULL); /* Check if memory allocation is successful */ if (itd == NULL) { OS_LOG_MESSAGE_MEDIUM(UHCD,"Unable to allocate mem for itd\n",0,0,0,0); UHCI_FREE(pHCDData->forFreeing); UHCI_FREE((UCHAR*)pHCDData->usbUhcdCQh - pHCDData->usbUhcdCQh->offsetForFreeing); UHCI_FREE((UCHAR*)pHCDData->usbUhcdBQh - pHCDData->usbUhcdBQh->offsetForFreeing ); UHCI_FREE((UCHAR*)pHCDData->usbUhcdBRQh->td - pHCDData->usbUhcdBRQh->td->offsetForFreeing); UHCI_FREE((UCHAR*)pHCDData->usbUhcdBRQh - pHCDData->usbUhcdBRQh->offsetForFreeing ); while (i) { i--; UHCI_FREE((UCHAR*)pHCDData->usbUhcdTable[i].td - pHCDData->usbUhcdTable[i].td->offsetForFreeing ); } OS_FREE(pHCDData->usbUhcdTree); OS_FREE(pHCDData->usbUhcdTable); return(FALSE); } /* Initialise the status field */ itd->dWord1Td &= ~(USBUHCD_TDCS_STS_MASK); /* Indicate that this is an isochronous TD */ itd->dWord1Td |= USBUHCD_TDCS_ISOCH; /* PID is OUT; if pid is invalid UHC will weep */ itd->dWord2Td &= ~(USBUHCD_TDTOK_PID_MASK); itd->dWord2Td |= USBUHCD_TDTOK_PID_FMT(0xE1); /* Update the link pointers of the TD */ linkIndex = usbUhcdFindQlinkToTree(i); itd->dWord0Td &= ~(USBUHCD_LINK_PTR_MASK); itd->dWord0Td |= USBUHCD_LINK_PTR_FMT( ((unsigned) (pHCDData->usbUhcdTree[linkIndex].qh)) >> 4); /* Indicate that this is not the last element in the schedule */ itd->dWord0Td &= ~(USBUHCD_LINK_TERMINATE); itd->dWord0Td = USB_UHCD_CONVERT_TO_BUS_MEM( pHCDData->busIndex, (PVOID)itd->dWord0Td); /* Update the next element of the schedule is a QH */ itd->dWord0Td |= USBUHCD_LINK_QH; usbUhcdMakeTDLE (pHCDData->busIndex, itd); /* Update the fields of the usbUhcdTable - Start */ /* Store the pointer as a periodic table array element */ pHCDData->usbUhcdTable[i].td = itd; /* Initialise the bandwidth reserved */ pHCDData->usbUhcdTable[i].bandWidth = 0; /* Update the fields of the usbUhcdTable - End */ /* Update the first list element of the Host Controller - Start */ /* Update the list pointer to the corresponding periodictable element */ pHCDData->usbUhcdFrameList->pfl[i] &= ~(USBUHCD_LINK_PTR_MASK); pHCDData->usbUhcdFrameList->pfl[i] |= USBUHCD_LINK_PTR_FMT(((unsigned)itd ) >> 4); /* Indicate that the next element in the schedule is a TD */ pHCDData->usbUhcdFrameList->pfl[i] &= ~(USBUHCD_LINK_QH); /* Indicate that this is not the last element in the schedule */ pHCDData->usbUhcdFrameList->pfl[i] &= ~(USBUHCD_LINK_TERMINATE); pHCDData->usbUhcdFrameList->pfl[i] = USB_UHCD_CONVERT_TO_BUS_MEM( pHCDData->busIndex, (PVOID)pHCDData->usbUhcdFrameList->pfl[i]); usbUhcdMakeFrameelementLE( pHCDData->busIndex, pHCDData->usbUhcdFrameList,i); /* Update the first list element of the Host Controller - End */ } OS_LOG_MESSAGE_MEDIUM(UHCD,"Exiting usbUhcdCreateFrameList()\n",0,0,0,0); /* Return success from the function */ return TRUE; }/* End of usbUhcdCreateFrameList() *//***************************************************************************** usbUhcdDeleteFrameList - deletes frame list.** The HCD maintains - a tree of 256 elements to maintain the* bandwidth usage in every frame for the interrupt transfers.* - an array of 1024 static isochronous Transfer Descriptor elements.* This function deallocates memory for the data structures.** RETURNS: False if the frame list deletion is a failure** ERRNO:* None.** \NOMANUAL*/BOOLEAN usbUhcdDeleteFrameList ( PUHCD_DATA pHCDData ) { UINT16 i = 0; OS_LOG_MESSAGE_MEDIUM(UHCD,"Entering usbUhcdDeleteFrameList()\n",0,0,0,0); if (pHCDData->usbUhcdTree) { for (i=0; i<255; ++i) { if (pHCDData->usbUhcdTree[i].qh) UHCI_FREE ((UCHAR*)pHCDData->usbUhcdTree[i].qh - pHCDData->usbUhcdTree[i].qh->offsetForFreeing ); } OS_FREE(pHCDData->usbUhcdTree); } if (pHCDData->usbUhcdTable) { for (i=0; i < 1024; ++i) { if (pHCDData->usbUhcdTable[i].td) UHCI_FREE((UCHAR*)pHCDData->usbUhcdTable[i].td - pHCDData->usbUhcdTable[i].td->offsetForFreeing ); } OS_FREE(pHCDData->usbUhcdTable); } if (pHCDData->usbUhcdCQh) UHCI_FREE((UCHAR*)pHCDData->usbUhcdCQh - pHCDData->usbUhcdCQh->offsetForFreeing); if (pHCDData->usbUhcdBQh) UHCI_FREE((UCHAR*)pHCDData->usbUhcdBQh - pHCDData->usbUhcdBQh->offsetForFreeing); if (pHCDData->usbUhcdBRQh->td) UHCI_FREE((UCHAR*)pHCDData->usbUhcdBRQh->td - pHCDData->usbUhcdBRQh->td->offsetForFreeing); if (pHCDData->usbUhcdBRQh) UHCI_FREE((UCHAR*)pHCDData->usbUhcdBRQh - pHCDData->usbUhcdBRQh->offsetForFreeing); UHCI_FREE (pHCDData->forFreeing); OS_LOG_MESSAGE_MEDIUM(UHCD,"Exiting usbUhcdDeleteFrameList\n",0,0,0,0); /* Return success from the function */ return TRUE; }/* End of usbUhcdDeleteFrameList() *//***************************************************************************** usbUhcdDeletePipe - deletes the pipe.** This function is used to delete the HCD maintained pipe and the QH created* for the pipe.** RETURNS: False if the pipe deletion is a failure** ERRNO:* None.** \NOMANUAL*/USBHST_STATUS usbUhcdDeletePipe ( UINT8 uBusIndex, UINT32 uPipeHandle ) { /* Pointer to the host controller data stucture */ PUHCD_DATA pHCDData = g_pUHCDData[uBusIndex]; /* To hold the pipe object to be deleted */ USB_UHCD_HCD_PIPE *pipeToDel = NULL; /* To hold the pipe object previous to the pipe to be deleted */ USB_UHCD_HCD_PIPE *prev = NULL; /* To hold the pipe object which is used for scanning the list of pipes */ USB_UHCD_HCD_PIPE *scanPipe = NULL; /* Count for the loop */ UINT32 i; /* WindView Instrumentation */ USB_HCD_LOG_EVENT( USB_UHCI_WV_TRANSFER, "usbUhcdDeletePipe() starts", USB_UHCD_WV_FILTER); OS_LOG_MESSAGE_MEDIUM(UHCD,"Entering usbUhcdDeletePipe()\n",0,0,0,0); /* Find the HCD maintained Pipe object to be deleted */ pipeToDel = (USB_UHCD_HCD_PIPE *)uPipeHandle; if (pipeToDel == NULL) { OS_LOG_MESSAGE_MEDIUM(UHCD,"Unable to locate pipe\n",0,0,0,0); /* Return error */ return USBHST_INVALID_REQUEST; }/* End of if( pipeToDel == NULL) */ /* Check if the request is for the Root hub and route it */ if (pipeToDel->deviceNum == pHCDData->rootHub.uDeviceAddress) { /* To hold the status of the request */ USBHST_STATUS status = USBHST_FAILURE; OS_LOG_MESSAGE_MEDIUM(UHCD,"Request is for root hub\n",0,0,0,0); status = usbUhcdRhDeletePipe(pHCDData,(UINT32)uPipeHandle); return status; } /* * Initialise the scanPipe variable to be the first element of the * list of HCD maintained pipes to scan the list. */ scanPipe = pHCDData->usbUhcdPipe; /* Search for the pipe to be deleted in the list maintained by HCD */ while (scanPipe != NULL && scanPipe != pipeToDel) { prev = scanPipe; scanPipe = scanPipe->next; } /* Check whether scanpipe is NULL .. Added by Sapna */ /*OS_ASSERT(scanPipe != NULL);*/ if (NULL == scanPipe) { OS_LOG_MESSAGE_HIGH(UHCD,"Pipe handle passed for Deletion is Invalid\n" ,0,0,0,0); /* Return Error */ return USBHST_INVALID_REQUEST; } usbUhcdEnterCritical (pHCDData); /* If the pipe is Non Isochronous delete the QH linked with the pipe */ if (pipeToDel->endPointType != PIPE_ISOCHRONOUS) { /* Unlink the QH from the HC's list - Start */ /* Indicate that the previous QH is the last QH in the schedule */ /* pipeToDel->qh->prevQh->dWord0Qh.t = 1; */ pipeToDel->qh->prevQh->dWord0Qh |= USB_UHCD_SWAP_DATA(uBusIndex, USBUHCD_LINK_TERMINATE); /* * Update the next link pointer in the previous QH pointer * to point to the deleted QH's next link pointer */ pipeToDel->qh->prevQh->dWord0Qh = pipeToDel->qh->dWord0Qh; /* Update the HCD maintained next pointers */ pipeToDel->qh->prevQh->nextQh = pipeToDel->qh->nextQh; /* Update the previous QH pointers */ if (pipeToDel->qh->nextQh && pipeToDel->qh->nextQh->prevQh) { OS_LOG_MESSAGE_MEDIUM(UHCD,"Update pointers\n",0,0,0,0); pipeToDel->qh->nextQh->prevQh = pipeToDel->qh->prevQh; } /* Unlink the QH from the HC's list - End */ /* wait for some time (atleast 1ms) so that its safe to delete */ OS_DELAY_MS(2); } /* Initialise the prev pointer */ prev = NULL; /* * Initialise the scanPipe variable to be the first element of the * list of HCD maintained pipes to scan the list. */ scanPipe = pHCDData->usbUhcdPipe; /* Search for the pipe to be deleted in the list maintained by HCD */ while (scanPipe != NULL && scanPipe != pipeToDel) { prev = scanPipe; scanPipe = scanPipe->next; } /* Check whether scanpipe is NULL .. Added by Sapna */ /*OS_ASSERT(scanPipe != NULL);*/ if (NULL == scanPipe) { OS_LOG_MESSAGE_HIGH(UHCD,"ERROR Scan pipe NULL and delete pipe called\n",0,0,0,0); /* Leave critical section */ usbUhcdLeaveCritical(pHCDData); return USBHST_INVALID_REQUEST; } /* Check if the pipe being deleted is the first pipe */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -