ATAPI PIO: Do not prematurely terminate the command if bytes are left to be transferred but all sectors have already been read into the buffer, fixes FreeBSD CD-ROM boot on some machines.

This commit is contained in:
OBattler
2025-03-17 16:54:41 +01:00
parent 49463607c1
commit 277273c05d

View File

@@ -1197,7 +1197,8 @@ ide_atapi_callback(ide_t *ide)
static void static void
ide_atapi_pio_request(ide_t *ide, uint8_t out) ide_atapi_pio_request(ide_t *ide, uint8_t out)
{ {
scsi_common_t *dev = ide->sc; scsi_common_t *dev = ide->sc;
int left = 0;
ide_irq_lower(ide); ide_irq_lower(ide);
@@ -1221,6 +1222,8 @@ ide_atapi_pio_request(ide_t *ide, uint8_t out)
ide_log("%i bytes %s, %i bytes are still left\n", ide->tf->pos, ide_log("%i bytes %s, %i bytes are still left\n", ide->tf->pos,
out ? "written" : "read", dev->packet_len - ide->tf->pos); out ? "written" : "read", dev->packet_len - ide->tf->pos);
left = 1;
/* /*
If less than (packet length) bytes are remaining, update packet length If less than (packet length) bytes are remaining, update packet length
accordingly. accordingly.
@@ -1252,23 +1255,33 @@ ide_atapi_pio_request(ide_t *ide, uint8_t out)
ide->write(dev); ide->write(dev);
if (dev->sector_len == 0) { if (dev->sector_len == 0) {
ide->sc->packet_status = PHASE_COMPLETE; if (left) {
ide->sc->callback = 0.0; ide_atapi_callback(ide);
ide_set_callback(ide, 0.0);
} else {
ide->sc->packet_status = PHASE_COMPLETE;
ide->sc->callback = 0.0;
if (ide->phase_data_out != NULL) if (ide->phase_data_out != NULL)
(void) ide->phase_data_out(dev); (void) ide->phase_data_out(dev);
ide_atapi_callback(ide); ide_atapi_callback(ide);
}
} }
} else { } else {
if (dev->sector_len == 0) { if (dev->sector_len == 0) {
if (ide->command_stop != NULL) if (left) {
ide->command_stop(dev); ide_atapi_callback(ide);
ide_set_callback(ide, 0.0);
} else {
if (ide->command_stop != NULL)
ide->command_stop(dev);
ide->sc->packet_status = PHASE_COMPLETE; ide->sc->packet_status = PHASE_COMPLETE;
ide->sc->callback = 0.0; ide->sc->callback = 0.0;
ide_atapi_callback(ide); ide_atapi_callback(ide);
}
} else if (ide->read != NULL) } else if (ide->read != NULL)
ide->read(dev); ide->read(dev);
} }