mirror of
https://github.com/opnsense/src.git
synced 2026-05-28 04:12:45 -04:00
Better handling of immediate commands, mainly to solve timeouts
in the atapi-tape code...
This commit is contained in:
parent
a9c1b0e23a
commit
07296bbba1
4 changed files with 37 additions and 12 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue