? sys/dev/acpi/wmi/wmi_twinhead.c
Index: sys/kern/kern_module.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_module.c,v
retrieving revision 1.73
diff -u -r1.73 kern_module.c
--- sys/kern/kern_module.c 16 Oct 2010 18:09:02 -0000 1.73
+++ sys/kern/kern_module.c 27 Oct 2010 09:11:40 -0000
@@ -78,6 +78,9 @@
static int module_thread_ticks;
int (*module_load_vfs_vec)(const char *, int, bool, module_t *,
prop_dictionary_t *) = (void *)eopnotsupp;
+int (*module_cfload_vfs_vec)(void *,
+ int (*)(void *, const char *, prop_dictionary_t)) =
+ (void *)eopnotsupp;
static kauth_listener_t module_listener;
@@ -577,6 +580,18 @@
}
/*
+ * module_cfload:
+ *
+ * Search the filesystem and load modules based on match criteria.
+ */
+int
+module_cfload(void *opaque,
+ int (*match)(void *, const char *, prop_dictionary_t))
+{
+ return module_cfload_vfs_vec(opaque, match);
+}
+
+/*
* module_unload:
*
* Find and unload a module by name.
Index: sys/kern/kern_module_vfs.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_module_vfs.c,v
retrieving revision 1.7
diff -u -r1.7 kern_module_vfs.c
--- sys/kern/kern_module_vfs.c 24 Jun 2010 13:03:11 -0000 1.7
+++ sys/kern/kern_module_vfs.c 27 Oct 2010 09:11:40 -0000
@@ -46,16 +46,23 @@
#include <sys/pool.h>
#include <sys/stat.h>
#include <sys/vnode.h>
+#include <sys/dirent.h>
+
+#include <ufs/ufs/dir.h> /* for DIRBLKSIZ */
#include <prop/proplib.h>
static int module_load_plist_vfs(const char *, const bool,
prop_dictionary_t *);
+static int module_cfload_vfs_probe(void *opaque,
+ int (*match)(void *, const char *, prop_dictionary_t),
+ const char *);
void
module_load_vfs_init(void)
{
module_load_vfs_vec = module_load_vfs;
+ module_cfload_vfs_vec = module_cfload_vfs;
}
int
@@ -118,6 +125,146 @@
return error;
}
+int
+module_cfload_vfs_probe(void *opaque,
+ int (*match)(void *, const char *, prop_dictionary_t),
+ const char *modname)
+{
+ prop_dictionary_t filedict, dict;
+ prop_object_iterator_t iter;
+ prop_object_t obj;
+ prop_array_t arr;
+ const char *ifattr;
+ char *modpath;
+ int error;
+
+ modpath = PNBUF_GET();
+ snprintf(modpath, MAXPATHLEN, "%s/%s/%s.kmod",
+ module_base, modname, modname);
+
+ error = module_load_plist_vfs(modpath, true, &filedict);
+ if (error)
+ return 0;
+
+ obj = prop_dictionary_get(filedict, "ModuleInfo");
+ if (obj == NULL || prop_object_type(obj) != PROP_TYPE_ARRAY)
+ goto badprops;
+
+ arr = (prop_array_t)obj;
+ iter = prop_array_iterator(arr);
+ while ((obj = prop_object_iterator_next(iter)) != NULL) {
+ if (prop_object_type(obj) != PROP_TYPE_DICTIONARY)
+ continue;
+ dict = (prop_dictionary_t)obj;
+ if (prop_dictionary_get_cstring_nocopy(dict, "CFInterface",
+ &ifattr) == false)
+ continue;
+ if (match(opaque, ifattr, dict)) {
+ module_print("Loading %s\n", modpath);
+ module_load(modpath, 0, filedict, MODULE_CLASS_ANY);
+ break;
+ }
+ }
+ prop_object_iterator_release(iter);
+
+badprops:
+ prop_object_release(filedict);
+ PNBUF_PUT(modpath);
+
+ return 0;
+}
+
+int
+module_cfload_vfs(void *opaque,
+ int (*match)(void *, const char *, prop_dictionary_t))
+{
+ struct nameidata nd;
+ struct vnode *vp;
+ struct vattr va;
+ struct iovec iov;
+ struct uio uio;
+ struct dirent *dp;
+ char *dirbuf = NULL, *cpos;
+ off_t off;
+ int dirbuflen;
+ int error = 0, eofflag;
+
+ KASSERT(match != NULL);
+
+ NDINIT(&nd, LOOKUP, FOLLOW | NOCHROOT, UIO_SYSSPACE, module_base);
+ error = vn_open(&nd, FREAD, 0);
+ if (error)
+ return error;
+ vp = nd.ni_vp;
+
+ if (vp->v_type != VDIR)
+ goto done;
+
+ error = VOP_GETATTR(vp, &va, curlwp->l_cred);
+ if (error)
+ goto done;
+
+ dirbuflen = DIRBLKSIZ;
+ if (dirbuflen < va.va_blocksize)
+ dirbuflen = va.va_blocksize;
+ dirbuf = kmem_alloc(dirbuflen, KM_SLEEP);
+
+ off = 0;
+ do {
+ int len, reclen;
+
+ iov.iov_base = dirbuf;
+ iov.iov_len = dirbuflen;
+ uio.uio_iov = &iov;
+ uio.uio_iovcnt = 1;
+ uio.uio_offset = off;
+ uio.uio_resid = dirbuflen;
+ uio.uio_rw = UIO_READ;
+ UIO_SETUP_SYSSPACE(&uio);
+
+ eofflag = 0;
+ error = VOP_READDIR(vp, &uio, curlwp->l_cred, &eofflag, 0, 0);
+ if (error)
+ break;
+
+ off = uio.uio_offset;
+
+ cpos = dirbuf;
+
+ vref(vp);
+ VOP_UNLOCK(vp);
+
+ for (len = (dirbuflen - uio.uio_resid); len > 0;
+ len -= reclen) {
+ dp = (struct dirent *)cpos;
+ reclen = dp->d_reclen;
+
+ if (reclen < _DIRENT_MINSIZE(dp)) {
+ error = EINVAL;
+ eofflag = 1;
+ break;
+ }
+
+ if (dp->d_type == DT_DIR && dp->d_name[0] != '.') {
+ module_cfload_vfs_probe(opaque,
+ match, dp->d_name);
+ }
+
+ cpos += reclen;
+ }
+
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
+ vrele(vp);
+ } while (!eofflag);
+
+done:
+ if (dirbuf)
+ kmem_free(dirbuf, dirbuflen);
+ VOP_UNLOCK(vp);
+ vn_close(vp, FREAD, curlwp->l_cred);
+ return error;
+}
+
/*
* module_load_plist_vfs:
*
@@ -195,7 +342,7 @@
out:
VOP_UNLOCK(nd.ni_vp);
- vn_close(nd.ni_vp, FREAD, kauth_cred_get());
+ vn_close(nd.ni_vp, FREAD, curlwp->l_cred);
out1:
PNBUF_PUT(proppath);
Index: sys/sys/module.h
===================================================================
RCS file: /cvsroot/src/sys/sys/module.h,v
retrieving revision 1.25
diff -u -r1.25 module.h
--- sys/sys/module.h 21 Aug 2010 13:17:32 -0000 1.25
+++ sys/sys/module.h 27 Oct 2010 09:11:40 -0000
@@ -133,6 +133,7 @@
int module_builtin_add(modinfo_t * const *, size_t, bool);
int module_builtin_remove(modinfo_t *, bool);
int module_autoload(const char *, modclass_t);
+int module_cfload(void *, int (*)(void *, const char *, prop_dictionary_t));
int module_unload(const char *);
int module_hold(const char *);
void module_rele(const char *);
@@ -147,8 +148,13 @@
extern
int (*module_load_vfs_vec)(const char *, int, bool, module_t *,
prop_dictionary_t *);
+extern
+int (*module_cfload_vfs_vec)(void *, int (*)(void *, const char *,
+ prop_dictionary_t));
int module_load_vfs(const char *, int, bool, module_t *,
prop_dictionary_t *);
+int module_cfload_vfs(void *, int (*)(void *, const char *,
+ prop_dictionary_t));
void module_error(const char *, ...)
__attribute__((__format__(__printf__,1,2)));
void module_print(const char *, ...)
Index: sys/dev/acpi/wmi/wmi_acpi.c
===================================================================
RCS file: /cvsroot/src/sys/dev/acpi/wmi/wmi_acpi.c,v
retrieving revision 1.10
diff -u -r1.10 wmi_acpi.c
--- sys/dev/acpi/wmi/wmi_acpi.c 25 Oct 2010 15:38:05 -0000 1.10
+++ sys/dev/acpi/wmi/wmi_acpi.c 27 Oct 2010 09:11:40 -0000
@@ -57,6 +57,8 @@
static int acpi_wmi_detach(device_t, int);
static int acpi_wmi_rescan(device_t, const char *, const int *);
static void acpi_wmi_childdet(device_t, device_t);
+static void acpi_wmi_mountroot(device_t);
+static int acpi_wmi_cfload(void *, const char *, prop_dictionary_t);
static int acpi_wmi_print(void *, const char *);
static bool acpi_wmi_init(struct acpi_wmi_softc *);
static bool acpi_wmi_add(struct acpi_wmi_softc *, ACPI_OBJECT *);
@@ -115,9 +117,9 @@
acpi_wmi_dump(sc);
acpi_wmi_event_add(sc);
- acpi_wmi_rescan(self, NULL, NULL);
-
(void)pmf_device_register(self, acpi_wmi_suspend, acpi_wmi_resume);
+
+ config_mountroot(self, acpi_wmi_mountroot);
}
static int
@@ -157,6 +159,47 @@
sc->sc_child = NULL;
}
+static void
+acpi_wmi_mountroot(device_t self)
+{
+ module_cfload(self, acpi_wmi_cfload);
+ acpi_wmi_rescan(self, NULL, NULL);
+}
+
+static int
+acpi_wmi_cfload(void *opaque, const char *ifattr, prop_dictionary_t props)
+{
+ device_t self = opaque;
+ prop_object_t obj;
+ int match = 0;
+
+ if (ifattr == NULL || strcmp(ifattr, "acpiwmibus") != 0)
+ goto done;
+ if (props == NULL)
+ goto done;
+
+ obj = prop_dictionary_get(props, "ACPIWMIGUIDMatch");
+ if (obj && prop_object_type(obj) == PROP_TYPE_ARRAY) {
+ prop_array_t arr = (prop_array_t)obj;
+ prop_object_iterator_t iter;
+ const char *guid;
+
+ iter = prop_array_iterator(arr);
+ while ((obj = prop_object_iterator_next(iter)) != NULL) {
+ if (prop_object_type(obj) != PROP_TYPE_STRING)
+ continue;
+ guid = prop_string_cstring_nocopy((prop_string_t)obj);
+ match = acpi_wmi_guid_match(self, guid);
+ if (match)
+ break;
+ }
+ prop_object_iterator_release(iter);
+ }
+
+done:
+ return match;
+}
+
static int
acpi_wmi_print(void *aux, const char *pnp)
{