ip autoconfig for PCMCIA NICs
PATCH 1/1 ip autoconfig for PCMCIA NICs
It appears that ip autoconf doesn't work for cardbus NICs at present because of an ordering problem. The call to init_pcmcia_ds() in init/main.c comes after the ip-autoconf initcall has run. So of course, autoconf complains that there are no network devices available.
This patch moves ds initialisation out of do_basic_setup() and into an initcall. The pcmcia makefile is shuffled so that the ds.c initcall comes at the end of pcmcia initialisation.
This all works fine. However it probably breaks something, but the rather unilluminating comment
#ifdef CONFIG_PCMCIA
init_pcmcia_ds(); /* Do this last */#endif
doesn't tell us what.
Also, yenta_open() currently defers device initialisation to keventd, so there is a good chance that cardbus init hasn't completed by the time we hit ip autoconf, so the yenta_open_bh functionality is made synchronous.
yenta_open() is changed so that it has a single exit point. An error-path
leak in yenta_open() is fixed - missing an iounmap(). The module
refcount handling in yenta_open() is changed to make it less racy. The registration of the polling timer in yenta_open_bh() is moved so that it happens after the socket initialisation, to avoid running the poll timer in the middle of initialisation.
Patch works fine for me, and is tested with modular PCMCIA support as well. But what does it break?
Now, every time I try to understand the relationship between socket services, card services, socket drivers and driver services my brain bursts. Could some kind soul please what these things do, and how
they fit together? Thanks.
init/main.c +0 -3
@@ -839,9 +839,6 @@ static void __init do_basic_setup(void)irda_proto_init ();irda_device_init ();/* Must be done after protocol initialization */ #endif -#ifdef CONFIG_PCMCIA -init_pcmcia_ds ();/* Do this last */ -#endif }extern void rd_load (void );
drivers/pcmcia/Makefile +2 -1
@@ -22,7 +22,7 @@ ifeq ($(CONFIG_CARDBUS),y) endif ifeq ($(CONFIG_PCMCIA),y) - obj-y := cistpl.o rsrc_mgr.o bulkmem.o ds.o cs.o + obj-y := cistpl.o rsrc_mgr.o bulkmem.o cs.o ifeq ($(CONFIG_CARDBUS),y) obj-y += cardbus.o cb_enabler.o yenta.o pci_socket.o endif
@@ -35,6 +35,7 @@ ifeq ($(CONFIG_PCMCIA),y) ifeq ($(CONFIG_HD64465_PCMCIA),y) obj-y += hd64465_ss.o endif + obj-y += ds.o else ifeq ($(CONFIG_PCMCIA),m) obj-m := pcmcia_core.o ds.o
drivers/pcmcia/ds.c +4 -9
@@ -964,14 +964,7 @@ int __init init_pcmcia_ds(void)return 0 ; } -#ifdef MODULE - -int __init init_module (void ) -{ -return init_pcmcia_ds (); -} - -void __exit cleanup_module(void) +void __exit cleanup_pcmcia_ds(void) {int i;#ifdef CONFIG_PROC_FS
@@ -986,4 +979,6 @@ void __exit cleanup_module(void)kfree (socket_table); } -#endif +module_init (init_pcmcia_ds); +module_exit (cleanup_pcmcia_ds); +
drivers/pcmcia/yenta.c +39 -46
129 lines not on this page · raw message
Quoted 4 lines · [email protected] said:
Also,
yenta_open()currently defers device initialisation to keventd,
so there is a good chance that cardbus init hasn't completed by the time we hit ip autoconf, so theyenta_open_bhfunctionality is made synchronous.
That was async at Linus' request - if we register the irq early, some boards die in an interrupt storm. Linux is currently fairly crap at noticing and recovering from interrupt storms.
--
dwmw2
Quoted 11 lines · David Woodhouse
Quoted 4 lines · [email protected] said:
Also,
yenta_open()currently defers device initialisation to keventd,
so there is a good chance that cardbus init hasn't completed by the time we hit ip autoconf, so theyenta_open_bhfunctionality is made synchronous.That was async at Linus' request - if we register the irq early, some boards die in an interrupt storm. Linux is currently fairly crap at noticing and recovering from interrupt storms.
So any change in this area is untestable in the 2.4 context. Sigh.
But how can the current code prevent IRQ problems? AFAICT it just delays the yenta_open_bh() operations by a short-but-random time interval.
Should the IRQ be registered _after_ the call to cardbus_register() when, presumably, the hardware is set up and has negated the IRQ signal?
-
Quoted 9 lines · Andrew Morton
This all works fine. However it probably breaks something, but the rather unilluminating comment
#ifdef CONFIG_PCMCIA init_pcmcia_ds(); /* Do this last */#endif
doesn't tell us what.
I'm not sure about the origin of the comment. But I can think of one reason for starting PCMCIA after at least other device drivers have
started: since the kernel generally relies on individual drivers to announce their resource allocations, there is no way to reliably do resource allocation for hot plug devices before non-hot-plug devices have enumerated what resources they're already using.
Quoted 4 lines
Now, every time I try to understand the relationship between socket services, card services, socket drivers and driver services my brain bursts. Could some kind soul please what these things do, and how
they fit together? Thanks.
Card services manages a few things for PCMCIA client drivers: hot plug event handling, resource allocation, PCMCIA bus configuration, Card Information Structure parsing, and some abstractions for talking to memory cards. The Linux version, in the pcmcia_core module, is based heavily on the PCMCIA standard documents. Socket services is the PCMCIA standard API for talking to socket drivers; Linux does not really implement this API and there's a simpler interface between pcmcia_core and socket drivers. The Linux driver services layer, in the "ds" module, supplies a few things for managing device drivers:
stuff for keeping track of which drivers manage which cards, and which logical devices are associated with which cards and drivers. It also provides a user mode pseudo-device for some Card Services functions.
This stuff is also explained in the intro of the Linux PCMCIA Programmer's Guide.
-- Dave