diff --git a/src/cdrom/cdrom.c b/src/cdrom/cdrom.c index 9c0279cd9..91bb614c6 100644 --- a/src/cdrom/cdrom.c +++ b/src/cdrom/cdrom.c @@ -2197,14 +2197,12 @@ void cdrom_request_sense(uint8_t id, uint8_t *buffer, uint8_t alloc_length) if ((cdrom_sense_key > 0) && ((cdrom[id].cd_status < CD_STATUS_PLAYING) || (cdrom[id].cd_status == CD_STATUS_STOPPED)) && cdrom_playing_completed(id)) { - SCSIPhase = SCSI_PHASE_STATUS; buffer[2]=SENSE_ILLEGAL_REQUEST; buffer[12]=ASC_AUDIO_PLAY_OPERATION; buffer[13]=ASCQ_AUDIO_PLAY_OPERATION_COMPLETED; } else if ((cdrom_sense_key == 0) && (cdrom[id].cd_status >= CD_STATUS_PLAYING) && (cdrom[id].cd_status != CD_STATUS_STOPPED)) { - SCSIPhase = SCSI_PHASE_STATUS; buffer[2]=SENSE_ILLEGAL_REQUEST; buffer[12]=ASC_AUDIO_PLAY_OPERATION; buffer[13]=(cdrom[id].cd_status == CD_STATUS_PLAYING) ? ASCQ_AUDIO_PLAY_OPERATION_IN_PROGRESS : ASCQ_AUDIO_PLAY_OPERATION_PAUSED; @@ -2213,7 +2211,6 @@ void cdrom_request_sense(uint8_t id, uint8_t *buffer, uint8_t alloc_length) { if (cdrom[id].unit_attention && (cdrom_sense_key == 0)) { - SCSIPhase = SCSI_PHASE_STATUS; buffer[2]=SENSE_UNIT_ATTENTION; buffer[12]=ASC_MEDIUM_MAY_HAVE_CHANGED; buffer[13]=0; diff --git a/src/network/net_slirp.c b/src/network/net_slirp.c index 256f79f22..2e4cf3e6c 100644 --- a/src/network/net_slirp.c +++ b/src/network/net_slirp.c @@ -147,6 +147,8 @@ poll_thread(void *arg) thread_destroy_event(evt); evt = poll_tid = NULL; + thread_close_mutex(slirpMutex); + pclog("SLiRP: polling stopped.\n"); } diff --git a/src/pc.c b/src/pc.c index e4f507c14..4adf9fd49 100644 --- a/src/pc.c +++ b/src/pc.c @@ -753,7 +753,7 @@ pc_run(void) mbstowcs(wmachine, machine_getname(), strlen(machine_getname())+1); mbstowcs(wcpu, machines[machine].cpu[cpu_manufacturer].cpus[cpu].name, strlen(machines[machine].cpu[cpu_manufacturer].cpus[cpu].name)+1); - swprintf(s, 100, L"%s v%s - %i%% - %s - %s - %s", + swprintf(s, 200, L"%ls v%ls - %i%% - %ls - %ls - %ls", EMU_NAME_W, EMU_VERSION_W, fps, wmachine, wcpu, (!mousecapture) ? plat_get_string(IDS_2077) : ((mouse_get_type(mouse_type) & MOUSE_TYPE_3BUTTON) ? plat_get_string(IDS_2078) : plat_get_string(IDS_2079))); diff --git a/src/scsi/scsi_aha154x.c b/src/scsi/scsi_aha154x.c index 5e9d7722a..02645b5f8 100644 --- a/src/scsi/scsi_aha154x.c +++ b/src/scsi/scsi_aha154x.c @@ -225,7 +225,7 @@ aha_get_host_id(void *p) { x54x_t *dev = (x54x_t *)p; - return dev->nvr[0] & 3; + return dev->nvr[0] & 0x07; } @@ -234,7 +234,7 @@ aha_get_irq(void *p) { x54x_t *dev = (x54x_t *)p; - return (dev->nvr[1] & 0x0F) + 9; + return (dev->nvr[1] & 0x07) + 9; } @@ -243,7 +243,7 @@ aha_get_dma(void *p) { x54x_t *dev = (x54x_t *)p; - return (dev->nvr[1] & 0xF0) >> 4; + return (dev->nvr[1] >> 4) & 0x07; } @@ -628,9 +628,9 @@ aha_setbios(x54x_t *dev) if (dev->bios_path == NULL) return; /* Open the BIOS image file and make sure it exists. */ - pclog("%s: loading BIOS from '%ls'\n", dev->name, dev->bios_path); + aha_log("%s: loading BIOS from '%ls'\n", dev->name, dev->bios_path); if ((f = rom_fopen(dev->bios_path, L"rb")) == NULL) { - pclog("%s: BIOS ROM not found!\n", dev->name); + aha_log("%s: BIOS ROM not found!\n", dev->name); return; } @@ -657,7 +657,7 @@ aha_setbios(x54x_t *dev) dev->rom2 = NULL; } if (temp != 0) { - pclog("%s: BIOS ROM size invalid!\n", dev->name); + aha_log("%s: BIOS ROM size invalid!\n", dev->name); free(dev->rom1); if (dev->rom2 != NULL) free(dev->rom2); @@ -678,7 +678,7 @@ aha_setbios(x54x_t *dev) if (temp <= 0x2000) size = 0x2000; mask = (size - 1); - pclog("%s: BIOS at 0x%06lX, size %lu, mask %08lx\n", + aha_log("%s: BIOS at 0x%06lX, size %lu, mask %08lx\n", dev->name, dev->rom_addr, size, mask); /* Initialize the ROM entry for this BIOS. */ @@ -711,7 +711,7 @@ aha_setbios(x54x_t *dev) for (i=0; i<8; i++) if (aha_ports[i] == dev->Base) break; if (i == 8) { - pclog("%s: invalid I/O address %04x selected!\n", + aha_log("%s: invalid I/O address %04x selected!\n", dev->name, dev->Base); return; } @@ -791,6 +791,7 @@ aha_init(device_t *info) dev->reset_duration = AHA_RESET_DURATION_US; dev->max_id = 7; dev->int_geom_writable = 0; + dev->cdrom_boot = 0; dev->ven_thread = aha_thread; dev->ven_cmd_is_fast = aha_cmd_is_fast; @@ -845,6 +846,7 @@ aha_init(device_t *info) dev->rom_shramsz = 128; /* size of shadow RAM */ dev->rom_ioaddr = 0x3F7E; /* [2:0] idx into addr table */ dev->rom_fwhigh = 0x0022; /* firmware version (hi/lo) */ + dev->cdrom_boot = 1; dev->ven_get_host_id = aha_get_host_id; /* function to return host ID from EEPROM */ dev->ven_get_irq = aha_get_irq; /* function to return IRQ from EEPROM */ dev->ven_get_dma = aha_get_dma; /* function to return DMA channel from EEPROM */ diff --git a/src/scsi/scsi_buslogic.c b/src/scsi/scsi_buslogic.c index bf3b72573..4363bddbd 100644 --- a/src/scsi/scsi_buslogic.c +++ b/src/scsi/scsi_buslogic.c @@ -1303,6 +1303,7 @@ buslogic_init(device_t *info) dev->reset_duration = BUSLOGIC_RESET_DURATION_US; dev->max_id = 7; dev->int_geom_writable = 1; + dev->cdrom_boot = 0; bl->chip = info->local; bl->PCIBase = 0; @@ -1375,6 +1376,7 @@ buslogic_init(device_t *info) scam_rom_name = L"roms/scsi/buslogic/BT-958D_SCAM.rom"; scam_rom_size = 0x0200; dev->fw_rev = "AA507B"; + dev->cdrom_boot = 1; break; } diff --git a/src/scsi/scsi_disk.c b/src/scsi/scsi_disk.c index 0a82e62e6..03e7904c7 100644 --- a/src/scsi/scsi_disk.c +++ b/src/scsi/scsi_disk.c @@ -1326,7 +1326,6 @@ void scsi_hd_request_sense(uint8_t id, uint8_t *buffer, uint8_t alloc_length) if (shdc[id].unit_attention && (scsi_hd_sense_key == 0)) { - SCSIPhase = SCSI_PHASE_STATUS; buffer[2]=SENSE_UNIT_ATTENTION; buffer[12]=ASC_MEDIUM_MAY_HAVE_CHANGED; buffer[13]=0x00; diff --git a/src/scsi/scsi_x54x.c b/src/scsi/scsi_x54x.c index 1d42fd3d7..4854d6cee 100644 --- a/src/scsi/scsi_x54x.c +++ b/src/scsi/scsi_x54x.c @@ -352,7 +352,7 @@ x54x_bios_command_15(uint8_t id, uint8_t lun, uint8_t *buffer) /* This returns the completion code. */ static uint8_t -x54x_bios_command(uint8_t max_id, BIOSCMD *cmd, int8_t islba) +x54x_bios_command(x54x_t *x54x, uint8_t max_id, BIOSCMD *cmd, int8_t islba) { uint8_t cdb[12] = { 0,0,0,0,0,0,0,0,0,0,0,0 }; scsi_device_t *dev; @@ -385,6 +385,12 @@ x54x_bios_command(uint8_t max_id, BIOSCMD *cmd, int8_t islba) return(0x80); } + if ((dev->LunType == SCSI_CDROM) && !x54x->cdrom_boot) { + x54x_log("BIOS Target ID %i and LUN %i is CD-ROM on unsupported BIOS\n", + cmd->id, cmd->lun); + return(0x80); + } + dma_address = ADDR_TO_U32(cmd->dma_address); x54x_log("BIOS Data Buffer write: length %d, pointer 0x%04X\n", @@ -451,6 +457,10 @@ x54x_bios_command(uint8_t max_id, BIOSCMD *cmd, int8_t islba) #endif scsi_device_command_phase0(cmd->id, cmd->lun, 12, cdb); + + if (SCSIPhase == SCSI_PHASE_STATUS) + goto skip_read_phase1; + scsi_device_command_phase1(cmd->id, cmd->lun); if (sector_len > 0) { x54x_log("BIOS DMA: Reading %i bytes at %08X\n", @@ -459,6 +469,7 @@ x54x_bios_command(uint8_t max_id, BIOSCMD *cmd, int8_t islba) (char *)dev->CmdBuffer, dev->BufferLength); } +skip_read_phase1: if (dev->CmdBuffer != NULL) { free(dev->CmdBuffer); dev->CmdBuffer = NULL; @@ -487,6 +498,9 @@ x54x_bios_command(uint8_t max_id, BIOSCMD *cmd, int8_t islba) scsi_device_command_phase0(cmd->id, cmd->lun, 12, cdb); + if (SCSIPhase == SCSI_PHASE_STATUS) + goto skip_write_phase1; + if (sector_len > 0) { x54x_log("BIOS DMA: Reading %i bytes at %08X\n", dev->BufferLength, dma_address); @@ -496,6 +510,7 @@ x54x_bios_command(uint8_t max_id, BIOSCMD *cmd, int8_t islba) scsi_device_command_phase1(cmd->id, cmd->lun); +skip_write_phase1: if (dev->CmdBuffer != NULL) { free(dev->CmdBuffer); dev->CmdBuffer = NULL; @@ -957,6 +972,21 @@ ConvertSenseLength(uint8_t RequestSenseLength) } +uint32_t +SenseBufferPointer(Req_t *req) +{ + uint32_t SenseBufferAddress; + if (req->Is24bit) { + SenseBufferAddress = req->CCBPointer; + SenseBufferAddress += req->CmdBlock.common.CdbLength + 18; + } else { + SenseBufferAddress = req->CmdBlock.new.SensePointer; + } + + return SenseBufferAddress; +} + + static void SenseBufferFree(Req_t *req, int Copy) { @@ -972,12 +1002,7 @@ SenseBufferFree(Req_t *req, int Copy) * Sense Pointer of the CCB, but in 24-bit mode, it is * located at the end of the Command Descriptor Block. */ - if (req->Is24bit) { - SenseBufferAddress = req->CCBPointer; - SenseBufferAddress += req->CmdBlock.common.CdbLength + 18; - } else { - SenseBufferAddress = req->CmdBlock.new.SensePointer; - } + SenseBufferAddress = SenseBufferPointer(req); x54x_log("Request Sense address: %02X\n", SenseBufferAddress); @@ -1002,6 +1027,7 @@ x54x_scsi_cmd(x54x_t *dev) uint8_t bit24 = !!req->Is24bit; int32_t *BufLen; uint8_t phase; + uint32_t SenseBufferAddress; id = req->TargetID; lun = req->LUN; @@ -1039,21 +1065,34 @@ x54x_scsi_cmd(x54x_t *dev) phase = SCSIPhase; + x54x_log("Control byte: %02X\n", (req->CmdBlock.common.ControlByte == 0x03)); + if (phase != SCSI_PHASE_STATUS) { - x54x_buf_alloc(id, lun, MIN(target_data_len, *BufLen)); - if (phase == SCSI_PHASE_DATA_OUT) - x54x_buf_dma_transfer(req, bit24, target_data_len, 1); - scsi_device_command_phase1(id, lun); - if (phase == SCSI_PHASE_DATA_IN) - x54x_buf_dma_transfer(req, bit24, target_data_len, 0); + if ((temp_cdb[0] == 0x03) && (req->CmdBlock.common.ControlByte == 0x03)) { + /* Request sense in non-data mode - sense goes to sense buffer. */ + *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)) { + SenseBufferAddress = SenseBufferPointer(req); + DMAPageWrite(SenseBufferAddress, (char *)SCSIDevices[id][lun].CmdBuffer, *BufLen); + } + } else { + x54x_buf_alloc(id, lun, MIN(target_data_len, *BufLen)); + if (phase == SCSI_PHASE_DATA_OUT) + x54x_buf_dma_transfer(req, bit24, target_data_len, 1); + scsi_device_command_phase1(id, lun); + if (phase == SCSI_PHASE_DATA_IN) + x54x_buf_dma_transfer(req, bit24, target_data_len, 0); + + SenseBufferFree(req, (SCSIStatus != SCSI_STATUS_OK)); + } } x54x_set_residue(req, target_data_len); x54x_buf_free(id, lun); - SenseBufferFree(req, (SCSIStatus != SCSI_STATUS_OK)); - x54x_log("Request complete\n"); if (SCSIStatus == SCSI_STATUS_OK) { @@ -1314,6 +1353,23 @@ x54x_cmd_thread(void *priv) endscsi(); } + if (poll_tid) { + thread_kill(poll_tid); + poll_tid = NULL; + } + + if (poll_complete) { + thread_destroy_event(poll_complete); + poll_complete = NULL; + } + + if (evt) { + thread_destroy_event(evt); + evt = NULL; + } + + scsi_mutex_close(); + x54x_log("%s: Callback: polling stopped.\n", dev->name); } @@ -1572,7 +1628,7 @@ x54x_out(uint16_t port, uint8_t val, void *priv) cmd->u.chs.head, cmd->u.chs.sec); } - dev->DataBuf[0] = x54x_bios_command(dev->max_id, cmd, (dev->bus & DEVICE_MCA)?1:0); + dev->DataBuf[0] = x54x_bios_command(dev, dev->max_id, cmd, (dev->bus & DEVICE_MCA)?1:0); x54x_log("BIOS Completion/Status Code %x\n", dev->DataBuf[0]); dev->DataReplyLeft = 1; break; @@ -1636,7 +1692,7 @@ x54x_out(uint16_t port, uint8_t val, void *priv) case CMD_RETCONF: /* return Configuration */ if (dev->ven_get_dma) - dev->DataBuf[0] = dev->ven_get_dma(dev); + dev->DataBuf[0] = (1<ven_get_dma(dev)); else dev->DataBuf[0] = (1<DmaChannel); diff --git a/src/scsi/scsi_x54x.h b/src/scsi/scsi_x54x.h index 9111344d2..4ca334809 100644 --- a/src/scsi/scsi_x54x.h +++ b/src/scsi/scsi_x54x.h @@ -419,14 +419,14 @@ typedef struct { uint8_t bus; /* Basically a copy of device flags */ uint8_t setup_info_len; uint8_t max_id; + uint8_t pci_slot; uint32_t reset_duration; - uint8_t pci_slot; - mem_mapping_t mmio_mapping; uint8_t int_geom_writable; + uint8_t cdrom_boot; /* Pointer to a structure of vendor-specific data that only the vendor-specific code can understand */ void *ven_data;