Fri Jan 7 15:30:30 2011 UTC ()
modularize hdaudio and hdafg drivers


(jmcneill)
diff -r1.8 -r1.9 src/sys/dev/pci/hdaudio/hdaudio.c
diff -r1.27 -r1.28 src/sys/dev/pci/hdaudio/hdaudio_afg.c
diff -r1.6 -r1.7 src/sys/dev/pci/hdaudio/hdaudio_pci.c
diff -r1.6 -r1.7 src/sys/dev/pci/hdaudio/hdaudiovar.h

cvs diff -r1.8 -r1.9 src/sys/dev/pci/hdaudio/Attic/hdaudio.c (expand / switch to context diff)
--- src/sys/dev/pci/hdaudio/Attic/hdaudio.c 2010/09/02 01:55:31 1.8
+++ src/sys/dev/pci/hdaudio/Attic/hdaudio.c 2011/01/07 15:30:29 1.9
@@ -1,4 +1,4 @@
-/* $NetBSD: hdaudio.c,v 1.8 2010/09/02 01:55:31 jmcneill Exp $ */
+/* $NetBSD: hdaudio.c,v 1.9 2011/01/07 15:30:29 jmcneill Exp $ */
 
 /*
  * Copyright (c) 2009 Precedence Technologies Ltd <support@precedence.co.uk>
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: hdaudio.c,v 1.8 2010/09/02 01:55:31 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: hdaudio.c,v 1.9 2011/01/07 15:30:29 jmcneill Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -39,6 +39,7 @@
 #include <sys/conf.h>
 #include <sys/bus.h>
 #include <sys/kmem.h>
+#include <sys/module.h>
 
 #include <dev/pci/hdaudio/hdaudiovar.h>
 #include <dev/pci/hdaudio/hdaudioreg.h>
@@ -865,6 +866,46 @@
 }
 
 int
+hdaudio_rescan(struct hdaudio_softc *sc, const char *ifattr, const int *locs)
+{
+	struct hdaudio_codec *co;
+	struct hdaudio_function_group *fg;
+	unsigned int codec;
+
+	if (!ifattr_match(ifattr, "hdaudiobus"))
+		return 0;
+
+	for (codec = 0; codec < HDAUDIO_MAX_CODECS; codec++) {
+		co = &sc->sc_codec[codec];
+		fg = co->co_fg;
+		if (!co->co_valid || fg == NULL)
+			continue;
+		if (fg->fg_device)
+			continue;
+		hdaudio_attach_fg(fg, NULL);
+	}
+
+	return 0;
+}
+
+void
+hdaudio_childdet(struct hdaudio_softc *sc, device_t child)
+{
+	struct hdaudio_codec *co;
+	struct hdaudio_function_group *fg;
+	unsigned int codec;
+
+	for (codec = 0; codec < HDAUDIO_MAX_CODECS; codec++) {
+		co = &sc->sc_codec[codec];
+		fg = co->co_fg;
+		if (!co->co_valid || fg == NULL)
+			continue;
+		if (fg->fg_device == child)
+			fg->fg_device = NULL;
+	}
+}
+
+int
 hdaudio_intr(struct hdaudio_softc *sc)
 {
 	struct hdaudio_stream *st;
@@ -1348,8 +1389,12 @@
     prop_dictionary_t request, prop_dictionary_t response)
 {
 	struct hdaudio_function_group *fg;
+	int (*infocb)(void *, prop_dictionary_t, prop_dictionary_t);
+	prop_dictionary_t fgrp_dict;
+	uint64_t info_fn;
 	int16_t codecid, nid;
 	void *fgrp_sc; 
+	bool rv;
 	int err;
 
 	if (!prop_dictionary_get_int16(request, "codecid", &codecid) ||
@@ -1360,17 +1405,26 @@
 	if (fg == NULL)
 		return ENODEV;
 	fgrp_sc = device_private(fg->fg_device);
+	fgrp_dict = device_properties(fg->fg_device);
 
 	switch (fg->fg_type) {
 	case HDAUDIO_GROUP_TYPE_AFG:
 		switch (cmd) {
 		case HDAUDIO_FGRP_CODEC_INFO:
-			err = hdaudio_afg_codec_info(fgrp_sc,
-			    request, response);
+			rv = prop_dictionary_get_uint64(fgrp_dict,
+			    "codecinfo-callback", &info_fn);
+			if (!rv)
+				return ENXIO;
+			infocb = (void *)(uintptr_t)info_fn;
+			err = infocb(fgrp_sc, request, response);
 			break;
 		case HDAUDIO_FGRP_WIDGET_INFO:
-			err = hdaudio_afg_widget_info(fgrp_sc,
-			    request, response);
+			rv = prop_dictionary_get_uint64(fgrp_dict,
+			    "widgetinfo-callback", &info_fn);
+			if (!rv)
+				return ENXIO;
+			infocb = (void *)(uintptr_t)info_fn;
+			err = infocb(fgrp_sc, request, response);
 			break;
 		default:
 			err = EINVAL;
@@ -1451,4 +1505,44 @@
 		prop_object_release(response);
 	prop_object_release(request);
 	return err;
+}
+
+MODULE(MODULE_CLASS_DRIVER, hdaudio, NULL);
+
+#ifdef _MODULE
+#include "ioconf.c"
+#endif
+
+static int
+hdaudio_modcmd(modcmd_t cmd, void *opaque)
+{
+	int error = 0;
+#ifdef _MODULE
+	int bmaj = -1, cmaj = -1;
+#endif
+
+	switch (cmd) {
+	case MODULE_CMD_INIT:
+#ifdef _MODULE
+		error = config_init_component(cfdriver_ioconf_hdaudio,
+		    cfattach_ioconf_hdaudio, cfdata_ioconf_hdaudio);
+		if (error)
+			return error;
+		error = devsw_attach("hdaudio", NULL, &bmaj,
+		    &hdaudio_cdevsw, &cmaj);
+		if (error)
+			config_fini_component(cfdriver_ioconf_hdaudio,
+			    cfattach_ioconf_hdaudio, cfdata_ioconf_hdaudio);
+#endif
+		return error;
+	case MODULE_CMD_FINI:
+#ifdef _MODULE
+		devsw_detach(NULL, &hdaudio_cdevsw);
+		error = config_fini_component(cfdriver_ioconf_hdaudio,
+		    cfattach_ioconf_hdaudio, cfdata_ioconf_hdaudio);
+#endif
+		return error;
+	default:
+		return ENOTTY;
+	}
 }

cvs diff -r1.27 -r1.28 src/sys/dev/pci/hdaudio/Attic/hdaudio_afg.c (expand / switch to context diff)
--- src/sys/dev/pci/hdaudio/Attic/hdaudio_afg.c 2010/09/02 01:55:31 1.27
+++ src/sys/dev/pci/hdaudio/Attic/hdaudio_afg.c 2011/01/07 15:30:29 1.28
@@ -1,4 +1,4 @@
-/* $NetBSD: hdaudio_afg.c,v 1.27 2010/09/02 01:55:31 jmcneill Exp $ */
+/* $NetBSD: hdaudio_afg.c,v 1.28 2011/01/07 15:30:29 jmcneill Exp $ */
 
 /*
  * Copyright (c) 2009 Precedence Technologies Ltd <support@precedence.co.uk>
@@ -60,7 +60,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: hdaudio_afg.c,v 1.27 2010/09/02 01:55:31 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: hdaudio_afg.c,v 1.28 2011/01/07 15:30:29 jmcneill Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -70,6 +70,7 @@
 #include <sys/conf.h>
 #include <sys/bus.h>
 #include <sys/kmem.h>
+#include <sys/module.h>
 
 #include <sys/audioio.h>
 #include <dev/audio_if.h>
@@ -321,6 +322,11 @@
 static bool	hdaudio_afg_suspend(device_t, const pmf_qual_t *);
 static bool	hdaudio_afg_resume(device_t, const pmf_qual_t *);
 
+static int	hdaudio_afg_widget_info(void *, prop_dictionary_t,
+					prop_dictionary_t);
+static int	hdaudio_afg_codec_info(void *, prop_dictionary_t,
+				       prop_dictionary_t);
+
 CFATTACH_DECL2_NEW(
     hdafg,
     sizeof(struct hdaudio_afg_softc),
@@ -378,7 +384,7 @@
 	.get_props		= hdaudio_afg_get_props,
 	.trigger_output		= hdaudio_afg_trigger_output,
 	.trigger_input		= hdaudio_afg_trigger_input,
-	.dev_ioctl		= hdaudio_afg_dev_ioctl
+	.dev_ioctl		= hdaudio_afg_dev_ioctl,
 };
 
 static int
@@ -3729,7 +3735,7 @@
 	return 0;
 }
 
-int
+static int
 hdaudio_afg_widget_info(void *opaque, prop_dictionary_t request,
     prop_dictionary_t response)
 {
@@ -3774,7 +3780,7 @@
 	return 0;
 }
 
-int
+static int
 hdaudio_afg_codec_info(void *opaque, prop_dictionary_t request,
     prop_dictionary_t response)
 {
@@ -3824,4 +3830,33 @@
 		prop_object_release(response);
 	prop_object_release(request);
 	return err;
+}
+
+MODULE(MODULE_CLASS_DRIVER, hdafg, "hdaudio");
+
+#ifdef _MODULE
+#include "ioconf.c"
+#endif
+
+static int
+hdafg_modcmd(modcmd_t cmd, void *opaque)
+{
+	int error;
+
+	switch (cmd) {
+	case MODULE_CMD_INIT:
+#ifdef _MODULE
+		error = config_init_component(cfdriver_ioconf_hdafg,
+		    cfattach_ioconf_hdafg, cfdata_ioconf_hdafg);
+#endif
+		return error;
+	case MODULE_CMD_FINI:
+#ifdef _MODULE
+		error = config_fini_component(cfdriver_ioconf_hdafg,
+		    cfattach_ioconf_hdafg, cfdata_ioconf_hdafg);
+#endif
+		return error;
+	default:
+		return ENOTTY;
+	}
 }

cvs diff -r1.6 -r1.7 src/sys/dev/pci/hdaudio/Attic/hdaudio_pci.c (expand / switch to context diff)
--- src/sys/dev/pci/hdaudio/Attic/hdaudio_pci.c 2010/08/07 16:59:48 1.6
+++ src/sys/dev/pci/hdaudio/Attic/hdaudio_pci.c 2011/01/07 15:30:30 1.7
@@ -1,4 +1,4 @@
-/* $NetBSD: hdaudio_pci.c,v 1.6 2010/08/07 16:59:48 jmcneill Exp $ */
+/* $NetBSD: hdaudio_pci.c,v 1.7 2011/01/07 15:30:30 jmcneill Exp $ */
 
 /*
  * Copyright (c) 2009 Precedence Technologies Ltd <support@precedence.co.uk>
@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: hdaudio_pci.c,v 1.6 2010/08/07 16:59:48 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: hdaudio_pci.c,v 1.7 2011/01/07 15:30:30 jmcneill Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -61,6 +61,7 @@
 static int		hdaudio_pci_match(device_t, cfdata_t, void *);
 static void		hdaudio_pci_attach(device_t, device_t, void *);
 static int		hdaudio_pci_detach(device_t, int);
+static int		hdaudio_pci_rescan(device_t, const char *, const int *);
 static void		hdaudio_pci_childdet(device_t, device_t);
 
 static int		hdaudio_pci_intr(void *);
@@ -75,7 +76,7 @@
     hdaudio_pci_attach,
     hdaudio_pci_detach,
     NULL,
-    NULL,
+    hdaudio_pci_rescan,
     hdaudio_pci_childdet
 );
 
@@ -170,14 +171,20 @@
 	hdaudio_attach(self, &sc->sc_hdaudio);
 }
 
+static int
+hdaudio_pci_rescan(device_t self, const char *ifattr, const int *locs)
+{
+	struct hdaudio_pci_softc *sc = device_private(self);
+
+	return hdaudio_rescan(&sc->sc_hdaudio, ifattr, locs);
+}
+
 void
 hdaudio_pci_childdet(device_t self, device_t child)
 {
-#if notyet
 	struct hdaudio_pci_softc *sc = device_private(self);
 
 	hdaudio_childdet(&sc->sc_hdaudio, child);
-#endif
 }
 
 static int

cvs diff -r1.6 -r1.7 src/sys/dev/pci/hdaudio/Attic/hdaudiovar.h (expand / switch to context diff)
--- src/sys/dev/pci/hdaudio/Attic/hdaudiovar.h 2010/08/15 19:39:56 1.6
+++ src/sys/dev/pci/hdaudio/Attic/hdaudiovar.h 2011/01/07 15:30:30 1.7
@@ -1,4 +1,4 @@
-/* $NetBSD: hdaudiovar.h,v 1.6 2010/08/15 19:39:56 jmcneill Exp $ */
+/* $NetBSD: hdaudiovar.h,v 1.7 2011/01/07 15:30:30 jmcneill Exp $ */
 
 /*
  * Copyright (c) 2009 Precedence Technologies Ltd <support@precedence.co.uk>
@@ -163,6 +163,9 @@
 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);
 int	hdaudio_intr(struct hdaudio_softc *);
 
@@ -179,8 +182,5 @@
 void	hdaudio_stream_reset(struct hdaudio_stream *);
 int	hdaudio_stream_tag(struct hdaudio_stream *);
 uint16_t hdaudio_stream_param(struct hdaudio_stream *, const audio_params_t *);
-
-int	hdaudio_afg_widget_info(void *, prop_dictionary_t, prop_dictionary_t);
-int	hdaudio_afg_codec_info(void *, prop_dictionary_t, prop_dictionary_t);
 
 #endif /* !_HDAUDIOVAR_H */