From 07296bbba12a3152f79e4c9407d6fe3b5585cd99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Schmidt?= Date: Sun, 12 Nov 2000 20:41:24 +0000 Subject: [PATCH] Better handling of immediate commands, mainly to solve timeouts in the atapi-tape code... --- sys/dev/ata/atapi-all.c | 37 ++++++++++++++++++++++++++++++++----- sys/dev/ata/atapi-all.h | 1 + sys/dev/ata/atapi-fd.c | 8 ++------ sys/dev/ata/atapi-tape.c | 3 ++- 4 files changed, 37 insertions(+), 12 deletions(-) diff --git a/sys/dev/ata/atapi-all.c b/sys/dev/ata/atapi-all.c index 04c42c0ee00..2ea1e5c23a4 100644 --- a/sys/dev/ata/atapi-all.c +++ b/sys/dev/ata/atapi-all.c @@ -248,9 +248,31 @@ atapi_transfer(struct atapi_request *request) request->device->devname, atapi_cmd2str(request->ccb[0])); atapi_dump("ccb = ", &request->ccb[0], sizeof(request->ccb)); #endif + /* is this just a POLL DSC command ? */ + if (request->ccb[0] == ATAPI_POLL_DSC) { + outb(atp->controller->ioaddr + ATA_DRIVE, ATA_D_IBM | atp->unit); + DELAY(10); + if (inb(atp->controller->altioaddr) & ATA_S_DSC) + request->error = 0; + else + request->error = EBUSY; + if (request->callback) { + if (!((request->callback)(request))) { + if (request->dmatab) + free(request->dmatab, M_DEVBUF); + free(request, M_ATAPI); + } + } + else + wakeup((caddr_t)request); + atp->controller->active = ATA_IDLE; /* should go in ata-all.c */ + return; + } + /* start timeout for this command */ request->timeout_handle = timeout((timeout_t *)atapi_timeout, request, request->timeout); + if (request->ccb[0] != ATAPI_REQUEST_SENSE) atp->cmd = request->ccb[0]; @@ -486,13 +508,17 @@ atapi_test_ready(struct atapi_softc *atp) int atapi_wait_ready(struct atapi_softc *atp, int timeout) { - int error = 0, timout = timeout * hz; + int error = 0; + int8_t ccb[16] = { ATAPI_POLL_DSC, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - while (timout > 0) { - if ((error = atapi_test_ready(atp)) != EBUSY) + timeout *= hz; + while (timeout > 0) { + error = atapi_queue_cmd(atp, ccb, NULL, 0, 0, 0, NULL, NULL); + if (error != EBUSY) break; - tsleep((caddr_t)&error, PRIBIO, "atpwt", 50); - timout -= 50; + tsleep((caddr_t)&error, PRIBIO, "atpwt", hz / 2); + timeout -= (hz / 2); } return error; } @@ -666,6 +692,7 @@ atapi_cmd2str(u_int8_t cmd) case 0xbb: return ("SET_SPEED"); case 0xbd: return ("MECH_STATUS"); case 0xbe: return ("READ_CD"); + case 0xff: return ("POLL_DSC"); default: { static char buffer[16]; sprintf(buffer, "unknown CMD (0x%02x)", cmd); diff --git a/sys/dev/ata/atapi-all.h b/sys/dev/ata/atapi-all.h index 72cf781e7c1..b81770fa375 100644 --- a/sys/dev/ata/atapi-all.h +++ b/sys/dev/ata/atapi-all.h @@ -116,6 +116,7 @@ #define ATAPI_SET_SPEED 0xbb /* set drive speed */ #define ATAPI_MECH_STATUS 0xbd /* get changer status */ #define ATAPI_READ_CD 0xbe /* read data */ +#define ATAPI_POLL_DSC 0xff /* poll DSC status bit */ /* ATAPI request sense structure */ struct atapi_reqsense { diff --git a/sys/dev/ata/atapi-fd.c b/sys/dev/ata/atapi-fd.c index 3f985efa5a9..62f844d04ce 100644 --- a/sys/dev/ata/atapi-fd.c +++ b/sys/dev/ata/atapi-fd.c @@ -412,14 +412,10 @@ afd_eject(struct afd_softc *fdp, int close) static int afd_start_stop(struct afd_softc *fdp, int start) { - int8_t ccb[16] = { ATAPI_START_STOP, 0x01, 0, 0, start, + int8_t ccb[16] = { ATAPI_START_STOP, 0, 0, 0, start, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - int error; - error = atapi_queue_cmd(fdp->atp, ccb, NULL, 0, 0, 10, NULL, NULL); - if (error) - return error; - return atapi_wait_ready(fdp->atp, 30); + return atapi_queue_cmd(fdp->atp, ccb, NULL, 0, 0, 30, NULL, NULL); } static int diff --git a/sys/dev/ata/atapi-tape.c b/sys/dev/ata/atapi-tape.c index e390b3f4315..ac1049c4048 100644 --- a/sys/dev/ata/atapi-tape.c +++ b/sys/dev/ata/atapi-tape.c @@ -482,7 +482,8 @@ ast_start(struct atapi_softc *atp) devstat_start_transaction(&stp->stats); atapi_queue_cmd(stp->atp, ccb, bp->bio_data, blkcount * stp->blksize, - (bp->bio_cmd == BIO_READ) ? ATPR_F_READ : 0, 60, ast_done, bp); + (bp->bio_cmd == BIO_READ) ? ATPR_F_READ : 0, + 120, ast_done, bp); } static int