📄 hcd_1161.c
字号:
/* Bit 2: Speed */ /* Bit 1..0: MaxPacketSize(9:8) */ /*********************************/ pbyHcdItlBuff[uItlByteCount] = 0; /* Clear the current contents */ byData = (__u8) ((pstCurrentHcdEd->hwINFO & HC_ED_EN) >> 7); /* get endpoint # */ pbyHcdItlBuff[uItlByteCount] |= (byData << 4); /* Move to ptd */ if(uItlIndex == (uLastPtd -1)) { /* Set the PTD as Last PTD */ pbyHcdItlBuff[uItlByteCount] |= PTD_LAST; } if(pstCurrentHcdEd->hwINFO & HC_ED_SPD) { /* Set High Speed Device */ pbyHcdItlBuff[uItlByteCount] |= PTD_SPEED; } /* Set MaxPacketSize(9:8) */ pbyHcdItlBuff[uItlByteCount++] |= (__u8)((uData1 >> 8) & 0x03);/* ISP1161 uses 9..8 */ /*******************************/ /* PTD byte 4 */ /* Bit 7..0: TotalBytes(7:0) */ /*******************************/ /* PTD byte 5 */ /* Bit 3..2: DirectionPID(1:0) */ /* Bit 1..0: TotalBytes(9:8) */ /*******************************/ pbyHcdItlBuff[uItlByteCount++] = 0; /* Clear the current contents */ pbyHcdItlBuff[uItlByteCount] = 0; /* Clear the current contents */ /* For filling the total bytes, we can depend on the CBP and BE as each Iso TD is split to different TD's before filling */ if(pstCurrentHcdGtd->hwCBP != 0) { /* NULL data packet */ uData1 = pstCurrentHcdGtd->hwBE - (pstCurrentHcdGtd->hwCBP+(pstCurrentHcdGtd->hwPSW[0] & 0x0FFF)) + 1; pbyHcdItlBuff[uItlByteCount-1] = (__u8)uData1; /* Fill 0-7 bits */ pbyHcdItlBuff[uItlByteCount] = (__u8)(uData1 >> 8); /* Fill 8-9 bits */ uTotal = uData1; /* total Number of payload bytes */ } else { /* NULL data packet */ uTotal = 0; /* total Number of payload bytes */ } byData = (__u8) (((pstCurrentHcdEd->hwINFO & HC_ED_DIR) >> 9) & 0x0C) ; /* Bit 12..11 in 3..2 */ pbyHcdItlBuff[uItlByteCount++] |= byData; /******************************/ /* PTD byte 6 */ /* Bit 7: Format */ /* Bit 6..0: Function address */ /******************************/ pbyHcdItlBuff[uItlByteCount] = 0; /* Clear the current contents */ /* Format bit is 1 for Isochronous transfers */ pbyHcdItlBuff[uItlByteCount] |= PTD_FORMAT ; /* Set function address */ byData = (__u8)(pstCurrentHcdEd->hwINFO & HC_ED_FA); pbyHcdItlBuff[uItlByteCount++] |= byData ; /**************/ /* PTD byte 7 */ /* Reserved */ /**************/ pbyHcdItlBuff[uItlByteCount++] = 0; /* Clear the current contents */ /* Copy the payload if exists uTotal */ pbyChar = (__u8*)(pstCurrentHcdGtd->hwCBP + (pstCurrentHcdGtd->hwPSW[0] & 0x0FFF) ); if(uTotal) memcpy((pbyHcdItlBuff+uItlByteCount),pbyChar,uTotal); uItlByteCount += uTotal; /* Adjust the uItlByteCount to the next double word boundary */ while(uItlByteCount & (ITL_ALIGNMENT - 1)) { /* Clear the padding byte and advance to next byte */ pbyHcdItlBuff[uItlByteCount++] = 0; } /* Save number of bytes of this PTD+Data */ pstItlTdMapBuffer[uItlIndex].uAtlNodeLength = uItlByteCount - uStartPTDByteCount; uStartPTDByteCount = uItlByteCount; /* Next PTD starts here */ pstCurrentHcdGtd->hwINFO &= ~HC_GTD_CC; /* Clear the original CC */ pstCurrentHcdGtd->hwINFO |= (TD_CC_NOERROR) << 28; /* Move CC into position */ pstCurrentHcdEd->hwHeadP = (pstCurrentHcdGtd->hwNextTD); if(pstCurrentHcdEd->hwINFO & 0x800) { /* ISO OUT, move to done queue */ /* Write the CC part of psw for the td */ pstCurrentHcdGtd->hwPSW[0] = 0; pstCurrentHcdGtd->hwPSW[0] |= (TD_CC_NOERROR) << 12; pstCurrentHcdGtd->hwNextTD = (__u32)pstDoneHead_hcd; pstDoneHead_hcd = pstCurrentHcdGtd; } else { pstCurrentHcdGtd->hwNextTD = (__u32)(aIsoTdMapBuffer[uIsoTdMapBuffSelector].pstIsoInDoneHead); aIsoTdMapBuffer[uIsoTdMapBuffSelector].pstIsoInDoneHead = pstCurrentHcdGtd; iso_in_flag = 0x02; } } /* for uItlIndex */ /* At this point, uAtlByteCount = number of total bytes in the HCD ATL buffer */ aIsoTdMapBuffer[uIsoTdMapBuffSelector].byStatus = (0x01 | iso_in_flag); aIsoTdMapBuffer[uIsoTdMapBuffSelector].uByteCount = uItlByteCount; aIsoTdMapBuffer[uIsoTdMapBuffSelector].uFrameNumber = uFrameNumber +1; /* Dump the HCD ITL buffer to the ISP1161 internal ITL buffer */ /* Pass HCD ITL to ISP1161 internal ITL through the 32-bit ITLBuffer register */ /* Use PIO for the time being. Will use DMA */ fnvIsp1161ItlWrite(pbyHcdItlBuff, uItlByteCount); /* Make sure uItlByteCount is multiple of 4 */ } /* if uItlIndex */ /* Check if transfer is in progress */ fnvIsp1161HcorRead(ohci,uHcHcdControl, &uData1); if (uData1 & OHCI_CTRL_TIP) { /* If the transfer is in progress */ goto End_of_Transfer_List; /* you can not touch ATL */ } /****************************/ /* Transfer list scheduling */ /****************************/Control_Transfer_Scheduling: /* Clear total number of bytes */ tstAtlBridge[0].uAtlNodeLength = 0; /* uPipeHandle field contains total number of bytes */ /* Clear the index of last entry */ tstAtlBridge[0].pstHcdTd = 0; /* pstHcdTd field contains the index of the last entry */ uAtlIndex = 1; /* Starting from 1; index 0 is reserved */ /* Control transfer scheduling */ fnvIsp1161HcorRead(ohci,uHcHcdControl, &uData1); if ((uData1 & OHCI_CTRL_CLE) == 0) goto Bulk_Transfer_Scheduling; fnvIsp1161HcorRead(ohci,uHcHcdCommandStatus, &uData1); if ((uData1 & OHCI_CLF) == 0) goto Bulk_Transfer_Scheduling; pstCurrentHcdEd = ohci->p_ed_controlhead; while( pstCurrentHcdEd != NULL ) { /* If the SKIP bit of the current ED is set, skip it */ if ((pstCurrentHcdEd->hwINFO & OHCI_ED_SKIP) == 0) { /* SKIP bit is not set */ /* Check if this is an empty transfer list under this ED */ /* If head TD pointer is equal to tail TD pointer, it is an empty TD list */ uPhysicalHead = (pstCurrentHcdEd->hwHeadP); uPhysicalTail = (pstCurrentHcdEd->hwTailP); if (uPhysicalHead != uPhysicalTail) { /* Find out the index number of the TD in the HCD GTD pool */ /* Must be greater than 0 */ uPhysical = (pstCurrentHcdEd->hwHeadP); /* Important: mask the CH bits */ if(uPhysical != 0) { uPipeHandle = ((td_t*)uPhysical)->urb->pipe ; tstAtlBridge[uAtlIndex].pstHcdTd = uPhysical; tstAtlBridge[0].pstHcdTd = uAtlIndex; tstAtlBridge[uAtlIndex].uPipeHandle = uPipeHandle; /* Reserved entry (tstAtlBridge[0])is used to save the index to the last item */ uAtlIndex++; } /* if uTdIndex > 0 */ } /* if uEdHeadP != uEdTailP */ } /* if OHCI_ED_SKIP */ /* Advances to next HCD ED in the control transfer ED list */ pstCurrentHcdEd = (ed_t*)(pstCurrentHcdEd->hwNextED); } /* Bulk transfer scheduling */Bulk_Transfer_Scheduling: /* Check if bulk transfer is enabled */ fnvIsp1161HcorRead(ohci,uHcHcdControl, &uData1); if ((uData1 & OHCI_CTRL_BLE) == 0) goto Int_Transfer_Scheduling; /* If bulk transfer is not enabled, don't do it */ /* Check if bulk-list-filled bit is set */ fnvIsp1161HcorRead(ohci,uHcHcdCommandStatus, &uData1); if ((uData1 & OHCI_BLF) == 0) goto Int_Transfer_Scheduling; /* If BLF is not set, don't do it */ /***************** ... Codes for bulk transfer list scheduling ... ******************/ pstCurrentHcdEd = ohci->p_ed_bulkhead ; while ( pstCurrentHcdEd != NULL ) { /* If the SKIP bit of the current ED is set, skip it */ if ((pstCurrentHcdEd->hwINFO & OHCI_ED_SKIP) == 0) { /* SKIP bit is not set */ /* Check if this is an empty transfer list under this ED */ /* If head TD pointer is equal to tail TD pointer, it is an empty TD list */ uPhysicalHead = (pstCurrentHcdEd->hwHeadP); uPhysicalTail = (pstCurrentHcdEd->hwTailP); if (uPhysicalHead != uPhysicalTail) { /* Find out the index number of the TD in the HCD GTD pool */ /* Must be greater than 0 */ uPhysical = (pstCurrentHcdEd->hwHeadP); /* Important: mask the CH bits */ /* TD is found in the HCD GTD pool */ if (uPhysical != 0) { uPipeHandle = ((td_t*)uPhysical)->urb->pipe; tstAtlBridge[uAtlIndex].uPipeHandle = uPipeHandle; tstAtlBridge[uAtlIndex].pstHcdTd = uPhysical; tstAtlBridge[0].pstHcdTd = uAtlIndex; /* Reserved entry (tstAtlBridge[0])is used to save the index to the last item */ uAtlIndex++; } /* if uTdIndex > 0 */ } /* if uEdHeadP != uEdTailP */ } /* if OHCI_ED_SKIP */ /* Advances to next HCD ED in the bulk transfer ED list */ pstCurrentHcdEd = (ed_t*)pstCurrentHcdEd->hwNextED ; } /* Interrupt transfer scheduling */Int_Transfer_Scheduling:// goto Transfer_List_Done; /* Check if periodic transfer (int. and iso. transfer) is enabled */ fnvIsp1161HcorRead(ohci,uHcHcdControl, &uData1); if ((uData1 & OHCI_CTRL_PLE) == 0) goto Transfer_List_Done; /***************** .. Codes for interrupt transfer and IsoChronous list scheduling ... ******************/ uHcdEdIndex = (uFrameNumber & 0x0000001F); pstCurrentHcdEd = ohci->p_int_table[uHcdEdIndex]; while( pstCurrentHcdEd != NULL ) { /* If the SKIP bit of the current ED is set, skip it */ if ((pstCurrentHcdEd->hwINFO & OHCI_ED_SKIP) == 0 && (pstCurrentHcdEd->type == PIPE_INTERRUPT) ) { /* SKIP bit is not set */ /* Check if this is an empty transfer list under this ED */ /* If head TD pointer is equal to tail TD pointer, it is an empty TD list */ uPhysicalHead = (pstCurrentHcdEd->hwHeadP); uPhysicalTail = (pstCurrentHcdEd->hwTailP); if (uPhysicalHead != uPhysicalTail) { /* Find out the index number of the TD in the HCD GTD pool */ /* Must be greater than 0 */ uPhysical = (pstCurrentHcdEd->hwHeadP); /* Important: mask the CH bits */ /* TD is found in the HCD GTD pool */ if (uPhysical != 0) { /* Make up a pipehandle from host ID and ED index */ uPipeHandle = ((td_t*)uPhysical)->urb->pipe ; tstAtlBridge[uAtlIndex].uPipeHandle = uPipeHandle; tstAtlBridge[uAtlIndex].pstHcdTd = uPhysical; tstAtlBridge[0].pstHcdTd = uAtlIndex; /* Reserved entry (tstAtlBridge[0])is used to save the index to the last item */ uAtlIndex++; } /* if uTdIndex > 0 */ } /* if uEdHeadP != uEdTailP */ } /* if OHCI_ED_SKIP */ /* Advances to next HCD ED in the control transfer ED list */ pstCurrentHcdEd = (ed_t*)pstCurrentHcdEd->hwNextED ; } /* Isochronous transfer scheduling */ /* Check if isochronous transfer is enabled */ fnvIsp1161HcorRead(ohci,uHcHcdControl, &uData1); if ((uData1 & OHCI_CTRL_IE) == 0) goto Transfer_List_Done; /***************** ... Codes for isochronous transfer list scheduling ... ******************/Transfer_List_Done: if (tstAtlBridge[0].pstHcdTd > 0) { /* tstAtlBridge[0].pstHcdTd is a reserved entry which contains index to */ /* the last PTD in the tstAtlBridge[] */ uAtlByteCount = 0; /* Offset of the HCD ATL buffer, starting with byte 0 */ uStartPTDByteCount = 0; /* Starting address of a new PTD */ uLastPtd = tstAtlBridge[0].pstHcdTd; /* Last index number of HCD GTD in PTD */ /* Construct HCD ATL buffer */ for (uAtlIndex = 1; uAtlIndex <= uLastPtd; uAtlIndex++) { pstCurrentHcdGtd = (td_t*)(tstAtlBridge[uAtlIndex].pstHcdTd); pstCurrentHcdEd = pstCurrentHcdGtd->ed ; /*****************************/ /* PTD byte 0 */ /* Bit 7..0: ActualByte(7:0) */ /*****************************/ pbyHcdAtlBuff[uAtlByteCount] = 0; uAtlByteCount++; /* Advances to byte 1 */ /************************************/ /* PTD byte 1 */ /* Bit 7..4: Completion code (3:0)) */ /* Bit 3: Active */ /* Bit 2: Toggle */ /* Bit 1..0: ActualByte(9:8) */ /************************************/ pbyHcdAtlBuff[uAtlByteCount] = 0; /* Clear the contents before write */ /* Gte completion code from OHCI GTD */ byData = (__u8) ((pstCurrentHcdGtd->hwINFO & HC_GTD_CC) >> 28); pbyHcdAtlBuff[uAtlByteCount] |= (byData << 4); /* Move into position in PTD */ /* Set active bit to a 1 */ pbyHcdAtlBuff[uAtlByteCount] |= PTD_ACTIVE; /* Get toggle bit from GTD if MSB of T field of the stGtd.uGtdControl is set */ if (pstCurrentHcdGtd->hwINFO & HC_GTD_MLSB) { /* Get toggle bit from LSB of T field of the GTD stGtd.uGtdControl */ byData = (__u8) ((pstCurrentHcdGtd->hwINFO & HC_GTD_TLSB) >> 24); } else { /* Get toggle bit from ED */ byData = (__u8) ((pstCurrentHcdEd->swHeadP & HC_ED_TOGGLE) >> 1); } /* Move toggle bit into position in PTD */ pbyHcdAtlBuff[uAtlByteCount] |= (byData << 2); uAtlByteCount++; /* Advances to byte 2 */ /******************************/ /* PTD byte 2 */ /* Bit 7..0: MaxPackSize(7:0) */ /******************************/ pbyHcdAtlBuff[uAtlByteCount] = 0; /* Clear the contents before write */ byData = (__u8) ((pstCurrentHcdEd->hwINFO & HC_ED_MPS) >> 16); pbyHcdAtlBuff[uAtlByteCount] = byData; uAtlByteCount++; /* Advances to byte 3 */ /*********************************/ /* PTD byte 3 */ /* Bit 7..4: EndpointNumber(3:0) */ /* Bit 3: Last
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -