summaryrefslogtreecommitdiff
path: root/src/dev
diff options
context:
space:
mode:
Diffstat (limited to 'src/dev')
-rw-r--r--src/dev/io_device.cc27
-rw-r--r--src/dev/io_device.hh35
2 files changed, 36 insertions, 26 deletions
diff --git a/src/dev/io_device.cc b/src/dev/io_device.cc
index 485216874..e769ef037 100644
--- a/src/dev/io_device.cc
+++ b/src/dev/io_device.cc
@@ -62,13 +62,14 @@ PioPort::getDeviceAddressRanges(AddrRangeList &resp, AddrRangeList &snoop)
void
PioPort::recvRetry()
{
- Packet* pkt = transmitList.front();
- if (Port::sendTiming(pkt)) {
- transmitList.pop_front();
+ bool result = true;
+ while (result && transmitList.size()) {
+ result = Port::sendTiming(transmitList.front());
+ if (result)
+ transmitList.pop_front();
}
}
-
void
PioPort::SendEvent::process()
{
@@ -83,10 +84,20 @@ PioPort::SendEvent::process()
bool
PioPort::recvTiming(Packet *pkt)
{
- Tick latency = device->recvAtomic(pkt);
- // turn packet around to go back to requester
- pkt->makeTimingResponse();
- sendTiming(pkt, latency);
+ if (pkt->result == Packet::Nacked) {
+ pkt->reinitNacked();
+ if (transmitList.size()) {
+ transmitList.push_front(pkt);
+ } else {
+ if (!Port::sendTiming(pkt))
+ transmitList.push_front(pkt);
+ }
+ } else {
+ Tick latency = device->recvAtomic(pkt);
+ // turn packet around to go back to requester
+ pkt->makeTimingResponse();
+ sendTiming(pkt, latency);
+ }
return true;
}
diff --git a/src/dev/io_device.hh b/src/dev/io_device.hh
index cd2c25eeb..a2b61c7f4 100644
--- a/src/dev/io_device.hh
+++ b/src/dev/io_device.hh
@@ -119,30 +119,29 @@ class PioPort : public Port
};
-struct DmaReqState : public Packet::SenderState
+class DmaPort : public Port
{
- /** Event to call on the device when this transaction (all packets)
- * complete. */
- Event *completionEvent;
+ protected:
+ struct DmaReqState : public Packet::SenderState
+ {
+ /** Event to call on the device when this transaction (all packets)
+ * complete. */
+ Event *completionEvent;
- /** Where we came from for some sanity checking. */
- Port *outPort;
+ /** Where we came from for some sanity checking. */
+ Port *outPort;
- /** Total number of bytes that this transaction involves. */
- Addr totBytes;
+ /** Total number of bytes that this transaction involves. */
+ Addr totBytes;
- /** Number of bytes that have been acked for this transaction. */
- Addr numBytes;
+ /** Number of bytes that have been acked for this transaction. */
+ Addr numBytes;
- bool final;
- DmaReqState(Event *ce, Port *p, Addr tb)
- : completionEvent(ce), outPort(p), totBytes(tb), numBytes(0)
- {}
-};
+ DmaReqState(Event *ce, Port *p, Addr tb)
+ : completionEvent(ce), outPort(p), totBytes(tb), numBytes(0)
+ {}
+ };
-class DmaPort : public Port
-{
- protected:
DmaDevice *device;
std::list<Packet*> transmitList;