Date: Mon, 22 Apr 2019 04:07:52 +0000 (UTC) From: Ian Lepore <ian@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r346520 - in stable/11/sys: arm/freescale/imx arm/freescale/vybrid dev/usb/controller Message-ID: <201904220407.x3M47qR4004937@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: ian Date: Mon Apr 22 04:07:51 2019 New Revision: 346520 URL: https://svnweb.freebsd.org/changeset/base/346520 Log: MFC r335982, r335985, r335988-r335989 r335982: Fix an out-of-bounds array access... the irq data for teardown is in two arrays, as elements 0 and 1 of one array and elements 1 and 2 of the other. Run the loop 0..1 instead of 1..2 and use named constants to offset into one of the arrays. PR: 229508 r335985: Remove a test and early-out which just can't possibly be right. It causes detach() to do nothing if attach() succeeded, which is the opposite of what's needed. Also, move device_delete_children() from the end to the beginning of detach(), so that children won't be trying to make use of the hardware we're in the process of shutting down. PR: 229510 r335988: Add a missing call to usb_bus_mem_free_all() when detaching. r335989: Detach all children before beginning to tear down the hardware, instead of doing it last. Also, remove the local tracking of whether usb's busdma memory allocation got done, because it's safe to call the free_all function even if it wasn't. Modified: stable/11/sys/arm/freescale/imx/imx_gpio.c stable/11/sys/arm/freescale/vybrid/vf_ehci.c stable/11/sys/dev/usb/controller/ehci_imx.c Directory Properties: stable/11/ (props changed) Modified: stable/11/sys/arm/freescale/imx/imx_gpio.c ============================================================================== --- stable/11/sys/arm/freescale/imx/imx_gpio.c Mon Apr 22 04:02:16 2019 (r346519) +++ stable/11/sys/arm/freescale/imx/imx_gpio.c Mon Apr 22 04:07:51 2019 (r346520) @@ -135,6 +135,8 @@ static struct resource_spec imx_gpio_spec[] = { { SYS_RES_IRQ, 1, RF_ACTIVE }, { -1, 0 } }; +#define FIRST_IRQRES 1 +#define NUM_IRQRES 2 /* * Helpers @@ -853,9 +855,10 @@ imx51_gpio_detach(device_t dev) sc = device_get_softc(dev); gpiobus_detach_bus(dev); - for (irq = 1; irq <= 2; irq++) { + for (irq = 0; irq < NUM_IRQRES; irq++) { if (sc->gpio_ih[irq]) - bus_teardown_intr(dev, sc->sc_res[irq], sc->gpio_ih[irq]); + bus_teardown_intr(dev, sc->sc_res[irq + FIRST_IRQRES], + sc->gpio_ih[irq]); } bus_release_resources(dev, imx_gpio_spec, sc->sc_res); mtx_destroy(&sc->sc_mtx); Modified: stable/11/sys/arm/freescale/vybrid/vf_ehci.c ============================================================================== --- stable/11/sys/arm/freescale/vybrid/vf_ehci.c Mon Apr 22 04:02:16 2019 (r346519) +++ stable/11/sys/arm/freescale/vybrid/vf_ehci.c Mon Apr 22 04:07:51 2019 (r346520) @@ -390,8 +390,9 @@ vybrid_ehci_detach(device_t dev) esc = device_get_softc(dev); sc = &esc->base; - if (sc->sc_flags & EHCI_SCFLG_DONEINIT) - return (0); + /* First detach all children; we can't detach if that fails. */ + if ((err = device_delete_children(dev)) != 0) + return (err); /* * only call ehci_detach() after ehci_init() @@ -420,13 +421,7 @@ vybrid_ehci_detach(device_t dev) sc->sc_intr_hdl = NULL; } - if (sc->sc_bus.bdev) { - device_delete_child(dev, sc->sc_bus.bdev); - sc->sc_bus.bdev = NULL; - } - - /* During module unload there are lots of children leftover */ - device_delete_children(dev); + usb_bus_mem_free_all(&sc->sc_bus, &ehci_iterate_hw_softc); bus_release_resources(dev, vybrid_ehci_spec, esc->res); Modified: stable/11/sys/dev/usb/controller/ehci_imx.c ============================================================================== --- stable/11/sys/dev/usb/controller/ehci_imx.c Mon Apr 22 04:02:16 2019 (r346519) +++ stable/11/sys/dev/usb/controller/ehci_imx.c Mon Apr 22 04:07:51 2019 (r346520) @@ -266,7 +266,6 @@ struct imx_ehci_softc { device_t dev; struct resource *ehci_mem_res; /* EHCI core regs. */ struct resource *ehci_irq_res; /* EHCI core IRQ. */ - bool usb_mem_allocated; }; static struct ofw_compat_data compat_data[] = { @@ -311,13 +310,16 @@ imx_ehci_detach(device_t dev) { struct imx_ehci_softc *sc; ehci_softc_t *esc; + int err; sc = device_get_softc(dev); esc = &sc->ehci_softc; - if (esc->sc_bus.bdev != NULL) - device_delete_child(dev, esc->sc_bus.bdev); + /* First detach all children; we can't detach if that fails. */ + if ((err = device_delete_children(dev)) != 0) + return (err); + if (esc->sc_flags & EHCI_SCFLG_DONEINIT) ehci_detach(esc); if (esc->sc_intr_hdl != NULL) @@ -330,12 +332,8 @@ imx_ehci_detach(device_t dev) bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->ehci_mem_res); - if (sc->usb_mem_allocated) - usb_bus_mem_free_all(&esc->sc_bus, &ehci_iterate_hw_softc); + usb_bus_mem_free_all(&esc->sc_bus, &ehci_iterate_hw_softc); - /* During module unload there are lots of children leftover */ - device_delete_children(dev); - return (0); } @@ -413,7 +411,6 @@ imx_ehci_attach(device_t dev) err = ENOMEM; goto out; } - sc->usb_mem_allocated = true; /* * Set handle to USB related registers subregion used by
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201904220407.x3M47qR4004937>