svn commit: r213540 - user/weongyo/usb/sys/dev/usb/net
Weongyo Jeong
weongyo at FreeBSD.org
Fri Oct 8 01:52:01 UTC 2010
Author: weongyo
Date: Fri Oct 8 01:52:01 2010
New Revision: 213540
URL: http://svn.freebsd.org/changeset/base/213540
Log:
o fixes a regression that setting the promiscuous mode should be
happened at the taskqueue. It's to avoid a `sleepable after
non-sleepable' because ioctl handler could be called with holding bpf
mtx which is a default mutex.
o defines SLEEPOUT_DRAIN_TASK helper.
Modified:
user/weongyo/usb/sys/dev/usb/net/if_aue.c
user/weongyo/usb/sys/dev/usb/net/if_auereg.h
user/weongyo/usb/sys/dev/usb/net/if_axe.c
user/weongyo/usb/sys/dev/usb/net/if_axereg.h
user/weongyo/usb/sys/dev/usb/net/if_cue.c
user/weongyo/usb/sys/dev/usb/net/if_cuereg.h
user/weongyo/usb/sys/dev/usb/net/if_kue.c
user/weongyo/usb/sys/dev/usb/net/if_rue.c
user/weongyo/usb/sys/dev/usb/net/if_ruereg.h
user/weongyo/usb/sys/dev/usb/net/if_udav.c
user/weongyo/usb/sys/dev/usb/net/if_udavreg.h
Modified: user/weongyo/usb/sys/dev/usb/net/if_aue.c
==============================================================================
--- user/weongyo/usb/sys/dev/usb/net/if_aue.c Fri Oct 8 01:47:14 2010 (r213539)
+++ user/weongyo/usb/sys/dev/usb/net/if_aue.c Fri Oct 8 01:52:01 2010 (r213540)
@@ -230,7 +230,8 @@ static void aue_setmulti_locked(struct a
static void aue_rxflush(struct aue_softc *);
static int aue_rxbuf(struct aue_softc *, struct usb_page_cache *,
unsigned int, unsigned int);
-static void aue_setpromisc(struct aue_softc *);
+static void aue_setpromisc(void *, int);
+static void aue_setpromisc_locked(struct aue_softc *);
static void aue_init_locked(struct aue_softc *);
static void aue_watchdog(void *);
@@ -709,6 +710,7 @@ aue_attach(device_t dev)
sleepout_create(&sc->sc_sleepout, "aue sleepout");
sleepout_init_mtx(&sc->sc_sleepout, &sc->sc_watchdog, &sc->sc_mtx, 0);
TASK_INIT(&sc->sc_setmulti, 0, aue_setmulti, sc);
+ TASK_INIT(&sc->sc_setpromisc, 0, aue_setpromisc, sc);
iface_index = AUE_IFACE_IDX;
error = usbd_transfer_setup(uaa->device, &iface_index,
@@ -764,7 +766,8 @@ aue_detach(device_t dev)
struct ifnet *ifp = sc->sc_ifp;
sleepout_drain(&sc->sc_watchdog);
- taskqueue_drain(sc->sc_sleepout.s_taskqueue, &sc->sc_setmulti);
+ SLEEPOUT_DRAIN_TASK(&sc->sc_sleepout, &sc->sc_setpromisc);
+ SLEEPOUT_DRAIN_TASK(&sc->sc_sleepout, &sc->sc_setmulti);
usbd_transfer_unsetup(sc->sc_xfer, AUE_N_TRANSFER);
if (sc->sc_miibus != NULL)
@@ -1032,7 +1035,7 @@ aue_init_locked(struct aue_softc *sc)
aue_csr_write_1(sc, AUE_PAR0 + i, IF_LLADDR(ifp)[i]);
/* update promiscuous setting */
- aue_setpromisc(sc);
+ aue_setpromisc_locked(sc);
/* Load the multicast filter. */
aue_setmulti_locked(sc);
@@ -1050,7 +1053,17 @@ aue_init_locked(struct aue_softc *sc)
}
static void
-aue_setpromisc(struct aue_softc *sc)
+aue_setpromisc(void *arg, int npending)
+{
+ struct aue_softc *sc = arg;
+
+ AUE_LOCK(sc);
+ aue_setpromisc_locked(sc);
+ AUE_UNLOCK(sc);
+}
+
+static void
+aue_setpromisc_locked(struct aue_softc *sc)
{
struct ifnet *ifp = sc->sc_ifp;
@@ -1140,7 +1153,8 @@ aue_ioctl(struct ifnet *ifp, u_long comm
AUE_LOCK(sc);
if (ifp->if_flags & IFF_UP) {
if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- aue_setpromisc(sc);
+ SLEEPOUT_RUN_TASK(&sc->sc_sleepout,
+ &sc->sc_setpromisc);
else
aue_init_locked(sc);
} else
Modified: user/weongyo/usb/sys/dev/usb/net/if_auereg.h
==============================================================================
--- user/weongyo/usb/sys/dev/usb/net/if_auereg.h Fri Oct 8 01:47:14 2010 (r213539)
+++ user/weongyo/usb/sys/dev/usb/net/if_auereg.h Fri Oct 8 01:52:01 2010 (r213540)
@@ -222,6 +222,7 @@ struct aue_softc {
struct sleepout sc_sleepout;
struct sleepout_task sc_watchdog;
struct task sc_setmulti;
+ struct task sc_setpromisc;
};
#define AUE_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx)
Modified: user/weongyo/usb/sys/dev/usb/net/if_axe.c
==============================================================================
--- user/weongyo/usb/sys/dev/usb/net/if_axe.c Fri Oct 8 01:47:14 2010 (r213539)
+++ user/weongyo/usb/sys/dev/usb/net/if_axe.c Fri Oct 8 01:52:01 2010 (r213540)
@@ -206,6 +206,8 @@ static void axe_start_locked(struct ifne
static void axe_tick(struct axe_softc *);
static void axe_stop(struct axe_softc *);
static void axe_setmulti_locked(struct axe_softc *);
+static void axe_setpromisc(void *, int);
+static void axe_setpromisc_locked(struct axe_softc *);
static const struct usb_config axe_config[AXE_N_TRANSFER] = {
[AXE_BULK_DT_WR] = {
@@ -787,6 +789,7 @@ axe_attach(device_t dev)
sleepout_create(&sc->sc_sleepout, "axe sleepout");
sleepout_init_mtx(&sc->sc_sleepout, &sc->sc_watchdog, &sc->sc_mtx, 0);
TASK_INIT(&sc->sc_setmulti, 0, axe_setmulti, sc);
+ TASK_INIT(&sc->sc_setpromisc, 0, axe_setpromisc, sc);
iface_index = AXE_IFACE_IDX;
error = usbd_transfer_setup(uaa->device, &iface_index, sc->sc_xfer,
@@ -846,7 +849,8 @@ axe_detach(device_t dev)
struct ifnet *ifp = sc->sc_ifp;
sleepout_drain(&sc->sc_watchdog);
- taskqueue_drain(sc->sc_sleepout.s_taskqueue, &sc->sc_setmulti);
+ SLEEPOUT_DRAIN_TASK(&sc->sc_sleepout, &sc->sc_setpromisc);
+ SLEEPOUT_DRAIN_TASK(&sc->sc_sleepout, &sc->sc_setmulti);
usbd_transfer_unsetup(sc->sc_xfer, AXE_N_TRANSFER);
if (sc->sc_miibus != NULL)
@@ -1232,7 +1236,17 @@ axe_init_locked(struct axe_softc *sc)
}
static void
-axe_setpromisc(struct axe_softc *sc)
+axe_setpromisc(void *arg, int npending)
+{
+ struct axe_softc *sc = arg;
+
+ AXE_LOCK(sc);
+ axe_setpromisc_locked(sc);
+ AXE_UNLOCK(sc);
+}
+
+static void
+axe_setpromisc_locked(struct axe_softc *sc)
{
struct ifnet *ifp = sc->sc_ifp;
uint16_t rxmode;
@@ -1286,7 +1300,8 @@ axe_ioctl(struct ifnet *ifp, u_long comm
AXE_LOCK(sc);
if (ifp->if_flags & IFF_UP) {
if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- axe_setpromisc(sc);
+ SLEEPOUT_RUN_TASK(&sc->sc_sleepout,
+ &sc->sc_setpromisc);
else
axe_init_locked(sc);
} else
Modified: user/weongyo/usb/sys/dev/usb/net/if_axereg.h
==============================================================================
--- user/weongyo/usb/sys/dev/usb/net/if_axereg.h Fri Oct 8 01:47:14 2010 (r213539)
+++ user/weongyo/usb/sys/dev/usb/net/if_axereg.h Fri Oct 8 01:52:01 2010 (r213540)
@@ -210,6 +210,7 @@ struct axe_softc {
struct sleepout sc_sleepout;
struct sleepout_task sc_watchdog;
struct task sc_setmulti;
+ struct task sc_setpromisc;
int sc_phyno;
int sc_flags;
Modified: user/weongyo/usb/sys/dev/usb/net/if_cue.c
==============================================================================
--- user/weongyo/usb/sys/dev/usb/net/if_cue.c Fri Oct 8 01:47:14 2010 (r213539)
+++ user/weongyo/usb/sys/dev/usb/net/if_cue.c Fri Oct 8 01:52:01 2010 (r213540)
@@ -131,6 +131,8 @@ static int cue_rxbuf(struct cue_softc *,
static void cue_rxflush(struct cue_softc *);
static void cue_stop(struct cue_softc *);
static void cue_watchdog(void *);
+static void cue_setpromisc(void *, int);
+static void cue_setpromisc_locked(struct cue_softc *);
#ifdef USB_DEBUG
static int cue_debug = 0;
@@ -286,7 +288,17 @@ cue_mchash(const uint8_t *addr)
}
static void
-cue_setpromisc(struct cue_softc *sc)
+cue_setpromisc(void *arg, int npending)
+{
+ struct cue_softc *sc = arg;
+
+ CUE_LOCK(sc);
+ cue_setpromisc_locked(sc);
+ CUE_UNLOCK(sc);
+}
+
+static void
+cue_setpromisc_locked(struct cue_softc *sc)
{
struct ifnet *ifp = sc->sc_ifp;
@@ -406,6 +418,7 @@ cue_attach(device_t dev)
mtx_init(&sc->sc_mtx, device_get_nameunit(dev), NULL, MTX_DEF);
sleepout_create(&sc->sc_sleepout, "cue sleepout");
sleepout_init_mtx(&sc->sc_sleepout, &sc->sc_watchdog, &sc->sc_mtx, 0);
+ TASK_INIT(&sc->sc_setpromisc, 0, cue_setpromisc, sc);
TASK_INIT(&sc->sc_setmulti, 0, cue_setmulti, sc);
iface_index = CUE_IFACE_IDX;
@@ -454,7 +467,8 @@ cue_detach(device_t dev)
struct ifnet *ifp = sc->sc_ifp;
sleepout_drain(&sc->sc_watchdog);
- taskqueue_drain(sc->sc_sleepout.s_taskqueue, &sc->sc_setmulti);
+ SLEEPOUT_DRAIN_TASK(&sc->sc_sleepout, &sc->sc_setpromisc);
+ SLEEPOUT_DRAIN_TASK(&sc->sc_sleepout, &sc->sc_setmulti);
usbd_transfer_unsetup(sc->sc_xfer, CUE_N_TRANSFER);
if (ifp != NULL) {
CUE_LOCK(sc);
@@ -643,7 +657,7 @@ cue_init_locked(struct cue_softc *sc)
cue_csr_write_1(sc, CUE_ETHCTL, CUE_ETHCTL_RX_ON | CUE_ETHCTL_MCAST_ON);
/* Load the multicast filter */
- cue_setpromisc(sc);
+ cue_setpromisc_locked(sc);
/*
* Set the number of RX and TX buffers that we want
@@ -766,7 +780,8 @@ cue_ioctl(struct ifnet *ifp, u_long comm
CUE_LOCK(sc);
if (ifp->if_flags & IFF_UP) {
if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- cue_setpromisc(sc);
+ SLEEPOUT_RUN_TASK(&sc->sc_sleepout,
+ &sc->sc_setpromisc);
else
cue_init_locked(sc);
} else
Modified: user/weongyo/usb/sys/dev/usb/net/if_cuereg.h
==============================================================================
--- user/weongyo/usb/sys/dev/usb/net/if_cuereg.h Fri Oct 8 01:47:14 2010 (r213539)
+++ user/weongyo/usb/sys/dev/usb/net/if_cuereg.h Fri Oct 8 01:52:01 2010 (r213540)
@@ -126,6 +126,7 @@ struct cue_softc {
struct usb_xfer *sc_xfer[CUE_N_TRANSFER];
struct sleepout sc_sleepout;
struct sleepout_task sc_watchdog;
+ struct task sc_setpromisc;
struct task sc_setmulti;
struct ifqueue sc_rxq;
/* ethernet address from eeprom */
Modified: user/weongyo/usb/sys/dev/usb/net/if_kue.c
==============================================================================
--- user/weongyo/usb/sys/dev/usb/net/if_kue.c Fri Oct 8 01:47:14 2010 (r213539)
+++ user/weongyo/usb/sys/dev/usb/net/if_kue.c Fri Oct 8 01:52:01 2010 (r213540)
@@ -527,7 +527,7 @@ kue_detach(device_t dev)
struct kue_softc *sc = device_get_softc(dev);
struct ifnet *ifp = sc->sc_ifp;
- taskqueue_drain(sc->sc_sleepout.s_taskqueue, &sc->sc_setmulti);
+ SLEEPOUT_DRAIN_TASK(&sc->sc_sleepout, &sc->sc_setmulti);
usbd_transfer_unsetup(sc->sc_xfer, KUE_N_TRANSFER);
if (ifp != NULL) {
KUE_LOCK(sc);
Modified: user/weongyo/usb/sys/dev/usb/net/if_rue.c
==============================================================================
--- user/weongyo/usb/sys/dev/usb/net/if_rue.c Fri Oct 8 01:47:14 2010 (r213539)
+++ user/weongyo/usb/sys/dev/usb/net/if_rue.c Fri Oct 8 01:52:01 2010 (r213540)
@@ -160,6 +160,8 @@ static void rue_start(struct ifnet *);
static void rue_start_locked(struct ifnet *);
static void rue_stop(struct rue_softc *);
static void rue_watchdog(void *);
+static void rue_setpromisc(void *, int);
+static void rue_setpromisc_locked(struct rue_softc *);
static const struct usb_config rue_config[RUE_N_TRANSFER] = {
[RUE_BULK_DT_WR] = {
@@ -451,7 +453,17 @@ rue_miibus_statchg(device_t dev)
}
static void
-rue_setpromisc(struct rue_softc *sc)
+rue_setpromisc(void *arg, int npending)
+{
+ struct rue_softc *sc = arg;
+
+ RUE_LOCK(sc);
+ rue_setpromisc_locked(sc);
+ RUE_UNLOCK(sc);
+}
+
+static void
+rue_setpromisc_locked(struct rue_softc *sc)
{
struct ifnet *ifp = sc->sc_ifp;
@@ -588,6 +600,7 @@ rue_attach(device_t dev)
mtx_init(&sc->sc_mtx, device_get_nameunit(dev), NULL, MTX_DEF);
sleepout_create(&sc->sc_sleepout, "rue sleepout");
sleepout_init_mtx(&sc->sc_sleepout, &sc->sc_watchdog, &sc->sc_mtx, 0);
+ TASK_INIT(&sc->sc_setpromisc, 0, rue_setpromisc, sc);
TASK_INIT(&sc->sc_setmulti, 0, rue_setmulti, sc);
iface_index = RUE_IFACE_IDX;
@@ -644,7 +657,8 @@ rue_detach(device_t dev)
struct ifnet *ifp = sc->sc_ifp;
sleepout_drain(&sc->sc_watchdog);
- taskqueue_drain(sc->sc_sleepout.s_taskqueue, &sc->sc_setmulti);
+ SLEEPOUT_DRAIN_TASK(&sc->sc_sleepout, &sc->sc_setpromisc);
+ SLEEPOUT_DRAIN_TASK(&sc->sc_sleepout, &sc->sc_setmulti);
usbd_transfer_unsetup(sc->sc_xfer, RUE_N_TRANSFER);
if (sc->sc_miibus != NULL)
device_delete_child(sc->sc_dev, sc->sc_miibus);
@@ -957,7 +971,7 @@ rue_init_locked(struct rue_softc *sc)
rue_csr_write_2(sc, RUE_RCR, RUE_RCR_CONFIG|RUE_RCR_AB);
/* Load the multicast filter */
- rue_setpromisc(sc);
+ rue_setpromisc_locked(sc);
/* Load the multicast filter. */
rue_setmulti(sc, 0);
@@ -1044,7 +1058,8 @@ rue_ioctl(struct ifnet *ifp, u_long comm
RUE_LOCK(sc);
if (ifp->if_flags & IFF_UP) {
if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- rue_setpromisc(sc);
+ SLEEPOUT_RUN_TASK(&sc->sc_sleepout,
+ &sc->sc_setpromisc);
else
rue_init_locked(sc);
} else
Modified: user/weongyo/usb/sys/dev/usb/net/if_ruereg.h
==============================================================================
--- user/weongyo/usb/sys/dev/usb/net/if_ruereg.h Fri Oct 8 01:47:14 2010 (r213539)
+++ user/weongyo/usb/sys/dev/usb/net/if_ruereg.h Fri Oct 8 01:52:01 2010 (r213540)
@@ -178,6 +178,7 @@ struct rue_softc {
struct usb_xfer *sc_xfer[RUE_N_TRANSFER];
struct sleepout sc_sleepout;
struct sleepout_task sc_watchdog;
+ struct task sc_setpromisc;
struct task sc_setmulti;
struct ifqueue sc_rxq;
/* ethernet address from eeprom */
Modified: user/weongyo/usb/sys/dev/usb/net/if_udav.c
==============================================================================
--- user/weongyo/usb/sys/dev/usb/net/if_udav.c Fri Oct 8 01:47:14 2010 (r213539)
+++ user/weongyo/usb/sys/dev/usb/net/if_udav.c Fri Oct 8 01:52:01 2010 (r213540)
@@ -116,7 +116,8 @@ static void udav_start(struct ifnet *);
static void udav_start_locked(struct ifnet *);
static void udav_setmulti(void *, int);
static void udav_stop(struct udav_softc *);
-static void udav_setpromisc(struct udav_softc *);
+static void udav_setpromisc(void *, int);
+static void udav_setpromisc_locked(struct udav_softc *);
static void udav_watchdog(void *);
static miibus_readreg_t udav_miibus_readreg;
@@ -250,6 +251,7 @@ udav_attach(device_t dev)
sleepout_create(&sc->sc_sleepout, "axe sleepout");
sleepout_init_mtx(&sc->sc_sleepout, &sc->sc_watchdog, &sc->sc_mtx, 0);
TASK_INIT(&sc->sc_setmulti, 0, udav_setmulti, sc);
+ TASK_INIT(&sc->sc_setpromisc, 0, udav_setpromisc, sc);
iface_index = UDAV_IFACE_INDEX;
error = usbd_transfer_setup(uaa->device, &iface_index,
@@ -304,7 +306,8 @@ udav_detach(device_t dev)
struct ifnet *ifp = sc->sc_ifp;
sleepout_drain(&sc->sc_watchdog);
- taskqueue_drain(sc->sc_sleepout.s_taskqueue, &sc->sc_setmulti);
+ SLEEPOUT_DRAIN_TASK(&sc->sc_sleepout, &sc->sc_setpromisc);
+ SLEEPOUT_DRAIN_TASK(&sc->sc_sleepout, &sc->sc_setmulti);
usbd_transfer_unsetup(sc->sc_xfer, UDAV_N_TRANSFER);
if (sc->sc_miibus != NULL)
@@ -469,7 +472,7 @@ udav_init_locked(struct udav_softc *sc)
UDAV_SETBIT(sc, UDAV_RCR, UDAV_RCR_DIS_LONG | UDAV_RCR_DIS_CRC);
/* load multicast filter and update promiscious mode bit */
- udav_setpromisc(sc);
+ udav_setpromisc_locked(sc);
/* enable RX */
UDAV_SETBIT(sc, UDAV_RCR, UDAV_RCR_RXEN);
@@ -557,7 +560,17 @@ udav_setmulti(void *arg, int npending)
}
static void
-udav_setpromisc(struct udav_softc *sc)
+udav_setpromisc(void *arg, int npending)
+{
+ struct udav_softc *sc = arg;
+
+ UDAV_LOCK(sc);
+ udav_setpromisc_locked(sc);
+ UDAV_UNLOCK(sc);
+}
+
+static void
+udav_setpromisc_locked(struct udav_softc *sc)
{
struct ifnet *ifp = sc->sc_ifp;
uint8_t rxmode;
@@ -982,7 +995,8 @@ udav_ioctl(struct ifnet *ifp, u_long com
UDAV_LOCK(sc);
if (ifp->if_flags & IFF_UP) {
if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- udav_setpromisc(sc);
+ SLEEPOUT_RUN_TASK(&sc->sc_sleepout,
+ &sc->sc_setpromisc);
else
udav_init_locked(sc);
} else
Modified: user/weongyo/usb/sys/dev/usb/net/if_udavreg.h
==============================================================================
--- user/weongyo/usb/sys/dev/usb/net/if_udavreg.h Fri Oct 8 01:47:14 2010 (r213539)
+++ user/weongyo/usb/sys/dev/usb/net/if_udavreg.h Fri Oct 8 01:52:01 2010 (r213540)
@@ -161,6 +161,7 @@ struct udav_softc {
struct sleepout sc_sleepout;
struct sleepout_task sc_watchdog;
struct task sc_setmulti;
+ struct task sc_setpromisc;
struct ifqueue sc_rxq;
/* ethernet address from eeprom */
uint8_t sc_eaddr[ETHER_ADDR_LEN];
More information about the svn-src-user
mailing list