Merge pull request #2517 from 86Box/pcnetfix

Networking: moved the pcnetPollTimer calls to a timer.
This commit is contained in:
Miran Grča
2022-07-26 22:47:13 +02:00
committed by GitHub
3 changed files with 169 additions and 152 deletions

View File

@@ -258,7 +258,7 @@ typedef struct {
uint32_t cMsLinkUpDelay;
int transfer_size;
uint8_t maclocal[6]; /* configured MAC (local) address */
pc_timer_t timer_soft_int, timer_restore;
pc_timer_t timer, timer_soft_int, timer_restore;
} nic_t;
/** @todo All structs: big endian? */
@@ -386,7 +386,6 @@ static uint8_t pcnet_pci_regs[PCI_REGSIZE];
static void pcnetAsyncTransmit(nic_t *dev);
static void pcnetPollRxTx(nic_t *dev);
static void pcnetPollTimer(nic_t *dev);
static void pcnetUpdateIrq(nic_t *dev);
static uint16_t pcnet_bcr_readw(nic_t *dev, uint16_t rap);
static void pcnet_bcr_writew(nic_t *dev, uint16_t rap, uint16_t val);
@@ -1038,7 +1037,7 @@ pcnetStart(nic_t *dev)
dev->aCSR[0] |= 0x0020; /* set RXON */
dev->aCSR[0] &= ~0x0004; /* clear STOP bit */
dev->aCSR[0] |= 0x0002; /* STRT */
pcnetPollTimer(dev);
timer_set_delay_u64(&dev->timer, 2000 * TIMER_USEC);
}
@@ -1052,7 +1051,7 @@ pcnetStop(nic_t *dev)
dev->aCSR[0] = 0x0004;
dev->aCSR[4] &= ~0x02c2;
dev->aCSR[5] &= ~0x0011;
pcnetPollTimer(dev);
timer_disable(&dev->timer);
}
@@ -1699,8 +1698,12 @@ pcnetPollRxTx(nic_t *dev)
static void
pcnetPollTimer(nic_t *dev)
pcnetPollTimer(void *p)
{
nic_t *dev = (nic_t *)p;
timer_advance_u64(&dev->timer, 2000 * TIMER_USEC);
if (CSR_TDMD(dev))
pcnetAsyncTransmit(dev);
@@ -2226,7 +2229,7 @@ pcnet_word_write(nic_t *dev, uint32_t addr, uint16_t val)
if (!BCR_DWIO(dev)) {
switch (addr & 0x0f) {
case 0x00: /* RDP */
pcnetPollTimer(dev);
timer_set_delay_u64(&dev->timer, 2000 * TIMER_USEC);
pcnet_csr_writew(dev, dev->u32RAP, val);
pcnetUpdateIrq(dev);
break;
@@ -2272,7 +2275,7 @@ pcnet_word_read(nic_t *dev, uint32_t addr)
/** @note if we're not polling, then the guest will tell us when to poll by setting TDMD in CSR0 */
/** Polling is then useless here and possibly expensive. */
if (!CSR_DPOLL(dev))
pcnetPollTimer(dev);
timer_set_delay_u64(&dev->timer, 2000 * TIMER_USEC);
val = pcnet_csr_readw(dev, dev->u32RAP);
if (dev->u32RAP == 0)
@@ -2306,7 +2309,7 @@ pcnet_dword_write(nic_t *dev, uint32_t addr, uint32_t val)
if (BCR_DWIO(dev)) {
switch (addr & 0x0f) {
case 0x00: /* RDP */
pcnetPollTimer(dev);
timer_set_delay_u64(&dev->timer, 2000 * TIMER_USEC);
pcnet_csr_writew(dev, dev->u32RAP, val & 0xffff);
pcnetUpdateIrq(dev);
break;
@@ -2334,7 +2337,7 @@ pcnet_dword_read(nic_t *dev, uint32_t addr)
switch (addr & 0x0f) {
case 0x00: /* RDP */
if (!CSR_DPOLL(dev))
pcnetPollTimer(dev);
timer_set_delay_u64(&dev->timer, 2000 * TIMER_USEC);
val = pcnet_csr_readw(dev, dev->u32RAP);
if (dev->u32RAP == 0)
goto skip_update_irq;
@@ -3050,6 +3053,8 @@ pcnet_init(const device_t *info)
/* Attach ourselves to the network module. */
network_attach(dev, dev->aPROM, pcnetReceiveNoSync, pcnetWaitReceiveAvail, pcnetSetLinkState);
timer_add(&dev->timer, pcnetPollTimer, dev, 0);
if (dev->board == DEV_AM79C973)
timer_add(&dev->timer_soft_int, pcnetTimerSoftInt, dev, 0);

View File

@@ -372,11 +372,13 @@ esp_get_cmd(esp_t *dev, uint32_t maxlen)
if (dmalen == 0)
return 0;
if (dev->mca) {
dma_set_drq(dev->DmaChannel, 1);
while (dev->dma_86c01.pos < dmalen) {
int val = dma_channel_read(dev->DmaChannel);
buf[dev->dma_86c01.pos++] = val & 0xff;
}
dev->dma_86c01.pos = 0;
dma_set_drq(dev->DmaChannel, 0);
} else {
esp_pci_dma_memory_rw(dev, buf, dmalen, WRITE_TO_DEVICE);
dmalen = MIN(fifo8_num_free(&dev->cmdfifo), dmalen);
@@ -677,11 +679,13 @@ esp_do_dma(esp_t *dev, scsi_device_t *sd)
esp_log("ESP Command on DMA\n");
count = MIN(count, fifo8_num_free(&dev->cmdfifo));
if (dev->mca) {
dma_set_drq(dev->DmaChannel, 1);
while (dev->dma_86c01.pos < count) {
dma_channel_write(dev->DmaChannel, buf[dev->dma_86c01.pos]);
dev->dma_86c01.pos++;
}
dev->dma_86c01.pos = 0;
dma_set_drq(dev->DmaChannel, 0);
} else
esp_pci_dma_memory_rw(dev, buf, count, READ_FROM_DEVICE);
fifo8_push_all(&dev->cmdfifo, buf, count);
@@ -719,24 +723,28 @@ esp_do_dma(esp_t *dev, scsi_device_t *sd)
if (sd->phase == SCSI_PHASE_DATA_IN) {
esp_log("ESP SCSI Read, dma cnt = %i, ti size = %i, positive len = %i\n", esp_get_tc(dev), dev->ti_size, count);
if (dev->mca) {
dma_set_drq(dev->DmaChannel, 1);
while (dev->dma_86c01.pos < count) {
dma_channel_write(dev->DmaChannel, sd->sc->temp_buffer[dev->buffer_pos + dev->dma_86c01.pos]);
esp_log("ESP SCSI DMA read for 53C90: pos = %i, val = %02x\n", dev->dma_86c01.pos, sd->sc->temp_buffer[dev->buffer_pos + dev->dma_86c01.pos]);
dev->dma_86c01.pos++;
}
dev->dma_86c01.pos = 0;
dma_set_drq(dev->DmaChannel, 0);
} else {
esp_pci_dma_memory_rw(dev, sd->sc->temp_buffer + dev->buffer_pos, count, READ_FROM_DEVICE);
}
} else if (sd->phase == SCSI_PHASE_DATA_OUT) {
esp_log("ESP SCSI Write, negative len = %i, ti size = %i, dma cnt = %i\n", count, -dev->ti_size, esp_get_tc(dev));
if (dev->mca) {
dma_set_drq(dev->DmaChannel, 1);
while (dev->dma_86c01.pos < count) {
int val = dma_channel_read(dev->DmaChannel);
esp_log("ESP SCSI DMA write for 53C90: pos = %i, val = %02x\n", dev->dma_86c01.pos, val & 0xff);
sd->sc->temp_buffer[dev->buffer_pos + dev->dma_86c01.pos] = val & 0xff;
dev->dma_86c01.pos++;
}
dma_set_drq(dev->DmaChannel, 0);
dev->dma_86c01.pos = 0;
} else
esp_pci_dma_memory_rw(dev, sd->sc->temp_buffer + dev->buffer_pos, count, WRITE_TO_DEVICE);
@@ -922,11 +930,13 @@ esp_write_response(esp_t *dev)
if (dev->dma) {
if (dev->mca) {
dma_set_drq(dev->DmaChannel, 1);
while (dev->dma_86c01.pos < 2) {
int val = dma_channel_read(dev->DmaChannel);
buf[dev->dma_86c01.pos++] = val & 0xff;
}
dev->dma_86c01.pos = 0;
dma_set_drq(dev->DmaChannel, 0);
} else
esp_pci_dma_memory_rw(dev, buf, 2, WRITE_TO_DEVICE);
dev->rregs[ESP_RSTAT] = STAT_TC | STAT_ST;

View File

@@ -438,74 +438,67 @@ spock_process_imm_cmd(spock_t *scsi)
int i;
int adapter_id, phys_id, lun_id;
switch (scsi->command & CMD_MASK) {
case CMD_ASSIGN:
adapter_id = (scsi->command >> 16) & 15;
phys_id = (scsi->command >> 20) & 7;
lun_id = (scsi->command >> 24) & 7;
switch (scsi->command & CMD_MASK) {
case CMD_ASSIGN:
adapter_id = (scsi->command >> 16) & 15;
phys_id = (scsi->command >> 20) & 7;
lun_id = (scsi->command >> 24) & 7;
if (adapter_id == 15) {
if (phys_id == 7) /*Device 15 always adapter*/
spock_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE);
else /*Can not re-assign device 15 (always adapter)*/
spock_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_COMMAND_FAIL);
} else {
if (scsi->command & (1 << 23)) {
spock_log("Assign: adapter id=%d\n", adapter_id);
scsi->dev_id[adapter_id].phys_id = -1;
spock_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE);
} else {
if (phys_id != scsi->adapter_id) {
scsi->dev_id[adapter_id].phys_id = phys_id;
scsi->dev_id[adapter_id].lun_id = lun_id;
spock_log("Assign: adapter dev=%x scsi ID=%i LUN=%i\n", adapter_id, scsi->dev_id[adapter_id].phys_id, scsi->dev_id[adapter_id].lun_id);
spock_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE);
} else { /*Can not assign adapter*/
spock_log("Assign: PUN=%d, cannot assign adapter\n", phys_id);
spock_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_COMMAND_FAIL);
}
}
}
if (phys_id == 7) /*Device 15 always adapter*/
spock_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE);
else /*Can not re-assign device 15 (always adapter)*/
spock_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_COMMAND_FAIL);
} else {
if (scsi->command & (1 << 23)) {
spock_log("Assign: adapter id=%d\n", adapter_id);
scsi->dev_id[adapter_id].phys_id = -1;
spock_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE);
} else {
if (phys_id != scsi->adapter_id) {
scsi->dev_id[adapter_id].phys_id = phys_id;
scsi->dev_id[adapter_id].lun_id = lun_id;
spock_log("Assign: adapter dev=%x scsi ID=%i LUN=%i\n", adapter_id, scsi->dev_id[adapter_id].phys_id, scsi->dev_id[adapter_id].lun_id);
spock_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE);
} else { /*Can not assign adapter*/
spock_log("Assign: PUN=%d, cannot assign adapter\n", phys_id);
spock_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_COMMAND_FAIL);
}
}
}
break;
case CMD_DMA_PACING_CONTROL:
scsi->pacing = scsi->cir[2];
spock_log("Pacing control: %i\n", scsi->pacing);
spock_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE);
break;
scsi->pacing = scsi->cir[2];
spock_log("Pacing control: %i\n", scsi->pacing);
spock_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE);
break;
case CMD_FEATURE_CONTROL:
spock_log("Feature control: timeout=%is d-rate=%i\n", (scsi->command >> 16) & 0x1fff, scsi->command >> 29);
spock_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE);
break;
case CMD_INVALID_412:
spock_log("Invalid 412\n");
spock_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE);
break;
case CMD_RESET:
spock_log("Reset Command\n");
if ((scsi->attention & 0x0f) == 0x0f) { /*Adapter reset*/
for (i = 0; i < 8; i++)
scsi_device_reset(&scsi_devices[scsi->bus][i]);
spock_log("Adapter Reset\n");
case CMD_FEATURE_CONTROL:
spock_log("Feature control: timeout=%is d-rate=%i\n", (scsi->command >> 16) & 0x1fff, scsi->command >> 29);
spock_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE);
break;
if (!scsi->adapter_reset) /*The early 1990 bios must have its boot drive
set to ID 6 according https://www.ardent-tool.com/IBM_SCSI/SCSI-A.html */
scsi->adapter_reset = 1;
case CMD_INVALID_412:
spock_log("Invalid 412\n");
spock_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE);
break;
case CMD_RESET:
spock_log("Reset Command\n");
if ((scsi->attention & 0x0f) == 0x0f) { /*Adapter reset*/
for (i = 0; i < 8; i++)
scsi_device_reset(&scsi_devices[scsi->bus][i]);
spock_log("Adapter Reset\n");
if (!scsi->adapter_reset && scsi->bios_ver) /*The early 1990 bios must have its boot drive
set to ID 6 according https://www.ardent-tool.com/IBM_SCSI/SCSI-A.html */
scsi->adapter_reset = 1;
else
scsi->adapter_reset = 0;
scsi->scb_state = 0;
scsi->scb_state = 0;
}
spock_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE);
break;
spock_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE);
break;
default:
fatal("scsi_callback: Bad command %02x\n", scsi->command);
break;
}
default:
fatal("scsi_callback: Bad command %02x\n", scsi->command);
break;
}
}
static void
@@ -523,11 +516,11 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb)
for (c = 0; c < SCSI_ID_MAX; c++)
spock_clear_irq(scsi, c);
if (scsi->in_reset == 1) {
scsi->basic_ctrl |= CTRL_IRQ_ENA;
spock_set_irq(scsi, 0xf, IRQ_TYPE_RESET_COMPLETE);
} else
spock_set_irq(scsi, 0xf, IRQ_TYPE_RESET_COMPLETE);
if (scsi->in_reset == 1) {
scsi->basic_ctrl |= CTRL_IRQ_ENA;
spock_set_irq(scsi, 0x0f, IRQ_TYPE_RESET_COMPLETE);
} else
spock_set_irq(scsi, 0x0f, IRQ_TYPE_RESET_COMPLETE);
/*Reset device mappings*/
for (c = 0; c < 7; c++) {
@@ -559,17 +552,17 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb)
break;
case 1: /* Select */
if (scsi->dev_id[scsi->scb_id].phys_id == -1) {
uint16_t term_stat_block_addr7 = (0xe << 8) | 0;
uint16_t term_stat_block_addr8 = (0xa << 8) | 0;
if (scsi->dev_id[scsi->scb_id].phys_id == -1) {
uint16_t term_stat_block_addr7 = (0xe << 8) | 0;
uint16_t term_stat_block_addr8 = (0xa << 8) | 0;
spock_log("Start failed, SCB ID = %d\n", scsi->scb_id);
spock_set_irq(scsi, scsi->scb_id, IRQ_TYPE_COMMAND_FAIL);
scsi->scb_state = 0;
dma_bm_write(scb->term_status_block_addr + 0x7*2, (uint8_t *)&term_stat_block_addr7, 2, 2);
dma_bm_write(scb->term_status_block_addr + 0x8*2, (uint8_t *)&term_stat_block_addr8, 2, 2);
break;
}
spock_log("Start failed, SCB ID = %d\n", scsi->scb_id);
spock_set_irq(scsi, scsi->scb_id, IRQ_TYPE_COMMAND_FAIL);
scsi->scb_state = 0;
dma_bm_write(scb->term_status_block_addr + 0x7*2, (uint8_t *)&term_stat_block_addr7, 2, 2);
dma_bm_write(scb->term_status_block_addr + 0x8*2, (uint8_t *)&term_stat_block_addr8, 2, 2);
break;
}
dma_bm_read(scsi->scb_addr, (uint8_t *)&scb->command, 2, 2);
dma_bm_read(scsi->scb_addr + 2, (uint8_t *)&scb->enable, 2, 2);
@@ -591,11 +584,11 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb)
" SCB chain address = %08x\n"
" Block count = %04x\n"
" Block length = %04x\n"
" SCB id = %d\n",
" SCB id = %d, Phys id = %d\n",
scb->command, scb->enable, scb->lba_addr,
scb->sge.sys_buf_addr, scb->sge.sys_buf_byte_count,
scb->term_status_block_addr, scb->scb_chain_addr,
scb->block_count, scb->block_length, scsi->scb_id);
scb->block_count, scb->block_length, scsi->scb_id, scsi->dev_id[scsi->scb_id].phys_id);
switch (scb->command & CMD_MASK) {
case CMD_GET_COMPLETE_STATUS:
@@ -669,11 +662,10 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb)
break;
case CMD_DEVICE_INQUIRY:
if (scsi->adapter_reset) {
scsi->cdb_id = scsi->scb_id;
} else {
scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id;
}
if (scb->command != CMD_DEVICE_INQUIRY)
scsi->cdb_id = scsi->scb_id;
else
scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id;
spock_log("Device Inquiry, ID=%d\n", scsi->cdb_id);
scsi->cdb[0] = GPCMD_INQUIRY;
scsi->cdb[1] = scsi->dev_id[scsi->scb_id].lun_id << 5; /*LUN*/
@@ -689,12 +681,11 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb)
return;
case CMD_SEND_OTHER_SCSI:
if (scsi->adapter_reset) {
scsi->cdb_id = scsi->scb_id;
} else {
scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id;
}
spock_log("Send Other SCSI, ID=%d\n", scsi->cdb_id);
if (scb->command != CMD_SEND_OTHER_SCSI)
scsi->cdb_id = scsi->scb_id;
else
scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id;
spock_log("Send Other SCSI, SCB ID=%d, PHYS ID=%d, reset=%d\n", scsi->scb_id, scsi->dev_id[scsi->scb_id].phys_id, scsi->adapter_reset);
dma_bm_read(scsi->scb_addr + 0x18, scsi->cdb, 12, 2);
scsi->cdb[1] = (scsi->cdb[1] & 0x1f) | (scsi->dev_id[scsi->scb_id].lun_id << 5); /*Patch correct LUN into command*/
scsi->cdb_len = (scb->lba_addr & 0xff) ? (scb->lba_addr & 0xff) : 6;
@@ -703,11 +694,11 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb)
return;
case CMD_READ_DEVICE_CAPACITY:
if (scsi->adapter_reset)
scsi->cdb_id = scsi->scb_id;
else
scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id;
spock_log("Device Capacity, ID=%d\n", scsi->cdb_id);
if (scb->command != CMD_READ_DEVICE_CAPACITY)
scsi->cdb_id = scsi->scb_id;
else
scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id;
spock_log("Device Capacity, SCB ID=%d, PHYS ID=%d, reset=%d\n", scsi->scb_id, scsi->dev_id[scsi->scb_id].phys_id, scsi->adapter_reset);
scsi->cdb[0] = GPCMD_READ_CDROM_CAPACITY;
scsi->cdb[1] = scsi->dev_id[scsi->scb_id].lun_id << 5; /*LUN*/
scsi->cdb[2] = 0; /*LBA*/
@@ -724,7 +715,11 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb)
return;
case CMD_READ_DATA:
spock_log("Device Read Data\n");
if (scb->command != CMD_READ_DATA)
scsi->cdb_id = scsi->scb_id;
else
scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id;
spock_log("Device Read Data, SCB ID=%d, PHYS ID=%d, reset=%d\n", scsi->scb_id, scsi->dev_id[scsi->scb_id].phys_id, scsi->adapter_reset);
scsi->cdb[0] = GPCMD_READ_10;
scsi->cdb[1] = scsi->dev_id[scsi->scb_id].lun_id << 5; /*LUN*/
scsi->cdb[2] = (scb->lba_addr >> 24) & 0xff; /*LBA*/
@@ -736,12 +731,15 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb)
scsi->cdb[8] = scb->block_count & 0xff;
scsi->cdb[9] = 0; /*Control*/
scsi->cdb_len = 10;
scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id;
scsi->scsi_state = SCSI_STATE_SELECT;
scsi->scb_state = 2;
return;
case CMD_WRITE_DATA:
if (scb->command != CMD_WRITE_DATA)
scsi->cdb_id = scsi->scb_id;
else
scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id;
spock_log("Device Write Data\n");
scsi->cdb[0] = GPCMD_WRITE_10;
scsi->cdb[1] = scsi->dev_id[scsi->scb_id].lun_id << 5; /*LUN*/
@@ -754,12 +752,15 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb)
scsi->cdb[8] = scb->block_count & 0xff;
scsi->cdb[9] = 0; /*Control*/
scsi->cdb_len = 10;
scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id;
scsi->scsi_state = SCSI_STATE_SELECT;
scsi->scb_state = 2;
return;
case CMD_VERIFY:
if (scb->command != CMD_VERIFY)
scsi->cdb_id = scsi->scb_id;
else
scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id;
spock_log("Device Verify\n");
scsi->cdb[0] = GPCMD_VERIFY_10;
scsi->cdb[1] = scsi->dev_id[scsi->scb_id].lun_id << 5; /*LUN*/
@@ -772,17 +773,16 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb)
scsi->cdb[8] = scb->block_count & 0xff;
scsi->cdb[9] = 0; /*Control*/
scsi->cdb_len = 10;
scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id;
scsi->data_len = 0;
scsi->scsi_state = SCSI_STATE_SELECT;
scsi->scb_state = 2;
return;
case CMD_REQUEST_SENSE:
if (scsi->adapter_reset)
scsi->cdb_id = scsi->scb_id;
else
scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id;
if (scb->command != CMD_REQUEST_SENSE)
scsi->cdb_id = scsi->scb_id;
else
scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id;
spock_log("Device Request Sense, ID=%d\n", scsi->cdb_id);
scsi->cdb[0] = GPCMD_REQUEST_SENSE;
scsi->cdb[1] = scsi->dev_id[scsi->scb_id].lun_id << 5; /*LUN*/
@@ -798,32 +798,35 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb)
break;
case 2: /* Wait */
if (scsi->scsi_state == SCSI_STATE_IDLE && scsi_device_present(&scsi_devices[scsi->bus][scsi->cdb_id])) {
if (scsi->last_status == SCSI_STATUS_OK) {
scsi->scb_state = 3;
spock_log("Status is Good on device ID %d, timer = %i\n", scsi->cdb_id, scsi->cmd_timer);
} else if (scsi->last_status == SCSI_STATUS_CHECK_CONDITION) {
uint16_t term_stat_block_addr7 = (0xc << 8) | 2;
uint16_t term_stat_block_addr8 = 0x20;
uint16_t term_stat_block_addrb = scsi->scb_addr & 0xffff;
uint16_t term_stat_block_addrc = scsi->scb_addr >> 16;
if (scsi->scsi_state == SCSI_STATE_IDLE) {
if (scsi_device_present(&scsi_devices[scsi->bus][scsi->cdb_id])) {
if (scsi->last_status == SCSI_STATUS_OK) {
scsi->scb_state = 3;
spock_log("Status is Good on device ID %d, reset = %d\n", scsi->scb_id, scsi->adapter_reset);
} else if (scsi->last_status == SCSI_STATUS_CHECK_CONDITION) {
uint16_t term_stat_block_addr7 = (0xc << 8) | 2;
uint16_t term_stat_block_addr8 = 0x20;
uint16_t term_stat_block_addrb = scsi->scb_addr & 0xffff;
uint16_t term_stat_block_addrc = scsi->scb_addr >> 16;
spock_set_irq(scsi, scsi->scb_id, IRQ_TYPE_COMMAND_FAIL);
scsi->scb_state = 0;
spock_log("Status Check Condition on device ID %d\n", scsi->cdb_id);
dma_bm_write(scb->term_status_block_addr + 0x7*2, (uint8_t *)&term_stat_block_addr7, 2, 2);
dma_bm_write(scb->term_status_block_addr + 0x8*2, (uint8_t *)&term_stat_block_addr8, 2, 2);
dma_bm_write(scb->term_status_block_addr + 0xb*2, (uint8_t *)&term_stat_block_addrb, 2, 2);
dma_bm_write(scb->term_status_block_addr + 0xc*2, (uint8_t *)&term_stat_block_addrc, 2, 2);
}
} else if (scsi->scsi_state == SCSI_STATE_IDLE && !scsi_device_present(&scsi_devices[scsi->bus][scsi->cdb_id])) {
uint16_t term_stat_block_addr7 = (0xc << 8) | 2;
uint16_t term_stat_block_addr8 = 0x10;
spock_set_irq(scsi, scsi->scb_id, IRQ_TYPE_COMMAND_FAIL);
scsi->scb_state = 0;
dma_bm_write(scb->term_status_block_addr + 0x7*2, (uint8_t *)&term_stat_block_addr7, 2, 2);
dma_bm_write(scb->term_status_block_addr + 0x8*2, (uint8_t *)&term_stat_block_addr8, 2, 2);
}
spock_set_irq(scsi, scsi->scb_id, IRQ_TYPE_COMMAND_FAIL);
scsi->scb_state = 0;
spock_log("Status Check Condition on device ID %d, reset = %d\n", scsi->scb_id, scsi->adapter_reset);
dma_bm_write(scb->term_status_block_addr + 0x7*2, (uint8_t *)&term_stat_block_addr7, 2, 2);
dma_bm_write(scb->term_status_block_addr + 0x8*2, (uint8_t *)&term_stat_block_addr8, 2, 2);
dma_bm_write(scb->term_status_block_addr + 0xb*2, (uint8_t *)&term_stat_block_addrb, 2, 2);
dma_bm_write(scb->term_status_block_addr + 0xc*2, (uint8_t *)&term_stat_block_addrc, 2, 2);
}
} else {
uint16_t term_stat_block_addr7 = (0xc << 8) | 2;
uint16_t term_stat_block_addr8 = 0x10;
spock_set_irq(scsi, scsi->scb_id, IRQ_TYPE_COMMAND_FAIL);
scsi->scb_state = 0;
spock_log("Status Check Condition on device ID %d on no device, reset = %d\n", scsi->scb_id, scsi->adapter_reset);
dma_bm_write(scb->term_status_block_addr + 0x7*2, (uint8_t *)&term_stat_block_addr7, 2, 2);
dma_bm_write(scb->term_status_block_addr + 0x8*2, (uint8_t *)&term_stat_block_addr8, 2, 2);
}
}
break;
case 3: /* Complete */
@@ -1104,30 +1107,29 @@ spock_init(const device_t *info)
scsi->bios_ver = device_get_config_int("bios_ver");
switch (scsi->bios_ver) {
switch (scsi->bios_ver) {
case 1:
rom_init_interleaved(&scsi->bios_rom, SPOCK_U68_1991_ROM, SPOCK_U69_1991_ROM,
0xc8000, 0x8000, 0x7fff, 0x4000, MEM_MAPPING_EXTERNAL);
break;
rom_init_interleaved(&scsi->bios_rom, SPOCK_U68_1991_ROM, SPOCK_U69_1991_ROM,
0xc8000, 0x8000, 0x7fff, 0x4000, MEM_MAPPING_EXTERNAL);
break;
case 0:
rom_init_interleaved(&scsi->bios_rom, SPOCK_U68_1990_ROM, SPOCK_U69_1990_ROM,
0xc8000, 0x8000, 0x7fff, 0x4000, MEM_MAPPING_EXTERNAL);
break;
}
rom_init_interleaved(&scsi->bios_rom, SPOCK_U68_1990_ROM, SPOCK_U69_1990_ROM,
0xc8000, 0x8000, 0x7fff, 0x4000, MEM_MAPPING_EXTERNAL);
break;
}
mem_mapping_disable(&scsi->bios_rom.mapping);
mem_mapping_disable(&scsi->bios_rom.mapping);
scsi->pos_regs[0] = 0xff;
scsi->pos_regs[1] = 0x8e;
scsi->pos_regs[0] = 0xff;
scsi->pos_regs[1] = 0x8e;
mca_add(spock_mca_read, spock_mca_write, spock_mca_feedb, spock_mca_reset, scsi);
scsi->in_reset = 2;
scsi->cmd_timer = SPOCK_TIME * 50;
scsi->status = STATUS_BUSY;
for (c = 0; c < (SCSI_ID_MAX-1); c++) {
scsi->dev_id[c].phys_id = -1;
}
for (c = 0; c < (SCSI_ID_MAX-1); c++) {
scsi->dev_id[c].phys_id = -1;
}
scsi->dev_id[SCSI_ID_MAX-1].phys_id = scsi->adapter_id;
@@ -1141,7 +1143,7 @@ spock_init(const device_t *info)
static void
spock_close(void *p)
{
spock_t *scsi = (spock_t *)p;
spock_t *scsi = (spock_t *)p;
if (scsi) {
free(scsi);