IDE from current bk tree, UDMA and two channels...
Quoted 10 lines · I wrote:
Quoted 9 lines · Marcin Dalecki
Quoted 8 lines
Second problem is that read operation which ends with "drive ready, seek complete, data request" (why it happened in first place?) will just read one sector from drive (it was DMA transfer, so
drive->mult_count== 0), and then it returns fromata_errorwithATA_OP_CONTINUES. But what continues? Drive told us that current operation is done, and no new operation was started, so there is very low chance that some IRQ will ever come, and timer was just removed byata_irq_request(), so channel will never awake.
Quoted 5 lines
Quoted 2 lines
What should continue is the retry of the operation, since otherwise it will be abondoned in
do_ide_request(). However I will recheck.It is UP machine (with SMP non-preemptible kernel). Stack trace does not look like that it was caused by some race.
There is something severely broken... I reenabled
ide: unexpected interrupt in ata_irq_request and to my surprise here we get one suprious interrupt for each request we do, on both channels - primary and secondary.
It looked:
udma_pci_init: sending read command to driveata_irq_request: IRQ arrived, for us, calling handlerata_irq_request: handler returned 0
ide: unexpected interrupt 1 15 handler=00000000
callstack: ata_irq_request + 7e/234, handle_IRQ_event + 29/4c,
do_IRQ + df/190, common_interrupt + 18/20, do_softirq + 50/ac,
do_IRQ + 179/190, common_interrupt + 18/20udma_pci_init: sending read command to driveata_irq_request: IRQ arrived, for us, calling handlerata_irq_request: handler returned 0
ide: unexpected interrupt 1 15 handler=00000000
callstack: same as aboveudma_pci_init: sending read command to driveata_irq_request: IRQ arrived, for us, calling handlerata_irq_request: handler returned 0udma_pci_init: sending read command to driveata_irq_request: command immediately queued by do_ide_requestata_irq_request: IRQ arrived, for us, calling handler
oops: ide_dma_intr: udmastatus=00, diskstatus=58
So we are getting one spurious interrupt for each UDMA request. Until we do not issue new command to the drive immediately, IRQ is silently ignored, and everybody is happy (?). But when we queue command immediately by call to do_ide_request in ata_irq_request, sooner or later spurious interrupt will arrive with wrong timming, and we'll think that command is done while it is still in progress.
I see same spurious interrupt problem on primary channel too, but somehow timming is different with UDMA100, and we always find command done instead of in progress when spurious interrupt happens.
Unfortunately ATA/ATAPIv7 says that single interrupt is triggered after command is done and all data transfered, and we do not play with select bit. But we play with nIEN bit of disk. Do you see any reason why this should cause spurious interrupt? (system is using XT-PIC, FYI)
Thanks,
Petr Vandrovec [email protected]
Quoted 58 lines · Petr Vandrovec
Quoted 11 lines · I wrote:
Quoted 9 lines · Marcin Dalecki
Quoted 8 lines
Second problem is that read operation which ends with "drive ready, seek complete, data request" (why it happened in first place?) will just read one sector from drive (it was DMA transfer, so
drive->mult_count== 0), and then it returns fromata_errorwithATA_OP_CONTINUES. But what continues? Drive told us that current operation is done, and no new operation was started, so there is very low chance that some IRQ will ever come, and timer was just removed byata_irq_request(), so channel will never awake.Quoted 4 lines
Quoted 2 lines
What should continue is the retry of the operation, since otherwise it will be abondoned in
do_ide_request(). However I will recheck.It is UP machine (with SMP non-preemptible kernel). Stack trace does not look like that it was caused by some race.
There is something severely broken... I reenabled
ide: unexpected interrupt inata_irq_requestand to my surprise here we get one suprious interrupt for each request we do, on both channels - primary and secondary.It looked:
udma_pci_init: sending read command to driveata_irq_request: IRQ arrived, for us, calling handlerata_irq_request: handler returned 0
ide: unexpected interrupt 1 15 handler=00000000
callstack:ata_irq_request+ 7e/234,handle_IRQ_event+ 29/4c,do_IRQ + df/190, common_interrupt + 18/20, do_softirq + 50/ac, do_IRQ + 179/190, common_interrupt + 18/20
udma_pci_init: sending read command to driveata_irq_request: IRQ arrived, for us, calling handlerata_irq_request: handler returned 0
ide: unexpected interrupt 1 15 handler=00000000
callstack: same as aboveudma_pci_init: sending read command to driveata_irq_request: IRQ arrived, for us, calling handlerata_irq_request: handler returned 0udma_pci_init: sending read command to driveata_irq_request: command immediately queued bydo_ide_requestata_irq_request: IRQ arrived, for us, calling handler
oops:ide_dma_intr: udmastatus=00, diskstatus=58So we are getting one spurious interrupt for each UDMA request. Until we do not issue new command to the drive immediately, IRQ is silently ignored, and everybody is happy (?). But when we queue command immediately by call to
do_ide_requestinata_irq_request, sooner or later spurious interrupt will arrive with wrong timming, and we'll think that command is done while it is still in progress.I see same spurious interrupt problem on primary channel too, but somehow timming is different with UDMA100, and we always find command done instead of in progress when spurious interrupt happens.
Quoted 5 lines
Unfortunately ATA/ATAPIv7 says that single interrupt is triggered after command is done and all data transfered, and we do not play with select bit. But we play with nIEN bit of disk. Do you see any reason why this should cause spurious interrupt? (system is using XT-PIC, FYI)
What I actually try to do is to maintain the nIEN bit enabled the times we don't do any transfer to the disk in question. Precisely to prevent the disk from spewing IRQs at times when it should not. And yes this bit is acting in a reversed manner. But I'm sure you already know this.
You could of course try to make the ata_irq_enbale() function a no-op and see whatever this is changing anything.
(Me: Scratching my head with a puzzled expression on the face...;-)