⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hcd_1161.c

📁 isp116x系列USB芯片在LINUX下的驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
			/* 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 + -