diff options
author | wpaul <wpaul@FreeBSD.org> | 2005-05-20 04:00:50 +0000 |
---|---|---|
committer | wpaul <wpaul@FreeBSD.org> | 2005-05-20 04:00:50 +0000 |
commit | 29dcab8107f3a57a4fa23bde0c84d48e6b124c06 (patch) | |
tree | 89907c32553e410f47b041d65254e4f97f3aa0ba | |
parent | 01b6c1ef442edd2751ae8728c9583dab08ae95e9 (diff) | |
download | FreeBSD-src-29dcab8107f3a57a4fa23bde0c84d48e6b124c06.zip FreeBSD-src-29dcab8107f3a57a4fa23bde0c84d48e6b124c06.tar.gz |
Deal with a few bootstrap issues:
We can't call KeFlushQueuedDpcs() during bootstrap (cold == 1), since
the flush operation sleeps to wait for completion, and we can't sleep
here (clowns will eat us).
On an i386 SMP system, if we're loaded/probed/attached during bootstrap,
smp_rendezvous() won't run us anywhere except CPU 0 (since the other CPUs
aren't launched until later), which means we won't be able to set up
the GDTs anywhere except CPU 0. To deal with this case, ctxsw_utow()
now checks to see if the TID for the current processor has been properly
initialized and sets up the GTD for the current CPU if not.
Lastly, in if_ndis.c:ndis_shutdown(), do an ndis_stop() to insure we
really halt the NIC and stop interrupts from happening.
Note that loading a driver during bootstrap is, unfortunately, kind of
a hit or miss sort of proposition. In Windows, the expectation is that
by the time a given driver's MiniportInitialize() method is called,
the system is already in 'multiuser' state, i.e. it's up and running
enough to support all the stuff specified in the NDIS API, which includes
the underlying OS-supplied facilities it implicitly depends on, such as
having all CPUs running, having the DPC queues initialized, WorkItem
threads running, etc. But in UNIX, a lot of that stuff won't work during
bootstrap. This causes a problem since we need to call MiniportInitialize()
at least once during ndis_attach() in order to find out what kind of NIC
we have and learn its station address.
What this means is that some cards just plain won't work right if
you try to pre-load the driver along with the kernel: they'll only be
probed/attach correctly if the driver is kldloaded _after_ the system
has reached multiuser. I can't really think of a way around this that
would still preserve the ability to use an NDIS device for diskless
booting.
-rw-r--r-- | sys/compat/ndis/kern_ndis.c | 3 | ||||
-rw-r--r-- | sys/dev/if_ndis/if_ndis.c | 2 |
2 files changed, 3 insertions, 2 deletions
diff --git a/sys/compat/ndis/kern_ndis.c b/sys/compat/ndis/kern_ndis.c index fec7650..1829330 100644 --- a/sys/compat/ndis/kern_ndis.c +++ b/sys/compat/ndis/kern_ndis.c @@ -1112,7 +1112,8 @@ ndis_halt_nic(arg) n->nmt_nexttimer = NULL; } sc->ndis_block->nmb_timerlist = NULL; - KeFlushQueuedDpcs(); + if (!cold) + KeFlushQueuedDpcs(); #endif NDIS_LOCK(sc); diff --git a/sys/dev/if_ndis/if_ndis.c b/sys/dev/if_ndis/if_ndis.c index 45f1134..af7e02c 100644 --- a/sys/dev/if_ndis/if_ndis.c +++ b/sys/dev/if_ndis/if_ndis.c @@ -3013,7 +3013,7 @@ ndis_shutdown(dev) struct ndis_softc *sc; sc = device_get_softc(dev); - ndis_shutdown_nic(sc); + ndis_stop(sc); return; } |