From 6589c7619ebe1d6df15a9228bd3db866fe36e4bc Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Wed, 21 Jan 2015 20:50:25 +0800 Subject: [PATCH] ecc: Use identify to add ecc device for E3-1200 memory controllers Misc - Disable ecc for X3400 temporarily; it seems to use E5 style ecc registers accessing method, which needs further investigation. - Ecc should not be forcefully added to hostb Tested-by: dillon@ on E3-1200 and E3-1200v3 --- sys/bus/pci/hostb_pci.c | 1 - sys/conf/files | 3 ++- sys/dev/misc/ecc/Makefile | 3 ++- sys/dev/misc/ecc/ecc_amd8000.c | 2 +- sys/dev/misc/ecc/ecc_e31200.c | 31 ++++++++++++++++++++++++++++--- 5 files changed, 33 insertions(+), 7 deletions(-) diff --git a/sys/bus/pci/hostb_pci.c b/sys/bus/pci/hostb_pci.c index 522ba2ab70..880a6a3505 100644 --- a/sys/bus/pci/hostb_pci.c +++ b/sys/bus/pci/hostb_pci.c @@ -81,7 +81,6 @@ pci_hostb_attach(device_t dev) */ if (pci_find_extcap(dev, PCIY_AGP, NULL) == 0) device_add_child(dev, "agp", -1); - device_add_child(dev, "ecc", -1); bus_generic_attach(dev); return (0); } diff --git a/sys/conf/files b/sys/conf/files index 73a159efa7..6b013d10c8 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -1684,7 +1684,8 @@ bus/isa/pnpeat.c optional isa dev/misc/amdsbwd/amdsbwd.c optional amdsbwd dev/misc/ecc/ecc_amd8000.c optional ecc dev/misc/ecc/ecc_e31200.c optional ecc -dev/misc/ecc/ecc_x3400.c optional ecc +# not ready yet +#dev/misc/ecc/ecc_x3400.c optional ecc dev/misc/joy/joy.c optional joy dev/misc/kbdmux/kbdmux.c optional kbdmux dev/misc/orm/orm.c optional isa diff --git a/sys/dev/misc/ecc/Makefile b/sys/dev/misc/ecc/Makefile index f1175314be..d85134cb80 100644 --- a/sys/dev/misc/ecc/Makefile +++ b/sys/dev/misc/ecc/Makefile @@ -1,5 +1,6 @@ KMOD = ecc -SRCS = ecc_amd8000.c ecc_e31200.c ecc_x3400.c +SRCS = ecc_amd8000.c ecc_e31200.c +#ecc_x3400.c SRCS += device_if.h bus_if.h pci_if.h pcib_if.h .include diff --git a/sys/dev/misc/ecc/ecc_amd8000.c b/sys/dev/misc/ecc/ecc_amd8000.c index 2263b878fa..a45c138aff 100644 --- a/sys/dev/misc/ecc/ecc_amd8000.c +++ b/sys/dev/misc/ecc/ecc_amd8000.c @@ -93,7 +93,7 @@ static driver_t ecc_amd8000_driver = { sizeof(struct ecc_amd8000_softc) }; static devclass_t ecc_devclass; -DRIVER_MODULE(ecc_amd8000, hostb, ecc_amd8000_driver, ecc_devclass, NULL, NULL); +DRIVER_MODULE(ecc_amd8000, pci, ecc_amd8000_driver, ecc_devclass, NULL, NULL); MODULE_DEPEND(ecc_amd8000, pci, 1, 1, 1); static int diff --git a/sys/dev/misc/ecc/ecc_e31200.c b/sys/dev/misc/ecc/ecc_e31200.c index 4db3d2cc57..5dc6ac2f65 100644 --- a/sys/dev/misc/ecc/ecc_e31200.c +++ b/sys/dev/misc/ecc/ecc_e31200.c @@ -75,6 +75,7 @@ struct ecc_e31200_softc { #define ecc_printf(sc, fmt, arg...) \ device_printf((sc)->ecc_mydev, fmt , ##arg) +static void ecc_e31200_identify(driver_t *, device_t); static int ecc_e31200_probe(device_t); static int ecc_e31200_attach(device_t); static int ecc_e31200_detach(device_t); @@ -100,6 +101,7 @@ static const struct ecc_e31200_memctrl ecc_memctrls[] = { static device_method_t ecc_e31200_methods[] = { /* Device interface */ + DEVMETHOD(device_identify, ecc_e31200_identify), DEVMETHOD(device_probe, ecc_e31200_probe), DEVMETHOD(device_attach, ecc_e31200_attach), DEVMETHOD(device_detach, ecc_e31200_detach), @@ -118,14 +120,37 @@ static devclass_t ecc_devclass; DRIVER_MODULE(ecc_e31200, hostb, ecc_e31200_driver, ecc_devclass, NULL, NULL); MODULE_DEPEND(ecc_e31200, pci, 1, 1, 1); +static void +ecc_e31200_identify(driver_t *driver, device_t parent) +{ + const struct ecc_e31200_memctrl *mc; + uint16_t vid, did; + + /* Already identified */ + if (device_find_child(parent, "ecc", -1) != NULL) + return; + + vid = pci_get_vendor(parent); + did = pci_get_device(parent); + + for (mc = ecc_memctrls; mc->desc != NULL; ++mc) { + if (mc->vid == vid && mc->did == did) { + if (device_add_child(parent, "ecc", -1) == NULL) + device_printf(parent, "add ecc child failed\n"); + return; + } + } +} + static int ecc_e31200_probe(device_t dev) { + device_t parent = device_get_parent(dev); const struct ecc_e31200_memctrl *mc; uint16_t vid, did; - vid = pci_get_vendor(dev); - did = pci_get_device(dev); + vid = pci_get_vendor(parent); + did = pci_get_device(parent); for (mc = ecc_memctrls; mc->desc != NULL; ++mc) { if (mc->vid == vid && mc->did == did) { @@ -133,7 +158,7 @@ ecc_e31200_probe(device_t dev) device_set_desc(dev, mc->desc); sc->ecc_mydev = dev; - sc->ecc_device = device_get_parent(dev); + sc->ecc_device = parent; sc->ecc_ver = mc->ver; return (0); } -- 2.41.0