typedef struct lsi_request {
uint32_t tag;
SCSIDevice *dev;
+ uint32_t dma_len;
+ uint8_t *dma_buf;
uint32_t pending;
int out;
QTAILQ_ENTRY(lsi_request) next;
int current_lun;
/* The tag is a combination of the device ID and the SCSI tag. */
uint32_t select_tag;
- uint32_t current_dma_len;
int command_complete;
- uint8_t *dma_buf;
QTAILQ_HEAD(, lsi_request) queue;
lsi_request *current;
uint32_t count;
target_phys_addr_t addr;
- if (!s->current_dma_len) {
+ assert(s->current);
+ if (!s->current->dma_len) {
/* Wait until data is available. */
DPRINTF("DMA no data available\n");
return;
}
count = s->dbc;
- if (count > s->current_dma_len)
- count = s->current_dma_len;
+ if (count > s->current->dma_len)
+ count = s->current->dma_len;
addr = s->dnad;
/* both 40 and Table Indirect 64-bit DMAs store upper bits in dnad64 */
s->dnad += count;
s->dbc -= count;
- if (s->dma_buf == NULL) {
- s->dma_buf = s->current->dev->info->get_buf(s->current->dev,
- s->current->tag);
+ if (s->current->dma_buf == NULL) {
+ s->current->dma_buf = s->current->dev->info->get_buf(s->current->dev,
+ s->current->tag);
}
/* ??? Set SFBR to first data byte. */
if (out) {
- cpu_physical_memory_read(addr, s->dma_buf, count);
+ cpu_physical_memory_read(addr, s->current->dma_buf, count);
} else {
- cpu_physical_memory_write(addr, s->dma_buf, count);
+ cpu_physical_memory_write(addr, s->current->dma_buf, count);
}
- s->current_dma_len -= count;
- if (s->current_dma_len == 0) {
- s->dma_buf = NULL;
+ s->current->dma_len -= count;
+ if (s->current->dma_len == 0) {
+ s->current->dma_buf = NULL;
if (out) {
/* Write the data. */
s->current->dev->info->write_data(s->current->dev, s->current->tag);
s->current->dev->info->read_data(s->current->dev, s->current->tag);
}
} else {
- s->dma_buf += count;
+ s->current->dma_buf += count;
lsi_resume_script(s);
}
}
DPRINTF("Queueing tag=0x%x\n", s->current_tag);
assert(s->current != NULL);
+ assert(s->current->dma_len == 0);
QTAILQ_INSERT_TAIL(&s->queue, s->current, next);
s->current = NULL;
s->scntl1 |= LSI_SCNTL1_CON;
lsi_set_phase(s, PHASE_MI);
s->msg_action = p->out ? 2 : 3;
- s->current_dma_len = p->pending;
- s->dma_buf = NULL;
+ s->current->dma_len = p->pending;
lsi_add_msg_byte(s, 0x80);
if (s->current->tag & LSI_TAG_VALID) {
lsi_add_msg_byte(s, 0x20);
/* host adapter (re)connected */
DPRINTF("Data ready tag=0x%x len=%d\n", tag, arg);
- s->current_dma_len = arg;
+ s->current->dma_len = arg;
s->command_complete = 1;
if (!s->waiting)
return;
lsi_request *p;
DPRINTF("Wait Reselect\n");
- if (s->current_dma_len)
- BADF("Reselect with pending DMA\n");
QTAILQ_FOREACH(p, &s->queue, next) {
if (p->pending) {
break;
}
}
- if (s->current_dma_len == 0) {
+ if (s->current == NULL) {
s->waiting = 1;
}
}
{
LSIState *s = opaque;
- assert(s->dma_buf == NULL);
- assert(s->current_dma_len == 0);
+ if (s->current) {
+ assert(s->current->dma_buf == NULL);
+ assert(s->current->dma_len == 0);
+ }
assert(QTAILQ_EMPTY(&s->queue));
}