Index: sys/kern/subr_bus.c =================================================================== --- sys/kern/subr_bus.c +++ sys/kern/subr_bus.c @@ -5730,6 +5730,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 +5964,40 @@ error = BUS_RESET_CHILD(device_get_parent(dev), dev, req->dr_flags); break; + case DEV_GET_PATH: { + struct sbuf *sb; + char locator[64]; + ssize_t len; + + error = copyinstr(req->dr_buffer.buffer, locator, sizeof(locator), NULL); + if (error) + break; + printf("Please find path to %s using %s\n", device_get_nameunit(dev), locator); + sb = sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND | SBUF_INCLUDENUL); + error = BUS_GET_DEVICE_PATH(device_get_parent(dev), dev, + locator, sb); + printf("Error = %d\n", error); + sbuf_finish(sb); + if (error == 0) { + len = sbuf_len(sb); + if (len < 0) { + printf("no mem\n"); + error = ENOMEM; + } else if (req->dr_buffer.length < len) { + printf("too short %zd vs %zd\n", + req->dr_buffer.length, len); + req->dr_buffer.length = len; + error = ENAMETOOLONG; + } else { + req->dr_buffer.length = len; + printf("Found it! len = %zd, path = %s\n", len, sbuf_data(sb)); + error = copyout(sbuf_data(sb), + req->dr_buffer.buffer, len); + } + } + sbuf_delete(sb); + 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