Current-Users archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: Acer M5229 IDE bugs (esp. on sparc64)

On Thu, Feb 14, 2008 at 03:59:53PM -0500, Rafal Boni wrote:
> Thanks for the reply, Manuel.. glad to have input from someone who knows 
> the code and ATA(PI) subsystem well!
> Manuel Bouyer wrote:
> >On Thu, Feb 14, 2008 at 02:17:47PM -0500, Rafal Boni wrote:
> [...]
> >>I see that wdc->dma_status is always 0x04 (WDC_DMAST_UNDER), which is a 
> >>synthetic error generated only by pciide_dma_finish().  I'm guessing 
> >>that the suspect pciiide_dma_finish() is the one called from wdcintr(). 
> >> Because the rev of the M1559 IDE controller I have doesn't have a 
> >>chan-id register to determine which channel caused an interrupt, for 
> >>this chip we end up *always* checking both channels, and the code in 
> >>wdcintr() / pciide_dma_finish() looks very suspicious... stop DMA first, 
> >>ask questions later.
> >
> >AFAIK it's not: before stopping the DMA channel, we check if the controller
> >did interrupt (status & IDEDMA_CTL_INTR).
> A minor point of clarification here... is that status per-controller, or 
> per-channel?

It's supposed to be per-channel

> Note that this controller is running in native-PCI mode 
> and there is no register to tell is which channel interrupted (see 
> aceride.c, ~ line 238).  I'm wondering if one channel interrupting could 
> have caused the early-DMA termination on the other.

If the IDEDMA_CTL_INTR bit is accurate, it should not. Of course
IDEDMA_CTL_INTR is only meaningfull for DMA transfers, not PIO.

One thing we could make it add a check in pciide_dma_start() that
IDEDMA_CTL_INTR isn't already set.

> >We have to stop the DMA first, because in some case the DMA engine will 
> >still
> >be active at end of transfer (if the device has less data to return than
> >requested for example - as the comment says, it's a valid condition for
> >ATAPI devices).
> Interestingly enough, the ATAPI devices connected to this controller on 
> both my machines (a V100, V120 and a T1/200) and machines Julian tested 
> (a Blade 100 at least, maybe a V120 as well) both are unable to do any 
> sort of DMA to/from the CD anyway.  I'm not sure it's related to this, 
> but maybe... (and not just UDMA... the CD downgrades right through the 
> UDMA range to MW DMA and then to PIO 4).  Of course, I have no PC's with 
>  this cursed controller to test if/whether this is somehow related to 
> the sparc64 platform or a generic issue ;)

From what I remember when I had such a PC, it's a generic issue.
Some controllers just can't properly do DMA for atapi devices, as they
can't handle non-512 byte transfers.

> >>FreeBSD looks like it does the checks a bit differnetly (their whole 
> >>handling of the Bus-Master DMA status register -- IDEDMA_CTL -- is a bit 
> >>different, but they key is they look like they check the active status 
> >>(IDEDMA_CTL_ACT) before attempting to kill the dma vs. our kill-1st, 
> >>check if active later.
> >
> >If this chip asserts IDEDMA_CTL_INTR supriously, and we need to check
> >IDEDMA_CTL_ACT instead, then it's broken. So it needs a private intr
> >routine, and it needs to disable DMA for ATAPI devices.
> Hmm, ok.  Is there a reference somewhere for how CTL_INTR, CTL_ACT and 
> generation of the actual hardware interrupt should behave with respect 
> to each other?  What I'm after is a way to actually test if the chip is 
> asserting IDEDMA_CTL_INTR spuriously or not.


> (The other reason I ask is that given what you say, I can't understand 
> why FreeBSD would pre-load that register with CTL_INTR | CTL_ERR (or the 
> equivalent bits there... (ATA_BMSTAT_INTERRUPT | ATA_BMSTAT_ERROR)).

This is to clear the interrupt and error bits. They are cleared by writing
a 1 to them (quite classic for bits set to 1 by hardware).
We do it in pciide_dma_init() and pciide_irqack() by writing back the
value we just read from the register.

Manuel Bouyer <>
     NetBSD: 26 ans d'experience feront toujours la difference

Home | Main Index | Thread Index | Old Index