Merge pull request #2517 from 86Box/pcnetfix
Networking: moved the pcnetPollTimer calls to a timer.
This commit is contained in:
@@ -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);
|
||||
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
|
Reference in New Issue
Block a user