Index: sys/dev/ahci/ahci.h =================================================================== --- sys/dev/ahci/ahci.h +++ sys/dev/ahci/ahci.h @@ -574,6 +574,8 @@ #define AHCI_Q_SATA1_UNIT0 0x00008000 /* need better method for this */ #define AHCI_Q_ABAR0 0x00010000 #define AHCI_Q_1MSI 0x00020000 +#define AHCI_Q_FORCE_PI 0x00040000 +#define AHCI_Q_RESTORE_CAP 0x00080000 #define AHCI_Q_BIT_STRING \ "\021" \ @@ -594,7 +596,9 @@ "\017MAXIO_64K" \ "\020SATA1_UNIT0" \ "\021ABAR0" \ - "\0221MSI" + "\0221MSI" \ + "\022FORCE_PI" \ + "\023RESTORE_CAP" int ahci_attach(device_t dev); int ahci_detach(device_t dev); Index: sys/dev/ahci/ahci.c =================================================================== --- sys/dev/ahci/ahci.c +++ sys/dev/ahci/ahci.c @@ -146,6 +146,18 @@ } /* Reenable AHCI mode */ ATA_OUTL(ctlr->r_mem, AHCI_GHC, AHCI_GHC_AE); + + if (ctlr->quirks & AHCI_Q_RESTORE_CAP) { + /* + * Restore capability field. + * This is write to a read-only register to restore its state. + * On fully standard-compliant hardware this is not needed and + * this operation shall not take place. See ahci_pci.c for + * platforms using this quirk. + */ + ATA_OUTL(ctlr->r_mem, AHCI_CAP, ctlr->caps); + } + return (0); } @@ -185,6 +197,22 @@ ctlr->caps2 = ATA_INL(ctlr->r_mem, AHCI_CAP2); if (ctlr->caps & AHCI_CAP_EMS) ctlr->capsem = ATA_INL(ctlr->r_mem, AHCI_EM_CTL); + + if (ctlr->quirks & AHCI_Q_FORCE_PI) { + /* + * Enable ports. + * The spec says that BIOS sets up bits corresponding to + * available ports. On platforms where this information + * is missing, the driver can define available ports on its own. + */ + int nports = (ctlr->caps & AHCI_CAP_NPMASK) + 1; + int nmask = (1 << nports) - 1; + + ATA_OUTL(ctlr->r_mem, AHCI_PI, nmask); + device_printf(dev, "Forcing PI to %d ports (mask = %x)\n", + nports, nmask); + } + ctlr->ichannels = ATA_INL(ctlr->r_mem, AHCI_PI); /* Identify and set separate quirks for HBA and RAID f/w Marvells. */ Index: sys/dev/ahci/ahci_pci.c =================================================================== --- sys/dev/ahci/ahci_pci.c +++ sys/dev/ahci/ahci_pci.c @@ -293,6 +293,7 @@ {0x11851039, 0x00, "SiS 968", 0}, {0x01861039, 0x00, "SiS 968", 0}, {0xa01c177d, 0x00, "ThunderX", AHCI_Q_ABAR0|AHCI_Q_1MSI}, + {0x00311c36, 0x00, "Annapurna", AHCI_Q_FORCE_PI|AHCI_Q_RESTORE_CAP}, {0x00000000, 0x00, NULL, 0} };