Index: sys/kern/subr_bus.c =================================================================== --- sys/kern/subr_bus.c +++ sys/kern/subr_bus.c @@ -5707,6 +5707,30 @@ bus_data_generation_update(); } +static const char * +device_get_path(device_t dev, const char *locator) +{ + struct sbuf *sb; + ssize_t len; + const char *rv = NULL; + char *r; + int error; + + sb = sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND | SBUF_INCLUDENUL); + error = BUS_GET_DEVICE_PATH(device_get_parent(dev), dev, locator, sb); + sbuf_finish(sb); + if (error != 0) + goto out; + len = sbuf_len(sb); + if (len <= 1) + goto out; + rv = r = malloc(len, M_BUS, M_NOWAIT); + memcpy(r, sbuf_data(sb), len); +out: + sbuf_delete(sb); + return rv; +} + static int devctl2_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag, struct thread *td) @@ -5730,6 +5754,7 @@ case DEV_RESCAN: case DEV_DELETE: case DEV_RESET: + case DEV_GET_PATH: error = priv_check(td, PRIV_DRIVER); if (error == 0) error = find_device(req, &dev); @@ -5963,6 +5988,29 @@ error = BUS_RESET_CHILD(device_get_parent(dev), dev, req->dr_flags); break; + case DEV_GET_PATH: { + char locator[64]; + const char *path; + ssize_t len; + + error = copyinstr(req->dr_buffer.buffer, locator, sizeof(locator), NULL); + if (error) + break; + path = device_get_path(dev, locator); + if (path == NULL) { + error = ENOMEM; + break; + } + len = strlen(path) + 1; + if (req->dr_buffer.length < len) { + error = ENAMETOOLONG; + } else { + error = copyout(path, req->dr_buffer.buffer, len); + } + req->dr_buffer.length = len; + free(__DECONST(void *, path), M_BUS); + break; + } } mtx_unlock(&Giant); return (error); Index: sys/sys/bus.h =================================================================== --- sys/sys/bus.h +++ sys/sys/bus.h @@ -130,6 +130,7 @@ #define DEV_FREEZE _IOW('D', 11, struct devreq) #define DEV_THAW _IOW('D', 12, struct devreq) #define DEV_RESET _IOW('D', 13, struct devreq) +#define DEV_GET_PATH _IOWR('D', 14, struct devreq) /* Flags for DEV_DETACH and DEV_DISABLE. */ #define DEVF_FORCE_DETACH 0x0000001