summaryrefslogtreecommitdiffstats
path: root/sys/dev/if_ndis/if_ndis.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/if_ndis/if_ndis.c')
-rw-r--r--sys/dev/if_ndis/if_ndis.c56
1 files changed, 43 insertions, 13 deletions
diff --git a/sys/dev/if_ndis/if_ndis.c b/sys/dev/if_ndis/if_ndis.c
index 1a2db17..a85effe 100644
--- a/sys/dev/if_ndis/if_ndis.c
+++ b/sys/dev/if_ndis/if_ndis.c
@@ -74,6 +74,8 @@ __FBSDID("$FreeBSD$");
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
+#include <dev/usb/usb.h>
+#include <dev/usb/usbdi.h>
#include <compat/ndis/pe_var.h>
#include <compat/ndis/cfg_var.h>
@@ -81,6 +83,7 @@ __FBSDID("$FreeBSD$");
#include <compat/ndis/ntoskrnl_var.h>
#include <compat/ndis/hal_var.h>
#include <compat/ndis/ndis_var.h>
+#include <compat/ndis/usbd_var.h>
#include <dev/if_ndis/if_ndisvar.h>
#define NDIS_DEBUG
@@ -93,6 +96,11 @@ SYSCTL_INT(_debug, OID_AUTO, ndis, CTLFLAG_RW, &ndis_debug, 0,
#define DPRINTF(x)
#endif
+SYSCTL_DECL(_hw_ndisusb);
+int ndisusb_halt = 1;
+SYSCTL_INT(_hw_ndisusb, OID_AUTO, halt, CTLFLAG_RW, &ndisusb_halt, 0,
+ "Halt NDIS USB driver when it's attached");
+
MODULE_DEPEND(ndis, ether, 1, 1, 1);
MODULE_DEPEND(ndis, wlan, 1, 1, 1);
MODULE_DEPEND(ndis, ndisapi, 1, 1, 1);
@@ -538,7 +546,9 @@ ndis_attach(dev)
mtx_init(&sc->ndis_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
MTX_DEF);
KeInitializeSpinLock(&sc->ndis_rxlock);
+ KeInitializeSpinLock(&sc->ndisusb_xferlock);
InitializeListHead(&sc->ndis_shlist);
+ InitializeListHead(&sc->ndisusb_xferlist);
callout_init(&sc->ndis_stat_callout, CALLOUT_MPSAFE);
if (sc->ndis_iftype == PCMCIABus) {
@@ -602,6 +612,7 @@ ndis_attach(dev)
sc->ndis_startitem = IoAllocateWorkItem(sc->ndis_block->nmb_deviceobj);
sc->ndis_resetitem = IoAllocateWorkItem(sc->ndis_block->nmb_deviceobj);
sc->ndis_inputitem = IoAllocateWorkItem(sc->ndis_block->nmb_deviceobj);
+ sc->ndisusb_xferitem = IoAllocateWorkItem(sc->ndis_block->nmb_deviceobj);
KeInitializeDpc(&sc->ndis_rxdpc, ndis_rxeof_xfr_wrap, sc->ndis_block);
/* Call driver's init routine. */
@@ -696,6 +707,8 @@ ndis_attach(dev)
if_initname(ifp, device_get_name(dev), device_get_unit(dev));
ifp->if_mtu = ETHERMTU;
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
+ if (sc->ndis_iftype == PNPBus)
+ ifp->if_flags |= IFF_NEEDSGIANT;
ifp->if_ioctl = ndis_ioctl;
ifp->if_start = ndis_start;
ifp->if_init = ndis_init;
@@ -934,11 +947,16 @@ got_crypto:
}
fail:
- if (error)
+ if (error) {
ndis_detach(dev);
- else
- /* We're done talking to the NIC for now; halt it. */
- ndis_halt_nic(sc);
+ return (error);
+ }
+
+ if (sc->ndis_iftype == PNPBus && ndisusb_halt == 0)
+ return (error);
+
+ /* We're done talking to the NIC for now; halt it. */
+ ndis_halt_nic(sc);
return(error);
}
@@ -1029,6 +1047,8 @@ ndis_detach(dev)
IoFreeWorkItem(sc->ndis_resetitem);
if (sc->ndis_inputitem != NULL)
IoFreeWorkItem(sc->ndis_inputitem);
+ if (sc->ndisusb_xferitem != NULL)
+ IoFreeWorkItem(sc->ndisusb_xferitem);
bus_generic_detach(dev);
ndis_unload_driver(sc);
@@ -1538,7 +1558,7 @@ ndis_txeof(adapter, packet, status)
ndis_free_packet(packet);
m_freem(m);
- NDIS_LOCK(sc);
+ NDISMTX_LOCK(sc);
sc->ndis_txarray[idx] = NULL;
sc->ndis_txpending++;
@@ -1550,7 +1570,7 @@ ndis_txeof(adapter, packet, status)
sc->ndis_tx_timer = 0;
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- NDIS_UNLOCK(sc);
+ NDISMTX_UNLOCK(sc);
IoQueueWorkItem(sc->ndis_startitem,
(io_workitem_func)ndis_starttask_wrap,
@@ -1575,9 +1595,9 @@ ndis_linksts(adapter, status, sbuf, slen)
/* Event list is all full up, drop this one. */
- NDIS_LOCK(sc);
+ NDISMTX_LOCK(sc);
if (sc->ndis_evt[sc->ndis_evtpidx].ne_sts) {
- NDIS_UNLOCK(sc);
+ NDISMTX_UNLOCK(sc);
return;
}
@@ -1587,7 +1607,7 @@ ndis_linksts(adapter, status, sbuf, slen)
sc->ndis_evt[sc->ndis_evtpidx].ne_buf = malloc(slen,
M_TEMP, M_NOWAIT);
if (sc->ndis_evt[sc->ndis_evtpidx].ne_buf == NULL) {
- NDIS_UNLOCK(sc);
+ NDISMTX_UNLOCK(sc);
return;
}
bcopy((char *)sbuf,
@@ -1596,7 +1616,7 @@ ndis_linksts(adapter, status, sbuf, slen)
sc->ndis_evt[sc->ndis_evtpidx].ne_sts = status;
sc->ndis_evt[sc->ndis_evtpidx].ne_len = slen;
NDIS_EVTINC(sc->ndis_evtpidx);
- NDIS_UNLOCK(sc);
+ NDISMTX_UNLOCK(sc);
return;
}
@@ -1966,8 +1986,14 @@ ndis_init(xsc)
*/
ndis_stop(sc);
- if (ndis_init_nic(sc))
- return;
+ if (!(sc->ndis_iftype == PNPBus && ndisusb_halt == 0)) {
+ error = ndis_init_nic(sc);
+ if (error != 0) {
+ device_printf(sc->ndis_dev,
+ "failed to initialize the device: %d\n", error);
+ return;
+ }
+ }
/* Init our MAC address */
@@ -2688,6 +2714,8 @@ ndis_getstate_80211(sc)
ifp = sc->ifp;
ic = ifp->if_l2com;
vap = TAILQ_FIRST(&ic->ic_vaps);
+ if (vap == NULL)
+ return;
ni = vap->iv_bss;
if (!NDIS_INITIALIZED(sc))
@@ -3173,7 +3201,9 @@ ndis_stop(sc)
ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
NDIS_UNLOCK(sc);
- ndis_halt_nic(sc);
+ if (!(sc->ndis_iftype == PNPBus && ndisusb_halt == 0) ||
+ sc->ndisusb_status & NDISUSB_STATUS_DETACH)
+ ndis_halt_nic(sc);
NDIS_LOCK(sc);
for (i = 0; i < NDIS_EVENTS; i++) {
OpenPOWER on IntegriCloud