ATA: write do not block forever

This commit is contained in:
Mathieu Maret 2021-11-03 23:00:20 +01:00
parent e94f87b798
commit afb622e17a
1 changed files with 18 additions and 3 deletions

View File

@ -536,6 +536,7 @@ int ATAReadSector(struct ata_device *dev, int lba, uint nb_sector, void *buf)
int ATAWriteSector(struct ata_device *dev, int lba, uint nb_sector, void *buf)
{
struct ata_controller *ctl = dev->ctl;
int ret = 0;
mutexLock(&ctl->mutex);
@ -561,7 +562,8 @@ int ATAWriteSector(struct ata_device *dev, int lba, uint nb_sector, void *buf)
printf("ATA write error\n");
return -1;
}
while (1) {
int retry = 100;
while (retry) {
int status = inb(ctl->base + ATA_PIO_STATUS);
if (status & ATA_PIO_STATUS_REG_ERR) {
mutexUnlock(&ctl->mutex);
@ -571,12 +573,19 @@ int ATAWriteSector(struct ata_device *dev, int lba, uint nb_sector, void *buf)
if ((status & ATA_PIO_STATUS_DRQ) &&
!(status & ATA_PIO_STATUS_DRIVE_BUSY))
break;
retry--;
}
if(retry == 0){
printf("ATA write timeout error\n");
ret=-1;
break;
}
for (uint i = 0; i < (DISK_SECTOR_SIZE / sizeof(uint16_t)); i++) {
outw(ctl->base + ATA_PIO_DATA, *ptr++);
}
retry = 1000;
// Wait for the device to receive the data
while (1) {
while (retry) {
int status = inb(ctl->base + ATA_PIO_STATUS);
if (status & ATA_PIO_STATUS_REG_ERR) {
mutexUnlock(&ctl->mutex);
@ -586,12 +595,18 @@ int ATAWriteSector(struct ata_device *dev, int lba, uint nb_sector, void *buf)
if (!(status & ATA_PIO_STATUS_DRQ) &&
!(status & ATA_PIO_STATUS_DRIVE_BUSY))
break;
retry --;
}
if(retry == 0){
printf("ATA write data timeout error\n");
ret=-1;
break;
}
}
mutexUnlock(&ctl->mutex);
return 0;
return ret;
}
struct ata_device *ATAGetDevice(int ctlId, int devId)