diff options
author | sos <sos@FreeBSD.org> | 2000-11-12 20:41:24 +0000 |
---|---|---|
committer | sos <sos@FreeBSD.org> | 2000-11-12 20:41:24 +0000 |
commit | c2971789cc079e18aad42dd1f7e9120dd18bc0ed (patch) | |
tree | 56290f2bc1382d58b3f31930dd6962ed69ffc697 | |
parent | d17388a5b237b0370d7e306255870c472cf2a4ef (diff) | |
download | FreeBSD-src-c2971789cc079e18aad42dd1f7e9120dd18bc0ed.zip FreeBSD-src-c2971789cc079e18aad42dd1f7e9120dd18bc0ed.tar.gz |
Better handling of immediate commands, mainly to solve timeouts
in the atapi-tape code...
-rw-r--r-- | sys/dev/ata/atapi-all.c | 37 | ||||
-rw-r--r-- | sys/dev/ata/atapi-all.h | 1 | ||||
-rw-r--r-- | sys/dev/ata/atapi-fd.c | 8 | ||||
-rw-r--r-- | 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 04c42c0..2ea1e5c 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 72cf781..b81770f 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 3f985ef..62f844d 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 e390b3f..ac1049c 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 |