tech-kern archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: Intel 82801H SATA interrupt issues
On Thu, Sep 05, 2024 at 12:53:00AM +0000, Emmanuel Dreyfus wrote:
> Is there something I am doing obviously wrong? I note the documentation
> says only the BIOS should do this, but how is this different from the
> BIOS doing it? The controller is not yet in operation.
I got more success: the operation must be done while enumerating PCI
bridge children, before they are configured. I run it from
pci_enumerate_bus. Patch (which is just a hacking in progress) attached .
I get this:
pci_force_ahci: try 0:31:2
armval = 0x81030000
write back armval = 0x81030040
updated armval = 0x81030040
pci_force_ahci: try 0:31:5
armval = 0x00030000
write back armval = 0x00030040
updated armval = 0x00030000
Then the AHCI controller appears instead of piixide at 0:31:2
(...)
ahcisata0 at pci0 dev 31 function 2: Intel 82801H AHCI SATA Controller w/ 4 ports (rev. 0x02)
autoconfiguration error: ahcisata0: reset failed
Not a full success. Then piixide appears at 0:31:5. Because ahcisata failed?
piixide0 at pci0 dev 31 function 5: Intel 82801H Serial ATA Controller (ICH8) (rev. 0x02)
--
Emmanuel Dreyfus
manu%netbsd.org@localhost
Index: pci.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/pci.c,v
retrieving revision 1.165
diff -U4 -r1.165 pci.c
--- pci.c 24 Aug 2022 11:19:25 -0000 1.165
+++ pci.c 7 Sep 2024 02:31:51 -0000
@@ -260,9 +260,9 @@
snprintb(devinfo, sizeof (devinfo),
"\002\001multifn\002singlefn\003skipfunc0"
"\004skipfunc1\005skipfunc2\006skipfunc3"
"\007skipfunc4\010skipfunc5\011skipfunc6"
- "\012skipfunc7", qd->quirks);
+ "\012skipfunc7\013forceahci", qd->quirks);
printf(" quirks %s", devinfo);
}
printf(")");
}
@@ -702,8 +702,51 @@
}
return 0;
}
+static void
+pci_force_ahci(pci_chipset_tag_t pc, pcitag_t tag)
+{
+ int bus, device, function;
+ pci_class_t class;
+ pcireg_t v;
+ const int ich89_address_map_reg = 0x90;
+
+ pci_decompose_tag(pc, tag, &bus, &device, &function);
+ printf("%s: try %d:%d:%d\n", __func__, bus, device, function);
+
+ class = pci_conf_read(pc, tag, PCI_CLASS_REG);
+
+ printf("%s: classreg = 0x%08x, class = 0x%02x, subclass = 0x%02x\n",
+ __func__, class, PCI_CLASS(class), PCI_SUBCLASS(class));
+
+#if 0
+ if (PCI_CLASS(class) != PCI_CLASS_MASS_STORAGE ||
+ PCI_SUBCLASS(class) != PCI_SUBCLASS_MASS_STORAGE_IDE)
+ return;
+#endif
+ if (device != 31 || (function != 2 && function != 5))
+ return;
+
+ printf("Force Intel AHCI mode function\n");
+
+ v = pci_conf_read(pc, tag, ich89_address_map_reg);
+ printf("armval = 0x%08x\n", v);
+
+ v |= 0x40;
+ v &= ~0x80;
+
+ printf("write back armval = 0x%08x\n", v);
+
+ pci_conf_write(pc, tag, ich89_address_map_reg, v);
+
+ v = pci_conf_read(pc, tag, ich89_address_map_reg);
+
+ printf("updated armval = 0x%08x\n", v);
+
+ return;
+}
+
#ifndef PCI_MACHDEP_ENUMERATE_BUS
/*
* Generic PCI bus enumeration routine. Used unless machine-dependent
* code needs to provide something else.
@@ -815,11 +858,18 @@
if (qd != NULL &&
(qd->quirks & PCI_QUIRK_SKIP_FUNC(function)) != 0)
continue;
tag = pci_make_tag(pc, sc->sc_bus, device, function);
+
+ if (qd != NULL &&
+ (qd->quirks & PCI_QUIRK_FORCE_AHCI) != 0) {
+ pci_force_ahci(pc, tag);
+ }
+
ret = pci_probe_device(sc, tag, match, pap);
if (match != NULL && ret != 0)
return ret;
+
}
}
return 0;
}
Index: pci_quirks.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/pci_quirks.c,v
retrieving revision 1.12
diff -U4 -r1.12 pci_quirks.c
--- pci_quirks.c 17 Oct 2018 01:16:50 -0000 1.12
+++ pci_quirks.c 7 Sep 2024 02:31:51 -0000
@@ -52,8 +52,20 @@
{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_XEOND_MEM_0_TTR_1,
PCI_QUIRK_HASEXTCNF },
{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_COREI76K_IMC_0,
PCI_QUIRK_HASEXTCNF },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801GBM_LPC,
+ PCI_QUIRK_FORCE_AHCI },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801HEM_LPC,
+ PCI_QUIRK_FORCE_AHCI },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801IR_LPC,
+ PCI_QUIRK_FORCE_AHCI },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801IEM_LPC,
+ PCI_QUIRK_FORCE_AHCI },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801IM_LPC,
+ PCI_QUIRK_FORCE_AHCI },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801H_LPC,
+ PCI_QUIRK_FORCE_AHCI },
};
const struct pci_quirkdata *
pci_lookup_quirkdata(pci_vendor_id_t vendor, pci_product_id_t product)
Index: pcivar.h
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/pcivar.h,v
retrieving revision 1.117
diff -U4 -r1.117 pcivar.h
--- pcivar.h 27 Feb 2022 14:18:52 -0000 1.117
+++ pcivar.h 7 Sep 2024 02:31:51 -0000
@@ -228,8 +228,9 @@
#define PCI_QUIRK_SKIP_FUNC6 PCI_QUIRK_SKIP_FUNC(6)
#define PCI_QUIRK_SKIP_FUNC7 PCI_QUIRK_SKIP_FUNC(7)
#define PCI_QUIRK_HASEXTCNF __BIT(10)
#define PCI_QUIRK_NOEXTCNF __BIT(11)
+#define PCI_QUIRK_FORCE_AHCI __BIT(12)
struct pci_conf_state {
pcireg_t reg[16];
Home |
Main Index |
Thread Index |
Old Index