From owner-svn-src-all@freebsd.org Sun Jul 30 15:19:08 2017 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 4F911DBD6C8; Sun, 30 Jul 2017 15:19:08 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 2BAF074928; Sun, 30 Jul 2017 15:19:08 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v6UFJ7Ed004184; Sun, 30 Jul 2017 15:19:07 GMT (envelope-from mav@FreeBSD.org) Received: (from mav@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v6UFJ7AT004183; Sun, 30 Jul 2017 15:19:07 GMT (envelope-from mav@FreeBSD.org) Message-Id: <201707301519.v6UFJ7AT004183@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mav set sender to mav@FreeBSD.org using -f From: Alexander Motin Date: Sun, 30 Jul 2017 15:19:07 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r321720 - head/sys/dev/ichwd X-SVN-Group: head X-SVN-Commit-Author: mav X-SVN-Commit-Paths: head/sys/dev/ichwd X-SVN-Commit-Revision: 321720 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 30 Jul 2017 15:19:08 -0000 Author: mav Date: Sun Jul 30 15:19:07 2017 New Revision: 321720 URL: https://svnweb.freebsd.org/changeset/base/321720 Log: Attach ichwd(4) only to ISA bus of the LPC bridge. Resource allocation for parent device does not look good by itself, but attempt to allocate them for unrelated device just does not end up good. On Asus X99-E WS/USB3.1 system reporting ISA bridge via both PCI and ACPI this reported to cause kernel panic on shutdown due to messed resources: https://bugs.freenas.org/issues/25237. MFC after: 1 week Modified: head/sys/dev/ichwd/ichwd.c Modified: head/sys/dev/ichwd/ichwd.c ============================================================================== --- head/sys/dev/ichwd/ichwd.c Sun Jul 30 11:50:16 2017 (r321719) +++ head/sys/dev/ichwd/ichwd.c Sun Jul 30 15:19:07 2017 (r321720) @@ -533,23 +533,26 @@ ichwd_event(void *arg, unsigned int cmd, int *error) } static device_t -ichwd_find_ich_lpc_bridge(struct ichwd_device **id_p) +ichwd_find_ich_lpc_bridge(device_t isa, struct ichwd_device **id_p) { struct ichwd_device *id; - device_t ich = NULL; + device_t isab; + uint16_t devid; - /* look for an ICH LPC interface bridge */ - for (id = ichwd_devices; id->desc != NULL; ++id) - if ((ich = pci_find_device(VENDORID_INTEL, id->device)) != NULL) - break; - - if (ich == NULL) + /* Check whether parent ISA bridge looks familiar. */ + isab = device_get_parent(isa); + if (pci_get_vendor(isab) != VENDORID_INTEL) return (NULL); + devid = pci_get_device(isab); + for (id = ichwd_devices; id->desc != NULL; ++id) { + if (devid == id->device) { + if (id_p != NULL) + *id_p = id; + return (isab); + } + } - if (id_p) - *id_p = id; - - return (ich); + return (NULL); } /* @@ -565,7 +568,7 @@ ichwd_identify(driver_t *driver, device_t parent) uint32_t base_address; int rc; - ich = ichwd_find_ich_lpc_bridge(&id_p); + ich = ichwd_find_ich_lpc_bridge(parent, &id_p); if (ich == NULL) return; @@ -618,7 +621,7 @@ ichwd_probe(device_t dev) if (isa_get_logicalid(dev) != 0) return (ENXIO); - if (ichwd_find_ich_lpc_bridge(&id_p) == NULL) + if (ichwd_find_ich_lpc_bridge(device_get_parent(dev), &id_p) == NULL) return (ENXIO); device_set_desc_copy(dev, id_p->desc); @@ -636,7 +639,7 @@ ichwd_attach(device_t dev) sc = device_get_softc(dev); sc->device = dev; - ich = ichwd_find_ich_lpc_bridge(&id_p); + ich = ichwd_find_ich_lpc_bridge(device_get_parent(dev), &id_p); if (ich == NULL) { device_printf(sc->device, "Can not find ICH device.\n"); goto fail; @@ -726,7 +729,6 @@ static int ichwd_detach(device_t dev) { struct ichwd_softc *sc; - device_t ich = NULL; sc = device_get_softc(dev); @@ -751,9 +753,8 @@ ichwd_detach(device_t dev) bus_release_resource(dev, SYS_RES_IOPORT, sc->smi_rid, sc->smi_res); /* deallocate memory resource */ - ich = ichwd_find_ich_lpc_bridge(NULL); - if (sc->gcs_res && ich) - bus_release_resource(ich, SYS_RES_MEMORY, sc->gcs_rid, + if (sc->gcs_res) + bus_release_resource(sc->ich, SYS_RES_MEMORY, sc->gcs_rid, sc->gcs_res); return (0);