Cleanups to make all logging functions use stdlog instead of stdout.

The new --logfile (-L) commandline option sets a file to log to.
The new --debug (-D) forces output to stderr if no logfile is given.
This commit is contained in:
waltje
2017-11-24 02:23:00 -05:00
parent d287293a75
commit ce1bab2967
20 changed files with 1547 additions and 1571 deletions

View File

@@ -10,7 +10,7 @@
* made by Adaptec, Inc. These controllers were designed for
* the ISA bus.
*
* Version: @(#)scsi_aha154x.c 1.0.34 2017/11/04
* Version: @(#)scsi_aha154x.c 1.0.35 2017/11/24
*
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Original Buslogic version by SA1988 and Miran Grca.
@@ -91,9 +91,9 @@ aha_log(const char *fmt, ...)
if (aha_do_log) {
va_start(ap, fmt);
vprintf(fmt, ap);
vfprintf(stdlog, fmt, ap);
va_end(ap);
fflush(stdout);
fflush(stdlog);
}
#endif
}

View File

@@ -8,7 +8,7 @@
*
* The generic SCSI bus operations handler.
*
* Version: @(#)scsi_bus.c 1.0.3 2017/11/04
* Version: @(#)scsi_bus.c 1.0.4 2017/11/24
*
* NOTES: For now ported from PCem with some modifications
* but at least it's a start.
@@ -38,22 +38,22 @@
#define SET_BUS_STATE(bus, state) bus->bus_out = (bus->bus_out & ~(SCSI_PHASE_MESSAGE_IN)) | (state & (SCSI_PHASE_MESSAGE_IN))
uint32_t SCSI_BufferLength;
#ifdef ENABLE_SCSI_BUS_LOG
int scsi_bus_do_log = ENABLE_SCSI_BUS_LOG;
#endif
void scsi_bus_log(const char *format, ...)
static void
scsi_bus_log(const char *format, ...)
{
#ifdef ENABLE_SCSI_BUS_LOG
if (scsi_bus_do_log)
{
va_list ap;
va_start(ap, format);
vprintf(format, ap);
va_end(ap);
fflush(stdout);
}
if (scsi_bus_do_log) {
va_list ap;
va_start(ap, format);
vfprintf(stdlog, format, ap);
va_end(ap);
fflush(stdlog);
}
#endif
}
@@ -61,327 +61,302 @@ void scsi_bus_log(const char *format, ...)
/* get the length of a SCSI command based on its command byte type */
static int get_cmd_len(int cbyte)
{
int len;
int group;
int len;
int group;
group = (cbyte>>5) & 7;
group = (cbyte>>5) & 7;
if (group == 0) len = 6;
if (group == 1 || group == 2) len = 10;
if (group == 5) len = 12;
if (group == 0) len = 6;
if (group == 1 || group == 2) len = 10;
if (group == 5) len = 12;
//scsi_bus_log("Command group %d, length %d\n", group, len);
return len;
// scsi_bus_log("Command group %d, length %d\n", group, len);
return(len);
}
static int get_dev_id(uint8_t data)
{
int c;
for (c = 0; c < SCSI_ID_MAX; c++)
{
if (data & (1 << c))
{
return c;
static int
get_dev_id(uint8_t data)
{
int c;
for (c = 0; c < SCSI_ID_MAX; c++) {
if (data & (1 << c)) return(c);
}
return(-1);
}
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;
switch (bus->state) {
case STATE_IDLE:
scsi_bus_log("State Idle\n");
bus->clear_req = bus->change_state_delay = bus->new_req_delay = 0;
if ((bus_assert & BUS_SEL) && !(bus_assert & BUS_BSY)) {
uint8_t sel_data = BUS_GETDATA(bus_assert);
bus->dev_id = get_dev_id(sel_data);
if ((bus->dev_id != -1) && scsi_device_present(bus->dev_id, 0)) {
bus->bus_out |= BUS_BSY;
bus->state = STATE_PHASESEL;
}
//scsi_bus_log("Device id %i\n", bus->dev_id);
break;
}
}
return -1;
}
break;
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;
switch (bus->state)
{
case STATE_IDLE:
scsi_bus_log("State Idle\n");
bus->clear_req = bus->change_state_delay = bus->new_req_delay = 0;
if ((bus_assert & BUS_SEL) && !(bus_assert & BUS_BSY))
{
uint8_t sel_data = BUS_GETDATA(bus_assert);
bus->dev_id = get_dev_id(sel_data);
if ((bus->dev_id != -1) && scsi_device_present(bus->dev_id, 0))
{
bus->bus_out |= BUS_BSY;
bus->state = STATE_PHASESEL;
case STATE_PHASESEL:
scsi_bus_log("State Phase Sel\n");
if (! (bus_assert & BUS_SEL)) {
if (! (bus_assert & BUS_ATN)) {
if ((bus->dev_id != -1) &&
scsi_device_present(bus->dev_id, 0)) {
bus->state = STATE_COMMAND;
bus->bus_out = BUS_BSY | BUS_REQ;
bus->command_pos = 0;
SET_BUS_STATE(bus, SCSI_PHASE_COMMAND);
} else {
bus->state = STATE_IDLE;
bus->bus_out = 0;
}
//scsi_bus_log("Device id %i\n", bus->dev_id);
break;
}
break;
case STATE_PHASESEL:
scsi_bus_log("State Phase Sel\n");
if (!(bus_assert & BUS_SEL))
{
if (!(bus_assert & BUS_ATN))
{
if ((bus->dev_id != -1) && scsi_device_present(bus->dev_id, 0))
{
bus->state = STATE_COMMAND;
bus->bus_out = BUS_BSY | BUS_REQ;
bus->command_pos = 0;
SET_BUS_STATE(bus, SCSI_PHASE_COMMAND);
}
else
{
bus->state = STATE_IDLE;
bus->bus_out = 0;
}
}
else
fatal("dropped sel %x\n", bus_assert & BUS_ATN);
}
break;
case STATE_COMMAND:
if ((bus_assert & BUS_ACK) && !(bus->bus_in & BUS_ACK))
{
scsi_bus_log("State Command\n");
bus->command[bus->command_pos++] = BUS_GETDATA(bus_assert);
bus->clear_req = 3;
bus->new_state = bus->bus_out & SCSI_PHASE_MESSAGE_IN;
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;
} else
fatal("dropped sel %x\n", bus_assert & BUS_ATN);
}
break;
dev = &SCSIDevices[bus->dev_id][lun];
case STATE_COMMAND:
if ((bus_assert & BUS_ACK) && !(bus->bus_in & BUS_ACK)) {
scsi_bus_log("State Command\n");
bus->command[bus->command_pos++] = BUS_GETDATA(bus_assert);
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_bus_log("(%02X:%02X): Command %02X: Buffer Length %i, SCSI Phase %02X\n", bus->dev_id, lun, bus->command[0], dev->BufferLength, SCSIPhase);
if ((SCSIPhase == SCSI_PHASE_DATA_IN) || (SCSIPhase == SCSI_PHASE_DATA_OUT))
{
scsi_bus_log("dev->CmdBuffer = %08X\n", dev->CmdBuffer);
dev->CmdBuffer = (uint8_t *) malloc(dev->BufferLength);
scsi_bus_log("dev->CmdBuffer = %08X\n", dev->CmdBuffer);
}
if (SCSIPhase == SCSI_PHASE_DATA_OUT)
{
/* Write direction commands have delayed execution - only execute them after the bus has gotten all the data from the host. */
scsi_bus_log("Next state is data out\n");
bus->state = STATE_COMMANDWAIT;
bus->clear_req = 0;
}
else
{
/* Other command - execute immediately. */
bus->new_state = SCSIPhase;
if (SCSIPhase == SCSI_PHASE_DATA_IN)
{
scsi_device_command_phase1(bus->dev_id, lun);
}
bus->change_state_delay = 4;
}
}
}
break;
case STATE_COMMANDWAIT:
bus->new_state = SCSI_PHASE_DATA_OUT;
bus->change_state_delay = 4;
bus->clear_req = 4;
break;
case STATE_DATAIN:
if ((bus_assert & BUS_ACK) && !(bus->bus_in & BUS_ACK))
{
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. */
bus->clear_req = 3;
bus->new_state = bus->bus_out & SCSI_PHASE_MESSAGE_IN;
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];
if (bus->data_pos >= SCSIDevices[bus->dev_id][lun].BufferLength)
{
free(dev->CmdBuffer);
dev->CmdBuffer = NULL;
bus->bus_out &= ~BUS_REQ;
bus->new_state = SCSI_PHASE_STATUS;
bus->change_state_delay = 4;
bus->new_req_delay = 8;
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_bus_log("(%02X:%02X): Command %02X: Buffer Length %i, SCSI Phase %02X\n", bus->dev_id, lun, bus->command[0], dev->BufferLength, SCSIPhase);
if ((SCSIPhase == SCSI_PHASE_DATA_IN) ||
(SCSIPhase == SCSI_PHASE_DATA_OUT)) {
scsi_bus_log("dev->CmdBuffer = %08X\n", dev->CmdBuffer);
dev->CmdBuffer = (uint8_t *) malloc(dev->BufferLength);
scsi_bus_log("dev->CmdBuffer = %08X\n", dev->CmdBuffer);
}
else
{
uint8_t val = dev->CmdBuffer[bus->data_pos++];
bus->bus_out = (bus->bus_out & ~BUS_DATAMASK) | BUS_SETDATA(val) | BUS_DBP | BUS_REQ;
bus->clear_req = 3;
bus->bus_out &= ~BUS_REQ;
bus->new_state = SCSI_PHASE_DATA_IN;
if (SCSIPhase == SCSI_PHASE_DATA_OUT) {
/* Write direction commands have delayed execution - only execute them after the bus has gotten all the data from the host. */
scsi_bus_log("Next state is data out\n");
bus->state = STATE_COMMANDWAIT;
bus->clear_req = 0;
} else {
/* Other command - execute immediately. */
bus->new_state = SCSIPhase;
if (SCSIPhase == SCSI_PHASE_DATA_IN) {
scsi_device_command_phase1(bus->dev_id, lun);
}
bus->change_state_delay = 4;
}
}
break;
}
break;
case STATE_DATAOUT:
if ((bus_assert & BUS_ACK) && !(bus->bus_in & BUS_ACK))
{
scsi_bus_log("State Data Out\n");
case STATE_COMMANDWAIT:
bus->new_state = SCSI_PHASE_DATA_OUT;
bus->change_state_delay = 4;
bus->clear_req = 4;
break;
lun = (bus->command[1] >> 5) & 7;
case STATE_DATAIN:
if ((bus_assert & BUS_ACK) && !(bus->bus_in & BUS_ACK)) {
scsi_bus_log("State Data In\n");
dev = &SCSIDevices[bus->dev_id][lun];
/* 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);
/* This seems to be read, so we first execute the command, then we return the bytes to the host. */
if (bus->data_pos >= SCSIDevices[bus->dev_id][lun].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);
free(dev->CmdBuffer);
dev->CmdBuffer = NULL;
bus->bus_out &= ~BUS_REQ;
bus->new_state = SCSI_PHASE_STATUS;
bus->change_state_delay = 4;
bus->new_req_delay = 8;
}
else
{
bus->bus_out |= BUS_REQ;
}
}
break;
case STATE_STATUS:
scsi_bus_log("State Status\n");
if ((bus_assert & BUS_ACK) && !(bus->bus_in & BUS_ACK))
{
/* scsi_bus_log("Preparing for message in\n"); */
lun = (bus->command[1] >> 5) & 7;
dev = &SCSIDevices[bus->dev_id][lun];
if (bus->data_pos >= SCSIDevices[bus->dev_id][lun].BufferLength) {
free(dev->CmdBuffer);
dev->CmdBuffer = NULL;
bus->bus_out &= ~BUS_REQ;
bus->new_state = SCSI_PHASE_MESSAGE_IN;
bus->new_state = SCSI_PHASE_STATUS;
bus->change_state_delay = 4;
bus->new_req_delay = 8;
}
break;
case STATE_MESSAGEIN:
scsi_bus_log("State Message In\n");
if ((bus_assert & BUS_ACK) && !(bus->bus_in & BUS_ACK))
{
} else {
uint8_t val = dev->CmdBuffer[bus->data_pos++];
bus->bus_out = (bus->bus_out & ~BUS_DATAMASK) | BUS_SETDATA(val) | BUS_DBP | BUS_REQ;
bus->clear_req = 3;
bus->bus_out &= ~BUS_REQ;
bus->new_state = BUS_IDLE;
bus->new_state = SCSI_PHASE_DATA_IN;
}
}
break;
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];
/* 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) {
/* 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);
free(dev->CmdBuffer);
dev->CmdBuffer = NULL;
bus->bus_out &= ~BUS_REQ;
bus->new_state = SCSI_PHASE_STATUS;
bus->change_state_delay = 4;
}
break;
}
bus->bus_in = bus_assert;
return bus->bus_out | bus->bus_in;
}
int scsi_bus_read(scsi_bus_t *bus)
{
scsi_device_t *dev;
uint8_t lun = 0;
if (bus->clear_req)
{
bus->clear_req--;
if (!bus->clear_req)
{
scsi_bus_log("Clear REQ\n");
SET_BUS_STATE(bus, bus->new_state);
bus->bus_out |= BUS_REQ;
}
}
if (bus->change_state_delay)
{
bus->change_state_delay--;
if (!bus->change_state_delay)
{
uint8_t val;
scsi_bus_log("Change state delay\n");
SET_BUS_STATE(bus, bus->new_state);
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];
scsi_bus_log("Phase data in\n");
bus->state = STATE_DATAIN;
val = dev->CmdBuffer[bus->data_pos++];
bus->bus_out = (bus->bus_out & ~BUS_DATAMASK) | BUS_SETDATA(val) | BUS_DBP;
break;
case SCSI_PHASE_DATA_OUT:
scsi_bus_log("Phase data out\n");
if (bus->new_state & BUS_IDLE)
{
bus->state = STATE_IDLE;
bus->bus_out &= ~BUS_BSY;
}
else
{
bus->state = STATE_DATAOUT;
}
break;
case SCSI_PHASE_STATUS:
scsi_bus_log("Phase status\n");
bus->state = STATE_STATUS;
bus->bus_out |= BUS_REQ;
bus->bus_out = (bus->bus_out & ~BUS_DATAMASK) | BUS_SETDATA(SCSIStatus) | BUS_DBP;
/* scsi_bus_log("SCSI Status (command %02X): %02X (%08X)\n", bus->command[0], SCSIStatus, bus->bus_out); */
break;
case SCSI_PHASE_MESSAGE_IN:
scsi_bus_log("Phase message in\n");
/* scsi_bus_log("Message in\n"); */
bus->state = STATE_MESSAGEIN;
bus->bus_out = (bus->bus_out & ~BUS_DATAMASK) | BUS_SETDATA(0) | BUS_DBP;
break;
default:
fatal("change_state_delay bad state %x\n", bus->bus_out);
bus->new_req_delay = 8;
} else {
bus->bus_out |= BUS_REQ;
}
}
}
if (bus->new_req_delay)
{
bus->new_req_delay--;
if (!bus->new_req_delay)
{
bus->bus_out |= BUS_REQ;
break;
case STATE_STATUS:
scsi_bus_log("State Status\n");
if ((bus_assert & BUS_ACK) && !(bus->bus_in & BUS_ACK)) {
/* scsi_bus_log("Preparing for message in\n"); */
bus->bus_out &= ~BUS_REQ;
bus->new_state = SCSI_PHASE_MESSAGE_IN;
bus->change_state_delay = 4;
bus->new_req_delay = 8;
}
}
return bus->bus_out;
break;
case STATE_MESSAGEIN:
scsi_bus_log("State Message In\n");
if ((bus_assert & BUS_ACK) && !(bus->bus_in & BUS_ACK)) {
bus->bus_out &= ~BUS_REQ;
bus->new_state = BUS_IDLE;
bus->change_state_delay = 4;
}
break;
}
bus->bus_in = bus_assert;
return(bus->bus_out | bus->bus_in);
}
int scsi_bus_match(scsi_bus_t *bus, int bus_assert)
int
scsi_bus_read(scsi_bus_t *bus)
{
return (bus_assert & (BUS_CD | BUS_IO | BUS_MSG)) == (bus->bus_out & (BUS_CD | BUS_IO | BUS_MSG));
scsi_device_t *dev;
uint8_t lun = 0;
if (bus->clear_req) {
bus->clear_req--;
if (!bus->clear_req) {
scsi_bus_log("Clear REQ\n");
SET_BUS_STATE(bus, bus->new_state);
bus->bus_out |= BUS_REQ;
}
}
if (bus->change_state_delay) {
bus->change_state_delay--;
if (!bus->change_state_delay) {
uint8_t val;
scsi_bus_log("Change state delay\n");
SET_BUS_STATE(bus, bus->new_state);
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];
scsi_bus_log("Phase data in\n");
bus->state = STATE_DATAIN;
val = dev->CmdBuffer[bus->data_pos++];
bus->bus_out = (bus->bus_out & ~BUS_DATAMASK) | BUS_SETDATA(val) | BUS_DBP;
break;
case SCSI_PHASE_DATA_OUT:
scsi_bus_log("Phase data out\n");
if (bus->new_state & BUS_IDLE) {
bus->state = STATE_IDLE;
bus->bus_out &= ~BUS_BSY;
} else {
bus->state = STATE_DATAOUT;
}
break;
case SCSI_PHASE_STATUS:
scsi_bus_log("Phase status\n");
bus->state = STATE_STATUS;
bus->bus_out |= BUS_REQ;
bus->bus_out = (bus->bus_out & ~BUS_DATAMASK) | BUS_SETDATA(SCSIStatus) | BUS_DBP;
/* scsi_bus_log("SCSI Status (command %02X): %02X (%08X)\n", bus->command[0], SCSIStatus, bus->bus_out); */
break;
case SCSI_PHASE_MESSAGE_IN:
scsi_bus_log("Phase message in\n");
/* scsi_bus_log("Message in\n"); */
bus->state = STATE_MESSAGEIN;
bus->bus_out = (bus->bus_out & ~BUS_DATAMASK) | BUS_SETDATA(0) | BUS_DBP;
break;
default:
fatal("change_state_delay bad state %x\n", bus->bus_out);
}
}
}
if (bus->new_req_delay) {
bus->new_req_delay--;
if (!bus->new_req_delay) {
bus->bus_out |= BUS_REQ;
}
}
return(bus->bus_out);
}
int
scsi_bus_match(scsi_bus_t *bus, int bus_assert)
{
return((bus_assert & (BUS_CD | BUS_IO | BUS_MSG)) ==
(bus->bus_out & (BUS_CD | BUS_IO | BUS_MSG)));
}

View File

@@ -11,7 +11,7 @@
* 1 - BT-545S ISA;
* 2 - BT-958D PCI
*
* Version: @(#)scsi_buslogic.c 1.0.28 2017/11/04
* Version: @(#)scsi_buslogic.c 1.0.29 2017/11/24
*
* Authors: TheCollector1995, <mariogplayer@gmail.com>
* Miran Grca, <mgrca8@gmail.com>
@@ -236,10 +236,12 @@ enum {
CHIP_BUSLOGIC_PCI
};
#ifdef ENABLE_BUSLOGIC_LOG
int buslogic_do_log = ENABLE_BUSLOGIC_LOG;
#endif
static void
buslogic_log(const char *format, ...)
{
@@ -248,9 +250,9 @@ buslogic_log(const char *format, ...)
if (buslogic_do_log) {
va_start(ap, format);
vprintf(format, ap);
vfprintf(stdlog, format, ap);
va_end(ap);
fflush(stdout);
fflush(stdlog);
}
#endif
}

View File

@@ -6,7 +6,7 @@
*
* Emulation of SCSI fixed and removable disks.
*
* Version: @(#)scsi_disk.c 1.0.9 2017/11/04
* Version: @(#)scsi_disk.c 1.0.10 2017/11/24
*
* Author: Miran Grca, <mgrca8@gmail.com>
*
@@ -450,21 +450,23 @@ uint8_t scsi_hd_mode_sense_pages_saved[HDD_NUM][0x40][0x40] =
[0x30] = { 0xB0, 0x16, '8', '6', 'B', 'o', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' } }
};
#ifdef ENABLE_SCSI_DISK_LOG
int scsi_hd_do_log = ENABLE_SCSI_DISK_LOG;
#endif
void scsi_hd_log(const char *format, ...)
static void
scsi_hd_log(const char *format, ...)
{
#ifdef ENABLE_SCSI_DISK_LOG
if (scsi_hd_do_log)
{
va_list ap;
va_start(ap, format);
vprintf(format, ap);
va_end(ap);
fflush(stdout);
}
if (scsi_hd_do_log) {
va_list ap;
va_start(ap, format);
vfprintf(stdlog, format, ap);
va_end(ap);
fflush(stdlog);
}
#endif
}

View File

@@ -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.6 2017/11/04
* Version: @(#)scsi_ncr5380.c 1.0.7 2017/11/24
*
* Authors: Sarah Walker, <tommowalker@tommowalker.co.uk>
* TheCollector1995, <mariogplayer@gmail.com>
@@ -156,9 +156,9 @@ ncr_log(const char *fmt, ...)
if (ncr5380_do_log) {
va_start(ap, fmt);
vprintf(fmt, ap);
vfprintf(stdlog, fmt, ap);
va_end(ap);
fflush(stdout);
fflush(stdlog);
}
#endif
}

View File

@@ -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.5 2017/11/04
* Version: @(#)scsi_x54x.c 1.0.6 2017/11/24
*
* Authors: TheCollector1995, <mariogplayer@gmail.com>
* Miran Grca, <mgrca8@gmail.com>
@@ -81,9 +81,9 @@ x54x_log(const char *fmt, ...)
if (x54x_do_log) {
va_start(ap, fmt);
vprintf(fmt, ap);
vfprintf(stdlog, fmt, ap);
va_end(ap);
fflush(stdout);
fflush(stdlog);
}
#endif
}
@@ -97,39 +97,27 @@ x54x_irq(x54x_t *dev, int set)
if (dev->ven_get_irq)
irq = dev->ven_get_irq(dev);
else
else
irq = dev->Irq;
if (dev->bus & DEVICE_PCI)
{
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)
{
} 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);
}
}
@@ -323,11 +311,11 @@ x54x_bios_command(x54x_t *x54x, uint8_t max_id, BIOSCMD *cmd, int8_t islba)
else
lba = (cmd->u.chs.cyl << 9) + (cmd->u.chs.head << 5) + cmd->u.chs.sec;
x54x_log("BIOS Command = 0x%02X\n", cmd->command);
x54x_log("BIOS Command = 0x%02X\n", cmd->command);
if ((cmd->id > max_id) || (cmd->lun > 7)) {
x54x_log("BIOS Target ID %i or LUN %i are above maximum\n",
cmd->id, cmd->lun);
cmd->id, cmd->lun);
return(0x80);
}
@@ -350,7 +338,7 @@ x54x_bios_command(x54x_t *x54x, uint8_t max_id, BIOSCMD *cmd, int8_t islba)
dma_address = ADDR_TO_U32(cmd->dma_address);
x54x_log("BIOS Data Buffer write: length %d, pointer 0x%04X\n",
sector_len, dma_address);
sector_len, dma_address);
if (dev->CmdBuffer != NULL) {
free(dev->CmdBuffer);
@@ -628,7 +616,7 @@ x54x_cmd_done(x54x_t *dev, int suppress)
static void
x54x_mbi_setup(x54x_t *dev, uint32_t CCBPointer, CCBU *CmdBlock,
uint8_t HostStatus, uint8_t TargetStatus, uint8_t mbcc)
uint8_t HostStatus, uint8_t TargetStatus, uint8_t mbcc)
{
Req_t *req = &dev->Req;
@@ -655,13 +643,9 @@ x54x_ccb(x54x_t *dev)
DMAPageWrite(req->CCBPointer + 0x000F, (char *)&(req->TargetStatus), 1);
if (dev->MailboxOutInterrupts)
{
dev->ToRaise = INTR_MBOA | INTR_ANY;
}
else
{
else
dev->ToRaise = 0;
}
}
@@ -669,7 +653,7 @@ static void
x54x_mbi(x54x_t *dev)
{
Req_t *req = &dev->Req;
// uint32_t CCBPointer = req->CCBPointer;
// uint32_t CCBPointer = req->CCBPointer;
addr24 CCBPointer;
CCBU *CmdBlock = &(req->CmdBlock);
uint8_t HostStatus = req->HostStatus;
@@ -681,8 +665,8 @@ x54x_mbi(x54x_t *dev)
if (MailboxCompletionCode != MBI_NOT_FOUND) {
CmdBlock->common.HostStatus = HostStatus;
CmdBlock->common.TargetStatus = TargetStatus;
CmdBlock->common.TargetStatus = TargetStatus;
/* Rewrite the CCB up to the CDB. */
x54x_log("CCB statuses rewritten (pointer %08X)\n", req->CCBPointer);
DMAPageWrite(req->CCBPointer + 0x000E, (char *)&(req->HostStatus), 1);
@@ -714,9 +698,7 @@ x54x_mbi(x54x_t *dev)
dev->ToRaise = INTR_MBIF | INTR_ANY;
if (dev->MailboxOutInterrupts)
{
dev->ToRaise |= INTR_MBOA;
}
}
@@ -753,13 +735,13 @@ x54x_get_length(Req_t *req, int Is24bit)
x54x_log("Data length: %08X\n", req->CmdBlock.old.DataLength);
} else {
DataPointer = req->CmdBlock.new.DataPointer;
DataLength = req->CmdBlock.new.DataLength;
DataLength = req->CmdBlock.new.DataLength;
}
x54x_log("Data Buffer write: length %d, pointer 0x%04X\n",
DataLength, DataPointer);
DataLength, DataPointer);
if (!DataLength)
return 0;
return(0);
if (req->CmdBlock.common.ControlByte != 0x03) {
if (req->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND ||
@@ -769,15 +751,15 @@ x54x_get_length(Req_t *req, int Is24bit)
DataToTransfer += SGBuffer.Segment;
}
return DataToTransfer;
return(DataToTransfer);
} else if (req->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND ||
req->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND_RES) {
return DataLength;
return(DataLength);
} else {
return 0;
return(0);
}
} else {
return 0;
return(0);
}
}
@@ -829,10 +811,10 @@ x54x_buf_dma_transfer(Req_t *req, int Is24bit, int TransferLength, int dir)
DataLength = ADDR_TO_U32(req->CmdBlock.old.DataLength);
} else {
DataPointer = req->CmdBlock.new.DataPointer;
DataLength = req->CmdBlock.new.DataLength;
DataLength = req->CmdBlock.new.DataLength;
}
x54x_log("Data Buffer %s: length %d, pointer 0x%04X\n",
dir ? "write" : "read", BufLen, DataPointer);
dir ? "write" : "read", BufLen, DataPointer);
if ((req->CmdBlock.common.ControlByte != 0x03) && TransferLength && BufLen) {
if ((req->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND) ||
@@ -873,13 +855,9 @@ x54x_buf_dma_transfer(Req_t *req, int Is24bit, int TransferLength, int dir)
Address = DataPointer;
if ((DataLength > 0) && (BufLen > 0) && (req->CmdBlock.common.ControlByte < 0x03)) {
if (read_from_host)
{
if (read_from_host) {
DMAPageRead(Address, (char *)SCSIDevices[req->TargetID][req->LUN].CmdBuffer, MIN(BufLen, DataLength));
}
else
if (write_to_host)
{
} else if (write_to_host) {
DMAPageWrite(Address, (char *)SCSIDevices[req->TargetID][req->LUN].CmdBuffer, MIN(BufLen, DataLength));
}
}
@@ -939,7 +917,7 @@ SenseBufferPointer(Req_t *req)
SenseBufferAddress = req->CmdBlock.new.SensePointer;
}
return SenseBufferAddress;
return(SenseBufferAddress);
}
@@ -1005,7 +983,7 @@ x54x_scsi_cmd(x54x_t *dev)
memset(temp_cdb, 0x00, target_cdb_len);
if (req->CmdBlock.common.CdbLength <= target_cdb_len) {
memcpy(temp_cdb, req->CmdBlock.common.Cdb,
req->CmdBlock.common.CdbLength);
req->CmdBlock.common.CdbLength);
} else {
memcpy(temp_cdb, req->CmdBlock.common.Cdb, target_cdb_len);
}
@@ -1071,14 +1049,10 @@ x54x_scsi_cmd(x54x_t *dev)
static void
x54x_notify(x54x_t *dev)
{
if (dev->MailboxIsBIOS)
{
x54x_ccb(dev);
}
else
{
x54x_mbi(dev);
}
if (dev->MailboxIsBIOS)
x54x_ccb(dev);
else
x54x_mbi(dev);
}
@@ -1107,8 +1081,8 @@ x54x_req_setup(x54x_t *dev, uint32_t CCBPointer, Mailbox32_t *Mailbox32)
x54x_notify(dev);
return;
}
x54x_log("Scanning SCSI Target ID %i\n", id);
x54x_log("Scanning SCSI Target ID %i\n", id);
SCSIStatus = SCSI_STATUS_OK;
@@ -1201,7 +1175,7 @@ x54x_mbo(x54x_t *dev, Mailbox32_t *Mailbox32)
} else {
Outgoing = Addr + (Cur * sizeof(Mailbox32_t));
DMAPageRead(Outgoing, (char *)Mailbox32, sizeof(Mailbox32_t));
DMAPageRead(Outgoing, (char *)Mailbox32, sizeof(Mailbox32_t));
}
return(Outgoing);
@@ -1235,23 +1209,22 @@ x54x_mbo_process(x54x_t *dev)
x54x_log("x54x_do_mail(): Writing %i bytes at %08X\n", sizeof(CmdStatus), Outgoing + CodeOffset);
DMAPageWrite(Outgoing + CodeOffset, (char *)&CmdStatus, 1);
if (dev->ToRaise)
{
if (dev->ToRaise) {
raise_irq(dev, 0, dev->ToRaise);
while (dev->Interrupt) {
}
while (dev->Interrupt)
;
}
if (dev->MailboxIsBIOS)
dev->BIOSMailboxReq--;
else
else
dev->MailboxReq--;
return 1;
return(1);
}
return 0;
return(0);
}
@@ -1313,8 +1286,7 @@ x54x_cmd_thread(void *priv)
x54x_log("Polling thread started\n");
while (x54x_dev)
{
while (x54x_dev) {
scsi_mutex_wait(1);
if ((dev->Status & STAT_INIT) || (!dev->MailboxInit && !dev->BIOSMailboxInit) || (!dev->MailboxReq && !dev->BIOSMailboxReq)) {
@@ -1325,8 +1297,7 @@ x54x_cmd_thread(void *priv)
continue;
}
if (!(x54x_dev->Status & STAT_INIT) && x54x_dev->MailboxInit && dev->MailboxReq)
{
if (!(x54x_dev->Status & STAT_INIT) && x54x_dev->MailboxInit && dev->MailboxReq) {
x54x_wait_for_poll();
x54x_do_mail(dev);
@@ -1365,14 +1336,14 @@ x54x_thread_start(x54x_t *dev)
uint8_t
x54x_is_busy(void)
{
return !!busy;
return(!!busy);
}
void
x54x_set_wait_event(void)
{
thread_set_event((event_t *) wait_evt);
thread_set_event((event_t *)wait_evt);
}
@@ -1387,7 +1358,7 @@ x54x_in(uint16_t port, void *priv)
default:
ret = dev->Status;
break;
case 1:
ret = dev->DataBuf[dev->DataReply];
if (dev->DataReplyLeft) {
@@ -1397,11 +1368,11 @@ x54x_in(uint16_t port, void *priv)
x54x_cmd_done(dev, 0);
}
break;
case 2:
ret = dev->Interrupt;
break;
case 3:
ret = dev->Geometry;
break;
@@ -1417,35 +1388,35 @@ x54x_in(uint16_t port, void *priv)
static uint16_t
x54x_inw(uint16_t port, void *priv)
{
return (uint16_t) x54x_in(port, priv);
return((uint16_t) x54x_in(port, priv));
}
static uint32_t
x54x_inl(uint16_t port, void *priv)
{
return (uint32_t) x54x_in(port, priv);
return((uint32_t) x54x_in(port, priv));
}
static uint8_t
x54x_read(uint32_t port, void *priv)
{
return x54x_in(port & 3, priv);
return(x54x_in(port & 3, priv));
}
static uint16_t
x54x_readw(uint32_t port, void *priv)
{
return x54x_inw(port & 3, priv);
return(x54x_inw(port & 3, priv));
}
static uint32_t
x54x_readl(uint32_t port, void *priv)
{
return x54x_inl(port & 3, priv);
return(x54x_inl(port & 3, priv));
}
@@ -1531,7 +1502,7 @@ x54x_out(uint16_t port, uint8_t val, void *priv)
x54x_busy(0);
break;
}
if (val & CTRL_IRST) {
x54x_busy(1);
clear_irq(dev);
@@ -1561,14 +1532,14 @@ x54x_out(uint16_t port, uint8_t val, void *priv)
dev->Command = val;
dev->CmdParam = 0;
dev->CmdParamLeft = 0;
dev->Status &= ~(STAT_INVCMD | STAT_IDLE);
x54x_log("%s: Operation Code 0x%02X\n", dev->name, val);
switch (dev->Command) {
case CMD_MBINIT:
dev->CmdParamLeft = sizeof(MailboxInit_t);
break;
case CMD_BIOSCMD:
dev->CmdParamLeft = 10;
break;
@@ -1616,14 +1587,14 @@ x54x_out(uint16_t port, uint8_t val, void *priv)
case CMD_MBINIT: /* mailbox initialization */
x54x_busy(1);
dev->Mbx24bit = 1;
mbi = (MailboxInit_t *)dev->CmdBuf;
dev->MailboxInit = 1;
dev->MailboxCount = mbi->Count;
dev->MailboxOutAddr = ADDR_TO_U32(mbi->Address);
dev->MailboxInAddr = dev->MailboxOutAddr + (dev->MailboxCount * sizeof(Mailbox_t));
x54x_log("Initialize Mailbox: MBO=0x%08lx, MBI=0x%08lx, %d entries at 0x%08lx\n",
dev->MailboxOutAddr,
dev->MailboxInAddr,
@@ -1641,7 +1612,7 @@ x54x_out(uint16_t port, uint8_t val, void *priv)
if (!(dev->bus & DEVICE_MCA)) {
/* 1640 uses LBA. */
cyl = ((cmd->u.chs.cyl & 0xff) << 8) | ((cmd->u.chs.cyl >> 8) & 0xff);
cmd->u.chs.cyl = cyl;
cmd->u.chs.cyl = cyl;
}
if (dev->bus & DEVICE_MCA) {
/* 1640 uses LBA. */
@@ -1681,19 +1652,19 @@ x54x_out(uint16_t port, uint8_t val, void *priv)
case CMD_SELTIMEOUT: /* Selection Time-out */
dev->DataReplyLeft = 0;
break;
case CMD_BUSON_TIME: /* bus-on time */
dev->BusOnTime = dev->CmdBuf[0];
dev->DataReplyLeft = 0;
x54x_log("Bus-on time: %d\n", dev->CmdBuf[0]);
break;
case CMD_BUSOFF_TIME: /* bus-off time */
dev->BusOffTime = dev->CmdBuf[0];
dev->DataReplyLeft = 0;
x54x_log("Bus-off time: %d\n", dev->CmdBuf[0]);
break;
case CMD_DMASPEED: /* DMA Transfer Rate */
dev->ATBusSpeed = dev->CmdBuf[0];
dev->DataReplyLeft = 0;
@@ -1718,7 +1689,7 @@ x54x_out(uint16_t port, uint8_t val, void *priv)
}
}
dev->DataReplyLeft = i;
break;
break;
case CMD_RETCONF: /* return Configuration */
if (dev->ven_get_dma)
@@ -1762,7 +1733,7 @@ x54x_out(uint16_t port, uint8_t val, void *priv)
x54x_log("Return Setup Information: %d (length: %i)\n", dev->CmdBuf[0], sizeof(ReplyInquireSetupInformation));
}
break;
case CMD_ECHO: /* ECHO data */
dev->DataBuf[0] = dev->CmdBuf[0];
dev->DataReplyLeft = 1;
@@ -1804,18 +1775,18 @@ x54x_out(uint16_t port, uint8_t val, void *priv)
break;
}
}
if (dev->DataReplyLeft)
dev->Status |= STAT_DFULL;
else if (!dev->CmdParamLeft)
x54x_cmd_done(dev, suppress);
break;
case 2:
if (dev->int_geom_writable)
dev->Interrupt = val;
break;
case 3:
if (dev->int_geom_writable)
dev->Geometry = val;
@@ -1941,8 +1912,7 @@ x54x_mem_enable(x54x_t *dev)
void
x54x_mem_set_addr(x54x_t *dev, uint32_t base)
{
mem_mapping_set_addr(&dev->mmio_mapping,
base, 0x20);
mem_mapping_set_addr(&dev->mmio_mapping, base, 0x20);
}
@@ -1992,8 +1962,7 @@ x54x_close(void *priv)
{
x54x_t *dev = (x54x_t *)priv;
if (dev)
{
if (dev) {
x54x_dev = NULL;
/* Tell the thread to terminate. */