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

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