Code:
outb(base_port + 6, 0xA0); //master
There may be two devices attached to an IDE channel; you're only checking one of them.
Code:
uint8_t c = insb(base_port + 7);
Are you using "inb" or "insb" here? They are not the same thing.
Code:
while(!(c & 0x08) || !(c & 0x01));
I'm pretty sure you wanted to use "&&" instead of "||" here. Also, if the error bit is set, you can't read the identify data from the disk.
Code:
*ptr = insw(base_port);
Are you using "inw" or "insw" here? They are not the same thing.
Code:
for(uint16_t i = 0x400; i < 0xFFFF; i += 8)
if(ata_identify(i))
Use PCI to find the addresses of IDE controllers, don't probe for them like this. (Unless you want to use IDE on an ancient PC that doesn't support PCI - then you can assume the IDE controller uses 0x1F0.)