Index: dev/pci/hdaudio_pci.c =================================================================== RCS file: /cvsroot/src/sys/dev/pci/hdaudio_pci.c,v retrieving revision 1.8 diff -p -u -r1.8 hdaudio_pci.c --- dev/pci/hdaudio_pci.c 4 Jun 2017 23:34:55 -0000 1.8 +++ dev/pci/hdaudio_pci.c 28 Oct 2017 06:06:42 -0000 @@ -48,17 +48,21 @@ __KERNEL_RCSID(0, "$NetBSD: hdaudio_pci. #include #include +#include #include -#include #include struct hdaudio_pci_softc { - struct hdaudio_softc sc_hdaudio; /* must be first */ pcitag_t sc_tag; pci_chipset_tag_t sc_pc; void *sc_ih; pcireg_t sc_id; pci_intr_handle_t *sc_pihp; + bool sc_memvalid; + bus_addr_t sc_membase; + bus_size_t sc_memsize; + struct hdaudio_attach_args sc_hdaaa; + device_t sc_child; }; static int hdaudio_pci_match(device_t, cfdata_t, void *); @@ -74,7 +78,7 @@ static void hdaudio_pci_reinit(struct hd static bool hdaudio_pci_resume(device_t, const pmf_qual_t *); CFATTACH_DECL2_NEW( - hdaudio_pci, + hdaudiopci, sizeof(struct hdaudio_pci_softc), hdaudio_pci_match, hdaudio_pci_attach, @@ -118,7 +122,7 @@ hdaudio_pci_attach(device_t parent, devi sc->sc_tag = pa->pa_tag; sc->sc_id = pa->pa_id; - sc->sc_hdaudio.sc_subsystem = pci_conf_read(sc->sc_pc, sc->sc_tag, + sc->sc_hdaaa.hdaaa_subsystem = pci_conf_read(sc->sc_pc, sc->sc_tag, PCI_SUBSYS_ID_REG); /* Enable busmastering and MMIO access */ @@ -128,16 +132,16 @@ hdaudio_pci_attach(device_t parent, devi /* Map MMIO registers */ err = pci_mapreg_map(pa, HDAUDIO_PCI_AZBARL, PCI_MAPREG_TYPE_MEM, 0, - &sc->sc_hdaudio.sc_memt, - &sc->sc_hdaudio.sc_memh, - &sc->sc_hdaudio.sc_membase, - &sc->sc_hdaudio.sc_memsize); + &sc->sc_hdaaa.hdaaa_memt, + &sc->sc_hdaaa.hdaaa_memh, + &sc->sc_membase, + &sc->sc_memsize); if (err) { aprint_error_dev(self, "couldn't map mmio space\n"); return; } - sc->sc_hdaudio.sc_memvalid = true; - sc->sc_hdaudio.sc_dmat = pa->pa_dmat; + sc->sc_memvalid = true; + sc->sc_hdaaa.hdaaa_dmat = pa->pa_dmat; /* Map interrupt and establish handler */ if (pci_intr_alloc(pa, &sc->sc_pihp, NULL, 0)) { @@ -159,26 +163,12 @@ hdaudio_pci_attach(device_t parent, devi hdaudio_pci_reinit(sc); - /* Attach bus-independent HD audio layer */ - if (hdaudio_attach(self, &sc->sc_hdaudio)) { - pci_intr_disestablish(sc->sc_pc, sc->sc_ih); - pci_intr_release(sc->sc_pc, sc->sc_pihp, 1); - sc->sc_ih = NULL; - bus_space_unmap(sc->sc_hdaudio.sc_memt, - sc->sc_hdaudio.sc_memh, - sc->sc_hdaudio.sc_memsize); - sc->sc_hdaudio.sc_memvalid = false; - csr = pci_conf_read(sc->sc_pc, sc->sc_tag, - PCI_COMMAND_STATUS_REG); - csr &= ~(PCI_COMMAND_MASTER_ENABLE | PCI_COMMAND_BACKTOBACK_ENABLE); - pci_conf_write(sc->sc_pc, sc->sc_tag, - PCI_COMMAND_STATUS_REG, csr); - - if (!pmf_device_register(self, NULL, NULL)) - aprint_error_dev(self, "couldn't establish power handler\n"); - } - else if (!pmf_device_register(self, NULL, hdaudio_pci_resume)) + if (pmf_device_register(self, NULL, hdaudio_pci_resume)) aprint_error_dev(self, "couldn't establish power handler\n"); + + /* Attach bus-independent HD audio layer */ + sc->sc_child = config_found_ia(self, HDAUDIOPARENT_IA, &sc->sc_hdaaa, + NULL); } static int @@ -186,7 +176,11 @@ hdaudio_pci_rescan(device_t self, const { struct hdaudio_pci_softc *sc = device_private(self); - return hdaudio_rescan(&sc->sc_hdaudio, ifattr, locs); + if (ifattr_match(ifattr, HDAUDIOPARENT_IA) && sc->sc_child == NULL) + sc->sc_child = config_found_ia(self, HDAUDIOPARENT_IA, + &sc->sc_hdaaa, NULL); + + return 0; } void @@ -194,7 +188,8 @@ hdaudio_pci_childdet(device_t self, devi { struct hdaudio_pci_softc *sc = device_private(self); - hdaudio_childdet(&sc->sc_hdaudio, child); + KASSERT(child == sc->sc_child); + sc->sc_child = NULL; } static int @@ -202,19 +197,22 @@ hdaudio_pci_detach(device_t self, int fl { struct hdaudio_pci_softc *sc = device_private(self); pcireg_t csr; + int error; - hdaudio_detach(&sc->sc_hdaudio, flags); + error = config_detach_children(self, flags); + if (error) + return error; if (sc->sc_ih != NULL) { pci_intr_disestablish(sc->sc_pc, sc->sc_ih); pci_intr_release(sc->sc_pc, sc->sc_pihp, 1); sc->sc_ih = NULL; } - if (sc->sc_hdaudio.sc_memvalid == true) { - bus_space_unmap(sc->sc_hdaudio.sc_memt, - sc->sc_hdaudio.sc_memh, - sc->sc_hdaudio.sc_memsize); - sc->sc_hdaudio.sc_memvalid = false; + if (sc->sc_memvalid == true) { + bus_space_unmap(sc->sc_hdaaa.hdaaa_memt, + sc->sc_hdaaa.hdaaa_memh, + sc->sc_memsize); + sc->sc_memvalid = false; } /* Disable busmastering and MMIO access */ @@ -232,7 +230,10 @@ hdaudio_pci_intr(void *opaque) { struct hdaudio_pci_softc *sc = opaque; - return hdaudio_intr(&sc->sc_hdaudio); + if (sc->sc_child) + return hdaudio_intr(sc->sc_child); + else + return 0; /* not ours */ } @@ -266,44 +267,30 @@ hdaudio_pci_resume(device_t self, const struct hdaudio_pci_softc *sc = device_private(self); hdaudio_pci_reinit(sc); - return hdaudio_resume(&sc->sc_hdaudio); + return true; } MODULE(MODULE_CLASS_DRIVER, hdaudio_pci, "pci,hdaudio,audio"); #ifdef _MODULE -/* - * XXX Don't allow ioconf.c to redefine the "struct cfdriver hdaudio_cd" - * XXX it will be defined in the common hdaudio module - */ - -#undef CFDRIVER_DECL -#define CFDRIVER_DECL(name, class, attr) /* nothing */ #include "ioconf.c" #endif static int hdaudio_pci_modcmd(modcmd_t cmd, void *opaque) { -#ifdef _MODULE - /* - * We ignore the cfdriver_vec[] that ioconf provides, since - * the cfdrivers are attached already. - */ - static struct cfdriver * const no_cfdriver_vec[] = { NULL }; -#endif int error = 0; switch (cmd) { case MODULE_CMD_INIT: #ifdef _MODULE - error = config_init_component(no_cfdriver_vec, + error = config_init_component(cfdriver_ioconf_hdaudio_pci, cfattach_ioconf_hdaudio_pci, cfdata_ioconf_hdaudio_pci); #endif return error; case MODULE_CMD_FINI: #ifdef _MODULE - error = config_fini_component(no_cfdriver_vec, + error = config_fini_component(cfdriver_ioconf_hdaudio_pci, cfattach_ioconf_hdaudio_pci, cfdata_ioconf_hdaudio_pci); #endif return error; Index: dev/pci/files.pci =================================================================== RCS file: /cvsroot/src/sys/dev/pci/files.pci,v retrieving revision 1.391 diff -p -u -r1.391 files.pci --- dev/pci/files.pci 5 Sep 2017 08:01:43 -0000 1.391 +++ dev/pci/files.pci 28 Oct 2017 06:06:42 -0000 @@ -1080,8 +1080,9 @@ file dev/pci/voyager.c voyager defflag opt_voyager.h VOYAGER_DEBUG # High Definition Audio -attach hdaudio at pci with hdaudio_pci -file dev/pci/hdaudio_pci.c hdaudio_pci +device hdaudiopci: hdaudioparent +attach hdaudiopci at pci +file dev/pci/hdaudio_pci.c hdaudiopci # Permedia 2 / Sun PGX32 / Raptor device pm2fb: wsemuldisplaydev, rasops8, rasops32, vcons, videomode, i2cbus, i2c_bitbang, ddc_read_edid, edid, glyphcache Index: dev/hdaudio/files.hdaudio =================================================================== RCS file: /cvsroot/src/sys/dev/hdaudio/files.hdaudio,v retrieving revision 1.3 diff -p -u -r1.3 files.hdaudio --- dev/hdaudio/files.hdaudio 30 May 2015 13:47:03 -0000 1.3 +++ dev/hdaudio/files.hdaudio 28 Oct 2017 06:06:42 -0000 @@ -11,8 +11,14 @@ defflag opt_hdaudio.h HDAUDIO_32BIT_ACCE defflag opt_hdaudio.h HDAFG_DEBUG defflag opt_hdaudio.h HDAFG_HDMI_DEBUG +# interface attribute for hdaudio on parent bus, e.g. pci +define hdaudioparent { } + +# interface attribute for function groups on hdaudio bus define hdaudiobus {[nid = -1]} + device hdaudio: hdaudiobus +attach hdaudio at hdaudioparent file dev/hdaudio/hdaudio.c hdaudio file dev/hdaudio/hdaudio_verbose.c hdaudio & hdaudioverbose Index: dev/hdaudio/hdaudio.c =================================================================== RCS file: /cvsroot/src/sys/dev/hdaudio/hdaudio.c,v retrieving revision 1.5 diff -p -u -r1.5 hdaudio.c --- dev/hdaudio/hdaudio.c 4 Jun 2017 23:34:55 -0000 1.5 +++ dev/hdaudio/hdaudio.c 28 Oct 2017 06:06:42 -0000 @@ -41,6 +41,9 @@ __KERNEL_RCSID(0, "$NetBSD: hdaudio.c,v #include #include +#include "ioconf.h" + +#include "hdaudioparent.h" #include "hdaudiovar.h" #include "hdaudioreg.h" #include "hdaudioio.h" @@ -54,6 +57,17 @@ __KERNEL_RCSID(0, "$NetBSD: hdaudio.c,v #define HDAUDIO_CODEC_DELAY 1000 /* spec calls for 250 */ +static int hdaudio_match(device_t, cfdata_t, void *); +static void hdaudio_attach(device_t, device_t, void *); +static int hdaudio_detach(device_t, int); +static int hdaudio_rescan(device_t, const char *, const int *); +static void hdaudio_childdet(device_t, device_t); +static bool hdaudio_resume(device_t, const pmf_qual_t *); + +CFATTACH_DECL2_NEW(hdaudio, sizeof(struct hdaudio_softc), + hdaudio_match, hdaudio_attach, hdaudio_detach, + NULL, hdaudio_rescan, hdaudio_childdet); + dev_type_open(hdaudioopen); dev_type_close(hdaudioclose); dev_type_ioctl(hdaudioioctl); @@ -73,8 +87,6 @@ const struct cdevsw hdaudio_cdevsw = { .d_flag = D_OTHER }; -extern struct cfdriver hdaudio_cd; - #define HDAUDIOUNIT(x) minor((x)) static void @@ -789,17 +801,32 @@ hdaudio_stream_tag(struct hdaudio_stream return ret; } -int -hdaudio_attach(device_t dev, struct hdaudio_softc *sc) +static int +hdaudio_match(device_t parent, cfdata_t match, void *aux) { + + return 1; +} + +static void +hdaudio_attach(device_t parent, device_t dev, void *aux) +{ + const struct hdaudio_attach_args *hdaaa = aux; + struct hdaudio_softc *sc = device_private(dev); int err, i; - KASSERT(sc->sc_memvalid == true); + sc->sc_subsystem = hdaaa->hdaaa_subsystem; + sc->sc_memt = hdaaa->hdaaa_memt; + sc->sc_memh = hdaaa->hdaaa_memh; + sc->sc_dmat = hdaaa->hdaaa_dmat; sc->sc_dev = dev; mutex_init(&sc->sc_corb_mtx, MUTEX_DEFAULT, IPL_AUDIO); mutex_init(&sc->sc_stream_mtx, MUTEX_DEFAULT, IPL_AUDIO); + if (!pmf_device_register(dev, NULL, hdaudio_resume)) + aprint_error_dev(dev, "couldn't establish power handler\n"); + hdaudio_init(sc); /* @@ -879,12 +906,12 @@ hdaudio_attach(device_t dev, struct hdau fail: if (err) hda_error(sc, "device driver failed to attach\n"); - return err; } -int -hdaudio_detach(struct hdaudio_softc *sc, int flags) +static int +hdaudio_detach(device_t dev, int flags) { + struct hdaudio_softc *sc = device_private(dev); int error; /* Disable interrupts */ @@ -905,9 +932,11 @@ hdaudio_detach(struct hdaudio_softc *sc, return 0; } -bool -hdaudio_resume(struct hdaudio_softc *sc) +static bool +hdaudio_resume(device_t self, const pmf_qual_t *qual) { + struct hdaudio_softc *sc = device_private(self); + if (hdaudio_reset(sc) != 0) return false; @@ -938,9 +967,10 @@ hdaudio_resume(struct hdaudio_softc *sc) return true; } -int -hdaudio_rescan(struct hdaudio_softc *sc, const char *ifattr, const int *locs) +static int +hdaudio_rescan(device_t dev, const char *ifattr, const int *locs) { + struct hdaudio_softc *sc = device_private(dev); struct hdaudio_codec *co; struct hdaudio_function_group *fg; unsigned int codec; @@ -961,9 +991,10 @@ hdaudio_rescan(struct hdaudio_softc *sc, return 0; } -void -hdaudio_childdet(struct hdaudio_softc *sc, device_t child) +static void +hdaudio_childdet(device_t dev, device_t child) { + struct hdaudio_softc *sc = device_private(dev); struct hdaudio_codec *co; struct hdaudio_function_group *fg; unsigned int codec; @@ -979,8 +1010,9 @@ hdaudio_childdet(struct hdaudio_softc *s } int -hdaudio_intr(struct hdaudio_softc *sc) +hdaudio_intr(device_t self) { + struct hdaudio_softc *sc = device_private(self); struct hdaudio_stream *st; uint32_t intsts, stream_mask; int streamid = 0; @@ -1604,15 +1636,7 @@ hdaudioioctl(dev_t dev, u_long cmd, void MODULE(MODULE_CLASS_DRIVER, hdaudio, "audio"); #ifdef _MODULE -static const struct cfiattrdata hdaudiobuscf_iattrdata = { - "hdaudiobus", 1, { - { "nid", "-1", -1 }, - } -}; -static const struct cfiattrdata * const hdaudio_attrs[] = { - &hdaudiobuscf_iattrdata, NULL -}; -CFDRIVER_DECL(hdaudio, DV_AUDIODEV, hdaudio_attrs); +#include "ioconf.c" #endif static int @@ -1626,13 +1650,23 @@ hdaudio_modcmd(modcmd_t cmd, void *opaqu switch (cmd) { case MODULE_CMD_INIT: #ifdef _MODULE + error = config_init_component(cfdriver_ioconf_hdaudio, + cfattach_ioconf_hdaudio, cfdata_ioconf_hdaudio); + if (error) + break; error = devsw_attach("hdaudio", NULL, &bmaj, &hdaudio_cdevsw, &cmaj); - if (error) + if (error) { + (void)config_fini_component(cfdriver_ioconf_hdaudio, + cfattach_ioconf_hdaudio, cfdata_ioconf_hdaudio); break; + } error = config_cfdriver_attach(&hdaudio_cd); - if (error) - devsw_detach(NULL, &hdaudio_cdevsw); + if (error) { + (void)devsw_detach(NULL, &hdaudio_cdevsw); + (void)config_fini_component(cfdriver_ioconf_hdaudio, + cfattach_ioconf_hdaudio, cfdata_ioconf_hdaudio); + } #endif break; case MODULE_CMD_FINI: @@ -1645,6 +1679,14 @@ hdaudio_modcmd(modcmd_t cmd, void *opaqu config_cfdriver_attach(&hdaudio_cd); break; } + error = config_fini_component(cfdriver_ioconf_hdaudio, + cfattach_ioconf_hdaudio, cfdata_ioconf_hdaudio); + if (error) { + devsw_attach("hdaudio", NULL, &bmaj, + &hdaudio_cdevsw, &cmaj); + config_cfdriver_attach(&hdaudio_cd); + break; + } #endif break; default: Index: dev/hdaudio/hdaudioparent.h =================================================================== RCS file: dev/hdaudio/hdaudioparent.h diff -N dev/hdaudio/hdaudioparent.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ dev/hdaudio/hdaudioparent.h 28 Oct 2017 06:06:42 -0000 @@ -0,0 +1,49 @@ +/* $NetBSD$ */ + +/*- + * Copyright (c) 2017 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Taylor R. Campbell. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef DEV_HDAUDIO_HDAUDIOPARENT_H +#define DEV_HDAUDIO_HDAUDIOPARENT_H + +#include +#include + +struct hdaudio_attach_args { + uint32_t hdaaa_subsystem; + bus_space_tag_t hdaaa_memt; + bus_space_handle_t hdaaa_memh; + bus_dma_tag_t hdaaa_dmat; +}; + +#define HDAUDIOPARENT_IA "hdaudioparent" + +int hdaudio_intr(device_t); + +#endif /* DEV_HDAUDIO_HDAUDIOPARENT_H */ Index: dev/hdaudio/hdaudioreg.h =================================================================== RCS file: /cvsroot/src/sys/dev/hdaudio/hdaudioreg.h,v retrieving revision 1.1 diff -p -u -r1.1 hdaudioreg.h --- dev/hdaudio/hdaudioreg.h 28 Mar 2015 14:09:59 -0000 1.1 +++ dev/hdaudio/hdaudioreg.h 28 Oct 2017 06:06:43 -0000 @@ -32,6 +32,9 @@ #ifndef _HDAUDIOREG_H #define _HDAUDIOREG_H +#include +#include + /* * High Definition Audio Audio PCI Configuration Space */ Index: dev/hdaudio/hdaudiovar.h =================================================================== RCS file: /cvsroot/src/sys/dev/hdaudio/hdaudiovar.h,v retrieving revision 1.5 diff -p -u -r1.5 hdaudiovar.h --- dev/hdaudio/hdaudiovar.h 23 Dec 2015 12:45:06 -0000 1.5 +++ dev/hdaudio/hdaudiovar.h 28 Oct 2017 06:06:43 -0000 @@ -141,9 +141,6 @@ struct hdaudio_softc { bus_dma_tag_t sc_dmat; bus_space_tag_t sc_memt; bus_space_handle_t sc_memh; - bus_addr_t sc_membase; - bus_size_t sc_memsize; - bool sc_memvalid; uint32_t sc_subsystem; @@ -159,16 +156,9 @@ struct hdaudio_softc { kmutex_t sc_stream_mtx; }; -int hdaudio_attach(device_t, struct hdaudio_softc *); -int hdaudio_detach(struct hdaudio_softc *, int); -bool hdaudio_resume(struct hdaudio_softc *); -int hdaudio_rescan(struct hdaudio_softc *, const char *, const int *); -void hdaudio_childdet(struct hdaudio_softc *, device_t); - uint32_t hdaudio_command(struct hdaudio_codec *, int, uint32_t, uint32_t); uint32_t hdaudio_command_unlocked(struct hdaudio_codec *, int, uint32_t, uint32_t); -int hdaudio_intr(struct hdaudio_softc *); int hdaudio_dma_alloc(struct hdaudio_softc *, struct hdaudio_dma *, int); void hdaudio_dma_free(struct hdaudio_softc *, struct hdaudio_dma *); Index: modules/hdaudio/Makefile.inc =================================================================== RCS file: /cvsroot/src/sys/modules/hdaudio/Makefile.inc,v retrieving revision 1.3 diff -p -u -r1.3 Makefile.inc --- modules/hdaudio/Makefile.inc 2 Jun 2015 00:38:37 -0000 1.3 +++ modules/hdaudio/Makefile.inc 28 Oct 2017 06:06:43 -0000 @@ -1,4 +1,8 @@ # $NetBSD: Makefile.inc,v 1.3 2015/06/02 00:38:37 pooka Exp $ +IOCONFDIR:= ${.PARSEDIR} + .PATH: ${NETBSDSRCDIR}/sys/dev/hdaudio + +IOCONF= hdaudio.ioconf SRCS+= hdaudio.c Index: modules/hdaudio/hdaudio.ioconf =================================================================== RCS file: modules/hdaudio/hdaudio.ioconf diff -N modules/hdaudio/hdaudio.ioconf --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ modules/hdaudio/hdaudio.ioconf 28 Oct 2017 06:06:43 -0000 @@ -0,0 +1,9 @@ +# $NetBSD$ + +ioconf hdaudio + +include "conf/files" + +pseudo-root hdaudioparent* + +hdaudio* at hdaudioparent?