ATA not firing IRQ
Posted: Sat May 28, 2016 7:38 am
Hi,
I am having a problem trying to make an ATA disk fire an interrupt.
I can detect all the disks and extract fw, model, serial, and disk size correctly.
When I try to write to one of the attached detected disks the interrupt does not fire. Here is the code that I expect to fire the interrupt:
I expect that at the end of the above code an interrupt fires.
The IVT handler for the primary and the secondary (14 and 15) is called once at the time I identify the disks and then no interrupts fires again.
A copy of the same interrupt handler works fine wit my network driver (E1000) and send EOI at the end of the ATA interrupt as well. I also read the status register at the end of the interrupt.
Also it is worth mentioning that I have tried this code from with and system call so it occurs within an interrupt, and from the main body of my kernel avoiding executing the code from within an interrupt.
Any ideas what might be the problem?
Thanks.
Karim.
I am having a problem trying to make an ATA disk fire an interrupt.
I can detect all the disks and extract fw, model, serial, and disk size correctly.
When I try to write to one of the attached detected disks the interrupt does not fire. Here is the code that I expect to fire the interrupt:
Code: Select all
// io_port = 0xf0
// drv_selector = 0xB0
// ATA_PRIMARY_DCR_AS = 0x3F6
// addr is the sector number and I use the value 100.
Ports::outportb(io_port + ATA_REG_HDDEVSEL,drv_selector); // select disk
Ports::outportb(ATA_PRIMARY_DCR_AS,0b00001000); // clearing nIEN bit
Ports::outportb(io_port + 1, 0x00);
Ports::outportb(io_port + 2, 0x01);
Ports::outportb(io_port + 3, (uint8_t)addr);
Ports::outportb(io_port + 4, (uint8_t)(addr >> 8));
Ports::outportb(io_port + 5, (uint8_t)(addr >> 16));
Ports::outportb(io_port + 6, 0xE0+slavebit | (slavebit << 4) | ((addr >> 24) & 0x0F));
Ports::outportb(io_port + 7, 0x30);
The IVT handler for the primary and the secondary (14 and 15) is called once at the time I identify the disks and then no interrupts fires again.
A copy of the same interrupt handler works fine wit my network driver (E1000) and send EOI at the end of the ATA interrupt as well. I also read the status register at the end of the interrupt.
Also it is worth mentioning that I have tried this code from with and system call so it occurs within an interrupt, and from the main body of my kernel avoiding executing the code from within an interrupt.
Any ideas what might be the problem?
Thanks.
Karim.