mirror of
https://github.com/dingusdev/dingusppc.git
synced 2025-08-06 10:25:27 +00:00
sc53c94: return actual number of bytes transferred
in xfer_to and xfer_from methods.
This commit is contained in:
@@ -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();
|
||||
}
|
||||
|
@@ -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 = {
|
||||
|
Reference in New Issue
Block a user