[1248] in linux-net channel archive
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 */