Re: Two 3COM Etherlink III netcards in one box

Jacques Gelinas (jack@solucorp.qc.ca)
Sun, 29 Dec 1996 21:03:01 -0500 (EST)


On Sat, 28 Dec 1996, Philip Blundell wrote:

>
> On Thu, 26 Dec 1996, Bryn Paul Arnold Jones wrote:
>
> > On Thu, 26 Dec 1996, Baldur Norddahl wrote:
> >
> > > I tried to put two 3com netcards in one box (to make it act as a router)
> >
> > Ok, exactly which driver is that (3c5??), and what did you tell the module
>
> Etherlink III is the 3c509.
>
> > insmod 3c5whichever.o io=0x0230,0x0240 irq=5,6
> >
> > where card one is at io 0x0230, and irq 5; and the other is at 0x0240, and
> > irq 6 (I don't know if all modules can accept multiple values, or the
> > leading zero after the "0x", but ideally they should). If that dosn't
>
> The leading zero is an insmod problem - the modules see that value after
> it's been converted to a number. A lot of the ethercard modules don't
> support multiple instantiation yet. I don't know offhand if 3c509 does.

The 3c509 can't and you can't load the driver multiple times because of
the way 3c509 are detected (there is a static counter telling the driver
which adaptor to detect). I have fixed the 3c509 to support multiple
adaptor and the fix is now part of kernel 2.1. I am including the fix here
as it works correctly.

*** linux-2.0.25/drivers/net/3c509.c Tue Oct 29 23:57:38 1996
--- linux/drivers/net/3c509.c Thu Nov 14 12:47:04 1996
***************
*** 758,794 ****
}

#ifdef MODULE
! static char devicename[9] = { 0, };
! static struct device dev_3c509 = {
! devicename, /* device name is inserted by linux/drivers/net/net_init.c */
! 0, 0, 0, 0,
! 0, 0,
! 0, 0, 0, NULL, el3_probe };

! static int io = 0;
! static int irq = 0;

int
init_module(void)
{
! dev_3c509.base_addr = io;
! dev_3c509.irq = irq;
! if (!EISA_bus && !io) {
! printk("3c509: WARNING! Module load-time probing works reliably only for EISA bus!!\n");
}
- if (register_netdev(&dev_3c509) != 0)
- return -EIO;
return 0;
}

void
cleanup_module(void)
{
! unregister_netdev(&dev_3c509);
! kfree_s(dev_3c509.priv,sizeof(struct el3_private));
! dev_3c509.priv=NULL;
! /* If we don't do this, we can't re-insmod it later. */
! release_region(dev_3c509.base_addr, EL3_IO_EXTENT);
}
#endif /* MODULE */

--- 758,819 ----
}

#ifdef MODULE
! #define MAX_3C_CARDS 4 /* Max number of NE cards per module */
! #define NAMELEN 8 /* # of chars for storing dev->name */
! static char namelist[NAMELEN * MAX_3C_CARDS] = { 0, };
! static struct device dev_3c509[MAX_3C_CARDS] = {
! {
! NULL, /* assign a chunk of namelist[] below */
! 0, 0, 0, 0,
! 0, 0,
! 0, 0, 0, NULL, NULL
! },
! };

! static int io[MAX_3C_CARDS] = { 0, };
! static int irq[MAX_3C_CARDS] = { 0, };

int
init_module(void)
{
! int this_dev, found = 0;
!
! for (this_dev = 0; this_dev < MAX_3C_CARDS; this_dev++) {
! struct device *dev = &dev_3c509[this_dev];
! dev->name = namelist+(NAMELEN*this_dev);
! dev->irq = irq[this_dev];
! dev->base_addr = io[this_dev];
! dev->init = el3_probe;
! if (io[this_dev] == 0) {
! if (this_dev != 0) break; /* only complain once */
! printk("3c509: WARNING! Module load-time probing works reliably only for EISA bus!!\n");
! }
! if (register_netdev(dev) != 0) {
! printk(KERN_WARNING "3c509.c: No 3c509 card found (i/o = 0x%x).\n", io[this_dev]);
! if (found != 0) return 0; /* Got at least one. */
! return -ENXIO;
! }
! found++;
}
return 0;
}

void
cleanup_module(void)
{
! int this_dev;
!
! for (this_dev = 0; this_dev < MAX_3C_CARDS; this_dev++) {
! struct device *dev = &dev_3c509[this_dev];
! if (dev->priv != NULL) {
! kfree_s(dev->priv,sizeof(struct el3_private));
! dev->priv = NULL;
! free_irq(dev->irq, NULL);
! irq2dev_map[dev->irq] = NULL;
! release_region(dev->base_addr, EL3_IO_EXTENT);
! unregister_netdev(dev);
! }
! }
}
#endif /* MODULE */

--------------------------------------------------------
Jacques Gelinas (jacques@solucorp.qc.ca)
Linuxconf: The ultimate administration system for Linux.
see http://www.solucorp.qc.ca/linuxconf