[Xenomai-git] Philippe Gerum : drivers/udd: fix mapper device supporting multiple regions
Module: xenomai-3 Branch: master Commit: 06b93e2908fc4712690c72e57d191125ab4b57dc URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=06b93e2908fc4712690c72e57d191125ab4b57dc Author: Philippe Gerum r...@xenomai.org Date: Sat Apr 18 11:12:51 2015 +0200 drivers/udd: fix mapper device supporting multiple regions --- include/cobalt/kernel/rtdm/udd.h |5 ++- kernel/drivers/udd/udd.c | 62 +++--- 2 files changed, 49 insertions(+), 18 deletions(-) diff --git a/include/cobalt/kernel/rtdm/udd.h b/include/cobalt/kernel/rtdm/udd.h index 8190d98..028e602 100644 --- a/include/cobalt/kernel/rtdm/udd.h +++ b/include/cobalt/kernel/rtdm/udd.h @@ -287,7 +287,10 @@ struct udd_device { struct rtdm_driver driver; struct rtdm_device device; struct rtdm_driver mapper_driver; - struct rtdm_device mapper; + struct udd_mapper { + struct udd_device *udd; + struct rtdm_device dev; + } mapdev[UDD_NR_MAPS]; char *mapper_name; int nr_maps; } __reserved; diff --git a/kernel/drivers/udd/udd.c b/kernel/drivers/udd/udd.c index e5a12a1..edac81a 100644 --- a/kernel/drivers/udd/udd.c +++ b/kernel/drivers/udd/udd.c @@ -208,7 +208,7 @@ static int mapper_open(struct rtdm_fd *fd, int oflags) if (minor 0 || minor = UDD_NR_MAPS) return -EIO; - udd = container_of(rtdm_fd_device(fd), struct udd_device, __reserved.mapper); + udd = udd_get_device(fd); if (udd-mem_regions[minor].type == UDD_MEM_NONE) return -EIO; @@ -227,7 +227,7 @@ static int mapper_mmap(struct rtdm_fd *fd, struct vm_area_struct *vma) size_t len; int ret; - udd = container_of(rtdm_fd_device(fd), struct udd_device, __reserved.mapper); + udd = udd_get_device(fd); if (udd-ops.mmap) /* Offload to client driver if handler is present. */ return udd-ops.mmap(fd, vma); @@ -260,10 +260,6 @@ static int mapper_mmap(struct rtdm_fd *fd, struct vm_area_struct *vma) static inline int check_memregion(struct udd_device *udd, struct udd_memregion *rn) { - /* We allow sparse region arrays. */ - if (rn-type == UDD_MEM_NONE) - return 0; - if (rn-name == NULL) return -EINVAL; @@ -273,16 +269,16 @@ static inline int check_memregion(struct udd_device *udd, if (rn-len == 0) return -EINVAL; - udd-__reserved.nr_maps++; - return 0; } static inline int register_mapper(struct udd_device *udd) { struct udd_reserved *ur = udd-__reserved; - struct rtdm_device *dev = ur-mapper; struct rtdm_driver *drv = ur-mapper_driver; + struct udd_mapper *mapper; + struct udd_memregion *rn; + int n, ret; ur-mapper_name = kasformat(%s,mapper%%d, udd-device_name); if (ur-mapper_name == NULL) @@ -291,17 +287,33 @@ static inline int register_mapper(struct udd_device *udd) drv-profile_info = (struct rtdm_profile_info) RTDM_PROFILE_INFO(mapper, RTDM_CLASS_MEMORY, RTDM_SUBCLASS_GENERIC, 0); - drv-device_flags = RTDM_NAMED_DEVICE; + drv-device_flags = RTDM_NAMED_DEVICE|RTDM_FIXED_MINOR; drv-device_count = UDD_NR_MAPS; drv-ops = (struct rtdm_fd_ops){ .open = mapper_open, .close = mapper_close, .mmap = mapper_mmap, }; - dev-driver = drv; - dev-label = ur-mapper_name; - return rtdm_dev_register(dev); + for (n = 0, mapper = ur-mapdev; n UDD_NR_MAPS; n++, mapper++) { + rn = udd-mem_regions + n; + if (rn-type == UDD_MEM_NONE) + continue; + mapper-dev.driver = drv; + mapper-dev.label = ur-mapper_name; + mapper-dev.minor = n; + mapper-udd = udd; + ret = rtdm_dev_register(mapper-dev); + if (ret) + goto undo; + } + + return 0; +undo: + while (--n = 0) + rtdm_dev_unregister(ur-mapdev[n].dev); + + return ret; } /** @@ -337,6 +349,7 @@ int udd_register_device(struct udd_device *udd) struct rtdm_device *dev = udd-__reserved.device; struct udd_reserved *ur = udd-__reserved; struct rtdm_driver *drv = ur-driver; + struct udd_memregion *rn; int ret, n; if (!realtime_core_enabled()) @@ -349,9 +362,14 @@ int udd_register_device(struct udd_device *udd) return -EINVAL; for (n = 0, ur-nr_maps = 0; n UDD_NR_MAPS; n++) { - ret = check_memregion(udd, udd-mem_regions + n); + /* We allow sparse region
[Xenomai-git] Philippe Gerum : drivers/udd: fix mapper device supporting multiple regions
Module: xenomai-3 Branch: next Commit: b41a23aebb37a50ef6c734f2813277d29007c67e URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=b41a23aebb37a50ef6c734f2813277d29007c67e Author: Philippe Gerum r...@xenomai.org Date: Sat Apr 18 11:12:51 2015 +0200 drivers/udd: fix mapper device supporting multiple regions --- include/cobalt/kernel/rtdm/udd.h |5 +++- kernel/drivers/udd/udd.c | 61 +++--- 2 files changed, 48 insertions(+), 18 deletions(-) diff --git a/include/cobalt/kernel/rtdm/udd.h b/include/cobalt/kernel/rtdm/udd.h index 8190d98..028e602 100644 --- a/include/cobalt/kernel/rtdm/udd.h +++ b/include/cobalt/kernel/rtdm/udd.h @@ -287,7 +287,10 @@ struct udd_device { struct rtdm_driver driver; struct rtdm_device device; struct rtdm_driver mapper_driver; - struct rtdm_device mapper; + struct udd_mapper { + struct udd_device *udd; + struct rtdm_device dev; + } mapdev[UDD_NR_MAPS]; char *mapper_name; int nr_maps; } __reserved; diff --git a/kernel/drivers/udd/udd.c b/kernel/drivers/udd/udd.c index e5a12a1..4a47e59 100644 --- a/kernel/drivers/udd/udd.c +++ b/kernel/drivers/udd/udd.c @@ -208,7 +208,7 @@ static int mapper_open(struct rtdm_fd *fd, int oflags) if (minor 0 || minor = UDD_NR_MAPS) return -EIO; - udd = container_of(rtdm_fd_device(fd), struct udd_device, __reserved.mapper); + udd = udd_get_device(fd); if (udd-mem_regions[minor].type == UDD_MEM_NONE) return -EIO; @@ -227,7 +227,7 @@ static int mapper_mmap(struct rtdm_fd *fd, struct vm_area_struct *vma) size_t len; int ret; - udd = container_of(rtdm_fd_device(fd), struct udd_device, __reserved.mapper); + udd = udd_get_device(fd); if (udd-ops.mmap) /* Offload to client driver if handler is present. */ return udd-ops.mmap(fd, vma); @@ -260,10 +260,6 @@ static int mapper_mmap(struct rtdm_fd *fd, struct vm_area_struct *vma) static inline int check_memregion(struct udd_device *udd, struct udd_memregion *rn) { - /* We allow sparse region arrays. */ - if (rn-type == UDD_MEM_NONE) - return 0; - if (rn-name == NULL) return -EINVAL; @@ -273,16 +269,16 @@ static inline int check_memregion(struct udd_device *udd, if (rn-len == 0) return -EINVAL; - udd-__reserved.nr_maps++; - return 0; } static inline int register_mapper(struct udd_device *udd) { struct udd_reserved *ur = udd-__reserved; - struct rtdm_device *dev = ur-mapper; struct rtdm_driver *drv = ur-mapper_driver; + struct udd_mapper *mapper; + struct udd_memregion *rn; + int n, ret; ur-mapper_name = kasformat(%s,mapper%%d, udd-device_name); if (ur-mapper_name == NULL) @@ -291,17 +287,32 @@ static inline int register_mapper(struct udd_device *udd) drv-profile_info = (struct rtdm_profile_info) RTDM_PROFILE_INFO(mapper, RTDM_CLASS_MEMORY, RTDM_SUBCLASS_GENERIC, 0); - drv-device_flags = RTDM_NAMED_DEVICE; + drv-device_flags = RTDM_NAMED_DEVICE|RTDM_FIXED_MINOR; drv-device_count = UDD_NR_MAPS; drv-ops = (struct rtdm_fd_ops){ .open = mapper_open, .close = mapper_close, .mmap = mapper_mmap, }; - dev-driver = drv; - dev-label = ur-mapper_name; - return rtdm_dev_register(dev); + for (n = 0, mapper = ur-mapdev; n UDD_NR_MAPS; n++, mapper++) { + rn = udd-mem_regions + n; + if (rn-type == UDD_MEM_NONE) + continue; + mapper-dev.driver = drv; + mapper-dev.label = ur-mapper_name; + mapper-dev.minor = n; + ret = rtdm_dev_register(mapper-dev); + if (ret) + goto undo; + } + + return 0; +undo: + while (--n = 0) + rtdm_dev_unregister(ur-mapdev[n].dev); + + return ret; } /** @@ -337,6 +348,7 @@ int udd_register_device(struct udd_device *udd) struct rtdm_device *dev = udd-__reserved.device; struct udd_reserved *ur = udd-__reserved; struct rtdm_driver *drv = ur-driver; + struct udd_memregion *rn; int ret, n; if (!realtime_core_enabled()) @@ -349,9 +361,14 @@ int udd_register_device(struct udd_device *udd) return -EINVAL; for (n = 0, ur-nr_maps = 0; n UDD_NR_MAPS; n++) { - ret = check_memregion(udd, udd-mem_regions + n); + /* We allow sparse region arrays. */ + rn =