Better handling of immediate commands, mainly to solve timeouts

in the atapi-tape code...
This commit is contained in:
Søren Schmidt 2000-11-12 20:41:24 +00:00
parent a9c1b0e23a
commit 07296bbba1
4 changed files with 37 additions and 12 deletions

View file

@ -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);

View file

@ -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 {

View file

@ -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

View file

@ -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