summaryrefslogtreecommitdiffstats
path: root/sys/dev/ata/ata-queue.c
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2009-05-01 08:03:46 +0000
committermav <mav@FreeBSD.org>2009-05-01 08:03:46 +0000
commite3041466988f968760de57959e5fd6674a0acf66 (patch)
tree3b444d7537d6bdd164161094c9099ba3ec128c40 /sys/dev/ata/ata-queue.c
parent700abeab8a81c590ae255dfa7225c8d891c5ca88 (diff)
downloadFreeBSD-src-e3041466988f968760de57959e5fd6674a0acf66.zip
FreeBSD-src-e3041466988f968760de57959e5fd6674a0acf66.tar.gz
Improve kernel dumping reliability for busy ATA channels:
- Generate fake channel interrupts even if channel busy with previous request to let it finish. Without this, dumping requests were just queued and never processed. - Drop pre-dump requests queue on dumping. ATA code, working in dumping (interruptless) mode, unable to handle long request queue. Actually, to get coherent dump we anyway should do as few unrelated actions as possible.
Diffstat (limited to 'sys/dev/ata/ata-queue.c')
-rw-r--r--sys/dev/ata/ata-queue.c33
1 files changed, 24 insertions, 9 deletions
diff --git a/sys/dev/ata/ata-queue.c b/sys/dev/ata/ata-queue.c
index 4a4bb19..8756884 100644
--- a/sys/dev/ata/ata-queue.c
+++ b/sys/dev/ata/ata-queue.c
@@ -218,20 +218,17 @@ ata_start(device_t dev)
ata_finish(request);
return;
}
- if (dumping) {
- mtx_unlock(&ch->state_mtx);
- mtx_unlock(&ch->queue_mtx);
- while (ch->running) {
- ata_interrupt(ch);
- DELAY(10);
- }
- return;
- }
}
mtx_unlock(&ch->state_mtx);
}
}
mtx_unlock(&ch->queue_mtx);
+ if (dumping) {
+ while (ch->running) {
+ ata_interrupt(ch);
+ DELAY(10);
+ }
+ }
}
void
@@ -560,6 +557,24 @@ ata_fail_requests(device_t dev)
}
}
+/*
+ * Rudely drop all requests queued to the channel of specified device.
+ * XXX: The requests are leaked, use only in fatal case.
+ */
+void
+ata_drop_requests(device_t dev)
+{
+ struct ata_channel *ch = device_get_softc(device_get_parent(dev));
+ struct ata_request *request, *tmp;
+
+ mtx_lock(&ch->queue_mtx);
+ TAILQ_FOREACH_SAFE(request, &ch->ata_queue, chain, tmp) {
+ TAILQ_REMOVE(&ch->ata_queue, request, chain);
+ request->result = ENXIO;
+ }
+ mtx_unlock(&ch->queue_mtx);
+}
+
static u_int64_t
ata_get_lba(struct ata_request *request)
{
OpenPOWER on IntegriCloud