📄 usbuhcdscheduleqsupport.c
字号:
/* * Check if the transfered length is not equal to 0 bytes * and if the TD has been processed by the host controller */ temptd = (USB_UHCD_TD *) FROM_PCIPTR(TO_PCIPTR(td)); len = USBUHCD_TDCS_ACTLEN(FROM_LITTLEL(temptd->dWord1Td)); if (len != 0x7FF && (FROM_LITTLEL(temptd->dWord1Td) & USBUHCD_TDCS_STS_ACTIVE) == 0) { OS_LOG_MESSAGE_MEDIUM(UHCD,"Checking transfer length\n",0,0,0,0); /* Record the transfered length */ transferedLen += len + 1; } /* If the tail is not reached, move to the next element */ td = td->hNextTd; } while (td != niRequest->tail->hNextTd); OS_LOG_MESSAGE_MEDIUM(UHCD,"Exiting usbUhcdGetTransferLength()\n",0,0,0,0); /* Return the transferred length */ return transferedLen; }/* End of usbUhcdGetTransferLength() *//***************************************************************************** usbUhcdCanIsoBeAccomodated - determines Isochronous transfer accomodation** This function is used to determine whether the Isochronous transfer can* be accomodated, called by usbUhcdIsBandwidthAvailable.** RETURNS: FALSE if isochronous endpoint cannot be accomodated.** ERRNO:* None.** \NOMANUAL*/BOOLEAN usbUhcdCanIsoBeAccomodated ( INT32 bwReqd, INT32 startIndex, INT32 maxNumOfItd, USB_UHCD_PERIODIC_TABLE * usbUhcdTable, USB_UHCD_PERIODIC_TREE * usbUhcdTree ) { /* To hold the index value */ INT32 i = 0; /* To hold the index into the number of isochronous TDs */ INT32 n = 0; OS_LOG_MESSAGE_MEDIUM(UHCD,"Entering usbUhcdCanIsoBeAccomodated()\n",0,0,0,0); /* * From the desired position, till all desired positions * are scanned, check if the isochronous TD insertion disturbs the maximum * BW condition of the tree */ for (i = startIndex, n = 0; n < maxNumOfItd; ++n) { /* If BW is exceeded, return error from the function */ if (usbUhcdTable[i].bandWidth + usbUhcdFindTreeBw(usbUhcdFindQlinkToTree(i), usbUhcdTree)+ bwReqd + USB_UHCD_SAFETY_MARGIN >= USB_UHCD_NINETY_PERCENT_BW) { OS_LOG_MESSAGE_MEDIUM(UHCD,"BW exceeded\n",0,0,0,0); return(FALSE); } /* If not, move on to the next TD */ else { OS_LOG_MESSAGE_MEDIUM(UHCD,"Moving to next TD\n",0,0,0,0); i++; if (i > 1023) { i=0; } }/* End of else */ }/* End of for () */ OS_LOG_MESSAGE_MEDIUM(UHCD,"Exiting usbUhcdCanIsoBeAccomodated\n",0,0,0,0); /* Return TRUE */ return(TRUE); }/* End of usbUhcdCanIsoBeAccomodated() *//***************************************************************************** usbUhcdLinkItds - links the isochronous TDs** This function is used to link the isochronous TDs to the HC list. This adds * each TD to the periodic table, called by UHCD_SubmitURB.** RETURNS: N/A** ERRNO:* None.** \NOMANUAL*/VOID usbUhcdLinkItds ( UINT8 BusIndex, USB_UHCD_TD *itd, INT32 startIndex ) { /* Copy the start index in the local variable */ INT32 index=startIndex; /* To hold the dword 0 */ UINT32 dword0 = 0; /* To store the pointer to the previous isochronous TD */ USB_UHCD_TD *prevItd = NULL; OS_LOG_MESSAGE_MEDIUM(UHCD,"Entering usbUhcdLinkItds\n",0,0,0,0); /* Check if the pointer is valid */ if (g_pUHCDData == NULL) { OS_LOG_MESSAGE_HIGH(UHCD,"HCD data is NULL\n",0,0,0,0); return; } /* This loop will be executed till all the isochronous TDs are linked */ while (itd != NULL) { /* * Get the pointer to the iTD in the * index specified in the periodic table */ prevItd = (USB_UHCD_TD *)(g_pUHCDData[BusIndex]->usbUhcdTable[index].td); /* Invalidate the cache */ DMA_INVALIDATE(prevItd, sizeof(USB_UHCD_TD)); /* Update link pointer of the isochronous TD */ itd->dWord0Td = prevItd->dWord0Td; /* * Indicate whether the next element is a QH or TD by copying the value * in the previous TD */ /* Update the previous TD element */ itd->hPrevTd = prevItd; /* Update the next TD pointer */ itd->hNextTd = prevItd->hNextTd; /* Update the next TD's previous pointer */ if (itd->hNextTd) { OS_LOG_MESSAGE_MEDIUM(UHCD,"Updating the next TD's previous pointer\n",0,0,0,0); itd->hNextTd->hPrevTd = itd; } /* Flush the contents of the cache to the RAM */ DMA_FLUSH(itd, sizeof(USB_UHCD_TD)); /* Update the next pointer of the previous pointer */ prevItd->hNextTd = itd; /* Update the HC TD's link pointer */ dword0 = 0; dword0 &= ~(USBUHCD_LINK_PTR_MASK); dword0 |= USBUHCD_LINK_PTR_FMT((unsigned)itd >> 4); dword0 = USB_UHCD_CONVERT_TO_BUS_MEM( BusIndex, (PVOID)dword0); /* Indicate that the previous TD is not the last element */ dword0 &=~(USBUHCD_LINK_QH); dword0 = USB_UHCD_SWAP_DATA(BusIndex, dword0); prevItd->dWord0Td = dword0; /* Flush the contents to the RAM */ DMA_FLUSH(prevItd, sizeof(USB_UHCD_TD)); /* Update the itd pointer to point to the next element */ itd = itd->vNextTd; /* Move on to the next point of linkage */ index++; /* If the index exceeds the maximum framelist number list, rollover */ if (index > 1023) { OS_LOG_MESSAGE_MEDIUM(UHCD,"Index exceeds max framelist number\n",0,0,0,0); index = 0; } }/* End of while () */ OS_LOG_MESSAGE_MEDIUM(UHCD,"Exiting usbUhcdLinkItds()\n",0,0,0,0); }/* End of usbUhcdLinkItds() *//***************************************************************************** usbUhcdUnlinkItds - unlinks and frees the isochronous TDs** This function is used to unlink and free up the iTDs from the periodic * table, called by uhc_ProcessCompletedTDs.** RETURNS: N/A** ERRNO:* None.** \NOMANUAL*/VOID usbUhcdUnlinkItds ( PUHCD_DATA pHCDData, USB_UHCD_TD *itd, BOOLEAN freeTds ) { /* To hold the temporary TD pointer */ USB_UHCD_TD *temp = NULL; OS_LOG_MESSAGE_MEDIUM(UHCD,"Entering usbUhcdUnlinkItds()\n",0,0,0,0); /* This loop will be executed till all the isochronous TDs are unlinked */ while (itd != NULL) { /* Indicate that the previous element is the last element in the list */ /* itd->hPrevTd->dWord0Td.t = 1; */ itd->hPrevTd->dWord0Td |=USB_UHCD_SWAP_DATA(pHCDData->busIndex, USBUHCD_LINK_TERMINATE); /* Update the HC TD's link pointer */ itd->hPrevTd->dWord0Td = itd->dWord0Td; itd->hPrevTd->dWord0Td &= USB_UHCD_SWAP_DATA(pHCDData->busIndex, ~(USBUHCD_LINK_TERMINATE)); DMA_FLUSH(itd->hPrevTd, sizeof(USB_UHCD_TD)); /* Update the next element pointers of the previous pointer */ itd->hPrevTd->hNextTd = itd->hNextTd; /* * Update the next element's previous pointer to point to the * itd's previous pointer */ if (itd->hNextTd) { OS_LOG_MESSAGE_MEDIUM(UHCD,"Update pointers\n",0,0,0,0); itd->hNextTd->hPrevTd = itd->hPrevTd; } /* Store the next pointer in a temporary variable */ temp = itd->vNextTd; if (freeTds) { /* Free up the memory allocated for the iTD */ UHCI_FREE ((UCHAR*)itd - itd->offsetForFreeing); } /* Update the new itd as the value stored in the temporary variable */ itd = temp; }/* End of while () */ }/* End of usbUhcdUnlinkItds() *//***************************************************************************** usbUhcdGetIsoTransferLength - gets the isochronous transfer length** This routine gets the isochronous transfer length.** RETURNS: UINT the transfer length** ERRNO:* None.** \NOMANUAL*/VOID usbUhcdGetIsoTransferLength ( UINT32 uBusIndex, USB_UHCD_ISO_REQUEST_QUEUE *iRequest ) { /* To hold the pointer to the TD */ USB_UHCD_TD *td = NULL; /* To hold the pointer to the Urb */ USBHST_URB *pUrb = iRequest->pUrb; /* To hold Isoc Specific information */ pUSBHST_ISO_PACKET_DESC pIsocPackets = (pUSBHST_ISO_PACKET_DESC) pUrb->pTransferSpecificData; /* Copy the head of the isochronous request queue */ td = iRequest->head; OS_LOG_MESSAGE_MEDIUM(UHCD,"Entering usbUhcdGetIsoTransferLength()\n",0,0,0,0); /* * This loop adds up the transfer length * starting from head to tail of the request queue */ do { UINT32 len; /* Update the length Information on a per TD basis */ /* if actual length not equal to zero */ len = USBUHCD_TDCS_ACTLEN(USB_UHCD_SWAP_DATA(uBusIndex, td->dWord1Td)); if (len != 0x7FF) { OS_LOG_MESSAGE_MEDIUM(UHCD,"Updating transfer length variable\n",0,0,0,0); /* Update the transfered length */ pIsocPackets->uLength = len + 1 ; } else{ /* ulength is zero */ pIsocPackets->uLength = 0; } /* If the tail is not reached, move on to the next TD */ if (td != iRequest->tail) { OS_LOG_MESSAGE_MEDIUM(UHCD,"Tail not reached\n",0,0,0,0); td = td->vNextTd; /* Increment to the next Isoc packet */ pIsocPackets++; } else { OS_LOG_MESSAGE_MEDIUM(UHCD,"Tail reached break\n",0,0,0,0); break; } } while (1); OS_LOG_MESSAGE_MEDIUM(UHCD,"Exiting usbUhcdGetIsoTransferLength()\n",0,0,0,0); return; }/* End of usbUhcdGetIsoTransferLength() *//***************************************************************************** usbUhcdMakeTDLE - convert the members of TD to Little Endian ** This routine converts the members of TD to Little Endian .** RETURNS: NA** ERRNO:* None.** \NOMANUAL*/void usbUhcdMakeTDLE ( UINT32 uBusIndex, PUSB_UHCD_TD td ) { td->dWord0Td = USB_UHCD_SWAP_DATA(uBusIndex, td->dWord0Td); td->dWord1Td = USB_UHCD_SWAP_DATA(uBusIndex, td->dWord1Td); td->dWord2Td = USB_UHCD_SWAP_DATA(uBusIndex, td->dWord2Td); td->dWord3Td = USB_UHCD_SWAP_DATA(uBusIndex, td->dWord3Td); }/***************************************************************************** usbUhcdMakeQDLE - convert the members of TD to Little Endian ** This routine converts the members of TD to Little Endian.** RETURNS: NA** ERRNO:* None.** \NOMANUAL*/void usbUhcdMakeQDLE ( UINT32 uBusIndex, PUSB_UHCD_QH qh ) { qh->dWord0Qh = USB_UHCD_SWAP_DATA(uBusIndex, qh->dWord0Qh); qh->dWord1Qh = USB_UHCD_SWAP_DATA(uBusIndex, qh->dWord1Qh); }/***************************************************************************** usbUhcdMakeFrameelementLE - convert the frame element to Little Endian ** This routine converts the specificed frame element to Little Endian.** RETURNS: NA** ERRNO:* None.** \NOMANUAL*/void usbUhcdMakeFrameelementLE ( UINT32 uBusIndex, USB_UHCD_FRAME_LIST * pframeList, UINT32 index ) { pframeList->pfl[index] = USB_UHCD_SWAP_DATA(uBusIndex, pframeList->pfl[index]); }/********************* End of File UHCD_ScheduleQsupport.c *******************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -