hw/ide/ahci.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
From: Niklas Cassel <niklas.cassel@wdc.com>
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 an arbitrary FIS).
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.
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>
---
hw/ide/ahci.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
index babdd7b458..3a8b97c325 100644
--- a/hw/ide/ahci.c
+++ b/hw/ide/ahci.c
@@ -1254,10 +1254,26 @@ static void handle_reg_h2d_fis(AHCIState *s, int port,
case STATE_RUN:
if (cmd_fis[15] & ATA_SRST) {
s->dev[port].port_state = STATE_RESET;
+ /*
+ * When setting SRST in the first H2D FIS in the reset sequence,
+ * the device does not send a D2H FIS. Host software thus has to
+ * set the "Clear Busy upon R_OK" bit such that PxCI (and BUSY)
+ * gets cleared. See AHCI 1.3.1, section 10.4.1 Software Reset.
+ */
+ if (opts & AHCI_CMD_CLR_BUSY) {
+ ahci_clear_cmd_issue(ad, slot);
+ }
}
break;
case STATE_RESET:
if (!(cmd_fis[15] & ATA_SRST)) {
+ /*
+ * When clearing SRST in the second H2D FIS in the reset
+ * sequence, the device will send a D2H FIS. See SATA 3.5a Gold,
+ * section 11.4 Software reset protocol.
+ */
+ ahci_write_fis_d2h(ad, false);
+ ahci_clear_cmd_issue(ad, slot);
ahci_reset_port(s, port);
}
break;
--
2.41.0
W dniu 5.10.2023 o 11:53, Niklas Cassel pisze: > From: Niklas Cassel<niklas.cassel@wdc.com> > > 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 an arbitrary FIS). > > 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. > > 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> Sorry, I missed that patch earlier. FreeBSD 14-rc3 boots fine on aarch64. Thanks! Trying to mount root from cd9660:/dev/iso9660/14_0_RC3_AARCH64_BO [ro]... cd0 at ahcich0 bus 0 scbus0 target 0 lun 0 cd0: <QEMU QEMU DVD-ROM 2.5+> Removable CD-ROM SCSI device cd0: Serial Number QM00001 cd0: 150.000MB/s transfers (SATA 1.x, UDMA5, ATAPI 12bytes, PIO 8192bytes) cd0: 347MB (177954 2048 byte sectors) ada0 at ahcich1 bus 0 scbus1 target 0 lun 0 ada0: <QEMU HARDDISK 2.5+> ATA-7 SATA device ada0: Serial Number QM00003 ada0: 150.000MB/s transfers (SATA 1.x, UDMA5, PIO 8192bytes) ada0: Command Queueing enabled ada0: 504MB (1032192 512 byte sectors) ada1 at ahcich2 bus 0 scbus2 target 0 lun 0 ada1: <QEMU HARDDISK 2.5+> ATA-7 SATA device ada1: Serial Number QM00005 ada1: 150.000MB/s transfers (SATA 1.x, UDMA5, PIO 8192bytes) ada1: Command Queueing enabled ada1: 8192MB (16777216 512 byte sectors) Tested-by: Marcin Juszkiewicz<marcin.juszkiewicz@linaro.org>
© 2016 - 2024 Red Hat, Inc.