diff options
author | sos <sos@FreeBSD.org> | 2004-08-16 09:32:35 +0000 |
---|---|---|
committer | sos <sos@FreeBSD.org> | 2004-08-16 09:32:35 +0000 |
commit | 2f36723c3d87eb1255bba04d4479818e08f8e487 (patch) | |
tree | f5fc17513329dbf6441060e1560a7e85bdc7fac8 /sys/dev/ata | |
parent | 486b54a301c46adf1d9141321f108c7d2f307ed5 (diff) | |
download | FreeBSD-src-2f36723c3d87eb1255bba04d4479818e08f8e487.zip FreeBSD-src-2f36723c3d87eb1255bba04d4479818e08f8e487.tar.gz |
Improve (hopefully) on the workaround code for devices that doesn't
interrupt when command is done, ie some ATAPI CD drives with no
media loaded.
Diffstat (limited to 'sys/dev/ata')
-rw-r--r-- | sys/dev/ata/ata-all.c | 2 | ||||
-rw-r--r-- | sys/dev/ata/ata-lowlevel.c | 13 | ||||
-rw-r--r-- | sys/dev/ata/ata-queue.c | 26 |
3 files changed, 18 insertions, 23 deletions
diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c index 59eec52..8da2851 100644 --- a/sys/dev/ata/ata-all.c +++ b/sys/dev/ata/ata-all.c @@ -554,7 +554,7 @@ ata_getparam(struct ata_device *atadev, u_int8_t command) while (retries-- > 0) { request->device = atadev; request->timeout = 5; - request->retries = -1; + request->retries = 0; request->u.ata.command = command; request->flags = (ATA_R_READ | ATA_R_IMMEDIATE); request->data = (caddr_t)atadev->param; diff --git a/sys/dev/ata/ata-lowlevel.c b/sys/dev/ata/ata-lowlevel.c index f747a36..0f93deb 100644 --- a/sys/dev/ata/ata-lowlevel.c +++ b/sys/dev/ata/ata-lowlevel.c @@ -100,7 +100,8 @@ ata_generic_transaction(struct ata_request *request) if (ch->hw.command(request->device, request->u.ata.command, request->u.ata.lba, request->u.ata.count, request->u.ata.feature)) { - ata_prtdev(request->device, "error issueing PIO command\n"); + ata_prtdev(request->device, "error issueing %s command\n", + ata_cmd2str(request)); request->result = EIO; break; } @@ -152,7 +153,8 @@ ata_generic_transaction(struct ata_request *request) if (ch->hw.command(request->device, request->u.ata.command, request->u.ata.lba, request->u.ata.count, request->u.ata.feature)) { - ata_prtdev(request->device, "error issuing DMA command\n"); + ata_prtdev(request->device, "error issueing %s command\n", + ata_cmd2str(request)); request->result = EIO; break; } @@ -524,13 +526,6 @@ ata_generic_interrupt(void *data) break; } - /* if we timed out the unlocking of the ATA channel is done later */ - if (!(request->flags & ATA_R_TIMEOUT)) { - ch->running = NULL; - ATA_UNLOCK_CH(ch); - ch->locking(ch, ATA_LF_UNLOCK); - } - /* schedule completition for this request */ ata_finish(request); } diff --git a/sys/dev/ata/ata-queue.c b/sys/dev/ata/ata-queue.c index cf07991..1dd7bc4 100644 --- a/sys/dev/ata/ata-queue.c +++ b/sys/dev/ata/ata-queue.c @@ -118,7 +118,7 @@ ata_controlcmd(struct ata_device *atadev, u_int8_t command, u_int16_t feature, request->u.ata.feature = feature; request->flags = ATA_R_CONTROL; request->timeout = 5; - request->retries = -1; + request->retries = 0; ata_queue_request(request); error = request->result; ata_free_request(request); @@ -194,10 +194,6 @@ ata_start(struct ata_channel *ch) if (ch->hw.transaction(request) == ATA_OP_CONTINUES) return; - /* unlock ATA channel HW */ - ATA_UNLOCK_CH(ch); - ch->locking(ch, ATA_LF_UNLOCK); - /* finish up this (failed) request */ ata_finish(request); } @@ -208,10 +204,18 @@ ata_start(struct ata_channel *ch) void ata_finish(struct ata_request *request) { + struct ata_channel *ch = request->device->channel; ATA_DEBUG_RQ(request, "taskqueue completition"); + /* if we timed out the unlocking of the ATA channel is done later */ + if (!(request->flags & ATA_R_TIMEOUT)) { + ch->running = NULL; + ATA_UNLOCK_CH(ch); + ch->locking(ch, ATA_LF_UNLOCK); + } + /* request is done schedule it for completition */ - if (request->device->channel->flags & ATA_IMMEDIATE_MODE) { + if (ch->flags & ATA_IMMEDIATE_MODE) { ata_completed(request, 0); } else { @@ -234,19 +238,15 @@ ata_completed(void *context, int dummy) ATA_DEBUG_RQ(request, "completed called"); if (request->flags & ATA_R_TIMEOUT) { - - /* if negative retry count just give up and unlock channel HW */ - if (request->retries < 0) { - if (!(request->flags & ATA_R_QUIET)) + /* workaround for devices failing to interrupt */ + if (request->status == (ATA_S_READY | ATA_S_DSC)) { ata_prtdev(request->device, - "FAILURE - %s no interrupt\n", + "WARNING - %s no interrupt but good status\n", ata_cmd2str(request)); - request->result = EIO; ATA_UNLOCK_CH(channel); channel->locking(channel, ATA_LF_UNLOCK); } else { - /* reset controller and devices */ ata_reinit(channel); |