When reading a completion record, avoid a race with the device. If the
host starts to read the completion record and then the device updates it
while we're reading it, we can have the early part of the record be old
and the later part of the record be new. This leads us to mistakenly
think that the record is in phase and we use the old values and look
at an already completed entry, which has no current tracker.
To work around this problem, we atomically read the status with acquire
semantics. If it's in phase, we then re-read the entire completion
record. In addition we resync the dmatag to reflect changes since the
prior loop for the bouncing dma case.
Found by: jrtc27 (this fix is based in part on her D30995 fix)
Sponsored by: Netflix