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: Select all
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;
}
Code: Select all
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);
}
}
Code: Select all
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;
}