diff options
Diffstat (limited to 'sys/dev/ioat/ioat.c')
-rw-r--r-- | sys/dev/ioat/ioat.c | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/sys/dev/ioat/ioat.c b/sys/dev/ioat/ioat.c index 3215c6f..bcc4e9a 100644 --- a/sys/dev/ioat/ioat.c +++ b/sys/dev/ioat/ioat.c @@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$"); #include <sys/rman.h> #include <sys/sbuf.h> #include <sys/sysctl.h> +#include <sys/taskqueue.h> #include <sys/time.h> #include <dev/pci/pcireg.h> #include <dev/pci/pcivar.h> @@ -92,6 +93,7 @@ static void ioat_submit_single(struct ioat_softc *ioat); static void ioat_comp_update_map(void *arg, bus_dma_segment_t *seg, int nseg, int error); static int ioat_reset_hw(struct ioat_softc *ioat); +static void ioat_reset_hw_task(void *, int); static void ioat_setup_sysctl(device_t device); static int sysctl_handle_reset(SYSCTL_HANDLER_ARGS); static inline struct ioat_softc *ioat_get(struct ioat_softc *, @@ -308,6 +310,7 @@ ioat_detach(device_t device) ioat = DEVICE2SOFTC(device); ioat_test_detach(); + taskqueue_drain(taskqueue_thread, &ioat->reset_task); mtx_lock(IOAT_REFLK); ioat->quiescing = TRUE; @@ -414,6 +417,7 @@ ioat3_attach(device_t device) mtx_init(&ioat->submit_lock, "ioat_submit", NULL, MTX_DEF); mtx_init(&ioat->cleanup_lock, "ioat_cleanup", NULL, MTX_DEF); callout_init(&ioat->timer, 1); + TASK_INIT(&ioat->reset_task, 0, ioat_reset_hw_task, ioat); /* Establish lock order for Witness */ mtx_lock(&ioat->submit_lock); @@ -672,7 +676,7 @@ out: wakeup(&ioat->tail); } - if (!is_ioat_halted(comp_update)) + if (!is_ioat_halted(comp_update) && !is_ioat_suspended(comp_update)) return; ioat->stats.channel_halts++; @@ -712,8 +716,23 @@ out: mtx_unlock(&ioat->submit_lock); ioat_log_message(0, "Resetting channel to recover from error\n"); + error = taskqueue_enqueue(taskqueue_thread, &ioat->reset_task); + KASSERT(error == 0, + ("%s: taskqueue_enqueue failed: %d", __func__, error)); +} + +static void +ioat_reset_hw_task(void *ctx, int pending __unused) +{ + struct ioat_softc *ioat; + int error; + + ioat = ctx; + ioat_log_message(1, "%s: Resetting channel\n", __func__); + error = ioat_reset_hw(ioat); KASSERT(error == 0, ("%s: reset failed: %d", __func__, error)); + (void)error; } /* |