Do a REQUEST SENSE when ATAPI operation returns an error. This is needed to clear

the Unit Attention status, i.e. after a media change on a CDROM.
This commit is contained in:
mhitch 1999-04-17 17:08:12 +00:00
parent d80adac6a7
commit 46f5ce02e0
1 changed files with 30 additions and 11 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: idesc.c,v 1.39 1999/04/16 03:29:49 mhitch Exp $ */
/* $NetBSD: idesc.c,v 1.40 1999/04/17 17:08:12 mhitch Exp $ */
/*
* Copyright (c) 1994 Michael L. Hitch
@ -219,6 +219,7 @@ struct ide_softc {
#define IDEF_ATAPI 0x02 /* it's an ATAPI device */
#define IDEF_ACAPLEN 0x04
#define IDEF_ACAPDRQ 0x08
#define IDEF_SENSE 0x10 /* Doing a request sense command */
short sc_error;
char sc_drive;
char sc_state;
@ -1140,6 +1141,7 @@ idego(dev, xs)
printf("idego: atapi cmd %02x\n", xs->cmd->opcode);
#endif
dev->sc_cur = ide;
ide->sc_flags &= ~IDEF_SENSE;
return (idestart(dev));
}
if (xs->cmd->opcode != SCSI_READ_COMMAND && xs->cmd->opcode != READ_BIG &&
@ -1393,8 +1395,8 @@ ide_atapi_icmd(dev, target, cbuf, clen, buf, len)
u_short *bf;
clen = dev->sc_flags & IDEF_ACAPLEN ? 16 : 12;
ide->sc_buf = xs->data;
ide->sc_bcount = xs->datalen;
ide->sc_buf = buf;
ide->sc_bcount = len;
if (wait_for_unbusy(dev) != 0) {
printf("ide_atapi_icmd: not ready, st = %02x\n",
@ -1477,7 +1479,7 @@ ide_atapi_intr(dev)
printf("atapi_intr: controller busy\n");
return (0);
} else {
xs->error = XS_SENSE;
xs->error = XS_SHORTSENSE;
xs->sense.atapi_sense = regs->ide_error;
ide_atapi_done(dev);
return (0);
@ -1592,13 +1594,26 @@ again:
if (ide_debug)
printf("PHASE_COMPLETED\n");
#endif
if (status & IDES_ERR) {
if (ide->sc_flags & IDEF_SENSE) {
ide->sc_flags &= ~IDEF_SENSE;
if ((status & IDES_ERR) == 0)
xs->error = XS_SENSE;
} else if (status & IDES_ERR) {
struct scsipi_sense rqs;
printf("ide_atapi_intr: error status %x err %x\n",
status, err);
if (err & ~0x28) { /* Ignore media change bits */
xs->error = XS_SENSE;
xs->sense.atapi_sense = err;
}
xs->error = XS_SHORTSENSE;
xs->sense.atapi_sense = err;
ide->sc_flags |= IDEF_SENSE;
rqs.opcode = REQUEST_SENSE;
rqs.byte2 = xs->sc_link->scsipi_scsi.lun << 5;
rqs.length = sizeof(xs->sense.scsi_sense);
rqs.unused[0] = rqs.unused[1] = rqs.control = 0;
ide_atapi_icmd(dev, xs->sc_link->scsipi_scsi.target,
&rqs, sizeof(rqs), &xs->sense.scsi_sense,
sizeof(xs->sense.scsi_sense));
return(1);
}
if (ide->sc_bcount != 0)
printf("ide_atapi_intr: %ld bytes remaining\n", ide->sc_bcount);
@ -1610,7 +1625,7 @@ again:
}
printf("ide_atapi_intr: unknown phase %x\n", phase);
if (status & IDES_ERR) {
xs->error = XS_SENSE;
xs->error = XS_SHORTSENSE;
xs->sense.atapi_sense = err;
} else
xs->error = XS_DRIVER_STUFFUP;
@ -1626,7 +1641,7 @@ ide_atapi_done(dev)
{
struct scsipi_xfer *xs = dev->sc_xs;
if (xs->error == XS_SENSE) {
if (xs->error == XS_SHORTSENSE) {
int atapi_sense = xs->sense.atapi_sense;
bzero((char *)&xs->sense.scsi_sense, sizeof(xs->sense.scsi_sense));
@ -1643,5 +1658,9 @@ ide_atapi_done(dev)
ide_scsidone(dev, SCSI_CHECK);
return;
}
if (xs->error == XS_SENSE) {
ide_scsidone(dev, SCSI_CHECK);
return;
}
ide_scsidone(dev, 0); /* ??? */
}