It's my code for detection drives:
Code: Select all
int ata_device_detect(ata_device_t *dev) {
ata_soft_reset(dev);
ata_io_wait(dev);
io_writePort(dev->base+ATA_REG_HDDEVSEL,0xA0 | dev->slave << 4);
ata_io_wait(dev);
ata_status_wait(dev,10000);
unsigned char cl = io_readPort(dev->base + ATA_REG_LBA1);
unsigned char ch = io_readPort(dev->base + ATA_REG_LBA2);
if (ch == 0xff && ch == 0xff) {
return 0;
}
if ((cl == 0x00 && ch == 0x00) || (cl == 0x3c && ch == 0xc3)) {
ata_device_init(dev);
int sectors = ata_max_offset(dev);
if (sectors == 0) {
// ATA must have at less 1 sector(512B)
printf("ATA: device sectors are zero!\n");
return 0;
}
printf("ATA: detected drive with %x size! CL: %x, CH: %x\n",sectors,cl,ch);
}
return 0;
}
void ata_device_init(ata_device_t *dev) {
io_writePort(dev->base+1,1);
io_writePort(dev->ctrl,0);
io_writePort(dev->base+ATA_REG_HDDEVSEL, 0xA0 | dev->slave << 4);
ata_io_wait(dev);
io_writePort(dev->base+ATA_REG_COMMAND,ATA_CMD_IDENTIFY);
ata_io_wait(dev);
io_readPort(dev->base+ATA_REG_COMMAND);
ata_wait(dev,0);
uint16_t *buf = (uint16_t *)&dev->identify;
for (int i = 0; i < 256; i++) {
buf[i] = io_readPortW(dev->base);
}
uint8_t *ptr = (uint8_t *)&dev->identify.model;
for (int i = 0; i < 39; i+=2) {
uint8_t tmp = ptr[i+1];
ptr[i+1] = ptr[i];
ptr[i] = tmp;
}
}