summaryrefslogtreecommitdiffstats
path: root/sys/dev/ata
diff options
context:
space:
mode:
authorsos <sos@FreeBSD.org>2003-09-16 15:21:37 +0000
committersos <sos@FreeBSD.org>2003-09-16 15:21:37 +0000
commitc13a8cc2c7c14d4d5b75dae625ae2d0c9eaa3933 (patch)
treeb4b17b38ad698c14a780e876a03ae3e307350090 /sys/dev/ata
parent8e84f6e31b6bd3ebe412d5d338cdfe30415d5dac (diff)
downloadFreeBSD-src-c13a8cc2c7c14d4d5b75dae625ae2d0c9eaa3933.zip
FreeBSD-src-c13a8cc2c7c14d4d5b75dae625ae2d0c9eaa3933.tar.gz
When ignoring interrupts (due to no running request set) then try
to grap the channel so we can read status (and clear an evt pending interrupt).
Diffstat (limited to 'sys/dev/ata')
-rw-r--r--sys/dev/ata/ata-lowlevel.c39
1 files changed, 19 insertions, 20 deletions
diff --git a/sys/dev/ata/ata-lowlevel.c b/sys/dev/ata/ata-lowlevel.c
index 8b4bf5c..9af651d 100644
--- a/sys/dev/ata/ata-lowlevel.c
+++ b/sys/dev/ata/ata-lowlevel.c
@@ -270,14 +270,28 @@ 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)
+ /* ignore this interrupt if there is no running request */
+ if (!request) {
+ if (ATA_LOCK_CH(ch, ATA_CONTROL)) {
+ u_int8_t status = ATA_IDX_INB(ch, ATA_STATUS);
+ u_int8_t error = ATA_IDX_INB(ch, ATA_ERROR);
+
+ if (bootverbose)
+ ata_printf(ch, -1,
+ "spurious interrupt - status=0x%02x error=0x%02x\n",
+ status, error);
+ ATA_UNLOCK_CH(ch);
+ }
+ else {
+ if (bootverbose)
+ ata_printf(ch, -1, "spurious interrupt - channel busy\n");
+ }
return;
+ }
- /* if device is busy it didn't interrupt, ignore interrupt (shared) */
+ /* ignore interrupt if device is busy */
if (ATA_IDX_INB(ch, ATA_ALTSTAT) & ATA_S_BUSY) {
DELAY(100);
if (!(ATA_IDX_INB(ch, ATA_ALTSTAT) & ATA_S_DRQ))
@@ -285,22 +299,7 @@ ata_interrupt(void *data)
}
/* 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 (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",
- status, ATA_IDX_INB(ch, ATA_ERROR),
- ATA_IDX_INB(ch, ATA_IREASON));
- }
- return;
- }
-
- request->status = status;
+ request->status = ATA_IDX_INB(ch, ATA_STATUS);
switch (request->flags & (ATA_R_ATAPI | ATA_R_DMA)) {
OpenPOWER on IntegriCloud