cvs commit: src/sys/compat/ndis kern_ndis.c subr_ntoskrnl.c src/sys/dev/if_ndis if_ndis.c src/sys/kern subr_witness.c

Bill Paul wpaul at FreeBSD.org
Mon Mar 7 03:05:32 GMT 2005


wpaul       2005-03-07 03:05:31 UTC

  FreeBSD src repository

  Modified files:
    sys/compat/ndis      kern_ndis.c subr_ntoskrnl.c 
    sys/dev/if_ndis      if_ndis.c 
    sys/kern             subr_witness.c 
  Log:
  When you call MiniportInitialize() for an 802.11 driver, it will
  at some point result in a status event being triggered (it should
  be a link down event: the Microsoft driver design guide says you
  should generate one when the NIC is initialized). Some drivers
  generate the event during MiniportInitialize(), such that by the
  time MiniportInitialize() completes, the NIC is ready to go. But
  some drivers, in particular the ones for Atheros wireless NICs,
  don't generate the event until after a device interrupt occurs
  at some point after MiniportInitialize() has completed.
  
  The gotcha is that you have to wait until the link status event
  occurs one way or the other before you try to fiddle with any
  settings (ssid, channel, etc...). For the drivers that set the
  event sycnhronously this isn't a problem, but for the others
  we have to pause after calling ndis_init_nic() and wait for the event
  to arrive before continuing. Failing to wait can cause big trouble:
  on my SMP system, calling ndis_setstate_80211() after ndis_init_nic()
  completes, but _before_ the link event arrives, will lock up or
  reset the system.
  
  What we do now is check to see if a link event arrived while
  ndis_init_nic() was running, and if it didn't we msleep() until
  it does.
  
  Along the way, I discovered a few other problems:
  
  - Defered procedure calls run at PASSIVE_LEVEL, not DISPATCH_LEVEL.
    ntoskrnl_run_dpc() has been fixed accordingly. (I read the documentation
    wrong.)
  
  - Similarly, the NDIS interrupt handler, which is essentially a
    DPC, also doesn't need to run at DISPATCH_LEVEL. ndis_intrtask()
    has been fixed accordingly.
  
  - MiniportQueryInformation() and MiniportSetInformation() run at
    DISPATCH_LEVEL, and each request must complete before another
    can be submitted. ndis_get_info() and ndis_set_info() have been
    fixed accordingly.
  
  - Turned the sleep lock that guards the NDIS thread job list into
    a spin lock. We never do anything with this lock held except manage
    the job list (no other locks are held), so it's safe to do this,
    and it's possible that ndis_sched() and ndis_unsched() can be
    called from DISPATCH_LEVEL, so using a sleep lock here is
    semantically incorrect. Also updated subr_witness.c to add the
    lock to the order list.
  
  Revision  Changes    Path
  1.70      +81 -48    src/sys/compat/ndis/kern_ndis.c
  1.57      +0 -3      src/sys/compat/ndis/subr_ntoskrnl.c
  1.83      +38 -4     src/sys/dev/if_ndis/if_ndis.c
  1.188     +1 -0      src/sys/kern/subr_witness.c


More information about the cvs-src mailing list