Revision tags: v9.1.0 |
|
#
2f73edac |
| 27-Feb-2024 |
BALATON Zoltan <balaton@eik.bme.hu> |
hw/ide/ahci: Rename ahci_internal.h to ahci-internal.h
Other headers now use dash instead of underscore. Rename ahci_internal.h accordingly for consistency.
Signed-off-by: BALATON Zoltan <balaton@e
hw/ide/ahci: Rename ahci_internal.h to ahci-internal.h
Other headers now use dash instead of underscore. Rename ahci_internal.h accordingly for consistency.
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu> Reviewed-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Thomas Huth <thuth@redhat.com> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Message-ID: <20240227131310.C24EB4E6005@zero.eik.bme.hu> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
show more ...
|
#
0316482e |
| 25-Feb-2024 |
Philippe Mathieu-Daudé <philmd@linaro.org> |
hw/ide: Include 'ide-internal.h' from current path
Rename "internal.h" as "ide-internal.h", and include it via its relative local path, instead of absolute to the project root path.
Signed-off-by:
hw/ide: Include 'ide-internal.h' from current path
Rename "internal.h" as "ide-internal.h", and include it via its relative local path, instead of absolute to the project root path.
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> Message-Id: <20240226080632.9596-4-philmd@linaro.org>
show more ...
|
#
fbb5945e |
| 12-Feb-2024 |
Philippe Mathieu-Daudé <philmd@linaro.org> |
hw/ide/ahci: Move SysBus definitions to 'ahci-sysbus.h'
Keep "hw/ide/ahci.h" AHCI-generic.
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> Reviewed-by: Leif Lindholm <quic_llindhol@quicin
hw/ide/ahci: Move SysBus definitions to 'ahci-sysbus.h'
Keep "hw/ide/ahci.h" AHCI-generic.
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> Reviewed-by: Leif Lindholm <quic_llindhol@quicinc.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Message-Id: <20240213081201.78951-10-philmd@linaro.org>
show more ...
|
#
b0bccc6a |
| 12-Feb-2024 |
Philippe Mathieu-Daudé <philmd@linaro.org> |
hw/ide/ahci: Remove SysbusAHCIState::num_ports field
No need to duplicate AHCIState::ports, directly access it.
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> Reviewed-by: Michael S. Tsi
hw/ide/ahci: Remove SysbusAHCIState::num_ports field
No need to duplicate AHCIState::ports, directly access it.
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-Id: <20240213081201.78951-9-philmd@linaro.org>
show more ...
|
#
be021501 |
| 12-Feb-2024 |
Philippe Mathieu-Daudé <philmd@linaro.org> |
hw/ide/ahci: Do not pass 'ports' argument to ahci_realize()
Explicitly set AHCIState::ports before calling ahci_realize().
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> Reviewed-by: Mic
hw/ide/ahci: Do not pass 'ports' argument to ahci_realize()
Explicitly set AHCIState::ports before calling ahci_realize().
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-Id: <20240213081201.78951-8-philmd@linaro.org>
show more ...
|
#
44c11b2e |
| 12-Feb-2024 |
Philippe Mathieu-Daudé <philmd@linaro.org> |
hw/ide/ahci: Convert AHCIState::ports to unsigned
AHCIState::ports should be unsigned. Besides, we never check it for negative value. It is unlikely it was ever used with more than INT32_MAX ports,
hw/ide/ahci: Convert AHCIState::ports to unsigned
AHCIState::ports should be unsigned. Besides, we never check it for negative value. It is unlikely it was ever used with more than INT32_MAX ports, so it is safe to convert it to unsigned.
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-Id: <20240213081201.78951-7-philmd@linaro.org>
show more ...
|
#
e2f8d280 |
| 13-Feb-2024 |
Philippe Mathieu-Daudé <philmd@linaro.org> |
hw/ide/ahci: Pass AHCI context to ahci_ide_create_devs()
Since ahci_ide_create_devs() is not PCI specific, pass it an AHCIState argument instead of PCIDevice.
Signed-off-by: Philippe Mathieu-Daudé
hw/ide/ahci: Pass AHCI context to ahci_ide_create_devs()
Since ahci_ide_create_devs() is not PCI specific, pass it an AHCIState argument instead of PCIDevice.
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-Id: <20240213081201.78951-6-philmd@linaro.org>
show more ...
|
#
e6097f18 |
| 13-Feb-2024 |
Philippe Mathieu-Daudé <philmd@linaro.org> |
hw/ide/ahci: Inline ahci_get_num_ports()
Introduce the 'ich9' variable and inline ahci_get_num_ports().
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> Reviewed-by: Michael S. Tsirkin <ms
hw/ide/ahci: Inline ahci_get_num_ports()
Introduce the 'ich9' variable and inline ahci_get_num_ports().
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-Id: <20240213081201.78951-5-philmd@linaro.org>
show more ...
|
#
d407be08 |
| 13-Feb-2024 |
Philippe Mathieu-Daudé <philmd@linaro.org> |
hw/ide/ahci: Expose AHCIPCIState structure
In order to be able to QOM-embed a structure, we need its full definition. Move it from "ahci_internal.h" to the new "hw/ide/ahci-pci.h" header.
Signed-of
hw/ide/ahci: Expose AHCIPCIState structure
In order to be able to QOM-embed a structure, we need its full definition. Move it from "ahci_internal.h" to the new "hw/ide/ahci-pci.h" header.
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-Id: <20240213081201.78951-3-philmd@linaro.org>
show more ...
|
#
8595c054 |
| 20-Dec-2023 |
Richard Henderson <richard.henderson@linaro.org> |
hw/ide: Constify VMState
Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-Id: <20231221031652.119827-33-richard.henderson@linaro.org>
|
#
eabb9212 |
| 08-Nov-2023 |
Niklas Cassel <niklas.cassel@wdc.com> |
hw/ide/ahci: fix legacy software reset
Legacy software contains a standard mechanism for generating a reset to a Serial ATA device - setting the SRST (software reset) bit in the Device Control regis
hw/ide/ahci: fix legacy software reset
Legacy software contains a standard mechanism for generating a reset to a Serial ATA device - setting the SRST (software reset) bit in the Device Control register.
Serial ATA has a more robust mechanism called COMRESET, also referred to as port reset. A port reset is the preferred mechanism for error recovery and should be used in place of software reset.
Commit e2a5d9b3d9c3 ("hw/ide/ahci: simplify and document PxCI handling") improved the handling of PxCI, such that PxCI gets cleared after handling a non-NCQ, or NCQ command (instead of incorrectly clearing PxCI after receiving anything - even a FIS that failed to parse, which should NOT clear PxCI, so that you can see which command slot that caused an error).
However, simply clearing PxCI after a non-NCQ, or NCQ command, is not enough, we also need to clear PxCI when receiving a SRST in the Device Control register.
A legacy software reset is performed by the host sending two H2D FISes, the first H2D FIS asserts SRST, and the second H2D FIS deasserts SRST.
The first H2D FIS will not get a D2H reply, and requires the FIS to have the C bit set to one, such that the HBA itself will clear the bit in PxCI.
The second H2D FIS will get a D2H reply once the diagnostic is completed. The clearing of the bit in PxCI for this command should ideally be done in ahci_init_d2h() (if it was a legacy software reset that caused the reset (a COMRESET does not use a command slot)). However, since the reset value for PxCI is 0, modify ahci_reset_port() to actually clear PxCI to 0, that way we can avoid complex logic in ahci_init_d2h().
This fixes an issue for FreeBSD where the device would fail to reset. The problem was not noticed in Linux, because Linux uses a COMRESET instead of a legacy software reset by default.
Fixes: e2a5d9b3d9c3 ("hw/ide/ahci: simplify and document PxCI handling") Reported-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org> Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com> Message-ID: <20231108222657.117984-1-nks@flawful.org> Reviewed-by: Kevin Wolf <kwolf@redhat.com> Tested-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
show more ...
|
#
b523a3d5 |
| 11-Oct-2023 |
Niklas Cassel <niklas.cassel@wdc.com> |
hw/ide/ahci: trigger either error IRQ or regular IRQ, not both
According to AHCI 1.3.1, 5.3.8.1 RegFIS:Entry, if ERR_STAT is set, we jump to state ERR:FatalTaskfile, which will raise a TFES IRQ unco
hw/ide/ahci: trigger either error IRQ or regular IRQ, not both
According to AHCI 1.3.1, 5.3.8.1 RegFIS: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.
NOTE: for QEMU platforms that use SeaBIOS, this patch depends on QEMU commit 784155cdcb02 ("seabios: update submodule to git snapshot"), and QEMU commit 14f5a7bae4cb ("seabios: update binaries to git snapshot"), which update SeaBIOS to a version that contains SeaBIOS commit 1281e340 ("ahci: handle TFES irq correctly").
Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com> Message-ID: <20231011131220.1992064-1-nks@flawful.org> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Reviewed-by: Kevin Wolf <kwolf@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
show more ...
|
#
a5afeefb |
| 04-Oct-2023 |
Philippe Mathieu-Daudé <philmd@linaro.org> |
hw/ide/ahci: Clean up local variable shadowing
Fix:
hw/ide/ahci.c:1577:23: error: declaration shadows a local variable [-Werror,-Wshadow] IDEState *s = &ad->port.ifs[j];
hw/ide/ahci: Clean up local variable shadowing
Fix:
hw/ide/ahci.c:1577:23: error: declaration shadows a local variable [-Werror,-Wshadow] IDEState *s = &ad->port.ifs[j]; ^ hw/ide/ahci.c:1569:29: note: previous declaration is here void ahci_uninit(AHCIState *s) ^
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> Message-ID: <20231004120019.93101-3-philmd@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: John Snow <jsnow@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
show more ...
|
#
9f894235 |
| 09-Jun-2023 |
Niklas Cassel <niklas.cassel@wdc.com> |
hw/ide/ahci: fix broken SError handling
When encountering an NCQ error, you should not write the NCQ tag to the SError register. This is completely wrong.
The SError register has a clear definition
hw/ide/ahci: fix broken SError handling
When encountering an NCQ error, you should not write the NCQ tag to the SError register. This is completely wrong.
The SError register has a clear definition, where each bit represents a different error, see PxSERR definition in AHCI 1.3.1.
If we write a random value (like the NCQ tag) in SError, e.g. Linux will read SError, and will trigger arbitrary error handling depending on the NCQ tag that happened to be executing.
In case of success, ncq_cb() will call ncq_finish(). In case of error, ncq_cb() will call ncq_err() (which will clear ncq_tfs->used), and then call ncq_finish(), thus using ncq_tfs->used is sufficient to tell if finished should get set or not.
Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Message-id: 20230609140844.202795-9-nks@flawful.org Signed-off-by: John Snow <jsnow@redhat.com>
show more ...
|
#
7e85cb0d |
| 09-Jun-2023 |
Niklas Cassel <niklas.cassel@wdc.com> |
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 wi
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@wdc.com> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Message-id: 20230609140844.202795-8-nks@flawful.org Signed-off-by: John Snow <jsnow@redhat.com>
show more ...
|
#
1a16ce64 |
| 09-Jun-2023 |
Niklas Cassel <niklas.cassel@wdc.com> |
hw/ide/ahci: PxCI should not get cleared when ERR_STAT is set
For NCQ, PxCI is cleared on command queued successfully. For non-NCQ, PxCI is cleared on command completed successfully. Successfully me
hw/ide/ahci: PxCI should not get cleared when ERR_STAT is set
For NCQ, PxCI is cleared on command queued successfully. For non-NCQ, PxCI is cleared on command completed successfully. Successfully means ERR_STAT, BUSY and DRQ are all cleared.
A command that has ERR_STAT set, does not get to clear PxCI. See AHCI 1.3.1, section 5.3.8, states RegFIS:Entry and RegFIS:ClearCI, and 5.3.16.5 ERR:FatalTaskfile.
In the case of non-NCQ commands, not clearing PxCI is needed in order for host software to be able to see which command slot that failed.
Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com> Message-id: 20230609140844.202795-7-nks@flawful.org Signed-off-by: John Snow <jsnow@redhat.com>
show more ...
|
#
d73b84d0 |
| 09-Jun-2023 |
Niklas Cassel <niklas.cassel@wdc.com> |
hw/ide/ahci: PxSACT and PxCI is cleared when PxCMD.ST is cleared
According to AHCI 1.3.1 definition of PxSACT: This field is cleared when PxCMD.ST is written from a '1' to a '0' by software. This fi
hw/ide/ahci: PxSACT and PxCI is cleared when PxCMD.ST is cleared
According to AHCI 1.3.1 definition of PxSACT: This field is cleared when PxCMD.ST is written from a '1' to a '0' by software. This field is not cleared by a COMRESET or a software reset.
According to AHCI 1.3.1 definition of PxCI: This field is also cleared when PxCMD.ST is written from a '1' to a '0' by software.
Clearing PxCMD.ST is part of the error recovery procedure, see AHCI 1.3.1, section "6.2 Error Recovery".
If we don't clear PxCI on error recovery, the previous command will incorrectly still be marked as pending after error recovery.
Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Message-id: 20230609140844.202795-6-nks@flawful.org Signed-off-by: John Snow <jsnow@redhat.com>
show more ...
|
#
e2a5d9b3 |
| 09-Jun-2023 |
Niklas Cassel <niklas.cassel@wdc.com> |
hw/ide/ahci: simplify and document PxCI handling
The AHCI spec states that: For NCQ, PxCI is cleared on command queued successfully.
For non-NCQ, PxCI is cleared on command completed successfully.
hw/ide/ahci: simplify and document PxCI handling
The AHCI spec states that: For NCQ, PxCI is cleared on command queued successfully.
For non-NCQ, PxCI is cleared on command completed successfully. (A non-NCQ command that completes with error does not clear PxCI.)
The current QEMU implementation either clears PxCI in check_cmd(), or in ahci_cmd_done().
check_cmd() will clear PxCI for a command if handle_cmd() returns 0. handle_cmd() will return -1 if BUSY or DRQ is set.
The QEMU implementation for NCQ commands will currently not set BUSY or DRQ, so they will always have PxCI cleared by handle_cmd(). ahci_cmd_done() will never even get called for NCQ commands.
Non-NCQ commands are executed by ide_bus_exec_cmd(). Non-NCQ commands in QEMU are implemented either in a sync or in an async way.
For non-NCQ commands implemented in a sync way, the command handler will return true, and when ide_bus_exec_cmd() sees that a command handler returns true, it will call ide_cmd_done() (which will call ahci_cmd_done()). For a command implemented in a sync way, ahci_cmd_done() will do nothing (since busy_slot is not set). Instead, after ide_bus_exec_cmd() has finished, check_cmd() will clear PxCI for these commands.
For non-NCQ commands implemented in an async way (using either aiocb or pio_aiocb), the command handler will return false, ide_bus_exec_cmd() will not call ide_cmd_done(), instead it is expected that the async callback function will call ide_cmd_done() once the async command is done. handle_cmd() will set busy_slot, if and only if BUSY or DRQ is set, and this is checked _after_ ide_bus_exec_cmd() has returned. handle_cmd() will return -1, so check_cmd() will not clear PxCI. When the async callback calls ide_cmd_done() (which will call ahci_cmd_done()), it will see that busy_slot is set, and ahci_cmd_done() will clear PxCI.
This seems racy, since busy_slot is set _after_ ide_bus_exec_cmd() has returned. The callback might come before busy_slot gets set. And it is quite confusing that ahci_cmd_done() will be called for all non-NCQ commands when the command is done, but will only clear PxCI in certain cases, even though it will always write a D2H FIS and raise an IRQ.
Even worse, in the case where ahci_cmd_done() does not clear PxCI, it still raises an IRQ. Host software might thus read an old PxCI value, since PxCI is cleared (by check_cmd()) after the IRQ has been raised.
Try to simplify this by always setting busy_slot for non-NCQ commands, such that ahci_cmd_done() will always be responsible for clearing PxCI for non-NCQ commands.
For NCQ commands, clear PxCI when we receive the D2H FIS, but before raising the IRQ, see AHCI 1.3.1, section 5.3.8, states RegFIS:Entry and RegFIS:ClearCI.
Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com> Message-id: 20230609140844.202795-5-nks@flawful.org Signed-off-by: John Snow <jsnow@redhat.com>
show more ...
|
#
2967dc82 |
| 09-Jun-2023 |
Niklas Cassel <niklas.cassel@wdc.com> |
hw/ide/ahci: write D2H FIS when processing NCQ command
The way that BUSY + PxCI is cleared for NCQ (FPDMA QUEUED) commands is described in SATA 3.5a Gold:
11.15 FPDMA QUEUED command protocol DFPDMA
hw/ide/ahci: write D2H FIS when processing NCQ command
The way that BUSY + PxCI is cleared for NCQ (FPDMA QUEUED) commands is described in SATA 3.5a Gold:
11.15 FPDMA QUEUED command protocol DFPDMAQ2: ClearInterfaceBsy "Transmit Register Device to Host FIS with the BSY bit cleared to zero and the DRQ bit cleared to zero and Interrupt bit cleared to zero to mark interface ready for the next command."
PxCI is currently cleared by handle_cmd(), but we don't write the D2H FIS to the FIS Receive Area that actually caused PxCI to be cleared.
Similar to how ahci_pio_transfer() calls ahci_write_fis_pio() with an additional parameter to write a PIO Setup FIS without raising an IRQ, add a parameter to ahci_write_fis_d2h() so that ahci_write_fis_d2h() also can write the FIS to the FIS Receive Area without raising an IRQ.
Change process_ncq_command() to call ahci_write_fis_d2h() without raising an IRQ (similar to ahci_pio_transfer()), such that the FIS Receive Area is in sync with the PxTFD shadow register.
E.g. Linux reads status and error fields from the FIS Receive Area directly, so it is wise to keep the FIS Receive Area and the PxTFD shadow register in sync.
Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com> Message-id: 20230609140844.202795-4-nks@flawful.org Signed-off-by: John Snow <jsnow@redhat.com>
show more ...
|
#
d5361580 |
| 09-Jun-2023 |
Niklas Cassel <niklas.cassel@wdc.com> |
hw/ide/ahci: fix broken SError handling
When encountering an NCQ error, you should not write the NCQ tag to the SError register. This is completely wrong.
The SError register has a clear definition
hw/ide/ahci: fix broken SError handling
When encountering an NCQ error, you should not write the NCQ tag to the SError register. This is completely wrong.
The SError register has a clear definition, where each bit represents a different error, see PxSERR definition in AHCI 1.3.1.
If we write a random value (like the NCQ tag) in SError, e.g. Linux will read SError, and will trigger arbitrary error handling depending on the NCQ tag that happened to be executing.
In case of success, ncq_cb() will call ncq_finish(). In case of error, ncq_cb() will call ncq_err() (which will clear ncq_tfs->used), and then call ncq_finish(), thus using ncq_tfs->used is sufficient to tell if finished should get set or not.
Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Message-id: 20230609140844.202795-9-nks@flawful.org Signed-off-by: John Snow <jsnow@redhat.com> (cherry picked from commit 9f89423537653de07ca40c18b5ff5b70b104cc93) Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
show more ...
|
#
e8f5ca57 |
| 09-Jun-2023 |
Niklas Cassel <niklas.cassel@wdc.com> |
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 wi
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@wdc.com> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Message-id: 20230609140844.202795-8-nks@flawful.org Signed-off-by: John Snow <jsnow@redhat.com> (cherry picked from commit 7e85cb0db4c693b4e084a00e66fe73a22ed1688a) Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
show more ...
|
#
4448c345 |
| 09-Jun-2023 |
Niklas Cassel <niklas.cassel@wdc.com> |
hw/ide/ahci: PxCI should not get cleared when ERR_STAT is set
For NCQ, PxCI is cleared on command queued successfully. For non-NCQ, PxCI is cleared on command completed successfully. Successfully me
hw/ide/ahci: PxCI should not get cleared when ERR_STAT is set
For NCQ, PxCI is cleared on command queued successfully. For non-NCQ, PxCI is cleared on command completed successfully. Successfully means ERR_STAT, BUSY and DRQ are all cleared.
A command that has ERR_STAT set, does not get to clear PxCI. See AHCI 1.3.1, section 5.3.8, states RegFIS:Entry and RegFIS:ClearCI, and 5.3.16.5 ERR:FatalTaskfile.
In the case of non-NCQ commands, not clearing PxCI is needed in order for host software to be able to see which command slot that failed.
Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com> Message-id: 20230609140844.202795-7-nks@flawful.org Signed-off-by: John Snow <jsnow@redhat.com> (cherry picked from commit 1a16ce64fda11bdf50f0c4ab5d9fdde72c1383a2) Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
show more ...
|
#
4fbd5a52 |
| 09-Jun-2023 |
Niklas Cassel <niklas.cassel@wdc.com> |
hw/ide/ahci: PxSACT and PxCI is cleared when PxCMD.ST is cleared
According to AHCI 1.3.1 definition of PxSACT: This field is cleared when PxCMD.ST is written from a '1' to a '0' by software. This fi
hw/ide/ahci: PxSACT and PxCI is cleared when PxCMD.ST is cleared
According to AHCI 1.3.1 definition of PxSACT: This field is cleared when PxCMD.ST is written from a '1' to a '0' by software. This field is not cleared by a COMRESET or a software reset.
According to AHCI 1.3.1 definition of PxCI: This field is also cleared when PxCMD.ST is written from a '1' to a '0' by software.
Clearing PxCMD.ST is part of the error recovery procedure, see AHCI 1.3.1, section "6.2 Error Recovery".
If we don't clear PxCI on error recovery, the previous command will incorrectly still be marked as pending after error recovery.
Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Message-id: 20230609140844.202795-6-nks@flawful.org Signed-off-by: John Snow <jsnow@redhat.com> (cherry picked from commit d73b84d0b664e60fffb66f46e84d0db4a8e1c713) Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
show more ...
|
#
16cc9594 |
| 09-Jun-2023 |
Niklas Cassel <niklas.cassel@wdc.com> |
hw/ide/ahci: simplify and document PxCI handling
The AHCI spec states that: For NCQ, PxCI is cleared on command queued successfully.
For non-NCQ, PxCI is cleared on command completed successfully.
hw/ide/ahci: simplify and document PxCI handling
The AHCI spec states that: For NCQ, PxCI is cleared on command queued successfully.
For non-NCQ, PxCI is cleared on command completed successfully. (A non-NCQ command that completes with error does not clear PxCI.)
The current QEMU implementation either clears PxCI in check_cmd(), or in ahci_cmd_done().
check_cmd() will clear PxCI for a command if handle_cmd() returns 0. handle_cmd() will return -1 if BUSY or DRQ is set.
The QEMU implementation for NCQ commands will currently not set BUSY or DRQ, so they will always have PxCI cleared by handle_cmd(). ahci_cmd_done() will never even get called for NCQ commands.
Non-NCQ commands are executed by ide_bus_exec_cmd(). Non-NCQ commands in QEMU are implemented either in a sync or in an async way.
For non-NCQ commands implemented in a sync way, the command handler will return true, and when ide_bus_exec_cmd() sees that a command handler returns true, it will call ide_cmd_done() (which will call ahci_cmd_done()). For a command implemented in a sync way, ahci_cmd_done() will do nothing (since busy_slot is not set). Instead, after ide_bus_exec_cmd() has finished, check_cmd() will clear PxCI for these commands.
For non-NCQ commands implemented in an async way (using either aiocb or pio_aiocb), the command handler will return false, ide_bus_exec_cmd() will not call ide_cmd_done(), instead it is expected that the async callback function will call ide_cmd_done() once the async command is done. handle_cmd() will set busy_slot, if and only if BUSY or DRQ is set, and this is checked _after_ ide_bus_exec_cmd() has returned. handle_cmd() will return -1, so check_cmd() will not clear PxCI. When the async callback calls ide_cmd_done() (which will call ahci_cmd_done()), it will see that busy_slot is set, and ahci_cmd_done() will clear PxCI.
This seems racy, since busy_slot is set _after_ ide_bus_exec_cmd() has returned. The callback might come before busy_slot gets set. And it is quite confusing that ahci_cmd_done() will be called for all non-NCQ commands when the command is done, but will only clear PxCI in certain cases, even though it will always write a D2H FIS and raise an IRQ.
Even worse, in the case where ahci_cmd_done() does not clear PxCI, it still raises an IRQ. Host software might thus read an old PxCI value, since PxCI is cleared (by check_cmd()) after the IRQ has been raised.
Try to simplify this by always setting busy_slot for non-NCQ commands, such that ahci_cmd_done() will always be responsible for clearing PxCI for non-NCQ commands.
For NCQ commands, clear PxCI when we receive the D2H FIS, but before raising the IRQ, see AHCI 1.3.1, section 5.3.8, states RegFIS:Entry and RegFIS:ClearCI.
Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com> Message-id: 20230609140844.202795-5-nks@flawful.org Signed-off-by: John Snow <jsnow@redhat.com> (cherry picked from commit e2a5d9b3d9c3d311618160603cc9bc04fbd98796) Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
show more ...
|
#
1efefd13 |
| 09-Jun-2023 |
Niklas Cassel <niklas.cassel@wdc.com> |
hw/ide/ahci: write D2H FIS when processing NCQ command
The way that BUSY + PxCI is cleared for NCQ (FPDMA QUEUED) commands is described in SATA 3.5a Gold:
11.15 FPDMA QUEUED command protocol DFPDMA
hw/ide/ahci: write D2H FIS when processing NCQ command
The way that BUSY + PxCI is cleared for NCQ (FPDMA QUEUED) commands is described in SATA 3.5a Gold:
11.15 FPDMA QUEUED command protocol DFPDMAQ2: ClearInterfaceBsy "Transmit Register Device to Host FIS with the BSY bit cleared to zero and the DRQ bit cleared to zero and Interrupt bit cleared to zero to mark interface ready for the next command."
PxCI is currently cleared by handle_cmd(), but we don't write the D2H FIS to the FIS Receive Area that actually caused PxCI to be cleared.
Similar to how ahci_pio_transfer() calls ahci_write_fis_pio() with an additional parameter to write a PIO Setup FIS without raising an IRQ, add a parameter to ahci_write_fis_d2h() so that ahci_write_fis_d2h() also can write the FIS to the FIS Receive Area without raising an IRQ.
Change process_ncq_command() to call ahci_write_fis_d2h() without raising an IRQ (similar to ahci_pio_transfer()), such that the FIS Receive Area is in sync with the PxTFD shadow register.
E.g. Linux reads status and error fields from the FIS Receive Area directly, so it is wise to keep the FIS Receive Area and the PxTFD shadow register in sync.
Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com> Message-id: 20230609140844.202795-4-nks@flawful.org Signed-off-by: John Snow <jsnow@redhat.com> (cherry picked from commit 2967dc8209dd27b61a6ab7bad78cf7c6ec58ddb4) Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
show more ...
|