ASMedia make a number of SATA chipsets on pcie cards which end up identifing themselves as PCI_SUBCLASS_MASS_STORAGE_IDE. It does not appear that they have never made any pciide chipsets, and the chances of them doing so in future are vanishing small. Rather than keep adding more entries to the quirk table (I just found another this week), we could allow matching PCI_SUBCLASS_MASS_STORAGE_IDE in ahcisata_pci, and allow matching on a per vendor level To allow for vendor level matching we need a 'wildcard' product code - I've picked 0xffff, which is the one aspect with which I'm not entirely happy Index: sys/dev/ic/ahcisatavar.h =================================================================== RCS file: /cvsroot/src/sys/dev/ic/ahcisatavar.h,v retrieving revision 1.27 diff -u -r1.27 ahcisatavar.h --- sys/dev/ic/ahcisatavar.h 19 Nov 2021 23:46:55 -0000 1.27 +++ sys/dev/ic/ahcisatavar.h 1 Sep 2023 12:35:30 -0000 @@ -56,10 +56,11 @@ int sc_atac_capflags; int sc_ahci_quirks; #define AHCI_PCI_QUIRK_FORCE __BIT(0) /* force attach */ -#define AHCI_PCI_QUIRK_BAD64 __BIT(1) /* broken 64-bit DMA */ -#define AHCI_QUIRK_BADPMP __BIT(2) /* broken PMP support, ignore */ -#define AHCI_QUIRK_BADNCQ __BIT(3) /* possibly broken NCQ support, ignore */ -#define AHCI_QUIRK_EXTRA_DELAY __BIT(4) /* needs extra delay */ +#define AHCI_PCI_QUIRK_MATCH_IDE __BIT(1) /* Match SUBCLASS_MASS_STORAGE_IDE */ +#define AHCI_PCI_QUIRK_BAD64 __BIT(2) /* broken 64-bit DMA */ +#define AHCI_QUIRK_BADPMP __BIT(3) /* broken PMP support, ignore */ +#define AHCI_QUIRK_BADNCQ __BIT(4) /* possibly broken NCQ support, ignore */ +#define AHCI_QUIRK_EXTRA_DELAY __BIT(5) /* needs extra delay */ uint32_t sc_ahci_cap; /* copy of AHCI_CAP */ int sc_ncmds; /* number of command slots */ Index: sys/dev/pci/ahcisata_pci.c =================================================================== RCS file: /cvsroot/src/sys/dev/pci/ahcisata_pci.c,v retrieving revision 1.68.2.1 diff -u -r1.68.2.1 ahcisata_pci.c --- sys/dev/pci/ahcisata_pci.c 22 Aug 2023 15:57:38 -0000 1.68.2.1 +++ sys/dev/pci/ahcisata_pci.c 1 Sep 2023 09:08:03 -0000 @@ -46,6 +46,8 @@ #include #include +#define PCI_PRODUCT_ANY 0xffff + struct ahci_pci_quirk { pci_vendor_id_t vendor; /* Vendor ID */ pci_product_id_t product; /* Product ID */ @@ -190,14 +192,10 @@ AHCI_QUIRK_BADPMP }, { PCI_VENDOR_VIATECH, PCI_PRODUCT_VIATECH_VT8251_SATA, AHCI_QUIRK_BADPMP }, - { PCI_VENDOR_ASMEDIA, PCI_PRODUCT_ASMEDIA_ASM1061_01, - AHCI_PCI_QUIRK_FORCE }, - { PCI_VENDOR_ASMEDIA, PCI_PRODUCT_ASMEDIA_ASM1061_02, - AHCI_PCI_QUIRK_FORCE }, - { PCI_VENDOR_ASMEDIA, PCI_PRODUCT_ASMEDIA_ASM1061_11, - AHCI_PCI_QUIRK_FORCE }, + { PCI_VENDOR_ASMEDIA, PCI_PRODUCT_ANY, + AHCI_PCI_QUIRK_MATCH_IDE }, { PCI_VENDOR_ASMEDIA, PCI_PRODUCT_ASMEDIA_ASM1061_12, - AHCI_PCI_QUIRK_FORCE | AHCI_QUIRK_EXTRA_DELAY }, + AHCI_PCI_QUIRK_MATCH_IDE | AHCI_QUIRK_EXTRA_DELAY }, { PCI_VENDOR_AMD, PCI_PRODUCT_AMD_HUDSON_SATA, AHCI_PCI_QUIRK_FORCE }, { PCI_VENDOR_AMD, PCI_PRODUCT_AMD_HUDSON_SATA_AHCI, @@ -269,7 +267,8 @@ for (i = 0; i < __arraycount(ahci_pci_quirks); i++) if (vendor == ahci_pci_quirks[i].vendor && - product == ahci_pci_quirks[i].product) + (product == ahci_pci_quirks[i].product + || PCI_PRODUCT_ANY == ahci_pci_quirks[i].product)) return ahci_pci_quirks[i].quirks; return 0; } @@ -297,9 +296,19 @@ bus_size_t size; int ret = 0; bool force; + int quirks; /* quirks; same as sc_ahci_quirks */ + + quirks = ahci_pci_has_quirk(PCI_VENDOR(pa->pa_id), + PCI_PRODUCT(pa->pa_id)); - force = ((ahci_pci_has_quirk( PCI_VENDOR(pa->pa_id), - PCI_PRODUCT(pa->pa_id)) & AHCI_PCI_QUIRK_FORCE) != 0); + /* + * Match unconditionally if AHCI_PCI_QUIRK_FORCE, and + * match PCI_SUBCLASS_MASS_STORAGE_IDE if AHCI_PCI_QUIRK_MATCH_IDE + */ + force = (quirks & AHCI_PCI_QUIRK_FORCE) != 0 || + ((quirks & AHCI_PCI_QUIRK_MATCH_IDE) && + PCI_CLASS(pa->pa_class) == PCI_CLASS_MASS_STORAGE && + PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_MASS_STORAGE_IDE); /* if wrong class and not forced by quirks, don't match */ if ((PCI_CLASS(pa->pa_class) != PCI_CLASS_MASS_STORAGE ||