From 9a49a75eaf599e667d5fd38c4a0cf28c96c12889 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 14 Apr 2019 13:47:20 +0100 Subject: [PATCH] IDE soft reset should also reset ATAPI devices. Should fix at least some 'Device failed to request command' errors. --- src/ide.c | 2 ++ src/ide_atapi.c | 10 ++++++++++ src/ide_atapi.h | 1 + src/scsi.c | 18 ++++++++++++++++++ src/scsi.h | 2 ++ src/scsi_cd.c | 9 +++++++++ src/scsi_hd.c | 1 + src/scsi_zip.c | 9 +++++++++ 8 files changed, 52 insertions(+) diff --git a/src/ide.c b/src/ide.c index 0cbad14..4e8d5ef 100644 --- a/src/ide.c +++ b/src/ide.c @@ -819,6 +819,7 @@ void callbackide(int ide_board) { ide->cylinder=0xEB14; atapi->stop(); + atapi_reset(&ide->atapi); } if (ide->type == IDE_NONE) { @@ -829,6 +830,7 @@ void callbackide(int ide_board) { ide_other->cylinder=0xEB14; atapi->stop(); + atapi_reset(&ide_other->atapi); } if (ide_other->type == IDE_NONE) { diff --git a/src/ide_atapi.c b/src/ide_atapi.c index 78a648b..0324e9c 100644 --- a/src/ide_atapi.c +++ b/src/ide_atapi.c @@ -563,3 +563,13 @@ void atapi_process_packet(atapi_device_t *atapi_dev) break; } } + +void atapi_reset(atapi_device_t *atapi_dev) +{ + pclog("atapi_reset\n"); + atapi_dev->state = ATAPI_STATE_IDLE; + atapi_dev->command_pos = 0; + atapi_dev->data_read_pos = 0; + atapi_dev->data_write_pos = 0; + scsi_bus_reset(&atapi_dev->bus); +} diff --git a/src/ide_atapi.h b/src/ide_atapi.h index f737090..ab2174c 100644 --- a/src/ide_atapi.h +++ b/src/ide_atapi.h @@ -64,5 +64,6 @@ uint8_t atapi_read_iir(atapi_device_t *atapi_dev); uint8_t atapi_read_drq(atapi_device_t *atapi_dev); void atapi_process_packet(atapi_device_t *atapi_dev); void atapi_set_transfer_granularity(atapi_device_t *atapi_dev, int size); +void atapi_reset(atapi_device_t *atapi_dev); #endif diff --git a/src/scsi.c b/src/scsi.c index df4b8a8..199ac6e 100644 --- a/src/scsi.c +++ b/src/scsi.c @@ -374,3 +374,21 @@ void scsi_bus_close(scsi_bus_t *bus) bus->devices[c]->close(bus->device_data[c]); } } + +void scsi_bus_reset(scsi_bus_t *bus) +{ + int c; + + bus->state = STATE_IDLE; + bus->clear_req = 0; + bus->change_state_delay = 0; + bus->new_req_delay = 0; + bus->bus_in = bus->bus_out = 0; + bus->command_pos = 0; + + for (c = 0; c < 8; c++) + { + if (bus->device_data[c] && bus->devices[c]->reset) + bus->devices[c]->reset(bus->device_data[c]); + } +} diff --git a/src/scsi.h b/src/scsi.h index 8791011..cba4a98 100644 --- a/src/scsi.h +++ b/src/scsi.h @@ -9,6 +9,7 @@ typedef struct scsi_device_t void *(*init)(struct scsi_bus_t *bus, int id); void *(*atapi_init)(struct scsi_bus_t *bus, int id, struct atapi_device_t *atapi_dev); void (*close)(void *p); + void (*reset)(void *p); void (*start_command)(void *p); int (*command)(uint8_t *cdb, void *p); @@ -106,6 +107,7 @@ int scsi_bus_match(scsi_bus_t *bus, int bus_assert); void scsi_bus_kick(scsi_bus_t *bus); void scsi_bus_init(scsi_bus_t *bus); void scsi_bus_close(scsi_bus_t *bus); +void scsi_bus_reset(scsi_bus_t *bus); void scsi_bus_atapi_init(scsi_bus_t *bus, scsi_device_t *device, int id, struct atapi_device_t *atapi_dev); diff --git a/src/scsi_cd.c b/src/scsi_cd.c index 5abe1f3..48dbdb6 100644 --- a/src/scsi_cd.c +++ b/src/scsi_cd.c @@ -420,6 +420,14 @@ static void scsi_cd_close(void *p) free(data); } +static void scsi_cd_reset(void *p) +{ + scsi_cd_data_t *data = p; + + timer_disable(&data->callback_timer); + data->cmd_pos = CMD_POS_IDLE; +} + static void scsi_cd_illegal(scsi_cd_data_t *data) { atapi_cmd_error(data, KEY_ILLEGAL_REQ, ASC_INVALID_LUN, 0); @@ -1546,6 +1554,7 @@ scsi_device_t scsi_cd = scsi_cd_init, scsi_cd_atapi_init, scsi_cd_close, + scsi_cd_reset, scsi_cd_start_command, scsi_cd_command, diff --git a/src/scsi_hd.c b/src/scsi_hd.c index bf6412e..914f984 100644 --- a/src/scsi_hd.c +++ b/src/scsi_hd.c @@ -816,6 +816,7 @@ scsi_device_t scsi_hd = scsi_hd_init, NULL, scsi_hd_close, + NULL, scsi_hd_start_command, scsi_hd_command, diff --git a/src/scsi_zip.c b/src/scsi_zip.c index 8f81700..51dacb2 100644 --- a/src/scsi_zip.c +++ b/src/scsi_zip.c @@ -218,6 +218,14 @@ static void scsi_zip_close(void *p) zip_data = NULL; } +static void scsi_zip_reset(void *p) +{ + scsi_zip_data *data = p; + + timer_disable(&data->callback_timer); + data->cmd_pos = CMD_POS_IDLE; +} + static int scsi_add_data(uint8_t val, void *p) { scsi_zip_data *data = p; @@ -1195,6 +1203,7 @@ scsi_device_t scsi_zip = scsi_zip_init, scsi_zip_atapi_init, scsi_zip_close, + scsi_zip_reset, scsi_zip_start_command, scsi_zip_command,