diff options
author | sos <sos@FreeBSD.org> | 2003-09-08 08:32:25 +0000 |
---|---|---|
committer | sos <sos@FreeBSD.org> | 2003-09-08 08:32:25 +0000 |
commit | d2bb76d9463520f2aef03b8b7ca1af51ab1e7ba3 (patch) | |
tree | abec4702814d8a4629df7256b88c452e30654fa4 | |
parent | f64155d27c46db3e7a29eb774c7feb0a16f2b2df (diff) | |
download | FreeBSD-src-d2bb76d9463520f2aef03b8b7ca1af51ab1e7ba3.zip FreeBSD-src-d2bb76d9463520f2aef03b8b7ca1af51ab1e7ba3.tar.gz |
Handle shared channels better.
Try to avoid the spurios interrupts better.
-rw-r--r-- | sys/dev/ata/ata-lowlevel.c | 29 |
1 files changed, 18 insertions, 11 deletions
diff --git a/sys/dev/ata/ata-lowlevel.c b/sys/dev/ata/ata-lowlevel.c index b1655c8..21a205d 100644 --- a/sys/dev/ata/ata-lowlevel.c +++ b/sys/dev/ata/ata-lowlevel.c @@ -270,30 +270,37 @@ ata_interrupt(void *data) { struct ata_channel *ch = (struct ata_channel *)data; struct ata_request *request = ch->running; + u_int8_t status; int length; + /* if the channel is idle this interrupt is not for us (shared) */ + if (ch->state == ATA_IDLE) + return; + + /* if device is busy it didn't interrupt, ignore interrupt (shared) */ + if (ATA_IDX_INB(ch, ATA_ALTSTAT) & ATA_S_BUSY) { + DELAY(100); + if (!(ATA_IDX_INB(ch, ATA_ALTSTAT) & ATA_S_DRQ)) + return; + } + + /* clear interrupt and get status */ + status = ATA_IDX_INB(ch, ATA_STATUS); + /* if we dont have a running request shout and ignore this interrupt */ if (request == NULL) { - if (bootverbose) { + if (1 || bootverbose) { printf("ata%d: spurious interrupt - ", device_get_unit(ch->dev)); if (request) printf("request OK - "); printf("status=0x%02x error=0x%02x reason=0x%02x\n", - ATA_IDX_INB(ch, ATA_ALTSTAT), ATA_IDX_INB(ch, ATA_ERROR), + status, ATA_IDX_INB(ch, ATA_ERROR), ATA_IDX_INB(ch, ATA_IREASON)); } return; } - /* if device is busy it didn't interrupt */ - if (ATA_IDX_INB(ch, ATA_ALTSTAT) & ATA_S_BUSY) { - DELAY(100); - if (!(ATA_IDX_INB(ch, ATA_ALTSTAT) & ATA_S_DRQ)) - return; - } - - /* clear interrupt and get status */ - request->status = ATA_IDX_INB(ch, ATA_STATUS); + request->status = status; switch (request->flags & (ATA_R_ATAPI | ATA_R_DMA)) { |