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

📄 ibmtr.c

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 C
📖 第 1 页 / 共 5 页
字号:
/* ibmtr.c:  A shared-memory IBM Token Ring 16/4 driver for linux * *	Written 1993 by Mark Swanson and Peter De Schrijver. *	This software may be used and distributed according to the terms *	of the GNU General Public License, incorporated herein by reference. * *	This device driver should work with Any IBM Token Ring Card that does *	not use DMA. * *	I used Donald Becker's (becker@scyld.com) device driver work *	as a base for most of my initial work. * *	Changes by Peter De Schrijver *		(Peter.Deschrijver@linux.cc.kuleuven.ac.be) : * *	+ changed name to ibmtr.c in anticipation of other tr boards. *	+ changed reset code and adapter open code. *	+ added SAP open code. *	+ a first attempt to write interrupt, transmit and receive routines. * *	Changes by David W. Morris (dwm@shell.portal.com) : *	941003 dwm: - Restructure tok_probe for multiple adapters, devices. *	+ Add comments, misc reorg for clarity. *	+ Flatten interrupt handler levels. * *	Changes by Farzad Farid (farzy@zen.via.ecp.fr) *	and Pascal Andre (andre@chimay.via.ecp.fr) (March 9 1995) : *	+ multi ring support clean up. *	+ RFC1042 compliance enhanced. * *	Changes by Pascal Andre (andre@chimay.via.ecp.fr) (September 7 1995) : *	+ bug correction in tr_tx *	+ removed redundant information display *	+ some code reworking * *	Changes by Michel Lespinasse (walken@via.ecp.fr), *	Yann Doussot (doussot@via.ecp.fr) and Pascal Andre (andre@via.ecp.fr) *	(February 18, 1996) : *	+ modified shared memory and mmio access port the driver to *	  alpha platform (structure access -> readb/writeb) * *	Changes by Steve Kipisz (bungy@ibm.net or kipisz@vnet.ibm.com) *	(January 18 1996): *	+ swapped WWOR and WWCR in ibmtr.h *	+ moved some init code from tok_probe into trdev_init.  The *	  PCMCIA code can call trdev_init to complete initializing *	  the driver. *	+ added -DPCMCIA to support PCMCIA *	+ detecting PCMCIA Card Removal in interrupt handler.  If *	  ISRP is FF, then a PCMCIA card has been removed *        10/2000 Burt needed a new method to avoid crashing the OS * *	Changes by Paul Norton (pnorton@cts.com) : *	+ restructured the READ.LOG logic to prevent the transmit SRB *	  from being rudely overwritten before the transmit cycle is *	  complete. (August 15 1996) *	+ completed multiple adapter support. (November 20 1996) *	+ implemented csum_partial_copy in tr_rx and increased receive  *        buffer size and count. Minor fixes. (March 15, 1997) * *	Changes by Christopher Turcksin <wabbit@rtfc.demon.co.uk> *	+ Now compiles ok as a module again. * *	Changes by Paul Norton (pnorton@ieee.org) : *      + moved the header manipulation code in tr_tx and tr_rx to *        net/802/tr.c. (July 12 1997) *      + add retry and timeout on open if cable disconnected. (May 5 1998) *      + lifted 2000 byte mtu limit. now depends on shared-RAM size. *        May 25 1998) *      + can't allocate 2k recv buff at 8k shared-RAM. (20 October 1998) * *      Changes by Joel Sloan (jjs@c-me.com) : *      + disable verbose debug messages by default - to enable verbose *	  debugging, edit the IBMTR_DEBUG_MESSAGES define below  *	 *	Changes by Mike Phillips <phillim@amtrak.com> : *	+ Added extra #ifdef's to work with new PCMCIA Token Ring Code. *	  The PCMCIA code now just sets up the card so it can be recognized *        by ibmtr_probe. Also checks allocated memory vs. on-board memory *	  for correct figure to use. * *	Changes by Tim Hockin (thockin@isunix.it.ilstu.edu) : *	+ added spinlocks for SMP sanity (10 March 1999) * *      Changes by Jochen Friedrich to enable RFC1469 Option 2 multicasting *      i.e. using functional address C0 00 00 04 00 00 to transmit and  *      receive multicast packets. * *      Changes by Mike Sullivan (based on original sram patch by Dave Grothe *      to support windowing into on adapter shared ram. *      i.e. Use LANAID to setup a PnP configuration with 16K RAM. Paging *      will shift this 16K window over the entire available shared RAM. * *      Changes by Peter De Schrijver (p2@mind.be) : *      + fixed a problem with PCMCIA card removal * *      Change by Mike Sullivan et al.: *      + added turbo card support. No need to use lanaid to configure *      the adapter into isa compatiblity mode. * *      Changes by Burt Silverman to allow the computer to behave nicely when *	a cable is pulled or not in place, or a PCMCIA card is removed hot. *//* change the define of IBMTR_DEBUG_MESSAGES to a nonzero value in the event that chatty debug messages are desired - jjs 12/30/98 */#define IBMTR_DEBUG_MESSAGES 0#include <linux/module.h>#ifdef PCMCIA#undef MODULE#undef ENABLE_PAGING#else#define ENABLE_PAGING 1		#endif#define FALSE 0#define TRUE (!FALSE)/* changes the output format of driver initialization */#define TR_VERBOSE	0/* some 95 OS send many non UI frame; this allow removing the warning */#define TR_FILTERNONUI	1#include <linux/sched.h>#include <linux/ioport.h>#include <linux/netdevice.h>#include <linux/trdevice.h>#include <linux/ibmtr.h>#include <net/checksum.h>#include <asm/io.h>#define DPRINTK(format, args...) printk("%s: " format, dev->name , ## args)#define DPRINTD(format, args...) DummyCall("%s: " format, dev->name , ## args)#define MIN(X, Y) ((X) < (Y) ? (X) : (Y))#define MAX(X, Y) ((X) > (Y) ? (X) : (Y))/* version and credits */#ifndef PCMCIAstatic char version[] __initdata =    "\nibmtr.c: v1.3.57   8/ 7/94 Peter De Schrijver and Mark Swanson\n"    "         v2.1.125 10/20/98 Paul Norton    <pnorton@ieee.org>\n"    "         v2.2.0   12/30/98 Joel Sloan     <jjs@c-me.com>\n"    "         v2.2.1   02/08/00 Mike Sullivan  <sullivam@us.ibm.com>\n"     "         v2.2.2   07/27/00 Burt Silverman <burts@us.ibm.com>\n"     "         v2.4.0   03/01/01 Mike Sullivan <sullivan@us.ibm.com>\n";#endif/* this allows displaying full adapter information */char *channel_def[] __initdata = { "ISA", "MCA", "ISA P&P" };static char pcchannelid[] __devinitdata = {	0x05, 0x00, 0x04, 0x09,	0x04, 0x03, 0x04, 0x0f,	0x03, 0x06, 0x03, 0x01,	0x03, 0x01, 0x03, 0x00,	0x03, 0x09, 0x03, 0x09,	0x03, 0x00, 0x02, 0x00};static char mcchannelid[] __devinitdata =  {	0x04, 0x0d, 0x04, 0x01,	0x05, 0x02, 0x05, 0x03,	0x03, 0x06, 0x03, 0x03,	0x05, 0x08, 0x03, 0x04,	0x03, 0x05, 0x03, 0x01,	0x03, 0x08, 0x02, 0x00};char __devinit *adapter_def(char type){	switch (type) {	case 0xF: return "PC Adapter | PC Adapter II | Adapter/A";	case 0xE: return "16/4 Adapter | 16/4 Adapter/A (long)";	case 0xD: return "16/4 Adapter/A (short) | 16/4 ISA-16 Adapter";	case 0xC: return "Auto 16/4 Adapter";	default: return "adapter (unknown type)";	};};#define TRC_INIT 0x01		/*  Trace initialization & PROBEs */#define TRC_INITV 0x02		/*  verbose init trace points     */unsigned char ibmtr_debug_trace = 0;int 		ibmtr_probe(struct net_device *dev);static int	ibmtr_probe1(struct net_device *dev, int ioaddr);static unsigned char get_sram_size(struct tok_info *adapt_info);static int 	trdev_init(struct net_device *dev);static int 	tok_open(struct net_device *dev);static int 	tok_init_card(struct net_device *dev);void 		tok_open_adapter(unsigned long dev_addr);static void 	open_sap(unsigned char type, struct net_device *dev);static void 	tok_set_multicast_list(struct net_device *dev);static int 	tok_send_packet(struct sk_buff *skb, struct net_device *dev);static int 	tok_close(struct net_device *dev);void 		tok_interrupt(int irq, void *dev_id, struct pt_regs *regs);static void 	initial_tok_int(struct net_device *dev);static void 	tr_tx(struct net_device *dev);static void 	tr_rx(struct net_device *dev);void 		ibmtr_reset_timer(struct timer_list*tmr,struct net_device *dev);static void	tok_rerun(unsigned long dev_addr);void 		ibmtr_readlog(struct net_device *dev);static struct 	net_device_stats *tok_get_stats(struct net_device *dev);int 		ibmtr_change_mtu(struct net_device *dev, int mtu);static void	find_turbo_adapters(int *iolist);static int ibmtr_portlist[IBMTR_MAX_ADAPTERS+1] __devinitdata = {	0xa20, 0xa24, 0, 0, 0};static int __devinitdata turbo_io[IBMTR_MAX_ADAPTERS] = {0};static int __devinitdata turbo_irq[IBMTR_MAX_ADAPTERS] = {0};static int __devinitdata turbo_searched = 0;#ifndef PCMCIAstatic __u32 ibmtr_mem_base __initdata = 0xd0000;#endifstatic void __devinit PrtChanID(char *pcid, short stride){	short i, j;	for (i = 0, j = 0; i < 24; i++, j += stride)		printk("%1x", ((int) pcid[j]) & 0x0f);	printk("\n");}static void __devinit HWPrtChanID(void * pcid, short stride){	short i, j;	for (i = 0, j = 0; i < 24; i++, j += stride)		printk("%1x", ((int) readb(pcid + j)) & 0x0f);	printk("\n");}static void __devinit find_turbo_adapters(int *iolist) {	int ram_addr;	int index=0;	__u32 chanid;	int found_turbo=0;	unsigned char *tchanid, ctemp;	int i,j;  	if (turbo_searched == 1) return;	turbo_searched=1;	for (ram_addr=0xC0000; ram_addr < 0xE0000; ram_addr+=0x2000) {		__u32 intf_tbl=0;		found_turbo=1;		chanid=(CHANNEL_ID + ram_addr);		tchanid=pcchannelid;		ctemp=isa_readb(chanid) & 0x0f;		if (ctemp != *tchanid) continue;		for (i=2,j=1; i<=46; i=i+2,j++) {			if ((isa_readb(chanid+i) & 0x0f) != tchanid[j]){				found_turbo=0;				break;			}		}		if (!found_turbo) continue;		isa_writeb(0x90, ram_addr+0x1E01);		for(i=2; i<0x0f; i++) {			isa_writeb(0x00, ram_addr+0x1E01+i);		}		isa_writeb(0x00, ram_addr+0x1E01);		for(i=jiffies+TR_BUSY_INTERVAL; time_before_eq(jiffies,i););		intf_tbl=ntohs(isa_readw(ram_addr+ACA_OFFSET+ACA_RW+WRBR_EVEN));		if (intf_tbl) {#if IBMTR_DEBUG_MESSAGES			printk("ibmtr::find_turbo_adapters, Turbo found at "				"ram_addr %x\n",ram_addr);			printk("ibmtr::find_turbo_adapters, interface_table ");			for(i=0; i<6; i++) {				printk("%x:",isa_readb(ram_addr+intf_tbl+i));			}			printk("\n");#endif			turbo_io[index]=ntohs(isa_readw(ram_addr+intf_tbl+4));			turbo_irq[index]=isa_readb(ram_addr+intf_tbl+3);			outb(0, turbo_io[index] + ADAPTRESET);			for(i=jiffies+TR_RST_TIME;time_before_eq(jiffies,i););			outb(0, turbo_io[index] + ADAPTRESETREL);			index++;			continue;		}#if IBMTR_DEBUG_MESSAGES 		printk("ibmtr::find_turbo_adapters, ibmtr card found at"			" %x but not a Turbo model\n",ram_addr);#endif	}	for(i=0; i<IBMTR_MAX_ADAPTERS; i++) {		if(!turbo_io[i]) break;		for (j=0; j<IBMTR_MAX_ADAPTERS; j++) {			if ( iolist[j] && iolist[j] != turbo_io[i]) continue;			iolist[j]=turbo_io[i];			break;		}	}}/**************************************************************************** *	ibmtr_probe():  Routine specified in the network device structure *	to probe for an IBM Token Ring Adapter.  Routine outline: *	I.    Interrogate hardware to determine if an adapter exists *	      and what the speeds and feeds are *	II.   Setup data structures to control execution based upon *	      adapter characteristics. * *	We expect ibmtr_probe to be called once for each device entry *	which references it. ****************************************************************************/int __devinit ibmtr_probe(struct net_device *dev){	int i;	int base_addr = dev->base_addr;	if (base_addr && base_addr <= 0x1ff) /* Don't probe at all. */		return -ENXIO;	if (base_addr > 0x1ff) { /* Check a single specified location.  */		if (!ibmtr_probe1(dev, base_addr)) return 0;		return -ENODEV;	}	find_turbo_adapters(ibmtr_portlist);	for (i = 0; ibmtr_portlist[i]; i++) {		int ioaddr = ibmtr_portlist[i];		if (!ibmtr_probe1(dev, ioaddr)) return 0;	}	return -ENODEV;}/*****************************************************************************/static int __devinit ibmtr_probe1(struct net_device *dev, int PIOaddr){	unsigned char segment, intr=0, irq=0, i, j, cardpresent=NOTOK, temp=0;	void * t_mmio = 0;	struct tok_info *ti = 0;	void *cd_chanid;	unsigned char *tchanid, ctemp;#ifndef PCMCIA	unsigned char t_irq=0;        unsigned long timeout;	static int version_printed;#endif#ifndef MODULE#ifndef PCMCIA	dev = init_trdev(dev, 0);	if (!dev)		return -ENOMEM;#endif#endif	/*    Query the adapter PIO base port which will return	 *    indication of where MMIO was placed. We also have a	 *    coded interrupt number.	 */	segment = inb(PIOaddr);	if (segment < 0x40 || segment > 0xe0) {		/* Out of range values so we'll assume non-existent IO device		 * but this is not necessarily a problem, esp if a turbo		 * adapter is being used.  */#if IBMTR_DEBUG_MESSAGES		DPRINTK("ibmtr_probe1(): unhappy that inb(0x%X) == 0x%X, "			"Hardware Problem?\n",PIOaddr,segment);#endif		return -ENODEV;	}	/*	 *    Compute the linear base address of the MMIO area	 *    as LINUX doesn't care about segments	 */	t_mmio = ioremap(((__u32) (segment & 0xfc) << 11) + 0x80000,2048);	if (!t_mmio) { 		DPRINTK("Cannot remap mmiobase memory area") ; 		return -ENODEV ; 	} 	intr = segment & 0x03;	/* low bits is coded interrupt # */	if (ibmtr_debug_trace & TRC_INIT)		DPRINTK("PIOaddr: %4hx seg/intr: %2x mmio base: %p intr: %d\n"				, PIOaddr, (int) segment, t_mmio, (int) intr);	/*	 *    Now we will compare expected 'channelid' strings with	 *    what we is there to learn of ISA/MCA or not TR card	 */#ifdef PCMCIA	iounmap(t_mmio);	ti = dev->priv;		/*BMS moved up here */	t_mmio = (void *)ti->mmio;	/*BMS to get virtual address */	irq = ti->irq;		/*BMS to display the irq!   */

⌨️ 快捷键说明

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