SCSI CD-ROM/Disk/MO/ZIP: Treat data commands with request length 0 in ATAPI PIO mode as non-data commands, also allow WIN_SRST to go through BSY, fixes the regressions introduced in build 6731 reported by JVERNET.
This commit is contained in:
@@ -1208,7 +1208,9 @@ ide_atapi_pio_request(ide_t *ide, uint8_t out)
|
||||
ide->tf->atastat = BSY_STAT;
|
||||
|
||||
if (ide->tf->pos >= dev->packet_len) {
|
||||
ide_log("%i bytes %s, command done\n", ide->tf->pos, out ? "written" : "read");
|
||||
// ide_log("%i bytes %s, command done\n", ide->tf->pos, out ? "written" : "read");
|
||||
ide_log("%i bytes %s, command done, %i sectors left\n", ide->tf->pos, out ? "written" : "read",
|
||||
dev->sector_len);
|
||||
|
||||
ide->tf->pos = dev->request_pos = 0;
|
||||
|
||||
@@ -1262,13 +1264,12 @@ ide_atapi_pio_request(ide_t *ide, uint8_t out)
|
||||
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)
|
||||
(void) ide->phase_data_out(dev);
|
||||
|
||||
ide_atapi_callback(ide);
|
||||
if ((ide->sc->packet_status == PHASE_COMPLETE) &&
|
||||
(ide->sc->callback == 0.0))
|
||||
ide_atapi_callback(ide);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -1280,10 +1281,9 @@ ide_atapi_pio_request(ide_t *ide, uint8_t out)
|
||||
if (ide->command_stop != NULL)
|
||||
ide->command_stop(dev);
|
||||
|
||||
ide->sc->packet_status = PHASE_COMPLETE;
|
||||
ide->sc->callback = 0.0;
|
||||
|
||||
ide_atapi_callback(ide);
|
||||
if ((ide->sc->packet_status == PHASE_COMPLETE) &&
|
||||
(ide->sc->callback == 0.0))
|
||||
ide_atapi_callback(ide);
|
||||
}
|
||||
} else if (ide->read != NULL)
|
||||
ide->read(dev);
|
||||
@@ -1299,8 +1299,8 @@ ide_atapi_packet_read(ide_t *ide)
|
||||
uint16_t ret = 0;
|
||||
|
||||
if (dev && dev->temp_buffer && (dev->packet_status == PHASE_DATA_IN)) {
|
||||
ide_log("PHASE_DATA_IN read: %i, %i, %i, %i\n",
|
||||
dev->request_pos, dev->max_transfer_len, ide->tf->pos, dev->packet_len);
|
||||
/* ide_log("PHASE_DATA_IN read: %i, %i, %i, %i\n",
|
||||
dev->request_pos, dev->max_transfer_len, ide->tf->pos, dev->packet_len); */
|
||||
|
||||
bufferw = (uint16_t *) dev->temp_buffer;
|
||||
|
||||
@@ -1722,7 +1722,8 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv)
|
||||
break;
|
||||
|
||||
case 0x7: /* Command register */
|
||||
if (ide->tf->atastat & (BSY_STAT | DRQ_STAT))
|
||||
if ((ide->tf->atastat & (BSY_STAT | DRQ_STAT)) &&
|
||||
((val != WIN_SRST) || (ide->type != IDE_ATAPI)))
|
||||
break;
|
||||
|
||||
if ((ide->type == IDE_NONE) || ((ide->type & IDE_SHADOW) && (val != WIN_DRIVE_DIAGNOSTICS)))
|
||||
@@ -2158,7 +2159,8 @@ ide_read_alt_status(UNUSED(const uint16_t addr), void *priv)
|
||||
if (!(addr & 0x0001))
|
||||
ret = ide_status(ide, ide_drives[ch ^ 1], ch);
|
||||
|
||||
ide_log("[%04X:%08X] ide_read_alt_status(%04X, %08X) = %02X\n", CS, cpu_state.pc, addr, priv, ret);
|
||||
// ide_log("[%04X:%08X] ide_read_alt_status(%04X, %08X) = %02X\n", CS, cpu_state.pc, addr, priv, ret);
|
||||
// ide_log("ide_read_alt_status(%04X, %08X) = %02X\n", CS, cpu_state.pc, addr, priv, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -3159,6 +3161,13 @@ ide_init(const device_t *info)
|
||||
ide_board_init(1, HDC_SECONDARY_IRQ, HDC_SECONDARY_BASE, HDC_SECONDARY_SIDE, info->local, info->flags);
|
||||
break;
|
||||
|
||||
case 8 ... 0x0d:
|
||||
ide_board_init(2, -1, 0, 0, info->local, info->flags);
|
||||
|
||||
if (info->local & 1)
|
||||
ide_board_init(3, -1, 0, 0, info->local, info->flags);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -3540,7 +3549,7 @@ const device_t mcide_device = {
|
||||
.name = "MCA McIDE Controller",
|
||||
.internal_name = "ide_mcide",
|
||||
.flags = DEVICE_MCA,
|
||||
.local = 3,
|
||||
.local = 1,
|
||||
.init = mcide_init,
|
||||
.close = mcide_close,
|
||||
.reset = mcide_reset,
|
||||
@@ -3661,3 +3670,17 @@ const device_t ide_qua_pnp_device = {
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t ide_pci_ter_qua_2ch_device = {
|
||||
.name = "PCI IDE Controller (Dual-Channel Tertiary/Quaternary)",
|
||||
.internal_name = "ide_pci_ter_qua_2ch",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0x0d,
|
||||
.init = ide_init,
|
||||
.close = ide_close,
|
||||
.reset = ide_reset,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
@@ -584,7 +584,10 @@ mo_data_command_finish(mo_t *dev, int len, const int block_len,
|
||||
mo_command_write_dma(dev);
|
||||
} else {
|
||||
mo_update_request_length(dev, len, block_len);
|
||||
if (direction == 0)
|
||||
if ((dev->drv->bus_type != MO_BUS_SCSI) &&
|
||||
(dev->tf->request_length == 0))
|
||||
mo_command_complete(dev);
|
||||
else if (direction == 0)
|
||||
mo_command_read(dev);
|
||||
else
|
||||
mo_command_write(dev);
|
||||
|
||||
@@ -665,7 +665,10 @@ zip_data_command_finish(zip_t *dev, int len, const int block_len,
|
||||
zip_command_write_dma(dev);
|
||||
} else {
|
||||
zip_update_request_length(dev, len, block_len);
|
||||
if (direction == 0)
|
||||
if ((dev->drv->bus_type != ZIP_BUS_SCSI) &&
|
||||
(dev->tf->request_length == 0))
|
||||
zip_command_complete(dev);
|
||||
else if (direction == 0)
|
||||
zip_command_read(dev);
|
||||
else
|
||||
zip_command_write(dev);
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
#include <inttypes.h>
|
||||
#include <math.h>
|
||||
#define ENABLE_SCSI_CDROM_LOG 2
|
||||
#ifdef ENABLE_SCSI_CDROM_LOG
|
||||
#include <stdarg.h>
|
||||
#endif
|
||||
@@ -689,6 +690,7 @@ scsi_cdrom_set_period(scsi_cdrom_t *dev)
|
||||
bytes_per_second *= (double) dev->drv->cur_speed;
|
||||
} else {
|
||||
bytes_per_second = scsi_cdrom_bus_speed(dev);
|
||||
pclog("%lf bytes per second\n", bytes_per_second);
|
||||
if (bytes_per_second == 0.0) {
|
||||
dev->callback = -1; /* Speed depends on SCSI controller */
|
||||
return;
|
||||
@@ -698,19 +700,24 @@ scsi_cdrom_set_period(scsi_cdrom_t *dev)
|
||||
period = 1000000.0 / bytes_per_second;
|
||||
scsi_cdrom_log(dev->log, "Byte transfer period: %" PRIu64 " us\n",
|
||||
(uint64_t) period);
|
||||
pclog("Byte transfer period: %lf us (%i bytes)\n", period, dev->packet_len);
|
||||
if (dev->was_cached == -1)
|
||||
period *= (double) dev->packet_len;
|
||||
else {
|
||||
int atapi_num = (dev->tf->request_length < dev->block_len) ?
|
||||
dev->block_len : dev->tf->request_length;
|
||||
atapi_num = (atapi_num / dev->block_len) * dev->block_len;
|
||||
if (atapi_num > dev->sector_len)
|
||||
atapi_num = dev->sector_len;
|
||||
const int num = ((dev->drv->bus_type == CDROM_BUS_SCSI) ||
|
||||
(dev->block_len == 0)) ?
|
||||
dev->requested_blocks :
|
||||
((scsi_cdrom_current_mode(dev) == 2) ? 1 :
|
||||
(dev->packet_len / dev->block_len));
|
||||
(dev->block_len == 0)) ? dev->requested_blocks :
|
||||
((scsi_cdrom_current_mode(dev) == 2) ? 1 : atapi_num);
|
||||
|
||||
period *= ((double) num) * 2352.0;
|
||||
}
|
||||
scsi_cdrom_log(dev->log, "Sector transfer period: %" PRIu64 " us\n",
|
||||
(uint64_t) period);
|
||||
pclog("Data transfer period: %lf us\n", period);
|
||||
dev->callback += period;
|
||||
}
|
||||
scsi_cdrom_set_callback(dev);
|
||||
@@ -800,7 +807,10 @@ scsi_cdrom_data_command_finish(scsi_cdrom_t *dev, int len, int block_len, int al
|
||||
scsi_cdrom_command_write_dma(dev);
|
||||
} else {
|
||||
scsi_cdrom_update_request_length(dev, len, block_len);
|
||||
if (direction == 0)
|
||||
if ((dev->drv->bus_type != CDROM_BUS_SCSI) &&
|
||||
(dev->tf->request_length == 0))
|
||||
scsi_cdrom_command_complete(dev);
|
||||
else if (direction == 0)
|
||||
scsi_cdrom_command_read(dev);
|
||||
else
|
||||
scsi_cdrom_command_write(dev);
|
||||
|
||||
@@ -570,7 +570,10 @@ scsi_disk_data_command_finish(scsi_disk_t *dev, int len, const int block_len,
|
||||
scsi_disk_command_write_dma(dev);
|
||||
} else {
|
||||
scsi_disk_update_request_length(dev, len, block_len);
|
||||
if (direction == 0)
|
||||
if ((dev->drv->bus_type != HDD_BUS_SCSI) &&
|
||||
(dev->tf->request_length == 0))
|
||||
scsi_disk_command_complete(dev);
|
||||
else if (direction == 0)
|
||||
scsi_disk_command_read(dev);
|
||||
else
|
||||
scsi_disk_command_write(dev);
|
||||
|
||||
Reference in New Issue
Block a user