From 444fa519a71ae01502bc0da54581fcca95002b09 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 6 Jan 2018 22:47:41 +0100 Subject: [PATCH] Fixed CD-ROM temporary buffer freeing and made the SCSI phase and SCSI status variable per-SCSI-device rather than two single global variables. --- src/cdrom/cdrom.c | 129 ++++++++++++++++++++++++-------------- src/scsi/scsi.c | 4 +- src/scsi/scsi.h | 12 ++-- src/scsi/scsi_bus.c | 21 ++++--- src/scsi/scsi_buslogic.c | 10 +-- src/scsi/scsi_device.c | 66 +++++-------------- src/scsi/scsi_disk.c | 106 +++++++++++++------------------ src/scsi/scsi_ncr53c810.c | 16 ++--- src/scsi/scsi_x54x.c | 28 ++++----- 9 files changed, 187 insertions(+), 205 deletions(-) diff --git a/src/cdrom/cdrom.c b/src/cdrom/cdrom.c index ece501e86..3c71885e9 100644 --- a/src/cdrom/cdrom.c +++ b/src/cdrom/cdrom.c @@ -9,11 +9,11 @@ * Implementation of the CD-ROM drive with SCSI(-like) * commands, for both ATAPI and SCSI usage. * - * Version: @(#)cdrom.c 1.0.25 2017/12/10 + * Version: @(#)cdrom.c 1.0.26 2018/01/06 * * Author: Miran Grca, * - * Copyright 2016,2017 Miran Grca. + * Copyright 2016,2018 Miran Grca. */ #include #include @@ -1406,9 +1406,20 @@ static void cdrom_sense_clear(int id, int command) cdrom_sense_key = cdrom_asc = cdrom_ascq = 0; } +static void cdrom_set_phase(uint8_t id, uint8_t phase) +{ + uint8_t scsi_id = cdrom_drives[id].scsi_device_id; + uint8_t scsi_lun = cdrom_drives[id].scsi_device_lun; + + if (cdrom_drives[id].bus_type != CDROM_BUS_SCSI) + return; + + SCSIDevices[scsi_id][scsi_lun].Phase = phase; +} + static void cdrom_cmd_error(uint8_t id) { - SCSIPhase = SCSI_PHASE_STATUS; + cdrom_set_phase(id, SCSI_PHASE_STATUS); cdrom[id].error = ((cdrom_sense_key & 0xf) << 4) | ABRT_ERR; if (cdrom[id].unit_attention) cdrom[id].error |= MCR_ERR; @@ -1422,7 +1433,7 @@ static void cdrom_cmd_error(uint8_t id) static void cdrom_unit_attention(uint8_t id) { - SCSIPhase = SCSI_PHASE_STATUS; + cdrom_set_phase(id, SCSI_PHASE_STATUS); cdrom[id].error = (SENSE_UNIT_ATTENTION << 4) | ABRT_ERR; if (cdrom[id].unit_attention) cdrom[id].error |= MCR_ERR; @@ -2130,17 +2141,15 @@ void cdrom_command(uint8_t id, uint8_t *cdb) msf = cdb[1] & 2; cdrom[id].sector_len = 0; - SCSIPhase = SCSI_PHASE_STATUS; + cdrom_set_phase(id, SCSI_PHASE_STATUS); /* This handles the Not Ready/Unit Attention check if it has to be handled at this point. */ if (cdrom_pre_execution_check(id, cdb) == 0) return; - cdrom_buf_free(id); - switch (cdb[0]) { case GPCMD_TEST_UNIT_READY: - SCSIPhase = SCSI_PHASE_STATUS; + cdrom_set_phase(id, SCSI_PHASE_STATUS); cdrom_command_complete(id); break; @@ -2149,13 +2158,13 @@ void cdrom_command(uint8_t id, uint8_t *cdb) cdrom_drives[id].handler->stop(id); cdrom[id].sector_pos = cdrom[id].sector_len = 0; cdrom_seek(id, 0); - SCSIPhase = SCSI_PHASE_STATUS; + cdrom_set_phase(id, SCSI_PHASE_STATUS); break; case GPCMD_REQUEST_SENSE: /* If there's a unit attention condition and there's a buffered not ready, a standalone REQUEST SENSE should forget about the not ready, and report unit attention straight away. */ - SCSIPhase = SCSI_PHASE_DATA_IN; + cdrom_set_phase(id, SCSI_PHASE_DATA_IN); max_len = cdb[4]; cdrom_buf_alloc(id, 256); cdrom_set_buf_len(id, BufLen, &max_len); @@ -2165,12 +2174,12 @@ void cdrom_command(uint8_t id, uint8_t *cdb) case GPCMD_SET_SPEED: case GPCMD_SET_SPEED_ALT: - SCSIPhase = SCSI_PHASE_STATUS; + cdrom_set_phase(id, SCSI_PHASE_STATUS); cdrom_command_complete(id); break; case GPCMD_MECHANISM_STATUS: - SCSIPhase = SCSI_PHASE_DATA_IN; + cdrom_set_phase(id, SCSI_PHASE_DATA_IN); len = (cdb[7] << 16) | (cdb[8] << 8) | cdb[9]; cdrom_buf_alloc(id, 8); @@ -2186,7 +2195,7 @@ void cdrom_command(uint8_t id, uint8_t *cdb) case GPCMD_READ_TOC_PMA_ATIP: cdrom[id].toctimes++; - SCSIPhase = SCSI_PHASE_DATA_IN; + cdrom_set_phase(id, SCSI_PHASE_DATA_IN); max_len = cdb[7]; max_len <<= 8; @@ -2197,7 +2206,6 @@ void cdrom_command(uint8_t id, uint8_t *cdb) if (cdrom_drives[id].handler->pass_through) { ret = cdrom_pass_through(id, &len, cdrom[id].current_cdb, cdbufferb); if (!ret) { - /* return; */ cdrom_sense_key = cdrom_asc = cdrom_ascq = 0; goto cdrom_readtoc_fallback; } @@ -2228,6 +2236,7 @@ cdrom_readtoc_fallback: break; default: cdrom_invalid_field(id); + cdrom_buf_free(id); return; } } @@ -2252,7 +2261,7 @@ cdrom_readtoc_fallback: case GPCMD_READ_12: case GPCMD_READ_CD: case GPCMD_READ_CD_MSF: - SCSIPhase = SCSI_PHASE_DATA_IN; + cdrom_set_phase(id, SCSI_PHASE_DATA_IN); alloc_length = 2048; switch(cdb[0]) { @@ -2294,7 +2303,7 @@ cdrom_readtoc_fallback: } if (!cdrom[id].sector_len) { - SCSIPhase = SCSI_PHASE_STATUS; + cdrom_set_phase(id, SCSI_PHASE_STATUS); /* cdrom_log("CD-ROM %i: All done - callback set\n", id); */ cdrom[id].packet_status = CDROM_PHASE_COMPLETE; cdrom[id].callback = 20LL * CDROM_TIME; @@ -2311,8 +2320,10 @@ cdrom_readtoc_fallback: cdrom_buf_alloc(id, cdrom[id].packet_len); ret = cdrom_read_blocks(id, &alloc_length, 1); - if (ret <= 0) + if (ret <= 0) { + cdrom_buf_free(id); return; + } cdrom[id].requested_blocks = max_len; cdrom[id].packet_len = alloc_length; @@ -2329,15 +2340,17 @@ cdrom_readtoc_fallback: return; case GPCMD_READ_HEADER: - SCSIPhase = SCSI_PHASE_DATA_IN; + cdrom_set_phase(id, SCSI_PHASE_DATA_IN); alloc_length = ((cdb[7] << 8) | cdb[8]); cdrom_buf_alloc(id, 8); if (cdrom_drives[id].handler->pass_through) { ret = cdrom_pass_through(id, &len, cdrom[id].current_cdb, cdbufferb); - if (!ret) + if (!ret) { + cdrom_buf_free(id); return; + } } else { cdrom[id].sector_len = 1; cdrom[id].sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4]<<8) | cdb[5]; @@ -2364,7 +2377,7 @@ cdrom_readtoc_fallback: case GPCMD_MODE_SENSE_6: case GPCMD_MODE_SENSE_10: - SCSIPhase = SCSI_PHASE_DATA_IN; + cdrom_set_phase(id, SCSI_PHASE_DATA_IN); if (cdrom_drives[id].bus_type == CDROM_BUS_SCSI) block_desc = ((cdb[1] >> 3) & 1) ? 0 : 1; @@ -2383,6 +2396,7 @@ cdrom_readtoc_fallback: if (!(cdrom_mode_sense_page_flags[id] & (1LL << cdrom[id].current_page_code))) { cdrom_invalid_field(id); + cdrom_buf_free(id); return; } @@ -2417,7 +2431,7 @@ cdrom_readtoc_fallback: case GPCMD_MODE_SELECT_6: case GPCMD_MODE_SELECT_10: - SCSIPhase = SCSI_PHASE_DATA_OUT; + cdrom_set_phase(id, SCSI_PHASE_DATA_OUT); if (cdb[0] == GPCMD_MODE_SELECT_6) { len = cdb[4]; @@ -2434,7 +2448,7 @@ cdrom_readtoc_fallback: return; case GPCMD_GET_CONFIGURATION: - SCSIPhase = SCSI_PHASE_DATA_IN; + cdrom_set_phase(id, SCSI_PHASE_DATA_IN); /* XXX: could result in alignment problems in some architectures */ feature = (cdb[2] << 8) | cdb[3]; @@ -2443,6 +2457,7 @@ cdrom_readtoc_fallback: /* only feature 0 is supported */ if ((cdb[2] != 0) || (cdb[3] > 2)) { cdrom_invalid_field(id); + cdrom_buf_free(id); return; } @@ -2530,7 +2545,7 @@ cdrom_readtoc_fallback: break; case GPCMD_GET_EVENT_STATUS_NOTIFICATION: - SCSIPhase = SCSI_PHASE_DATA_IN; + cdrom_set_phase(id, SCSI_PHASE_DATA_IN); cdrom_buf_alloc(id, 8 + sizeof(gesn_event_header)); @@ -2542,6 +2557,7 @@ cdrom_readtoc_fallback: /* asynchronous mode */ /* Only polling is supported, asynchronous mode is not. */ cdrom_invalid_field(id); + cdrom_buf_free(id); return; } @@ -2591,7 +2607,7 @@ cdrom_readtoc_fallback: break; case GPCMD_READ_DISC_INFORMATION: - SCSIPhase = SCSI_PHASE_DATA_IN; + cdrom_set_phase(id, SCSI_PHASE_DATA_IN); max_len = cdb[7]; max_len <<= 8; @@ -2601,8 +2617,10 @@ cdrom_readtoc_fallback: if (cdrom_drives[id].handler->pass_through) { ret = cdrom_pass_through(id, &len, cdrom[id].current_cdb, cdbufferb); - if (!ret) + if (!ret) { + cdrom_buf_free(id); return; + } alloc_length = cdbufferb[0]; alloc_length <<= 8; alloc_length |= cdbufferb[1]; @@ -2627,7 +2645,7 @@ cdrom_readtoc_fallback: break; case GPCMD_READ_TRACK_INFORMATION: - SCSIPhase = SCSI_PHASE_DATA_IN; + cdrom_set_phase(id, SCSI_PHASE_DATA_IN); max_len = cdb[7]; max_len <<= 8; @@ -2642,8 +2660,10 @@ cdrom_readtoc_fallback: if (cdrom_drives[id].handler->pass_through) { ret = cdrom_pass_through(id, &len, cdrom[id].current_cdb, cdbufferb); - if (!ret) + if (!ret) { + cdrom_buf_free(id); return; + } alloc_length = cdbufferb[0]; alloc_length <<= 8; alloc_length |= cdbufferb[1]; @@ -2652,6 +2672,7 @@ cdrom_readtoc_fallback: } else { if (((cdb[1] & 0x03) != 1) || (track != 1)) { cdrom_invalid_field(id); + cdrom_buf_free(id); return; } @@ -2686,7 +2707,7 @@ cdrom_readtoc_fallback: case GPCMD_PLAY_AUDIO_12: case GPCMD_PLAY_AUDIO_MSF: case GPCMD_PLAY_AUDIO_TRACK_INDEX: - SCSIPhase = SCSI_PHASE_STATUS; + cdrom_set_phase(id, SCSI_PHASE_STATUS); switch(cdb[0]) { case GPCMD_PLAY_AUDIO_10: @@ -2729,7 +2750,7 @@ cdrom_readtoc_fallback: break; case GPCMD_READ_SUBCHANNEL: - SCSIPhase = SCSI_PHASE_DATA_IN; + cdrom_set_phase(id, SCSI_PHASE_DATA_IN); max_len = cdb[7]; max_len <<= 8; @@ -2741,8 +2762,10 @@ cdrom_readtoc_fallback: cdrom_log("CD-ROM %i: Getting page %i (%s)\n", id, cdb[3], msf ? "MSF" : "LBA"); if ((cdrom_drives[id].handler->pass_through) && (cdb[3] != 1)) { ret = cdrom_pass_through(id, &len, cdrom[id].current_cdb, cdbufferb); - if (!ret) + if (!ret) { + cdrom_buf_free(id); return; + } switch(cdrom[id].cd_status) { case CD_STATUS_PLAYING: cdbufferb[1] = 0x11; @@ -2776,6 +2799,7 @@ cdrom_readtoc_fallback: if (cdb[3] > 3) { /* cdrom_log("CD-ROM %i: Read subchannel check condition %02X\n", id, cdb[3]); */ cdrom_invalid_field(id); + cdrom_buf_free(id); return; } @@ -2826,7 +2850,7 @@ cdrom_readtoc_fallback: break; case GPCMD_READ_DVD_STRUCTURE: - SCSIPhase = SCSI_PHASE_DATA_IN; + cdrom_set_phase(id, SCSI_PHASE_DATA_IN); alloc_length = (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); @@ -2835,6 +2859,7 @@ cdrom_readtoc_fallback: if (cdrom_drives[id].handler->pass_through) { ret = cdrom_pass_through(id, &len, cdrom[id].current_cdb, cdbufferb); if (!ret) { + cdrom_buf_free(id); return; } else { if (cdrom_drives[id].bus_type == CDROM_BUS_SCSI) { @@ -2852,6 +2877,7 @@ cdrom_readtoc_fallback: if (cdb[7] < 0xc0) { if (len <= CD_MAX_SECTORS) { cdrom_incompatible_format(id); + cdrom_buf_free(id); return; } } @@ -2879,10 +2905,11 @@ cdrom_readtoc_fallback: if (cdb[1] == 0) { ret = cdrom_read_dvd_structure(id, format, cdb, cdbufferb); - cdrom_set_buf_len(id, BufLen, &alloc_length); - - if (ret) + if (ret) { + cdrom_set_buf_len(id, BufLen, &alloc_length); cdrom_data_command_finish(id, alloc_length, alloc_length, len, 0); + } else + cdrom_buf_free(id); return; } /* TODO: BD support, fall through for now */ @@ -2896,13 +2923,14 @@ cdrom_readtoc_fallback: case 0xc0: /* TODO: Write protection status */ default: cdrom_invalid_field(id); + cdrom_buf_free(id); return; } } break; case GPCMD_START_STOP_UNIT: - SCSIPhase = SCSI_PHASE_STATUS; + cdrom_set_phase(id, SCSI_PHASE_STATUS); switch(cdb[4] & 3) { case 0: /* Stop the disc. */ @@ -2926,7 +2954,7 @@ cdrom_readtoc_fallback: break; case GPCMD_INQUIRY: - SCSIPhase = SCSI_PHASE_DATA_IN; + cdrom_set_phase(id, SCSI_PHASE_DATA_IN); max_len = cdb[3]; max_len <<= 8; @@ -2952,6 +2980,7 @@ cdrom_readtoc_fallback: case 0x83: if (idx + 24 > max_len) { cdrom_data_phase_error(id); + cdrom_buf_free(id); return; } @@ -2978,6 +3007,7 @@ cdrom_readtoc_fallback: default: cdrom_log("INQUIRY: Invalid page: %02X\n", cdb[2]); cdrom_invalid_field(id); + cdrom_buf_free(id); return; } } else { @@ -3017,13 +3047,13 @@ atapi_out: break; case GPCMD_PREVENT_REMOVAL: - SCSIPhase = SCSI_PHASE_STATUS; + cdrom_set_phase(id, SCSI_PHASE_STATUS); cdrom_command_complete(id); break; case GPCMD_PAUSE_RESUME_ALT: case GPCMD_PAUSE_RESUME: - SCSIPhase = SCSI_PHASE_STATUS; + cdrom_set_phase(id, SCSI_PHASE_STATUS); if (cdb[8] & 1) { if (cdrom_drives[id].handler->resume) @@ -3045,7 +3075,7 @@ atapi_out: case GPCMD_SEEK_6: case GPCMD_SEEK_10: - SCSIPhase = SCSI_PHASE_STATUS; + cdrom_set_phase(id, SCSI_PHASE_STATUS); switch(cdb[0]) { case GPCMD_SEEK_6: @@ -3060,12 +3090,14 @@ atapi_out: break; case GPCMD_READ_CDROM_CAPACITY: - SCSIPhase = SCSI_PHASE_DATA_IN; + cdrom_set_phase(id, SCSI_PHASE_DATA_IN); cdrom_buf_alloc(id, 8); - if (cdrom_read_capacity(id, cdrom[id].current_cdb, cdbufferb, &len) == 0) + if (cdrom_read_capacity(id, cdrom[id].current_cdb, cdbufferb, &len) == 0) { + cdrom_buf_free(id); return; + } cdrom_set_buf_len(id, BufLen, &len); @@ -3073,7 +3105,7 @@ atapi_out: break; case GPCMD_STOP_PLAY_SCAN: - SCSIPhase = SCSI_PHASE_STATUS; + cdrom_set_phase(id, SCSI_PHASE_STATUS); if (cdrom_drives[id].handler->stop) cdrom_drives[id].handler->stop(id); @@ -3090,6 +3122,9 @@ atapi_out: } /* cdrom_log("CD-ROM %i: Phase: %02X, request length: %i\n", cdrom[id].phase, cdrom[id].request_length); */ + + if (cdrom_atapi_phase_to_scsi(id) == SCSI_PHASE_STATUS) + cdrom_buf_free(id); } /* This is the general ATAPI callback. */ @@ -3110,6 +3145,7 @@ void cdrom_callback(uint8_t id) /* Callback for non-Read CD commands */ cdrom[id].pos = cdrom[id].request_pos = 0; cdrom_command_complete(id); + cdrom_buf_free(id); } else { cdrom_log("CD-ROM %i: %i bytes read, %i bytes are still left\n", id, cdrom[id].pos, cdrom[id].packet_len - cdrom[id].pos); @@ -3132,6 +3168,7 @@ int cdrom_mode_select_return(uint8_t id, int ret) case -6: /* Attempted to write to a non-existent CD-ROM drive (should never occur, but you never know). */ cdrom_invalid_field_pl(id); + cdrom_buf_free(id); return -2; case 1: /* Successful, more data needed. */ @@ -3149,10 +3186,11 @@ int cdrom_mode_select_return(uint8_t id, int ret) case -4: /* Unknown phase. */ cdrom_illegal_opcode(id); + cdrom_buf_free(id); return -2; case -5: /* Command terminated successfully. */ - /* cdrom_command_complete(id); */ + cdrom_buf_free(id); return -1; default: return -15; @@ -3317,7 +3355,6 @@ void cdrom_phase_callback(uint8_t id) cdrom_log("CD-ROM %i: CDROM_PHASE_COMMAND\n", id); cdrom[id].status = BUSY_STAT | (cdrom[id].status &ERR_STAT); memcpy(cdrom[id].atapi_cdb, cdbufferb, cdrom[id].cdb_len); - cdrom_buf_free(id); cdrom_command(id, cdrom[id].atapi_cdb); return; case CDROM_PHASE_COMPLETE: @@ -3325,7 +3362,6 @@ void cdrom_phase_callback(uint8_t id) cdrom[id].status = READY_STAT; cdrom[id].phase = 3; cdrom[id].packet_status = 0xFF; - cdrom_buf_free(id); ui_sb_update_icon(SB_CDROM | id, 0); cdrom_irq_raise(id); return; @@ -3338,6 +3374,7 @@ void cdrom_phase_callback(uint8_t id) case CDROM_PHASE_DATA_OUT_DMA: cdrom_log("CD-ROM %i: CDROM_PHASE_DATA_OUT_DMA\n", id); cdrom_read_from_dma(id); + cdrom_buf_free(id); cdrom[id].packet_status = CDROM_PHASE_COMPLETE; cdrom[id].status = READY_STAT; cdrom[id].phase = 3; @@ -3353,6 +3390,7 @@ void cdrom_phase_callback(uint8_t id) case CDROM_PHASE_DATA_IN_DMA: cdrom_log("CD-ROM %i: CDROM_PHASE_DATA_IN_DMA\n", id); cdrom_write_to_dma(id); + cdrom_buf_free(id); cdrom[id].packet_status = CDROM_PHASE_COMPLETE; cdrom[id].status = READY_STAT; cdrom[id].phase = 3; @@ -3363,7 +3401,6 @@ void cdrom_phase_callback(uint8_t id) cdrom_log("CD-ROM %i: CDROM_PHASE_ERROR\n", id); cdrom[id].status = READY_STAT | ERR_STAT; cdrom[id].phase = 3; - cdrom_buf_free(id); cdrom_irq_raise(id); ui_sb_update_icon(SB_CDROM | id, 0); return; diff --git a/src/scsi/scsi.c b/src/scsi/scsi.c index 65076b27a..a25895661 100644 --- a/src/scsi/scsi.c +++ b/src/scsi/scsi.c @@ -42,8 +42,8 @@ scsi_device_t SCSIDevices[SCSI_ID_MAX][SCSI_LUN_MAX]; -uint8_t SCSIPhase = 0xff; -uint8_t SCSIStatus = SCSI_STATUS_OK; +// uint8_t SCSIPhase = 0xff; +// uint8_t SCSIStatus = SCSI_STATUS_OK; uint8_t scsi_cdrom_id = 3; /*common setting*/ char scsi_fn[SCSI_NUM][512]; uint16_t scsi_hd_location[SCSI_NUM]; diff --git a/src/scsi/scsi.h b/src/scsi/scsi.h index 1b209a316..4ee1f2c69 100644 --- a/src/scsi/scsi.h +++ b/src/scsi/scsi.h @@ -8,15 +8,15 @@ * * SCSI controller handler header. * - * Version: @(#)scsi_h 1.0.8 2017/10/15 + * Version: @(#)scsi_h 1.0.9 2018/01/06 * * Authors: TheCollector1995, * Miran Grca, * Fred N. van Kempen, * - * Copyright 2016,2017 TheCollector1995. - * Copyright 2016,2017 Miran Grca. - * Copyright 2017 Fred N. van Kempen. + * Copyright 2016,2018 TheCollector1995. + * Copyright 2016,2018 Miran Grca. + * Copyright 2018 Fred N. van Kempen. */ #ifndef EMU_SCSI_H #define EMU_SCSI_H @@ -215,8 +215,6 @@ extern uint8_t page_current; #define PAGE_CHANGEABLE 1 #define PAGE_CHANGED 2 -extern uint8_t SCSIStatus; -extern uint8_t SCSIPhase; extern uint8_t scsi_cdrom_id; struct _scsisense_ { @@ -267,6 +265,8 @@ typedef struct { uint8_t *CmdBuffer; int LunType; int32_t BufferLength; + uint8_t Status; + uint8_t Phase; } scsi_device_t; diff --git a/src/scsi/scsi_bus.c b/src/scsi/scsi_bus.c index d803a0004..5d870954d 100644 --- a/src/scsi/scsi_bus.c +++ b/src/scsi/scsi_bus.c @@ -8,7 +8,7 @@ * * The generic SCSI bus operations handler. * - * Version: @(#)scsi_bus.c 1.0.5 2017/12/09 + * Version: @(#)scsi_bus.c 1.0.6 2018/01/06 * * NOTES: For now ported from PCem with some modifications * but at least it's a start. @@ -159,16 +159,16 @@ scsi_bus_update(scsi_bus_t *bus, int bus_assert) get_cmd_len(bus->command[0]), bus->command); - scsi_bus_log("(%02X:%02X): Command %02X: Buffer Length %i, SCSI Phase %02X\n", bus->dev_id, lun, bus->command[0], dev->BufferLength, SCSIPhase); + scsi_bus_log("(%02X:%02X): Command %02X: Buffer Length %i, SCSI Phase %02X\n", bus->dev_id, lun, bus->command[0], dev->BufferLength, dev->Phase); - if ((SCSIPhase == SCSI_PHASE_DATA_IN) || - (SCSIPhase == SCSI_PHASE_DATA_OUT)) { + if ((dev->Phase == SCSI_PHASE_DATA_IN) || + (dev->Phase == SCSI_PHASE_DATA_OUT)) { scsi_bus_log("dev->CmdBuffer = %08X\n", dev->CmdBuffer); dev->CmdBuffer = (uint8_t *) malloc(dev->BufferLength); scsi_bus_log("dev->CmdBuffer = %08X\n", dev->CmdBuffer); } - if (SCSIPhase == SCSI_PHASE_DATA_OUT) { + if (dev->Phase == SCSI_PHASE_DATA_OUT) { /* Write direction commands have delayed execution - only execute them after the bus has gotten all the data from the host. */ scsi_bus_log("Next state is data out\n"); @@ -176,8 +176,8 @@ scsi_bus_update(scsi_bus_t *bus, int bus_assert) bus->clear_req = 0; } else { /* Other command - execute immediately. */ - bus->new_state = SCSIPhase; - if (SCSIPhase == SCSI_PHASE_DATA_IN) { + bus->new_state = dev->Phase; + if (dev->Phase == SCSI_PHASE_DATA_IN) { scsi_device_command_phase1(bus->dev_id, lun); } @@ -324,11 +324,14 @@ scsi_bus_read(scsi_bus_t *bus) break; case SCSI_PHASE_STATUS: + lun = (bus->command[1] >> 5) & 7; + dev = &SCSIDevices[bus->dev_id][lun]; + scsi_bus_log("Phase status\n"); bus->state = STATE_STATUS; bus->bus_out |= BUS_REQ; - bus->bus_out = (bus->bus_out & ~BUS_DATAMASK) | BUS_SETDATA(SCSIStatus) | BUS_DBP; - /* scsi_bus_log("SCSI Status (command %02X): %02X (%08X)\n", bus->command[0], SCSIStatus, bus->bus_out); */ + bus->bus_out = (bus->bus_out & ~BUS_DATAMASK) | BUS_SETDATA(dev->Status) | BUS_DBP; + /* scsi_bus_log("SCSI Status (command %02X): %02X (%08X)\n", bus->command[0], dev->Status, bus->bus_out); */ break; case SCSI_PHASE_MESSAGE_IN: diff --git a/src/scsi/scsi_buslogic.c b/src/scsi/scsi_buslogic.c index cb8a0ae0d..8e99c81f9 100644 --- a/src/scsi/scsi_buslogic.c +++ b/src/scsi/scsi_buslogic.c @@ -11,7 +11,7 @@ * 1 - BT-545S ISA; * 2 - BT-958D PCI * - * Version: @(#)scsi_buslogic.c 1.0.33 2018/01/02 + * Version: @(#)scsi_buslogic.c 1.0.34 2018/01/06 * * Authors: TheCollector1995, * Miran Grca, @@ -599,7 +599,7 @@ BuslogicSCSIBIOSRequestSetup(x54x_t *dev, uint8_t *CmdBuf, uint8_t *DataInBuf, u buslogic_log("Scanning SCSI Target ID %i\n", ESCSICmd->TargetId); - SCSIStatus = SCSI_STATUS_OK; + SCSIDevices[ESCSICmd->TargetId][ESCSICmd->LogicalUnit].Status = SCSI_STATUS_OK; if (!scsi_device_present(ESCSICmd->TargetId, 0)) { buslogic_log("SCSI Target ID %i has no device attached\n",ESCSICmd->TargetId,ESCSICmd->LogicalUnit); @@ -639,7 +639,7 @@ BuslogicSCSIBIOSRequestSetup(x54x_t *dev, uint8_t *CmdBuf, uint8_t *DataInBuf, u SCSIDevices[ESCSICmd->TargetId][ESCSICmd->LogicalUnit].BufferLength = ESCSICmd->DataLength; scsi_device_command_phase0(ESCSICmd->TargetId, ESCSICmd->LogicalUnit, ESCSICmd->CDBLength, temp_cdb); - phase = SCSIPhase; + phase = SCSIDevices[ESCSICmd->TargetId][ESCSICmd->LogicalUnit].Phase; if (phase != SCSI_PHASE_STATUS) { if (phase == SCSI_PHASE_DATA_IN) scsi_device_command_phase1(ESCSICmd->TargetId, ESCSICmd->LogicalUnit); @@ -652,10 +652,10 @@ BuslogicSCSIBIOSRequestSetup(x54x_t *dev, uint8_t *CmdBuf, uint8_t *DataInBuf, u buslogic_log("BIOS Request complete\n"); - if (SCSIStatus == SCSI_STATUS_OK) { + if (SCSIDevices[ESCSICmd->TargetId][ESCSICmd->LogicalUnit].Status == SCSI_STATUS_OK) { DataInBuf[2] = CCB_COMPLETE; DataInBuf[3] = SCSI_STATUS_OK; - } else if (SCSIStatus == SCSI_STATUS_CHECK_CONDITION) { + } else if (SCSIDevices[ESCSICmd->TargetId][ESCSICmd->LogicalUnit].Status == SCSI_STATUS_CHECK_CONDITION) { DataInBuf[2] = CCB_COMPLETE; DataInBuf[3] = SCSI_STATUS_CHECK_CONDITION; } diff --git a/src/scsi/scsi_device.c b/src/scsi/scsi_device.c index 9cd1dd086..29a830b41 100644 --- a/src/scsi/scsi_device.c +++ b/src/scsi/scsi_device.c @@ -8,13 +8,13 @@ * * The generic SCSI device command handler. * - * Version: @(#)scsi_device.c 1.0.9 2017/11/04 + * Version: @(#)scsi_device.c 1.0.10 2018/01/06 * * Authors: Miran Grca, * Fred N. van Kempen, * - * Copyright 2016,2017 Miran Grca. - * Copyright 2017 Fred N. van Kempen. + * Copyright 2016,2018 Miran Grca. + * Copyright 2018 Fred N. van Kempen. */ #include #include @@ -31,41 +31,21 @@ static uint8_t scsi_null_device_sense[14] = { 0x70,0,SENSE_ILLEGAL_REQUEST,0,0,0,0,0,0,0,0,0,ASC_INV_LUN,0 }; -static void scsi_device_target_command(int lun_type, uint8_t id, uint8_t *cdb) +static uint8_t scsi_device_target_command(int lun_type, uint8_t id, uint8_t *cdb) { if (lun_type == SCSI_DISK) { - SCSIPhase = SCSI_PHASE_COMMAND; scsi_hd_command(id, cdb); - SCSIStatus = scsi_hd_err_stat_to_scsi(id); + return scsi_hd_err_stat_to_scsi(id); } else if (lun_type == SCSI_CDROM) { - SCSIPhase = SCSI_PHASE_COMMAND; cdrom_command(id, cdb); - SCSIStatus = cdrom_CDROM_PHASE_to_scsi(id); + return cdrom_CDROM_PHASE_to_scsi(id); } else { - SCSIPhase = SCSI_PHASE_STATUS; - SCSIStatus = SCSI_STATUS_CHECK_CONDITION; - } -} - - -static int scsi_device_target_phase_to_scsi(int lun_type, uint8_t id) -{ - if (lun_type == SCSI_DISK) - { - return scsi_hd_phase_to_scsi(id); - } - else if (lun_type == SCSI_CDROM) - { - return cdrom_atapi_phase_to_scsi(id); - } - else - { - return 0; + return SCSI_STATUS_CHECK_CONDITION; } } @@ -281,7 +261,6 @@ int scsi_device_block_shift(uint8_t scsi_id, uint8_t scsi_lun) void scsi_device_command_phase0(uint8_t scsi_id, uint8_t scsi_lun, int cdb_len, uint8_t *cdb) { - uint8_t phase = 0; uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType; uint8_t id = 0; @@ -296,8 +275,8 @@ void scsi_device_command_phase0(uint8_t scsi_id, uint8_t scsi_lun, int cdb_len, break; default: id = 0; - SCSIPhase = SCSI_PHASE_STATUS; - SCSIStatus = SCSI_STATUS_CHECK_CONDITION; + SCSIDevices[scsi_id][scsi_lun].Phase = SCSI_PHASE_STATUS; + SCSIDevices[scsi_id][scsi_lun].Status = SCSI_STATUS_CHECK_CONDITION; return; } @@ -317,26 +296,14 @@ void scsi_device_command_phase0(uint8_t scsi_id, uint8_t scsi_lun, int cdb_len, } /* Finally, execute the SCSI command immediately and get the transfer length. */ - scsi_device_target_command(lun_type, id, cdb); - if (SCSIStatus == SCSI_STATUS_OK) { - phase = scsi_device_target_phase_to_scsi(lun_type, id); - if (phase == 2) { - /* Command completed - call the phase callback to complete the command. */ - scsi_device_target_phase_callback(lun_type, id); - } else { - /* Command first phase complete - call the callback to execute the second phase. */ - if (SCSIPhase == SCSI_PHASE_STATUS) - { - scsi_device_target_phase_callback(lun_type, id); - SCSIStatus = scsi_device_target_err_stat_to_scsi(lun_type, id); - /* Command second phase complete - call the callback to complete the command. */ - scsi_device_target_phase_callback(lun_type, id); - } - } - } else { - /* Error (Check Condition) - call the phase callback to complete the command. */ + SCSIDevices[scsi_id][scsi_lun].Phase = SCSI_PHASE_COMMAND; + SCSIDevices[scsi_id][scsi_lun].Status = scsi_device_target_command(lun_type, id, cdb); + + if (SCSIDevices[scsi_id][scsi_lun].Phase == SCSI_PHASE_STATUS) { + /* Command completed (either OK or error) - call the phase callback to complete the command. */ scsi_device_target_phase_callback(lun_type, id); } + /* If the phase is DATA IN or DATA OUT, finish this here. */ } void scsi_device_command_phase1(uint8_t scsi_id, uint8_t scsi_lun) @@ -358,8 +325,9 @@ void scsi_device_command_phase1(uint8_t scsi_id, uint8_t scsi_lun) return; } + /* Call the second phase. */ scsi_device_target_phase_callback(lun_type, id); - SCSIStatus = scsi_device_target_err_stat_to_scsi(lun_type, id); + SCSIDevices[scsi_id][scsi_lun].Status = scsi_device_target_err_stat_to_scsi(lun_type, id); /* Command second phase complete - call the callback to complete the command. */ scsi_device_target_phase_callback(lun_type, id); } diff --git a/src/scsi/scsi_disk.c b/src/scsi/scsi_disk.c index 8f24b41e0..49a92ebc2 100644 --- a/src/scsi/scsi_disk.c +++ b/src/scsi/scsi_disk.c @@ -6,11 +6,11 @@ * * Emulation of SCSI fixed and removable disks. * - * Version: @(#)scsi_disk.c 1.0.11 2017/12/09 + * Version: @(#)scsi_disk.c 1.0.12 2018/01/06 * * Author: Miran Grca, * - * Copyright 2017 Miran Grca. + * Copyright 2018 Miran Grca. */ #include #include @@ -490,40 +490,6 @@ int scsi_hd_err_stat_to_scsi(uint8_t id) } -/* Translates ATAPI phase (DRQ, I/O, C/D) to SCSI phase (MSG, C/D, I/O). */ -int scsi_hd_phase_to_scsi(uint8_t id) -{ - if (shdc[id].status & 8) - { - switch (shdc[id].phase & 3) - { - case 0: - return 0; - case 1: - return 2; - case 2: - return 1; - case 3: - return 7; - } - } - else - { - if ((shdc[id].phase & 3) == 3) - { - return 3; - } - else - { - /* Translate reserved ATAPI phase to reserved SCSI phase. */ - return 4; - } - } - - return 0; -} - - int find_hdd_for_scsi_id(uint8_t scsi_id, uint8_t scsi_lun) { uint8_t i = 0; @@ -1095,9 +1061,21 @@ static void scsi_hd_sense_clear(int id, int command) } +static void scsi_hd_set_phase(uint8_t id, uint8_t phase) +{ + uint8_t scsi_id = hdd[id].scsi_id; + uint8_t scsi_lun = hdd[id].scsi_lun; + + if ((hdd[id].bus != HDD_BUS_SCSI) && (hdd[id].bus != HDD_BUS_SCSI_REMOVABLE)) + return; + + SCSIDevices[scsi_id][scsi_lun].Phase = phase; +} + + static void scsi_hd_cmd_error(uint8_t id) { - SCSIPhase = SCSI_PHASE_STATUS; + scsi_hd_set_phase(id, SCSI_PHASE_STATUS); shdc[id].error = ((scsi_hd_sense_key & 0xf) << 4) | ABRT_ERR; if (shdc[id].unit_attention & 3) { @@ -1113,7 +1091,7 @@ static void scsi_hd_cmd_error(uint8_t id) static void scsi_hd_unit_attention(uint8_t id) { - SCSIPhase = SCSI_PHASE_STATUS; + scsi_hd_set_phase(id, SCSI_PHASE_STATUS); shdc[id].error = (SENSE_NOT_READY << 4) | ABRT_ERR; if (shdc[id].unit_attention & 3) { @@ -1150,7 +1128,7 @@ static void scsi_hd_invalid_lun(uint8_t id) scsi_hd_sense_key = SENSE_ILLEGAL_REQUEST; scsi_hd_asc = ASC_INV_LUN; scsi_hd_ascq = 0; - SCSIPhase = BUS_CD | BUS_IO; + scsi_hd_set_phase(id, SCSI_PHASE_STATUS); scsi_hd_cmd_error(id); } @@ -1461,7 +1439,7 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) shdc[id].sector_len = 0; - SCSIPhase = SCSI_PHASE_STATUS; + scsi_hd_set_phase(id, SCSI_PHASE_STATUS); /* This handles the Not Ready/Unit Attention check if it has to be handled at this point. */ if (scsi_hd_pre_execution_check(id, cdb) == 0) @@ -1473,14 +1451,14 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) { case GPCMD_TEST_UNIT_READY: case GPCMD_FORMAT_UNIT: - SCSIPhase = SCSI_PHASE_STATUS; + scsi_hd_set_phase(id, SCSI_PHASE_STATUS); scsi_hd_command_complete(id); break; case GPCMD_REZERO_UNIT: shdc[id].sector_pos = shdc[id].sector_len = 0; scsi_hd_seek(id, 0); - SCSIPhase = SCSI_PHASE_STATUS; + scsi_hd_set_phase(id, SCSI_PHASE_STATUS); break; case GPCMD_REQUEST_SENSE: @@ -1496,7 +1474,7 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) cdb[4] = *BufLen; } - SCSIPhase = SCSI_PHASE_DATA_IN; + scsi_hd_set_phase(id, SCSI_PHASE_DATA_IN); scsi_hd_data_command_finish(id, 18, 18, cdb[4], 0); break; @@ -1508,7 +1486,7 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) *BufLen = len; } - SCSIPhase = SCSI_PHASE_DATA_IN; + scsi_hd_set_phase(id, SCSI_PHASE_DATA_IN); scsi_hd_data_command_finish(id, 8, 8, len, 0); break; @@ -1539,7 +1517,7 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) if ((!shdc[id].sector_len) || (*BufLen == 0)) { - SCSIPhase = SCSI_PHASE_STATUS; + scsi_hd_set_phase(id, SCSI_PHASE_STATUS); ui_sb_update_icon((hdd[id].bus == HDD_BUS_SCSI_REMOVABLE) ? (SB_RDISK | id) : (SB_HDD | HDD_BUS_SCSI), 0); scsi_hd_log("SCSI HD %i: All done - callback set\n", id); shdc[id].packet_status = CDROM_PHASE_COMPLETE; @@ -1557,7 +1535,7 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) *BufLen = alloc_length; } - SCSIPhase = SCSI_PHASE_DATA_IN; + scsi_hd_set_phase(id, SCSI_PHASE_DATA_IN); if (shdc[id].requested_blocks > 1) { @@ -1575,7 +1553,7 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) case GPCMD_VERIFY_10: case GPCMD_VERIFY_12: if (!(cdb[1] & 2)) { - SCSIPhase = SCSI_PHASE_STATUS; + scsi_hd_set_phase(id, SCSI_PHASE_STATUS); scsi_hd_command_complete(id); break; } @@ -1621,7 +1599,7 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) if ((!shdc[id].sector_len) || (*BufLen == 0)) { - SCSIPhase = SCSI_PHASE_STATUS; + scsi_hd_set_phase(id, SCSI_PHASE_STATUS); ui_sb_update_icon((hdd[id].bus == HDD_BUS_SCSI_REMOVABLE) ? (SB_RDISK | id) : (SB_HDD | HDD_BUS_SCSI), 0); scsi_hd_log("SCSI HD %i: All done - callback set\n", id); shdc[id].packet_status = CDROM_PHASE_COMPLETE; @@ -1639,7 +1617,7 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) *BufLen = alloc_length; } - SCSIPhase = SCSI_PHASE_DATA_OUT; + scsi_hd_set_phase(id, SCSI_PHASE_DATA_OUT); if (shdc[id].requested_blocks > 1) { @@ -1678,7 +1656,7 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) if ((!shdc[id].sector_len) || (*BufLen == 0)) { - SCSIPhase = SCSI_PHASE_STATUS; + scsi_hd_set_phase(id, SCSI_PHASE_STATUS); ui_sb_update_icon((hdd[id].bus == HDD_BUS_SCSI_REMOVABLE) ? (SB_RDISK | id) : (SB_HDD | HDD_BUS_SCSI), 0); scsi_hd_log("SCSI HD %i: All done - callback set\n", id); shdc[id].packet_status = CDROM_PHASE_COMPLETE; @@ -1696,7 +1674,7 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) *BufLen = alloc_length; } - SCSIPhase = SCSI_PHASE_DATA_OUT; + scsi_hd_set_phase(id, SCSI_PHASE_DATA_OUT); if (shdc[id].requested_blocks > 1) { @@ -1712,7 +1690,7 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) case GPCMD_MODE_SENSE_6: case GPCMD_MODE_SENSE_10: - SCSIPhase = SCSI_PHASE_DATA_IN; + scsi_hd_set_phase(id, SCSI_PHASE_DATA_IN); block_desc = ((cdb[1] >> 3) & 1) ? 0 : 1; @@ -1792,7 +1770,7 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) case GPCMD_MODE_SELECT_6: case GPCMD_MODE_SELECT_10: - SCSIPhase = SCSI_PHASE_DATA_OUT; + scsi_hd_set_phase(id, SCSI_PHASE_DATA_OUT); if (cdb[0] == GPCMD_MODE_SELECT_6) { @@ -1833,7 +1811,7 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) break; } - SCSIPhase = SCSI_PHASE_STATUS; + scsi_hd_set_phase(id, SCSI_PHASE_STATUS); scsi_hd_command_complete(id); break; @@ -1844,7 +1822,7 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) if ((!max_len) || (*BufLen == 0)) { - SCSIPhase = SCSI_PHASE_STATUS; + scsi_hd_set_phase(id, SCSI_PHASE_STATUS); /* scsi_hd_log("SCSI HD %i: All done - callback set\n", id); */ shdc[id].packet_status = CDROM_PHASE_COMPLETE; shdc[id].callback = 20 * SCSI_TIME; @@ -1962,12 +1940,12 @@ atapi_out: len = *BufLen; } - SCSIPhase = SCSI_PHASE_DATA_IN; + scsi_hd_set_phase(id, SCSI_PHASE_DATA_IN); scsi_hd_data_command_finish(id, len, len, max_len, 0); break; case GPCMD_PREVENT_REMOVAL: - SCSIPhase = SCSI_PHASE_STATUS; + scsi_hd_set_phase(id, SCSI_PHASE_STATUS); scsi_hd_command_complete(id); break; @@ -1984,7 +1962,7 @@ atapi_out: } scsi_hd_seek(id, pos); - SCSIPhase = SCSI_PHASE_STATUS; + scsi_hd_set_phase(id, SCSI_PHASE_STATUS); scsi_hd_command_complete(id); break; @@ -1993,7 +1971,7 @@ atapi_out: if (scsi_hd_read_capacity(id, shdc[id].current_cdb, shdc[id].temp_buffer, &len) == 0) { - SCSIPhase = SCSI_PHASE_STATUS; + scsi_hd_set_phase(id, SCSI_PHASE_STATUS); return; } @@ -2002,7 +1980,7 @@ atapi_out: *BufLen = len; } - SCSIPhase = SCSI_PHASE_DATA_IN; + scsi_hd_set_phase(id, SCSI_PHASE_DATA_IN); scsi_hd_data_command_finish(id, len, len, len, 0); break; @@ -2061,7 +2039,7 @@ void scsi_hd_phase_data_in(uint8_t id) if (!*BufLen) { scsi_hd_log("scsi_hd_phase_data_in(): Buffer length is 0\n"); - SCSIPhase = SCSI_PHASE_STATUS; + scsi_hd_set_phase(id, SCSI_PHASE_STATUS); ui_sb_update_icon((hdd[id].bus == HDD_BUS_SCSI_REMOVABLE) ? (SB_RDISK | id) : (SB_HDD | HDD_BUS_SCSI), 0); return; @@ -2109,7 +2087,7 @@ void scsi_hd_phase_data_in(uint8_t id) break; } - SCSIPhase = SCSI_PHASE_STATUS; + scsi_hd_set_phase(id, SCSI_PHASE_STATUS); ui_sb_update_icon((hdd[id].bus == HDD_BUS_SCSI_REMOVABLE) ? (SB_RDISK | id) : (SB_HDD | HDD_BUS_SCSI), 0); } @@ -2130,7 +2108,7 @@ void scsi_hd_phase_data_out(uint8_t id) if (!*BufLen) { - SCSIPhase = SCSI_PHASE_STATUS; + scsi_hd_set_phase(id, SCSI_PHASE_STATUS); ui_sb_update_icon((hdd[id].bus == HDD_BUS_SCSI_REMOVABLE) ? (SB_RDISK | id) : (SB_HDD | HDD_BUS_SCSI), 0); return; @@ -2211,7 +2189,7 @@ void scsi_hd_phase_data_out(uint8_t id) break; } - SCSIPhase = SCSI_PHASE_STATUS; + scsi_hd_set_phase(id, SCSI_PHASE_STATUS); ui_sb_update_icon((hdd[id].bus == HDD_BUS_SCSI_REMOVABLE) ? (SB_RDISK | id) : (SB_HDD | HDD_BUS_SCSI), 0); } diff --git a/src/scsi/scsi_ncr53c810.c b/src/scsi/scsi_ncr53c810.c index 189515790..bc970282d 100644 --- a/src/scsi/scsi_ncr53c810.c +++ b/src/scsi/scsi_ncr53c810.c @@ -10,16 +10,16 @@ * NCR and later Symbios and LSI. This controller was designed * for the PCI bus. * - * Version: @(#)scsi_ncr53c810.c 1.0.5 2017/12/25 + * Version: @(#)scsi_ncr53c810.c 1.0.6 2018/01/06 * * Authors: Paul Brook (QEMU) * Artyom Tarasenko (QEMU) * TheCollector1995, * Miran Grca, * - * Copyright 2006-2017 Paul Brook. - * Copyright 2009-2017 Artyom Tarasenko. - * Copyright 2017 Miran Grca. + * Copyright 2006-2018 Paul Brook. + * Copyright 2009-2018 Artyom Tarasenko. + * Copyright 2018 Miran Grca. */ #include #include @@ -623,7 +623,7 @@ ncr53c810_do_dma(ncr53c810_t *dev, int out, uint8_t id) free(sd->CmdBuffer); sd->CmdBuffer = NULL; } - ncr53c810_command_complete(dev, SCSIStatus); + ncr53c810_command_complete(dev, sd->Status); } else { ncr53c810_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: Resume SCRIPTS\n", id, dev->current_lun, dev->last_command); dev->sstop = 0; @@ -687,14 +687,14 @@ ncr53c810_do_command(ncr53c810_t *dev, uint8_t id) dev->current->dma_len = sd->BufferLength; } - if ((SCSIPhase == SCSI_PHASE_DATA_IN) && (sd->BufferLength > 0)) { + if ((sd->Phase == SCSI_PHASE_DATA_IN) && (sd->BufferLength > 0)) { ncr53c810_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: PHASE_DI\n", id, dev->current_lun, buf[0]); ncr53c810_set_phase(dev, PHASE_DI); - } else if ((SCSIPhase == SCSI_PHASE_DATA_OUT) && (sd->BufferLength > 0)) { + } else if ((sd->Phase == SCSI_PHASE_DATA_OUT) && (sd->BufferLength > 0)) { ncr53c810_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: PHASE_DO\n", id, dev->current_lun, buf[0]); ncr53c810_set_phase(dev, PHASE_DO); } else - ncr53c810_command_complete(dev, SCSIStatus); + ncr53c810_command_complete(dev, sd->Status); } diff --git a/src/scsi/scsi_x54x.c b/src/scsi/scsi_x54x.c index ec1b8d936..33a1ccf38 100644 --- a/src/scsi/scsi_x54x.c +++ b/src/scsi/scsi_x54x.c @@ -11,7 +11,7 @@ * series of SCSI Host Adapters made by Mylex. * These controllers were designed for various buses. * - * Version: @(#)scsi_x54x.c 1.0.10 2018/01/02 + * Version: @(#)scsi_x54x.c 1.0.11 2018/01/06 * * Authors: TheCollector1995, * Miran Grca, @@ -363,10 +363,6 @@ x54x_bios_command(x54x_t *x54x, uint8_t max_id, BIOSCMD *cmd, int8_t islba) dev->CmdBuffer = (uint8_t *)malloc(14); memset(dev->CmdBuffer, 0x00, 14); -#if 0 - SCSIStatus = x54x_bios_command_08(cmd->id, cmd->lun, dev->CmdBuffer) ? SCSI_STATUS_OK : SCSI_STATUS_CHECK_CONDITION; -#endif - if (sector_len > 0) { x54x_log("BIOS DMA: Reading 14 bytes at %08X\n", dma_address); @@ -402,7 +398,7 @@ x54x_bios_command(x54x_t *x54x, uint8_t max_id, BIOSCMD *cmd, int8_t islba) scsi_device_command_phase0(cmd->id, cmd->lun, 12, cdb); - if (SCSIPhase == SCSI_PHASE_STATUS) + if (dev->Phase == SCSI_PHASE_STATUS) goto skip_read_phase1; scsi_device_command_phase1(cmd->id, cmd->lun); @@ -442,7 +438,7 @@ skip_read_phase1: scsi_device_command_phase0(cmd->id, cmd->lun, 12, cdb); - if (SCSIPhase == SCSI_PHASE_STATUS) + if (dev->Phase == SCSI_PHASE_STATUS) goto skip_write_phase1; if (sector_len > 0) { @@ -532,7 +528,7 @@ skip_write_phase1: scsi_device_command_phase0(cmd->id, cmd->lun, 12, cdb); - return((SCSIStatus == SCSI_STATUS_OK) ? 1 : 0); + return((dev->Status == SCSI_STATUS_OK) ? 1 : 0); case 0x0d: /* Alternate Disk Reset, in practice it's a nop */ //FIXME: add a longer delay here --FvK @@ -997,7 +993,7 @@ x54x_scsi_cmd(x54x_t *dev) scsi_device_command_phase0(id, lun, req->CmdBlock.common.CdbLength, temp_cdb); - phase = SCSIPhase; + phase = SCSIDevices[id][lun].Phase; x54x_log("Control byte: %02X\n", (req->CmdBlock.common.ControlByte == 0x03)); @@ -1007,7 +1003,7 @@ x54x_scsi_cmd(x54x_t *dev) *BufLen = ConvertSenseLength(req->CmdBlock.common.RequestSenseLength); x54x_buf_alloc(id, lun, *BufLen); scsi_device_command_phase1(id, lun); - if ((SCSIStatus != SCSI_STATUS_OK) && (*BufLen > 0)) { + if ((SCSIDevices[id][lun].Status != SCSI_STATUS_OK) && (*BufLen > 0)) { SenseBufferAddress = SenseBufferPointer(req); DMAPageWrite(SenseBufferAddress, SCSIDevices[id][lun].CmdBuffer, *BufLen); } @@ -1019,10 +1015,10 @@ x54x_scsi_cmd(x54x_t *dev) if (phase == SCSI_PHASE_DATA_IN) x54x_buf_dma_transfer(req, bit24, target_data_len, 0); - SenseBufferFree(req, (SCSIStatus != SCSI_STATUS_OK)); + SenseBufferFree(req, (SCSIDevices[id][lun].Status != SCSI_STATUS_OK)); } } else - SenseBufferFree(req, (SCSIStatus != SCSI_STATUS_OK)); + SenseBufferFree(req, (SCSIDevices[id][lun].Status != SCSI_STATUS_OK)); x54x_set_residue(req, target_data_len); @@ -1030,15 +1026,15 @@ x54x_scsi_cmd(x54x_t *dev) x54x_log("Request complete\n"); - if (SCSIStatus == SCSI_STATUS_OK) { + if (SCSIDevices[id][lun].Status == SCSI_STATUS_OK) { x54x_mbi_setup(dev, req->CCBPointer, &req->CmdBlock, CCB_COMPLETE, SCSI_STATUS_OK, MBI_SUCCESS); - } else if (SCSIStatus == SCSI_STATUS_CHECK_CONDITION) { + } else if (SCSIDevices[id][lun].Status == SCSI_STATUS_CHECK_CONDITION) { x54x_mbi_setup(dev, req->CCBPointer, &req->CmdBlock, CCB_COMPLETE, SCSI_STATUS_CHECK_CONDITION, MBI_ERROR); } - x54x_log("SCSIStatus = %02X\n", SCSIStatus); + x54x_log("SCSIDevices[%02i][%02i].Status = %02X\n", id, lun, SCSIDevices[id][lun].Status); if (temp_cdb[0] == 0x42) { thread_wait_event((event_t *) evt, 10); @@ -1084,7 +1080,7 @@ x54x_req_setup(x54x_t *dev, uint32_t CCBPointer, Mailbox32_t *Mailbox32) x54x_log("Scanning SCSI Target ID %i\n", id); - SCSIStatus = SCSI_STATUS_OK; + SCSIDevices[id][lun].Status = SCSI_STATUS_OK; /* If there is no device at ID:0, timeout the selection - the LUN is then checked later. */ if (! scsi_device_present(id, 0)) {