diff options
author | Weongyo Jeong <weongyo@FreeBSD.org> | 2009-03-12 02:51:55 +0000 |
---|---|---|
committer | Weongyo Jeong <weongyo@FreeBSD.org> | 2009-03-12 02:51:55 +0000 |
commit | 2c964f43b6942c615de5527ab0203b8057d4f0ef (patch) | |
tree | 9c2dded23354b57a889167db21eb33a953362afe /sys/dev/if_ndis | |
parent | 46364b29a8e5aa56c15e39469ce4b87957ae4bb4 (diff) | |
download | src-2c964f43b6942c615de5527ab0203b8057d4f0ef.tar.gz src-2c964f43b6942c615de5527ab0203b8057d4f0ef.zip |
Notes
Diffstat (limited to 'sys/dev/if_ndis')
-rw-r--r-- | sys/dev/if_ndis/if_ndis.c | 12 | ||||
-rw-r--r-- | sys/dev/if_ndis/if_ndis_usb.c | 8 | ||||
-rw-r--r-- | sys/dev/if_ndis/if_ndisvar.h | 16 |
3 files changed, 32 insertions, 4 deletions
diff --git a/sys/dev/if_ndis/if_ndis.c b/sys/dev/if_ndis/if_ndis.c index eb5b099eb462..976253c06845 100644 --- a/sys/dev/if_ndis/if_ndis.c +++ b/sys/dev/if_ndis/if_ndis.c @@ -557,8 +557,10 @@ ndis_attach(dev) mtx_init(&sc->ndis_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, MTX_DEF); KeInitializeSpinLock(&sc->ndis_rxlock); + KeInitializeSpinLock(&sc->ndisusb_tasklock); KeInitializeSpinLock(&sc->ndisusb_xferdonelock); InitializeListHead(&sc->ndis_shlist); + InitializeListHead(&sc->ndisusb_tasklist); InitializeListHead(&sc->ndisusb_xferdonelist); callout_init(&sc->ndis_stat_callout, CALLOUT_MPSAFE); @@ -625,6 +627,8 @@ ndis_attach(dev) sc->ndis_inputitem = IoAllocateWorkItem(sc->ndis_block->nmb_deviceobj); sc->ndisusb_xferdoneitem = IoAllocateWorkItem(sc->ndis_block->nmb_deviceobj); + sc->ndisusb_taskitem = + IoAllocateWorkItem(sc->ndis_block->nmb_deviceobj); KeInitializeDpc(&sc->ndis_rxdpc, ndis_rxeof_xfr_wrap, sc->ndis_block); /* Call driver's init routine. */ @@ -1066,6 +1070,8 @@ ndis_detach(dev) IoFreeWorkItem(sc->ndis_inputitem); if (sc->ndisusb_xferdoneitem != NULL) IoFreeWorkItem(sc->ndisusb_xferdoneitem); + if (sc->ndisusb_taskitem != NULL) + IoFreeWorkItem(sc->ndisusb_taskitem); bus_generic_detach(dev); ndis_unload_driver(sc); @@ -3236,8 +3242,10 @@ ndis_stop(sc) ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); NDIS_UNLOCK(sc); - if (!(sc->ndis_iftype == PNPBus && ndisusb_halt == 0) || - sc->ndisusb_status & NDISUSB_STATUS_DETACH) + if (sc->ndis_iftype != PNPBus || + (sc->ndis_iftype == PNPBus && + !(sc->ndisusb_status & NDISUSB_STATUS_DETACH) && + ndisusb_halt != 0)) ndis_halt_nic(sc); NDIS_LOCK(sc); diff --git a/sys/dev/if_ndis/if_ndis_usb.c b/sys/dev/if_ndis/if_ndis_usb.c index 79f104f2723e..7aeed9a30f20 100644 --- a/sys/dev/if_ndis/if_ndis_usb.c +++ b/sys/dev/if_ndis/if_ndis_usb.c @@ -168,6 +168,7 @@ ndisusb_attach(device_t self) db = uaa->driver_info; sc = (struct ndis_softc *)dummy; sc->ndis_dev = self; + mtx_init(&sc->ndisusb_mtx, "NDIS USB", MTX_NETWORK_LOCK, MTX_DEF); sc->ndis_dobj = db->windrv_object; sc->ndis_regvals = db->windrv_regvals; sc->ndis_iftype = PNPBus; @@ -207,14 +208,17 @@ ndisusb_detach(device_t self) sc->ndisusb_status |= NDISUSB_STATUS_DETACH; + ndis_pnpevent_nic(self, NDIS_PNP_EVENT_SURPRISE_REMOVED); + for (i = 0; i < NDISUSB_ENDPT_MAX; i++) { ne = &sc->ndisusb_ep[i]; usb2_transfer_unsetup(ne->ne_xfer, 1); } - ndis_pnpevent_nic(self, NDIS_PNP_EVENT_SURPRISE_REMOVED); + (void)ndis_detach(self); - return ndis_detach(self); + mtx_destroy(&sc->ndisusb_mtx); + return (0); } static struct resource_list * diff --git a/sys/dev/if_ndis/if_ndisvar.h b/sys/dev/if_ndis/if_ndisvar.h index c661491c4b4d..c86b26715ee3 100644 --- a/sys/dev/if_ndis/if_ndisvar.h +++ b/sys/dev/if_ndis/if_ndisvar.h @@ -142,6 +142,14 @@ struct ndisusb_xferdone { list_entry nd_donelist; }; +struct ndisusb_task { + unsigned nt_type; +#define NDISUSB_TASK_TSTART 0 +#define NDISUSB_TASK_IRPCANCEL 1 + void *nt_ctx; + list_entry nt_tasklist; +}; + struct ndis_softc { struct ifnet *ifp; struct ifmedia ifmedia; /* media info */ @@ -220,6 +228,7 @@ struct ndis_softc { int ndis_hang_timer; struct usb2_device *ndisusb_dev; + struct mtx ndisusb_mtx; #define NDISUSB_GET_ENDPT(addr) \ ((UE_GET_DIR(addr) >> 7) | (UE_GET_ADDR(addr) << 1)) #define NDISUSB_ENDPT_MAX ((UE_ADDR + 1) * 2) @@ -227,6 +236,9 @@ struct ndis_softc { io_workitem *ndisusb_xferdoneitem; list_entry ndisusb_xferdonelist; kspin_lock ndisusb_xferdonelock; + io_workitem *ndisusb_taskitem; + list_entry ndisusb_tasklist; + kspin_lock ndisusb_tasklock; int ndisusb_status; #define NDISUSB_STATUS_DETACH 0x1 }; @@ -234,3 +246,7 @@ struct ndis_softc { #define NDIS_LOCK(_sc) mtx_lock(&(_sc)->ndis_mtx) #define NDIS_UNLOCK(_sc) mtx_unlock(&(_sc)->ndis_mtx) #define NDIS_LOCK_ASSERT(_sc, t) mtx_assert(&(_sc)->ndis_mtx, t) +#define NDISUSB_LOCK(_sc) mtx_lock(&(_sc)->ndisusb_mtx) +#define NDISUSB_UNLOCK(_sc) mtx_unlock(&(_sc)->ndisusb_mtx) +#define NDISUSB_LOCK_ASSERT(_sc, t) mtx_assert(&(_sc)->ndisusb_mtx, t) + |