I have strange problem. My PIO driver sometimes read values and sometimes not.
Code: Select all
int ata_pio28(uint16_t base, uint8_t type, uint64_t addr) {
int cycle=0;
//PIO28
outb(base+ATA_PORT_FEATURES, 0x00);
outb(base+ATA_PORT_SCT_COUNT, 0x01);
outb(base+ATA_PORT_SCT_NUMBER, (unsigned char)addr);
outb(base+ATA_PORT_CYL_LOW, (unsigned char)(addr >> 8));
outb(base+ATA_PORT_CYL_HIGH, (unsigned char)(addr >> 16));
//type
if(type==ATA_READ) {
outb(base+ATA_PORT_COMMAND, 0x20); // Send command
}
else {
outb(base+ATA_PORT_COMMAND, 0x30);
}
//wait for BSY clear and DRQ set
cycle=0;
for(int i=0; i<1000; i++) {
inb(base+ATA_PORT_ALT_STATUS); //wait
if( (inb(base+ATA_PORT_ALT_STATUS) & 0x88)==0x08 ) { //drq is set
cycle=1;
break;
}
}
if(cycle==0) { //Something is wrong
if( (inb(base+ATA_PORT_ALT_STATUS) & 0x01)==0x01 ) { //bad block
system_ata_pio_error();
}
return 0;
}
if( (inb(base+ATA_PORT_ALT_STATUS) & 0x01)==0x01 ) { //bad block
system_ata_pio_error();
}
for (int idx = 0; idx < 256; idx++)
{
if(type==ATA_READ) {
ata_buffer[idx] = inw(base + ATA_PORT_DATA);
}
else {
outw(base + ATA_PORT_DATA, ata_buffer[idx]);
}
}
return 1;
}
Code: Select all
void irq14_handler(void) {
outb(0xA0, 0x20);
outb(0x20, 0x20); //EOI
//acknowledge interrupt
inb(0x1F7);
}