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

📄 daynaport.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
		return -1;		nubus_get_rsrc_mem(addr, &ent, 6);	return 0;}int __init ns8390_probe1(struct net_device *dev, int word16, char *model_name,			 int type, int promoff, struct nubus_dev *ndev){	static u32 fwrd4_offsets[16]={		0,      4,      8,      12,		16,     20,     24,     28,		32,     36,     40,     44,		48,     52,     56,     60	};	static u32 back4_offsets[16]={		60,     56,     52,     48,		44,     40,     36,     32,		28,     24,     20,     16,		12,     8,      4,      0	};	static u32 fwrd2_offsets[16]={		0,      2,      4,      6,		8,     10,     12,     14,		16,    18,     20,     22,		24,    26,     28,     30	};	unsigned char *prom = (unsigned char*) ndev->board->slot_addr + promoff;	/* Allocate dev->priv and fill in 8390 specific dev fields. */	if (ethdev_init(dev)) 	{			printk ("%s: unable to get memory for dev->priv.\n", dev->name);		return -ENOMEM;	}	/* OK, we are certain this is going to work.  Setup the device. */	ei_status.name = model_name;	ei_status.word16 = word16;       if (type==NS8390_CABLETRON) {               /* Cabletron card puts the RX buffer before the TX buffer */               ei_status.tx_start_page = CABLETRON_TX_START_PG;               ei_status.rx_start_page = CABLETRON_RX_START_PG;               ei_status.stop_page = CABLETRON_RX_STOP_PG;               dev->rmem_start = dev->mem_start;               dev->rmem_end = dev->mem_start + CABLETRON_RX_STOP_PG*256;       } else {               ei_status.tx_start_page = WD_START_PG;               ei_status.rx_start_page = WD_START_PG + TX_PAGES;               ei_status.stop_page = (dev->mem_end - dev->mem_start)/256;               dev->rmem_start = dev->mem_start + TX_PAGES*256;               dev->rmem_end = dev->mem_end;       }		if(promoff==-1)		/* Use nubus resources ? */	{		if(mac8390_ethernet_addr(ndev, dev->dev_addr))		{		  printk("mac_ns8390: MAC address not in resources!\n");		  return -ENODEV;		}	}	else			/* Pull it off the card */	{		int i=0;		int x=1;		/* These should go in the end I hope */		if(type==NS8390_DAYNA)			x=2;		if(type==NS8390_INTERLAN || type==NS8390_KINETICS)			x=4;		while(i<6)		{			dev->dev_addr[i]=*prom;			prom+=x;			if(i)				printk(":");			printk("%02X",dev->dev_addr[i++]);		}	}	printk(KERN_INFO "%s: %s in slot %X (type %s)\n",		   dev->name, ndev->board->name, ndev->board->slot, model_name);	printk(KERN_INFO "MAC ");	{		int i;		for (i = 0; i < 6; i++) {			printk("%2.2x", dev->dev_addr[i]);			if (i < 5)				printk(":");		}	}	printk(" IRQ %d, shared memory at %#lx-%#lx.\n",		   dev->irq, dev->mem_start, dev->mem_end-1);	switch(type)	{		case NS8390_DAYNA:      /* Dayna card */		case NS8390_KINETICS:   /* Kinetics --  8 bit config, but 16 bit mem */			/* 16 bit, 4 word offsets */			ei_status.reset_8390 = &ns8390_no_reset;			ei_status.block_input = &dayna_block_input;			ei_status.block_output = &dayna_block_output;			ei_status.get_8390_hdr = &dayna_get_8390_hdr;			ei_status.reg_offset = fwrd4_offsets;			break;		case NS8390_CABLETRON: /* Cabletron */			/*		16 bit card, register map is short forward */			ei_status.reset_8390 = &ns8390_no_reset;			/* Ctron card won't accept 32bit values read or written to it */			ei_status.block_input = &slow_sane_block_input;			ei_status.block_output = &slow_sane_block_output;			ei_status.get_8390_hdr = &slow_sane_get_8390_hdr;			ei_status.reg_offset = fwrd2_offsets;			break;		case NS8390_FARALLON:		case NS8390_APPLE:	/* Apple/Asante/Farallon */			/*      16 bit card, register map is reversed */			ei_status.reset_8390 = &ns8390_no_reset;			ei_status.block_input = &slow_sane_block_input;			ei_status.block_output = &slow_sane_block_output;			ei_status.get_8390_hdr = &slow_sane_get_8390_hdr;			ei_status.reg_offset = back4_offsets;			break;		case NS8390_ASANTE:			/*      16 bit card, register map is reversed */			ei_status.reset_8390 = &ns8390_no_reset;			ei_status.block_input = &sane_block_input;			ei_status.block_output = &sane_block_output;			ei_status.get_8390_hdr = &sane_get_8390_hdr;			ei_status.reg_offset = back4_offsets;			break;		case NS8390_INTERLAN:   /* Interlan */			/*      16 bit card, map is forward */			ei_status.reset_8390 = &interlan_reset;			ei_status.block_input = &sane_block_input;			ei_status.block_output = &sane_block_output;			ei_status.get_8390_hdr = &sane_get_8390_hdr;			ei_status.reg_offset = back4_offsets;			break;#if 0 /* i think this suffered code rot.  my kinetics card has much	   * different settings.  -- CSA [22-May-1999] */		case NS8390_KINETICS:   /* Kinetics */			/*      8bit card, map is forward */			ei_status.reset_8390 = &ns8390_no_reset;			ei_status.block_input = &sane_block_input;			ei_status.block_output = &sane_block_output;			ei_status.get_8390_hdr = &sane_get_8390_hdr;			ei_status.reg_offset = back4_offsets;			break;#endif		default:			panic("Detected a card I can't drive - whoops\n");	}	dev->open = &ns8390_open;	dev->stop = &ns8390_close_card;	NS8390_init(dev, 0);	return 0;}static int ns8390_open(struct net_device *dev){	MOD_INC_USE_COUNT;	ei_open(dev);	/* At least on my card (a Focus Enhancements PDS card) I start */	/* getting interrupts right away, so the driver needs to be    */	/* completely initialized before enabling the interrupt.        */	/*                             - funaho@jurai.org (1999-05-17) */	/* Non-slow interrupt, works around issues with the SONIC driver */	if (request_irq(dev->irq, ei_interrupt, 0, "8390 Ethernet", dev)) 	{		printk ("%s: unable to get IRQ %d.\n", dev->name, dev->irq);		MOD_DEC_USE_COUNT;		return -EAGAIN;	}	return 0;}static void ns8390_no_reset(struct net_device *dev){	if (ei_debug > 1) 		printk("Need to reset the NS8390 t=%lu...", jiffies);	ei_status.txing = 0;	if (ei_debug > 1) printk("reset not supported\n");	return;}static int ns8390_close_card(struct net_device *dev){	if (ei_debug > 1)		printk("%s: Shutting down ethercard.\n", dev->name);	free_irq(dev->irq, dev);	ei_close(dev);	MOD_DEC_USE_COUNT;	return 0;}/* *    Interlan Specific Code Starts Here */static void interlan_reset(struct net_device *dev){	unsigned char *target=nubus_slot_addr(IRQ2SLOT(dev->irq));	if (ei_debug > 1) 		printk("Need to reset the NS8390 t=%lu...", jiffies);	ei_status.txing = 0;	/* This write resets the card */	target[0xC0000]=0;	if (ei_debug > 1) printk("reset complete\n");	return;}/* *    Daynaport code (some is used by other drivers) *//* Grab the 8390 specific header. Similar to the block_input routine, but   we don't need to be concerned with ring wrap as the header will be at   the start of a page, so we optimize accordingly. *//* Block input and output are easy on shared memory ethercards, and trivial   on the Daynaport card where there is no choice of how to do it.   The only complications are that the ring buffer wraps.*/static void dayna_memcpy_fromcard(struct net_device *dev, void *to, int from, int count){	volatile unsigned short *ptr;	unsigned short *target=to;	from<<=1;	/* word, skip overhead */	ptr=(unsigned short *)(dev->mem_start+from);	/*	 * Leading byte?	 */	if (from&2) {		*((char *)target)++ = *(((char *)ptr++)-1);		count--;	}	while(count>=2)	{		*target++=*ptr++;	/* Copy and */		ptr++;			/* skip cruft */		count-=2;	}	/*	 *	Trailing byte ?	 */	if(count)	{		/* Big endian */		unsigned short v=*ptr;		*((char *)target)=v>>8;	}}static void dayna_memcpy_tocard(struct net_device *dev, int to, const void *from, int count){	volatile unsigned short *ptr;	const unsigned short *src=from;	to<<=1;	/* word, skip overhead */	ptr=(unsigned short *)(dev->mem_start+to);	/*	 * Leading byte?	 */	if (to&2) { /* avoid a byte write (stomps on other data) */		ptr[-1] = (ptr[-1]&0xFF00)|*((unsigned char *)src)++;		ptr++;		count--;	}	while(count>=2)	{		*ptr++=*src++;		/* Copy and */		ptr++;			/* skip cruft */		count-=2;	}	/*	 *	Trailing byte ?	 */	if(count)	{		/* Big endian */		unsigned short v=*src;		/* card doesn't like byte writes */		*ptr=(*ptr&0x00FF)|(v&0xFF00);	}}static void dayna_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page){	unsigned long hdr_start = (ring_page - WD_START_PG)<<8;	dayna_memcpy_fromcard(dev, (void *)hdr, hdr_start, 4);	/* Register endianism - fix here rather than 8390.c */	hdr->count=(hdr->count&0xFF)<<8|(hdr->count>>8);}static void dayna_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset){	unsigned long xfer_base = ring_offset - (WD_START_PG<<8);	unsigned long xfer_start = xfer_base+dev->mem_start;	/*	 *	Note the offset maths is done in card memory space which	 *	is word per long onto our space.	 */	 	if (xfer_start + count > dev->rmem_end) 	{		/* We must wrap the input move. */		int semi_count = dev->rmem_end - xfer_start;		dayna_memcpy_fromcard(dev, skb->data, xfer_base, semi_count);		count -= semi_count;		dayna_memcpy_fromcard(dev, skb->data + semi_count, 			dev->rmem_start - dev->mem_start, count);	}	else	{		dayna_memcpy_fromcard(dev, skb->data, xfer_base, count);	}}static void dayna_block_output(struct net_device *dev, int count, const unsigned char *buf,				int start_page){	long shmem = (start_page - WD_START_PG)<<8;		dayna_memcpy_tocard(dev, shmem, buf, count);}/* *	Cards with full width memory */static void sane_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page){	unsigned long hdr_start = (ring_page - WD_START_PG)<<8;	memcpy((void *)hdr, (char *)dev->mem_start+hdr_start, 4);	/* Register endianism - fix here rather than 8390.c */	hdr->count=(hdr->count&0xFF)<<8|(hdr->count>>8);}static void sane_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset){	unsigned long xfer_base = ring_offset - (WD_START_PG<<8);	unsigned long xfer_start = xfer_base+dev->mem_start;	if (xfer_start + count > dev->rmem_end) 	{		/* We must wrap the input move. */		int semi_count = dev->rmem_end - xfer_start;		memcpy(skb->data, (char *)dev->mem_start+xfer_base, semi_count);		count -= semi_count;		memcpy(skb->data + semi_count, 			(char *)dev->rmem_start, count);	}	else	{		memcpy(skb->data, (char *)dev->mem_start+xfer_base, count);	}}static void sane_block_output(struct net_device *dev, int count, const unsigned char *buf,				int start_page){	long shmem = (start_page - WD_START_PG)<<8;		memcpy((char *)dev->mem_start+shmem, buf, count);}static void word_memcpy_tocard(void *tp, const void *fp, int count){	volatile unsigned short *to = tp;	const unsigned short *from = fp;		count++;	count/=2;		while(count--)		*to++=*from++;}static void word_memcpy_fromcard(void *tp, const void *fp, int count){	unsigned short *to = tp;	const volatile unsigned short *from = fp;		count++;	count/=2;		while(count--)		*to++=*from++;}static void slow_sane_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page){	unsigned long hdr_start = (ring_page - WD_START_PG)<<8;	word_memcpy_fromcard((void *)hdr, (char *)dev->mem_start+hdr_start, 4);	/* Register endianism - fix here rather than 8390.c */	hdr->count=(hdr->count&0xFF)<<8|(hdr->count>>8);}static void slow_sane_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset){	unsigned long xfer_base = ring_offset - (WD_START_PG<<8);	unsigned long xfer_start = xfer_base+dev->mem_start;	if (xfer_start + count > dev->rmem_end) 	{		/* We must wrap the input move. */		int semi_count = dev->rmem_end - xfer_start;		word_memcpy_fromcard(skb->data, (char *)dev->mem_start+xfer_base, semi_count);		count -= semi_count;		word_memcpy_fromcard(skb->data + semi_count, 			(char *)dev->rmem_start, count);	}	else	{		word_memcpy_fromcard(skb->data, (char *)dev->mem_start+xfer_base, count);	}}static void slow_sane_block_output(struct net_device *dev, int count, const unsigned char *buf,				int start_page){	long shmem = (start_page - WD_START_PG)<<8;		word_memcpy_tocard((char *)dev->mem_start+shmem, buf, count);#if 0	long shmem = (start_page - WD_START_PG)<<8;	volatile unsigned short *to=(unsigned short *)(dev->mem_start+shmem);	volatile int p;	unsigned short *bp=(unsigned short *)buf;		count=(count+1)/2;		while(count--)	{		*to++=*bp++;		for(p=0;p<10;p++)			p++;	}#endif	}/* * Local variables: *  compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c daynaport.c" *  version-control: t *  c-basic-offset: 4 *  tab-width: 4 *  kept-new-versions: 5 * End: */

⌨️ 快捷键说明

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