summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorJerry Gilliam <Jerry.Gilliam@Sun.COM>2010-06-08 13:46:34 -0700
committerJerry Gilliam <Jerry.Gilliam@Sun.COM>2010-06-08 13:46:34 -0700
commitc8742f6496e41bcf40b54b09b48835c42f91e574 (patch)
tree30c6569140979ed1e980ac6c804767152de20246 /usr/src
parent837b568b3a2559f8c9b9403f95104271a85d129e (diff)
downloadillumos-joyent-c8742f6496e41bcf40b54b09b48835c42f91e574.tar.gz
6955559 ddi_driver_name() returns NULL to e_ddi_free_instance(), leading to a bad trap panic in in_drvwalk()
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/uts/common/os/devcfg.c16
-rw-r--r--usr/src/uts/common/os/modsubr.c23
-rw-r--r--usr/src/uts/common/sys/modctl.h6
3 files changed, 29 insertions, 16 deletions
diff --git a/usr/src/uts/common/os/devcfg.c b/usr/src/uts/common/os/devcfg.c
index 7c38ca4220..2b3314bd13 100644
--- a/usr/src/uts/common/os/devcfg.c
+++ b/usr/src/uts/common/os/devcfg.c
@@ -937,7 +937,7 @@ init_node(dev_info_t *dip)
* to add a path-oriented alias for both paths.
*/
major = ddi_name_to_major(path);
- if (driver_installed(major) && (major != DEVI(dip)->devi_major) &&
+ if (driver_active(major) && (major != DEVI(dip)->devi_major) &&
(ndi_dev_is_persistent_node(dip) || driver_conf_allow_path_alias)) {
/* Mark node for rebind processing. */
@@ -2741,7 +2741,7 @@ ddi_compatible_driver_major(dev_info_t *dip, char **formp)
if (devi->devi_flags & DEVI_REBIND) {
p = devi->devi_rebinding_name;
major = ddi_name_to_major(p);
- if (driver_installed(major)) {
+ if (driver_active(major)) {
if (formp)
*formp = p;
return (major);
@@ -2764,7 +2764,7 @@ ddi_compatible_driver_major(dev_info_t *dip, char **formp)
/* find the highest precedence compatible form with a driver binding */
while ((p = prom_decode_composite_string(compat, len, p)) != NULL) {
major = ddi_name_to_major(p);
- if (driver_installed(major)) {
+ if (driver_active(major)) {
if (formp)
*formp = p;
return (major);
@@ -2776,7 +2776,7 @@ ddi_compatible_driver_major(dev_info_t *dip, char **formp)
* the node name has a driver binding.
*/
major = ddi_name_to_major(ddi_node_name(dip));
- if (driver_installed(major))
+ if (driver_active(major))
return (major);
/* no driver */
@@ -4285,13 +4285,13 @@ bind_dip(dev_info_t *dip, void *arg)
path = kmem_alloc(MAXPATHLEN, KM_SLEEP);
(void) ddi_pathname(dip, path);
pmajor = ddi_name_to_major(path);
- if (driver_installed(pmajor))
+ if (driver_active(pmajor))
major = pmajor;
kmem_free(path, MAXPATHLEN);
}
/* attempt unbind if current driver is incorrect */
- if (driver_installed(major) &&
+ if (driver_active(major) &&
(major != DEVI(dip)->devi_major))
(void) ndi_devi_unbind_driver(dip);
}
@@ -6686,7 +6686,7 @@ path_to_major(char *path)
/* check for path-oriented alias */
major = ddi_name_to_major(path);
- if (driver_installed(major)) {
+ if (driver_active(major)) {
NDI_CONFIG_DEBUG((CE_NOTE, "path_to_major: %s path bound %s\n",
path, ddi_major_to_name(major)));
return (major);
@@ -7261,7 +7261,7 @@ ddi_hold_installed_driver(major_t major)
*/
dnp = &devnamesp[major];
enter_driver(dnp);
- ASSERT(driver_installed(major));
+ ASSERT(driver_active(major));
if (dnp->dn_flags & DN_DRIVER_HELD) {
exit_driver(dnp);
diff --git a/usr/src/uts/common/os/modsubr.c b/usr/src/uts/common/os/modsubr.c
index b75c772d14..cccffffaba 100644
--- a/usr/src/uts/common/os/modsubr.c
+++ b/usr/src/uts/common/os/modsubr.c
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
*/
#include <sys/param.h>
@@ -73,10 +72,22 @@ static void hwc_hash(struct hwc_spec *, major_t);
static void hwc_unhash(struct hwc_spec *);
int
+major_valid(major_t major)
+{
+ return (major != DDI_MAJOR_T_NONE &&
+ (major >= 0 && major < devcnt));
+}
+
+int
driver_installed(major_t major)
{
- return ((major < devcnt) && (major != DDI_MAJOR_T_NONE) &&
- !(devnamesp[major].dn_flags &
+ return (major_valid(major) && devnamesp[major].dn_name != NULL);
+}
+
+int
+driver_active(major_t major)
+{
+ return (driver_installed(major) && !(devnamesp[major].dn_flags &
(DN_DRIVER_REMOVED|DN_DRIVER_INACTIVE)));
}
@@ -87,7 +98,7 @@ mod_hold_dev_by_major(major_t major)
int loaded;
char *drvname;
- if (!driver_installed(major))
+ if (!driver_active(major))
return (NULL);
LOCK_DEV_OPS(&(devnamesp[major].dn_lock));
@@ -121,7 +132,7 @@ mod_rele_dev_by_major(major_t major)
struct dev_ops *ops;
struct devnames *dnp;
- if (!driver_installed(major))
+ if (!driver_active(major))
return;
dnp = &devnamesp[major];
diff --git a/usr/src/uts/common/sys/modctl.h b/usr/src/uts/common/sys/modctl.h
index 3ac19b948e..391768d5a5 100644
--- a/usr/src/uts/common/sys/modctl.h
+++ b/usr/src/uts/common/sys/modctl.h
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
*/
#ifndef _SYS_MODCTL_H
@@ -595,7 +594,10 @@ extern modctl_t *mod_load_requisite(modctl_t *, char *);
extern modctl_t *mod_find_by_filename(char *, char *);
extern uintptr_t modgetsymvalue(char *, int);
+extern int major_valid(major_t);
extern int driver_installed(major_t);
+extern int driver_active(major_t);
+
extern void mod_rele_dev_by_major(major_t);
extern struct dev_ops *mod_hold_dev_by_major(major_t);
extern struct dev_ops *mod_hold_dev_by_devi(dev_info_t *);