| 503 | } |
| 504 | |
| 505 | void ScsiController::Receive() |
| 506 | { |
| 507 | assert(!GetBus().GetREQ()); |
| 508 | assert(!GetBus().GetIO()); |
| 509 | |
| 510 | if (HasValidLength()) { |
| 511 | LogTrace("Receiving data, transfer length: " + to_string(GetLength()) + " byte(s)"); |
| 512 | |
| 513 | // If not able to receive all, move to status phase |
| 514 | if (uint32_t len = GetBus().ReceiveHandShake(GetBuffer().data() + GetOffset(), GetLength()); len != GetLength()) { |
| 515 | LogError("Not able to receive " + to_string(GetLength()) + " byte(s) of data, only received " |
| 516 | + to_string(len)); |
| 517 | Error(sense_key::aborted_command); |
| 518 | return; |
| 519 | } |
| 520 | } |
| 521 | |
| 522 | if (IsByteTransfer()) { |
| 523 | ReceiveBytes(); |
| 524 | return; |
| 525 | } |
| 526 | |
| 527 | if (HasValidLength()) { |
| 528 | UpdateOffsetAndLength(); |
| 529 | return; |
| 530 | } |
| 531 | |
| 532 | DecrementBlocks(); |
| 533 | bool result = true; |
| 534 | |
| 535 | // Processing after receiving data (by phase) |
| 536 | LogTrace("Phase: " + string(BUS::GetPhaseStrRaw(GetPhase()))); |
| 537 | switch (GetPhase()) { |
| 538 | case phase_t::dataout: |
| 539 | if (!HasBlocks()) { |
| 540 | // End with this buffer |
| 541 | result = XferOut(false); |
| 542 | } else { |
| 543 | // Continue to next buffer (set offset, length) |
| 544 | result = XferOut(true); |
| 545 | } |
| 546 | break; |
| 547 | |
| 548 | case phase_t::msgout: |
| 549 | SetMessage(GetBuffer()[0]); |
| 550 | if (!XferMsg(GetMessage())) { |
| 551 | // Immediately free the bus if message output fails |
| 552 | BusFree(); |
| 553 | return; |
| 554 | } |
| 555 | |
| 556 | // Clear message data in preparation for message-in |
| 557 | SetMessage(0x00); |
| 558 | break; |
| 559 | |
| 560 | default: |
| 561 | break; |
| 562 | } |
nothing calls this directly
no test coverage detected