summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/os/modctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/uts/common/os/modctl.c')
-rw-r--r--usr/src/uts/common/os/modctl.c82
1 files changed, 76 insertions, 6 deletions
diff --git a/usr/src/uts/common/os/modctl.c b/usr/src/uts/common/os/modctl.c
index 3509231ee2..4acbaae74f 100644
--- a/usr/src/uts/common/os/modctl.c
+++ b/usr/src/uts/common/os/modctl.c
@@ -1098,7 +1098,7 @@ modctl_get_minorname(dev_t dev, int spectype, uint_t len, char *uname)
}
/*
- * Return the size of the devfspath name.
+ * Return the size of the (dev_t,spectype) devfspath name.
*/
static int
modctl_devfspath_len(dev_t dev, int spectype, uint_t *len)
@@ -1124,7 +1124,7 @@ modctl_devfspath_len(dev_t dev, int spectype, uint_t *len)
}
/*
- * Return the devfspath name.
+ * Return the (dev_t,spectype) devfspath name.
*/
static int
modctl_devfspath(dev_t dev, int spectype, uint_t len, char *uname)
@@ -1155,6 +1155,66 @@ modctl_devfspath(dev_t dev, int spectype, uint_t len, char *uname)
return (err);
}
+/*
+ * Return the size of the (major,instance) devfspath name.
+ */
+static int
+modctl_devfspath_mi_len(major_t major, int instance, uint_t *len)
+{
+ uint_t sz;
+ char *name;
+
+ /* get the path name */
+ name = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
+ if (e_ddi_majorinstance_to_path(major, instance, name) != DDI_SUCCESS) {
+ kmem_free(name, MAXPATHLEN);
+ return (EINVAL);
+ }
+
+ sz = strlen(name) + 1;
+ kmem_free(name, MAXPATHLEN);
+
+ /* copy out the size of the path name */
+ if (copyout(&sz, len, sizeof (sz)) != 0)
+ return (EFAULT);
+
+ return (0);
+}
+
+/*
+ * Return the (major_instance) devfspath name.
+ * NOTE: e_ddi_majorinstance_to_path does not require the device to attach to
+ * return a path - it uses the instance tree.
+ */
+static int
+modctl_devfspath_mi(major_t major, int instance, uint_t len, char *uname)
+{
+ uint_t sz;
+ char *name;
+ int err = 0;
+
+ /* get the path name */
+ name = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
+ if (e_ddi_majorinstance_to_path(major, instance, name) != DDI_SUCCESS) {
+ kmem_free(name, MAXPATHLEN);
+ return (EINVAL);
+ }
+
+ sz = strlen(name) + 1;
+
+ /* Error if the path name is larger than the space allocated */
+ if (sz > len) {
+ kmem_free(name, MAXPATHLEN);
+ return (ENOSPC);
+ }
+
+ /* copy out the path name */
+ if (copyout(name, uname, sz) != 0)
+ err = EFAULT;
+ kmem_free(name, MAXPATHLEN);
+ return (err);
+}
+
static int
modctl_get_fbname(char *path)
{
@@ -1874,7 +1934,7 @@ modctl(int cmd, uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4,
error = modctl_get_devid(dev, (uint_t)a2, (ddi_devid_t)a3);
break;
- case MODSIZEOF_MINORNAME: /* sizeof minor nm of dev_t/spectype */
+ case MODSIZEOF_MINORNAME: /* sizeof minor nm (dev_t,spectype) */
if (get_udatamodel() == DATAMODEL_NATIVE) {
error = modctl_sizeof_minorname((dev_t)a1, (int)a2,
(uint_t *)a3);
@@ -1888,7 +1948,7 @@ modctl(int cmd, uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4,
#endif
break;
- case MODGETMINORNAME: /* get minor name of dev_t and spec type */
+ case MODGETMINORNAME: /* get minor name of (dev_t,spectype) */
if (get_udatamodel() == DATAMODEL_NATIVE) {
error = modctl_get_minorname((dev_t)a1, (int)a2,
(uint_t)a3, (char *)a4);
@@ -1901,7 +1961,7 @@ modctl(int cmd, uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4,
#endif
break;
- case MODGETDEVFSPATH_LEN: /* sizeof path nm of dev_t/spectype */
+ case MODGETDEVFSPATH_LEN: /* sizeof path nm of (dev_t,spectype) */
if (get_udatamodel() == DATAMODEL_NATIVE) {
error = modctl_devfspath_len((dev_t)a1, (int)a2,
(uint_t *)a3);
@@ -1915,7 +1975,7 @@ modctl(int cmd, uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4,
#endif
break;
- case MODGETDEVFSPATH: /* get path name of dev_t and spec type */
+ case MODGETDEVFSPATH: /* get path name of (dev_t,spec) type */
if (get_udatamodel() == DATAMODEL_NATIVE) {
error = modctl_devfspath((dev_t)a1, (int)a2,
(uint_t)a3, (char *)a4);
@@ -1928,6 +1988,16 @@ modctl(int cmd, uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4,
#endif
break;
+ case MODGETDEVFSPATH_MI_LEN: /* sizeof path nm of (major,instance) */
+ error = modctl_devfspath_mi_len((major_t)a1, (int)a2,
+ (uint_t *)a3);
+ break;
+
+ case MODGETDEVFSPATH_MI: /* get path name of (major,instance) */
+ error = modctl_devfspath_mi((major_t)a1, (int)a2,
+ (uint_t)a3, (char *)a4);
+ break;
+
case MODEVENTS:
error = modctl_modevents((int)a1, a2, a3, a4, (uint_t)a5);