summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorimp <imp@FreeBSD.org>2007-07-09 16:58:07 +0000
committerimp <imp@FreeBSD.org>2007-07-09 16:58:07 +0000
commit1c0ad7a383f372ebdb902b489434ed882ba0ccbb (patch)
treeff02e52f127891d8730cf47817b91744777dae26
parent75055779dbc3ed92854d1aa4ab2406ccdfe86400 (diff)
downloadFreeBSD-src-1c0ad7a383f372ebdb902b489434ed882ba0ccbb.zip
FreeBSD-src-1c0ad7a383f372ebdb902b489434ed882ba0ccbb.tar.gz
When all the other drivers were converted to scheduling a taskqueue to
do the heavy lifting of the 'mii_tick' function, rue was left behind. Implement this in a naive way. Reports from the field show this makes the driver functional with some locking issues, as opposed to an instant panic. Those will be addressed in a later version of the driver. Approved by: re@ (bmah)
-rw-r--r--sys/dev/usb/if_rue.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/sys/dev/usb/if_rue.c b/sys/dev/usb/if_rue.c
index 6f4b267..4449f7d 100644
--- a/sys/dev/usb/if_rue.c
+++ b/sys/dev/usb/if_rue.c
@@ -142,6 +142,7 @@ static void rue_intr(usbd_xfer_handle, usbd_private_handle, usbd_status);
static void rue_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
static void rue_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
static void rue_tick(void *);
+static void rue_tick_task(void *);
static void rue_rxstart(struct ifnet *);
static void rue_start(struct ifnet *);
static int rue_ioctl(struct ifnet *, u_long, caddr_t);
@@ -594,6 +595,8 @@ rue_attach(device_t self)
goto error;
}
+ usb_init_task(&sc->rue_tick_task, rue_tick_task, sc);
+
err = usbd_device2interface_handle(uaa->device, RUE_IFACE_IDX, &iface);
if (err) {
device_printf(sc->rue_dev, "getting interface handle failed\n");
@@ -704,6 +707,7 @@ rue_detach(device_t dev)
sc->rue_dying = 1;
untimeout(rue_tick, sc, sc->rue_stat_ch);
+ usb_rem_task(sc->rue_udev, &sc->rue_tick_task);
ether_ifdetach(ifp);
if_free(ifp);
@@ -916,6 +920,20 @@ rue_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
static void
rue_tick(void *xsc)
{
+ struct rue_softc *sc = xsc;
+
+ if (sc == NULL)
+ return;
+ if (sc->rue_dying)
+ return;
+
+ /* Perform periodic stuff in process context */
+ usb_add_task(sc->rue_udev, &sc->rue_tick_task, USB_TASKQ_DRIVER);
+}
+
+static void
+rue_tick_task(void *xsc)
+{
struct rue_softc *sc = xsc;
struct ifnet *ifp;
struct mii_data *mii;
OpenPOWER on IntegriCloud