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

📄 usb_phci.c

📁 linux下的usb开发
💻 C
📖 第 1 页 / 共 5 页
字号:
/************************************************************* * Philips HCD (Host Controller Driver) for USB. * *	Original Host Controller driver code from Linux OS 2.4.5 Kernel and  *  modified for Philips ISP1362 HCD *  * File Name:	usb_phci.c * * History:	 * *	Version	Date		Author		Comments * ------------------------------------------------- * 	1.0		09/23/02	SYARRA		Initial Release *  1.1		11/22/02	SYARRA		Waiting in while loop for IsoTx *									start of frame is changed (ISO_WAIT_FIX) *  *************************************************************/ #include <linux/config.h>#define MODULE#include <linux/module.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 <asm/dma.h>#include "usb_phci.h"struct isp1362_dev	*isp1362_device = NULL;static 		LIST_HEAD (phci_hcd_list);static 		spinlock_t 				usb_ed_lock = SPIN_LOCK_UNLOCKED;static int cc_to_error[16] = { /* mapping of the OHCI CC status to error codes */ 	/* No  Error  */               USB_ST_NOERROR,	/* CRC Error  */               USB_ST_CRC,	/* Bit Stuff  */               USB_ST_BITSTUFF,	/* Data Togg  */               USB_ST_CRC,	/* Stall      */               USB_ST_STALL,	/* DevNotResp */               USB_ST_NORESPONSE,	/* PIDCheck   */               USB_ST_BITSTUFF,	/* UnExpPID   */               USB_ST_BITSTUFF,	/* DataOver   */               USB_ST_DATAOVERRUN,	/* DataUnder  */               USB_ST_DATAUNDERRUN,	/* reservd    */               USB_ST_NORESPONSE,	/* reservd    */               USB_ST_NORESPONSE,	/* BufferOver */               USB_ST_BUFFEROVERRUN,	/* BuffUnder  */               USB_ST_BUFFERUNDERRUN,	/* Not Access */               USB_ST_NORESPONSE,	/* Not Access */               USB_ST_NORESPONSE };#define		phc_name					"PHCI-HC"	#define		PHCI_UNLINK_TIMEOUT			(HZ / 10)#define		DRIVER_AUTHOR	"Linux kernel 2.4.5 usb-ohci.c modified for Philips Semiconductors"#define		DRIVER_DESC	"USB Philips ISP1362 Host Controller Driver"/* Trace functions */#ifdef DEBUGvoid 	print_int_ed_list(phci_t	*phci);#endif#ifdef __PHCI_DEBUG_DETAIL__static	void 	phci_print_map_buffers(__u8	index);static	void 	phci_print_ptd_header(__u8	*header, __u32	pipe);static	void 	phci_print_hex_data(__u8	*data, __u32	length);static	void 	phci_print_hc_regs(phci_t	*phci, __u8	buff_type);static 	void 	phci_urb_print (urb_t * urb, char * str, int small);#endif /* __detail_debug__ *//* HC Register accessing functions decleration */void 	fnvPhciHcorWrite	(phci_t 	*phci,__u32 	uReg, __u32 	uRegData);void 	fnvPhciHcorRead	(phci_t 	*phci,__u32 	uReg, __u32 	*puRegData);void 	phci_reg_read16	(__u32	uReg, __u32 	*puRegData);void 	phci_reg_write16	(__u32 	uReg, __u32 	uRegData);/* HC RAM accessing functions decleration */void	fnvPhciRamRead(phci_t	*phci, __u32	length, __u32	direction, __u32	addr, __u8	*byte_data);void	fnvPhciRamWrite(phci_t	*phci, __u32	length, __u32	direction, __u32	addr, __u8	*byte_data);/* HC Initialization functions decleration */static	__u32 	fnvPhciHostReset	(phci_t 	*phci);static	void 	fnvHcIntEnable	(phci_t 	*phci);static	void 	fnvHcControlInit	(phci_t 	*phci);static	void 	fnvHcInterruptInit	(phci_t 	*phci);static	void 	fnvHcFmIntervalInit	(phci_t 	*phci);static	void 	fnvHcRhPower	(phci_t 	*phci);static	int	 	fnuPhciHostInit	(phci_t 	*phci);static	void	fnvHcRamBufferInit( phci_t	*phci) ;static	phci_t * __devinit 	hc_alloc_phci (struct isp1362_dev *dev);int __devinit 		hc_found_phci (struct isp1362_dev *dev) ;void 	hc_release_phci (phci_t * phci);/* HC Interrupt Functions */void 	phci_isr(struct isp1362_dev *dev, void *isr_data);static void 	fnvProcessAtlInt(phci_t	*phci);static void 	fnvProcessIntlInt(phci_t	*phci);static void 	fnvProcessIstlInt(phci_t	*phci);/* TD-PTD map function declerations */static	void 	phci_init_map_buffers(phci_t	*phci) ;static	void 	phci_get_td_ptd_index(ed_t	*ed);static	void 	phci_release_td_ptd_index(ed_t		*ed);static	void phci_move_pending_td_ptds(td_ptd_map_buff_t   *ptd_map_buff);static	void 	phci_fill_send_ptd(phci_t	*phci, __u32	send_ptd_bitmap,td_ptd_map_buff_t *ptd_map_buff);static	void 	phci_fill_send_isoc_ptd(phci_t	*phci, __u32	send_ptd_bitmap,td_ptd_map_buff_t *ptd_map_buff);static	void 	phci_submit_ed(phci_t	*phci,	ed_t	*ed) ;/* TD functions decleration */static 	void 	td_fill (unsigned int info, void * data, int len, urb_t * urb, int index);static 	void 	td_submit_urb (urb_t * urb);/* EP handling functions */static int 		ep_int_ballance (phci_t * phci, 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 (phci_t * phci, ed_t * edi);static int 		ep_unlink (phci_t * phci, 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 (urb_t * urb);static void 	dl_del_list (phci_t  * phci, unsigned int frame);static td_t * 	dl_reverse_done_list (phci_t * phci, td_t *td_list);static void 	dl_done_list (phci_t * phci, td_t * td_list);/* Root Hub function declerations */int 			rh_send_irq (phci_t * phci, void * rh_data, int rh_len);static void 	rh_int_timer_do (unsigned long ptr);static int 		rh_init_int_timer (urb_t * urb);static int 		rh_submit_urb (urb_t * urb);static int 		rh_unlink_urb (urb_t * urb);/* URB support functions */static void 	urb_free_priv( struct phci	*hc, urb_priv_t	*urb_priv);static void 	urb_rm_priv_locked (urb_t	*urb);static void 	urb_rm_priv (urb_t	*urb);/* USB core (usb.c) interface functions */static int 		sphci_alloc_dev (struct usb_device *usb_dev);static int 		sphci_free_dev (struct usb_device *usb_dev);static int 		sphci_get_current_frame_number (struct usb_device *usb_dev);static int 		sphci_return_urb (urb_t * urb);static int 		sphci_submit_urb (urb_t	*urb);static int 		sphci_unlink_urb (urb_t	*urb);#ifdef CONFIG_USB_HCDC_OTG/* otg function declerations for OTG driver interface */int		phci_register_otg(phci_otg_data_t	*otg_data);void	phci_unregister_otg(phci_otg_data_t	*otg_data);void	phci_otg_port_control(void *priv, __u8	cmd, __u32 *data);#endif /* CONFIG_USB_HCDC_OTG *//* Global Variable decleration */static td_ptd_map_buff_t	td_ptd_map_buff[TD_PTD_TOTAL_BUFF_TYPES];	/* td-ptd map buffer for all 1362 buffers */static	__u8				td_ptd_pipe_x_buff_type[PIPE_BULK+1] = {	/* Pipe vs buffer type data structure */								TD_PTD_BUFF_TYPE_ISTL0, 					/* ISOC for ISTL0 */								TD_PTD_BUFF_TYPE_INTL,					/* INT	for INTL */								TD_PTD_BUFF_TYPE_ATL,					/* CONTROL for ATL */								TD_PTD_BUFF_TYPE_ATL					/* BULK for ATL */};static	__u8				atl_active_ptd_X_threshold_ptd[17] = {0,1,2,2,3,3,4,5,6,6,7,8,9,9,10,11,12};#define		phci_spin_lock_irqsave(p,f)	if(!(in_interrupt())) spin_lock_irqsave(p, f)#define		phci_spin_unlock_irqrestore(p,f)	if(!(in_interrupt())) spin_unlock_irqrestore (p, f)/*--------------------------------------------------------------* * Host Controller operational registers write *--------------------------------------------------------------*/void fnvPhciHcorWrite(phci_t *phci,__u32 uReg, __u32 uRegData) {	__u32	uData;	detail_debug(("fnvPhciHcorWrite(phci = 0x%p, uReg = 0x%x, uRegData = 0x%x)\n",phci, uReg, uRegData))	/* Check if the registers are controlled by software */	if ((uReg == uHcHcdControl ) || (uReg == (uHcHcdControl | 0x80))) {		phci->uHcHcdControl_hcd = uRegData;		return;	}	if ((uReg == uHcHcdCommandStatus) || (uReg == (uHcHcdCommandStatus | 0x80))) {		phci->uHcHcdCommandStatus_hcd = uRegData;		return;	}#ifdef CONFIG_USB_HCDC_OTG	/* In OTG mode, clear the internal connect status change bit */	if((uReg == (uHcRhPort1Status+OTG_HC_PORT_NO)) || (uReg == ((uHcRhPort1Status+OTG_HC_PORT_NO)|0x80))) {		if(uRegData & RH_PS_CSC) phci->otg_port_status &= ~(RH_PS_CSC);	}#endif /* CONFIG_USB_HCDC_OTG */	isp1362_command((uReg|0x80), isp1362_device);	uData = uRegData & 0x0000FFFF;	isp1362_write16(uData,isp1362_device);	uData = (uRegData & 0xFFFF0000) >> 16;	isp1362_write16(uData,isp1362_device);} /* fnvPhciHcorWrite() *//*--------------------------------------------------------------* * Host Controller operational registers read *--------------------------------------------------------------*/void fnvPhciHcorRead(phci_t *phci,__u32 uReg, __u32 *puRegData) {	__u32	uData;	detail_debug(("fnvPhciHcorRead(phci = 0x%p, uReg = 0x%x, puRegData = 0x%p)\n",phci, uReg, puRegData))	/* Service the HCD HC transfer control registers first */	if (uReg == uHcHcdControl ) {		*puRegData = phci->uHcHcdControl_hcd;		return;	}	if (uReg == uHcHcdCommandStatus) {		*puRegData = phci->uHcHcdCommandStatus_hcd;		return;	}	isp1362_command(uReg, isp1362_device);	uData = isp1362_read16(isp1362_device);	*puRegData = uData & 0x0000FFFF;	uData = isp1362_read16(isp1362_device);	*puRegData |= (uData & 0x0000FFFF) << 16;#ifdef CONFIG_USB_HCDC_OTG	/* In OTG mode mask the Connect status, connect status change bits from HC and give	 * internal values which are controlled by OTG module */	if(uReg == (uHcRhPort1Status+OTG_HC_PORT_NO)) {		*puRegData &= ~(RH_PS_CSC|RH_PS_CCS);		*puRegData |= (phci->otg_port_status & (RH_PS_CSC|RH_PS_CCS));	}#endif /* CONFIG_USB_HCDC_OTG */} /* fnvPhciHcorRead() *//*--------------------------------------------------------------* * Host Controller registers read *--------------------------------------------------------------*/void phci_reg_read16(__u32 uReg, __u32 *puRegData) {	__u32	uData;	detail_debug(("phci_reg_read16(uReg = 0x%x, puRegData = 0x%p)\n",uReg, puRegData))	isp1362_command(uReg,isp1362_device);	uData = isp1362_read16(isp1362_device);	*puRegData = uData;} /* phci_reg_read16() *//*--------------------------------------------------------------* * Host Controller registers write *--------------------------------------------------------------*/void phci_reg_write16(__u32 uReg, __u32 uRegData) {	detail_debug(("phci_reg_write16(uReg = 0x%x, uRegData = 0x%x)\n",uReg, uRegData))	isp1362_command((uReg|0x80), isp1362_device);	isp1362_write16(uRegData, isp1362_device);} /* phci_reg_write16() *//*--------------------------------------------------------------* * Host Controller registers read 32 bit  *--------------------------------------------------------------*/void phci_reg_read32(__u32 uReg, __u32 *puRegData) {	__u32	uData;	detail_debug(("phci_reg_read32(uReg = 0x%x, puRegData = 0x%p)\n",uReg, puRegData))	isp1362_command(uReg, isp1362_device);	uData = isp1362_read16(isp1362_device);	*puRegData = uData & 0x0000FFFF;	uData = isp1362_read16(isp1362_device);	*puRegData |= (uData & 0x0000FFFF) << 16;} /* phci_reg_read32() *//*--------------------------------------------------------------* * Host Controller registers write 32 bit  *--------------------------------------------------------------*/void phci_reg_write32(__u32 uReg, __u32 uRegData) {    __u32 	uData;	detail_debug(("phci_reg_write32(uReg = 0x%x, uRegData = 0x%x)\n",uReg, uRegData))    	isp1362_command((uReg|0x80), isp1362_device);	uData = uRegData & 0x0000FFFF;	isp1362_write16(uData,isp1362_device);	uData = (uRegData & 0xFFFF0000) >> 16;	isp1362_write16(uData,isp1362_device);	} /* phci_reg_write32() */#ifdef CONFIG_USB_PHCD_DMAvoid	fnvPhciRamWrite(phci_t	*phci, __u32	length, __u32	direction, __u32	addr, __u8	*byte_data) {	__u32		direct_addr_len;	__u16		dma_cnfg = 0;	__u32		int_reg;	unsigned int	flags;	__u32		original_length;	detail_debug(("fnvPhciRamWrite(length = %d, direction = %d, addr = 0x%x, byte_data = 0x%p)\n",length, direction, addr, byte_data))	if(!length || !byte_data) return;				/* If there is nothing to write , return back */	original_length = length;	if(length & 0x01)	length++;			/* Align length to even number */	/* fill the direct address length register with len+dir+addr */	direct_addr_len = addr & 0x7FFF;	direct_addr_len |= direction;	direct_addr_len |= (length << 16);	phci_reg_write32(REG_DIRECT_ADDR_LEN  ,direct_addr_len);  // writing the direct address length 	memcpy(phci->dma_buff, byte_data, original_length);	dma_cnfg = (DMA_BUFF_TYPE_DIR_ADDR | DMA_1CYCLE_BURST_LEN | DMA_COUNTER_ENABLE);	/* Disable DMA */	phci_reg_write16(REG_DMA_CNFG, dma_cnfg);	/* Clear EOT bit inthe interrupt register */	phci_reg_write16(REG_IRQ, EOT_INT);	save_flags(flags);	disable_dma(DMA4HC_CHNNL);	clear_dma_ff(DMA4HC_CHNNL);	set_dma_mode(DMA4HC_CHNNL,DMA_MODE_WRITE);	set_dma_addr(DMA4HC_CHNNL,virt_to_bus(phci->dma_buff));	set_dma_count(DMA4HC_CHNNL, length);	/* Enable PC DMA */	enable_dma(DMA4HC_CHNNL);

⌨️ 快捷键说明

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