diff options
-rw-r--r-- | sys/dev/ata/ata-all.c | 21 | ||||
-rw-r--r-- | sys/dev/ata/ata-queue.c | 41 |
2 files changed, 38 insertions, 24 deletions
diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c index d23c3d9..bd59faf 100644 --- a/sys/dev/ata/ata-all.c +++ b/sys/dev/ata/ata-all.c @@ -563,20 +563,19 @@ ata_getparam(struct ata_device *atadev, u_int8_t command) if (atadev->param) { request = ata_alloc_request(); if (request) { - request->device = atadev; - request->u.ata.command = command; - request->flags = (ATA_R_READ | ATA_R_IMMEDIATE | ATA_R_QUIET); - request->data = (caddr_t)atadev->param; - request->timeout = 2; - request->retries = 3; - request->bytecount = sizeof(struct ata_params); - request->transfersize = DEV_BSIZE; - while (request->retries > 0 ) { + int retries = 2; + while (retries-- > 0) { + request->device = atadev; + request->timeout = 5; + request->retries = -1; + request->u.ata.command = command; + request->flags = (ATA_R_READ | ATA_R_IMMEDIATE); + request->data = (caddr_t)atadev->param; + request->bytecount = sizeof(struct ata_params); + request->transfersize = DEV_BSIZE; ata_queue_request(request); if (!(error = request->result)) break; - request->retries--; - request->flags |= ATA_R_REQUEUE; } ata_free_request(request); } diff --git a/sys/dev/ata/ata-queue.c b/sys/dev/ata/ata-queue.c index 5a28351..ac5375e 100644 --- a/sys/dev/ata/ata-queue.c +++ b/sys/dev/ata/ata-queue.c @@ -234,23 +234,38 @@ ata_completed(void *context, int dummy) ATA_DEBUG_RQ(request, "completed called"); if (request->flags & ATA_R_TIMEOUT) { - ata_reinit(channel); - /* if retries still permit, reinject this request */ - if (request->retries-- > 0) { - request->flags &= ~ATA_R_TIMEOUT; - request->flags |= (ATA_R_IMMEDIATE | ATA_R_REQUEUE); - ata_queue_request(request); - return; - } - - /* otherwise just finish with error */ - else { + /* if negative retry count just give up and unlock channel HW */ + if (request->retries < 0) { if (!(request->flags & ATA_R_QUIET)) ata_prtdev(request->device, - "FAILURE - %s timed out\n", + "FAILURE - %s no interrupt\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); + + /* if retries still permit, reinject this request */ + if (request->retries-- > 0) { + request->flags &= ~ATA_R_TIMEOUT; + request->flags |= (ATA_R_IMMEDIATE | ATA_R_REQUEUE); + ata_queue_request(request); + return; + } + + /* otherwise just finish with error */ + else { + if (!(request->flags & ATA_R_QUIET)) + ata_prtdev(request->device, + "FAILURE - %s timed out\n", + ata_cmd2str(request)); + request->result = EIO; + } } } else { @@ -402,7 +417,7 @@ ata_timeout(struct ata_request *request) } /* report that we timed out */ - if (!(request->flags & ATA_R_QUIET)) { + if (!(request->flags & ATA_R_QUIET) && request->retries > 0) { ata_prtdev(request->device, "TIMEOUT - %s retrying (%d retr%s left)", ata_cmd2str(request), request->retries, |