summaryrefslogtreecommitdiffstats
path: root/sys/dev/ata/ata-queue.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/ata/ata-queue.c')
-rw-r--r--sys/dev/ata/ata-queue.c23
1 files changed, 18 insertions, 5 deletions
diff --git a/sys/dev/ata/ata-queue.c b/sys/dev/ata/ata-queue.c
index 036b008..5de54ff 100644
--- a/sys/dev/ata/ata-queue.c
+++ b/sys/dev/ata/ata-queue.c
@@ -95,12 +95,14 @@ ata_queue_request(struct ata_request *request)
/* if this is not a callback wait until request is completed */
if (!request->callback) {
ATA_DEBUG_RQ(request, "wait for completition");
- while (!dumping &&
- sema_timedwait(&request->done, request->timeout * hz * 4)) {
+ if (!dumping &&
+ sema_timedwait(&request->done, request->timeout * hz * 4)) {
device_printf(request->dev,
- "req=%p %s semaphore timeout !! DANGER Will Robinson !!\n",
- request, ata_cmd2str(request));
- ata_start(ch->dev);
+ "WARNING - %s taskqueue timeout "
+ "- completing request directly\n",
+ ata_cmd2str(request));
+ request->flags |= ATA_R_DANGER1;
+ ata_completed(request, 0);
}
sema_destroy(&request->done);
}
@@ -252,6 +254,17 @@ ata_completed(void *context, int dummy)
struct ata_device *atadev = device_get_softc(request->dev);
struct ata_composite *composite;
+ if (request->flags & ATA_R_DANGER2) {
+ device_printf(request->dev,
+ "WARNING - %s freeing taskqueue zombie request\n",
+ ata_cmd2str(request));
+ request->flags &= ~(ATA_R_DANGER1 | ATA_R_DANGER2);
+ ata_free_request(request);
+ return;
+ }
+ if (request->flags & ATA_R_DANGER1)
+ request->flags |= ATA_R_DANGER2
+
ATA_DEBUG_RQ(request, "completed entered");
/* if we had a timeout, reinit channel and deal with the falldown */
OpenPOWER on IntegriCloud