diff options
Diffstat (limited to 'sys/dev/if_ndis/if_ndis.c')
-rw-r--r-- | sys/dev/if_ndis/if_ndis.c | 56 |
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++) { |