Subject: kern/7247: Incorrect handling of interrupts with pciide driver in native
To: None <gnats-bugs@gnats.netbsd.org>
From: None <mark@causality.com>
List: netbsd-bugs
Date: 03/25/1999 23:37:54
>Number: 7247
>Category: kern
>Synopsis: Incorrect handling of interrupts with pciide driver in native
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: kern-bug-people (Kernel Bug People)
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Thu Mar 25 23:50:01 1999
>Last-Modified:
>Originator: Mark Brinicombe
>Organization:
BCCS Ltd
>Release: NetBSD-current 1999/03/25
>Environment:
System: NetBSD p2.devlab.nc.com 1.3I-NCOS NetBSD 1.3I-NCOS (P2) #1: Wed Mar 17 16:37:17 PST 1999 mark@p2.devlab.nc.com:/usr/export/mark/NCOS/os-src/sys/arch/i386/compile/P2 i386
>Description:
Interrupt handling does not work correctly with the pciide driver if
running in native mode with two channels bus mustering at the same time.
In native mode a single interrupt is shared by both IDE channels. The
result is that wdcintr() gets called for both channels whenever an
interrupt occurs. If two channels are bus mastering at the same time
and one completes generating an interrupt, wdcintr() is called for
both channels, each of which assumes the interrupt was for it.
This means one DMA transfer completes correctly but the other channel's
DMA transfer is cut short (with an error) as it assumes that the
interupt was it's completion.
This will not normally be seen in i386 architectures with motherboard
IDE as this configuration does not use native interrupts.
>How-To-Repeat:
Try bus mastering on two channels on a plug in PCI card (i.e. promise
ultra/33 or ultra/66). Note the DMA to either channel individually works
but simultaneous DMA transfers results in lots of nasty errors.
>Fix:
The routine pciide_pci_intr() needs to check that the IDE channel is
not still doing DMA before calling wdcintr() by checking the
status in the bus mastering register i.e. the IDEDMA_CTL_INTR
bit will be set if a channel did generate the interrupt thus making
sure that only the channel that generated the interrupt gets it
delivered.
>Audit-Trail:
>Unformatted:
mode<synopsis of the problem (one line)>