[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[qemu-xen stable-4.19] hw/ide/ahci: fix ahci_write_fis_sdb()



commit 9c7e2253eba2e057f11377beb64dd78d12a1e27d
Author:     Niklas Cassel <niklas.cassel@xxxxxxx>
AuthorDate: Fri Jun 9 16:08:43 2023 +0200
Commit:     Michael Tokarev <mjt@xxxxxxxxxx>
CommitDate: Sun Sep 10 19:40:11 2023 +0300

    hw/ide/ahci: fix ahci_write_fis_sdb()
    
    When there is an error, we need to raise a TFES error irq, see AHCI 1.3.1,
    5.3.13.1 SDB:Entry.
    
    If ERR_STAT is set, we jump to state ERR:FatalTaskfile, which will raise
    a TFES IRQ unconditionally, regardless if the I bit is set in the FIS or
    not.
    
    Thus, we should never raise a normal IRQ after having sent an error IRQ.
    
    It is valid to signal successfully completed commands as finished in the
    same SDB FIS that generates the error IRQ. The important thing is that
    commands that did not complete successfully (e.g. commands that were
    aborted, do not get the finished bit set).
    
    Before this commit, there was never a TFES IRQ raised on NCQ error.
    
    Signed-off-by: Niklas Cassel <niklas.cassel@xxxxxxx>
    Reviewed-by: Philippe Mathieu-Daudé <philmd@xxxxxxxxxx>
    Message-id: 20230609140844.202795-8-nks@xxxxxxxxxxx
    Signed-off-by: John Snow <jsnow@xxxxxxxxxx>
    (cherry picked from commit 7e85cb0db4c693b4e084a00e66fe73a22ed1688a)
    Signed-off-by: Michael Tokarev <mjt@xxxxxxxxxx>
---
 hw/ide/ahci.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
index a7b487ff33..8ce3dd796e 100644
--- a/hw/ide/ahci.c
+++ b/hw/ide/ahci.c
@@ -806,8 +806,14 @@ static void ahci_write_fis_sdb(AHCIState *s, 
NCQTransferState *ncq_tfs)
     pr->scr_act &= ~ad->finished;
     ad->finished = 0;
 
-    /* Trigger IRQ if interrupt bit is set (which currently, it always is) */
-    if (sdb_fis->flags & 0x40) {
+    /*
+     * TFES IRQ is always raised if ERR_STAT is set, regardless of I bit.
+     * If ERR_STAT is not set, trigger SDBS IRQ if interrupt bit is set
+     * (which currently, it always is).
+     */
+    if (sdb_fis->status & ERR_STAT) {
+        ahci_trigger_irq(s, ad, AHCI_PORT_IRQ_BIT_TFES);
+    } else if (sdb_fis->flags & 0x40) {
         ahci_trigger_irq(s, ad, AHCI_PORT_IRQ_BIT_SDBS);
     }
 }
--
generated by git-patchbot for /home/xen/git/qemu-xen.git#stable-4.19



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.