Hello Matt, On Wed, Mar 13, 2024 at 06:37:56PM +0100, Cryptearth wrote: > > As for why the ASM chips report 30+ ports: A wild guess in the blue: > They were designed with port multipliers in mind and likely report the > max number of drives they can handle when combined with multipliers. > From what I get the "fix" is supposed to reduce boot time - well, from > my logs I see it's not the enumeration of the empty ports which takes > time but of course the initialization of the detected drives. > To me the initial report that lead to this changed just should had > been marked as won't fix or even as invalid - as looking thru the > history of ahci.c litterally noone seem to have bothered about it > since the ASM IDs were added. Well, that is simply not how PMP works. For PMP to be supported the HBA needs to set CAP.SPM (Supports Port Muliplier). (This also implies Command-based switching is supported.) The HBA can additionally set CAP.FBSS (FIS-based Switching Supported), if CAP.SPM is set. If CAP.SPM is set, you can plug in a PMP to each of the ports. Each PMP can support a max of 15 ports. If PMP is enabled, you fill in the port number behind the port when queuing the command: https://github.com/torvalds/linux/blob/v6.8/drivers/ata/libahci.c#L1424 https://github.com/torvalds/linux/blob/v6.8/drivers/ata/libata-sata.c#L154 Looking at your SATA HBA: > [ 0.608537] ahci 0000:04:00.0: AHCI 0001.0301 32 slots 24 ports 6 Gbps 0xffff0f impl SATA mode > [ 0.608540] ahci 0000:04:00.0: flags: 64bit ncq sntf stag pm led only pio sxs deso sadm sds apst We can see that it does not support PMP at all. There is no "pmp" in print, which means that CAP.SPM was not set. So your HBA does not support PMP, sorry. Yes, we can see that it claims that it has 24 ports from the print, so it appears that they have implemented their own version of PMP that is not compatible with AHCI. Lovely :) I think this brings more questions than answers... What is the PCI device and vendor ID for this device? You said that this is a PCIe card with a ASM1064 and two port multipliers on the same PCIe card? >From what we've heard before, a ASMedia card with 4 physical slots, like this card: https://www.newegg.com/p/17Z-0061-000B5 Has PCIe device and vendor ID: { PCI_VDEVICE(ASMEDIA, 0x1064), board_ahci }, /* ASM1064 */ But you have a PCIe card with the same device and vendor ID, but your card also has 2 port multipliers with 4 ports each? Well, I guess it should be fine to use the PCI device and vendor ID for the underlying HBA... considering that devices connected to the ports are supposed to be discoverable... If they only claimed that the HBA supported PMP, the Linux device driver would try to enumerate the devices behind the PMP according to the standard. See AHCI 1.3.1, section 9.2 Port Multiplier Enumeration. Or SATA-IO - Port Multiplier 1.0, 7.4.2 Device Enumeration. The PMP standard also describes how you read the device and vendor ID of the PMP. Right now, they AMedia? seem to have their own home-made PMP implementation. Could you try the attached patch on top of v6.8, to see if Linux can detect the devices behind the two JMB575 PMPs? If that works, we could still support PMP (according to the standard), and people with a ASM1064 PCIe card that does not have any port multipliers on the PCIe card would not suffer from significantly increased boot times. I guess a second step would be to see if ASM1064 also supports FIS-based switching. https://www.asmedia.com.tw/product/A58yQC9Sp5qg6TrF/58dYQ8bxZ4UR9wG5 Simply says "Supported port multiplier command based switching", it doesn't seem to mention FIS-based switching... so I guess not? (If it did, libata already has a AHCI_HFLAG_YES_FBS for other broken HBAs.) Kind regards, Niklas
>From a5001fd7b19d3a6a9abd42a19b58e2aaee1b83e2 Mon Sep 17 00:00:00 2001 From: Niklas Cassel <cassel@xxxxxxxxxx> Date: Thu, 14 Mar 2024 16:36:34 +0100 Subject: [PATCH] add hflag to force PMP cap on Signed-off-by: Niklas Cassel <cassel@xxxxxxxxxx> --- drivers/ata/ahci.c | 2 ++ drivers/ata/ahci.h | 1 + drivers/ata/libahci.c | 5 +++++ 3 files changed, 8 insertions(+) diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 682ff550ccfb9..a99de94075a1a 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -676,10 +676,12 @@ static void ahci_pci_save_initial_config(struct pci_dev *pdev, case 0x1166: dev_info(&pdev->dev, "ASM1166 has only six ports\n"); hpriv->saved_port_map = 0x3f; + hpriv->flags |= AHCI_HFLAG_YES_PMP; break; case 0x1064: dev_info(&pdev->dev, "ASM1064 has only four ports\n"); hpriv->saved_port_map = 0xf; + hpriv->flags |= AHCI_HFLAG_YES_PMP; break; } } diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h index df8f8a1a3a34c..f9cae26848480 100644 --- a/drivers/ata/ahci.h +++ b/drivers/ata/ahci.h @@ -230,6 +230,7 @@ enum { error-handling stage) */ AHCI_HFLAG_NO_DEVSLP = BIT(17), /* no device sleep */ AHCI_HFLAG_NO_FBS = BIT(18), /* no FBS */ + AHCI_HFLAG_YES_PMP = BIT(19), /* force PMP cap on */ #ifdef CONFIG_PCI_MSI AHCI_HFLAG_MULTI_MSI = BIT(20), /* per-port MSI(-X) */ diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c index 1a63200ea437b..9a1d10205de85 100644 --- a/drivers/ata/libahci.c +++ b/drivers/ata/libahci.c @@ -493,6 +493,11 @@ void ahci_save_initial_config(struct device *dev, struct ahci_host_priv *hpriv) cap |= HOST_CAP_NCQ; } + if (!(cap & HOST_CAP_PMP) && (hpriv->flags & AHCI_HFLAG_YES_PMP)) { + dev_info(dev, "controller can do PMP, turning on CAP_PMP\n"); + cap |= HOST_CAP_PMP; + } + if ((cap & HOST_CAP_PMP) && (hpriv->flags & AHCI_HFLAG_NO_PMP)) { dev_info(dev, "controller can't do PMP, turning off CAP_PMP\n"); cap &= ~HOST_CAP_PMP; -- 2.44.0