Page 1 of 1

How to distinguish IDE interrupts

Posted: Mon Mar 11, 2013 3:10 am
by Armin
Assume following (rather simple and common) situation:
There are two hard drives attached to one parallel ATA cable, i.e. drive 0 and drive 1 (or master and slave...). The ATA cable is attached to an IDE controller and it's assigned to one of the two IDE channels.

So, if one the drives generates an interrupt, how can I distinguish whether drive 0 or drive 1 generated the interrupt?

According to my understanding, IDE interrupts are assigned on a "per channel" basis.
So, for example if the PIC reports an IRQ14, that would mean that IDE channel 1 generated an interrupt. But that doesn't precisely tell me which drive at that channel generated the interrupt.

Thanks in advance.

Re: How to distinguish IDE interrupts

Posted: Mon Mar 11, 2013 3:57 am
by Combuster
This isn't as complicated as PCI interrupt sharing, but in this particular case:

- you know which drives have requests pending
- There's a thing called a status register.

Re: How to distinguish IDE interrupts

Posted: Mon Mar 11, 2013 5:05 am
by Armin
Thanks very much for your "hints". I already suspected the status register to be a key to my problem.

I assume, the solution to my problem is the combination of both issues that you mentioned in your post. Here's what I think how it may look like.

E.g. when the OS requests to read some sectors from a particular hard drive, it gets noticed about the completion of that operation by receiving an interrupt. Then, the OS looks into the status register and inspects the DRQ bit. If it's set, the OS knows that there is some data ready to be transferred from that particulary drive.

Provided, the above is correct, what about the following scenario? Again, there are two hard drives attached to one ATA bus...
1. request to read some sectors from drive 0
2. before the interrupt of this read request arrives, the OS requests to read some sectors from the second drive (drive 1)
3. finally an interrupt arrives...
4. Then again, the OS would check the status register and discover the DRQ bit to be set.
Now, the whole thing would not be deterministic.

Or is that scenario impossible because step 2 would fail as the ATA bus is occupied by step 1 (i.e. bit BSY is set in the status register)?

Regards

Re: How to distinguish IDE interrupts

Posted: Mon Mar 11, 2013 5:39 am
by Combuster
Assuming an ISA device, two consecutive IRQs would discard the latter. To fix that you'll have to acknowledge the interrupt and then check all possible causes:

Code: Select all

on_ata_irq:
    if (get_ata_status(DRV_MASTER) & DRQ_BIT)
        schedule_ata_transfer DRV_MASTER

    if (get_ata_status(DRV_SLAVE) & DRQ_BIT)
        schedule_ata_transfer DRV_SLAVE
And you can optimise out a bunch of I/Os by keeping track of the selected device and not polling the drives you know are idle.

Re: How to distinguish IDE interrupts

Posted: Mon Mar 11, 2013 8:43 am
by Owen
...This is really no different to any interrupt sharing scenario (i.e. you always need to check all devices which share an interrupt line which could potentially have interrupts pending)

With ISA interrupts in particular, because they're edge triggered you need to acknowledge the interrupt before you start to check all the devices otherwise an interrupt can get lost in between the time you check a device and re-enable the interrupt. This can cause "spurious" interrupts (i.e. an interrupt where there is no event to handle because you've already done it) but that's better than a device driver wedging because of a lost interrupt