Index: sys/fs/devfs/devfs_vnops.c =================================================================== --- sys/fs/devfs/devfs_vnops.c +++ sys/fs/devfs/devfs_vnops.c @@ -769,16 +769,17 @@ /* ARGSUSED */ static int -devfs_ioctl_f(struct file *fp, u_long com, void *data, struct ucred *cred, struct thread *td) +devfs_ioctl_f(struct file *fp, u_long com, void *data, struct ucred *cred, + struct thread *td) { struct cdev *dev; struct cdevsw *dsw; struct vnode *vp; struct vnode *vpold; - int error, i, ref; - const char *p; + char *p; struct fiodgname_arg *fgn; struct file *fpop; + int error, i, ref; fpop = td->td_fpop; error = devfs_fp_check(fp, &dev, &dsw, &ref); @@ -794,12 +795,16 @@ return (0); } else if (com == FIODGNAME) { fgn = data; - p = devtoname(dev); - i = strlen(p) + 1; - if (i > fgn->len) - error = EINVAL; - else - error = copyout(p, fgn->buf, i); + p = malloc(SPECNAMELEN + 1, M_TEMP, M_WAITOK); + error = dsw->d_devname(dev, p, SPECNAMELEN + 1); + if (error == 0) { + i = strlen(p) + 1; + if (i > fgn->len) + error = EINVAL; + else + error = copyout(p, fgn->buf, i); + } + free(p, M_TEMP); td->td_fpop = fpop; dev_relthread(dev, ref); return (error); Index: sys/kern/kern_conf.c =================================================================== --- sys/kern/kern_conf.c +++ sys/kern/kern_conf.c @@ -301,6 +301,14 @@ biofinish(bp, NULL, ENXIO); } +static int +dead_devname(struct cdev *dev, char *buf, size_t len) +{ + + strlcpy(buf, dev->si_name, len); + return (0); +} + #define dead_dump (dumper_t *)enxio #define dead_kqfilter (d_kqfilter_t *)enxio #define dead_mmap_single (d_mmap_single_t *)enodev @@ -318,7 +326,8 @@ .d_name = "dead", .d_dump = dead_dump, .d_kqfilter = dead_kqfilter, - .d_mmap_single = dead_mmap_single + .d_mmap_single = dead_mmap_single, + .d_devname = dead_devname, }; /* Default methods if driver does not specify method */ @@ -531,6 +540,22 @@ return (retval); } +static int +giant_devname(struct cdev *dev, char *buf, size_t len) +{ + struct cdevsw *dsw; + int ref, retval; + + dsw = dev_refthread(dev, &ref); + if (dsw == NULL) + return (ENXIO); + mtx_lock(&Giant); + retval = dsw->d_gianttrick->d_devname(dev, buf, len); + mtx_unlock(&Giant); + dev_relthread(dev, ref); + return (retval); +} + static void notify(struct cdev *dev, const char *ev, int flags) { @@ -623,7 +648,7 @@ return (0); } - if (devsw->d_version != D_VERSION_03) { + if (devsw->d_version != D_VERSION_04) { printf( "WARNING: Device driver \"%s\" has wrong version %s\n", devsw->d_name == NULL ? "???" : devsw->d_name, @@ -639,6 +664,7 @@ devsw->d_strategy = dead_strategy; devsw->d_dump = dead_dump; devsw->d_kqfilter = dead_kqfilter; + devsw->d_devname = dead_devname; } if (devsw->d_flags & D_NEEDGIANT) { @@ -669,13 +695,13 @@ FIXUP(d_strategy, no_strategy, giant_strategy); FIXUP(d_kqfilter, no_kqfilter, giant_kqfilter); FIXUP(d_mmap_single, no_mmap_single, giant_mmap_single); + FIXUP(d_devname, dead_devname, giant_devname); +#undef FIXUP - if (devsw->d_dump == NULL) devsw->d_dump = no_dump; - + if (devsw->d_dump == NULL) + devsw->d_dump = no_dump; LIST_INIT(&devsw->d_devs); - devsw->d_flags |= D_INIT; - if (dsw2 != NULL) cdevsw_free_devlocked(dsw2); return (0); Index: sys/sys/conf.h =================================================================== --- sys/sys/conf.h +++ sys/sys/conf.h @@ -106,22 +106,25 @@ struct vm_object; struct vnode; -typedef int d_open_t(struct cdev *dev, int oflags, int devtype, struct thread *td); -typedef int d_fdopen_t(struct cdev *dev, int oflags, struct thread *td, struct file *fp); -typedef int d_close_t(struct cdev *dev, int fflag, int devtype, struct thread *td); -typedef void d_strategy_t(struct bio *bp); +typedef int d_open_t(struct cdev *dev, int oflags, int devtype, + struct thread *td); +typedef int d_fdopen_t(struct cdev *dev, int oflags, struct thread *td, + struct file *fp); +typedef int d_close_t(struct cdev *dev, int fflag, int devtype, + struct thread *td); +typedef int d_devname_t(struct cdev *dev, char *buf, size_t len); typedef int d_ioctl_t(struct cdev *dev, u_long cmd, caddr_t data, - int fflag, struct thread *td); - + int fflag, struct thread *td); typedef int d_read_t(struct cdev *dev, struct uio *uio, int ioflag); typedef int d_write_t(struct cdev *dev, struct uio *uio, int ioflag); typedef int d_poll_t(struct cdev *dev, int events, struct thread *td); typedef int d_kqfilter_t(struct cdev *dev, struct knote *kn); typedef int d_mmap_t(struct cdev *dev, vm_ooffset_t offset, vm_paddr_t *paddr, - int nprot, vm_memattr_t *memattr); + int nprot, vm_memattr_t *memattr); typedef int d_mmap_single_t(struct cdev *cdev, vm_ooffset_t *offset, - vm_size_t size, struct vm_object **object, int nprot); + vm_size_t size, struct vm_object **object, int nprot); typedef void d_purge_t(struct cdev *dev); +typedef void d_strategy_t(struct bio *bp); typedef int dumper_t( void *_priv, /* Private to the driver. */ @@ -159,7 +162,8 @@ #define D_VERSION_01 0x17032005 /* Add d_uid,gid,mode & kind */ #define D_VERSION_02 0x28042009 /* Add d_mmap_single */ #define D_VERSION_03 0x17122009 /* d_mmap takes memattr,vm_ooffset_t */ -#define D_VERSION D_VERSION_03 +#define D_VERSION_04 0x55e81e6f /* d_devname */ +#define D_VERSION D_VERSION_04 /* * Flags used for internal housekeeping @@ -186,6 +190,7 @@ d_kqfilter_t *d_kqfilter; d_purge_t *d_purge; d_mmap_single_t *d_mmap_single; + d_devname_t *d_devname; int32_t d_spare0[3]; void *d_spare1[3];