diff --git a/src/disk/hdc_ide_cmd640.c b/src/disk/hdc_ide_cmd640.c index a958eebdf..ad2c739cc 100644 --- a/src/disk/hdc_ide_cmd640.c +++ b/src/disk/hdc_ide_cmd640.c @@ -133,6 +133,9 @@ cmd640_common_write(int addr, uint8_t val, cmd640_t *dev) case 0x57: dev->regs[addr] = val & 0xdc; break; + case 0x5b: /* Undocumented register that Linux attempts to use! */ + dev->regs[addr] = val; + break; } } diff --git a/src/disk/mo.c b/src/disk/mo.c index bdb5d2824..c390759cd 100644 --- a/src/disk/mo.c +++ b/src/disk/mo.c @@ -1160,7 +1160,7 @@ mo_pre_execution_check(mo_t *dev, uint8_t *cdb) int ready = 0; if (dev->drv->bus_type == MO_BUS_SCSI) { - if ((cdb[0] != GPCMD_REQUEST_SENSE) && (cdb[1] & 0xe0)) { + if ((cdb[0] != GPCMD_REQUEST_SENSE) && (dev->cur_lun == SCSI_LUN_USE_CDB) && (cdb[1] & 0xe0)) { mo_log("MO %i: Attempting to execute a unknown command targeted at SCSI LUN %i\n", dev->id, ((dev->request_length >> 5) & 7)); mo_invalid_lun(dev); return 0; @@ -1260,6 +1260,7 @@ mo_reset(scsi_common_t *sc) dev->request_length = 0xEB14; dev->packet_status = PHASE_NONE; dev->unit_attention = 0; + dev->cur_lun = SCSI_LUN_USE_CDB; } @@ -2121,6 +2122,7 @@ mo_drive_reset(int c) dev = (mo_t *) mo_drives[c].priv; dev->id = c; + dev->cur_lun = SCSI_LUN_USE_CDB; if (mo_drives[c].bus_type == MO_BUS_SCSI) { /* SCSI MO, attach to the SCSI bus. */ diff --git a/src/disk/zip.c b/src/disk/zip.c index 2de8a2c0d..920f70d5e 100644 --- a/src/disk/zip.c +++ b/src/disk/zip.c @@ -1227,7 +1227,7 @@ zip_pre_execution_check(zip_t *dev, uint8_t *cdb) int ready = 0; if (dev->drv->bus_type == ZIP_BUS_SCSI) { - if ((cdb[0] != GPCMD_REQUEST_SENSE) && (cdb[1] & 0xe0)) { + if ((cdb[0] != GPCMD_REQUEST_SENSE) && (dev->cur_lun == SCSI_LUN_USE_CDB) && (cdb[1] & 0xe0)) { zip_log("ZIP %i: Attempting to execute a unknown command targeted at SCSI LUN %i\n", dev->id, ((dev->request_length >> 5) & 7)); zip_invalid_lun(dev); return 0; @@ -1327,6 +1327,7 @@ zip_reset(scsi_common_t *sc) dev->request_length = 0xEB14; dev->packet_status = PHASE_NONE; dev->unit_attention = 0; + dev->cur_lun = SCSI_LUN_USE_CDB; } @@ -2338,6 +2339,7 @@ zip_drive_reset(int c) dev = (zip_t *) zip_drives[c].priv; dev->id = c; + dev->cur_lun = SCSI_LUN_USE_CDB; if (zip_drives[c].bus_type == ZIP_BUS_SCSI) { /* SCSI ZIP, attach to the SCSI bus. */ diff --git a/src/include/86box/mo.h b/src/include/86box/mo.h index 81efb6927..a1c372c62 100644 --- a/src/include/86box/mo.h +++ b/src/include/86box/mo.h @@ -130,8 +130,8 @@ typedef struct { uint8_t status, phase, error, id, - features, pad0, - pad1, pad2; + features, cur_lun, + pad0, pad1; uint16_t request_length, max_transfer_len; diff --git a/src/include/86box/scsi_cdrom.h b/src/include/86box/scsi_cdrom.h index 00f263ad6..95f3634bf 100644 --- a/src/include/86box/scsi_cdrom.h +++ b/src/include/86box/scsi_cdrom.h @@ -36,8 +36,8 @@ typedef struct { uint8_t status, phase, error, id, - features, pad0, - pad1, pad2; + features, cur_lun, + pad0, pad1; uint16_t request_length, max_transfer_len; diff --git a/src/include/86box/scsi_device.h b/src/include/86box/scsi_device.h index d9b39ffe2..0dddfdb97 100644 --- a/src/include/86box/scsi_device.h +++ b/src/include/86box/scsi_device.h @@ -24,6 +24,8 @@ #define SCSI_ID_MAX 16 /* 16 on wide buses */ #define SCSI_LUN_MAX 8 /* always 8 */ +#define SCSI_LUN_USE_CDB 0xff + #ifdef WALTJE #define SCSI_TIME 50.0 #else @@ -320,7 +322,7 @@ typedef struct scsi_common_s { uint8_t status, phase, error, id, - features, pad, + features, cur_lun, pad0, pad1; uint16_t request_length, max_transfer_len; @@ -378,6 +380,7 @@ extern int scsi_device_cdb_length(scsi_device_t *dev); extern void scsi_device_command_phase0(scsi_device_t *dev, uint8_t *cdb); extern void scsi_device_command_phase1(scsi_device_t *dev); extern void scsi_device_command_stop(scsi_device_t *dev); +extern void scsi_device_identify(scsi_device_t *dev, uint8_t lun); extern void scsi_device_close_all(void); extern void scsi_device_init(void); diff --git a/src/include/86box/scsi_disk.h b/src/include/86box/scsi_disk.h index 86245f625..0caef4d26 100644 --- a/src/include/86box/scsi_disk.h +++ b/src/include/86box/scsi_disk.h @@ -26,8 +26,8 @@ typedef struct { uint8_t status, phase, error, id, - pad0, pad1, - pad2, pad3; + pad0, cur_lun, + pad1, pad2; uint16_t request_length, pad4; diff --git a/src/include/86box/scsi_ncr53c8xx.h b/src/include/86box/scsi_ncr53c8xx.h index 423f8648e..730da5fed 100644 --- a/src/include/86box/scsi_ncr53c8xx.h +++ b/src/include/86box/scsi_ncr53c8xx.h @@ -27,6 +27,8 @@ extern const device_t ncr53c810_pci_device; extern const device_t ncr53c810_onboard_pci_device; +extern const device_t ncr53c815_pci_device; +extern const device_t ncr53c820_pci_device; extern const device_t ncr53c825a_pci_device; extern const device_t ncr53c860_pci_device; extern const device_t ncr53c875_pci_device; diff --git a/src/include/86box/zip.h b/src/include/86box/zip.h index 4fd9bb5e5..378247f67 100644 --- a/src/include/86box/zip.h +++ b/src/include/86box/zip.h @@ -76,8 +76,8 @@ typedef struct { uint8_t status, phase, error, id, - features, pad0, - pad1, pad2; + features, cur_lun, + pad0, pad1; uint16_t request_length, max_transfer_len; diff --git a/src/scsi/scsi.c b/src/scsi/scsi.c index bbf728431..d61596898 100644 --- a/src/scsi/scsi.c +++ b/src/scsi/scsi.c @@ -77,6 +77,8 @@ static SCSI_CARD scsi_cards[] = { { "spock", &spock_device, }, { "bt958d", &buslogic_pci_device, }, { "ncr53c810", &ncr53c810_pci_device, }, + { "ncr53c815", &ncr53c815_pci_device, }, + { "ncr53c820", &ncr53c820_pci_device, }, { "ncr53c825a", &ncr53c825a_pci_device, }, { "ncr53c860", &ncr53c860_pci_device, }, { "ncr53c875", &ncr53c875_pci_device, }, diff --git a/src/scsi/scsi_buslogic.c b/src/scsi/scsi_buslogic.c index 8ecbbe536..2fd627dc5 100644 --- a/src/scsi/scsi_buslogic.c +++ b/src/scsi/scsi_buslogic.c @@ -617,13 +617,14 @@ BuslogicSCSIBIOSRequestSetup(x54x_t *dev, uint8_t *CmdBuf, uint8_t *DataInBuf, u sd->status = SCSI_STATUS_OK; - if (!scsi_device_present(sd)) { + if (!scsi_device_present(sd) || (ESCSICmd->LogicalUnit > 0)) { buslogic_log("SCSI Target ID %i has no device attached\n", ESCSICmd->TargetId); DataInBuf[2] = CCB_SELECTION_TIMEOUT; DataInBuf[3] = SCSI_STATUS_OK; return; } else { buslogic_log("SCSI Target ID %i detected and working\n", ESCSICmd->TargetId); + scsi_device_identify(sd, ESCSICmd->LogicalUnit); buslogic_log("Transfer Control %02X\n", ESCSICmd->DataDirection); buslogic_log("CDB Length %i\n", ESCSICmd->CDBLength); @@ -658,6 +659,7 @@ BuslogicSCSIBIOSRequestSetup(x54x_t *dev, uint8_t *CmdBuf, uint8_t *DataInBuf, u } buslogic_log("BIOS Request complete\n"); + scsi_device_identify(sd, SCSI_LUN_USE_CDB); if (sd->status == SCSI_STATUS_OK) { DataInBuf[2] = CCB_COMPLETE; @@ -667,7 +669,7 @@ BuslogicSCSIBIOSRequestSetup(x54x_t *dev, uint8_t *CmdBuf, uint8_t *DataInBuf, u DataInBuf[3] = SCSI_STATUS_CHECK_CONDITION; } - dev->DataReplyLeft = DataReply; + dev->DataReplyLeft = DataReply; } diff --git a/src/scsi/scsi_cdrom.c b/src/scsi/scsi_cdrom.c index 4b148a08e..5876fa455 100644 --- a/src/scsi/scsi_cdrom.c +++ b/src/scsi/scsi_cdrom.c @@ -1203,7 +1203,7 @@ scsi_cdrom_pre_execution_check(scsi_cdrom_t *dev, uint8_t *cdb) int ready = 0; if (dev->drv->bus_type == CDROM_BUS_SCSI) { - if ((cdb[0] != GPCMD_REQUEST_SENSE) && (cdb[1] & 0xe0)) { + if ((cdb[0] != GPCMD_REQUEST_SENSE) && (dev->cur_lun == SCSI_LUN_USE_CDB) && (cdb[1] & 0xe0)) { scsi_cdrom_log("CD-ROM %i: Attempting to execute a unknown command targeted at SCSI LUN %i\n", dev->id, ((dev->request_length >> 5) & 7)); scsi_cdrom_invalid_lun(dev); @@ -1314,6 +1314,7 @@ scsi_cdrom_reset(scsi_common_t *sc) dev->request_length = 0xEB14; dev->packet_status = PHASE_NONE; dev->unit_attention = 0xff; + dev->cur_lun = SCSI_LUN_USE_CDB; } @@ -2704,6 +2705,9 @@ scsi_cdrom_drive_reset(int c) dev->id = c; dev->drv = drv; + + dev->cur_lun = SCSI_LUN_USE_CDB; + drv->insert = scsi_cdrom_insert; drv->get_volume = scsi_cdrom_get_volume; drv->get_channel = scsi_cdrom_get_channel; diff --git a/src/scsi/scsi_device.c b/src/scsi/scsi_device.c index f4dc555c0..371dfedf5 100644 --- a/src/scsi/scsi_device.c +++ b/src/scsi/scsi_device.c @@ -158,6 +158,21 @@ scsi_device_command_phase1(scsi_device_t *dev) } +/* When LUN is FF, there has been no IDENTIFY message, otherwise + there has been one. */ +void +scsi_device_identify(scsi_device_t *dev, uint8_t lun) +{ + if ((dev == NULL) || (dev->type == SCSI_NONE) || !dev->sc) + return; + + dev->sc->cur_lun = lun; + + /* TODO: This should return a value, should IDENTIFY fail due to a + a LUN not supported by the target. */ +} + + void scsi_device_close_all(void) { diff --git a/src/scsi/scsi_disk.c b/src/scsi/scsi_disk.c index e411916fa..cc92cbd29 100644 --- a/src/scsi/scsi_disk.c +++ b/src/scsi/scsi_disk.c @@ -436,7 +436,7 @@ scsi_disk_data_phase_error(scsi_disk_t *dev) static int scsi_disk_pre_execution_check(scsi_disk_t *dev, uint8_t *cdb) { - if ((cdb[0] != GPCMD_REQUEST_SENSE) && (cdb[1] & 0xe0)) { + if ((cdb[0] != GPCMD_REQUEST_SENSE) && (dev->cur_lun == SCSI_LUN_USE_CDB) && (cdb[1] & 0xe0)) { scsi_disk_log("SCSI HD %i: Attempting to execute a unknown command targeted at SCSI LUN %i\n", dev->id, ((dev->request_length >> 5) & 7)); scsi_disk_invalid_lun(dev); @@ -488,6 +488,7 @@ scsi_disk_reset(scsi_common_t *sc) dev->status = 0; dev->callback = 0.0; dev->packet_status = PHASE_NONE; + dev->cur_lun = SCSI_LUN_USE_CDB; } @@ -1252,6 +1253,8 @@ scsi_disk_hard_reset(void) dev->id = c; dev->drv = &hdd[c]; + dev->cur_lun = SCSI_LUN_USE_CDB; + scsi_disk_mode_sense_load(dev); scsi_disk_log("SCSI disk %i attached to SCSI ID %i\n", c, hdd[c].scsi_id); diff --git a/src/scsi/scsi_ncr5380.c b/src/scsi/scsi_ncr5380.c index 0009b4430..972d0daf1 100644 --- a/src/scsi/scsi_ncr5380.c +++ b/src/scsi/scsi_ncr5380.c @@ -428,8 +428,7 @@ ncr_bus_update(void *priv, int bus) if (ncr->command_pos == cmd_len[(ncr->command[0] >> 5) & 7]) { if (ncr->is_msgout) { ncr->is_msgout = 0; - ncr->command[1] &= ~(0x80 | 0x40 | 0x20); - ncr->command[1] |= ncr->msglun << 5; + // ncr->command[1] = (ncr->command[1] & 0x1f) | (ncr->msglun << 5); } /*Reset data position to default*/ @@ -515,6 +514,7 @@ ncr_bus_update(void *priv, int bus) case STATE_STATUS: if ((bus & BUS_ACK) && !(ncr->bus_in & BUS_ACK)) { /*All transfers done, wait until next transfer*/ + scsi_device_identify(&scsi_devices[ncr->target_id], SCSI_LUN_USE_CDB); ncr->cur_bus &= ~BUS_REQ; ncr->new_phase = SCSI_PHASE_MESSAGE_IN; ncr->wait_data = 4; @@ -535,7 +535,7 @@ ncr_bus_update(void *priv, int bus) msglen = getmsglen(ncr->msgout, ncr->msgout_pos); if (ncr->msgout_pos >= msglen) { if ((ncr->msgout[0] & (0x80 | 0x20)) == 0x80) - ncr->msglun = ncr->msgout[0] & 7; + ncr->msglun = ncr->msgout[0] & 7; ncr->cur_bus &= ~BUS_REQ; ncr->state = STATE_MESSAGE_ID; } @@ -544,6 +544,7 @@ ncr_bus_update(void *priv, int bus) case STATE_MESSAGE_ID: if ((ncr->target_id != (uint8_t)-1) && scsi_device_present(&scsi_devices[ncr->target_id])) { ncr_log("Device found at ID %i on MSGOUT, Current Bus BSY=%02x\n", ncr->target_id, ncr->cur_bus); + scsi_device_identify(&scsi_devices[ncr->target_id], ncr->msglun); ncr->state = STATE_COMMAND; ncr->cur_bus = BUS_BSY | BUS_REQ; ncr_log("CurBus BSY|REQ=%02x\n", ncr->cur_bus); diff --git a/src/scsi/scsi_ncr53c8xx.c b/src/scsi/scsi_ncr53c8xx.c index 8c11a3a7a..2dcd40f8d 100644 --- a/src/scsi/scsi_ncr53c8xx.c +++ b/src/scsi/scsi_ncr53c8xx.c @@ -46,17 +46,8 @@ #include <86box/scsi_ncr53c8xx.h> -#define NCR53C810_SDMS3_ROM L"roms/scsi/ncr53c8xx/810/NCR307.BIN" -#define SYM53C810_SDMS4_ROM L"roms/scsi/ncr53c8xx/810/8XX_64.ROM" -#define NCR53C815_SDMS3_ROM L"roms/scsi/ncr53c8xx/815/NCR307.BIN" -#define SYM53C815_SDMS4_ROM L"roms/scsi/ncr53c8xx/815/8XX_64.ROM" -#define NCR53C825A_SDMS3_ROM L"roms/scsi/ncr53c8xx/825A/NCR307.BIN" -#define SYM53C825A_SDMS4_ROM L"roms/scsi/ncr53c8xx/825A/8XX_64.ROM" -#define NCR53C860_SDMS3_ROM L"roms/scsi/ncr53c8xx/860/NCR307.BIN" -#define SYM53C860_SDMS4_ROM L"roms/scsi/ncr53c8xx/860/8XX_64.ROM" -#define NCR53C875_SDMS3_ROM L"roms/scsi/ncr53c8xx/875/NCR307.BIN" -#define SYM53C875_SDMS4_ROM L"roms/scsi/ncr53c8xx/875/8XX_64.ROM" -// #define SYM53C875_SDMS4_ROM L"roms/scsi/ncr53c8xx/875/8xx_64.rom.419" +#define NCR53C8XX_SDMS3_ROM L"roms/scsi/ncr53c8xx/NCR307.BIN" +#define SYM53C8XX_SDMS4_ROM L"roms/scsi/ncr53c8xx/8xx_64.ROM" #define HA_ID 7 @@ -620,10 +611,15 @@ ncr53c8xx_bad_phase(ncr53c8xx_t *dev, int out, int new_phase) static void ncr53c8xx_disconnect(ncr53c8xx_t *dev) { + scsi_device_t *sd; + + sd = &scsi_devices[dev->sdid]; + dev->scntl1 &= ~NCR_SCNTL1_CON; dev->sstat1 &= ~PHASE_MASK; if (dev->dcmd & 0x01) /* Select with ATN */ dev->sstat1 |= 0x07; + scsi_device_identify(sd, SCSI_LUN_USE_CDB); } @@ -755,7 +751,7 @@ ncr53c8xx_do_command(ncr53c8xx_t *dev, uint8_t id) dev->command_complete = 0; sd = &scsi_devices[id]; - if (!scsi_device_present(sd)) { + if (!scsi_device_present(sd) || (dev->current_lun > 0)) { ncr53c8xx_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: Bad Selection\n", id, dev->current_lun, buf[0]); ncr53c8xx_bad_selection(dev, id); return 0; @@ -1006,6 +1002,7 @@ ncr53c8xx_do_msgout(ncr53c8xx_t *dev, uint8_t id) /* 0x80 to 0xff are IDENTIFY messages. */ ncr53c8xx_log("MSG: Identify\n"); dev->current_lun = msg & 7; + scsi_device_identify(sd, msg & 7); ncr53c8xx_log("Select LUN %d\n", dev->current_lun); #ifdef USE_WDTR if ((dev->chip == CHIP_875) && !dev->tr_set[dev->sdid]) @@ -2492,7 +2489,7 @@ ncr53c8xx_pci_write(int func, int addr, uint8_t val, void *p) /* Then let's calculate the new I/O base. */ ncr53c8xx_pci_bar[3].addr &= (dev->bios_mask | 0x00000001); dev->BIOSBase = ncr53c8xx_pci_bar[3].addr & dev->bios_mask; - pclog("BIOS BAR: %08X\n", dev->BIOSBase | ncr53c8xx_pci_bar[3].addr_regs[0]); + ncr53c8xx_log("BIOS BAR: %08X\n", dev->BIOSBase | ncr53c8xx_pci_bar[3].addr_regs[0]); /* Log the new base. */ ncr53c8xx_log("NCR53c8xx: New BIOS base is %08X\n" , dev->BIOSBase); /* We're done, so get out of the here. */ @@ -2521,23 +2518,33 @@ ncr53c8xx_init(const device_t *info) dev->chip = info->local & 0xff; - if ((dev->chip != CHIP_810) && (dev->chip != CHIP_820) && !(info->local & 0x8000)) + if ((dev->chip != CHIP_810) && (dev->chip != CHIP_820) && !(info->local & 0x8000)) { dev->has_bios = device_get_config_int("bios"); - else + + /* We have to auto-patch the BIOS to have the correct PCI Device ID, because for some reason, they all ship with + the PCI Device ID set to that of the NCR 53c825, but for a machine BIOS to load the SCSI BIOS correctly, the + PCI Device ID in the BIOS' PCIR block must match the one returned in the PCI registers. */ + if (dev->has_bios == 2) { + rom_init(&dev->bios, SYM53C8XX_SDMS4_ROM, 0xd0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); + ncr53c8xx_log("BIOS v4.19: Old BIOS CHIP ID: %02X, old BIOS checksum: %02X\n", dev->bios.rom[0x0022], dev->bios.rom[0xffff]); + dev->bios.rom[0xffff] += (dev->bios.rom[0x0022] - dev->chip); + dev->bios.rom[0x0022] = dev->chip; + ncr53c8xx_log("BIOS v4.19: New BIOS CHIP ID: %02X, old BIOS checksum: %02X\n", dev->bios.rom[0x0022], dev->bios.rom[0xffff]); + } else if (dev->has_bios == 1) { + rom_init(&dev->bios, NCR53C8XX_SDMS3_ROM, 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + ncr53c8xx_log("BIOS v3.07: Old BIOS CHIP ID: %02X, old BIOS checksum: %02X\n", dev->bios.rom[0x3fcb], dev->bios.rom[0x3fff]); + dev->bios.rom[0x3fff] += (dev->bios.rom[0x3fcb] - dev->chip); + dev->bios.rom[0x3fcb] = dev->chip; + ncr53c8xx_log("BIOS v3.07: New BIOS CHIP ID: %02X, old BIOS checksum: %02X\n", dev->bios.rom[0x3fcb], dev->bios.rom[0x3fff]); + } + } else dev->has_bios = 0; + if (dev->chip == CHIP_875) { - if (dev->has_bios == 2) - rom_init(&dev->bios, SYM53C875_SDMS4_ROM, 0xd0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); - else if (dev->has_bios == 1) - rom_init(&dev->bios, NCR53C875_SDMS3_ROM, 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); dev->chip_rev = 0x04; dev->nvr_path = L"ncr53c875.nvr"; dev->wide = 1; } else if (dev->chip == CHIP_860) { - if (dev->has_bios == 2) - rom_init(&dev->bios, SYM53C860_SDMS4_ROM, 0xd0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); - else if (dev->has_bios == 1) - rom_init(&dev->bios, NCR53C860_SDMS3_ROM, 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); dev->chip_rev = 0x04; dev->nvr_path = L"ncr53c860.nvr"; dev->wide = 1; @@ -2545,10 +2552,6 @@ ncr53c8xx_init(const device_t *info) dev->nvr_path = L"ncr53c820.nvr"; dev->wide = 1; } else if (dev->chip == CHIP_825) { - if (dev->has_bios == 2) - rom_init(&dev->bios, SYM53C825A_SDMS4_ROM, 0xd0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); - else if (dev->has_bios == 1) - rom_init(&dev->bios, NCR53C825A_SDMS3_ROM, 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); dev->chip_rev = 0x26; dev->nvr_path = L"ncr53c825a.nvr"; dev->wide = 1; @@ -2556,15 +2559,11 @@ ncr53c8xx_init(const device_t *info) dev->nvr_path = L"ncr53c810.nvr"; dev->wide = 0; } else if (dev->chip == CHIP_815) { - if (dev->has_bios == 2) - rom_init(&dev->bios, SYM53C815_SDMS4_ROM, 0xd0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); - else if (dev->has_bios == 1) - rom_init(&dev->bios, NCR53C815_SDMS3_ROM, 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); dev->chip_rev = 0x04; dev->nvr_path = L"ncr53c815.nvr"; dev->wide = 0; } - + ncr53c8xx_pci_bar[0].addr_regs[0] = 1; ncr53c8xx_pci_bar[1].addr_regs[0] = 0; ncr53c8xx_pci_regs[0x04] = 3; diff --git a/src/scsi/scsi_pcscsi.c b/src/scsi/scsi_pcscsi.c index 6d633dc77..adf49663b 100644 --- a/src/scsi/scsi_pcscsi.c +++ b/src/scsi/scsi_pcscsi.c @@ -289,7 +289,7 @@ esp_get_cmd(esp_t *dev, uint8_t *buf, uint8_t buflen) dev->ti_rptr = 0; dev->ti_wptr = 0; - if (scsi_device_present(&scsi_devices[dev->id]) && (dev->lun >= 1 && dev->lun <= 7)) { + if (scsi_device_present(&scsi_devices[dev->id]) && (dev->lun > 0)) { /* We only support LUN 0 */ dev->rregs[ESP_RSTAT] = 0; dev->rregs[ESP_RINTR] = INTR_DC; @@ -297,7 +297,9 @@ esp_get_cmd(esp_t *dev, uint8_t *buf, uint8_t buflen) esp_raise_irq(dev); return 0; } - + + scsi_device_identify(&scsi_devices[dev->id], dev->lun); + return dmalen; } @@ -341,6 +343,8 @@ esp_do_busid_cmd(esp_t *dev, uint8_t *buf, uint8_t busid) esp_pci_command_complete(dev, sd->status); } + scsi_device_identify(sd, SCSI_LUN_USE_CDB); + dev->rregs[ESP_RINTR] = INTR_BS | INTR_FC; dev->rregs[ESP_RSEQ] = SEQ_CD; esp_raise_irq(dev); diff --git a/src/scsi/scsi_x54x.c b/src/scsi/scsi_x54x.c index 5a00930aa..ea6f1b38b 100644 --- a/src/scsi/scsi_x54x.c +++ b/src/scsi/scsi_x54x.c @@ -439,6 +439,8 @@ x54x_bios_command(x54x_t *x54x, uint8_t max_id, BIOSCMD *cmd, int8_t islba) x54x_log("BIOS Target ID %i has no device attached\n", cmd->id); ret = 0x80; } else { + scsi_device_identify(dev, 0xff); + if ((dev->type == SCSI_REMOVABLE_CDROM) && !(x54x->flags & X54X_CDROM_BOOT)) { x54x_log("BIOS Target ID %i is CD-ROM on unsupported BIOS\n", cmd->id); return(0x80); @@ -1051,12 +1053,21 @@ x54x_mbo_free(x54x_t *dev) static void x54x_notify(x54x_t *dev) { + Req_t *req = &dev->Req; + scsi_device_t *sd; + + sd = &scsi_devices[req->TargetID]; + x54x_mbo_free(dev); if (dev->MailboxIsBIOS) x54x_ccb(dev); else x54x_mbi(dev); + + /* Make sure to restore device to non-IDENTIFY'd state as we disconnect. */ + if (sd->type != SCSI_NONE) + scsi_device_identify(sd, SCSI_LUN_USE_CDB); } @@ -1091,14 +1102,14 @@ x54x_req_setup(x54x_t *dev, uint32_t CCBPointer, Mailbox32_t *Mailbox32) sd->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(sd)) { + if (!scsi_device_present(sd) || (lun > 0)) { x54x_log("SCSI Target ID %i and LUN %i have no device attached\n",id,lun); x54x_mbi_setup(dev, CCBPointer, &req->CmdBlock, CCB_SELECTION_TIMEOUT, SCSI_STATUS_OK, MBI_ERROR); dev->callback_sub_phase = 4; } else { x54x_log("SCSI Target ID %i detected and working\n", id); + scsi_device_identify(sd, lun); x54x_log("Transfer Control %02X\n", req->CmdBlock.common.ControlByte); x54x_log("CDB Length %i\n", req->CmdBlock.common.CdbLength);