summaryrefslogtreecommitdiffstats
path: root/sys/dev/if_ndis/if_ndis.c
diff options
context:
space:
mode:
authorwpaul <wpaul@FreeBSD.org>2004-01-08 10:44:37 +0000
committerwpaul <wpaul@FreeBSD.org>2004-01-08 10:44:37 +0000
commitde79d89d3757a7a271a891ba7f2281794dbd5e9e (patch)
tree7f6797ce379203fb828df74c6fed3232f62b877e /sys/dev/if_ndis/if_ndis.c
parentb1f53e3dd87253d767de956ba02d637d15deba87 (diff)
downloadFreeBSD-src-de79d89d3757a7a271a891ba7f2281794dbd5e9e.zip
FreeBSD-src-de79d89d3757a7a271a891ba7f2281794dbd5e9e.tar.gz
Correct the definition of the ndis_miniport_interrupt structure:
the ni_dpccountlock member is an ndis_kspin_lock, not an ndis_spin_lock (the latter is too big). Run if_ndis.c:ndis_tick() via taskqueue_schedule(). Also run ndis_start() via taskqueue in certain circumstances. Using these tweaks, I can now get the Broadcom BCM5701 NDIS driver to load and run. Unfortunately, the version I have seems to suffer from the same bug as the SMC 83820 driver, which is that it creates a spinlock during its DriverEntry() routine. I'm still debating the right way to deal with this.
Diffstat (limited to 'sys/dev/if_ndis/if_ndis.c')
-rw-r--r--sys/dev/if_ndis/if_ndis.c43
1 files changed, 34 insertions, 9 deletions
diff --git a/sys/dev/if_ndis/if_ndis.c b/sys/dev/if_ndis/if_ndis.c
index 2870b4d..6b5b78f 100644
--- a/sys/dev/if_ndis/if_ndis.c
+++ b/sys/dev/if_ndis/if_ndis.c
@@ -108,7 +108,9 @@ static __stdcall void ndis_linksts_done (ndis_handle);
static void ndis_intr (void *);
static void ndis_intrtask (void *, int);
static void ndis_tick (void *);
+static void ndis_ticktask (void *, int);
static void ndis_start (struct ifnet *);
+static void ndis_starttask (void *, int);
static int ndis_ioctl (struct ifnet *, u_long, caddr_t);
static void ndis_init (void *);
static void ndis_stop (struct ndis_softc *);
@@ -332,6 +334,8 @@ ndis_attach(dev)
mtx_init(&sc->ndis_intrmtx, device_get_nameunit(dev), "ndisisrlock",
MTX_DEF | MTX_RECURSE);
TASK_INIT(&sc->ndis_intrtask, 0, ndis_intrtask, sc);
+ TASK_INIT(&sc->ndis_ticktask, 0, ndis_ticktask, sc);
+ TASK_INIT(&sc->ndis_starttask, 0, ndis_starttask, sc);
/*
* Allocate the parent bus DMA tag appropriate for PCI.
@@ -772,8 +776,7 @@ ndis_txeof(adapter, packet, status)
m_freem(m);
- if (ifp->if_snd.ifq_head != NULL)
- ndis_start(ifp);
+ taskqueue_enqueue(taskqueue_swi, &sc->ndis_starttask);
return;
}
@@ -814,8 +817,7 @@ ndis_linksts_done(adapter)
device_printf(sc->ndis_dev, "link up\n");
if (sc->ndis_80211)
ndis_getstate_80211(sc);
- if (ifp->if_snd.ifq_head != NULL)
- ndis_start(ifp);
+ taskqueue_enqueue(taskqueue_swi, &sc->ndis_starttask);
break;
case NDIS_STATUS_MEDIA_DISCONNECT:
device_printf(sc->ndis_dev, "link down\n");
@@ -887,6 +889,16 @@ ndis_tick(xsc)
void *xsc;
{
struct ndis_softc *sc;
+ sc = xsc;
+ taskqueue_enqueue(taskqueue_swi, &sc->ndis_ticktask);
+}
+
+static void
+ndis_ticktask(xsc, pending)
+ void *xsc;
+ int pending;
+{
+ struct ndis_softc *sc;
__stdcall ndis_checkforhang_handler hangfunc;
uint8_t rval;
ndis_media_state linkstate;
@@ -946,6 +958,19 @@ ndis_map_sclist(arg, segs, nseg, mapsize, error)
return;
}
+static void
+ndis_starttask(arg, pending)
+ void *arg;
+ int pending;
+{
+ struct ifnet *ifp;
+
+ ifp = arg;
+ if (ifp->if_snd.ifq_head != NULL)
+ ndis_start(ifp);
+ return;
+}
+
/*
* Main transmit routine. To make NDIS drivers happy, we need to
* transform mbuf chains into NDIS packets and feed them to the
@@ -1120,12 +1145,12 @@ ndis_init(xsc)
* the default checkforhang timeout is approximately 2
* seconds.
*/
+
if (sc->ndis_block.nmb_checkforhangsecs == 0)
sc->ndis_block.nmb_checkforhangsecs = 2;
- if (sc->ndis_chars.nmc_checkhang_func != NULL)
- sc->ndis_stat_ch = timeout(ndis_tick, sc,
- hz * sc->ndis_block.nmb_checkforhangsecs);
+ sc->ndis_stat_ch = timeout(ndis_tick, sc,
+ hz * sc->ndis_block.nmb_checkforhangsecs);
/*NDIS_UNLOCK(sc);*/
@@ -1486,8 +1511,8 @@ ndis_watchdog(ifp)
ndis_reset(sc);
- if (ifp->if_snd.ifq_head != NULL)
- ndis_start(ifp);
+ taskqueue_enqueue(taskqueue_swi, &sc->ndis_starttask);
+
NDIS_UNLOCK(sc);
return;
OpenPOWER on IntegriCloud