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

📄 hcd_1161.c

📁 isp116x系列USB芯片在LINUX下的驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * Philips 1161 HCD (Host Controller Driver) for USB. * *  Original Source from Linux 2.4.5 kernel OHCI HCD *  modified for Phlips Semi Conductors *  * Copyright  2002	Philips Semiconductors, * * File Name:	hcd_1161.c * * History:	 * *	Version	Date		Author		Comments * ------------------------------------------------- * 	1.0		03/14/02	SYARRA		Initial Release * 	1.1		04/24/03	SYARRA		NO_PTD_BIT5_5 flag * 									dependancy of td_t on 16 byte start  * 									address is removed. * *  1.11	05/15/03	SYARRA		enabling OHCI_CTRL_CLE/OHCI_CTRL_BLE * 									in dl_del_list function * 									Skip RH-timer processing in ISR *									proper clearing of ATL & SOF interrupts * *  * Note: Use tab space 4 */ #include <linux/config.h>#define MODULE#include <linux/module.h>#include <linux/pci.h>#include <linux/kernel.h>#include <linux/delay.h>#include <linux/ioport.h>#include <linux/sched.h>#include <linux/slab.h>#include <linux/smp_lock.h>#include <linux/errno.h>#include <linux/init.h>#include <linux/timer.h>#include <linux/list.h>#include <linux/interrupt.h>  /* for in_interrupt() */#undef DEBUG#include <linux/usb.h>#include <asm/io.h>#include <asm/irq.h>#include <asm/system.h>#include <asm/unaligned.h>#include "hcd_1161.h"typedef	__u32		ULONG;typedef	__u8		UCHAR;typedef	void		VOID;static      td_tree_addr_t   		tstAtlBridge[MAX_GTD+1];static      td_t             		*pstDoneHead_hcd ;static		isotd_map_buffer_t		aIsoTdMapBuffer[2];			/* One for each ITL */static 		LIST_HEAD (ohci_1161_hcd_list);static 		spinlock_t 				usb_ed_lock = SPIN_LOCK_UNLOCKED;#define		MAX_BULK_TD_BUFF_SIZE		512#define		MAX_CNTL_TD_BUFF_SIZE		1024#define		hc_1161_name	"ISP116x_HCD"	#define		OHCI_UNLINK_TIMEOUT			(HZ / 10)void print_int_ed_list(ohci_t	*ohci);/* 1161 HC accessing functions decleration */void 	fnvIsp1161HcorWrite	(ohci_t 	*ohci,ULONG 	uReg, ULONG 	uRegData);void 	fnvIsp1161HcorRead	(ohci_t 	*ohci,ULONG 	uReg, ULONG 	*puRegData);void 	fnvIsp1161HcRead	(ULONG	uReg, ULONG 	*puRegData);void 	fnvIsp1161HcWrite	(ULONG 	uReg, ULONG 	uRegData);void 	fnvIsp1161AtlRead	(__u8* 	pbyChar, __u32 	uTotalByte);void 	fnvIsp1161AtlWrite	(__u8* 	pbyChar, __u32 	uTotalByte);void 	fnvIsp1161ItlRead	(__u8* 	pbyChar, __u32 	uTotalByte);void 	fnvIsp1161ItlWrite	(__u8* 	pbyChar, __u32 	uTotalByte);/* 1161 HC Initialization functions decleration */ULONG 	fnvIsp1161HostReset	(ohci_t 	*ohci);ULONG 	fnuIsp1161HostDetect	(void);void 	fnvHcHardwareConfig	(ohci_t	*ohci, ULONG	uIntLevel);void 	fnvHcIntEnable	(ohci_t 	*ohci);void 	fnvHcControlInit	(ohci_t 	*ohci);void 	fnvHcInterruptInit	(ohci_t 	*ohci);void 	fnvHcFmIntervalInit	(ohci_t 	*ohci);void 	fnvHcRhPower	(ohci_t 	*ohci);int	 	fnuHci1161HostInit	(ohci_t 	*ohci);/* 1161 HC Interrupt Functions */static 	void 	fnvHci1161IrqHandler (int 	irq, void 	*__ohci, struct 	pt_regs *r);void 	fnvProcessSofItlInt	(ohci_t *ohci);/* TD functions decleration */static 	void 	td_fill (unsigned int info, void * data, int len, struct urb * urb, int index);static 	void 	td_submit_urb (struct urb * urb);/* EP handling functions */static int ep_int_ballance (ohci_t * ohci, int interval, int load);static int ep_2_n_interval (int inter);static int ep_rev (int num_bits, int word);static int ep_link (ohci_t * ohci, ed_t * edi);static int ep_unlink (ohci_t * ohci, ed_t * ed);static void ep_rm_ed (struct usb_device * usb_dev, ed_t * ed);static ed_t * ep_add_ed (struct usb_device * usb_dev, unsigned int pipe, int interval, int load);/* Done List handling functions */static void dl_transfer_length(td_t * td);static void dl_del_urb (struct urb * urb);static void dl_del_list (ohci_t  * ohci, unsigned int frame);static td_t * dl_reverse_done_list (ohci_t * ohci, td_t *td_list);static void dl_done_list (ohci_t * ohci, td_t * td_list);/* Root Hub function declerations */static int rh_send_irq (ohci_t * ohci, void * rh_data, int rh_len);static void rh_int_timer_do (unsigned long ptr);static int rh_init_int_timer (struct urb * urb);static int rh_submit_urb (struct urb * urb);static int rh_unlink_urb (struct urb * urb);/* URB support functions */static void urb_free_priv( struct ohci	*hc, urb_priv_t	*urb_priv);static void urb_rm_priv_locked (struct urb	*urb);static void urb_rm_priv (struct urb	*urb);/* SOHCI functions */static int s1161_alloc_dev (struct usb_device *usb_dev);static int s1161_free_dev (struct usb_device *usb_dev);static int s1161_get_current_frame_number (struct usb_device *usb_dev);static int s1161_return_urb (struct urb * urb);static int s1161_submit_urb (struct urb	*urb);static int s1161_unlink_urb (struct urb	*urb);/* OHCI functions */static void hc_release_1161 (ohci_t * ohci);static ohci_t * __devinit hc_alloc_1161 (struct pci_dev *dev);static int __devinit hc_found_1161 ( void) ;#define  outb(x,y)		outb(y,x)#define  inb	        inb#define  outw_hcd(x,y)	outw_p(y,x)#define  inw_hcd		inw_p#define	 sti_hcd		sti#define	 cli_hcd		cli#define	 iodelay_hcd()	udelay(1)#define	cmd_delay_hcd()		do{udelay(1);}while(0)#define	data_delay_hcd()	do{}while(0)/*--------------------------------------------------------------* * 1161 Host Controller operational registers write *--------------------------------------------------------------*/void fnvIsp1161HcorWrite(ohci_t *ohci,ULONG uReg, ULONG uRegData){	ULONG	uData;	/* Check if the registers are controlled by software */	if ((uReg == uHcHcdControl ) || (uReg == (uHcHcdControl | 0x80))) {		ohci->uHcHcdControl_hcd = uRegData;		return;	}	if ((uReg == uHcHcdCommandStatus) || (uReg == (uHcHcdCommandStatus | 0x80))) {		ohci->uHcHcdCommandStatus_hcd = uRegData;		return;	}	/* Write the register index to the command register */	outw_hcd(HC_COM, uReg | 0x80);	/* Write the data to the data register */	uData = uRegData & 0x0000FFFF;				/* Write lower 16-bit first */	outw_hcd(HC_DATA, uData);	uData = (uRegData & 0xFFFF0000) >> 16;		/* Then the higher 16-bit */	outw_hcd(HC_DATA, uData);} /* fnvIsp1161HcorWrite() *//*--------------------------------------------------------------* * 1161 Host Controller operational registers read *--------------------------------------------------------------*/void fnvIsp1161HcorRead(ohci_t *ohci,ULONG uReg, ULONG *puRegData){	ULONG	uData;	/* Service the HCD HC transfer control registers first */	if (uReg == uHcHcdControl ) {		*puRegData = ohci->uHcHcdControl_hcd;		return;	}	if (uReg == uHcHcdCommandStatus) {		*puRegData = ohci->uHcHcdCommandStatus_hcd;		return;	}	/* Write the register index to the command register */	outw_hcd(HC_COM, uReg);	/* Read the data from the data register */	uData = inw_hcd(HC_DATA);	*puRegData = uData & 0x0000FFFF;			/* Save the lower 16-bit value */	uData = inw_hcd(HC_DATA);	*puRegData |= (uData & 0x0000FFFF) << 16;		/* Take the higher 16-bit */} /* fnvIsp1161HcorRead() *//*--------------------------------------------------------------* * 1161 Host Controller registers read *--------------------------------------------------------------*/void fnvIsp1161HcRead(ULONG uReg, ULONG *puRegData){	ULONG	uData;	/* Write the register index to the command register */	outw_hcd(HC_COM, uReg);	/* Read the data from the data register */	uData = inw_hcd(HC_DATA);	*puRegData = uData;} /* fnvIsp1161HcRead() *//*--------------------------------------------------------------* * 1161 Host Controller registers write *--------------------------------------------------------------*/void fnvIsp1161HcWrite(ULONG uReg, ULONG uRegData){	/* Write the register index to the command register */	outw_hcd(HC_COM, uReg | 0x80);	/* Write the data to the data register */	outw_hcd(HC_DATA, uRegData);} /* fnvIsp1161HcWrite() *//*--------------------------------------------------------------* * 1161 Host Controller Atl Buffer Reading  *--------------------------------------------------------------*/void fnvIsp1161AtlRead(__u8* pbyChar, __u32 uTotalByte){	__u32           uTotalDoubleWord;	__u32*          puLong;	__u32           uIndex;	__u32           uData1;	__u32           uData2;#ifdef __TRACE_MID_LEVEL__	printk("fnvIsp1161AtlRead( buff = 0x%p, bytes = %d)\n",pbyChar,uTotalByte);#endif /* __TRACE_MID_LEVEL__ */	/* Program the transfer counter */	fnvIsp1161HcWrite(REG_XFER_CNTR, uTotalByte);	/* 2. Pass HCD ATL to ISP1161 internal ATL through the 32-bit ATLBuffer register */	/* Use PIO for the time being. Will use DMA */	uTotalDoubleWord = uTotalByte >> 2;             /* Number of double words to move from ISP1161 ATL */	puLong = (__u32*) pbyChar;      /* Convert the HCD byte buffer to double-word buffer */	cli_hcd();	/* Send the command */	outw_hcd(HC_COM,REG_ATL_BUFF_IO);	iodelay_hcd();	/* Read data from data port */	for (uIndex = 0; uIndex < uTotalDoubleWord; uIndex ++) {		uData1 = inw_hcd(HC_DATA);              /* Read lower 16-bit first */		uData2 = inw_hcd(HC_DATA);              /* then higher 16-bit */		/* Combine to 32-bit double word */		puLong[uIndex] = (uData1 & 0x0000FFFF) | ((uData2 & 0x0000FFFF) << 16);         /* Take the higher 16-bit */	} /* for */	sti_hcd();} /* End of fnvIsp1161AtlRead() *//*--------------------------------------------------------------* * 1161 Host Controller Atl Buffer Reading  *--------------------------------------------------------------*/void fnvIsp1161AtlWrite(__u8* pbyChar, __u32 uTotalByte){	__u32           uTotalDoubleWord;	__u32*          puLong;	__u32           uIndex;	__u32           uData1;	__u32           uData2;#ifdef __TRACE_MID_LEVEL__	printk("fnvIsp1161AtlWrite( buff = 0x%p, bytes = %d)\n",pbyChar,uTotalByte);#endif /* __TRACE_MID_LEVEL__ */	/* Program the transfer counter */	fnvIsp1161HcWrite(REG_XFER_CNTR, uTotalByte);	/* 2. Pass HCD ATL to ISP1161 internal ATL through the 32-bit ATLBuffer register */	/* Use PIO for the time being. Will use DMA */	uTotalDoubleWord = uTotalByte >> 2;			/* Number of double words to move from ISP1161 ATL */	puLong = (__u32*) pbyChar;					/* Convert the HCD byte buffer to double-word buffer */	/* Send the command */	outw_hcd(HC_COM,(REG_ATL_BUFF_IO | 0x80));		/* Don't forget to set bit 7 for write*/	iodelay_hcd();	cli_hcd();	/* Write data to the data port */	for (uIndex = 0; uIndex < uTotalDoubleWord; uIndex ++) {		uData1 = puLong[uIndex] & 0x0000FFFF;		/* Take the lower 16-bit of the double word */		uData2 = (puLong[uIndex] & 0xFFFF0000) >> 16;	/* Take the higher 16-bit of the double word */		/* Write them to ATL */		outw_hcd(HC_DATA,uData1);				/* Write lower 16-bit first */		outw_hcd(HC_DATA,uData2);				/* Write higher 16-bit */	} /* for */	sti_hcd();} /* End of fnvIsp1161AtlWrite() *//*--------------------------------------------------------------* * 1161 Host Controller Itl Buffer Reading  *--------------------------------------------------------------*/void fnvIsp1161ItlRead(__u8* pbyChar, __u32 uTotalByte){	__u32           uTotalDoubleWord;	__u32*          puLong;	__u32           uIndex;	__u32           uData1;	__u32           uData2;#ifdef __TRACE_MID_LEVEL__	printk("fnvIsp1161ItlRead( buff = 0x%p, bytes = %d)\n",pbyChar,uTotalByte);#endif /* __TRACE_MID_LEVEL__ */	outw_hcd(HC_COM, REG_XFER_CNTR | 0x80);	outw_hcd(HC_DATA, uTotalByte);	/* 2. Pass HCD ITL to ISP1161 internal ITL through the 32-bit ITLBuffer register */	/* Use PIO for the time being. Will use DMA */	uTotalDoubleWord = uTotalByte >> 2;             /* Number of double words to move from ISP1161 ATL */	puLong = (__u32*) pbyChar;      /* Convert the HCD byte buffer to double-word buffer */	cli_hcd();	/* Send the command */	outw_hcd(HC_COM,REG_ITL_BUFF_IO);	/* Read data from data port */	for (uIndex = 0; uIndex < uTotalDoubleWord; uIndex ++) {		uData1 = inw_hcd(HC_DATA);              /* Read lower 16-bit first */		uData2 = inw_hcd(HC_DATA);              /* then higher 16-bit */		/* Combine to 32-bit double word */		puLong[uIndex] = (uData1 & 0x0000FFFF) | ((uData2 & 0x0000FFFF) << 16);         /* Take the higher 16-bit */	} /* for */

⌨️ 快捷键说明

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