summaryrefslogtreecommitdiffstats
path: root/sys/dev/fdc/fdc.c
diff options
context:
space:
mode:
authorjoerg <joerg@FreeBSD.org>2004-09-23 21:12:21 +0000
committerjoerg <joerg@FreeBSD.org>2004-09-23 21:12:21 +0000
commitf2a11c9f2e7cf0a8afeb91bd96c79df921c86dea (patch)
tree52a18f91be708d3a3f54c050bd331429d9ab8362 /sys/dev/fdc/fdc.c
parente7c39452fd145d2952a8d73e5ee20d81bdad504a (diff)
downloadFreeBSD-src-f2a11c9f2e7cf0a8afeb91bd96c79df921c86dea.zip
FreeBSD-src-f2a11c9f2e7cf0a8afeb91bd96c79df921c86dea.tar.gz
Implement terminating the worker thread when the driver is about to
be deregistered. Not yet tested, since by now, GEOM doesn't want us to deregister. PHK wants to fix that RSN.
Diffstat (limited to 'sys/dev/fdc/fdc.c')
-rw-r--r--sys/dev/fdc/fdc.c24
1 files changed, 21 insertions, 3 deletions
diff --git a/sys/dev/fdc/fdc.c b/sys/dev/fdc/fdc.c
index 139285c..6df202c 100644
--- a/sys/dev/fdc/fdc.c
+++ b/sys/dev/fdc/fdc.c
@@ -761,8 +761,17 @@ fdc_worker(struct fdc_data *fdc)
if (fdc->bp == NULL)
msleep(&fdc->head, &fdc->fdc_mtx,
PRIBIO, "-", hz);
- } while (fdc->bp == NULL);
+ } while (fdc->bp == NULL &&
+ (fdc->flags & FDC_KTHREAD_EXIT) == 0);
mtx_unlock(&fdc->fdc_mtx);
+
+ if (fdc->bp == NULL)
+ /*
+ * Nothing to do, worker thread has been
+ * requested to stop.
+ */
+ return (0);
+
bp = fdc->bp;
fd = fdc->fd = bp->bio_driver1;
fdc->retry = 0;
@@ -1118,7 +1127,8 @@ fdc_thread(void *arg)
fdc = arg;
int i;
- for (;;) {
+ fdc->flags |= FDC_KTHREAD_ALIVE;
+ while ((fdc->flags & FDC_KTHREAD_EXIT) == 0) {
i = fdc_worker(fdc);
if (i && debugflags & 0x20) {
if (fdc->bp != NULL) {
@@ -1129,6 +1139,8 @@ fdc_thread(void *arg)
}
fdc->retry += i;
}
+ fdc->flags &= ~(FDC_KTHREAD_EXIT | FDC_KTHREAD_ALIVE);
+ wakeup(&fdc->fdc_thread);
}
/*
@@ -1624,7 +1636,13 @@ fdc_detach(device_t dev)
if ((error = bus_generic_detach(dev)))
return (error);
- /* XXX: kill thread */
+ /* kill worker thread */
+ fdc->flags |= FDC_KTHREAD_EXIT;
+ mtx_lock(&fdc->fdc_mtx);
+ while ((fdc->flags & FDC_KTHREAD_ALIVE) != 0)
+ msleep(&fdc->fdc_thread, &fdc->fdc_mtx, PRIBIO, "fdcdet", 0);
+ mtx_unlock(&fdc->fdc_mtx);
+
/* reset controller, turn motor off */
fdout_wr(fdc, 0);
OpenPOWER on IntegriCloud