sc53c94: return actual number of bytes transferred

in xfer_to and xfer_from methods.
This commit is contained in:
Maxim Poliakovski
2025-03-31 15:22:24 +02:00
parent ba030abb3b
commit c742beb623
2 changed files with 21 additions and 12 deletions

View File

@@ -427,7 +427,8 @@ void DMAChannel::xfer_from_device() {
this->xfer_dir = DMA_DIR_FROM_DEV;
if (!this->dev_obj->xfer_from(this->queue_data, this->queue_len)) {
int got_bytes = this->dev_obj->xfer_from(this->queue_data, this->queue_len);
if (got_bytes == this->queue_len) {
this->queue_len = 0;
this->finish_cmd();
}
@@ -441,7 +442,8 @@ void DMAChannel::xfer_to_device() {
this->xfer_dir = DMA_DIR_TO_DEV;
if (!this->dev_obj->xfer_to(this->queue_data, this->queue_len)) {
int got_bytes = this->dev_obj->xfer_to(this->queue_data, this->queue_len);
if (got_bytes == this->queue_len) {
this->queue_len = 0;
this->finish_cmd();
}

View File

@@ -783,48 +783,53 @@ void Sc53C94::dma_stop()
}
int Sc53C94::xfer_from(uint8_t *buf, int len) {
int bytes_moved = 0;
if (this->cur_cmd != CMD_XFER || !this->is_dma_cmd ||
this->cur_bus_phase != ScsiPhase::DATA_IN) {
LOG_F(9, "%s: ignoring DMA data transfer request", this->name.c_str());
return len;
return bytes_moved;
}
if (len > this->xfer_count + this->data_fifo_pos)
LOG_F(WARNING, "%s: DMA xfer len > command xfer len", this->name.c_str());
len = std::min(len, (int)(this->xfer_count));
if (this->data_fifo_pos) {
int fifo_bytes = std::min(this->data_fifo_pos, len);
std::memcpy(buf, this->data_fifo, fifo_bytes);
this->data_fifo_pos -= fifo_bytes;
this->xfer_count -= fifo_bytes;
bytes_moved += fifo_bytes;
len -= fifo_bytes;
buf += fifo_bytes;
if (!this->xfer_count) {
this->status |= STAT_TC; // signal zero transfer count
this->cur_state = SeqState::XFER_END;
this->sequencer();
return 0;
return bytes_moved;
}
}
if (this->bus_obj->pull_data(this->target_id, buf, this->xfer_count)) {
bytes_moved += this->xfer_count;
this->xfer_count = 0;
this->status |= STAT_TC; // signal zero transfer count
this->cur_state = SeqState::XFER_END;
this->sequencer();
return 0;
}
return len;
return bytes_moved;
}
int Sc53C94::xfer_to(uint8_t *buf, int len) {
if (!this->xfer_count || this->cur_cmd != CMD_XFER || !this->is_dma_cmd ||
this->cur_bus_phase != ScsiPhase::DATA_OUT) {
int bytes_moved = 0;
if (!this->xfer_count || !this->is_dma_cmd) {
LOG_F(9, "%s: ignoring DMA data transfer request", this->name.c_str());
return len;
return bytes_moved;
}
len = std::min(len, (int)(this->xfer_count));
// Being in the DATA_OUT phase means that we're about to move
// a big chunk of data. The real device uses its FIFO as buffer.
// For simplicity, the code below transfers the whole chunk at once.
@@ -832,6 +837,7 @@ int Sc53C94::xfer_to(uint8_t *buf, int len) {
if (this->cur_bus_phase == ScsiPhase::DATA_OUT) {
if (this->bus_obj->push_data(this->target_id, buf, len)) {
this->xfer_count -= len;
bytes_moved += len;
if (!this->xfer_count) {
this->status |= STAT_TC; // signal zero transfer count
this->cur_state = SeqState::XFER_END;
@@ -849,13 +855,14 @@ int Sc53C94::xfer_to(uint8_t *buf, int len) {
len -= fifo_bytes;
this->data_fifo_pos += fifo_bytes;
this->xfer_count -= fifo_bytes;
bytes_moved += fifo_bytes;
if (!this->xfer_count) {
this->status |= STAT_TC; // signal zero transfer count
this->sequencer();
}
}
return len;
return bytes_moved;
}
static const PropMap Sc53C94_properties = {