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, after the first read, 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