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:
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user