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

📄 hal_pci.c

📁 linux下的usb开发
💻 C
📖 第 1 页 / 共 2 页
字号:
/* PCI cleanup function of ISP1362 * This function is called from PCI Driver as an removal function * in the absence of PCI device or a de-registration of driver. * This functions checks the registerd drivers (HCD, DCD, OTG) and calls * the corresponding removal functions. Also initializes the local variables * to zero. */static void __devexitisp1362_pci_remove (struct pci_dev *dev){	struct isp1362_dev	*loc_dev;	int			index;	func_debug(("isp1362_pci_remove(dev=%p)\n",dev))	/* For each controller check whether driver is registerd         * or not. If registerd call the removal function if it is	 * present	 */	for(index=ISP1362_1ST_DEV;index<ISP1362_LAST_DEV;index++) {		loc_dev = &isp1362_loc_dev[index];		if(loc_dev->driver) {			loc_dev->driver->remove(loc_dev);			loc_dev->driver = NULL;			return;		}	}	/* Clear the local variables	 */	hal_data.io_usage = 0;	hal_data.irq_usage = 0;	return;} /* End of isp1362_pci_remove *//* PCI suspend function of ISP1362 * This function is called from PCI Driver. * This functions checks the registerd drivers (HCD, DCD, OTG) and calls * the corresponding suspend functions if present.  */static int isp1362_pci_suspend (struct pci_dev *dev, __u32 state) {	struct isp1362_dev	*loc_dev;	int			index;	func_debug(("isp1362_pci_suspend(dev=%p, state = %x)\n",dev, state))	loc_dev = (struct isp1362_dev *)pci_get_drvdata(dev);	/* For each controller check whether driver is registerd         * or not. If registerd call the suspend function if it is	 * present	 */	for(index=ISP1362_1ST_DEV;index<ISP1362_LAST_DEV;(index++,loc_dev++)) {		if(loc_dev->driver && loc_dev->driver->suspend) {			loc_dev->driver->suspend(loc_dev);		}	}	return 0;} /* End of isp1362_pci_suspend *//* PCI resume function of ISP1362 * This function is called from PCI Driver. * This functions checks the registerd drivers (HCD, DCD, OTG) and calls * the corresponding resume functions if present.  */static int isp1362_pci_resume (struct pci_dev *dev){	struct isp1362_dev	*loc_dev;	int			index;	func_debug(("isp1362_pci_resume(dev=%p)\n",dev))	loc_dev = (struct isp1362_dev *)pci_get_drvdata(dev);	/* For each controller check whether driver is registerd         * or not. If registerd call the resume function if it is	 * present	 */	for(index=ISP1362_1ST_DEV;index<ISP1362_LAST_DEV;(index++,loc_dev++)) {		if(loc_dev->driver && loc_dev->driver->resume) {			loc_dev->driver->resume(loc_dev);		}	}	return 0;} /* End of isp1362_pci_resume *//*--------------------------------------------------------------* *         Top Drivers (HCD, DCD, OTG) interface functions *--------------------------------------------------------------*//*--------------------------------------------------------------* *            hardware register initialization *--------------------------------------------------------------*//* This fuction initializes the ISP1362 device hardware configuration * register for PCI interface. */void 	isp1362_set_hw_config(struct isp1362_dev *dev){	__u32		hw_cnfg;	func_debug(("isp1362_set_hw_config(dev=%p)\n",dev))	switch(dev->index) {		case ISP1362_HC:			isp1362_reg_read16(dev, HC_HW_CNFG_REG,hw_cnfg);			/* Enable HC interrupt Pin			 * Use only one interrupt for HC and DC			 * Connect the 15K pulldown registers on port1&2			 * Level triggering, Active low polarity			 */			hw_cnfg |= (HC_INT_PIN_ENABLE | HC_ONE_INT);			hw_cnfg |= (HC_CONNECT_PLDN_15K_DS2 | HC_CONNECT_PLDN_15K_DS1);#ifdef CONFIG_USB_PHCD_DMA			hw_cnfg |= (HC_DREQ_OUT_POLARITY | HC_DATA_BUS_16BIT_WIDTH);#endif /* CONFIG_USB_PHCD_DMA */			isp1362_reg_write16(dev,(HC_HW_CNFG_REG|0x80),hw_cnfg);		break;		case ISP1362_DC:			isp1362_reg_read16(dev, DC_HW_CNFG_REG, hw_cnfg);			 /* No Clock Division, Clock is always running			  * Level triggering, Active low polarity			  */			hw_cnfg &= ~(DC_CLK_DIV);	/* No clock division */			hw_cnfg |= (DC_CLK_RUN);	/* Clock is always running */			isp1362_reg_write16(dev,(DC_HW_CNFG_REG&0xFE),hw_cnfg);		break;		default:		break;	}} /* End of isp1362_set_hw_config() *//*--------------------------------------------------------------* *            IO PORT Management Functions *--------------------------------------------------------------*//* This fuction checks whether the IO region is free for use or not * The IO region is specified in the dev structure fields. * Since OTG uses same IO ports as Host Controller and OTG driver * depends on HCD, by the time OTG is loaded HCD has already been loaded * and if HC is using IO resources, we say OTG can access the IO resources * for HCD and DCD we use system call check_region() */int	isp1362_check_io_region(struct isp1362_dev *dev){	func_debug(("isp1362_check_io_region(dev=%p)\n",dev))	/* If OTG driver, check the IO resources of HCD	 */	if(dev->index == ISP1362_OTG) {		if(isp1362_loc_dev[ISP1362_HC].io_res) return 0;		else return -EBUSY;			}	return check_region(dev->io_base, dev->io_len);} /* End of isp1362_check_io_region *//* This fuction assigns IO region to the driver * The IO region is specified in the "dev" structure fields. * Since OTG uses same IO ports as Host Controller and OTG driver * depends on HCD, for OTG driver the HCD io resources are returned * for HCD and DCD we use system call request_region() */struct resource*	isp1362_request_io_region(struct isp1362_dev	*dev){	func_debug(("isp1362_request_io_region(dev=%p)\n",dev))	hal_data.io_usage++;	if(dev->index == ISP1362_OTG) {		/* If OTG return the HCD io resources */		dev->io_res = isp1362_loc_dev[ISP1362_HC].io_res;	} else {		/* Store the IO resources */		dev->io_res = request_region(dev->io_base, dev->io_len, isp1362_driver_name);	}	return dev->io_res;} /* End of isp1362_request_io_region *//* This fuction releases IO region for the driver * The IO region is specified in the "dev" structure fields. * Since OTG uses same IO ports as Host Controller and OTG driver * depends on HCD, for OTG driver nothing is done * for HCD and DCD we use system call release_region() */void isp1362_release_io_region(struct isp1362_dev *dev){	func_debug(("isp1362_release_io_region(dev=%p)\n",dev))	hal_data.io_usage--;	dev->io_res = NULL;	if(dev->index == ISP1362_OTG)	return;	return release_region(dev->io_base, dev->io_len);	} /* End of isp1362_release_io_region *//*--------------------------------------------------------------* *            Interrupt Management Functions *--------------------------------------------------------------*//* This function registers the ISR of driver with this driver. * Since there is only one interrupt line, when the first driver * is registerd, will call the system function request_irq. The PLX * bridge needs enabling of interrupt in the interrupt control register to  * pass the local interrupts to the PCI (cpu). * For later registrations will just update the variables. On ISR, this driver * will look for registered handlers and calls the corresponding driver's * ISR "handler" function with "isr_data" as parameter. */int isp1362_request_irq(void (*handler)(struct isp1362_dev *, void *),                       struct isp1362_dev *dev, void *isr_data) {	int result = 0;	__u16	intcsr;	func_debug(("isp1362_request_irq(handler=%p,dev=%p,isr_data=%p)\n",handler,dev,isr_data))	if(!(hal_data.irq_usage)) {		/* If this is the first request 		 */   		result= request_irq(dev->irq,isp1362_pci_isr,				SA_SHIRQ, isp1362_driver_name, 				(void*)isp1362_loc_dev);	}	hal_data.irq_usage++;	if(result >= 0) {		if(hal_data.irq_usage == 1) {			/* If this is the first request 			 */			intcsr = inb(pci_io_base + PLX_INT_CSR_REG+1);			intcsr |= 0x09;			outb(intcsr,(pci_io_base + PLX_INT_CSR_REG+1));			func_debug(("Enabling PLX bridge local/cpu interrupts\n"))		}		dev->handler = handler;		dev->isr_data = isr_data;	}	return result;} /* End of isp1362_request_irq *//* This function de-registers the ISR of driver with this driver. * Since there is only one interrupt line, when the last driver * is de-registerd, will call the system function free_irq. The PLX * bridge needs disabling of interrupt in the interrupt control register to  * block the local interrupts to the PCI (cpu). */void isp1362_free_irq(struct isp1362_dev *dev, void *isr_data){	__u16	intcsr;	func_debug(("isp1362_free_irq(dev=%p,isr_data=%p)\n",dev,isr_data))	hal_data.irq_usage--;	if(!hal_data.irq_usage) {		/* If this is the last free request		 */		free_irq(dev->irq,isp1362_loc_dev);		intcsr = inb(pci_io_base + PLX_INT_CSR_REG+1);		intcsr &= 0xF6;		outb(intcsr,(pci_io_base + PLX_INT_CSR_REG+1));		detail_debug(("disabling PLX bridge local/PCI interrupts"))	}		} /* isp1362_free_irq *//*--------------------------------------------------------------* *            Driver Registration Functions *--------------------------------------------------------------*//* This function is used by top driver (OTG, HCD, DCD) to register * their communication functions (probe, remove, suspend, resume) using * the drv data structure. * This function will call the probe function of the driver if the ISP1362 * corresponding to the driver is enabled */int	isp1362_register_driver(struct isp1362_driver *drv) {	struct isp1362_dev	*dev;	int	result;	func_debug(("isp1362_register_driver(drv=%p)\n",drv))	if(!drv) return -EINVAL;	dev = &isp1362_loc_dev[drv->index];	if(dev->active) result = drv->probe(dev);	else result = -ENODEV;	if(result >= 0 ) {		dev->driver = drv;	}	return result;} /* End of isp1362_register_driver *//* This function is used by top driver (OTG, HCD, DCD) to de-register * their communication functions (probe, remove, suspend, resume) using * the drv data structure. * This function will check whether the driver is registered or not and * call the remove function of the driver if registered */void	isp1362_unregister_driver(struct isp1362_driver *drv){	struct isp1362_dev	*dev;	func_debug(("isp1362_unregister_driver(drv=%p)\n",drv))	dev = &isp1362_loc_dev[drv->index];	if(dev->driver == drv) {		/* driver registered is same as the requestig driver */		drv->remove(dev);		dev->driver = NULL;		return;	}} /* End of isp1362_unregister_driver *//*--------------------------------------------------------------* *                 Module Management Functions *--------------------------------------------------------------*//* This  is the module initialization function. It registers to  * PCI driver for a PLX PCI bridge device. And also resets the * internal data structures before registering to PCI driver. */static int __init isp1362_pci_module_init (void) {	int	result = 0;	func_debug(("isp1362_pci_module_init(void)\n"))	memset(isp1362_loc_dev,0,sizeof(isp1362_loc_dev));	if((result = pci_module_init(&isp1362_pci_driver)) < 0) {		detail_debug(("%s: Initialization Failed %d",isp1362_driver_name,result))		return result;	}	return result;}/* This  is the module eleanup function. It de-registers from  * PCI driver and resets the internal data structures. */static void __exit isp1362_pci_module_cleanup (void) {	func_debug(("isp1362_pci_module_cleanup(void)\n"))	pci_unregister_driver (&isp1362_pci_driver);	memset(isp1362_loc_dev,0,sizeof(isp1362_loc_dev));}  module_init (isp1362_pci_module_init);module_exit (isp1362_pci_module_cleanup);MODULE_AUTHOR (DRIVER_AUTHOR);MODULE_DESCRIPTION(DRIVER_DESC);

⌨️ 快捷键说明

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