[1248] in linux-net channel archive

home help back first fref pref prev next nref lref last post

Network Drivers as Module

daemon@ATHENA.MIT.EDU (NIIBE Yutaka)
Wed Oct 25 12:21:17 1995

Date: Wed, 25 Oct 1995 13:52:47 +0900
From: NIIBE Yutaka <gniibe@mri.co.jp>
To: Paul Gortmaker <gpg109@rsphy1.anu.edu.au>
Cc: linux-net@vger.rutgers.edu

Hi,

Currently (as of 1.3.35), most network drivers cannot handle two (or
more) cards simulteneously as module.  That is, we don't use module
for multi-homed host with same network cards.

To solve this situation, I took following approach for PLIP.
This approach is upward compatible to current behavior.

	(1) When user specify I/O address or IRQ, use it.  Don't
	probe other ports.  Here are examples:

	# insmod plip io=0x378 irq=7
	# insmod plip io=0x378,0x3bc irq=7,5

	(2) When user doesn't feed any parameter, probe all ports
	and clame as PLIP when found.  It is equivalent to:

	# insmod plip io=0x378,0x3bc,0x278 irq=7,5,2

Following code is part of PLIP.  I hope that this approach can be
applied for other network drivers.

Thanks,
-- 
NIIBE Yutaka
Mitsubishi Research Institute, Inc.

==================================
#ifdef MODULE
char kernel_version[] = UTS_RELEASE;
int io[] = {0, 0, 0};
int irq[] = {0, 0, 0};

static struct device dev_plip[] = {
	{
		"plip0",
		0, 0, 0, 0,		/* memory */
		0x3BC, 5,		/* base, irq */
		0, 0, 0, NULL, plip_init 
	},
	{
		"plip1",
		0, 0, 0, 0,		/* memory */
		0x378, 7,		/* base, irq */
		0, 0, 0, NULL, plip_init 
	},
	{
		"plip2",
		0, 0, 0, 0,		/* memory */
		0x278, 2,		/* base, irq */
		0, 0, 0, NULL, plip_init 
	}
};

int
init_module(void)
{
	int no_parameters=1;
	int devices=0;
	int i;

	/* When user feeds parameters, use them */
	for (i=0; i < 3; i++) {
		int specified=0;

		if (io[i] != 0) {
			dev_plip[i].base_addr = io[i];
			specified++;
		}
		if (irq[i] != 0) {
			dev_plip[i].irq = irq[i];
			specified++;
		}
		if (specified) {
			if (register_netdev(&dev_plip[i]) != 0) {
				printk(KERN_INFO "plip%d: Not found\n", i);
				return -EIO;
			}
			no_parameters = 0;
		}
	}
	if (!no_parameters)
		return 0;

	/* No parameters.  Default action is probing all interfaces. */
	for (i=0; i < 3; i++) { 
		if (register_netdev(&dev_plip[i]) == 0)
			devices++;
	}
	if (devices == 0) {
		printk(KERN_INFO "plip: no interfaces found\n");
		return -EIO;
	}
	return 0;
}

void
cleanup_module(void)
{
	int i;

	for (i=0; i < 3; i++) {
		if (dev_plip[i].priv) {
			unregister_netdev(&dev_plip[i]);
			release_region(PAR_DATA(&dev_plip[i]), (PAR_DATA(&dev_plip[i]) == 0x3bc)? 3 : 8);
			kfree_s(dev_plip[i].priv, sizeof(struct net_local));
			dev_plip[i].priv = NULL;
		}
	}
}
#endif /* MODULE */


home help back first fref pref prev next nref lref last post