Hello,
I'm having a problem with an ATA LBA48 read funtion. Can you help me solve the issue? Here is the funtion I wrote:
Code:
static int ATA_read48_pio(ATADevice *device, uint32_t LBA, unsigned int count, uint8_t *buffer){
int ch = device->channel;
int dr = device->drive;
outw(channels[ch].base + ATA_REG_HDDEVSEL, (uint8_t []){0x40, 0x50}[dr]);
io_wait();
outb(channels[ch].base + ATA_REG_ERROR, 0); // Supposedly it's useless
io_wait();
outb(channels[ch].base + ATA_REG_SECCOUNT0, (uint8_t)(count >> 8)); // high sector count byte
io_wait();
outb(channels[ch].base + ATA_REG_LBAlo, (uint8_t)(LBA >> 24));
io_wait();
outb(channels[ch].base + ATA_REG_LBAmid, 0);
io_wait();
outb(channels[ch].base + ATA_REG_LBAhi, 0);
io_wait();
outb(channels[ch].base + ATA_REG_SECCOUNT0, (uint8_t)(count)); // low sector count byte
io_wait();
outb(channels[ch].base + ATA_REG_LBAlo, (uint8_t)LBA);
io_wait();
outb(channels[ch].base + ATA_REG_LBAmid, (uint8_t)(LBA >> 8));
io_wait();
outb(channels[ch].base + ATA_REG_LBAhi, (uint8_t)(LBA >> 16));
io_wait();
outb(channels[ch].base + ATA_REG_COMMAND, (uint8_t)(ATA_CMD_READ_PIO_EXT));
long_wait();
for(int i=0; i<count; i++){
int ret = poll_channel(ch);
if(ret) // Error code 1: Device not responding!, Error code 2: Unexpected error occured!
return ret;
insw(channels[ch].base + ATA_REG_DATA, (uint16_t *)(buffer + i*512), 256);
}
long_wait();
return 0;
}
For some reason I'm getting an "Aborted command" error on bochs. It works on quemu though. The bochs drive should support LBA48 because I'm making sure it does before deciding wheather to use LBA28 or LBA48 like so:
Code:
int ATA_read_pio(ATADevice *device, uint32_t LBA, unsigned int count, uint8_t *buffer){
if(!device->exists)
return 3; // Error code 3: Device does not exist
if(device->commandSets & (1 << 26)){ // Device uses 48-Bit Addressing
terminal_print(debugTerminal, "[DEBUG] LBA48\n");
if((LBA + count > device->size) || count > 0xFFFF)
return 4; // Error code 4: Inapropriate LBA and count
return ATA_read48_pio(device, LBA, count, buffer);
}
else{
terminal_print(debugTerminal, "[DEBUG] LBA28\n");
if((LBA + count > device->size) || LBA > 0xfffffff || count > 0xFF)
return 4; // Error code 4: Inapropriate LBA and count
return ATA_read28_pio(device, LBA, count, buffer);
}
}
If you think the problem may lay in polling function here it is:
Code:
static int poll_channel(int channel){
uint8_t error = 0;
uint8_t status = 0xff;
int counter = 0;
while((status & ATA_SR_BSY) && counter < 10000){
status = inb(channels[channel].base + ATA_REG_STATUS);
counter++;
}
if(counter >= 10000)
return 1; // Error code 1: Device not responding!
counter = 0;
while(!(status & ATA_SR_DRQ) && counter < 10000){
status = inb(channels[channel].base + ATA_REG_STATUS);
if(status & ATA_SR_ERR){
error = inb(channels[channel].base + ATA_REG_ERROR);
break;
}
counter++;
}
if(counter >= 10000)
return 1; // Error code 1: Device not responding!
if(error){
print_error(error);
soft_reset(channel);
return 2; // Error code 2: Unexpected error ocured
}
return 0;
}