Added the 3Com 3C503 Network card;
Several bug fixes; Preliminar addition of the SDL 2 renderer (does not yet work correctly in full screen mode); SCSI devices no longer have configurable LUN's (this matches the configurability of real SCSI devices); SCSI LUN's are now handed by the device's handler; Removed all unused strings; Removed some unused code files; Significantly rewrote the bus mouse emulation.
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Handling of the SCSI controllers.
|
||||
*
|
||||
* Version: @(#)scsi.c 1.0.19 2018/04/29
|
||||
* Version: @(#)scsi.c 1.0.20 2018/06/02
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
@@ -30,10 +30,12 @@
|
||||
#include "../timer.h"
|
||||
#include "../device.h"
|
||||
#include "../disk/hdc.h"
|
||||
#include "../disk/zip.h"
|
||||
#include "../disk/hdd.h"
|
||||
#include "../plat.h"
|
||||
#include "scsi.h"
|
||||
#include "../cdrom/cdrom.h"
|
||||
#include "../disk/zip.h"
|
||||
#include "scsi_disk.h"
|
||||
#include "scsi_device.h"
|
||||
#include "scsi_aha154x.h"
|
||||
#include "scsi_buslogic.h"
|
||||
@@ -45,11 +47,9 @@
|
||||
#include "scsi_x54x.h"
|
||||
|
||||
|
||||
scsi_device_t SCSIDevices[SCSI_ID_MAX][SCSI_LUN_MAX];
|
||||
// uint8_t SCSIPhase = 0xff;
|
||||
// uint8_t SCSIStatus = SCSI_STATUS_OK;
|
||||
scsi_device_t SCSIDevices[SCSI_ID_MAX];
|
||||
char scsi_fn[SCSI_NUM][512];
|
||||
uint16_t scsi_hd_location[SCSI_NUM];
|
||||
uint16_t scsi_disk_location[SCSI_NUM];
|
||||
|
||||
int scsi_card_current = 0;
|
||||
int scsi_card_last = 0;
|
||||
@@ -169,30 +169,30 @@ void scsi_mutex(uint8_t start)
|
||||
|
||||
void scsi_card_init(void)
|
||||
{
|
||||
int i, j;
|
||||
int i;
|
||||
|
||||
if (!scsi_cards[scsi_card_current].device)
|
||||
return;
|
||||
|
||||
scsi_log("Building SCSI hard disk map...\n");
|
||||
build_scsi_hd_map();
|
||||
build_scsi_disk_map();
|
||||
scsi_log("Building SCSI CD-ROM map...\n");
|
||||
build_scsi_cdrom_map();
|
||||
scsi_log("Building SCSI ZIP map...\n");
|
||||
build_scsi_zip_map();
|
||||
|
||||
for (i=0; i<SCSI_ID_MAX; i++) {
|
||||
for (j=0; j<SCSI_LUN_MAX; j++) {
|
||||
if (scsi_hard_disks[i][j] != 0xff)
|
||||
SCSIDevices[i][j].LunType = SCSI_DISK;
|
||||
else if (scsi_cdrom_drives[i][j] != 0xff)
|
||||
SCSIDevices[i][j].LunType = SCSI_CDROM;
|
||||
else if (scsi_zip_drives[i][j] != 0xff)
|
||||
SCSIDevices[i][j].LunType = SCSI_ZIP;
|
||||
else
|
||||
SCSIDevices[i][j].LunType = SCSI_NONE;
|
||||
SCSIDevices[i][j].CmdBuffer = NULL;
|
||||
}
|
||||
if (scsi_disks[i] != 0xff)
|
||||
SCSIDevices[i].LunType = SCSI_DISK;
|
||||
else if (scsi_cdrom_drives[i] != 0xff)
|
||||
SCSIDevices[i].LunType = SCSI_CDROM;
|
||||
else if (scsi_zip_drives[i] != 0xff)
|
||||
SCSIDevices[i].LunType = SCSI_ZIP;
|
||||
else
|
||||
SCSIDevices[i].LunType = SCSI_NONE;
|
||||
if (SCSIDevices[i].CmdBuffer)
|
||||
free(SCSIDevices[i].CmdBuffer);
|
||||
SCSIDevices[i].CmdBuffer = NULL;
|
||||
}
|
||||
|
||||
device_add(scsi_cards[scsi_card_current].device);
|
||||
@@ -202,27 +202,26 @@ void scsi_card_init(void)
|
||||
|
||||
|
||||
/* Initialization function for the SCSI layer */
|
||||
void SCSIReset(uint8_t id, uint8_t lun)
|
||||
void SCSIReset(uint8_t id)
|
||||
{
|
||||
uint8_t cdrom_id = scsi_cdrom_drives[id][lun];
|
||||
uint8_t zip_id = scsi_zip_drives[id][lun];
|
||||
uint8_t hdc_id = scsi_hard_disks[id][lun];
|
||||
uint8_t cdrom_id = scsi_cdrom_drives[id];
|
||||
uint8_t zip_id = scsi_zip_drives[id];
|
||||
uint8_t hdc_id = scsi_disks[id];
|
||||
|
||||
if (hdc_id != 0xff)
|
||||
SCSIDevices[id][lun].LunType = SCSI_DISK;
|
||||
SCSIDevices[id].LunType = SCSI_DISK;
|
||||
else if (cdrom_id != 0xff)
|
||||
SCSIDevices[id][lun].LunType = SCSI_CDROM;
|
||||
SCSIDevices[id].LunType = SCSI_CDROM;
|
||||
else if (zip_id != 0xff)
|
||||
SCSIDevices[id][lun].LunType = SCSI_ZIP;
|
||||
SCSIDevices[id].LunType = SCSI_ZIP;
|
||||
else
|
||||
SCSIDevices[id][lun].LunType = SCSI_NONE;
|
||||
SCSIDevices[id].LunType = SCSI_NONE;
|
||||
|
||||
scsi_device_reset(id, lun);
|
||||
scsi_device_reset(id);
|
||||
|
||||
if (SCSIDevices[id][lun].CmdBuffer != NULL) {
|
||||
free(SCSIDevices[id][lun].CmdBuffer);
|
||||
SCSIDevices[id][lun].CmdBuffer = NULL;
|
||||
}
|
||||
if (SCSIDevices[id].CmdBuffer)
|
||||
free(SCSIDevices[id].CmdBuffer);
|
||||
SCSIDevices[id].CmdBuffer = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* SCSI controller handler header.
|
||||
*
|
||||
* Version: @(#)scsi_h 1.0.16 2018/03/28
|
||||
* Version: @(#)scsi_h 1.0.17 2018/06/02
|
||||
*
|
||||
* Authors: TheCollector1995, <mariogplayer@gmail.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -290,9 +290,9 @@ typedef struct {
|
||||
} scsi_device_t;
|
||||
|
||||
|
||||
extern scsi_device_t SCSIDevices[SCSI_ID_MAX][SCSI_LUN_MAX];
|
||||
extern scsi_device_t SCSIDevices[SCSI_ID_MAX];
|
||||
|
||||
extern void SCSIReset(uint8_t id, uint8_t lun);
|
||||
extern void SCSIReset(uint8_t id);
|
||||
|
||||
extern int cdrom_add_error_and_subchannel(uint8_t *b, int real_sector_type);
|
||||
extern int cdrom_LBAtoMSF_accurate(void);
|
||||
@@ -314,17 +314,6 @@ extern int scsi_card_get_from_internal_name(char *s);
|
||||
extern void scsi_mutex(uint8_t start);
|
||||
extern void scsi_card_init(void);
|
||||
|
||||
extern uint8_t scsi_hard_disks[16][8];
|
||||
|
||||
extern int scsi_hd_err_stat_to_scsi(uint8_t id);
|
||||
extern int scsi_hd_phase_to_scsi(uint8_t id);
|
||||
extern int find_hdc_for_scsi_id(uint8_t scsi_id, uint8_t scsi_lun);
|
||||
extern void build_scsi_hd_map(void);
|
||||
extern void scsi_hd_reset(uint8_t id);
|
||||
extern void scsi_hd_request_sense_for_scsi(uint8_t id, uint8_t *buffer, uint8_t alloc_length);
|
||||
extern void scsi_hd_command(uint8_t id, uint8_t *cdb);
|
||||
extern void scsi_hd_callback(uint8_t id);
|
||||
|
||||
|
||||
#pragma pack(push,1)
|
||||
typedef struct {
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
* made by Adaptec, Inc. These controllers were designed for
|
||||
* the ISA bus.
|
||||
*
|
||||
* Version: @(#)scsi_aha154x.c 1.0.41 2018/04/26
|
||||
* Version: @(#)scsi_aha154x.c 1.0.42 2018/06/12
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Original Buslogic version by SA1988 and Miran Grca.
|
||||
@@ -573,7 +573,7 @@ aha_mca_write(int port, uint8_t val, void *priv)
|
||||
}
|
||||
|
||||
/* Say hello. */
|
||||
pclog("AHA-1640: I/O=%04x, IRQ=%d, DMA=%d, BIOS @%05X, HOST ID %i\n",
|
||||
aha_log("AHA-1640: I/O=%04x, IRQ=%d, DMA=%d, BIOS @%05X, HOST ID %i\n",
|
||||
dev->Base, dev->Irq, dev->DmaChannel, dev->rom_addr, dev->HostID);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* The generic SCSI bus operations handler.
|
||||
*
|
||||
* Version: @(#)scsi_bus.c 1.0.6 2018/01/06
|
||||
* Version: @(#)scsi_bus.c 1.0.7 2018/06/18
|
||||
*
|
||||
* NOTES: For now ported from PCem with some modifications
|
||||
* but at least it's a start.
|
||||
@@ -94,7 +94,6 @@ int
|
||||
scsi_bus_update(scsi_bus_t *bus, int bus_assert)
|
||||
{
|
||||
scsi_device_t *dev;
|
||||
uint8_t lun = 0;
|
||||
|
||||
if (bus_assert & BUS_ARB)
|
||||
bus->state = STATE_IDLE;
|
||||
@@ -108,7 +107,7 @@ scsi_bus_update(scsi_bus_t *bus, int bus_assert)
|
||||
|
||||
bus->dev_id = get_dev_id(sel_data);
|
||||
|
||||
if ((bus->dev_id != -1) && scsi_device_present(bus->dev_id, 0)) {
|
||||
if ((bus->dev_id != -1) && scsi_device_present(bus->dev_id)) {
|
||||
bus->bus_out |= BUS_BSY;
|
||||
bus->state = STATE_PHASESEL;
|
||||
}
|
||||
@@ -122,7 +121,7 @@ scsi_bus_update(scsi_bus_t *bus, int bus_assert)
|
||||
if (! (bus_assert & BUS_SEL)) {
|
||||
if (! (bus_assert & BUS_ATN)) {
|
||||
if ((bus->dev_id != -1) &&
|
||||
scsi_device_present(bus->dev_id, 0)) {
|
||||
scsi_device_present(bus->dev_id)) {
|
||||
bus->state = STATE_COMMAND;
|
||||
bus->bus_out = BUS_BSY | BUS_REQ;
|
||||
bus->command_pos = 0;
|
||||
@@ -146,20 +145,17 @@ scsi_bus_update(scsi_bus_t *bus, int bus_assert)
|
||||
bus->bus_out &= ~BUS_REQ;
|
||||
|
||||
if (get_cmd_len(bus->command[0]) == bus->command_pos) {
|
||||
lun = (bus->command[1] >> 5) & 7;
|
||||
bus->data_pos = 0;
|
||||
|
||||
dev = &SCSIDevices[bus->dev_id][lun];
|
||||
dev = &SCSIDevices[bus->dev_id];
|
||||
|
||||
scsi_bus_log("Command 0x%02X\n", bus->command[0]);
|
||||
|
||||
dev->BufferLength = -1;
|
||||
|
||||
scsi_device_command_phase0(bus->dev_id, lun,
|
||||
get_cmd_len(bus->command[0]),
|
||||
bus->command);
|
||||
scsi_device_command_phase0(bus->dev_id, bus->command);
|
||||
|
||||
scsi_bus_log("(%02X:%02X): Command %02X: Buffer Length %i, SCSI Phase %02X\n", bus->dev_id, lun, bus->command[0], dev->BufferLength, dev->Phase);
|
||||
scsi_bus_log("(ID %02X): Command %02X: Buffer Length %i, SCSI Phase %02X\n", bus->dev_id, bus->command[0], dev->BufferLength, dev->Phase);
|
||||
|
||||
if ((dev->Phase == SCSI_PHASE_DATA_IN) ||
|
||||
(dev->Phase == SCSI_PHASE_DATA_OUT)) {
|
||||
@@ -178,7 +174,7 @@ scsi_bus_update(scsi_bus_t *bus, int bus_assert)
|
||||
/* Other command - execute immediately. */
|
||||
bus->new_state = dev->Phase;
|
||||
if (dev->Phase == SCSI_PHASE_DATA_IN) {
|
||||
scsi_device_command_phase1(bus->dev_id, lun);
|
||||
scsi_device_command_phase1(bus->dev_id);
|
||||
}
|
||||
|
||||
bus->change_state_delay = 4;
|
||||
@@ -198,12 +194,9 @@ scsi_bus_update(scsi_bus_t *bus, int bus_assert)
|
||||
scsi_bus_log("State Data In\n");
|
||||
|
||||
/* This seems to be read, so we first execute the command, then we return the bytes to the host. */
|
||||
dev = &SCSIDevices[bus->dev_id];
|
||||
|
||||
lun = (bus->command[1] >> 5) & 7;
|
||||
|
||||
dev = &SCSIDevices[bus->dev_id][lun];
|
||||
|
||||
if (bus->data_pos >= SCSIDevices[bus->dev_id][lun].BufferLength) {
|
||||
if (bus->data_pos >= SCSIDevices[bus->dev_id].BufferLength) {
|
||||
free(dev->CmdBuffer);
|
||||
dev->CmdBuffer = NULL;
|
||||
bus->bus_out &= ~BUS_REQ;
|
||||
@@ -224,18 +217,15 @@ scsi_bus_update(scsi_bus_t *bus, int bus_assert)
|
||||
case STATE_DATAOUT:
|
||||
if ((bus_assert & BUS_ACK) && !(bus->bus_in & BUS_ACK)) {
|
||||
scsi_bus_log("State Data Out\n");
|
||||
|
||||
lun = (bus->command[1] >> 5) & 7;
|
||||
|
||||
dev = &SCSIDevices[bus->dev_id][lun];
|
||||
dev = &SCSIDevices[bus->dev_id];
|
||||
|
||||
/* This is write, so first get the data from the host, then execute the last phase of the command. */
|
||||
dev->CmdBuffer[bus->data_pos++] = BUS_GETDATA(bus_assert);
|
||||
|
||||
if (bus->data_pos >= SCSIDevices[bus->dev_id][lun].BufferLength) {
|
||||
if (bus->data_pos >= SCSIDevices[bus->dev_id].BufferLength) {
|
||||
/* scsi_bus_log("%04X bytes written (%02X %02X)\n", bus->data_pos, bus->command[0], bus->command[1]); */
|
||||
scsi_bus_log("Actually executing write command\n");
|
||||
scsi_device_command_phase1(bus->dev_id, lun);
|
||||
scsi_device_command_phase1(bus->dev_id);
|
||||
free(dev->CmdBuffer);
|
||||
dev->CmdBuffer = NULL;
|
||||
bus->bus_out &= ~BUS_REQ;
|
||||
@@ -281,7 +271,6 @@ int
|
||||
scsi_bus_read(scsi_bus_t *bus)
|
||||
{
|
||||
scsi_device_t *dev;
|
||||
uint8_t lun = 0;
|
||||
|
||||
if (bus->clear_req) {
|
||||
bus->clear_req--;
|
||||
@@ -304,8 +293,7 @@ scsi_bus_read(scsi_bus_t *bus)
|
||||
|
||||
switch (bus->bus_out & SCSI_PHASE_MESSAGE_IN) {
|
||||
case SCSI_PHASE_DATA_IN:
|
||||
lun = (bus->command[1] >> 5) & 7;
|
||||
dev = &SCSIDevices[bus->dev_id][lun];
|
||||
dev = &SCSIDevices[bus->dev_id];
|
||||
|
||||
scsi_bus_log("Phase data in\n");
|
||||
bus->state = STATE_DATAIN;
|
||||
@@ -324,8 +312,7 @@ scsi_bus_read(scsi_bus_t *bus)
|
||||
break;
|
||||
|
||||
case SCSI_PHASE_STATUS:
|
||||
lun = (bus->command[1] >> 5) & 7;
|
||||
dev = &SCSIDevices[bus->dev_id][lun];
|
||||
dev = &SCSIDevices[bus->dev_id];
|
||||
|
||||
scsi_bus_log("Phase status\n");
|
||||
bus->state = STATE_STATUS;
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
* 1 - BT-545S ISA;
|
||||
* 2 - BT-958D PCI
|
||||
*
|
||||
* Version: @(#)scsi_buslogic.c 1.0.38 2018/04/26
|
||||
* Version: @(#)scsi_buslogic.c 1.0.39 2018/06/11
|
||||
*
|
||||
* Authors: TheCollector1995, <mariogplayer@gmail.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -480,7 +480,7 @@ buslogic_get_irq(void *p)
|
||||
|
||||
HALocalRAM *HALR = &bl->LocalRAM;
|
||||
|
||||
if (bl->chip == CHIP_BUSLOGIC_PCI)
|
||||
if ((bl->chip == CHIP_BUSLOGIC_ISA_542) || (bl->chip == CHIP_BUSLOGIC_PCI))
|
||||
return dev->Irq;
|
||||
else
|
||||
return bl_irq[HALR->structured.autoSCSIData.uIrqChannel];
|
||||
@@ -499,6 +499,8 @@ buslogic_get_dma(void *p)
|
||||
|
||||
if (bl->chip == CHIP_BUSLOGIC_PCI)
|
||||
return (dev->Base ? 7 : 0);
|
||||
else if (bl->chip == CHIP_BUSLOGIC_ISA_542)
|
||||
return dev->DmaChannel;
|
||||
else
|
||||
return bl_dma[HALR->structured.autoSCSIData.uDMAChannel];
|
||||
}
|
||||
@@ -548,7 +550,7 @@ buslogic_param_len(void *p)
|
||||
|
||||
|
||||
static void
|
||||
BuslogicSCSIBIOSDMATransfer(ESCMD *ESCSICmd, uint8_t TargetID, uint8_t LUN, int dir)
|
||||
BuslogicSCSIBIOSDMATransfer(ESCMD *ESCSICmd, uint8_t TargetID, int dir)
|
||||
{
|
||||
uint32_t DataPointer = ESCSICmd->DataPointer;
|
||||
int DataLength = ESCSICmd->DataLength;
|
||||
@@ -565,16 +567,16 @@ BuslogicSCSIBIOSDMATransfer(ESCMD *ESCSICmd, uint8_t TargetID, uint8_t LUN, int
|
||||
|
||||
/* 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) && (SCSIDevices[TargetID][LUN].BufferLength > 0)) {
|
||||
if ((DataLength > 0) && (SCSIDevices[TargetID].BufferLength > 0)) {
|
||||
Address = DataPointer;
|
||||
TransferLength = MIN(DataLength, SCSIDevices[TargetID][LUN].BufferLength);
|
||||
TransferLength = MIN(DataLength, SCSIDevices[TargetID].BufferLength);
|
||||
|
||||
if (dir && ((ESCSICmd->DataDirection == CCB_DATA_XFER_OUT) || (ESCSICmd->DataDirection == 0x00))) {
|
||||
buslogic_log("BusLogic BIOS DMA: Reading %i bytes from %08X\n", TransferLength, Address);
|
||||
DMAPageRead(Address, (uint8_t *)SCSIDevices[TargetID][LUN].CmdBuffer, TransferLength);
|
||||
DMAPageRead(Address, (uint8_t *)SCSIDevices[TargetID].CmdBuffer, TransferLength);
|
||||
} 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);
|
||||
DMAPageWrite(Address, (uint8_t *)SCSIDevices[TargetID][LUN].CmdBuffer, TransferLength);
|
||||
DMAPageWrite(Address, (uint8_t *)SCSIDevices[TargetID].CmdBuffer, TransferLength);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -600,14 +602,14 @@ BuslogicSCSIBIOSRequestSetup(x54x_t *dev, uint8_t *CmdBuf, uint8_t *DataInBuf, u
|
||||
|
||||
buslogic_log("Scanning SCSI Target ID %i\n", ESCSICmd->TargetId);
|
||||
|
||||
SCSIDevices[ESCSICmd->TargetId][ESCSICmd->LogicalUnit].Status = SCSI_STATUS_OK;
|
||||
SCSIDevices[ESCSICmd->TargetId].Status = SCSI_STATUS_OK;
|
||||
|
||||
if (!scsi_device_present(ESCSICmd->TargetId, 0)) {
|
||||
buslogic_log("SCSI Target ID %i has no device attached\n",ESCSICmd->TargetId,ESCSICmd->LogicalUnit);
|
||||
if (!scsi_device_present(ESCSICmd->TargetId)) {
|
||||
buslogic_log("SCSI Target ID %i has no device attached\n", ESCSICmd->TargetId);
|
||||
DataInBuf[2] = CCB_SELECTION_TIMEOUT;
|
||||
DataInBuf[3] = SCSI_STATUS_OK;
|
||||
} else {
|
||||
buslogic_log("SCSI Target ID %i detected and working\n", ESCSICmd->TargetId, ESCSICmd->LogicalUnit);
|
||||
buslogic_log("SCSI Target ID %i detected and working\n", ESCSICmd->TargetId);
|
||||
|
||||
buslogic_log("Transfer Control %02X\n", ESCSICmd->DataDirection);
|
||||
buslogic_log("CDB Length %i\n", ESCSICmd->CDBLength);
|
||||
@@ -617,11 +619,11 @@ BuslogicSCSIBIOSRequestSetup(x54x_t *dev, uint8_t *CmdBuf, uint8_t *DataInBuf, u
|
||||
}
|
||||
}
|
||||
|
||||
x54x_buf_alloc(ESCSICmd->TargetId, ESCSICmd->LogicalUnit, ESCSICmd->DataLength);
|
||||
x54x_buf_alloc(ESCSICmd->TargetId, ESCSICmd->DataLength);
|
||||
|
||||
target_cdb_len = scsi_device_cdb_length(ESCSICmd->TargetId, ESCSICmd->LogicalUnit);
|
||||
target_cdb_len = 12;
|
||||
|
||||
if (!scsi_device_valid(ESCSICmd->TargetId, ESCSICmd->LogicalUnit)) fatal("SCSI target on %02i:%02i has disappeared\n", ESCSICmd->TargetId, ESCSICmd->LogicalUnit);
|
||||
if (!scsi_device_valid(ESCSICmd->TargetId)) fatal("SCSI target on ID %02i has disappeared\n", ESCSICmd->TargetId);
|
||||
|
||||
buslogic_log("SCSI target command being executed on: SCSI ID %i, SCSI LUN %i, Target %i\n", ESCSICmd->TargetId, ESCSICmd->LogicalUnit, target_id);
|
||||
|
||||
@@ -637,26 +639,26 @@ BuslogicSCSIBIOSRequestSetup(x54x_t *dev, uint8_t *CmdBuf, uint8_t *DataInBuf, u
|
||||
memcpy(temp_cdb, ESCSICmd->CDB, target_cdb_len);
|
||||
}
|
||||
|
||||
SCSIDevices[ESCSICmd->TargetId][ESCSICmd->LogicalUnit].BufferLength = ESCSICmd->DataLength;
|
||||
scsi_device_command_phase0(ESCSICmd->TargetId, ESCSICmd->LogicalUnit, ESCSICmd->CDBLength, temp_cdb);
|
||||
SCSIDevices[ESCSICmd->TargetId].BufferLength = ESCSICmd->DataLength;
|
||||
scsi_device_command_phase0(ESCSICmd->TargetId, temp_cdb);
|
||||
|
||||
phase = SCSIDevices[ESCSICmd->TargetId][ESCSICmd->LogicalUnit].Phase;
|
||||
phase = SCSIDevices[ESCSICmd->TargetId].Phase;
|
||||
if (phase != SCSI_PHASE_STATUS) {
|
||||
if (phase == SCSI_PHASE_DATA_IN)
|
||||
scsi_device_command_phase1(ESCSICmd->TargetId, ESCSICmd->LogicalUnit);
|
||||
BuslogicSCSIBIOSDMATransfer(ESCSICmd, ESCSICmd->TargetId, ESCSICmd->LogicalUnit, (phase == SCSI_PHASE_DATA_OUT));
|
||||
scsi_device_command_phase1(ESCSICmd->TargetId);
|
||||
BuslogicSCSIBIOSDMATransfer(ESCSICmd, ESCSICmd->TargetId, (phase == SCSI_PHASE_DATA_OUT));
|
||||
if (phase == SCSI_PHASE_DATA_OUT)
|
||||
scsi_device_command_phase1(ESCSICmd->TargetId, ESCSICmd->LogicalUnit);
|
||||
scsi_device_command_phase1(ESCSICmd->TargetId);
|
||||
}
|
||||
|
||||
x54x_buf_free(ESCSICmd->TargetId, ESCSICmd->LogicalUnit);
|
||||
x54x_buf_free(ESCSICmd->TargetId);
|
||||
|
||||
buslogic_log("BIOS Request complete\n");
|
||||
|
||||
if (SCSIDevices[ESCSICmd->TargetId][ESCSICmd->LogicalUnit].Status == SCSI_STATUS_OK) {
|
||||
if (SCSIDevices[ESCSICmd->TargetId].Status == SCSI_STATUS_OK) {
|
||||
DataInBuf[2] = CCB_COMPLETE;
|
||||
DataInBuf[3] = SCSI_STATUS_OK;
|
||||
} else if (SCSIDevices[ESCSICmd->TargetId][ESCSICmd->LogicalUnit].Status == SCSI_STATUS_CHECK_CONDITION) {
|
||||
} else if (SCSIDevices[ESCSICmd->TargetId].Status == SCSI_STATUS_CHECK_CONDITION) {
|
||||
DataInBuf[2] = CCB_COMPLETE;
|
||||
DataInBuf[3] = SCSI_STATUS_CHECK_CONDITION;
|
||||
}
|
||||
@@ -677,7 +679,6 @@ buslogic_cmds(void *p)
|
||||
uint16_t TargetsPresentMask = 0;
|
||||
uint32_t Offset;
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
MailboxInitExtended_t *MailboxInitE;
|
||||
ReplyInquireExtendedSetupInformation *ReplyIESI;
|
||||
BuslogicPCIInformation_t *ReplyPI;
|
||||
@@ -697,16 +698,14 @@ buslogic_cmds(void *p)
|
||||
memset(dev->DataBuf, 0, 8);
|
||||
for (i = 8; i < 15; i++) {
|
||||
dev->DataBuf[i-8] = 0;
|
||||
for (j=0; j<8; j++) {
|
||||
if (scsi_device_present(i, j) && (i != buslogic_get_host_id(dev)))
|
||||
dev->DataBuf[i-8] |= (1<<j);
|
||||
}
|
||||
if (scsi_device_present(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(i, 0) && (i != buslogic_get_host_id(dev)))
|
||||
if (scsi_device_present(i) && (i != buslogic_get_host_id(dev)))
|
||||
TargetsPresentMask |= (1 << i);
|
||||
}
|
||||
dev->DataBuf[0] = TargetsPresentMask & 0xFF;
|
||||
@@ -1387,6 +1386,7 @@ buslogic_mca_write(int port, uint8_t val, void *priv)
|
||||
* pos[2]=000xxxxx = 0
|
||||
*/
|
||||
dev->HostID = (dev->pos_regs[4] >> 5) & 0x07;
|
||||
HALR->structured.autoSCSIData.uSCSIId = dev->HostID;
|
||||
|
||||
/*
|
||||
* SYNC mode is pos[2]=xxxxxx1x.
|
||||
@@ -1406,6 +1406,45 @@ buslogic_mca_write(int port, uint8_t val, void *priv)
|
||||
HALR->structured.autoSCSIData.uBIOSConfiguration &= ~4;
|
||||
HALR->structured.autoSCSIData.uBIOSConfiguration |= (dev->pos_regs[4] & 8) ? 4 : 0;
|
||||
|
||||
switch(dev->DmaChannel) {
|
||||
case 5:
|
||||
HALR->structured.autoSCSIData.uDMAChannel = 1;
|
||||
break;
|
||||
case 6:
|
||||
HALR->structured.autoSCSIData.uDMAChannel = 2;
|
||||
break;
|
||||
case 7:
|
||||
HALR->structured.autoSCSIData.uDMAChannel = 3;
|
||||
break;
|
||||
default:
|
||||
HALR->structured.autoSCSIData.uDMAChannel = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
switch(dev->Irq) {
|
||||
case 9:
|
||||
HALR->structured.autoSCSIData.uIrqChannel = 1;
|
||||
break;
|
||||
case 10:
|
||||
HALR->structured.autoSCSIData.uIrqChannel = 2;
|
||||
break;
|
||||
case 11:
|
||||
HALR->structured.autoSCSIData.uIrqChannel = 3;
|
||||
break;
|
||||
case 12:
|
||||
HALR->structured.autoSCSIData.uIrqChannel = 4;
|
||||
break;
|
||||
case 14:
|
||||
HALR->structured.autoSCSIData.uIrqChannel = 5;
|
||||
break;
|
||||
case 15:
|
||||
HALR->structured.autoSCSIData.uIrqChannel = 6;
|
||||
break;
|
||||
default:
|
||||
HALR->structured.autoSCSIData.uIrqChannel = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* The PS/2 Model 80 BIOS always enables a card if it finds one,
|
||||
* even if no resources were assigned yet (because we only added
|
||||
@@ -1430,8 +1469,8 @@ buslogic_mca_write(int port, uint8_t val, void *priv)
|
||||
}
|
||||
|
||||
/* Say hello. */
|
||||
pclog("BT-640A: I/O=%04x, IRQ=%d, DMA=%d, BIOS @%05X, HOST ID %i\n",
|
||||
dev->Base, dev->Irq, dev->DmaChannel, bl->bios_addr, dev->HostID);
|
||||
buslogic_log("BT-640A: I/O=%04x, IRQ=%d, DMA=%d, BIOS @%05X, HOST ID %i\n",
|
||||
dev->Base, dev->Irq, dev->DmaChannel, bl->bios_addr, dev->HostID);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* The generic SCSI device command handler.
|
||||
*
|
||||
* Version: @(#)scsi_device.c 1.0.16 2018/03/26
|
||||
* Version: @(#)scsi_device.c 1.0.17 2018/06/02
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
@@ -23,120 +23,85 @@
|
||||
#include "../86box.h"
|
||||
#include "../device.h"
|
||||
#include "../disk/hdd.h"
|
||||
#include "../disk/zip.h"
|
||||
#include "scsi.h"
|
||||
#include "scsi_device.h"
|
||||
#include "../cdrom/cdrom.h"
|
||||
#include "../disk/zip.h"
|
||||
#include "scsi_disk.h"
|
||||
|
||||
|
||||
static uint8_t scsi_null_device_sense[14] = { 0x70,0,SENSE_ILLEGAL_REQUEST,0,0,0,0,0,0,0,0,0,ASC_INV_LUN,0 };
|
||||
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 };
|
||||
|
||||
|
||||
static uint8_t scsi_device_target_command(int lun_type, uint8_t id, uint8_t *cdb)
|
||||
static uint8_t
|
||||
scsi_device_target_command(int lun_type, uint8_t id, uint8_t *cdb)
|
||||
{
|
||||
if (lun_type == SCSI_DISK)
|
||||
{
|
||||
scsi_hd_command(id, cdb);
|
||||
return scsi_hd_err_stat_to_scsi(id);
|
||||
}
|
||||
else if (lun_type == SCSI_CDROM)
|
||||
{
|
||||
switch(lun_type) {
|
||||
case SCSI_DISK:
|
||||
scsi_disk_command(scsi_disk[id], cdb);
|
||||
return scsi_disk_err_stat_to_scsi(scsi_disk[id]);
|
||||
case SCSI_CDROM:
|
||||
cdrom_command(cdrom[id], cdb);
|
||||
return cdrom_CDROM_PHASE_to_scsi(cdrom[id]);
|
||||
}
|
||||
else if (lun_type == SCSI_ZIP)
|
||||
{
|
||||
zip_command(id, cdb);
|
||||
return zip_ZIP_PHASE_to_scsi(id);
|
||||
}
|
||||
else
|
||||
{
|
||||
case SCSI_ZIP:
|
||||
zip_command(zip[id], cdb);
|
||||
return zip_ZIP_PHASE_to_scsi(zip[id]);
|
||||
default:
|
||||
return SCSI_STATUS_CHECK_CONDITION;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void scsi_device_target_phase_callback(int lun_type, uint8_t id)
|
||||
{
|
||||
if (lun_type == SCSI_DISK)
|
||||
{
|
||||
scsi_hd_callback(id);
|
||||
}
|
||||
else if (lun_type == SCSI_CDROM)
|
||||
{
|
||||
switch(lun_type) {
|
||||
case SCSI_DISK:
|
||||
scsi_disk_callback(scsi_disk[id]);
|
||||
break;
|
||||
case SCSI_CDROM:
|
||||
cdrom_phase_callback(cdrom[id]);
|
||||
}
|
||||
else if (lun_type == SCSI_ZIP)
|
||||
{
|
||||
zip_phase_callback(id);
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case SCSI_ZIP:
|
||||
zip_phase_callback(zip[id]);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static int scsi_device_target_err_stat_to_scsi(int lun_type, uint8_t id)
|
||||
{
|
||||
if (lun_type == SCSI_DISK)
|
||||
{
|
||||
return scsi_hd_err_stat_to_scsi(id);
|
||||
}
|
||||
else if (lun_type == SCSI_CDROM)
|
||||
{
|
||||
switch(lun_type) {
|
||||
case SCSI_DISK:
|
||||
return scsi_disk_err_stat_to_scsi(scsi_disk[id]);
|
||||
case SCSI_CDROM:
|
||||
return cdrom_CDROM_PHASE_to_scsi(cdrom[id]);
|
||||
}
|
||||
else if (lun_type == SCSI_ZIP)
|
||||
{
|
||||
return zip_ZIP_PHASE_to_scsi(id);
|
||||
}
|
||||
else
|
||||
{
|
||||
case SCSI_ZIP:
|
||||
return zip_ZIP_PHASE_to_scsi(zip[id]);
|
||||
default:
|
||||
return SCSI_STATUS_CHECK_CONDITION;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void scsi_device_target_save_cdb_byte(int lun_type, uint8_t id, uint8_t cdb_byte)
|
||||
int64_t scsi_device_get_callback(uint8_t scsi_id)
|
||||
{
|
||||
if (lun_type == SCSI_DISK)
|
||||
{
|
||||
shdc[id].request_length = cdb_byte;
|
||||
}
|
||||
else if (lun_type == SCSI_CDROM)
|
||||
{
|
||||
cdrom[id]->request_length = cdb_byte;
|
||||
}
|
||||
else if (lun_type == SCSI_ZIP)
|
||||
{
|
||||
zip[id]->request_length = cdb_byte;
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int64_t scsi_device_get_callback(uint8_t scsi_id, uint8_t scsi_lun)
|
||||
{
|
||||
uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType;
|
||||
uint8_t lun_type = SCSIDevices[scsi_id].LunType;
|
||||
|
||||
uint8_t id = 0;
|
||||
|
||||
switch (lun_type)
|
||||
{
|
||||
case SCSI_DISK:
|
||||
id = scsi_hard_disks[scsi_id][scsi_lun];
|
||||
return shdc[id].callback;
|
||||
id = scsi_disks[scsi_id];
|
||||
return scsi_disk[id]->callback;
|
||||
break;
|
||||
case SCSI_CDROM:
|
||||
id = scsi_cdrom_drives[scsi_id][scsi_lun];
|
||||
id = scsi_cdrom_drives[scsi_id];
|
||||
return cdrom[id]->callback;
|
||||
break;
|
||||
case SCSI_ZIP:
|
||||
id = scsi_zip_drives[scsi_id][scsi_lun];
|
||||
id = scsi_zip_drives[scsi_id];
|
||||
return zip[id]->callback;
|
||||
break;
|
||||
default:
|
||||
@@ -146,24 +111,24 @@ int64_t scsi_device_get_callback(uint8_t scsi_id, uint8_t scsi_lun)
|
||||
}
|
||||
|
||||
|
||||
uint8_t *scsi_device_sense(uint8_t scsi_id, uint8_t scsi_lun)
|
||||
uint8_t *scsi_device_sense(uint8_t scsi_id)
|
||||
{
|
||||
uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType;
|
||||
uint8_t lun_type = SCSIDevices[scsi_id].LunType;
|
||||
|
||||
uint8_t id = 0;
|
||||
|
||||
switch (lun_type)
|
||||
{
|
||||
case SCSI_DISK:
|
||||
id = scsi_hard_disks[scsi_id][scsi_lun];
|
||||
return shdc[id].sense;
|
||||
id = scsi_disks[scsi_id];
|
||||
return scsi_disk[id]->sense;
|
||||
break;
|
||||
case SCSI_CDROM:
|
||||
id = scsi_cdrom_drives[scsi_id][scsi_lun];
|
||||
id = scsi_cdrom_drives[scsi_id];
|
||||
return cdrom[id]->sense;
|
||||
break;
|
||||
case SCSI_ZIP:
|
||||
id = scsi_zip_drives[scsi_id][scsi_lun];
|
||||
id = scsi_zip_drives[scsi_id];
|
||||
return zip[id]->sense;
|
||||
break;
|
||||
default:
|
||||
@@ -173,25 +138,25 @@ uint8_t *scsi_device_sense(uint8_t scsi_id, uint8_t scsi_lun)
|
||||
}
|
||||
|
||||
|
||||
void scsi_device_request_sense(uint8_t scsi_id, uint8_t scsi_lun, uint8_t *buffer, uint8_t alloc_length)
|
||||
void scsi_device_request_sense(uint8_t scsi_id, uint8_t *buffer, uint8_t alloc_length)
|
||||
{
|
||||
uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType;
|
||||
uint8_t lun_type = SCSIDevices[scsi_id].LunType;
|
||||
|
||||
uint8_t id = 0;
|
||||
|
||||
switch (lun_type)
|
||||
{
|
||||
case SCSI_DISK:
|
||||
id = scsi_hard_disks[scsi_id][scsi_lun];
|
||||
scsi_hd_request_sense_for_scsi(id, buffer, alloc_length);
|
||||
id = scsi_disks[scsi_id];
|
||||
scsi_disk_request_sense_for_scsi(scsi_disk[id], buffer, alloc_length);
|
||||
break;
|
||||
case SCSI_CDROM:
|
||||
id = scsi_cdrom_drives[scsi_id][scsi_lun];
|
||||
id = scsi_cdrom_drives[scsi_id];
|
||||
cdrom_request_sense_for_scsi(cdrom[id], buffer, alloc_length);
|
||||
break;
|
||||
case SCSI_ZIP:
|
||||
id = scsi_zip_drives[scsi_id][scsi_lun];
|
||||
zip_request_sense_for_scsi(id, buffer, alloc_length);
|
||||
id = scsi_zip_drives[scsi_id];
|
||||
zip_request_sense_for_scsi(zip[id], buffer, alloc_length);
|
||||
break;
|
||||
default:
|
||||
memcpy(buffer, scsi_null_device_sense, alloc_length);
|
||||
@@ -200,33 +165,33 @@ void scsi_device_request_sense(uint8_t scsi_id, uint8_t scsi_lun, uint8_t *buffe
|
||||
}
|
||||
|
||||
|
||||
void scsi_device_reset(uint8_t scsi_id, uint8_t scsi_lun)
|
||||
void scsi_device_reset(uint8_t scsi_id)
|
||||
{
|
||||
uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType;
|
||||
uint8_t lun_type = SCSIDevices[scsi_id].LunType;
|
||||
|
||||
uint8_t id = 0;
|
||||
|
||||
switch (lun_type)
|
||||
{
|
||||
case SCSI_DISK:
|
||||
id = scsi_hard_disks[scsi_id][scsi_lun];
|
||||
scsi_hd_reset(id);
|
||||
id = scsi_disks[scsi_id];
|
||||
scsi_disk_reset(scsi_disk[id]);
|
||||
break;
|
||||
case SCSI_CDROM:
|
||||
id = scsi_cdrom_drives[scsi_id][scsi_lun];
|
||||
id = scsi_cdrom_drives[scsi_id];
|
||||
cdrom_reset(cdrom[id]);
|
||||
break;
|
||||
case SCSI_ZIP:
|
||||
id = scsi_zip_drives[scsi_id][scsi_lun];
|
||||
zip_reset(id);
|
||||
id = scsi_zip_drives[scsi_id];
|
||||
zip_reset(zip[id]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void scsi_device_type_data(uint8_t scsi_id, uint8_t scsi_lun, uint8_t *type, uint8_t *rmb)
|
||||
void scsi_device_type_data(uint8_t scsi_id, uint8_t *type, uint8_t *rmb)
|
||||
{
|
||||
uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType;
|
||||
uint8_t lun_type = SCSIDevices[scsi_id].LunType;
|
||||
|
||||
switch (lun_type)
|
||||
{
|
||||
@@ -248,32 +213,32 @@ void scsi_device_type_data(uint8_t scsi_id, uint8_t scsi_lun, uint8_t *type, uin
|
||||
}
|
||||
|
||||
|
||||
int scsi_device_read_capacity(uint8_t scsi_id, uint8_t scsi_lun, uint8_t *cdb, uint8_t *buffer, uint32_t *len)
|
||||
int scsi_device_read_capacity(uint8_t scsi_id, uint8_t *cdb, uint8_t *buffer, uint32_t *len)
|
||||
{
|
||||
uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType;
|
||||
uint8_t lun_type = SCSIDevices[scsi_id].LunType;
|
||||
|
||||
uint8_t id = 0;
|
||||
|
||||
switch (lun_type)
|
||||
{
|
||||
case SCSI_DISK:
|
||||
id = scsi_hard_disks[scsi_id][scsi_lun];
|
||||
return scsi_hd_read_capacity(id, cdb, buffer, len);
|
||||
id = scsi_disks[scsi_id];
|
||||
return scsi_disk_read_capacity(scsi_disk[id], cdb, buffer, len);
|
||||
case SCSI_CDROM:
|
||||
id = scsi_cdrom_drives[scsi_id][scsi_lun];
|
||||
id = scsi_cdrom_drives[scsi_id];
|
||||
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);
|
||||
id = scsi_zip_drives[scsi_id];
|
||||
return zip_read_capacity(zip[id], cdb, buffer, len);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int scsi_device_present(uint8_t scsi_id, uint8_t scsi_lun)
|
||||
int scsi_device_present(uint8_t scsi_id)
|
||||
{
|
||||
uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType;
|
||||
uint8_t lun_type = SCSIDevices[scsi_id].LunType;
|
||||
|
||||
switch (lun_type)
|
||||
{
|
||||
@@ -285,22 +250,22 @@ int scsi_device_present(uint8_t scsi_id, uint8_t scsi_lun)
|
||||
}
|
||||
|
||||
|
||||
int scsi_device_valid(uint8_t scsi_id, uint8_t scsi_lun)
|
||||
int scsi_device_valid(uint8_t scsi_id)
|
||||
{
|
||||
uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType;
|
||||
uint8_t lun_type = SCSIDevices[scsi_id].LunType;
|
||||
|
||||
uint8_t id = 0;
|
||||
|
||||
switch (lun_type)
|
||||
{
|
||||
case SCSI_DISK:
|
||||
id = scsi_hard_disks[scsi_id][scsi_lun];
|
||||
id = scsi_disks[scsi_id];
|
||||
break;
|
||||
case SCSI_CDROM:
|
||||
id = scsi_cdrom_drives[scsi_id][scsi_lun];
|
||||
id = scsi_cdrom_drives[scsi_id];
|
||||
break;
|
||||
case SCSI_ZIP:
|
||||
id = scsi_zip_drives[scsi_id][scsi_lun];
|
||||
id = scsi_zip_drives[scsi_id];
|
||||
break;
|
||||
default:
|
||||
id = 0;
|
||||
@@ -311,106 +276,74 @@ int scsi_device_valid(uint8_t scsi_id, uint8_t scsi_lun)
|
||||
}
|
||||
|
||||
|
||||
int scsi_device_cdb_length(uint8_t scsi_id, uint8_t scsi_lun)
|
||||
int scsi_device_cdb_length(uint8_t scsi_id)
|
||||
{
|
||||
uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType;
|
||||
|
||||
uint8_t id = 0;
|
||||
|
||||
switch (lun_type)
|
||||
{
|
||||
case SCSI_CDROM:
|
||||
id = scsi_cdrom_drives[scsi_id][scsi_lun];
|
||||
return cdrom[id]->cdb_len;
|
||||
case SCSI_ZIP:
|
||||
id = scsi_zip_drives[scsi_id][scsi_lun];
|
||||
return zip[id]->cdb_len;
|
||||
default:
|
||||
return 12;
|
||||
}
|
||||
/* Right now, it's 12 for all devices. */
|
||||
return 12;
|
||||
}
|
||||
|
||||
|
||||
void scsi_device_command_phase0(uint8_t scsi_id, uint8_t scsi_lun, int cdb_len, uint8_t *cdb)
|
||||
void scsi_device_command_phase0(uint8_t scsi_id, uint8_t *cdb)
|
||||
{
|
||||
uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType;
|
||||
|
||||
uint8_t id = 0;
|
||||
uint8_t lun_type = SCSIDevices[scsi_id].LunType;
|
||||
|
||||
switch (lun_type)
|
||||
{
|
||||
switch (lun_type) {
|
||||
case SCSI_DISK:
|
||||
id = scsi_hard_disks[scsi_id][scsi_lun];
|
||||
id = scsi_disks[scsi_id];
|
||||
break;
|
||||
case SCSI_CDROM:
|
||||
id = scsi_cdrom_drives[scsi_id][scsi_lun];
|
||||
id = scsi_cdrom_drives[scsi_id];
|
||||
break;
|
||||
case SCSI_ZIP:
|
||||
id = scsi_zip_drives[scsi_id][scsi_lun];
|
||||
id = scsi_zip_drives[scsi_id];
|
||||
break;
|
||||
default:
|
||||
id = 0;
|
||||
SCSIDevices[scsi_id][scsi_lun].Phase = SCSI_PHASE_STATUS;
|
||||
SCSIDevices[scsi_id][scsi_lun].Status = SCSI_STATUS_CHECK_CONDITION;
|
||||
SCSIDevices[scsi_id].Phase = SCSI_PHASE_STATUS;
|
||||
SCSIDevices[scsi_id].Status = SCSI_STATUS_CHECK_CONDITION;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Since that field in the target struct is never used when
|
||||
* the bus type is SCSI, let's use it for this scope.
|
||||
*/
|
||||
scsi_device_target_save_cdb_byte(lun_type, id, cdb[1]);
|
||||
|
||||
if (cdb_len != 12) {
|
||||
/*
|
||||
* Make sure the LUN field of the temporary CDB is always 0,
|
||||
* otherwise Daemon Tools drives will misbehave when a command
|
||||
* is passed through to them.
|
||||
*/
|
||||
cdb[1] &= 0x1f;
|
||||
}
|
||||
|
||||
/* Finally, execute the SCSI command immediately and get the transfer length. */
|
||||
SCSIDevices[scsi_id][scsi_lun].Phase = SCSI_PHASE_COMMAND;
|
||||
SCSIDevices[scsi_id][scsi_lun].Status = scsi_device_target_command(lun_type, id, cdb);
|
||||
SCSIDevices[scsi_id].Phase = SCSI_PHASE_COMMAND;
|
||||
SCSIDevices[scsi_id].Status = scsi_device_target_command(lun_type, id, cdb);
|
||||
|
||||
if (SCSIDevices[scsi_id][scsi_lun].Phase == SCSI_PHASE_STATUS) {
|
||||
if (SCSIDevices[scsi_id].Phase == SCSI_PHASE_STATUS) {
|
||||
/* Command completed (either OK or error) - call the phase callback to complete the command. */
|
||||
scsi_device_target_phase_callback(lun_type, id);
|
||||
}
|
||||
/* If the phase is DATA IN or DATA OUT, finish this here. */
|
||||
}
|
||||
|
||||
void scsi_device_command_phase1(uint8_t scsi_id, uint8_t scsi_lun)
|
||||
void scsi_device_command_phase1(uint8_t scsi_id)
|
||||
{
|
||||
uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType;
|
||||
uint8_t id = 0;
|
||||
uint8_t lun_type = SCSIDevices[scsi_id].LunType;
|
||||
|
||||
uint8_t id = 0;
|
||||
switch (lun_type) {
|
||||
case SCSI_DISK:
|
||||
id = scsi_disks[scsi_id];
|
||||
break;
|
||||
case SCSI_CDROM:
|
||||
id = scsi_cdrom_drives[scsi_id];
|
||||
break;
|
||||
case SCSI_ZIP:
|
||||
id = scsi_zip_drives[scsi_id];
|
||||
break;
|
||||
default:
|
||||
id = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (lun_type)
|
||||
{
|
||||
case SCSI_DISK:
|
||||
id = scsi_hard_disks[scsi_id][scsi_lun];
|
||||
break;
|
||||
case SCSI_CDROM:
|
||||
id = scsi_cdrom_drives[scsi_id][scsi_lun];
|
||||
break;
|
||||
case SCSI_ZIP:
|
||||
id = scsi_zip_drives[scsi_id][scsi_lun];
|
||||
break;
|
||||
default:
|
||||
id = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Call the second phase. */
|
||||
scsi_device_target_phase_callback(lun_type, id);
|
||||
SCSIDevices[scsi_id][scsi_lun].Status = scsi_device_target_err_stat_to_scsi(lun_type, id);
|
||||
/* Command second phase complete - call the callback to complete the command. */
|
||||
scsi_device_target_phase_callback(lun_type, id);
|
||||
/* Call the second phase. */
|
||||
scsi_device_target_phase_callback(lun_type, id);
|
||||
SCSIDevices[scsi_id].Status = scsi_device_target_err_stat_to_scsi(lun_type, id);
|
||||
/* Command second phase complete - call the callback to complete the command. */
|
||||
scsi_device_target_phase_callback(lun_type, id);
|
||||
}
|
||||
|
||||
int32_t *scsi_device_get_buf_len(uint8_t scsi_id, uint8_t scsi_lun)
|
||||
int32_t *scsi_device_get_buf_len(uint8_t scsi_id)
|
||||
{
|
||||
return &SCSIDevices[scsi_id][scsi_lun].BufferLength;
|
||||
return &SCSIDevices[scsi_id].BufferLength;
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Definitions for the generic SCSI device command handler.
|
||||
*
|
||||
* Version: @(#)scsi_device.h 1.0.7 2018/03/29
|
||||
* Version: @(#)scsi_device.h 1.0.8 2018/06/12
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
@@ -32,26 +32,21 @@ typedef struct
|
||||
int new_req_delay;
|
||||
} scsi_bus_t;
|
||||
|
||||
extern uint8_t *scsi_device_sense(uint8_t id, uint8_t lun);
|
||||
extern void scsi_device_type_data(uint8_t id, uint8_t lun,
|
||||
uint8_t *type, uint8_t *rmb);
|
||||
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,
|
||||
extern uint8_t *scsi_device_sense(uint8_t id);
|
||||
extern void scsi_device_type_data(uint8_t id, uint8_t *type, uint8_t *rmb);
|
||||
extern int64_t scsi_device_get_callback(uint8_t scsi_id);
|
||||
extern void scsi_device_request_sense(uint8_t scsi_id, 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);
|
||||
extern int scsi_device_present(uint8_t id, uint8_t lun);
|
||||
extern int scsi_device_valid(uint8_t id, uint8_t lun);
|
||||
extern int scsi_device_cdb_length(uint8_t id, uint8_t lun);
|
||||
extern void scsi_device_command(uint8_t id, uint8_t lun, int cdb_len,
|
||||
uint8_t *cdb);
|
||||
extern void scsi_device_command_phase0(uint8_t scsi_id, uint8_t scsi_lun,
|
||||
int cdb_len, uint8_t *cdb);
|
||||
extern void scsi_device_command_phase1(uint8_t scsi_id, uint8_t scsi_lun);
|
||||
extern int32_t *scsi_device_get_buf_len(uint8_t scsi_id, uint8_t scsi_lun);
|
||||
extern void scsi_device_reset(uint8_t scsi_id);
|
||||
extern int scsi_device_read_capacity(uint8_t id, uint8_t *cdb,
|
||||
uint8_t *buffer, uint32_t *len);
|
||||
extern int scsi_device_present(uint8_t id);
|
||||
extern int scsi_device_valid(uint8_t id);
|
||||
extern int scsi_device_cdb_length(uint8_t id);
|
||||
extern void scsi_device_command(uint8_t id, int cdb_len, uint8_t *cdb);
|
||||
extern void scsi_device_command_phase0(uint8_t scsi_id, uint8_t *cdb);
|
||||
extern void scsi_device_command_phase1(uint8_t scsi_id);
|
||||
extern int32_t *scsi_device_get_buf_len(uint8_t scsi_id);
|
||||
|
||||
extern int scsi_bus_update(scsi_bus_t *bus, int bus_assert);
|
||||
extern int scsi_bus_read(scsi_bus_t *bus);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -6,7 +6,7 @@
|
||||
*
|
||||
* Emulation of SCSI fixed and removable disks.
|
||||
*
|
||||
* Version: @(#)scsi_disk.h 1.0.4 2018/04/24
|
||||
* Version: @(#)scsi_disk.h 1.0.5 2018/06/02
|
||||
*
|
||||
* Author: Miran Grca, <mgrca8@gmail.com>
|
||||
* Copyright 2017,2018 Miran Grca.
|
||||
@@ -14,32 +14,47 @@
|
||||
|
||||
|
||||
typedef struct {
|
||||
/* Stuff for SCSI hard disks. */
|
||||
uint8_t status, phase,
|
||||
error,
|
||||
current_cdb[16],
|
||||
sense[256];
|
||||
mode_sense_pages_t ms_pages_saved;
|
||||
|
||||
uint16_t request_length;
|
||||
hard_disk_t *drv;
|
||||
|
||||
int requested_blocks, block_total,
|
||||
packet_status, callback,
|
||||
block_descriptor_len,
|
||||
total_length, do_page_save;
|
||||
/* Stuff for SCSI hard disks. */
|
||||
uint8_t status, phase,
|
||||
error, id,
|
||||
current_cdb[16],
|
||||
sense[256];
|
||||
|
||||
uint32_t sector_pos, sector_len,
|
||||
packet_len;
|
||||
uint16_t request_length;
|
||||
|
||||
uint64_t current_page_code;
|
||||
int requested_blocks, block_total,
|
||||
packet_status, callback,
|
||||
block_descriptor_len,
|
||||
total_length, do_page_save;
|
||||
|
||||
uint8_t *temp_buffer;
|
||||
} scsi_hard_disk_t;
|
||||
uint32_t sector_pos, sector_len,
|
||||
packet_len;
|
||||
|
||||
uint64_t current_page_code;
|
||||
|
||||
uint8_t *temp_buffer;
|
||||
} scsi_disk_t;
|
||||
|
||||
|
||||
extern scsi_hard_disk_t shdc[HDD_NUM];
|
||||
extern FILE *shdf[HDD_NUM];
|
||||
extern scsi_disk_t *scsi_disk[HDD_NUM];
|
||||
extern uint8_t scsi_disks[16];
|
||||
|
||||
|
||||
extern void scsi_loadhd(int scsi_id, int scsi_lun, int id);
|
||||
extern void scsi_loadhd(int scsi_id, int id);
|
||||
extern void scsi_disk_global_init(void);
|
||||
extern void scsi_disk_hard_reset(void);
|
||||
extern void scsi_disk_close(void);
|
||||
|
||||
int scsi_hd_read_capacity(uint8_t id, uint8_t *cdb, uint8_t *buffer, uint32_t *len);
|
||||
extern int scsi_disk_read_capacity(scsi_disk_t *dev, uint8_t *cdb, uint8_t *buffer, uint32_t *len);
|
||||
extern int scsi_disk_err_stat_to_scsi(scsi_disk_t *dev);
|
||||
extern int scsi_disk_phase_to_scsi(scsi_disk_t *dev);
|
||||
extern int find_hdd_for_scsi_id(uint8_t scsi_id);
|
||||
extern void build_scsi_disk_map(void);
|
||||
extern void scsi_disk_reset(scsi_disk_t *dev);
|
||||
extern void scsi_disk_request_sense_for_scsi(scsi_disk_t *dev, uint8_t *buffer, uint8_t alloc_length);
|
||||
extern void scsi_disk_command(scsi_disk_t *dev, uint8_t *cdb);
|
||||
extern void scsi_disk_callback(scsi_disk_t *dev);
|
||||
|
||||
@@ -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.14 2018/04/26
|
||||
* Version: @(#)scsi_ncr5380.c 1.0.15 2018/06/13
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* TheCollector1995, <mariogplayer@gmail.com>
|
||||
@@ -290,7 +290,7 @@ ncr_write(uint16_t port, uint8_t val, void *priv)
|
||||
|
||||
default:
|
||||
#if 1
|
||||
pclog("NCR5380: bad write %04x %02x\n", port, val);
|
||||
ncr_log("NCR5380: bad write %04x %02x\n", port, val);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
@@ -496,7 +496,7 @@ dma_callback(void *priv)
|
||||
|
||||
default:
|
||||
#if 1
|
||||
pclog("DMA callback bad mode %i\n", scsi->ncr.dma_mode);
|
||||
ncr_log("DMA callback bad mode %i\n", scsi->ncr.dma_mode);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
@@ -668,9 +668,12 @@ t130b_read(uint32_t addr, void *priv)
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
addr &= 0x3fff;
|
||||
if (addr < 0x1800)
|
||||
if ((addr < 0x1800) && scsi->rom_addr)
|
||||
ret = scsi->bios_rom.rom[addr & 0x1fff];
|
||||
else
|
||||
if ((addr < 0x1800) && !scsi->rom_addr)
|
||||
ret = 0xff;
|
||||
else
|
||||
if (addr < 0x1880)
|
||||
ret = scsi->ext_ram[addr & 0x7f];
|
||||
|
||||
@@ -849,47 +852,79 @@ ncr_init(const device_t *info)
|
||||
break;
|
||||
|
||||
case 1: /* Ranco RT1000B */
|
||||
scsi->rom_addr = 0xDC000;
|
||||
rom_init(&scsi->bios_rom, RT1000B_ROM,
|
||||
scsi->rom_addr, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL);
|
||||
scsi->base = device_get_config_hex16("base");
|
||||
scsi->rom_addr = device_get_config_hex20("bios_addr");
|
||||
|
||||
mem_mapping_disable(&scsi->bios_rom.mapping);
|
||||
if (scsi->rom_addr) {
|
||||
rom_init(&scsi->bios_rom, RT1000B_ROM,
|
||||
scsi->rom_addr, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL);
|
||||
|
||||
mem_mapping_disable(&scsi->bios_rom.mapping);
|
||||
} else {
|
||||
scsi->bios_rom.rom = (uint8_t *) malloc(0x4000);
|
||||
memset(scsi->bios_rom.rom, 0xff, 0x4000);
|
||||
}
|
||||
|
||||
mem_mapping_add(&scsi->mapping, scsi->rom_addr, 0x4000,
|
||||
memio_read, NULL, NULL,
|
||||
memio_write, NULL, NULL,
|
||||
scsi->bios_rom.rom, 0, scsi);
|
||||
|
||||
if (scsi->base) {
|
||||
io_sethandler(scsi->base, 16,
|
||||
t130b_in,NULL,NULL, t130b_out,NULL,NULL, scsi);
|
||||
}
|
||||
break;
|
||||
|
||||
case 2: /* Trantor T130B */
|
||||
scsi->rom_addr = 0xDC000;
|
||||
scsi->base = 0x0350;
|
||||
rom_init(&scsi->bios_rom, T130B_ROM,
|
||||
scsi->rom_addr, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL);
|
||||
scsi->base = device_get_config_hex16("base");
|
||||
scsi->rom_addr = device_get_config_hex20("bios_addr");
|
||||
|
||||
if (scsi->rom_addr) {
|
||||
rom_init(&scsi->bios_rom, T130B_ROM,
|
||||
scsi->rom_addr, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL);
|
||||
|
||||
mem_mapping_disable(&scsi->bios_rom.mapping);
|
||||
} else {
|
||||
scsi->bios_rom.rom = (uint8_t *) malloc(0x4000);
|
||||
memset(scsi->bios_rom.rom, 0xff, 0x4000);
|
||||
}
|
||||
|
||||
mem_mapping_add(&scsi->mapping, scsi->rom_addr, 0x4000,
|
||||
t130b_read, NULL, NULL,
|
||||
t130b_write, NULL, NULL,
|
||||
scsi->bios_rom.rom, 0, scsi);
|
||||
|
||||
io_sethandler(scsi->base, 16,
|
||||
t130b_in,NULL,NULL, t130b_out,NULL,NULL, scsi);
|
||||
if (scsi->base) {
|
||||
io_sethandler(scsi->base, 16,
|
||||
t130b_in,NULL,NULL, t130b_out,NULL,NULL, scsi);
|
||||
}
|
||||
break;
|
||||
|
||||
case 3: /* Sumo SCSI-AT */
|
||||
scsi->base = device_get_config_hex16("base");
|
||||
scsi->irq = device_get_config_int("irq");
|
||||
scsi->rom_addr = device_get_config_hex20("bios_addr");
|
||||
rom_init(&scsi->bios_rom, SCSIAT_ROM,
|
||||
scsi->rom_addr, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL);
|
||||
|
||||
if (scsi->rom_addr) {
|
||||
rom_init(&scsi->bios_rom, SCSIAT_ROM,
|
||||
scsi->rom_addr, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL);
|
||||
|
||||
mem_mapping_disable(&scsi->bios_rom.mapping);
|
||||
} else {
|
||||
scsi->bios_rom.rom = (uint8_t *) malloc(0x4000);
|
||||
memset(scsi->bios_rom.rom, 0xff, 0x4000);
|
||||
}
|
||||
|
||||
mem_mapping_add(&scsi->mapping, scsi->rom_addr, 0x4000,
|
||||
t130b_read, NULL, NULL,
|
||||
t130b_write, NULL, NULL,
|
||||
scsi->bios_rom.rom, 0, scsi);
|
||||
|
||||
io_sethandler(scsi->base, 16,
|
||||
scsiat_in,NULL,NULL, scsiat_out,NULL,NULL, scsi);
|
||||
if (scsi->base) {
|
||||
io_sethandler(scsi->base, 16,
|
||||
scsiat_in,NULL,NULL, scsiat_out,NULL,NULL, scsi);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -898,7 +933,7 @@ ncr_init(const device_t *info)
|
||||
sprintf(&temp[strlen(temp)], " I/O=%04x", scsi->base);
|
||||
if (scsi->irq != 0)
|
||||
sprintf(&temp[strlen(temp)], " IRQ=%d", scsi->irq);
|
||||
pclog("%s\n", temp);
|
||||
ncr_log("%s\n", temp);
|
||||
|
||||
ncr5380_reset(&scsi->ncr);
|
||||
|
||||
@@ -948,6 +983,59 @@ scsiat_available(void)
|
||||
}
|
||||
|
||||
|
||||
static const device_config_t ncr5380_config[] = {
|
||||
{
|
||||
"base", "Address", CONFIG_HEX16, "", 0x0350,
|
||||
{
|
||||
{
|
||||
"None", 0
|
||||
},
|
||||
{
|
||||
"240H", 0x0240
|
||||
},
|
||||
{
|
||||
"250H", 0x0250
|
||||
},
|
||||
{
|
||||
"340H", 0x0340
|
||||
},
|
||||
{
|
||||
"350H", 0x0350
|
||||
},
|
||||
{
|
||||
""
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
"bios_addr", "BIOS Address", CONFIG_HEX20, "", 0xDC000,
|
||||
{
|
||||
{
|
||||
"Disabled", 0
|
||||
},
|
||||
{
|
||||
"C800H", 0xc8000
|
||||
},
|
||||
{
|
||||
"CC00H", 0xcc000
|
||||
},
|
||||
{
|
||||
"D800H", 0xd8000
|
||||
},
|
||||
{
|
||||
"DC00H", 0xdc000
|
||||
},
|
||||
{
|
||||
""
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
"", "", -1
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
static const device_config_t scsiat_config[] = {
|
||||
{
|
||||
"base", "Address", CONFIG_HEX16, "", 0x0310,
|
||||
@@ -1064,7 +1152,7 @@ const device_t scsi_rt1000b_device =
|
||||
ncr_init, ncr_close, NULL,
|
||||
rt1000b_available,
|
||||
NULL, NULL,
|
||||
NULL
|
||||
ncr5380_config
|
||||
};
|
||||
|
||||
const device_t scsi_t130b_device =
|
||||
@@ -1075,7 +1163,7 @@ const device_t scsi_t130b_device =
|
||||
ncr_init, ncr_close, NULL,
|
||||
t130b_available,
|
||||
NULL, NULL,
|
||||
NULL
|
||||
ncr5380_config
|
||||
};
|
||||
|
||||
const device_t scsi_scsiat_device =
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
* NCR and later Symbios and LSI. This controller was designed
|
||||
* for the PCI bus.
|
||||
*
|
||||
* Version: @(#)scsi_ncr53c810.c 1.0.13 2018/05/23
|
||||
* Version: @(#)scsi_ncr53c810.c 1.0.14 2018/05/28
|
||||
*
|
||||
* Authors: Paul Brook (QEMU)
|
||||
* Artyom Tarasenko (QEMU)
|
||||
@@ -22,11 +22,12 @@
|
||||
* Copyright 2017,2018 Miran Grca.
|
||||
*/
|
||||
#include <inttypes.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include <wchar.h>
|
||||
#include "../86box.h"
|
||||
#include "../io.h"
|
||||
@@ -333,7 +334,7 @@ ncr53c810_irq_on_rsl(ncr53c810_t *dev)
|
||||
static void
|
||||
ncr53c810_soft_reset(ncr53c810_t *dev)
|
||||
{
|
||||
int i, j;
|
||||
int i;
|
||||
|
||||
ncr53c810_log("LSI Reset\n");
|
||||
dev->timer_period = dev->timer_enabled = 0;
|
||||
@@ -390,10 +391,8 @@ ncr53c810_soft_reset(ncr53c810_t *dev)
|
||||
dev->gpreg0 = 0;
|
||||
dev->sstop = 1;
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
for (j = 0; j < 8; j++)
|
||||
scsi_device_reset(i, j);
|
||||
}
|
||||
for (i = 0; i < 16; i++)
|
||||
scsi_device_reset(i);
|
||||
}
|
||||
|
||||
|
||||
@@ -598,9 +597,9 @@ ncr53c810_do_dma(ncr53c810_t *dev, int out, uint8_t id)
|
||||
|
||||
scsi_device_t *sd;
|
||||
|
||||
sd = &SCSIDevices[id][dev->current_lun];
|
||||
sd = &SCSIDevices[id];
|
||||
|
||||
if ((!scsi_device_present(id, dev->current_lun))) {
|
||||
if ((!scsi_device_present(id))) {
|
||||
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;
|
||||
}
|
||||
@@ -627,7 +626,7 @@ ncr53c810_do_dma(ncr53c810_t *dev, int out, uint8_t id)
|
||||
else {
|
||||
if (!dev->buffer_pos) {
|
||||
ncr53c810_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: SCSI Command Phase 1 on PHASE_DI\n", id, dev->current_lun, dev->last_command);
|
||||
scsi_device_command_phase1(dev->current->tag, dev->current_lun);
|
||||
scsi_device_command_phase1(dev->current->tag);
|
||||
}
|
||||
ncr53c810_write(dev, addr, sd->CmdBuffer+dev->buffer_pos, count);
|
||||
}
|
||||
@@ -638,7 +637,7 @@ ncr53c810_do_dma(ncr53c810_t *dev, int out, uint8_t id)
|
||||
if (dev->temp_buf_len <= 0) {
|
||||
if (out) {
|
||||
ncr53c810_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: SCSI Command Phase 1 on PHASE_DO\n", id, dev->current_lun, dev->last_command);
|
||||
scsi_device_command_phase1(id, dev->current_lun);
|
||||
scsi_device_command_phase1(id);
|
||||
}
|
||||
if (sd->CmdBuffer != NULL) {
|
||||
free(sd->CmdBuffer);
|
||||
@@ -684,8 +683,8 @@ ncr53c810_do_command(ncr53c810_t *dev, uint8_t id)
|
||||
dev->sfbr = buf[0];
|
||||
dev->command_complete = 0;
|
||||
|
||||
sd = &SCSIDevices[id][dev->current_lun];
|
||||
if (!scsi_device_present(id, dev->current_lun)) {
|
||||
sd = &SCSIDevices[id];
|
||||
if (!scsi_device_present(id)) {
|
||||
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;
|
||||
@@ -699,7 +698,7 @@ ncr53c810_do_command(ncr53c810_t *dev, uint8_t id)
|
||||
ncr53c810_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: DBC=%i\n", id, dev->current_lun, buf[0], dev->dbc);
|
||||
dev->last_command = buf[0];
|
||||
|
||||
scsi_device_command_phase0(dev->current->tag, dev->current_lun, dev->dbc, buf);
|
||||
scsi_device_command_phase0(dev->current->tag, buf);
|
||||
dev->hba_private = (void *)dev->current;
|
||||
|
||||
dev->waiting = 0;
|
||||
@@ -715,7 +714,7 @@ ncr53c810_do_command(ncr53c810_t *dev, uint8_t id)
|
||||
if ((sd->Phase == SCSI_PHASE_DATA_IN) && (sd->BufferLength > 0)) {
|
||||
ncr53c810_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: PHASE_DI\n", id, dev->current_lun, buf[0]);
|
||||
ncr53c810_set_phase(dev, PHASE_DI);
|
||||
p = scsi_device_get_callback(dev->current->tag, dev->current_lun);
|
||||
p = scsi_device_get_callback(dev->current->tag);
|
||||
if (p <= 0LL) {
|
||||
period = ((double) sd->BufferLength) * 0.1 * ((double) TIMER_USEC); /* Fast SCSI: 10000000 bytes per second */
|
||||
dev->timer_period += (int64_t) period;
|
||||
@@ -723,9 +722,9 @@ ncr53c810_do_command(ncr53c810_t *dev, uint8_t id)
|
||||
dev->timer_period += p;
|
||||
return 1;
|
||||
} else if ((sd->Phase == SCSI_PHASE_DATA_OUT) && (sd->BufferLength > 0)) {
|
||||
ncr53c810_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: PHASE_DO\n", id, dev->current_lun, buf[0]);
|
||||
ncr53c810_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: PHASE_DO\n", id, buf[0]);
|
||||
ncr53c810_set_phase(dev, PHASE_DO);
|
||||
p = scsi_device_get_callback(dev->current->tag, dev->current_lun);
|
||||
p = scsi_device_get_callback(dev->current->tag);
|
||||
if (p <= 0LL) {
|
||||
period = ((double) sd->BufferLength) * 0.1 * ((double) TIMER_USEC); /* Fast SCSI: 10000000 bytes per second */
|
||||
dev->timer_period += (int64_t) period;
|
||||
@@ -833,7 +832,7 @@ ncr53c810_do_msgout(ncr53c810_t *dev, uint8_t id)
|
||||
uint32_t current_tag;
|
||||
scsi_device_t *sd;
|
||||
|
||||
sd = &SCSIDevices[id][dev->current_lun];
|
||||
sd = &SCSIDevices[id];
|
||||
|
||||
current_tag = id;
|
||||
|
||||
@@ -1079,7 +1078,7 @@ again:
|
||||
}
|
||||
dev->sstat0 |= NCR_SSTAT0_WOA;
|
||||
dev->scntl1 &= ~NCR_SCNTL1_IARB;
|
||||
if (!scsi_device_present(id, 0)) {
|
||||
if (!scsi_device_present(id)) {
|
||||
ncr53c810_bad_selection(dev, id);
|
||||
break;
|
||||
}
|
||||
@@ -1098,8 +1097,12 @@ again:
|
||||
break;
|
||||
case 2: /* Wait Reselect */
|
||||
ncr53c810_log("Wait Reselect\n");
|
||||
if (!ncr53c810_irq_on_rsl(dev))
|
||||
dev->waiting = 1;
|
||||
if (dev->istat & NCR_ISTAT_SIGP)
|
||||
dev->dsp = dev->dnad; /* If SIGP is set, this command causes an immediate jump to DNAD. */
|
||||
else {
|
||||
if (!ncr53c810_irq_on_rsl(dev))
|
||||
dev->waiting = 1;
|
||||
}
|
||||
break;
|
||||
case 3: /* Set */
|
||||
ncr53c810_log("Set%s%s%s%s\n", insn & (1 << 3) ? " ATN" : "",
|
||||
@@ -1462,7 +1465,7 @@ ncr53c810_reg_writeb(ncr53c810_t *dev, uint32_t offset, uint8_t val)
|
||||
ncr53c810_update_irq(dev);
|
||||
}
|
||||
|
||||
if (dev->waiting == 1 && val & NCR_ISTAT_SIGP) {
|
||||
if ((dev->waiting == 1) && (val & NCR_ISTAT_SIGP)) {
|
||||
ncr53c810_log("Woken by SIGP\n");
|
||||
dev->waiting = 0;
|
||||
dev->dsp = dev->dnad;
|
||||
@@ -1668,7 +1671,8 @@ ncr53c810_reg_readb(ncr53c810_t *dev, uint32_t offset)
|
||||
CASE_GET_REG32(dsa, 0x10)
|
||||
case 0x14: /* ISTAT */
|
||||
ncr53c810_log("NCR 810: Read ISTAT %02X\n", dev->istat);
|
||||
return dev->istat;
|
||||
tmp = dev->istat;
|
||||
return tmp;
|
||||
case 0x16: /* MBOX0 */
|
||||
ncr53c810_log("NCR 810: Read MBOX0 %02X\n", dev->mbox0);
|
||||
return dev->mbox0;
|
||||
@@ -2170,7 +2174,7 @@ ncr53c810_init(const device_t *info)
|
||||
|
||||
/* Enable our BIOS space in PCI, if needed. */
|
||||
if (dev->has_bios)
|
||||
rom_init(&dev->bios, NCR53C810_ROM, 0xd8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL);
|
||||
rom_init(&dev->bios, NCR53C810_ROM, 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL);
|
||||
|
||||
return(dev);
|
||||
}
|
||||
|
||||
@@ -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.21 2018/03/28
|
||||
* Version: @(#)scsi_x54x.c 1.0.21 2018/06/12
|
||||
*
|
||||
* Authors: TheCollector1995, <mariogplayer@gmail.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -90,24 +90,21 @@ x54x_irq(x54x_t *dev, int set)
|
||||
|
||||
if (dev->bus & DEVICE_PCI) {
|
||||
x54x_log("PCI IRQ: %02X, PCI_INTA\n", dev->pci_slot);
|
||||
if (set) {
|
||||
if (set)
|
||||
pci_set_irq(dev->pci_slot, PCI_INTA);
|
||||
} else {
|
||||
else
|
||||
pci_clear_irq(dev->pci_slot, PCI_INTA);
|
||||
}
|
||||
} else {
|
||||
if (set) {
|
||||
if (dev->interrupt_type)
|
||||
int_type = dev->interrupt_type(dev);
|
||||
|
||||
if (int_type) {
|
||||
if (int_type)
|
||||
picintlevel(1 << irq);
|
||||
} else {
|
||||
else
|
||||
picint(1 << irq);
|
||||
}
|
||||
} else {
|
||||
} else
|
||||
picintc(1 << irq);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,10 +154,10 @@ clear_irq(x54x_t *dev)
|
||||
|
||||
|
||||
static void
|
||||
target_check(uint8_t id, uint8_t lun)
|
||||
target_check(uint8_t id)
|
||||
{
|
||||
if (! scsi_device_valid(id, lun)) {
|
||||
fatal("BIOS INT13 device on %02i:%02i has disappeared\n", id, lun);
|
||||
if (! scsi_device_valid(id)) {
|
||||
fatal("BIOS INT13 device on ID %02i has disappeared\n", id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -235,15 +232,15 @@ completion_code(uint8_t *sense)
|
||||
|
||||
|
||||
static uint8_t
|
||||
x54x_bios_command_08(uint8_t id, uint8_t lun, uint8_t *buffer)
|
||||
x54x_bios_command_08(uint8_t id, uint8_t *buffer)
|
||||
{
|
||||
uint8_t cdb[12] = { GPCMD_READ_CDROM_CAPACITY, 0,0,0,0,0,0,0,0,0,0,0 };
|
||||
uint8_t rcbuf[8] = { 0,0,0,0,0,0,0,0 };
|
||||
uint32_t len = 0;
|
||||
int i, ret, sc;
|
||||
|
||||
ret = scsi_device_read_capacity(id, lun, cdb, rcbuf, &len);
|
||||
sc = completion_code(scsi_device_sense(id, lun));
|
||||
ret = scsi_device_read_capacity(id, cdb, rcbuf, &len);
|
||||
sc = completion_code(scsi_device_sense(id));
|
||||
if (ret == 0) return(sc);
|
||||
|
||||
memset(buffer, 0x00, 6);
|
||||
@@ -259,21 +256,21 @@ x54x_bios_command_08(uint8_t id, uint8_t lun, uint8_t *buffer)
|
||||
|
||||
|
||||
static int
|
||||
x54x_bios_command_15(uint8_t id, uint8_t lun, uint8_t *buffer)
|
||||
x54x_bios_command_15(uint8_t id, uint8_t *buffer)
|
||||
{
|
||||
uint8_t cdb[12] = { GPCMD_READ_CDROM_CAPACITY, 0,0,0,0,0,0,0,0,0,0,0 };
|
||||
uint8_t rcbuf[8] = { 0,0,0,0,0,0,0,0 };
|
||||
uint32_t len = 0;
|
||||
int i, ret, sc;
|
||||
|
||||
ret = scsi_device_read_capacity(id, lun, cdb, rcbuf, &len);
|
||||
sc = completion_code(scsi_device_sense(id, lun));
|
||||
ret = scsi_device_read_capacity(id, cdb, rcbuf, &len);
|
||||
sc = completion_code(scsi_device_sense(id));
|
||||
|
||||
memset(buffer, 0x00, 6);
|
||||
for (i=0; i<4; i++)
|
||||
buffer[i] = (ret == 0) ? 0 : rcbuf[i];
|
||||
|
||||
scsi_device_type_data(id, lun, &(buffer[4]), &(buffer[5]));
|
||||
scsi_device_type_data(id, &(buffer[4]), &(buffer[5]));
|
||||
|
||||
x54x_log("BIOS Command 0x15: %02X %02X %02X %02X %02X %02X\n",
|
||||
buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5]);
|
||||
@@ -306,19 +303,22 @@ x54x_bios_command(x54x_t *x54x, uint8_t max_id, BIOSCMD *cmd, int8_t islba)
|
||||
return(0x80);
|
||||
}
|
||||
|
||||
if (cmd->lun) {
|
||||
x54x_log("BIOS Target LUN is not 0\n");
|
||||
return(0x80);
|
||||
}
|
||||
|
||||
/* Get pointer to selected device. */
|
||||
dev = &SCSIDevices[cmd->id][cmd->lun];
|
||||
dev = &SCSIDevices[cmd->id];
|
||||
dev->BufferLength = 0;
|
||||
|
||||
if (! scsi_device_present(cmd->id, cmd->lun)) {
|
||||
x54x_log("BIOS Target ID %i and LUN %i have no device attached\n",
|
||||
cmd->id, cmd->lun);
|
||||
if (! scsi_device_present(cmd->id)) {
|
||||
x54x_log("BIOS Target ID %i has no device attached\n", cmd->id);
|
||||
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);
|
||||
x54x_log("BIOS Target ID %i is CD-ROM on unsupported BIOS\n", cmd->id);
|
||||
return(0x80);
|
||||
}
|
||||
|
||||
@@ -337,7 +337,7 @@ x54x_bios_command(x54x_t *x54x, uint8_t max_id, BIOSCMD *cmd, int8_t islba)
|
||||
return(0);
|
||||
|
||||
case 0x01: /* Read Status of Last Operation */
|
||||
target_check(cmd->id, cmd->lun);
|
||||
target_check(cmd->id);
|
||||
|
||||
/*
|
||||
* Assuming 14 bytes because that is the default
|
||||
@@ -352,7 +352,7 @@ x54x_bios_command(x54x_t *x54x, uint8_t max_id, BIOSCMD *cmd, int8_t islba)
|
||||
x54x_log("BIOS DMA: Reading 14 bytes at %08X\n",
|
||||
dma_address);
|
||||
DMAPageWrite(dma_address,
|
||||
scsi_device_sense(cmd->id, cmd->lun), 14);
|
||||
scsi_device_sense(cmd->id), 14);
|
||||
}
|
||||
|
||||
if (dev->CmdBuffer != NULL) {
|
||||
@@ -363,7 +363,7 @@ x54x_bios_command(x54x_t *x54x, uint8_t max_id, BIOSCMD *cmd, int8_t islba)
|
||||
return(0);
|
||||
|
||||
case 0x02: /* Read Desired Sectors to Memory */
|
||||
target_check(cmd->id, cmd->lun);
|
||||
target_check(cmd->id);
|
||||
|
||||
dev->BufferLength = -1;
|
||||
|
||||
@@ -379,14 +379,14 @@ x54x_bios_command(x54x_t *x54x, uint8_t max_id, BIOSCMD *cmd, int8_t islba)
|
||||
x54x_log("BIOS CMD(READ, %08lx, %d)\n", lba, cmd->secount);
|
||||
#endif
|
||||
|
||||
scsi_device_command_phase0(cmd->id, cmd->lun, 12, cdb);
|
||||
scsi_device_command_phase0(cmd->id, cdb);
|
||||
|
||||
if (dev->Phase == SCSI_PHASE_STATUS)
|
||||
goto skip_read_phase1;
|
||||
|
||||
dev->CmdBuffer = (uint8_t *)malloc(dev->BufferLength);
|
||||
|
||||
scsi_device_command_phase1(cmd->id, cmd->lun);
|
||||
scsi_device_command_phase1(cmd->id);
|
||||
if (sector_len > 0) {
|
||||
x54x_log("BIOS DMA: Reading %i bytes at %08X\n",
|
||||
dev->BufferLength, dma_address);
|
||||
@@ -400,10 +400,10 @@ skip_read_phase1:
|
||||
dev->CmdBuffer = NULL;
|
||||
}
|
||||
|
||||
return(completion_code(scsi_device_sense(cmd->id, cmd->lun)));
|
||||
return(completion_code(scsi_device_sense(cmd->id)));
|
||||
|
||||
case 0x03: /* Write Desired Sectors from Memory */
|
||||
target_check(cmd->id, cmd->lun);
|
||||
target_check(cmd->id);
|
||||
|
||||
dev->BufferLength = -1;
|
||||
|
||||
@@ -419,7 +419,7 @@ skip_read_phase1:
|
||||
x54x_log("BIOS CMD(WRITE, %08lx, %d)\n", lba, cmd->secount);
|
||||
#endif
|
||||
|
||||
scsi_device_command_phase0(cmd->id, cmd->lun, 12, cdb);
|
||||
scsi_device_command_phase0(cmd->id, cdb);
|
||||
|
||||
if (dev->Phase == SCSI_PHASE_STATUS)
|
||||
goto skip_write_phase1;
|
||||
@@ -433,7 +433,7 @@ skip_read_phase1:
|
||||
dev->CmdBuffer, dev->BufferLength);
|
||||
}
|
||||
|
||||
scsi_device_command_phase1(cmd->id, cmd->lun);
|
||||
scsi_device_command_phase1(cmd->id);
|
||||
|
||||
skip_write_phase1:
|
||||
if (dev->CmdBuffer != NULL) {
|
||||
@@ -441,10 +441,10 @@ skip_write_phase1:
|
||||
dev->CmdBuffer = NULL;
|
||||
}
|
||||
|
||||
return(completion_code(scsi_device_sense(cmd->id, cmd->lun)));
|
||||
return(completion_code(scsi_device_sense(cmd->id)));
|
||||
|
||||
case 0x04: /* Verify Desired Sectors */
|
||||
target_check(cmd->id, cmd->lun);
|
||||
target_check(cmd->id);
|
||||
|
||||
cdb[0] = GPCMD_VERIFY_10;
|
||||
cdb[1] = (cmd->lun & 7) << 5;
|
||||
@@ -455,9 +455,9 @@ skip_write_phase1:
|
||||
cdb[7] = 0;
|
||||
cdb[8] = sector_len;
|
||||
|
||||
scsi_device_command_phase0(cmd->id, cmd->lun, 12, cdb);
|
||||
scsi_device_command_phase0(cmd->id, cdb);
|
||||
|
||||
return(completion_code(scsi_device_sense(cmd->id, cmd->lun)));
|
||||
return(completion_code(scsi_device_sense(cmd->id)));
|
||||
|
||||
case 0x05: /* Format Track, invalid since SCSI has no tracks */
|
||||
//FIXME: add a longer delay here --FvK
|
||||
@@ -468,23 +468,23 @@ skip_write_phase1:
|
||||
return(0);
|
||||
|
||||
case 0x07: /* Format Unit */
|
||||
target_check(cmd->id, cmd->lun);
|
||||
target_check(cmd->id);
|
||||
|
||||
cdb[0] = GPCMD_FORMAT_UNIT;
|
||||
cdb[1] = (cmd->lun & 7) << 5;
|
||||
|
||||
scsi_device_command_phase0(cmd->id, cmd->lun, 12, cdb);
|
||||
scsi_device_command_phase0(cmd->id, cdb);
|
||||
|
||||
return(completion_code(scsi_device_sense(cmd->id, cmd->lun)));
|
||||
return(completion_code(scsi_device_sense(cmd->id)));
|
||||
|
||||
case 0x08: /* Read Drive Parameters */
|
||||
target_check(cmd->id, cmd->lun);
|
||||
target_check(cmd->id);
|
||||
|
||||
dev->BufferLength = 6;
|
||||
dev->CmdBuffer = (uint8_t *)malloc(dev->BufferLength);
|
||||
memset(dev->CmdBuffer, 0x00, dev->BufferLength);
|
||||
|
||||
ret = x54x_bios_command_08(cmd->id, cmd->lun, dev->CmdBuffer);
|
||||
ret = x54x_bios_command_08(cmd->id, dev->CmdBuffer);
|
||||
|
||||
x54x_log("BIOS DMA: Reading 6 bytes at %08X\n", dma_address);
|
||||
DMAPageWrite(dma_address,
|
||||
@@ -502,7 +502,7 @@ skip_write_phase1:
|
||||
return(0);
|
||||
|
||||
case 0x0c: /* Seek */
|
||||
target_check(cmd->id, cmd->lun);
|
||||
target_check(cmd->id);
|
||||
|
||||
cdb[0] = GPCMD_SEEK_10;
|
||||
cdb[1] = (cmd->lun & 7) << 5;
|
||||
@@ -511,7 +511,7 @@ skip_write_phase1:
|
||||
cdb[4] = (lba >> 8) & 0xff;
|
||||
cdb[5] = lba & 0xff;
|
||||
|
||||
scsi_device_command_phase0(cmd->id, cmd->lun, 12, cdb);
|
||||
scsi_device_command_phase0(cmd->id, cdb);
|
||||
|
||||
return((dev->Status == SCSI_STATUS_OK) ? 1 : 0);
|
||||
|
||||
@@ -520,37 +520,37 @@ skip_write_phase1:
|
||||
return(0);
|
||||
|
||||
case 0x10: /* Test Drive Ready */
|
||||
target_check(cmd->id, cmd->lun);
|
||||
target_check(cmd->id);
|
||||
|
||||
cdb[0] = GPCMD_TEST_UNIT_READY;
|
||||
cdb[1] = (cmd->lun & 7) << 5;
|
||||
|
||||
scsi_device_command_phase0(cmd->id, cmd->lun, 12, cdb);
|
||||
scsi_device_command_phase0(cmd->id, cdb);
|
||||
|
||||
return(completion_code(scsi_device_sense(cmd->id, cmd->lun)));
|
||||
return(completion_code(scsi_device_sense(cmd->id)));
|
||||
|
||||
case 0x11: /* Recalibrate */
|
||||
target_check(cmd->id, cmd->lun);
|
||||
target_check(cmd->id);
|
||||
|
||||
cdb[0] = GPCMD_REZERO_UNIT;
|
||||
cdb[1] = (cmd->lun & 7) << 5;
|
||||
|
||||
scsi_device_command_phase0(cmd->id, cmd->lun, 12, cdb);
|
||||
scsi_device_command_phase0(cmd->id, cdb);
|
||||
|
||||
return(completion_code(scsi_device_sense(cmd->id, cmd->lun)));
|
||||
return(completion_code(scsi_device_sense(cmd->id)));
|
||||
|
||||
case 0x14: /* Controller Diagnostic */
|
||||
//FIXME: add a longer delay here --FvK
|
||||
return(0);
|
||||
|
||||
case 0x15: /* Read DASD Type */
|
||||
target_check(cmd->id, cmd->lun);
|
||||
target_check(cmd->id);
|
||||
|
||||
dev->BufferLength = 6;
|
||||
dev->CmdBuffer = (uint8_t *)malloc(dev->BufferLength);
|
||||
memset(dev->CmdBuffer, 0x00, dev->BufferLength);
|
||||
|
||||
ret = x54x_bios_command_15(cmd->id, cmd->lun, dev->CmdBuffer);
|
||||
ret = x54x_bios_command_15(cmd->id, dev->CmdBuffer);
|
||||
|
||||
x54x_log("BIOS DMA: Reading 6 bytes at %08X\n", dma_address);
|
||||
DMAPageWrite(dma_address,
|
||||
@@ -762,7 +762,7 @@ x54x_set_residue(Req_t *req, int32_t TransferLength)
|
||||
{
|
||||
uint32_t Residue = 0;
|
||||
addr24 Residue24;
|
||||
int32_t BufLen = SCSIDevices[req->TargetID][req->LUN].BufferLength;
|
||||
int32_t BufLen = SCSIDevices[req->TargetID].BufferLength;
|
||||
|
||||
if ((req->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND_RES) ||
|
||||
(req->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND_RES)) {
|
||||
@@ -793,7 +793,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, i;
|
||||
int32_t BufLen = SCSIDevices[req->TargetID][req->LUN].BufferLength;
|
||||
int32_t BufLen = SCSIDevices[req->TargetID].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)));
|
||||
int sg_pos = 0;
|
||||
@@ -807,8 +807,8 @@ x54x_buf_dma_transfer(Req_t *req, int Is24bit, int TransferLength, int dir)
|
||||
DataPointer = req->CmdBlock.new.DataPointer;
|
||||
DataLength = req->CmdBlock.new.DataLength;
|
||||
}
|
||||
x54x_log("Data Buffer %s: length %d, pointer 0x%04X\n",
|
||||
dir ? "write" : "read", BufLen, DataPointer);
|
||||
x54x_log("Data Buffer %s: length %d (%u), pointer 0x%04X\n",
|
||||
dir ? "write" : "read", BufLen, DataLength, DataPointer);
|
||||
|
||||
if ((req->CmdBlock.common.ControlByte != 0x03) && TransferLength && BufLen) {
|
||||
if ((req->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND) ||
|
||||
@@ -825,11 +825,11 @@ x54x_buf_dma_transfer(Req_t *req, int Is24bit, int TransferLength, int dir)
|
||||
|
||||
if (read_from_host && DataToTransfer) {
|
||||
x54x_log("Reading S/G segment %i: length %i, pointer %08X\n", i, DataToTransfer, Address);
|
||||
DMAPageRead(Address, &(SCSIDevices[req->TargetID][req->LUN].CmdBuffer[sg_pos]), DataToTransfer);
|
||||
DMAPageRead(Address, &(SCSIDevices[req->TargetID].CmdBuffer[sg_pos]), DataToTransfer);
|
||||
}
|
||||
else if (write_to_host && DataToTransfer) {
|
||||
x54x_log("Writing S/G segment %i: length %i, pointer %08X\n", i, DataToTransfer, Address);
|
||||
DMAPageWrite(Address, &(SCSIDevices[req->TargetID][req->LUN].CmdBuffer[sg_pos]), DataToTransfer);
|
||||
DMAPageWrite(Address, &(SCSIDevices[req->TargetID].CmdBuffer[sg_pos]), DataToTransfer);
|
||||
}
|
||||
else
|
||||
x54x_log("No action on S/G segment %i: length %i, pointer %08X\n", i, DataToTransfer, Address);
|
||||
@@ -849,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, (int) DataLength));
|
||||
DMAPageRead(Address, SCSIDevices[req->TargetID].CmdBuffer, MIN(BufLen, (int) DataLength));
|
||||
else if (write_to_host)
|
||||
DMAPageWrite(Address, SCSIDevices[req->TargetID][req->LUN].CmdBuffer, MIN(BufLen, (int) DataLength));
|
||||
DMAPageWrite(Address, SCSIDevices[req->TargetID].CmdBuffer, MIN(BufLen, (int) DataLength));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -859,25 +859,25 @@ x54x_buf_dma_transfer(Req_t *req, int Is24bit, int TransferLength, int dir)
|
||||
|
||||
|
||||
void
|
||||
x54x_buf_alloc(uint8_t id, uint8_t lun, int length)
|
||||
x54x_buf_alloc(uint8_t id, int length)
|
||||
{
|
||||
if (SCSIDevices[id][lun].CmdBuffer != NULL) {
|
||||
free(SCSIDevices[id][lun].CmdBuffer);
|
||||
SCSIDevices[id][lun].CmdBuffer = NULL;
|
||||
if (SCSIDevices[id].CmdBuffer != NULL) {
|
||||
free(SCSIDevices[id].CmdBuffer);
|
||||
SCSIDevices[id].CmdBuffer = NULL;
|
||||
}
|
||||
|
||||
x54x_log("Allocating data buffer (%i bytes)\n", length);
|
||||
SCSIDevices[id][lun].CmdBuffer = (uint8_t *) malloc(length);
|
||||
memset(SCSIDevices[id][lun].CmdBuffer, 0, length);
|
||||
SCSIDevices[id].CmdBuffer = (uint8_t *) malloc(length);
|
||||
memset(SCSIDevices[id].CmdBuffer, 0, length);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
x54x_buf_free(uint8_t id, uint8_t lun)
|
||||
x54x_buf_free(uint8_t id)
|
||||
{
|
||||
if (SCSIDevices[id][lun].CmdBuffer != NULL) {
|
||||
free(SCSIDevices[id][lun].CmdBuffer);
|
||||
SCSIDevices[id][lun].CmdBuffer = NULL;
|
||||
if (SCSIDevices[id].CmdBuffer != NULL) {
|
||||
free(SCSIDevices[id].CmdBuffer);
|
||||
SCSIDevices[id].CmdBuffer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -921,7 +921,7 @@ SenseBufferFree(Req_t *req, int Copy)
|
||||
uint8_t temp_sense[256];
|
||||
|
||||
if (SenseLength && Copy) {
|
||||
scsi_device_request_sense(req->TargetID, req->LUN, temp_sense, SenseLength);
|
||||
scsi_device_request_sense(req->TargetID, temp_sense, SenseLength);
|
||||
|
||||
/*
|
||||
* The sense address, in 32-bit mode, is located in the
|
||||
@@ -960,11 +960,11 @@ x54x_scsi_cmd(x54x_t *dev)
|
||||
id = req->TargetID;
|
||||
lun = req->LUN;
|
||||
|
||||
target_cdb_len = scsi_device_cdb_length(id, lun);
|
||||
target_cdb_len = 12;
|
||||
target_data_len = x54x_get_length(req, bit24);
|
||||
|
||||
if (!scsi_device_valid(id, lun))
|
||||
fatal("SCSI target on %02i:%02i has disappeared\n", id, lun);
|
||||
if (!scsi_device_valid(id))
|
||||
fatal("SCSI target on %02i has disappeared\n", id);
|
||||
|
||||
x54x_log("target_data_len = %i\n", target_data_len);
|
||||
|
||||
@@ -986,14 +986,14 @@ x54x_scsi_cmd(x54x_t *dev)
|
||||
|
||||
dev->Residue = 0;
|
||||
|
||||
BufLen = scsi_device_get_buf_len(id, lun);
|
||||
BufLen = scsi_device_get_buf_len(id);
|
||||
*BufLen = target_data_len;
|
||||
|
||||
x54x_log("Command buffer: %08X\n", SCSIDevices[id][lun].CmdBuffer);
|
||||
x54x_log("Command buffer: %08X\n", SCSIDevices[id].CmdBuffer);
|
||||
|
||||
scsi_device_command_phase0(id, lun, req->CmdBlock.common.CdbLength, temp_cdb);
|
||||
scsi_device_command_phase0(id, temp_cdb);
|
||||
|
||||
phase = SCSIDevices[id][lun].Phase;
|
||||
phase = SCSIDevices[id].Phase;
|
||||
|
||||
x54x_log("Control byte: %02X\n", (req->CmdBlock.common.ControlByte == 0x03));
|
||||
|
||||
@@ -1001,46 +1001,46 @@ x54x_scsi_cmd(x54x_t *dev)
|
||||
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 ((SCSIDevices[id][lun].Status != SCSI_STATUS_OK) && (*BufLen > 0)) {
|
||||
x54x_buf_alloc(id, *BufLen);
|
||||
scsi_device_command_phase1(id);
|
||||
if ((SCSIDevices[id].Status != SCSI_STATUS_OK) && (*BufLen > 0)) {
|
||||
SenseBufferAddress = SenseBufferPointer(req);
|
||||
DMAPageWrite(SenseBufferAddress, SCSIDevices[id][lun].CmdBuffer, *BufLen);
|
||||
DMAPageWrite(SenseBufferAddress, SCSIDevices[id].CmdBuffer, *BufLen);
|
||||
x54x_add_to_period(*BufLen);
|
||||
}
|
||||
} else {
|
||||
p = scsi_device_get_callback(id, lun);
|
||||
p = scsi_device_get_callback(id);
|
||||
if (p <= 0LL)
|
||||
x54x_add_to_period(*BufLen);
|
||||
else
|
||||
dev->media_period += p;
|
||||
x54x_buf_alloc(id, lun, MIN(target_data_len, *BufLen));
|
||||
x54x_buf_alloc(id, 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);
|
||||
scsi_device_command_phase1(id);
|
||||
if (phase == SCSI_PHASE_DATA_IN)
|
||||
x54x_buf_dma_transfer(req, bit24, target_data_len, 0);
|
||||
|
||||
SenseBufferFree(req, (SCSIDevices[id][lun].Status != SCSI_STATUS_OK));
|
||||
SenseBufferFree(req, (SCSIDevices[id].Status != SCSI_STATUS_OK));
|
||||
}
|
||||
} else
|
||||
SenseBufferFree(req, (SCSIDevices[id][lun].Status != SCSI_STATUS_OK));
|
||||
SenseBufferFree(req, (SCSIDevices[id].Status != SCSI_STATUS_OK));
|
||||
|
||||
x54x_set_residue(req, target_data_len);
|
||||
|
||||
x54x_buf_free(id, lun);
|
||||
x54x_buf_free(id);
|
||||
|
||||
x54x_log("Request complete\n");
|
||||
|
||||
if (SCSIDevices[id][lun].Status == SCSI_STATUS_OK) {
|
||||
if (SCSIDevices[id].Status == SCSI_STATUS_OK) {
|
||||
x54x_mbi_setup(dev, req->CCBPointer, &req->CmdBlock,
|
||||
CCB_COMPLETE, SCSI_STATUS_OK, MBI_SUCCESS);
|
||||
} else if (SCSIDevices[id][lun].Status == SCSI_STATUS_CHECK_CONDITION) {
|
||||
} else if (SCSIDevices[id].Status == SCSI_STATUS_CHECK_CONDITION) {
|
||||
x54x_mbi_setup(dev, req->CCBPointer, &req->CmdBlock,
|
||||
CCB_COMPLETE, SCSI_STATUS_CHECK_CONDITION, MBI_ERROR);
|
||||
}
|
||||
|
||||
x54x_log("SCSIDevices[%02i][%02i].Status = %02X\n", id, lun, SCSIDevices[id][lun].Status);
|
||||
x54x_log("SCSIDevices[%02i].Status = %02X\n", id, SCSIDevices[id].Status);
|
||||
}
|
||||
|
||||
|
||||
@@ -1082,10 +1082,10 @@ x54x_req_setup(x54x_t *dev, uint32_t CCBPointer, Mailbox32_t *Mailbox32)
|
||||
|
||||
x54x_log("Scanning SCSI Target ID %i\n", id);
|
||||
|
||||
SCSIDevices[id][lun].Status = SCSI_STATUS_OK;
|
||||
SCSIDevices[id].Status = SCSI_STATUS_OK;
|
||||
|
||||
/* If there is no device at ID:0, timeout the selection - the LUN is then checked later. */
|
||||
if (! scsi_device_present(id, 0)) {
|
||||
if (! scsi_device_present(id)) {
|
||||
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);
|
||||
@@ -1107,7 +1107,7 @@ 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);
|
||||
scsi_device_reset(id);
|
||||
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);
|
||||
@@ -1423,7 +1423,7 @@ x54x_reset_poll(void *priv)
|
||||
static void
|
||||
x54x_reset(x54x_t *dev)
|
||||
{
|
||||
int i, j;
|
||||
int i;
|
||||
|
||||
clear_irq(dev);
|
||||
if (dev->int_geom_writable)
|
||||
@@ -1443,10 +1443,8 @@ x54x_reset(x54x_t *dev)
|
||||
dev->MailboxOutPosCur = 0;
|
||||
|
||||
/* Reset all devices on controller reset. */
|
||||
for (i = 0; i < 16; i++) {
|
||||
for (j = 0; j < 8; j++)
|
||||
scsi_device_reset(i, j);
|
||||
}
|
||||
for (i = 0; i < 16; i++)
|
||||
scsi_device_reset(i);
|
||||
|
||||
if (dev->ven_reset)
|
||||
dev->ven_reset(dev);
|
||||
@@ -1479,7 +1477,6 @@ x54x_out(uint16_t port, uint8_t val, void *priv)
|
||||
x54x_t *dev = (x54x_t *)priv;
|
||||
MailboxInit_t *mbi;
|
||||
int i = 0;
|
||||
uint8_t j = 0;
|
||||
BIOSCMD *cmd;
|
||||
uint16_t cyl = 0;
|
||||
int suppress = 0;
|
||||
@@ -1503,10 +1500,8 @@ 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++) {
|
||||
for (j = 0; j < 8; j++)
|
||||
scsi_device_reset(i, j);
|
||||
}
|
||||
for (i = 0; i < 16; i++)
|
||||
scsi_device_reset(i);
|
||||
}
|
||||
|
||||
if (val & CTRL_IRST) {
|
||||
@@ -1682,10 +1677,9 @@ x54x_out(uint16_t port, uint8_t val, void *priv)
|
||||
/* Skip the HA .. */
|
||||
if (i == host_id) continue;
|
||||
|
||||
for (j=0; j<SCSI_LUN_MAX; j++) {
|
||||
if (scsi_device_present(i, j))
|
||||
dev->DataBuf[i] |= (1<<j);
|
||||
}
|
||||
/* TODO: Query device for LUN's. */
|
||||
if (scsi_device_present(i))
|
||||
dev->DataBuf[i] |= 1;
|
||||
}
|
||||
dev->DataReplyLeft = i;
|
||||
break;
|
||||
|
||||
@@ -492,8 +492,8 @@ typedef struct
|
||||
|
||||
|
||||
extern void x54x_reset_ctrl(x54x_t *dev, uint8_t Reset);
|
||||
extern void x54x_buf_alloc(uint8_t id, uint8_t lun, int length);
|
||||
extern void x54x_buf_free(uint8_t id, uint8_t lun);
|
||||
extern void x54x_buf_alloc(uint8_t id, int length);
|
||||
extern void x54x_buf_free(uint8_t id);
|
||||
extern uint8_t x54x_mbo_process(x54x_t *dev);
|
||||
extern void x54x_wait_for_poll(void);
|
||||
extern void x54x_io_set(x54x_t *dev, uint32_t base, uint8_t len);
|
||||
|
||||
Reference in New Issue
Block a user