diff options
author | wpaul <wpaul@FreeBSD.org> | 2004-01-09 06:53:49 +0000 |
---|---|---|
committer | wpaul <wpaul@FreeBSD.org> | 2004-01-09 06:53:49 +0000 |
commit | 1d43d52f79cad462e21256035e4900d91531600a (patch) | |
tree | c1685459398a5b77abead4f6bc795a0c457d1d40 /sys | |
parent | b676d86e23eec800e52a40be2803231c60b1e57f (diff) | |
download | FreeBSD-src-1d43d52f79cad462e21256035e4900d91531600a.zip FreeBSD-src-1d43d52f79cad462e21256035e4900d91531600a.tar.gz |
The private data section of ndis_packets has a 'packet flags' byte
which has two important flags in it: the 'allocated by NDIS' flag
and the 'media specific info present' flag. There are two Windows macros
for getting/setting media specific info fields within the ndis_packet
structure which can behave improperly if these flags are not initialized
correctly when a packet is allocated. It seems the correct thing
to do is always set the NDIS_PACKET_ALLOCATED_BY_NDIS flag on
all newly allocated packets.
This fixes the crashes with the Intel Centrino wireless driver.
My sample card now seems to work correctly.
Also, fix a potential LOR involving ndis_txeof() in if_ndis.c.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/compat/ndis/kern_ndis.c | 1 | ||||
-rw-r--r-- | sys/compat/ndis/ndis_var.h | 4 | ||||
-rw-r--r-- | sys/compat/ndis/subr_ndis.c | 7 | ||||
-rw-r--r-- | sys/dev/if_ndis/if_ndis.c | 6 |
4 files changed, 14 insertions, 4 deletions
diff --git a/sys/compat/ndis/kern_ndis.c b/sys/compat/ndis/kern_ndis.c index 80b9261..f138439 100644 --- a/sys/compat/ndis/kern_ndis.c +++ b/sys/compat/ndis/kern_ndis.c @@ -600,6 +600,7 @@ ndis_mtop(m0, p) priv = &(*p)->np_private; priv->npp_totlen = m0->m_pkthdr.len; priv->npp_packetooboffset = offsetof(ndis_packet, np_oob); + priv->npp_ndispktflags = NDIS_PACKET_ALLOCATED_BY_NDIS; for (m = m0; m != NULL; m = m->m_next) { if (m->m_len == 0) diff --git a/sys/compat/ndis/ndis_var.h b/sys/compat/ndis/ndis_var.h index 2f37322..a0bb5d0 100644 --- a/sys/compat/ndis/ndis_var.h +++ b/sys/compat/ndis/ndis_var.h @@ -919,6 +919,10 @@ struct ndis_packet_private { #define NDIS_FLAGS_SENT_AT_DPC 0x00001000 #define NDIS_FLAGS_USES_SG_BUFFER_LIST 0x00002000 +#define NDIS_PACKET_WRAPPER_RESERVED 0x3F +#define NDIS_PACKET_CONTAINS_MEDIA_SPECIFIC_INFO 0x40 +#define NDIS_PACKET_ALLOCATED_BY_NDIS 0x80 + #define NDIS_PROTOCOL_ID_DEFAULT 0x00 #define NDIS_PROTOCOL_ID_TCP_IP 0x02 #define NDIS_PROTOCOL_ID_IPX 0x06 diff --git a/sys/compat/ndis/subr_ndis.c b/sys/compat/ndis/subr_ndis.c index 2b39b04..4dca682 100644 --- a/sys/compat/ndis/subr_ndis.c +++ b/sys/compat/ndis/subr_ndis.c @@ -1548,6 +1548,13 @@ ndis_alloc_packet(status, packet, pool) pkt->np_private.npp_packetooboffset = offsetof(ndis_packet, np_oob); + /* + * We must initialize the packet flags correctly in order + * for the NDIS_SET_PACKET_MEDIA_SPECIFIC_INFO() and + * NDIS_GET_PACKET_MEDIA_SPECIFIC_INFO() to work correctly. + */ + pkt->np_private.npp_ndispktflags = NDIS_PACKET_ALLOCATED_BY_NDIS; + *packet = pkt; head->np_private.npp_count++; diff --git a/sys/dev/if_ndis/if_ndis.c b/sys/dev/if_ndis/if_ndis.c index 6b5b78f..0d1a168 100644 --- a/sys/dev/if_ndis/if_ndis.c +++ b/sys/dev/if_ndis/if_ndis.c @@ -757,8 +757,6 @@ ndis_txeof(adapter, packet, status) sc = (struct ndis_softc *)block->nmb_ifp; ifp = block->nmb_ifp; - NDIS_LOCK(sc); - m = packet->np_m0; idx = packet->np_txidx; ifp->if_opackets++; @@ -772,8 +770,6 @@ ndis_txeof(adapter, packet, status) ifp->if_timer = 0; ifp->if_flags &= ~IFF_OACTIVE; - NDIS_UNLOCK(sc); - m_freem(m); taskqueue_enqueue(taskqueue_swi, &sc->ndis_starttask); @@ -843,7 +839,9 @@ ndis_intrtask(arg, pending) sc = arg; ifp = &sc->arpcom.ac_if; + NDIS_LOCK(sc); ndis_intrhand(sc); + NDIS_UNLOCK(sc); mtx_lock(&sc->ndis_intrmtx); ndis_enable_intr(sc); mtx_unlock(&sc->ndis_intrmtx); |