atapi: Add timeout checks to resolve boot failures in newer QEMUs

This commit is contained in:
K. Lange 2021-05-31 09:24:06 +09:00
parent 2769081f71
commit 229c4f9631
2 changed files with 16 additions and 0 deletions

View File

@ -90,9 +90,11 @@ static void atapi_device_init(struct ata_device * dev) {
outportb(bus + ATA_REG_COMMAND, ATA_CMD_PACKET);
/* poll */
int timeout = 100;
while (1) {
uint8_t status = inportb(dev->io_base + ATA_REG_STATUS);
if ((status & ATA_SR_ERR)) goto atapi_error;
if (timeout-- < 0) goto atapi_timeout;
if (!(status & ATA_SR_BSY) && (status & ATA_SR_DRDY)) break;
}
@ -101,9 +103,11 @@ static void atapi_device_init(struct ata_device * dev) {
}
/* poll */
timeout = 100;
while (1) {
uint8_t status = inportb(dev->io_base + ATA_REG_STATUS);
if ((status & ATA_SR_ERR)) goto atapi_error_read;
if (timeout-- < 0) goto atapi_timeout;
if (!(status & ATA_SR_BSY) && (status & ATA_SR_DRDY)) break;
if ((status & ATA_SR_DRQ)) break;
}
@ -131,8 +135,13 @@ atapi_error_read:
return;
atapi_error:
dev->is_atapi = 0;
print_("ATAPI error.\n");
return;
atapi_timeout:
dev->is_atapi = 0;
return;
}
static int ata_device_detect(struct ata_device * dev) {

View File

@ -521,9 +521,11 @@ static int atapi_device_init(struct ata_device * dev) {
outportb(bus + ATA_REG_COMMAND, ATA_CMD_PACKET);
/* poll */
int timeout = 100;
while (1) {
uint8_t status = inportb(dev->io_base + ATA_REG_STATUS);
if ((status & ATA_SR_ERR)) goto atapi_error;
if (timeout-- < 100) goto atapi_timeout;
if (!(status & ATA_SR_BSY) && (status & ATA_SR_DRDY)) break;
}
@ -532,9 +534,11 @@ static int atapi_device_init(struct ata_device * dev) {
}
/* poll */
timeout = 100;
while (1) {
uint8_t status = inportb(dev->io_base + ATA_REG_STATUS);
if ((status & ATA_SR_ERR)) goto atapi_error_read;
if (timeout-- < 100) goto atapi_timeout;
if (!(status & ATA_SR_BSY) && (status & ATA_SR_DRDY)) break;
if ((status & ATA_SR_DRQ)) break;
}
@ -568,6 +572,9 @@ atapi_error:
debug_print(ERROR, "ATAPI early error; unsure");
return 1;
atapi_timeout:
debug_print(ERROR, "ATAPI device timeout, ignoring.");
return 1;
}
static int ata_device_detect(struct ata_device * dev) {