On 08/30/2017 08:48 PM, Jeff Webb wrote: > On 08/29/2017 02:56 AM, Philippe Gerum wrote: >> On 08/28/2017 08:45 PM, Jeff Webb wrote: >>> On 08/07/2017 11:15 AM, Jeff Webb wrote: >>>> On 08/07/2017 10:08 AM, Jeff Webb wrote: >>>>> I am attempting to port legacy Xenomai 2.6.4 code to Xenomai 3. >>>>> In our current code base, we implement userspace drivers using >>>>> libpci, iopl, inb/outb, /dev/mem, and the pthread_intr_*_np >>>>> family of functions. Since the pthread_intr_*_np functions are >>>>> no longer part of Xenomai, I have been researching and >>>>> experimenting with the new UDD framework as a replacement. >>>>> Although documentation and examples are a little scarce, I have >>>>> found most of the information I need. I also used some >>>>> documentation on the Linux UIO framwork to fill in some gaps in >>>>> my knowledge. My preliminary conclusion is that using the UDD >>>>> framework would allow us to port our existing code base without >>>>> too much modification, but I still have a few remaining >>>>> questions. >>>>> >>>>> I see the way that PCI device memory regions can be accessed >>>>> using mmap with UDD_MEM_PHYS mem_regions, but on some PCI devices >>>>> we also need to access I/O port regions, such as: >>>>> >>>>> Region 0: Memory at f7102000 (32-bit, non-prefetchable) [size=128] >>>>> Region 1: I/O ports at b100 [size=128] >>>>> Region 2: I/O ports at b280 [size=4] >>>>> >>>>> The UIO documentation recommends using the struct uio_info's port >>>>> field (an array of 'uio_port' structs) to pass information about >>>>> the I/O port regions associated with the device to userspace. I >>>>> did not see the equivalent of this functionality in the UDD >>>>> framework, and was wondering why it was omitted. What is the >>>>> recommended way of determining the ports associated with a device >>>>> when using a UDD driver? It seems like continuing to do this >>>>> using libpci and then somehow matching this up with the >>>>> corresponding UDD device would be messy and error-prone. >>>> >>>> If no other support exists, perhaps I could use kmalloc to allocate a >>>> UDD_MEM_LOGICAL region corresponding to each PCI I/O port region on the >>>> card. The kernel UDD driver would then populate these regions with >>>> the I/O addresses of the corresponding PCI I/O port regions. The >>>> UDD_MEM_LOGICAL regions could then be read by the userspace driver >>>> to determine the I/O address to use with inb/outb (and iopl). >>> >>> Another way would be to pass the port I/O region addresses (and possibly >>> sizes) to userspace via explicit IOCTLs. If so, should the IOCTL >>> numbers for such a use case be standardized? >>> >>> If there is no standard way to do this sort of thing, and if there are >>> no recommendations about how to do proceed, I'll just do what feels >>> right in my case, but I thought someone might have some experience or >>> opinion on how this should be done in the Xenomai UDD context, since the >>> Linux UIO method of passing port information is not available. >>> >> >> I would implement this as the original UIO driver does, which is >> basically about adding a sysfs hierarchy that represents each I/O port >> range declared by the UIO device. >> >> For UDD, that would entail adding an array of "udd_ioport" structures to >> struct udd_device to be filled in by the caller. Then, >> udd_register_device() would iterate over this array, creating sysfs >> entries on the fly, based on the information available into each ioport >> definition, such as name, start and size. >> >> The sysfs mechanism has the advantage of only requiring to define a pack >> of attributes and a couple of sysfs handlers for showing them. Besides, >> requiring that the app retrieves those attributes from secondary mode at >> init, using regular file I/O on sysfs entries seems acceptable, those >> attributes are not supposed to vary anyway. > > That sounds like good advice, Philippe. Thanks. > > Your suggestion to follow the UIO approach for the I/O ports now > has me wondering why the Linux UIO approach and structures > weren't mirrored more closely in Xenomai UDD. I personally like > the way some things are done better in UDD, but I would think > that keeping things as similar as possible to how the standard > kernel works would ease the learning curve and allow some of the > init code to be reused, but I might be missing something. It > would seem that the UDD and UIO kernel-space code one would need > to write for a particular device would be almost identical, and > having the APIs as similar as possible would be desirable. > >
IIRC, having to pass the mapping number in the offset field of the mmap() request with UIO (offset = N * getpagesize()) was the scary API detail that froze my brain machinery. From that point, I did not care that much for compatibility between UIO and UDD for the rest of the API, a stance which was admittedly wrong. There are things imposed on Cobalt drivers though, such as having the device nodes managed by RTDM under the /dev/rtdm hierarchy, and not by sysfs. The choice of using the ioctl() interface instead of read()/write() for interrupt control has no particular justification. So I agree with you. In retrospect, if I were to (re)write UDD, I would indeed conform to the UIO interface for all technically compatible aspects, except for the mmap() support where providing a distinct device entry for each mapping is clearly better. -- Philippe. _______________________________________________ Xenomai mailing list [email protected] https://xenomai.org/mailman/listinfo/xenomai
