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

📄 aironet4500_card.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *	 Aironet 4500 PCI-ISA-i365 driver * *		Elmer Joandi, Januar 1999 *	Copyright GPL *	 * *	Revision 0.1 ,started  30.12.1998 * *	Revision 0.2, Feb 27, 2000 *		Jeff Garzik - softnet, cleanups * */#ifdef MODULEstatic const char *awc_version ="aironet4500_cards.c v0.2  Feb 27, 2000  Elmer Joandi, elmer@ylenurme.ee.\n";#endif#include <linux/version.h>#include <linux/config.h>#include <linux/module.h>#include <linux/kernel.h>#include <linux/sched.h>#include <linux/ptrace.h>#include <linux/malloc.h>#include <linux/string.h>#include <linux/timer.h>#include <linux/interrupt.h>#include <linux/in.h>#include <asm/io.h>#include <asm/system.h>#include <asm/bitops.h>#include <linux/netdevice.h>#include <linux/etherdevice.h>#include <linux/skbuff.h>#include <linux/if_arp.h>#include <linux/ioport.h>#include <linux/delay.h>#include "aironet4500.h"#define PCI_VENDOR_ID_AIRONET 	0x14b9#define PCI_DEVICE_AIRONET_4800_1 0x1#define PCI_DEVICE_AIRONET_4800 0x4500#define PCI_DEVICE_AIRONET_4500 0x4800#define AIRONET4X00_IO_SIZE 	0x40#define AIRONET4X00_CIS_SIZE	0x300#define AIRONET4X00_MEM_SIZE	0x300#define AIRONET4500_PCI 	1#define AIRONET4500_PNP		2#define AIRONET4500_ISA		3#define AIRONET4500_365		4#ifdef CONFIG_AIRONET4500_PCI#include <linux/pci.h>static int reverse_probe;static int awc_pci_init(struct net_device * dev, struct pci_dev *pdev, 			int ioaddr, int cis_addr, int mem_addr,u8 pci_irq_line) ;int awc4500_pci_probe(struct net_device *dev){	int cards_found = 0;	static int pci_index;	/* Static, for multiple probe calls. */	u8 pci_irq_line = 0;//	int p;	unsigned char awc_pci_dev, awc_pci_bus;	if (!pci_present()) 		return -1;	for (;pci_index < 0xff; pci_index++) {		u16 vendor, device, pci_command, new_command;		u32 pci_memaddr;		u32 pci_ioaddr;		u32 pci_cisaddr;		struct pci_dev *pdev;		if (pcibios_find_class	(PCI_CLASS_NETWORK_OTHER << 8,			 reverse_probe ? 0xfe - pci_index : pci_index,				 &awc_pci_bus, &awc_pci_dev) != PCIBIOS_SUCCESSFUL){				if (reverse_probe){					continue;				} else {					break;				}		}		pdev = pci_find_slot(awc_pci_bus, awc_pci_dev);		if (!pdev)			continue;		if (pci_enable_device(pdev))			continue;		vendor = pdev->vendor;		device = pdev->device;	        pci_irq_line = pdev->irq;		pci_memaddr = pci_resource_start (pdev, 0);                pci_cisaddr = pci_resource_start (pdev, 1);		pci_ioaddr = pci_resource_start (pdev, 2);//		printk("\n pci capabilities %x and ptr %x \n",pci_caps,pci_caps_ptr);		/* Remove I/O space marker in bit 0. */		if (vendor != PCI_VENDOR_ID_AIRONET)			continue;		if (device != PCI_DEVICE_AIRONET_4800_1 && 				device != PCI_DEVICE_AIRONET_4800 &&				device != PCI_DEVICE_AIRONET_4500 )                        continue;//		if (check_region(pci_ioaddr, AIRONET4X00_IO_SIZE) ||//			check_region(pci_cisaddr, AIRONET4X00_CIS_SIZE) ||//			check_region(pci_memaddr, AIRONET4X00_MEM_SIZE)) {//				printk(KERN_ERR "aironet4X00 mem addrs not available for maping \n");//				continue;//		}		if (!request_region(pci_ioaddr, AIRONET4X00_IO_SIZE, "aironet4x00 ioaddr"))			continue;//		request_region(pci_cisaddr, AIRONET4X00_CIS_SIZE, "aironet4x00 cis");//		request_region(pci_memaddr, AIRONET4X00_MEM_SIZE, "aironet4x00 mem");//		pci_write_config_word(pdev, PCI_COMMAND, 0);		udelay(10000);		pci_read_config_word(pdev, PCI_COMMAND, &pci_command);		new_command = pci_command |0x100 | PCI_COMMAND_MEMORY|PCI_COMMAND_IO;		if (pci_command != new_command) {			printk(KERN_INFO "  The PCI BIOS has not enabled this"				   " device!  Updating PCI command %4.4x->%4.4x.\n",				   pci_command, new_command);			pci_write_config_word(pdev, PCI_COMMAND, new_command);		}/*		if (device == PCI_DEVICE_AIRONET_4800)			pci_write_config_dword(pdev, 0x40, 0x00000000);		udelay(1000);*/		if (device == PCI_DEVICE_AIRONET_4800)			pci_write_config_dword(pdev, 0x40, 0x40000000);		if (awc_pci_init(dev, pdev, pci_ioaddr,pci_cisaddr,pci_memaddr,pci_irq_line)){			printk(KERN_ERR "awc4800 pci init failed \n");			break;		}		dev = 0;		cards_found++;	}	return cards_found ? 0 : -ENODEV;}static int awc_pci_init(struct net_device * dev, struct pci_dev *pdev, 			int ioaddr, int cis_addr, int mem_addr, u8 pci_irq_line) {	int i, allocd_dev = 0;	if (!dev) {		dev = init_etherdev(NULL, 0);			if (!dev)			return -ENOMEM;		allocd_dev = 1;	}	dev->priv = kmalloc(sizeof(struct awc_private),GFP_KERNEL );	memset(dev->priv,0,sizeof(struct awc_private));	if (!dev->priv) {		printk(KERN_CRIT "aironet4x00: could not allocate device private, some unstability may follow\n");		if (allocd_dev) {			unregister_netdev(dev);			kfree(dev);		}		return -ENOMEM;	};//	ether_setup(dev);//	dev->tx_queue_len = tx_queue_len;	dev->hard_start_xmit = 		&awc_start_xmit;//	dev->set_config = 		&awc_config_misiganes,aga mitte awc_config;	dev->get_stats = 		&awc_get_stats;//	dev->set_multicast_list = 	&awc_set_multicast_list;	dev->change_mtu		=	awc_change_mtu;	dev->init = &awc_init;	dev->open = &awc_open;	dev->stop = &awc_close;    	dev->base_addr = ioaddr;    	dev->irq = pci_irq_line;	dev->tx_timeout = &awc_tx_timeout;	dev->watchdog_timeo = AWC_TX_TIMEOUT;		i = request_irq(dev->irq,awc_interrupt, SA_SHIRQ | SA_INTERRUPT, dev->name, dev);	if (i) {		kfree(dev->priv);		dev->priv = NULL;		if (allocd_dev) {			unregister_netdev(dev);			kfree(dev);		}		return i;	}	awc_private_init( dev);	awc_init(dev);	i=0;	while (aironet4500_devices[i] && i < MAX_AWCS-1) i++;	if (!aironet4500_devices[i]){		aironet4500_devices[i]=dev;		((struct awc_private *)		aironet4500_devices[i]->priv)->card_type = AIRONET4500_PCI;		if (awc_proc_set_fun)			awc_proc_set_fun(i);	}//	if (register_netdev(dev) != 0) {//		printk(KERN_NOTICE "awc_cs: register_netdev() failed\n");//		goto failed;//	}	return 0; //  failed://  	return -1;}#ifdef MODULEstatic void awc_pci_release(void) {//	long flags;	int i=0;	DEBUG(0, "awc_detach \n");	i=0;	while ( i < MAX_AWCS) {		if (!aironet4500_devices[i])                        {i++; continue;};		if (((struct awc_private *)aironet4500_devices[i]->priv)->card_type != AIRONET4500_PCI)		                  {i++;      continue;}		if (awc_proc_unset_fun)			awc_proc_unset_fun(i);		release_region(aironet4500_devices[i]->base_addr, AIRONET4X00_IO_SIZE);//		release_region(pci_cisaddr, AIRONET4X00_CIS_SIZE, "aironet4x00 cis");//		release_region(pci_memaddr, AIRONET4X00_MEM_SIZE, "aironet4x00 mem");		unregister_netdev(aironet4500_devices[i]);		free_irq(aironet4500_devices[i]->irq,aironet4500_devices[i]);		kfree(aironet4500_devices[i]->priv);		kfree(aironet4500_devices[i]);		aironet4500_devices[i]=0;		i++;	}	} #endif //MODULE#endif /* CONFIG_AIRONET4500_PCI */#ifdef CONFIG_AIRONET4500_PNP#include <linux/isapnp.h>#define AIRONET4X00_IO_SIZE 	0x40#define isapnp_logdev pci_dev#define isapnp_dev    pci_bus#define isapnp_find_device isapnp_find_card#define isapnp_find_logdev isapnp_find_dev#define PNP_BUS bus#define PNP_BUS_NUMBER number#define PNP_DEV_NUMBER devfnint awc4500_pnp_hw_reset(struct net_device *dev){	struct isapnp_logdev *logdev;	DEBUG(0, "awc_pnp_reset \n");	if (!dev->priv ) {		printk("awc4500 no dev->priv in hw_reset\n");		return -1;	};	logdev = ((struct isapnp_logdev *) ((struct awc_private *)dev->priv)->bus);	if (!logdev ) {		printk("awc4500 no pnp logdev in hw_reset\n");		return -1;	};	if (isapnp_cfg_begin(logdev->PNP_BUS->PNP_BUS_NUMBER, logdev->PNP_DEV_NUMBER)<0)		printk("isapnp cfg failed at release \n");	isapnp_deactivate(logdev->PNP_DEV_NUMBER);	isapnp_cfg_end();	udelay(100);	if (isapnp_cfg_begin(logdev->PNP_BUS->PNP_BUS_NUMBER, logdev->PNP_DEV_NUMBER) < 0) {		printk("%s cfg begin failed in hw_reset for csn %x devnum %x \n",				dev->name, logdev->PNP_BUS->PNP_BUS_NUMBER, logdev->PNP_DEV_NUMBER);		return -EAGAIN;	}	isapnp_activate(logdev->PNP_DEV_NUMBER);	/* activate device */	isapnp_cfg_end();	return 0;}int awc4500_pnp_probe(struct net_device *dev){	int isa_index = 0;	int isa_irq_line = 0;	int isa_ioaddr = 0;	int card = 0;	int i=0;	struct isapnp_dev * pnp_dev ;	struct isapnp_logdev *logdev;	while (1) {		pnp_dev = isapnp_find_device(						ISAPNP_VENDOR('A','W','L'), 						ISAPNP_DEVICE(1),						0);			if (!pnp_dev) break;  				isa_index++;		logdev = isapnp_find_logdev(pnp_dev, ISAPNP_VENDOR('A','W','L'),				    ISAPNP_FUNCTION(1),				    0);		if (!logdev){			printk("No logical device found on Aironet board \n");			return -ENODEV;		}		if (isapnp_cfg_begin(logdev->PNP_BUS->PNP_BUS_NUMBER, logdev->PNP_DEV_NUMBER) < 0) {			printk("cfg begin failed for csn %x devnum %x \n",					logdev->PNP_BUS->PNP_BUS_NUMBER, logdev->PNP_DEV_NUMBER);			return -EAGAIN;		}		isapnp_activate(logdev->PNP_DEV_NUMBER);	/* activate device */		isapnp_cfg_end();		isa_irq_line = logdev->irq;		isa_ioaddr = logdev->resource[0].start;		request_region(isa_ioaddr, AIRONET4X00_IO_SIZE, "aironet4x00 ioaddr");		if (!dev) {			dev = init_etherdev(dev, 0 );			}		dev->priv = kmalloc(sizeof(struct awc_private),GFP_KERNEL );		memset(dev->priv,0,sizeof(struct awc_private));		if (!dev->priv) {			printk(KERN_CRIT "aironet4x00: could not allocate device private, some unstability may follow\n");			return -1;		};		((struct awc_private *)dev->priv)->bus =  logdev;	//	ether_setup(dev);		//	dev->tx_queue_len = tx_queue_len;			dev->hard_start_xmit = 		&awc_start_xmit;	//	dev->set_config = 		&awc_config_misiganes,aga mitte awc_config;		dev->get_stats = 		&awc_get_stats;	//	dev->set_multicast_list = 	&awc_set_multicast_list;			dev->change_mtu		=	awc_change_mtu;			dev->init = &awc_init;		dev->open = &awc_open;		dev->stop = &awc_close;	    	dev->base_addr = isa_ioaddr;	    	dev->irq = isa_irq_line;		dev->tx_timeout = &awc_tx_timeout;		dev->watchdog_timeo = AWC_TX_TIMEOUT;				netif_start_queue (dev);				request_irq(dev->irq,awc_interrupt , SA_SHIRQ | SA_INTERRUPT ,"Aironet 4X00",dev);		awc_private_init( dev);		((struct awc_private *)dev->priv)->bus =  logdev;		cli();		if ( awc_init(dev) ){			printk("card not found at irq %x io %lx\n",dev->irq, dev->base_addr);			if (card==0){				sti();				return -1;			}			sti();			break;		}		udelay(10);		sti();		i=0;		while (aironet4500_devices[i] && i < MAX_AWCS-1) i++;		if (!aironet4500_devices[i] && i < MAX_AWCS-1 ){			aironet4500_devices[i]=dev;		((struct awc_private *)		aironet4500_devices[i]->priv)->card_type = AIRONET4500_PNP;			if (awc_proc_set_fun)				awc_proc_set_fun(i);			} else { 			printk(KERN_CRIT "Out of resources (MAX_AWCS) \n");			return -1;		}		card++;		}	if (card == 0) return -ENODEV;	return 0;}#ifdef MODULEstatic void awc_pnp_release(void) {//	long flags;	int i=0;	struct isapnp_logdev *logdev;	DEBUG(0, "awc_detach \n");	i=0;	while ( i < MAX_AWCS) {		if (!aironet4500_devices[i])		                  {i++;      continue;}		if (((struct awc_private *)aironet4500_devices[i]->priv)->card_type != AIRONET4500_PNP)		                  {i++;      continue;}		logdev = ((struct isapnp_logdev *) ((struct awc_private *)aironet4500_devices[i]->priv)->bus);		if (!logdev ) 			printk("awc4500 no pnp logdev in pnp_release\n");		if (awc_proc_unset_fun)			awc_proc_unset_fun(i);		if (isapnp_cfg_begin(logdev->PNP_BUS->PNP_BUS_NUMBER, logdev->PNP_DEV_NUMBER)<0)			printk("isapnp cfg failed at release \n");		isapnp_deactivate(logdev->PNP_DEV_NUMBER);		isapnp_cfg_end();		release_region(aironet4500_devices[i]->base_addr, AIRONET4X00_IO_SIZE);//		release_region(isa_cisaddr, AIRONET4X00_CIS_SIZE, "aironet4x00 cis");//		release_region(isa_memaddr, AIRONET4X00_MEM_SIZE, "aironet4x00 mem");		unregister_netdev(aironet4500_devices[i]);		free_irq(aironet4500_devices[i]->irq,aironet4500_devices[i]);		kfree(aironet4500_devices[i]->priv);		kfree(aironet4500_devices[i]);		aironet4500_devices[i]=0;		i++;	}	} #endif //MODULE#endif /* CONFIG_AIRONET4500_PNP */#ifdef  CONFIG_AIRONET4500_ISA static int irq[] = {0,0,0,0,0};static int io[] = {0,0,0,0,0};/* 	EXPORT_SYMBOL(irq);	EXPORT_SYMBOL(io);*/MODULE_PARM(irq,"i");MODULE_PARM_DESC(irq,"Aironet 4x00 ISA non-PNP irqs,required");MODULE_PARM(io,"i");MODULE_PARM_DESC(io,"Aironet 4x00 ISA non-PNP ioports,required");int awc4500_isa_probe(struct net_device *dev){//	int cards_found = 0;//	static int isa_index;	/* Static, for multiple probe calls. */	int isa_irq_line = 0;

⌨️ 快捷键说明

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