📄 usbuhcdscheduleqsupport.c
字号:
pUSBHST_ISO_PACKET_DESC pIsocPackets = (pUSBHST_ISO_PACKET_DESC) purb->pTransferSpecificData; /* Call the function to create the 1st TD needed for the transfer */ currentTd = *head = usbUhcdFormEmptyTd ((UINT32)targetPipe); OS_LOG_MESSAGE_MEDIUM(UHCD,"Entering usbUhcdMakeTds()\n",0,0,0,0); /* If unable to create the TD, return FALSE */ if (currentTd == NULL) { OS_LOG_MESSAGE_MEDIUM(UHCD,"Unable to create TD\n",0,0,0,0); return FALSE; } /* * This loop will create TDs based on the number of * bytes to be transmitted */ while (numberOfTDs) { /* Set the buffer pointer of the TD */ /*currentTd->dWord3Td.bufferPointer = purb->pTransferBuffer + pIsocPackets->uOffset ;*/ currentTd->dWord3Td = USB_UHCD_CONVERT_TO_BUS_MEM ( uBusIndex, ((UINT32)(purb->pTransferBuffer) + pIsocPackets->uOffset)); /* Set the Maxlength Field of the TD */ currentTd->dWord2Td &= ~(USBUHCD_TDTOK_MAXLEN_MASK); currentTd->dWord2Td |= USBUHCD_TDTOK_MAXLEN_FMT(pIsocPackets->uLength); /* Check if the bytes to transfer is less than maximum packet size */ OS_LOG_MESSAGE_MEDIUM(UHCD,"pipe is Isochronous -- no toggle\n",0,0,0,0); /* Toggle bit is zero */ currentTd->toggle = 0; currentTd->dWord2Td &= ~(USBUHCD_TDTOK_DATA_TOGGLE); /* Update PID field of the TD */ currentTd->dWord2Td &= ~(USBUHCD_TDTOK_PID_MASK); if (targetPipe ->endPointDirection == 1) currentTd->dWord2Td |= USBUHCD_TDTOK_PID_FMT(0x69); else currentTd->dWord2Td |= USBUHCD_TDTOK_PID_FMT(0xE1); /* Decrement the TD count */ numberOfTDs--; /* Increment the pointer to the next Isoc data */ pIsocPackets++; /* More TDs required */ if (numberOfTDs) { /* Create another TD*/ currentTd->vNextTd = usbUhcdFormEmptyTd ((UINT32)targetPipe); /* If unable to allocate memory for the TD */ if (currentTd->vNextTd == NULL) { OS_LOG_MESSAGE_MEDIUM(UHCD,"Unable to allocate memoery \n",0,0,0,0); /* Clean up memory allocated for the TD till now */ for (currentTd = *head; currentTd != NULL;) { temp = currentTd->vNextTd; UHCI_FREE((UCHAR*)currentTd - currentTd->offsetForFreeing); currentTd = temp; } /* Return FALSE */ return FALSE; } /* Store the previous element of the next TD */ currentTd->vNextTd->vPrevTd = currentTd; /* Update the current pointer */ currentTd = currentTd->vNextTd; /* Make the next pointer as NULL */ currentTd->vNextTd = NULL; }/* End of if() */ else { /* This is the last TD */ currentTd->vNextTd = NULL; } }/* End of while () */ /* Update the tail pointer so as to make it point to the last TD */ *tail = currentTd; OS_LOG_MESSAGE_MEDIUM(UHCD,"Exiting usbUhcdMakeTds()\n",0,0,0,0); /* Return TRUE */ return(TRUE); }/* End of usbUhcdMakeIsocTds() *//***************************************************************************** usbUhcdFillNonisoStatus - fills the status of a non isochronous** This routine fills the status of a non isochronous.** RETURNS: N/A** ERRNO:* None.** \NOMANUAL*/VOID usbUhcdFillNonisoStatus ( UINT32 status, INT8 *statusInUrb, UINT8 markedForDel, UINT8 reqThatHalted ) { OS_LOG_MESSAGE_MEDIUM(UHCD,"Entering usbUhcdFillNonisoStatus()\n",0,0,0,0); /* * If the pipe is being deleted and the pipe is still active * and the request did not result in a stall */ if (markedForDel && (status & USBUHCD_TDCS_STS_ACTIVE) && !reqThatHalted) { OS_LOG_MESSAGE_MEDIUM(UHCD,"Pipe Deleted\n",0,0,0,0); /* record status as cancelled */ *statusInUrb = USBHST_TRANSFER_CANCELLED; } /* If the pipe is not being deleted */ else { OS_LOG_MESSAGE_MEDIUM(UHCD,"Pipe not deleted\n",0,0,0,0); /* If pipe has stalled */ if ((status & USBUHCD_TDCS_STS_STALLED) || reqThatHalted) { OS_LOG_MESSAGE_MEDIUM(UHCD,"Pipe has stalled\n",0,0,0,0); *statusInUrb = USBHST_STALL_ERROR ; } /* If Data underrun */ else if (status & USBUHCD_TDCS_STS_DBUFERR) { OS_LOG_MESSAGE_MEDIUM(UHCD,"data underrun\n",0,0,0,0); *statusInUrb = USBHST_DATA_UNDERRUN_ERROR; } /* If Babble error */ else if (status & USBUHCD_TDCS_STS_BABBLE) { OS_LOG_MESSAGE_MEDIUM(UHCD,"Babble error\n",0,0,0,0); *statusInUrb = USBHST_FAILURE; } /* If NAK */ else if (status & USBUHCD_TDCS_STS_NAK) { OS_LOG_MESSAGE_MEDIUM(UHCD,"NAK\n",0,0,0,0); *statusInUrb = USBHST_FAILURE; } /* If Time out error */ else if (status & USBUHCD_TDCS_STS_TIME_CRC) { OS_LOG_MESSAGE_MEDIUM(UHCD,"Time out\n",0,0,0,0); *statusInUrb = USBHST_TIMEOUT; } /* If Bit stuff error */ else if (status & USBUHCD_TDCS_STS_BITSTUFF) { OS_LOG_MESSAGE_MEDIUM(UHCD,"Bit stuff error\n",0,0,0,0); *statusInUrb = USBHST_FAILURE; } /* Everything is OK, normal transfer completion */ else { OS_LOG_MESSAGE_MEDIUM(UHCD,"Normal transfer completion\n",0,0,0,0); *statusInUrb = USBHST_SUCCESS; } }/* End of else */ OS_LOG_MESSAGE_MEDIUM(UHCD,"Exiting usbUhcdFillNonisoStatus()\n",0,0,0,0); }/* End of usbUhcdFillNonisoStatus() *//***************************************************************************** usbUhcdFillIsoStatus - fills the status of a isochronous** This function is used to fill the status of a Isochronous data transfer* upon completion, called by uhc_ProcessCompletedTDs.** RETURNS: N/A** ERRNO:* None** \NOMANUAL*/VOID usbUhcdFillIsoStatus ( UINT32 uBusIndex, USBHST_STATUS status, pUSBHST_URB pUrb, USB_UHCD_ISO_REQUEST_QUEUE *iReQ ) { /* Since it is an Isoc request the pUrb->pTransferSpecificData contains * the Isoc packets information */ pUSBHST_ISO_PACKET_DESC pIsocPackets = NULL; /* To hold the TD for the current request */ PUSB_UHCD_TD iTD = NULL; /* To hold the number of TDs for the Request */ UINT16 uCount = pUrb->uNumberOfPackets; UINT32 tdstatus; pIsocPackets = (pUSBHST_ISO_PACKET_DESC)pUrb->pTransferSpecificData; OS_LOG_MESSAGE_MEDIUM(UHCD,"Entering usbUhcdFillIsoStatus()\n",0,0,0,0); /* Updating the status on a per TD basis */ iTD = iReQ->head; while (uCount) { /* Update the status */ DMA_INVALIDATE(iTD, sizeof(USB_UHCD_TD)); tdstatus = USB_UHCD_SWAP_DATA(uBusIndex, iTD->dWord1Td); /* Check for the various error conditions */ if (tdstatus & USBUHCD_TDCS_STS_STALLED) { OS_LOG_MESSAGE_MEDIUM(UHCD,"Pipe has stalled\n",0,0,0,0); pIsocPackets->nStatus = USBHST_STALL_ERROR ; } /* If Data underrun */ else if (tdstatus & USBUHCD_TDCS_STS_DBUFERR) { OS_LOG_MESSAGE_MEDIUM(UHCD,"data underrun\n",0,0,0,0); pIsocPackets->nStatus = USBHST_DATA_UNDERRUN_ERROR; } /* If Babble error */ else if (tdstatus & USBUHCD_TDCS_STS_BABBLE) { OS_LOG_MESSAGE_MEDIUM(UHCD,"Babble error\n",0,0,0,0); pIsocPackets->nStatus = USBHST_STALL_ERROR; } else if (tdstatus & USBUHCD_TDCS_STS_TIME_CRC) { OS_LOG_MESSAGE_MEDIUM(UHCD,"Time out\n",0,0,0,0); pIsocPackets->nStatus = USBHST_FAILURE; } /* If Bit stuff error */ else if (tdstatus & USBUHCD_TDCS_STS_BITSTUFF) { OS_LOG_MESSAGE_MEDIUM(UHCD,"Bit stuff error\n",0,0,0,0); pIsocPackets->nStatus = USBHST_FAILURE; } /* Everything is OK, normal transfer completion */ else { OS_LOG_MESSAGE_MEDIUM(UHCD,"Normal transfer completion\n",0,0,0,0); pIsocPackets->nStatus = USBHST_SUCCESS; } /* Point to the next TD */ iTD = iTD->vNextTd; /* Point to the next Isoc packet */ pIsocPackets++; /* Decrement the count */ uCount--; }/* End while (uCount)*/ /* Update the status of the URB with status of Tail*/ pIsocPackets--; pUrb->nStatus = pIsocPackets->nStatus; OS_LOG_MESSAGE_MEDIUM(UHCD,"Exiting usbUhcdFillIsoStatus()\n",0,0,0,0); } /* End usbUhcdFillIsoStatus() *//***************************************************************************** usbUhcdFreeTds - frees up memory allocated for a chain of TDs** This routine frees up memory allocated for a chain of TDs.** RETURNS: N/A** ERRNO:* None.** \NOMANUAL*/VOID usbUhcdFreeTds ( USB_UHCD_TD *start, USB_UHCD_TD *stop ) { /* Pointer to the TD */ USB_UHCD_TD *td; /* Pointer to hold the next TD */ USB_UHCD_TD *next; OS_LOG_MESSAGE_MEDIUM(UHCD,"Entering usbUhcdFreeTds()\n",0,0,0,0); /* If the very first TD's addr is NULL, there is nothing to free */ if (start == NULL || stop == NULL) { OS_LOG_MESSAGE_MEDIUM(UHCD,"Tree is empty\n",0,0,0,0); return; } /* Store the start address in the temporary pointer */ td = start; /* CHeck if the request has only one TD... */ if(start == stop) { /* Free up memory allocated for the TD */ UHCI_FREE((UCHAR*)td - td->offsetForFreeing); return; } /* This loop gets executed till the address indicated by stop is reached */ while (1) { /* Record link to next TD */ next = td->hNextTd; /* Free up memory allocated for the TD */ UHCI_FREE((UCHAR*)td - td->offsetForFreeing); /* If the last TD has been freed, break */ if (td == stop || next == NULL) { OS_LOG_MESSAGE_MEDIUM(UHCD,"Last TD is freed\n",0,0,0,0); break; } /* Update the 'td' pointer to the next element pointed */ td = next; OS_LOG_MESSAGE_MEDIUM(UHCD,"Exiting usbUhcdFreeTds\n",0,0,0,0); }/* End of while () */ return; }/* End of usbUhcdFreeTds() *//***************************************************************************** usbUhcdGetTransferLength - determine the number of bytes transfered** This fucntion is used to determine the number of bytes actually* transfered at the end of a transfer.** RETURNS: UINT number of bytes trnasfered** ERRNO:* None.** \NOMANUAL*/UINT usbUhcdGetTransferLength ( USB_UHCD_NON_ISO_REQUEST_QUEUE *niRequest ) { /* To hold the transfer length */ UINT transferedLen=0; /* To hold the pointer to the TD */ USB_UHCD_TD *td = NULL; USB_UHCD_TD *temptd = NULL; UINT32 len; /* Start from the 1st TD in the request queue */ td = niRequest->head; OS_LOG_MESSAGE_MEDIUM(UHCD,"Entering usbUhcdGetTransferLength()\n",0,0,0,0); /* If control pipe, ignore the 1st TD as it is a setup TD */ if (niRequest->pipe->endPointType == PIPE_CONTROL) { OS_LOG_MESSAGE_MEDIUM(UHCD,"Ignoring 1st TD as for Control pipe\n",0,0,0,0); td = td->hNextTd; } /* Scan the entire TD chain till the tail is reached */ do { /* * If pipe is control, break just before the tail * as the tail is for the Status TD */ if (niRequest->pipe->endPointType == PIPE_CONTROL && td == niRequest->tail) { OS_LOG_MESSAGE_MEDIUM(UHCD,"Breaking before tail\n",0,0,0,0); break; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -