[1572] in linux-net channel archive
Re: Network device setup (was Re: unresolved register_netdev() in 52)
daemon@ATHENA.MIT.EDU (Paul Gortmaker)
Tue Jan 2 02:34:53 1996
From: Paul Gortmaker <gpg109@rsphy1.anu.edu.au>
To: apenwarr@foxnet.net (Avery Pennarun)
Date: Tue, 2 Jan 1996 15:37:30 +1100 (EST)
Cc: linux-net@vger.rutgers.edu
In-Reply-To: <Pine.LNX.3.91.951231142817.11924B-100000@wingnut.foxnet.net> from "Avery Pennarun" at Jan 1, 96 07:52:19 pm
I wrote:
> > 2) Put a semi-bogus static dev into Space.c to hook the driver probe
> > into the probe sequence, or put the probe call directly into
> > core/dev.c (pi2, pt) Then kmalloc a "dev" sized chunk of memory,
> > or declare it static, from within the driver itself. Then fill in
> > some of the fields, and call register_netdev() to squeeze it into the
> > linked list. Then register_netdev() calls dev->init(dev) itself
> > to see if the device comes up.
Avery replied:
> I, as the author of arcnet.c, thought it was a great idea at the time, and I
> still do. It seemed the best way to handle multiple different TCP/IP
> protocol encapsulations on the same card. Eventually I want to make each of
Yeah, I like a solution similar to register_netdev() as well, but what I
was trying to get across is that all the "static struct device ..." in
Space.c just to hook into the probe are ugly (with the exception of
eth0->3). I was thinking along the line of getting rid of those non-ether
"static struct device ..." and then these drivers would (upon detecting a
valid physical device) do an init_netdev() (similar to part of
the present init_etherdev(), but w/o touching the list) which would create
a device struct, and fill in some of the fields, The driver would then
fill in the rest, make sure everything came up allright, and then call
add_to_list() or whatever to get itself into the linked list. Not
horribly different from the register_netdev(), but if all drivers
(i.e. non ethN ones) used it, Space.c wouldn't be so ugggggly.
> Of course, you still need something like Space.c to do the probing before
> register_netdev will ever be called, if modules aren't being used. It's
> hard to win :)
Exactly. So the aforementioned devices that handle their own dev
structures dynamically (arcnet, slip, ppp, etc.) go into a
function similar to ethif_probe(), lets say netif_probe() which is
also in Space.c and called once from net/core/dev.c - something like:
static void netif_probe(void *unused)
{
#if defined(CONFIG_ARCNET)
arcnet_probe();
#endif
#if defined(CONFIG_PPP)
ppp_init();
#endif
[...]
#if defined(SLIP) || defined(CONFIG_SLIP)
slip_init();
#endif
}
You get the idea. No struct device is passed in or allocated in Space.c
for these devices. They would allocate them themselves, be it one,
two or twenty, and do so as they are required. In the case of the above,
arcnet_probe() would be responsible for finding all arcnet cards, and so
one may wish to consider setting up an "arcnet=" command line, so users
could do "arcnet=5,0x280,0xd0000,arc0 arcnet=9,0x300,0xd8000,arc1" etc.
It would also be responsible for inserting all the valid arcnet device
structures into the linked list, using the hypothetical add_to_list(dev);
> Oh, by the way, whatever happened to the patch that added a "kick me"
> function call to all the network drivers? I remember there was a patch for
> this in 1.2.x during the old 1.3.6-or-so days.
That was/is a brutal editing job. If I could convince net driver authors
to separate out their individual Tx timeout code into a separate
function, then it would be easy. For example:
Change:
----------------------------------------------------------------
if (dev->tbusy) {
int tickssofar = jiffies - dev->trans_start;
if (tickssofar < TX_TIMEOUT)
return 1;
printk("%s: transmit timed out, oops\n",dev->name);
....
[transmit timeout fixup code here]
....
}
----------------------------------------------------------------
to:
----------------------------------------------------------------
/* Routine to handle Tx timeout for Foo Bar net device */
static int foo_timeout(dev)
{
printk("%s: transmit timed out, oops\n",dev->name);
....
[transmit timeout fixup code here]
....
}
[...]
if (dev->tbusy) {
int tickssofar = jiffies - dev->trans_start;
if (tickssofar < TX_TIMEOUT)
return 1;
foo_timeout(dev);
}
----------------------------------------------------------------
As you can see this type of change is not rocket science, and makes
the driver source easier to read anyway. I don't have the time to
do this again for all 5 zillion linux net devices, however.
Paul.