summaryrefslogtreecommitdiffstats
path: root/sys/dev/ata
diff options
context:
space:
mode:
authorsos <sos@FreeBSD.org>2004-08-16 09:32:35 +0000
committersos <sos@FreeBSD.org>2004-08-16 09:32:35 +0000
commit2f36723c3d87eb1255bba04d4479818e08f8e487 (patch)
treef5fc17513329dbf6441060e1560a7e85bdc7fac8 /sys/dev/ata
parent486b54a301c46adf1d9141321f108c7d2f307ed5 (diff)
downloadFreeBSD-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.c2
-rw-r--r--sys/dev/ata/ata-lowlevel.c13
-rw-r--r--sys/dev/ata/ata-queue.c26
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);
OpenPOWER on IntegriCloud