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

📄 sbni.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 3 页
字号:
	nl->cur_rxl_rcvd  = 0;}/* -------------------------------------------------------------------------- *//* *	Open/initialize the board.  */static intsbni_open( struct net_device  *dev ){	struct net_local	*nl = (struct net_local *) dev->priv;	struct timer_list	*w  = &nl->watchdog;	/*	 * For double ISA adapters within "common irq" mode, we have to	 * determine whether primary or secondary channel is initialized,	 * and set the irq handler only in first case.	 */	if( dev->base_addr < 0x400 ) {		/* ISA only */		struct net_device  **p = sbni_cards;		for( ;  *p  &&  p < sbni_cards + SBNI_MAX_NUM_CARDS;  ++p )			if( (*p)->irq == dev->irq			    &&  ((*p)->base_addr == dev->base_addr + 4				 ||  (*p)->base_addr == dev->base_addr - 4)			    &&  (*p)->flags & IFF_UP ) {				((struct net_local *) ((*p)->priv))					->second = dev;				printk( KERN_NOTICE "%s: using shared irq "					"with %s\n", dev->name, (*p)->name );				nl->state |= FL_SECONDARY;				goto  handler_attached;			}	}	if( request_irq(dev->irq, sbni_interrupt, SA_SHIRQ, dev->name, dev) ) {		printk( KERN_ERR "%s: unable to get IRQ %d.\n",			dev->name, dev->irq );		return  -EAGAIN;	}handler_attached:	spin_lock( &nl->lock );	memset( &nl->stats, 0, sizeof(struct net_device_stats) );	memset( &nl->in_stats, 0, sizeof(struct sbni_in_stats) );	card_start( dev );	netif_start_queue( dev );	/* set timer watchdog */	init_timer( w );	w->expires	= jiffies + SBNI_TIMEOUT;	w->data		= (unsigned long) dev;	w->function	= sbni_watchdog;	add_timer( w );   	spin_unlock( &nl->lock );	return 0;}static intsbni_close( struct net_device  *dev ){	struct net_local  *nl = (struct net_local *) dev->priv;	if( nl->second  &&  nl->second->flags & IFF_UP ) {		printk( KERN_NOTICE "Secondary channel (%s) is active!\n",			nl->second->name );		return  -EBUSY;	}#ifdef CONFIG_SBNI_MULTILINE	if( nl->state & FL_SLAVE )		emancipate( dev );	else		while( nl->link )	/* it's master device! */			emancipate( nl->link );#endif	spin_lock( &nl->lock );	nl->second = NULL;	drop_xmit_queue( dev );		netif_stop_queue( dev );   	del_timer( &nl->watchdog );	outb( 0, dev->base_addr + CSR0 );	if( !(nl->state & FL_SECONDARY) )		free_irq( dev->irq, dev );	nl->state &= FL_SECONDARY;	spin_unlock( &nl->lock );	return 0;}/*	Valid combinations in CSR0 (for probing):	VALID_DECODER	0000,0011,1011,1010				    	; 0   ; -				TR_REQ	; 1   ; +			TR_RDY	    	; 2   ; -			TR_RDY	TR_REQ	; 3   ; +		BU_EMP		    	; 4   ; +		BU_EMP	     	TR_REQ	; 5   ; +		BU_EMP	TR_RDY	    	; 6   ; -		BU_EMP	TR_RDY	TR_REQ	; 7   ; +	RC_RDY 		     		; 8   ; +	RC_RDY			TR_REQ	; 9   ; +	RC_RDY		TR_RDY		; 10  ; -	RC_RDY		TR_RDY	TR_REQ	; 11  ; -	RC_RDY	BU_EMP			; 12  ; -	RC_RDY	BU_EMP		TR_REQ	; 13  ; -	RC_RDY	BU_EMP	TR_RDY		; 14  ; -	RC_RDY	BU_EMP	TR_RDY	TR_REQ	; 15  ; -*/#define VALID_DECODER (2 + 8 + 0x10 + 0x20 + 0x80 + 0x100 + 0x200)static intsbni_card_probe( unsigned long  ioaddr ){	unsigned char  csr0;	csr0 = inb( ioaddr + CSR0 );	if( csr0 != 0xff  &&  csr0 != 0x00 ) {		csr0 &= ~EN_INT;		if( csr0 & BU_EMP )			csr0 |= EN_INT;      		if( VALID_DECODER & (1 << (csr0 >> 4)) )			return  0;	}   	return  -ENODEV;}/* -------------------------------------------------------------------------- */static intsbni_ioctl( struct net_device  *dev,  struct ifreq  *ifr,  int  cmd ){	struct net_local  *nl = (struct net_local *) dev->priv; 	struct sbni_flags  flags;	int  error = 0;#ifdef CONFIG_SBNI_MULTILINE	struct net_device  *slave_dev;	char  slave_name[ 8 ];#endif  	switch( cmd ) {	case  SIOCDEVGETINSTATS :		if (copy_to_user( ifr->ifr_data, &nl->in_stats,					sizeof(struct sbni_in_stats) ))			error = -EFAULT;		break;	case  SIOCDEVRESINSTATS :		if( current->euid != 0 )	/* root only */			return  -EPERM;		memset( &nl->in_stats, 0, sizeof(struct sbni_in_stats) );		break;	case  SIOCDEVGHWSTATE :		flags.mac_addr	= *(u32 *)(dev->dev_addr + 3);		flags.rate	= nl->csr1.rate;		flags.slow_mode	= (nl->state & FL_SLOW_MODE) != 0;		flags.rxl	= nl->cur_rxl_index;		flags.fixed_rxl	= nl->delta_rxl == 0;		if (copy_to_user( ifr->ifr_data, &flags, sizeof flags ))			error = -EFAULT;		break;	case  SIOCDEVSHWSTATE :		if( current->euid != 0 )	/* root only */			return  -EPERM;		spin_lock( &nl->lock );		flags = *(struct sbni_flags*) &ifr->ifr_ifru;		if( flags.fixed_rxl )			nl->delta_rxl = 0,			nl->cur_rxl_index = flags.rxl;		else			nl->delta_rxl = DEF_RXL_DELTA,			nl->cur_rxl_index = DEF_RXL;		nl->csr1.rxl = rxl_tab[ nl->cur_rxl_index ];		nl->csr1.rate = flags.rate;		outb( *(u8 *)&nl->csr1 | PR_RES, dev->base_addr + CSR1 );		spin_unlock( &nl->lock );		break;#ifdef CONFIG_SBNI_MULTILINE	case  SIOCDEVENSLAVE :		if( current->euid != 0 )	/* root only */			return  -EPERM;		if (copy_from_user( slave_name, ifr->ifr_data, sizeof slave_name ))			return -EFAULT;		slave_dev = dev_get_by_name( slave_name );		if( !slave_dev  ||  !(slave_dev->flags & IFF_UP) ) {			printk( KERN_ERR "%s: trying to enslave non-active "				"device %s\n", dev->name, slave_name );			return  -EPERM;		}		return  enslave( dev, slave_dev );	case  SIOCDEVEMANSIPATE :		if( current->euid != 0 )	/* root only */			return  -EPERM;		return  emancipate( dev );#endif	/* CONFIG_SBNI_MULTILINE */	default :		return  -EOPNOTSUPP;	}	return  error;}#ifdef CONFIG_SBNI_MULTILINEstatic intenslave( struct net_device  *dev,  struct net_device  *slave_dev ){	struct net_local  *nl  = (struct net_local *) dev->priv;	struct net_local  *snl = (struct net_local *) slave_dev->priv;	if( nl->state & FL_SLAVE )	/* This isn't master or free device */		return  -EBUSY;	if( snl->state & FL_SLAVE )	/* That was already enslaved */		return  -EBUSY;	spin_lock( &nl->lock );	spin_lock( &snl->lock );	/* append to list */	snl->link = nl->link;	nl->link  = slave_dev;	snl->master = dev;	snl->state |= FL_SLAVE;	/* Summary statistics of MultiLine operation will be stored	   in master's counters */	memset( &snl->stats, 0, sizeof(struct net_device_stats) );	netif_stop_queue( slave_dev );	netif_wake_queue( dev );	/* Now we are able to transmit */	spin_unlock( &snl->lock );	spin_unlock( &nl->lock );	printk( KERN_NOTICE "%s: slave device (%s) attached.\n",		dev->name, slave_dev->name );	return  0;}static intemancipate( struct net_device  *dev ){	struct net_local   *snl = (struct net_local *) dev->priv;	struct net_device  *p   = snl->master;	struct net_local   *nl  = (struct net_local *) p->priv;	if( !(snl->state & FL_SLAVE) )		return  -EINVAL;	spin_lock( &nl->lock );	spin_lock( &snl->lock );	drop_xmit_queue( dev );	/* exclude from list */	for(;;) {	/* must be in list */		struct net_local  *t = (struct net_local *) p->priv;		if( t->link == dev ) {			t->link = snl->link;			break;		}		p = t->link;	}	snl->link = NULL;	snl->master = dev;	snl->state &= ~FL_SLAVE;	netif_start_queue( dev );	spin_unlock( &snl->lock );	spin_unlock( &nl->lock );	dev_put( dev );	return  0;}#endifstatic struct net_device_stats *sbni_get_stats( struct net_device  *dev ){	return  &((struct net_local *) dev->priv)->stats;}static voidset_multicast_list( struct net_device  *dev ){	return;		/* sbni always operate in promiscuos mode */}#ifdef MODULEmodule_param_array(io, int, NULL, 0);module_param_array(irq, int, NULL, 0);module_param_array(baud, int, NULL, 0);module_param_array(rxl, int, NULL, 0);module_param_array(mac, int, NULL, 0);module_param(skip_pci_probe, bool, 0);MODULE_LICENSE("GPL");intinit_module( void ){	struct net_device  *dev;	int err;	while( num < SBNI_MAX_NUM_CARDS ) {		dev = alloc_netdev(sizeof(struct net_local), 				   "sbni%d", sbni_devsetup);		if( !dev)			break;		sprintf( dev->name, "sbni%d", num );		err = sbni_init(dev);		if (err) {			free_netdev(dev);			break;		}		if( register_netdev( dev ) ) {			release_region( dev->base_addr, SBNI_IO_EXTENT );			free_netdev( dev );			break;		}	}	return  *sbni_cards  ?  0  :  -ENODEV;}voidcleanup_module( void ){	struct net_device  *dev;	int  num;	for( num = 0;  num < SBNI_MAX_NUM_CARDS;  ++num )		if( (dev = sbni_cards[ num ]) != NULL ) {			unregister_netdev( dev );			release_region( dev->base_addr, SBNI_IO_EXTENT );			free_netdev( dev );		}}#else	/* MODULE */static int __initsbni_setup( char  *p ){	int  n, parm;	if( *p++ != '(' )		goto  bad_param;	for( n = 0, parm = 0;  *p  &&  n < 8; ) {		(*dest[ parm ])[ n ] = simple_strtol( p, &p, 0 );		if( !*p  ||  *p == ')' )			return 1;		if( *p == ';' )			++p, ++n, parm = 0;		else if( *p++ != ',' )			break;		else			if( ++parm >= 5 )				break;	}bad_param:	printk( KERN_ERR "Error in sbni kernel parameter!\n" );	return 0;}__setup( "sbni=", sbni_setup );#endif	/* MODULE *//* -------------------------------------------------------------------------- */#ifdef ASM_CRCstatic u32calc_crc32( u32  crc,  u8  *p,  u32  len ){	register u32  _crc;	_crc = crc;		__asm__ __volatile__ (		"xorl	%%ebx, %%ebx\n"		"movl	%2, %%esi\n" 		"movl	%3, %%ecx\n" 		"movl	$crc32tab, %%edi\n"		"shrl	$2, %%ecx\n"		"jz	1f\n"		".align 4\n"	"0:\n"		"movb	%%al, %%bl\n"		"movl	(%%esi), %%edx\n"		"shrl	$8, %%eax\n"		"xorb	%%dl, %%bl\n"		"shrl	$8, %%edx\n"		"xorl	(%%edi,%%ebx,4), %%eax\n"		"movb	%%al, %%bl\n"		"shrl	$8, %%eax\n"		"xorb	%%dl, %%bl\n"		"shrl	$8, %%edx\n"		"xorl	(%%edi,%%ebx,4), %%eax\n"		"movb	%%al, %%bl\n"		"shrl	$8, %%eax\n"		"xorb	%%dl, %%bl\n"		"movb	%%dh, %%dl\n" 		"xorl	(%%edi,%%ebx,4), %%eax\n"		"movb	%%al, %%bl\n"		"shrl	$8, %%eax\n"		"xorb	%%dl, %%bl\n"		"addl	$4, %%esi\n"		"xorl	(%%edi,%%ebx,4), %%eax\n"		"decl	%%ecx\n"		"jnz	0b\n"	"1:\n"		"movl	%3, %%ecx\n"		"andl	$3, %%ecx\n"		"jz	2f\n"		"movb	%%al, %%bl\n"		"shrl	$8, %%eax\n"		"xorb	(%%esi), %%bl\n"		"xorl	(%%edi,%%ebx,4), %%eax\n"		"decl	%%ecx\n"		"jz	2f\n"		"movb	%%al, %%bl\n"		"shrl	$8, %%eax\n"		"xorb	1(%%esi), %%bl\n"		"xorl	(%%edi,%%ebx,4), %%eax\n"		"decl	%%ecx\n"		"jz	2f\n"		"movb	%%al, %%bl\n"		"shrl	$8, %%eax\n"		"xorb	2(%%esi), %%bl\n"		"xorl	(%%edi,%%ebx,4), %%eax\n"	"2:\n"		: "=a" (_crc)		: "0" (_crc), "g" (p), "g" (len)		: "bx", "cx", "dx", "si", "di"	);	return  _crc;}#else	/* ASM_CRC */static u32calc_crc32( u32  crc,  u8  *p,  u32  len ){	while( len-- )		crc = CRC32( *p++, crc );	return  crc;}#endif	/* ASM_CRC */static u32  crc32tab[] __attribute__ ((aligned(8))) = {	0xD202EF8D,  0xA505DF1B,  0x3C0C8EA1,  0x4B0BBE37,	0xD56F2B94,  0xA2681B02,  0x3B614AB8,  0x4C667A2E,	0xDCD967BF,  0xABDE5729,  0x32D70693,  0x45D03605,	0xDBB4A3A6,  0xACB39330,  0x35BAC28A,  0x42BDF21C,	0xCFB5FFE9,  0xB8B2CF7F,  0x21BB9EC5,  0x56BCAE53,	0xC8D83BF0,  0xBFDF0B66,  0x26D65ADC,  0x51D16A4A,	0xC16E77DB,  0xB669474D,  0x2F6016F7,  0x58672661,	0xC603B3C2,  0xB1048354,  0x280DD2EE,  0x5F0AE278,	0xE96CCF45,  0x9E6BFFD3,  0x0762AE69,  0x70659EFF,	0xEE010B5C,  0x99063BCA,  0x000F6A70,  0x77085AE6,	0xE7B74777,  0x90B077E1,  0x09B9265B,  0x7EBE16CD,	0xE0DA836E,  0x97DDB3F8,  0x0ED4E242,  0x79D3D2D4,	0xF4DBDF21,  0x83DCEFB7,  0x1AD5BE0D,  0x6DD28E9B,	0xF3B61B38,  0x84B12BAE,  0x1DB87A14,  0x6ABF4A82,	0xFA005713,  0x8D076785,  0x140E363F,  0x630906A9,	0xFD6D930A,  0x8A6AA39C,  0x1363F226,  0x6464C2B0,	0xA4DEAE1D,  0xD3D99E8B,  0x4AD0CF31,  0x3DD7FFA7,	0xA3B36A04,  0xD4B45A92,  0x4DBD0B28,  0x3ABA3BBE,	0xAA05262F,  0xDD0216B9,  0x440B4703,  0x330C7795,	0xAD68E236,  0xDA6FD2A0,  0x4366831A,  0x3461B38C,	0xB969BE79,  0xCE6E8EEF,  0x5767DF55,  0x2060EFC3,	0xBE047A60,  0xC9034AF6,  0x500A1B4C,  0x270D2BDA,	0xB7B2364B,  0xC0B506DD,  0x59BC5767,  0x2EBB67F1,	0xB0DFF252,  0xC7D8C2C4,  0x5ED1937E,  0x29D6A3E8,	0x9FB08ED5,  0xE8B7BE43,  0x71BEEFF9,  0x06B9DF6F,	0x98DD4ACC,  0xEFDA7A5A,  0x76D32BE0,  0x01D41B76,	0x916B06E7,  0xE66C3671,  0x7F6567CB,  0x0862575D,	0x9606C2FE,  0xE101F268,  0x7808A3D2,  0x0F0F9344,	0x82079EB1,  0xF500AE27,  0x6C09FF9D,  0x1B0ECF0B,	0x856A5AA8,  0xF26D6A3E,  0x6B643B84,  0x1C630B12,	0x8CDC1683,  0xFBDB2615,  0x62D277AF,  0x15D54739,	0x8BB1D29A,  0xFCB6E20C,  0x65BFB3B6,  0x12B88320,	0x3FBA6CAD,  0x48BD5C3B,  0xD1B40D81,  0xA6B33D17,	0x38D7A8B4,  0x4FD09822,  0xD6D9C998,  0xA1DEF90E,	0x3161E49F,  0x4666D409,  0xDF6F85B3,  0xA868B525,	0x360C2086,  0x410B1010,  0xD80241AA,  0xAF05713C,	0x220D7CC9,  0x550A4C5F,  0xCC031DE5,  0xBB042D73,	0x2560B8D0,  0x52678846,  0xCB6ED9FC,  0xBC69E96A,	0x2CD6F4FB,  0x5BD1C46D,  0xC2D895D7,  0xB5DFA541,	0x2BBB30E2,  0x5CBC0074,  0xC5B551CE,  0xB2B26158,	0x04D44C65,  0x73D37CF3,  0xEADA2D49,  0x9DDD1DDF,	0x03B9887C,  0x74BEB8EA,  0xEDB7E950,  0x9AB0D9C6,	0x0A0FC457,  0x7D08F4C1,  0xE401A57B,  0x930695ED,	0x0D62004E,  0x7A6530D8,  0xE36C6162,  0x946B51F4,	0x19635C01,  0x6E646C97,  0xF76D3D2D,  0x806A0DBB,	0x1E0E9818,  0x6909A88E,  0xF000F934,  0x8707C9A2,	0x17B8D433,  0x60BFE4A5,  0xF9B6B51F,  0x8EB18589,	0x10D5102A,  0x67D220BC,  0xFEDB7106,  0x89DC4190,	0x49662D3D,  0x3E611DAB,  0xA7684C11,  0xD06F7C87,	0x4E0BE924,  0x390CD9B2,  0xA0058808,  0xD702B89E,	0x47BDA50F,  0x30BA9599,  0xA9B3C423,  0xDEB4F4B5,	0x40D06116,  0x37D75180,  0xAEDE003A,  0xD9D930AC,	0x54D13D59,  0x23D60DCF,  0xBADF5C75,  0xCDD86CE3,	0x53BCF940,  0x24BBC9D6,  0xBDB2986C,  0xCAB5A8FA,	0x5A0AB56B,  0x2D0D85FD,  0xB404D447,  0xC303E4D1,	0x5D677172,  0x2A6041E4,  0xB369105E,  0xC46E20C8,	0x72080DF5,  0x050F3D63,  0x9C066CD9,  0xEB015C4F,	0x7565C9EC,  0x0262F97A,  0x9B6BA8C0,  0xEC6C9856,	0x7CD385C7,  0x0BD4B551,  0x92DDE4EB,  0xE5DAD47D,	0x7BBE41DE,  0x0CB97148,  0x95B020F2,  0xE2B71064,	0x6FBF1D91,  0x18B82D07,  0x81B17CBD,  0xF6B64C2B,	0x68D2D988,  0x1FD5E91E,  0x86DCB8A4,  0xF1DB8832,	0x616495A3,  0x1663A535,  0x8F6AF48F,  0xF86DC419,	0x660951BA,  0x110E612C,  0x88073096,  0xFF000000};

⌨️ 快捷键说明

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