Page 1 of 1
How to read 48 bit IDE registers
Posted: Sun Oct 15, 2017 6:43 pm
by maximus
I am using the following C code in Linux to attempt to read 48 bit IDE registers after a command. But I am not getting proper results for the high registers, only the low ones. The high registers seem to just be duplicate of the low registers, when I know the data to be be different. What am I doing wrong to read them? I can write high and low just fine.
error = inb(reg_base+1);
count_high = inb(reg_base+2);
lba_low_high = inb(reg_base+3);
lba_mid_high = inb(reg_base+4);
lba_high_high = inb(reg_base+5);
count_low = inb(reg_base+2);
lba_low_low = inb(reg_base+3);
lba_mid_low = inb(reg_base+4);
lba_high_low = inb(reg_base+5);
device = inb(reg_base+6);
status = inb(reg_base+7);
Re: How to read 48 bit IDE registers
Posted: Mon Oct 16, 2017 6:34 am
by jnc100
You need to set the high order bit (bit 7) of the device control register to 1 to read the high order bytes in command responses. This is not required when writing 48-bit LBAs. You also shouldn't need to reset it to zero again after reading the high order bytes as this is done for you on the next write to a command register.
I'm not sure how you obtain the IO address of the control registers on Linux, but once you have it, you would want to do something like:
Code: Select all
error = inb(reg_base+1);
count_low = inb(reg_base+2);
lba_low_low = inb(reg_base+3);
lba_mid_low = inb(reg_base+4);
lba_high_low = inb(reg_base+5);
outb(ctrl_base, 0x80);
count_high = inb(reg_base+2);
lba_low_high = inb(reg_base+3);
lba_mid_high = inb(reg_base+4);
lba_high_high = inb(reg_base+5);
device = inb(reg_base+6);
status = inb(reg_base+7);
Bear in mind that many commands do not return a sector count value. The setting of the device control register to 0x80 also has the side effect of enabling interrupts although these are probably already enabled anyway.
Regards,
John.
Re: How to read 48 bit IDE registers
Posted: Mon Oct 16, 2017 5:29 pm
by maximus
Wow, I can't believe I missed that. And I was just looking through the documentation on here where that is shown before I posted. Thank you very much, I was stumped.
As for interrupts, I do my best to keep them turned off for my purpose, so I am sending 0x02 to the control base address before the command, as bit 1 is supposed to tell the drive to suppress interrupts. I may want to send that again after setting the high order bit and reading the high order registers just to be safe. I also read the control base address (alt status) afterwards which I thought was also supposed to clear any interrupts. All of this is done with the drive (port) disabled from the Linux OS during boot so that it can be worked with without the OS interfering.
Thanks again very much
Re: How to read 48 bit IDE registers
Posted: Tue Oct 17, 2017 9:12 am
by Octocontrabass
maximus wrote:As for interrupts, I do my best to keep them turned off for my purpose, so I am sending 0x02 to the control base address before the command, as bit 1 is supposed to tell the drive to suppress interrupts.
In that case, you can send 0x82 to leave interrupts disabled while you're reading the high-order bytes.