Added support for up to four SCSI controllers, closes #343.

This commit is contained in:
OBattler
2021-07-22 20:13:44 +02:00
parent f31e8b27d5
commit 729b6d5069
25 changed files with 665 additions and 313 deletions

View File

@@ -26,6 +26,7 @@
#define HAVE_STDARG_H
#include <86box/86box.h>
#include <86box/device.h>
#include <86box/machine.h>
#include <86box/hdc.h>
#include <86box/hdd.h>
#include <86box/plat.h>
@@ -45,8 +46,10 @@
#endif
int scsi_card_current = 0;
int scsi_card_last = 0;
int scsi_card_current_legacy = 0;
int scsi_card_current[SCSI_BUS_MAX] = { 0, 0 };
static uint8_t next_scsi_bus = 0;
typedef const struct {
@@ -88,6 +91,27 @@ static SCSI_CARD scsi_cards[] = {
};
void
scsi_reset(void)
{
next_scsi_bus = 0;
}
uint8_t
scsi_get_bus(void)
{
uint8_t ret = next_scsi_bus;
if (next_scsi_bus >= SCSI_BUS_MAX)
return 0xff;
next_scsi_bus++;
return ret;
}
int
scsi_card_available(int card)
{
@@ -139,10 +163,27 @@ scsi_card_get_from_internal_name(char *s)
void
scsi_card_init(void)
{
if (!scsi_cards[scsi_card_current].device)
return;
int i = 0, max = SCSI_BUS_MAX;
device_add(scsi_cards[scsi_card_current].device);
/* On-board SCSI controllers get the first bus, so if one is present,
increase our instance number here. */
if (machines[machine].flags & MACHINE_SCSI)
max--;
scsi_card_last = scsi_card_current;
/* This is for grandfathering legacy single-controller configurations. */
if (scsi_cards[scsi_card_current_legacy].device) {
device_add(scsi_cards[scsi_card_current_legacy].device);
max--;
}
/* Do not initialize any controllers if we have do not have any SCSI
bus left. */
if (max > 0) {
for (i = 0; i < max; i++) {
if (!scsi_cards[scsi_card_current[i]].device)
continue;
device_add_inst(scsi_cards[scsi_card_current[i]].device, i + 1);
}
}
}

View File

@@ -40,6 +40,7 @@
#include <86box/fdc.h>
#include <86box/isapnp.h>
#include <86box/scsi.h>
#include <86box/scsi_device.h>
#include <86box/scsi_aha154x.h>
#include <86box/scsi_x54x.h>
@@ -964,6 +965,7 @@ aha_init(const device_t *info)
/* Call common initializer. */
dev = x54x_init(info);
dev->bus = scsi_get_bus();
/*
* Set up the (initial) I/O address, IRQ and DMA info.
@@ -976,7 +978,7 @@ aha_init(const device_t *info)
dev->Irq = device_get_config_int("irq");
dev->DmaChannel = device_get_config_int("dma");
dev->rom_addr = device_get_config_hex20("bios_addr");
if (!(dev->bus & DEVICE_MCA))
if (!(dev->card_bus & DEVICE_MCA))
dev->fdc_address = device_get_config_hex16("fdc_addr");
else
dev->fdc_address = 0;
@@ -1121,7 +1123,7 @@ aha_init(const device_t *info)
/* Initialize the device. */
x54x_device_reset(dev);
if (!(dev->bus & DEVICE_MCA) && !(dev->flags & X54X_ISAPNP)) {
if (!(dev->card_bus & DEVICE_MCA) && !(dev->flags & X54X_ISAPNP)) {
/* Register our address space. */
x54x_io_set(dev, dev->Base, 4);

View File

@@ -559,13 +559,13 @@ buslogic_param_len(void *p)
static void
BuslogicSCSIBIOSDMATransfer(ESCMD *ESCSICmd, uint8_t TargetID, int dir, int transfer_size)
BuslogicSCSIBIOSDMATransfer(x54x_t *dev, ESCMD *ESCSICmd, uint8_t TargetID, int dir, int transfer_size)
{
uint32_t DataPointer = ESCSICmd->DataPointer;
int DataLength = ESCSICmd->DataLength;
uint32_t Address;
uint32_t TransferLength;
scsi_device_t *dev = &scsi_devices[TargetID];
scsi_device_t *sd = &scsi_devices[dev->bus][TargetID];
if (ESCSICmd->DataDirection == 0x03) {
/* Non-data command. */
@@ -577,16 +577,16 @@ BuslogicSCSIBIOSDMATransfer(ESCMD *ESCSICmd, uint8_t TargetID, int dir, int tran
/* If the control byte is 0x00, it means that the transfer direction is set up by the SCSI command without
checking its length, so do this procedure for both read/write commands. */
if ((DataLength > 0) && (dev->buffer_length > 0)) {
if ((DataLength > 0) && (sd->buffer_length > 0)) {
Address = DataPointer;
TransferLength = MIN(DataLength, dev->buffer_length);
TransferLength = MIN(DataLength, sd->buffer_length);
if (dir && ((ESCSICmd->DataDirection == CCB_DATA_XFER_OUT) || (ESCSICmd->DataDirection == 0x00))) {
buslogic_log("BusLogic BIOS DMA: Reading %i bytes from %08X\n", TransferLength, Address);
dma_bm_read(Address, (uint8_t *)dev->sc->temp_buffer, TransferLength, transfer_size);
dma_bm_read(Address, (uint8_t *)sd->sc->temp_buffer, TransferLength, transfer_size);
} else if (!dir && ((ESCSICmd->DataDirection == CCB_DATA_XFER_IN) || (ESCSICmd->DataDirection == 0x00))) {
buslogic_log("BusLogic BIOS DMA: Writing %i bytes at %08X\n", TransferLength, Address);
dma_bm_write(Address, (uint8_t *)dev->sc->temp_buffer, TransferLength, transfer_size);
dma_bm_write(Address, (uint8_t *)sd->sc->temp_buffer, TransferLength, transfer_size);
}
}
}
@@ -603,7 +603,7 @@ BuslogicSCSIBIOSRequestSetup(x54x_t *dev, uint8_t *CmdBuf, uint8_t *DataInBuf, u
uint8_t target_id = 0;
#endif
int phase;
scsi_device_t *sd = &scsi_devices[ESCSICmd->TargetId];
scsi_device_t *sd = &scsi_devices[dev->bus][ESCSICmd->TargetId];
DataInBuf[0] = DataInBuf[1] = 0;
@@ -654,7 +654,7 @@ BuslogicSCSIBIOSRequestSetup(x54x_t *dev, uint8_t *CmdBuf, uint8_t *DataInBuf, u
phase = sd->phase;
if (phase != SCSI_PHASE_STATUS) {
BuslogicSCSIBIOSDMATransfer(ESCSICmd, ESCSICmd->TargetId, (phase == SCSI_PHASE_DATA_OUT), dev->transfer_size);
BuslogicSCSIBIOSDMATransfer(dev, ESCSICmd, ESCSICmd->TargetId, (phase == SCSI_PHASE_DATA_OUT), dev->transfer_size);
scsi_device_command_phase1(sd);
}
@@ -664,7 +664,7 @@ BuslogicSCSIBIOSRequestSetup(x54x_t *dev, uint8_t *CmdBuf, uint8_t *DataInBuf, u
if (sd->status == SCSI_STATUS_OK) {
DataInBuf[2] = CCB_COMPLETE;
DataInBuf[3] = SCSI_STATUS_OK;
} else if (scsi_devices[ESCSICmd->TargetId].status == SCSI_STATUS_CHECK_CONDITION) {
} else if (scsi_devices[dev->bus][ESCSICmd->TargetId].status == SCSI_STATUS_CHECK_CONDITION) {
DataInBuf[2] = CCB_COMPLETE;
DataInBuf[3] = SCSI_STATUS_CHECK_CONDITION;
}
@@ -704,14 +704,14 @@ buslogic_cmds(void *p)
memset(dev->DataBuf, 0, 8);
for (i = 8; i < 15; i++) {
dev->DataBuf[i - 8] = 0;
if (scsi_device_present(&scsi_devices[i]) && (i != buslogic_get_host_id(dev)))
if (scsi_device_present(&scsi_devices[dev->bus][i]) && (i != buslogic_get_host_id(dev)))
dev->DataBuf[i - 8] |= 1;
}
dev->DataReplyLeft = 8;
break;
case 0x24:
for (i = 0; i < 15; i++) {
if (scsi_device_present(&scsi_devices[i]) && (i != buslogic_get_host_id(dev)))
if (scsi_device_present(&scsi_devices[dev->bus][i]) && (i != buslogic_get_host_id(dev)))
TargetsPresentMask |= (1 << i);
}
dev->DataBuf[0] = TargetsPresentMask & 0xFF;
@@ -1532,13 +1532,14 @@ buslogic_init(const device_t *info)
/* Call common initializer. */
dev = x54x_init(info);
dev->bus = scsi_get_bus();
dev->ven_data = malloc(sizeof(buslogic_data_t));
memset(dev->ven_data, 0x00, sizeof(buslogic_data_t));
bl = (buslogic_data_t *) dev->ven_data;
dev->bus = info->flags;
dev->card_bus = info->flags;
if (!(info->flags & DEVICE_MCA) && !(info->flags & DEVICE_PCI)) {
dev->Base = device_get_config_hex16("base");
dev->Irq = device_get_config_int("irq");
@@ -1668,7 +1669,7 @@ buslogic_init(const device_t *info)
break;
}
if ((dev->Base != 0) && !(dev->bus & DEVICE_MCA) && !(dev->bus & DEVICE_PCI)) {
if ((dev->Base != 0) && !(dev->card_bus & DEVICE_MCA) && !(dev->card_bus & DEVICE_PCI)) {
x54x_io_set(dev, dev->Base, 4);
}

View File

@@ -798,12 +798,13 @@ scsi_cdrom_sense_clear(scsi_cdrom_t *dev, int command)
static void
scsi_cdrom_set_phase(scsi_cdrom_t *dev, uint8_t phase)
{
uint8_t scsi_id = dev->drv->scsi_device_id;
uint8_t scsi_bus = (dev->drv->scsi_device_id >> 4) & 0x0f;
uint8_t scsi_id = dev->drv->scsi_device_id & 0x0f;
if (dev->drv->bus_type != CDROM_BUS_SCSI)
return;
scsi_devices[scsi_id].phase = phase;
scsi_devices[scsi_bus][scsi_id].phase = phase;
}
@@ -1417,9 +1418,11 @@ scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb)
int32_t blen = 0, *BufLen;
uint8_t *b;
uint32_t profiles[2] = { MMC_PROFILE_CD_ROM, MMC_PROFILE_DVD_ROM };
uint8_t scsi_bus = (dev->drv->scsi_device_id >> 4) & 0x0f;
uint8_t scsi_id = dev->drv->scsi_device_id & 0x0f;
if (dev->drv->bus_type == CDROM_BUS_SCSI) {
BufLen = &scsi_devices[dev->drv->scsi_device_id].buffer_length;
BufLen = &scsi_devices[scsi_bus][scsi_id].buffer_length;
dev->status &= ~ERR_STAT;
} else {
BufLen = &blen;
@@ -2687,10 +2690,18 @@ scsi_cdrom_drive_reset(int c)
scsi_cdrom_t *dev;
scsi_device_t *sd;
ide_t *id;
uint8_t scsi_bus = (drv->scsi_device_id >> 4) & 0x0f;
uint8_t scsi_id = drv->scsi_device_id & 0x0f;
/* Make sure to ignore any SCSI CD-ROM drive that has an out of range ID. */
if ((drv->bus_type == CDROM_BUS_SCSI) && (drv->scsi_device_id >= SCSI_ID_MAX))
return;
if (drv->bus_type == CDROM_BUS_SCSI) {
/* Make sure to ignore any SCSI CD-ROM drive that has an out of range SCSI bus. */
if (scsi_bus >= SCSI_BUS_MAX)
return;
/* Make sure to ignore any SCSI CD-ROM drive that has an out of range ID. */
if (scsi_id >= SCSI_ID_MAX)
return;
}
/* Make sure to ignore any ATAPI CD-ROM drive that has an out of range IDE channel. */
if ((drv->bus_type == CDROM_BUS_ATAPI) && (drv->ide_channel > 7))
@@ -2717,7 +2728,7 @@ scsi_cdrom_drive_reset(int c)
if (drv->bus_type == CDROM_BUS_SCSI) {
/* SCSI CD-ROM, attach to the SCSI bus. */
sd = &scsi_devices[drv->scsi_device_id];
sd = &scsi_devices[scsi_bus][scsi_id];
sd->sc = (scsi_common_t *) dev;
sd->command = scsi_cdrom_command;

View File

@@ -27,7 +27,7 @@
#include <86box/scsi_device.h>
scsi_device_t scsi_devices[SCSI_ID_MAX];
scsi_device_t scsi_devices[SCSI_BUS_MAX][SCSI_ID_MAX];
uint8_t scsi_null_device_sense[18] = { 0x70,0,SENSE_ILLEGAL_REQUEST,0,0,0,0,0,0,0,0,0,ASC_INV_LUN,0,0,0,0,0 };
@@ -176,13 +176,15 @@ scsi_device_identify(scsi_device_t *dev, uint8_t lun)
void
scsi_device_close_all(void)
{
int i;
int i, j;
scsi_device_t *dev;
for (i = 0; i < SCSI_ID_MAX; i++) {
dev = &(scsi_devices[i]);
if (dev->command_stop && dev->sc)
dev->command_stop(dev->sc);
for (i = 0; i < SCSI_BUS_MAX; i++) {
for (j = 0; j < SCSI_ID_MAX; j++) {
dev = &(scsi_devices[i][j]);
if (dev->command_stop && dev->sc)
dev->command_stop(dev->sc);
}
}
}
@@ -190,13 +192,15 @@ scsi_device_close_all(void)
void
scsi_device_init(void)
{
int i;
int i, j;
scsi_device_t *dev;
for (i = 0; i < SCSI_ID_MAX; i++) {
dev = &(scsi_devices[i]);
for (i = 0; i < SCSI_BUS_MAX; i++) {
for (j = 0; j < SCSI_ID_MAX; j++) {
dev = &(scsi_devices[i][j]);
memset(dev, 0, sizeof(scsi_device_t));
dev->type = SCSI_NONE;
memset(dev, 0, sizeof(scsi_device_t));
dev->type = SCSI_NONE;
}
}
}

View File

@@ -347,12 +347,13 @@ scsi_disk_sense_clear(scsi_disk_t *dev, int command)
static void
scsi_disk_set_phase(scsi_disk_t *dev, uint8_t phase)
{
uint8_t scsi_id = dev->drv->scsi_id;
uint8_t scsi_bus = (dev->drv->scsi_id >> 4) & 0x0f;
uint8_t scsi_id = dev->drv->scsi_id & 0x0f;
if (dev->drv->bus != HDD_BUS_SCSI)
return;
scsi_devices[scsi_id].phase = phase;
scsi_devices[scsi_bus][scsi_id].phase = phase;
}
@@ -572,8 +573,10 @@ scsi_disk_command(scsi_common_t *sc, uint8_t *cdb)
char device_identify[9] = { '8', '6', 'B', '_', 'H', 'D', '0', '0', 0 };
char device_identify_ex[15] = { '8', '6', 'B', '_', 'H', 'D', '0', '0', ' ', 'v', '1', '.', '0', '0', 0 };
int block_desc = 0;
uint8_t scsi_bus = (dev->drv->scsi_id >> 4) & 0x0f;
uint8_t scsi_id = dev->drv->scsi_id & 0x0f;
BufLen = &scsi_devices[dev->drv->scsi_id].buffer_length;
BufLen = &scsi_devices[scsi_bus][scsi_id].buffer_length;
last_sector = hdd_image_get_last_sector(dev->id);
@@ -1073,8 +1076,10 @@ static uint8_t
scsi_disk_phase_data_out(scsi_common_t *sc)
{
scsi_disk_t *dev = (scsi_disk_t *) sc;
uint8_t scsi_bus = (dev->drv->scsi_id >> 4) & 0x0f;
uint8_t scsi_id = dev->drv->scsi_id & 0x0f;
int i;
int32_t *BufLen = &scsi_devices[dev->drv->scsi_id].buffer_length;
int32_t *BufLen = &scsi_devices[scsi_bus][scsi_id].buffer_length;
uint32_t last_sector = hdd_image_get_last_sector(dev->id);
uint32_t c, h, s, last_to_write = 0;
uint16_t block_desc_len, pos;
@@ -1215,13 +1220,21 @@ scsi_disk_hard_reset(void)
int c;
scsi_disk_t *dev;
scsi_device_t *sd;
uint8_t scsi_bus, scsi_id;
for (c = 0; c < HDD_NUM; c++) {
if (hdd[c].bus == HDD_BUS_SCSI) {
scsi_disk_log("SCSI disk hard_reset drive=%d\n", c);
scsi_bus = (hdd[c].scsi_id >> 4) & 0x0f;
scsi_id = hdd[c].scsi_id & 0x0f;
/* Make sure to ignore any SCSI disk that has an out of range SCSI bus. */
if (scsi_bus >= SCSI_BUS_MAX)
continue;
/* Make sure to ignore any SCSI disk that has an out of range ID. */
if (hdd[c].scsi_id >= SCSI_ID_MAX)
if (scsi_id >= SCSI_ID_MAX)
continue;
/* Make sure to ignore any SCSI disk whose image file name is empty. */
@@ -1240,7 +1253,7 @@ scsi_disk_hard_reset(void)
dev = (scsi_disk_t *) hdd[c].priv;
/* SCSI disk, attach to the SCSI bus. */
sd = &scsi_devices[hdd[c].scsi_id];
sd = &scsi_devices[scsi_bus][scsi_id];
sd->sc = (scsi_common_t *) dev;
sd->command = scsi_disk_command;
@@ -1268,10 +1281,14 @@ scsi_disk_close(void)
{
scsi_disk_t *dev;
int c;
uint8_t scsi_bus, scsi_id;
for (c = 0; c < HDD_NUM; c++) {
if (hdd[c].bus == HDD_BUS_SCSI) {
memset(&scsi_devices[hdd[c].scsi_id], 0x00, sizeof(scsi_device_t));
scsi_bus = (hdd[c].scsi_id >> 4) & 0x0f;
scsi_id = hdd[c].scsi_id & 0x0f;
memset(&scsi_devices[scsi_bus][scsi_id], 0x00, sizeof(scsi_device_t));
hdd_image_close(c);

View File

@@ -124,7 +124,7 @@ typedef struct {
int8_t bios_ver;
uint8_t block_count, block_count_num;
uint8_t status_ctrl;
uint8_t pad[2];
uint8_t bus, pad;
rom_t bios_rom;
mem_mapping_t mapping;
@@ -236,7 +236,7 @@ ncr_reset(ncr5380_t *ncr_dev, ncr_t *ncr)
timer_stop(&ncr_dev->timer);
for (int i = 0; i < 8; i++)
scsi_device_reset(&scsi_devices[i]);
scsi_device_reset(&scsi_devices[ncr_dev->bus][i]);
ncr_irq(ncr_dev, ncr, 0);
}
@@ -318,7 +318,7 @@ ncr_bus_read(ncr5380_t *ncr_dev)
if (ncr->wait_data) {
ncr->wait_data--;
if (!ncr->wait_data) {
dev = &scsi_devices[ncr->target_id];
dev = &scsi_devices[ncr_dev->bus][ncr->target_id];
SET_BUS_STATE(ncr, ncr->new_phase);
phase = (ncr->cur_bus & SCSI_PHASE_MESSAGE_IN);
@@ -360,7 +360,7 @@ ncr_bus_update(void *priv, int bus)
{
ncr5380_t *ncr_dev = (ncr5380_t *)priv;
ncr_t *ncr = &ncr_dev->ncr;
scsi_device_t *dev = &scsi_devices[ncr->target_id];
scsi_device_t *dev = &scsi_devices[ncr_dev->bus][ncr->target_id];
double p;
uint8_t sel_data;
int msglen;
@@ -383,7 +383,7 @@ ncr_bus_update(void *priv, int bus)
ncr_log("Select - target ID = %i\n", ncr->target_id);
/*Once the device has been found and selected, mark it as busy*/
if ((ncr->target_id != (uint8_t)-1) && scsi_device_present(&scsi_devices[ncr->target_id])) {
if ((ncr->target_id != (uint8_t)-1) && scsi_device_present(&scsi_devices[ncr_dev->bus][ncr->target_id])) {
ncr->cur_bus |= BUS_BSY;
ncr->state = STATE_SELECT;
} else {
@@ -395,7 +395,7 @@ ncr_bus_update(void *priv, int bus)
case STATE_SELECT:
if (!(bus & BUS_SEL)) {
if (!(bus & BUS_ATN)) {
if ((ncr->target_id != (uint8_t)-1) && scsi_device_present(&scsi_devices[ncr->target_id])) {
if ((ncr->target_id != (uint8_t)-1) && scsi_device_present(&scsi_devices[ncr_dev->bus][ncr->target_id])) {
ncr_log("Device found at ID %i, Current Bus BSY=%02x\n", ncr->target_id, ncr->cur_bus);
ncr->state = STATE_COMMAND;
ncr->cur_bus = BUS_BSY | BUS_REQ;
@@ -434,7 +434,7 @@ ncr_bus_update(void *priv, int bus)
/*Reset data position to default*/
ncr->data_pos = 0;
dev = &scsi_devices[ncr->target_id];
dev = &scsi_devices[ncr_dev->bus][ncr->target_id];
ncr_log("SCSI Command 0x%02X for ID %d, status code=%02x\n", ncr->command[0], ncr->target_id, dev->status);
dev->buffer_length = -1;
@@ -462,7 +462,7 @@ ncr_bus_update(void *priv, int bus)
}
break;
case STATE_DATAIN:
dev = &scsi_devices[ncr->target_id];
dev = &scsi_devices[ncr_dev->bus][ncr->target_id];
if ((bus & BUS_ACK) && !(ncr->bus_in & BUS_ACK)) {
if (ncr->data_pos >= dev->buffer_length) {
ncr->cur_bus &= ~BUS_REQ;
@@ -487,7 +487,7 @@ ncr_bus_update(void *priv, int bus)
}
break;
case STATE_DATAOUT:
dev = &scsi_devices[ncr->target_id];
dev = &scsi_devices[ncr_dev->bus][ncr->target_id];
if ((bus & BUS_ACK) && !(ncr->bus_in & BUS_ACK)) {
dev->sc->temp_buffer[ncr->data_pos++] = BUS_GETDATA(bus);
@@ -514,7 +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);
scsi_device_identify(&scsi_devices[ncr_dev->bus][ncr->target_id], SCSI_LUN_USE_CDB);
ncr->cur_bus &= ~BUS_REQ;
ncr->new_phase = SCSI_PHASE_MESSAGE_IN;
ncr->wait_data = 4;
@@ -542,9 +542,9 @@ ncr_bus_update(void *priv, int bus)
}
break;
case STATE_MESSAGE_ID:
if ((ncr->target_id != (uint8_t)-1) && scsi_device_present(&scsi_devices[ncr->target_id])) {
if ((ncr->target_id != (uint8_t)-1) && scsi_device_present(&scsi_devices[ncr_dev->bus][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);
scsi_device_identify(&scsi_devices[ncr_dev->bus][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);
@@ -1091,7 +1091,7 @@ ncr_callback(void *priv)
{
ncr5380_t *ncr_dev = (ncr5380_t *)priv;
ncr_t *ncr = &ncr_dev->ncr;
scsi_device_t *dev = &scsi_devices[ncr->target_id];
scsi_device_t *dev = &scsi_devices[ncr_dev->bus][ncr->target_id];
ncr_log("DMA mode=%d, status ctrl = %02x\n", ncr->dma_mode, ncr_dev->status_ctrl);
@@ -1166,6 +1166,8 @@ ncr_init(const device_t *info)
ncr_dev->name = info->name;
ncr_dev->type = info->local;
ncr_dev->bus = scsi_get_bus();
switch(ncr_dev->type) {
case 0: /* Longshine LCS6821N */
ncr_dev->rom_addr = device_get_config_hex20("bios_addr");

View File

@@ -308,6 +308,8 @@ typedef struct {
uint32_t bios_mask;
uint8_t bus;
pc_timer_t timer;
#ifdef USE_WDTR
@@ -440,7 +442,7 @@ ncr53c8xx_soft_reset(ncr53c8xx_t *dev)
#ifdef USE_WDTR
dev->tr_set[i] = 0;
#endif
scsi_device_reset(&scsi_devices[i]);
scsi_device_reset(&scsi_devices[dev->bus][i]);
}
} else {
/* This is *NOT* a wide SCSI controller, so do not touch
@@ -449,7 +451,7 @@ ncr53c8xx_soft_reset(ncr53c8xx_t *dev)
#ifdef USE_WDTR
dev->tr_set[i] = 0;
#endif
scsi_device_reset(&scsi_devices[i]);
scsi_device_reset(&scsi_devices[dev->bus][i]);
}
}
}
@@ -613,7 +615,7 @@ ncr53c8xx_disconnect(ncr53c8xx_t *dev)
{
scsi_device_t *sd;
sd = &scsi_devices[dev->sdid];
sd = &scsi_devices[dev->bus][dev->sdid];
dev->scntl1 &= ~NCR_SCNTL1_CON;
dev->sstat1 &= ~PHASE_MASK;
@@ -659,7 +661,7 @@ ncr53c8xx_do_dma(ncr53c8xx_t *dev, int out, uint8_t id)
uint32_t addr, tdbc;
int count;
scsi_device_t *sd = &scsi_devices[id];
scsi_device_t *sd = &scsi_devices[dev->bus][id];
if ((!scsi_device_present(sd))) {
ncr53c8xx_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);
@@ -697,7 +699,7 @@ ncr53c8xx_do_dma(ncr53c8xx_t *dev, int out, uint8_t id)
dev->buffer_pos += count;
if (dev->temp_buf_len <= 0) {
scsi_device_command_phase1(&scsi_devices[id]);
scsi_device_command_phase1(&scsi_devices[dev->bus][id]);
#ifdef ENABLE_NCR53C8XX_LOG
if (out)
ncr53c8xx_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: SCSI Command Phase 1 on PHASE_DO\n", id, dev->current_lun, dev->last_command);
@@ -750,7 +752,7 @@ ncr53c8xx_do_command(ncr53c8xx_t *dev, uint8_t id)
dev->sfbr = buf[0];
dev->command_complete = 0;
sd = &scsi_devices[id];
sd = &scsi_devices[dev->bus][id];
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);
@@ -769,7 +771,7 @@ ncr53c8xx_do_command(ncr53c8xx_t *dev, uint8_t id)
if ((buf[1] & 0xe0) != (dev->current_lun << 5))
buf[1] = (buf[1] & 0x1f) | (dev->current_lun << 5);
scsi_device_command_phase0(&scsi_devices[dev->current->tag], buf);
scsi_device_command_phase0(&scsi_devices[dev->bus][dev->current->tag], buf);
dev->hba_private = (void *)dev->current;
dev->waiting = 0;
@@ -785,12 +787,12 @@ ncr53c8xx_do_command(ncr53c8xx_t *dev, uint8_t id)
if ((sd->phase == SCSI_PHASE_DATA_IN) && (sd->buffer_length > 0)) {
ncr53c8xx_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: PHASE_DI\n", id, dev->current_lun, buf[0]);
ncr53c8xx_set_phase(dev, PHASE_DI);
ncr53c8xx_timer_on(dev, sd, scsi_device_get_callback(&scsi_devices[dev->current->tag]));
ncr53c8xx_timer_on(dev, sd, scsi_device_get_callback(&scsi_devices[dev->bus][dev->current->tag]));
return 1;
} else if ((sd->phase == SCSI_PHASE_DATA_OUT) && (sd->buffer_length > 0)) {
ncr53c8xx_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: PHASE_DO\n", id, buf[0]);
ncr53c8xx_set_phase(dev, PHASE_DO);
ncr53c8xx_timer_on(dev, sd, scsi_device_get_callback(&scsi_devices[dev->current->tag]));
ncr53c8xx_timer_on(dev, sd, scsi_device_get_callback(&scsi_devices[dev->bus][dev->current->tag]));
return 1;
} else {
ncr53c8xx_command_complete(dev, sd->status);
@@ -913,7 +915,7 @@ ncr53c8xx_do_msgout(ncr53c8xx_t *dev, uint8_t id)
#endif
scsi_device_t *sd;
sd = &scsi_devices[id];
sd = &scsi_devices[dev->bus][id];
#ifdef ENABLE_NCR53C8XX_LOG
current_tag = id;
@@ -1169,7 +1171,7 @@ again:
}
dev->sstat0 |= NCR_SSTAT0_WOA;
dev->scntl1 &= ~NCR_SCNTL1_IARB;
if (!scsi_device_present(&scsi_devices[id])) {
if (!scsi_device_present(&scsi_devices[dev->bus][id])) {
ncr53c8xx_bad_selection(dev, id);
break;
}
@@ -2513,6 +2515,8 @@ ncr53c8xx_init(const device_t *info)
dev = malloc(sizeof(ncr53c8xx_t));
memset(dev, 0x00, sizeof(ncr53c8xx_t));
dev->bus = scsi_get_bus();
dev->chip_rev = 0;
dev->chip = info->local & 0xff;

View File

@@ -168,6 +168,7 @@ typedef struct {
int deferred_complete;
uint32_t dma;
uint8_t ti_buf[TI_BUFSZ];
uint8_t bus;
uint8_t id, lun;
uint8_t cmdbuf[ESP_CMDBUF_SZ];
uint32_t cmdlen;
@@ -289,7 +290,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 > 0)) {
if (scsi_device_present(&scsi_devices[dev->bus][dev->id]) && (dev->lun > 0)) {
/* We only support LUN 0 */
dev->rregs[ESP_RSTAT] = 0;
dev->rregs[ESP_RINTR] = INTR_DC;
@@ -298,7 +299,7 @@ esp_get_cmd(esp_t *dev, uint8_t *buf, uint8_t buflen)
return 0;
}
scsi_device_identify(&scsi_devices[dev->id], dev->lun);
scsi_device_identify(&scsi_devices[dev->bus][dev->id], dev->lun);
return dmalen;
}
@@ -308,7 +309,7 @@ esp_do_busid_cmd(esp_t *dev, uint8_t *buf, uint8_t busid)
{
scsi_device_t *sd;
sd = &scsi_devices[busid];
sd = &scsi_devices[dev->bus][busid];
sd->buffer_length = -1;
@@ -388,7 +389,7 @@ esp_hard_reset(esp_t *dev)
timer_stop(&dev->timer);
for (int i = 0; i < 8; i++)
scsi_device_reset(&scsi_devices[i]);
scsi_device_reset(&scsi_devices[dev->bus][i]);
}
static void
@@ -536,7 +537,7 @@ static void
handle_ti(void *priv)
{
esp_t *dev = (esp_t *)priv;
scsi_device_t *sd = &scsi_devices[dev->id];
scsi_device_t *sd = &scsi_devices[dev->bus][dev->id];
uint32_t dmalen;
if (dev->dma) {
@@ -1430,6 +1431,8 @@ dc390_init(const device_t *info)
dev = malloc(sizeof(esp_t));
memset(dev, 0x00, sizeof(esp_t));
dev->bus = scsi_get_bus();
dev->PCIBase = 0;
dev->MMIOBase = 0;

View File

@@ -143,7 +143,7 @@ typedef struct {
int lun_id;
} dev_id[SCSI_ID_MAX];
uint8_t last_status;
uint8_t last_status, bus;
uint8_t cdb[12];
int cdb_len;
int cdb_id;
@@ -488,7 +488,7 @@ spock_process_imm_cmd(spock_t *scsi)
spock_log("Reset Command\n");
if ((scsi->attention & 0x0f) == 0x0f) { /*Adapter reset*/
for (i = 0; i < 8; i++)
scsi_device_reset(&scsi_devices[i]);
scsi_device_reset(&scsi_devices[scsi->bus][i]);
spock_log("Adapter Reset\n");
if (!scsi->adapter_reset && scsi->bios_ver) /*The early 1990 bios must have its boot drive
@@ -798,7 +798,7 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb)
break;
case 2: /* Wait */
if (scsi->scsi_state == SCSI_STATE_IDLE && scsi_device_present(&scsi_devices[scsi->cdb_id])) {
if (scsi->scsi_state == SCSI_STATE_IDLE && scsi_device_present(&scsi_devices[scsi->bus][scsi->cdb_id])) {
if (scsi->last_status == SCSI_STATUS_OK) {
scsi->scb_state = 3;
spock_log("Status is Good on device ID %d, timer = %i\n", scsi->cdb_id, scsi->cmd_timer);
@@ -816,7 +816,7 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb)
dma_bm_write(scb->term_status_block_addr + 0xb*2, (uint8_t *)&term_stat_block_addrb, 2, 2);
dma_bm_write(scb->term_status_block_addr + 0xc*2, (uint8_t *)&term_stat_block_addrc, 2, 2);
}
} else if (scsi->scsi_state == SCSI_STATE_IDLE && !scsi_device_present(&scsi_devices[scsi->cdb_id])) {
} else if (scsi->scsi_state == SCSI_STATE_IDLE && !scsi_device_present(&scsi_devices[scsi->bus][scsi->cdb_id])) {
uint16_t term_stat_block_addr7 = (0xc << 8) | 2;
uint16_t term_stat_block_addr8 = 0x10;
spock_set_irq(scsi, scsi->scb_id, IRQ_TYPE_COMMAND_FAIL);
@@ -854,7 +854,7 @@ spock_process_scsi(spock_t *scsi, scb_t *scb)
case SCSI_STATE_SELECT:
spock_log("Selecting ID %d\n", scsi->cdb_id);
if ((scsi->cdb_id != (uint8_t)-1) && scsi_device_present(&scsi_devices[scsi->cdb_id])) {
if ((scsi->cdb_id != (uint8_t)-1) && scsi_device_present(&scsi_devices[scsi->bus][scsi->cdb_id])) {
scsi->scsi_state = SCSI_STATE_SEND_COMMAND;
spock_log("Device selected at ID %i\n", scsi->cdb_id);
} else {
@@ -869,7 +869,7 @@ spock_process_scsi(spock_t *scsi, scb_t *scb)
break;
case SCSI_STATE_SEND_COMMAND:
sd = &scsi_devices[scsi->cdb_id];
sd = &scsi_devices[scsi->bus][scsi->cdb_id];
memset(scsi->temp_cdb, 0x00, 12);
if (scsi->cdb_len < 12) {
@@ -1086,7 +1086,7 @@ spock_mca_reset(void *priv)
/* Reset all devices on controller reset. */
for (i = 0; i < 8; i++)
scsi_device_reset(&scsi_devices[i]);
scsi_device_reset(&scsi_devices[scsi->bus][i]);
scsi->adapter_reset = 0;
}
@@ -1097,7 +1097,9 @@ spock_init(const device_t *info)
int c;
spock_t *scsi = malloc(sizeof(spock_t));
memset(scsi, 0x00, sizeof(spock_t));
scsi->bus = scsi_get_bus();
scsi->irq = 14;
scsi->bios_ver = device_get_config_int("bios_ver");

View File

@@ -85,7 +85,7 @@ x54x_irq(x54x_t *dev, int set)
else
irq = dev->Irq;
if (dev->bus & DEVICE_PCI) {
if (dev->card_bus & DEVICE_PCI) {
x54x_log("PCI IRQ: %02X, PCI_INTA\n", dev->pci_slot);
if (set)
pci_set_irq(dev->pci_slot, PCI_INTA);
@@ -155,9 +155,9 @@ clear_irq(x54x_t *dev)
static void
target_check(uint8_t id)
target_check(x54x_t *dev, uint8_t id)
{
if (! scsi_device_valid(&scsi_devices[id]))
if (! scsi_device_valid(&scsi_devices[dev->bus][id]))
fatal("BIOS INT13 device on ID %02i has disappeared\n", id);
}
@@ -432,7 +432,7 @@ x54x_bios_command(x54x_t *x54x, uint8_t max_id, BIOSCMD *cmd, int8_t islba)
if (!ret) {
/* Get pointer to selected device. */
dev = &scsi_devices[cmd->id];
dev = &scsi_devices[x54x->bus][cmd->id];
dev->buffer_length = 0;
if (! scsi_device_present(dev)) {
@@ -459,7 +459,7 @@ x54x_bios_command(x54x_t *x54x, uint8_t max_id, BIOSCMD *cmd, int8_t islba)
break;
case 0x01: /* Read Status of Last Operation */
target_check(cmd->id);
target_check(x54x, cmd->id);
/*
* Assuming 14 bytes because that is the default
@@ -479,7 +479,7 @@ x54x_bios_command(x54x_t *x54x, uint8_t max_id, BIOSCMD *cmd, int8_t islba)
case 0x03: /* Write Desired Sectors from Memory */
case 0x04: /* Verify Desired Sectors */
case 0x0c: /* Seek */
target_check(cmd->id);
target_check(x54x, cmd->id);
cdb[0] = bios_cmd_to_scsi[cmd->command];
cdb[1] = (cmd->lun & 7) << 5;
@@ -519,7 +519,7 @@ x54x_bios_command(x54x_t *x54x, uint8_t max_id, BIOSCMD *cmd, int8_t islba)
case 0x07: /* Format Unit */
case 0x10: /* Test Drive Ready */
case 0x11: /* Recalibrate */
target_check(cmd->id);
target_check(x54x, cmd->id);
cdb[0] = bios_cmd_to_scsi[cmd->command];
cdb[1] = (cmd->lun & 7) << 5;
@@ -529,7 +529,7 @@ x54x_bios_command(x54x_t *x54x, uint8_t max_id, BIOSCMD *cmd, int8_t islba)
case 0x08: /* Read Drive Parameters */
case 0x15: /* Read DASD Type */
target_check(cmd->id);
target_check(x54x, cmd->id);
dev->buffer_length = 6;
@@ -758,7 +758,7 @@ x54x_set_residue(x54x_t *dev, Req_t *req, int32_t TransferLength)
{
uint32_t Residue = 0;
addr24 Residue24;
int32_t BufLen = scsi_devices[req->TargetID].buffer_length;
int32_t BufLen = scsi_devices[dev->bus][req->TargetID].buffer_length;
uint8_t bytes[4] = { 0, 0, 0, 0 };
if ((req->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND_RES) ||
@@ -792,7 +792,7 @@ x54x_buf_dma_transfer(x54x_t *dev, Req_t *req, int Is24bit, int TransferLength,
uint32_t DataPointer, DataLength;
uint32_t SGEntryLength = (Is24bit ? sizeof(SGE) : sizeof(SGE32));
uint32_t Address, i;
int32_t BufLen = scsi_devices[req->TargetID].buffer_length;
int32_t BufLen = scsi_devices[dev->bus][req->TargetID].buffer_length;
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)));
int sg_pos = 0;
@@ -824,11 +824,11 @@ x54x_buf_dma_transfer(x54x_t *dev, Req_t *req, int Is24bit, int TransferLength,
if (read_from_host && DataToTransfer) {
x54x_log("Reading S/G segment %i: length %i, pointer %08X\n", i, DataToTransfer, Address);
dma_bm_read(Address, &(scsi_devices[req->TargetID].sc->temp_buffer[sg_pos]), DataToTransfer, dev->transfer_size);
dma_bm_read(Address, &(scsi_devices[dev->bus][req->TargetID].sc->temp_buffer[sg_pos]), DataToTransfer, dev->transfer_size);
}
else if (write_to_host && DataToTransfer) {
x54x_log("Writing S/G segment %i: length %i, pointer %08X\n", i, DataToTransfer, Address);
dma_bm_write(Address, &(scsi_devices[req->TargetID].sc->temp_buffer[sg_pos]), DataToTransfer, dev->transfer_size);
dma_bm_write(Address, &(scsi_devices[dev->bus][req->TargetID].sc->temp_buffer[sg_pos]), DataToTransfer, dev->transfer_size);
}
else
x54x_log("No action on S/G segment %i: length %i, pointer %08X\n", i, DataToTransfer, Address);
@@ -848,9 +848,9 @@ x54x_buf_dma_transfer(x54x_t *dev, Req_t *req, int Is24bit, int TransferLength,
if ((DataLength > 0) && (BufLen > 0) && (req->CmdBlock.common.ControlByte < 0x03)) {
if (read_from_host)
dma_bm_read(Address, scsi_devices[req->TargetID].sc->temp_buffer, MIN(BufLen, (int) DataLength), dev->transfer_size);
dma_bm_read(Address, scsi_devices[dev->bus][req->TargetID].sc->temp_buffer, MIN(BufLen, (int) DataLength), dev->transfer_size);
else if (write_to_host)
dma_bm_write(Address, scsi_devices[req->TargetID].sc->temp_buffer, MIN(BufLen, (int) DataLength), dev->transfer_size);
dma_bm_write(Address, scsi_devices[dev->bus][req->TargetID].sc->temp_buffer, MIN(BufLen, (int) DataLength), dev->transfer_size);
}
}
}
@@ -896,7 +896,7 @@ SenseBufferFree(x54x_t *dev, Req_t *req, int Copy)
uint8_t temp_sense[256];
if (SenseLength && Copy) {
scsi_device_request_sense(&scsi_devices[req->TargetID], temp_sense, SenseLength);
scsi_device_request_sense(&scsi_devices[dev->bus][req->TargetID], temp_sense, SenseLength);
/*
* The sense address, in 32-bit mode, is located in the
@@ -925,7 +925,7 @@ x54x_scsi_cmd(x54x_t *dev)
uint32_t i, target_cdb_len = 12;
scsi_device_t *sd;
sd = &scsi_devices[req->TargetID];
sd = &scsi_devices[dev->bus][req->TargetID];
target_cdb_len = 12;
dev->target_data_len = x54x_get_length(dev, req, bit24);
@@ -965,7 +965,7 @@ x54x_scsi_cmd(x54x_t *dev)
else
dev->callback_sub_phase = 2;
x54x_log("scsi_devices[%02i].Status = %02X\n", req->TargetID, sd->status);
x54x_log("scsi_devices[%02i][%02i].Status = %02X\n", dev->bus, req->TargetID, sd->status);
}
@@ -977,7 +977,7 @@ x54x_scsi_cmd_phase1(x54x_t *dev)
uint8_t bit24 = !!req->Is24bit;
scsi_device_t *sd;
sd = &scsi_devices[req->TargetID];
sd = &scsi_devices[dev->bus][req->TargetID];
if (dev->scsi_cmd_phase != SCSI_PHASE_STATUS) {
if ((dev->temp_cdb[0] != 0x03) || (req->CmdBlock.common.ControlByte != 0x03)) {
@@ -992,7 +992,7 @@ x54x_scsi_cmd_phase1(x54x_t *dev)
}
dev->callback_sub_phase = 3;
x54x_log("scsi_devices[%02i].Status = %02X\n", req->TargetID, sd->status);
x54x_log("scsi_devices[%02xi][%02i].Status = %02X\n", x54x->bus, req->TargetID, sd->status);
}
@@ -1003,7 +1003,7 @@ x54x_request_sense(x54x_t *dev)
uint32_t SenseBufferAddress;
scsi_device_t *sd;
sd = &scsi_devices[req->TargetID];
sd = &scsi_devices[dev->bus][req->TargetID];
if (dev->scsi_cmd_phase != SCSI_PHASE_STATUS) {
if ((dev->temp_cdb[0] == 0x03) && (req->CmdBlock.common.ControlByte == 0x03)) {
@@ -1011,7 +1011,7 @@ x54x_request_sense(x54x_t *dev)
sd->buffer_length = ConvertSenseLength(req->CmdBlock.common.RequestSenseLength);
if ((sd->status != SCSI_STATUS_OK) && (sd->buffer_length > 0)) {
SenseBufferAddress = SenseBufferPointer(req);
dma_bm_write(SenseBufferAddress, scsi_devices[req->TargetID].sc->temp_buffer, sd->buffer_length, dev->transfer_size);
dma_bm_write(SenseBufferAddress, scsi_devices[dev->bus][req->TargetID].sc->temp_buffer, sd->buffer_length, dev->transfer_size);
x54x_add_to_period(dev, sd->buffer_length);
}
scsi_device_command_phase1(sd);
@@ -1033,7 +1033,7 @@ x54x_request_sense(x54x_t *dev)
}
dev->callback_sub_phase = 4;
x54x_log("scsi_devices[%02i].Status = %02X\n", req->TargetID, sd->status);
x54x_log("scsi_devices[%02i][%02i].Status = %02X\n", dev->bus, req->TargetID, sd->status);
}
@@ -1056,7 +1056,7 @@ x54x_notify(x54x_t *dev)
Req_t *req = &dev->Req;
scsi_device_t *sd;
sd = &scsi_devices[req->TargetID];
sd = &scsi_devices[dev->bus][req->TargetID];
x54x_mbo_free(dev);
@@ -1088,7 +1088,7 @@ x54x_req_setup(x54x_t *dev, uint32_t CCBPointer, Mailbox32_t *Mailbox32)
req->LUN = req->Is24bit ? req->CmdBlock.old.Lun : req->CmdBlock.new.Lun;
id = req->TargetID;
sd = &scsi_devices[id];
sd = &scsi_devices[dev->bus][id];
lun = req->LUN;
if ((id > dev->max_id) || (lun > 7)) {
x54x_log("SCSI Target ID %i or LUN %i is not valid\n",id,lun);
@@ -1466,7 +1466,7 @@ x54x_reset(x54x_t *dev)
/* Reset all devices on controller reset. */
for (i = 0; i < 16; i++)
scsi_device_reset(&scsi_devices[i]);
scsi_device_reset(&scsi_devices[dev->bus][i]);
if (dev->ven_reset)
dev->ven_reset(dev);
@@ -1522,7 +1522,7 @@ x54x_out(uint16_t port, uint8_t val, void *priv)
if (val & CTRL_SCRST) {
/* Reset all devices on SCSI bus reset. */
for (i = 0; i < 16; i++)
scsi_device_reset(&scsi_devices[i]);
scsi_device_reset(&scsi_devices[dev->bus][i]);
}
if (val & CTRL_IRST) {
@@ -1699,7 +1699,7 @@ x54x_out(uint16_t port, uint8_t val, void *priv)
if (i == host_id) continue;
/* TODO: Query device for LUN's. */
if (scsi_device_present(&scsi_devices[i]))
if (scsi_device_present(&scsi_devices[dev->bus][i]))
dev->DataBuf[i] |= 1;
}
dev->DataReplyLeft = i;
@@ -1846,9 +1846,9 @@ x54x_is_32bit(x54x_t *dev)
{
int bit32 = 0;
if (dev->bus & DEVICE_PCI)
if (dev->card_bus & DEVICE_PCI)
bit32 = 1;
else if ((dev->bus & DEVICE_MCA) && (dev->flags & X54X_32BIT))
else if ((dev->card_bus & DEVICE_MCA) && (dev->flags & X54X_32BIT))
bit32 = 1;
return bit32;
@@ -1939,7 +1939,7 @@ x54x_init(const device_t *info)
memset(dev, 0x00, sizeof(x54x_t));
dev->type = info->local;
dev->bus = info->flags;
dev->card_bus = info->flags;
dev->callback_phase = 0;
timer_add(&dev->ResetCB, x54x_reset_poll, dev, 0);