diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c index 954386a2b500..96bef8007856 100644 --- a/drivers/ata/libahci.c +++ b/drivers/ata/libahci.c @@ -2071,6 +2071,20 @@ static bool ahci_qc_fill_rtf(struct ata_queued_cmd *qc) !(qc->flags & ATA_QCFLAG_FAILED)) { ata_tf_from_fis(rx_fis + RX_FIS_PIO_SETUP, &qc->result_tf); qc->result_tf.status = (rx_fis + RX_FIS_PIO_SETUP)[15]; + + /* + * For NCQ commands, we never get a D2H FIS, so reading the D2H Register + * FIS area of the Received FIS Structure (which contains a copy of the + * last D2H FIS received) will contain an outdated status code. + * For NCQ commands, we instead get a SDB FIS, so read the SDB FIS area + * instead. However, the SDB FIS does not contain the LBA, so we can't + * use the ata_tf_from_fis() helper. + */ + } else if (ata_is_ncq(qc->tf.protocol)) { + const u8 *fis = rx_fis + RX_FIS_SDB; + + qc->result_tf.status = fis[2]; + qc->result_tf.error = fis[3]; } else ata_tf_from_fis(rx_fis + RX_FIS_D2H_REG, &qc->result_tf);