--- //depot/vendor/freebsd/src/sys/conf/files 2005/11/22 17:15:19 +++ //depot/user/jhb/pat/conf/files 2005/11/23 18:43:46 @@ -1315,6 +1315,7 @@ kern/subr_blist.c standard kern/subr_bus.c standard kern/subr_clock.c optional genclock +kern/subr_devmap.c standard kern/subr_devstat.c standard kern/subr_disk.c standard kern/subr_eventhandler.c standard --- //depot/vendor/freebsd/src/sys/kern/kern_conf.c 2005/10/18 18:30:35 +++ //depot/user/jhb/pat/kern/kern_conf.c 2005/11/08 16:53:07 @@ -180,6 +180,7 @@ #define dead_dump (dumper_t *)enxio #define dead_kqfilter (d_kqfilter_t *)enxio +#define dead_mmap_single (d_mmap_single_t *)enodev static struct cdevsw dead_cdevsw = { .d_version = D_VERSION, @@ -194,7 +195,8 @@ .d_strategy = dead_strategy, .d_name = "dead", .d_dump = dead_dump, - .d_kqfilter = dead_kqfilter + .d_kqfilter = dead_kqfilter, + .d_mmap_single = dead_mmap_single }; /* Default methods if driver does not specify method */ @@ -232,6 +234,7 @@ } #define no_dump (dumper_t *)enodev +#define no_mmap_single (d_mmap_single_t *)enodev static int giant_open(struct cdev *dev, int oflags, int devtype, struct thread *td) @@ -446,7 +449,8 @@ dsw2 = NULL; dev_lock(); - if (devsw->d_version != D_VERSION_01) { + if (devsw->d_version != D_VERSION_01 && + devsw->d_version != D_VERSION_02) { printf( "WARNING: Device driver \"%s\" has wrong version %s\n", devsw->d_name, "and is disabled. Recompile KLD module."); @@ -461,6 +465,8 @@ devsw->d_dump = dead_dump; devsw->d_kqfilter = dead_kqfilter; } + if (devsw->d_version == D_VERSION_01) + devsw->d_mmap_single = NULL; if (devsw->d_flags & D_TTY) { if (devsw->d_ioctl == NULL) devsw->d_ioctl = ttyioctl; @@ -499,6 +505,7 @@ FIXUP(d_kqfilter, no_kqfilter, giant_kqfilter); if (devsw->d_dump == NULL) devsw->d_dump = no_dump; + if (devsw->d_mmap_single == NULL) devsw->d_mmap_single = no_mmap_single; LIST_INIT(&devsw->d_devs); --- //depot/vendor/freebsd/src/sys/sys/conf.h 2005/09/19 20:01:08 +++ //depot/user/jhb/pat/sys/conf.h 2005/10/13 19:31:07 @@ -135,8 +135,16 @@ 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); +#ifdef notyet +/* XXX: can't use cache_mode_t */ +typedef int d_mmap_t(struct cdev *dev, vm_offset_t offset, vm_paddr_t *paddr, + u_char *cache_mode, int nprot); +#else typedef int d_mmap_t(struct cdev *dev, vm_offset_t offset, vm_paddr_t *paddr, - int nprot); + int nprot); +#endif +typedef int d_mmap_single_t(struct cdev *cdev, vm_offset_t offset, + vm_offset_t size, int nprot); typedef void d_purge_t(struct cdev *dev); typedef int d_spare2_t(struct cdev *dev); @@ -176,7 +184,8 @@ */ #define D_VERSION_00 0x20011966 #define D_VERSION_01 0x17032005 /* Add d_uid,gid,mode & kind */ -#define D_VERSION D_VERSION_01 +#define D_VERSION_02 0x19082005 /* Add d_mmap_single */ +#define D_VERSION D_VERSION_02 /* * Flags used for internal housekeeping @@ -202,7 +211,7 @@ dumper_t *d_dump; d_kqfilter_t *d_kqfilter; d_purge_t *d_purge; - d_spare2_t *d_spare2; + d_mmap_single_t *d_mmap_single; uid_t d_uid; gid_t d_gid; mode_t d_mode; --- //depot/vendor/freebsd/src/sys/vm/device_pager.c 2005/06/10 17:30:32 +++ //depot/user/jhb/pat/vm/device_pager.c 2005/08/25 18:52:55 @@ -133,7 +133,13 @@ * protection. * * XXX assumes VM_PROT_* == PROT_* + * + * Try d_mmap_single first. If it fails, fall back to the regular + * d_mmap. */ + if ((*csw->d_mmap_single)(dev, foff, size, (int)prot) == 0) + goto mmap_single_worked; + npages = OFF_TO_IDX(size); for (off = foff; npages--; off += PAGE_SIZE) if ((*csw->d_mmap)(dev, off, &paddr, (int)prot) != 0) { @@ -141,6 +147,7 @@ dev_relthread(dev); return (NULL); } +mmap_single_worked: /* * Lock to prevent object creation race condition.