diff options
| author | Jerry Gilliam <Jerry.Gilliam@Sun.COM> | 2010-06-08 13:46:34 -0700 |
|---|---|---|
| committer | Jerry Gilliam <Jerry.Gilliam@Sun.COM> | 2010-06-08 13:46:34 -0700 |
| commit | c8742f6496e41bcf40b54b09b48835c42f91e574 (patch) | |
| tree | 30c6569140979ed1e980ac6c804767152de20246 /usr/src | |
| parent | 837b568b3a2559f8c9b9403f95104271a85d129e (diff) | |
| download | illumos-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.c | 16 | ||||
| -rw-r--r-- | usr/src/uts/common/os/modsubr.c | 23 | ||||
| -rw-r--r-- | usr/src/uts/common/sys/modctl.h | 6 |
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 *); |
