Handle disk partitioning
This commit is contained in:
@ -121,7 +121,7 @@ void ata_probe(void) {
|
||||
.iobase = 0x1F0,
|
||||
.ctrlbase = 0x3F6,
|
||||
};
|
||||
storedev_create(STOREDEV_ATASD, (void *)&extra);
|
||||
storedev_create(STOREDEV_ATASD, "atasd-ch0-M", (void *)&extra);
|
||||
}
|
||||
|
||||
probesize = ata_probesize_bytes(0x1F0, 0x3F6, ATA_SLAVE);
|
||||
@ -135,7 +135,7 @@ void ata_probe(void) {
|
||||
.iobase = 0x1F0,
|
||||
.ctrlbase = 0x3F6,
|
||||
};
|
||||
storedev_create(STOREDEV_ATASD, (void *)&extra);
|
||||
storedev_create(STOREDEV_ATASD, "atasd-ch0-S", (void *)&extra);
|
||||
}
|
||||
|
||||
probesize = ata_probesize_bytes(0x170, 0x376, ATA_MASTER);
|
||||
@ -149,7 +149,7 @@ void ata_probe(void) {
|
||||
.iobase = 0x170,
|
||||
.ctrlbase = 0x376,
|
||||
};
|
||||
storedev_create(STOREDEV_ATASD, (void *)&extra);
|
||||
storedev_create(STOREDEV_ATASD, "atasd-ch1-M", (void *)&extra);
|
||||
}
|
||||
|
||||
probesize = ata_probesize_bytes(0x170, 0x376, ATA_SLAVE);
|
||||
@ -163,7 +163,7 @@ void ata_probe(void) {
|
||||
.iobase = 0x170,
|
||||
.ctrlbase = 0x376,
|
||||
};
|
||||
storedev_create(STOREDEV_ATASD, (void *)&extra);
|
||||
storedev_create(STOREDEV_ATASD, "atasd-ch1-S", (void *)&extra);
|
||||
}
|
||||
}
|
||||
|
||||
@ -185,6 +185,51 @@ void ata_setup(uint16_t iobase, uint16_t ctrlbase, int devno, uint16_t sectors,
|
||||
|
||||
}
|
||||
|
||||
int32_t ata_read(uint16_t iobase, uint16_t ctrlbase, int devno,
|
||||
uint64_t sectorsize, uint8_t *const buffer,
|
||||
ptrdiff_t sector, ptrdiff_t off, size_t size) {
|
||||
int32_t ret = E_OK;
|
||||
|
||||
uint64_t lba = (uint64_t)(sector * (ptrdiff_t)sectorsize + off) / sectorsize;
|
||||
size_t sectors = size / sectorsize;
|
||||
if (size % sectorsize) sectors++;
|
||||
|
||||
ata_setup(iobase, ctrlbase, devno, sectors, lba);
|
||||
io_out8(iobase + ATA_REG_COMMAND, ATA_CMD_READ_PIO_EXT);
|
||||
|
||||
for (size_t s = 0; s < sectors; s++) {
|
||||
if (ata_wait(iobase, 100000, true, 1) < 0) { ret = E_BADIO; goto done; }
|
||||
io_ins16(iobase + ATA_REG_DATA, (uint16_t *)(buffer + s * sectorsize), sectorsize / 2);
|
||||
}
|
||||
|
||||
done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t ata_write(uint16_t iobase, uint16_t ctrlbase, int devno,
|
||||
uint64_t sectorsize, const uint8_t *const buffer,
|
||||
ptrdiff_t sector, ptrdiff_t off, size_t size) {
|
||||
int32_t ret = E_OK;
|
||||
|
||||
uint64_t lba = (uint64_t)(sector * (ptrdiff_t)sectorsize + off) / sectorsize;
|
||||
size_t sectors = size / sectorsize;
|
||||
if (size % sectorsize) sectors++;
|
||||
|
||||
ata_setup(iobase, ctrlbase, devno, sectors, lba);
|
||||
io_out8(iobase + ATA_REG_COMMAND, ATA_CMD_WRITE_PIO_EXT);
|
||||
|
||||
for (size_t s = 0; s < sectors; s++) {
|
||||
if (ata_wait(iobase, 100000, true, 1) < 0) { ret = E_BADIO; goto done; }
|
||||
io_outs16(iobase + ATA_REG_DATA, (uint16_t *)(buffer + s * sectorsize), sectorsize / 2);
|
||||
}
|
||||
|
||||
io_out8(iobase + ATA_REG_COMMAND, ATA_CMD_CACHE_FLUSH_EXT);
|
||||
if (ata_wait(iobase, 100000, false, 1) < 0) { ret = E_BADIO; goto done; }
|
||||
|
||||
done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t atasd_init(struct StoreDev *sd, void *extra) {
|
||||
AtaSdInitExtra *e = (AtaSdInitExtra *)extra;
|
||||
sd->sd.atasd.devno = e->devno;
|
||||
@ -200,21 +245,9 @@ int32_t atasd_read(struct StoreDev *sd, uint8_t *const buffer, ptrdiff_t sector,
|
||||
|
||||
AtaSd *ata = &sd->sd.atasd;
|
||||
|
||||
uint64_t lba = (uint64_t)(sector * (ptrdiff_t)sd->sectorsize + off) / (uint64_t)STOREDEV_ATASD_SECTORSIZE;
|
||||
size_t sectors = size / STOREDEV_ATASD_SECTORSIZE;
|
||||
if (size % STOREDEV_ATASD_SECTORSIZE) sectors++;
|
||||
ret = ata_read(ata->iobase, ata->ctrlbase, ata->devno,
|
||||
sd->sectorsize, buffer, sector, off, size);
|
||||
|
||||
ata_setup(ata->iobase, ata->ctrlbase, ata->devno, sectors, lba);
|
||||
io_out8(ata->iobase + ATA_REG_COMMAND, ATA_CMD_READ_PIO_EXT);
|
||||
|
||||
for (size_t s = 0; s < sectors; s++) {
|
||||
if (ata_wait(ata->iobase, 100000, true, 1) < 0) { ret = E_BADIO; goto done; }
|
||||
io_ins16(ata->iobase + ATA_REG_DATA, (uint16_t *)(buffer + s * STOREDEV_ATASD_SECTORSIZE), STOREDEV_ATASD_SECTORSIZE/2);
|
||||
}
|
||||
|
||||
ret = E_OK;
|
||||
|
||||
done:
|
||||
spinlock_release(&sd->spinlock);
|
||||
return ret;
|
||||
}
|
||||
@ -225,24 +258,9 @@ int32_t atasd_write(struct StoreDev *sd, const uint8_t *const buffer, ptrdiff_t
|
||||
|
||||
AtaSd *ata = &sd->sd.atasd;
|
||||
|
||||
uint64_t lba = (uint64_t)(sector * (ptrdiff_t)sd->sectorsize + off) / (uint64_t)STOREDEV_ATASD_SECTORSIZE;
|
||||
size_t sectors = size / STOREDEV_ATASD_SECTORSIZE;
|
||||
if (size % STOREDEV_ATASD_SECTORSIZE) sectors++;
|
||||
|
||||
ata_setup(ata->iobase, ata->ctrlbase, ata->devno, sectors, lba);
|
||||
io_out8(ata->iobase + ATA_REG_COMMAND, ATA_CMD_WRITE_PIO_EXT);
|
||||
|
||||
for (size_t s = 0; s < sectors; s++) {
|
||||
if (ata_wait(ata->iobase, 100000, true, 1) < 0) { ret = E_BADIO; goto done; }
|
||||
io_outs16(ata->iobase + ATA_REG_DATA, (uint16_t *)(buffer + s * STOREDEV_ATASD_SECTORSIZE), STOREDEV_ATASD_SECTORSIZE/2);
|
||||
}
|
||||
|
||||
io_out8(ata->iobase + ATA_REG_COMMAND, ATA_CMD_CACHE_FLUSH_EXT);
|
||||
if (ata_wait(ata->iobase, 100000, false, 1) < 0) { ret = E_BADIO; goto done; }
|
||||
|
||||
ret = E_OK;
|
||||
ret = ata_write(ata->iobase, ata->ctrlbase, ata->devno,
|
||||
sd->sectorsize, buffer, sector, off, size);
|
||||
|
||||
done:
|
||||
spinlock_release(&sd->spinlock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user