diff options
author | imp <imp@FreeBSD.org> | 2007-07-09 16:58:07 +0000 |
---|---|---|
committer | imp <imp@FreeBSD.org> | 2007-07-09 16:58:07 +0000 |
commit | 1c0ad7a383f372ebdb902b489434ed882ba0ccbb (patch) | |
tree | ff02e52f127891d8730cf47817b91744777dae26 | |
parent | 75055779dbc3ed92854d1aa4ab2406ccdfe86400 (diff) | |
download | FreeBSD-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.c | 18 |
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; |