Applied all relevant PCem commits;
Extensively cleaned up and changed the CD-ROM code; Removed CD-ROM IOCTTL (it was causing performance and stability issues); Turned a lot of things into device_t's; Added the PS/1 Model 2011 XTA and standalone XTA hard disk controllers, ported from Varcem; Numerous FDC fixes for the PS/1 Model 2121; NVR changes ported from Varcem; The PCap code no longer requires libpcap to be compiled; Numerous fixes to various SCSI controllers; Updated NukedOPL to 1.8; Fixes to OpenAL initialization and closing, should give less Audio issues now; Revorked parts of the common (S)VGA code (also based on code from QEMU); Removed the Removable SCSI hard disks (they were a never finished experiment so there was no need to keep them there); Cleaned up the SCSI hard disk and Iomega ZIP code (but more cleanups of that are coming in the future); In some occasions (IDE hard disks in multiple sector mode and SCSI hard disks) the status bar icon is no longer updated, should improve performance a bit; Redid the way the tertiary and quaternary IDE controllers are configured (and they are now device_t's); Extensively reworked the IDE code and fixed quite a few bugs; Fixes to XT MFM, AT MFM, and AT ESDI code; Some changes to XTIDE and MCA ESDI code; Some fixes to the CD-ROM image handler.
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Handling of the SCSI controllers.
|
||||
*
|
||||
* Version: @(#)scsi.c 1.0.17 2018/03/18
|
||||
* Version: @(#)scsi.c 1.0.18 2018/03/26
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
@@ -27,11 +27,12 @@
|
||||
#include "../rom.h"
|
||||
#include "../timer.h"
|
||||
#include "../device.h"
|
||||
#include "../cdrom/cdrom.h"
|
||||
#include "../disk/hdc.h"
|
||||
#include "../disk/zip.h"
|
||||
#include "../plat.h"
|
||||
#include "scsi.h"
|
||||
#include "../cdrom/cdrom.h"
|
||||
#include "scsi_device.h"
|
||||
#include "scsi_aha154x.h"
|
||||
#include "scsi_buslogic.h"
|
||||
#include "scsi_ncr5380.h"
|
||||
@@ -60,30 +61,29 @@ typedef const struct {
|
||||
const char *name;
|
||||
const char *internal_name;
|
||||
const device_t *device;
|
||||
void (*reset)(void *p);
|
||||
} SCSI_CARD;
|
||||
|
||||
|
||||
static SCSI_CARD scsi_cards[] = {
|
||||
{ "None", "none", NULL, NULL },
|
||||
{ "[ISA] Adaptec AHA-1540B","aha1540b", &aha1540b_device, x54x_device_reset },
|
||||
{ "[ISA] Adaptec AHA-1542C","aha1542c", &aha1542c_device, x54x_device_reset },
|
||||
{ "[ISA] Adaptec AHA-1542CF","aha1542cf", &aha1542cf_device, x54x_device_reset },
|
||||
{ "[ISA] BusLogic BT-542BH","bt542bh", &buslogic_device, BuslogicDeviceReset },
|
||||
{ "[ISA] BusLogic BT-545S", "bt545s", &buslogic_545s_device,BuslogicDeviceReset },
|
||||
{ "[ISA] Longshine LCS-6821N","lcs6821n", &scsi_lcs6821n_device,NULL },
|
||||
{ "[ISA] Ranco RT1000B", "rt1000b", &scsi_rt1000b_device, NULL },
|
||||
{ "[ISA] Trantor T130B", "t130b", &scsi_t130b_device, NULL },
|
||||
{ "[ISA] Sumo SCSI-AT", "scsiat", &scsi_scsiat_device, NULL },
|
||||
{ "None", "none", NULL, },
|
||||
{ "[ISA] Adaptec AHA-1540B","aha1540b", &aha1540b_device, },
|
||||
{ "[ISA] Adaptec AHA-1542C","aha1542c", &aha1542c_device, },
|
||||
{ "[ISA] Adaptec AHA-1542CF","aha1542cf", &aha1542cf_device, },
|
||||
{ "[ISA] BusLogic BT-542BH","bt542bh", &buslogic_device, },
|
||||
{ "[ISA] BusLogic BT-545S", "bt545s", &buslogic_545s_device,},
|
||||
{ "[ISA] Longshine LCS-6821N","lcs6821n", &scsi_lcs6821n_device,},
|
||||
{ "[ISA] Ranco RT1000B", "rt1000b", &scsi_rt1000b_device, },
|
||||
{ "[ISA] Trantor T130B", "t130b", &scsi_t130b_device, },
|
||||
{ "[ISA] Sumo SCSI-AT", "scsiat", &scsi_scsiat_device, },
|
||||
#ifdef WALTJE
|
||||
{ "[ISA] Generic WDC33C93", "wd33c93", &scsi_wd33c93_device, NULL },
|
||||
{ "[ISA] Generic WDC33C93", "wd33c93", &scsi_wd33c93_device, },
|
||||
#endif
|
||||
{ "[MCA] Adaptec AHA-1640", "aha1640", &aha1640_device, x54x_device_reset },
|
||||
{ "[MCA] BusLogic BT-640A", "bt640a", &buslogic_640a_device,BuslogicDeviceReset },
|
||||
{ "[PCI] BusLogic BT-958D", "bt958d", &buslogic_pci_device, BuslogicDeviceReset },
|
||||
{ "[PCI] NCR 53C810", "ncr53c810", &ncr53c810_pci_device,NULL },
|
||||
{ "[VLB] BusLogic BT-445S", "bt445s", &buslogic_445s_device,BuslogicDeviceReset },
|
||||
{ "", "", NULL, NULL },
|
||||
{ "[MCA] Adaptec AHA-1640", "aha1640", &aha1640_device, },
|
||||
{ "[MCA] BusLogic BT-640A", "bt640a", &buslogic_640a_device,},
|
||||
{ "[PCI] BusLogic BT-958D", "bt958d", &buslogic_pci_device, },
|
||||
{ "[PCI] NCR 53C810", "ncr53c810", &ncr53c810_pci_device,},
|
||||
{ "[VLB] BusLogic BT-445S", "bt445s", &buslogic_445s_device,},
|
||||
{ "", "", NULL, },
|
||||
};
|
||||
|
||||
|
||||
@@ -149,6 +149,9 @@ void scsi_card_init(void)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
if (!scsi_cards[scsi_card_current].device)
|
||||
return;
|
||||
|
||||
pclog("Building SCSI hard disk map...\n");
|
||||
build_scsi_hd_map();
|
||||
pclog("Building SCSI CD-ROM map...\n");
|
||||
@@ -158,41 +161,24 @@ void scsi_card_init(void)
|
||||
|
||||
for (i=0; i<SCSI_ID_MAX; i++) {
|
||||
for (j=0; j<SCSI_LUN_MAX; j++) {
|
||||
if (scsi_hard_disks[i][j] != 0xff) {
|
||||
if (scsi_hard_disks[i][j] != 0xff)
|
||||
SCSIDevices[i][j].LunType = SCSI_DISK;
|
||||
} else if (scsi_cdrom_drives[i][j] != 0xff) {
|
||||
else if (scsi_cdrom_drives[i][j] != 0xff)
|
||||
SCSIDevices[i][j].LunType = SCSI_CDROM;
|
||||
} else if (scsi_zip_drives[i][j] != 0xff) {
|
||||
else if (scsi_zip_drives[i][j] != 0xff)
|
||||
SCSIDevices[i][j].LunType = SCSI_ZIP;
|
||||
} else {
|
||||
else
|
||||
SCSIDevices[i][j].LunType = SCSI_NONE;
|
||||
}
|
||||
SCSIDevices[i][j].CmdBuffer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (scsi_cards[scsi_card_current].device)
|
||||
device_add(scsi_cards[scsi_card_current].device);
|
||||
device_add(scsi_cards[scsi_card_current].device);
|
||||
|
||||
scsi_card_last = scsi_card_current;
|
||||
}
|
||||
|
||||
|
||||
void scsi_card_reset(void)
|
||||
{
|
||||
void *p = NULL;
|
||||
|
||||
if (scsi_cards[scsi_card_current].device) {
|
||||
p = device_get_priv(scsi_cards[scsi_card_current].device);
|
||||
if (p) {
|
||||
if (scsi_cards[scsi_card_current].reset) {
|
||||
scsi_cards[scsi_card_current].reset(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Initialization function for the SCSI layer */
|
||||
void SCSIReset(uint8_t id, uint8_t lun)
|
||||
{
|
||||
@@ -200,20 +186,16 @@ void SCSIReset(uint8_t id, uint8_t lun)
|
||||
uint8_t zip_id = scsi_zip_drives[id][lun];
|
||||
uint8_t hdc_id = scsi_hard_disks[id][lun];
|
||||
|
||||
if (hdc_id != 0xff) {
|
||||
scsi_hd_reset(hdc_id);
|
||||
if (hdc_id != 0xff)
|
||||
SCSIDevices[id][lun].LunType = SCSI_DISK;
|
||||
} else {
|
||||
if (cdrom_id != 0xff) {
|
||||
cdrom_reset(cdrom_id);
|
||||
SCSIDevices[id][lun].LunType = SCSI_CDROM;
|
||||
} else if (zip_id != 0xff) {
|
||||
zip_reset(zip_id);
|
||||
SCSIDevices[id][lun].LunType = SCSI_ZIP;
|
||||
} else {
|
||||
SCSIDevices[id][lun].LunType = SCSI_NONE;
|
||||
}
|
||||
}
|
||||
else if (cdrom_id != 0xff)
|
||||
SCSIDevices[id][lun].LunType = SCSI_CDROM;
|
||||
else if (zip_id != 0xff)
|
||||
SCSIDevices[id][lun].LunType = SCSI_ZIP;
|
||||
else
|
||||
SCSIDevices[id][lun].LunType = SCSI_NONE;
|
||||
|
||||
scsi_device_reset(id, lun);
|
||||
|
||||
if (SCSIDevices[id][lun].CmdBuffer != NULL) {
|
||||
free(SCSIDevices[id][lun].CmdBuffer);
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* SCSI controller handler header.
|
||||
*
|
||||
* Version: @(#)scsi_h 1.0.15 2018/03/21
|
||||
* Version: @(#)scsi_h 1.0.16 2018/03/28
|
||||
*
|
||||
* Authors: TheCollector1995, <mariogplayer@gmail.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -103,6 +103,13 @@
|
||||
#define GPMODE_CAPABILITIES_PAGE 0x2a
|
||||
#define GPMODE_ALL_PAGES 0x3f
|
||||
|
||||
/* Mode page codes for presence */
|
||||
#define GPMODEP_R_W_ERROR_PAGE 0x0000000000000002LL
|
||||
#define GPMODEP_CDROM_PAGE 0x0000000000002000LL
|
||||
#define GPMODEP_CDROM_AUDIO_PAGE 0x0000000000004000LL
|
||||
#define GPMODEP_CAPABILITIES_PAGE 0x0000040000000000LL
|
||||
#define GPMODEP_ALL_PAGES 0x8000000000000000LL
|
||||
|
||||
/* SCSI Status Codes */
|
||||
#define SCSI_STATUS_OK 0
|
||||
#define SCSI_STATUS_CHECK_CONDITION 2
|
||||
@@ -306,7 +313,6 @@ extern char *scsi_card_get_internal_name(int card);
|
||||
extern int scsi_card_get_from_internal_name(char *s);
|
||||
extern void scsi_mutex(uint8_t start);
|
||||
extern void scsi_card_init(void);
|
||||
extern void scsi_card_reset(void);
|
||||
|
||||
extern uint8_t scsi_hard_disks[16][8];
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
* made by Adaptec, Inc. These controllers were designed for
|
||||
* the ISA bus.
|
||||
*
|
||||
* Version: @(#)scsi_aha154x.c 1.0.40 2018/03/18
|
||||
* Version: @(#)scsi_aha154x.c 1.0.40 2018/04/11
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Original Buslogic version by SA1988 and Miran Grca.
|
||||
@@ -30,11 +30,11 @@
|
||||
#include "../mem.h"
|
||||
#include "../mca.h"
|
||||
#include "../rom.h"
|
||||
#include "../device.h"
|
||||
#include "../nvr.h"
|
||||
#include "../dma.h"
|
||||
#include "../pic.h"
|
||||
#include "../timer.h"
|
||||
#include "../device.h"
|
||||
#include "../plat.h"
|
||||
#include "../cpu/cpu.h"
|
||||
#include "scsi.h"
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
* 1 - BT-545S ISA;
|
||||
* 2 - BT-958D PCI
|
||||
*
|
||||
* Version: @(#)scsi_buslogic.c 1.0.36 2018/03/18
|
||||
* Version: @(#)scsi_buslogic.c 1.0.37 2018/03/28
|
||||
*
|
||||
* Authors: TheCollector1995, <mariogplayer@gmail.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -33,12 +33,12 @@
|
||||
#include "../mem.h"
|
||||
#include "../mca.h"
|
||||
#include "../rom.h"
|
||||
#include "../device.h"
|
||||
#include "../nvr.h"
|
||||
#include "../dma.h"
|
||||
#include "../pic.h"
|
||||
#include "../pci.h"
|
||||
#include "../timer.h"
|
||||
#include "../device.h"
|
||||
#include "../plat.h"
|
||||
#include "scsi.h"
|
||||
#include "scsi_buslogic.h"
|
||||
@@ -529,6 +529,7 @@ buslogic_param_len(void *p)
|
||||
case 0x91:
|
||||
return 2;
|
||||
case 0x94:
|
||||
case 0xFB:
|
||||
return 3;
|
||||
case 0x93: /* Valid only for VLB */
|
||||
return (bl->chip == CHIP_BUSLOGIC_VLB) ? 1 : 0;
|
||||
@@ -550,7 +551,7 @@ static void
|
||||
BuslogicSCSIBIOSDMATransfer(ESCMD *ESCSICmd, uint8_t TargetID, uint8_t LUN, int dir)
|
||||
{
|
||||
uint32_t DataPointer = ESCSICmd->DataPointer;
|
||||
uint32_t DataLength = ESCSICmd->DataLength;
|
||||
int DataLength = ESCSICmd->DataLength;
|
||||
uint32_t Address;
|
||||
uint32_t TransferLength;
|
||||
|
||||
@@ -997,6 +998,9 @@ buslogic_cmds(void *p)
|
||||
|
||||
dev->DataReply = 0;
|
||||
break;
|
||||
case 0xFB:
|
||||
dev->DataReplyLeft = dev->CmdBuf[2];
|
||||
break;
|
||||
default:
|
||||
dev->DataReplyLeft = 0;
|
||||
dev->Status |= STAT_INVCMD;
|
||||
@@ -1583,6 +1587,7 @@ buslogic_init(const device_t *info)
|
||||
dev->cdrom_boot = 1;
|
||||
dev->bit32 = 1;
|
||||
dev->ha_bps = 20000000.0; /* ultra SCSI */
|
||||
dev->max_id = 15; /* wide SCSI */
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1683,7 +1688,7 @@ static const device_config_t BT_ISA_Config[] = {
|
||||
"0x134", 0x134
|
||||
},
|
||||
{
|
||||
""
|
||||
"", 0
|
||||
}
|
||||
},
|
||||
},
|
||||
@@ -1709,7 +1714,7 @@ static const device_config_t BT_ISA_Config[] = {
|
||||
"IRQ 15", 15
|
||||
},
|
||||
{
|
||||
""
|
||||
"", 0
|
||||
}
|
||||
},
|
||||
},
|
||||
@@ -1726,7 +1731,7 @@ static const device_config_t BT_ISA_Config[] = {
|
||||
"DMA 7", 7
|
||||
},
|
||||
{
|
||||
""
|
||||
"", 0
|
||||
}
|
||||
},
|
||||
},
|
||||
@@ -1746,7 +1751,7 @@ static const device_config_t BT_ISA_Config[] = {
|
||||
"D800H", 0xd8000
|
||||
},
|
||||
{
|
||||
""
|
||||
"", 0
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* The generic SCSI device command handler.
|
||||
*
|
||||
* Version: @(#)scsi_device.c 1.0.15 2018/03/16
|
||||
* Version: @(#)scsi_device.c 1.0.16 2018/03/26
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
@@ -22,10 +22,10 @@
|
||||
#include <wchar.h>
|
||||
#include "../86box.h"
|
||||
#include "../device.h"
|
||||
#include "../cdrom/cdrom.h"
|
||||
#include "../disk/hdd.h"
|
||||
#include "../disk/zip.h"
|
||||
#include "scsi.h"
|
||||
#include "../cdrom/cdrom.h"
|
||||
#include "scsi_disk.h"
|
||||
|
||||
|
||||
@@ -41,8 +41,8 @@ static uint8_t scsi_device_target_command(int lun_type, uint8_t id, uint8_t *cdb
|
||||
}
|
||||
else if (lun_type == SCSI_CDROM)
|
||||
{
|
||||
cdrom_command(id, cdb);
|
||||
return cdrom_CDROM_PHASE_to_scsi(id);
|
||||
cdrom_command(cdrom[id], cdb);
|
||||
return cdrom_CDROM_PHASE_to_scsi(cdrom[id]);
|
||||
}
|
||||
else if (lun_type == SCSI_ZIP)
|
||||
{
|
||||
@@ -64,7 +64,7 @@ static void scsi_device_target_phase_callback(int lun_type, uint8_t id)
|
||||
}
|
||||
else if (lun_type == SCSI_CDROM)
|
||||
{
|
||||
cdrom_phase_callback(id);
|
||||
cdrom_phase_callback(cdrom[id]);
|
||||
}
|
||||
else if (lun_type == SCSI_ZIP)
|
||||
{
|
||||
@@ -85,7 +85,7 @@ static int scsi_device_target_err_stat_to_scsi(int lun_type, uint8_t id)
|
||||
}
|
||||
else if (lun_type == SCSI_CDROM)
|
||||
{
|
||||
return cdrom_CDROM_PHASE_to_scsi(id);
|
||||
return cdrom_CDROM_PHASE_to_scsi(cdrom[id]);
|
||||
}
|
||||
else if (lun_type == SCSI_ZIP)
|
||||
{
|
||||
@@ -110,7 +110,7 @@ static void scsi_device_target_save_cdb_byte(int lun_type, uint8_t id, uint8_t c
|
||||
}
|
||||
else if (lun_type == SCSI_ZIP)
|
||||
{
|
||||
zip[id].request_length = cdb_byte;
|
||||
zip[id]->request_length = cdb_byte;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -137,7 +137,7 @@ int64_t scsi_device_get_callback(uint8_t scsi_id, uint8_t scsi_lun)
|
||||
break;
|
||||
case SCSI_ZIP:
|
||||
id = scsi_zip_drives[scsi_id][scsi_lun];
|
||||
return zip[id].callback;
|
||||
return zip[id]->callback;
|
||||
break;
|
||||
default:
|
||||
return -1LL;
|
||||
@@ -164,7 +164,7 @@ uint8_t *scsi_device_sense(uint8_t scsi_id, uint8_t scsi_lun)
|
||||
break;
|
||||
case SCSI_ZIP:
|
||||
id = scsi_zip_drives[scsi_id][scsi_lun];
|
||||
return zip[id].sense;
|
||||
return zip[id]->sense;
|
||||
break;
|
||||
default:
|
||||
return scsi_null_device_sense;
|
||||
@@ -187,7 +187,7 @@ void scsi_device_request_sense(uint8_t scsi_id, uint8_t scsi_lun, uint8_t *buffe
|
||||
break;
|
||||
case SCSI_CDROM:
|
||||
id = scsi_cdrom_drives[scsi_id][scsi_lun];
|
||||
cdrom_request_sense_for_scsi(id, buffer, alloc_length);
|
||||
cdrom_request_sense_for_scsi(cdrom[id], buffer, alloc_length);
|
||||
break;
|
||||
case SCSI_ZIP:
|
||||
id = scsi_zip_drives[scsi_id][scsi_lun];
|
||||
@@ -200,7 +200,7 @@ void scsi_device_request_sense(uint8_t scsi_id, uint8_t scsi_lun, uint8_t *buffe
|
||||
}
|
||||
|
||||
|
||||
void scsi_device_type_data(uint8_t scsi_id, uint8_t scsi_lun, uint8_t *type, uint8_t *rmb)
|
||||
void scsi_device_reset(uint8_t scsi_id, uint8_t scsi_lun)
|
||||
{
|
||||
uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType;
|
||||
|
||||
@@ -210,8 +210,28 @@ void scsi_device_type_data(uint8_t scsi_id, uint8_t scsi_lun, uint8_t *type, uin
|
||||
{
|
||||
case SCSI_DISK:
|
||||
id = scsi_hard_disks[scsi_id][scsi_lun];
|
||||
*type = 0x00;
|
||||
*rmb = (hdd[id].bus == HDD_BUS_SCSI_REMOVABLE) ? 0x80 : 0x00;
|
||||
scsi_hd_reset(id);
|
||||
break;
|
||||
case SCSI_CDROM:
|
||||
id = scsi_cdrom_drives[scsi_id][scsi_lun];
|
||||
cdrom_reset(cdrom[id]);
|
||||
break;
|
||||
case SCSI_ZIP:
|
||||
id = scsi_zip_drives[scsi_id][scsi_lun];
|
||||
zip_reset(id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void scsi_device_type_data(uint8_t scsi_id, uint8_t scsi_lun, uint8_t *type, uint8_t *rmb)
|
||||
{
|
||||
uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType;
|
||||
|
||||
switch (lun_type)
|
||||
{
|
||||
case SCSI_DISK:
|
||||
*type = *rmb = 0x00;
|
||||
break;
|
||||
case SCSI_CDROM:
|
||||
*type = 0x05;
|
||||
@@ -222,7 +242,7 @@ void scsi_device_type_data(uint8_t scsi_id, uint8_t scsi_lun, uint8_t *type, uin
|
||||
*rmb = 0x80;
|
||||
break;
|
||||
default:
|
||||
*type = *rmb = 0xFF;
|
||||
*type = *rmb = 0xff;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -241,7 +261,7 @@ int scsi_device_read_capacity(uint8_t scsi_id, uint8_t scsi_lun, uint8_t *cdb, u
|
||||
return scsi_hd_read_capacity(id, cdb, buffer, len);
|
||||
case SCSI_CDROM:
|
||||
id = scsi_cdrom_drives[scsi_id][scsi_lun];
|
||||
return cdrom_read_capacity(id, cdb, buffer, len);
|
||||
return cdrom_read_capacity(cdrom[id], cdb, buffer, len);
|
||||
case SCSI_ZIP:
|
||||
id = scsi_zip_drives[scsi_id][scsi_lun];
|
||||
return zip_read_capacity(id, cdb, buffer, len);
|
||||
@@ -304,7 +324,7 @@ int scsi_device_cdb_length(uint8_t scsi_id, uint8_t scsi_lun)
|
||||
return cdrom[id]->cdb_len;
|
||||
case SCSI_ZIP:
|
||||
id = scsi_zip_drives[scsi_id][scsi_lun];
|
||||
return zip[id].cdb_len;
|
||||
return zip[id]->cdb_len;
|
||||
default:
|
||||
return 12;
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Definitions for the generic SCSI device command handler.
|
||||
*
|
||||
* Version: @(#)scsi_device.h 1.0.6 2018/03/07
|
||||
* Version: @(#)scsi_device.h 1.0.7 2018/03/29
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
@@ -39,6 +39,7 @@ extern int64_t scsi_device_get_callback(uint8_t scsi_id, uint8_t scsi_lun);
|
||||
extern void scsi_device_request_sense(uint8_t scsi_id, uint8_t scsi_lun,
|
||||
uint8_t *buffer,
|
||||
uint8_t alloc_length);
|
||||
extern void scsi_device_reset(uint8_t scsi_id, uint8_t scsi_lun);
|
||||
extern int scsi_device_read_capacity(uint8_t id, uint8_t lun,
|
||||
uint8_t *cdb, uint8_t *buffer,
|
||||
uint32_t *len);
|
||||
|
||||
2262
src/scsi/scsi_disk.c
2262
src/scsi/scsi_disk.c
File diff suppressed because it is too large
Load Diff
@@ -6,54 +6,31 @@
|
||||
*
|
||||
* Emulation of SCSI fixed and removable disks.
|
||||
*
|
||||
* Version: @(#)scsi_disk.h 1.0.3 2017/10/14
|
||||
* Version: @(#)scsi_disk.h 1.0.4 2018/04/24
|
||||
*
|
||||
* Author: Miran Grca, <mgrca8@gmail.com>
|
||||
* Copyright 2017 Miran Grca.
|
||||
* Copyright 2017,2018 Miran Grca.
|
||||
*/
|
||||
|
||||
|
||||
typedef struct {
|
||||
/* Stuff for SCSI hard disks. */
|
||||
uint8_t cdb[16];
|
||||
uint8_t current_cdb[16];
|
||||
uint8_t max_cdb_len;
|
||||
int requested_blocks;
|
||||
int max_blocks_at_once;
|
||||
uint8_t status, phase,
|
||||
error,
|
||||
current_cdb[16],
|
||||
sense[256];
|
||||
|
||||
uint16_t request_length;
|
||||
int block_total;
|
||||
int all_blocks_total;
|
||||
uint32_t packet_len;
|
||||
int packet_status;
|
||||
uint8_t status;
|
||||
uint8_t phase;
|
||||
uint32_t pos;
|
||||
int callback;
|
||||
int total_read;
|
||||
int unit_attention;
|
||||
uint8_t sense[256];
|
||||
uint8_t previous_command;
|
||||
uint8_t error;
|
||||
uint32_t sector_pos;
|
||||
uint32_t sector_len;
|
||||
uint32_t seek_pos;
|
||||
int data_pos;
|
||||
int old_len;
|
||||
int request_pos;
|
||||
uint8_t hd_cdb[16];
|
||||
|
||||
int requested_blocks, block_total,
|
||||
packet_status, callback,
|
||||
block_descriptor_len,
|
||||
total_length, do_page_save;
|
||||
|
||||
uint32_t sector_pos, sector_len,
|
||||
packet_len;
|
||||
|
||||
uint64_t current_page_code;
|
||||
int current_page_len;
|
||||
|
||||
int current_page_pos;
|
||||
|
||||
int mode_select_phase;
|
||||
|
||||
int total_length;
|
||||
int written_length;
|
||||
|
||||
int do_page_save;
|
||||
int block_descriptor_len;
|
||||
|
||||
uint8_t *temp_buffer;
|
||||
} scsi_hard_disk_t;
|
||||
@@ -63,9 +40,6 @@ extern scsi_hard_disk_t shdc[HDD_NUM];
|
||||
extern FILE *shdf[HDD_NUM];
|
||||
|
||||
|
||||
extern void scsi_disk_insert(uint8_t id);
|
||||
extern void scsi_loadhd(int scsi_id, int scsi_lun, int id);
|
||||
extern void scsi_reloadhd(int id);
|
||||
extern void scsi_unloadhd(int scsi_id, int scsi_lun, int id);
|
||||
|
||||
int scsi_hd_read_capacity(uint8_t id, uint8_t *cdb, uint8_t *buffer, uint32_t *len);
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
* Implementation of the NCR 5380 series of SCSI Host Adapters
|
||||
* made by NCR. These controllers were designed for the ISA bus.
|
||||
*
|
||||
* Version: @(#)scsi_ncr5380.c 1.0.12 2018/03/18
|
||||
* Version: @(#)scsi_ncr5380.c 1.0.13 2018/04/11
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* TheCollector1995, <mariogplayer@gmail.com>
|
||||
@@ -34,8 +34,8 @@
|
||||
#include "../mca.h"
|
||||
#include "../mem.h"
|
||||
#include "../rom.h"
|
||||
#include "../nvr.h"
|
||||
#include "../device.h"
|
||||
#include "../nvr.h"
|
||||
#include "../timer.h"
|
||||
#include "../plat.h"
|
||||
#include "scsi.h"
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
* NCR and later Symbios and LSI. This controller was designed
|
||||
* for the PCI bus.
|
||||
*
|
||||
* Version: @(#)scsi_ncr53c810.c 1.0.10 2018/03/18
|
||||
* Version: @(#)scsi_ncr53c810.c 1.0.11 2018/03/28
|
||||
*
|
||||
* Authors: Paul Brook (QEMU)
|
||||
* Artyom Tarasenko (QEMU)
|
||||
@@ -35,8 +35,8 @@
|
||||
#include "../mem.h"
|
||||
#include "../rom.h"
|
||||
#include "../pci.h"
|
||||
#include "../nvr.h"
|
||||
#include "../device.h"
|
||||
#include "../nvr.h"
|
||||
#include "../timer.h"
|
||||
#include "../plat.h"
|
||||
#include "scsi.h"
|
||||
@@ -329,6 +329,8 @@ ncr53c810_irq_on_rsl(ncr53c810_t *dev)
|
||||
static void
|
||||
ncr53c810_soft_reset(ncr53c810_t *dev)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
ncr53c810_log("LSI Reset\n");
|
||||
dev->timer_period = dev->timer_enabled = 0;
|
||||
|
||||
@@ -383,13 +385,18 @@ ncr53c810_soft_reset(ncr53c810_t *dev)
|
||||
dev->last_level = 0;
|
||||
dev->gpreg0 = 0;
|
||||
dev->sstop = 1;
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
for (j = 0; j < 8; j++)
|
||||
scsi_device_reset(i, j);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ncr53c810_read(ncr53c810_t *dev, uint32_t addr, uint8_t *buf, uint32_t len)
|
||||
{
|
||||
int i = 0;
|
||||
uint32_t i = 0;
|
||||
|
||||
ncr53c810_log("ncr53c810_read(): %08X-%08X, length %i\n", addr, (addr + len - 1), len);
|
||||
|
||||
@@ -407,7 +414,7 @@ ncr53c810_read(ncr53c810_t *dev, uint32_t addr, uint8_t *buf, uint32_t len)
|
||||
static void
|
||||
ncr53c810_write(ncr53c810_t *dev, uint32_t addr, uint8_t *buf, uint32_t len)
|
||||
{
|
||||
int i = 0;
|
||||
uint32_t i = 0;
|
||||
|
||||
ncr53c810_log("ncr53c810_write(): %08X-%08X, length %i\n", addr, (addr + len - 1), len);
|
||||
|
||||
@@ -582,13 +589,14 @@ ncr53c810_command_complete(void *priv, uint32_t status)
|
||||
static void
|
||||
ncr53c810_do_dma(ncr53c810_t *dev, int out, uint8_t id)
|
||||
{
|
||||
uint32_t addr, count, tdbc;
|
||||
uint32_t addr, tdbc;
|
||||
int count;
|
||||
|
||||
scsi_device_t *sd;
|
||||
|
||||
sd = &SCSIDevices[id][dev->current_lun];
|
||||
|
||||
if ((((id) == -1) && !scsi_device_present(id, dev->current_lun))) {
|
||||
if ((!scsi_device_present(id, dev->current_lun))) {
|
||||
ncr53c810_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: Device not present when attempting to do DMA\n", id, dev->current_lun, dev->last_command);
|
||||
return;
|
||||
}
|
||||
@@ -673,7 +681,7 @@ ncr53c810_do_command(ncr53c810_t *dev, uint8_t id)
|
||||
dev->command_complete = 0;
|
||||
|
||||
sd = &SCSIDevices[id][dev->current_lun];
|
||||
if (((id == -1) || !scsi_device_present(id, dev->current_lun))) {
|
||||
if (!scsi_device_present(id, dev->current_lun)) {
|
||||
ncr53c810_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: Bad Selection\n", id, dev->current_lun, buf[0]);
|
||||
ncr53c810_bad_selection(dev, id);
|
||||
return 0;
|
||||
@@ -747,7 +755,7 @@ ncr53c810_do_status(ncr53c810_t *dev)
|
||||
static void
|
||||
ncr53c810_do_msgin(ncr53c810_t *dev)
|
||||
{
|
||||
int len;
|
||||
uint32_t len;
|
||||
ncr53c810_log("Message in len=%d/%d\n", dev->dbc, dev->msg_len);
|
||||
dev->sfbr = dev->msg[0];
|
||||
len = dev->msg_len;
|
||||
@@ -1067,7 +1075,7 @@ again:
|
||||
}
|
||||
dev->sstat0 |= NCR_SSTAT0_WOA;
|
||||
dev->scntl1 &= ~NCR_SCNTL1_IARB;
|
||||
if (((id == -1) || !scsi_device_present(id, 0))) {
|
||||
if (!scsi_device_present(id, 0)) {
|
||||
ncr53c810_bad_selection(dev, id);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -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.20 2018/03/18
|
||||
* Version: @(#)scsi_x54x.c 1.0.21 2018/03/28
|
||||
*
|
||||
* Authors: TheCollector1995, <mariogplayer@gmail.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -36,8 +36,8 @@
|
||||
#include "../mca.h"
|
||||
#include "../mem.h"
|
||||
#include "../rom.h"
|
||||
#include "../nvr.h"
|
||||
#include "../device.h"
|
||||
#include "../nvr.h"
|
||||
#include "../timer.h"
|
||||
#include "../plat.h"
|
||||
#include "../cpu/cpu.h"
|
||||
@@ -720,8 +720,7 @@ x54x_get_length(Req_t *req, int Is24bit)
|
||||
uint32_t DataPointer, DataLength;
|
||||
uint32_t SGEntryLength = (Is24bit ? sizeof(SGE) : sizeof(SGE32));
|
||||
SGE32 SGBuffer;
|
||||
uint32_t DataToTransfer = 0;
|
||||
int i = 0;
|
||||
uint32_t DataToTransfer = 0, i = 0;
|
||||
|
||||
if (Is24bit) {
|
||||
DataPointer = ADDR_TO_U32(req->CmdBlock.old.DataPointer);
|
||||
@@ -793,8 +792,7 @@ x54x_buf_dma_transfer(Req_t *req, int Is24bit, int TransferLength, int dir)
|
||||
{
|
||||
uint32_t DataPointer, DataLength;
|
||||
uint32_t SGEntryLength = (Is24bit ? sizeof(SGE) : sizeof(SGE32));
|
||||
uint32_t Address;
|
||||
int i = 0;
|
||||
uint32_t Address, i;
|
||||
int32_t BufLen = SCSIDevices[req->TargetID][req->LUN].BufferLength;
|
||||
uint8_t read_from_host = (dir && ((req->CmdBlock.common.ControlByte == CCB_DATA_XFER_OUT) || (req->CmdBlock.common.ControlByte == 0x00)));
|
||||
uint8_t write_to_host = (!dir && ((req->CmdBlock.common.ControlByte == CCB_DATA_XFER_IN) || (req->CmdBlock.common.ControlByte == 0x00)));
|
||||
@@ -823,7 +821,7 @@ x54x_buf_dma_transfer(Req_t *req, int Is24bit, int TransferLength, int dir)
|
||||
x54x_rd_sge(Is24bit, DataPointer + i, &SGBuffer);
|
||||
|
||||
Address = SGBuffer.SegmentPointer;
|
||||
DataToTransfer = MIN(SGBuffer.Segment, BufLen);
|
||||
DataToTransfer = MIN((int) SGBuffer.Segment, BufLen);
|
||||
|
||||
if (read_from_host && DataToTransfer) {
|
||||
x54x_log("Reading S/G segment %i: length %i, pointer %08X\n", i, DataToTransfer, Address);
|
||||
@@ -851,9 +849,9 @@ x54x_buf_dma_transfer(Req_t *req, int Is24bit, int TransferLength, int dir)
|
||||
|
||||
if ((DataLength > 0) && (BufLen > 0) && (req->CmdBlock.common.ControlByte < 0x03)) {
|
||||
if (read_from_host)
|
||||
DMAPageRead(Address, SCSIDevices[req->TargetID][req->LUN].CmdBuffer, MIN(BufLen, DataLength));
|
||||
DMAPageRead(Address, SCSIDevices[req->TargetID][req->LUN].CmdBuffer, MIN(BufLen, (int) DataLength));
|
||||
else if (write_to_host)
|
||||
DMAPageWrite(Address, SCSIDevices[req->TargetID][req->LUN].CmdBuffer, MIN(BufLen, DataLength));
|
||||
DMAPageWrite(Address, SCSIDevices[req->TargetID][req->LUN].CmdBuffer, MIN(BufLen, (int) DataLength));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1061,7 +1059,6 @@ x54x_req_setup(x54x_t *dev, uint32_t CCBPointer, Mailbox32_t *Mailbox32)
|
||||
{
|
||||
Req_t *req = &dev->Req;
|
||||
uint8_t id, lun;
|
||||
uint8_t max_id = SCSI_ID_MAX-1;
|
||||
|
||||
/* Fetch data from the Command Control Block. */
|
||||
DMAPageRead(CCBPointer, (uint8_t *)&req->CmdBlock, sizeof(CCB32));
|
||||
@@ -1074,7 +1071,7 @@ x54x_req_setup(x54x_t *dev, uint32_t CCBPointer, Mailbox32_t *Mailbox32)
|
||||
|
||||
id = req->TargetID;
|
||||
lun = req->LUN;
|
||||
if ((id > max_id) || (lun > 7)) {
|
||||
if ((id > dev->max_id) || (lun > 7)) {
|
||||
x54x_log("SCSI Target ID %i or LUN %i is not valid\n",id,lun);
|
||||
x54x_mbi_setup(dev, CCBPointer, &req->CmdBlock,
|
||||
CCB_SELECTION_TIMEOUT, SCSI_STATUS_OK, MBI_ERROR);
|
||||
@@ -1110,12 +1107,14 @@ x54x_req_setup(x54x_t *dev, uint32_t CCBPointer, Mailbox32_t *Mailbox32)
|
||||
}
|
||||
if (req->CmdBlock.common.Opcode == 0x81) {
|
||||
x54x_log("Bus reset opcode\n");
|
||||
scsi_device_reset(id, lun);
|
||||
x54x_mbi_setup(dev, req->CCBPointer, &req->CmdBlock,
|
||||
CCB_COMPLETE, SCSI_STATUS_OK, MBI_SUCCESS);
|
||||
x54x_log("%s: Callback: Send incoming mailbox\n", dev->name);
|
||||
x54x_notify(dev);
|
||||
return;
|
||||
}
|
||||
|
||||
if (req->CmdBlock.common.ControlByte > 0x03) {
|
||||
x54x_log("Invalid control byte: %02X\n",
|
||||
req->CmdBlock.common.ControlByte);
|
||||
@@ -1276,7 +1275,12 @@ x54x_cmd_callback(void *priv)
|
||||
double period;
|
||||
x54x_t *dev = (x54x_t *) x54x_dev;
|
||||
|
||||
if ((dev->Status & STAT_INIT) || (!dev->MailboxInit && !dev->BIOSMailboxInit) || (!dev->MailboxReq && !dev->BIOSMailboxReq)) {
|
||||
int mailboxes_present, bios_mailboxes_present;
|
||||
|
||||
mailboxes_present = (!(dev->Status & STAT_INIT) && dev->MailboxInit && dev->MailboxReq);
|
||||
bios_mailboxes_present = (dev->ven_callback && dev->BIOSMailboxInit && dev->BIOSMailboxReq);
|
||||
|
||||
if (!mailboxes_present && !bios_mailboxes_present) {
|
||||
/* If we did not get anything, do nothing and wait 10 us. */
|
||||
dev->timer_period = 10LL * TIMER_USEC;
|
||||
return;
|
||||
@@ -1284,11 +1288,21 @@ x54x_cmd_callback(void *priv)
|
||||
|
||||
dev->temp_period = dev->media_period = 0LL;
|
||||
|
||||
if (!(x54x_dev->Status & STAT_INIT) && x54x_dev->MailboxInit && dev->MailboxReq)
|
||||
x54x_do_mail(dev);
|
||||
|
||||
if (dev->ven_callback)
|
||||
if (!mailboxes_present) {
|
||||
/* Do only BIOS mailboxes. */
|
||||
dev->ven_callback(dev);
|
||||
} else if (!bios_mailboxes_present) {
|
||||
/* Do only normal mailboxes. */
|
||||
x54x_do_mail(dev);
|
||||
} else {
|
||||
/* Do both kinds of mailboxes. */
|
||||
if (dev->callback_phase)
|
||||
dev->ven_callback(dev);
|
||||
else
|
||||
x54x_do_mail(dev);
|
||||
|
||||
dev->callback_phase = (dev->callback_phase + 1) & 0x01;
|
||||
}
|
||||
|
||||
period = (1000000.0 / x54x_dev->ha_bps) * ((double) TIMER_USEC) * ((double) dev->temp_period);
|
||||
dev->timer_period = dev->media_period + ((int64_t) period) + (40LL * TIMER_USEC);
|
||||
@@ -1319,7 +1333,10 @@ x54x_in(uint16_t port, void *priv)
|
||||
break;
|
||||
|
||||
case 2:
|
||||
ret = dev->Interrupt;
|
||||
if (dev->int_geom_writable)
|
||||
ret = dev->Interrupt;
|
||||
else
|
||||
ret = dev->Interrupt & ~0x70;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
@@ -1406,11 +1423,14 @@ x54x_reset_poll(void *priv)
|
||||
static void
|
||||
x54x_reset(x54x_t *dev)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
clear_irq(dev);
|
||||
if (dev->int_geom_writable)
|
||||
dev->Geometry = 0x80;
|
||||
else
|
||||
dev->Geometry = 0x00;
|
||||
dev->callback_phase = 0;
|
||||
dev->Command = 0xFF;
|
||||
dev->CmdParam = 0;
|
||||
dev->CmdParamLeft = 0;
|
||||
@@ -1422,9 +1442,14 @@ x54x_reset(x54x_t *dev)
|
||||
dev->MailboxCount = 0;
|
||||
dev->MailboxOutPosCur = 0;
|
||||
|
||||
if (dev->ven_reset) {
|
||||
dev->ven_reset(dev);
|
||||
/* Reset all devices on controller reset. */
|
||||
for (i = 0; i < 16; i++) {
|
||||
for (j = 0; j < 8; j++)
|
||||
scsi_device_reset(i, j);
|
||||
}
|
||||
|
||||
if (dev->ven_reset)
|
||||
dev->ven_reset(dev);
|
||||
}
|
||||
|
||||
|
||||
@@ -1476,6 +1501,14 @@ x54x_out(uint16_t port, uint8_t val, void *priv)
|
||||
break;
|
||||
}
|
||||
|
||||
if (val & CTRL_SCRST) {
|
||||
/* Reset all devices on SCSI bus reset. */
|
||||
for (i = 0; i < 16; i++) {
|
||||
for (j = 0; j < 8; j++)
|
||||
scsi_device_reset(i, j);
|
||||
}
|
||||
}
|
||||
|
||||
if (val & CTRL_IRST) {
|
||||
clear_irq(dev);
|
||||
x54x_log("Interrupt reset: ");
|
||||
@@ -1643,7 +1676,7 @@ x54x_out(uint16_t port, uint8_t val, void *priv)
|
||||
if (dev->ven_get_host_id)
|
||||
host_id = dev->ven_get_host_id(dev);
|
||||
|
||||
for (i=0; i<SCSI_ID_MAX; i++) {
|
||||
for (i=0; i<8; i++) {
|
||||
dev->DataBuf[i] = 0x00;
|
||||
|
||||
/* Skip the HA .. */
|
||||
@@ -1902,6 +1935,7 @@ x54x_init(const device_t *info)
|
||||
dev->type = info->local;
|
||||
|
||||
dev->bus = info->flags;
|
||||
dev->callback_phase = 0;
|
||||
|
||||
timer_add(x54x_reset_poll, &dev->ResetCB, &dev->ResetCB, dev);
|
||||
dev->timer_period = 10LL * TIMER_USEC;
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
* of SCSI Host Adapters made by Mylex.
|
||||
* These controllers were designed for various buses.
|
||||
*
|
||||
* Version: @(#)scsi_x54x.h 1.0.6 2018/03/18
|
||||
* Version: @(#)scsi_x54x.h 1.0.7 2018/04/06
|
||||
*
|
||||
* Authors: TheCollector1995, <mariogplayer@gmail.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -333,6 +333,7 @@ typedef struct {
|
||||
char name[16]; /* name of device */
|
||||
|
||||
int64_t timer_period, temp_period;
|
||||
uint8_t callback_phase;
|
||||
int64_t media_period;
|
||||
double ha_bps; /* bytes per second */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user