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

📄 hcd_1161.c

📁 isp116x系列USB芯片在LINUX下的驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
		if (uData == YES)			uHostConfigData |= HC_RH_DESCRIPTORA_OCPM;	/* Set the power on to power good time */	uHostConfigData |= ((POWER_ON_TO_POWER_GOOD_TIME / 2) << 24);			/* Divided by 2, then move it into position */	fnvIsp1161HcorWrite(ohci,uHcRhDescriptorA, uHostConfigData);	/* Set the global power to all the ports */        uHostConfigData = RH_HS_LPSC;        fnvIsp1161HcorWrite(ohci,uHcRhStatus, uHostConfigData);	/* Wait till the POWER ON TO POWER GOOD time */        mdelay(POWER_ON_TO_POWER_GOOD_TIME);	/* Set the HcRhDescriptorB register (13h) */	uHostConfigData = DEVICE_REMOVABLE;	if (PORT_POWER_SWITCHING == YES)		uHostConfigData |= 0xFFFF0000;		/* Set PPCM bits 31..16 to disable gang-mode power switching */	fnvIsp1161HcorWrite(ohci,uHcRhDescriptorB, uHostConfigData);} /* End of fnvHcRhPower() *//*--------------------------------------------------------------* * 1161 Host Controller Initialization *--------------------------------------------------------------*/int	 fnuHci1161HostInit(ohci_t	*ohci){	struct usb_device 	*usb_dev;	/* 1. ISP1161 Host Controller Extended Registers Initialization */	fnvHcHardwareConfig(ohci, ohci->irq);	fnvHcIntEnable(ohci);	/* Set the HC ATL buffer length */	fnvIsp1161HcWrite(REG_ITL_BUFLEN, ITL_BUFF_LENGTH);	/* Set the HC ATL buffer length */	fnvIsp1161HcWrite(REG_ATL_BUFLEN, ATL_BUFF_LENGTH);	/* 2. ISP1161 Host Controller Operational Registers Initialization */	pstDoneHead_hcd  = 0;								/* Done head */	aIsoTdMapBuffer[0].byStatus = 0;	aIsoTdMapBuffer[1].byStatus = 0;	aIsoTdMapBuffer[0].uFrameNumber = INVALID_FRAME_NUMBER;	aIsoTdMapBuffer[1].uFrameNumber = INVALID_FRAME_NUMBER;	fnvHcControlInit(ohci);						 /* Initialize HcControl register */		ohci->disabled = 0;	fnvHcInterruptInit(ohci/*, stHostCallback*/);	/* Initialize HcInterruptEnable/Disable registers */	fnvHcFmIntervalInit(ohci);				  /* Initialize HcFmInterval Register */	fnvHcRhPower(ohci);						/* Root hub port power switching mode */	ohci->rh.devnum = 0;					/* No root hub yet */	ohci->p_ed_controlhead = NULL;			/* Initialize control & bulk list heads */	ohci->p_ed_bulkhead = NULL;	/* Allocate data structure for root hub */	usb_dev = usb_alloc_dev ( NULL, ohci->bus) ;		if( !usb_dev ) {		ohci->disabled = 1;		return -ENOMEM;	}	ohci->bus->root_hub = usb_dev;	/* Connect the virtual hub to the usb bus, host stack will do all the enumeration,	   configuration etc.. */	usb_connect (usb_dev); 	if(usb_new_device(usb_dev) != 0) {		usb_free_dev(usb_dev);		ohci->disabled = 1;		return -ENODEV;	}	return 0;} /* End of fnuHci1161HostInit() *//*--------------------------------------------------------------* * 1161 HC Interrupt Functions									*  *--------------------------------------------------------------*//*--------------------------------------------------------------* * 1161 Host Controller Interrupt function						* *--------------------------------------------------------------*/static void fnvHci1161IrqHandler (int irq, void * __ohci, struct pt_regs * r){	ohci_t	*ohci = (ohci_t*)__ohci;	ULONG uIntStatus;				/* Int. status of the HCOR */	ULONG uEnabledHcorIntStatus;	/* HcInterruptStatus HCOR anded with HcInterruptEnable */	ULONG uIntExtStatus;			/* Int. status of the ISP1161 ext. int register */	ULONG uData1, uData2;	ohci->in_isr = 1;	fnvIsp1161HcRead(REG_IRQ, &uData1);	fnvIsp1161HcRead(REG_IRQ_MASK, &uData2);	uIntExtStatus = uData1 & uData2;				/* Get the true int. status */	/* uIntExtStatus contains enabled interrupt status bits read from the */	/* ISP1161 HC ext. register REG_IRQ (0x24) */	/* If the IRQ is not from ISP1161 HC, don't do anything. */	if (uIntExtStatus == 0)	{			/* ISP1161 int. status in HC extended register */		ohci->in_isr = 0;		return;	}	/* Get the enabled HcInterruptStatus HCOR */	fnvIsp1161HcorRead(ohci,uHcInterruptStatus, &uData1);	/* Read the HCOR int. status */	fnvIsp1161HcorRead(ohci,uHcInterruptEnable, &uData2);	/* Read the HCOR int. enable status */	uIntStatus = uData1 & uData2;						/* Get the true int. status */	uEnabledHcorIntStatus = uData1 & uData2;	/*******************************/	/* Process SOFITLInt IRQ       */	/* SOF and ITL interrupts      */	/*******************************/	if (uIntExtStatus & SOF_ITL_INT) {		/* SOFITL Int. service */		fnvProcessSofItlInt(ohci);		/* Clear SOFITLInt IRQ of REG_IRQ register of ISP1161 ext regsiter */		uData1 = SOF_ITL_INT;		fnvIsp1161HcWrite(REG_IRQ, uData1);	} /* if SOF_ITL_INT */	/*********************************************/	/* Process ATL_INT                           */	/* ALT Done                                  */	/*********************************************/	if (uIntExtStatus & ATL_INT) {		/* fnvProcessOprInt(pstHostNode); */		/* Clear ATL_INT IRQ */		uData1 = ATL_INT;		fnvIsp1161HcWrite(REG_IRQ, uData1);	} /* if ATL_INT */	/*********************************************/	/* Process EOT_INT                           */	/* End of Transfer                           */	/*********************************************/	if (uIntExtStatus & EOT_INT) {		/* fnvProcessOprInt(pstHostNode); */		/* Clear EOT_INT IRQ */		uData1 = EOT_INT;		fnvIsp1161HcWrite(REG_IRQ, uData1);	} /* if EOT_INT */	/*********************************************/	/* Process OPR_INT                           */	/* HC operational register HcInterruptStatus */	/*********************************************/	if (uIntExtStatus & OPR_INT) {		/*fnvProcessOprInt(pstHostNode, uEnabledHcorIntStatus);*/		/* Clear OPR_INT IRQ */		uData1 = OPR_INT;		fnvIsp1161HcWrite(REG_IRQ, uData1);	} /* if OPR_INT */	/*********************************************/	/* Process HC_SUSPEND_INT                    */	/* HC Suspended                              */	/*********************************************/	if (uIntExtStatus & HC_SUSPEND_INT) {		/* fnvProcessOprInt(pstHostNode); */		/* Clear HC_SUSPEND_INT IRQ */		uData1 = HC_SUSPEND_INT;		fnvIsp1161HcWrite(REG_IRQ, uData1);	} /* if HC_SUSPEND_INT */	/*********************************************/	/* Process HC_RESUME_INT                     */	/* HC Resume int.                            */	/*********************************************/	if (uIntExtStatus & HC_RESUME_INT) {		/* fnvProcessOprInt(pstHostNode); */		/* Clear HC_RESUME_INT IRQ */		uData1 = HC_RESUME_INT;		fnvIsp1161HcWrite(REG_IRQ, uData1);	} /* if HC_RESUME_INT */	ohci->in_isr = 0;} /* End of fnvHci1161IrqHandler() */__u8	cc6_flag = 0;__u16	cc65_count = 0;/*--------------------------------------------------------------* * 1161 Host Controller SOF/ITL Interrupt function				* *--------------------------------------------------------------*/void fnvProcessSofItlInt(ohci_t * ohci){	__u32   		uData1;	__u8  		 	byData;	__u32			uFrameNumber;			/* Frame number of 1161 */	__u8			* pbyHcdAtlBuff;        /* HCD ATL buffer address */	ed_t			* pstCurrentHcdEd;      /* Pointer to the current HCD ED entry in the HCD ED pool */	td_t			* pstCurrentHcdGtd;     /* Pointer to the current HCD GTD entry in the HCD GTD pool */	__u32   		uHcdEdIndex;			/* Ed index in Interrupt ed table */	__u32   		uAtlIndex;				/* ATL buffer td-ptd index */	__u32   		uPipeHandle;			/* URB pipe handle */	__u32   		uAtlByteCount;			/* Atl buffer byte counter */	__u32   		uLastPtd;				/* number of PTD's in the buffer or last ptd */	__u32   		uTotal;					/* General total bytes variable */	__u32   		uIndex;					/* General count index */	__u8			* pbyChar;	__u32   		uStartPTDByteCount;	__u8			* pbyData;	__u32   		uPhysical;	__u32   		uPtdCompletionCode;		/* PTD completion Code */	__u32   		uPhysicalHead;			/* TD Head pointer of ED */	__u32   		uPhysicalTail;			/* TD Tail pointer of ED */	__u32			frame ;					/* Even or Odd frame */	__u8                * pbyHcdItlBuff;	__u32               uItlByteCount;		/* ITL buffer byte counter */	isotd_map_buffer_t  * pstItdMapBuffer;	/* ITL map buffer pointer */	__u32               uTdFrameNumber;		/* TD frmae number */	__u8                uIsoTdMapBuffSelector = 0;		/* ITL0/1 buffer selector */	__u8                uItlIndex = 0;		/* ITL td-ptd index */	td_tree_addr_t      * pstItlTdMapBuffer;	/* ITL td-ptd map buffer pointer */	__u32   			uData2;	td_t				* pstTd;			/* td pointer */	__u16				bytes;				/* General no of bytes */	__u8			iso_in_flag = 0;	/* Read the current frame number from HCOR uHcRmNumber */	fnvIsp1161HcorRead(ohci,uHcFmNumber, &uFrameNumber);	frame = uFrameNumber & 0x1 ;	pbyHcdAtlBuff = ohci->p_atl_buffer ;	fnvIsp1161HcRead(REG_IRQ, &uData1);	fnvIsp1161HcRead(REG_BUFF_STS, &uData2);		if( uData1 & SOF_ITL_INT ) {		pbyHcdItlBuff = ohci->p_itl_buffer;		uIsoTdMapBuffSelector = 0;Iso_Done_Queue_Processing:		pstItdMapBuffer = &(aIsoTdMapBuffer[uIsoTdMapBuffSelector]);		pstItlTdMapBuffer = pstItdMapBuffer->aItlTdTreeBridge;				if(pstItdMapBuffer->byStatus) {						if(uFrameNumber == ((pstItdMapBuffer->uFrameNumber + 1)%0x10000)) {				/* Read buffer, process & go to done */				if(pstItdMapBuffer->byStatus & 0x02) {		/* ISO In ptd's exist */					uItlByteCount = pstItdMapBuffer->uByteCount ;//					if( (uData2 & ISOA_BUFF_DONE) || (uData2 & ISOB_BUFF_DONE) ) 					{						fnvIsp1161ItlRead(pbyHcdItlBuff, uItlByteCount);	/* Read ITL */									uLastPtd = pstItdMapBuffer->byActiveTds;			/* # of ISO TD's under progress */						pbyChar	= pbyHcdItlBuff;								for( uIndex = 0; uIndex < uLastPtd; uIndex++) {										pstCurrentHcdGtd = (td_t*)(pstItlTdMapBuffer[uIndex].pstHcdTd);	/* Td in process */							pstCurrentHcdEd = pstCurrentHcdGtd->ed ;							if( pstCurrentHcdEd->hwINFO & 0x1000) {		/* ISOC in PTD */								/* process completion code */								byData = pbyChar[1];								if( (byData & PTD_ACTIVE) == 0 ) {									/* Copy Compeltion code from PTD */									uPtdCompletionCode = (__u32)( (byData & PTD_COMPLETION_CODE) >> 4);									/* TODO do the necessary things needed for the ed/td bits */											pstCurrentHcdGtd->hwINFO &= ~HC_GTD_CC; /* Clear the original CC */									pstCurrentHcdGtd->hwINFO |= uPtdCompletionCode << 28; /* Move CC into position */														/* Forget about data toggle bit, as data toggle bit is not important for ISOC trnasfers */									/* Write the CC part of psw for the td */																/* Move data returned from device to the buffer for IN transfer */									/* Take out the PID token from PTD byte 5 */									if( uPtdCompletionCode == TD_CC_NOERROR || uPtdCompletionCode == TD_DATAUNDERRUN ) {										pbyData = (__u8*) (pstCurrentHcdGtd->hwCBP+(pstCurrentHcdGtd->hwPSW[0] & 0x0FFF)) ;										/* get the actual number of bytes transfered */										uTotal = ((__u32) (pbyChar[1] & PTD_ACTUAL_BYTES98) ) << 8; /* Bit 9..8 */										uTotal |= (__u32)(pbyChar[0]); /* Bit 7..0 */										/* Write the actual amount of data transfered for ISO IN trnasfers,										for out it is zero */											pstCurrentHcdGtd->hwPSW[0] = uTotal & 0x07FF;											memcpy(pbyData,pbyChar+8,uTotal);										pstCurrentHcdGtd->hwCBP = 0;									} /* (uPtdCompletionCode == 0 || == 9) */ else									{											pstCurrentHcdGtd->hwPSW[0] = 0; 									}									pstCurrentHcdGtd->hwPSW[0] |= (uPtdCompletionCode << 12);									}	/* (byData & PTD_ACTIVE) == 0 */							} /* pstCurrentHcdEd->hwINFO & 0x1000 */ 							pbyChar += pstItlTdMapBuffer[uIndex].uAtlNodeLength;										} /* for( uIndex = 0; uIndex < uLastPtd; uIndex++) */					} /* if( (uData2 & ISOA_BUFF_DONE) || (uData2 & ISOB_BUFF_DONE) ) */					/* move pstInDone queue to the DoneQueue */					pstTd = pstItdMapBuffer->pstIsoInDoneHead;					if(pstTd) {						while(pstTd->hwNextTD) pstTd = (td_t*)(pstTd->hwNextTD); 						pstTd->hwNextTD = (__u32)(pstDoneHead_hcd);						pstDoneHead_hcd  = pstItdMapBuffer->pstIsoInDoneHead;					}				} /* if(pstItdMapBuffer->byStatus & 0x02) */				pstItdMapBuffer->byStatus = 0;				pstItdMapBuffer->uFrameNumber = INVALID_FRAME_NUMBER;				pstItdMapBuffer->pstIsoInDoneHead = 0;				pstItdMapBuffer->byActiveTds = 0;			} else if(uFrameNumber != pstItdMapBuffer->uFrameNumber ) {						/* This is a missed frame processing, move pstInDone queue to the DoneQueue */				pstTd = pstItdMapBuffer->pstIsoInDoneHead;				if(pstTd) {					while(pstTd->hwNextTD) {						pstTd = (td_t*)(pstTd->hwNextTD); 					}					pstTd->hwNextTD = (__u32)(pstDoneHead_hcd);					pstDoneHead_hcd  = pstItdMapBuffer->pstIsoInDoneHead;				}				pstItdMapBuffer->byStatus = 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -