Adaptec/BusLogic SCSI improvements - more commands, a few bug fixes
This commit is contained in:
parent
5d5b4dce8a
commit
b5c8ad4bd6
1 changed files with 93 additions and 40 deletions
|
|
@ -93,6 +93,8 @@ typedef struct aha154x_t
|
|||
uint8_t isr_pending;
|
||||
uint8_t status;
|
||||
|
||||
int mbo_irq_enable;
|
||||
|
||||
uint8_t cmd_data;
|
||||
uint8_t data_in;
|
||||
|
||||
|
|
@ -118,6 +120,7 @@ typedef struct aha154x_t
|
|||
int bios_mbc;
|
||||
uint32_t bios_mba;
|
||||
int bios_mbo_req;
|
||||
int bios_mbo_inited;
|
||||
|
||||
cmd_state_t cmd_state;
|
||||
ccb_state_t ccb_state;
|
||||
|
|
@ -187,6 +190,8 @@ typedef struct aha154x_t
|
|||
int scatter_gather;
|
||||
int bytes_transferred;
|
||||
} cdb;
|
||||
|
||||
int reg3_idx;
|
||||
} aha154x_t;
|
||||
|
||||
#define STATUS_INVDCMD 0x01
|
||||
|
|
@ -206,20 +211,22 @@ typedef struct aha154x_t
|
|||
#define ISR_HACC 0x04
|
||||
#define ISR_ANYINTR 0x80
|
||||
|
||||
#define COMMAND_NOP 0x00
|
||||
#define COMMAND_MAILBOX_INITIALIZATION 0x01
|
||||
#define COMMAND_START_SCSI_COMMAND 0x02
|
||||
#define COMMAND_START_BIOS_COMMAND 0x03
|
||||
#define COMMAND_ADAPTER_INQUIRY 0x04
|
||||
#define COMMAND_SET_SELECTION_TIMEOUT 0x06
|
||||
#define COMMAND_SET_BUS_ON_TIME 0x07
|
||||
#define COMMAND_SET_BUS_OFF_TIME 0x08
|
||||
#define COMMAND_SET_AT_BUS_SPEED 0x09
|
||||
#define COMMAND_RETURN_CONFIG_DATA 0x0b
|
||||
#define COMMAND_RETURN_SETUP_DATA 0x0d
|
||||
#define COMMAND_WRITE_CHANNEL_2_BUF 0x1a
|
||||
#define COMMAND_READ_CHANNEL_2_BUF 0x1b
|
||||
#define COMMAND_ECHO 0x1f
|
||||
#define COMMAND_NOP 0x00
|
||||
#define COMMAND_MAILBOX_INITIALIZATION 0x01
|
||||
#define COMMAND_START_SCSI_COMMAND 0x02
|
||||
#define COMMAND_START_BIOS_COMMAND 0x03
|
||||
#define COMMAND_ADAPTER_INQUIRY 0x04
|
||||
#define COMMAND_MAILBOX_OUT_IRQ_ENA 0x05
|
||||
#define COMMAND_SET_SELECTION_TIMEOUT 0x06
|
||||
#define COMMAND_SET_BUS_ON_TIME 0x07
|
||||
#define COMMAND_SET_BUS_OFF_TIME 0x08
|
||||
#define COMMAND_SET_AT_BUS_SPEED 0x09
|
||||
#define COMMAND_INQUIRE_INSTALLED_DEVICES 0x0a
|
||||
#define COMMAND_RETURN_CONFIG_DATA 0x0b
|
||||
#define COMMAND_RETURN_SETUP_DATA 0x0d
|
||||
#define COMMAND_WRITE_CHANNEL_2_BUF 0x1a
|
||||
#define COMMAND_READ_CHANNEL_2_BUF 0x1b
|
||||
#define COMMAND_ECHO 0x1f
|
||||
|
||||
#define COMMAND_ADAPTEC_PROGRAM_EEPROM 0x22
|
||||
#define COMMAND_ADAPTEC_RETURN_EEPROM_DATA 0x23
|
||||
|
|
@ -235,6 +242,8 @@ typedef struct aha154x_t
|
|||
#define COMMAND_BUSLOGIC_81 0x81
|
||||
#define COMMAND_BUSLOGIC_84 0x84
|
||||
#define COMMAND_BUSLOGIC_85 0x85
|
||||
#define COMMAND_BUSLOGIC_ADAPTER_MODEL_NR 0x8b
|
||||
#define COMMAND_BUSLOGIC_INQUIRY_SYNC_PERIOD 0x8c
|
||||
#define COMMAND_BUSLOGIC_EXTENDED_SETUP_INFO 0x8d
|
||||
#define COMMAND_BUSLOGIC_STRICT_RR 0x8f
|
||||
#define COMMAND_BUSLOGIC_SET_CCB_FORMAT 0x96
|
||||
|
|
@ -267,9 +276,7 @@ static void process_cmd(aha154x_t *scsi);
|
|||
|
||||
static void set_irq(aha154x_t *scsi, uint8_t val)
|
||||
{
|
||||
// pclog("set_irq %02x %02x\n", scsi->isr, val);
|
||||
if (!scsi->isr)
|
||||
picint(1 << scsi->irq);
|
||||
picint(1 << scsi->irq);
|
||||
scsi->isr |= val;
|
||||
}
|
||||
|
||||
|
|
@ -301,21 +308,20 @@ static void aha154x_out(uint16_t port, uint8_t val, void *p)
|
|||
scsi->scsi_state = SCSI_STATE_IDLE;
|
||||
scsi->mb_format = MB_FORMAT_4;
|
||||
scsi->current_mbi = 0;
|
||||
scsi->mbo_irq_enable = 0;
|
||||
}
|
||||
if (val & CTRL_SRST)
|
||||
{
|
||||
scsi->isr = 0;
|
||||
clear_irq(scsi);
|
||||
if (scsi->type == SCSI_BT545S)
|
||||
scsi->status = STATUS_INIT;
|
||||
else
|
||||
scsi->status = 0;
|
||||
scsi->status = STATUS_INIT;
|
||||
// pclog("software reset\n");
|
||||
scsi->cmd_state = CMD_STATE_IDLE;
|
||||
scsi->ccb_state = CCB_STATE_IDLE;
|
||||
scsi->scsi_state = SCSI_STATE_IDLE;
|
||||
scsi->mb_format = MB_FORMAT_4;
|
||||
scsi->current_mbi = 0;
|
||||
scsi->mbo_irq_enable = 0;
|
||||
}
|
||||
if (val & CTRL_IRST)
|
||||
{
|
||||
|
|
@ -341,7 +347,7 @@ static void aha154x_out(uint16_t port, uint8_t val, void *p)
|
|||
// fatal("Write command reg while full\n");
|
||||
scsi->status |= STATUS_CDF;
|
||||
scsi->cmd_data = val;
|
||||
pclog("Write command %02x %04x(%08x):%08x\n", val, CS,cs,cpu_state.pc);
|
||||
// pclog("Write command %02x %04x(%08x):%08x\n", val, CS,cs,cpu_state.pc);
|
||||
process_cmd(scsi);
|
||||
break;
|
||||
}
|
||||
|
|
@ -379,7 +385,16 @@ static uint8_t aha154x_in(uint16_t port, void *p)
|
|||
if (scsi->type == SCSI_BT545S)
|
||||
temp = 0x29; /*BT-545S BIOS expects this to return not zero or 0xff for six consecutive reads*/
|
||||
else
|
||||
temp = 0xff;
|
||||
{
|
||||
scsi->reg3_idx++;
|
||||
switch (scsi->reg3_idx & 3)
|
||||
{
|
||||
case 0: temp = 'A'; break;
|
||||
case 1: temp = 'D'; break;
|
||||
case 2: temp = 'A'; break;
|
||||
case 3: temp = 'P'; break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (CS != 0xc800)
|
||||
|
|
@ -564,6 +579,7 @@ static void process_cmd(aha154x_t *scsi)
|
|||
case COMMAND_NOP:
|
||||
case COMMAND_START_SCSI_COMMAND:
|
||||
case COMMAND_ADAPTER_INQUIRY:
|
||||
case COMMAND_INQUIRE_INSTALLED_DEVICES:
|
||||
case COMMAND_RETURN_CONFIG_DATA:
|
||||
scsi->command_len = 0;
|
||||
break;
|
||||
|
|
@ -587,6 +603,7 @@ static void process_cmd(aha154x_t *scsi)
|
|||
break;
|
||||
|
||||
case COMMAND_ECHO:
|
||||
case COMMAND_MAILBOX_OUT_IRQ_ENA:
|
||||
case COMMAND_SET_BUS_ON_TIME:
|
||||
case COMMAND_SET_BUS_OFF_TIME:
|
||||
case COMMAND_SET_AT_BUS_SPEED:
|
||||
|
|
@ -617,6 +634,8 @@ static void process_cmd(aha154x_t *scsi)
|
|||
case COMMAND_BUSLOGIC_SET_CCB_FORMAT:
|
||||
case COMMAND_BUSLOGIC_STRICT_RR:
|
||||
case COMMAND_BUSLOGIC_EXTENDED_SETUP_INFO:
|
||||
case COMMAND_BUSLOGIC_ADAPTER_MODEL_NR:
|
||||
case COMMAND_BUSLOGIC_INQUIRY_SYNC_PERIOD:
|
||||
if (scsi->type == SCSI_BT545S)
|
||||
scsi->command_len = 1;
|
||||
else
|
||||
|
|
@ -1053,6 +1072,12 @@ static void process_cmd(aha154x_t *scsi)
|
|||
scsi->result_len = 4;
|
||||
break;
|
||||
|
||||
case COMMAND_MAILBOX_OUT_IRQ_ENA:
|
||||
scsi->mbo_irq_enable = scsi->params[0];
|
||||
set_irq(scsi, ISR_HACC);
|
||||
scsi->cmd_state = CMD_STATE_IDLE;
|
||||
break;
|
||||
|
||||
case COMMAND_SET_SELECTION_TIMEOUT:
|
||||
scsi->e_d = scsi->params[0];
|
||||
scsi->to = (scsi->params[1] << 8) | scsi->params[2];
|
||||
|
|
@ -1077,6 +1102,14 @@ static void process_cmd(aha154x_t *scsi)
|
|||
set_irq(scsi, ISR_HACC);
|
||||
scsi->cmd_state = CMD_STATE_IDLE;
|
||||
break;
|
||||
|
||||
case COMMAND_INQUIRE_INSTALLED_DEVICES:
|
||||
for (c = 0; c < 8; c++)
|
||||
scsi->result[c] = scsi->bus.devices[c] ? 1 : 0;
|
||||
scsi->cmd_state = CMD_STATE_SEND_RESULT;
|
||||
scsi->result_pos = 0;
|
||||
scsi->result_len = 8;
|
||||
break;
|
||||
|
||||
case COMMAND_RETURN_CONFIG_DATA:
|
||||
scsi->result[0] = 1 << scsi->dma;
|
||||
|
|
@ -1215,8 +1248,8 @@ static void process_cmd(aha154x_t *scsi)
|
|||
case COMMAND_ADAPTEC_BIOS_MAILBOX_INIT:
|
||||
scsi->bios_mbc = scsi->params[0];
|
||||
scsi->bios_mba = scsi->params[3] | (scsi->params[2] << 8) | (scsi->params[1] << 16);
|
||||
scsi->bios_mbo_inited = 1;
|
||||
pclog("BIOS mailbox init: MBC=%02x MBC=%06x\n", scsi->bios_mbc, scsi->bios_mba);
|
||||
scsi->status &= ~STATUS_INIT;
|
||||
set_irq(scsi, ISR_HACC);
|
||||
scsi->cmd_state = CMD_STATE_IDLE;
|
||||
break;
|
||||
|
|
@ -1280,7 +1313,31 @@ static void process_cmd(aha154x_t *scsi)
|
|||
scsi->result_pos = 0;
|
||||
scsi->result_len = 1;
|
||||
break;
|
||||
|
||||
|
||||
case COMMAND_BUSLOGIC_ADAPTER_MODEL_NR:
|
||||
scsi->result[0] = '5';
|
||||
scsi->result[1] = '4';
|
||||
scsi->result[2] = '2';
|
||||
scsi->result[3] = 'B';
|
||||
scsi->result[4] = 'H';
|
||||
scsi->cmd_state = CMD_STATE_SEND_RESULT;
|
||||
scsi->result_pos = 0;
|
||||
scsi->result_len = MIN(scsi->params[0], 5);
|
||||
for (; scsi->result_len < scsi->params[0]; scsi->result_len++)
|
||||
scsi->result[scsi->result_len] = 0;
|
||||
break;
|
||||
|
||||
case COMMAND_BUSLOGIC_INQUIRY_SYNC_PERIOD:
|
||||
for (c = 0; c < 8; c++)
|
||||
scsi->result[c] = 0;
|
||||
scsi->cmd_state = CMD_STATE_SEND_RESULT;
|
||||
scsi->result_pos = 0;
|
||||
scsi->result_len = MIN(scsi->params[0], 8);
|
||||
for (; scsi->result_len < scsi->params[0]; scsi->result_len++)
|
||||
scsi->result[scsi->result_len] = 0;
|
||||
break;
|
||||
|
||||
|
||||
case COMMAND_BUSLOGIC_EXTENDED_SETUP_INFO:
|
||||
pclog("Extended setup info %i\n", scsi->params[0]);
|
||||
scsi->result[0] = 0x41;
|
||||
|
|
@ -1359,9 +1416,7 @@ static void process_ccb(aha154x_t *scsi)
|
|||
switch (scsi->ccb_state)
|
||||
{
|
||||
case CCB_STATE_IDLE:
|
||||
if (scsi->status & STATUS_INIT)
|
||||
break;
|
||||
if (scsi->mbo_req)
|
||||
if (!(scsi->status & STATUS_INIT) && scsi->mbo_req)
|
||||
{
|
||||
// pclog("mbo_req %i\n", scsi->mbc);
|
||||
for (c = 0; c < scsi->mbc; c++)
|
||||
|
|
@ -1395,7 +1450,7 @@ static void process_ccb(aha154x_t *scsi)
|
|||
|
||||
scsi->mbo_req--;
|
||||
|
||||
set_irq(scsi, ISR_HACC);
|
||||
//set_irq(scsi, ISR_HACC);
|
||||
break;
|
||||
}
|
||||
else if (command == COMMAND_ABORT_CCB)
|
||||
|
|
@ -1423,12 +1478,12 @@ static void process_ccb(aha154x_t *scsi)
|
|||
scsi->current_mbi++;
|
||||
if (scsi->current_mbi >= scsi->mbc)
|
||||
scsi->current_mbi = 0;
|
||||
set_irq(scsi, ISR_MBOA | ISR_MBIF | ISR_HACC);
|
||||
set_irq(scsi, (scsi->mbo_irq_enable ? ISR_MBOA : 0) | ISR_MBIF | ISR_HACC);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (scsi->bios_mbo_req)
|
||||
if (scsi->bios_mbo_inited && scsi->bios_mbo_req)
|
||||
{
|
||||
for (c = 0; c < scsi->bios_mbc; c++)
|
||||
{
|
||||
|
|
@ -1529,9 +1584,9 @@ static void process_ccb(aha154x_t *scsi)
|
|||
scsi->current_mbi++;
|
||||
if (scsi->current_mbi >= scsi->mbc)
|
||||
scsi->current_mbi = 0;
|
||||
set_irq(scsi, ISR_MBOA | ISR_MBIF);
|
||||
set_irq(scsi, (scsi->mbo_irq_enable ? ISR_MBOA : 0) | ISR_MBIF);
|
||||
}
|
||||
else
|
||||
else if (scsi->mbo_irq_enable)
|
||||
set_irq(scsi, ISR_MBOA);
|
||||
}
|
||||
// set_irq(scsi, ISR_HACC);
|
||||
|
|
@ -1610,9 +1665,9 @@ static void process_ccb(aha154x_t *scsi)
|
|||
scsi->current_mbi++;
|
||||
if (scsi->current_mbi >= scsi->mbc)
|
||||
scsi->current_mbi = 0;
|
||||
set_irq(scsi, ISR_MBOA | ISR_MBIF);
|
||||
set_irq(scsi, (scsi->mbo_irq_enable ? ISR_MBOA : 0) | ISR_MBIF);
|
||||
}
|
||||
else
|
||||
else if (scsi->mbo_irq_enable)
|
||||
set_irq(scsi, ISR_MBOA);
|
||||
}
|
||||
scsi->ccb_state = CCB_STATE_IDLE;
|
||||
|
|
@ -1705,12 +1760,10 @@ static void process_ccb(aha154x_t *scsi)
|
|||
scsi->current_mbi++;
|
||||
if (scsi->current_mbi >= scsi->mbc)
|
||||
scsi->current_mbi = 0;
|
||||
set_irq(scsi, ISR_MBOA | ISR_MBIF);
|
||||
set_irq(scsi, (scsi->mbo_irq_enable ? ISR_MBOA : 0) | ISR_MBIF);
|
||||
}
|
||||
else
|
||||
else if (scsi->mbo_irq_enable)
|
||||
set_irq(scsi, ISR_MBOA);
|
||||
|
||||
set_irq(scsi, ISR_MBOA | ISR_MBIF);
|
||||
}
|
||||
// pclog("CCB_STATE_WAIT_REQUEST_SENSE over %i\n", scsi->ccb.from_mailbox);
|
||||
scsi->ccb_state = CCB_STATE_IDLE;
|
||||
|
|
@ -1783,7 +1836,7 @@ static void process_scsi(aha154x_t *scsi)
|
|||
}
|
||||
|
||||
bus_out = BUS_SETDATA(scsi->cdb.data[scsi->cdb.idx]);
|
||||
// pclog(" Command send %02x\n", scsi->cdb.data[scsi->cdb.idx]);
|
||||
// pclog(" Command send %02x %i\n", scsi->cdb.data[scsi->cdb.idx], scsi->cdb.len);
|
||||
// if (!scsi->cdb.idx && scsi->cdb.data[scsi->cdb.idx] == 0x25 && scsi->current_mbo == 1)
|
||||
// output = 3;
|
||||
scsi->cdb.idx++;
|
||||
|
|
|
|||
Loading…
Reference in a new issue